2026-04-10 16:30:42 +08:00
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
/**
|
2026-04-15 20:46:07 +08:00
|
|
|
|
* 用户汇报关系操作对话框
|
2026-04-10 16:30:42 +08:00
|
|
|
|
*
|
|
|
|
|
|
* 功能说明:
|
2026-04-15 20:46:07 +08:00
|
|
|
|
* - 新增用户汇报关系
|
|
|
|
|
|
* - 编辑用户汇报关系
|
2026-04-10 16:30:42 +08:00
|
|
|
|
* - 表单验证和提交
|
|
|
|
|
|
*
|
|
|
|
|
|
* 表单字段:
|
|
|
|
|
|
* - 管理者用户:必填,下拉选择,默认当前登录用户
|
|
|
|
|
|
* - 被管理用户:必填,下拉选择,默认空
|
|
|
|
|
|
* - 生效开始时间:可选
|
|
|
|
|
|
* - 生效结束时间:可选
|
|
|
|
|
|
* - 备注:可选
|
|
|
|
|
|
*
|
|
|
|
|
|
* 用户列表通过 props 传入,由父组件统一管理
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import { computed, nextTick, ref, watch } from 'vue';
|
|
|
|
|
|
import {
|
|
|
|
|
|
fetchCreateUserManagementRelation,
|
|
|
|
|
|
fetchGetUserManagementRelation,
|
|
|
|
|
|
fetchUpdateUserManagementRelation
|
|
|
|
|
|
} from '@/service/api';
|
|
|
|
|
|
import { useAuthStore } from '@/store/modules/auth';
|
|
|
|
|
|
import { useForm, useFormRules } from '@/hooks/common/form';
|
|
|
|
|
|
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
|
|
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'RelationOperateDialog' });
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件 Props 定义
|
|
|
|
|
|
*/
|
|
|
|
|
|
interface Props {
|
|
|
|
|
|
/** 操作类型:新增或编辑 */
|
|
|
|
|
|
operateType: UI.TableOperateType;
|
|
|
|
|
|
/** 编辑时的行数据 */
|
|
|
|
|
|
rowData?: Api.SystemManage.UserManagementRelation | null;
|
|
|
|
|
|
/** 用户列表,由父组件统一提供 */
|
|
|
|
|
|
userList: Api.SystemManage.UserSimple[];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件 Emits 定义
|
|
|
|
|
|
*
|
|
|
|
|
|
* 使用 Vue 3.5 标准语法
|
|
|
|
|
|
*/
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
|
/** 提交事件:返回提交后的关系 ID */
|
|
|
|
|
|
submitted: [relationId: number];
|
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 对话框可见性,支持 v-model 双向绑定
|
|
|
|
|
|
*/
|
|
|
|
|
|
const visible = defineModel<boolean>('visible', {
|
|
|
|
|
|
default: false
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 表单相关
|
|
|
|
|
|
const { formRef, validate } = useForm();
|
|
|
|
|
|
const { createRequiredRule } = useFormRules();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前登录用户信息
|
|
|
|
|
|
const authStore = useAuthStore();
|
|
|
|
|
|
|
|
|
|
|
|
// 加载和提交状态
|
|
|
|
|
|
const detailLoading = ref(false);
|
|
|
|
|
|
const submitting = ref(false);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算属性:是否为编辑模式
|
|
|
|
|
|
const isEdit = computed(() => props.operateType === 'edit');
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 计算对话框标题
|
|
|
|
|
|
*/
|
|
|
|
|
|
const title = computed(() => {
|
|
|
|
|
|
const titleMap: Record<UI.TableOperateType, string> = {
|
2026-04-15 20:46:07 +08:00
|
|
|
|
add: '新增用户汇报关系',
|
|
|
|
|
|
edit: '编辑用户汇报关系'
|
2026-04-10 16:30:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return titleMap[props.operateType];
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 表单模型类型
|
|
|
|
|
|
*/
|
|
|
|
|
|
type Model = Api.SystemManage.UserManagementRelationSaveReqVO;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 表单模型
|
|
|
|
|
|
*/
|
|
|
|
|
|
const model = ref(createDefaultModel());
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建默认表单模型
|
|
|
|
|
|
*
|
|
|
|
|
|
* @returns 默认模型对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
function createDefaultModel(): Model {
|
|
|
|
|
|
return {
|
|
|
|
|
|
managerUserId: null,
|
|
|
|
|
|
subordinateUserId: null,
|
|
|
|
|
|
effectiveFrom: null,
|
|
|
|
|
|
effectiveUntil: null,
|
|
|
|
|
|
remark: null
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 表单验证规则
|
|
|
|
|
|
*/
|
|
|
|
|
|
const rules = {
|
|
|
|
|
|
managerUserId: createRequiredRule('请选择管理者用户'),
|
|
|
|
|
|
subordinateUserId: createRequiredRule('请选择被管理用户')
|
|
|
|
|
|
} satisfies Record<string, App.Global.FormRule>;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 关闭对话框
|
|
|
|
|
|
*/
|
|
|
|
|
|
function closeModal() {
|
|
|
|
|
|
visible.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化表单模型
|
|
|
|
|
|
*
|
|
|
|
|
|
* 编辑模式下加载详情数据,新增模式下设置默认值
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function initModel() {
|
|
|
|
|
|
model.value = createDefaultModel();
|
|
|
|
|
|
|
|
|
|
|
|
if (!isEdit.value) {
|
|
|
|
|
|
// 新增模式:设置管理者用户
|
|
|
|
|
|
// 优先使用 rowData 中传入的管理者用户 ID(如从树形节点新增)
|
|
|
|
|
|
// 否则使用当前登录用户
|
|
|
|
|
|
let managerUserIdToSet: number | undefined;
|
|
|
|
|
|
|
|
|
|
|
|
if (props.rowData && props.rowData.managerUserId) {
|
|
|
|
|
|
// 从树形节点点击新增,管理者为当前节点用户
|
|
|
|
|
|
managerUserIdToSet = props.rowData.managerUserId;
|
|
|
|
|
|
} else if (authStore.userInfo.userId) {
|
|
|
|
|
|
// 头部新增,管理者为当前登录用户
|
|
|
|
|
|
const currentUserId = Number(authStore.userInfo.userId);
|
|
|
|
|
|
const currentUserName = authStore.userInfo.userName;
|
|
|
|
|
|
|
|
|
|
|
|
// 先尝试通过 ID 匹配
|
|
|
|
|
|
let currentUser = props.userList.find(user => Number(user.id) === currentUserId);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果 ID 匹配失败,尝试通过用户名匹配
|
|
|
|
|
|
if (!currentUser && currentUserName) {
|
|
|
|
|
|
currentUser = props.userList.find(user => user.nickname === currentUserName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (currentUser) {
|
|
|
|
|
|
managerUserIdToSet = currentUser.id;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (managerUserIdToSet) {
|
|
|
|
|
|
model.value.managerUserId = managerUserIdToSet;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
formRef.value?.clearValidate();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 编辑模式:加载详情数据
|
|
|
|
|
|
if (!props.rowData) {
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
formRef.value?.clearValidate();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
detailLoading.value = true;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { error, data } = await fetchGetUserManagementRelation(props.rowData.id);
|
|
|
|
|
|
|
|
|
|
|
|
if (data !== null && !error) {
|
|
|
|
|
|
model.value = {
|
|
|
|
|
|
id: data.id,
|
|
|
|
|
|
managerUserId: data.managerUserId,
|
|
|
|
|
|
subordinateUserId: data.subordinateUserId,
|
|
|
|
|
|
effectiveFrom: data.effectiveFrom ? new Date(data.effectiveFrom).getTime() : null,
|
|
|
|
|
|
effectiveUntil: data.effectiveUntil ? new Date(data.effectiveUntil).getTime() : null,
|
|
|
|
|
|
remark: data.remark ?? null
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
detailLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
formRef.value?.clearValidate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理表单提交
|
|
|
|
|
|
*
|
|
|
|
|
|
* 验证通过后调用创建或更新接口
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function handleSubmit() {
|
|
|
|
|
|
await validate();
|
|
|
|
|
|
|
|
|
|
|
|
submitting.value = true;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const submitData: Api.SystemManage.UserManagementRelationSaveReqVO = {
|
|
|
|
|
|
...model.value
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const request =
|
|
|
|
|
|
isEdit.value && props.rowData
|
|
|
|
|
|
? await fetchUpdateUserManagementRelation({ id: props.rowData.id, ...submitData })
|
|
|
|
|
|
: await fetchCreateUserManagementRelation(submitData);
|
|
|
|
|
|
|
|
|
|
|
|
const { error, data } = request;
|
|
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const relationId = isEdit.value && props.rowData ? props.rowData.id : Number(data);
|
|
|
|
|
|
|
|
|
|
|
|
window.$message?.success(isEdit.value ? '修改成功' : '新增成功');
|
|
|
|
|
|
|
|
|
|
|
|
closeModal();
|
|
|
|
|
|
emit('submitted', relationId);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
submitting.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 监听对话框可见性
|
|
|
|
|
|
*
|
|
|
|
|
|
* 打开时初始化表单
|
|
|
|
|
|
*/
|
|
|
|
|
|
watch(visible, value => {
|
|
|
|
|
|
if (value) {
|
|
|
|
|
|
initModel();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<BusinessFormDialog
|
|
|
|
|
|
v-model="visible"
|
|
|
|
|
|
:title="title"
|
|
|
|
|
|
preset="md"
|
|
|
|
|
|
:loading="detailLoading"
|
|
|
|
|
|
:confirm-loading="submitting"
|
|
|
|
|
|
:scrollbar="false"
|
|
|
|
|
|
@confirm="handleSubmit"
|
|
|
|
|
|
>
|
|
|
|
|
|
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
|
|
|
|
|
|
<ElRow :gutter="16">
|
|
|
|
|
|
<ElCol :span="12">
|
|
|
|
|
|
<ElFormItem label="管理者用户" prop="managerUserId">
|
|
|
|
|
|
<ElSelect v-model="model.managerUserId" class="w-full" placeholder="请选择管理者用户" filterable>
|
|
|
|
|
|
<ElOption v-for="user in props.userList" :key="user.id" :label="user.nickname" :value="user.id" />
|
|
|
|
|
|
</ElSelect>
|
|
|
|
|
|
</ElFormItem>
|
|
|
|
|
|
</ElCol>
|
|
|
|
|
|
<ElCol :span="12">
|
|
|
|
|
|
<ElFormItem label="被管理用户" prop="subordinateUserId">
|
|
|
|
|
|
<ElSelect
|
|
|
|
|
|
v-model="model.subordinateUserId"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
placeholder="请选择被管理用户"
|
|
|
|
|
|
filterable
|
|
|
|
|
|
:disabled="isEdit"
|
|
|
|
|
|
>
|
|
|
|
|
|
<ElOption v-for="user in props.userList" :key="user.id" :label="user.nickname" :value="user.id" />
|
|
|
|
|
|
</ElSelect>
|
|
|
|
|
|
</ElFormItem>
|
|
|
|
|
|
</ElCol>
|
2026-04-14 16:33:47 +08:00
|
|
|
|
</ElRow>
|
|
|
|
|
|
<ElRow :gutter="16">
|
2026-04-10 16:30:42 +08:00
|
|
|
|
<ElCol :span="12">
|
2026-04-15 09:35:54 +08:00
|
|
|
|
<ElFormItem label="生效开始时间" prop="effectiveFrom" style="width: 100%">
|
2026-04-10 16:30:42 +08:00
|
|
|
|
<ElDatePicker
|
|
|
|
|
|
v-model="model.effectiveFrom"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
type="datetime"
|
|
|
|
|
|
placeholder="请选择生效开始时间"
|
|
|
|
|
|
value-format="x"
|
2026-04-15 09:35:54 +08:00
|
|
|
|
style="width: 100%"
|
2026-04-10 16:30:42 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</ElFormItem>
|
|
|
|
|
|
</ElCol>
|
|
|
|
|
|
<ElCol :span="12">
|
2026-04-15 09:35:54 +08:00
|
|
|
|
<ElFormItem label="生效结束时间" prop="effectiveUntil" style="width: 100%">
|
2026-04-10 16:30:42 +08:00
|
|
|
|
<ElDatePicker
|
|
|
|
|
|
v-model="model.effectiveUntil"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
type="datetime"
|
|
|
|
|
|
placeholder="请选择生效结束时间"
|
|
|
|
|
|
value-format="x"
|
2026-04-15 09:35:54 +08:00
|
|
|
|
style="width: 100%"
|
2026-04-10 16:30:42 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</ElFormItem>
|
|
|
|
|
|
</ElCol>
|
2026-04-14 16:33:47 +08:00
|
|
|
|
</ElRow>
|
|
|
|
|
|
<ElRow :gutter="16">
|
2026-04-10 16:30:42 +08:00
|
|
|
|
<ElCol :span="24">
|
|
|
|
|
|
<ElFormItem label="备注" prop="remark">
|
|
|
|
|
|
<ElInput v-model="model.remark" type="textarea" :rows="4" placeholder="请输入备注" />
|
|
|
|
|
|
</ElFormItem>
|
|
|
|
|
|
</ElCol>
|
|
|
|
|
|
</ElRow>
|
|
|
|
|
|
</ElForm>
|
|
|
|
|
|
</BusinessFormDialog>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2026-04-15 09:35:54 +08:00
|
|
|
|
<style scoped></style>
|