feat(用户组管理): 左侧菜单静态页面
This commit is contained in:
parent
9cf5df3635
commit
fedde82130
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
|
|
|
@ -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';
|
||||
|
|
Loading…
Reference in New Issue