Files
geg-gas-web/src/views/system/menu/components/MenuDrawer.vue

409 lines
14 KiB
Vue
Raw Normal View History

<template>
2025-10-21 18:04:02 +08:00
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
destroyOnClose
:title="getTitle"
width="50%"
@ok="handleSubmit"
@visible-change="
() => {
activeKey = '1';
}
"
>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" :tab="t('菜单信息')">
<BasicForm @register="registerForm" />
</a-tab-pane>
<a-tab-pane key="2" :tab="t('按钮信息')">
<ButtonTable :menuId="rowId" :hasMetaFormId="hasMetaFormId" ref="buttonTable" v-if="activeKey" />
</a-tab-pane>
<a-tab-pane key="3" :tab="t('表格信息')">
<ColumnTable :menuId="rowId" ref="columnTable" v-if="activeKey" />
</a-tab-pane>
<a-tab-pane key="4" :tab="t('表单信息')">
<FormTable :menuId="rowId" ref="formTable" v-if="activeKey" />
</a-tab-pane>
</a-tabs>
</BasicDrawer>
</template>
<script lang="ts">
2025-10-21 18:04:02 +08:00
import { defineComponent, ref, computed } from 'vue';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { BasicColumn } from '/@/components/Table';
2025-10-21 18:04:02 +08:00
import ButtonTable from './ButtonTable.vue';
import ColumnTable from './ColumnTable.vue';
import FormTable from './FormTable.vue';
import { getMenuTree, addMenu, updateMenu, getMenuButtonById, getMenuColumnById, getMenuFormById } from '/@/api/system/menu';
import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n';
import { MenuButtonModel } from '/@/api/system/menuButton/model';
import { getSubSystemList } from '/@/api/system/subSystem';
2025-10-21 18:04:02 +08:00
import { usePermissionStore } from '/@/store/modules/permission';
const { t } = useI18n();
2025-10-21 18:04:02 +08:00
const isUpdate = ref<boolean>(false);
const componentType = ref<number>(0);
const hasMetaFormId = ref(false);
export const formSchema: FormSchema[] = [
{
field: 'title',
label: t('菜单名称'),
component: 'Input',
required: true
},
{
field: 'name',
label: t('组件名称'),
component: 'Input',
required: true
},
{
field: 'code',
label: t('编码'),
component: 'Input',
required: true
},
{
field: 'sortCode',
label: t('排序'),
component: 'InputNumber',
required: true
},
2025-10-21 18:04:02 +08:00
{
field: 'parentId',
label: t('上级菜单'),
component: 'MenuSelect',
colProps: { lg: 24, md: 24 }
},
{
field: 'systemId',
label: t('所属系统'),
component: 'Select',
componentProps: {
fieldNames: {
label: 'name',
value: 'id'
},
getPopupContainer: () => document.body,
allowClear: false
},
colProps: { lg: 24, md: 24 },
dynamicDisabled: ({ values }) => {
return values.parentId ? true : false;
}
},
{
field: 'path',
label: t('路由地址'),
component: 'Input',
required: true,
colProps: { lg: 24, md: 24 },
helpMessage: '如果是外链新开窗口,在此输入地址!',
dynamicDisabled: ({ values }) => {
return values.componentType === 1;
}
},
{
field: 'outLink',
label: t('是否外链'),
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: t('是'), value: 1 },
{ label: t('否'), value: 0 }
]
}
},
{
field: 'icon',
label: t('图标'),
component: 'IconPicker'
},
2025-10-21 18:04:02 +08:00
{
field: 'component',
label: t('组件路径'),
component: 'Input',
colProps: { lg: 24, md: 24 },
required: true,
ifShow: ({ values }) => {
return values.outLink === 0 && values.componentType === 0;
}
},
{
field: 'iframeSrc',
label: t('外链地址'),
component: 'Input',
colProps: { lg: 24, md: 24 },
required: true,
helpMessage: '如果是外链内嵌,在此输入地址!',
ifShow: ({ values }) => {
return values.outLink == 1;
}
},
{
field: 'remark',
label: t('备注'),
component: 'InputTextArea',
colProps: { lg: 24, md: 24 }
},
{
field: 'menuType',
label: t('页面/菜单'),
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: t('页面'), value: 1 },
{ label: t('菜单'), value: 0 }
]
}
},
{
field: 'enabledMark',
label: t('状态'),
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: t('启用'), value: 1 },
{ label: t('禁用'), value: 0 }
]
}
},
2025-10-21 18:04:02 +08:00
{
field: 'display',
label: t('是否显示'),
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: t('是'), value: 1 },
{ label: t('否'), value: 0 }
]
}
},
{
field: 'componentType', //隐藏组件
label: t('是否自定义'),
component: 'RadioButtonGroup',
componentProps: {
options: [
{ label: t('是'), value: 1 },
{ label: t('否'), value: 0 }
]
},
show: false
}
];
2025-10-21 18:04:02 +08:00
export const columns: BasicColumn[] = [
{
title: t('按钮名称'),
dataIndex: 'name',
width: 100,
align: 'left'
},
{
title: t('编码'),
dataIndex: 'code',
width: 100
},
{
title: t('地址'),
dataIndex: 'url',
width: 200
},
{
title: t('请求方式'),
dataIndex: 'method',
width: 180,
format: (text: string | number) => {
if (text === 0) return 'GET';
else if (text === 1) return 'POST';
else if (text === 2) return 'PUT';
else return 'DELETE';
}
}
];
2025-10-21 18:04:02 +08:00
export default defineComponent({
name: 'MenuDrawer',
components: {
BasicDrawer,
BasicForm,
FormTable,
2025-10-21 18:04:02 +08:00
ButtonTable,
ColumnTable
},
emits: ['success', 'register'],
setup(_, { emit }) {
const permissionStore = usePermissionStore();
const { notification } = useMessage();
const rowId = ref('');
const activeKey = ref('1');
const buttonTable = ref();
const columnTable = ref();
const formTable = ref();
const buttonDatas = ref<MenuButtonModel[]>([]);
const columnDatas = ref<MenuButtonModel[]>([]);
const formDatas = ref<MenuButtonModel[]>([]);
const systemId = ref('1');
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { lg: 12, md: 24 }
});
2025-10-21 18:04:02 +08:00
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields();
setDrawerProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
2025-10-21 18:04:02 +08:00
if (isUpdate.value) {
rowId.value = data.record.id;
if (data.record && data.record.meta && data.record.meta.formId) {
hasMetaFormId.value = true;
}
componentType.value = data.record.componentType;
if (data.record.outLink == 1) {
data.record.url = data.record.component;
}
if (data.record.parentId) {
data.record.systemId = null;
}
setFieldsValue({
...data.record
});
getMenuButtonById({ id: data.record.id }).then((res) => {
buttonDatas.value = res;
});
getMenuColumnById({ menuId: data.record.id }).then((res) => {
columnDatas.value = res;
});
getMenuFormById({ menuId: data.record.id }).then((res) => {
formDatas.value = res;
});
} else {
rowId.value = '';
componentType.value = 0;
setFieldsValue({
menuType: 1,
enabledMark: 1,
outLink: 0,
display: 1,
componentType: 0,
systemId: '1'
});
}
const treeData = await getMenuTree();
2025-10-21 18:04:02 +08:00
const system = await getSubSystemList();
2025-10-21 18:04:02 +08:00
updateSchema([
{
field: 'parentId',
componentProps: ({ formModel }) => {
return {
getPopupContainer: () => document.body,
onChange: (v) => {
findParentSystem(treeData, treeData, v);
formModel.systemId = systemId.value;
}
};
}
},
{
field: 'systemId',
componentProps: { options: system }
},
{
field: 'outLink',
dynamicDisabled: () => {
return isUpdate.value && componentType.value == 1;
}
},
{
field: 'path',
dynamicDisabled: () => {
return isUpdate.value && componentType.value == 1;
}
}
]);
});
2025-10-21 18:04:02 +08:00
const getTitle = computed(() => (!isUpdate.value ? t('新增菜单') : t('编辑菜单')));
2025-10-21 18:04:02 +08:00
async function handleSubmit() {
try {
const values = await validate();
if (values.outLink == 1) {
values.component = values.url;
}
values.buttonList = buttonTable.value ? buttonTable.value.getDataSource() : buttonDatas.value;
values.columnList = columnTable.value ? columnTable.value.getDataSource() : columnDatas.value;
values.formList = formTable.value ? formTable.value.getDataSource() : formDatas.value;
setDrawerProps({ confirmLoading: true });
// TODO custom api
if (!isUpdate.value) {
//false 新增
await addMenu(values);
notification.success({
message: t('提示'),
description: t('新增菜单成功')
}); //提示消息
} else {
values.id = rowId.value;
await updateMenu(values);
notification.success({
message: t('提示'),
description: t('修改菜单成功')
}); //提示消息
}
await permissionStore.buildRoutesAction();
closeDrawer();
emit('success');
} catch (error) {
setDrawerProps({ confirmLoading: false });
}
}
function findParentSystem(treeData, tempTree, id) {
for (let i = 0; i < treeData.length; i++) {
let o = treeData[i];
2025-10-21 18:04:02 +08:00
if (o.id == id) {
systemId.value = o.systemId;
if (o.parentId) {
findParentSystem(tempTree, tempTree, o.parentId);
} else {
break;
}
} else if (o.children?.length > 0) {
findParentSystem(o.children, tempTree, id);
}
}
}
2025-10-21 18:04:02 +08:00
return {
registerDrawer,
registerForm,
getTitle,
hasMetaFormId,
handleSubmit,
buttonTable,
rowId,
columnTable,
formTable,
activeKey,
t
};
}
2025-10-21 18:04:02 +08:00
});
</script>