This commit is contained in:
parent
262de67a8e
commit
8ae6dcfa88
|
|
@ -1,4 +1,4 @@
|
|||
using MiAssessment.Admin.Business.Attributes;
|
||||
using MiAssessment.Admin.Business.Attributes;
|
||||
using MiAssessment.Admin.Business.Models;
|
||||
using MiAssessment.Admin.Business.Models.Common;
|
||||
using MiAssessment.Admin.Business.Models.User;
|
||||
|
|
@ -129,6 +129,64 @@ public class UserController : BusinessControllerBase
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定上下级关系(渠道商-合伙人)
|
||||
/// </summary>
|
||||
/// <param name="request">绑定请求</param>
|
||||
/// <returns>操作结果</returns>
|
||||
[HttpPost("bindParent")]
|
||||
[BusinessPermission("user:update")]
|
||||
public async Task<IActionResult> BindParentUser([FromBody] BindParentUserRequest request)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return ValidationError("参数验证失败");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _userService.BindParentUserAsync(request.UserId, request.ParentUserId);
|
||||
if (result)
|
||||
{
|
||||
return Ok("绑定上下级关系成功");
|
||||
}
|
||||
return Error(ErrorCodes.BusinessError, "绑定失败");
|
||||
}
|
||||
catch (BusinessException ex)
|
||||
{
|
||||
return Error(ex.Code, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解除上下级关系
|
||||
/// </summary>
|
||||
/// <param name="request">请求(包含用户ID)</param>
|
||||
/// <returns>操作结果</returns>
|
||||
[HttpPost("unbindParent")]
|
||||
[BusinessPermission("user:update")]
|
||||
public async Task<IActionResult> UnbindParentUser([FromBody] DeleteRequest request)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return ValidationError("参数验证失败");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _userService.UnbindParentUserAsync(request.Id);
|
||||
if (result)
|
||||
{
|
||||
return Ok("解除上下级关系成功");
|
||||
}
|
||||
return Error(ErrorCodes.BusinessError, "解除失败");
|
||||
}
|
||||
catch (BusinessException ex)
|
||||
{
|
||||
return Error(ex.Code, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出用户列表
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -182,6 +182,11 @@ public static class ErrorCodes
|
|||
/// </summary>
|
||||
public const int UserNotFound = 3301;
|
||||
|
||||
/// <summary>
|
||||
/// 上级用户不存在
|
||||
/// </summary>
|
||||
public const int ParentUserNotFound = 3302;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 订单模块错误 (3400-3499)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MiAssessment.Admin.Business.Models.User;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定上下级关系请求
|
||||
/// </summary>
|
||||
public class BindParentUserRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 下级用户ID(合伙人)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上级用户ID(渠道商)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public long ParentUserId { get; set; }
|
||||
}
|
||||
|
|
@ -58,6 +58,21 @@ public interface IUserBusinessService
|
|||
/// <returns>导出数据</returns>
|
||||
Task<List<UserDto>> ExportUsersAsync(UserQueryRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 绑定上下级关系(上级必须是渠道商,下级必须是合伙人)
|
||||
/// </summary>
|
||||
/// <param name="userId">下级用户ID(合伙人)</param>
|
||||
/// <param name="parentUserId">上级用户ID(渠道商)</param>
|
||||
/// <returns>是否成功</returns>
|
||||
Task<bool> BindParentUserAsync(long userId, long parentUserId);
|
||||
|
||||
/// <summary>
|
||||
/// 解除上下级关系
|
||||
/// </summary>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>是否成功</returns>
|
||||
Task<bool> UnbindParentUserAsync(long userId);
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户(硬删除,同时清除登录记录和令牌)
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -211,12 +211,143 @@ public class UserBusinessService : IUserBusinessService
|
|||
throw new BusinessException(ErrorCodes.UserNotFound, "用户不存在");
|
||||
}
|
||||
|
||||
if (userLevel < 1 || userLevel > 3)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.ParamError, "无效的用户等级");
|
||||
}
|
||||
|
||||
var oldLevel = user.UserLevel;
|
||||
user.UserLevel = userLevel;
|
||||
user.UpdateTime = DateTime.Now;
|
||||
|
||||
// 等级变更时自动处理上下级关系
|
||||
if (user.ParentUserId.HasValue && oldLevel != userLevel)
|
||||
{
|
||||
var shouldUnbind = await ShouldUnbindParentOnLevelChange(user.ParentUserId.Value, userLevel);
|
||||
if (shouldUnbind)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"用户 {UserId} 等级从 {OldLevel} 变更为 {NewLevel},自动解除与上级 {ParentUserId} 的关系",
|
||||
id, oldLevel, userLevel, user.ParentUserId.Value);
|
||||
user.ParentUserId = null;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("更新用户等级成功,ID: {UserId}, 等级: {OldLevel} -> {UserLevel}", id, oldLevel, userLevel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断等级变更时是否需要解除与上级的关系
|
||||
/// 规则:
|
||||
/// - 提升为渠道商(3):一律解除上下级关系
|
||||
/// - 提升为合伙人(2):仅当上级是渠道商(3)时保留,否则解除
|
||||
/// - 变为普通用户(1):保留原有关系不变
|
||||
/// </summary>
|
||||
private async Task<bool> ShouldUnbindParentOnLevelChange(long parentUserId, int newLevel)
|
||||
{
|
||||
if (newLevel == 3)
|
||||
return true;
|
||||
|
||||
if (newLevel == 2)
|
||||
{
|
||||
var parentLevel = await _dbContext.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Id == parentUserId && !u.IsDeleted)
|
||||
.Select(u => u.UserLevel)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return parentLevel != 3;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> BindParentUserAsync(long userId, long parentUserId)
|
||||
{
|
||||
if (userId == parentUserId)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "不能绑定自己为上级");
|
||||
}
|
||||
|
||||
var user = await _dbContext.Users
|
||||
.Where(u => u.Id == userId && !u.IsDeleted)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.UserNotFound, "用户不存在");
|
||||
}
|
||||
|
||||
var parentUser = await _dbContext.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Id == parentUserId && !u.IsDeleted)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (parentUser == null)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.ParentUserNotFound, "上级用户不存在");
|
||||
}
|
||||
|
||||
if (parentUser.UserLevel != 3)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "上级用户必须是渠道商");
|
||||
}
|
||||
|
||||
if (user.UserLevel != 2)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "只有合伙人才能绑定上级渠道商");
|
||||
}
|
||||
|
||||
if (user.ParentUserId.HasValue)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "该用户已有上级,请先解除现有上下级关系");
|
||||
}
|
||||
|
||||
// 防止循环引用:检查上级的上级是否是当前用户
|
||||
if (parentUser.ParentUserId == userId)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "不能形成循环上下级关系");
|
||||
}
|
||||
|
||||
user.ParentUserId = parentUserId;
|
||||
user.UpdateTime = DateTime.Now;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("更新用户等级成功,ID: {UserId}, 等级: {UserLevel}", id, userLevel);
|
||||
_logger.LogInformation("绑定上下级关系成功,用户 {UserId} 的上级设为 {ParentUserId}", userId, parentUserId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> UnbindParentUserAsync(long userId)
|
||||
{
|
||||
var user = await _dbContext.Users
|
||||
.Where(u => u.Id == userId && !u.IsDeleted)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.UserNotFound, "用户不存在");
|
||||
}
|
||||
|
||||
if (!user.ParentUserId.HasValue)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidOperation, "该用户没有上级,无需解除");
|
||||
}
|
||||
|
||||
var oldParentId = user.ParentUserId.Value;
|
||||
user.ParentUserId = null;
|
||||
user.UpdateTime = DateTime.Now;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("解除上下级关系成功,用户 {UserId} 与上级 {ParentUserId} 解绑", userId, oldParentId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,16 @@ export interface UpdateUserLevelRequest {
|
|||
userLevel: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定上下级关系请求
|
||||
*/
|
||||
export interface BindParentUserRequest {
|
||||
/** 下级用户ID(合伙人) */
|
||||
userId: number
|
||||
/** 上级用户ID(渠道商) */
|
||||
parentUserId: number
|
||||
}
|
||||
|
||||
// ==================== User API ====================
|
||||
|
||||
/**
|
||||
|
|
@ -161,6 +171,32 @@ export function exportUsers(params: UserQuery): Promise<ApiResponse<Blob>> {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定上下级关系(渠道商-合伙人)
|
||||
* @param data 绑定请求
|
||||
* @returns 绑定结果
|
||||
*/
|
||||
export function bindParentUser(data: BindParentUserRequest): Promise<ApiResponse<boolean>> {
|
||||
return request<boolean>({
|
||||
url: '/admin/user/bindParent',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除上下级关系
|
||||
* @param id 用户ID
|
||||
* @returns 解除结果
|
||||
*/
|
||||
export function unbindParentUser(id: number): Promise<ApiResponse<boolean>> {
|
||||
return request<boolean>({
|
||||
url: '/admin/user/unbindParent',
|
||||
method: 'post',
|
||||
data: { id }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户(硬删除,同时清除登录记录和令牌)
|
||||
* @param id 用户ID
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@
|
|||
</el-table-column>
|
||||
|
||||
<!-- 操作 -->
|
||||
<el-table-column label="操作" width="250" fixed="right" align="center">
|
||||
<el-table-column label="操作" width="320" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
||||
<el-icon><View /></el-icon>
|
||||
|
|
@ -175,6 +175,10 @@
|
|||
<el-icon><Edit /></el-icon>
|
||||
等级
|
||||
</el-button>
|
||||
<el-button type="success" link size="small" @click="handleBindParent(row)">
|
||||
<el-icon><Link /></el-icon>
|
||||
上级
|
||||
</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
删除
|
||||
|
|
@ -246,6 +250,24 @@
|
|||
{{ state.userDetail.parentUserNickname || '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-button
|
||||
v-if="state.userDetail.parentUserId"
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDetailUnbind"
|
||||
>
|
||||
解除上级关系
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else-if="state.userDetail.userLevel === USER_LEVEL.PARTNER"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleBindParent(state.userDetail)"
|
||||
>
|
||||
绑定上级渠道商
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 财务信息 -->
|
||||
|
|
@ -348,7 +370,7 @@
|
|||
<el-dialog
|
||||
v-model="state.levelDialogVisible"
|
||||
title="修改用户等级"
|
||||
width="400px"
|
||||
width="460px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form
|
||||
|
|
@ -371,6 +393,14 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-alert
|
||||
v-if="levelChangeWarning"
|
||||
:title="levelChangeWarning"
|
||||
type="warning"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="margin-top: 8px;"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="state.levelDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="state.levelFormLoading" @click="handleLevelSubmit">
|
||||
|
|
@ -378,6 +408,74 @@
|
|||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 绑定上级对话框 -->
|
||||
<el-dialog
|
||||
v-model="state.bindDialogVisible"
|
||||
title="管理上级关系"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<div class="bind-info">
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="当前用户">
|
||||
{{ state.bindFormData.userNickname }}({{ state.bindFormData.userUid }})
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户等级">
|
||||
<el-tag :type="getLevelTagType(state.bindFormData.userLevel)">
|
||||
{{ getLevelName(state.bindFormData.userLevel) }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="当前上级">
|
||||
<template v-if="state.bindFormData.currentParentNickname">
|
||||
{{ state.bindFormData.currentParentNickname }}({{ state.bindFormData.currentParentUid }})
|
||||
<el-button type="danger" link size="small" @click="handleUnbindParent" :loading="state.bindFormLoading" style="margin-left: 8px;">
|
||||
解除关系
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-else class="no-parent">暂无上级</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<template v-if="!state.bindFormData.currentParentNickname">
|
||||
<el-alert
|
||||
v-if="state.bindFormData.userLevel !== USER_LEVEL.PARTNER"
|
||||
title="只有合伙人才能绑定上级渠道商"
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="margin-bottom: 16px;"
|
||||
/>
|
||||
<el-form
|
||||
v-else
|
||||
ref="bindFormRef"
|
||||
:model="state.bindFormData"
|
||||
:rules="bindFormRules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="上级渠道商" prop="parentUid">
|
||||
<el-input
|
||||
v-model="state.bindFormData.parentUid"
|
||||
placeholder="请输入渠道商的UID"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="state.bindFormLoading" @click="handleBindSubmit">
|
||||
确认绑定
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="state.bindDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -387,8 +485,8 @@
|
|||
* @description 管理C端用户信息,支持搜索、查看详情、状态管理、等级修改、导出
|
||||
* @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, Delete } from '@element-plus/icons-vue'
|
||||
import { reactive, ref, computed, onMounted } from 'vue'
|
||||
import { Search, Refresh, View, Edit, Download, User, Delete, Link } from '@element-plus/icons-vue'
|
||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||
import {
|
||||
getUserList,
|
||||
|
|
@ -397,6 +495,8 @@ import {
|
|||
updateUserLevel,
|
||||
exportUsers,
|
||||
deleteUser,
|
||||
bindParentUser,
|
||||
unbindParentUser,
|
||||
type UserItem,
|
||||
type UserDetail,
|
||||
type UserQuery
|
||||
|
|
@ -461,6 +561,16 @@ interface LevelFormData {
|
|||
userLevel: string
|
||||
}
|
||||
|
||||
interface BindFormData {
|
||||
userId: number
|
||||
userNickname: string
|
||||
userUid: string
|
||||
userLevel: number
|
||||
currentParentNickname: string
|
||||
currentParentUid: string
|
||||
parentUid: string
|
||||
}
|
||||
|
||||
interface UserPageState {
|
||||
loading: boolean
|
||||
tableData: UserItemWithLoading[]
|
||||
|
|
@ -481,12 +591,16 @@ interface UserPageState {
|
|||
subParentId: number
|
||||
subParentNickname: string
|
||||
subParentUid: string
|
||||
bindDialogVisible: boolean
|
||||
bindFormData: BindFormData
|
||||
bindFormLoading: boolean
|
||||
}
|
||||
|
||||
// ============ Refs ============
|
||||
|
||||
const tableRef = ref<InstanceType<typeof import('element-plus')['ElTable']>>()
|
||||
const levelFormRef = ref<FormInstance>()
|
||||
const bindFormRef = ref<FormInstance>()
|
||||
const dateRange = ref<[string, string] | null>(null)
|
||||
|
||||
// ============ State ============
|
||||
|
|
@ -527,7 +641,18 @@ const state = reactive<UserPageState>({
|
|||
subPageSize: 10,
|
||||
subParentId: 0,
|
||||
subParentNickname: '',
|
||||
subParentUid: ''
|
||||
subParentUid: '',
|
||||
bindDialogVisible: false,
|
||||
bindFormData: {
|
||||
userId: 0,
|
||||
userNickname: '',
|
||||
userUid: '',
|
||||
userLevel: 0,
|
||||
currentParentNickname: '',
|
||||
currentParentUid: '',
|
||||
parentUid: ''
|
||||
},
|
||||
bindFormLoading: false
|
||||
})
|
||||
|
||||
// ============ Form Rules ============
|
||||
|
|
@ -538,6 +663,26 @@ const levelFormRules: FormRules = {
|
|||
]
|
||||
}
|
||||
|
||||
const bindFormRules: FormRules = {
|
||||
parentUid: [
|
||||
{ required: true, message: '请输入渠道商的UID', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
const levelChangeWarning = computed(() => {
|
||||
const newLevel = Number(state.levelFormData.userLevel)
|
||||
const currentLevel = state.levelFormData.currentLevel
|
||||
if (!newLevel || newLevel === currentLevel) return ''
|
||||
|
||||
if (newLevel === USER_LEVEL.CHANNEL) {
|
||||
return '提升为渠道商后,该用户与其上级的关系将自动解除'
|
||||
}
|
||||
if (newLevel === USER_LEVEL.PARTNER && currentLevel === USER_LEVEL.NORMAL) {
|
||||
return '提升为合伙人后,仅当上级是渠道商时保留上下级关系,否则自动解除'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
// ============ Helper Functions ============
|
||||
|
||||
function getLevelTagType(level: number): 'info' | 'success' | 'warning' | 'danger' {
|
||||
|
|
@ -802,6 +947,141 @@ async function handleLevelSubmit() {
|
|||
}
|
||||
}
|
||||
|
||||
async function handleDetailUnbind() {
|
||||
if (!state.userDetail) return
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认解除 "${state.userDetail.nickname}" 与上级 "${state.userDetail.parentUserNickname}" 的关系吗?`,
|
||||
'解除确认',
|
||||
{ confirmButtonText: '确认解除', cancelButtonText: '取消', type: 'warning' }
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await unbindParentUser(state.userDetail.id)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('解除上下级关系成功')
|
||||
await loadUserDetail(state.userDetail.id)
|
||||
await loadUserList()
|
||||
} else {
|
||||
throw new Error(res.message || '解除失败')
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : '解除失败'
|
||||
ElMessage.error(message)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBindParent(row: UserItem) {
|
||||
state.bindFormData = {
|
||||
userId: row.id,
|
||||
userNickname: row.nickname,
|
||||
userUid: row.uid,
|
||||
userLevel: row.userLevel,
|
||||
currentParentNickname: '',
|
||||
currentParentUid: '',
|
||||
parentUid: ''
|
||||
}
|
||||
|
||||
// 获取用户详情以了解当前上级
|
||||
try {
|
||||
const res = await getUserDetail(row.id)
|
||||
if (res.code === 0 && res.data) {
|
||||
state.bindFormData.currentParentNickname = res.data.parentUserNickname || ''
|
||||
state.bindFormData.currentParentUid = res.data.parentUserUid || ''
|
||||
state.bindFormData.userLevel = res.data.userLevel
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
state.bindDialogVisible = true
|
||||
}
|
||||
|
||||
async function handleBindSubmit() {
|
||||
if (!bindFormRef.value) return
|
||||
try {
|
||||
await bindFormRef.value.validate()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
// 先通过 UID 查找渠道商用户
|
||||
state.bindFormLoading = true
|
||||
try {
|
||||
const searchRes = await getUserList({
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
uid: state.bindFormData.parentUid,
|
||||
userLevel: USER_LEVEL.CHANNEL
|
||||
})
|
||||
|
||||
if (searchRes.code !== 0 || !searchRes.data?.list?.length) {
|
||||
ElMessage.error('未找到该UID对应的渠道商用户,请确认UID是否正确')
|
||||
return
|
||||
}
|
||||
|
||||
const parentUser = searchRes.data.list[0]
|
||||
|
||||
await ElMessageBox.confirm(
|
||||
`确认将 "${state.bindFormData.userNickname}" 绑定到渠道商 "${parentUser.nickname}"(${parentUser.uid})下吗?`,
|
||||
'绑定确认',
|
||||
{ confirmButtonText: '确认绑定', cancelButtonText: '取消', type: 'warning' }
|
||||
)
|
||||
|
||||
const res = await bindParentUser({
|
||||
userId: state.bindFormData.userId,
|
||||
parentUserId: parentUser.id
|
||||
})
|
||||
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('绑定上下级关系成功')
|
||||
state.bindDialogVisible = false
|
||||
await loadUserList()
|
||||
} else {
|
||||
throw new Error(res.message || '绑定失败')
|
||||
}
|
||||
} catch (error) {
|
||||
if (error === 'cancel' || (error instanceof Object && 'action' in error)) return
|
||||
const message = error instanceof Error ? error.message : '绑定失败'
|
||||
ElMessage.error(message)
|
||||
} finally {
|
||||
state.bindFormLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUnbindParent() {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确认解除 "${state.bindFormData.userNickname}" 与上级 "${state.bindFormData.currentParentNickname}" 的关系吗?`,
|
||||
'解除确认',
|
||||
{ confirmButtonText: '确认解除', cancelButtonText: '取消', type: 'warning' }
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
state.bindFormLoading = true
|
||||
try {
|
||||
const res = await unbindParentUser(state.bindFormData.userId)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('解除上下级关系成功')
|
||||
state.bindDialogVisible = false
|
||||
await loadUserList()
|
||||
} else {
|
||||
throw new Error(res.message || '解除失败')
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : '解除失败'
|
||||
ElMessage.error(message)
|
||||
} finally {
|
||||
state.bindFormLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
state.exportLoading = true
|
||||
try {
|
||||
|
|
@ -1007,4 +1287,12 @@ onMounted(() => {
|
|||
:deep(.el-descriptions) {
|
||||
--el-descriptions-item-bordered-label-background: var(--bg-light, #f5f7fa);
|
||||
}
|
||||
|
||||
.bind-info {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.no-parent {
|
||||
color: var(--text-secondary, #909399);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user