From 220e0316e07a0842664db4355b3c921104c67e22 Mon Sep 17 00:00:00 2001 From: xingyu4j <xingyu4j@vip.qq.com> Date: Tue, 1 Nov 2022 14:36:18 +0800 Subject: [PATCH] feat: vxe demo --- .../src/api/system/post/types.ts | 8 +- .../src/plugins/vxeTable/index.ts | 32 ++ .../src/views/system/post/index.vue | 409 ++++++++++++------ .../src/views/system/post/indexd.vue | 194 +++++++++ 4 files changed, 504 insertions(+), 139 deletions(-) create mode 100644 yudao-ui-admin-vue3/src/views/system/post/indexd.vue diff --git a/yudao-ui-admin-vue3/src/api/system/post/types.ts b/yudao-ui-admin-vue3/src/api/system/post/types.ts index 261553514..5d6a70c85 100644 --- a/yudao-ui-admin-vue3/src/api/system/post/types.ts +++ b/yudao-ui-admin-vue3/src/api/system/post/types.ts @@ -1,5 +1,5 @@ export type PostVO = { - id: number + id?: number name: string code: string sort: number @@ -11,11 +11,13 @@ export type PostVO = { export type PostPageReqVO = { code: string name: string - status: number + status?: number + pageSize?: number + pageNo?: number } export type PostExportReqVO = { code: string name: string - status: number + status?: number } diff --git a/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts b/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts index 53a9aad17..40831feee 100644 --- a/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts +++ b/yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts @@ -53,14 +53,46 @@ VXETable.setup({ version: 0, // 版本号,对于某些带数据缓存的功能有用到,上升版本号可以用于重置数据 zIndex: 1008, // 全局 zIndex 起始值,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡 loadingText: '加载中...', // 全局loading提示内容,如果为null则不显示文本 + height: 600, table: { + border: 'inner', // 自动监听父元素的变化去重新计算表格 autoResize: true, emptyText: '暂无数据', // 鼠标移到行是否要高亮显示 highlightHoverRow: true }, + grid: { + toolbarConfig: { + refresh: true, + import: true, + export: true, + print: true, + zoom: true, + custom: true + }, + pagerConfig: { + border: false, + background: true, + autoHidden: true, + perfect: true, + pageSize: 10, + pagerCount: 7, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500], + layouts: [ + 'PrevJump', + 'PrevPage', + 'Jump', + 'PageCount', + 'NextPage', + 'NextJump', + 'Sizes', + 'Total' + ] + } + }, pager: { + background: true, autoHidden: false, perfect: true, pageSize: 10, diff --git a/yudao-ui-admin-vue3/src/views/system/post/index.vue b/yudao-ui-admin-vue3/src/views/system/post/index.vue index 4275ec15b..0b58abd8f 100644 --- a/yudao-ui-admin-vue3/src/views/system/post/index.vue +++ b/yudao-ui-admin-vue3/src/views/system/post/index.vue @@ -1,139 +1,270 @@ <script setup lang="ts"> -import { ref, unref } from 'vue' +import { reactive, ref } from 'vue' import dayjs from 'dayjs' -import { ElMessage } from 'element-plus' -import { DICT_TYPE } from '@/utils/dict' -import { useTable } from '@/hooks/web/useTable' +import XEUtils from 'xe-utils' import { useI18n } from '@/hooks/web/useI18n' -import { FormExpose } from '@/components/Form' -import type { PostVO } from '@/api/system/post/types' -import { rules, allSchemas } from './post.data' +import { VxeFormEvents, VxeFormItemProps, VxeGrid, VxeGridInstance, VxeGridProps } from 'vxe-table' import * as PostApi from '@/api/system/post' +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' +import { ContentWrap } from '@/components/ContentWrap' +import { PostPageReqVO, PostVO } from '@/api/system/post/types' +import { rules, allSchemas } from './post.data' +import { ElMessage, ElMessageBox } from 'element-plus' + const { t } = useI18n() // 国际化 -// ========== 列表相关 ========== -const { register, tableObject, methods } = useTable<PostVO>({ - getListApi: PostApi.getPostPageApi, - delListApi: PostApi.deletePostApi, - exportListApi: PostApi.exportPostApi -}) -const { getList, setSearchParams, delList, exportList } = methods - -// ========== CRUD 相关 ========== -const actionLoading = ref(false) // 遮罩层 -const actionType = ref('') // 操作按钮的类型 +const xGrid = ref<VxeGridInstance>() const dialogVisible = ref(false) // 是否显示弹出层 const dialogTitle = ref('edit') // 弹出层标题 -const formRef = ref<FormExpose>() // 表单 Ref +const actionType = ref('') // 操作按钮的类型 +const actionLoading = ref(false) // 遮罩层 +const gridOptions = reactive<VxeGridProps>({ + loading: false, + rowConfig: { + keyField: 'id', + isHover: true + }, + toolbarConfig: { + buttons: [{ code: 'insert_actived', name: '新增' }] + }, + printConfig: { + columns: [ + { field: 'name' }, + { field: 'code' }, + { field: 'sort' }, + { field: 'status' }, + { field: 'createTime' } + ] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + { + field: 'name', + title: '岗位名称', + span: 8, + itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } } + }, + { + field: 'code', + title: '岗位编码', + span: 8, + itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } } + }, + { + field: 'status', + title: t('common.status'), + span: 8, + itemRender: { name: '$select', options: getIntDictOptions(DICT_TYPE.COMMON_STATUS) } + }, + { + span: 24, + align: 'center', + collapseNode: true, + itemRender: { + name: '$buttons', + children: [ + { props: { type: 'submit', content: t('common.query'), status: 'primary' } }, + { props: { type: 'reset', content: t('common.reset') } } + ] + } + } + ] + }, + columns: [ + { type: 'seq', title: t('common.index'), width: 100 }, + { field: 'name', title: '岗位名称' }, + { field: 'code', title: '岗位编码' }, + { field: 'sort', title: '岗位顺序' }, + { + field: 'status', + title: t('common.status'), + slots: { + default: 'status_default' + } + }, + { + field: 'createTime', + title: t('common.createTime'), + width: 160, + sortable: true, + formatter({ cellValue }) { + return XEUtils.toDateString(cellValue, 'yyyy-MM-dd HH:ss:mm') + } + }, + { + field: 'action', + title: t('table.action'), + width: '240px', + showOverflow: true, + slots: { + default: 'action_default' + } + } + ], + pagerConfig: { + border: false, + background: false, + perfect: true, + pageSize: 10, + pagerCount: 7, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500], + layouts: ['PrevJump', 'PrevPage', 'Jump', 'PageCount', 'NextPage', 'NextJump', 'Sizes', 'Total'] + }, + proxyConfig: { + seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号) + props: { + result: 'list', + total: 'total' + }, + ajax: { + query: ({ page, form }) => { + const queryParams: PostPageReqVO = Object.assign({}, form) + queryParams.pageSize = page.pageSize + queryParams.pageNo = page.currentPage + return new Promise(async (resolve) => { + resolve(await PostApi.getPostPageApi(queryParams)) + }) + } + } + } +}) +const formData = ref<PostVO>({ + name: '', + code: '', + sort: 0, + status: 0, + remark: '', + createTime: '' +}) +const formItems = reactive<VxeFormItemProps[]>([ + { + field: 'id', + title: 'id', + visible: false + }, + { + field: 'name', + title: '岗位名称', + span: 8, + itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } } + }, + { + field: 'code', + title: '岗位编码', + span: 8, + itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } } + }, + { + field: 'sort', + title: '岗位顺序', + span: 8, + itemRender: { name: '$input', props: { type: 'number', placeholder: '请输入岗位顺序' } } + }, + { + field: 'status', + title: t('common.status'), + span: 8, + itemRender: { + name: '$select', + options: getIntDictOptions(DICT_TYPE.COMMON_STATUS), + props: { placeholder: '请选择' } + } + }, + { + align: 'center', + span: 24, + itemRender: { + name: '$buttons', + children: [ + { props: { type: 'submit', content: t('action.save'), status: 'primary' } }, + { props: { type: 'reset', content: t('common.reset') } } + ] + } + } +]) // 设置标题 const setDialogTile = (type: string) => { dialogTitle.value = t('action.' + type) actionType.value = type dialogVisible.value = true } - +// ========== 详情相关 ========== +const detailRef = ref() // 详情 Ref +// 详情操作 +const handleDetail = (row: PostVO) => { + setDialogTile('detail') + detailRef.value = row +} // 新增操作 const handleCreate = () => { setDialogTile('create') - // 重置表单 - unref(formRef)?.getElFormRef()?.resetFields() } // 修改操作 -const handleUpdate = async (row: PostVO) => { +const handleUpdate = async (rowId: number) => { setDialogTile('update') // 设置数据 - const res = await PostApi.getPostApi(row.id) - unref(formRef)?.setValues(res) + const res = await PostApi.getPostApi(rowId) + formData.value = res } - -// 提交按钮 -const submitForm = async () => { - const elForm = unref(formRef)?.getElFormRef() - if (!elForm) return - elForm.validate(async (valid) => { - if (valid) { - actionLoading.value = true - // 提交请求 - try { - const data = unref(formRef)?.formModel as PostVO - if (actionType.value === 'create') { - await PostApi.createPostApi(data) - ElMessage.success(t('common.createSuccess')) - } else { - await PostApi.updatePostApi(data) - ElMessage.success(t('common.updateSuccess')) - } - // 操作成功,重新加载列表 - dialogVisible.value = false - await getList() - } finally { - actionLoading.value = false - } - } +// 删除操作 +const handleDelete = (rowId: number) => { + ElMessageBox.confirm(t('common.delMessage'), t('common.confirmTitle'), { + confirmButtonText: t('common.ok'), + cancelButtonText: t('common.cancel'), + type: 'warning' }) + .then(async () => { + await PostApi.deletePostApi(rowId) + }) + .finally(() => { + ElMessage.success(t('common.delSuccess')) + const $grid = xGrid.value + $grid?.commitProxy('query') + }) } - -// ========== 详情相关 ========== -const detailRef = ref() // 详情 Ref - -// 详情操作 -const handleDetail = async (row: PostVO) => { - // 设置数据 - detailRef.value = row - setDialogTile('detail') +// 提交按钮 +const submitForm: VxeFormEvents.Submit = async () => { + actionLoading.value = true + // 提交请求 + try { + const data = formData.value as PostVO + if (actionType.value === 'create') { + await PostApi.createPostApi(data) + ElMessage.success(t('common.createSuccess')) + } else { + await PostApi.updatePostApi(data) + ElMessage.success(t('common.updateSuccess')) + } + // 操作成功,重新加载列表 + dialogVisible.value = false + } finally { + actionLoading.value = false + const $grid = xGrid.value + $grid?.commitProxy('query') + } } - -// ========== 初始化 ========== -getList() </script> - <template> - <!-- 搜索工作区 --> <ContentWrap> - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> - </ContentWrap> - <ContentWrap> - <!-- 操作工具栏 --> - <div class="mb-10px"> - <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} - </el-button> - <el-button - type="warning" - v-hasPermi="['system:post:export']" - :loading="tableObject.exportLoading" - @click="exportList('岗位数据.xls')" - > - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }} - </el-button> - </div> - <!-- 列表 --> - <Table - :columns="allSchemas.tableColumns" - :selection="false" - :data="tableObject.tableList" - :loading="tableObject.loading" - :pagination="{ - total: tableObject.total - }" - v-model:pageSize="tableObject.pageSize" - v-model:currentPage="tableObject.currentPage" - @register="register" - > - <template #status="{ row }"> + <vxe-grid ref="xGrid" v-bind="gridOptions"> + <template #toolbar_buttons> + <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} + </el-button> + </template> + <template #status_default="{ row }"> <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> </template> - <template #createTime="{ row }"> - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> - </template> - <template #action="{ row }"> + <template #action_default="{ row }"> <el-button link type="primary" v-hasPermi="['system:post:update']" - @click="handleUpdate(row)" + @click="handleUpdate(row.id)" > <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} </el-button> @@ -149,46 +280,52 @@ getList() link type="primary" v-hasPermi="['system:post:delete']" - @click="delList(row.id, false)" + @click="handleDelete(row.id)" > <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} </el-button> </template> - </Table> + </vxe-grid> </ContentWrap> - - <Dialog v-model="dialogVisible" :title="dialogTitle"> - <!-- 对话框(添加 / 修改) --> - <Form - v-if="['create', 'update'].includes(actionType)" - :schema="allSchemas.formSchema" - :rules="rules" - ref="formRef" - /> - <!-- 对话框(详情) --> - <Descriptions - v-if="actionType === 'detail'" - :schema="allSchemas.detailSchema" - :data="detailRef" - > - <template #status="{ row }"> - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> - </template> - <template #createTime="{ row }"> - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> - </template> - </Descriptions> - <!-- 操作按钮 --> - <template #footer> - <el-button - v-if="['create', 'update'].includes(actionType)" - type="primary" - :loading="actionLoading" - @click="submitForm" - > - {{ t('action.save') }} - </el-button> - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> + <vxe-modal + v-model="dialogVisible" + id="myModal6" + width="800" + height="400" + min-width="460" + min-height="320" + show-zoom + resize + remember + storage + transfer + show-footer + > + <template #title> + <span>{{ dialogTitle }}</span> </template> - </Dialog> + <template #default> + <!-- 对话框(添加 / 修改) --> + <vxe-form + v-if="['create', 'update'].includes(actionType)" + :data="formData" + :items="formItems" + :rules="rules" + titleColon + @submit="submitForm" + /> + <Descriptions + v-if="actionType === 'detail'" + :schema="allSchemas.detailSchema" + :data="detailRef" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + </Descriptions> + </template> + </vxe-modal> </template> diff --git a/yudao-ui-admin-vue3/src/views/system/post/indexd.vue b/yudao-ui-admin-vue3/src/views/system/post/indexd.vue new file mode 100644 index 000000000..4275ec15b --- /dev/null +++ b/yudao-ui-admin-vue3/src/views/system/post/indexd.vue @@ -0,0 +1,194 @@ +<script setup lang="ts"> +import { ref, unref } from 'vue' +import dayjs from 'dayjs' +import { ElMessage } from 'element-plus' +import { DICT_TYPE } from '@/utils/dict' +import { useTable } from '@/hooks/web/useTable' +import { useI18n } from '@/hooks/web/useI18n' +import { FormExpose } from '@/components/Form' +import type { PostVO } from '@/api/system/post/types' +import { rules, allSchemas } from './post.data' +import * as PostApi from '@/api/system/post' +const { t } = useI18n() // 国际化 + +// ========== 列表相关 ========== +const { register, tableObject, methods } = useTable<PostVO>({ + getListApi: PostApi.getPostPageApi, + delListApi: PostApi.deletePostApi, + exportListApi: PostApi.exportPostApi +}) +const { getList, setSearchParams, delList, exportList } = methods + +// ========== CRUD 相关 ========== +const actionLoading = ref(false) // 遮罩层 +const actionType = ref('') // 操作按钮的类型 +const dialogVisible = ref(false) // 是否显示弹出层 +const dialogTitle = ref('edit') // 弹出层标题 +const formRef = ref<FormExpose>() // 表单 Ref + +// 设置标题 +const setDialogTile = (type: string) => { + dialogTitle.value = t('action.' + type) + actionType.value = type + dialogVisible.value = true +} + +// 新增操作 +const handleCreate = () => { + setDialogTile('create') + // 重置表单 + unref(formRef)?.getElFormRef()?.resetFields() +} + +// 修改操作 +const handleUpdate = async (row: PostVO) => { + setDialogTile('update') + // 设置数据 + const res = await PostApi.getPostApi(row.id) + unref(formRef)?.setValues(res) +} + +// 提交按钮 +const submitForm = async () => { + const elForm = unref(formRef)?.getElFormRef() + if (!elForm) return + elForm.validate(async (valid) => { + if (valid) { + actionLoading.value = true + // 提交请求 + try { + const data = unref(formRef)?.formModel as PostVO + if (actionType.value === 'create') { + await PostApi.createPostApi(data) + ElMessage.success(t('common.createSuccess')) + } else { + await PostApi.updatePostApi(data) + ElMessage.success(t('common.updateSuccess')) + } + // 操作成功,重新加载列表 + dialogVisible.value = false + await getList() + } finally { + actionLoading.value = false + } + } + }) +} + +// ========== 详情相关 ========== +const detailRef = ref() // 详情 Ref + +// 详情操作 +const handleDetail = async (row: PostVO) => { + // 设置数据 + detailRef.value = row + setDialogTile('detail') +} + +// ========== 初始化 ========== +getList() +</script> + +<template> + <!-- 搜索工作区 --> + <ContentWrap> + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> + </ContentWrap> + <ContentWrap> + <!-- 操作工具栏 --> + <div class="mb-10px"> + <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate"> + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} + </el-button> + <el-button + type="warning" + v-hasPermi="['system:post:export']" + :loading="tableObject.exportLoading" + @click="exportList('岗位数据.xls')" + > + <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }} + </el-button> + </div> + <!-- 列表 --> + <Table + :columns="allSchemas.tableColumns" + :selection="false" + :data="tableObject.tableList" + :loading="tableObject.loading" + :pagination="{ + total: tableObject.total + }" + v-model:pageSize="tableObject.pageSize" + v-model:currentPage="tableObject.currentPage" + @register="register" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + <template #action="{ row }"> + <el-button + link + type="primary" + v-hasPermi="['system:post:update']" + @click="handleUpdate(row)" + > + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} + </el-button> + <el-button + link + type="primary" + v-hasPermi="['system:post:update']" + @click="handleDetail(row)" + > + <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} + </el-button> + <el-button + link + type="primary" + v-hasPermi="['system:post:delete']" + @click="delList(row.id, false)" + > + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} + </el-button> + </template> + </Table> + </ContentWrap> + + <Dialog v-model="dialogVisible" :title="dialogTitle"> + <!-- 对话框(添加 / 修改) --> + <Form + v-if="['create', 'update'].includes(actionType)" + :schema="allSchemas.formSchema" + :rules="rules" + ref="formRef" + /> + <!-- 对话框(详情) --> + <Descriptions + v-if="actionType === 'detail'" + :schema="allSchemas.detailSchema" + :data="detailRef" + > + <template #status="{ row }"> + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> + </template> + <template #createTime="{ row }"> + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span> + </template> + </Descriptions> + <!-- 操作按钮 --> + <template #footer> + <el-button + v-if="['create', 'update'].includes(actionType)" + type="primary" + :loading="actionLoading" + @click="submitForm" + > + {{ t('action.save') }} + </el-button> + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button> + </template> + </Dialog> +</template>