feat(用户组管理): 左侧菜单静态页面

This commit is contained in:
RubyLiu 2023-06-13 11:36:55 +08:00 committed by 刘瑞斌
parent 9cf5df3635
commit fedde82130
7 changed files with 185 additions and 71 deletions

View File

@ -58,7 +58,8 @@
"vue-echarts": "^6.5.5",
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.2",
"vue3-ace-editor": "^2.2.2"
"vue3-ace-editor": "^2.2.2",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@arco-plugins/vite-vue": "^1.4.5",

View File

@ -1,75 +1,171 @@
<template>
<div class="type-list">
<a-input-search v-model="searchKey" @press-enter="searchData" />
<a-tree :data="treeData">
<template #title="nodeData">
<div>{{ nodeData }}</div>
</template>
</a-tree>
<div>
<a-input-search
v-model="searchKey"
class="w-[252px]"
:placeholder="t('system.userGroup.searchHolder')"
@press-enter="searchData"
/>
<div class="mt-2 flex flex-col">
<div class="second-color">
<icon-plus-circle v-if="!systemHidden" @click="handleSystemHidden" />
<icon-minus-circle v-if="systemHidden" @click="handleSystemHidden" />
<span class="ml-1"> {{ t('system.userGroup.inSystem') }}</span>
</div>
<div v-if="systemHidden">
<div
v-for="element in systemList"
:key="element.id"
:class="{
'flex': true,
' h-[38px]': true,
'items-center': true,
'is-active': element.id === currentId,
'px-[4px]': true,
}"
@click="currentId = element.id"
>
<div class="draglist-item flex grow flex-row justify-between">
<div :class="'ml-[20px]'">{{ element.name }}</div>
<div v-if="element.id === currentId">
<a-popconfirm position="rb">
<template #content>
<a-button type="primary" @click="addUser(element.id)">{{ t('system.userGroup.addUser') }}</a-button>
</template>
<icon-plus />
</a-popconfirm>
</div>
</div>
</div>
</div>
<a-divider />
<div class="second-color flex items-center justify-between px-[4px]">
<div>
<icon-plus-circle v-if="!customHidden" @click="handleCustomHidden" />
<icon-minus-circle v-if="customHidden" @click="handleCustomHidden" />
<span class="ml-1"> {{ t('system.userGroup.customUserGroup') }}</span>
</div>
<div class="flex items-center">
<icon-plus-circle class="primary-color text-xl" @click="addSystemUserGroup" />
</div>
</div>
<div class="mt-[16px] px-[4px]">
<div v-if="customShowEmpty" class="custom-empty">{{ t('system.userGroup.emptyUserGroup') }}</div>
<draggable v-else v-model="customList" class="list-group" item-key="name" handle=".handle">
<template #item="{ element }">
<div
:class="{
'flex': true,
' h-[38px]': true,
'items-center': true,
'is-active': element.id === currentId,
'px-[4px]': true,
}"
@click="currentId = element.id"
>
<div v-if="element.id === currentId" class="handle"><icon-drag-dot-vertical /></div>
<div class="draglist-item flex grow flex-row justify-between">
<div :class="element.id === currentId ? 'ml-[8px]' : 'ml-[20px]'">{{ element.name }}</div>
<div v-if="element.id === currentId">
<a-popconfirm position="rb">
<template #content>
<a-button type="primary" @click="addUser(element.id)">{{
t('system.userGroup.addUser')
}}</a-button>
</template>
<icon-plus />
</a-popconfirm>
</div>
</div>
</div>
</template>
</draggable>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { TreeNodeData } from '@arco-design/web-vue';
import { ref, computed } from 'vue';
import { useI18n } from '@/hooks/useI18n';
import draggable from 'vuedraggable';
import { UserGroupListItem } from './type';
const originTreeData: TreeNodeData[] = [
{
title: 'Trunk 0-0',
key: '0-0',
children: [
{
title: 'Branch 0-0-1',
key: '0-0-1',
children: [
{
title: 'Leaf 0-0-1-1',
key: '0-0-1-1',
},
{
title: 'Leaf 0-0-1-2',
key: '0-0-1-2',
},
],
},
],
},
{
title: 'Trunk 0-1',
key: '0-1',
children: [
{
title: 'Branch 0-1-1',
key: '0-1-1',
children: [
{
title: 'Leaf 0-1-1-0',
key: '0-1-1-0',
},
],
},
{
title: 'Branch 0-1-2',
key: '0-1-2',
children: [
{
title: 'Leaf 0-1-2-0',
key: '0-1-2-0',
},
],
},
],
},
];
const treeData = ref(originTreeData);
const { t } = useI18n();
const searchKey = ref('');
// true +; false -
const systemHidden = ref(true);
const customHidden = ref(true);
// loading
const loading = ref(false);
const currentId = ref(0);
const systemList = ref<UserGroupListItem[]>([
{ name: '系统管理员1', id: 1 },
{ name: '系统管理员2', id: 2 },
{ name: '系统管理员3', id: 3 },
]);
const customList = ref<UserGroupListItem[]>([
{ name: '自定义用户组 1 (系统)', id: 4 },
{ name: '自定义用户组 2 (系统)', id: 5 },
{ name: '自定义用户组 3 (系统)', id: 6 },
]);
// const customList = ref<UserGroupListItem[]>([]);
const currentSystemId = ref(0);
const handleSystemHidden = () => {
systemHidden.value = !systemHidden.value;
};
const handleCustomHidden = () => {
customHidden.value = !customHidden.value;
};
const addUser = (id: number) => {
currentSystemId.value = id;
};
const addSystemUserGroup = () => {
// eslint-disable-next-line no-console
console.log('addSystemUserGroup');
};
function searchData(keyword: string) {
// eslint-disable-next-line no-console
console.log(keyword);
}
const customShowEmpty = computed(() => {
return !loading.value && !customList.value.length;
});
</script>
<style lang="less" scoped></style>
<style scoped lang="less">
.primary-color {
color: rgb(var(--primary-5));
}
.second-color {
color: var(--color-text-input-border);
}
.handle {
cursor: move;
opacity: 0.3;
}
.is-active {
background-color: rgb(var(--primary-1));
}
.custom-empty {
padding: 8px;
font-size: 12px;
font-family: 'PingFang SC';
font-weight: 400;
border-radius: 4px;
color: #8f959e;
background: #f7f9fc;
font-style: normal;
line-height: 20px;
overflow-wrap: break-word;
}
</style>

View File

@ -6,12 +6,13 @@ import minder from '@/components/pure/minder-editor/locale/en-US';
import localeLogin from '@/views/login/locale/en-US';
import localeTable from '@/components/pure/ms-table/locale/en-US';
import localeApiTest from '@/views/api-test/locale/en-US';
import localeUser from '@/views/system/locale/en-US';
import localeSystem from '@/views/system/locale/en-US';
export default {
message: {
'menu.apiTest': 'Api Test',
'menu.settings': 'System Settings',
'menu.settings.usergroup': 'User Group',
'menu.settings.user': 'User',
'menu.settings.organization': 'Organization',
'navbar.action.locale': 'Switch to English',
@ -22,7 +23,7 @@ export default {
...minder,
...localeTable,
...localeApiTest,
...localeUser,
...localeSystem,
},
dayjsLocale,
dayjsLocaleName: 'en-US',

View File

@ -6,13 +6,14 @@ import minder from '@/components/pure/minder-editor/locale/zh-CN';
import localeLogin from '@/views/login/locale/zh-CN';
import localeTable from '@/components/pure/ms-table/locale/zh-CN';
import localeApiTest from '@/views/api-test/locale/zh-CN';
import localeUser from '@/views/system/locale/zh-CN';
import localeSystem from '@/views/system/locale/zh-CN';
export default {
message: {
'menu.apiTest': '接口测试',
'menu.settings': '系统设置',
'menu.settings.user': '用户',
'menu.settings.usergroup': '用户组',
'menu.settings.organization': '组织',
'menu.user': '个人中心',
'navbar.action.locale': '切换为中文',
@ -23,7 +24,7 @@ export default {
...minder,
...localeTable,
...localeApiTest,
...localeUser,
...localeSystem,
},
dayjsLocale,
dayjsLocaleName: 'zh-CN',

View File

@ -102,6 +102,16 @@ setupMock({
icon: 'icon-computer',
},
},
{
path: 'usergroup',
name: 'usergroup',
component: () => import('@/views/system/usergroup/index.vue'),
meta: {
locale: 'menu.settings.usergroup',
roles: ['*'],
icon: 'icon-computer',
},
},
],
},
];

View File

@ -24,9 +24,9 @@ const ApiTest: AppRouteRecordRaw = {
{
path: 'usergroup',
name: 'usergroup',
component: () => import('@/views/system/user/index.vue'),
component: () => import('@/views/system/usergroup/index.vue'),
meta: {
locale: 'menu.settings.user',
locale: 'menu.settings.usergroup',
roles: ['*'],
icon: 'icon-computer',
},

View File

@ -1,13 +1,18 @@
<template>
<div class="h-[100vh] bg-white px-[20px] py-[16px] pb-0">
<div class="left h-[730px] w-[300px]"> </div>
<div class="right"></div>
<ms-base-table v-bind="propsRes" v-on="propsEvent"> </ms-base-table>
<div class="flex h-[100vh] flex-row bg-white px-[20px] py-[16px] pb-0">
<div class="h-[730px] w-[300px] p-6">
<UserGroupLeft />
</div>
<div class="grow-1 overflow-scroll">
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> </MsBaseTable>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import UserGroupLeft from '@/components/bussiness/usergroup/index.vue';
import { MsTableColumn } from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import { getTableList } from '@/api/modules/api-test/index';