2025-10-13 11:55:39 +08:00

339 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="org-management">
<div class="header" v-if="!hasData">
<h1>组织管理</h1>
<a-button type="primary" @click="showAddModal()">添加根节点</a-button>
</div>
<div class="org-table">
<a-table
:columns="columns"
:data-source="dataSource"
:pagination="false"
row-key="orgId"
:expand-icon-as-cell="false"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'disabled'">
<a-tag :color="record.disabled === false ? 'green' : 'red'">
{{ record.disabled === false ? '启用' : '禁用' }}
</a-tag>
</template>
<template v-if="column.key === 'created_at'">
<div>{{ record.created_at ? dayjs(record.created_at).format('YYYY-MM-DD HH:mm') : '-' }}</div>
</template>
<template v-if="column.key === 'updated_at'">
<div>{{ record.updated_at ? dayjs(record.updated_at).format('YYYY-MM-DD HH:mm') : '-' }}</div>
</template>
<template v-if="column.key === 'actions'">
<div class="actions">
<!-- 修改这里只在前两层显示添加子节点按钮 -->
<a-button
v-if="getNodeLevel(record) < 2"
size="small"
type="primary"
@click="showAddModal(record)"
>
添加子节点
</a-button>
<a-button
style="margin-left: 20px;"
size="small"
danger
@click="handleDelete(record)"
>
删除
</a-button>
</div>
</template>
</template>
</a-table>
</div>
<!-- 添加节点模态框 -->
<a-modal
v-model:visible="addModalVisible"
:title="isEditing ? '编辑节点' : '添加节点'"
@ok="handleAdd"
@cancel="handleCancel"
:confirm-loading="confirmLoading"
>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
layout="vertical"
>
<a-form-item label="节点名称" name="name">
<a-input v-model:value="formState.name" placeholder="请输入节点名称" />
</a-form-item>
<a-form-item label="状态" name="status">
<a-switch
v-model:checked="formState.status"
:checked-children="statusText.checked"
:un-checked-children="statusText.unchecked"
:disabled="!isEditing"
/>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import apis from '@/apis';
import { Modal, message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { config } from '@/config';
import { usePagination } from '@/hooks';
const { listData, paginationState, loading, showLoading, hideLoading, resetPagination, searchFormData } = usePagination();
// 是否有数据的计算属性
const hasData = computed(() => {
return listData.value && listData.value.length > 0;
});
paginationState.onChange = (page, pageSize) => {
paginationState.current = page
paginationState.pageSize = pageSize
getList()
}
// 转换数据格式,将 subOrgList 转换为 children
const convertData = (data) => {
if (!data || data.length === 0) return [];
return data.map(item => {
const converted = {
...item,
key: item.id, // 使用 id 作为 key注意这里应该是 id 而不是 orgId
};
if (item.subOrgList && item.subOrgList.length > 0) {
converted.children = convertData(item.subOrgList);
}
return converted;
});
};
// 数据源
const dataSource = ref([]);
// 模态框状态
const addModalVisible = ref(false);
const isEditing = ref(false);
const currentParent = ref(null);
const confirmLoading = ref(false);
// 表单状态 - 默认状态为启用false
const formState = reactive({
name: '',
status: false // 默认为false表示启用
});
// 状态显示文本
const statusText = computed(() => {
return {
checked: '禁用',
unchecked: '启用'
};
});
// 表单验证规则
const rules = {
name: [
{ required: true, message: '请输入节点名称', trigger: 'blur' }
]
};
// 表格列定义 - 移除 projectType 列
const columns = [
{
title: '组织名称',
dataIndex: 'name',
key: 'name',
width: 200,
},
{
title: '状态',
dataIndex: 'disabled',
key: 'disabled',
width: 100,
},
{
title: '创建时间',
dataIndex: 'created_at',
key: 'created_at',
width: 180,
},
{
title: '更新时间',
dataIndex: 'updated_at',
key: 'updated_at',
width: 180,
},
{
title: '操作',
key: 'actions',
width: 200,
},
];
/**
* 获取节点的层级
* @param {Object} node 节点数据
* @param {Array} data 数据源
* @param {number} level 当前层级
* @returns {number} 节点层级0表示第一层1表示第二层2表示第三层
*/
const getNodeLevel = (node, data = null, level = 0) => {
// 如果是根节点直接返回0
if (!node.parentId || node.parentId === "") {
return 0;
}
// 如果没有传入data使用dataSource
const searchData = data || dataSource.value;
// 递归查找父节点
const findParentLevel = (nodes, targetId, currentLevel) => {
for (const item of nodes) {
if (item.id === targetId) {
return currentLevel;
}
if (item.children && item.children.length > 0) {
const found = findParentLevel(item.children, targetId, currentLevel + 1);
if (found !== -1) {
return found;
}
}
}
return -1;
};
// 查找父节点的层级
const parentLevel = findParentLevel(searchData, node.parentId, 0);
// 返回当前节点层级(父节点层级 + 1
return parentLevel + 1;
};
/**
* 获取表格数据
* @returns {Promise<void>}
*/
async function getList() {
try {
showLoading()
const { pageSize, current } = paginationState
const { success, data, total } = await apis.serviceMenu
.getNodeList({
pageSize,
current: current
})
.catch(() => {
throw new Error()
})
hideLoading()
if (config('http.code.success') === success) {
console.log("接口返回数据:", data)
listData.value = data || [];
paginationState.total = total || 0;
// 转换数据格式用于表格显示
dataSource.value = convertData(listData.value);
}
} catch (error) {
hideLoading()
console.error('获取数据失败:', error);
message.error('获取数据失败');
}
}
// 删除节点
const handleDelete = async (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除"${record.name}"吗?${record.children && record.children.length > 0 ? '此操作将同时删除所有子节点。' : ''}`,
async onOk() {
console.log('删除节点:', record.id);
try {
// 调用删除接口
const { success } = await apis.serviceMenu.delNode(record.id);
if (config('http.code.success') === success) {
message.success('删除成功');
// 重新获取数据
await getList();
} else {
message.error('删除失败');
}
} catch (error) {
console.error('删除失败:', error);
message.error('删除失败');
}
}
});
};
// 显示添加模态框
const showAddModal = (parent = null) => {
currentParent.value = parent;
isEditing.value = false;
// 重置表单 - 默认启用状态
Object.assign(formState, {
name: '',
status: false // 默认为启用状态
});
addModalVisible.value = true;
};
// 处理添加节点
const handleAdd = async () => {
if (!formState.name) {
message.error('请输入节点名称');
return;
}
confirmLoading.value = true;
try {
// 准备提交数据 - 始终包含 parentId 字段
const submitData = {
companyId: 'c001',
disabled: formState.status, // 状态为false表示启用true表示禁用
name: formState.name,
status: "",
parentId: currentParent.value ? currentParent.value.id : "" // 使用 id 字段
};
// 调用添加接口
const { success } = await apis.serviceMenu.createNode(submitData);
if (config('http.code.success') === success) {
addModalVisible.value = false;
message.success('添加成功');
// 重新获取数据
await getList();
} else {
message.error('添加失败');
}
} catch (error) {
console.error('添加失败:', error);
message.error('添加失败');
} finally {
confirmLoading.value = false;
}
};
// 取消添加
const handleCancel = () => {
addModalVisible.value = false;
};
onMounted(() => {
getList();
});
</script>