mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-11-12 00:59:23 +08:00
feat: 角色管理增加授权用户功能 (#33)
This commit is contained in:
@@ -9,7 +9,10 @@ const BASE_URL = '/common'
|
|||||||
export function listDeptTree(query: { description: string }) {
|
export function listDeptTree(query: { description: string }) {
|
||||||
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query)
|
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query)
|
||||||
}
|
}
|
||||||
|
/** @desc 查询部门用户树 */
|
||||||
|
export function listDeptWithUsersTree(query: { description?: string, status: number }) {
|
||||||
|
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/deptWithUsers`, query)
|
||||||
|
}
|
||||||
/** @desc 查询菜单树 */
|
/** @desc 查询菜单树 */
|
||||||
export function listMenuTree(query: { description: string }) {
|
export function listMenuTree(query: { description: string }) {
|
||||||
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/menu`, query)
|
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/menu`, query)
|
||||||
|
|||||||
@@ -29,3 +29,11 @@ export function updateRole(data: any, id: string) {
|
|||||||
export function deleteRole(ids: string | Array<string>) {
|
export function deleteRole(ids: string | Array<string>) {
|
||||||
return http.del(`${BASE_URL}/${ids}`)
|
return http.del(`${BASE_URL}/${ids}`)
|
||||||
}
|
}
|
||||||
|
/** @desc 获取角色绑定的用户列表 */
|
||||||
|
export function listRoleUsers(id: string) {
|
||||||
|
return http.get(`${BASE_URL}/listRoleUsers/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bindUsers(id: string, userIds : Array<string>) {
|
||||||
|
return http.post(`${BASE_URL}/bindUsers/${id}`,userIds)
|
||||||
|
}
|
||||||
|
|||||||
6
src/types/auto-imports.d.ts
vendored
6
src/types/auto-imports.d.ts
vendored
@@ -46,6 +46,7 @@ declare global {
|
|||||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||||
const onUpdated: typeof import('vue')['onUpdated']
|
const onUpdated: typeof import('vue')['onUpdated']
|
||||||
|
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||||
const provide: typeof import('vue')['provide']
|
const provide: typeof import('vue')['provide']
|
||||||
const reactive: typeof import('vue')['reactive']
|
const reactive: typeof import('vue')['reactive']
|
||||||
const readonly: typeof import('vue')['readonly']
|
const readonly: typeof import('vue')['readonly']
|
||||||
@@ -66,10 +67,13 @@ declare global {
|
|||||||
const useAttrs: typeof import('vue')['useAttrs']
|
const useAttrs: typeof import('vue')['useAttrs']
|
||||||
const useCssModule: typeof import('vue')['useCssModule']
|
const useCssModule: typeof import('vue')['useCssModule']
|
||||||
const useCssVars: typeof import('vue')['useCssVars']
|
const useCssVars: typeof import('vue')['useCssVars']
|
||||||
|
const useId: typeof import('vue')['useId']
|
||||||
const useLink: typeof import('vue-router')['useLink']
|
const useLink: typeof import('vue-router')['useLink']
|
||||||
|
const useModel: typeof import('vue')['useModel']
|
||||||
const useRoute: typeof import('vue-router')['useRoute']
|
const useRoute: typeof import('vue-router')['useRoute']
|
||||||
const useRouter: typeof import('vue-router')['useRouter']
|
const useRouter: typeof import('vue-router')['useRouter']
|
||||||
const useSlots: typeof import('vue')['useSlots']
|
const useSlots: typeof import('vue')['useSlots']
|
||||||
|
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||||
const watch: typeof import('vue')['watch']
|
const watch: typeof import('vue')['watch']
|
||||||
const watchEffect: typeof import('vue')['watchEffect']
|
const watchEffect: typeof import('vue')['watchEffect']
|
||||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||||
@@ -78,6 +82,6 @@ declare global {
|
|||||||
// for type re-export
|
// for type re-export
|
||||||
declare global {
|
declare global {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
import('vue')
|
import('vue')
|
||||||
}
|
}
|
||||||
|
|||||||
116
src/views/system/role/RoleUserAssociation.vue
Normal file
116
src/views/system/role/RoleUserAssociation.vue
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="visible"
|
||||||
|
title="关联用户"
|
||||||
|
:mask-closable="false"
|
||||||
|
:esc-to-close="false"
|
||||||
|
:modal-style="{ maxWidth: '625px' }"
|
||||||
|
:body-style="{ maxHeight: '70vh' }"
|
||||||
|
width="90%"
|
||||||
|
draggable
|
||||||
|
@before-ok="save"
|
||||||
|
@close="close"
|
||||||
|
>
|
||||||
|
<a-transfer :data="transferData" :model-value="values" :title="['未选择','已选择']" @change="handleChange">
|
||||||
|
<template #source="{ data, selectedKeys, onSelect }">
|
||||||
|
<a-tree
|
||||||
|
size="medium"
|
||||||
|
:checkable="true"
|
||||||
|
checked-strategy="child"
|
||||||
|
:checked-keys="selectedKeys"
|
||||||
|
:data="getTreeData()"
|
||||||
|
@check="(keys) => onSelect(keys)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</a-transfer>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { bindUsers, listDeptWithUsersTree, listRoleUsers } from '@/apis';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import type { TransferItem } from '@arco-design/web-vue/es/transfer/interface';
|
||||||
|
import { Message, type TreeNodeData } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
const roleId = ref('');
|
||||||
|
const treeData = ref<TreeNodeData[]>([]);
|
||||||
|
const transferData = ref<TransferItem[]>([]);
|
||||||
|
const values = ref<string[]>(['']);
|
||||||
|
const close = () => {
|
||||||
|
visible.value = false;
|
||||||
|
};
|
||||||
|
const save = async () => {
|
||||||
|
const newValues = values.value.map((item) => item.replace('user_', ''));
|
||||||
|
const res = await bindUsers(roleId.value, newValues);
|
||||||
|
if (res.success) {
|
||||||
|
Message.success('修改成功')
|
||||||
|
visible.value = false;
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
Message.error(res.msg)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleChange = (value: string[]) => {
|
||||||
|
values.value = value
|
||||||
|
}
|
||||||
|
const getTransferData = (treeData: TreeNodeData[], transferDataSource: TransferItem[] = []) => {
|
||||||
|
treeData.forEach((item) => {
|
||||||
|
if (item["isUser"] === true) {
|
||||||
|
transferDataSource.push({ label: item.title ?? '', value: String(item.key) ?? '', disabled: false });
|
||||||
|
}
|
||||||
|
if (item.children) {
|
||||||
|
getTransferData(item.children, transferDataSource);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return transferDataSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTreeData = () => {
|
||||||
|
const travel = (_treeData: TreeNodeData[] = []) => {
|
||||||
|
const treeDataSource: TreeNodeData[] = [];
|
||||||
|
_treeData.forEach((item) => {
|
||||||
|
const disabled = values.value.filter((v) => v === item.key).length > 0;
|
||||||
|
treeDataSource.push({ title: item.title, key: item.key, children: travel(item.children) , disabled: disabled});
|
||||||
|
});
|
||||||
|
return treeDataSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
return travel(treeData.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onAssociation = async (id: string) => {
|
||||||
|
console.log(1);
|
||||||
|
|
||||||
|
visible.value = true;
|
||||||
|
roleId.value = id;
|
||||||
|
values.value = []
|
||||||
|
getDeptList();
|
||||||
|
listUsers(roleId.value);
|
||||||
|
};
|
||||||
|
const getDeptList = async () => {
|
||||||
|
const res = await listDeptWithUsersTree({ status: 1 });
|
||||||
|
treeData.value = res.data;
|
||||||
|
transferData.value = getTransferData(treeData.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const listUsers = async (roleId: string) => {
|
||||||
|
const res = await listRoleUsers(roleId);
|
||||||
|
res.data.forEach(item => {
|
||||||
|
values.value.push( "user_" + item)
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
onAssociation
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.arco-transfer-view) {
|
||||||
|
height: 40vh;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-link v-permission="['system:role:update']" @click="onUpdate(record)">修改</a-link>
|
<a-link v-permission="['system:role:update']" @click="onUpdate(record)">修改</a-link>
|
||||||
|
<a-link v-permission="['system:role:bindUsers']" @click="onAssociation(record)">关联用户</a-link>
|
||||||
<a-link
|
<a-link
|
||||||
v-permission="['system:role:delete']"
|
v-permission="['system:role:delete']"
|
||||||
status="danger"
|
status="danger"
|
||||||
@@ -67,6 +68,8 @@
|
|||||||
<RoleAddModal ref="RoleAddModalRef" @save-success="search" />
|
<RoleAddModal ref="RoleAddModalRef" @save-success="search" />
|
||||||
<RoleUpdateDrawer ref="RoleUpdateDrawerRef" @save-success="search" />
|
<RoleUpdateDrawer ref="RoleUpdateDrawerRef" @save-success="search" />
|
||||||
<RoleDetailDrawer ref="RoleDetailDrawerRef" />
|
<RoleDetailDrawer ref="RoleDetailDrawerRef" />
|
||||||
|
<RoleUserAssociation ref="RoleUserAssociationRef" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -74,6 +77,7 @@
|
|||||||
import RoleUpdateDrawer from './RoleUpdateDrawer.vue'
|
import RoleUpdateDrawer from './RoleUpdateDrawer.vue'
|
||||||
import RoleDetailDrawer from './RoleDetailDrawer.vue'
|
import RoleDetailDrawer from './RoleDetailDrawer.vue'
|
||||||
import RoleAddModal from './RoleAddModal.vue'
|
import RoleAddModal from './RoleAddModal.vue'
|
||||||
|
import RoleUserAssociation from './RoleUserAssociation.vue'
|
||||||
import { type RoleQuery, type RoleResp, deleteRole, listRole } from '@/apis/system'
|
import { type RoleQuery, type RoleResp, deleteRole, listRole } from '@/apis/system'
|
||||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||||
import { useTable } from '@/hooks'
|
import { useTable } from '@/hooks'
|
||||||
@@ -152,6 +156,12 @@ const RoleDetailDrawerRef = ref<InstanceType<typeof RoleDetailDrawer>>()
|
|||||||
const onDetail = (record: RoleResp) => {
|
const onDetail = (record: RoleResp) => {
|
||||||
RoleDetailDrawerRef.value?.onDetail(record.id)
|
RoleDetailDrawerRef.value?.onDetail(record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RoleUserAssociationRef = ref<InstanceType<typeof RoleUserAssociation>>()
|
||||||
|
// 关联用户
|
||||||
|
const onAssociation = (record: RoleResp) => {
|
||||||
|
RoleUserAssociationRef.value?.onAssociation(record.id)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
Reference in New Issue
Block a user