diff --git "a/\350\265\226\345\277\227\347\224\237/20240709_\345\210\206\351\205\215\350\247\222\350\211\262\347\273\231\347\224\250\346\210\267.md" "b/\350\265\226\345\277\227\347\224\237/20240709_\345\210\206\351\205\215\350\247\222\350\211\262\347\273\231\347\224\250\346\210\267.md" new file mode 100644 index 0000000000000000000000000000000000000000..1506bacfbcb542f95cdd53a04319b97caf9b781e --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240709_\345\210\206\351\205\215\350\247\222\350\211\262\347\273\231\347\224\250\346\210\267.md" @@ -0,0 +1,99 @@ +## 分配角色给用户 + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.Interface; + +namespace Admin2024.Domain.DomainService; + +public class AppUserDomainService : IAppUserDomainService +{ + private readonly IRepository _appUserRepository; + private readonly IRepository _appRoleRepository; + private readonly IRepository _appUserRoleRepository; + + public AppUserDomainService(IRepository appUserRepository, + IRepository appUserRoleRepository, IRepository appRoleRepository) + { + _appUserRepository = appUserRepository; + _appRoleRepository = appRoleRepository; + _appUserRoleRepository = appUserRoleRepository; + } + + // 给用户分配角色 + public async Task AssigmRole(Guid appUserId, Guid appRoleId) + { + // 1.需要对id对应的实例存在不存在做验证 + // 2.如果都存在,需要对id对应的领域对象做进一步验证,如状态验证和业务验证 + var user = await _appUserRepository.GetByIdAsync(appUserId); + var role = await _appRoleRepository.GetByIdAsync(appRoleId); + // id对应的用户和角色都存在的情况下 + if (user != null && role != null) + { + // 业务要求:用户没有被删除,也没有被禁用 + // 业务要求:角色没有被删除,也没有被禁用 + if (user.IsDeleted != true && user.IsActived == true + && role.IsDeleted != true && role.IsActived == true) + { + var userRole = new AppUserRole { AppUserId = appUserId, AppRoleId = appRoleId }; + var res = await _appUserRoleRepository.CreateAsync(userRole); + return res; + } + + return null; + } + + return null; + + } + + public async Task Create(string username, string password, string confirmPassword) + { + // 先用用户名去查找数据库有无相当用户名的记录,如果找到,说明用户名重复了 + var user = _appUserRepository.Table.FirstOrDefault(x => x.Username == username); + + if (user == null && password == confirmPassword) + { + var appUser = await _appUserRepository.CreateAsync(new AppUser + { + Username = username, + Password = password, + Salt = "可盐可甜" + }); + return appUser; + } + return null; + } + + public void HasPemission(AppPermission appPermission) + { + throw new NotImplementedException(); + } + + public string? Login(string username, string password) + { + var user = _appUserRepository.Table.FirstOrDefault(x => x.Username == username); + + if (user != null && user.Password == password) + { + return "我是token"; + } + + return null; + } + + // 修改密码,修改密码的大部分操作在领域类型中完成的,如,md5加密,或者base64加密 + // 领域服务中,仅仅只是完成持久化 + public async void ModifyPassword(Guid id, string password) + { + var user = await _appUserRepository.GetByIdAsync(id); + if (user != null) + { + // 真正修改密码,其实是在领域模型中完成 + user.ModifyPassword(password); + await _appUserRepository.UpdateAsync(id, user); + } + + } +} +``` \ No newline at end of file diff --git "a/\350\265\226\345\277\227\347\224\237/20240710_\347\273\237\344\270\200\351\242\206\345\237\237\346\234\215\345\212\241\350\277\224\345\233\236\345\200\274\347\273\223\346\236\204.md" "b/\350\265\226\345\277\227\347\224\237/20240710_\347\273\237\344\270\200\351\242\206\345\237\237\346\234\215\345\212\241\350\277\224\345\233\236\345\200\274\347\273\223\346\236\204.md" new file mode 100644 index 0000000000000000000000000000000000000000..8547ba695611d6dbbdfdcd7f106d47d72e255458 --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240710_\347\273\237\344\270\200\351\242\206\345\237\237\346\234\215\345\212\241\350\277\224\345\233\236\345\200\274\347\273\223\346\236\204.md" @@ -0,0 +1,176 @@ +### 修改各接口及实现,统一领域服务返回值结构 + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.Interface; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService; + +public class AppUserDomainService : IAppUserDomainService +{ + private readonly IRepository _appUserRepository; + private readonly IRepository _appRoleRepository; + private readonly IRepository _appUserRoleRepository; + + public AppUserDomainService(IRepository appUserRepository, + IRepository appUserRoleRepository, IRepository appRoleRepository) + { + _appUserRepository = appUserRepository; + _appRoleRepository = appRoleRepository; + _appUserRoleRepository = appUserRoleRepository; + } + + // 给用户分配角色 + public async Task AssigmRole(Guid appUserId, Guid appRoleId) + { + // 1.需要对id对应的实例存在不存在做验证 + // 2.如果都存在,需要对id对应的领域对象做进一步验证,如状态验证和业务验证 + var user = await _appUserRepository.GetByIdAsync(appUserId); + var role = await _appRoleRepository.GetByIdAsync(appRoleId); + // id对应的用户和角色都存在的情况下 + if (user != null && role != null) + { + // 业务要求:用户没有被删除,也没有被禁用 + // 业务要求:角色没有被删除,也没有被禁用 + if (user.IsDeleted != true && user.IsActived == true + && role.IsDeleted != true && role.IsActived == true) + { + var userRole = new AppUserRole { AppUserId = appUserId, AppRoleId = appRoleId }; + var res = await _appUserRoleRepository.CreateAsync(userRole); + return res; + } + + return null; + } + + return null; + + } + + public async Task> Create(string username, string password, string confirmPassword) + { + // 去除前后空格 + username = username.Trim(); + password = password.Trim(); + confirmPassword = confirmPassword.Trim(); + + // 先用用户名去查找数据库有无相当用户名的记录,如果找到,说明用户名重复了 + var user = _appUserRepository.Table.FirstOrDefault(x => x.Username == username); + + // 如果有找到同步用户,则直接返回消息 + + if (user != null) + { + return DomainResult.Error("用户名重复"); + } + + // 判断用户名长度和密码是否符合要求 用户名>=5 <=30 密码>=6 <=18 + if (!(username.Length >= 5 && username.Length <= 30)) + { + return DomainResult.Error("用户名长度不符合规范,请确认后重试"); + } + + if (!(password.Length >= 5 && password.Length < 18)) + { + return DomainResult.Error("密码长度不符合规范,请确认后重试"); + } + // 两次密码不一致 + if (password != confirmPassword) + { + return DomainResult.Error("两次密码输入不一致,请确认后重试"); + } + + // 所有要求都符合,开始创建用户 + var appUser = new AppUser {Username=username,Password=password,Salt="随机字符" }; + var x = await _appUserRepository.CreateAsync(appUser); + + return DomainResult.Success(x); + } + + public void HasPemission(AppPermission appPermission) + { + throw new NotImplementedException(); + } + + public DomainResult Login(string username, string password) + { + // 通用用户名先查找有没有对应用户 + var user = _appUserRepository.Table.FirstOrDefault(x => x.Username == username); + + if (user == null) + { + return DomainResult.Error("用户名或密码不正确,请稍后重试"); + } + + if (user.IsDeleted) + { + return DomainResult.Error("用户已经被删除,请确认后重试"); + } + + if (!user.IsActived) + { + return DomainResult.Error("用户已经被禁用/封号,请确认后重试"); + } + + if (user.Password != password) + { + return DomainResult.Error("用户名或密码不正确,请稍后重试"); + } + + return DomainResult.Success(user); + } + + // 修改密码,修改密码的大部分操作在领域类型中完成的,如,md5加密,或者base64加密 + // 领域服务中,仅仅只是完成持久化 + public async void ModifyPassword(Guid id, string password) + { + var user = await _appUserRepository.GetByIdAsync(id); + if (user != null) + { + // 真正修改密码,其实是在领域模型中完成 + user.ModifyPassword(password); + await _appUserRepository.UpdateAsync(id, user); + } + + } +} + + + +``` + + +``` +namespace Admin2024.Domain.ObjectValue; + +public class DomainResult +{ + public bool IsSuccess { get; protected set; } + public T Data { get; protected set; } + public string ErrorMessage { get; protected set; } + + public DomainResult(bool isSuccess, T data, string errorMessage) + { + IsSuccess = isSuccess; + Data = data; + ErrorMessage = errorMessage; + } + + public static DomainResult Success(T data) + { + return new DomainResult(true, data, "成功"); + } + public static DomainResult Error(string errorMessage) + { +#pragma warning disable CS8604 // 引用类型参数可能为 null。 + return new DomainResult(false, default, errorMessage); +#pragma warning restore CS8604 // 引用类型参数可能为 null。 + } +} + + + + + +``` \ No newline at end of file diff --git "a/\350\265\226\345\277\227\347\224\237/20240711_\351\242\206\345\237\237\346\234\215\345\212\241\346\216\245\345\217\243\346\216\242\347\264\242\345\222\214\345\260\235\350\257\225.md" "b/\350\265\226\345\277\227\347\224\237/20240711_\351\242\206\345\237\237\346\234\215\345\212\241\346\216\245\345\217\243\346\216\242\347\264\242\345\222\214\345\260\235\350\257\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..b5d8ab67900a51e43866e906eb364b55431c188b --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240711_\351\242\206\345\237\237\346\234\215\345\212\241\346\216\245\345\217\243\346\216\242\347\264\242\345\222\214\345\260\235\350\257\225.md" @@ -0,0 +1,144 @@ +## 领域服务接口探索和尝试 + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +// 资源访问控制服务 +public interface IResourceAccessControlService +{ + Task> CanAccessResource(Guid appUserId, Guid appResourceId); + +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +// 用户认证服务接口 +public interface IAuthenticationService +{ + Task> Authenticate(string username, string password); + + Task> RefreshToken(string token); +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +// 用户认证服务接口 +public interface IAuthenticationService +{ + Task> Authenticate(string username, string password); + + Task> RefreshToken(string token); +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +// 用户认证服务接口 +public interface IAuthorizationService +{ + Task> HasRole(Guid appUserId, string roleName); + + Task> HasPermission(Guid appUserId,string permission); +} + +``` + + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +public interface IPasswordManagementService +{ + Task> ChangePassword(Guid appUserId, string password); + + Task> ResetPassword(Guid appUserId,string newPassword); +} + + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +public interface IPermissionManagementService +{ + Task> CreatePermission(Guid username, string password); + + Task> DeletePermission(string token); +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +// 角色管理服务接口 +public interface IRoleManagementService +{ + Task> CreateRole(string roleName); + + Task> DeleteRole(string token); + Task> UpdateRoleName(Guid appRoleId, string roleName); + Task> AssignPermissionToRole(Guid appRoleId, Guid appPermissionId); + Task> RemovePermissionFromRole(Guid appRoleId, Guid appPermissionId); +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +public interface IUserInformationManagementService +{ + Task> UpdateUserInfo(Guid appUserId, string password); + +} + +``` + +``` +using Admin2024.Domain.Entity.System; +using Admin2024.Domain.ObjectValue; + +namespace Admin2024.Domain.DomainService.System; + +public interface IUserRoleManagementService +{ + Task> AssignRoleToUser(Guid appUserId, Guid appRoleId); + + Task> RemoveRoleFromUser(Guid appUserId, Guid appRoleId); +} + +``` \ No newline at end of file diff --git "a/\350\265\226\345\277\227\347\224\237/20240712_\346\220\255\345\273\272\345\211\215\347\253\257\351\241\265\351\235\242.md" "b/\350\265\226\345\277\227\347\224\237/20240712_\346\220\255\345\273\272\345\211\215\347\253\257\351\241\265\351\235\242.md" new file mode 100644 index 0000000000000000000000000000000000000000..096c041fd661c3e4597d3517ec089d02d20b05be --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240712_\346\220\255\345\273\272\345\211\215\347\253\257\351\241\265\351\235\242.md" @@ -0,0 +1,31 @@ +## 搭建前端管理界面 + +main.js +``` +import { createApp } from 'vue' +import App from './App.vue' +// 以下完整引入antdv +import antdv from 'ant-design-vue' +import 'ant-design-vue/dist/reset.css' + +import { createRouter, createWebHistory } from 'vue-router' + +let router = createRouter({ + history: createWebHistory(), + routes: [ + { + path: '/', + component: () => import('./views/test.vue') + }, + { + path: '/about', + component: () => import('./views/about.vue') + } + ] +}) + +let app = createApp(App); + +app.use(router).use(antdv).mount('#app') + +``` \ No newline at end of file