Commit dfcbcf09d49d56de771647c25f8c5e4d8ede6efe

Authored by puhui999
1 parent f3aa501e

【代码优化】代码生成: vue3_vben5_antd schema 主子表标准模式和内嵌模式模板完成

yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
... ... @@ -3,6 +3,12 @@ import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleCl
3 3  
4 4 import { useVbenModal } from '@vben/common-ui';
5 5 import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  6 +## 特殊:主子表专属逻辑
  7 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  8 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  9 + import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
  10 + #end
  11 +#end
6 12  
7 13 import { computed, ref } from 'vue';
8 14 import { $t } from '#/locales';
... ... @@ -10,20 +16,6 @@ import { useVbenForm } from '#/adapter/form';
10 16 import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
11 17  
12 18 import { useFormSchema } from '../data';
13   -#if ( $table.templateType == 10 || $table.templateType == 12 )
14   -#if ( $subTables && $subTables.size() > 0 )
15   -#foreach ($subTable in $subTables)
16   - #set ($index = $foreach.count - 1)
17   - #set ($subSimpleClassName = $subSimpleClassNames.get($index))
18   - #if ($subTable.subJoinMany) ## 一对多
19   -import { useVbenVxeGrid } from '#/adapter/vxe-table';
20   -import { use${subSimpleClassName}GridColumns } from '../data';
21   - #else
22   -import { use${subSimpleClassName}FormSchema } from '../data';
23   - #end
24   -#end
25   -#end
26   -#end
27 19  
28 20 const emit = defineEmits(['success']);
29 21 const formData = ref<${simpleClassName}Api.${simpleClassName}>();
... ... @@ -48,43 +40,17 @@ const getTitle = computed(() =&gt; {
48 40  
49 41 ## 特殊:主子表专属逻辑
50 42 #if ( $table.templateType == 10 || $table.templateType == 12 )
51   -#if ( $subTables && $subTables.size() > 0 )
52   -/** 子表的表单 */
53   -const subTabsName = ref('$subClassNameVars.get(0)')
54   -## 特殊:主子表专属逻辑
55   -#foreach ($subTable in $subTables)
56   - #set ($index = $foreach.count - 1)
57   - #set ($subSimpleClassName = $subSimpleClassNames.get($index))
58   - #set ($subClassNameVar = $subClassNameVars.get($index))
59   - #if ($subTable.subJoinMany) ## 一对多
60   -const [${subSimpleClassName}Grid, ${subClassNameVar}GridApi] = useVbenVxeGrid({
61   - gridOptions: {
62   - columns: use${subSimpleClassName}GridColumns(),
63   - border: true,
64   - showOverflow: true,
65   - autoResize: true,
66   - keepSource: true,
67   - rowConfig: {
68   - keyField: 'id',
69   - },
70   - pagerConfig: {
71   - enabled: false,
72   - },
73   - toolbarConfig: {
74   - enabled: false,
75   - },
76   - },
77   -});
78   - #else
79   -const [${subSimpleClassName}Form, ${subClassNameVar}FormApi] = useVbenForm({
80   - layout: 'horizontal',
81   - schema: use${subSimpleClassName}FormSchema(),
82   - showDefaultActions: false
83   -});
  43 + #if ( $subTables && $subTables.size() > 0 )
  44 +
  45 + /** 子表的表单 */
  46 + const subTabsName = ref('$subClassNameVars.get(0)')
  47 + #foreach ($subClassNameVar in $subClassNameVars)
  48 + #set ($index = $foreach.count - 1)
  49 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  50 + const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
  51 + #end
84 52 #end
85 53 #end
86   -#end
87   -#end
88 54  
89 55 const [Form, formApi] = useVbenForm({
90 56 layout: 'horizontal',
... ... @@ -92,7 +58,6 @@ const [Form, formApi] = useVbenForm({
92 58 showDefaultActions: false
93 59 });
94 60  
95   -// TODO @puhui999: 处理完成主子表标准模式和内嵌模式下的表单提交
96 61 const [Modal, modalApi] = useVbenModal({
97 62 async onConfirm() {
98 63 const { valid } = await formApi.validate();
... ... @@ -107,9 +72,9 @@ const [Modal, modalApi] = useVbenModal({
107 72 #set ($index = $foreach.count - 1)
108 73 #set ($subClassNameVar = $subClassNameVars.get($index))
109 74 #if ($subTable.subJoinMany) ## 一对多
110   -
  75 + ## TODO 列表值校验?
111 76 #else
112   - const { valid: ${subClassNameVar}Valid } = await ${subClassNameVar}FormApi.validate();
  77 + const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();
113 78 if (!${subClassNameVar}Valid) {
114 79 subTabsName.value = '${subClassNameVar}';
115 80 return;
... ... @@ -129,9 +94,9 @@ const [Modal, modalApi] = useVbenModal({
129 94 #set ($index = $foreach.count - 1)
130 95 #set ($subClassNameVar = $subClassNameVars.get($index))
131 96 #if ($subTable.subJoinMany)
132   - data.${subClassNameVar}s = ${subClassNameVar}GridApi.grid.getData();
  97 + data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
133 98 #else
134   - data.${subClassNameVar} = await ${subClassNameVar}FormApi.getValues();
  99 + data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues();
135 100 #end
136 101 #end
137 102 #end
... ... @@ -187,67 +152,9 @@ const [Modal, modalApi] = useVbenModal({
187 152 #set ($index = $foreach.count - 1)
188 153 #set ($subClassNameVar = $subClassNameVars.get($index))
189 154 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
190   - #set ($subColumns = $subColumnsList.get($index))##当前字段数组
191   - #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
192   - <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}">
193   - #if ($subTable.subJoinMany) ## 一对多
194   - <${subSimpleClassName}Grid class="mx-4">
195   - #foreach($column in $subColumns)
196   - #if ($column.createOperation || $column.updateOperation)
197   - #set ($javaField = $column.javaField)
198   - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
199   - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
200   - <template #${javaField}="{ row }">
201   - <Input v-model:value="row.${javaField}" />
202   - </template>
203   - #elseif($column.htmlType == "imageUpload")## 图片上传
204   - <template #${javaField}="{ row }">
205   - <UploadImg v-model:value="row.${javaField}" />
206   - </template>
207   - #elseif($column.htmlType == "fileUpload")## 文件上传
208   - <template #${javaField}="{ row }">
209   - <UploadFile v-model:value="row.${javaField}" />
210   - </template>
211   - #elseif($column.htmlType == "editor")## 文本编辑器
212   - <template #${javaField}="{ row }">
213   - <Textarea v-model:value="row.${javaField}" />
214   - </template>
215   - #elseif($column.htmlType == "select")## 下拉框
216   - <template #${javaField}="{ row, column }">
217   - <Select v-model:value="row.${javaField}" class="w-full">
218   - <Select.Option v-for="option in column.params.options" :key="option.value" :value="option.value">
219   - {{ option.label }}
220   - </Select.Option>
221   - </Select>
222   - </template>
223   - #elseif($column.htmlType == "checkbox")## 多选框
224   - <template #${javaField}="{ row, column }">
225   - <CheckboxGroup v-model:value="row.${javaField}" :options="column.params.options" />
226   - </template>
227   - #elseif($column.htmlType == "radio")## 单选框
228   - <template #${javaField}="{ row, column }">
229   - <RadioGroup v-model:value="row.${javaField}" :options="column.params.options" />
230   - </template>
231   - #elseif($column.htmlType == "datetime")## 时间框
232   - <template #${javaField}="{ row }">
233   - <DatePicker
234   - v-model:value="row.${javaField}"
235   - :showTime="true"
236   - format="YYYY-MM-DD HH:mm:ss"
237   - valueFormat='x'
238   - />
239   - </template>
240   - #elseif($column.htmlType == "textarea")## 文本框
241   - <template #${javaField}="{ row }">
242   - <Textarea v-model:value="row.${javaField}" />
243   - </template>
244   - #end
245   - #end
246   - #end
247   - </${subSimpleClassName}Grid>
248   - #else
249   - <${subSimpleClassName}Form class="mx-4" />
250   - #end
  155 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  156 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  157 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
251 158 </Tabs.TabPane>
252 159 #end
253 160 </Tabs>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm
... ... @@ -2,359 +2,192 @@
2 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
3 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5   -#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7   -<template>
8   -#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
9   - <el-form
10   - ref="formRef"
11   - :model="formData"
12   - :rules="formRules"
13   - v-loading="formLoading"
14   - label-width="0px"
15   - :inline-message="true"
16   - >
17   - <el-table :data="formData" class="-mt-10px">
18   - <el-table-column label="序号" type="index" width="100" />
19   -#foreach($column in $subColumns)
20   - #if ($column.createOperation || $column.updateOperation)
21   - #set ($dictType = $column.dictType)
22   - #set ($javaField = $column.javaField)
23   - #set ($javaType = $column.javaType)
24   - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
25   - #set ($comment = $column.columnComment)
26   - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
27   - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
28   - #set ($dictMethod = "getIntDictOptions")
29   - #elseif ($javaType == "String")
30   - #set ($dictMethod = "getStrDictOptions")
31   - #elseif ($javaType == "Boolean")
32   - #set ($dictMethod = "getBoolDictOptions")
33   - #end
34   - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
35   - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
36   - <el-table-column label="${comment}" min-width="150">
37   - <template #default="{ row, $index }">
38   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
39   - <el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
40   - </el-form-item>
41   - </template>
42   - </el-table-column>
43   - #elseif($column.htmlType == "imageUpload")## 图片上传
44   - <el-table-column label="${comment}" min-width="200">
45   - <template #default="{ row, $index }">
46   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
47   - <UploadImg v-model="row.${javaField}" />
48   - </el-form-item>
49   - </template>
50   - </el-table-column>
51   - #elseif($column.htmlType == "fileUpload")## 文件上传
52   - <el-table-column label="${comment}" min-width="200">
53   - <template #default="{ row, $index }">
54   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
55   - <UploadFile v-model="row.${javaField}" />
56   - </el-form-item>
57   - </template>
58   - </el-table-column>
59   - #elseif($column.htmlType == "editor")## 文本编辑器
60   - <el-table-column label="${comment}" min-width="400">
61   - <template #default="{ row, $index }">
62   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
63   - <Editor v-model="row.${javaField}" height="150px" />
64   - </el-form-item>
65   - </template>
66   - </el-table-column>
67   - #elseif($column.htmlType == "select")## 下拉框
68   - <el-table-column label="${comment}" min-width="150">
69   - <template #default="{ row, $index }">
70   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
71   - <el-select v-model="row.${javaField}" placeholder="请选择${comment}">
72   - #if ("" != $dictType)## 有数据字典
73   - <el-option
74   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
75   - :key="dict.value"
76   - :label="dict.label"
77   - :value="dict.value"
78   - />
79   - #else##没数据字典
80   - <el-option label="请选择字典生成" value="" />
81   - #end
82   - </el-select>
83   - </el-form-item>
84   - </template>
85   - </el-table-column>
86   - #elseif($column.htmlType == "checkbox")## 多选框
87   - <el-table-column label="${comment}" min-width="150">
88   - <template #default="{ row, $index }">
89   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
90   - <el-checkbox-group v-model="row.${javaField}">
91   - #if ("" != $dictType)## 有数据字典
92   - <el-checkbox
93   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
94   - :key="dict.value"
95   - :label="dict.label"
96   - :value="dict.value"
97   - />
98   - #else##没数据字典
99   - <el-checkbox label="请选择字典生成" />
100   - #end
101   - </el-checkbox-group>
102   - </el-form-item>
103   - </template>
104   - </el-table-column>
105   - #elseif($column.htmlType == "radio")## 单选框
106   - <el-table-column label="${comment}" min-width="150">
107   - <template #default="{ row, $index }">
108   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
109   - <el-radio-group v-model="row.${javaField}">
110   - #if ("" != $dictType)## 有数据字典
111   - <el-radio
112   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
113   - :key="dict.value"
114   - :label="dict.value"
115   - >
116   - {{ dict.label }}
117   - </el-radio>
118   - #else##没数据字典
119   - <el-radio value="1">请选择字典生成</el-radio>
120   - #end
121   - </el-radio-group>
122   - </el-form-item>
123   - </template>
124   - </el-table-column>
125   - #elseif($column.htmlType == "datetime")## 时间框
126   - <el-table-column label="${comment}" min-width="150">
127   - <template #default="{ row, $index }">
128   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
129   - <el-date-picker
130   - v-model="row.${javaField}"
131   - type="date"
132   - value-format="x"
133   - placeholder="选择${comment}"
134   - />
135   - </el-form-item>
136   - </template>
137   - </el-table-column>
138   - #elseif($column.htmlType == "textarea")## 文本框
139   - <el-table-column label="${comment}" min-width="200">
140   - <template #default="{ row, $index }">
141   - <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
142   - <el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
143   - </el-form-item>
144   - </template>
145   - </el-table-column>
146   - #end
147   - #end
148   -#end
149   - <el-table-column align="center" fixed="right" label="操作" width="60">
150   - <template #default="{ $index }">
151   - <el-button @click="handleDelete($index)" link>—</el-button>
152   - </template>
153   - </el-table-column>
154   - </el-table>
155   - </el-form>
156   - <el-row justify="center" class="mt-3">
157   - <el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
158   - </el-row>
159   -#else## 情况二:一对一,form
160   - <el-form
161   - ref="formRef"
162   - :model="formData"
163   - :rules="formRules"
164   - label-width="100px"
165   - v-loading="formLoading"
166   - >
167   -#foreach($column in $subColumns)
168   - #if ($column.createOperation || $column.updateOperation)
169   - #set ($dictType = $column.dictType)
170   - #set ($javaField = $column.javaField)
171   - #set ($javaType = $column.javaType)
172   - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
173   - #set ($comment = $column.columnComment)
174   - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
175   - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
176   - #set ($dictMethod = "getIntDictOptions")
177   - #elseif ($javaType == "String")
178   - #set ($dictMethod = "getStrDictOptions")
179   - #elseif ($javaType == "Boolean")
180   - #set ($dictMethod = "getBoolDictOptions")
181   - #end
182   - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
183   - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
184   - <el-form-item label="${comment}" prop="${javaField}">
185   - <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
186   - </el-form-item>
187   - #elseif($column.htmlType == "imageUpload")## 图片上传
188   - <el-form-item label="${comment}" prop="${javaField}">
189   - <UploadImg v-model="formData.${javaField}" />
190   - </el-form-item>
191   - #elseif($column.htmlType == "fileUpload")## 文件上传
192   - <el-form-item label="${comment}" prop="${javaField}">
193   - <UploadFile v-model="formData.${javaField}" />
194   - </el-form-item>
195   - #elseif($column.htmlType == "editor")## 文本编辑器
196   - <el-form-item label="${comment}" prop="${javaField}">
197   - <Editor v-model="formData.${javaField}" height="150px" />
198   - </el-form-item>
199   - #elseif($column.htmlType == "select")## 下拉框
200   - <el-form-item label="${comment}" prop="${javaField}">
201   - <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
202   - #if ("" != $dictType)## 有数据字典
203   - <el-option
204   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
205   - :key="dict.value"
206   - :label="dict.label"
207   - :value="dict.value"
208   - />
209   - #else##没数据字典
210   - <el-option label="请选择字典生成" value="" />
211   - #end
212   - </el-select>
213   - </el-form-item>
214   - #elseif($column.htmlType == "checkbox")## 多选框
215   - <el-form-item label="${comment}" prop="${javaField}">
216   - <el-checkbox-group v-model="formData.${javaField}">
217   - #if ("" != $dictType)## 有数据字典
218   - <el-checkbox
219   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
220   - :key="dict.value"
221   - :label="dict.label"
222   - :value="dict.value"
223   - />
224   - #else##没数据字典
225   - <el-checkbox label="请选择字典生成" />
226   - #end
227   - </el-checkbox-group>
228   - </el-form-item>
229   - #elseif($column.htmlType == "radio")## 单选框
230   - <el-form-item label="${comment}" prop="${javaField}">
231   - <el-radio-group v-model="formData.${javaField}">
232   - #if ("" != $dictType)## 有数据字典
233   - <el-radio
234   - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
235   - :key="dict.value"
236   - :label="dict.value"
237   - >
238   - {{ dict.label }}
239   - </el-radio>
240   - #else##没数据字典
241   - <el-radio value="1">请选择字典生成</el-radio>
242   - #end
243   - </el-radio-group>
244   - </el-form-item>
245   - #elseif($column.htmlType == "datetime")## 时间框
246   - <el-form-item label="${comment}" prop="${javaField}">
247   - <el-date-picker
248   - v-model="formData.${javaField}"
249   - type="date"
250   - value-format="x"
251   - placeholder="选择${comment}"
252   - />
253   - </el-form-item>
254   - #elseif($column.htmlType == "textarea")## 文本框
255   - <el-form-item label="${comment}" prop="${javaField}">
256   - <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
257   - </el-form-item>
258   - #end
259   - #end
260   -#end
261   - </el-form>
  7 +<script lang="ts" setup>
  8 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  9 +
  10 + import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  11 + import { $t } from '#/locales';
  12 +
  13 +#if ($subTable.subJoinMany) ## 一对多
  14 +import { Plus } from "@vben/icons";
  15 +import { Button, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  16 +import type { OnActionClickParams } from '#/adapter/vxe-table';
  17 +import { useVbenVxeGrid } from '#/adapter/vxe-table';
  18 +import { use${subSimpleClassName}GridColumns } from '../data';
  19 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  20 +#else
  21 +import { useVbenForm } from '#/adapter/form';
  22 +import { use${subSimpleClassName}FormSchema } from '../data';
  23 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
262 24 #end
263   -</template>
264   -<script setup lang="ts">
265   -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
266   -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
267 25  
268 26 const props = defineProps<{
269   - ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
  27 + ${subJoinColumn.javaField}?: any // ${subJoinColumn.columnComment}(主表的关联字段)
270 28 }>()
271   -const formLoading = ref(false) // 表单的加载中
272   -const formData = ref([])
273   -const formRules = reactive({
274   -#foreach ($column in $subColumns)
275   - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
276   - #set($comment=$column.columnComment)
277   - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
278   - #end
279   -#end
280   -})
281   -const formRef = ref() // 表单 Ref
282 29  
283   -/** 监听主表的关联字段的变化,加载对应的子表数据 */
284   -watch(
285   - () => props.${subJoinColumn.javaField},
286   - async (val) => {
287   - // 1. 重置表单
288   -#if ( $subTable.subJoinMany )
289   - formData.value = []
290   -#else
291   - formData.value = {
292   - #foreach ($column in $subColumns)
293   - #if ($column.createOperation || $column.updateOperation)
294   - #if ($column.htmlType == "checkbox")
295   - $column.javaField: [],
296   - #else
297   - $column.javaField: undefined,
298   - #end
299   - #end
300   - #end
301   - }
302   -#end
303   - // 2. val 非空,则加载数据
304   - if (!val) {
305   - return;
  30 +#if ($subTable.subJoinMany) ## 一对多
  31 +/** 表格操作按钮的回调函数 */
  32 +function onActionClick({
  33 + code,
  34 + row,
  35 +}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) {
  36 + switch (code) {
  37 + case 'delete': {
  38 + onDelete(row);
  39 + break;
306 40 }
307   - try {
308   - formLoading.value = true
309   -#if ( $subTable.subJoinMany )
310   - formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)
311   -#else
312   - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
313   - if (!data) {
314   - return
315   - }
316   - formData.value = data
317   -#end
318   - } finally {
319   - formLoading.value = false
320   - }
321   - },
322   - { immediate: true }
323   -)
324   -#if ( $subTable.subJoinMany )
325   -
326   -/** 新增按钮操作 */
327   -const handleAdd = () => {
328   - const row = {
329   -#foreach ($column in $subColumns)
330   - #if ($column.createOperation || $column.updateOperation)
331   - #if ($column.htmlType == "checkbox")
332   - $column.javaField: [],
333   - #else
334   - $column.javaField: undefined,
335   - #end
336   - #end
337   -#end
338 41 }
339   - row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}
340   - formData.value.push(row)
341 42 }
342 43  
343   -/** 删除按钮操作 */
344   -const handleDelete = (index) => {
345   - formData.value.splice(index, 1)
346   -}
347   -#end
  44 +const [${subSimpleClassName}Grid, ${subClassNameVar}GridApi] = useVbenVxeGrid({
  45 +gridOptions: {
  46 + columns: use${subSimpleClassName}GridColumns(onActionClick),
  47 + border: true,
  48 + showOverflow: true,
  49 + autoResize: true,
  50 + keepSource: true,
  51 + rowConfig: {
  52 + keyField: 'id',
  53 + },
  54 + pagerConfig: {
  55 + enabled: false,
  56 + },
  57 + toolbarConfig: {
  58 + enabled: false,
  59 + },
  60 +},
  61 +});
348 62  
349   -/** 表单校验 */
350   -const validate = () => {
351   - return formRef.value.validate()
  63 +/** 删除${subTable.classComment} */
  64 +const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
  65 + await ${subClassNameVar}GridApi.grid.remove(row);
352 66 }
353 67  
354   -/** 表单值 */
355   -const getData = () => {
356   - return formData.value
  68 +/** 添加${subTable.classComment} */
  69 +const handleAdd = async () => {
  70 + await ${subClassNameVar}GridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
357 71 }
358 72  
359   -defineExpose({ validate, getData })
360   -</script>
361 73 \ No newline at end of file
  74 +/** 提供获取表格数据的方法供父组件调用 */
  75 +defineExpose({
  76 + getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
  77 + return [
  78 + ...${subClassNameVar}GridApi.grid.getData(),
  79 + ...${subClassNameVar}GridApi.grid.getInsertRecords().map((row) => {
  80 + delete row.id;
  81 + return row;
  82 + }),
  83 + ];
  84 + },
  85 +});
  86 +
  87 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  88 +watch(
  89 + () => props.${subJoinColumn.javaField},
  90 + async (val) => {
  91 + if (!val) {
  92 + return;
  93 + }
  94 +
  95 + await nextTick();
  96 + await ${subClassNameVar}GridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  97 + },
  98 +);
  99 +#else
  100 +const [${subSimpleClassName}Form, ${subClassNameVar}FormApi] = useVbenForm({
  101 +layout: 'horizontal',
  102 +schema: use${subSimpleClassName}FormSchema(),
  103 +showDefaultActions: false
  104 +});
  105 +
  106 +/** 暴露出表单校验方法和表单值获取方法 */
  107 +defineExpose({
  108 + validate: async () => {
  109 + const { valid } = await ${subClassNameVar}FormApi.validate();
  110 + return valid;
  111 + },
  112 + getValues: ${subClassNameVar}FormApi.getValues,
  113 +});
  114 +
  115 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  116 +watch(
  117 + () => props.${subJoinColumn.javaField},
  118 + async (val) => {
  119 + if (!val) {
  120 + return;
  121 + }
  122 +
  123 + await nextTick();
  124 + await ${subClassNameVar}FormApi.setValues(await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  125 + },
  126 +);
  127 +#end
  128 +</script>
  129 +
  130 +<template>
  131 +#if ($subTable.subJoinMany) ## 一对多
  132 + <${subSimpleClassName}Grid class="mx-4">
  133 + #foreach($column in $subColumns)
  134 + #if ($column.createOperation || $column.updateOperation)
  135 + #set ($javaField = $column.javaField)
  136 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  137 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  138 + <template #${javaField}="{ row }">
  139 + <Input v-model:value="row.${javaField}" />
  140 + </template>
  141 + #elseif($column.htmlType == "imageUpload")## 图片上传
  142 + <template #${javaField}="{ row }">
  143 + <UploadImg v-model:value="row.${javaField}" />
  144 + </template>
  145 + #elseif($column.htmlType == "fileUpload")## 文件上传
  146 + <template #${javaField}="{ row }">
  147 + <UploadFile v-model:value="row.${javaField}" />
  148 + </template>
  149 + #elseif($column.htmlType == "editor")## 文本编辑器
  150 + <template #${javaField}="{ row }">
  151 + <Textarea v-model:value="row.${javaField}" />
  152 + </template>
  153 + #elseif($column.htmlType == "select")## 下拉框
  154 + <template #${javaField}="{ row, column }">
  155 + <Select v-model:value="row.${javaField}" class="w-full">
  156 + <Select.Option v-for="option in column.params.options" :key="option.value" :value="option.value">
  157 + {{ option.label }}
  158 + </Select.Option>
  159 + </Select>
  160 + </template>
  161 + #elseif($column.htmlType == "checkbox")## 多选框
  162 + <template #${javaField}="{ row, column }">
  163 + <CheckboxGroup v-model:value="row.${javaField}" :options="column.params.options" />
  164 + </template>
  165 + #elseif($column.htmlType == "radio")## 单选框
  166 + <template #${javaField}="{ row, column }">
  167 + <RadioGroup v-model:value="row.${javaField}" :options="column.params.options" />
  168 + </template>
  169 + #elseif($column.htmlType == "datetime")## 时间框
  170 + <template #${javaField}="{ row }">
  171 + <DatePicker
  172 + v-model:value="row.${javaField}"
  173 + :showTime="true"
  174 + format="YYYY-MM-DD HH:mm:ss"
  175 + valueFormat='x'
  176 + />
  177 + </template>
  178 + #elseif($column.htmlType == "textarea")## 文本框
  179 + <template #${javaField}="{ row }">
  180 + <Textarea v-model:value="row.${javaField}" />
  181 + </template>
  182 + #end
  183 + #end
  184 + #end
  185 + </${subSimpleClassName}Grid>
  186 + <div class="flex justify-center">
  187 + <Button :icon="h(Plus)" type="primary" ghost @click="handleAdd" v-access:code="['${subTable.moduleName}:${simpleClassName_strikeCase}:create']">
  188 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  189 + </Button>
  190 + </div>
  191 +#else
  192 + <${subSimpleClassName}Form class="mx-4" />
  193 +#end
  194 +</template>
... ...