fix(user): 修复用户等级显示乱码,添加删除用户功能
- 修正用户等级常量:1=普通用户, 2=合伙人, 3=渠道合伙人 - 添加删除用户接口(硬删除),同时清除 user_refresh_tokens 和 user_login_logs - 前端添加删除按钮和确认对话框
This commit is contained in:
parent
795e5586ac
commit
26902724c8
|
|
@ -149,5 +149,34 @@ public class UserController : BusinessControllerBase
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户(硬删除,同时清除登录记录和令牌)
|
||||
/// </summary>
|
||||
/// <param name="request">删除请求</param>
|
||||
/// <returns>操作结果</returns>
|
||||
[HttpPost("delete")]
|
||||
[BusinessPermission("user:delete")]
|
||||
public async Task<IActionResult> 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,12 +52,19 @@ public interface IUserBusinessService
|
|||
Task<bool> UpdateUserLevelAsync(long id, int userLevel);
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>б<EFBFBD>
|
||||
/// 导出用户列表
|
||||
/// </summary>
|
||||
/// <param name="request"><EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||
/// <returns><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
||||
/// <param name="request">查询参数</param>
|
||||
/// <returns>导出数据</returns>
|
||||
Task<List<UserDto>> ExportUsersAsync(UserQueryRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户(硬删除,同时清除登录记录和令牌)
|
||||
/// </summary>
|
||||
/// <param name="id">用户ID</param>
|
||||
/// <returns>是否成功</returns>
|
||||
Task<bool> DeleteUserAsync(long id);
|
||||
|
||||
#endregion
|
||||
|
||||
#region ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽӿ<EFBFBD> - <EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
||||
|
|
|
|||
|
|
@ -238,11 +238,53 @@ public class UserBusinessService : IUserBusinessService
|
|||
})
|
||||
.ToListAsync();
|
||||
|
||||
_logger.LogInformation("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: {Count}", items.Count);
|
||||
_logger.LogInformation("导出用户列表成功,数量: {Count}", items.Count);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> 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 <EFBFBD>ɽӿڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
||||
|
|
|
|||
|
|
@ -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<ApiResponse<Blob>> {
|
|||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户(硬删除,同时清除登录记录和令牌)
|
||||
* @param id 用户ID
|
||||
* @returns 删除结果
|
||||
*/
|
||||
export function deleteUser(id: number): Promise<ApiResponse<boolean>> {
|
||||
return request<boolean>({
|
||||
url: '/admin/user/delete',
|
||||
method: 'post',
|
||||
data: { id }
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@
|
|||
</el-table-column>
|
||||
|
||||
<!-- 操作 -->
|
||||
<el-table-column label="操作" width="150" fixed="right" align="center">
|
||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
||||
<el-icon><View /></el-icon>
|
||||
|
|
@ -167,6 +167,10 @@
|
|||
<el-icon><Edit /></el-icon>
|
||||
等级
|
||||
</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user