@@ -24,7 +24,7 @@ export default function createEnum(dictList) { | |||||
}; | }; | ||||
} | } | ||||
// 角色状态 | // 角色状态 | ||||
export const RULE_STATUS = createEnum([ | |||||
export const ROLE_STATUS = createEnum([ | |||||
{ | { | ||||
value: 0, | value: 0, | ||||
label: "启用", | label: "启用", | ||||
@@ -45,7 +45,7 @@ | |||||
<el-table-column align="center" property="roleName" label="角色名称" /> | <el-table-column align="center" property="roleName" label="角色名称" /> | ||||
<el-table-column align="center" property="status" label="状态"> | <el-table-column align="center" property="status" label="状态"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
{{ RULE_STATUS.getLabelByValue(scope.row.status) }} | |||||
{{ ROLE_STATUS.getLabelByValue(scope.row.status) }} | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column align="center" property="createTime" label="创建时间" /> | <el-table-column align="center" property="createTime" label="创建时间" /> | ||||
@@ -67,10 +67,10 @@ | |||||
<el-main> | <el-main> | ||||
<div class="sf-title">分配功能权限</div> | <div class="sf-title">分配功能权限</div> | ||||
<el-table :data="tableData" border row-key="id" :span-method="handleSpanMethod"> | |||||
<el-table-column align="center" property="firstLevel" label="一级功能" /> | |||||
<el-table-column align="center" property="secondLevel" label="二级功能" /> | |||||
<!-- <el-table-column align="center" property="thirdLevel" label="权限名称" /> --> | |||||
<el-table :data="tableData" border row-key="id" :span-method="mergeTable"> | |||||
<el-table-column align="center" property="moduleName" label="模块" /> | |||||
<el-table-column align="center" property="firstName" label="一级功能" /> | |||||
<el-table-column align="center" property="secondName" label="二级功能" /> | |||||
</el-table> | </el-table> | ||||
</el-main> | </el-main> | ||||
</el-container> | </el-container> | ||||
@@ -82,9 +82,10 @@ | |||||
<script> | <script> | ||||
import ApiButton from "@/components/ApiButton/index.vue"; | import ApiButton from "@/components/ApiButton/index.vue"; | ||||
import CrudPopup from "../roleList/components/CrudPopup/index.vue"; | import CrudPopup from "../roleList/components/CrudPopup/index.vue"; | ||||
import { getRoleAllList } from "@/api/userManage/role"; | |||||
import { getRoleMenuList, geMenuTreeList } from '@/api/userManage/menu' | |||||
import { RULE_STATUS } from '@/enums/index' | |||||
import { getRoleAllList } from "@/api/userManage/role"; | |||||
import { getRoleMenuList, geMenuTreeList } from "@/api/userManage/menu"; | |||||
import { ROLE_STATUS } from "@/enums/index"; | |||||
import { to } from "await-to-js"; | |||||
export default { | export default { | ||||
name: "RoleDetail", | name: "RoleDetail", | ||||
components: { | components: { | ||||
@@ -93,43 +94,22 @@ export default { | |||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
RULE_STATUS, | |||||
loading: true, | |||||
ROLE_STATUS, | |||||
loading: false, | |||||
roleList: [], | roleList: [], | ||||
currentRole: null, | currentRole: null, | ||||
doctorWorkPers: [], | |||||
saleManagePers: [], | |||||
saleProcessPers: [], | |||||
doctorWorkMenus: [], | |||||
saleManageMenus: [], | |||||
saleProcessMenus: [], | |||||
tableData: [], | |||||
treeData: [], | treeData: [], | ||||
menuIds: [], | |||||
}; | }; | ||||
}, | }, | ||||
created() { | created() { | ||||
Promise.all([this.loadRoleList(), this.loadTreeList()]).finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
computed: { | |||||
currentMenus() { | |||||
if (this.menuIds.length === 0 || this.treeData.length === 0) return []; | |||||
return this.filterMenusAndKeepParents(this.treeData, this.menuIds); | |||||
}, | |||||
tableData() { | |||||
const result = []; | |||||
const flattenMenuData = (data, parentNames = []) => { | |||||
data.forEach((item) => { | |||||
if (item.children?.length > 0) { | |||||
flattenMenuData(item.children, [...parentNames, item.menuName]); | |||||
} else { | |||||
const [firstLevel, secondLevel, ...others] = [...parentNames, item.menuName]; | |||||
result.push({ | |||||
firstLevel, | |||||
secondLevel, | |||||
thirdLevel: others.join("/"), | |||||
}); | |||||
} | |||||
}); | |||||
}; | |||||
flattenMenuData(this.currentMenus); | |||||
return this.mergeRowsAndCols(result); | |||||
}, | |||||
this.init(); | |||||
}, | }, | ||||
watch: { | watch: { | ||||
currentRole(val) { | currentRole(val) { | ||||
@@ -139,87 +119,47 @@ export default { | |||||
}, | }, | ||||
}, | }, | ||||
methods: { | methods: { | ||||
async init() { | |||||
this.loading = true; | |||||
Promise.all([this.loadRoleList(), this.loadTreeList()]).finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
loadRoleList() { | loadRoleList() { | ||||
return getRoleAllList().then((res) => { | return getRoleAllList().then((res) => { | ||||
console.log("getRoleAllList=", res); | |||||
this.roleList = res.data; | this.roleList = res.data; | ||||
let selectRole; | let selectRole; | ||||
if (this.currentRole) { | if (this.currentRole) { | ||||
selectRole = this.roleList.find((item) => item.id === this.currentRole.id); | selectRole = this.roleList.find((item) => item.id === this.currentRole.id); | ||||
} | } | ||||
this.$refs.singleTable.setCurrentRow(selectRole || res.data[0]); | |||||
this.$nextTick(() => { | |||||
this.$refs.singleTable.setCurrentRow(selectRole || res.data[0]); | |||||
}); | |||||
}); | }); | ||||
}, | }, | ||||
loadTreeList() { | loadTreeList() { | ||||
return geMenuTreeList().then((res) => { | return geMenuTreeList().then((res) => { | ||||
this.treeData = res.data; | |||||
}); | |||||
}, | |||||
loadMenuIdList(roleId) { | |||||
return getRoleMenuList({ roleId }).then((res) => { | |||||
this.menuIds = res.data.map((item) => item.menuId); | |||||
this.doctorWorkMenus = res?.data?.doctorWork || []; | |||||
this.saleManageMenus = res?.data?.saleManage || []; | |||||
this.saleProcessMenus = res?.data?.saleProcess || []; | |||||
}); | }); | ||||
}, | }, | ||||
// 添加角色 {} | |||||
// 计算表格合并相同项 | |||||
mergeRowsAndCols(inputList) { | |||||
const firstLevelCount = {}; | |||||
const secondLevelCount = {}; | |||||
const outputList = []; | |||||
inputList.forEach((item) => { | |||||
const { firstLevel, secondLevel } = item; | |||||
firstLevelCount[firstLevel] = (firstLevelCount[firstLevel] || 0) + 1; | |||||
secondLevelCount[secondLevel] = (secondLevelCount[secondLevel] || 0) + 1; | |||||
}); | |||||
inputList.forEach((item, index) => { | |||||
const { firstLevel, secondLevel, thirdLevel } = item; | |||||
const newItem = { firstLevel, secondLevel, thirdLevel }; | |||||
if (firstLevelCount[firstLevel] > 1) { | |||||
if (index === inputList.findIndex((x) => x.firstLevel === firstLevel)) { | |||||
newItem.firstRowSpan = firstLevelCount[firstLevel]; | |||||
} else { | |||||
newItem.firstColSpan = 0; | |||||
} | |||||
} | |||||
if (secondLevelCount[secondLevel] > 1) { | |||||
if (index === inputList.findIndex((x) => x.secondLevel === secondLevel)) { | |||||
newItem.secondRowSpan = secondLevelCount[secondLevel]; | |||||
} else { | |||||
newItem.secondColSpan = 0; | |||||
} | |||||
} | |||||
outputList.push(newItem); | |||||
}); | |||||
return outputList; | |||||
}, | |||||
// 根据全量菜单过滤 | |||||
filterMenusAndKeepParents(menus, menuIds) { | |||||
const filteredMenus = []; | |||||
for (const menu of menus) { | |||||
if (menuIds.includes(menu.id)) { | |||||
// 如果菜单在menuIds中,则保留该菜单 | |||||
const filteredMenu = { ...menu }; | |||||
// 如果菜单有子菜单,递归过滤并保留父菜单 | |||||
if (menu.children) { | |||||
filteredMenu.children = this.filterMenusAndKeepParents(menu.children, menuIds); | |||||
} | |||||
filteredMenus.push(filteredMenu); | |||||
} else if (menu.children) { | |||||
// 如果菜单不在menuIds中但有子菜单,递归过滤并保留父菜单 | |||||
const filteredChildren = this.filterMenusAndKeepParents(menu.children, menuIds); | |||||
if (filteredChildren.length > 0) { | |||||
const filteredMenu = { ...menu, children: filteredChildren }; | |||||
filteredMenus.push(filteredMenu); | |||||
} | |||||
} | |||||
async loadMenuIdList() { | |||||
const [err, res] = await to(getRoleMenuList({ roleId: this.currentRole.id })); | |||||
if (!err) { | |||||
this.doctorWorkPers = res?.data?.doctorWork || []; | |||||
this.saleManagePers = res?.data?.saleManage || []; | |||||
this.saleProcessPers = res?.data?.saleProcess || []; | |||||
this.tableData = this.packageTableData(); | |||||
} else { | |||||
this.doctorWorkPers = []; | |||||
this.saleManagePers = []; | |||||
this.saleProcessPers = []; | |||||
this.permissionTableData = []; | |||||
this.tableData = []; | |||||
} | } | ||||
return filteredMenus; | |||||
console.log("getRoleMenuList=", res); | |||||
}, | }, | ||||
handleCurrentChange(item) { | handleCurrentChange(item) { | ||||
this.currentRole = item; | this.currentRole = item; | ||||
@@ -236,23 +176,115 @@ export default { | |||||
this.$refs.crud | this.$refs.crud | ||||
.open({ | .open({ | ||||
...this.currentRole, | ...this.currentRole, | ||||
menuIdList: this.menuIds, | |||||
}) | }) | ||||
.then(this.loadRoleList); | .then(this.loadRoleList); | ||||
}, | }, | ||||
handleSpanMethod({ row, column, rowIndex, columnIndex }) { | |||||
packageTableData: (() => { | |||||
let tableData = []; | |||||
let doctorWorkData = []; | |||||
let saleManageData = []; | |||||
let saleProcessData = []; | |||||
return function () { | |||||
tableData = []; | |||||
doctorWorkData = []; | |||||
saleManageData = []; | |||||
saleProcessData = []; | |||||
if (this.doctorWorkMenus?.length > 0) { | |||||
this.doctorWorkMenus?.forEach((item) => { | |||||
const { children = [], menuName: firstName, ...otherItem } = item; | |||||
(children || []).forEach((item2, index2) => { | |||||
const { menuName: secondName, id } = item2; | |||||
if (!this.doctorWorkPers.includes(id)) { | |||||
return | |||||
} | |||||
let pushItem = { | |||||
id, | |||||
firstName, | |||||
secondName, | |||||
}; | |||||
if (index2 === 0) { | |||||
pushItem.rowspan2 = children.length; | |||||
} | |||||
doctorWorkData.push(pushItem); | |||||
}); | |||||
}); | |||||
} | |||||
if (doctorWorkData.length > 0) { | |||||
doctorWorkData[0].rowspan = doctorWorkData.length; | |||||
doctorWorkData[0].moduleName = "随访中心" | |||||
} | |||||
if (this.saleManageMenus?.length > 0) { | |||||
this.saleManageMenus.forEach((item) => { | |||||
const { children = [], menuName: firstName, ...otherItem } = item; | |||||
(children || []).forEach((item2, index2) => { | |||||
const { menuName: secondName, id } = item2; | |||||
if (!this.saleManagePers.includes(id)) { | |||||
return | |||||
} | |||||
let pushItem = { | |||||
id, | |||||
firstName, | |||||
secondName, | |||||
}; | |||||
if (index2 === 0) { | |||||
pushItem.rowspan2 = children.length; | |||||
} | |||||
saleManageData.push(pushItem); | |||||
}); | |||||
}); | |||||
} | |||||
if (saleManageData.length > 0) { | |||||
saleManageData[0].rowspan = saleManageData.length; | |||||
saleManageData[0].moduleName = "营销中心-管理层"; | |||||
} | |||||
if (this.saleProcessMenus?.length > 0) { | |||||
this.saleProcessMenus.forEach((item) => { | |||||
const { children = [], menuName: firstName, ...otherItem } = item; | |||||
(children || []).forEach((item2, index2) => { | |||||
const { menuName: secondName, id } = item2; | |||||
if (!this.saleProcessPers.includes(id)) { | |||||
return | |||||
} | |||||
let pushItem = { | |||||
id, | |||||
firstName, | |||||
secondName, | |||||
}; | |||||
if (index2 === 0) { | |||||
pushItem.rowspan2 = children.length; | |||||
} | |||||
saleProcessData.push(pushItem); | |||||
}); | |||||
}); | |||||
} | |||||
if (saleProcessData.length > 0) { | |||||
saleProcessData[0].rowspan = saleManageData.length; | |||||
saleProcessData[0].moduleName = "营销中心-执行层"; | |||||
} | |||||
tableData = [...doctorWorkData, ...saleManageData, ...saleProcessData]; | |||||
return tableData; | |||||
}; | |||||
})(), | |||||
mergeTable({row, column, rowIndex, columnIndex}) { | |||||
if (columnIndex === 0) { | if (columnIndex === 0) { | ||||
return { | return { | ||||
rowspan: row.firstRowSpan >= 0 ? row.firstRowSpan : 1, | |||||
colspan: row.firstColSpan >= 0 ? row.firstColSpan : 1, | |||||
}; | |||||
rowspan: row.rowspan ? row.rowspan : 0, | |||||
colspan: 1 | |||||
} | |||||
} else if (columnIndex === 1) { | } else if (columnIndex === 1) { | ||||
return { | return { | ||||
rowspan: row.secondRowSpan >= 0 ? row.secondRowSpan : 1, | |||||
colspan: row.secondColSpan >= 0 ? row.secondColSpan : 1, | |||||
}; | |||||
rowspan: row.rowspan2 ? row.rowspan2 : 0, | |||||
colspan: 1 | |||||
} | |||||
} else { | |||||
return { | |||||
rowspan: 1, | |||||
colspan: 1 | |||||
} | |||||
} | } | ||||
}, | |||||
} | |||||
}, | }, | ||||
}; | }; | ||||
</script> | </script> | ||||
@@ -0,0 +1,265 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-container style="height: 100%; border: 1px solid #eee" v-loading="loading"> | |||||
<el-aside | |||||
width="400px" | |||||
style=" | |||||
background-color: transparent; | |||||
border-right: 1px solid #eee; | |||||
margin: 0; | |||||
padding-top: 40px; | |||||
" | |||||
> | |||||
<el-table | |||||
ref="singleTable" | |||||
:data="roleList" | |||||
highlight-current-row | |||||
@current-change="handleCurrentChange" | |||||
:show-header="false" | |||||
border | |||||
> | |||||
<el-table-column align="center" property="roleName" label="角色名称" /> | |||||
<template slot="append"> | |||||
<div | |||||
@click="handleAddRole" | |||||
style=" | |||||
height: 44px; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
cursor: pointer; | |||||
" | |||||
> | |||||
<i class="el-icon-plus mr5" style="color: #1890ff"></i> | |||||
<el-button type="text">新增角色</el-button> | |||||
</div> | |||||
</template> | |||||
</el-table> | |||||
</el-aside> | |||||
<el-container> | |||||
<el-header height="auto"> | |||||
<div class="sf-title mt10">角色信息</div> | |||||
<el-table :data="currentRole ? [currentRole] : []" border> | |||||
<el-table-column align="center" property="id" label="角色ID" /> | |||||
<el-table-column align="center" property="roleName" label="角色名称" /> | |||||
<el-table-column align="center" property="status" label="状态"> | |||||
<template slot-scope="scope"> | |||||
{{ ROLE_STATUS.getLabelByValue(scope.row.status) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="createTime" label="创建时间" /> | |||||
<el-table-column align="center" property="updateTime" label="最后编辑时间" /> | |||||
<el-table-column | |||||
align="center" | |||||
label="操作" | |||||
class-name="small-padding fixed-width" | |||||
fixed="right" | |||||
> | |||||
<template slot-scope="scope"> | |||||
<el-button size="mini" type="text" @click="handleEditRole(scope.row)"> | |||||
编辑 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
</el-header> | |||||
<el-main> | |||||
<div class="sf-title">分配功能权限</div> | |||||
<el-table :data="tableData" border row-key="id" :span-method="handleSpanMethod"> | |||||
<el-table-column align="center" property="firstLevel" label="一级功能" /> | |||||
<el-table-column align="center" property="secondLevel" label="二级功能" /> | |||||
<!-- <el-table-column align="center" property="thirdLevel" label="权限名称" /> --> | |||||
</el-table> | |||||
</el-main> | |||||
</el-container> | |||||
</el-container> | |||||
<CrudPopup ref="crud" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import ApiButton from "@/components/ApiButton/index.vue"; | |||||
import CrudPopup from "../roleList/components/CrudPopup/index.vue"; | |||||
import { getRoleAllList } from "@/api/userManage/role"; | |||||
import { getRoleMenuList, geMenuTreeList } from '@/api/userManage/menu' | |||||
import { ROLE_STATUS } from '@/enums/index' | |||||
export default { | |||||
name: "RoleDetail", | |||||
components: { | |||||
ApiButton, | |||||
CrudPopup, | |||||
}, | |||||
data() { | |||||
return { | |||||
ROLE_STATUS, | |||||
loading: true, | |||||
roleList: [], | |||||
currentRole: null, | |||||
treeData: [], | |||||
menuIds: [], | |||||
}; | |||||
}, | |||||
created() { | |||||
Promise.all([this.loadRoleList(), this.loadTreeList()]).finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
computed: { | |||||
currentMenus() { | |||||
if (this.menuIds.length === 0 || this.treeData.length === 0) return []; | |||||
return this.filterMenusAndKeepParents(this.treeData, this.menuIds); | |||||
}, | |||||
tableData() { | |||||
const result = []; | |||||
const flattenMenuData = (data, parentNames = []) => { | |||||
data.forEach((item) => { | |||||
if (item.children?.length > 0) { | |||||
flattenMenuData(item.children, [...parentNames, item.menuName]); | |||||
} else { | |||||
const [firstLevel, secondLevel, ...others] = [...parentNames, item.menuName]; | |||||
result.push({ | |||||
firstLevel, | |||||
secondLevel, | |||||
thirdLevel: others.join("/"), | |||||
}); | |||||
} | |||||
}); | |||||
}; | |||||
flattenMenuData(this.currentMenus); | |||||
return this.mergeRowsAndCols(result); | |||||
}, | |||||
}, | |||||
watch: { | |||||
currentRole(val) { | |||||
if (val?.id) { | |||||
this.loadMenuIdList(val.id); | |||||
} | |||||
}, | |||||
}, | |||||
methods: { | |||||
loadRoleList() { | |||||
return getRoleAllList().then((res) => { | |||||
this.roleList = res.data; | |||||
let selectRole; | |||||
if (this.currentRole) { | |||||
selectRole = this.roleList.find((item) => item.id === this.currentRole.id); | |||||
} | |||||
this.$refs.singleTable.setCurrentRow(selectRole || res.data[0]); | |||||
}); | |||||
}, | |||||
loadTreeList() { | |||||
return geMenuTreeList().then((res) => { | |||||
console.log('geMenuTreeList=', res) | |||||
this.treeData = res.data; | |||||
}); | |||||
}, | |||||
loadMenuIdList(roleId) { | |||||
return getRoleMenuList({ roleId }).then((res) => { | |||||
console.log('getRoleMenuList=', res) | |||||
this.menuIds = res.data.map((item) => item.menuId); | |||||
}); | |||||
}, | |||||
// 添加角色 {} | |||||
// 计算表格合并相同项 | |||||
mergeRowsAndCols(inputList) { | |||||
const firstLevelCount = {}; | |||||
const secondLevelCount = {}; | |||||
const outputList = []; | |||||
inputList.forEach((item) => { | |||||
const { firstLevel, secondLevel } = item; | |||||
firstLevelCount[firstLevel] = (firstLevelCount[firstLevel] || 0) + 1; | |||||
secondLevelCount[secondLevel] = (secondLevelCount[secondLevel] || 0) + 1; | |||||
}); | |||||
inputList.forEach((item, index) => { | |||||
const { firstLevel, secondLevel, thirdLevel } = item; | |||||
const newItem = { firstLevel, secondLevel, thirdLevel }; | |||||
if (firstLevelCount[firstLevel] > 1) { | |||||
if (index === inputList.findIndex((x) => x.firstLevel === firstLevel)) { | |||||
newItem.firstRowSpan = firstLevelCount[firstLevel]; | |||||
} else { | |||||
newItem.firstColSpan = 0; | |||||
} | |||||
} | |||||
if (secondLevelCount[secondLevel] > 1) { | |||||
if (index === inputList.findIndex((x) => x.secondLevel === secondLevel)) { | |||||
newItem.secondRowSpan = secondLevelCount[secondLevel]; | |||||
} else { | |||||
newItem.secondColSpan = 0; | |||||
} | |||||
} | |||||
outputList.push(newItem); | |||||
}); | |||||
return outputList; | |||||
}, | |||||
// 根据全量菜单过滤 | |||||
filterMenusAndKeepParents(menus, menuIds) { | |||||
const filteredMenus = []; | |||||
for (const menu of menus) { | |||||
if (menuIds.includes(menu.id)) { | |||||
// 如果菜单在menuIds中,则保留该菜单 | |||||
const filteredMenu = { ...menu }; | |||||
// 如果菜单有子菜单,递归过滤并保留父菜单 | |||||
if (menu.children) { | |||||
filteredMenu.children = this.filterMenusAndKeepParents(menu.children, menuIds); | |||||
} | |||||
filteredMenus.push(filteredMenu); | |||||
} else if (menu.children) { | |||||
// 如果菜单不在menuIds中但有子菜单,递归过滤并保留父菜单 | |||||
const filteredChildren = this.filterMenusAndKeepParents(menu.children, menuIds); | |||||
if (filteredChildren.length > 0) { | |||||
const filteredMenu = { ...menu, children: filteredChildren }; | |||||
filteredMenus.push(filteredMenu); | |||||
} | |||||
} | |||||
} | |||||
return filteredMenus; | |||||
}, | |||||
handleCurrentChange(item) { | |||||
this.currentRole = item; | |||||
}, | |||||
// 新增角色 | |||||
handleAddRole() { | |||||
this.$refs.crud.open().then((res) => { | |||||
this.currentRole = res; | |||||
this.loadRoleList(); | |||||
}); | |||||
}, | |||||
// 编辑角色 | |||||
handleEditRole() { | |||||
this.$refs.crud | |||||
.open({ | |||||
...this.currentRole, | |||||
menuIdList: this.menuIds, | |||||
}) | |||||
.then(this.loadRoleList); | |||||
}, | |||||
handleSpanMethod({ row, column, rowIndex, columnIndex }) { | |||||
if (columnIndex === 0) { | |||||
return { | |||||
rowspan: row.firstRowSpan >= 0 ? row.firstRowSpan : 1, | |||||
colspan: row.firstColSpan >= 0 ? row.firstColSpan : 1, | |||||
}; | |||||
} else if (columnIndex === 1) { | |||||
return { | |||||
rowspan: row.secondRowSpan >= 0 ? row.secondRowSpan : 1, | |||||
colspan: row.secondColSpan >= 0 ? row.secondColSpan : 1, | |||||
}; | |||||
} | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.app-container { | |||||
height: 100%; | |||||
} | |||||
</style> |
@@ -1,5 +1,5 @@ | |||||
<template> | <template> | ||||
<Popup ref="popup" title="角色信息" @closed="dialogClosed"> | |||||
<Popup ref="popup" title="角色信息" width="800px" @closed="dialogClosed"> | |||||
<el-form :model="form" :rules="rules" ref="form" label-width="80px"> | <el-form :model="form" :rules="rules" ref="form" label-width="80px"> | ||||
<el-form-item label="角色名称" prop="roleName" placeholder="请输入角色名称"> | <el-form-item label="角色名称" prop="roleName" placeholder="请输入角色名称"> | ||||
<el-input v-model="form.roleName" :maxlength="32"></el-input> | <el-input v-model="form.roleName" :maxlength="32"></el-input> | ||||
@@ -9,22 +9,61 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item label="角色状态" prop="status" required> | <el-form-item label="角色状态" prop="status" required> | ||||
<el-switch | <el-switch | ||||
:value="form.status === RULE_STATUS.getValueByName('enabled')" | |||||
@change="form.status = $event ? RULE_STATUS.getValueByName('enabled') : RULE_STATUS.getValueByName('disabled')" | |||||
:value="form.status === ROLE_STATUS.getValueByName('enabled')" | |||||
@change=" | |||||
form.status = $event | |||||
? ROLE_STATUS.getValueByName('enabled') | |||||
: ROLE_STATUS.getValueByName('disabled') | |||||
" | |||||
/> | /> | ||||
</el-form-item> | </el-form-item> | ||||
<el-form-item label="角色权限" prop="menuIdList"> | <el-form-item label="角色权限" prop="menuIdList"> | ||||
<div class="tree-menus"> | |||||
<el-tree | |||||
ref="tree" | |||||
v-model="form.menuIdList" | |||||
:data="treeData" | |||||
show-checkbox | |||||
node-key="id" | |||||
@check="handleSelectMenuChange" | |||||
:props="{ children: 'children', label: 'menuName', isLeaf: true }" | |||||
default-expand-all | |||||
></el-tree> | |||||
<div class="tree-menus" v-loading="loading"> | |||||
<div class="tree-menu-item"> | |||||
<div class="header">随访中心</div> | |||||
<div class="tree-menu-item-content"> | |||||
<el-tree | |||||
ref="tree" | |||||
:default-checked-keys="form.doctorWorkChecks" | |||||
:data="treeData" | |||||
show-checkbox | |||||
node-key="id" | |||||
@check="(_, val) => handleSelectMenuChange(val, 'doctorWorkChecks')" | |||||
:props="{ children: 'children', label: 'menuName', isLeaf: true }" | |||||
default-expand-all | |||||
></el-tree> | |||||
</div> | |||||
</div> | |||||
<div class="tree-menu-item"> | |||||
<div class="header">营销中心-管理层</div> | |||||
<div class="tree-menu-item-content"> | |||||
<el-tree | |||||
ref="tree2" | |||||
:default-checked-keys="form.saleManageChecks" | |||||
:data="treeData2" | |||||
show-checkbox | |||||
node-key="id" | |||||
@check="(_, val) => handleSelectMenuChange(val, 'saleManageChecks')" | |||||
:props="{ children: 'children', label: 'menuName', isLeaf: true }" | |||||
default-expand-all | |||||
></el-tree> | |||||
</div> | |||||
</div> | |||||
<div class="tree-menu-item"> | |||||
<div class="header">营销中心-执行层</div> | |||||
<div class="tree-menu-item-content"> | |||||
<el-tree | |||||
ref="tree3" | |||||
:default-checked-keys="form.saleProcessChecks" | |||||
:data="treeData3" | |||||
show-checkbox | |||||
node-key="id" | |||||
@check="(_, val) => handleSelectMenuChange(val, 'saleProcessChecks')" | |||||
:props="{ children: 'children', label: 'menuName', isLeaf: true }" | |||||
default-expand-all | |||||
></el-tree> | |||||
</div> | |||||
</div> | |||||
</div> | </div> | ||||
</el-form-item> | </el-form-item> | ||||
</el-form> | </el-form> | ||||
@@ -38,15 +77,16 @@ | |||||
<script> | <script> | ||||
import Popup from "@/components/Popup"; | import Popup from "@/components/Popup"; | ||||
import { saveRole } from "@/api/userManage/role"; | import { saveRole } from "@/api/userManage/role"; | ||||
import { getRoleMenuList, geMenuTreeList } from '@/api/userManage/menu' | |||||
import { RULE_STATUS } from '@/enums/index'; | |||||
import { getRoleMenuList, geMenuTreeList } from "@/api/userManage/menu"; | |||||
import { ROLE_STATUS } from "@/enums/index"; | |||||
import { to } from "await-to-js"; | |||||
export default { | export default { | ||||
components: { | components: { | ||||
Popup, | Popup, | ||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
RULE_STATUS, | |||||
ROLE_STATUS, | |||||
loading: false, | loading: false, | ||||
form: this.getFormDefaultValue(), | form: this.getFormDefaultValue(), | ||||
rules: { | rules: { | ||||
@@ -54,9 +94,25 @@ export default { | |||||
{ required: true, message: "请输入角色名称", trigger: "blur" }, | { required: true, message: "请输入角色名称", trigger: "blur" }, | ||||
{ max: 32, message: "长度不能超过32个字符", trigger: "blur" }, | { max: 32, message: "长度不能超过32个字符", trigger: "blur" }, | ||||
], | ], | ||||
menuIdList: [{ required: true, message: "请选择角色权限", trigger: "change" }], | |||||
menuIdList: [ | |||||
{ | |||||
validator: (rule, value, callback) => { | |||||
if ( | |||||
this.form.doctorWorkChecks?.length >= 0 || | |||||
this.form.saleManageChecks?.length >= 0 || | |||||
this.form.saleProcessChecks?.length >= 0 | |||||
) { | |||||
return callback(); | |||||
} | |||||
callback(new Error("请选择角色权限")); | |||||
}, | |||||
}, | |||||
], | |||||
}, | }, | ||||
treeData: [], | treeData: [], | ||||
treeData2: [], | |||||
treeData3: [], | |||||
loading: false, | |||||
}; | }; | ||||
}, | }, | ||||
created() { | created() { | ||||
@@ -65,39 +121,55 @@ export default { | |||||
methods: { | methods: { | ||||
loadAllMenuList() { | loadAllMenuList() { | ||||
return geMenuTreeList().then((res) => { | return geMenuTreeList().then((res) => { | ||||
this.treeData = res.data; | |||||
this.treeData = res.data?.doctorWork || []; | |||||
this.treeData2 = res.data?.saleManage || []; | |||||
this.treeData3 = res.data?.saleProcess || []; | |||||
}); | }); | ||||
}, | }, | ||||
loadMenuIdList(roleId) { | |||||
return getRoleMenuList({ roleId }).then((res) => { | |||||
this.form.menuIdList = res.data.map((item) => item.menuId); | |||||
async loadMenuIdList(roleId) { | |||||
this.loading = true; | |||||
const [err, res] = await to(getRoleMenuList({ roleId })); | |||||
if (!err) { | |||||
this.form.doctorWorkChecks = res?.data?.doctorWork || []; | |||||
this.form.saleManageChecks = res?.data?.saleManage || []; | |||||
this.form.saleProcessChecks = res?.data?.saleProcess || []; | |||||
} | |||||
this.$nextTick(() => { | |||||
console.log("this.$refs.tree=", this.$refs.tree); | |||||
this.$refs.tree.setCheckedKeys(this.form.doctorWorkChecks); | |||||
this.$refs.tree2.setCheckedKeys(this.form.saleManageChecks); | |||||
this.$refs.tree3.setCheckedKeys(this.form.saleProcessChecks); | |||||
}); | }); | ||||
this.loading = false; | |||||
}, | }, | ||||
handleSelectMenuChange(_, { checkedKeys, halfCheckedKeys }) { | |||||
this.form.menuIdList = checkedKeys; | |||||
this.$refs.form.validateField("menuIdList"); | |||||
handleSelectMenuChange({ checkedKeys, halfCheckedKeys }, property) { | |||||
console.log("property=", property); | |||||
this.form[property] = checkedKeys; | |||||
// this.form.menuIdList = checkedKeys; | |||||
this.$nextTick(() => { | |||||
this.$refs.form?.validateField("menuIdList"); | |||||
}); | |||||
}, | }, | ||||
getFormDefaultValue() { | getFormDefaultValue() { | ||||
return { | return { | ||||
roleName: "", | roleName: "", | ||||
status: RULE_STATUS.getValueByName('enabled'), | |||||
status: ROLE_STATUS.getValueByName("enabled"), | |||||
menuIdList: [], | menuIdList: [], | ||||
doctorWorkChecks: [], | |||||
saleManageChecks: [], | |||||
saleProcessChecks: [], | |||||
}; | }; | ||||
}, | }, | ||||
open(params) { | |||||
async open(params) { | |||||
console.log("params=", params); | |||||
await this.$nextTick(); | |||||
this.$refs.popup.open(params); | this.$refs.popup.open(params); | ||||
if (params) { | if (params) { | ||||
for (const key of Object.keys(this.form)) { | for (const key of Object.keys(this.form)) { | ||||
this.form[key] = params[key]; | this.form[key] = params[key]; | ||||
} | } | ||||
this.form.roleId = params.id; | this.form.roleId = params.id; | ||||
if (params.menuIdList) { | |||||
this.$nextTick(() => { | |||||
this.$refs.tree.setCheckedKeys(params.menuIdList); | |||||
}); | |||||
} else { | |||||
this.loadMenuIdList(params.id); | |||||
} | |||||
this.loadMenuIdList(params.id); | |||||
} | } | ||||
this.promise = {}; | this.promise = {}; | ||||
return new Promise((resolve, reject) => { | return new Promise((resolve, reject) => { | ||||
@@ -113,7 +185,12 @@ export default { | |||||
if (valid) { | if (valid) { | ||||
this.loading = true; | this.loading = true; | ||||
try { | try { | ||||
const res = await saveRole(this.form); | |||||
const { menuIdList, doctorWorkChecks, saleManageChecks, saleProcessChecks, ...params } = | |||||
this.form; | |||||
const res = await saveRole({ | |||||
menuIdList: [...doctorWorkChecks, ...saleManageChecks, ...saleProcessChecks], | |||||
...params, | |||||
}); | |||||
if (this.form.roleId) { | if (this.form.roleId) { | ||||
this.$message.success("修改成功"); | this.$message.success("修改成功"); | ||||
} else { | } else { | ||||
@@ -143,9 +220,34 @@ export default { | |||||
</script> | </script> | ||||
<style lang="scss" scoped> | <style lang="scss" scoped> | ||||
.tree-menus { | .tree-menus { | ||||
display: flex; | |||||
border: 1px solid #dfe4ed; | border: 1px solid #dfe4ed; | ||||
height: 200px; | |||||
border-radius: 4px; | border-radius: 4px; | ||||
overflow-y: auto; | |||||
.tree-menu-item { | |||||
flex: 1; | |||||
.header { | |||||
overflow-y: auto; | |||||
box-sizing: border-box; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
width: 100%; | |||||
height: 40px; | |||||
border-right: 1px solid #dfe4ed; | |||||
border-bottom: 1px solid #dfe4ed; | |||||
} | |||||
.header:last-child { | |||||
border-right: none; | |||||
} | |||||
.tree-menu-item-content { | |||||
overflow-y: auto; | |||||
height: 200px; | |||||
border-right: 1px solid #dfe4ed; | |||||
} | |||||
.tree-menu-item-content:last-child { | |||||
border-right: none; | |||||
} | |||||
} | |||||
} | } | ||||
</style> | </style> |
@@ -55,7 +55,7 @@ | |||||
/> | /> | ||||
<el-table-column align="center" label="状态" prop="status" :show-overflow-tooltip="true"> | <el-table-column align="center" label="状态" prop="status" :show-overflow-tooltip="true"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
{{ RULE_STATUS.getLabelByValue(scope.row.status) }} | |||||
{{ ROLE_STATUS.getLabelByValue(scope.row.status) }} | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column | <el-table-column | ||||
@@ -66,13 +66,13 @@ | |||||
> | > | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<el-button size="mini" type="text" @click="handleSwitchEnable(scope.row)"> | <el-button size="mini" type="text" @click="handleSwitchEnable(scope.row)"> | ||||
{{ scope.row.status === RULE_STATUS.getValueByName('enabled') ? "停用" : "启用" }} | |||||
{{ scope.row.status === ROLE_STATUS.getValueByName('enabled') ? "停用" : "启用" }} | |||||
</el-button> | </el-button> | ||||
<el-button | <el-button | ||||
size="mini" | size="mini" | ||||
type="text" | type="text" | ||||
@click="handleEdit(scope.row)" | @click="handleEdit(scope.row)" | ||||
:disabled="scope.row.status === RULE_STATUS.getValueByName('enabled')" | |||||
:disabled="scope.row.status === ROLE_STATUS.getValueByName('enabled')" | |||||
> | > | ||||
编辑 | 编辑 | ||||
</el-button> | </el-button> | ||||
@@ -80,7 +80,7 @@ | |||||
size="mini" | size="mini" | ||||
type="text" | type="text" | ||||
@click="handleDelete(scope.row)" | @click="handleDelete(scope.row)" | ||||
:disabled="scope.row.status === RULE_STATUS.getValueByName('enabled')" | |||||
:disabled="scope.row.status === ROLE_STATUS.getValueByName('enabled')" | |||||
> | > | ||||
删除 | 删除 | ||||
</el-button> | </el-button> | ||||
@@ -103,7 +103,7 @@ | |||||
import ApiButton from "@/components/ApiButton/index.vue"; | import ApiButton from "@/components/ApiButton/index.vue"; | ||||
import { rolePageList, disableRole, enableRole, delRole } from "@/api/userManage/role"; | import { rolePageList, disableRole, enableRole, delRole } from "@/api/userManage/role"; | ||||
import CrudPopup from "./components/CrudPopup/index.vue"; | import CrudPopup from "./components/CrudPopup/index.vue"; | ||||
import { RULE_STATUS } from '@/enums/index'; | |||||
import { ROLE_STATUS } from '@/enums/index'; | |||||
export default { | export default { | ||||
name: "RoleManage", | name: "RoleManage", | ||||
components: { | components: { | ||||
@@ -112,7 +112,7 @@ export default { | |||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
RULE_STATUS, | |||||
ROLE_STATUS, | |||||
// 遮罩层 | // 遮罩层 | ||||
loading: true, | loading: true, | ||||
// 显示搜索条件 | // 显示搜索条件 | ||||
@@ -178,7 +178,7 @@ export default { | |||||
/** 启用/禁用切换 */ | /** 启用/禁用切换 */ | ||||
handleSwitchEnable(item) { | handleSwitchEnable(item) { | ||||
const isEnable = item.status === this.RULE_STATUS.getValueByName('enabled'); | |||||
const isEnable = item.status === this.ROLE_STATUS.getValueByName('enabled'); | |||||
const fetch = async () => { | const fetch = async () => { | ||||
if (isEnable) { | if (isEnable) { | ||||
await disableRole(item.id); | await disableRole(item.id); | ||||