wip: system management sample page

This commit is contained in:
Vben
2021-03-03 22:52:25 +08:00
parent f79cae63d9
commit 9a1ba74920
31 changed files with 852 additions and 52 deletions

View File

@@ -0,0 +1,70 @@
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
:title="getTitle"
width="50%"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
</BasicDrawer>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from './menu.data';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { getMenuList } from '/@/api/demo/system';
export default defineComponent({
name: 'MenuDrawer',
components: { BasicDrawer, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { lg: 12, md: 24 },
});
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields();
setDrawerProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
const treeData = await getMenuList();
updateSchema({
field: 'parentMenu',
componentProps: { treeData },
});
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增菜单' : '编辑菜单'));
async function handleSubmit() {
try {
const values = await validate();
setDrawerProps({ confirmLoading: true });
// TODO custom api
console.log(values);
closeDrawer();
emit('success');
} finally {
setDrawerProps({ confirmLoading: false });
}
}
return { registerDrawer, registerForm, getTitle, handleSubmit };
},
});
</script>

View File

@@ -0,0 +1,100 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> 新增菜单 </a-button>
</template>
<template #action="{ record }">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</BasicTable>
<MenuDrawer @register="registerDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { getMenuList } from '/@/api/demo/system';
import { useDrawer } from '/@/components/Drawer';
import MenuDrawer from './MenuDrawer.vue';
import { columns, searchFormSchema } from './menu.data';
export default defineComponent({
name: 'MenuManagement',
components: { BasicTable, MenuDrawer, TableAction },
setup() {
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerTable, { reload }] = useTable({
title: '菜单列表',
api: getMenuList,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
pagination: false,
striped: false,
useSearchForm: true,
showTableSetting: true,
bordered: true,
showIndexColumn: false,
canResize: false,
actionColumn: {
width: 80,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
fixed: undefined,
},
});
function handleCreate() {
openDrawer(true, {
isUpdate: false,
});
}
function handleEdit(record: Recordable) {
openDrawer(true, {
record,
isUpdate: true,
});
}
function handleDelete(record: Recordable) {
console.log(record);
}
function handleSuccess() {
reload();
}
return {
registerTable,
registerDrawer,
handleCreate,
handleEdit,
handleDelete,
handleSuccess,
};
},
});
</script>

View File

@@ -0,0 +1,202 @@
import { BasicColumn } from '/@/components/Table';
import { FormSchema } from '/@/components/Table';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
import { Icon } from '/@/components/Icon';
export const columns: BasicColumn[] = [
{
title: '菜单名称',
dataIndex: 'menuName',
width: 200,
align: 'left',
},
{
title: '图标',
dataIndex: 'icon',
width: 50,
customRender: ({ record }) => {
return h(Icon, { icon: record.icon });
},
},
{
title: '权限标识',
dataIndex: 'permission',
width: 180,
},
{
title: '组件',
dataIndex: 'component',
},
{
title: '排序',
dataIndex: 'orderNo',
width: 50,
},
{
title: '状态',
dataIndex: 'status',
width: 80,
customRender: ({ record }) => {
const status = record.status;
const enable = ~~status === 0;
const color = enable ? 'green' : 'red';
const text = enable ? '启用' : '停用';
return h(Tag, { color: color }, () => text);
},
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
},
];
const isDir = (type: string) => type === '0';
const isMenu = (type: string) => type === '1';
const isButton = (type: string) => type === '2';
export const searchFormSchema: FormSchema[] = [
{
field: 'menuName',
label: '菜单名称',
component: 'Input',
colProps: { span: 8 },
},
{
field: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: [
{ label: '启用', value: '0' },
{ label: '停用', value: '1' },
],
},
colProps: { span: 8 },
},
];
export const formSchema: FormSchema[] = [
{
field: 'type',
label: '菜单类型',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '目录', value: '0' },
{ label: '菜单', value: '1' },
{ label: '按钮', value: '2' },
],
},
colProps: { lg: 24, md: 24 },
},
{
field: 'menuName',
label: '菜单名称',
component: 'Input',
required: true,
},
{
field: 'parentMenu',
label: '上级菜单',
component: 'TreeSelect',
componentProps: {
replaceFields: {
title: 'menuName',
key: 'id',
value: 'id',
},
getPopupContainer: () => document.body,
},
},
{
field: 'orderNo',
label: '排序',
component: 'InputNumber',
required: true,
},
{
field: 'icon',
label: '图标',
component: 'IconPicker',
required: true,
show: ({ values }) => !isButton(values.type),
},
{
field: 'routePath',
label: '路由地址',
component: 'Input',
required: true,
show: ({ values }) => !isButton(values.type),
},
{
field: 'component',
label: '组件路径',
component: 'Input',
show: ({ values }) => isMenu(values.type),
},
{
field: 'permission',
label: '权限标识',
component: 'Input',
show: ({ values }) => !isDir(values.type),
},
{
field: 'status',
label: '状态',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '启用', value: '0' },
{ label: '禁用', value: '1' },
],
},
},
{
field: 'isExt',
label: '是否外链',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '否', value: '0' },
{ label: '是', value: '1' },
],
},
show: ({ values }) => !isButton(values.type),
},
{
field: 'keepalive',
label: '是否缓存',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '否', value: '0' },
{ label: '是', value: '1' },
],
},
show: ({ values }) => isMenu(values.type),
},
{
field: 'show',
label: '是否显示',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '是', value: '0' },
{ label: '否', value: '1' },
],
},
show: ({ values }) => !isButton(values.type),
},
];