平安校园
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

SysUserService.cs 49 KiB

il y a 4 mois
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. 
  2. //
  3. using SafeCampus.Core.Extension;
  4. namespace SafeCampus.System;
  5. /// <summary>
  6. /// <inheritdoc cref="ISysUserService"/>
  7. /// </summary>
  8. public class SysUserService : DbRepository<SysUser>, ISysUserService
  9. {
  10. private readonly ILogger<ILogger> _logger;
  11. private readonly ISimpleCacheService _simpleCacheService;
  12. private readonly IRelationService _relationService;
  13. private readonly IResourceService _resourceService;
  14. private readonly ISysOrgService _sysOrgService;
  15. private readonly ISysRoleService _sysRoleService;
  16. private readonly IImportExportService _importExportService;
  17. private readonly ISysPositionService _sysPositionService;
  18. private readonly IDictService _dictService;
  19. private readonly IConfigService _configService;
  20. private readonly IBatchEditService _batchEditService;
  21. public SysUserService(ILogger<ILogger> logger, ISimpleCacheService simpleCacheService, IRelationService relationService,
  22. IResourceService resourceService, ISysOrgService orgService, ISysRoleService sysRoleService,
  23. IImportExportService importExportService, ISysPositionService sysPositionService, IDictService dictService,
  24. IConfigService configService, IBatchEditService updateBatchService)
  25. {
  26. _logger = logger;
  27. _simpleCacheService = simpleCacheService;
  28. _relationService = relationService;
  29. _resourceService = resourceService;
  30. _sysOrgService = orgService;
  31. _sysRoleService = sysRoleService;
  32. _importExportService = importExportService;
  33. _sysPositionService = sysPositionService;
  34. _dictService = dictService;
  35. _configService = configService;
  36. _batchEditService = updateBatchService;
  37. }
  38. #region 查询
  39. /// <inheritdoc/>
  40. public async Task<string> GetUserAvatar(long userId)
  41. {
  42. //先从缓存拿
  43. var avatar = _simpleCacheService.HashGetOne<string>(SystemConst.CACHE_SYS_USER_AVATAR, userId.ToString());
  44. if (string.IsNullOrEmpty(avatar))
  45. {
  46. //单查获取用户头像
  47. avatar = await GetFirstAsync(it => it.Id == userId, it => it.Avatar);
  48. if (!string.IsNullOrEmpty(avatar))
  49. {
  50. //插入缓存
  51. _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER_AVATAR, userId.ToString(), avatar);
  52. }
  53. }
  54. return avatar;
  55. }
  56. /// <inheritdoc/>
  57. public async Task<SysUser> GetUserByAccount(string account, long? tenantId = null)
  58. {
  59. var userId = await GetIdByAccount(account, tenantId);//获取用户ID
  60. if (userId != SafeCampusConst.ZERO)
  61. {
  62. var sysUser = await GetUserById(userId);//获取用户信息
  63. if (sysUser.Account == account)//这里做了比较用来限制大小写
  64. return sysUser;
  65. return null;
  66. }
  67. return null;
  68. }
  69. /// <inheritdoc/>
  70. public async Task<SysUser> GetUserByPhone(string phone, long? tenantId = null)
  71. {
  72. var userId = await GetIdByPhone(phone, tenantId);//获取用户ID
  73. if (userId > 0)
  74. {
  75. return await GetUserById(userId);//获取用户信息
  76. }
  77. return null;
  78. }
  79. /// <inheritdoc/>
  80. public async Task<long> GetIdByPhone(string phone, long? tenantId = null)
  81. {
  82. var orgIds = new List<long>();
  83. var key = SystemConst.CACHE_SYS_USER_PHONE;
  84. if (tenantId != null)
  85. {
  86. key += $":{tenantId}";
  87. orgIds = await _sysOrgService.GetOrgChildIds(tenantId.Value);//获取下级机构
  88. }
  89. //先从缓存拿
  90. var userId = _simpleCacheService.HashGetOne<long>(key, phone);
  91. if (userId == 0)
  92. {
  93. var sm4Phone = CryptogramUtil.Sm4Encrypt(phone);//SM4加密一下
  94. //单查获取用户手机号对应的账号
  95. userId = await Context.Queryable<SysUser>()
  96. .Where(it => it.Phone == sm4Phone)
  97. .WhereIF(orgIds.Count > 0, it => orgIds.Contains(it.OrgId))
  98. .Select(it => it.Id)
  99. .FirstAsync();
  100. if (userId > 0)
  101. {
  102. //插入缓存
  103. _simpleCacheService.HashAdd(key, phone, userId);
  104. }
  105. }
  106. return userId;
  107. }
  108. /// <inheritdoc/>
  109. public async Task<SysUser> GetUserById(long userId)
  110. {
  111. //先从缓存拿
  112. var sysUser = _simpleCacheService.HashGetOne<SysUser>(SystemConst.CACHE_SYS_USER, userId.ToString());
  113. if (sysUser == null)
  114. {
  115. sysUser = await GetUserFromDb(userId);//从数据库拿用户信息
  116. }
  117. return sysUser;
  118. }
  119. /// <inheritdoc/>
  120. public async Task<T> GetUserById<T>(long userId)
  121. {
  122. var user = await GetUserById(userId);
  123. return user.Adapt<T>();
  124. }
  125. /// <inheritdoc/>
  126. public async Task<long> GetIdByAccount(string account, long? tenantId = null)
  127. {
  128. var orgIds = new List<long>();
  129. var key = SystemConst.CACHE_SYS_USER_ACCOUNT;
  130. if (tenantId != null)
  131. {
  132. key += $":{tenantId}";
  133. orgIds = await _sysOrgService.GetOrgChildIds(tenantId.Value);//获取下级机构
  134. }
  135. //先从缓存拿
  136. var userId = _simpleCacheService.HashGetOne<long>(key, account);
  137. if (userId == 0)
  138. {
  139. //单查获取用户账号对应ID
  140. userId = await Context.Queryable<SysUser>()
  141. .Where(it => it.Account == account)
  142. .WhereIF(orgIds.Count > 0, it => orgIds.Contains(it.OrgId))
  143. .Select(it => it.Id)
  144. .FirstAsync();
  145. if (userId != 0)
  146. {
  147. //插入缓存
  148. _simpleCacheService.HashAdd(key, account, userId);
  149. }
  150. }
  151. return userId;
  152. }
  153. /// <inheritdoc/>
  154. public async Task<List<string>> GetButtonCodeList(long userId)
  155. {
  156. var buttonCodeList = new List<string>();//按钮ID集合
  157. //获取用户资源集合
  158. var resourceList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);
  159. var buttonIdList = new List<long>();//按钮ID集合
  160. if (resourceList.Count == 0)//如果有表示用户单独授权了不走用户角色
  161. {
  162. //获取用户角色关系集合
  163. var roleList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);
  164. var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表
  165. if (roleIdList.Count > 0)//如果该用户有角色
  166. {
  167. resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(roleIdList,
  168. CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE);//获取资源集合
  169. }
  170. }
  171. resourceList.ForEach(it =>
  172. {
  173. if (!string.IsNullOrEmpty(it.ExtJson))
  174. buttonIdList.AddRange(it.ExtJson.ToJsonEntity<RelationRoleResource>().ButtonInfo);//如果有按钮权限,将按钮ID放到buttonIdList
  175. });
  176. if (buttonIdList.Count > 0)
  177. {
  178. buttonCodeList = await _resourceService.GetCodeByIds(buttonIdList, CateGoryConst.RESOURCE_BUTTON);
  179. }
  180. return buttonCodeList;
  181. }
  182. /// <inheritdoc/>
  183. public async Task<List<DataScope>> GetPermissionListByUserId(long userId, long orgId)
  184. {
  185. var permissions = new List<DataScope>();//权限集合
  186. var sysRelations =
  187. await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//根据用户ID获取用户权限
  188. if (sysRelations.Count == 0)//如果有表示用户单独授权了不走用户角色
  189. {
  190. var roleIdList =
  191. await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID
  192. if (roleIdList.Count > 0)//如果角色ID不为空
  193. {
  194. //获取角色权限信息
  195. sysRelations = await _relationService.GetRelationListByObjectIdListAndCategory(roleIdList.Select(it => it.TargetId.ToLong()).ToList(),
  196. CateGoryConst.RELATION_SYS_ROLE_HAS_PERMISSION);
  197. }
  198. }
  199. var relationGroup = sysRelations.GroupBy(it => it.TargetId).ToList();//根据目标ID,也就是接口名分组,因为存在一个用户多个角色
  200. //遍历分组
  201. foreach (var it in relationGroup)
  202. {
  203. var scopeSet = new HashSet<long>();//定义不可重复列表
  204. var relationList = it.ToList();//关系列表
  205. var scopeCategory = CateGoryConst.SCOPE_SELF;//数据权限分类,默认为仅自己
  206. //获取角色权限信息列表
  207. var rolePermissions = relationList.Select(it => it.ExtJson.ToJsonEntity<RelationRolePermission>()).ToList();
  208. if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ALL))//如果有全部
  209. scopeCategory = CateGoryConst.SCOPE_ALL;//标记为全部
  210. else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG_CHILD))//如果有机构及以下机构
  211. scopeCategory = CateGoryConst.SCOPE_ORG_CHILD;//标记为机构及以下机构
  212. else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG))//如果有仅自己机构
  213. scopeCategory = CateGoryConst.SCOPE_ORG;//标记为仅自己机构
  214. else if (rolePermissions.Any(role => role.ScopeCategory == CateGoryConst.SCOPE_ORG_DEFINE))//如果有自定义机构
  215. {
  216. scopeCategory = CateGoryConst.SCOPE_ORG_DEFINE;//标记为仅自己
  217. rolePermissions.ForEach(s =>
  218. {
  219. scopeSet.AddRange(s.ScopeDefineOrgIdList);//添加自定义范围的机构ID
  220. });
  221. }
  222. var dataScopes = scopeSet.ToList();//获取范围列表转列表
  223. permissions.Add(new DataScope
  224. {
  225. ApiUrl = it.Key,
  226. ScopeCategory = scopeCategory,
  227. DataScopes = dataScopes
  228. });//将改URL的权限集合加入权限集合列表
  229. }
  230. return permissions;
  231. }
  232. /// <inheritdoc/>
  233. public async Task<SqlSugarPagedList<UserSelectorOutPut>> Selector(UserSelectorInput input)
  234. {
  235. var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构
  236. var result = await Context.Queryable<SysUser>()
  237. .WhereIF(input.OrgId > 0, u => orgIds.Contains(u.OrgId))//指定机构
  238. .WhereIF(input.OrgIds != null, u => input.OrgIds.Contains(u.OrgId))//在指定机构列表查询
  239. .WhereIF(input.PositionId > 0, u => u.PositionId == input.PositionId)//指定职位
  240. .WhereIF(input.RoleId > 0,
  241. u => SqlFunc.Subqueryable<SysRelation>()
  242. .Where(r => r.TargetId == input.RoleId.ToString() && r.ObjectId == u.Id && r.Category == CateGoryConst.RELATION_SYS_USER_HAS_ROLE)
  243. .Any())//指定角色
  244. .WhereIF(!string.IsNullOrEmpty(input.Account), u => u.Account.Contains(input.Account))//根据关键字查询
  245. .Select<UserSelectorOutPut>().ToPagedListAsync(input.PageNum, input.PageSize);
  246. return result;
  247. }
  248. /// <inheritdoc/>
  249. public async Task<SqlSugarPagedList<SysUser>> Page(UserPageInput input)
  250. {
  251. var query = await GetQuery(input);//获取查询条件
  252. var pageInfo = await query.ToPagedListAsync(input.PageNum, input.PageSize);//分页
  253. return pageInfo;
  254. }
  255. /// <inheritdoc/>
  256. public async Task<List<SysUser>> List(UserPageInput input)
  257. {
  258. var query = await GetQuery(input);//获取查询条件
  259. var list = await query.ToListAsync();
  260. return list;
  261. }
  262. /// <inheritdoc/>
  263. public async Task<List<RoleSelectorOutPut>> OwnRole(BaseIdInput input)
  264. {
  265. var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.RELATION_SYS_USER_HAS_ROLE);
  266. var roleIds = relations.Select(it => it.TargetId.ToLong()).ToList();
  267. var roleList = await Context.Queryable<SysRole>().Where(it => roleIds.Contains(it.Id)).Select<RoleSelectorOutPut>().ToListAsync();
  268. return roleList;
  269. }
  270. /// <inheritdoc />
  271. public async Task<RoleOwnResourceOutput> OwnResource(BaseIdInput input)
  272. {
  273. return await _sysRoleService.OwnResource(input, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);
  274. }
  275. /// <inheritdoc />
  276. public async Task<RoleOwnPermissionOutput> OwnPermission(BaseIdInput input)
  277. {
  278. var roleOwnPermission = new RoleOwnPermissionOutput
  279. {
  280. Id = input.Id
  281. };//定义结果集
  282. var grantInfoList = new List<RelationRolePermission>();//已授权信息集合
  283. //获取关系列表
  284. var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);
  285. //遍历关系表
  286. relations.ForEach(it =>
  287. {
  288. //将扩展信息转为实体
  289. var relationPermission = it.ExtJson.ToJsonEntity<RelationRolePermission>();
  290. grantInfoList.Add(relationPermission);//添加到已授权信息
  291. });
  292. roleOwnPermission.GrantInfoList = grantInfoList;//赋值已授权信息
  293. return roleOwnPermission;
  294. }
  295. /// <inheritdoc />
  296. public async Task<List<string>> UserPermissionTreeSelector(BaseIdInput input)
  297. {
  298. var permissionTreeSelectors = new List<string>();//授权树结果集
  299. //获取用户资源关系
  300. var relationsRes = await _relationService.GetRelationByCategory(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);
  301. var menuIds = relationsRes.Where(it => it.ObjectId == input.Id).Select(it => it.TargetId.ToLong()).ToList();
  302. if (menuIds.Any())
  303. {
  304. //获取菜单信息
  305. var menus = await _resourceService.GetResourcesByIds(menuIds, CateGoryConst.RESOURCE_MENU);
  306. //获取权限授权树
  307. var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList());
  308. if (permissions.Count > 0)
  309. {
  310. permissionTreeSelectors = permissions.Select(it => it.PermissionName).ToList();//返回授权树权限名称列表
  311. }
  312. }
  313. return permissionTreeSelectors;
  314. }
  315. /// <inheritdoc />
  316. public async Task<List<UserSelectorOutPut>> GetUserListByIdList(IdListInput input)
  317. {
  318. var userList = await Context.Queryable<SysUser>().Where(it => input.IdList.Contains(it.Id)).Select<UserSelectorOutPut>().ToListAsync();
  319. return userList;
  320. }
  321. /// <inheritdoc />
  322. public async Task<SysUser> Detail(BaseIdInput input)
  323. {
  324. var user = await GetUserById(input.Id);
  325. if (user != null)
  326. {
  327. user.Password = null;//清空密码
  328. }
  329. return user;
  330. }
  331. #endregion 查询
  332. #region 数据范围相关
  333. /// <inheritdoc/>
  334. public async Task<List<long>?> GetLoginUserApiDataScope()
  335. {
  336. var userInfo = await GetUserById(UserManager.UserId);//获取用户信息
  337. // 路由名称
  338. var routeName = App.HttpContext.Request.Path.Value;
  339. //获取当前url的数据范围
  340. var dataScope = userInfo.DataScopeList.Where(it => it.ApiUrl == routeName).FirstOrDefault();
  341. if (dataScope != null)
  342. {
  343. //根据数据范围分类获取数据范围
  344. //null:代表拥有全部数据权限
  345. //[xx,xx]:代表拥有部分机构的权限
  346. //[]:代表仅自己权限
  347. switch (dataScope.ScopeCategory)
  348. {
  349. case CateGoryConst.SCOPE_ALL:
  350. return null;
  351. case CateGoryConst.SCOPE_ORG_CHILD:
  352. return userInfo.ScopeOrgChildList;
  353. case CateGoryConst.SCOPE_ORG:
  354. return new List<long> { userInfo.OrgId };
  355. case CateGoryConst.SCOPE_ORG_DEFINE:
  356. return dataScope.DataScopes;
  357. case CateGoryConst.SCOPE_SELF:
  358. return new List<long>();
  359. }
  360. }
  361. return new List<long>();
  362. }
  363. /// <inheritdoc/>
  364. public async Task<bool> CheckApiDataScope(long? orgId, long? createUerId, string errMsg = "")
  365. {
  366. var hasPermission = true;
  367. //判断数据范围
  368. var dataScope = await GetLoginUserApiDataScope();
  369. if (dataScope is { Count: > 0 })//如果有机构
  370. {
  371. if (orgId == null || !dataScope.Contains(orgId.Value))//判断机构id是否在数据范围
  372. hasPermission = false;
  373. }
  374. else if (dataScope is { Count: 0 })// 表示仅自己
  375. {
  376. if (createUerId != UserManager.UserId)
  377. hasPermission = false;//机构的创建人不是自己则报错
  378. }
  379. //如果传了错误信息,直接抛出异常
  380. if (!hasPermission && !string.IsNullOrEmpty(errMsg))
  381. throw Oops.Bah(errMsg);
  382. return hasPermission;
  383. }
  384. public async Task<bool> CheckApiDataScope(List<long> orgIds, List<long> createUerIds, string errMsg = "")
  385. {
  386. var hasPermission = true;
  387. //判断数据范围
  388. var dataScope = await GetLoginUserApiDataScope();
  389. if (dataScope is { Count: > 0 })//如果有机构
  390. {
  391. if (orgIds == null || !dataScope.ContainsAll(orgIds))//判断机构id列表是否全在数据范围
  392. hasPermission = false;
  393. }
  394. else if (dataScope is { Count: 0 })// 表示仅自己
  395. {
  396. if (createUerIds.Any(it => it != UserManager.UserId))//如果创建者id里有任何不是自己创建的机构
  397. hasPermission = false;
  398. }
  399. //如果传了错误信息,直接抛出异常
  400. if (!hasPermission && !string.IsNullOrEmpty(errMsg))
  401. throw Oops.Bah(errMsg);
  402. return hasPermission;
  403. }
  404. #endregion
  405. #region 新增
  406. /// <inheritdoc/>
  407. public async Task Add(UserAddInput input)
  408. {
  409. await CheckInput(input);//检查参数
  410. var sysUser = input.Adapt<SysUser>();//实体转换
  411. //默认头像
  412. sysUser.Avatar = AvatarUtil.GetNameImageBase64(sysUser.Name);
  413. //获取默认密码
  414. sysUser.Password = await GetDefaultPassWord(true);//设置密码
  415. sysUser.Status = CommonStatusConst.ENABLE;//默认状态
  416. await InsertAsync(sysUser);//添加数据
  417. }
  418. #endregion 新增
  419. #region 编辑
  420. /// <inheritdoc/>
  421. public async Task Edit(UserEditInput input)
  422. {
  423. await CheckInput(input);//检查参数
  424. var exist = await GetUserById(input.Id);//获取用户信息
  425. if (exist != null)
  426. {
  427. var isSuperAdmin = exist.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管
  428. if (isSuperAdmin && !UserManager.SuperAdmin)
  429. throw Oops.Bah("不可修改系统内置超管用户账号");
  430. var name = exist.Name;//姓名
  431. var sysUser = input.Adapt<SysUser>();//实体转换
  432. if (name != input.Name)
  433. sysUser.Avatar = AvatarUtil.GetNameImageBase64(input.Name);//如果姓名改变了,重新生成头像
  434. if (await Context.Updateable(sysUser).IgnoreColumns(it => new
  435. {
  436. //忽略更新字段
  437. it.Password,
  438. it.LastLoginAddress,
  439. it.LastLoginDevice,
  440. it.LastLoginIp,
  441. it.LastLoginTime,
  442. it.LatestLoginAddress,
  443. it.LatestLoginDevice,
  444. it.LatestLoginIp,
  445. it.LatestLoginTime
  446. }).IgnoreColumnsIF(name == input.Name, it => it.Avatar).ExecuteCommandAsync() > 0
  447. )//修改数据
  448. {
  449. DeleteUserFromRedis(sysUser.Id);//删除用户缓存
  450. //删除用户token缓存
  451. _simpleCacheService.HashDel<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, sysUser.Id.ToString());
  452. }
  453. }
  454. }
  455. /// <inheritdoc/>
  456. public async Task Edits(BatchEditInput input)
  457. {
  458. //获取参数字典
  459. var data = await _batchEditService.GetUpdateBatchConfigDict(input.Code, input.Columns);
  460. if (data.Count > 0)
  461. {
  462. await Context.Updateable<SysUser>(data).Where(it => input.Ids.Contains(it.Id)).ExecuteCommandAsync();
  463. }
  464. }
  465. /// <inheritdoc/>
  466. public async Task DisableUser(BaseIdInput input)
  467. {
  468. var sysUser = await GetUserById(input.Id);//获取用户信息
  469. if (sysUser != null)
  470. {
  471. var isSuperAdmin = sysUser.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管
  472. if (isSuperAdmin)
  473. throw Oops.Bah("不可禁用系统内置超管用户账号");
  474. CheckSelf(input.Id, SystemConst.DISABLE);//判断是不是自己
  475. //设置状态为禁用
  476. if (await UpdateSetColumnsTrueAsync(it => new SysUser
  477. {
  478. Status = CommonStatusConst.DISABLED
  479. }, it => it.Id == input.Id))
  480. DeleteUserFromRedis(input.Id);//从缓存删除用户信息
  481. }
  482. }
  483. /// <inheritdoc/>
  484. public async Task EnableUser(BaseIdInput input)
  485. {
  486. CheckSelf(input.Id, SystemConst.ENABLE);//判断是不是自己
  487. //设置状态为启用
  488. if (await UpdateSetColumnsTrueAsync(it => new SysUser
  489. {
  490. Status = CommonStatusConst.ENABLE
  491. }, it => it.Id == input.Id))
  492. DeleteUserFromRedis(input.Id);//从缓存删除用户信息
  493. }
  494. /// <inheritdoc/>
  495. public async Task ResetPassword(BaseIdInput input)
  496. {
  497. var password = await GetDefaultPassWord(true);//获取默认密码,这里不走Aop所以需要加密一下
  498. //重置密码
  499. if (await UpdateSetColumnsTrueAsync(it => new SysUser
  500. {
  501. Password = password
  502. }, it => it.Id == input.Id))
  503. DeleteUserFromRedis(input.Id);//从缓存删除用户信息
  504. }
  505. /// <inheritdoc />
  506. public async Task GrantRole(UserGrantRoleInput input)
  507. {
  508. var sysUser = await GetUserById(input.Id);//获取用户信息
  509. if (sysUser != null)
  510. {
  511. var isSuperAdmin = sysUser.Account == SysRoleConst.SUPER_ADMIN;//判断是否有超管
  512. if (isSuperAdmin)
  513. throw Oops.Bah("不能给超管分配角色");
  514. CheckSelf(input.Id, SystemConst.GRANT_ROLE);//判断是不是自己
  515. //给用户赋角色
  516. await _relationService.SaveRelationBatch(CateGoryConst.RELATION_SYS_USER_HAS_ROLE, input.Id,
  517. input.RoleIdList.Select(it => it.ToString()).ToList(), null, true);
  518. DeleteUserFromRedis(input.Id);//从缓存删除用户信息
  519. }
  520. }
  521. /// <inheritdoc />
  522. public async Task GrantResource(UserGrantResourceInput input)
  523. {
  524. var menuIds = input.GrantInfoList.Select(it => it.MenuId).ToList();//菜单ID
  525. var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息
  526. var relationRoles = new List<SysRelation>();//要添加的用户资源和授权关系表
  527. var sysUser = await GetUserById(input.Id);//获取用户
  528. if (sysUser != null)
  529. {
  530. #region 用户资源处理
  531. //遍历角色列表
  532. for (var i = 0; i < menuIds.Count; i++)
  533. {
  534. //将用户资源添加到列表
  535. relationRoles.Add(new SysRelation
  536. {
  537. ObjectId = sysUser.Id,
  538. TargetId = menuIds[i].ToString(),
  539. Category = CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE,
  540. ExtJson = extJsons == null ? null : extJsons[i]
  541. });
  542. }
  543. #endregion 用户资源处理
  544. #region 用户权限处理.
  545. var relationRolePer = new List<SysRelation>();//要添加的用户有哪些权限列表
  546. var defaultDataScope = input.DefaultDataScope;//获取默认数据范围
  547. //获取菜单信息
  548. var menus = await _resourceService.GetResourcesByIds(menuIds, CateGoryConst.RESOURCE_MENU);
  549. if (menus.Count > 0)
  550. {
  551. #region 用户模块关系
  552. //获取我的模块信息Id列表
  553. var moduleIds = menus.Select(it => it.Module.Value).Distinct().ToList();
  554. moduleIds.ForEach(it =>
  555. {
  556. //将角色资源添加到列表
  557. relationRoles.Add(new SysRelation
  558. {
  559. ObjectId = sysUser.Id,
  560. TargetId = it.ToString(),
  561. Category = CateGoryConst.RELATION_SYS_USER_HAS_MODULE
  562. });
  563. });
  564. #endregion
  565. //获取权限授权树
  566. var permissions = _resourceService.PermissionTreeSelector(menus.Select(it => it.Path).ToList());
  567. permissions.ForEach(it =>
  568. {
  569. //新建角色权限关系
  570. relationRolePer.Add(new SysRelation
  571. {
  572. ObjectId = sysUser.Id,
  573. TargetId = it.ApiRoute,
  574. Category = CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION,
  575. ExtJson = new RelationRolePermission
  576. {
  577. ApiUrl = it.ApiRoute,
  578. ScopeCategory = defaultDataScope.ScopeCategory,
  579. ScopeDefineOrgIdList = defaultDataScope.ScopeDefineOrgIdList
  580. }.ToJson()
  581. });
  582. });
  583. }
  584. relationRoles.AddRange(relationRolePer);//合并列表
  585. #endregion 用户权限处理.
  586. #region 保存数据库
  587. //事务
  588. var result = await Tenant.UseTranAsync(async () =>
  589. {
  590. var relationRep = ChangeRepository<DbRepository<SysRelation>>();//切换仓储
  591. await relationRep.DeleteAsync(it => it.ObjectId == sysUser.Id && (it.Category == CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION
  592. || it.Category == CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE) || it.Category == CateGoryConst.RELATION_SYS_USER_HAS_MODULE);
  593. await relationRep.InsertRangeAsync(relationRoles);//添加新的
  594. });
  595. if (result.IsSuccess)//如果成功了
  596. {
  597. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//刷新关系缓存
  598. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);//刷新关系缓存
  599. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//刷新关系缓存
  600. DeleteUserFromRedis(input.Id);//删除该用户缓存
  601. }
  602. else
  603. {
  604. //写日志
  605. _logger.LogError(result.ErrorMessage, result.ErrorException);
  606. throw Oops.Oh(ErrorCodeEnum.A0003);
  607. }
  608. #endregion 保存数据库
  609. }
  610. }
  611. /// <inheritdoc />
  612. public async Task GrantPermission(GrantPermissionInput input)
  613. {
  614. var sysUser = await GetUserById(input.Id);//获取用户
  615. if (sysUser != null)
  616. {
  617. var apiUrls = input.GrantInfoList.Select(it => it.ApiUrl).ToList();//apiurl列表
  618. var extJsons = input.GrantInfoList.Select(it => it.ToJson()).ToList();//拓展信息
  619. await _relationService.SaveRelationBatch(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION, input.Id, apiUrls, extJsons,
  620. true);//添加到数据库
  621. DeleteUserFromRedis(input.Id);
  622. }
  623. }
  624. #endregion 编辑
  625. #region 删除
  626. /// <inheritdoc/>
  627. public async Task Delete(BaseIdListInput input)
  628. {
  629. //获取所有ID
  630. var ids = input.Ids;
  631. if (ids.Count > 0)
  632. {
  633. var containsSuperAdmin = await IsAnyAsync(it => it.Account == SysRoleConst.SUPER_ADMIN && ids.Contains(it.Id));//判断是否有超管
  634. if (containsSuperAdmin)
  635. throw Oops.Bah("不可删除系统内置超管用户");
  636. if (ids.Contains(UserManager.UserId))
  637. throw Oops.Bah("不可删除自己");
  638. //定义删除的关系
  639. var delRelations = new List<string>
  640. {
  641. CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE,
  642. CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION,
  643. CateGoryConst.RELATION_SYS_USER_HAS_ROLE,
  644. CateGoryConst.RELATION_SYS_USER_HAS_MODULE,
  645. CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA,
  646. CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA
  647. };
  648. //事务
  649. var result = await Tenant.UseTranAsync(async () =>
  650. {
  651. //清除该用户作为主管信息
  652. await UpdateAsync(it => new SysUser
  653. {
  654. DirectorId = null
  655. }, it => ids.Contains(it.DirectorId.Value));
  656. //删除用户
  657. await DeleteByIdsAsync(ids.Cast<object>().ToArray());
  658. var relationRep = ChangeRepository<DbRepository<SysRelation>>();//切换仓储
  659. //删除关系表用户与资源关系,用户与权限关系,用户与角色关系
  660. await relationRep.DeleteAsync(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category));
  661. var orgRep = ChangeRepository<DbRepository<SysOrg>>();//切换仓储
  662. //删除组织表主管信息
  663. await orgRep.DeleteAsync(it => ids.Contains(it.DirectorId.Value));
  664. });
  665. if (result.IsSuccess)//如果成功了
  666. {
  667. DeleteUserFromRedis(ids);//缓存删除用户
  668. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_ROLE);//关系表刷新SYS_USER_HAS_ROLE缓存
  669. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE);//关系表刷新SYS_USER_HAS_ROLE缓存
  670. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_PERMISSION);//关系表刷新SYS_USER_HAS_ROLE缓存
  671. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_HAS_MODULE);//关系表刷新RELATION_SYS_USER_HAS_MODULE缓存
  672. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_SCHEDULE_DATA);//关系表刷新RELATION_SYS_USER_SCHEDULE_DATA缓存
  673. await _relationService.RefreshCache(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA);//关系表刷新RELATION_SYS_USER_WORKBENCH_DATA缓存
  674. // TODO 此处需要将这些用户踢下线,并永久注销这些用户
  675. var idArray = ids.Select(it => it.ToString()).ToArray();
  676. //从列表中删除
  677. _simpleCacheService.HashDel<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, idArray);
  678. }
  679. else
  680. {
  681. //写日志
  682. _logger.LogError(result.ErrorMessage, result.ErrorException);
  683. throw Oops.Oh(ErrorCodeEnum.A0002);
  684. }
  685. }
  686. }
  687. /// <inheritdoc />
  688. public void DeleteUserFromRedis(long userId)
  689. {
  690. DeleteUserFromRedis(new List<long>
  691. {
  692. userId
  693. });
  694. }
  695. /// <inheritdoc />
  696. public void DeleteUserFromRedis(List<long> ids)
  697. {
  698. var userIds = ids.Select(it => it.ToString()).ToArray();//id转string列表
  699. var sysUsers = _simpleCacheService.HashGet<SysUser>(SystemConst.CACHE_SYS_USER, userIds);//获取用户列表
  700. sysUsers = sysUsers.Where(it => it != null).ToList();//过滤掉不存在的
  701. if (sysUsers.Count > 0)
  702. {
  703. var accounts = sysUsers.Select(it => it.Account).ToArray();//账号集合
  704. var phones = sysUsers.Select(it => it.Phone).ToArray();//手机号集合
  705. //删除用户信息
  706. _simpleCacheService.HashDel<SysUser>(SystemConst.CACHE_SYS_USER, userIds);
  707. //删除用户头像信息
  708. _simpleCacheService.HashDel<string>(SystemConst.CACHE_SYS_USER_AVATAR, userIds);
  709. var userAccountKey = SystemConst.CACHE_SYS_USER_ACCOUNT;
  710. var userPhoneKey = SystemConst.CACHE_SYS_USER_PHONE;
  711. if (sysUsers.Any(it => it.TenantId != null))//如果有租户id不是空的表示是多租户模式
  712. {
  713. var tenantIds = sysUsers.Where(it => it.TenantId != null).Select(it => it.TenantId.Value).Distinct().ToArray();//租户id列表
  714. foreach (var tenantId in tenantIds)
  715. {
  716. userAccountKey = $"{userAccountKey}:{tenantId}";
  717. userPhoneKey = $"{userPhoneKey}:{tenantId}";
  718. //删除账号
  719. _simpleCacheService.HashDel<long>(userAccountKey, accounts);
  720. //删除手机
  721. if (phones != null)
  722. _simpleCacheService.HashDel<long>(userPhoneKey, phones);
  723. }
  724. }
  725. else
  726. {
  727. //删除账号
  728. _simpleCacheService.HashDel<long>(userAccountKey, accounts);
  729. //删除手机
  730. if (phones != null)
  731. _simpleCacheService.HashDel<long>(userPhoneKey, phones);
  732. }
  733. }
  734. }
  735. #endregion 删除
  736. #region 导入导出
  737. /// <inheritdoc/>
  738. public async Task<FileStreamResult> Template()
  739. {
  740. var templateName = "用户信息";
  741. //var result = _importExportService.GenerateLocalTemplate(templateName);
  742. var result = await _importExportService.GenerateTemplate<SysUserImportInput>(templateName);
  743. return result;
  744. }
  745. /// <inheritdoc/>
  746. public async Task<ImportPreviewOutput<SysUserImportInput>> Preview(ImportPreviewInput input)
  747. {
  748. var importPreview = await _importExportService.GetImportPreview<SysUserImportInput>(input.File);
  749. importPreview.Data = await CheckImport(importPreview.Data);//检查导入数据
  750. return importPreview;
  751. }
  752. /// <inheritdoc/>
  753. public async Task<ImportResultOutPut<SysUserImportInput>> Import(ImportResultInput<SysUserImportInput> input)
  754. {
  755. var data = await CheckImport(input.Data, true);//检查数据格式
  756. var result = _importExportService.GetImportResultPreview(data, out var importData);
  757. var sysUsers = importData.Adapt<List<SysUser>>();//转实体
  758. await SetUserDefault(sysUsers);//设置默认值
  759. await InsertOrBulkCopy(sysUsers);// 数据导入
  760. return result;
  761. }
  762. /// <inheritdoc/>
  763. public async Task<FileStreamResult> Export(UserPageInput input)
  764. {
  765. var genTests = await List(input);
  766. var data = genTests.Adapt<List<SysUserExportOutput>>();//转为Dto
  767. var result = await _importExportService.Export(data, "用户信息");
  768. return result;
  769. }
  770. /// <inheritdoc/>
  771. public async Task<List<T>> CheckImport<T>(List<T> data, bool clearError = false) where T : SysUserImportInput
  772. {
  773. #region 校验要用到的数据
  774. var accounts = data.Select(it => it.Account).ToList();//当前导入数据账号列表
  775. var phones = data.Where(it => !string.IsNullOrEmpty(it.Phone)).Select(it => it.Phone).ToList();//当前导入数据手机号列表
  776. var emails = data.Where(it => !string.IsNullOrEmpty(it.Email)).Select(it => it.Email).ToList();//当前导入数据邮箱列表
  777. var sysUsers = await GetListAsync(it => true, it => new SysUser
  778. {
  779. Account = it.Account,
  780. Phone = it.Phone,
  781. Email = it.Email
  782. });//获取数据用户信息
  783. var dbAccounts = sysUsers.Select(it => it.Account).ToList();//数据库账号列表
  784. var dbPhones = sysUsers.Where(it => !string.IsNullOrEmpty(it.Phone)).Select(it => it.Phone).ToList();//数据库手机号列表
  785. var dbEmails = sysUsers.Where(it => !string.IsNullOrEmpty(it.Email)).Select(it => it.Email).ToList();//邮箱账号列表
  786. var sysOrgList = await _sysOrgService.GetListAsync();
  787. var sysPositions = await _sysPositionService.GetListAsync();
  788. var dictList = await _dictService.GetListAsync();
  789. #endregion 校验要用到的数据
  790. foreach (var item in data)
  791. {
  792. if (clearError)//如果需要清除错误
  793. {
  794. item.ErrorInfo = new Dictionary<string, string>();
  795. item.HasError = false;
  796. }
  797. #region 校验账号
  798. if (dbAccounts.Contains(item.Account))
  799. item.ErrorInfo.Add(nameof(item.Account), $"系统已存在账号{item.Account}");
  800. if (accounts.Where(u => u == item.Account).Count() > 1)
  801. item.ErrorInfo.Add(nameof(item.Account), "账号重复");
  802. #endregion 校验账号
  803. #region 校验手机号
  804. if (!string.IsNullOrEmpty(item.Phone))
  805. {
  806. if (dbPhones.Contains(item.Phone))
  807. item.ErrorInfo.Add(nameof(item.Phone), $"系统已存在手机号{item.Phone}的用户");
  808. if (phones.Where(u => u == item.Phone).Count() > 1)
  809. item.ErrorInfo.Add(nameof(item.Phone), "手机号重复");
  810. }
  811. #endregion 校验手机号
  812. #region 校验邮箱
  813. if (!string.IsNullOrEmpty(item.Email))
  814. {
  815. if (dbEmails.Contains(item.Email))
  816. item.ErrorInfo.Add(nameof(item.Email), $"系统已存在邮箱{item.Email}");
  817. if (emails.Where(u => u == item.Email).Count() > 1)
  818. item.ErrorInfo.Add(nameof(item.Email), "邮箱重复");
  819. }
  820. #endregion 校验邮箱
  821. #region 校验部门和职位
  822. if (!string.IsNullOrEmpty(item.OrgName))
  823. {
  824. var org = sysOrgList.Where(u => u.Names == item.OrgName).FirstOrDefault();
  825. if (org != null) item.OrgId = org.Id;//赋值组织Id
  826. else item.ErrorInfo.Add(nameof(item.OrgName), $"部门{org}不存在");
  827. }
  828. //校验职位
  829. if (!string.IsNullOrEmpty(item.PositionName))
  830. {
  831. if (string.IsNullOrEmpty(item.OrgName))
  832. item.ErrorInfo.Add(nameof(item.PositionName), "请填写部门");
  833. else
  834. {
  835. //根据部门ID和职位名判断是否有职位
  836. var position = sysPositions.FirstOrDefault(u => u.OrgId == item.OrgId && u.Name == item.PositionName);
  837. if (position != null) item.PositionId = position.Id;
  838. else item.ErrorInfo.Add(nameof(item.PositionName), $"职位{item.PositionName}不存在");
  839. }
  840. }
  841. #endregion 校验部门和职位
  842. #region 校验性别等字典
  843. var genders = await _dictService.GetValuesByDictValue(SysDictConst.GENDER, dictList);
  844. if (!genders.Contains(item.Gender))
  845. item.ErrorInfo.Add(nameof(item.Gender), "性别只能是男和女");
  846. if (!string.IsNullOrEmpty(item.Nation))
  847. {
  848. var nations = await _dictService.GetValuesByDictValue(SysDictConst.NATION, dictList);
  849. if (!nations.Contains(item.Nation))
  850. item.ErrorInfo.Add(nameof(item.Nation), "不存在的民族");
  851. }
  852. if (!string.IsNullOrEmpty(item.IdCardType))
  853. {
  854. var idCarTypes = await _dictService.GetValuesByDictValue(SysDictConst.ID_CARD_TYPE, dictList);
  855. if (!idCarTypes.Contains(item.IdCardType))
  856. item.ErrorInfo.Add(nameof(item.IdCardType), "证件类型错误");
  857. }
  858. if (!string.IsNullOrEmpty(item.CultureLevel))
  859. {
  860. var cultureLevels = await _dictService.GetValuesByDictValue(SysDictConst.CULTURE_LEVEL, dictList);
  861. if (!cultureLevels.Contains(item.CultureLevel))
  862. item.ErrorInfo.Add(nameof(item.CultureLevel), "文化程度有误");
  863. }
  864. #endregion 校验性别等字典
  865. if (item.ErrorInfo.Count > 0) item.HasError = true;//如果错误信息数量大于0则表示有错误
  866. }
  867. data = data.OrderByDescending(it => it.HasError).ToList();//排序
  868. return data;
  869. }
  870. /// <inheritdoc/>
  871. public async Task SetUserDefault(List<SysUser> sysUsers)
  872. {
  873. var defaultPassword = await GetDefaultPassWord(true);//默认密码
  874. //默认值赋值
  875. sysUsers.ForEach(user =>
  876. {
  877. user.Status = CommonStatusConst.ENABLE;//状态
  878. user.Phone = CryptogramUtil.Sm4Encrypt(user.Phone);//手机号
  879. user.Password = defaultPassword;//默认密码
  880. user.Avatar = AvatarUtil.GetNameImageBase64(user.Name);//默认头像
  881. });
  882. }
  883. #endregion 导入导出
  884. #region 方法
  885. /// <summary>
  886. /// 获取默认密码
  887. /// </summary>
  888. /// <returns></returns>
  889. private async Task<string> GetDefaultPassWord(bool isSm4 = false)
  890. {
  891. //获取默认密码
  892. var defaultPassword = (await _configService.GetByConfigKey(CateGoryConst.CONFIG_PWD_POLICY, SysConfigConst.PWD_DEFAULT_PASSWORD)).ConfigValue;
  893. return isSm4 ? CryptogramUtil.Sm4Encrypt(defaultPassword) : defaultPassword;//判断是否需要加密
  894. }
  895. /// <summary>
  896. /// 检查输入参数
  897. /// </summary>
  898. /// <param name="sysUser"></param>
  899. private async Task CheckInput(SysUser sysUser)
  900. {
  901. var sysOrgList = await _sysOrgService.GetListAsync();//获取组织列表
  902. var userOrg = sysOrgList.FirstOrDefault(it => it.Id == sysUser.OrgId);
  903. if (userOrg == null)
  904. throw Oops.Bah($"组织机构不存在");
  905. //获取多租户配置
  906. var isTenant = await _configService.IsTenant();
  907. long? tenantId = null;
  908. if (isTenant)
  909. tenantId = await _sysOrgService.GetTenantIdByOrgId(sysUser.OrgId, sysOrgList);
  910. //判断账号重复,直接从缓存拿
  911. var accountId = await GetIdByAccount(sysUser.Account, tenantId);
  912. if (accountId > 0 && accountId != sysUser.Id)
  913. throw Oops.Bah($"存在重复的账号:{sysUser.Account}");
  914. //如果手机号不是空
  915. if (!string.IsNullOrEmpty(sysUser.Phone))
  916. {
  917. if (!sysUser.Phone.MatchPhoneNumber())//验证手机格式
  918. throw Oops.Bah($"手机号码:{sysUser.Phone} 格式错误");
  919. var phoneId = await GetIdByPhone(sysUser.Phone, tenantId);
  920. if (phoneId > 0 && sysUser.Id != phoneId)//判断重复
  921. throw Oops.Bah($"存在重复的手机号:{sysUser.Phone}");
  922. sysUser.Phone = CryptogramUtil.Sm4Encrypt(sysUser.Phone);
  923. }
  924. //如果邮箱不是空
  925. if (!string.IsNullOrEmpty(sysUser.Email))
  926. {
  927. var (isMatch, match) = sysUser.Email.MatchEmail();//验证邮箱格式
  928. if (!isMatch)
  929. throw Oops.Bah($"邮箱:{sysUser.Email} 格式错误");
  930. if (await IsAnyAsync(it => it.Email == sysUser.Email && it.Id != sysUser.Id))
  931. throw Oops.Bah($"存在重复的邮箱:{sysUser.Email}");
  932. }
  933. if (sysUser.DirectorId != null)
  934. {
  935. if (sysUser.DirectorId.Value == UserManager.UserId) throw Oops.Bah($"不能设置自己为主管");
  936. }
  937. }
  938. /// <summary>
  939. /// 检查是否为自己
  940. /// </summary>
  941. /// <param name="id"></param>
  942. /// <param name="operate">操作名称</param>
  943. private void CheckSelf(long id, string operate)
  944. {
  945. if (id == UserManager.UserId)//如果是自己
  946. {
  947. throw Oops.Bah($"禁止{operate}自己");
  948. }
  949. }
  950. /// <summary>
  951. /// 根据日期计算年龄
  952. /// </summary>
  953. /// <param name="birthdate"></param>
  954. /// <returns></returns>
  955. public int GetAgeByBirthdate(DateTime birthdate)
  956. {
  957. var now = DateTime.Now;
  958. var age = now.Year - birthdate.Year;
  959. if (now.Month < birthdate.Month || now.Month == birthdate.Month && now.Day < birthdate.Day)
  960. {
  961. age--;
  962. }
  963. return age < 0 ? 0 : age;
  964. }
  965. /// <summary>
  966. /// 获取SqlSugar的ISugarQueryable
  967. /// </summary>
  968. /// <param name="input"></param>
  969. /// <returns></returns>
  970. private async Task<ISugarQueryable<SysUser>> GetQuery(UserPageInput input)
  971. {
  972. var orgIds = await _sysOrgService.GetOrgChildIds(input.OrgId);//获取下级机构
  973. var query = Context.Queryable<SysUser>().LeftJoin<SysOrg>((u, o) => u.OrgId == o.Id).LeftJoin<SysPosition>((u, o, p) => u.PositionId == p.Id)
  974. .WhereIF(input.OrgId > 0, u => orgIds.Contains(u.OrgId))//根据组织
  975. .WhereIF(input.Expression != null, input.Expression?.ToExpression())//动态查询
  976. .WhereIF(!string.IsNullOrEmpty(input.Status), u => u.Status == input.Status)//根据状态查询
  977. .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u => u.Name.Contains(input.SearchKey) || u.Account.Contains(input.SearchKey))//根据关键字查询
  978. .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"u.{input.SortField} {input.SortOrder}").OrderBy(u => u.Id)//排序
  979. .OrderBy((u, o) => u.CreateTime)//排序
  980. .Select((u, o, p) => new SysUser
  981. {
  982. Id = u.Id.SelectAll(),
  983. OrgName = o.Name,
  984. PositionName = p.Name,
  985. OrgNames = o.Names
  986. }).Mapper(u =>
  987. {
  988. u.Password = null;//密码清空
  989. u.Phone = CryptogramUtil.Sm4Decrypt(u.Phone);//手机号解密
  990. });
  991. return query;
  992. }
  993. /// <summary>
  994. /// 数据库获取用户信息
  995. /// </summary>
  996. /// <param name="userId">用户ID</param>
  997. /// <returns></returns>
  998. private async Task<SysUser> GetUserFromDb(long userId)
  999. {
  1000. var sysUser = await Context.Queryable<SysUser>().LeftJoin<SysOrg>((u, o) => u.OrgId == o.Id)//连表
  1001. .LeftJoin<SysPosition>((u, o, p) => u.PositionId == p.Id)//连表
  1002. .Where(u => u.Id == userId)
  1003. .Select((u, o, p) => new SysUser
  1004. {
  1005. Id = u.Id.SelectAll(),
  1006. OrgName = o.Name,
  1007. OrgNames = o.Names,
  1008. PositionName = p.Name,
  1009. OrgAndPosIdList = o.ParentIdList
  1010. }).FirstAsync();
  1011. if (sysUser != null)
  1012. {
  1013. sysUser.Password = CryptogramUtil.Sm4Decrypt(sysUser.Password);//解密密码
  1014. sysUser.Phone = CryptogramUtil.Sm4Decrypt(sysUser.Phone);//解密手机号
  1015. sysUser.OrgAndPosIdList.AddRange(sysUser.OrgId, sysUser.PositionId);//添加组织和职位Id
  1016. if (sysUser.DirectorId != null)
  1017. {
  1018. sysUser.DirectorInfo = await GetUserById<UserSelectorOutPut>(sysUser.DirectorId.Value);//获取主管信息
  1019. }
  1020. //获取按钮码
  1021. var buttonCodeList = await GetButtonCodeList(sysUser.Id);
  1022. //获取数据权限
  1023. var dataScopeList = await GetPermissionListByUserId(sysUser.Id, sysUser.OrgId);
  1024. //获取权限码
  1025. var permissionCodeList = dataScopeList.Select(it => it.ApiUrl).ToList();
  1026. //获取角色码
  1027. var roleCodeList = await _sysRoleService.GetRoleListByUserId(sysUser.Id);
  1028. //权限码赋值
  1029. sysUser.ButtonCodeList = buttonCodeList;
  1030. sysUser.RoleCodeList = roleCodeList.Select(it => it.Code).ToList();
  1031. sysUser.RoleIdList = roleCodeList.Select(it => it.Id).ToList();
  1032. sysUser.PermissionCodeList = permissionCodeList;
  1033. sysUser.DataScopeList = dataScopeList;
  1034. var sysOrgList = await _sysOrgService.GetListAsync();
  1035. var scopeOrgChildList =
  1036. (await _sysOrgService.GetChildListById(sysUser.OrgId, true, sysOrgList)).Select(it => it.Id).ToList();//获取所属机构的下级机构Id列表
  1037. sysUser.ScopeOrgChildList = scopeOrgChildList;
  1038. if (await _configService.IsTenant())//如果是多租户就获取用户的租户Id
  1039. {
  1040. var tenantId = await _sysOrgService.GetTenantIdByOrgId(sysUser.OrgId, sysOrgList);
  1041. sysUser.TenantId = tenantId;
  1042. }
  1043. var moduleIds = await _relationService.GetUserModuleId(sysUser.RoleIdList, sysUser.Id);//获取模块ID列表
  1044. var modules = await _resourceService.GetResourcesByIds(moduleIds, CateGoryConst.RESOURCE_MODULE);//获取模块列表
  1045. sysUser.ModuleList = modules;//模块列表赋值给用户
  1046. //插入缓存
  1047. _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER_AVATAR, sysUser.Id.ToString(), sysUser.Avatar);
  1048. sysUser.Avatar = null;//头像清空,减少CACHE_SYS_USER的大小
  1049. _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER, sysUser.Id.ToString(), sysUser);
  1050. return sysUser;
  1051. }
  1052. return null;
  1053. }
  1054. #endregion 方法
  1055. }