<template>
|
<div class="menu-page">
|
<a-card>
|
<a-space style="margin-bottom: 16px">
|
<a-button type="primary" @click="handleAdd">
|
<template #icon><plus-outlined /></template>
|
新增菜单
|
</a-button>
|
</a-space>
|
|
<a-table
|
:columns="columns"
|
:data-source="dataSource"
|
:loading="loading"
|
:pagination="false"
|
row-key="Id"
|
>
|
<template #bodyCell="{ column, record }">
|
<template v-if="column.key === 'Enable'">
|
<a-tag :color="record.Enable === 1 ? 'green' : 'red'">
|
{{ record.Enable === 1 ? '启用' : '禁用' }}
|
</a-tag>
|
</template>
|
<template v-else-if="column.key === 'action'">
|
<a-space>
|
<a @click="handleEdit(record)">编辑</a>
|
<a-divider type="vertical" />
|
<a-popconfirm title="确定要删除吗?" @confirm="handleDelete(record)">
|
<a style="color: red">删除</a>
|
</a-popconfirm>
|
</a-space>
|
</template>
|
</template>
|
</a-table>
|
</a-card>
|
|
<a-modal
|
v-model:open="modalVisible"
|
:title="modalTitle"
|
@ok="handleModalOk"
|
@cancel="handleModalCancel"
|
>
|
<a-form
|
ref="formRef"
|
:model="formState"
|
:rules="rules"
|
:label-col="{ span: 6 }"
|
:wrapper-col="{ span: 16 }"
|
>
|
<a-form-item label="菜单名称" name="MenuName">
|
<a-input v-model:value="formState.MenuName" />
|
</a-form-item>
|
<a-form-item label="菜单路径" name="Url">
|
<a-input v-model:value="formState.Url" />
|
</a-form-item>
|
<a-form-item label="图标" name="Icon">
|
<a-input v-model:value="formState.Icon" />
|
</a-form-item>
|
<a-form-item label="排序号" name="OrderNo">
|
<a-input-number v-model:value="formState.OrderNo" style="width: 100%" />
|
</a-form-item>
|
<a-form-item label="状态" name="Enable">
|
<a-select v-model:value="formState.Enable">
|
<a-select-option :value="1">启用</a-select-option>
|
<a-select-option :value="0">禁用</a-select-option>
|
</a-select>
|
</a-form-item>
|
</a-form>
|
</a-modal>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, reactive, onMounted } from 'vue';
|
import { message } from 'ant-design-vue';
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
import { getMenuList, addMenu, updateMenu, deleteMenu } from '../../../api/system';
|
import type { MenuInfo } from '../../../types/user';
|
|
const columns = [
|
{ title: '菜单名称', dataIndex: 'MenuName', key: 'MenuName' },
|
{ title: '菜单路径', dataIndex: 'Url', key: 'Url' },
|
{ title: '图标', dataIndex: 'Icon', key: 'Icon' },
|
{ title: '排序号', dataIndex: 'OrderNo', key: 'OrderNo' },
|
{ title: '状态', dataIndex: 'Enable', key: 'Enable' },
|
{ title: '操作', key: 'action', width: 150 },
|
];
|
|
const dataSource = ref<MenuInfo[]>([]);
|
const loading = ref(false);
|
|
const modalVisible = ref(false);
|
const modalTitle = ref('新增菜单');
|
const formRef = ref();
|
const formState = reactive<Partial<MenuInfo>>({
|
MenuName: '',
|
Url: '',
|
Icon: '',
|
OrderNo: 0,
|
Enable: 1,
|
});
|
|
const rules = {
|
MenuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
};
|
|
onMounted(() => {
|
fetchData();
|
});
|
|
async function fetchData() {
|
loading.value = true;
|
try {
|
const res = await getMenuList({
|
page: 1,
|
rows: 1000,
|
sort: 'OrderNo',
|
order: 'asc',
|
});
|
if (res.status && res.data) {
|
dataSource.value = res.data.rows || [];
|
}
|
} catch (error) {
|
console.error('Fetch data error:', error);
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
function handleAdd() {
|
modalTitle.value = '新增菜单';
|
Object.assign(formState, {
|
Id: undefined,
|
MenuName: '',
|
Url: '',
|
Icon: '',
|
OrderNo: 0,
|
Enable: 1,
|
});
|
modalVisible.value = true;
|
}
|
|
function handleEdit(record: MenuInfo) {
|
modalTitle.value = '编辑菜单';
|
Object.assign(formState, record);
|
modalVisible.value = true;
|
}
|
|
async function handleModalOk() {
|
try {
|
await formRef.value.validate();
|
const api = formState.Id ? updateMenu : addMenu;
|
const res = await api(formState);
|
if (res.status) {
|
message.success(formState.Id ? '更新成功' : '新增成功');
|
modalVisible.value = false;
|
fetchData();
|
}
|
} catch (error) {
|
console.error('Save error:', error);
|
}
|
}
|
|
function handleModalCancel() {
|
modalVisible.value = false;
|
formRef.value?.resetFields();
|
}
|
|
async function handleDelete(record: MenuInfo) {
|
try {
|
const res = await deleteMenu([record.Id]);
|
if (res.status) {
|
message.success('删除成功');
|
fetchData();
|
}
|
} catch (error) {
|
console.error('Delete error:', error);
|
}
|
}
|
</script>
|
|
<style scoped>
|
.menu-page {
|
padding: 0;
|
}
|
</style>
|