Commit cb6b7a754e8631703c1fad6ebe2d17c983410e3a
1 parent
9d272e79
Vue3 CRUD Schema 模版,index 和 form 完善
Showing
3 changed files
with
135 additions
and
141 deletions
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
| ... | ... | @@ -112,6 +112,10 @@ public class CodegenEngine { |
| 112 | 112 | // Vue3 Schema 模版 |
| 113 | 113 | .put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/data.ts"), |
| 114 | 114 | vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts")) |
| 115 | + .put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/index.vue"), | |
| 116 | + vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue")) | |
| 117 | + .put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/form.vue"), | |
| 118 | + vue3FilePath("views/${table.moduleName}/${classNameVar}/${simpleClassName}Form.vue")) | |
| 115 | 119 | .build(); |
| 116 | 120 | |
| 117 | 121 | @Resource | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_schema/views/form.vue.vm
0 → 100644
| 1 | +<template> | |
| 2 | + <Dialog :title="dialogTitle" v-model="dialogVisible"> | |
| 3 | + <Form ref="formRef" :schema="allSchemas.formSchema" :rules="rules" v-loading="formLoading" /> | |
| 4 | + <template #footer> | |
| 5 | + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | |
| 6 | + <el-button @click="dialogVisible = false">取 消</el-button> | |
| 7 | + </template> | |
| 8 | + </Dialog> | |
| 9 | +</template> | |
| 10 | +<script setup lang="ts"> | |
| 11 | + import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}' | |
| 12 | +import { rules, allSchemas } from './${classNameVar}.data' | |
| 13 | +const { t } = useI18n() // 国际化 | |
| 14 | +const message = useMessage() // 消息弹窗 | |
| 15 | + | |
| 16 | +const dialogVisible = ref(false) // 弹窗的是否展示 | |
| 17 | +const dialogTitle = ref('') // 弹窗的标题 | |
| 18 | +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 | |
| 19 | +const formType = ref('') // 表单的类型:create - 新增;update - 修改 | |
| 20 | +const formRef = ref() // 表单 Ref | |
| 21 | + | |
| 22 | +/** 打开弹窗 */ | |
| 23 | +const open = async (type: string, id?: number) => { | |
| 24 | + dialogVisible.value = true | |
| 25 | + dialogTitle.value = t('action.' + type) | |
| 26 | + formType.value = type | |
| 27 | + // 修改时,设置数据 | |
| 28 | + if (id) { | |
| 29 | + formLoading.value = true | |
| 30 | + try { | |
| 31 | + const data = await ${simpleClassName}Api.get${simpleClassName}(id) | |
| 32 | + formRef.value.setValues(data) | |
| 33 | + } finally { | |
| 34 | + formLoading.value = false | |
| 35 | + } | |
| 36 | + } | |
| 37 | +} | |
| 38 | +defineExpose({ open }) // 提供 open 方法,用于打开弹窗 | |
| 39 | + | |
| 40 | +/** 提交表单 */ | |
| 41 | +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 | |
| 42 | +const submitForm = async () => { | |
| 43 | + // 校验表单 | |
| 44 | + if (!formRef) return | |
| 45 | + const valid = await formRef.value.getElFormRef().validate() | |
| 46 | + if (!valid) return | |
| 47 | + // 提交请求 | |
| 48 | + formLoading.value = true | |
| 49 | + try { | |
| 50 | + const data = formRef.value.formModel as ${simpleClassName}Api.${simpleClassName}VO | |
| 51 | + if (formType.value === 'create') { | |
| 52 | + await ${simpleClassName}Api.create${simpleClassName}(data) | |
| 53 | + message.success(t('common.createSuccess')) | |
| 54 | + } else { | |
| 55 | + await ${simpleClassName}Api.update${simpleClassName}(data) | |
| 56 | + message.success(t('common.updateSuccess')) | |
| 57 | + } | |
| 58 | + dialogVisible.value = false | |
| 59 | + // 发送操作成功的事件 | |
| 60 | + emit('success') | |
| 61 | + } finally { | |
| 62 | + formLoading.value = false | |
| 63 | + } | |
| 64 | +} | |
| 65 | +</script> | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_schema/views/index.vue.vm
| 1 | 1 | <template> |
| 2 | + <!-- 搜索工作栏 --> | |
| 2 | 3 | <ContentWrap> |
| 3 | - <!-- 列表 --> | |
| 4 | - <XTable @register="registerTable"> | |
| 5 | - <template #toolbar_buttons> | |
| 6 | - <!-- 操作:新增 --> | |
| 7 | - <XButton | |
| 4 | + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams"> | |
| 5 | + <!-- 新增等操作按钮 --> | |
| 6 | + <template #actionMore> | |
| 7 | + <el-button | |
| 8 | 8 | type="primary" |
| 9 | - preIcon="ep:zoom-in" | |
| 10 | - :title="t('action.add')" | |
| 9 | + plain | |
| 10 | + @click="openForm('create')" | |
| 11 | 11 | v-hasPermi="['${permissionPrefix}:create']" |
| 12 | - @click="handleCreate()" | |
| 13 | - /> | |
| 14 | - <!-- 操作:导出 --> | |
| 15 | - <XButton | |
| 16 | - type="warning" | |
| 17 | - preIcon="ep:download" | |
| 18 | - :title="t('action.export')" | |
| 19 | - v-hasPermi="['${permissionPrefix}:export']" | |
| 20 | - @click="exportList('${table.classComment}.xls')" | |
| 21 | - /> | |
| 12 | + > | |
| 13 | + <Icon icon="ep:plus" class="mr-5px" /> 新增 | |
| 14 | + </el-button> | |
| 22 | 15 | </template> |
| 23 | - <template #actionbtns_default="{ row }"> | |
| 24 | - <!-- 操作:修改 --> | |
| 25 | - <XTextButton | |
| 26 | - preIcon="ep:edit" | |
| 27 | - :title="t('action.edit')" | |
| 16 | + </Search> | |
| 17 | + </ContentWrap> | |
| 18 | + | |
| 19 | + <!-- 列表 --> | |
| 20 | + <ContentWrap> | |
| 21 | + <Table | |
| 22 | + :columns="allSchemas.tableColumns" | |
| 23 | + :data="tableObject.tableList" | |
| 24 | + :loading="tableObject.loading" | |
| 25 | + :pagination="{ | |
| 26 | + total: tableObject.total | |
| 27 | + }" | |
| 28 | + v-model:pageSize="tableObject.pageSize" | |
| 29 | + v-model:currentPage="tableObject.currentPage" | |
| 30 | + > | |
| 31 | + <template #action="{ row }"> | |
| 32 | + <el-button | |
| 33 | + link | |
| 34 | + type="primary" | |
| 35 | + @click="openForm('update', row.id)" | |
| 28 | 36 | v-hasPermi="['${permissionPrefix}:update']" |
| 29 | - @click="handleUpdate(row.id)" | |
| 30 | - /> | |
| 31 | - <!-- 操作:详情 --> | |
| 32 | - <XTextButton | |
| 33 | - preIcon="ep:view" | |
| 34 | - :title="t('action.detail')" | |
| 35 | - v-hasPermi="['${permissionPrefix}:query']" | |
| 36 | - @click="handleDetail(row.id)" | |
| 37 | - /> | |
| 38 | - <!-- 操作:删除 --> | |
| 39 | - <XTextButton | |
| 40 | - preIcon="ep:delete" | |
| 41 | - :title="t('action.del')" | |
| 37 | + > | |
| 38 | + 编辑 | |
| 39 | + </el-button> | |
| 40 | + <el-button | |
| 41 | + link | |
| 42 | + type="danger" | |
| 42 | 43 | v-hasPermi="['${permissionPrefix}:delete']" |
| 43 | - @click="deleteData(row.id)" | |
| 44 | - /> | |
| 44 | + @click="handleDelete(row.id)" | |
| 45 | + > | |
| 46 | + 删除 | |
| 47 | + </el-button> | |
| 45 | 48 | </template> |
| 46 | - </XTable> | |
| 49 | + </Table> | |
| 47 | 50 | </ContentWrap> |
| 48 | - <!-- 弹窗 --> | |
| 49 | - <XModal id="${classNameVar}Model" :loading="modelLoading" v-model="modelVisible" :title="modelTitle"> | |
| 50 | - <!-- 表单:添加/修改 --> | |
| 51 | - <Form | |
| 52 | - ref="formRef" | |
| 53 | - v-if="['create', 'update'].includes(actionType)" | |
| 54 | - :schema="allSchemas.formSchema" | |
| 55 | - :rules="rules" | |
| 56 | - /> | |
| 57 | - <!-- 表单:详情 --> | |
| 58 | - <Descriptions | |
| 59 | - v-if="actionType === 'detail'" | |
| 60 | - :schema="allSchemas.detailSchema" | |
| 61 | - :data="detailData" | |
| 62 | - /> | |
| 63 | - <template #footer> | |
| 64 | - <!-- 按钮:保存 --> | |
| 65 | - <XButton | |
| 66 | - v-if="['create', 'update'].includes(actionType)" | |
| 67 | - type="primary" | |
| 68 | - :title="t('action.save')" | |
| 69 | - :loading="actionLoading" | |
| 70 | - @click="submitForm()" | |
| 71 | - /> | |
| 72 | - <!-- 按钮:关闭 --> | |
| 73 | - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" /> | |
| 74 | - </template> | |
| 75 | - </XModal> | |
| 51 | + | |
| 52 | + <!-- 表单弹窗:添加/修改 --> | |
| 53 | + <${simpleClassName}Form ref="formRef" @success="getList" /> | |
| 76 | 54 | </template> |
| 77 | -<script setup lang="ts" name="${simpleClassName}"> | |
| 78 | -import { FormExpose } from '@/components/Form' | |
| 79 | -// 业务相关的 import | |
| 80 | -import { rules, allSchemas } from './${classNameVar}.data' | |
| 55 | +<script setup lang="ts" name="${table.className}"> | |
| 56 | +import { allSchemas } from './${classNameVar}.data' | |
| 81 | 57 | import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}' |
| 58 | +import ${simpleClassName}Form from './${simpleClassName}Form.vue' | |
| 82 | 59 | |
| 83 | -const { t } = useI18n() // 国际化 | |
| 84 | -const message = useMessage() // 消息弹窗 | |
| 85 | - | |
| 86 | -// 列表相关的变量 | |
| 87 | -const [registerTable, { reload, deleteData, exportList }] = useXTable({ | |
| 88 | - allSchemas: allSchemas, | |
| 89 | - getListApi: ${simpleClassName}Api.get${simpleClassName}PageApi, | |
| 90 | - deleteApi: ${simpleClassName}Api.delete${simpleClassName}Api, | |
| 91 | - exportListApi: ${simpleClassName}Api.export${simpleClassName}Api | |
| 60 | +// tableObject:表格的属性对象,可获得分页大小、条数等属性 | |
| 61 | +// tableMethods:表格的操作对象,可进行获得分页、删除记录等操作 | |
| 62 | +// 详细可见:https://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/table.html#usetable | |
| 63 | +const { tableObject, tableMethods } = useTable({ | |
| 64 | + getListApi: ${simpleClassName}Api.get${simpleClassName}Page, // 分页接口 | |
| 65 | + delListApi: ${simpleClassName}Api.delete${simpleClassName} // 删除接口 | |
| 92 | 66 | }) |
| 67 | +// 获得表格的各种操作 | |
| 68 | +const { getList, setSearchParams } = tableMethods | |
| 93 | 69 | |
| 94 | -// 弹窗相关的变量 | |
| 95 | -const modelVisible = ref(false) // 是否显示弹出层 | |
| 96 | -const modelTitle = ref('edit') // 弹出层标题 | |
| 97 | -const modelLoading = ref(false) // 弹出层loading | |
| 98 | -const actionType = ref('') // 操作按钮的类型 | |
| 99 | -const actionLoading = ref(false) // 按钮 Loading | |
| 100 | -const formRef = ref<FormExpose>() // 表单 Ref | |
| 101 | -const detailData = ref() // 详情 Ref | |
| 102 | - | |
| 103 | -// 设置标题 | |
| 104 | -const setDialogTile = (type: string) => { | |
| 105 | - modelLoading.value = true | |
| 106 | - modelTitle.value = t('action.' + type) | |
| 107 | - actionType.value = type | |
| 108 | - modelVisible.value = true | |
| 70 | +/** 添加/修改操作 */ | |
| 71 | +const formRef = ref() | |
| 72 | +const openForm = (type: string, id?: number) => { | |
| 73 | + formRef.value.open(type, id) | |
| 109 | 74 | } |
| 110 | 75 | |
| 111 | -// 新增操作 | |
| 112 | -const handleCreate = () => { | |
| 113 | - setDialogTile('create') | |
| 114 | - modelLoading.value = false | |
| 76 | +/** 删除按钮操作 */ | |
| 77 | +const handleDelete = (id: number) => { | |
| 78 | + tableMethods.delList(id, false) | |
| 115 | 79 | } |
| 116 | 80 | |
| 117 | -// 修改操作 | |
| 118 | -const handleUpdate = async (rowId: number) => { | |
| 119 | - setDialogTile('update') | |
| 120 | - // 设置数据 | |
| 121 | - const res = await ${simpleClassName}Api.get${simpleClassName}Api(rowId) | |
| 122 | - unref(formRef)?.setValues(res) | |
| 123 | - modelLoading.value = false | |
| 124 | -} | |
| 125 | - | |
| 126 | -// 详情操作 | |
| 127 | -const handleDetail = async (rowId: number) => { | |
| 128 | - setDialogTile('detail') | |
| 129 | - const res = await ${simpleClassName}Api.get${simpleClassName}Api(rowId) | |
| 130 | - detailData.value = res | |
| 131 | - modelLoading.value = false | |
| 132 | -} | |
| 133 | - | |
| 134 | -// 提交按钮 | |
| 135 | -const submitForm = async () => { | |
| 136 | - const elForm = unref(formRef)?.getElFormRef() | |
| 137 | - if (!elForm) return | |
| 138 | - elForm.validate(async (valid) => { | |
| 139 | - if (valid) { | |
| 140 | - actionLoading.value = true | |
| 141 | - // 提交请求 | |
| 142 | - try { | |
| 143 | - const data = unref(formRef)?.formModel as ${simpleClassName}Api.${simpleClassName}VO | |
| 144 | - if (actionType.value === 'create') { | |
| 145 | - await ${simpleClassName}Api.create${simpleClassName}Api(data) | |
| 146 | - message.success(t('common.createSuccess')) | |
| 147 | - } else { | |
| 148 | - await ${simpleClassName}Api.update${simpleClassName}Api(data) | |
| 149 | - message.success(t('common.updateSuccess')) | |
| 150 | - } | |
| 151 | - modelVisible.value = false | |
| 152 | - } finally { | |
| 153 | - actionLoading.value = false | |
| 154 | - // 刷新列表 | |
| 155 | - await reload() | |
| 156 | - } | |
| 157 | - } | |
| 158 | - }) | |
| 159 | -} | |
| 81 | +/** 初始化 **/ | |
| 82 | +onMounted(() => { | |
| 83 | + getList() | |
| 84 | +}) | |
| 160 | 85 | </script> | ... | ... |