401 lines
13 KiB
Vue
401 lines
13 KiB
Vue
<!-- 后勤模块 - 账户管理 -->
|
||
|
||
<template>
|
||
<div class="MainBox">
|
||
<el-row :gutter="20">
|
||
<!-- 左侧树形结构 -->
|
||
<el-col :span="8">
|
||
<div class="CardBox">
|
||
<div class="LeftTitle">组织架构树</div>
|
||
<div class="TreeBox">
|
||
<el-tree :data="treeData" :props="treeProps" show-line default-expand-all highlight-current
|
||
@current-change="handleTreeChange" v-loading="loading" :expand-on-click-node="false" />
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
|
||
<!-- 右侧节点详情 -->
|
||
<el-col :span="16">
|
||
<el-card class="detail-card" shadow="hover">
|
||
<template #header>
|
||
<span>节点详情</span>
|
||
</template>
|
||
<el-form :model="JDformData" label-width="120px" label-position="top">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="节点名称">
|
||
<el-input v-model="JDformData.deptName" disabled />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="节点编码">
|
||
<el-input v-model="JDformData.deptId" disabled />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="上级节点">
|
||
<el-input v-model="JDformData.parentName" disabled />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="创建时间">
|
||
<el-input v-model="JDformData.createTime" disabled />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</el-card>
|
||
|
||
<!-- 关联账户 -->
|
||
<!-- <el-card class="account-card" shadow="hover" style="margin-top: 20px;">
|
||
<template #header>
|
||
<span>关联账户</span>
|
||
</template>
|
||
<el-table :data="accountList" height="230px">
|
||
<el-table-column prop="accountName" label="账户名" />
|
||
<el-table-column prop="realName" label="姓名" />
|
||
<el-table-column prop="unit" label="所属单位" />
|
||
<el-table-column prop="phone" label="联系电话" />
|
||
<el-table-column prop="role" label="角色" />
|
||
<el-table-column prop="status" label="状态">
|
||
<template #default="{ row }">
|
||
<el-tag :type="getStatusTagType(row.status)">{{ row.status }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
</el-table>
|
||
<el-pagination layout="prev, pager, next" :total="25" :page-size="10" :current-page="1"
|
||
class="float-right" />
|
||
</el-card> -->
|
||
</el-col>
|
||
</el-row>
|
||
<!-- 账户列表 -->
|
||
<el-row :gutter="20">
|
||
<el-col :span="24">
|
||
<el-card class="account-card" shadow="hover" style="margin-top: 20px;">
|
||
<template #header>
|
||
<span>账户列表</span>
|
||
<el-button type="primary" icon="Plus" class="float-right" size="small"
|
||
@click="handleAddUserClick">新建账户</el-button>
|
||
</template>
|
||
<el-table :data="accountList" border height="350px">
|
||
<el-table-column prop="userName" label="账户名" />
|
||
<el-table-column prop="nickName" label="姓名" />
|
||
<el-table-column prop="deptName" label="所属单位">
|
||
<template #default="{ row }">
|
||
{{ row.dept.deptName || '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="phonenumber" label="联系电话" />
|
||
<el-table-column prop="roleNames" label="角色" />
|
||
<el-table-column prop="status" label="状态">
|
||
<template #default="{ row }">
|
||
<el-tag :type="getStatusTagType(row.status)">{{ statusMap[row.status] }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作">
|
||
<template #default="{ row }">
|
||
<el-button v-if="row.status === '2'" type="text" icon="Edit"
|
||
@click="handleEditUser(row)">编辑</el-button>
|
||
<el-button type="text" icon="Delete" @click="handleDeleteUser(row)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="PageBox">
|
||
<el-pagination :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize"
|
||
:total="pageInfo.total" layout="total, prev, pager, next"
|
||
@current-change="handleCurrentChange" />
|
||
</div>
|
||
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 账户【新增/编辑/查看】弹窗 -->
|
||
<UserDialog v-if="dialogShow" :show="dialogShow" :userId="userId" :CloseDialog="handleCancel" />
|
||
</div>
|
||
</template>
|
||
<script setup>
|
||
import { ref, onMounted, getCurrentInstance, reactive } from 'vue'
|
||
import { listDept } from '@/api/treeRatingManagement'
|
||
import { listUser, delUser } from '@/api/system/user.js'
|
||
import UserDialog from "./UserDialog.vue";
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
const { proxy } = getCurrentInstance()
|
||
|
||
// 用户状态对照表
|
||
const statusMap = {
|
||
'0': '已生效',
|
||
'1': '已停用',
|
||
'2': '待审核',
|
||
'3': '已驳回',
|
||
}
|
||
|
||
const dialogShow = ref(false); // 新增账户弹窗显示状态
|
||
|
||
// 分页信息
|
||
const pageInfo = reactive({
|
||
total: 10,
|
||
pageSize: 10,
|
||
pageNum: 1,
|
||
})
|
||
|
||
// 当前操作的用户ID
|
||
const userId = ref('')
|
||
|
||
// 加载状态
|
||
const loading = ref(false)
|
||
|
||
// 树形结构数据
|
||
const treeData = ref([])
|
||
|
||
// 树形结构配置
|
||
const treeProps = {
|
||
children: 'children',
|
||
label: 'label'
|
||
}
|
||
|
||
// 节点表单数据
|
||
const JDformData = ref({
|
||
deptName: '',
|
||
deptId: '',
|
||
parentName: '',
|
||
parentId: '',
|
||
createTime: ''
|
||
})
|
||
|
||
|
||
// 账户列表数据
|
||
const accountList = ref([])
|
||
|
||
/** 将接口数据转换为树形结构格式 */
|
||
function convertToTreeData(data) {
|
||
if (!Array.isArray(data)) return []
|
||
|
||
return data.map(item => ({
|
||
label: item.deptName || item.name || item.label,
|
||
type: item.type || '单位',
|
||
status: item.status === '0' ? '已生效' : item.status === '1' ? '已禁用' : (item.status || '已生效'),
|
||
projects: item.projects || 0,
|
||
originalData: {
|
||
...item,
|
||
parentName: item.parentName || '',
|
||
}, // 保留原始数据,用于编辑和删除操作
|
||
children: item.children && item.children.length > 0 ? convertToTreeData(item.children) : undefined
|
||
}))
|
||
}
|
||
|
||
onMounted(() => {
|
||
getDeptTree()
|
||
getUserList()
|
||
})
|
||
|
||
// 获取组织架构树
|
||
const getDeptTree = async () => {
|
||
loading.value = true;
|
||
try {
|
||
const response = await listDept({
|
||
pageNum: '1',
|
||
pageSize: '1000',
|
||
})
|
||
if (response.code === 200) {
|
||
// 获取原始数据
|
||
let rawData = []
|
||
if (response.data && response.data.rows && Array.isArray(response.data.rows)) {
|
||
rawData = response.data.rows
|
||
} else if (response.rows && Array.isArray(response.rows)) {
|
||
rawData = response.rows
|
||
} else if (Array.isArray(response.data)) {
|
||
rawData = response.data
|
||
}
|
||
|
||
// 如果数据是扁平结构(有 parentId),使用 handleTree 转换为树形结构
|
||
// 如果数据已经是树形结构(有 children),直接使用
|
||
let treeStructure = []
|
||
if (rawData.length > 0 && rawData[0].parentId !== undefined) {
|
||
// 扁平结构,需要先处理 parentName
|
||
rawData = rawData.map(item => {
|
||
let parentName = ''
|
||
if (item.parentId && item.parentId !== 0) {
|
||
const parent = rawData.find(p => p.deptId === item.parentId)
|
||
if (parent) {
|
||
parentName = parent.deptName
|
||
}
|
||
}
|
||
return {
|
||
...item,
|
||
parentName,
|
||
}
|
||
})
|
||
// 转换为树形结构
|
||
treeStructure = proxy.handleTree(rawData, "deptId", "parentId", "children")
|
||
} else {
|
||
// 已经是树形结构
|
||
treeStructure = rawData
|
||
}
|
||
|
||
// 转换为组件需要的格式
|
||
let newData = convertToTreeData(treeStructure)
|
||
console.log('获取组织架构树成功:', newData)
|
||
treeData.value = newData
|
||
}
|
||
} catch (error) {
|
||
console.error('获取组织架构树失败:', error)
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
}
|
||
|
||
// 获取用户列表
|
||
const getUserList = async () => {
|
||
loading.value = true;
|
||
try {
|
||
const response = await listUser({
|
||
pageNum: pageInfo.pageNum,
|
||
pageSize: pageInfo.pageSize,
|
||
deptId: JDformData.value.deptId || '',
|
||
})
|
||
if (response.code === 200) {
|
||
accountList.value = response.rows || []
|
||
pageInfo.total = response.total || 0
|
||
}
|
||
} catch (error) {
|
||
console.error('获取用户列表失败:', error)
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
}
|
||
|
||
// 分页改变事件
|
||
const handleCurrentChange = (val) => {
|
||
pageInfo.pageNum = val
|
||
getUserList()
|
||
}
|
||
|
||
|
||
// 树形结构点击事件
|
||
const handleTreeChange = (data) => {
|
||
// 赋值节点表单数据
|
||
JDformData.value = {
|
||
deptName: data.label,
|
||
deptId: data.originalData.deptId,
|
||
parentName: data.originalData.parentName || '-',
|
||
parentId: data.originalData.parentId || '-',
|
||
createTime: data.originalData.createTime || '-'
|
||
}
|
||
console.log(data, '获取当前节点', JDformData.value)
|
||
// 刷新用户列表
|
||
getUserList()
|
||
}
|
||
|
||
// 获取状态标签类型
|
||
const getStatusTagType = (status) => {
|
||
if (status === '0') return 'success'
|
||
if (status === '1') return 'info'
|
||
if (status === '2') return 'primary'
|
||
if (status === '3') return 'danger'
|
||
return 'info'
|
||
}
|
||
|
||
// 新增账户弹窗显示
|
||
const handleAddUserClick = () => {
|
||
dialogShow.value = true;
|
||
userId.value = ''
|
||
}
|
||
|
||
// 新增账户弹窗关闭
|
||
const handleCancel = () => {
|
||
dialogShow.value = false;
|
||
userId.value = ''
|
||
getUserList()
|
||
}
|
||
|
||
// 编辑账户弹窗显示
|
||
const handleEditUser = (user) => {
|
||
dialogShow.value = true;
|
||
userId.value = user.userId
|
||
}
|
||
|
||
// 删除账户
|
||
const handleDeleteUser = async (user) => {
|
||
// 确认删除
|
||
const confirm = await ElMessageBox.confirm('确定删除账户 ' + user.userName + ' 吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
if (!confirm) return
|
||
try {
|
||
const response = await delUser(user.userId)
|
||
if (response.code === 200) {
|
||
ElMessage.success('删除成功')
|
||
getUserList()
|
||
} else {
|
||
ElMessage.error(response.msg || '删除失败')
|
||
}
|
||
} catch (error) {
|
||
console.error('删除账户失败:', error)
|
||
ElMessage.error('删除账户失败')
|
||
}
|
||
}
|
||
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.MainBox {
|
||
padding: 20px;
|
||
height: 100%;
|
||
background: #F9FAFB;
|
||
}
|
||
|
||
.CardBox {
|
||
height: 240px;
|
||
display: flex;
|
||
padding: 0px 26px;
|
||
background: #fff;
|
||
overflow: auto;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
flex-direction: column;
|
||
border-radius: 8px;
|
||
|
||
.LeftTitle {
|
||
font-size: 16px;
|
||
color: #303133;
|
||
line-height: 40px;
|
||
border-bottom: 1px solid #E4E7ED;
|
||
}
|
||
|
||
.TreeBox {
|
||
height: calc(100% - 100px);
|
||
margin-top: 20px;
|
||
border: 1px solid #E4E7ED;
|
||
overflow: auto;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
.detail-card {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.account-card {
|
||
position: relative;
|
||
}
|
||
|
||
.PageBox {
|
||
padding: 20px;
|
||
margin-top: 20px;
|
||
height: 40px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.float-right {
|
||
position: absolute;
|
||
right: 20px;
|
||
top: 14px;
|
||
}
|
||
</style> |