123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- using Azure.Cosmos;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Models;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.Models.Dto;
- using TEAMModelOS.SDK;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
- using TEAMModelOS.SDK.Helper.Common.StringHelper;
- namespace TEAMModelOS.Controllers
- {
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- //[Authorize(Roles = "IES5")]
- //[Route("knowledge")]
- //[ApiController]
- //[Authorize]
- public class KnowledgeController : ControllerBase
- {
- private readonly AzureStorageFactory _azureStorage;
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly SnowflakeId _snowflakeId;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- public KnowledgeController(AzureStorageFactory azureStorage, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId,DingDing dingDing, IOptionsSnapshot<Option> option)
- {
- _snowflakeId = snowflakeId;
- _azureStorage = azureStorage;
- _azureCosmos = azureCosmos;
- _dingDing = dingDing;
- _option = option?.Value;
- }
- /// <summary>
- /// 删除学校 知识点 或 知识块 代理
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="request"></param>
- /// <param name="builder"></param>
- /// <returns></returns>
- delegate Task<List<T>> DeleteDelegate<T>(JsonElement request) where T : CosmosEntity;
- /// <summary>
- /// 保存或者更新学校 知识点 或者 知识块 代理
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="schoolBlock"></param>
- /// <param name="_azureCosmos"></param>
- /// <returns></returns>
- delegate Task<string> SchoolSaveOrUpdate<T>(dynamic schoolBlock, AzureCosmosFactory _azureCosmos);
- // private delegate dynamic SaveOrUpdate(dynamic t);
- /// <summary>
- /// 获取标准知识点
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("find-std-point")]
- public async Task<IActionResult> FindStdPoint(KnowledgeDto request)
- {
- // request.@params.PointParams.TryAdd("PartitionKey", request.lang);
- ResponseBuilder builder = ResponseBuilder.custom();
- List<KnowledgePoint> data = new List<KnowledgePoint>();
- if (request != null && request.PointParams.TryGetValue("SubjectCode", out _))
- {
- List<KnowledgePoint> points = await _azureStorage.FindListByDict<KnowledgePoint>(request.PointParams);
- if (request.Periods.IsNotEmpty())
- {
- HashSet<KnowledgePoint> knowledges = new HashSet<KnowledgePoint>();
- foreach (string period in request.Periods)
- {
- if (!string.IsNullOrEmpty(period))
- {
- knowledges.UnionWith(points.Where(x => x.AdvicePeriodCode.Contains(period)).ToHashSet());
- }
- }
- data = knowledges.OrderBy(x => x.Order).ToList();
- }
- else
- {
- data = points.OrderBy(x => x.Order).ToList();
- }
- }
- else
- {
- return Ok(new { ResponseCode.PARAMS_ERROR, V = "SubjectCode is null or empty!" });
-
- }
- //return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();
- return Ok(new { data , data.Count});
- }
- /// <summary>
- /// 获取标准的知识块及包含的知识点
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("find-std-block-point")]
- public async Task<IActionResult> FindStdBlockPoint(KnowledgeDto request)
- {
- //request.@params.PointParams.TryAdd("PartitionKey", request.lang);
- ResponseBuilder builder = ResponseBuilder.custom();
- List<BlockPointDto> data = new List<BlockPointDto>();
- if (request != null && request.PointParams.TryGetValue("SubjectCode", out _))
- {
- List<KnowledgeBlockPoint> blockPoints = await _azureStorage.FindListByDict<KnowledgeBlockPoint>(request.PointParams);
- List<KnowledgeBlock> blocks = await _azureStorage.FindListByDict<KnowledgeBlock>(request.PointParams);
- if (request.Periods.IsNotEmpty())
- {
- HashSet<KnowledgeBlock> knowledges = new HashSet<KnowledgeBlock>();
- HashSet<KnowledgeBlockPoint> knowledgeBlocks = new HashSet<KnowledgeBlockPoint>();
- foreach (string period in request.Periods)
- {
- if (!string.IsNullOrEmpty(period))
- {
- knowledges.UnionWith(blocks.Where(x => x.AdvicePeriodCode.Contains(period)).ToHashSet());
- knowledgeBlocks.UnionWith(blockPoints.Where(x => x.AdvicePeriodCode.Contains(period)).ToHashSet());
- }
- }
- blocks = knowledges.OrderBy(x => x.Order).ToList();
- blockPoints = knowledgeBlocks.OrderBy(x => x.Order).ToList();
- }
- List<BlockPointDto> blockPointDtos = new List<BlockPointDto>();
- data = FindTree(ListToTree(blocks, blockPoints), request.BlockId, blockPointDtos);
- }
- else
- {
- //return builder.Error(ResponseCode.PARAMS_ERROR, "SubjectCode is null or empty!").build();
- return Ok(new { ResponseCode.PARAMS_ERROR, V = "SubjectCode is null or empty!" });
- }
- //return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();
- return Ok(new { data, data.Count });
- }
- /// <summary>
- /// 获取知识
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("find")]
- public async Task<IActionResult> Find(JsonElement requert)
- {
- var client = _azureCosmos.GetCosmosClient();
- if (!requert.TryGetProperty("code", out JsonElement school_code)) return BadRequest();
- if (!requert.TryGetProperty("type", out JsonElement type)) return BadRequest();
- if (!requert.TryGetProperty("periodId", out JsonElement period)) return BadRequest();
- if (!requert.TryGetProperty("subjectId", out JsonElement subjectCode)) return BadRequest();
- //if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
- List<object> Knowledges = new List<object>();
- List<Dictionary<string, object>> roles = new List<Dictionary<string, object>>();
- /* var response = await client.GetContainer("TEAMModelOSTemp", "Common").ReadItemStreamAsync(id + "", new PartitionKey($"Knowledge-{school_code}"));
- if (response.Status == 200)
- {
- using var json = await JsonDocument.ParseAsync(response.ContentStream);
- foreach (var obj in json.RootElement.GetProperty("points").EnumerateArray())
- {
- roles.Add(obj.GetString());
- }
- }*/
- var query = $"select c.id,c.type,c.code, c.name,c.alias,c.subjectId,c.points,c.knowledgeId,c.periodId from c where c.type = {type} and c.periodId = '{period}' and c.subjectId = '{subjectCode}'";
- await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Knowledge-{school_code}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
-
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- Dictionary<string, object> keyValues = new Dictionary<string, object>();
- foreach (var obj_ in obj.EnumerateObject()) {
- if ((obj_.Name + "").Equals("type")) {
- keyValues.Add("type", obj_.Value + "");
- }
- if ((obj_.Name+"").Equals("points")) {
- keyValues.Add("points", obj_.Value +"");
- }
- }
- roles.Add(keyValues);
- Knowledges.Add(obj.ToObject<object>());
- }
-
- }
- }
- return Ok(new { Knowledges, roles, Knowledges.Count });
- // request.@params.TryAdd("PartitionKey", request.lang);
- /* ResponseBuilder builder = ResponseBuilder.custom();
- List<Knowledge> data = new List<Knowledge>();
- if (StringHelper.getKeyCount(request) > 0)
- {
- data = await _azureCosmos.FindByDict<Knowledge>(request);
- data.ForEach(d =>
- {
- if (d.type == 1) {
- if (d.code.Equals("habook#0001"))
- {
- d.ownCount = d.points.Count;
- }
- else {
- d.openCount = d.points.Count;
- }
- }
- });
- }
- else
- {
- return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常!").build();
- }
- return builder.Data(data.OrderBy(m => m.order)).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
- }
- /// <summary>
- /// 保存或更新知识
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("upsert-all")]
- public async Task<IActionResult> UpsertAll(List<Knowledge> request)
- {
- try
- {
- var client = _azureCosmos.GetCosmosClient();
- List<Knowledge> Knowledges = new List<Knowledge>();
- if (request.IsNotEmpty())
- {
- foreach (Knowledge knowledge in request) {
- knowledge.code = "Knowledge-" + knowledge.code;
- Knowledge kno = new Knowledge();
- if (knowledge.id == null)
- {
- knowledge.id = Guid.NewGuid().ToString();
- kno = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(knowledge, new PartitionKey($"{knowledge.code}"));
- Knowledges.Add(kno);
- }
- else {
- kno = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(knowledge, knowledge.id, new PartitionKey($"{knowledge.code}"));
- Knowledges.Add(kno);
- }
- }
- //Knowledges = await SaveOrUpdateKnowledge(request);
- /*if (ts.Count > 0) builder.Data(ts).Extend(new Dictionary<string, object> { { "count", ts.Count } });
- else {
- return Ok(new { ResponseCode.FAILED, V = "失败!" });
- }; */
- }
- return Ok(new { Knowledges });
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"knowledge,{_option.Location},upsert-all()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- // TODO 代码优化
- /// <summary>
- /// 删除知识
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("delete")]
- public async Task<IActionResult> Delete(JsonElement request)
- {
- try {
- var client = _azureCosmos.GetCosmosClient();
- if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
- if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
- await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Knowledge-{code}"));
- return Ok(id);
- } catch (Exception ex) {
- await _dingDing.SendBotMsg($"knowledge,{_option.Location},delete()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- return Ok();
- //ResponseBuilder builder = ResponseBuilder.custom();
- //DeleteDelegate<Knowledge> deleteDelegate1 = Delete<Knowledge>;
- //List<Knowledge> Knowledges = await deleteDelegate1(request);
- //if(Knowledges.Count >0) {
- // foreach (Knowledge Knowledge in Knowledges)
- // {
- // if (Knowledge.type == 1)
- // {
- // List<Knowledge> knowledges = await _azureCosmos.FindSQL<Knowledge>("SELECT value(c) FROM c join a in c.points where c.pk='Knowledge'and Contains(a, '" + Knowledge.id + "') = true ");
- // List<Resource> Resources = await _azureCosmos.FindSQL<Resource>("SELECT value(c) FROM c join a in c.points where c.pk='Resources' and Contains(a, '" + Knowledge.id + "') = true ");
- // //select value(c) from c join A0 in c.points where 1=1 and A0 = @points0
- // foreach (Knowledge knowledge in knowledges) knowledge.points.Remove(Knowledge.id);
- // foreach (Resource Resource in Resources) Resource.points.Remove(Knowledge.id);
- // await _azureCosmos.SaveOrUpdateAll(Resources);
- // await _azureCosmos.SaveOrUpdateAll(knowledges);
- // }
- // }
- // return Ok(new { Knowledges });
- //}else
- //{
- // return Ok(new { erro = ResponseCode.FAILED, v = "删除失败!" });
- //}
-
- }
- /// <summary>
- /// 统计个数
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("count")]
- public async Task<IActionResult> Count(JsonElement request)
- {
- List<List<List<int>>> sCount = new List<List<List<int>>>();
- //List<List<List<List<int>>>> allCount = new List<List<List<List<int>>>>();
- ResponseBuilder builder = ResponseBuilder.custom();
- request.TryGetProperty("code",out JsonElement code);
- if (StringHelper.getKeyCount(request) > 0) {
- /*List<School> sc = await _azureCosmos.FindByDict<School>(new Dictionary<string, object>() { { "id", code.ToString()}});*/
- List<School> sc = new List<School>();
- var client = _azureCosmos.GetCosmosClient();
- //List<object> schools = new List<object>();
- var query = $"select c.id,c.pk,c.code, c.name,c.region,c.province,c.city,c.timeZone,c.picture,c.size,c.period,c.campuses from c where c.id ='{code}'";
- await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- sc.Add(obj.ToObject<School>());
- }
- }
- }
- /* //查询校本所有知识块
- Dictionary<string, object> scMap = new Dictionary<string, object>
- {
- { "type", 0},
- { "status", 1}
- };
- List<Knowledge> knowlegeo = await _azureCosmos.FindByDict<Knowledge>(scMap);*/
- List<Knowledge> knowlegeo = new List<Knowledge>();
- var queryOne = $"select c.id,c.type,c.code, c.name,c.alias,c.subjectId,c.points,c.knowledgeId,c.periodId from c where c.type = 0 and c.status = 1";
- await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: queryOne, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Knowledge-{code}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- knowlegeo.Add(obj.ToObject<Knowledge>());
- }
- }
- }
- for (int i = 0; i < sc.Count; i++)
- {
- for (int j = 0; j < sc[i].period.Count; j++)
- {
- List<List<int>> pCount = new List<List<int>>();
- for (int k = 0; k < sc[i].period[j].subjects.Count; k++)
- {
- List<int> listCount = new List<int>() { 0, 0 };
- //查询校本知识块
- //计数校本知识块与个人知识块
- int n = 0;
- int s = 0;
- for (int m = 0; m < knowlegeo.Count; m++)
- {
- if (sc[i].period[j].id.Equals(knowlegeo[m].periodId) &&
- sc[i].period[j].subjects[k].id.Equals(knowlegeo[m].subjectId))
- {
- n++;
- }
- if (knowlegeo[m].code.Equals("habook#0001") &&
- sc[i].period[j].id.Equals(knowlegeo[m].periodId) &&
- sc[i].period[j].subjects[k].id.Equals(knowlegeo[m].subjectId))
- {
- s++;
- }
- }
- //册别数量
- listCount[0] = n;
- listCount[1] = s;
- pCount.Add(listCount);
- }
- sCount.Add(pCount);
- }
- }
- }
- //return builder.Data(sCount).build();
- return Ok(sCount);
- }
-
- #region private
- private List<BlockPointDto> ListToTree(List<KnowledgeBlock> blocks, List<KnowledgeBlockPoint> points)
- {
- List<PointDto> pointList = points.ToJsonString().ToObject<List<PointDto>>();
- List<BlockPointDto> blockList = points.ToJsonString().ToObject<List<BlockPointDto>>();
- Dictionary<string, List<PointDto>> pointDict = new Dictionary<string, List<PointDto>>();
- List<string> keys = (pointList.GroupBy(c => c.BlockId).Select(group => group.Key)).ToList();
- foreach (string key in keys)
- {
- pointDict.Add(key, pointList.Where(x => x.BlockId.Equals(key)).ToList());
- }
- //var blockDict = blockList.ToDictionary(n => n.RowKey, n => n);
- var res = from r in blockList group r by r.RowKey into g select g;
- Dictionary<string, BlockPointDto> blockDict = new Dictionary<string, BlockPointDto>();
- foreach (var s in res)
- {
- blockDict.TryAdd(s.First().RowKey, s.First());
- }
- return GetChild(blockList, blockDict, pointDict);
- }
- private List<BlockPointDto> GetChild(List<BlockPointDto> list, Dictionary<string, BlockPointDto> blockDict, Dictionary<string, List<PointDto>> pointDict)
- {
- List<PointDto> empt = new List<PointDto>();
- list = list.OrderBy(m => m.Order).ToList();
- List<BlockPointDto> trees = new List<BlockPointDto>();
- foreach (BlockPointDto node in list)
- {
- node.Type = 0;
- bool fl = pointDict.TryGetValue(node.RowKey, out List<PointDto> points);
- if (fl && points.IsNotEmpty())
- {
- points.ForEach(m =>
- {
- node.Children.Add(new BlockPointDto
- {
- PartitionKey = m.PartitionKey,
- Pid = m.BlockId,
- RowKey = m.PointId,
- Type = 1,
- Order = m.Order,
- Name = m.Name,
- SubjectCode = m.SubjectCode,
- AdvicePeriodCode = m.AdvicePeriodCode,
- //Timestamp = m.Timestamp
- });
- });
- }
- bool flag = blockDict.TryGetValue(node.Pid, out BlockPointDto syllabus);
- if (flag && syllabus != null)
- {
- syllabus.Children.Add(node);
- }
- else
- {
- trees.Add(node);
- }
- }
- return trees.OrderBy(x => x.Order).ToList();
- }
- private List<BlockPointDto> FindTree(List<BlockPointDto> trees, String rowKey, List<BlockPointDto> blockPoints)
- {
- if (!string.IsNullOrEmpty(rowKey))
- {
- foreach (BlockPointDto tree in trees)
- {
- if (tree.RowKey.Equals(rowKey))
- {
- blockPoints.Add(tree);
- }
- if (null != tree.Children && tree.Children.Count > 0)
- {
- FindTree(tree.Children, rowKey, blockPoints);
- }
- }
- }
- else
- {
- blockPoints = trees;
- }
- return blockPoints;
- }
- // TODO 代码优化
- private async Task<List<Knowledge>> SaveOrUpdateKnowledge(List<Knowledge> request)
- {
- return new List<Knowledge>();
- //foreach (Knowledge item in request)
- //{
- // if (item.id == null)
- // {
- // item.id = _snowflakeId.NextId() + "";
- // }
- // if (item.type == 1 && item.points.Count > 0)
- // {
- // List<string> vs = item.points;
- // foreach (string s in vs)
- // {
- // List<Knowledge> knowledges = await _azureCosmos.FindByDict<Knowledge>(new Dictionary<string, object>() { { "id", s } });
- // foreach (Knowledge knowledge in knowledges)
- // {
- // knowledge.points.Remove(item.id);
- // knowledge.points.Add(item.id);
- // }
- // await _azureCosmos.SaveOrUpdateAll(knowledges);
- // }
- // item.points.Clear();
- // }
- //}
- //List<Knowledge> ts = await _azureCosmos.SaveOrUpdateAll(request);
- //return ts;
- }
- #endregion
- }
- }
|