KnowledgeTypeService.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. using Hotline.Share.Dtos.Knowledge;
  2. using Hotline.Share.Enums.KnowledgeBase;
  3. using MapsterMapper;
  4. using XF.Domain.Dependency;
  5. using XF.Domain.Exceptions;
  6. namespace Hotline.KnowledgeBase
  7. {
  8. public class KnowledgeTypeService : IKnowledgeTypeService, IScopeDependency
  9. {
  10. /// <summary>
  11. ///
  12. /// </summary>
  13. private readonly IKnowledgeTypeRepository _knowledgeTypeRepository;
  14. private readonly IKnowledgeRepository _knowledgeRepository;
  15. private readonly IMapper _mapper;
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. /// <param name="knowledgeTypeRepository"></param>
  20. /// <param name="mapper"></param>
  21. public KnowledgeTypeService(IKnowledgeTypeRepository knowledgeTypeRepository, IMapper mapper, IKnowledgeRepository knowledgeRepository)
  22. {
  23. _knowledgeTypeRepository = knowledgeTypeRepository;
  24. _mapper = mapper;
  25. _knowledgeRepository = knowledgeRepository;
  26. }
  27. /// <summary>
  28. /// 查询所有子级
  29. /// </summary>
  30. /// <param name="treeDatas">分类数据</param>
  31. /// <param name="ID">需要查询哪级下面的分类</param>
  32. /// <param name="checkId">选中的数据ID</param>
  33. /// <returns></returns>
  34. public List<TreeListDto> GetChildren(List<KnowledgeType> treeDatas, string ID, string? checkId)
  35. {
  36. List<TreeListDto> nodeList = new();
  37. //根据ID查询子级
  38. var children = treeDatas.Where(q => q.ParentId == ID);
  39. foreach (var dr in children)
  40. {
  41. //组装数据
  42. TreeListDto node = new()
  43. {
  44. name = dr.Name,
  45. ParentID = dr.ParentId,
  46. value = dr.Id,
  47. IsEnable = dr.IsEnable
  48. };
  49. //是否选中
  50. if (!string.IsNullOrEmpty(checkId) && checkId != Guid.Empty.ToString() && checkId == dr.Id)
  51. node.selected = true;
  52. //子级数据赋值
  53. node.children = GetChildren(treeDatas, node.value, checkId);
  54. //添加数据
  55. nodeList.Add(node);
  56. }
  57. return nodeList;
  58. }
  59. /// <summary>
  60. /// 查询父级名称
  61. /// </summary>
  62. /// <param name="Id"></param>
  63. /// <returns></returns>
  64. private async Task<List<string>> GetParentNode(string Id)
  65. {
  66. List<string> list = new();
  67. //查询父级数据
  68. var type = await _knowledgeTypeRepository.GetAsync(p => p.Id == Id);
  69. if (type != null)
  70. {
  71. //添加名称
  72. list.Add(type.Name);
  73. list.AddRange(await GetParentNode(type.ParentId));
  74. }
  75. return list;
  76. }
  77. /// <summary>
  78. /// 查询子级节点数据
  79. /// </summary>
  80. /// <param name="Id"></param>
  81. /// <returns></returns>
  82. private async Task<List<KnowledgeType>> GetChildNode(string Id)
  83. {
  84. List<KnowledgeType> list = new();
  85. //查询数据
  86. var typelist = await _knowledgeTypeRepository.QueryAsync(p => p.ParentId == Id);
  87. if (typelist != null)
  88. {
  89. //处理数据
  90. foreach (var item in typelist)
  91. {
  92. list.Add(item);
  93. list.AddRange(await GetChildNode(item.Id));
  94. }
  95. }
  96. return list;
  97. }
  98. /// <summary>
  99. /// 知识分类- 新增
  100. /// </summary>
  101. /// <param name="dto"></param>
  102. /// <param name="cancellationToken"></param>
  103. /// <returns></returns>
  104. public async Task<string> TypeAdd(AddKnowledgeTypeDto dto, CancellationToken cancellationToken)
  105. {
  106. var type = _mapper.Map<KnowledgeType>(dto);
  107. type.IsEnable = true;
  108. //获取分类名称全称
  109. string FullName = await GetFullName(type.ParentId);
  110. //处理全称,如果为第一级直接用全称,否则获取全称后拼接名称
  111. type.SpliceName = string.IsNullOrEmpty(FullName) ? dto.Name : FullName + "-" + dto.Name;
  112. return await _knowledgeTypeRepository.AddAsync(type, cancellationToken);
  113. }
  114. /// <summary>
  115. /// 知识分类- 编辑
  116. /// </summary>
  117. /// <param name="dto"></param>
  118. /// <param name="cancellationToken"></param>
  119. /// <returns></returns>
  120. public async Task TypeUpdate(UpdateKnowledgeTypeDto dto, CancellationToken cancellationToken)
  121. {
  122. //查询原有数据
  123. var type = await _knowledgeTypeRepository.GetAsync(dto.Id, cancellationToken);
  124. if (type is null)
  125. throw UserFriendlyException.SameMessage("编辑失败!");
  126. bool result = false;
  127. //是否更改分类名称
  128. if (type.Name != dto.Name)
  129. result = true;
  130. //转换
  131. _mapper.Map(dto, type);
  132. //如果更改了名称,则修改全称,未更改不修改
  133. if (result)
  134. {
  135. string FullName = await GetFullName(type.ParentId);//获取分类名称全称
  136. type.SpliceName = string.IsNullOrEmpty(FullName) ? dto.Name : FullName + "-" + dto.Name;//处理全称,如果为第一级直接用全称,否则获取全称后拼接名称
  137. }
  138. //修改数据
  139. await _knowledgeTypeRepository.UpdateAsync(type, cancellationToken);
  140. //如果修改了名称,对应修改子分类全称
  141. if (result)
  142. await UpdateChildNode(type.Id);
  143. }
  144. /// <summary>
  145. /// 知识分类-新增、编辑初始化
  146. /// </summary>
  147. /// <param name="Id"></param>
  148. /// <param name="ParentId"></param>
  149. /// <param name="cancellationToken"></param>
  150. /// <returns></returns>
  151. public async Task<KnowledgeTypeDto> TypeInit(string Id, string ParentId, CancellationToken cancellationToken)
  152. {
  153. KnowledgeTypeDto knowledgeTypeDto = new();
  154. //查询是否有数据
  155. if (!string.IsNullOrEmpty(Id))
  156. {
  157. var type = await _knowledgeTypeRepository.GetAsync(p => p.Id == Id, cancellationToken);
  158. _mapper.Map(type, knowledgeTypeDto);
  159. }
  160. //查询已经启用的分类名称
  161. var list = await _knowledgeTypeRepository.QueryAsync(p => p.IsEnable == true);
  162. //分类组装树形
  163. knowledgeTypeDto.TreeLists = GetChildren(list, Guid.Empty.ToString(), ParentId);
  164. return knowledgeTypeDto;
  165. }
  166. /// <summary>
  167. /// 知识分类-启用、禁用切换
  168. /// </summary>
  169. /// <param name="Id"></param>
  170. /// <param name="cancellationToken"></param>
  171. /// <returns></returns>
  172. public async Task TypeChangeState(string Id, CancellationToken cancellationToken)
  173. {
  174. //查询数据是否存在
  175. var type = await _knowledgeTypeRepository.GetAsync(Id);
  176. if (type is null)
  177. throw UserFriendlyException.SameMessage("分类不存在!");
  178. if (type.IsEnable)//禁用
  179. {
  180. //查询子级数据
  181. var getChild = await _knowledgeTypeRepository.GetChild(Id);
  182. //禁用子级数据
  183. if (getChild != null && getChild.Count > 0)
  184. {
  185. foreach (var item in getChild)
  186. {
  187. item.IsEnable = false;
  188. await _knowledgeTypeRepository.UpdateAsync(item, cancellationToken);
  189. }
  190. }
  191. }
  192. else //启用
  193. {
  194. //查询上级是否是启用状态,如果是禁用状态不能修改
  195. var CheckParent = await _knowledgeTypeRepository.GetAsync(type.ParentId, cancellationToken);
  196. if (CheckParent is null)
  197. throw UserFriendlyException.SameMessage("分类启用失败!");
  198. if (!CheckParent.IsEnable)
  199. throw UserFriendlyException.SameMessage("请先启用父级分类!");
  200. //将状态修改为启用
  201. type.IsEnable = true;
  202. await _knowledgeTypeRepository.UpdateAsync(type, cancellationToken);
  203. }
  204. }
  205. /// <summary>
  206. /// 知识分类-禁用,并且下架知识
  207. /// </summary>
  208. /// <param name="Id"></param>
  209. /// <param name="cancellationToken"></param>
  210. /// <returns></returns>
  211. public async Task TypeChangeStateAndOffShelf(string Id, CancellationToken cancellationToken)
  212. {
  213. //查询数据是否存在
  214. var type = await _knowledgeTypeRepository.GetAsync(Id, cancellationToken);
  215. if (type is null)
  216. throw UserFriendlyException.SameMessage("分类不存在!");
  217. if (type.IsEnable)//启用状态
  218. {
  219. //查询子级数据
  220. var getChild = await _knowledgeTypeRepository.GetChild(Id);
  221. //禁用子级数据
  222. if (getChild != null && getChild.Count > 0)
  223. {
  224. foreach (var item in getChild)
  225. {
  226. item.IsEnable = false;
  227. await _knowledgeTypeRepository.UpdateAsync(item, cancellationToken);
  228. //下架知识
  229. //查询当前分类下的知识(查询条件:此分类下/状态为成功/未删除/已上架)
  230. var knowList = _knowledgeRepository.Queryable().Where(p => p.KnowledgeTypeId == item.Id && p.Status == EKnowledgeStatus.Succeed && p.IsDeleted == false && p.IsOnShelf == true).ToList();
  231. if (knowList != null && knowList.Count > 0)
  232. {
  233. //修改知识为下架状态
  234. foreach (var itemKnow in knowList)
  235. {
  236. itemKnow.IsOnShelf = false;
  237. itemKnow.OffShelfTime = DateTime.Now;
  238. itemKnow.OnShelfTime = null;
  239. await _knowledgeRepository.UpdateAsync(itemKnow, cancellationToken);
  240. }
  241. }
  242. }
  243. }
  244. }
  245. else
  246. throw UserFriendlyException.SameMessage("禁用分类失败!");
  247. }
  248. /// <summary>
  249. /// 知识分类-删除
  250. /// </summary>
  251. /// <param name="Id"></param>
  252. /// <param name="cancellationToken"></param>
  253. /// <returns></returns>
  254. public async Task TypeDelete(string Id, CancellationToken cancellationToken)
  255. {
  256. //查询数据是否存在
  257. var sandard = await _knowledgeTypeRepository.GetAsync(Id, cancellationToken);
  258. if (sandard is null)
  259. throw UserFriendlyException.SameMessage("分类不存在!");
  260. //查询是否有子级分类
  261. var checkChild = await _knowledgeTypeRepository.CountAsync(p => p.ParentId == Id, cancellationToken);
  262. if (checkChild > 0)
  263. throw UserFriendlyException.SameMessage("存在子级分类!");
  264. //查询是否有知识分类
  265. var checkKnowledge = await _knowledgeRepository.CountAsync(p => p.KnowledgeTypeId == Id && p.IsDeleted == false, cancellationToken);
  266. if (checkKnowledge > 0)
  267. throw UserFriendlyException.SameMessage("分类存在知识!");
  268. //删除操作
  269. await _knowledgeTypeRepository.RemoveAsync(sandard, false, cancellationToken);
  270. }
  271. #region 私有方法
  272. /// <summary>
  273. /// 获取全称
  274. /// </summary>
  275. /// <param name="Id"></param>
  276. /// <returns></returns>
  277. private async Task<string> GetFullName(string Id)
  278. {
  279. //获取全部父级名称
  280. var list = await GetParentNode(Id);
  281. //倒叙
  282. list.Reverse();
  283. //拆分
  284. return string.Join("-", list.ToArray());
  285. }
  286. /// <summary>
  287. /// 修改子级分类全称
  288. /// </summary>
  289. /// <param name="Id"></param>
  290. /// <returns></returns>
  291. private async Task UpdateChildNode(string Id)
  292. {
  293. //查询子分类
  294. var list = await GetChildNode(Id);
  295. if (list is not null && list.Count > 0)
  296. {
  297. foreach (var item in list)
  298. {
  299. //获取全称
  300. string FullName = await GetFullName(item.ParentId);
  301. item.SpliceName = string.IsNullOrEmpty(FullName) ? item.Name : FullName + "-" + item.Name;
  302. //修改全称
  303. await _knowledgeTypeRepository.UpdateAsync(item);
  304. }
  305. }
  306. }
  307. #endregion
  308. }
  309. }