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
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,19 @@ public interface IUserBusinessService
|
||||||
Task<bool> UpdateUserLevelAsync(long id, int userLevel);
|
Task<bool> UpdateUserLevelAsync(long id, int userLevel);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>б<EFBFBD>
|
/// 导出用户列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"><EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
/// <param name="request">查询参数</param>
|
||||||
/// <returns><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></returns>
|
/// <returns>导出数据</returns>
|
||||||
Task<List<UserDto>> ExportUsersAsync(UserQueryRequest request);
|
Task<List<UserDto>> ExportUsersAsync(UserQueryRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除用户(硬删除,同时清除登录记录和令牌)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">用户ID</param>
|
||||||
|
/// <returns>是否成功</returns>
|
||||||
|
Task<bool> DeleteUserAsync(long id);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽӿ<EFBFBD> - <EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
#region ״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽӿ<EFBFBD> - <EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
||||||
|
|
|
||||||
|
|
@ -238,11 +238,53 @@ public class UserBusinessService : IUserBusinessService
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.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;
|
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
|
#endregion
|
||||||
|
|
||||||
#region <EFBFBD>ɽӿڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
#region <EFBFBD>ɽӿڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export interface UserItem {
|
||||||
nickname: string
|
nickname: string
|
||||||
/** 头像URL */
|
/** 头像URL */
|
||||||
avatar: string
|
avatar: string
|
||||||
/** 用户等级 (0: 普通用户, 1: VIP, 2: 分销商) */
|
/** 用户等级 (1: 普通用户, 2: 合伙人, 3: 渠道合伙人) */
|
||||||
userLevel: number
|
userLevel: number
|
||||||
/** 用户等级名称 */
|
/** 用户等级名称 */
|
||||||
userLevelName: string
|
userLevelName: string
|
||||||
|
|
@ -158,3 +158,16 @@ export function exportUsers(params: UserQuery): Promise<ApiResponse<Blob>> {
|
||||||
responseType: '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>
|
||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<el-table-column label="操作" width="150" fixed="right" align="center">
|
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
||||||
<el-icon><View /></el-icon>
|
<el-icon><View /></el-icon>
|
||||||
|
|
@ -167,6 +167,10 @@
|
||||||
<el-icon><Edit /></el-icon>
|
<el-icon><Edit /></el-icon>
|
||||||
等级
|
等级
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="danger" link size="small" @click="handleDelete(row)">
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -318,14 +322,15 @@
|
||||||
* @requirements 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7
|
* @requirements 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7
|
||||||
*/
|
*/
|
||||||
import { reactive, ref, onMounted } from 'vue'
|
import { reactive, ref, onMounted } from 'vue'
|
||||||
import { Search, Refresh, View, Edit, Download, User } from '@element-plus/icons-vue'
|
import { Search, Refresh, View, Edit, Download, User, Delete } from '@element-plus/icons-vue'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||||
import {
|
import {
|
||||||
getUserList,
|
getUserList,
|
||||||
getUserDetail,
|
getUserDetail,
|
||||||
updateUserStatus,
|
updateUserStatus,
|
||||||
updateUserLevel,
|
updateUserLevel,
|
||||||
exportUsers,
|
exportUsers,
|
||||||
|
deleteUser,
|
||||||
type UserItem,
|
type UserItem,
|
||||||
type UserDetail,
|
type UserDetail,
|
||||||
type UserQuery
|
type UserQuery
|
||||||
|
|
@ -336,9 +341,9 @@ import { DictSelect } from '@/components'
|
||||||
|
|
||||||
/** 用户等级枚举 */
|
/** 用户等级枚举 */
|
||||||
const USER_LEVEL = {
|
const USER_LEVEL = {
|
||||||
NORMAL: 0, // 普通用户
|
NORMAL: 1, // 普通用户
|
||||||
VIP: 1, // VIP
|
PARTNER: 2, // 合伙人
|
||||||
DISTRIBUTOR: 2 // 分销商
|
CHANNEL: 3 // 渠道合伙人
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
/** 用户状态枚举 */
|
/** 用户状态枚举 */
|
||||||
|
|
@ -455,9 +460,9 @@ function getLevelTagType(level: number): 'info' | 'success' | 'warning' | 'dange
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case USER_LEVEL.NORMAL:
|
case USER_LEVEL.NORMAL:
|
||||||
return 'info'
|
return 'info'
|
||||||
case USER_LEVEL.VIP:
|
case USER_LEVEL.PARTNER:
|
||||||
return 'success'
|
return 'success'
|
||||||
case USER_LEVEL.DISTRIBUTOR:
|
case USER_LEVEL.CHANNEL:
|
||||||
return 'warning'
|
return 'warning'
|
||||||
default:
|
default:
|
||||||
return 'info'
|
return 'info'
|
||||||
|
|
@ -468,10 +473,10 @@ function getLevelName(level: number): string {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case USER_LEVEL.NORMAL:
|
case USER_LEVEL.NORMAL:
|
||||||
return '普通用户'
|
return '普通用户'
|
||||||
case USER_LEVEL.VIP:
|
case USER_LEVEL.PARTNER:
|
||||||
return 'VIP'
|
return '合伙人'
|
||||||
case USER_LEVEL.DISTRIBUTOR:
|
case USER_LEVEL.CHANNEL:
|
||||||
return '分销商'
|
return '渠道合伙人'
|
||||||
default:
|
default:
|
||||||
return '未知'
|
return '未知'
|
||||||
}
|
}
|
||||||
|
|
@ -623,6 +628,35 @@ function handleChangeLevel(row: UserItem) {
|
||||||
state.levelDialogVisible = true
|
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() {
|
async function handleLevelSubmit() {
|
||||||
if (!levelFormRef.value) return
|
if (!levelFormRef.value) return
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user