mirror of
http://183.237.82.114:10086/kilo/leaser_front.git
synced 2026-10-23 20:36:02 +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,
|
'import/no-extraneous-dependencies': 0,
|
||||||
// 禁用 prefer-destructuring 规则,因为它对对象解构和数组解构都产生错误警告
|
// 禁用 prefer-destructuring 规则,因为它对对象解构和数组解构都产生错误警告
|
||||||
'prefer-destructuring': 0,
|
'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': '全部清空',
|
'all.clear': '全部清空',
|
||||||
'function.permission.setting': '功能权限设置',
|
'function.permission.setting': '功能权限设置',
|
||||||
'user.assignment.setting': '用户分配设置',
|
'user.assignment.setting': '用户分配设置',
|
||||||
|
'data.permission.setting': '数据权限设置',
|
||||||
'change.role': '变更角色',
|
'change.role': '变更角色',
|
||||||
|
'all.data.permission': '全部数据权限',
|
||||||
|
'customize.data.permission': '自定义数据权限',
|
||||||
|
'self.data.permission': '仅本人数据',
|
||||||
|
|
||||||
...localeSettings,
|
...localeSettings,
|
||||||
...localeMessageBox,
|
...localeMessageBox,
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,11 @@
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-tree
|
<DepartmentTree
|
||||||
v-model:expanded-keys="expandedKeys"
|
v-model:expanded-keys="expandedKeys"
|
||||||
v-model:selected-keys="selectedKeys"
|
v-model:selected-keys="selectedKeys"
|
||||||
:field-names="{ key: 'id', title: 'name' }"
|
|
||||||
:data="departmentListData"
|
:data="departmentListData"
|
||||||
>
|
/>
|
||||||
<template #icon>
|
|
||||||
<IconStar />
|
|
||||||
</template>
|
|
||||||
</a-tree>
|
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col flex="auto">
|
<a-col flex="auto">
|
||||||
|
|
@ -82,9 +77,9 @@
|
||||||
<template #operate="{ record }">
|
<template #operate="{ record }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<!-- <a-button>查看</a-button> -->
|
<!-- <a-button>查看</a-button> -->
|
||||||
<a-button type="primary" @click="handleEditUser(record.id)">{{
|
<a-button type="primary" @click="handleEditUser(record.id)">
|
||||||
$t('edit')
|
{{ $t('edit') }}</a-button
|
||||||
}}</a-button>
|
>
|
||||||
<a-popover trigger="click" position="bottom">
|
<a-popover trigger="click" position="bottom">
|
||||||
<a-button>{{ $t('more') }}</a-button>
|
<a-button>{{ $t('more') }}</a-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
|
|
@ -138,6 +133,7 @@
|
||||||
import useDepartmentList from '@/composables/useDepartmentList';
|
import useDepartmentList from '@/composables/useDepartmentList';
|
||||||
import useDataTable from '@/composables/useDataTable';
|
import useDataTable from '@/composables/useDataTable';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import DepartmentTree from '@/components/common/DepartmentTree.vue';
|
||||||
import userFormDrawer from './components/user-form-drawer.vue';
|
import userFormDrawer from './components/user-form-drawer.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
|
||||||
|
|
@ -63,15 +63,19 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col flex="auto" class="full_height">
|
<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>
|
<template #extra>
|
||||||
<p style="margin-right: 10px">
|
<p style="margin-right: 10px">
|
||||||
<span>{{ $t('last.updated') }}</span>
|
<span>{{ $t('last.updated') }}</span>
|
||||||
<span>{{ roleItemInfo ? roleItemInfo.updatedAt : '' }}</span>
|
<span>{{ roleItemInfo ? roleItemInfo.updatedAt : '' }}</span>
|
||||||
</p>
|
</p>
|
||||||
<a-button type="primary" @click="handleSubmit">{{
|
<a-button
|
||||||
$t('submit')
|
v-if="currentTabsKey !== '3'"
|
||||||
}}</a-button>
|
type="primary"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
{{ $t('submit') }}</a-button
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<a-tab-pane key="1" :title="$t('function.permission')">
|
<a-tab-pane key="1" :title="$t('function.permission')">
|
||||||
<permissionCollapse
|
<permissionCollapse
|
||||||
|
|
@ -81,37 +85,73 @@
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="2" :title="$t('data.permission')">
|
<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>
|
||||||
<a-tab-pane key="3" :title="$t('user.assignment')">
|
<a-tab-pane key="3" :title="$t('user.assignment')">
|
||||||
<h4>{{ $t('user.assignment.setting') }}</h4>
|
<h4>{{ $t('user.assignment.setting') }}</h4>
|
||||||
<DataTable
|
<div style="padding-bottom: 20px">
|
||||||
style="margin-top: 20px"
|
<DataTable
|
||||||
:data="renderData"
|
style="margin-top: 20px"
|
||||||
:columns="projectColumn"
|
:data="renderData"
|
||||||
:loading="loading"
|
:columns="projectColumn"
|
||||||
:total="total"
|
:loading="loading"
|
||||||
:current="current"
|
:total="total"
|
||||||
:page-size="pageSize"
|
:current="current"
|
||||||
pagination
|
:page-size="pageSize"
|
||||||
@page-change="onPageChange"
|
pagination
|
||||||
@page-size-change="onPageSizeChange"
|
@page-change="onPageChange"
|
||||||
>
|
@page-size-change="onPageSizeChange"
|
||||||
<template #realname="{ record }">
|
>
|
||||||
<span>{{ record.realname }}</span>
|
<template #realname="{ record }">
|
||||||
<icon-idcard v-if="record.isManager === 1" />
|
<span>{{ record.realname }}</span>
|
||||||
</template>
|
<icon-idcard v-if="record.isManager === 1" />
|
||||||
<template #status="{ record }">
|
</template>
|
||||||
<a-tag :color="record.status == 1 ? 'green' : 'red'">
|
<template #status="{ record }">
|
||||||
{{ record.status == 1 ? $t('enable') : $t('disable') }}</a-tag
|
<a-tag :color="record.status == 1 ? 'green' : 'red'">
|
||||||
>
|
{{
|
||||||
</template>
|
record.status == 1 ? $t('enable') : $t('disable')
|
||||||
<template #operate="{ record }">
|
}}</a-tag
|
||||||
<a-button @click="changeRole(record?.id)">{{
|
>
|
||||||
$t('change.role')
|
</template>
|
||||||
}}</a-button>
|
<template #operate="{ record }">
|
||||||
</template>
|
<a-button @click="changeRole(record?.id)">{{
|
||||||
</DataTable>
|
$t('change.role')
|
||||||
|
}}</a-button>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
<changeRoleDrawer
|
<changeRoleDrawer
|
||||||
v-model:visible="changeRoleDrawerVisible"
|
v-model:visible="changeRoleDrawerVisible"
|
||||||
:role-id="currentRoleActiveId"
|
:role-id="currentRoleActiveId"
|
||||||
|
|
@ -127,7 +167,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted, watch } from 'vue';
|
||||||
import {
|
import {
|
||||||
getRoleList,
|
getRoleList,
|
||||||
RoleItem,
|
RoleItem,
|
||||||
|
|
@ -142,10 +182,14 @@
|
||||||
import useDataTable from '@/composables/useDataTable';
|
import useDataTable from '@/composables/useDataTable';
|
||||||
import type { TableColumnData } from '@arco-design/web-vue';
|
import type { TableColumnData } from '@arco-design/web-vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
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 permissionCollapse from './components/permission-collapse.vue';
|
||||||
import roleFormDrawer from './components/role-form-drawer.vue';
|
import roleFormDrawer from './components/role-form-drawer.vue';
|
||||||
import changeRoleDrawer from './components/change-role-drawer.vue';
|
import changeRoleDrawer from './components/change-role-drawer.vue';
|
||||||
|
|
||||||
|
const { departmentListData, allDepartmentKeys } = useDepartmentList();
|
||||||
|
|
||||||
const { loading, setLoading } = useLoading(true);
|
const { loading, setLoading } = useLoading(true);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const roleList = ref<RoleItem[]>([]);
|
const roleList = ref<RoleItem[]>([]);
|
||||||
|
|
@ -157,6 +201,10 @@
|
||||||
const permissionList = ref<any[]>([]);
|
const permissionList = ref<any[]>([]);
|
||||||
const changeRoleDrawerVisible = ref<boolean>(false);
|
const changeRoleDrawerVisible = ref<boolean>(false);
|
||||||
const selectedUserId = ref<number | null>(null);
|
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
|
// 使用 DataTable composable
|
||||||
const {
|
const {
|
||||||
data: renderData,
|
data: renderData,
|
||||||
|
|
@ -213,6 +261,7 @@
|
||||||
title: t('lastLogin'),
|
title: t('lastLogin'),
|
||||||
dataIndex: 'lastLoginTime',
|
dataIndex: 'lastLoginTime',
|
||||||
key: 'lastLoginTime',
|
key: 'lastLoginTime',
|
||||||
|
align: 'center',
|
||||||
render: ({ record }) => record.lastLoginTime || '-',
|
render: ({ record }) => record.lastLoginTime || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -325,7 +374,13 @@
|
||||||
const onRoleSubmit = () => {
|
const onRoleSubmit = () => {
|
||||||
getRoleListData(false);
|
getRoleListData(false);
|
||||||
};
|
};
|
||||||
|
watch(
|
||||||
|
allDepartmentKeys,
|
||||||
|
(val) => {
|
||||||
|
expandedKeys.value = val;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
if (!currentRoleActiveId.value) {
|
if (!currentRoleActiveId.value) {
|
||||||
Message.warning('请先选择一个角色');
|
Message.warning('请先选择一个角色');
|
||||||
|
|
@ -365,12 +420,6 @@
|
||||||
console.error('保存角色权限失败:', error);
|
console.error('保存角色权限失败:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTabChange = (key) => {
|
|
||||||
if (key === '3') {
|
|
||||||
// 占位注释,避免空代码块
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 分页事件处理
|
// 分页事件处理
|
||||||
const onPageChange = (page: number) => {
|
const onPageChange = (page: number) => {
|
||||||
setCurrent(page);
|
setCurrent(page);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue