feat(用户组管理): 左侧菜单静态页面
This commit is contained in:
parent
9cf5df3635
commit
fedde82130
|
@ -58,7 +58,8 @@
|
||||||
"vue-echarts": "^6.5.5",
|
"vue-echarts": "^6.5.5",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.2.2",
|
"vue-router": "^4.2.2",
|
||||||
"vue3-ace-editor": "^2.2.2"
|
"vue3-ace-editor": "^2.2.2",
|
||||||
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arco-plugins/vite-vue": "^1.4.5",
|
"@arco-plugins/vite-vue": "^1.4.5",
|
||||||
|
|
|
@ -1,75 +1,171 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="type-list">
|
<div>
|
||||||
<a-input-search v-model="searchKey" @press-enter="searchData" />
|
<a-input-search
|
||||||
<a-tree :data="treeData">
|
v-model="searchKey"
|
||||||
<template #title="nodeData">
|
class="w-[252px]"
|
||||||
<div>{{ nodeData }}</div>
|
: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>
|
</template>
|
||||||
</a-tree>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { TreeNodeData } from '@arco-design/web-vue';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import draggable from 'vuedraggable';
|
||||||
|
import { UserGroupListItem } from './type';
|
||||||
|
|
||||||
const originTreeData: TreeNodeData[] = [
|
const { t } = useI18n();
|
||||||
{
|
|
||||||
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 searchKey = ref('');
|
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) {
|
function searchData(keyword: string) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(keyword);
|
console.log(keyword);
|
||||||
}
|
}
|
||||||
|
const customShowEmpty = computed(() => {
|
||||||
|
return !loading.value && !customList.value.length;
|
||||||
|
});
|
||||||
</script>
|
</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>
|
||||||
|
|
|
@ -6,12 +6,13 @@ import minder from '@/components/pure/minder-editor/locale/en-US';
|
||||||
import localeLogin from '@/views/login/locale/en-US';
|
import localeLogin from '@/views/login/locale/en-US';
|
||||||
import localeTable from '@/components/pure/ms-table/locale/en-US';
|
import localeTable from '@/components/pure/ms-table/locale/en-US';
|
||||||
import localeApiTest from '@/views/api-test/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 {
|
export default {
|
||||||
message: {
|
message: {
|
||||||
'menu.apiTest': 'Api Test',
|
'menu.apiTest': 'Api Test',
|
||||||
'menu.settings': 'System Settings',
|
'menu.settings': 'System Settings',
|
||||||
|
'menu.settings.usergroup': 'User Group',
|
||||||
'menu.settings.user': 'User',
|
'menu.settings.user': 'User',
|
||||||
'menu.settings.organization': 'Organization',
|
'menu.settings.organization': 'Organization',
|
||||||
'navbar.action.locale': 'Switch to English',
|
'navbar.action.locale': 'Switch to English',
|
||||||
|
@ -22,7 +23,7 @@ export default {
|
||||||
...minder,
|
...minder,
|
||||||
...localeTable,
|
...localeTable,
|
||||||
...localeApiTest,
|
...localeApiTest,
|
||||||
...localeUser,
|
...localeSystem,
|
||||||
},
|
},
|
||||||
dayjsLocale,
|
dayjsLocale,
|
||||||
dayjsLocaleName: 'en-US',
|
dayjsLocaleName: 'en-US',
|
||||||
|
|
|
@ -6,13 +6,14 @@ import minder from '@/components/pure/minder-editor/locale/zh-CN';
|
||||||
import localeLogin from '@/views/login/locale/zh-CN';
|
import localeLogin from '@/views/login/locale/zh-CN';
|
||||||
import localeTable from '@/components/pure/ms-table/locale/zh-CN';
|
import localeTable from '@/components/pure/ms-table/locale/zh-CN';
|
||||||
import localeApiTest from '@/views/api-test/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 {
|
export default {
|
||||||
message: {
|
message: {
|
||||||
'menu.apiTest': '接口测试',
|
'menu.apiTest': '接口测试',
|
||||||
'menu.settings': '系统设置',
|
'menu.settings': '系统设置',
|
||||||
'menu.settings.user': '用户',
|
'menu.settings.user': '用户',
|
||||||
|
'menu.settings.usergroup': '用户组',
|
||||||
'menu.settings.organization': '组织',
|
'menu.settings.organization': '组织',
|
||||||
'menu.user': '个人中心',
|
'menu.user': '个人中心',
|
||||||
'navbar.action.locale': '切换为中文',
|
'navbar.action.locale': '切换为中文',
|
||||||
|
@ -23,7 +24,7 @@ export default {
|
||||||
...minder,
|
...minder,
|
||||||
...localeTable,
|
...localeTable,
|
||||||
...localeApiTest,
|
...localeApiTest,
|
||||||
...localeUser,
|
...localeSystem,
|
||||||
},
|
},
|
||||||
dayjsLocale,
|
dayjsLocale,
|
||||||
dayjsLocaleName: 'zh-CN',
|
dayjsLocaleName: 'zh-CN',
|
||||||
|
|
|
@ -102,6 +102,16 @@ setupMock({
|
||||||
icon: 'icon-computer',
|
icon: 'icon-computer',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'usergroup',
|
||||||
|
name: 'usergroup',
|
||||||
|
component: () => import('@/views/system/usergroup/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'menu.settings.usergroup',
|
||||||
|
roles: ['*'],
|
||||||
|
icon: 'icon-computer',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -24,9 +24,9 @@ const ApiTest: AppRouteRecordRaw = {
|
||||||
{
|
{
|
||||||
path: 'usergroup',
|
path: 'usergroup',
|
||||||
name: 'usergroup',
|
name: 'usergroup',
|
||||||
component: () => import('@/views/system/user/index.vue'),
|
component: () => import('@/views/system/usergroup/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.settings.user',
|
locale: 'menu.settings.usergroup',
|
||||||
roles: ['*'],
|
roles: ['*'],
|
||||||
icon: 'icon-computer',
|
icon: 'icon-computer',
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-[100vh] bg-white px-[20px] py-[16px] pb-0">
|
<div class="flex h-[100vh] flex-row bg-white px-[20px] py-[16px] pb-0">
|
||||||
<div class="left h-[730px] w-[300px]"> </div>
|
<div class="h-[730px] w-[300px] p-6">
|
||||||
<div class="right"></div>
|
<UserGroupLeft />
|
||||||
<ms-base-table v-bind="propsRes" v-on="propsEvent"> </ms-base-table>
|
</div>
|
||||||
|
<div class="grow-1 overflow-scroll">
|
||||||
|
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> </MsBaseTable>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from 'vue';
|
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 { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import { getTableList } from '@/api/modules/api-test/index';
|
import { getTableList } from '@/api/modules/api-test/index';
|
||||||
|
|
Loading…
Reference in New Issue