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
}
}