mirror of
http://183.237.82.114:10086/kilo/leaser_front.git
synced 2026-10-23 19:35:25 +00:00
feat: 设置模块角色权限中数据权限70%
This commit is contained in:
parent
c5588374ba
commit
73a0d92fe7
5 changed files with 195 additions and 50 deletions
|
|
@ -69,5 +69,6 @@ module.exports = {
|
|||
'import/no-extraneous-dependencies': 0,
|
||||
// 禁用 prefer-destructuring 规则,因为它对对象解构和数组解构都产生错误警告
|
||||
'prefer-destructuring': 0,
|
||||
'no-return-assign': ['error', 'except-parens'],
|
||||
},
|
||||
};
|
||||
|
|
|
|||
95
src/components/common/DepartmentTree.vue
Normal file
95
src/components/common/DepartmentTree.vue
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<a-tree
|
||||
:data="data"
|
||||
:expanded-keys="expandedKeys"
|
||||
:selected-keys="selectedKeys"
|
||||
:field-names="fieldNames"
|
||||
:checkable="checkable"
|
||||
:checked-keys="checkable ? checkedKeys : undefined"
|
||||
v-bind="$attrs"
|
||||
@update:expanded-keys="(val) => updateExpandedKeys(val)"
|
||||
@update:selected-keys="(val) => updateSelectedKeys(val)"
|
||||
@update:checked-keys="(val) => updateCheckedKeys(val)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconStar v-if="!checkable" />
|
||||
</template>
|
||||
<slot />
|
||||
</a-tree>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as () => unknown[],
|
||||
required: true,
|
||||
},
|
||||
expandedKeys: {
|
||||
type: Array as () => (string | number)[],
|
||||
default: () => [],
|
||||
},
|
||||
selectedKeys: {
|
||||
type: Array as () => (string | number)[],
|
||||
default: () => [],
|
||||
},
|
||||
checkedKeys: {
|
||||
type: Array as () => (string | number)[],
|
||||
default: () => [],
|
||||
},
|
||||
checkable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
fieldNames: {
|
||||
type: Object as () => { key: string; title: string; children?: string },
|
||||
default: () => ({ key: 'id', title: 'name', children: 'children' }),
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits([
|
||||
'update:expandedKeys',
|
||||
'update:selectedKeys',
|
||||
'update:checkedKeys',
|
||||
]);
|
||||
|
||||
const expandedKeys = ref<(string | number)[]>(props.expandedKeys ?? []);
|
||||
const selectedKeys = ref<(string | number)[]>(props.selectedKeys ?? []);
|
||||
const checkedKeys = ref<(string | number)[]>(props.checkedKeys ?? []);
|
||||
|
||||
watch(
|
||||
() => props.expandedKeys,
|
||||
(val) => (expandedKeys.value = val ?? [])
|
||||
);
|
||||
watch(
|
||||
() => props.selectedKeys,
|
||||
(val) => (selectedKeys.value = val ?? [])
|
||||
);
|
||||
watch(
|
||||
() => props.checkedKeys,
|
||||
(val) => (checkedKeys.value = val ?? [])
|
||||
);
|
||||
|
||||
watch(expandedKeys, (val) => emits('update:expandedKeys', val));
|
||||
watch(selectedKeys, (val) => emits('update:selectedKeys', val));
|
||||
watch(checkedKeys, (val) => emits('update:checkedKeys', val));
|
||||
|
||||
function updateExpandedKeys(val: (string | number)[] | undefined): void {
|
||||
const newVal = val ?? [];
|
||||
expandedKeys.value = newVal;
|
||||
emits('update:expandedKeys', newVal);
|
||||
}
|
||||
|
||||
function updateSelectedKeys(val: (string | number)[] | undefined): void {
|
||||
const newVal = val ?? [];
|
||||
selectedKeys.value = newVal;
|
||||
emits('update:selectedKeys', newVal);
|
||||
}
|
||||
|
||||
function updateCheckedKeys(val: (string | number)[] | undefined): void {
|
||||
const newVal = val ?? [];
|
||||
checkedKeys.value = newVal;
|
||||
emits('update:checkedKeys', newVal);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -112,7 +112,11 @@ export default {
|
|||
'all.clear': '全部清空',
|
||||
'function.permission.setting': '功能权限设置',
|
||||
'user.assignment.setting': '用户分配设置',
|
||||
'data.permission.setting': '数据权限设置',
|
||||
'change.role': '变更角色',
|
||||
'all.data.permission': '全部数据权限',
|
||||
'customize.data.permission': '自定义数据权限',
|
||||
'self.data.permission': '仅本人数据',
|
||||
|
||||
...localeSettings,
|
||||
...localeMessageBox,
|
||||
|
|
|
|||
|
|
@ -14,16 +14,11 @@
|
|||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-tree
|
||||
<DepartmentTree
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
v-model:selected-keys="selectedKeys"
|
||||
:field-names="{ key: 'id', title: 'name' }"
|
||||
:data="departmentListData"
|
||||
>
|
||||
<template #icon>
|
||||
<IconStar />
|
||||
</template>
|
||||
</a-tree>
|
||||
/>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
|
|
@ -82,9 +77,9 @@
|
|||
<template #operate="{ record }">
|
||||
<a-space>
|
||||
<!-- <a-button>查看</a-button> -->
|
||||
<a-button type="primary" @click="handleEditUser(record.id)">{{
|
||||
$t('edit')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleEditUser(record.id)">
|
||||
{{ $t('edit') }}</a-button
|
||||
>
|
||||
<a-popover trigger="click" position="bottom">
|
||||
<a-button>{{ $t('more') }}</a-button>
|
||||
<template #content>
|
||||
|
|
@ -138,6 +133,7 @@
|
|||
import useDepartmentList from '@/composables/useDepartmentList';
|
||||
import useDataTable from '@/composables/useDataTable';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import DepartmentTree from '@/components/common/DepartmentTree.vue';
|
||||
import userFormDrawer from './components/user-form-drawer.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
|
|
|||
|
|
@ -63,15 +63,19 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col flex="auto" class="full_height">
|
||||
<a-tabs class="tabs_card" @change="handleTabChange">
|
||||
<a-tabs v-model:active-key="currentTabsKey" class="tabs_card">
|
||||
<template #extra>
|
||||
<p style="margin-right: 10px">
|
||||
<span>{{ $t('last.updated') }}</span>
|
||||
<span>{{ roleItemInfo ? roleItemInfo.updatedAt : '' }}</span>
|
||||
</p>
|
||||
<a-button type="primary" @click="handleSubmit">{{
|
||||
$t('submit')
|
||||
}}</a-button>
|
||||
<a-button
|
||||
v-if="currentTabsKey !== '3'"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
{{ $t('submit') }}</a-button
|
||||
>
|
||||
</template>
|
||||
<a-tab-pane key="1" :title="$t('function.permission')">
|
||||
<permissionCollapse
|
||||
|
|
@ -81,37 +85,73 @@
|
|||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" :title="$t('data.permission')">
|
||||
Content of Tab Panel 2
|
||||
<h4>{{ $t('data.permission.setting') }}</h4>
|
||||
<div style="padding: 20px 0">
|
||||
<a-radio-group v-model="dataType">
|
||||
<a-radio :value="1">{{ $t('all.data.permission') }}</a-radio>
|
||||
<a-radio :value="2">{{
|
||||
$t('customize.data.permission')
|
||||
}}</a-radio>
|
||||
<a-radio :value="3">{{ $t('self.data.permission') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<a-row
|
||||
v-if="dataType === 2"
|
||||
:gutter="12"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<a-col :span="12">
|
||||
<a-card>
|
||||
<h4 style="margin-bottom: 10px">选择组织架构</h4>
|
||||
<DepartmentTree
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
v-model:selected-keys="selectedKeys"
|
||||
:data="departmentListData"
|
||||
checkable
|
||||
/>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-card>
|
||||
<h4 style="margin-bottom: 10px">选择项目</h4>
|
||||
<div style="margin-top: 20px"> TODO 后面再对接 </div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" :title="$t('user.assignment')">
|
||||
<h4>{{ $t('user.assignment.setting') }}</h4>
|
||||
<DataTable
|
||||
style="margin-top: 20px"
|
||||
:data="renderData"
|
||||
:columns="projectColumn"
|
||||
:loading="loading"
|
||||
:total="total"
|
||||
:current="current"
|
||||
:page-size="pageSize"
|
||||
pagination
|
||||
@page-change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
>
|
||||
<template #realname="{ record }">
|
||||
<span>{{ record.realname }}</span>
|
||||
<icon-idcard v-if="record.isManager === 1" />
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="record.status == 1 ? 'green' : 'red'">
|
||||
{{ record.status == 1 ? $t('enable') : $t('disable') }}</a-tag
|
||||
>
|
||||
</template>
|
||||
<template #operate="{ record }">
|
||||
<a-button @click="changeRole(record?.id)">{{
|
||||
$t('change.role')
|
||||
}}</a-button>
|
||||
</template>
|
||||
</DataTable>
|
||||
<div style="padding-bottom: 20px">
|
||||
<DataTable
|
||||
style="margin-top: 20px"
|
||||
:data="renderData"
|
||||
:columns="projectColumn"
|
||||
:loading="loading"
|
||||
:total="total"
|
||||
:current="current"
|
||||
:page-size="pageSize"
|
||||
pagination
|
||||
@page-change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
>
|
||||
<template #realname="{ record }">
|
||||
<span>{{ record.realname }}</span>
|
||||
<icon-idcard v-if="record.isManager === 1" />
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="record.status == 1 ? 'green' : 'red'">
|
||||
{{
|
||||
record.status == 1 ? $t('enable') : $t('disable')
|
||||
}}</a-tag
|
||||
>
|
||||
</template>
|
||||
<template #operate="{ record }">
|
||||
<a-button @click="changeRole(record?.id)">{{
|
||||
$t('change.role')
|
||||
}}</a-button>
|
||||
</template>
|
||||
</DataTable>
|
||||
</div>
|
||||
<changeRoleDrawer
|
||||
v-model:visible="changeRoleDrawerVisible"
|
||||
:role-id="currentRoleActiveId"
|
||||
|
|
@ -127,7 +167,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import {
|
||||
getRoleList,
|
||||
RoleItem,
|
||||
|
|
@ -142,10 +182,14 @@
|
|||
import useDataTable from '@/composables/useDataTable';
|
||||
import type { TableColumnData } from '@arco-design/web-vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import DepartmentTree from '@/components/common/DepartmentTree.vue';
|
||||
import useDepartmentList from '@/composables/useDepartmentList';
|
||||
import permissionCollapse from './components/permission-collapse.vue';
|
||||
import roleFormDrawer from './components/role-form-drawer.vue';
|
||||
import changeRoleDrawer from './components/change-role-drawer.vue';
|
||||
|
||||
const { departmentListData, allDepartmentKeys } = useDepartmentList();
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
const { t } = useI18n();
|
||||
const roleList = ref<RoleItem[]>([]);
|
||||
|
|
@ -157,6 +201,10 @@
|
|||
const permissionList = ref<any[]>([]);
|
||||
const changeRoleDrawerVisible = ref<boolean>(false);
|
||||
const selectedUserId = ref<number | null>(null);
|
||||
const currentTabsKey = ref<string>('1');
|
||||
const dataType = ref<number>(1);
|
||||
const expandedKeys = ref<(string | number)[]>([]);
|
||||
const selectedKeys = ref<(string | number)[]>([]);
|
||||
// 使用 DataTable composable
|
||||
const {
|
||||
data: renderData,
|
||||
|
|
@ -213,6 +261,7 @@
|
|||
title: t('lastLogin'),
|
||||
dataIndex: 'lastLoginTime',
|
||||
key: 'lastLoginTime',
|
||||
align: 'center',
|
||||
render: ({ record }) => record.lastLoginTime || '-',
|
||||
},
|
||||
{
|
||||
|
|
@ -325,7 +374,13 @@
|
|||
const onRoleSubmit = () => {
|
||||
getRoleListData(false);
|
||||
};
|
||||
|
||||
watch(
|
||||
allDepartmentKeys,
|
||||
(val) => {
|
||||
expandedKeys.value = val;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
function handleSubmit() {
|
||||
if (!currentRoleActiveId.value) {
|
||||
Message.warning('请先选择一个角色');
|
||||
|
|
@ -365,12 +420,6 @@
|
|||
console.error('保存角色权限失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
const handleTabChange = (key) => {
|
||||
if (key === '3') {
|
||||
// 占位注释,避免空代码块
|
||||
}
|
||||
};
|
||||
// 分页事件处理
|
||||
const onPageChange = (page: number) => {
|
||||
setCurrent(page);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue