mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-19 01:56:38 +08:00
feat(projects): add menu route field
This commit is contained in:
parent
a1920fcad9
commit
dbe31eb1dc
@ -355,12 +355,15 @@ const local: App.I18n.Schema = {
|
|||||||
localIcon: 'Local Icon',
|
localIcon: 'Local Icon',
|
||||||
iconTypeTitle: 'Icon Type',
|
iconTypeTitle: 'Icon Type',
|
||||||
order: 'Order',
|
order: 'Order',
|
||||||
|
constant: 'Constant',
|
||||||
keepAlive: 'Keep Alive',
|
keepAlive: 'Keep Alive',
|
||||||
href: 'Href',
|
href: 'Href',
|
||||||
hideInMenu: 'Hide In Menu',
|
hideInMenu: 'Hide In Menu',
|
||||||
activeMenu: 'Active Menu',
|
activeMenu: 'Active Menu',
|
||||||
multiTab: 'Multi Tab',
|
multiTab: 'Multi Tab',
|
||||||
fixedIndexInTab: 'Fixed Index In Tab',
|
fixedIndexInTab: 'Fixed Index In Tab',
|
||||||
|
roles: 'Roles',
|
||||||
|
query: 'Query Params',
|
||||||
button: 'Button',
|
button: 'Button',
|
||||||
buttonCode: 'Button Code',
|
buttonCode: 'Button Code',
|
||||||
buttonDesc: 'Button Desc',
|
buttonDesc: 'Button Desc',
|
||||||
@ -380,10 +383,13 @@ const local: App.I18n.Schema = {
|
|||||||
keepAlive: 'Please select whether to cache route',
|
keepAlive: 'Please select whether to cache route',
|
||||||
href: 'Please enter href',
|
href: 'Please enter href',
|
||||||
hideInMenu: 'Please select whether to hide menu',
|
hideInMenu: 'Please select whether to hide menu',
|
||||||
activeMenu: 'Please enter the route name of the highlighted menu',
|
activeMenu: 'Please select route name of the highlighted menu',
|
||||||
multiTab: 'Please select whether to support multiple tabs',
|
multiTab: 'Please select whether to support multiple tabs',
|
||||||
fixedInTab: 'Please select whether to fix in the tab',
|
fixedInTab: 'Please select whether to fix in the tab',
|
||||||
fixedIndexInTab: 'Please enter the index fixed in the tab',
|
fixedIndexInTab: 'Please enter the index fixed in the tab',
|
||||||
|
roles: 'Please select roles',
|
||||||
|
queryKey: 'Please enter route parameter Key',
|
||||||
|
queryValue: 'Please enter route parameter Value',
|
||||||
button: 'Please select whether it is a button',
|
button: 'Please select whether it is a button',
|
||||||
buttonCode: 'Please enter button code',
|
buttonCode: 'Please enter button code',
|
||||||
buttonDesc: 'Please enter button description',
|
buttonDesc: 'Please enter button description',
|
||||||
|
@ -355,12 +355,15 @@ const local: App.I18n.Schema = {
|
|||||||
localIcon: '本地图标',
|
localIcon: '本地图标',
|
||||||
iconTypeTitle: '图标类型',
|
iconTypeTitle: '图标类型',
|
||||||
order: '排序',
|
order: '排序',
|
||||||
|
constant: '常量路由',
|
||||||
keepAlive: '缓存路由',
|
keepAlive: '缓存路由',
|
||||||
href: '外链',
|
href: '外链',
|
||||||
hideInMenu: '隐藏菜单',
|
hideInMenu: '隐藏菜单',
|
||||||
activeMenu: '高亮的菜单',
|
activeMenu: '高亮的菜单',
|
||||||
multiTab: '支持多页签',
|
multiTab: '支持多页签',
|
||||||
fixedIndexInTab: '固定在页签中的序号',
|
fixedIndexInTab: '固定在页签中的序号',
|
||||||
|
roles: '角色',
|
||||||
|
query: '路由参数',
|
||||||
button: '按钮',
|
button: '按钮',
|
||||||
buttonCode: '按钮编码',
|
buttonCode: '按钮编码',
|
||||||
buttonDesc: '按钮描述',
|
buttonDesc: '按钮描述',
|
||||||
@ -380,10 +383,13 @@ const local: App.I18n.Schema = {
|
|||||||
keepAlive: '请选择是否缓存路由',
|
keepAlive: '请选择是否缓存路由',
|
||||||
href: '请输入外链',
|
href: '请输入外链',
|
||||||
hideInMenu: '请选择是否隐藏菜单',
|
hideInMenu: '请选择是否隐藏菜单',
|
||||||
activeMenu: '请输入高亮的菜单的路由名称',
|
activeMenu: '请选择高亮的菜单的路由名称',
|
||||||
multiTab: '请选择是否支持多标签',
|
multiTab: '请选择是否支持多标签',
|
||||||
fixedInTab: '请选择是否固定在页签中',
|
fixedInTab: '请选择是否固定在页签中',
|
||||||
fixedIndexInTab: '请输入固定在页签中的序号',
|
fixedIndexInTab: '请输入固定在页签中的序号',
|
||||||
|
roles: '请选择角色',
|
||||||
|
queryKey: '请输入路由参数Key',
|
||||||
|
queryValue: '请输入路由参数Value',
|
||||||
button: '请选择是否按钮',
|
button: '请选择是否按钮',
|
||||||
buttonCode: '请输入按钮编码',
|
buttonCode: '请输入按钮编码',
|
||||||
buttonDesc: '请输入按钮描述',
|
buttonDesc: '请输入按钮描述',
|
||||||
|
14
src/typings/api.d.ts
vendored
14
src/typings/api.d.ts
vendored
@ -198,6 +198,12 @@ declare namespace Api {
|
|||||||
order: number;
|
order: number;
|
||||||
/** whether to cache the route */
|
/** whether to cache the route */
|
||||||
keepAlive?: boolean;
|
keepAlive?: boolean;
|
||||||
|
/**
|
||||||
|
* Is constant route
|
||||||
|
*
|
||||||
|
* Does not need to login, and the route is defined in the front-end
|
||||||
|
*/
|
||||||
|
constant?: boolean;
|
||||||
/** outer link */
|
/** outer link */
|
||||||
href?: string;
|
href?: string;
|
||||||
/** whether to hide the route in the menu */
|
/** whether to hide the route in the menu */
|
||||||
@ -215,8 +221,16 @@ declare namespace Api {
|
|||||||
multiTab?: boolean;
|
multiTab?: boolean;
|
||||||
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
|
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
|
||||||
fixedIndexInTab?: number;
|
fixedIndexInTab?: number;
|
||||||
|
/** if set query parameters, it will be automatically carried when entering the route */
|
||||||
|
query: Record<string, string>;
|
||||||
/** menu buttons */
|
/** menu buttons */
|
||||||
buttons?: MenuButton[];
|
buttons?: MenuButton[];
|
||||||
|
/**
|
||||||
|
* Roles of the route
|
||||||
|
*
|
||||||
|
* Route can be accessed if the current user has at least one of the roles
|
||||||
|
*/
|
||||||
|
roles?: string[];
|
||||||
/** children menu */
|
/** children menu */
|
||||||
children?: Menu[];
|
children?: Menu[];
|
||||||
}>;
|
}>;
|
||||||
|
6
src/typings/app.d.ts
vendored
6
src/typings/app.d.ts
vendored
@ -539,12 +539,15 @@ declare namespace App {
|
|||||||
localIcon: string;
|
localIcon: string;
|
||||||
iconTypeTitle: string;
|
iconTypeTitle: string;
|
||||||
order: string;
|
order: string;
|
||||||
|
constant: string;
|
||||||
keepAlive: string;
|
keepAlive: string;
|
||||||
href: string;
|
href: string;
|
||||||
hideInMenu: string;
|
hideInMenu: string;
|
||||||
activeMenu: string;
|
activeMenu: string;
|
||||||
multiTab: string;
|
multiTab: string;
|
||||||
fixedIndexInTab: string;
|
fixedIndexInTab: string;
|
||||||
|
roles: string;
|
||||||
|
query: string;
|
||||||
button: string;
|
button: string;
|
||||||
buttonCode: string;
|
buttonCode: string;
|
||||||
buttonDesc: string;
|
buttonDesc: string;
|
||||||
@ -568,6 +571,9 @@ declare namespace App {
|
|||||||
multiTab: string;
|
multiTab: string;
|
||||||
fixedInTab: string;
|
fixedInTab: string;
|
||||||
fixedIndexInTab: string;
|
fixedIndexInTab: string;
|
||||||
|
roles: string;
|
||||||
|
queryKey: string;
|
||||||
|
queryValue: string;
|
||||||
button: string;
|
button: string;
|
||||||
buttonCode: string;
|
buttonCode: string;
|
||||||
buttonDesc: string;
|
buttonDesc: string;
|
||||||
|
3
src/typings/components.d.ts
vendored
3
src/typings/components.d.ts
vendored
@ -19,9 +19,11 @@ declare module 'vue' {
|
|||||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
|
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
|
||||||
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
||||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
||||||
|
'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
|
||||||
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
||||||
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
||||||
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
||||||
|
IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
|
||||||
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
||||||
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
||||||
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
||||||
@ -49,6 +51,7 @@ declare module 'vue' {
|
|||||||
NDrawer: typeof import('naive-ui')['NDrawer']
|
NDrawer: typeof import('naive-ui')['NDrawer']
|
||||||
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
||||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||||
|
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
|
||||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||||
NForm: typeof import('naive-ui')['NForm']
|
NForm: typeof import('naive-ui')['NForm']
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { computed, reactive, watch } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
import { computed, reactive, ref, watch } from 'vue';
|
||||||
import type { SelectOption } from 'naive-ui';
|
import type { SelectOption } from 'naive-ui';
|
||||||
|
import type { LastLevelRouteKey } from '@elegant-router/types';
|
||||||
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { enableStatusOptions, menuIconTypeOptions, menuTypeOptions } from '@/constants/business';
|
import { enableStatusOptions, menuIconTypeOptions, menuTypeOptions } from '@/constants/business';
|
||||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||||
import { getLocalIcons } from '@/utils/icon';
|
import { getLocalIcons } from '@/utils/icon';
|
||||||
import { getLayoutAndPage, transformLayoutAndPageToComponent } from './shared';
|
import { fetchGetAllRoles } from '@/service/api';
|
||||||
|
import {
|
||||||
|
getLayoutAndPage,
|
||||||
|
transformLayoutAndPageToComponent,
|
||||||
|
transformToKeyValuePairs,
|
||||||
|
transformToQueryObject
|
||||||
|
} from './shared';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MenuOperateDrawer'
|
name: 'MenuOperateDrawer'
|
||||||
@ -51,6 +59,7 @@ type Model = Pick<
|
|||||||
Api.SystemManage.Menu,
|
Api.SystemManage.Menu,
|
||||||
| 'menuType'
|
| 'menuType'
|
||||||
| 'menuName'
|
| 'menuName'
|
||||||
|
| 'i18nKey'
|
||||||
| 'icon'
|
| 'icon'
|
||||||
| 'iconType'
|
| 'iconType'
|
||||||
| 'routeName'
|
| 'routeName'
|
||||||
@ -58,8 +67,17 @@ type Model = Pick<
|
|||||||
| 'component'
|
| 'component'
|
||||||
| 'status'
|
| 'status'
|
||||||
| 'hideInMenu'
|
| 'hideInMenu'
|
||||||
|
| 'activeMenu'
|
||||||
| 'order'
|
| 'order'
|
||||||
| 'parentId'
|
| 'parentId'
|
||||||
|
| 'constant'
|
||||||
|
| 'keepAlive'
|
||||||
|
| 'href'
|
||||||
|
| 'multiTab'
|
||||||
|
| 'fixedIndexInTab'
|
||||||
|
| 'roles'
|
||||||
|
| 'buttons'
|
||||||
|
| 'query'
|
||||||
> & {
|
> & {
|
||||||
layout: string;
|
layout: string;
|
||||||
page: string;
|
page: string;
|
||||||
@ -71,16 +89,26 @@ function createDefaultModel(): Model {
|
|||||||
return {
|
return {
|
||||||
menuType: '1',
|
menuType: '1',
|
||||||
menuName: '',
|
menuName: '',
|
||||||
|
i18nKey: '' as App.I18n.I18nKey,
|
||||||
icon: '',
|
icon: '',
|
||||||
iconType: '1',
|
iconType: '1',
|
||||||
routeName: '',
|
routeName: '',
|
||||||
routePath: '',
|
routePath: '',
|
||||||
layout: '',
|
layout: '',
|
||||||
page: '',
|
page: '',
|
||||||
status: null,
|
status: '1',
|
||||||
hideInMenu: false,
|
hideInMenu: false,
|
||||||
|
activeMenu: '' as LastLevelRouteKey,
|
||||||
order: 0,
|
order: 0,
|
||||||
parentId: 0
|
parentId: 0,
|
||||||
|
constant: false,
|
||||||
|
keepAlive: false,
|
||||||
|
href: '',
|
||||||
|
multiTab: false,
|
||||||
|
fixedIndexInTab: 0,
|
||||||
|
roles: [],
|
||||||
|
buttons: [],
|
||||||
|
query: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +164,29 @@ const layoutOptions: CommonType.Option[] = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const dynamicQueryKeyValuePairs: Ref<Record<string, string>[]> = ref([
|
||||||
|
{
|
||||||
|
key: '',
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** the enabled role options */
|
||||||
|
const roleOptions = ref<CommonType.Option<string>[]>([]);
|
||||||
|
|
||||||
|
async function getRoleOptions() {
|
||||||
|
const { error, data } = await fetchGetAllRoles();
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
const options = data.map(item => ({
|
||||||
|
label: item.roleName,
|
||||||
|
value: item.roleCode
|
||||||
|
}));
|
||||||
|
|
||||||
|
roleOptions.value = [...options];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleUpdateModel() {
|
function handleUpdateModel() {
|
||||||
if (props.operateType === 'add') {
|
if (props.operateType === 'add') {
|
||||||
Object.assign(model, createDefaultModel());
|
Object.assign(model, createDefaultModel());
|
||||||
@ -150,11 +201,12 @@ function handleUpdateModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (props.operateType === 'edit' && props.rowData) {
|
if (props.operateType === 'edit' && props.rowData) {
|
||||||
const { component, ...rest } = props.rowData;
|
const { component, query, ...rest } = props.rowData;
|
||||||
|
|
||||||
const { layout, page } = getLayoutAndPage(component);
|
const { layout, page } = getLayoutAndPage(component);
|
||||||
|
|
||||||
Object.assign(model, rest, { layout, page });
|
Object.assign(model, rest, { layout, page });
|
||||||
|
dynamicQueryKeyValuePairs.value = transformToKeyValuePairs(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +218,12 @@ async function handleSubmit() {
|
|||||||
await validate();
|
await validate();
|
||||||
|
|
||||||
model.component = transformLayoutAndPageToComponent(model.layout, model.page);
|
model.component = transformLayoutAndPageToComponent(model.layout, model.page);
|
||||||
|
model.query = transformToQueryObject(dynamicQueryKeyValuePairs.value);
|
||||||
|
|
||||||
|
// model.buttons = [];
|
||||||
|
// Need: Get buttons based on roles
|
||||||
|
|
||||||
|
console.log('model:', model);
|
||||||
|
|
||||||
// request
|
// request
|
||||||
window.$message?.success($t('common.updateSuccess'));
|
window.$message?.success($t('common.updateSuccess'));
|
||||||
@ -177,73 +235,154 @@ watch(visible, () => {
|
|||||||
if (visible.value) {
|
if (visible.value) {
|
||||||
handleUpdateModel();
|
handleUpdateModel();
|
||||||
restoreValidation();
|
restoreValidation();
|
||||||
|
getRoleOptions();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="360">
|
<NDrawer v-model:show="visible" display-directive="show" :width="400">
|
||||||
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
||||||
<NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="80">
|
<NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="80">
|
||||||
<NFormItem :label="$t('page.manage.menu.menuType')" path="menuType">
|
<NGrid>
|
||||||
<NRadioGroup v-model:value="model.menuType" :disabled="disabledMenuType">
|
<NFormItemGi span="12" :label="$t('page.manage.menu.menuType')" path="menuType">
|
||||||
<NRadio v-for="item in menuTypeOptions" :key="item.value" :value="item.value" :label="$t(item.label)" />
|
<NRadioGroup v-model:value="model.menuType" :disabled="disabledMenuType">
|
||||||
</NRadioGroup>
|
<NRadio v-for="item in menuTypeOptions" :key="item.value" :value="item.value" :label="$t(item.label)" />
|
||||||
</NFormItem>
|
</NRadioGroup>
|
||||||
<NFormItem :label="$t('page.manage.menu.menuName')" path="menuName">
|
</NFormItemGi>
|
||||||
<NInput v-model:value="model.menuName" :placeholder="$t('page.manage.menu.form.menuName')" />
|
<NFormItemGi span="12" :label="$t('page.manage.menu.order')" path="order">
|
||||||
</NFormItem>
|
<NInputNumber v-model:value="model.order" :placeholder="$t('page.manage.menu.form.order')" />
|
||||||
<NFormItem :label="$t('page.manage.menu.iconTypeTitle')" path="iconType">
|
</NFormItemGi>
|
||||||
<NRadioGroup v-model:value="model.iconType">
|
<NFormItemGi span="24" :label="$t('page.manage.menu.menuName')" path="menuName">
|
||||||
<NRadio v-for="item in menuIconTypeOptions" :key="item.value" :value="item.value" :label="$t(item.label)" />
|
<NInput v-model:value="model.menuName" :placeholder="$t('page.manage.menu.form.menuName')" />
|
||||||
</NRadioGroup>
|
</NFormItemGi>
|
||||||
</NFormItem>
|
<NFormItemGi span="24" :label="$t('page.manage.menu.i18nKey')" path="i18nKey">
|
||||||
<NFormItem :label="$t('page.manage.menu.icon')" path="icon">
|
<NInput v-model:value="model.i18nKey" :placeholder="$t('page.manage.menu.form.i18nKey')" />
|
||||||
<template v-if="model.iconType === '1'">
|
</NFormItemGi>
|
||||||
<NInput v-model:value="model.icon" :placeholder="$t('page.manage.menu.form.icon')" class="flex-1">
|
<NFormItemGi span="12" :label="$t('page.manage.menu.menuStatus')" path="status">
|
||||||
<template #suffix>
|
<NRadioGroup v-model:value="model.status">
|
||||||
<SvgIcon v-if="model.icon" :icon="model.icon" class="text-icon" />
|
<NRadio
|
||||||
</template>
|
v-for="item in enableStatusOptions"
|
||||||
</NInput>
|
:key="item.value"
|
||||||
</template>
|
:value="item.value"
|
||||||
<template v-if="model.iconType === '2'">
|
:label="$t(item.label)"
|
||||||
<NSelect
|
/>
|
||||||
v-model:value="model.icon"
|
</NRadioGroup>
|
||||||
:placeholder="$t('page.manage.menu.form.localIcon')"
|
</NFormItemGi>
|
||||||
:options="localIconOptions"
|
<NFormItemGi span="12" :label="$t('page.manage.menu.hideInMenu')" path="hideInMenu">
|
||||||
|
<NRadioGroup v-model:value="model.hideInMenu">
|
||||||
|
<NRadio value :label="$t('common.yesOrNo.yes')" />
|
||||||
|
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
|
||||||
|
</NRadioGroup>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="12" :label="$t('page.manage.menu.keepAlive')" path="keepAlive">
|
||||||
|
<NRadioGroup v-model:value="model.keepAlive">
|
||||||
|
<NRadio value :label="$t('common.yesOrNo.yes')" />
|
||||||
|
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
|
||||||
|
</NRadioGroup>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="12" :label="$t('page.manage.menu.constant')" path="constant">
|
||||||
|
<NRadioGroup v-model:value="model.constant">
|
||||||
|
<NRadio value :label="$t('common.yesOrNo.yes')" />
|
||||||
|
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
|
||||||
|
</NRadioGroup>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="12" :label="$t('page.manage.menu.multiTab')" path="multiTab">
|
||||||
|
<NRadioGroup v-model:value="model.multiTab">
|
||||||
|
<NRadio value :label="$t('common.yesOrNo.yes')" />
|
||||||
|
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
|
||||||
|
</NRadioGroup>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="12" :label="$t('page.manage.menu.fixedIndexInTab')" path="fixedIndexInTab">
|
||||||
|
<NInputNumber
|
||||||
|
v-model:value="model.fixedIndexInTab"
|
||||||
|
:placeholder="$t('page.manage.menu.form.fixedIndexInTab')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</NFormItemGi>
|
||||||
</NFormItem>
|
<NFormItemGi span="24" :label="$t('page.manage.menu.iconTypeTitle')" path="iconType">
|
||||||
<NFormItem :label="$t('page.manage.menu.routeName')" path="routeName">
|
<NRadioGroup v-model:value="model.iconType">
|
||||||
<NInput v-model:value="model.routeName" :placeholder="$t('page.manage.menu.form.routeName')" />
|
<NRadio
|
||||||
</NFormItem>
|
v-for="item in menuIconTypeOptions"
|
||||||
<NFormItem :label="$t('page.manage.menu.routePath')" path="routePath">
|
:key="item.value"
|
||||||
<NInput v-model:value="model.routePath" :placeholder="$t('page.manage.menu.form.routePath')" />
|
:value="item.value"
|
||||||
</NFormItem>
|
:label="$t(item.label)"
|
||||||
<NFormItem v-if="showLayout" :label="$t('page.manage.menu.layout')" path="layout">
|
/>
|
||||||
<NSelect
|
</NRadioGroup>
|
||||||
v-model:value="model.layout"
|
</NFormItemGi>
|
||||||
:options="layoutOptions"
|
<NFormItemGi span="24" :label="$t('page.manage.menu.icon')" path="icon">
|
||||||
:placeholder="$t('page.manage.menu.form.layout')"
|
<template v-if="model.iconType === '1'">
|
||||||
/>
|
<NInput v-model:value="model.icon" :placeholder="$t('page.manage.menu.form.icon')" class="flex-1">
|
||||||
</NFormItem>
|
<template #suffix>
|
||||||
<NFormItem v-if="showPage" :label="$t('page.manage.menu.page')" path="page">
|
<SvgIcon v-if="model.icon" :icon="model.icon" class="text-icon" />
|
||||||
<NSelect v-model:value="model.page" :options="pageOptions" :placeholder="$t('page.manage.menu.form.page')" />
|
</template>
|
||||||
</NFormItem>
|
</NInput>
|
||||||
<NFormItem :label="$t('page.manage.menu.menuStatus')" path="status">
|
</template>
|
||||||
<NRadioGroup v-model:value="model.status">
|
<template v-if="model.iconType === '2'">
|
||||||
<NRadio v-for="item in enableStatusOptions" :key="item.value" :value="item.value" :label="$t(item.label)" />
|
<NSelect
|
||||||
</NRadioGroup>
|
v-model:value="model.icon"
|
||||||
</NFormItem>
|
:placeholder="$t('page.manage.menu.form.localIcon')"
|
||||||
<NFormItem :label="$t('page.manage.menu.hideInMenu')" path="hideInMenu">
|
:options="localIconOptions"
|
||||||
<NRadioGroup v-model:value="model.hideInMenu">
|
/>
|
||||||
<NRadio value :label="$t('common.yesOrNo.yes')" />
|
</template>
|
||||||
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
|
</NFormItemGi>
|
||||||
</NRadioGroup>
|
<NFormItemGi span="24" :label="$t('page.manage.menu.routeName')" path="routeName">
|
||||||
</NFormItem>
|
<NInput v-model:value="model.routeName" :placeholder="$t('page.manage.menu.form.routeName')" />
|
||||||
<NFormItem :label="$t('page.manage.menu.order')" path="order">
|
</NFormItemGi>
|
||||||
<NInputNumber v-model:value="model.order" :placeholder="$t('page.manage.menu.form.order')" />
|
<NFormItemGi span="24" :label="$t('page.manage.menu.routePath')" path="routePath">
|
||||||
</NFormItem>
|
<NInput v-model:value="model.routePath" :placeholder="$t('page.manage.menu.form.routePath')" />
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi v-if="showLayout" span="24" :label="$t('page.manage.menu.layout')" path="layout">
|
||||||
|
<NSelect
|
||||||
|
v-model:value="model.layout"
|
||||||
|
:options="layoutOptions"
|
||||||
|
:placeholder="$t('page.manage.menu.form.layout')"
|
||||||
|
/>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi v-if="showPage" span="24" :label="$t('page.manage.menu.page')" path="page">
|
||||||
|
<NSelect
|
||||||
|
v-model:value="model.page"
|
||||||
|
:options="pageOptions"
|
||||||
|
:placeholder="$t('page.manage.menu.form.page')"
|
||||||
|
/>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi v-if="showPage" span="24" :label="$t('page.manage.menu.activeMenu')" path="activeMenu">
|
||||||
|
<NSelect
|
||||||
|
v-model:value="model.activeMenu"
|
||||||
|
:options="pageOptions"
|
||||||
|
:placeholder="$t('page.manage.menu.form.activeMenu')"
|
||||||
|
/>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="24" :label="$t('page.manage.menu.href')" path="href">
|
||||||
|
<NInput v-model:value="model.href" :placeholder="$t('page.manage.menu.form.href')" />
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="24" :label="$t('page.manage.menu.roles')" path="roles">
|
||||||
|
<NSelect
|
||||||
|
v-model:value="model.roles"
|
||||||
|
multiple
|
||||||
|
:options="roleOptions"
|
||||||
|
:placeholder="$t('page.manage.menu.form.roles')"
|
||||||
|
/>
|
||||||
|
</NFormItemGi>
|
||||||
|
<NFormItemGi span="24" :label="$t('page.manage.menu.query')">
|
||||||
|
<NDynamicInput
|
||||||
|
v-model:value="dynamicQueryKeyValuePairs"
|
||||||
|
preset="pair"
|
||||||
|
:key-placeholder="$t('page.manage.menu.form.queryKey')"
|
||||||
|
:value-placeholder="$t('page.manage.menu.form.queryValue')"
|
||||||
|
>
|
||||||
|
<template #action="{ index, create, remove }">
|
||||||
|
<NSpace class="ml-2">
|
||||||
|
<NButton size="medium" @click="() => create(index)">
|
||||||
|
<icon-ic:round-plus class="text-icon" />
|
||||||
|
</NButton>
|
||||||
|
<NButton size="medium" @click="() => remove(index)">
|
||||||
|
<icon-ic-round-remove class="text-icon" />
|
||||||
|
</NButton>
|
||||||
|
</NSpace>
|
||||||
|
</template>
|
||||||
|
</NDynamicInput>
|
||||||
|
</NFormItemGi>
|
||||||
|
</NGrid>
|
||||||
</NForm>
|
</NForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<NSpace :size="16">
|
<NSpace :size="16">
|
||||||
|
@ -40,3 +40,21 @@ export function transformLayoutAndPageToComponent(layout: string, page: string)
|
|||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function transformToQueryObject(data: Record<string, string>[]) {
|
||||||
|
const query: Record<string, string> = {};
|
||||||
|
data.forEach(pair => {
|
||||||
|
if (pair.key && pair.value) {
|
||||||
|
query[pair.key] = pair.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transformToKeyValuePairs(query?: Record<string, string>) {
|
||||||
|
const safeQuery = query || {};
|
||||||
|
return Object.entries(safeQuery).map(([key, value]) => ({
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user