增加erp组织架构
This commit is contained in:
parent
186315d82c
commit
6c904ef3cd
65
src/api/erp.js
Normal file
65
src/api/erp.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
****************** 组织机构相关接口 ******************
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组织机构列表
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function getOrganizationList() {
|
||||||
|
return request({
|
||||||
|
url: '/admin/erp/organization',
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组织机构详情
|
||||||
|
* @param {number} id 组织机构ID
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function getOrganizationDetail(id) {
|
||||||
|
return request({
|
||||||
|
url: `/admin/erp/getOrganizationDetail/${id}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建组织机构数据
|
||||||
|
* @param {Object} data 组织机构数据
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function createOrganization(data) {
|
||||||
|
return request({
|
||||||
|
url: "/admin/erp/organization",
|
||||||
|
method: "post",
|
||||||
|
data: data,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新组织机构信息
|
||||||
|
export function editOrganization(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/admin/erp/organization/${id}`,
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除组织机构数据
|
||||||
|
* @param {number} id 组织机构ID
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function deleteOrganization(id) {
|
||||||
|
return request({
|
||||||
|
url: `/admin/erp/organization/${id}`,
|
||||||
|
method: "delete",
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -8,6 +8,14 @@ export function getAllUsers() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取租户用户
|
||||||
|
export function getTenantUsers(tenantId) {
|
||||||
|
return request({
|
||||||
|
url: `/admin/getTenantUsers/${tenantId}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
export function getUserInfo(userId) {
|
export function getUserInfo(userId) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@ -40,6 +40,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
account: userInfo.account || '',
|
account: userInfo.account || '',
|
||||||
name: userInfo.name || '',
|
name: userInfo.name || '',
|
||||||
group_id: userInfo.group_id || '',
|
group_id: userInfo.group_id || '',
|
||||||
|
tenant_id: userInfo.tenant_id || '',
|
||||||
avatar: userInfo.avatar || ''
|
avatar: userInfo.avatar || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
202
src/views/apps/erp/organization/components/edit.vue
Normal file
202
src/views/apps/erp/organization/components/edit.vue
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
:title="isEdit ? '编辑部门' : '添加部门'"
|
||||||
|
width="500px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
|
||||||
|
<el-form-item label="上级部门" prop="parent_id">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="formData.parent_id"
|
||||||
|
:data="treeData"
|
||||||
|
:props="treeProps"
|
||||||
|
check-strictly
|
||||||
|
placeholder="请选择上级部门"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门名称" prop="org_name">
|
||||||
|
<el-input v-model="formData.org_name" placeholder="请输入部门名称,例如:连云港云泽集团" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门编码" prop="org_code">
|
||||||
|
<el-input v-model="formData.org_code" placeholder="请输入部门编码,例如:LYG-YZ-GROUP" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="负责人" prop="leader_id">
|
||||||
|
<el-select v-model="formData.leader_id" placeholder="请选择负责人">
|
||||||
|
<el-option v-for="item in leaderList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input-number v-model="formData.sort" :min="0" :max="999" controls-position="right" style="width: 100%" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-radio-group v-model="formData.status">
|
||||||
|
<el-radio :label="1">启用</el-radio>
|
||||||
|
<el-radio :label="0">禁用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
||||||
|
import { createOrganization, editOrganization } from '@/api/erp'
|
||||||
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
import { getTenantUsers } from '@/api/user'
|
||||||
|
|
||||||
|
interface TreeNode {
|
||||||
|
id: number
|
||||||
|
org_name: string
|
||||||
|
org_code?: string
|
||||||
|
parent_id?: number
|
||||||
|
parent_name?: string
|
||||||
|
leader_id?: number
|
||||||
|
sort?: number
|
||||||
|
status?: number
|
||||||
|
remark?: string
|
||||||
|
children?: TreeNode[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
treeData: TreeNode[]
|
||||||
|
treeProps: { label: string; children: string; value: string }
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
success: []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const tenantId = (authStore.user as any)?.tenant_id
|
||||||
|
const leaderList = ref([])
|
||||||
|
const formData = reactive({
|
||||||
|
id: 0,
|
||||||
|
parent_id: undefined as number | undefined,
|
||||||
|
org_name: '',
|
||||||
|
org_code: '',
|
||||||
|
leader_id: undefined as number | undefined,
|
||||||
|
sort: 0,
|
||||||
|
status: 1,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules: FormRules = {
|
||||||
|
org_name: [{ required: true, message: '请输入部门名称', trigger: 'blur' }],
|
||||||
|
org_code: [{ required: true, message: '请输入部门编码', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getLeaderList()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getLeaderList = async () => {
|
||||||
|
const res = await getTenantUsers(tenantId)
|
||||||
|
if (res.code === 200) {
|
||||||
|
leaderList.value = res.data.list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const open = (data?: TreeNode, parentId?: number) => {
|
||||||
|
if (data) {
|
||||||
|
// 编辑
|
||||||
|
isEdit.value = true
|
||||||
|
Object.assign(formData, data)
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
isEdit.value = false
|
||||||
|
formData.id = 0
|
||||||
|
formData.parent_id = parentId
|
||||||
|
formData.org_name = ''
|
||||||
|
formData.org_code = ''
|
||||||
|
formData.leader_id = undefined
|
||||||
|
formData.sort = 0
|
||||||
|
formData.status = 1
|
||||||
|
formData.remark = ''
|
||||||
|
}
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
const handleClose = () => {
|
||||||
|
visible.value = false
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!formRef.value) return
|
||||||
|
|
||||||
|
await formRef.value.validate()
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
let res
|
||||||
|
|
||||||
|
if (isEdit.value && formData.id) {
|
||||||
|
// 编辑:使用普通对象提交
|
||||||
|
const submitData: Record<string, any> = {}
|
||||||
|
Object.keys(formData).forEach(key => {
|
||||||
|
if (
|
||||||
|
key !== 'id' &&
|
||||||
|
(formData as any)[key] !== undefined &&
|
||||||
|
(formData as any)[key] !== null
|
||||||
|
) {
|
||||||
|
submitData[key] = (formData as any)[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (tenantId) {
|
||||||
|
submitData.tenant_id = tenantId
|
||||||
|
}
|
||||||
|
res = await editOrganization(formData.id, submitData)
|
||||||
|
} else {
|
||||||
|
// 新增:使用 FormData 以兼容后端 multipart/form-data
|
||||||
|
const submitData = new FormData()
|
||||||
|
Object.keys(formData).forEach(key => {
|
||||||
|
const value = (formData as any)[key]
|
||||||
|
if (key !== 'id' && value !== undefined && value !== null) {
|
||||||
|
submitData.append(key, String(value))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (tenantId) {
|
||||||
|
submitData.append('tenant_id', String(tenantId))
|
||||||
|
}
|
||||||
|
res = await createOrganization(submitData)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success(isEdit.value ? '编辑成功' : '添加成功')
|
||||||
|
emit('success')
|
||||||
|
handleClose()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || (isEdit.value ? '编辑失败' : '添加失败'))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交失败:', error)
|
||||||
|
ElMessage.error('提交失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getLeaderList()
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
350
src/views/apps/erp/organization/index.vue
Normal file
350
src/views/apps/erp/organization/index.vue
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<template>
|
||||||
|
<div class="organization-container">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<!-- 左侧:组织架构树 -->
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card shadow="hover" class="tree-card" v-loading="loading">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>组织架构</span>
|
||||||
|
<el-button type="primary" link @click="handleAddRoot">
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
添加
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="treeData"
|
||||||
|
:props="treeProps"
|
||||||
|
node-key="id"
|
||||||
|
default-expand-all
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<div class="tree-node">
|
||||||
|
<span class="node-label">{{ node.label }}</span>
|
||||||
|
<div class="node-actions" @click.stop>
|
||||||
|
<el-button link type="primary" size="small" @click="handleAdd(data)">
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<el-button link type="primary" size="small" @click="handleEdit(data)">
|
||||||
|
<el-icon><Edit /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<el-button link type="danger" size="small" @click="handleDelete(data)">
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右侧:详情面板 -->
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-card shadow="hover" class="detail-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>{{ detailTitle }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div v-if="selectedNode" class="detail-content">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="部门名称">
|
||||||
|
{{ selectedNode.org_name }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="部门编码">
|
||||||
|
{{ selectedNode.org_code || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="上级部门">
|
||||||
|
{{ selectedNode.parent_name || '顶级部门' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="负责人">
|
||||||
|
{{ selectedNode.leader_name || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态" :span="2">
|
||||||
|
<el-tag :type="selectedNode.status === 1 ? 'success' : 'danger'">
|
||||||
|
{{ selectedNode.status === 1 ? '启用' : '禁用' }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">
|
||||||
|
{{ selectedNode.remark || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<div class="detail-actions">
|
||||||
|
<el-button type="primary" @click="handleEdit(selectedNode)">
|
||||||
|
<el-icon><Edit /></el-icon>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button type="danger" @click="handleDelete(selectedNode)">
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-empty v-else description="请选择左侧组织节点查看详情" />
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 添加/编辑对话框 -->
|
||||||
|
<OrganizationEdit
|
||||||
|
ref="editRef"
|
||||||
|
:tree-data="treeData"
|
||||||
|
:tree-props="treeProps"
|
||||||
|
@success="handleSuccess"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
|
||||||
|
import OrganizationEdit from './components/edit.vue'
|
||||||
|
import { getOrganizationList, getOrganizationDetail, deleteOrganization } from '@/api/erp'
|
||||||
|
|
||||||
|
// 树形结构数据(与后台字段对应)
|
||||||
|
interface TreeNode {
|
||||||
|
id: number
|
||||||
|
tenant_id?: number
|
||||||
|
org_name: string
|
||||||
|
org_code?: string
|
||||||
|
parent_id?: number
|
||||||
|
parent_name?: string
|
||||||
|
leader_id?: number
|
||||||
|
leader_name?: string
|
||||||
|
sort?: number
|
||||||
|
status?: number
|
||||||
|
remark?: string
|
||||||
|
children?: TreeNode[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 树形数据
|
||||||
|
const treeData = ref<TreeNode[]>([])
|
||||||
|
|
||||||
|
const treeProps = {
|
||||||
|
label: 'org_name',
|
||||||
|
children: 'children',
|
||||||
|
value: 'id'
|
||||||
|
}
|
||||||
|
|
||||||
|
const treeRef = ref()
|
||||||
|
const editRef = ref()
|
||||||
|
const selectedNode = ref<TreeNode | null>(null)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 将扁平列表构建为树形结构
|
||||||
|
const buildTree = (list: any[]): TreeNode[] => {
|
||||||
|
const nodeMap = new Map<number, TreeNode>()
|
||||||
|
const roots: TreeNode[] = []
|
||||||
|
|
||||||
|
list.forEach(item => {
|
||||||
|
const node: TreeNode = {
|
||||||
|
id: item.id,
|
||||||
|
tenant_id: item.tenant_id,
|
||||||
|
org_name: item.org_name,
|
||||||
|
org_code: item.org_code,
|
||||||
|
parent_id: item.parent_id,
|
||||||
|
parent_name: item.parent_name,
|
||||||
|
leader_id: item.leader_id,
|
||||||
|
leader_name: item.leader_name,
|
||||||
|
sort: item.sort,
|
||||||
|
status: item.status,
|
||||||
|
remark: item.remark,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
nodeMap.set(node.id, node)
|
||||||
|
})
|
||||||
|
|
||||||
|
nodeMap.forEach(node => {
|
||||||
|
if (node.parent_id && nodeMap.has(node.parent_id)) {
|
||||||
|
const parent = nodeMap.get(node.parent_id)!
|
||||||
|
if (!parent.children) {
|
||||||
|
parent.children = []
|
||||||
|
}
|
||||||
|
parent.children.push(node)
|
||||||
|
} else {
|
||||||
|
roots.push(node)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return roots
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取组织机构详情
|
||||||
|
const loadOrganizationDetail = async (id: number) => {
|
||||||
|
try {
|
||||||
|
const res = await getOrganizationDetail(id)
|
||||||
|
if (res.code === 200) {
|
||||||
|
const data = res.data || null
|
||||||
|
if (data) {
|
||||||
|
selectedNode.value = {
|
||||||
|
id: data.id,
|
||||||
|
tenant_id: data.tenant_id,
|
||||||
|
org_name: data.org_name,
|
||||||
|
org_code: data.org_code,
|
||||||
|
parent_id: data.parent_id,
|
||||||
|
parent_name: data.parent_name,
|
||||||
|
leader_id: data.leader_id,
|
||||||
|
leader_name: data.leader_name,
|
||||||
|
sort: data.sort,
|
||||||
|
status: data.status,
|
||||||
|
remark: data.remark,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedNode.value = null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '获取组织机构详情失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取组织机构详情失败:', error)
|
||||||
|
ElMessage.error('获取组织机构详情失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取组织机构列表
|
||||||
|
const fetchOrganizationList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getOrganizationList()
|
||||||
|
if (res.code === 200) {
|
||||||
|
const list = res.data || []
|
||||||
|
treeData.value = buildTree(list)
|
||||||
|
|
||||||
|
// 如果当前没有选中的节点且有数据,默认加载第一个节点详情
|
||||||
|
if (!selectedNode.value && list.length) {
|
||||||
|
await loadOrganizationDetail(list[0].id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '获取组织机构列表失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取组织机构列表失败:', error)
|
||||||
|
ElMessage.error('获取组织机构列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情标题
|
||||||
|
const detailTitle = computed(() => {
|
||||||
|
return selectedNode.value ? `部门详情 - ${selectedNode.value.org_name}` : '部门详情'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击节点,加载详情
|
||||||
|
const handleNodeClick = (data: TreeNode) => {
|
||||||
|
loadOrganizationDetail(data.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加根节点
|
||||||
|
const handleAddRoot = () => {
|
||||||
|
editRef.value?.open(undefined, undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加子节点
|
||||||
|
const handleAdd = (data: TreeNode) => {
|
||||||
|
editRef.value?.open(undefined, data.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const handleEdit = (data: TreeNode) => {
|
||||||
|
editRef.value?.open(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交成功回调,重新加载列表
|
||||||
|
const handleSuccess = () => {
|
||||||
|
fetchOrganizationList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete = (data: TreeNode) => {
|
||||||
|
ElMessageBox.confirm(`确定要删除部门「${data.org_name}」吗?`, '提示', {
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const res = await deleteOrganization(data.id)
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
fetchOrganizationList()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '删除失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error)
|
||||||
|
ElMessage.error('删除失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchOrganizationList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.organization-container {
|
||||||
|
// padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-card {
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 8px;
|
||||||
|
|
||||||
|
.node-label {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-actions {
|
||||||
|
display: none;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .node-actions {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-card {
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
.el-descriptions {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user