TenantService.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. using System.Linq;
  2. using System.Threading.Tasks;
  3. using Microsoft.AspNetCore.Mvc;
  4. using ZhonTai.Admin.Core.Attributes;
  5. using ZhonTai.Common.Helpers;
  6. using ZhonTai.Admin.Core.Dto;
  7. using ZhonTai.Admin.Domain.Role;
  8. using ZhonTai.Admin.Domain.RolePermission;
  9. using ZhonTai.Admin.Domain.Tenant;
  10. using ZhonTai.Admin.Domain.User;
  11. using ZhonTai.Admin.Domain.UserRole;
  12. using ZhonTai.Admin.Services.Tenant.Dto;
  13. using ZhonTai.Admin.Domain.Tenant.Dto;
  14. using ZhonTai.DynamicApi;
  15. using ZhonTai.DynamicApi.Attributes;
  16. using ZhonTai.Admin.Core.Consts;
  17. using ZhonTai.Admin.Core.Configs;
  18. using ZhonTai.Admin.Domain.Org;
  19. using ZhonTai.Admin.Domain.UserStaff;
  20. using ZhonTai.Admin.Domain.UserOrg;
  21. using Microsoft.AspNetCore.Identity;
  22. using System.Linq.Expressions;
  23. using System;
  24. using System.Collections.Generic;
  25. using Yitter.IdGenerator;
  26. using ZhonTai.Admin.Domain.Pkg;
  27. using ZhonTai.Admin.Domain.TenantPkg;
  28. using ZhonTai.Admin.Services.Pkg;
  29. using ZhonTai.Admin.Domain.Platform;
  30. using ZhonTai.Admin.Repositories.Platform;
  31. using ZhonTai.Admin.Core.Auth;
  32. namespace ZhonTai.Admin.Services.Tenant;
  33. /// <summary>
  34. /// 租户服务
  35. /// </summary>
  36. [Order(50)]
  37. [DynamicApi(Area = AdminConsts.AreaName)]
  38. public class TenantService : BaseService, ITenantService, IDynamicApi
  39. {
  40. private AppConfig _appConfig => LazyGetRequiredService<AppConfig>();
  41. private ITenantRepository _tenantRepository => LazyGetRequiredService<ITenantRepository>();
  42. private IRoleRepository _roleRepository => LazyGetRequiredService<IRoleRepository>();
  43. private IUserRepository _userRepository => LazyGetRequiredService<IUserRepository>();
  44. private IOrgRepository _orgRepository => LazyGetRequiredService<IOrgRepository>();
  45. private IUserRoleRepository _userRoleRepository => LazyGetRequiredService<IUserRoleRepository>();
  46. private IRolePermissionRepository _rolePermissionRepository => LazyGetRequiredService<IRolePermissionRepository>();
  47. private IUserStaffRepository _userStaffRepository => LazyGetRequiredService<IUserStaffRepository>();
  48. private IUserOrgRepository _userOrgRepository => LazyGetRequiredService<IUserOrgRepository>();
  49. private IPasswordHasher<UserEntity> _passwordHasher => LazyGetRequiredService<IPasswordHasher<UserEntity>>();
  50. private ITenantPkgRepository _tenantPkgRepository => LazyGetRequiredService<ITenantPkgRepository>();
  51. private IPlatformUserRepository _platformUserRepository => LazyGetRequiredService<PlatformUserRepository>();
  52. public TenantService()
  53. {
  54. }
  55. /// <summary>
  56. /// 查询
  57. /// </summary>
  58. /// <param name="id"></param>
  59. /// <returns></returns>
  60. public async Task<TenantGetOutput> GetAsync(long id)
  61. {
  62. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  63. {
  64. var tenant = await _tenantRepository.Select
  65. .WhereDynamic(id)
  66. .IncludeMany(a => a.Pkgs.Select(b => new PkgEntity { Id = b.Id, Name = b.Name }))
  67. .FirstAsync(a => new TenantGetOutput
  68. {
  69. Name = a.Org.Name,
  70. Code = a.Org.Code,
  71. Pkgs = a.Pkgs,
  72. UserName = a.User.UserName,
  73. RealName = a.User.Name,
  74. Phone = a.User.Mobile,
  75. Email = a.User.Email,
  76. });
  77. return tenant;
  78. }
  79. }
  80. /// <summary>
  81. /// 查询分页
  82. /// </summary>
  83. /// <param name="input"></param>
  84. /// <returns></returns>
  85. [HttpPost]
  86. public async Task<PageOutput<TenantListOutput>> GetPageAsync(PageInput<TenantGetPageDto> input)
  87. {
  88. using var _ = _tenantRepository.DataFilter.Disable(FilterNames.Tenant);
  89. var key = input.Filter?.Name;
  90. var list = await _tenantRepository.Select
  91. .WhereDynamicFilter(input.DynamicFilter)
  92. .WhereIf(key.NotNull(), a => a.Org.Name.Contains(key))
  93. .Count(out var total)
  94. .OrderByDescending(true, a => a.Id)
  95. .IncludeMany(a => a.Pkgs.Select(b => new PkgEntity { Name = b.Name }))
  96. .Page(input.CurrentPage, input.PageSize)
  97. .ToListAsync(a => new TenantListOutput
  98. {
  99. Name = a.Org.Name,
  100. Code = a.Org.Code,
  101. UserName = a.User.UserName,
  102. RealName = a.User.Name,
  103. Phone = a.User.Mobile,
  104. Email = a.User.Email,
  105. Pkgs = a.Pkgs,
  106. });
  107. var data = new PageOutput<TenantListOutput>()
  108. {
  109. List = Mapper.Map<List<TenantListOutput>>(list),
  110. Total = total
  111. };
  112. return data;
  113. }
  114. /// <summary>
  115. /// 新增
  116. /// </summary>
  117. /// <param name="input"></param>
  118. /// <returns></returns>
  119. [AdminTransaction]
  120. public virtual async Task<long> AddAsync(TenantAddInput input)
  121. {
  122. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  123. {
  124. var existsOrg = await _orgRepository.Select
  125. .Where(a => (a.Name == input.Name || a.Code == input.Code) && a.ParentId == 0)
  126. .FirstAsync(a => new { a.Name, a.Code });
  127. if (existsOrg != null)
  128. {
  129. if (existsOrg.Name == input.Name)
  130. {
  131. throw ResultOutput.Exception($"企业名称已存在");
  132. }
  133. if (existsOrg.Code == input.Code)
  134. {
  135. throw ResultOutput.Exception($"企业编码已存在");
  136. }
  137. }
  138. Expression<Func<UserEntity, bool>> where = (a => a.UserName == input.UserName);
  139. where = where.Or(input.Phone.NotNull(), a => a.Mobile == input.Phone)
  140. .Or(input.Email.NotNull(), a => a.Email == input.Email);
  141. var existsUser = await _userRepository.Select.Where(where)
  142. .FirstAsync(a => new { a.UserName, a.Mobile, a.Email });
  143. if (existsUser != null)
  144. {
  145. if (existsUser.UserName == input.UserName)
  146. {
  147. throw ResultOutput.Exception($"企业账号已存在");
  148. }
  149. if (input.Phone.NotNull() && existsUser.Mobile == input.Phone)
  150. {
  151. throw ResultOutput.Exception($"企业手机号已存在");
  152. }
  153. if (input.Email.NotNull() && existsUser.Email == input.Email)
  154. {
  155. throw ResultOutput.Exception($"企业邮箱已存在");
  156. }
  157. }
  158. //添加租户
  159. TenantEntity entity = Mapper.Map<TenantEntity>(input);
  160. TenantEntity tenant = await _tenantRepository.InsertAsync(entity);
  161. long tenantId = tenant.Id;
  162. //添加租户套餐
  163. if (input.PkgIds != null && input.PkgIds.Any())
  164. {
  165. var pkgs = input.PkgIds.Select(pkgId => new TenantPkgEntity
  166. {
  167. TenantId = tenantId,
  168. PkgId = pkgId
  169. }).ToList();
  170. await _tenantPkgRepository.InsertAsync(pkgs);
  171. }
  172. //添加部门
  173. var org = new OrgEntity
  174. {
  175. TenantId = tenantId,
  176. Name = input.Name,
  177. Code = input.Code,
  178. ParentId = 0,
  179. MemberCount = 1,
  180. Sort = 1,
  181. Enabled = true
  182. };
  183. await _orgRepository.InsertAsync(org);
  184. //添加用户
  185. if (input.Password.IsNull())
  186. {
  187. input.Password = _appConfig.DefaultPassword;
  188. }
  189. var user = new UserEntity
  190. {
  191. TenantId = tenantId,
  192. UserName = input.UserName,
  193. Name = input.RealName,
  194. Mobile = input.Phone,
  195. Email = input.Email,
  196. Type = UserType.TenantAdmin,
  197. OrgId = org.Id,
  198. Enabled = true
  199. };
  200. if (_appConfig.PasswordHasher)
  201. {
  202. user.Password = _passwordHasher.HashPassword(user, input.Password);
  203. user.PasswordEncryptType = PasswordEncryptType.PasswordHasher;
  204. }
  205. else
  206. {
  207. user.Password = MD5Encrypt.Encrypt32(input.Password);
  208. user.PasswordEncryptType = PasswordEncryptType.MD5Encrypt32;
  209. }
  210. await _userRepository.InsertAsync(user);
  211. long userId = user.Id;
  212. //添加用户员工
  213. var emp = new UserStaffEntity
  214. {
  215. Id = userId,
  216. TenantId = tenantId
  217. };
  218. await _userStaffRepository.InsertAsync(emp);
  219. //添加用户部门
  220. var userOrg = new UserOrgEntity
  221. {
  222. UserId = userId,
  223. OrgId = org.Id
  224. };
  225. await _userOrgRepository.InsertAsync(userOrg);
  226. //添加角色分组和角色
  227. var roleGroupId = YitIdHelper.NextId();
  228. var roleId = YitIdHelper.NextId();
  229. var jobGroupId = YitIdHelper.NextId();
  230. var roles = new List<RoleEntity>{
  231. new RoleEntity
  232. {
  233. Id = roleGroupId,
  234. ParentId = 0,
  235. TenantId = tenantId,
  236. Type = RoleType.Group,
  237. Name = "系统默认",
  238. Sort = 1
  239. },
  240. new RoleEntity
  241. {
  242. Id = roleId,
  243. TenantId = tenantId,
  244. Type = RoleType.Role,
  245. Name = "主管理员",
  246. Code = "main-admin",
  247. ParentId = roleGroupId,
  248. DataScope = DataScope.All,
  249. Sort = 1
  250. },
  251. new RoleEntity
  252. {
  253. Id= jobGroupId,
  254. ParentId = 0,
  255. TenantId = tenantId,
  256. Type = RoleType.Group,
  257. Name = "岗位",
  258. Sort = 2
  259. },
  260. new RoleEntity
  261. {
  262. TenantId = tenantId,
  263. Type = RoleType.Role,
  264. Name = "普通员工",
  265. Code = "emp",
  266. ParentId = jobGroupId,
  267. DataScope = DataScope.Self,
  268. Sort = 2
  269. }
  270. };
  271. await _roleRepository.InsertAsync(roles);
  272. //添加用户角色
  273. var userRole = new UserRoleEntity()
  274. {
  275. UserId = userId,
  276. RoleId = roleId
  277. };
  278. await _userRoleRepository.InsertAsync(userRole);
  279. //新增平台用户
  280. string invite = await CreateInviteCode();
  281. var platfromUser = new PlatformUserEntity()
  282. {
  283. TenantId = tenantId,
  284. Name = user.UserName,
  285. Phone = user.Mobile,
  286. Password = user.Password,
  287. Role = "1",
  288. ParentId = "0_",
  289. InviteCode = invite
  290. };
  291. await _platformUserRepository.InsertAsync(platfromUser);
  292. long platfromUserId = platfromUser.Id;
  293. //更新租户的用户和部门
  294. tenant.UserId = userId;
  295. tenant.OrgId = org.Id;
  296. tenant.PlatfromUserId = platfromUserId;
  297. await _tenantRepository.UpdateAsync(tenant);
  298. return tenant.Id;
  299. }
  300. }
  301. /// <summary>
  302. /// 修改
  303. /// </summary>
  304. /// <param name="input"></param>
  305. /// <returns></returns>
  306. public async Task UpdateAsync(TenantUpdateInput input)
  307. {
  308. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  309. {
  310. var tenant = await _tenantRepository.GetAsync(input.Id);
  311. if (!(tenant?.Id > 0))
  312. {
  313. throw ResultOutput.Exception("租户不存在");
  314. }
  315. var existsOrg = await _orgRepository.Select
  316. .Where(a => a.Id != tenant.OrgId && (a.Name == input.Name || a.Code == input.Code))
  317. .FirstAsync(a => new { a.Name, a.Code });
  318. if (existsOrg != null)
  319. {
  320. if (existsOrg.Name == input.Name)
  321. {
  322. throw ResultOutput.Exception($"企业名称已存在");
  323. }
  324. if (existsOrg.Code == input.Code)
  325. {
  326. throw ResultOutput.Exception($"企业编码已存在");
  327. }
  328. }
  329. Expression<Func<UserEntity, bool>> where = (a => a.UserName == input.UserName);
  330. where = where.Or(input.Phone.NotNull(), a => a.Mobile == input.Phone)
  331. .Or(input.Email.NotNull(), a => a.Email == input.Email);
  332. var existsUser = await _userRepository.Select.Where(a => a.Id != tenant.UserId).Where(where)
  333. .FirstAsync(a => new { a.Id, a.Name, a.UserName, a.Mobile, a.Email });
  334. if (existsUser != null)
  335. {
  336. if (existsUser.UserName == input.UserName)
  337. {
  338. throw ResultOutput.Exception($"企业账号已存在");
  339. }
  340. if (input.Phone.NotNull() && existsUser.Mobile == input.Phone)
  341. {
  342. throw ResultOutput.Exception($"企业手机号已存在");
  343. }
  344. if (input.Email.NotNull() && existsUser.Email == input.Email)
  345. {
  346. throw ResultOutput.Exception($"企业邮箱已存在");
  347. }
  348. }
  349. //更新用户
  350. await _userRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource(
  351. new UserEntity()
  352. {
  353. Id = tenant.UserId,
  354. Name = input.RealName,
  355. UserName = input.UserName,
  356. Mobile = input.Phone,
  357. Email = input.Email
  358. })
  359. .UpdateColumns(a => new { a.Name, a.UserName, a.Mobile, a.Email, a.ModifiedTime }).ExecuteAffrowsAsync();
  360. //更新部门
  361. await _orgRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource(
  362. new OrgEntity()
  363. {
  364. Id = tenant.OrgId,
  365. Name = input.Name,
  366. Code = input.Code
  367. })
  368. .UpdateColumns(a => new { a.Name, a.Code, a.ModifiedTime }).ExecuteAffrowsAsync();
  369. //更新租户
  370. await _tenantRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource(
  371. new TenantEntity()
  372. {
  373. Id = tenant.Id,
  374. Description = input.Description,
  375. })
  376. .UpdateColumns(a => new { a.Description, a.ModifiedTime }).ExecuteAffrowsAsync();
  377. //更新租户套餐
  378. await _tenantPkgRepository.DeleteAsync(a => a.TenantId == tenant.Id);
  379. if (input.PkgIds != null && input.PkgIds.Any())
  380. {
  381. var pkgs = input.PkgIds.Select(pkgId => new TenantPkgEntity
  382. {
  383. TenantId = tenant.Id,
  384. PkgId = pkgId
  385. }).ToList();
  386. await _tenantPkgRepository.InsertAsync(pkgs);
  387. //清除租户下所有用户权限缓存
  388. await LazyGetRequiredService<PkgService>().ClearUserPermissionsAsync(new List<long> { tenant.Id });
  389. }
  390. //更新平台用户
  391. await _platformUserRepository.UpdateDiy.SetSource(new PlatformUserEntity()
  392. {
  393. Id=tenant.PlatfromUserId,
  394. Name = input.RealName,
  395. Phone = input.Phone,
  396. }).UpdateColumns(m => new { m.Name, m.Phone }).ExecuteAffrowsAsync(); ;
  397. }
  398. }
  399. /// <summary>
  400. /// 彻底删除
  401. /// </summary>
  402. /// <param name="id"></param>
  403. /// <returns></returns>
  404. [AdminTransaction]
  405. public virtual async Task DeleteAsync(long id)
  406. {
  407. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  408. {
  409. var tenantType = await _tenantRepository.Select.WhereDynamic(id).ToOneAsync(a => a.TenantType);
  410. if (tenantType == TenantType.Platform)
  411. {
  412. throw ResultOutput.Exception("平台租户禁止删除");
  413. }
  414. //删除角色权限
  415. await _rolePermissionRepository.Where(a => a.Role.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  416. //删除用户角色
  417. await _userRoleRepository.Where(a => a.User.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  418. //删除员工
  419. await _userStaffRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  420. //删除用户部门
  421. await _userOrgRepository.Where(a => a.User.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  422. //删除部门
  423. await _orgRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  424. //删除用户
  425. await _userRepository.Where(a => a.TenantId == id && a.Type != UserType.Member).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  426. //删除角色
  427. await _roleRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync();
  428. //删除租户套餐
  429. await _tenantPkgRepository.DeleteAsync(a => a.TenantId == id);
  430. //删除租户
  431. await _tenantRepository.DeleteAsync(id);
  432. //清除租户下所有用户权限缓存
  433. await LazyGetRequiredService<PkgService>().ClearUserPermissionsAsync(new List<long> { id });
  434. }
  435. }
  436. /// <summary>
  437. /// 删除
  438. /// </summary>
  439. /// <param name="id"></param>
  440. /// <returns></returns>
  441. [AdminTransaction]
  442. public virtual async Task SoftDeleteAsync(long id)
  443. {
  444. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  445. {
  446. var tenantType = await _tenantRepository.Select.WhereDynamic(id).ToOneAsync(a => a.TenantType);
  447. if (tenantType == TenantType.Platform)
  448. {
  449. throw ResultOutput.Exception("平台租户禁止删除");
  450. }
  451. //删除部门
  452. await _orgRepository.SoftDeleteAsync(a => a.TenantId == id, FilterNames.Tenant);
  453. //删除用户
  454. await _userRepository.SoftDeleteAsync(a => a.TenantId == id && a.Type != UserType.Member, FilterNames.Tenant);
  455. //删除角色
  456. await _roleRepository.SoftDeleteAsync(a => a.TenantId == id, FilterNames.Tenant);
  457. //删除租户
  458. var result = await _tenantRepository.SoftDeleteAsync(id);
  459. //清除租户下所有用户权限缓存
  460. await LazyGetRequiredService<PkgService>().ClearUserPermissionsAsync(new List<long> { id });
  461. }
  462. }
  463. /// <summary>
  464. /// 批量删除
  465. /// </summary>
  466. /// <param name="ids"></param>
  467. /// <returns></returns>
  468. [AdminTransaction]
  469. public virtual async Task BatchSoftDeleteAsync(long[] ids)
  470. {
  471. using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant))
  472. {
  473. var tenantType = await _tenantRepository.Select.WhereDynamic(ids).ToOneAsync(a => a.TenantType);
  474. if (tenantType == TenantType.Platform)
  475. {
  476. throw ResultOutput.Exception("平台租户禁止删除");
  477. }
  478. //删除部门
  479. await _orgRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value), FilterNames.Tenant);
  480. //删除用户
  481. await _userRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value) && a.Type != UserType.Member, FilterNames.Tenant);
  482. //删除角色
  483. await _roleRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value), FilterNames.Tenant);
  484. //删除租户
  485. var result = await _tenantRepository.SoftDeleteAsync(ids);
  486. //清除租户下所有用户权限缓存
  487. await LazyGetRequiredService<PkgService>().ClearUserPermissionsAsync(ids.ToList());
  488. }
  489. }
  490. /// <summary>
  491. /// 设置启用
  492. /// </summary>
  493. /// <param name="input"></param>
  494. /// <returns></returns>
  495. public async Task SetEnableAsync(TenantSetEnableInput input)
  496. {
  497. var entity = await _tenantRepository.GetAsync(input.TenantId);
  498. if (entity.TenantType == TenantType.Platform)
  499. {
  500. throw ResultOutput.Exception("平台租户禁止禁用");
  501. }
  502. entity.Enabled = input.Enabled;
  503. await _tenantRepository.UpdateAsync(entity);
  504. }
  505. private async Task<string> CreateInviteCode()
  506. {
  507. string invite = StringHelper.GenerateRandomNumber();
  508. var count = await _platformUserRepository.Select.Where(m => m.InviteCode == invite).CountAsync();
  509. if (count > 0)
  510. {
  511. invite = await CreateInviteCode();
  512. }
  513. return invite;
  514. }
  515. }