Commit 368d6b06 authored by 罗林杰's avatar 罗林杰

增加工作组模块

parent 5bb35ab9
......@@ -3,7 +3,6 @@ import type { AppRouteRecordRaw, AppRouteModule } from '@/router/types';
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes/basic';
import { LAYOUT } from '@/router/constant';
import { mainOutRoutes } from './mainOut';
import { PageEnum } from '@/enums/pageEnum';
import { t } from '@/hooks/web/useI18n';
// import.meta.glob() 直接引入所有的模块 Vite 独有的功能
......@@ -83,12 +82,36 @@ export const UserRoute: AppRouteRecordRaw = {
},
],
};
export const WorkSpaceRoute: AppRouteRecordRaw = {
path: '/workspace',
name: 'Workspace',
component: LAYOUT,
meta: {
title: '工作区管理',
icon: '',
hidden: true,
currentActiveMenu: '/system/workspace',
},
children: [
{
path: 'detail',
name: 'Detail',
component: () => import('@/views/system/workspace/detail.vue'),
meta: {
title: '工作区详情',
icon: '',
},
},
],
};
// Basic routing without permission
// 没有权限要求的基本路由
export const basicRoutes = [
LoginRoute,
DictRoute,
UserRoute,
WorkSpaceRoute,
// RootRoute,
...mainOutRoutes,
REDIRECT_ROUTE,
......
<template>
<div>
工作组管理
</div>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
title="工作区列表"
ref="treeRef"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="true"
:defaultExpandAll="true"
:treeData="treeData"
:fieldNames="{ key: 'businessId', title: 'workSpaceName' }"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { TreeData } from '@/views/system/workspace/workSpaceData';
import {router} from "@/router";
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const treeRef = ref<Nullable<TreeActionType>>(null);
function getTree() {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
async function fetch() {
const data = TreeData;
treeData.value = handleTree(data, 'businessId', undefined, undefined, undefined);
await nextTick(() => {
getTree().expandAll(true);
});
}
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
function handleSelect() {
router.push({
path: '/workspace/detail',
});
}
onMounted(() => {
fetch();
});
</script>
import { getAllRoleList } from '@/api/system/role/role';
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Switch } from 'ant-design-vue';
import { useMessage } from '@/hooks/web/useMessage';
import { changeFlagApi } from '@/api/system/user/user';
// 引入开关组件
type CheckedType = boolean | string | number;
/**
* transform mock data
* {
* 0: '华东分部',
* '0-0': '华东分部-研发部'
* '0-1': '华东分部-市场部',
* ...
* }
*/
export const deptMap = (() => {
const pDept = ['华东分部', '华南分部', '西北分部'];
const cDept = ['研发部', '市场部', '商务部', '财务部'];
return pDept.reduce((map, p, pIdx) => {
map[pIdx] = p;
cDept.forEach((c, cIndex) => (map[`${pIdx}-${cIndex}`] = `${p}-${c}`));
return map;
}, {});
})();
export const columns: BasicColumn[] = [
{
title: '工作区名称',
dataIndex: 'workSpaceName',
width: 120,
},
{
title: '创建人',
dataIndex: 'createBy',
width: 120,
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 140,
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'username',
label: '账号',
component: 'Input',
colProps: { span: 8 },
},
];
function passwordCheck(rule, value, callback) {
const hasUpperCase = /[A-Z]/.test(value);
const hasLowerCase = /[a-z]/.test(value);
const hasNumber = /\d/.test(value);
const hasSpecialChar = /[~`!@#$%^&*()_\-={}\[\]\\|;:"'<,>.?\/]/.test(value);
// 检查密码组成
let count = 0;
if (hasUpperCase) count++;
if (hasLowerCase) count++;
if (hasNumber) count++;
if (hasSpecialChar) count++;
if (count < 3) {
return callback(new Error('密码中需至少包含大写字母、小写字母、数字及特殊字符中的 3 种'));
}
// 如果所有检查都通过,则调用callback无参数表示验证成功
callback();
}
export const accountFormSchema: any[] = [
{
field: 'username',
label: '账号',
component: 'Input',
// helpMessage: ['本字段演示异步验证', '不能输入带有admin的用户名'],
rules: [
{
required: true,
message: '请输入登录名',
},
],
},
{
field: 'password',
label: '密码',
component: 'InputPassword',
rules: [
{
required: true,
message: '请输入用户密码',
},
{ min: 8, max: 25, message: '长度在 8 到 25 个字符', trigger: 'blur' },
{
validator: passwordCheck,
trigger: 'blur',
},
],
},
{
field: 'name',
label: '姓名',
component: 'Input',
},
{
field: 'nickName',
label: '昵称',
component: 'Input',
},
{
field: 'sex',
label: '性别',
component: 'Select',
componentProps: {
options: [
{ label: '男', value: '1' },
{ label: '女', value: '0' },
],
},
},
{
field: 'phone',
label: '手机号码',
component: 'Input',
rules: [
{ required: false, message: '请输入手机号码', trigger: 'blur' },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur',
},
],
},
{
field: 'idNumber',
label: '身份证号',
component: 'Input',
rules: [
{
required: false,
message: '请输入身份证号',
trigger: 'blur',
},
{ min: 18, max: 18, message: '长度18字符', trigger: 'blur' },
],
},
{
field: 'email',
label: '邮箱',
component: 'Input',
rules: [
{ required: false, message: '请输入邮箱地址', trigger: 'blur' },
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change'],
},
],
},
{
field: 'flag',
label: '状态',
component: 'RadioGroup',
colProps: { lg: 24, md: 24 },
componentProps: {
options: [
{ label: '启用', value: '1' },
{ label: '停用', value: '0' },
],
},
required: true,
},
{
field: 'deptId',
label: '所属部门',
component: 'TreeSelect',
colProps: { lg: 24, md: 24 },
componentProps: {
fieldNames: {
label: 'deptName',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
required: true,
},
{
field: 'roleList',
label: '角色',
component: 'ApiSelect',
colProps: { lg: 24, md: 24 },
componentProps: {
// placeholder: '公开给',
mode: 'multiple',
api: getAllRoleList,
labelField: 'roleName',
valueField: 'businessId',
resultField: 'data',
},
required: true,
},
];
export const searchDetailFormSchema: FormSchema[] = [
{
field: 'username',
label: '角色名称',
component: 'Input',
colProps: { span: 8 },
},
];
export const detailColumns: BasicColumn[] = [
{
title: '角色名称',
dataIndex: 'roleNames',
width: 200,
},
{
title: '角色描述',
dataIndex: 'phone',
width: 200,
},
];
export const groupColumns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'name',
width: 200,
},
{
title: '账号',
dataIndex: 'username',
width: 200,
},
{
title: '部门',
dataIndex: 'deptId',
width: 200,
},
{
title: '角色',
dataIndex: 'roleNames',
width: 200,
},
];
<template>
<PageWrapper title="工作区详情" class="content-padding" contentBackground @back="goBack">
<template #footer>
<a-tabs default-active-key="global" v-model:activeKey="currentKey">
<a-tab-pane key="global" tab="概览" />
<a-tab-pane key="user" tab="用户列表" />
<a-tab-pane key="group" tab="工作组" />
</a-tabs>
</template>
<div class="pt-4 m-4 desc-wrap">
<template v-if="currentKey == 'global'"> </template>
<template v-if="currentKey == 'user'">
<BasicTable @register="registerGroupTable" :searchInfo="searchInfo">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
label: '',
onClick: handleEdit.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
color: 'error',
label: '',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
</template>
<template v-if="currentKey == 'group'">
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<GroupTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable @register="registerTable" class="w-2/4 xl:w-4/5" :searchInfo="searchInfo">
<template #toolbar>
<a-button type="primary" @click="handleCreate">新增用户</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '详情',
onClick: handleView.bind(null, record),
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
color: 'error',
label: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
</PageWrapper>
</template>
<AccountModal @register="registerModal" @success="handleSuccess" />
</div>
</PageWrapper>
</template>
<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';
import { useRoute } from 'vue-router';
import { PageWrapper } from '@/components/Page';
import { useGo } from '@/hooks/web/usePage';
import { useTabs } from '@/hooks/web/useTabs';
import { Tabs } from 'ant-design-vue';
import { BasicTable, TableAction, useTable } from '@/components/Table';
import { deleteUser, getAccountList } from '@/api/system/user/user';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import AccountModal from '@/views/system/user/AccountModal.vue';
import {
columns,
groupColumns,
searchDetailFormSchema,
searchFormSchema,
} from '@/views/system/workspace/data';
import GroupTree from '@/views/system/workspace/GroupTree.vue';
import { TreeData } from '@/views/system/workspace/workSpaceData';
defineOptions({ name: 'AccountDetail' });
const tableData = ref([]);
const [registerTable, { reload, updateTableDataRecord, getSearchInfo, getForm }] = useTable({
title: '工作组列表',
api: async (params) => {
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: tableData.value.length,
code: '',
message: '',
data: [],
};
//过滤data中的数据,取出等于params.deptId的数据
var data = [];
if (params.institutionId != undefined && params.institutionId != '') {
data = tableData.value.filter((item) => item.institutionId === params.institutionId);
} else {
data = tableData.value.filter((item) => item.parentId !== 100 && item.parentId !== 0);
}
return { ...response, data: data };
},
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.deptId = '';
},
},
useSearchForm: true,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 100,
title: '操作',
dataIndex: 'action',
},
});
const [registerGroupTable, { reloadGroup, getGroupForm }] = useTable({
title: '用户列表',
api: getAccountList,
columns: groupColumns,
formConfig: {
labelWidth: 100,
schemas: searchDetailFormSchema,
},
useSearchForm: true,
showTableSetting: false,
bordered: true,
showIndexColumn: false,
actionColumn: {
width: 80,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
fixed: undefined,
},
});
const [registerModal, { openModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const { createMessage } = useMessage();
const ATabs = Tabs;
const ATabPane = Tabs.TabPane;
const route = useRoute();
const go = useGo();
const currentKey = ref('global');
const { setTitle } = useTabs();
// 设置Tab的标题(不会影响页面标题)
setTitle('工作区详情');
/** 删除按钮*/
function handleDelete(record: Recordable) {
console.log(record);
deleteUser({ id: record.businessId });
createMessage.success('删除成功!');
reload();
}
/** 编辑按钮*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
});
}
function handleSuccess({ isUpdate, values }) {
if (isUpdate) {
// 演示不刷新表格直接更新内部数据。
// 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
const result = updateTableDataRecord(values.id, values);
console.log(result);
reload();
} else {
reload();
}
}
function handleView(record: Recordable) {}
/** 新增按钮*/
function handleCreate() {
openModal(true, {
isUpdate: false,
});
}
/** 部门树的select*/
function handleSelect(deptId = '') {
searchInfo.deptId = deptId;
reload();
}
// 页面左侧点击返回链接时的操作
function goBack() {
// 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
go('/system/system/workspace');
}
onMounted(() => {
tableData.value = TreeData;
});
</script>
<style></style>
<template>
<div>
工作区管理
</div>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<GroupTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
<template #toolbar>
<a-button type="primary" @click="handleCreate">新增</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '详情',
onClick: handleView.bind(null, record),
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '更换管理员',
onClick: handleEdit.bind(null, record),
},
{
color: 'error',
label: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<AccountModal @register="registerModal" @success="handleSuccess" />
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getAccountList, deleteUser } from '@/api/system/user/user';
import { PageWrapper } from '@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { useModal } from '@/components/Modal';
import AccountModal from '@/views/system/user/AccountModal.vue';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { useFilterStore } from '@/store/modules/filterData';
import { columns, searchFormSchema } from '@/views/system/workspace/data';
import GroupTree from '@/views/system/workspace/GroupTree.vue';
import { router } from '@/router';
import { TreeData } from '@/views/system/workspace/workSpaceData';
<script>
export default {
name: "index"
}
defineOptions({ name: 'AccountManagement' });
const { createMessage } = useMessage();
const filterStore = useFilterStore();
const route = useRoute();
const [registerModal, { openModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const tableData = ref([]);
const [registerTable, { reload, updateTableDataRecord, getSearchInfo, getForm }] = useTable({
title: '工作区列表',
api: async (params) => {
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: tableData.value.length,
code: '',
message: '',
data: [],
};
//过滤data中的数据,取出等于params.deptId的数据
var data = [];
if (params.institutionId != undefined && params.institutionId != '') {
data = tableData.value.filter((item) => item.institutionId === params.institutionId);
} else {
data = tableData.value.filter((item) => item.parentId !== 100 && item.parentId !== 0);
}
return { ...response, data: data };
},
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.deptId = '';
},
},
useSearchForm: true,
showIndexColumn: false,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 140,
title: '操作',
dataIndex: 'action',
},
});
/** 新增按钮*/
function handleCreate() {
openModal(true, {
isUpdate: false,
});
}
/** 编辑按钮*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
});
}
/** 重置密码弹窗确定按钮*/
/** 删除按钮*/
function handleDelete(record: Recordable) {
console.log(record);
deleteUser({ id: record.businessId });
createMessage.success('删除成功!');
reload();
}
/** 新增/编辑成功*/
function handleSuccess({ isUpdate, values }) {
if (isUpdate) {
// 演示不刷新表格直接更新内部数据。
// 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
const result = updateTableDataRecord(values.id, values);
console.log(result);
reload();
} else {
reload();
}
}
function handleView(record: Recordable) {
router.push({
path: '/workspace/detail',
});
}
/** 部门树的select*/
function handleSelect(deptId = '') {
searchInfo.deptId = deptId;
reload();
}
onMounted(() => {
tableData.value = TreeData;
const path = route.path;
if (filterStore.getSearchParams[path]) {
if (JSON.parse(filterStore.getSearchParams[path] !== {})) {
const params = JSON.parse(filterStore.getSearchParams[path]);
console.log('11111111111111111111111111111', params);
getForm().setFieldsValue({
page: params.page,
pageSize: params.pageSize,
username: params.username,
flag: params.flag,
});
searchInfo.deptId = params.deptId;
}
}
});
onBeforeRouteLeave((to, from, next) => {
const params = Object.assign({}, getSearchInfo(), getForm().getFieldsValue());
console.log('path', from.path);
console.log('params', params);
filterStore.setSearchParams({
path: from.path,
param: {
...params,
},
});
next(); // 允许导航
});
</script>
<style scoped>
</style>
export const TreeData: any[] = [
{
delFlag: '0',
flag: '1',
businessId: 100,
workSpaceName: '工作区管理',
parentId: 0,
'code:': '001',
ancestors: '0',
orderNum: 0,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 101,
workSpaceName: '数据平台治理部',
parentId: 100,
'code:': '002',
ancestors: '0,100',
orderNum: 1,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 107,
workSpaceName: '数据资源管理部',
parentId: 100,
'code:': '003',
ancestors: '0,100',
orderNum: 2,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 102,
workSpaceName: '研发部门',
parentId: 101,
'code:': '004',
ancestors: '0,100,101',
orderNum: 1,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 103,
workSpaceName: '市场部门',
parentId: 101,
'code:': '005',
ancestors: '0,100,101',
orderNum: 2,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 104,
workSpaceName: '测试部门',
parentId: 101,
'code:': '006',
ancestors: '0,100,101',
orderNum: 3,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 105,
workSpaceName: '财务部门',
parentId: 101,
'code:': '007',
ancestors: '0,100,101',
orderNum: 4,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 106,
workSpaceName: '运维部门',
parentId: 101,
'code:': '008',
ancestors: '0,100,101',
orderNum: 5,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '1',
businessId: 202,
workSpaceName: '数据部门',
parentId: 107,
'code:': '009',
ancestors: '0,100,107',
orderNum: 1,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
{
delFlag: '0',
flag: '0',
businessId: 203,
workSpaceName: '检查部门',
parentId: 107,
'code:': '010',
ancestors: '0,100,107',
orderNum: 2,
children: [],
selectType: null,
createTime: '2024-10-24 10:04:04',
createBy: 'admin',
},
];
export const userData: any[] = [
{
delFlag: '0',
flag: '1',
businessId: 309,
username: 'yonghu1',
nickName: '测试用户1',
userType: '1',
name: '测试用户1',
createDate: '2024-10-24 10:04:04',
institutionId: 105,
workSpaceName: '财务部门',
code: '123f',
identity: '1',
roleIds: null,
roleNames: '三级用户',
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 310,
username: 'yonghu2',
nickName: '测试用户2',
userType: '1',
name: '测试用户2',
createDate: '2024-10-25 10:05:05',
sex: '0',
institutionId: 105,
workSpaceName: '财务部门',
code: '123a',
identity: '1',
roleIds: null,
roleNames: null,
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 317,
username: 'yonghu3',
nickName: '测试用户3',
userType: '1',
name: '测试用户3',
createDate: '2024-10-26 10:06:06',
sex: '1',
institutionId: 102,
workSpaceName: '研发部门',
code: '123c',
identity: '1',
roleIds: null,
roleNames: '超级管理员',
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 318,
username: 'yonghu4',
nickName: '测试用户4',
userType: '1',
name: '测试用户4',
createDate: '2024-10-26 10:06:06',
sex: '1',
institutionId: 102,
workSpaceName: '研发部门',
code: '123b',
identity: '1',
roleIds: null,
roleNames: '超级管理员',
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 319,
username: 'yonghu5',
nickName: '测试用户5',
userType: '1',
name: '测试用户5',
createDate: '2024-10-26 10:06:06',
sex: '1',
institutionId: 102,
workSpaceName: '研发部门',
code: '123x',
identity: '1',
roleIds: null,
roleNames: '超级管理员',
roleList: null,
menuList: [],
},
];
export const accountFormSchema: any[] = [];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment