!55 使用accessMenus增强用户存储 & 优化 自定义API组件
Merge pull request !55 from chenminjie/dev-v5_cmjpull/56/MERGE
commit
5e22a00da7
|
@ -160,22 +160,24 @@ const handleMenuClick = (e: any) => {
|
||||||
</Button>
|
</Button>
|
||||||
</slot>
|
</slot>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<Menu @click="handleMenuClick">
|
<Menu class="w-full" @click="handleMenuClick">
|
||||||
<MenuItem v-for="(action, index) in getDropdownList" :key="index">
|
<MenuItem v-for="(action, index) in getDropdownList" :key="index">
|
||||||
<template v-if="action.popConfirm">
|
<template v-if="action.popConfirm">
|
||||||
<Popconfirm v-bind="getPopConfirmProps(action.popConfirm)">
|
<Popconfirm v-bind="getPopConfirmProps(action.popConfirm)">
|
||||||
<template v-if="action.popConfirm.icon" #icon>
|
<template v-if="action.popConfirm.icon" #icon>
|
||||||
<IconifyIcon :icon="action.popConfirm.icon" />
|
<IconifyIcon :icon="action.popConfirm.icon" />
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div class="flex items-center">
|
||||||
<IconifyIcon v-if="action.icon" :icon="action.icon" />
|
<IconifyIcon v-if="action.icon" :icon="action.icon" />
|
||||||
<span class="ml-1">{{ action.text }}</span>
|
<span class="ml-1">{{ action.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<IconifyIcon v-if="action.icon" :icon="action.icon" />
|
<div class="flex items-center">
|
||||||
<span class="ml-1">{{ action.label }}</span>
|
<IconifyIcon v-if="action.icon" :icon="action.icon" />
|
||||||
|
<span class="ml-1">{{ action.text }}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, type PropType } from 'vue';
|
import { computed, type PropType } from 'vue';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { useDictStore } from '@vben/stores';
|
||||||
|
|
||||||
import { ApiCheckboxGroup, ApiRadioGroup, ApiSelect } from '..';
|
import { ApiCheckboxGroup, ApiRadioGroup, ApiSelect } from '..';
|
||||||
|
|
||||||
|
@ -42,9 +42,10 @@ const DictComponent = computed(() => {
|
||||||
return ApiSelect;
|
return ApiSelect;
|
||||||
});
|
});
|
||||||
const fetch = () => {
|
const fetch = () => {
|
||||||
return requestClient.post('/sys/dict/getByDictType', {
|
return new Promise<OptionsItem[]>((resolve) => {
|
||||||
dictType: props.code,
|
const dict = useDictStore().getDictOptions(props.code!);
|
||||||
...props.params,
|
const options: OptionsItem[] = dict as OptionsItem[];
|
||||||
|
resolve(options);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -111,6 +111,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
authPermissionInfo = await getAuthPermissionInfoApi();
|
authPermissionInfo = await getAuthPermissionInfoApi();
|
||||||
userStore.setUserInfo(authPermissionInfo.user);
|
userStore.setUserInfo(authPermissionInfo.user);
|
||||||
userStore.setUserRoles(authPermissionInfo.roles);
|
userStore.setUserRoles(authPermissionInfo.roles);
|
||||||
|
userStore.setAccessMenus(authPermissionInfo.menus as []);
|
||||||
accessStore.setAccessCodes(authPermissionInfo.permissions);
|
accessStore.setAccessCodes(authPermissionInfo.permissions);
|
||||||
return authPermissionInfo;
|
return authPermissionInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import type { VbenFormProps } from '@vben/common-ui';
|
|
||||||
|
|
||||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
import type { CodegenApi } from '#/api/infra/codegen';
|
import type { CodegenApi } from '#/api/infra/codegen';
|
||||||
|
|
||||||
|
import { type VbenFormProps, z } from '@vben/common-ui';
|
||||||
|
import { useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
import { getDataSourceConfigList } from '#/api/infra/data-source-config';
|
import { getDataSourceConfigList } from '#/api/infra/data-source-config';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
import { DICT_TYPE } from '#/utils/dict';
|
||||||
|
|
||||||
export namespace CodegenDefaultData {
|
export namespace CodegenDefaultData {
|
||||||
/**
|
/**
|
||||||
|
@ -114,3 +116,138 @@ export namespace CodegenImportTableModalData {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//* ****************************** CodegenOptionsModal.vue *******************************//
|
||||||
|
export namespace CodegenOptionsModalData {
|
||||||
|
export const formSchema: VbenFormProps['schema'] = [
|
||||||
|
{
|
||||||
|
label: '表名称',
|
||||||
|
fieldName: 'tableName',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入表名称',
|
||||||
|
},
|
||||||
|
rules: z.string().min(1, { message: '表名称不能为空' }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '表描述',
|
||||||
|
fieldName: 'tableComment',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入表描述',
|
||||||
|
},
|
||||||
|
rules: z.string().min(1, { message: '表描述不能为空' }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '实体类名',
|
||||||
|
fieldName: 'className',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '实体类名不能为空' }),
|
||||||
|
componentProps: {
|
||||||
|
tooltip:
|
||||||
|
'默认去除表名的前缀。如果存在重复,则需要手动添加前缀,避免 MyBatis 报 Alias 重复的问题。',
|
||||||
|
placeholder: '请输入实体类名',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '作者',
|
||||||
|
fieldName: 'author',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '作者不能为空' }),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入作者',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
fieldName: 'remark',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入备注',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '生成模版',
|
||||||
|
fieldName: 'template',
|
||||||
|
component: 'ApiDict',
|
||||||
|
componentProps: {
|
||||||
|
code: DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE,
|
||||||
|
class: 'w-full',
|
||||||
|
placeholder: '请选择生成模版',
|
||||||
|
},
|
||||||
|
rules: z.string().min(1, { message: '生成模版不能为空' }),
|
||||||
|
defaultValue: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '前端类型',
|
||||||
|
fieldName: 'frontType',
|
||||||
|
component: 'ApiDict',
|
||||||
|
componentProps: {
|
||||||
|
code: DICT_TYPE.INFRA_CODEGEN_FRONT_TYPE,
|
||||||
|
class: 'w-full',
|
||||||
|
placeholder: '请选择前端类型',
|
||||||
|
},
|
||||||
|
rules: z.string().min(1, { message: '前端类型不能为空' }),
|
||||||
|
defaultValue: '31',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '生成场景',
|
||||||
|
fieldName: 'scene',
|
||||||
|
component: 'ApiDict',
|
||||||
|
componentProps: {
|
||||||
|
code: DICT_TYPE.INFRA_CODEGEN_SCENE,
|
||||||
|
class: 'w-full',
|
||||||
|
placeholder: '请选择生成场景',
|
||||||
|
},
|
||||||
|
rules: z.string().min(1, { message: '生成场景不能为空' }),
|
||||||
|
defaultValue: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '上级菜单',
|
||||||
|
fieldName: 'parentMenuId',
|
||||||
|
component: 'ApiTreeSelect',
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
api: () => {
|
||||||
|
const { accessMenus } = useUserStore();
|
||||||
|
return accessMenus;
|
||||||
|
},
|
||||||
|
labelField: 'name',
|
||||||
|
valueField: 'id',
|
||||||
|
placeholder: '请选择上级菜单',
|
||||||
|
},
|
||||||
|
rules: z.number().min(1, { message: '上级菜单不能为空' }),
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '模块名',
|
||||||
|
fieldName: 'moduleName',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '模块名不能为空' }),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入模块名',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '业务名',
|
||||||
|
fieldName: 'businessName',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '业务名不能为空' }),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入业务名',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '类名',
|
||||||
|
fieldName: 'className',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '类名不能为空' }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '类描述',
|
||||||
|
fieldName: 'classComment',
|
||||||
|
component: 'Input',
|
||||||
|
rules: z.string().min(1, { message: '类描述不能为空' }),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useVbenForm, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { CodegenOptionsModalData } from '../codegen.data';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'CodegenOptionsModal',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用表单组件
|
||||||
|
const [Form] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
wrapperClass: 'w-full',
|
||||||
|
},
|
||||||
|
schema: CodegenOptionsModalData.formSchema,
|
||||||
|
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||||
|
wrapperClass: 'grid-cols-1 md:grid-cols-2',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用弹窗组件
|
||||||
|
const [Modal] = useVbenModal({
|
||||||
|
title: '修改代码生成配置',
|
||||||
|
class: 'w-[90%] h-[90%]',
|
||||||
|
onOpenChange(isOpen) {
|
||||||
|
if (isOpen) {
|
||||||
|
// TODO: 打开弹窗
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal>
|
||||||
|
<Form />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
|
@ -16,13 +16,6 @@ import { CodegenDefaultData } from './codegen.data';
|
||||||
// checked
|
// checked
|
||||||
const checkedStatus = ref<boolean>(false);
|
const checkedStatus = ref<boolean>(false);
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑
|
|
||||||
*/
|
|
||||||
const handleEdit = (_row: CodegenApi.CodegenTableRespVO) => {
|
|
||||||
// console.log('编辑', row);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
*/
|
*/
|
||||||
|
@ -145,6 +138,13 @@ const [PreviewCodeModal, previewCodeModalApi] = useVbenModal({
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 使用修改代码生成配置弹窗组件
|
||||||
|
const [CodegenOptionsModal, codegenOptionsModalApi] = useVbenModal({
|
||||||
|
connectedComponent: defineAsyncComponent(
|
||||||
|
() => import('./components/codegen-options-modal.vue'),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开导入表弹窗
|
* 打开导入表弹窗
|
||||||
*/
|
*/
|
||||||
|
@ -159,6 +159,14 @@ const handleOpenPreviewCodeModal = (row: CodegenApi.CodegenTableRespVO) => {
|
||||||
previewCodeModalApi.setData(row);
|
previewCodeModalApi.setData(row);
|
||||||
previewCodeModalApi.open();
|
previewCodeModalApi.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开修改代码生成配置弹窗
|
||||||
|
*/
|
||||||
|
const handleOpenCodegenOptionsModal = (row: CodegenApi.CodegenTableRespVO) => {
|
||||||
|
codegenOptionsModalApi.setData(row);
|
||||||
|
codegenOptionsModalApi.open();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -214,7 +222,7 @@ const handleOpenPreviewCodeModal = (row: CodegenApi.CodegenTableRespVO) => {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
label: '编辑',
|
label: '编辑',
|
||||||
icon: 'ant-design:edit-outlined',
|
icon: 'ant-design:edit-outlined',
|
||||||
onClick: handleEdit.bind(null, row),
|
onClick: handleOpenCodegenOptionsModal.bind(null, row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'link',
|
type: 'link',
|
||||||
|
@ -241,5 +249,6 @@ const handleOpenPreviewCodeModal = (row: CodegenApi.CodegenTableRespVO) => {
|
||||||
</Grid>
|
</Grid>
|
||||||
<ImportTableModal />
|
<ImportTableModal />
|
||||||
<PreviewCodeModal />
|
<PreviewCodeModal />
|
||||||
|
<CodegenOptionsModal />
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -79,9 +79,9 @@ export const modalSchema: VbenFormSchema[] = [
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'ApiDict',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
|
code: DICT_TYPE.COMMON_STATUS,
|
||||||
},
|
},
|
||||||
fieldName: 'status',
|
fieldName: 'status',
|
||||||
label: '状态',
|
label: '状态',
|
||||||
|
|
|
@ -25,6 +25,10 @@ interface BasicUserInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AccessState {
|
interface AccessState {
|
||||||
|
/**
|
||||||
|
* 用户菜单
|
||||||
|
*/
|
||||||
|
accessMenus: [];
|
||||||
/**
|
/**
|
||||||
* 用户信息
|
* 用户信息
|
||||||
*/
|
*/
|
||||||
|
@ -40,6 +44,9 @@ interface AccessState {
|
||||||
*/
|
*/
|
||||||
export const useUserStore = defineStore('core-user', {
|
export const useUserStore = defineStore('core-user', {
|
||||||
actions: {
|
actions: {
|
||||||
|
setAccessMenus(menus: []) {
|
||||||
|
this.accessMenus = menus;
|
||||||
|
},
|
||||||
setUserInfo(userInfo: BasicUserInfo | null) {
|
setUserInfo(userInfo: BasicUserInfo | null) {
|
||||||
// 设置用户信息
|
// 设置用户信息
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
|
@ -56,6 +63,7 @@ export const useUserStore = defineStore('core-user', {
|
||||||
pick: ['userInfo', 'userRoles'],
|
pick: ['userInfo', 'userRoles'],
|
||||||
},
|
},
|
||||||
state: (): AccessState => ({
|
state: (): AccessState => ({
|
||||||
|
accessMenus: [],
|
||||||
userInfo: null,
|
userInfo: null,
|
||||||
userRoles: [],
|
userRoles: [],
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue