using Azure.Cosmos; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK.Models.Cosmos.Common; namespace TEAMModelOS.SDK.Services { public static class SyllabusService { /// /// 根据id查询列表串联id pid的新的关系列表 /// /// /// /// /// public async static Task<(List> idCodes, List tree)> ImportSyllabus(List> nodes,string volumeId,string scope ,string code,string creatorId ,string creatorName,string grant_type, AzureCosmosFactory azureCosmos, bool ignoreCharacter = true) { HashSet syllabuses= new HashSet(); string tbname = scope.Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher; await foreach (var item in azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetItemQueryIterator(queryText: $"select value(c) from c where c.volumeId='{volumeId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{code}") })) { syllabuses.Add(item); } Volume volume = await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync($"{volumeId}", new PartitionKey($"Volume-{code}")); HashSet chapters = new HashSet(); long now= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); List > resNodes = new List>(); foreach (var points in nodes) { // points 作为 层级路径 ["汽车考照", "汽车法规","驾驶道德、交通安全常识及行车安全检查与维护"] int level = 0; // 根节点 作为章节进行当前 路径操作的主要对象 Syllabus chapter = null; //用于记录 ["汽车考照", "汽车法规","驾驶道德、交通安全常识及行车安全检查与维护"] 标题的id 路径 List<(string title, string id)> nodesVal = new List<(string title, string id)>(); //上一次操作的 id 用于方便检索下一层级时作为pid string lastId =null; foreach (var point in points) { string express = "[ \\[ \\] \\^ \\-|()【】/' {}_*×――(^)$%~!@#$…&%¥—+=<>《》!!???::•`·、。,;,.;\"‘’“”-]"; //是否开启特殊符号的正则过滤 string pt = ignoreCharacter? Regex.Replace(point, express, ""):point; if (level == 0) { var sylbs = syllabuses.SelectMany(z => z.children).Where(c => c.pid.Equals(volumeId) && pt.Equals(ignoreCharacter? Regex.Replace(c.title, express, ""): c.title)); if (sylbs.Any()) { //找到相关的章节 chapter = syllabuses.Where(z=>z.id.Equals(sylbs.First().id)).FirstOrDefault(); if (chapter == null ) { foreach (var item in syllabuses) { var it = item.children.Find(z => z.id.Equals(sylbs.First().id)); if (it != null) { item.id = sylbs.First().id; chapter = item; chapters.Add(chapter); lastId = item.id; nodesVal.Add((point, item.id)); break; } } } else { chapters.Add(chapter); lastId = chapter.id; nodesVal.Add((point, sylbs.First().id)); } } else { //未找到相关的章节 string id = id = Guid.NewGuid().ToString(); lastId= id; chapter = new Syllabus { id = id, volumeId = volumeId, code = $"Syllabus-{code}", pk = "Syllabus", ttl = -1, scope= scope, children= new List { new Tnode {id = id ,pid=volumeId, creatorId = creatorId, creatorName = creatorName,title=pt,updateTime= now} } }; chapters.Add(chapter); syllabuses.Add(chapter); nodesVal.Add((point, id)); } //下钻一层 level += 1; } else { if (!string.IsNullOrWhiteSpace(lastId)) { var child = chapter.children.Find(child => child.pid.Equals(lastId) && pt.Equals(ignoreCharacter ? Regex.Replace(child.title, express, "") : child.title)); if (child == null) { string id = id = Guid.NewGuid().ToString(); child = new Tnode { id = id, pid = lastId, creatorId = creatorId, creatorName = creatorName, title = pt, updateTime = now }; chapter.children.Add(child); lastId = child.id; nodesVal.Add((point, child.id)); } else { lastId= child.id; nodesVal.Add((point, child.id)); } level += 1; } } } if (chapter != null) { resNodes.Add(nodesVal.Select(z => new IdCode { id = z.id, code = z.title }).ToList()); } } bool volumeChange=false; List treeNodes = new List(); foreach (var chapter in chapters) { if (!volume.syllabusIds.Contains(chapter.id)) { volume.syllabusIds.Add(chapter.id); volumeChange = true; } if (!string.IsNullOrWhiteSpace(grant_type) && grant_type.Equals("upsert")) { await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(chapter); } List trees = SyllabusService.ListToTree(chapter.children); SyllabusTreeNode tree = new SyllabusTreeNode() { id = chapter.id, scope = chapter.scope, trees = trees, volumeId = chapter.volumeId, auth = chapter.auth, codeval = code }; treeNodes.Add(tree); } if (volumeChange && !string.IsNullOrWhiteSpace(grant_type) && grant_type.Equals("upsert")) { await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync(volume, volume.id, new PartitionKey(volume.code)); } List redt = new List(); //对课纲树形结构排序 if (volume.syllabusIds.IsNotEmpty()) { volume.syllabusIds.ForEach(x => { for (int index = 0; index < treeNodes.Count; index++) { if (treeNodes[index].id == x) { redt.Add(treeNodes[index]); treeNodes.RemoveAt(index); } } }); redt.AddRange(treeNodes); return (resNodes, redt); } else { return (resNodes, treeNodes); } } /// /// 根据id查询列表串联id pid的新的关系列表 /// /// /// /// /// public static HashSet GetNewNode(List nodes, string pid, HashSet newNodes) { bool flag = false; string spid = ""; foreach (var node in nodes) { if (node.pid == pid) { newNodes.Add(node); spid = node.id; GetNewNode(nodes, spid, newNodes); flag = true; } } return newNodes; //if (flag) //{ // return GetNewNode(nodes, spid, newNodes); //} //else { // return newNodes; //} } public static List TreeToList(List trees, List nodes,long now) { int index = 0; foreach (SyllabusTree tr in trees) { tr.order = index; index++; } trees = trees.OrderBy(x => x.order).ToList(); List list = new List(); //var list = trees.ToJsonString().ToObject>(); trees.ForEach(x=> { List cids = new List(); if (x.children.IsNotEmpty()) { x.children.ForEach(y => cids.Add(y.id)); } var node = new Tnode { title = x.title, id = x.id, pid = x.pid, order = x.order, rnodes = x.rnodes, cids= cids, creatorId=x.creatorId, creatorName=x.creatorName, updateTime= now }; list.Add(node); }); nodes.AddRange(list); foreach (SyllabusTree tree in trees) { if (null != tree.children && tree.children.Count > 0) { TreeToList(tree.children, nodes,now); } } return nodes; } public static List ListToTree(List noes) { List list = noes.ToJsonString().ToObject>(); //var lookup = list.ToDictionary(n => n.RowKey, n => n); var res = from r in list group r by r.id into g select g; Dictionary blockDict = new Dictionary(); foreach (var s in res) { blockDict.TryAdd(s.First().id, s.First()); } return GetChild(list, blockDict); } private static List GetChild(List list, Dictionary dict) { // list = list.OrderBy(m => m.Order).ToList(); List trees = new List(); trees = trees.OrderBy(x => x.order).ToList(); foreach (SyllabusTree node in list) { bool flag = dict.TryGetValue(node.pid, out SyllabusTree syllabus); if (flag && syllabus != null) { syllabus.children.Add(node); } else { trees.Add(node); } } return trees; } #region 开放平台使用 public static List OListToTree(List noes) { List list = noes.ToJsonString().ToObject>(); //var lookup = list.ToDictionary(n => n.RowKey, n => n); var res = from r in list group r by r.id into g select g; Dictionary blockDict = new Dictionary(); foreach (var s in res) { blockDict.TryAdd(s.First().id, s.First()); } return GetChildO(list, blockDict); } private static List GetChildO(List list, Dictionary dict) { // list = list.OrderBy(m => m.Order).ToList(); List trees = new List(); trees = trees.OrderBy(x => x.order).ToList(); foreach (OSyllabusTree node in list) { bool flag = dict.TryGetValue(node.pid, out OSyllabusTree syllabus); if (flag && syllabus != null) { syllabus.children.Add(node); } else { trees.Add(node); } } return trees; } #endregion } }