dzc committed 2025-07-10 18:32:22 +08:00
commit 913e08bfb9
3 files changed
+260 -80

No files matched your search

+241 -80
View File
@@ -1,118 +1,279 @@
<template>
<el-dialog :title="dataForm.deptId ? $t('common.editBtn') : $t('common.addBtn')" v-model="visible" width="600">
<el-form ref="deptDialogFormRef" :model="dataForm" label-width="90px" :rules="dataRules" v-loading="loading">
<el-form-item :label="$t('sysdept.parentId')" prop="parentId">
<el-tree-select
v-model="dataForm.parentId"
:data="parentData"
:props="{ value: 'id', label: 'name', children: 'children' }"
class="w100"
clearable
check-strictly
:render-after-expand="false"
:placeholder="$t('sysdept.inputparentIdTip')"
/>
</el-form-item>
<el-form-item :label="$t('sysdept.name')" prop="name">
<el-input v-model="dataForm.name" :placeholder="$t('sysdept.inputnameTip')" clearable />
</el-form-item>
<el-form-item :label="$t('sysdept.sortOrder')" prop="sortOrder">
<el-input-number v-model="dataForm.sortOrder" :placeholder="$t('sysdept.inputsortOrderTip')" clearable />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
</span>
</template>
</el-dialog>
<el-dialog
:title="dataForm.deptId ? $t('common.editBtn') : $t('common.addBtn')"
v-model="visible"
width="600"
>
<el-form
ref="deptDialogFormRef"
:model="dataForm"
label-width="90px"
:rules="dataRules"
v-loading="loading"
>
<el-form-item :label="$t('sysdept.parentId')" prop="parentId">
<el-tree-select
v-model="dataForm.parentId"
:data="parentData"
:props="{ value: 'id', label: 'name', children: 'children' }"
class="w100"
clearable
check-strictly
:render-after-expand="false"
:placeholder="$t('sysdept.inputparentIdTip')"
/>
</el-form-item>
<el-form-item :label="$t('sysdept.name')" prop="name">
<el-input
v-model="dataForm.name"
:placeholder="$t('sysdept.inputnameTip')"
clearable
/>
</el-form-item>
<el-form-item :label="$t('sysdept.sortOrder')" prop="sortOrder">
<el-input-number
v-model="dataForm.sortOrder"
:placeholder="$t('sysdept.inputsortOrderTip')"
clearable
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">{{
$t("common.cancelButtonText")
}}</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">{{
$t("common.confirmButtonText")
}}</el-button>
</span>
</template>
</el-dialog>
<!-- 新增人员管理弹窗 -->
<el-dialog
title="人员管理"
v-model="staffDialogVisible"
width="30%"
:before-close="handleStaffDialogClose"
>
<span>请选择用户添加到当前部门:{{ currentDeptName }}</span>
<div class="list-container">
<div v-for="(item, index) in staffList" :key="index" class="list-item">
<div class="list-item-content">
<span>{{ item.name }}</span>
<el-button
type="primary"
size="small"
:disabled="item.added"
@click="handleAddStaff(item, index)"
>
{{ item.added ? "已添加" : "添加" }}
</el-button>
</div>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="staffDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="staffDialogVisible = false"
>确 定</el-button
>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="systemDeptDialog">
import { useI18n } from 'vue-i18n';
import { getObj, deptTree, addObj, putObj } from '/@/api/admin/dept';
import { useMessage } from '/@/hooks/message';
import {rule} from "/@/utils/validate";
import { useI18n } from "vue-i18n";
import { getObj, deptTree, addObj, putObj } from "/@/api/admin/dept";
import { useMessage } from "/@/hooks/message";
import { rule } from "/@/utils/validate";
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
const emit = defineEmits(["refresh"]);
const { t } = useI18n();
// 定义变量内容
const deptDialogFormRef = ref();
const dataForm = reactive({
parentId: '',
deptId: '',
name: '',
sortOrder: 9999,
parentId: "",
deptId: "",
name: "",
sortOrder: 9999,
});
const staffDataForm = reactive({
deptId: "",
username: "",
password: "",
role: [],
});
const parentData = ref<any[]>([]);
const visible = ref(false);
const loading = ref(false);
// 新增人员管理相关变量
const staffDialogVisible = ref(false);
const staffList = ref<any[]>([]);
const currentDeptId = ref("");
const currentDeptName = ref("");
const dataRules = ref({
parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
name: [{ validator: rule.overLength, trigger: 'blur' },{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
sortOrder: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
parentId: [{ required: true, message: "上级部门不能为空", trigger: "blur" }],
name: [
{ validator: rule.overLength, trigger: "blur" },
{ required: true, message: "部门名称不能为空", trigger: "blur" },
],
sortOrder: [{ required: true, message: "排序不能为空", trigger: "blur" }],
});
// 打开弹窗
const openDialog = (type: string, id: string) => {
visible.value = true;
dataForm.deptId = '';
// 控制弹窗显示
visible.value = true;
// 清空当前部门ID,准备创建新部门或编辑现有部门
dataForm.deptId = "";
nextTick(() => {
deptDialogFormRef.value?.resetFields();
dataForm.parentId = id;
});
// 等待DOM更新完成后执行
nextTick(() => {
// 重置表单字段到初始值
deptDialogFormRef.value?.resetFields();
// 设置上级部门ID为传入的ID
dataForm.parentId = id;
});
if (type === 'edit') {
getObj(id)
.then((res) => {
Object.assign(dataForm, res.data);
})
.catch((err) => {
useMessage().error(err.msg);
});
}
// 如果是编辑模式
if (type === "edit") {
// 调用API获取部门详情数据
getObj(id)
.then((res) => {
// 将API返回的数据合并到表单对象
Object.assign(dataForm, res.data);
})
.catch((err) => {
// 错误处理:显示错误消息
useMessage().error(err.msg);
});
}
getDeptData();
// 获取部门树数据(用于上级部门选择器) 刷新树表
getDeptData();
};
// 右键Node(节点)->员工管理->弹出员工管理弹窗
const openStaffManagementDialog = (type: string, id: string) => {
console.log("打开人员管理弹窗", id); // 添加此行
// 控制弹窗显示
staffDialogVisible.value = true;
currentDeptId.value = id;
currentDeptName.value = "加载中..."; // 设置加载状态
// 获取部门名称
getObj(id)
.then((res) => {
currentDeptName.value = res.data.name || "未知部门";
})
.catch((err) => {
useMessage().error(err.msg);
currentDeptName.value = "获取失败";
});
// 加载员工列表(这里使用模拟数据)
loadStaffList(id);
};
// 加载员工列表(模拟)
const loadStaffList = (deptId: string) => {
// 实际项目中应调用API获取员工列表
staffList.value = [
{ id: 1, name: "张三", added: false },
{ id: 2, name: "李四", added: false },
{ id: 3, name: "王五", added: false },
{ id: 4, name: "赵六", added: false },
];
};
// 添加员工到部门
const handleAddStaff = (item: any, index: number) => {
useMessage().success(`已添加: ${item.name}`);
// 更新状态
staffList.value[index].added = true;
// 实际项目中应调用API将员工添加到部门
// addStaffToDept(item.id, currentDeptId.value);
};
// 关闭人员管理弹窗前处理
const handleStaffDialogClose = () => {
staffDialogVisible.value = false;
};
// 提交
const onSubmit = async () => {
const valid = await deptDialogFormRef.value.validate().catch(() => {});
if (!valid) return false;
const valid = await deptDialogFormRef.value.validate().catch(() => {});
if (!valid) return false;
try {
loading.value = true;
dataForm.deptId ? await putObj(dataForm) : await addObj(dataForm);
useMessage().success(t(dataForm.deptId ? 'common.editSuccessText' : 'common.addSuccessText'));
visible.value = false;
emit('refresh');
} catch (err: any) {
useMessage().error(err.msg);
} finally {
loading.value = false;
}
try {
loading.value = true;
// 根据deptId判断是新增还是编辑
dataForm.deptId
? await putObj(dataForm) // 编辑
: await addObj(dataForm); // 新增
useMessage().success(
t(dataForm.deptId ? "common.editSuccessText" : "common.addSuccessText")
);
visible.value = false;
emit("refresh"); // 通知父组件刷新
} catch (err: any) {
useMessage().error(err.msg);
} finally {
loading.value = false;
}
};
// 从后端获取菜单信息
const getDeptData = async () => {
deptTree().then((res) => {
parentData.value = [];
const dept = {
id: '0',
name: '根部门',
children: [] as any[],
};
dept.children = res.data;
parentData.value.push(dept);
});
deptTree().then((res) => {
parentData.value = [];
const dept = {
id: "0",
name: "根部门",
children: [] as any[],
};
dept.children = res.data;
parentData.value.push(dept);
});
};
// 暴露变量
defineExpose({
openDialog,
openDialog,
openStaffManagementDialog,
});
</script>
<style scoped>
/* 新增人员管理样式 */
.list-container {
margin-top: 15px;
border: 1px solid #ebeef5;
border-radius: 4px;
max-height: 200px;
overflow-y: auto;
}
.list-item {
padding: 8px 16px;
border-bottom: 1px solid #ebeef5;
}
.list-item:last-child {
border-bottom: none;
}
.list-item-content {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
@@ -15,6 +15,7 @@ export default {
addNodeText: '添加部门',
editNodeText: '编辑部门',
delNodeText: '删除部门',
nodeStaffManagementText: '人员管理',
tenantNodeErrorText: '当前节点不可操作,请在租户管理功能中维护',
view: '树/表视图'
},
+18
View File
@@ -16,6 +16,7 @@
:node-add="addNode"
:node-delete="delNode"
:node-edit="editNode"
:node-staff-management="nodeStaffManagement"
@on-node-click="onNodeClick"
/>
</div>
@@ -44,6 +45,10 @@ const defineMenus = reactive([
{ name: t('sysdept.addNodeText'), command: 'add' },
{ name: t('sysdept.editNodeText'), command: 'edit' },
{ name: t('sysdept.delNodeText'), command: 'delete' },
{
name: t('sysdept.nodeStaffManagementText'),
command: 'staffManagement'
},
]);
const cloneNodeDrag = ref(true);
@@ -175,6 +180,18 @@ const getOrgData = async () => {
});
};
/**
* 查询和管理该部门下的人员
* @param {object} node 节点对象
*/
const nodeStaffManagement = (node) => {
console.log("触发人员管理", node?.id); // 添加此行
if (!checkNode(node)) return;
// 确保调用 openStaffManagementDialog 方法
deptDialogRef.value.openStaffManagementDialog('staffManagement', node?.id);
}
onMounted(() => {
getOrgData();
});
@@ -184,6 +201,7 @@ defineExpose({
getOrgData,
handleExpand,
filter,
nodeStaffManagement,
});
</script>