| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- <template>
- <div class="safety-platform-container">
- <header class="safety-platform-container__header">
- <div class="breadcrumb-title"> 安全组织体系管理 </div>
- </header>
- <main class="safety-platform-container__main flex">
- <div class="nav">
- <el-button type="primary" :icon="Plus" @click="addTeam('parent')"> 添加组织</el-button>
-
- <div class="collapse-wrapper">
- <!-- 组织树v-model="activeName"-->
- <el-collapse accordion v-if="fetchSafetyOrganizationList.length > 0">
- <CollapseItem
- v-for="item in fetchSafetyOrganizationList"
- :key="item.id"
- :data="item"
- :level="level"
- @click-node="querySafetyTeamData"
- @create-node="handleCreateSafetySystem"
- @edit-node="handleEditSafetySystem"
- @delete-node="handleDelSafetySystem"
- />
- </el-collapse>
-
- <div v-else>
- <el-empty description="未添加组织" />
- </div>
- </div>
- <!-- 添加、编辑组织弹窗 -->
- <AddSafetySystem
- v-model:visible="addSafetySystemVisible"
- :data="addSafetyOrganizationSystemFormData"
- @confirmAddSafetySystem="confirmAddSafetySystemCallback"
- />
- </div>
- <div class="search-table-container table-content">
- <!-- 架构图 -->
- <OrgChart :treeData="treeData" @node-click="handleNodeClick" />
- <TeamDetailDrawer ref="teamDetailDrawerRef" :selected-team-id="selectedTeamId" />
- <div class="text-right mb-4">
- <el-button @click="toStaff"> 编辑 </el-button>
- </div>
- </div>
- </main>
- <!-- <BatchImport
- v-if="batchImportVisible"
- :visible="batchImportVisible"
- :import-api-url="importApiUrl"
- :template-url="templateUrl"
- template-name="安全组织体系管理导入模版"
- :show-template="true"
- @close="batchImportVisible = false"
- @update="handleUpdate"
- /> -->
- </div>
- </template>
- <script setup lang="ts">
- import { onMounted, reactive, ref, provide } from 'vue';
- import { ElMessage, ElMessageBox } from 'element-plus';
- import BasicTable from '@/components/BasicTable.vue';
- import useTableConfig from '@/hooks/useTableConfigHook';
- import { TABLE_OPTIONS, TABLE_COLUMNS } from './configs/tables';
- import { useRouter } from 'vue-router';
- import type { QueryPageRequest } from '@/types/basic-query';
- import {
- getSafetySystemList,
- addSafetySystem,
- updateSafetySystem,
- deleteSafetySystem,
- fetchTableList,
- delEmployee,
- exportSafetyOrganizationSystemManagement
- } from '@/api/safety-organization-management';
- // import { downloadByData } from '@/utils/file/download';
- // import BatchImport from '@/components/batch-import/BatchImport.vue';
- // import { useGlobSetting } from '@/hooks/setting';
- // import urlJoin from 'url-join';
- import AddSafetySystem from './components/addSafetySystem.vue';
- import {
- Delete,
- Edit,
- Plus,
- } from '@element-plus/icons-vue'
- import OrgChart from './components/orgChart.vue';
- import CollapseItem from './components/collapseItem.vue'
- import TeamDetailDrawer from './components/TeamDetailDrawer.vue';
- const position = ref('left')
- const router = useRouter();
- // 表格
- // const basicTableRef = ref<InstanceType<typeof BasicTable>>();
- const { tableConfig, pagination } = useTableConfig(TABLE_COLUMNS, TABLE_OPTIONS);
- const tableData = ref<any[]>([]);
- const fetchSafetyOrganizationList = ref<any[]>([]);
- const activeName = ref('');
- // 给组件递归时使用
- // provide('activeName', activeName)
- const level = ref(1)
- // 日期范围(用于日期选择器)
- const dateRange = ref<[string, string] | string>('');
- const tableQuery = reactive<QueryPageRequest<any>>({
- pageNumber: pagination.pageNumber,
- pageSize: pagination.pageSize,
- queryParam: {
- classifyName: '',
- keyword: '',
- status: '',
- startTime: '',
- endTime: '',
- },
- });
- type OrganizationTreeType = {
- id: string;
- data: { name: string };
- children?: OrganizationTreeType[];
- };
- const treeData = ref<OrganizationTreeType>({
- id: 'root',
- data: { name: '请添加组织' },
- children: [],
- });
-
- // const handlerEdit = ()=>{
- // router.push({name: 'securityOrganizationalStructure'})
- // }
- // const handleSizeChange = (value: number) => {
- // pagination.pageSize = value;
- // tableQuery.pageSize = value;
- // getTableData();
- // };
- // const handleCurrentChange = (value: number) => {
- // pagination.pageNumber = value;
- // tableQuery.pageNumber = value;
- // getTableData();
- // };
- const teamDetailDrawerRef = ref<InstanceType<typeof TeamDetailDrawer>>();
- const selectedTeamId = ref<number | null>(null);
- const handleNodeClick = (nodeData: any) => {
- const id = nodeData?.id?.replace('org-', '')
- console.log(nodeData, 'canshu')
- selectedTeamId.value = Number(id);
- teamDetailDrawerRef.value?.drawerShow();
- };
- // async function getTableData() {
- // tableConfig.loading = true;
- // try {
- // const res = await fetchTableList(tableQuery);
- // if (res) {
- // tableData.value = res.records
- // pagination.total = res.totalRow;
- // }
- // } catch (e) {
- // console.error('获取列表失败:', e);
- // tableData.value = [];
- // pagination.total = 0;
- // } finally {
- // tableConfig.loading = false;
- // }
- // }
- interface addSafetyOrganizationSystemFormDataType {
- type: String;
- orgName?: String;
- orgId?: String | number;
- action?: String;
- parentid?: String | number;
- }
- const addSafetySystemVisible = ref(false);
- const addSafetyOrganizationSystemFormData = ref<addSafetyOrganizationSystemFormDataType>({
- type: '',
- orgName: '',
- orgId: '',
- action: '',
- parentid: '',
- });
- /**
- * 递归给树形结构添加 id 、data 、children 字段
- * @param {Array} tree 原始树形数组
- * @returns 格式化后的标准树结构
- */
- const formatTreeData = (tree)=> {
- if (!tree || !Array.isArray(tree)) return [];
- return tree.map(item => {
- // 给每一层节点都加上 id 和 data
- const formattedItem = {
- children: item.children || [],
- id: `org-${item.orgId}`,
- data: {
- name: item.orgName
- }
- };
- // 递归处理子节点
- if (formattedItem.children && formattedItem.children.length > 0) {
- formattedItem.children = formatTreeData(formattedItem.children);
- }
- return formattedItem;
- });
- }
- function convertData(leaderTeams): OrganizationTreeType {
- return {
- id: `org-${leaderTeams.orgId}`,
- data: {
- name: leaderTeams.orgName
- },
- children: leaderTeams.children?.map((child) => convertData(child)),
- };
- }
- // 获取组织列表
- const fetchSafetyOrganizationTeamList = async () => {
- try {
- const res = await getSafetySystemList();
- fetchSafetyOrganizationList.value = res;
- // 默认选择第一个组织
- if(res[0].orgId){
- treeNodePreview(res[0])
- activeName.value = String(res[0].orgId)
- tableQuery.queryParam.classifyName = res[0].orgId
- }
- } catch (error) {
- ElMessage.error('获取组织列表失败');
- }
- };
- // 给架构图赋值
- const treeNodePreview = (data)=>{
- let TreeNode = convertData(data)
- treeData.value = TreeNode
- }
- // 一级新增
- const addTeam = (type) => {
- addSafetyOrganizationSystemFormData.value = {
- type,
- action: 'add',
- };
- addSafetySystemVisible.value = true;
- };
- // 子级新增
- const handleCreateSafetySystem = async (type, value) => {
- // console.log('新增参数--',type, value)
- addSafetyOrganizationSystemFormData.value = {
- type:'children',
- action: 'add',
- orgName: value.orgName,
- orgId: value.orgId,
- };
- addSafetySystemVisible.value = true;
- // 打开某一个
- // activeName.value = value.orgId;
- };
- // 编辑
- const handleEditSafetySystem = (type, value, parentid) => {
- // console.log('编辑参数--', type, value, parentid)
- addSafetySystemVisible.value = true;
- addSafetyOrganizationSystemFormData.value = {
- type,
- action: 'edit',
- orgName: value.orgName,
- orgId: value.orgId,
- parentid,
- };
- };
- // 删除
- const handleDelSafetySystem = async (type, value) => {
- // console.log('删除', type, value)
- ElMessageBox.confirm('确认删除该组织吗?', '警告', { type: 'warning' }).then(async () => {
- try {
- if(value.children.length > 0){
- ElMessage.error('当前一级组织存在子级数据,无法删除,请先删除子级组织')
- return
- }
- await deleteSafetySystem(value.orgId);
- ElMessage.success('删除成功');
- // 刷新组织列表
- fetchSafetyOrganizationTeamList();
- } catch (error) {
- ElMessage.error(error || '删除失败');
- }
- });
- };
- // 查询
- const querySafetyTeamData = (value) => {
- // console.log('查询', value);
- tableQuery.queryParam.classifyName = value.orgId;
- activeName.value = String(value.orgId)
- treeNodePreview(value)
- };
- // 定义组织数据类型
- interface SafetySystemFormData {
- value: string; // 输入的组织名称
- action: 'add' | 'edit'; // 操作类型:新增或编辑
- orgId?: string | number; // 组织ID(编辑时必传)
- parentid?: string | number; // 父组织ID(新增子组织时必传)
- type?: 'children' | 'parent'; // 组织类型(子组织或根组织)
- }
- // 保存弹窗回调
- const confirmAddSafetySystemCallback = async (formData: SafetySystemFormData) => {
- try {
- if (!formData.value?.trim()) {
- ElMessage.warning('请输入有效的组织名称!');
- return;
- }
- // 新增时,传orgName(组织名称)、parentid(父组织ID)
- // 编辑时,传当前ID和orgName
- const requestData = {
- orgName: formData.value.trim(),
- id: formData.action === 'edit' ? formData.orgId : undefined,
- // 第一级不需要传parentid
- parentid: formData.action === 'add' ? formData.parentid : undefined,
- };
- console.log(formData, '参数--formData')
- if (formData.action === 'add') {
- if (formData.type === 'children' && formData.orgId) {
- requestData.parentid = formData.orgId;
- }
- await addSafetySystem(requestData);
- ElMessage.success('新增组织成功!');
- } else {
- // 如果是子类,补充父级ID
- if (formData.type === 'children' && formData.parentid) {
- requestData.parentid = formData.parentid;
- }
- await updateSafetySystem(requestData);
- ElMessage.success('编辑组织成功!');
- }
- // 刷新列表
- fetchSafetyOrganizationTeamList();
- } catch (error) {
- console.error('操作失败:', error);
- ElMessage.error(formData.action === 'add' ? '新增组织失败!' : '编辑组织失败!');
- }
- };
- const toStaff = ()=>{
- router.push({name: 'securityOrganizationalStructure', query: {id: tableQuery.queryParam.classifyName}})
- }
- // 时间查询
- // const onchangeDateRange = () => {
- // if (dateRange.value && Array.isArray(dateRange.value) && dateRange.value.length === 2) {
- // tableQuery.queryParam.startTime = dateRange.value[0] || '';
- // tableQuery.queryParam.endTime = dateRange.value[1] || '';
- // } else {
- // tableQuery.queryParam.startTime = '';
- // tableQuery.queryParam.endTime = '';
- // }
- // getTableData();
- // };
- // const handleSearch = () => {
- // pagination.pageNumber = 1;
- // tableQuery.pageNumber = 1;
- // getTableData();
- // };
- // const handleReset = () => {
- // pagination.pageNumber = 1;
- // tableQuery.queryParam = {
- // classifyName: '',
- // keyword: '',
- // status: '', // 重置为默认启用状态
- // startTime: '',
- // endTime: '',
- // };
- // dateRange.value = '';
- // handleSearch();
- // };
- // 批量导入
- // const batchImportVisible = ref(false);
- // const { urlPrefix } = useGlobSetting();
- // const importApiUrl = ref(urlJoin(urlPrefix, '/safetyorguser/importSafetyOrgUser'));
- // const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/安全组织体系管理导入模版.xlsx');
- // const handleImport = () => {
- // batchImportVisible.value = true;
- // };
- // const handleUpdate = () => {
- // batchImportVisible.value = false;
- // getTableData();
- // };
- // const handleDownload = async () => {
- // try {
- // const response = await exportSafetyOrganizationSystemManagement(tableQuery.queryParam);
- // if (response) {
- // const fileName = `安全组织体系管理_${new Date().toISOString().split('T')[0]}.xlsx`;
- // downloadByData(response, fileName);
- // ElMessage.success('导出成功');
- // }
- // } catch (e) {
- // console.error('导出安全组织体系管理失败:', e);
- // ElMessage.error('导出失败,请重试');
- // }
- // };
- // const handleCreate = () => {
- // router.push({
- // name: 'SafetyOrganizationSystemManagementItem',
- // query: {
- // operate: 'employee-create',
- // },
- // });
- // };
- // const handleEdit = (id: number) => {
- // router.push({
- // name: 'SafetyOrganizationSystemManagementItem',
- // query: {
- // id,
- // operate: 'employee-edit',
- // },
- // });
- // };
- // const handleDelete = async (id: number) => {
- // try {
- // await delEmployee(id);
- // ElMessage.success('删除成功');
- // getTableData();
- // } catch (e) {
- // console.error('删除员工失败:', e);
- // ElMessage.error('删除失败,请重试');
- // }
- // };
- // const handleView = (id: number) => {
- // router.push({
- // name: 'SafetyOrganizationSystemManagementItem',
- // query: {
- // id,
- // operate: 'employee-view',
- // },
- // });
- // };
- onMounted(() => {
- fetchSafetyOrganizationTeamList();
- // getTableData();
- });
- </script>
- <style scoped lang="scss">
- @use '@/styles/page-details-layout.scss' as *;
- @use '@/styles/page-main-layout.scss' as *;
- @use '@/styles/basic-table-action.scss' as *;
- @use '@/views/traffic/violation/style/act-search-table.scss' as *;
- .text-right{
- text-align: right;
- }
- .mb-4{
- margin-bottom: 12px;
- }
- .nav {
- flex: 0 0 300px;
- margin-right: 15px;
- padding-right: 15px;
- border-right: 1px solid #eee;
- :deep(.collapse-title) {
- flex: 1 0 90%;
- order: 1;
- .el-collapse-item__header {
- flex: 1 0 auto;
- order: -1;
- }
- }
- .collapse-wrapper {
- margin-top: 10px;
- .title-wrapper {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- .handler {
- flex: 1;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- padding-right: 15px;
- }
- }
- .collapse-item-content {
- ul {
- padding-left: 40px;
- li {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- padding: 6px 0;
- border-bottom: 1px solid #eeeeeed1;
- span {
- cursor: pointer;
- }
- }
- }
- }
- }
- }
- </style>
|