Commit cb6b7a754e8631703c1fad6ebe2d17c983410e3a

Authored by YunaiV
1 parent 9d272e79

Vue3 CRUD Schema 模版,index 和 form 完善

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,6 +112,10 @@ public class CodegenEngine {
112 // Vue3 Schema 模版 112 // Vue3 Schema 模版
113 .put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/data.ts"), 113 .put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/data.ts"),
114 vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts")) 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 .build(); 119 .build();
116 120
117 @Resource 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 <template> 1 <template>
  2 + <!-- 搜索工作栏 -->
2 <ContentWrap> 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 type="primary" 8 type="primary"
9 - preIcon="ep:zoom-in"  
10 - :title="t('action.add')" 9 + plain
  10 + @click="openForm('create')"
11 v-hasPermi="['${permissionPrefix}:create']" 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 </template> 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 v-hasPermi="['${permissionPrefix}:update']" 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 v-hasPermi="['${permissionPrefix}:delete']" 43 v-hasPermi="['${permissionPrefix}:delete']"
43 - @click="deleteData(row.id)"  
44 - /> 44 + @click="handleDelete(row.id)"
  45 + >
  46 + 删除
  47 + </el-button>
45 </template> 48 </template>
46 - </XTable> 49 + </Table>
47 </ContentWrap> 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 </template> 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 import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}' 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 </script> 85 </script>