feat: 角色管理改造
This commit is contained in:
parent
a3b29ae01e
commit
99533a38be
|
@ -1,3 +1,4 @@
|
|||
import request from '@/utils/request';
|
||||
import server from '@/utils/request';
|
||||
|
||||
// 获取角色列表
|
||||
|
@ -26,3 +27,9 @@ export const getUserByRole_api = (data: any): Promise<any> => server.post(`/user
|
|||
export const bindUser_api = (roleId:string, data: string[]): Promise<any> => server.post(`/role/${roleId}/users/_bind`, data);
|
||||
// 将用户与角色解绑
|
||||
export const unbindUser_api = (roleId:string, data: string[]): Promise<any> => server.post(`/role/${roleId}/users/_unbind`, data);
|
||||
//查询分组
|
||||
export const queryRoleGroup = (data:any) => request.post('/role/group/_query/no-paging',data)
|
||||
//保存分组
|
||||
export const saveRoleGroup = (data:any) => request.patch('/role/group',data)
|
||||
//删除分组
|
||||
export const deleteRoleGroup = (id:string) => request.remove(`/role/group/${id}`)
|
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<div class="left-contain">
|
||||
<j-input placeholder="分组名称" v-model:value="searchValue" @pressEnter="search" @change="searchChange">
|
||||
<template #suffix>
|
||||
<AIcon type="SearchOutlined" @click="search" />
|
||||
</template>
|
||||
</j-input>
|
||||
<div class="controls">
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
hasPermission="system/Dictionary:add"
|
||||
@click="addGroup"
|
||||
style="width: 100%"
|
||||
>
|
||||
新增分组
|
||||
</PermissionButton>
|
||||
</div>
|
||||
<div>
|
||||
<j-tree :tree-data="listData" v-if="listData.length" :fieldNames="{title:'name',key:'id'}" blockNode :selectedKeys="selectedKeys">
|
||||
<template #title="item">
|
||||
<div class="treeItem" @click="()=>selectGroup(item.data.id)" v-if="!item.data?.edit">
|
||||
<div class="itemText">
|
||||
<Ellipsis style="width: calc(100%-100px)">{{ item.name }}</Ellipsis>
|
||||
|
||||
</div>
|
||||
<div @click="(e) => e.stopPropagation()">
|
||||
<PermissionButton
|
||||
type="text"
|
||||
hasPermission="system/Role:delete"
|
||||
:popConfirm="{
|
||||
title: `确定要删除?`,
|
||||
onConfirm: () => deleteGroup(item.id),
|
||||
}"
|
||||
>
|
||||
删除
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="text"
|
||||
hasPermission="system/Role:update"
|
||||
@click="editGroup(item.data)"
|
||||
>
|
||||
编辑
|
||||
</PermissionButton>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<j-input v-model:value="addName" @blur="()=>saveGroup(item.data)" ref="inputRef"></j-input>
|
||||
<div style="color: red;" v-if="validateTip">分组名称不能为空</div>
|
||||
</div>
|
||||
</template>
|
||||
</j-tree>
|
||||
<j-empty v-else style="margin-top: 100px;"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { queryRoleGroup , saveRoleGroup , deleteRoleGroup } from '@/api/system/role'
|
||||
import { randomString } from '@/utils/utils'
|
||||
const emit = defineEmits(['selectData'])
|
||||
const listData:any = ref([])
|
||||
const selectedKeys = ref<string[]>([])
|
||||
const searchValue = ref()
|
||||
const inputRef = ref()
|
||||
const validateTip = ref()
|
||||
const addName = ref()
|
||||
const queryGroup = async(select?:Boolean,searchName?:string) =>{
|
||||
const params = searchName ? {sorts: [{ name: 'createTime', order: 'desc' }],terms:[{terms:[{value:'%'+ searchName +'%',termType:'like',column:'name'}]}]} : {sorts: [{ name: 'createTime', order: 'desc' }]}
|
||||
const req:any = await queryRoleGroup(params)
|
||||
if(req.status === 200){
|
||||
listData.value = req.result
|
||||
if(req.result.length && select){
|
||||
selectGroup(req.result[0].id)
|
||||
}
|
||||
}
|
||||
}
|
||||
const addGroup = () =>{
|
||||
listData.value.push({
|
||||
name:'',
|
||||
edit:true,
|
||||
id: randomString()
|
||||
})
|
||||
nextTick(()=>{
|
||||
inputRef.value.focus()
|
||||
})
|
||||
}
|
||||
const saveGroup = async(data:any) =>{
|
||||
if(addName.value === ''){
|
||||
validateTip.value = true
|
||||
}else{
|
||||
validateTip.value = false
|
||||
const saveData = {
|
||||
name:addName.value,
|
||||
id:data.id
|
||||
}
|
||||
const res = await saveRoleGroup(saveData)
|
||||
if(res.status === 200){
|
||||
onlyMessage('操作成功!')
|
||||
queryGroup()
|
||||
}else{
|
||||
onlyMessage('操作失败!')
|
||||
}
|
||||
}
|
||||
}
|
||||
const search = () =>{
|
||||
queryGroup(true,searchValue.value)
|
||||
}
|
||||
const searchChange = () =>{
|
||||
if(searchValue.value === '' ){
|
||||
queryGroup()
|
||||
}
|
||||
}
|
||||
const selectGroup = (id:string) =>{
|
||||
selectedKeys.value = [id]
|
||||
emit('selectData',selectedKeys.value)
|
||||
}
|
||||
const deleteGroup = async(id:string)=>{
|
||||
const res:any = await deleteRoleGroup(id)
|
||||
if(res.status === 200){
|
||||
onlyMessage('操作成功!')
|
||||
queryGroup(true)
|
||||
}else{
|
||||
onlyMessage('操作失败!')
|
||||
}
|
||||
}
|
||||
const editGroup = (data:any) => {
|
||||
addName.value = data.name
|
||||
listData.value.forEach((item:any)=>{
|
||||
if(item.id === data.id){
|
||||
item.edit = true
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
queryGroup(true)
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-tree-switcher){
|
||||
display: none;
|
||||
}
|
||||
.controls{
|
||||
margin: 10px 0;
|
||||
}
|
||||
.treeItem{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.itemText{
|
||||
line-height: 32px;
|
||||
max-width:40%
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -22,6 +22,19 @@
|
|||
allow-clear
|
||||
/>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
name="groupId"
|
||||
label="分组"
|
||||
:rules="[
|
||||
{ required: true, message: '请选择分组' },
|
||||
]"
|
||||
>
|
||||
<j-select
|
||||
v-model:value="form.groupId"
|
||||
placeholder="请选择分组"
|
||||
:options="groupOptions"
|
||||
/>
|
||||
</j-form-item>
|
||||
<j-form-item name="name" label="说明">
|
||||
<j-textarea
|
||||
v-model:value="form.description"
|
||||
|
@ -37,7 +50,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { FormInstance } from 'ant-design-vue';
|
||||
import { saveRole_api } from '@/api/system/role';
|
||||
import { saveRole_api , queryRoleGroup} from '@/api/system/role';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
const route = useRoute();
|
||||
|
@ -46,12 +59,20 @@ const { jumpPage } = useMenuStore();
|
|||
const emits = defineEmits(['update:visible']);
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
groupId:{
|
||||
type:String,
|
||||
default:""
|
||||
}
|
||||
}>();
|
||||
// 弹窗相关
|
||||
const loading = ref(false);
|
||||
const form = ref<any>({});
|
||||
const form = ref<any>({
|
||||
name:'',
|
||||
groupId:'',
|
||||
description:''
|
||||
});
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const groupOptions = ref<any>([])
|
||||
const confirm = () => {
|
||||
loading.value = true;
|
||||
formRef.value
|
||||
|
@ -74,6 +95,22 @@ const confirm = () => {
|
|||
.finally(() => (loading.value = false));
|
||||
};
|
||||
// 表单相关
|
||||
const getGroupOptions = ()=>{
|
||||
queryRoleGroup({sorts: [{ name: 'createTime', order: 'desc' }]}).then((res:any)=>{
|
||||
if(res.status ===200){
|
||||
groupOptions.value = res.result.map((item:any)=>{
|
||||
return {
|
||||
label:item.name,
|
||||
value:item.id
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
getGroupOptions()
|
||||
form.value.groupId = props.groupId
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<div class="role-container">
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
target="system-role"
|
||||
@search="(params:any)=>queryParams = {...params}"
|
||||
/>
|
||||
<FullPage>
|
||||
<j-pro-table
|
||||
ref="tableRef"
|
||||
: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>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="dialogVisible = true"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
</PermissionButton>
|
||||
</template>
|
||||
|
||||
<template #action="slotProps">
|
||||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
:hasPermission="`${permission}:update`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: '编辑',
|
||||
}"
|
||||
@click="
|
||||
jumpPage(`system/Role/Detail`, {
|
||||
id: slotProps.id,
|
||||
})
|
||||
"
|
||||
>
|
||||
<AIcon type="EditOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
:tooltip="{ title: '删除' }"
|
||||
:popConfirm="{
|
||||
title: `确定要删除吗`,
|
||||
onConfirm: () => clickDel(slotProps),
|
||||
}"
|
||||
>
|
||||
<AIcon type="DeleteOutlined" />
|
||||
</PermissionButton>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-pro-table>
|
||||
</FullPage>
|
||||
|
||||
<AddDialog v-if="dialogVisible" v-model:visible="dialogVisible" :groupId="groupId"/>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Role">
|
||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||
import AddDialog from './components/AddDialog.vue';
|
||||
import { getRoleList_api, delRole_api } from '@/api/system/role';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
const props = defineProps({
|
||||
groupId:{
|
||||
type:String,
|
||||
default:''
|
||||
}
|
||||
})
|
||||
const permission = 'system/Role';
|
||||
const { jumpPage } = useMenuStore();
|
||||
|
||||
const isSave = !!useRoute().query.save;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '标识',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
ellipsis: true,
|
||||
fixed: 'left',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
ellipsis: true,
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
key: 'description',
|
||||
ellipsis: true,
|
||||
dataIndex: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
scopedSlots: true,
|
||||
},
|
||||
];
|
||||
const queryParams = ref({});
|
||||
// 表格
|
||||
const tableRef = ref<Record<string, any>>();
|
||||
const clickDel = (row: any) => {
|
||||
delRole_api(row.id).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
tableRef.value?.reload();
|
||||
onlyMessage('操作成功!');
|
||||
}
|
||||
});
|
||||
};
|
||||
const dialogVisible = ref(isSave);
|
||||
watch(()=>props.groupId,()=>{
|
||||
tableRef.value?.reload()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.role-container {
|
||||
:deep(.ant-table-cell) {
|
||||
.ant-btn-link {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,142 +1,40 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<div class="role-container">
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
target="system-role"
|
||||
@search="(params:any)=>queryParams = {...params}"
|
||||
/>
|
||||
<FullPage>
|
||||
<j-pro-table
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:request="getRoleList_api"
|
||||
model="TABLE"
|
||||
:params="queryParams"
|
||||
:defaultParams="{
|
||||
sorts: [
|
||||
{ name: 'createTime', order: 'desc' },
|
||||
{ name: 'id', order: 'desc' },
|
||||
],
|
||||
}"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="dialogVisible = true"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
</PermissionButton>
|
||||
</template>
|
||||
|
||||
<template #action="slotProps">
|
||||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
:hasPermission="`${permission}:update`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: '编辑',
|
||||
}"
|
||||
@click="
|
||||
jumpPage(`system/Role/Detail`, {
|
||||
id: slotProps.id,
|
||||
})
|
||||
"
|
||||
>
|
||||
<AIcon type="EditOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
:tooltip="{ title: '删除' }"
|
||||
:popConfirm="{
|
||||
title: `确定要删除吗`,
|
||||
onConfirm: () => clickDel(slotProps),
|
||||
}"
|
||||
>
|
||||
<AIcon type="DeleteOutlined" />
|
||||
</PermissionButton>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-pro-table>
|
||||
</FullPage>
|
||||
|
||||
<AddDialog v-if="dialogVisible" v-model:visible="dialogVisible" />
|
||||
<div class="dictionary_contain">
|
||||
<div class="dictionary_left">
|
||||
<Left @select-data="selectData"/>
|
||||
</div>
|
||||
<div class="dictionary_right">
|
||||
<Right :groupId="groupId"/>
|
||||
</div>
|
||||
</div>
|
||||
</FullPage>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Role">
|
||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||
import AddDialog from './components/AddDialog.vue';
|
||||
import { getRoleList_api, delRole_api } from '@/api/system/role';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
const permission = 'system/Role';
|
||||
const { jumpPage } = useMenuStore();
|
||||
|
||||
const isSave = !!useRoute().query.save;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '标识',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
ellipsis: true,
|
||||
fixed: 'left',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
ellipsis: true,
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
key: 'description',
|
||||
ellipsis: true,
|
||||
dataIndex: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
scopedSlots: true,
|
||||
},
|
||||
];
|
||||
const queryParams = ref({});
|
||||
// 表格
|
||||
const tableRef = ref<Record<string, any>>();
|
||||
const clickDel = (row: any) => {
|
||||
delRole_api(row.id).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
tableRef.value?.reload();
|
||||
onlyMessage('操作成功!');
|
||||
<script lang="ts" setup>
|
||||
import Left from './RoleLeft/index.vue'
|
||||
import Right from './RoleRight/index.vue'
|
||||
const groupId = ref()
|
||||
const selectData = (data:any)=>{
|
||||
groupId.value = data[0]
|
||||
}
|
||||
});
|
||||
};
|
||||
const dialogVisible = ref(isSave);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.role-container {
|
||||
:deep(.ant-table-cell) {
|
||||
.ant-btn-link {
|
||||
padding: 0;
|
||||
.dictionary_contain{
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
padding: 24px;
|
||||
height: 100%;
|
||||
}
|
||||
.dictionary_left{
|
||||
border-right: 1px solid #f0f0f0;
|
||||
padding-right: 24px;
|
||||
flex:1;
|
||||
height:100%
|
||||
}
|
||||
.dictionary_right{
|
||||
flex:4
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue