From a51d183ed40f52bdcfeb2cf5a6bffede0e2c00af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=8E=89=E4=BA=AE=20=20=28=E9=AB=98=E7=A5=96=29?= <17779658783@163.com> Date: Fri, 25 Jul 2025 08:20:33 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BackOffice.Api/BackOffice.Web.csproj | 1 + .../BackOffice.Application.csproj | 5 + .../Handlers/RegisterUserCommandHandler.cs | 98 +++++++++++++++++++ .../Services/RegisterUserCommand.cs | 68 +++++++++++++ .../Repositories/UserRepository.cs | 64 ++++++++++++ 5 files changed, 236 insertions(+) create mode 100644 backend/BackOffice/BackOffice.Application/Handlers/RegisterUserCommandHandler.cs create mode 100644 backend/BackOffice/BackOffice.Application/Services/RegisterUserCommand.cs create mode 100644 backend/BackOffice/BackOffice.Infrastructure/Repositories/UserRepository.cs diff --git a/backend/BackOffice/BackOffice.Api/BackOffice.Web.csproj b/backend/BackOffice/BackOffice.Api/BackOffice.Web.csproj index 06bc7aa..f5c472b 100644 --- a/backend/BackOffice/BackOffice.Api/BackOffice.Web.csproj +++ b/backend/BackOffice/BackOffice.Api/BackOffice.Web.csproj @@ -7,6 +7,7 @@ + diff --git a/backend/BackOffice/BackOffice.Application/BackOffice.Application.csproj b/backend/BackOffice/BackOffice.Application/BackOffice.Application.csproj index b932aaf..e1d31a2 100644 --- a/backend/BackOffice/BackOffice.Application/BackOffice.Application.csproj +++ b/backend/BackOffice/BackOffice.Application/BackOffice.Application.csproj @@ -4,6 +4,11 @@ + + + + + net8.0 enable diff --git a/backend/BackOffice/BackOffice.Application/Handlers/RegisterUserCommandHandler.cs b/backend/BackOffice/BackOffice.Application/Handlers/RegisterUserCommandHandler.cs new file mode 100644 index 0000000..6534b74 --- /dev/null +++ b/backend/BackOffice/BackOffice.Application/Handlers/RegisterUserCommandHandler.cs @@ -0,0 +1,98 @@ +//用户注册命令处理器 + +using System; +using System.Threading; +using System.Threading.Tasks; +using BackOffice.Application.Commands.Users; +using MediatR; + +namespace BackOffice.Application.Handlers.Users +{ + /// + /// 用户注册命令处理器 + /// + public class RegisterUserCommandHandler : IRequestHandler + { + // 模拟用户存储(可以替换为数据库上下文或其他存储机制) + private readonly IUserRepository _userRepository; + + /// + /// 构造函数 + /// + /// 用户存储仓库 + public RegisterUserCommandHandler(IUserRepository userRepository) + { + _userRepository = userRepository ?? throw new ArgumentNullException(nameof(userRepository)); + } + + /// + /// 处理用户注册命令 + /// + /// 用户注册命令 + /// 取消令牌 + /// 用户注册结果 + public async Task Handle(RegisterUserCommand request, CancellationToken cancellationToken) + { + // 检查用户名或邮箱是否已存在 + if (await _userRepository.ExistsByUsernameOrEmailAsync(request.Username, request.Email)) + { + throw new InvalidOperationException("用户名或电子邮箱已被占用"); + } + + // 创建新用户 + var user = new User + { + Username = request.Username, + Email = request.Email, + PasswordHash = HashPassword(request.Password), // 假设有一个密码哈希方法 + Phone = request.Phone, + CreatedAt = DateTime.UtcNow + }; + + // 保存用户到存储 + await _userRepository.AddAsync(user); + + // 返回注册结果 + return new RegisterUserResult + { + Id = user.Id, + Username = user.Username, + Email = user.Email, + CreatedAt = user.CreatedAt + }; + } + + /// + /// 哈希密码(示例方法) + /// + /// 明文密码 + /// 哈希后的密码 + private string HashPassword(string password) + { + // 使用实际的密码哈希算法(如 BCrypt 或 PBKDF2) + return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(password)); + } + } + + /// + /// 用户存储仓库接口 + /// + public interface IUserRepository + { + Task ExistsByUsernameOrEmailAsync(string username, string email); + Task AddAsync(User user); + } + + /// + /// 用户实体 + /// + public class User + { + public int Id { get; set; } + public required string Username { get; set; } + public required string Email { get; set; } + public string PasswordHash { get; set; } + public string Phone { get; set; } + public DateTime CreatedAt { get; set; } + } +} \ No newline at end of file diff --git a/backend/BackOffice/BackOffice.Application/Services/RegisterUserCommand.cs b/backend/BackOffice/BackOffice.Application/Services/RegisterUserCommand.cs new file mode 100644 index 0000000..46a9943 --- /dev/null +++ b/backend/BackOffice/BackOffice.Application/Services/RegisterUserCommand.cs @@ -0,0 +1,68 @@ +// 用户注册命令 + +namespace BackOffice.Application.Commands.Users +{ + using MediatR; + using System; + using System.ComponentModel.DataAnnotations; + + /// + /// 用户注册命令 + /// + public class RegisterUserCommand : IRequest + { + /// + /// 用户名 + /// + [Required(ErrorMessage = "用户名是必填项")] + [StringLength(50, ErrorMessage = "用户名长度不能超过50个字符")] + public required string Username { get; set; } + + /// + /// 电子邮箱 + /// + [Required(ErrorMessage = "电子邮箱是必填项")] + [EmailAddress(ErrorMessage = "电子邮箱格式不正确")] + public required string Email { get; set; } + + /// + /// 密码 + /// + [Required(ErrorMessage = "密码是必填项")] + [StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度必须在6到100个字符之间")] + public required string Password { get; set; } + + /// + /// 手机号码 + /// + [Required(ErrorMessage = "手机号码是必填项")] + [Phone(ErrorMessage = "手机号码格式不正确")] + public required string Phone { get; set; } + } + + /// + /// 用户注册结果 + /// + public class RegisterUserResult + { + /// + /// 用户ID + /// + public int Id { get; set; } + + /// + /// 用户名 + /// + public required string Username { get; set; } + + /// + /// 电子邮箱 + /// + public required string Email { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } + } +} \ No newline at end of file diff --git a/backend/BackOffice/BackOffice.Infrastructure/Repositories/UserRepository.cs b/backend/BackOffice/BackOffice.Infrastructure/Repositories/UserRepository.cs new file mode 100644 index 0000000..aa66706 --- /dev/null +++ b/backend/BackOffice/BackOffice.Infrastructure/Repositories/UserRepository.cs @@ -0,0 +1,64 @@ +//用户存储仓库的实现类 + +using System.Linq; +using System.Threading.Tasks; +using BackOffice.Application.Handlers.Users; +using Microsoft.EntityFrameworkCore; + +namespace BackOffice.Infrastructure.Repositories +{ + /// + /// 用户存储仓库实现 + /// + public class UserRepository : IUserRepository + { + private readonly BackOfficeDbContext _dbContext; + + /// + /// 构造函数 + /// + /// 数据库上下文 + public UserRepository(BackOfficeDbContext dbContext) + { + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + } + + /// + /// 检查用户名或电子邮箱是否已存在 + /// + /// 用户名 + /// 电子邮箱 + /// 是否存在 + public async Task ExistsByUsernameOrEmailAsync(string username, string email) + { + return await _dbContext.Users + .AnyAsync(u => u.Username == username || u.Email == email); + } + + /// + /// 添加新用户 + /// + /// 用户实体 + /// 任务 + public async Task AddAsync(User user) + { + await _dbContext.Users.AddAsync(user); + await _dbContext.SaveChangesAsync(); + } + } + + /// + /// 数据库上下文 + /// + public class BackOfficeDbContext : DbContext + { + public BackOfficeDbContext(DbContextOptions options) : base(options) + { + } + + /// + /// 用户表 + /// + public DbSet Users { get; set; } + } +} \ No newline at end of file -- Gitee From 3630c45eb270222c36be5d54e3c4ff74c3095841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E6=96=8C?= <2463860418@qq.com> Date: Fri, 25 Jul 2025 10:49:13 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E5=89=8D=E7=AB=AF=E9=A1=B5=E9=9D=A2=E5=88=9D?= =?UTF-8?q?=E5=85=B7=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/BackOffice/mini-flow/src/main.js | 2 +- .../BackOffice/mini-flow/src/router/index.js | 12 + .../mini-flow/src/views/Gotopassword.vue | 2 +- .../mini-flow/src/views/Gotouser.vue | 2 +- .../mini-flow/src/views/LoginView.vue | 2 +- .../mini-flow/src/views/user/UserDialog.vue | 30 ++ .../mini-flow/src/views/user/UserList.vue | 337 ++++++++++++++++++ 7 files changed, 383 insertions(+), 4 deletions(-) create mode 100644 frontend/BackOffice/mini-flow/src/views/user/UserDialog.vue create mode 100644 frontend/BackOffice/mini-flow/src/views/user/UserList.vue diff --git a/frontend/BackOffice/mini-flow/src/main.js b/frontend/BackOffice/mini-flow/src/main.js index 8bb678b..6ec5e44 100644 --- a/frontend/BackOffice/mini-flow/src/main.js +++ b/frontend/BackOffice/mini-flow/src/main.js @@ -1,4 +1,4 @@ -import './assets/main.css' +// import './assets/main.css' import { createApp } from 'vue' import { createPinia } from 'pinia' diff --git a/frontend/BackOffice/mini-flow/src/router/index.js b/frontend/BackOffice/mini-flow/src/router/index.js index de26177..0ca5f28 100644 --- a/frontend/BackOffice/mini-flow/src/router/index.js +++ b/frontend/BackOffice/mini-flow/src/router/index.js @@ -2,6 +2,8 @@ import { createRouter, createWebHistory } from 'vue-router' import LoginView from '../views/LoginView.vue' import Gotopassword from '../views/Gotopassword.vue' import Gotouser from '../views/Gotouser.vue' +import UserList from '../views/user/UserList.vue' +import UserDialog from '../views/user/UserDialog.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -21,6 +23,16 @@ const router = createRouter({ name: 'Gotouser', component: Gotouser, }, + { + path: '/UserList', + name: 'UserList', + component: UserList, + }, + { + path: '/UserDialog', + name: 'UserDialog', + component: UserDialog, + }, ], }) diff --git a/frontend/BackOffice/mini-flow/src/views/Gotopassword.vue b/frontend/BackOffice/mini-flow/src/views/Gotopassword.vue index fa399ba..a61dfad 100644 --- a/frontend/BackOffice/mini-flow/src/views/Gotopassword.vue +++ b/frontend/BackOffice/mini-flow/src/views/Gotopassword.vue @@ -215,7 +215,7 @@ } .forgot-box { - width: 1200px; + width: 500px; padding: 350px; border-radius: 12px; } diff --git a/frontend/BackOffice/mini-flow/src/views/Gotouser.vue b/frontend/BackOffice/mini-flow/src/views/Gotouser.vue index d6ad491..3317253 100644 --- a/frontend/BackOffice/mini-flow/src/views/Gotouser.vue +++ b/frontend/BackOffice/mini-flow/src/views/Gotouser.vue @@ -193,7 +193,7 @@ } .register-box { - width: 1200px; + width: 500px; padding: 350px; border-radius: 12px; } diff --git a/frontend/BackOffice/mini-flow/src/views/LoginView.vue b/frontend/BackOffice/mini-flow/src/views/LoginView.vue index de103bd..4caeea8 100644 --- a/frontend/BackOffice/mini-flow/src/views/LoginView.vue +++ b/frontend/BackOffice/mini-flow/src/views/LoginView.vue @@ -251,7 +251,7 @@ const handleLogin = () => { setTimeout(() => { loading.value = false ElMessage.success('登录成功') - router.push('/') + router.push('/UserList') }, 1500) } diff --git a/frontend/BackOffice/mini-flow/src/views/user/UserDialog.vue b/frontend/BackOffice/mini-flow/src/views/user/UserDialog.vue new file mode 100644 index 0000000..9aa2607 --- /dev/null +++ b/frontend/BackOffice/mini-flow/src/views/user/UserDialog.vue @@ -0,0 +1,30 @@ + + \ No newline at end of file diff --git a/frontend/BackOffice/mini-flow/src/views/user/UserList.vue b/frontend/BackOffice/mini-flow/src/views/user/UserList.vue new file mode 100644 index 0000000..edb0fe8 --- /dev/null +++ b/frontend/BackOffice/mini-flow/src/views/user/UserList.vue @@ -0,0 +1,337 @@ + + + + + \ No newline at end of file -- Gitee