角色管理与机构管理基础功能实现

This commit is contained in:
高云鹏 2024-06-26 00:58:59 +08:00
parent 9a866632b6
commit 6d0796ae34
14 changed files with 911 additions and 32 deletions

View File

@ -5,7 +5,7 @@ ENV = 'development'
VITE_BASE_PATH = './'
# 代理配置(开发使用),必须在一行中
VITE_APP_PROXY=[["/api","http://192.168.130.12:8080/api"]]
VITE_APP_PROXY=[["/api","http://192.168.109.195:8080/api"]]
# 开发环境下跨域代理请输入要跨域的api地址 - 尾部无需带'/'
# VITE_PROXY_URL = 'http://localhost:8000'

View File

@ -16,6 +16,7 @@
"axios": "1.7.2",
"countup.js": "2.8.0",
"echarts": "5.5.0",
"element-china-area-data": "^6.1.0",
"element-plus": "2.7.4",
"esno": "4.7.0",
"font-awesome": "4.7.0",

View File

@ -2,4 +2,5 @@ export default{
search:'Search',
add:'Add',
'Query roles by name':'Query roles by name',
'Are you sure to delete this?':'Are you sure to delete this?'
}

View File

@ -2,4 +2,5 @@ export default{
search:'搜索',
add:'新增',
'Query roles by name':'按名称查询角色',
'Are you sure to delete this?':'确定要删除吗?',
}

View File

@ -24,6 +24,7 @@ import { useEventListener } from '@vueuse/core'
import { BEFORE_RESIZE_LAYOUT } from '/@/stores/constant/cacheKey'
import { isEmpty } from 'lodash-es'
import { setNavTabsWidth } from '/@/utils/layout'
import { id } from 'element-plus/es/locales.mjs'
defineOptions({
components: { Default, Classic, Streamline, Double },
@ -97,6 +98,36 @@ const menu = [
keepalive: 0,
extend: 'none',
children: [
{
id: 99,
pid: 98,
type: 'menu',
title: '角色管理',
name: 'auth\/RoleManagement',
path: 'auth\/RoleManagement',
icon: 'fa fa-group',
menu_type: 'tab',
url: '',
component: '\/src\/views\/backend\/RoleManagement\/RoleManagement.vue',
keepalive: 'auth\/RoleManagement',
extend: 'none',
children: [],
},
{
id: 97,
pid: 96,
type: 'menu',
title: '机构管理',
name: 'auth\/InstitutionalManagement',
path: 'auth\/InstitutionalManagement',
icon: 'fa fa-group',
menu_type: 'tab',
url: '',
component: '\/src\/views\/backend\/InstitutionalManagement\/InstitutionalManagement.vue',
keepalive: 'auth\/InstitutionalManagement',
extend: 'none',
children: [],
},
{
id: 3,
pid: 2,

View File

@ -14,6 +14,7 @@ export const useAdminInfo = defineStore('adminInfo', {
refresh_token: '',
// 是否是superAdmin用于判定是否显示终端按钮等不做任何权限判断
super: false,
orgid:0
}
},
actions: {

View File

@ -54,6 +54,7 @@ export interface AdminInfo {
token: string
refresh_token: string
super: boolean
orgid:number
}
export interface UserInfo {

View File

@ -1,24 +1,82 @@
<template>
<div class="instititionalManagement">
<div class="institutionalManagement">
<el-dialog v-model="dialogVible" :title="dialogTitle" width="600">
<el-form :model="formModel" ref="formRef">
<template v-for="item in addFormItemList" :key="item.prop">
<el-form-item :prop="item.prop" :label="item.label" label-width="80" :rules="item.rules">
<template v-if="item.type === 'input'">
<el-input v-model="formModel[item.prop]" :placeholder="item.placeholder"></el-input>
</template>
<template v-if="item.type === 'custom'">
<el-select
v-if="item.prop === 'province'"
v-model="formModel[item.prop]"
:placeholder="item.placeholder"
@change="changeProvince"
>
<el-option v-for="opt in provinceOptions" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
</el-select>
<el-select
v-if="item.prop === 'county'"
v-model="formModel[item.prop]"
:placeholder="item.placeholder"
@change="changeCounty"
>
<el-option v-for="opt in countyOptions" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
</el-select>
<el-select v-if="item.prop === 'city'" v-model="formModel[item.prop]" :placeholder="item.placeholder">
<el-option v-for="opt in cityOptions" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
</el-select>
</template>
</el-form-item>
</template>
</el-form>
<template #footer>
<el-button type="primary" @click="submitAddForm">提交</el-button>
<el-button @click="closeAddForm">关闭</el-button>
</template>
</el-dialog>
<el-container>
<el-aside class="defaultAside">
<el-header class="treeHeader">
<el-input v-model="searchInputTreeValue" :placeholder="treeSearchInputPlaceholder" class="searchInput"></el-input>
</el-header>
<el-main>
<el-tree :data="treeData"></el-tree>
<el-main class="treeMain">
<el-tree :data="treeData" lazy node-key="id" :load="loadTreeData" :props="treeReplaceProps" @node-click="treeNodeClick"></el-tree>
</el-main>
</el-aside>
<el-container>
<el-header class="defaultHeader">
<div class="searchPart">
<el-input class="searchInput"></el-input>
<el-button type="primary" :icon="Search" class="defaultBtn">{{ t('management.search') }}</el-button>
<el-input v-model:value="searchTableInput" class="searchInput"></el-input>
<el-button @click="searchTable" type="primary" :icon="Search" class="defaultBtn">{{ t('management.search') }}</el-button>
</div>
<el-button type="primary" :icon="Plus" class="defaultBtn">{{ t('management.add') }}</el-button>
<el-button type="primary" :icon="Plus" class="defaultBtn" @click="addInstitutional">{{ t('management.add') }}</el-button>
</el-header>
<el-main>
<el-table></el-table>
<el-main class="defaultMain">
<el-table :data="tableData">
<el-table-column
v-for="item in tableColumn"
:key="item.key"
:prop="item.prop"
:label="item.label"
:fixed="item.fixed"
:align="item.align ?? 'center'"
></el-table-column>
<el-table-column fixed="right" label="操作" min-width="80" align="center">
<template #default="scope">
<div class="tableOperate">
<a @click="editForm(scope.row)">编辑</a>
<a>|</a>
<el-popconfirm title="确定删除么?" @confirm="delForm(scope.row)">
<template #reference>
<a>删除</a>
</template>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
@ -26,15 +84,350 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElContainer, ElAside, ElHeader, ElMain, ElInput, ElButton, ElTable, ElTree } from 'element-plus'
import { onMounted, ref } from 'vue'
import {
ElContainer,
ElAside,
ElHeader,
ElMain,
ElInput,
ElButton,
ElTable,
ElTree,
ElDialog,
ElForm,
ElFormItem,
ElSelect,
ElOption,
ElPopconfirm,
ElMessage,
} from 'element-plus'
import type { FormInstance } from 'element-plus'
import type Node from 'element-plus/es/components/tree/src/model/node'
import { Plus, Search } from '@element-plus/icons-vue'
import {
getInstitutionalListReq,
addInstitutionalListReq,
changeInstitutionalListReq,
delInstitutionalListReq,
getInstitutionalTreeListReq,
} from './request'
import {
addDataEnum,
addDataType,
formItemListType,
addDataEnumKeyJointType,
tableColumnType,
changeDataType,
selectDataType,
getTreeDataReturnType,
} from './type'
import { pcaTextArr } from 'element-china-area-data'
import { useAdminInfo } from '/@/stores/adminInfo'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const adminInfo = useAdminInfo()
const treeSearchInputPlaceholder = '搜索机构'
const searchInputTreeValue = ref<string>('')
const treeData = ref()
const formRef = ref<FormInstance>()
const formModel = ref<addDataType | changeDataType>({
mrid: '',
name: '',
aliasName: '',
province: '',
city: '',
county: '',
address: '',
contactPhone: '',
remarks: '',
parentOrgId: null,
revision: 1,
})
const defaultFormModel = JSON.parse(JSON.stringify(formModel.value))
const provinceOptions: selectDataType[] = pcaTextArr
const countyOptions = ref<selectDataType[]>([])
const cityOptions = ref<selectDataType[]>([])
const changeProvince = (value: string) => {
const selectOptions = provinceOptions.find((item) => item.value === value)?.children
selectOptions && (countyOptions.value = selectOptions)
formModel.value.city = ''
formModel.value.county = ''
}
const changeCounty = (value: string) => {
const selectOptions = countyOptions.value.find((item) => item.value === value)?.children
selectOptions && (cityOptions.value = selectOptions)
formModel.value.city = ''
}
const phoneReg = /^1(3|4|5|7|8|9)\d{9}$/
const phoneRule = (rule: any, value: any, callback: any) => {
if (!value) {
callback(new Error('请输入手机号'))
} else if (!phoneReg.test(value)) {
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
}
const addFormItemList: formItemListType<addDataEnumKeyJointType>[] = [
{
type: 'input',
prop: 'mrid',
label: addDataEnum['mrid'],
placeholder: `请输入${addDataEnum['mrid']}`,
rules: [{ required: true, message: `请输入${addDataEnum['mrid']}`, trigger: 'blur' }],
},
{
type: 'input',
prop: 'name',
label: addDataEnum['name'],
placeholder: `请输入${addDataEnum['name']}`,
rules: [{ required: true, message: `请输入${addDataEnum['name']}`, trigger: 'blur' }],
},
{
type: 'input',
prop: 'aliasName',
label: addDataEnum['aliasName'],
placeholder: `请输入${addDataEnum['aliasName']}`,
rules: [{ required: true, message: `请输入${addDataEnum['aliasName']}`, trigger: 'blur' }],
},
{
type: 'custom',
prop: 'province',
label: addDataEnum['province'],
placeholder: `请选择${addDataEnum['province']}`,
rules: [{ required: true, message: `请选择${addDataEnum['province']}`, trigger: 'blur' }],
},
{
type: 'custom',
prop: 'county',
label: addDataEnum['county'],
placeholder: `请选择${addDataEnum['county']}`,
rules: [{ required: true, message: '请输入机构名称', trigger: 'blur' }],
},
{
type: 'custom',
prop: 'city',
label: addDataEnum['city'],
placeholder: `请选择${addDataEnum['city']}`,
rules: [{ required: true, message: `请选择${addDataEnum['city']}`, trigger: 'blur' }],
},
{
type: 'input',
prop: 'address',
label: addDataEnum['address'],
placeholder: `请输入${addDataEnum['address']}`,
rules: [{ required: true, message: `请输入${addDataEnum['address']}`, trigger: 'blur' }],
},
{
type: 'input',
prop: 'contactPhone',
label: addDataEnum['contactPhone'],
placeholder: `请输入${addDataEnum['contactPhone']}`,
rules: [{ required: true, validator: phoneRule, trigger: 'blur' }],
},
{
type: 'input',
prop: 'parentOrgId',
label: addDataEnum['parentOrgId'],
placeholder: `请选择${addDataEnum['parentOrgId']}`,
rules: [{ required: true, message: `请选择${addDataEnum['parentOrgId']}`, trigger: 'blur' }],
},
{
type: 'input',
prop: 'remarks',
label: addDataEnum['remarks'],
placeholder: `请输入${addDataEnum['remarks']}`,
rules: [{ required: true, message: `请输入${addDataEnum['remarks']}`, trigger: 'blur' }],
},
]
const dialogTitle = ref('新增机构')
const dialogVible = ref(false)
const addInstitutional = () => {
dialogTitle.value = '新增机构'
formRef.value && formRef.value.resetFields()
formModel.value = defaultFormModel
dialogVible.value = true
}
const submitAddForm = () => {
console.log(formModel.value)
if (!formRef.value) return
formRef.value.validate((valid) => {
if (valid) {
if (dialogTitle.value === '新增机构') {
addInstitutionalListReq(formModel.value).then((res) => {
if (res.success) {
ElMessage.success('新增成功')
getInstitutionList()
dialogVible.value = false
}
})
} else if (dialogTitle.value === '编辑机构') {
changeInstitutionalListReq(formModel.value as changeDataType).then((res) => {
if (res.success) {
ElMessage.success('编辑成功')
getInstitutionList()
dialogVible.value = false
} else {
ElMessage.error('编辑失败')
}
})
}
}
})
}
const closeAddForm = () => {
dialogVible.value = false
}
const getInstitutionList = () => {
getInstitutionalListReq({
name: null,
}).then((res) => {
console.log(res)
tableData.value = res.rows
})
}
const tableData = ref<getTreeDataReturnType[]>()
const tableColumn: tableColumnType<addDataEnumKeyJointType>[] = [
{
key: 'mridColumn',
prop: 'mrid',
label: addDataEnum['mrid'],
},
{
key: 'nameColumn',
prop: 'name',
label: addDataEnum['name'],
},
{
key: 'aliasNameColumn',
prop: 'aliasName',
label: addDataEnum['aliasName'],
},
{
key: 'provinceColumn',
prop: 'province',
label: addDataEnum['province'],
},
{
key: 'cityColumn',
prop: 'city',
label: addDataEnum['city'],
},
{
key: 'countyColumn',
prop: 'county',
label: addDataEnum['county'],
},
{
key: 'addressColumn',
prop: 'address',
label: addDataEnum['address'],
},
{
key: 'contactPhoneColumn',
prop: 'contactPhone',
label: addDataEnum['contactPhone'],
},
{
key: 'remarksColumn',
prop: 'remarks',
label: addDataEnum['remarks'],
},
{
key: 'parentOrgIdColumn',
prop: 'parentOrgId',
label: addDataEnum['parentOrgId'],
},
]
const editForm = (column: changeDataType) => {
formModel.value = JSON.parse(JSON.stringify(column))
formModel.value.parentOrgId = 1
dialogTitle.value = '编辑机构'
dialogVible.value = true
}
const delForm = (column: changeDataType) => {
delInstitutionalListReq({ id: column.id }).then((res) => {
if (res.success) {
ElMessage.success('删除成功')
getInstitutionList()
}
})
}
const treeData = ref<getTreeDataReturnType[]>()
const treeReplaceProps = {
children: 'children',
label: 'name',
}
const loadTreeData = (node: Node, resolve: any) => {
if (node.level === 0) {
return resolve([])
}
getTreeData(node.data.id)
.then((res) => {
if (!res.length) {
node.data.isLeaf = true
}
tableData.value = [...res]
return resolve(res)
})
.catch((err) => {
console.log(err)
})
}
const getTreeData = (orgId: number | string, recursive = false) => {
return new Promise((resolve: (data: getTreeDataReturnType[]) => unknown) => {
getInstitutionalTreeListReq({ parentOrgId: orgId, recursive: recursive }).then((res) => {
if (res.data) {
resolve(res.data)
} else {
resolve([])
}
})
})
}
const initData = () => {
getTreeData(adminInfo.orgid, true)
.then((res) => {
console.log(res)
treeData.value = [...res]
return
})
.then(() => {
return getTreeData(adminInfo.orgid)
})
.then((res) => {
tableData.value = [...res]
})
}
const treeNodeClick = (nodeData: getTreeDataReturnType, node: Node) => {
console.log(node.childNodes, nodeData.isLeaf)
if (node.childNodes.length || nodeData.isLeaf) {
getTreeData(nodeData.id).then((res) => {
tableData.value = [...res]
})
}
}
const searchTableInput = ref('')
const searchTable = () => {
if (searchTableInput.value === '') return
// table
}
onMounted(() => {
initData()
})
</script>
<style lang="scss" scoped>
@ -43,9 +436,10 @@ const treeData = ref()
width: 220px;
height: 40px;
}
.instititionalManagement {
.institutionalManagement {
.defaultAside {
width: 260px;
border-right: 1px solid #eaebed;
.treeHeader {
display: flex;
align-items: center;
@ -72,5 +466,20 @@ const treeData = ref()
@include searchInput(10px);
}
}
.defaultMain {
.tableOperate {
display: flex;
justify-content: center;
align-items: center;
a {
margin: 5px;
color: #0064aa;
font-weight: 600;
&:hover {
cursor: pointer;
}
}
}
}
}
</style>

View File

@ -0,0 +1,43 @@
import createAxios from '/@/utils/axios'
import { getDataType, addDataType, changeDataType, delDataType, getDataReturnType, operateDataReturnType, getTreeDataType,getTreeDataReturnType } from './type'
export const getInstitutionalListReq = (data: getDataType) => {
return createAxios<addDataType, getDataReturnType<changeDataType>>({
url: '/api/org/query',
method: 'post',
data: data,
})
}
export const addInstitutionalListReq = (data: addDataType) => {
return createAxios<never, operateDataReturnType>({
url: '/api/org/add',
method: 'post',
data: data,
})
}
export const changeInstitutionalListReq = (data: changeDataType) => {
return createAxios<never, operateDataReturnType>({
url: '/api/org/update',
method: 'post',
data: data,
})
}
export const delInstitutionalListReq = (data: delDataType) => {
return createAxios<never, operateDataReturnType>({
url: '/api/org/delete',
method: 'post',
data: data,
})
}
export const getInstitutionalTreeListReq = (data: getTreeDataType) => {
console.log(data);
return createAxios<never, operateDataReturnType<getTreeDataReturnType[]>>({
url: '/api/org/list',
method: 'post',
data: data,
})
}

View File

@ -0,0 +1,107 @@
export type getDataType = {
name?: string | null
parentOrgId?: string
province?: string
city?: string
county?: string
}
export type getDataReturnType<T extends any> = Promise<{
code: number
msg: string
rows: T[]
total: number
}>
export enum addDataEnum {
mrid = '机构编码',
name = '机构名称',
aliasName = '机构简称',
province = '机构省份',
city = '机构城市',
county = '机构区县',
address = '详细地址',
contactPhone = '联系电话',
remarks = '备注',
parentOrgId = '上级机构',
}
export type addDataEnumKeyJointType = keyof typeof addDataEnum
export type formItemListType<T extends addDataEnumKeyJointType> = {
type: 'input' | 'select' | 'custom'
prop: T
label: (typeof addDataEnum)[T]
placeholder: `请输入${(typeof addDataEnum)[T]}` | `请选择${(typeof addDataEnum)[T]}`
rules:
| [{ required: boolean; message: `请输入${(typeof addDataEnum)[T]}` | `请选择${(typeof addDataEnum)[T]}`; trigger: 'blur' | 'change' }]
| [{ required?: boolean; validator: (rule: any, value: any, callback: any) => void; trigger: 'blur' | 'change' }]
}
export type selectDataType = {
label: string
value: string
children?: selectDataType[]
}
export type addDataType = {
mrid: string
name: string
aliasName: string
province: string
city: string
county: string
address: string
contactPhone: string
remarks: string
parentOrgId: number | null
revision: number
}
export type changeDataType = {
id: string
mrid: string
name: string
aliasName: string
province: string
city: string
county: string
address: string
contactPhone: string
remarks: string
parentOrgId: number
revision: number
}
export type operateDataReturnType<T = any> = Promise<{
code: number
msg: string
success: boolean
data?: T
}>
export type delDataType = {
id: string
}
export type getTreeDataType = {
parentOrgId: number|string
recursive: boolean
}
export type tableColumnType<T extends addDataEnumKeyJointType> = {
key: string
prop: T
label: (typeof addDataEnum)[T]
fixed?: boolean
align?: 'left' | 'center' | 'right'
}
export type getTreeDataReturnType = {
address: string
children?: getTreeDataReturnType[]
city: string
contactPhone: string
county: string
id: string
mrid: string
name: string
parentOrgId: number
province: string
remarks: string
revision: number
isLeaf?:boolean
}

View File

@ -1,5 +1,32 @@
<template>
<div class="roleManagement">
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600">
<el-form :model="formModel" ref="formRef">
<template v-for="item in formColumnList" :key="item.prop">
<el-form-item :label="item.label" :rules="item.rule" :label-width="80" :prop="item.prop">
<template v-if="item.type === 'input'">
<el-input v-model="formModel[item.prop]" :placeholder="'请输入' + item.label"></el-input>
</template>
<template v-if="item.type === 'custom'">
<template v-if="item.prop === 'authList'">
<el-select v-model="formModel[item.prop]" multiple :placeholder="'请选择' + item.label">
<el-option
v-for="item in authorityListOptions"
:key="item.id"
:label="item.authorityName"
:value="item.id"
></el-option>
</el-select>
</template>
</template>
</el-form-item>
</template>
</el-form>
<template #footer>
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="cancelSubmitForm">取消</el-button>
</template>
</el-dialog>
<el-container>
<el-header class="containerHeader">
<div class="searchPart">
@ -18,6 +45,19 @@
:fixed="item.fixed"
:align="item.align ?? 'center'"
></el-table-column>
<el-table-column fixed="right" label="操作" align="center">
<template #default="scope">
<div class="tableOperate">
<a @click="editForm(scope.row)">编辑</a>
<a>|</a>
<el-popconfirm title="确定删除么?" @confirm="delForm(scope.row)">
<template #reference>
<a>删除</a>
</template>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
</el-main>
</el-container>
@ -25,13 +65,85 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElContainer, ElHeader, ElMain, ElInput, ElButton, ElTable, ElTableColumn } from 'element-plus'
import { ref, onMounted } from 'vue'
import { ElContainer, ElHeader, ElMain, ElInput, ElButton, ElTable, ElTableColumn, ElDialog, ElForm, ElFormItem, ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import { Plus, Search } from '@element-plus/icons-vue'
import { tableDataType, tableColumnType, roleDataEnum, roleTableDataKeyType } from './type'
import {
tableDataType,
tableColumnType,
formDataEnum,
formDataEnumKeyJointType,
formColumnListType,
formDataType,
authorityDataListType,
} from './type'
import { useI18n } from 'vue-i18n'
import { getRoleListReq, changeRoleListReq, addRoleListReq, delRoleListReq, getAllRoleListReq } from './request'
import { placeholderSign } from 'element-plus/es/components/table-v2/src/private.mjs'
const { t } = useI18n()
const dialogTitle = ref('新增角色')
const dialogVisible = ref(false)
const formModel = ref<formDataType>({
id: '',
authList: [],
roleName: '',
roleCode: '',
})
const defaultFormModel = JSON.parse(JSON.stringify(formModel.value))
const formColumnList: formColumnListType<formDataEnumKeyJointType>[] = [
{ type: 'input', label: formDataEnum['roleName'], prop: 'roleName', rule: [{ required: true, message: '请输入角色名称', trigger: 'blur' }] },
{ type: 'input', label: formDataEnum['roleCode'], prop: 'roleCode', rule: [{ required: true, message: '请输入角色编码', trigger: 'blur' }] },
{
type: 'custom',
label: formDataEnum['authList'],
prop: 'authList',
rule: [{ required: true, message: '请选择权限列表', trigger: 'change' }],
},
]
const authorityListOptions = ref<authorityDataListType[]>([])
const formRef = ref<FormInstance>()
const submitForm = () => {
if (!formRef.value) return
formRef.value.validate((valid) => {
console.log(valid);
if (valid) {
if (dialogTitle.value === '新增角色') {
console.log(formModel.value)
addRoleListReq(formModel.value).then((res) => {
if (res.success) {
getRoleList()
ElMessage.success('新增成功')
}
}).catch(err=>{
ElMessage.error(err?.response?.data?.msg ?? '新增失败')
})
dialogVisible.value = false
} else if (dialogTitle.value === '编辑角色') {
changeRoleListReq(formModel.value)
.then((res) => {
if (res.success) {
getRoleList()
ElMessage.success('编辑成功')
}
dialogVisible.value = false
})
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '编辑失败')
})
}
}
})
}
const cancelSubmitForm = () => {
dialogVisible.value = false
}
const searchInputPlacehoder = t('management.Query roles by name')
const searchInputValue = ref<string>('')
@ -39,27 +151,61 @@ const searchClick = () => {
if (!searchInputValue.value) return
}
const tableColumn = ref<tableColumnType<roleTableDataKeyType>[]>([
const tableColumn = ref<tableColumnType<formDataEnumKeyJointType>[]>([
{
key: '1',
key: 'roleName-table',
prop: 'roleName',
label: roleDataEnum['roleName'],
label: formDataEnum['roleName'],
},
{
key: '2',
key: 'roleCode_table',
prop: 'roleCode',
label: roleDataEnum['roleCode'],
label: formDataEnum['roleCode'],
},
{
key: '3',
prop: 'remark',
label: roleDataEnum['remark'],
label: formDataEnum['authList'],
prop: 'authList',
key: 'authList-table',
},
])
const tableData = ref<tableDataType[]>([])
const addClick = () => {
//
dialogTitle.value = '新增角色'
formRef.value && formRef.value.resetFields()
formModel.value = defaultFormModel
dialogVisible.value = true
}
const editForm = (formData: formDataType) => {
const data = JSON.parse(JSON.stringify(formData))
dialogTitle.value = '编辑角色'
formModel.value = data
dialogVisible.value = true
}
const delForm = (formData: formDataType) => {
delRoleListReq({ id: formData.id }).then((res) => {
if (res.success) {
ElMessage.success('删除成功')
getRoleList()
}
})
}
const getRoleList = (roleName = '') => {
getRoleListReq({
roleName,
}).then((res) => {
tableData.value = res.rows
})
}
onMounted(() => {
getRoleList()
getAllRoleListReq().then((res) => {
authorityListOptions.value = [...res.data]
})
})
</script>
<style scoped lang="scss">
@ -82,6 +228,19 @@ const addClick = () => {
}
.containerMain {
width: 100%;
.tableOperate {
display: flex;
justify-content: center;
align-items: center;
a {
margin: 5px;
color: #0064aa;
font-weight: 600;
&:hover {
cursor: pointer;
}
}
}
}
}
</style>

View File

@ -0,0 +1,51 @@
import createAxios from '/@/utils/axios'
import {
roleListReturnType,
roleListReturnDataType,
getDataType,
getDataReturnType,
changeDataType,
changeDataReturnType,
addDataType,
addDataReturnType,
delDataType,
authorityDataListType
} from './type'
export const getRoleListReq = (params: getDataType) => {
return createAxios<never, roleListReturnType<getDataReturnType>>({
url: '/api/role/query',
method: 'post',
data: params,
})
}
export const changeRoleListReq = (params: changeDataType) => {
return createAxios<never,roleListReturnDataType<changeDataReturnType>>({
url: '/api/role/update',
method: 'post',
data: params,
})
}
export const addRoleListReq = (params: addDataType) => {
return createAxios<never,roleListReturnDataType<addDataReturnType>>({
url: '/api/role/add',
method: 'post',
data: params,
})
}
export const delRoleListReq = (params: delDataType) => {
return createAxios<never, roleListReturnDataType<never>>({
url: '/api/role/delete',
method: 'post',
data: params,
})
}
export const getAllRoleListReq = () => {
return createAxios<never,roleListReturnDataType<authorityDataListType>>({
url: '/api/authority/query',
method: 'post',
})
}

View File

@ -1,19 +1,92 @@
export enum roleDataEnum {
export enum formDataEnum {
id = '系统角色id',
authList = '角色权限',
roleName = '角色名称',
roleCode = '角色编码',
remark = '备注',
}
export type roleTableDataKeyType = keyof typeof roleDataEnum
export type formDataType = {
id: string
authList: number[]
roleName: string
roleCode: string
}
export type formDataEnumKeyJointType = keyof typeof formDataEnum
export type formColumnListType<T extends formDataEnumKeyJointType> = {
key?: string
label: (typeof formDataEnum)[T]
prop: T
type: 'input' | 'custom'
fixed?: boolean
align?: 'center' | 'left' | 'right'
rule:
| [{ required: true; message: string; trigger: 'blur' | 'change' }]
| [{ validator: (rule: any, value: any, callback: any) => void; trigger: 'blur' | 'change' }]
}
export type tableDataType = {
roleName: string
createdTime?: string
id: string
revision: number
roleCode: number
remark: string
roleName: string
updatedTime?: string
}
export type tableColumnType<T extends roleTableDataKeyType> = {
export type tableColumnType<T extends formDataEnumKeyJointType> = {
key: string
prop: T
label: (typeof roleDataEnum)[T]
label: (typeof formDataEnum)[T]
fixed?: boolean
align?: 'left' | 'center' | 'right'
}
export type authorityDataListType = {
authorityCode: string
authorityName: string
id: string
revision: number
}
export type roleListReturnType<T> = Promise<{
code: number
msg: string
rows: T[]
total: number
}>
export type roleListReturnDataType<T> = Promise<{
code: number
msg: string
data: T[]
success: boolean
}>
export type getDataType = {
roleName: string
}
export type getDataReturnType = {
createdTime: string
id: string
revision: number
roleCode: number
roleName: string
updatedTime: string
}
export type changeDataType = Omit<formDataType, 'roleCode'>
export type changeDataReturnType = {
authList: number[]
id: string
roleCode: string
roleName: string
}
export type addDataType = Omit<formDataType, 'id'>
export type addDataReturnType = changeDataReturnType
export type delDataType = {
id: string
}

View File

@ -183,7 +183,7 @@ const onSubmit = () => {
state.submitLoading = true
login(form)
.then((res) => {
if (res.code == 200) {
if (res.code == 200) {
adminInfo.dataFill({
id: res.data.sysUser.id,
username: res.data.sysUser.account,
@ -194,6 +194,7 @@ const onSubmit = () => {
refresh_token: res.data.refershToken,
// superAdmin
super: false,
orgid:res.data.sysUser.orgId
})
router.push({ path: adminBaseRoutePath })
} else {