feat(user-management-relation): 创建带人关系页面、编写各组件代码,完善诸多细节
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
<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>
|
||||
<ElCol :span="12">
|
||||
<ElFormItem label="生效开始时间" prop="effectiveFrom">
|
||||
<ElDatePicker
|
||||
v-model="model.effectiveFrom"
|
||||
class="w-full"
|
||||
type="datetime"
|
||||
placeholder="请选择生效开始时间"
|
||||
value-format="x"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElCol>
|
||||
<ElCol :span="12">
|
||||
<ElFormItem label="生效结束时间" prop="effectiveUntil">
|
||||
<ElDatePicker
|
||||
v-model="model.effectiveUntil"
|
||||
class="w-full"
|
||||
type="datetime"
|
||||
placeholder="请选择生效结束时间"
|
||||
value-format="x"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElCol>
|
||||
<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>
|
||||
Reference in New Issue
Block a user