323 lines
8.3 KiB
Vue
323 lines
8.3 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* 用户汇报关系操作对话框
|
||
*
|
||
* 功能说明:
|
||
* - 新增用户汇报关系
|
||
* - 编辑用户汇报关系
|
||
* - 表单验证和提交
|
||
*
|
||
* 表单字段:
|
||
* - 管理者用户:必填,下拉选择,默认当前登录用户
|
||
* - 被管理用户:必填,下拉选择,默认空
|
||
* - 生效开始时间:可选
|
||
* - 生效结束时间:可选
|
||
* - 备注:可选
|
||
*
|
||
* 用户列表通过 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> = {
|
||
add: '新增用户汇报关系',
|
||
edit: '编辑用户汇报关系'
|
||
};
|
||
|
||
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>
|
||
</ElRow>
|
||
<ElRow :gutter="16">
|
||
<ElCol :span="12">
|
||
<ElFormItem label="生效开始时间" prop="effectiveFrom" style="width: 100%">
|
||
<ElDatePicker
|
||
v-model="model.effectiveFrom"
|
||
class="w-full"
|
||
type="datetime"
|
||
placeholder="请选择生效开始时间"
|
||
value-format="x"
|
||
style="width: 100%"
|
||
/>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="生效结束时间" prop="effectiveUntil" style="width: 100%">
|
||
<ElDatePicker
|
||
v-model="model.effectiveUntil"
|
||
class="w-full"
|
||
type="datetime"
|
||
placeholder="请选择生效结束时间"
|
||
value-format="x"
|
||
style="width: 100%"
|
||
/>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
<ElRow :gutter="16">
|
||
<ElCol :span="24">
|
||
<ElFormItem label="备注" prop="remark">
|
||
<ElInput v-model="model.remark" type="textarea" :rows="4" placeholder="请输入备注" />
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
</ElForm>
|
||
</BusinessFormDialog>
|
||
</template>
|
||
|
||
<style scoped></style>
|