平安校园
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

308 lines
12 KiB

  1. //
  2. namespace SafeCampus.System;
  3. /// <summary>
  4. /// <inheritdoc cref="ISysPositionService"/>
  5. /// </summary>
  6. public class SysPositionService : DbRepository<SysPosition>, ISysPositionService
  7. {
  8. private readonly ISimpleCacheService _simpleCacheService;
  9. private readonly ISysOrgService _sysOrgService;
  10. private readonly IDictService _dictService;
  11. public SysPositionService(ISimpleCacheService simpleCacheService, ISysOrgService sysOrgService, IDictService dictService)
  12. {
  13. _simpleCacheService = simpleCacheService;
  14. _sysOrgService = sysOrgService;
  15. _dictService = dictService;
  16. }
  17. #region 查询
  18. /// <summary>
  19. /// 获取全部
  20. /// </summary>
  21. /// <returns></returns>
  22. public override async Task<List<SysPosition>> GetListAsync()
  23. {
  24. //先从Redis拿
  25. var sysPositions = _simpleCacheService.Get<List<SysPosition>>(SystemConst.CACHE_SYS_POSITION);
  26. if (sysPositions == null)
  27. {
  28. //redis没有就去数据库拿
  29. sysPositions = await base.GetListAsync();
  30. if (sysPositions.Count > 0)
  31. {
  32. //插入Redis
  33. _simpleCacheService.Set(SystemConst.CACHE_SYS_POSITION, sysPositions);
  34. }
  35. }
  36. return sysPositions;
  37. }
  38. /// <inheritdoc />
  39. public async Task<List<SysPosition>> GetPositionListByIdList(IdListInput input)
  40. {
  41. var positions = await GetListAsync();
  42. var positionList = positions.Where(it => input.IdList.Contains(it.Id)).ToList();// 获取指定ID的岗位列表
  43. return positionList;
  44. }
  45. /// <inheritdoc/>
  46. public async Task<List<PositionSelectorOutput>> Selector(PositionSelectorInput input)
  47. {
  48. var sysOrgList = await _sysOrgService.GetListAsync(false);//获取所有组织
  49. var sysPositions = await GetListAsync();//获取所有职位
  50. if (input.OrgIds != null)//根据数据范围查
  51. {
  52. sysOrgList = sysOrgList.Where(it => input.OrgIds.Contains(it.Id)).ToList();//在指定组织列表查询
  53. sysPositions = sysPositions.Where(it => input.OrgIds.Contains(it.OrgId)).ToList();//在指定职位列表查询
  54. }
  55. var result = await ConstructPositionSelector(sysOrgList, sysPositions);//构造树
  56. return result;
  57. }
  58. /// <inheritdoc />
  59. public async Task<SysPosition> GetSysPositionById(long id)
  60. {
  61. var sysPositions = await GetListAsync();
  62. var result = sysPositions.Where(it => it.Id == id).FirstOrDefault();
  63. return result;
  64. }
  65. /// <inheritdoc/>
  66. public async Task<SqlSugarPagedList<SysPosition>> Page(PositionPageInput input)
  67. {
  68. var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级组织
  69. var query = Context.Queryable<SysPosition>().WhereIF(input.OrgId > 0, it => orgIds.Contains(it.OrgId))//根据组织ID查询
  70. .WhereIF(input.OrgIds != null, it => input.OrgIds.Contains(it.OrgId))//在指定组织列表查询
  71. .WhereIF(!string.IsNullOrEmpty(input.Category), it => it.Category == input.Category)//根据分类
  72. .WhereIF(!string.IsNullOrEmpty(input.Status), it => it.Status == input.Status)//根据状态
  73. .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询
  74. .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")
  75. .OrderBy(it => it.SortCode)//排序
  76. .OrderBy(it => it.CreateTime);//排序
  77. var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页
  78. return pageInfo;
  79. }
  80. /// <inheritdoc/>
  81. public async Task<List<PositionTreeOutput>> Tree(PositionTreeInput input)
  82. {
  83. var result = new List<PositionTreeOutput>();//返回结果
  84. var sysOrgList = await _sysOrgService.GetListAsync(false);//获取所有组织
  85. var sysPositions = await GetListAsync();//获取所有职位
  86. if (input.OrgIds != null)//根据数据范围查
  87. {
  88. sysOrgList = sysOrgList.Where(it => input.OrgIds.Contains(it.Id)).ToList();//在指定组织列表查询
  89. sysPositions = sysPositions.Where(it => input.OrgIds.Contains(it.OrgId)).ToList();//在指定职位列表查询
  90. }
  91. var posCategory = await _dictService.GetChildrenByDictValue(SysDictConst.POSITION_CATEGORY);//获取职位分类
  92. var topOrgList = sysOrgList.Where(it => it.ParentId == 0).ToList();//获取顶级组织
  93. //遍历顶级组织
  94. foreach (var org in topOrgList)
  95. {
  96. var childIds = await _sysOrgService.GetOrgChildIds(org.Id, true, sysOrgList);//获取组织下的所有子级ID
  97. var orgPositions = sysPositions.Where(it => childIds.Contains(it.OrgId)).ToList();//获取组织下的职位
  98. if (orgPositions.Count == 0) continue;
  99. var positionTreeOutput = new PositionTreeOutput
  100. {
  101. Id = org.Id,
  102. Name = org.Name,
  103. IsPosition = false
  104. };//实例化组织树
  105. //获取组织下的职位职位分类
  106. foreach (var category in posCategory)
  107. {
  108. var id = CommonUtils.GetSingleId();//生成唯一ID临时用,因为前端需要ID
  109. var categoryTreeOutput = new PositionTreeOutput
  110. {
  111. Id = id,
  112. Name = category.DictLabel,
  113. IsPosition = false
  114. };//实例化职位分类树
  115. var positions = orgPositions.Where(it => it.Category == category.DictValue).ToList();//获取职位分类下的职位
  116. //遍历职位,实例化职位树
  117. positions.ForEach(it =>
  118. {
  119. categoryTreeOutput.Children.Add(new PositionTreeOutput()
  120. {
  121. Id = it.Id,
  122. Name = it.Name,
  123. IsPosition = true
  124. });//添加职位
  125. });
  126. positionTreeOutput.Children.Add(categoryTreeOutput);
  127. }
  128. result.Add(positionTreeOutput);
  129. }
  130. return result;
  131. }
  132. /// <inheritdoc />
  133. public async Task<SysPosition> Detail(BaseIdInput input)
  134. {
  135. return await GetSysPositionById(input.Id);
  136. }
  137. #endregion
  138. #region 编辑
  139. /// <inheritdoc />
  140. public async Task Edit(PositionEditInput input, string name = SystemConst.SYS_POS)
  141. {
  142. await CheckInput(input, name);//检查参数
  143. var sysPosition = input.Adapt<SysPosition>();//实体转换
  144. if (await UpdateAsync(sysPosition))//更新数据
  145. await RefreshCache();//刷新缓存
  146. }
  147. /// <inheritdoc />
  148. public async Task RefreshCache()
  149. {
  150. _simpleCacheService.Remove(SystemConst.CACHE_SYS_POSITION);//删除缓存
  151. await GetListAsync();//重新写入缓存
  152. }
  153. #endregion
  154. #region 新增
  155. /// <inheritdoc />
  156. public async Task Add(PositionAddInput input, string name = SystemConst.SYS_POS)
  157. {
  158. await CheckInput(input, name);//检查参数
  159. var sysPosition = input.Adapt<SysPosition>();//实体转换
  160. if (await InsertAsync(sysPosition))//插入数据
  161. await RefreshCache();//刷新缓存
  162. }
  163. #endregion
  164. #region 删除
  165. /// <inheritdoc />
  166. public async Task Delete(BaseIdListInput input, string name = SystemConst.SYS_POS)
  167. {
  168. //获取所有ID
  169. var ids = input.Ids;
  170. if (ids.Count > 0)
  171. {
  172. //如果组织下有用户则不能删除
  173. if (await Context.Queryable<SysUser>().AnyAsync(it => ids.Contains(it.PositionId)))
  174. {
  175. throw Oops.Bah($"请先删除{name}下的用户");
  176. }
  177. //删除职位
  178. if (await DeleteByIdsAsync(ids.Cast<object>().ToArray()))
  179. await RefreshCache();//刷新缓存
  180. }
  181. }
  182. #endregion
  183. #region 方法
  184. /// <summary>
  185. /// 检查输入参数
  186. /// </summary>
  187. /// <param name="sysPosition"></param>
  188. /// <param name="name">名称</param>
  189. private async Task CheckInput(SysPosition sysPosition, string name)
  190. {
  191. //所有分类放一个列表
  192. var posCategoryList = new List<string>
  193. {
  194. CateGoryConst.POSITION_HIGH, CateGoryConst.POSITION_LOW, CateGoryConst.POSITION_MIDDLE
  195. };
  196. if (!posCategoryList.Contains(sysPosition.Category))
  197. throw Oops.Bah($"{name}所属分类错误:{sysPosition.Category}");
  198. var sysPositions = await GetListAsync();//获取全部
  199. if (sysPositions.Any(it => it.OrgId == sysPosition.OrgId && it.Name == sysPosition.Name && it.Id != sysPosition.Id))//判断同级是否有名称重复的
  200. throw Oops.Bah($"存在重复的{name}:{sysPosition.Name}");
  201. if (sysPosition.Id > 0)//如果ID大于0表示编辑
  202. {
  203. var position = sysPositions.Where(it => it.Id == sysPosition.Id).FirstOrDefault();//获取当前职位
  204. if (position == null)
  205. throw Oops.Bah($"{name}不存在");
  206. }
  207. //如果code没填
  208. if (string.IsNullOrEmpty(sysPosition.Code))
  209. {
  210. sysPosition.Code = RandomHelper.CreateRandomString(10);//赋值Code
  211. }
  212. else
  213. {
  214. //判断是否有相同的Code
  215. if (sysPositions.Any(it => it.Code == sysPosition.Code && it.Id != sysPosition.Id))
  216. throw Oops.Bah($"存在重复的编码:{sysPosition.Code}");
  217. }
  218. }
  219. /// <summary>
  220. /// 构建职位选择器
  221. /// </summary>
  222. /// <param name="orgList">组织列表</param>
  223. /// <param name="sysPositions">职位列表</param>
  224. /// <param name="parentId">父Id</param>
  225. /// <returns></returns>
  226. public async Task<List<PositionSelectorOutput>> ConstructPositionSelector(List<SysOrg> orgList, List<SysPosition> sysPositions,
  227. long parentId = SafeCampusConst.ZERO)
  228. {
  229. //找下级组织列表
  230. var orgInfos = orgList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList();
  231. var data = new List<PositionSelectorOutput>();
  232. if (orgInfos.Count > 0)//如果数量大于0
  233. {
  234. foreach (var item in orgInfos)//遍历组织
  235. {
  236. var childIds = await _sysOrgService.GetOrgChildIds(item.Id, true, orgList);//获取组织下的所有子级ID
  237. var orgPositions = sysPositions.Where(it => childIds.Contains(it.OrgId)).ToList();//获取组织下的职位
  238. if (orgPositions.Count > 0)//如果组织和组织下级有职位
  239. {
  240. var positionSelectorOutput = new PositionSelectorOutput
  241. {
  242. Id = item.Id,
  243. Name = item.Name,
  244. Children = await ConstructPositionSelector(orgList, sysPositions, item.Id)//递归
  245. };//实例化职位树
  246. var positions = orgPositions.Where(it => it.OrgId == item.Id).ToList();//获取组织下的职位
  247. if (positions.Count > 0)//如果数量大于0
  248. {
  249. foreach (var position in positions)
  250. {
  251. positionSelectorOutput.Children.Add(new PositionSelectorOutput
  252. {
  253. Id = position.Id,
  254. Name = position.Name
  255. });//添加职位
  256. }
  257. }
  258. data.Add(positionSelectorOutput);//添加到列表
  259. }
  260. }
  261. return data;//返回结果
  262. }
  263. return new List<PositionSelectorOutput>();
  264. }
  265. #endregion 方法
  266. }