feat: 角色管理用户管理改造

This commit is contained in:
leiqiaochu 2023-09-11 14:34:26 +08:00
parent 99533a38be
commit 69e4599337
12 changed files with 205 additions and 133 deletions

View File

@ -15,6 +15,9 @@ export const validateField_api = (type: 'username' | 'password', name: string) =
// 获取角色列表 // 获取角色列表
export const getRoleList_api = () => server.get(`/role/_query/no-paging?paging=false`); export const getRoleList_api = () => server.get(`/role/_query/no-paging?paging=false`);
//获取角色列表
export const getRoleList = () => server.post('/role/group/detail/_query/tree')
// 获取组织列表 // 获取组织列表
export const getDepartmentList_api = () => server.get(`/organization/_all/tree?paging=false`); export const getDepartmentList_api = () => server.get(`/organization/_all/tree?paging=false`);

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="role-permiss-container"> <div class="role-permiss-container">
<section class="card"> <!-- <section class="card">
<h5>基本信息</h5> <h5>基本信息</h5>
<j-form <j-form
ref="formRef" ref="formRef"
@ -30,7 +30,7 @@
/> />
</j-form-item> </j-form-item>
</j-form> </j-form>
</section> </section> -->
<section class="card"> <section class="card">
<h5>权限分配</h5> <h5>权限分配</h5>
@ -38,7 +38,7 @@
<j-button <j-button
type="primary" type="primary"
:disabled="form.loading" :confirm-loading="form.loading"
@click="form.clickSave" @click="form.clickSave"
style="margin-top: 24px" style="margin-top: 24px"
>保存</j-button >保存</j-button
@ -70,33 +70,33 @@ const roleId = route.params.id as string;
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const form = reactive({ const form = reactive({
loading: false, loading: false,
data: { // data: {
name: '', // name: '',
description: '', // description: '',
}, // },
menus: [], // USER_CENTER_MENU_DATA menus: [], // USER_CENTER_MENU_DATA
getForm: () => { // getForm: () => {
getRoleDetails_api(roleId).then((resp) => { // getRoleDetails_api(roleId).then((resp) => {
if (resp.status) { // if (resp.status) {
form.data = resp.result; // form.data = resp.result;
} // }
}); // });
}, // },
clickSave: () => { clickSave: () => {
formRef.value?.validate().then(() => { // formRef.value?.validate().then(() => {
const updateRole = editRole_api(roleId, form.data); // const updateRole = editRole_api(roleId, form.data);
const updateTree = updatePrimissTree_api(roleId, { const updateTree = updatePrimissTree_api(roleId, {
menus: form.menus, menus: form.menus,
}); });
Promise.all([updateRole, updateTree]).then((resp) => { Promise.all([ updateTree]).then((resp) => {
onlyMessage('操作成功'); onlyMessage('操作成功');
// jumpPage(`system/Role`); // jumpPage(`system/Role`);
}); })
}); // });
}, },
}); });
form.getForm(); // form.getForm();
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -44,7 +44,7 @@
</div> </div>
</div> </div>
<div v-else> <div v-else>
<j-input v-model:value="addName" @blur="()=>saveGroup(item.data)" ref="inputRef"></j-input> <j-input v-model:value="addName" @blur="()=>saveGroup(item.data)" ref="inputRef" :maxlength="64"></j-input>
<div style="color: red;" v-if="validateTip">分组名称不能为空</div> <div style="color: red;" v-if="validateTip">分组名称不能为空</div>
</div> </div>
</template> </template>
@ -76,6 +76,7 @@ const queryGroup = async(select?:Boolean,searchName?:string) =>{
} }
} }
const addGroup = () =>{ const addGroup = () =>{
addName.value = ''
listData.value.push({ listData.value.push({
name:'', name:'',
edit:true, edit:true,

View File

@ -1,7 +1,7 @@
<template> <template>
<j-modal <j-modal
visible visible
title="新增" :title="modalType ==='add' ? '新增' : '编辑'"
width="670px" width="670px"
@cancel="emits('update:visible', false)" @cancel="emits('update:visible', false)"
@ok="confirm" @ok="confirm"
@ -50,20 +50,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { FormInstance } from 'ant-design-vue'; import { FormInstance } from 'ant-design-vue';
import { saveRole_api , queryRoleGroup} from '@/api/system/role'; import { saveRole_api , queryRoleGroup , updateRole_api} from '@/api/system/role';
import { useMenuStore } from '@/store/menu'; import { useMenuStore } from '@/store/menu';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
const route = useRoute(); const route = useRoute();
const { jumpPage } = useMenuStore(); const { jumpPage } = useMenuStore();
const emits = defineEmits(['update:visible']); const emits = defineEmits(['update:visible']);
const props = defineProps<{ const props = defineProps({
visible: boolean; visible: {
type:Boolean,
default:false
},
groupId:{ groupId:{
type:String, type:String,
default:"" default:""
},
modalType:{
type:String,
default:'add'
},
current:{
type:Object,
default:{}
} }
}>(); })
// //
const loading = ref(false); const loading = ref(false);
const form = ref<any>({ const form = ref<any>({
@ -73,26 +84,35 @@ const form = ref<any>({
}); });
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const groupOptions = ref<any>([]) const groupOptions = ref<any>([])
const confirm = () => { const confirm = async() => {
loading.value = true; loading.value = true;
formRef.value formRef.value
?.validate() ?.validate()
.then(() => saveRole_api(form.value)) .then(() => {
.then((resp) => { if(props.modalType === 'add'){
if (resp.status === 200) { saveRole_api(form.value).then((resp:any)=>{
onlyMessage('操作成功'); if (resp.status === 200) {
emits('update:visible', false); onlyMessage('操作成功');
emits('update:visible', false);
if (route.query.save) { if (route.query.save) {
// @ts-ignore // @ts-ignore
if((window as any).onTabSaveSuccess){ if((window as any).onTabSaveSuccess){
(window as any).onTabSaveSuccess(resp.result.id); (window as any).onTabSaveSuccess(resp.result.id);
setTimeout(() => window.close(), 300); setTimeout(() => window.close(), 300);
} }
} else jumpPage(`system/Role/Detail`, { id: resp.result.id }); } else jumpPage(`system/Role/Detail`, { id: resp.result.id });
} }
}).catch(() => (loading.value = false));
}else{
updateRole_api(form.value).then((resp:any)=>{
if (resp.status === 200) {
onlyMessage('操作成功');
emits('update:visible', false);
}
}).catch(() => (loading.value = false));
}
}) })
.finally(() => (loading.value = false)); .catch(() => (loading.value = false));
}; };
// //
const getGroupOptions = ()=>{ const getGroupOptions = ()=>{
@ -110,6 +130,9 @@ const getGroupOptions = ()=>{
onMounted(()=>{ onMounted(()=>{
getGroupOptions() getGroupOptions()
form.value.groupId = props.groupId form.value.groupId = props.groupId
if(props.modalType === 'edit'){
form.value = props.current
}
}) })
</script> </script>

View File

@ -1,77 +1,36 @@
<template> <template>
<page-container> <page-container>
<div class="role-container"> <div class="role-container">
<pro-search <pro-search :columns="columns" target="system-role" @search="handelSearch" />
:columns="columns"
target="system-role"
@search="(params:any)=>queryParams = {...params}"
/>
<FullPage> <FullPage>
<j-pro-table <j-pro-table ref="tableRef" :columns="columns" :request="getRoleList_api" model="TABLE"
ref="tableRef" :params="queryParams" :defaultParams="defaultParams">
:columns="columns"
:request="getRoleList_api"
model="TABLE"
:params="queryParams"
:defaultParams="{
sorts: [
{ name: 'createTime', order: 'desc' },
{ name: 'id', order: 'desc' },
],
terms:[
{
terms:[{
value: groupId,
termType:'eq',
column:'groupId'
}]
}
]
}"
>
<template #headerTitle> <template #headerTitle>
<PermissionButton <PermissionButton type="primary" :hasPermission="`${permission}:add`" @click="addRole">
type="primary"
:hasPermission="`${permission}:add`"
@click="dialogVisible = true"
>
<AIcon type="PlusOutlined" />新增 <AIcon type="PlusOutlined" />新增
</PermissionButton> </PermissionButton>
</template> </template>
<template #action="slotProps"> <template #action="slotProps">
<j-space :size="16"> <j-space>
<PermissionButton <template v-for="i in getActions(slotProps, 'table')" :key="i.key">
:hasPermission="`${permission}:update`" <PermissionButton :disabled="i.disabled" :popConfirm="i.popConfirm" :tooltip="{
type="link" ...i.tooltip,
:tooltip="{ }" @click="i.onClick" type="link" style="padding: 0 5px"
title: '编辑', :danger="i.key === 'delete'" :hasPermission="'system/Role:' + i.key
}" ">
@click=" <template #icon>
jumpPage(`system/Role/Detail`, { <AIcon :type="i.icon" />
id: slotProps.id, </template>
}) </PermissionButton>
" </template>
>
<AIcon type="EditOutlined" />
</PermissionButton>
<PermissionButton
type="link"
:hasPermission="`${permission}:delete`"
:tooltip="{ title: '删除' }"
:popConfirm="{
title: `确定要删除吗`,
onConfirm: () => clickDel(slotProps),
}"
>
<AIcon type="DeleteOutlined" />
</PermissionButton>
</j-space> </j-space>
</template> </template>
</j-pro-table> </j-pro-table>
</FullPage> </FullPage>
<AddDialog v-if="dialogVisible" v-model:visible="dialogVisible" :groupId="groupId"/> <AddDialog v-if="dialogVisible" v-model:visible="dialogVisible" :groupId="groupId" :modalType="modalType"
:current="current" />
</div> </div>
</page-container> </page-container>
</template> </template>
@ -80,19 +39,39 @@
import PermissionButton from '@/components/PermissionButton/index.vue'; import PermissionButton from '@/components/PermissionButton/index.vue';
import AddDialog from './components/AddDialog.vue'; import AddDialog from './components/AddDialog.vue';
import { getRoleList_api, delRole_api } from '@/api/system/role'; import { getRoleList_api, delRole_api } from '@/api/system/role';
import type { ActionsType } from './typings';
import { useMenuStore } from '@/store/menu'; import { useMenuStore } from '@/store/menu';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
const props = defineProps({ const props = defineProps({
groupId:{ groupId: {
type:String, type: String,
default:'' default: ''
} }
}) })
const permission = 'system/Role'; const permission = 'system/Role';
const { jumpPage } = useMenuStore(); const { jumpPage } = useMenuStore();
const modalType = ref('add')
const current = ref()
const isSave = !!useRoute().query.save; const isSave = !!useRoute().query.save;
const queryParams = ref({});
const defaultParams = ref({
sorts: [
{ name: 'createTime', order: 'desc' },
{ name: 'id', order: 'desc' },
],
terms: [
{
terms: [{
value: props.groupId,
termType: 'eq',
column: 'groupId'
}]
}
]
})
//
const tableRef = ref<Record<string, any>>();
const dialogVisible = ref(isSave);
const columns = [ const columns = [
{ {
title: '标识', title: '标识',
@ -131,19 +110,73 @@ const columns = [
scopedSlots: true, scopedSlots: true,
}, },
]; ];
const queryParams = ref({}); const getActions = (
// data: Partial<Record<string, any>>,
const tableRef = ref<Record<string, any>>(); type: 'card' | 'table',
const clickDel = (row: any) => { ): ActionsType[] => {
delRole_api(row.id).then((resp: any) => { if (!data) return [];
if (resp.status === 200) { const actions = [
tableRef.value?.reload(); {
onlyMessage('操作成功!'); key: 'update',
} text: '编辑',
}); tooltip: {
title: '编辑',
},
icon: 'EditOutlined',
onClick: () => {
dialogVisible.value = true;
modalType.value = 'edit';
current.value = data
},
},
{
key: 'update',
text: '权限配置',
tooltip: {
title: '权限配置'
},
onClick: () => {
jumpPage(`system/Role/Detail`, {
id: data.id,
})
},
icon: 'FormOutlined'
},
{
key: 'delete',
text: '删除',
tooltip: {
title: '删除',
},
popConfirm: {
title: '确认删除?',
onConfirm: async () => {
const res = await delRole_api(data.id)
if (res.status === 200) {
onlyMessage('操作成功!')
tableRef.value?.reload()
} else {
onlyMessage('操作失败!', 'error')
}
},
},
icon: 'DeleteOutlined',
},
];
if (type === 'card')
return actions.filter((i: ActionsType) => i.key !== 'view');
return actions;
}; };
const dialogVisible = ref(isSave);
watch(()=>props.groupId,()=>{ const addRole = () =>{
dialogVisible.value = true
modalType.value = 'add'
}
const handelSearch = (search: any) => {
queryParams.value = search
}
watch(() => props.groupId, () => {
defaultParams.value.terms[0].terms[0].value = props.groupId
tableRef.value?.reload() tableRef.value?.reload()
}) })
</script> </script>

View File

@ -99,14 +99,15 @@
{ required: form.data.username !== 'admin', message: '请选择角色' }, { required: form.data.username !== 'admin', message: '请选择角色' },
]" ]"
> >
<j-select <j-tree-select
v-model:value="form.data.roleIdList" v-model:value="form.data.roleIdList"
mode="multiple" multiple
style="width: calc(100% - 40px)" style="width: calc(100% - 40px)"
placeholder="请选择角色" placeholder="请选择角色"
:options="_roleOptions" :tree-data="form.roleOptions"
:fieldNames="{ label: 'name', value: 'id', children:'children' }"
:disabled="form.data.username === 'admin'" :disabled="form.data.username === 'admin'"
></j-select> ></j-tree-select>
<PermissionButton <PermissionButton
:hasPermission="`${rolePermission}:add`" :hasPermission="`${rolePermission}:add`"
@ -199,6 +200,7 @@ import {
updateUser_api, updateUser_api,
updatePassword_api, updatePassword_api,
getUser_api, getUser_api,
getRoleList
} from '@/api/system/user'; } from '@/api/system/user';
import { Rule } from 'ant-design-vue/es/form'; import { Rule } from 'ant-design-vue/es/form';
import { DefaultOptionType } from 'ant-design-vue/es/vc-tree-select/TreeSelect'; import { DefaultOptionType } from 'ant-design-vue/es/vc-tree-select/TreeSelect';
@ -277,10 +279,9 @@ const form = reactive({
}, },
}, },
roleOptions: [] as optionType[], roleOptions: [],
departmentOptions: [] as DefaultOptionType[], departmentOptions: [] as DefaultOptionType[],
_roleOptions: [] as optionType[],
_departmentOptions: [] as DefaultOptionType[], _departmentOptions: [] as DefaultOptionType[],
init: () => { init: () => {
@ -304,8 +305,8 @@ const form = reactive({
(item: dictType) => item.id, (item: dictType) => item.id,
), ),
}; };
form._roleOptions = resp.result?.roleList?.map((i: any) => { form.data.roleIdList = resp.result?.roleList?.map((i: any) => {
return {label: i.name, value: i.id} return i.id
}); });
form._departmentOptions = resp.result?.orgList form._departmentOptions = resp.result?.orgList
nextTick(() => { nextTick(() => {
@ -343,11 +344,10 @@ const form = reactive({
return api(params); return api(params);
}, },
getRoleList: () => { getRoleList: () => {
getRoleList_api().then((resp: any) => { getRoleList().then((resp: any) => {
form.roleOptions = resp.result.map((item: dictType) => ({ if(resp.status === 200){
label: item.name, form.roleOptions = dealRoleList(resp.result)
value: item.id, }
}));
}); });
}, },
getDepartmentList: () => { getDepartmentList: () => {
@ -366,9 +366,21 @@ const form = reactive({
}, },
}); });
const _roleOptions = computed(() => { const dealRoleList = (data:any) =>{
return uniqBy([...form.roleOptions, ...form._roleOptions], 'value') return data.map((item:any)=>{
}) return {
name: item.groupName,
id: item.groupId,
disabled: true,
children: item?.roles ? item.roles.map((i:any)=>{
return {
name:i.name,
id:i.id
}
}) : []
}
})
}
const _departmentOptions = computed(() => { const _departmentOptions = computed(() => {
return uniqBy([...form.departmentOptions, ...form._departmentOptions], 'id') return uniqBy([...form.departmentOptions, ...form._departmentOptions], 'id')