diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs index b3e15d6..641f098 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs @@ -149,5 +149,34 @@ public class UserController : BusinessControllerBase } } + /// + /// 删除用户(硬删除,同时清除登录记录和令牌) + /// + /// 删除请求 + /// 操作结果 + [HttpPost("delete")] + [BusinessPermission("user:delete")] + public async Task Delete([FromBody] DeleteRequest request) + { + if (!ModelState.IsValid) + { + return ValidationError("参数验证失败"); + } + + try + { + var result = await _userService.DeleteUserAsync(request.Id); + if (result) + { + return Ok("用户删除成功"); + } + return Error(ErrorCodes.UserNotFound, "用户不存在"); + } + catch (BusinessException ex) + { + return Error(ex.Code, ex.Message); + } + } + #endregion } diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IUserBusinessService.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IUserBusinessService.cs index d31f682..8fe213f 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IUserBusinessService.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IUserBusinessService.cs @@ -52,12 +52,19 @@ public interface IUserBusinessService Task UpdateUserLevelAsync(long id, int userLevel); /// - /// �����û��б� + /// 导出用户列表 /// - /// ��ѯ���� - /// �������� + /// 查询参数 + /// 导出数据 Task> ExportUsersAsync(UserQueryRequest request); + /// + /// 删除用户(硬删除,同时清除登录记录和令牌) + /// + /// 用户ID + /// 是否成功 + Task DeleteUserAsync(long id); + #endregion #region ״̬�������ɽӿ� - ���ݣ� diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/UserBusinessService.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/UserBusinessService.cs index cd2d885..985a947 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/UserBusinessService.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/UserBusinessService.cs @@ -238,11 +238,53 @@ public class UserBusinessService : IUserBusinessService }) .ToListAsync(); - _logger.LogInformation("�����û��б��ɹ�������: {Count}", items.Count); + _logger.LogInformation("导出用户列表成功,数量: {Count}", items.Count); return items; } + /// + public async Task DeleteUserAsync(long id) + { + var user = await _dbContext.Users + .Where(u => u.Id == id) + .FirstOrDefaultAsync(); + + if (user == null) + { + throw new BusinessException(ErrorCodes.UserNotFound, "用户不存在"); + } + + // 使用事务确保数据一致性 + using var transaction = await _dbContext.Database.BeginTransactionAsync(); + try + { + // 删除用户刷新令牌 + await _dbContext.Database.ExecuteSqlRawAsync( + "DELETE FROM user_refresh_tokens WHERE UserId = {0}", id); + + // 删除用户登录日志 + await _dbContext.Database.ExecuteSqlRawAsync( + "DELETE FROM user_login_logs WHERE UserId = {0}", id); + + // 删除用户记录(硬删除) + _dbContext.Users.Remove(user); + await _dbContext.SaveChangesAsync(); + + await transaction.CommitAsync(); + + _logger.LogInformation("删除用户成功,ID: {UserId}, UID: {Uid}", id, user.Uid); + + return true; + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + _logger.LogError(ex, "删除用户失败,ID: {UserId}", id); + throw; + } + } + #endregion #region �ɽӿڣ����ݣ� diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/user.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/user.ts index 328de50..eb29000 100644 --- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/user.ts +++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/user.ts @@ -23,7 +23,7 @@ export interface UserItem { nickname: string /** 头像URL */ avatar: string - /** 用户等级 (0: 普通用户, 1: VIP, 2: 分销商) */ + /** 用户等级 (1: 普通用户, 2: 合伙人, 3: 渠道合伙人) */ userLevel: number /** 用户等级名称 */ userLevelName: string @@ -158,3 +158,16 @@ export function exportUsers(params: UserQuery): Promise> { responseType: 'blob' }) } + +/** + * 删除用户(硬删除,同时清除登录记录和令牌) + * @param id 用户ID + * @returns 删除结果 + */ +export function deleteUser(id: number): Promise> { + return request({ + url: '/admin/user/delete', + method: 'post', + data: { id } + }) +} diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/user/index.vue b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/user/index.vue index 8df96e2..028bcb1 100644 --- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/user/index.vue +++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/user/index.vue @@ -157,7 +157,7 @@ - + @@ -318,14 +322,15 @@ * @requirements 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7 */ import { reactive, ref, onMounted } from 'vue' -import { Search, Refresh, View, Edit, Download, User } from '@element-plus/icons-vue' -import { ElMessage, type FormInstance, type FormRules } from 'element-plus' +import { Search, Refresh, View, Edit, Download, User, Delete } from '@element-plus/icons-vue' +import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus' import { getUserList, getUserDetail, updateUserStatus, updateUserLevel, exportUsers, + deleteUser, type UserItem, type UserDetail, type UserQuery @@ -336,9 +341,9 @@ import { DictSelect } from '@/components' /** 用户等级枚举 */ const USER_LEVEL = { - NORMAL: 0, // 普通用户 - VIP: 1, // VIP - DISTRIBUTOR: 2 // 分销商 + NORMAL: 1, // 普通用户 + PARTNER: 2, // 合伙人 + CHANNEL: 3 // 渠道合伙人 } as const /** 用户状态枚举 */ @@ -455,9 +460,9 @@ function getLevelTagType(level: number): 'info' | 'success' | 'warning' | 'dange switch (level) { case USER_LEVEL.NORMAL: return 'info' - case USER_LEVEL.VIP: + case USER_LEVEL.PARTNER: return 'success' - case USER_LEVEL.DISTRIBUTOR: + case USER_LEVEL.CHANNEL: return 'warning' default: return 'info' @@ -468,10 +473,10 @@ function getLevelName(level: number): string { switch (level) { case USER_LEVEL.NORMAL: return '普通用户' - case USER_LEVEL.VIP: - return 'VIP' - case USER_LEVEL.DISTRIBUTOR: - return '分销商' + case USER_LEVEL.PARTNER: + return '合伙人' + case USER_LEVEL.CHANNEL: + return '渠道合伙人' default: return '未知' } @@ -623,6 +628,35 @@ function handleChangeLevel(row: UserItem) { state.levelDialogVisible = true } +async function handleDelete(row: UserItem) { + try { + await ElMessageBox.confirm( + `确定要删除用户 "${row.nickname}"(UID: ${row.uid})吗?删除后将同时清除该用户的登录记录和令牌数据,此操作不可恢复。`, + '删除确认', + { + confirmButtonText: '确定删除', + cancelButtonText: '取消', + type: 'warning' + } + ) + } catch { + return + } + + try { + const res = await deleteUser(row.id) + if (res.code === 0) { + ElMessage.success('用户删除成功') + await loadUserList() + } else { + throw new Error(res.message || '删除失败') + } + } catch (error) { + const message = error instanceof Error ? error.message : '删除失败' + ElMessage.error(message) + } +} + async function handleLevelSubmit() { if (!levelFormRef.value) return