Commit 8b70307ae75580f3585d2f0c7309022861d8f00b

Authored by 芋道源码
Committed by Gitee
2 parents 5af9496d c6582b2a

!1336 【功能完善】INFRA:代码生成 vben5 antd 树表、主子表模版

Merge pull request !1336 from puhui999/master-jdk17
Showing 13 changed files with 860 additions and 655 deletions
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -164,8 +164,6 @@ public class CodegenEngine { @@ -164,8 +164,6 @@ public class CodegenEngine {
164 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 164 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
165 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) 165 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
166 // VUE3_VBEN5_ANTD 166 // VUE3_VBEN5_ANTD
167 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/data.ts"),  
168 - vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))  
169 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"), 167 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
170 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) 168 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
171 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"), 169 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/api/api.ts.vm
1 import type { PageParam, PageResult } from '@vben/request'; 1 import type { PageParam, PageResult } from '@vben/request';
  2 +import type { Dayjs } from 'dayjs';
2 3
3 import { requestClient } from '#/api/request'; 4 import { requestClient } from '#/api/request';
4 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}") 5 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
@@ -16,7 +17,7 @@ export namespace ${simpleClassName}Api { @@ -16,7 +17,7 @@ export namespace ${simpleClassName}Api {
16 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") 17 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
17 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment} 18 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
18 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime") 19 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
19 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment} 20 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
20 #else 21 #else
21 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment} 22 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
22 #end 23 #end
@@ -32,7 +33,7 @@ export namespace ${simpleClassName}Api { @@ -32,7 +33,7 @@ export namespace ${simpleClassName}Api {
32 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") 33 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
33 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment} 34 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
34 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime") 35 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
35 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment} 36 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
36 #else 37 #else
37 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment} 38 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
38 #end 39 #end
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/data.ts.vm deleted
1 -import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';  
2 -import type { VbenFormSchema } from '#/adapter/form';  
3 -import type { OnActionClickFn } from '#/adapter/vxe-table';  
4 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
5 -  
6 -import { z } from '#/adapter/form';  
7 -#if(${table.templateType} == 2)## 树表需要导入这些  
8 -import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
9 -import { handleTree } from '#/utils/tree';  
10 -#end  
11 -import { DICT_TYPE, getDictOptions } from '#/utils/dict';  
12 -import { getRangePickerDefaultProps } from '#/utils/date';  
13 -import { useAccess } from '@vben/access';  
14 -  
15 -const { hasAccessByCodes } = useAccess();  
16 -  
17 -/** 列表的搜索表单 */  
18 -export function useGridFormSchema(): VbenFormSchema[] {  
19 - return [  
20 -#foreach($column in $columns)  
21 -#if ($column.listOperation)  
22 - #set ($dictType = $column.dictType)  
23 - #set ($javaType = $column.javaType)  
24 - #set ($javaField = $column.javaField)  
25 - #set ($comment = $column.columnComment)  
26 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
27 - #set ($dictMethod = "number")  
28 - #elseif ($javaType == "String")  
29 - #set ($dictMethod = "string")  
30 - #elseif ($javaType == "Boolean")  
31 - #set ($dictMethod = "boolean")  
32 - #end  
33 - {  
34 - fieldName: '${javaField}',  
35 - label: '${comment}',  
36 - #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")  
37 - component: 'Input',  
38 - componentProps: {  
39 - allowClear: true,  
40 - placeholder: '请输入${comment}',  
41 - },  
42 - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")  
43 - component: 'Select',  
44 - componentProps: {  
45 - allowClear: true,  
46 - #if ("" != $dictType)## 设置了 dictType 数据字典的情况  
47 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),  
48 - #else## 未设置 dictType 数据字典的情况  
49 - options: [],  
50 - #end  
51 - placeholder: '请选择${comment}',  
52 - },  
53 - #elseif($column.htmlType == "datetime")  
54 - component: 'RangePicker',  
55 - componentProps: {  
56 - ...getRangePickerDefaultProps(),  
57 - allowClear: true,  
58 - },  
59 - #end  
60 - },  
61 -#end  
62 -#end  
63 - ];  
64 -}  
65 -  
66 -/** 列表的字段 */  
67 -export function useGridColumns(  
68 - onActionClick?: OnActionClickFn<${simpleClassName}Api.${simpleClassName}>,  
69 -): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] {  
70 - return [  
71 -#if ($table.templateType == 12) ## 内嵌情况  
72 - { type: 'expand', width: 80, slots: { content: 'expand_content' } },  
73 -#end  
74 -#foreach($column in $columns)  
75 -#if ($column.listOperationResult)  
76 - #set ($dictType = $column.dictType)  
77 - #set ($javaField = $column.javaField)  
78 - #set ($comment = $column.columnComment)  
79 - {  
80 - field: '${javaField}',  
81 - title: '${comment}',  
82 - minWidth: 120,  
83 - #if ($column.javaType == "LocalDateTime")## 时间类型  
84 - formatter: 'formatDateTime',  
85 - #elseif("" != $dictType)## 数据字典  
86 - cellRender: {  
87 - name: 'CellDict',  
88 - props: { type: DICT_TYPE.$dictType.toUpperCase() },  
89 - },  
90 - #end  
91 - #if (${table.templateType} == 2 && $column.id == $treeNameColumn.id)## 树表特有:标记树节点列  
92 - treeNode: true,  
93 - #end  
94 - },  
95 -#end  
96 -#end  
97 - {  
98 - field: 'operation',  
99 - title: '操作',  
100 - minWidth: 200,  
101 - align: 'center',  
102 - fixed: 'right',  
103 - headerAlign: 'center',  
104 - showOverflow: false,  
105 - cellRender: {  
106 - attrs: {  
107 - nameField: '${columns[0].javaField}',  
108 - nameTitle: '${table.classComment}',  
109 - onClick: onActionClick,  
110 - },  
111 - name: 'CellOperation',  
112 - options: [  
113 -#if (${table.templateType} == 2)## 树表特有操作  
114 - {  
115 - code: 'append',  
116 - text: '新增下级',  
117 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:create']),  
118 - },  
119 -#end  
120 - {  
121 - code: 'edit',  
122 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),  
123 - },  
124 - {  
125 - code: 'delete',  
126 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),  
127 -#if (${table.templateType} == 2)## 树表禁止删除带有子节点的数据  
128 - disabled: (row: ${simpleClassName}Api.${simpleClassName}) => {  
129 - return !!(row.children && row.children.length > 0);  
130 - },  
131 -#end  
132 - },  
133 - ],  
134 - },  
135 - },  
136 - ];  
137 -}  
138 -  
139 -## 标准模式和内嵌模式时,主子关系一对一则生成表单schema,一对多则生成列表schema(内嵌模式时表单schema也要生成)。erp 模式时都生成  
140 -## 特殊:主子表专属逻辑  
141 -#foreach ($subTable in $subTables)  
142 - #set ($index = $foreach.count - 1)  
143 - #set ($subColumns = $subColumnsList.get($index))##当前字段数组  
144 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
145 - #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段  
146 - #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))  
147 -// ==================== 子表($subTable.classComment) ====================  
148 -  
149 -#if ($table.templateType == 11) ## erp 情况  
150 -/** 列表的搜索表单 */  
151 -export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {  
152 - return [  
153 - #foreach($column in $subColumns)  
154 - #if ($column.listOperation)  
155 - #set ($dictType = $column.dictType)  
156 - #set ($javaType = $column.javaType)  
157 - #set ($javaField = $column.javaField)  
158 - #set ($comment = $column.columnComment)  
159 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
160 - #set ($dictMethod = "number")  
161 - #elseif ($javaType == "String")  
162 - #set ($dictMethod = "string")  
163 - #elseif ($javaType == "Boolean")  
164 - #set ($dictMethod = "boolean")  
165 - #end  
166 - {  
167 - fieldName: '${javaField}',  
168 - label: '${comment}',  
169 - #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")  
170 - component: 'Input',  
171 - componentProps: {  
172 - allowClear: true,  
173 - placeholder: '请输入${comment}',  
174 - },  
175 - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")  
176 - component: 'Select',  
177 - componentProps: {  
178 - allowClear: true,  
179 - #if ("" != $dictType)## 设置了 dictType 数据字典的情况  
180 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),  
181 - #else## 未设置 dictType 数据字典的情况  
182 - options: [],  
183 - #end  
184 - placeholder: '请选择${comment}',  
185 - },  
186 - #elseif($column.htmlType == "datetime")  
187 - component: 'RangePicker',  
188 - componentProps: {  
189 - ...getRangePickerDefaultProps(),  
190 - allowClear: true,  
191 - },  
192 - #end  
193 - },  
194 - #end  
195 - #end  
196 - ];  
197 -}  
198 -  
199 -/** 列表的字段 */  
200 -export function use${subSimpleClassName}GridColumns(  
201 - onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,  
202 -): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {  
203 - return [  
204 - #foreach($column in $subColumns)  
205 - #if ($column.listOperationResult)  
206 - #set ($dictType = $column.dictType)  
207 - #set ($javaField = $column.javaField)  
208 - #set ($comment = $column.columnComment)  
209 - {  
210 - field: '${javaField}',  
211 - title: '${comment}',  
212 - minWidth: 120,  
213 - #if ($column.javaType == "LocalDateTime")## 时间类型  
214 - formatter: 'formatDateTime',  
215 - #elseif("" != $dictType)## 数据字典  
216 - cellRender: {  
217 - name: 'CellDict',  
218 - props: { type: DICT_TYPE.$dictType.toUpperCase() },  
219 - },  
220 - #end  
221 - },  
222 - #end  
223 - #end  
224 - {  
225 - field: 'operation',  
226 - title: '操作',  
227 - minWidth: 200,  
228 - align: 'center',  
229 - fixed: 'right',  
230 - headerAlign: 'center',  
231 - showOverflow: false,  
232 - cellRender: {  
233 - attrs: {  
234 - nameField: '${columns[0].javaField}',  
235 - nameTitle: '${subTable.classComment}',  
236 - onClick: onActionClick,  
237 - },  
238 - name: 'CellOperation',  
239 - options: [  
240 - {  
241 - code: 'edit',  
242 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),  
243 - },  
244 - {  
245 - code: 'delete',  
246 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),  
247 - },  
248 - ],  
249 - },  
250 - },  
251 - ];  
252 -}  
253 -  
254 -#else  
255 - #if ($subTable.subJoinMany) ## 一对多  
256 - /** 新增/修改列表的字段 */  
257 - export function use${subSimpleClassName}GridEditColumns(  
258 - onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,  
259 - ): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {  
260 - return [  
261 - #foreach($column in $subColumns)  
262 - #if ($column.createOperation || $column.updateOperation)  
263 - #if (!$column.primaryKey && $column.listOperationResult && $column.id != $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
264 - #set ($dictType = $column.dictType)  
265 - #set ($javaField = $column.javaField)  
266 - #set ($comment = $column.columnComment)  
267 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
268 - #set ($dictMethod = "number")  
269 - #elseif ($javaType == "String")  
270 - #set ($dictMethod = "string")  
271 - #elseif ($javaType == "Boolean")  
272 - #set ($dictMethod = "boolean")  
273 - #end  
274 - {  
275 - field: '${javaField}',  
276 - title: '${comment}',  
277 - minWidth: 120,  
278 - slots: { default: '${javaField}' },  
279 - #if ($column.htmlType == "select" || $column.htmlType == "checkbox" || $column.htmlType == "radio")  
280 - #if ("" != $dictType)## 有数据字典  
281 - params: {  
282 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),  
283 - },  
284 - #else  
285 - params: {  
286 - options: [],  
287 - },  
288 - #end  
289 - #end  
290 - },  
291 - #end  
292 - #end  
293 - #end  
294 - {  
295 - field: 'operation',  
296 - title: '操作',  
297 - minWidth: 60,  
298 - align: 'center',  
299 - fixed: 'right',  
300 - headerAlign: 'center',  
301 - showOverflow: false,  
302 - cellRender: {  
303 - attrs: {  
304 - nameField: '${columns[0].javaField}',  
305 - nameTitle: '${table.classComment}',  
306 - onClick: onActionClick,  
307 - },  
308 - name: 'CellOperation',  
309 - options: [  
310 - {  
311 - code: 'delete',  
312 - show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),  
313 - },  
314 - ],  
315 - },  
316 - },  
317 - ];  
318 - }  
319 - #end  
320 - #if ($table.templateType == 12) ## 内嵌情况  
321 - /** 列表的字段 */  
322 - export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {  
323 - return [  
324 - #foreach($column in $subColumns)  
325 - #if ($column.listOperationResult)  
326 - #set ($dictType = $column.dictType)  
327 - #set ($javaField = $column.javaField)  
328 - #set ($comment = $column.columnComment)  
329 - {  
330 - field: '${javaField}',  
331 - title: '${comment}',  
332 - minWidth: 120,  
333 - #if ($column.javaType == "LocalDateTime")## 时间类型  
334 - formatter: 'formatDateTime',  
335 - #elseif("" != $dictType)## 数据字典  
336 - cellRender: {  
337 - name: 'CellDict',  
338 - props: { type: DICT_TYPE.$dictType.toUpperCase() },  
339 - },  
340 - #end  
341 - },  
342 - #end  
343 - #end  
344 - ];  
345 - }  
346 -  
347 - #end  
348 -#end  
349 -#end  
350 \ No newline at end of file 0 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm
@@ -5,11 +5,11 @@ import type { Rule } from &#39;ant-design-vue/es/form&#39;; @@ -5,11 +5,11 @@ import type { Rule } from &#39;ant-design-vue/es/form&#39;;
5 import { useVbenModal } from '@vben/common-ui'; 5 import { useVbenModal } from '@vben/common-ui';
6 import { Tinymce as RichTextarea } from '#/components/tinymce'; 6 import { Tinymce as RichTextarea } from '#/components/tinymce';
7 import { ImageUpload, FileUpload } from "#/components/upload"; 7 import { ImageUpload, FileUpload } from "#/components/upload";
8 -import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue'; 8 +import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
9 import { DICT_TYPE, getDictOptions } from '#/utils/dict'; 9 import { DICT_TYPE, getDictOptions } from '#/utils/dict';
10 #if($table.templateType == 2)## 树表需要导入这些 10 #if($table.templateType == 2)## 树表需要导入这些
11 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 11 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
12 -import { handleTree } from '#/utils/tree'; 12 +import { handleTree } from '@vben/utils'
13 #end 13 #end
14 ## 特殊:主子表专属逻辑 14 ## 特殊:主子表专属逻辑
15 #if ( $table.templateType == 10 || $table.templateType == 12 ) 15 #if ( $table.templateType == 10 || $table.templateType == 12 )
@@ -25,9 +25,8 @@ import { $t } from &#39;#/locales&#39;; @@ -25,9 +25,8 @@ import { $t } from &#39;#/locales&#39;;
25 import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 25 import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
26 26
27 const emit = defineEmits(['success']); 27 const emit = defineEmits(['success']);
  28 +
28 const formRef = ref(); 29 const formRef = ref();
29 -const labelCol = { span: 5 };  
30 -const wrapperCol = { span: 13 };  
31 const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({ 30 const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({
32 #foreach ($column in $columns) 31 #foreach ($column in $columns)
33 #if ($column.createOperation || $column.updateOperation) 32 #if ($column.createOperation || $column.updateOperation)
@@ -91,10 +90,12 @@ const resetForm = () =&gt; { @@ -91,10 +90,12 @@ const resetForm = () =&gt; {
91 /** 获得${table.classComment}树 */ 90 /** 获得${table.classComment}树 */
92 const get${simpleClassName}Tree = async () => { 91 const get${simpleClassName}Tree = async () => {
93 ${classNameVar}Tree.value = [] 92 ${classNameVar}Tree.value = []
94 - const data = await get${simpleClassName}List()  
95 - const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }  
96 - root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')  
97 - ${classNameVar}Tree.value.push(root) 93 + const data = await get${simpleClassName}List({});
  94 + data.unshift({
  95 + id: 0,
  96 + name: '顶级${table.classComment}',
  97 + });
  98 + ${classNameVar}Tree.value = handleTree(data);
98 } 99 }
99 #end 100 #end
100 101
@@ -111,10 +112,11 @@ const [Modal, modalApi] = useVbenModal({ @@ -111,10 +112,11 @@ const [Modal, modalApi] = useVbenModal({
111 #if ($subTable.subJoinMany) ## 一对多 112 #if ($subTable.subJoinMany) ## 一对多
112 ## TODO 列表值校验? 113 ## TODO 列表值校验?
113 #else 114 #else
114 - const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();  
115 - if (!${subClassNameVar}Valid) {  
116 - subTabsName.value = '${subClassNameVar}';  
117 - return; 115 + try {
  116 + await ${subClassNameVar}FormRef.value?.validate()
  117 + } catch (e) {
  118 + subTabsName.value = '${subClassNameVar}'
  119 + return
118 } 120 }
119 #end 121 #end
120 #end 122 #end
@@ -133,7 +135,7 @@ const [Modal, modalApi] = useVbenModal({ @@ -133,7 +135,7 @@ const [Modal, modalApi] = useVbenModal({
133 #if ($subTable.subJoinMany) 135 #if ($subTable.subJoinMany)
134 data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData(); 136 data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
135 #else 137 #else
136 - data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues(); 138 + data.${subClassNameVar} = ${subClassNameVar}FormRef.value?.getValues();
137 #end 139 #end
138 #end 140 #end
139 #end 141 #end
@@ -156,7 +158,6 @@ const [Modal, modalApi] = useVbenModal({ @@ -156,7 +158,6 @@ const [Modal, modalApi] = useVbenModal({
156 resetForm() 158 resetForm()
157 return; 159 return;
158 } 160 }
159 -  
160 // 加载数据 161 // 加载数据
161 let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>(); 162 let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
162 if (!data) { 163 if (!data) {
@@ -185,8 +186,8 @@ const [Modal, modalApi] = useVbenModal({ @@ -185,8 +186,8 @@ const [Modal, modalApi] = useVbenModal({
185 ref="formRef" 186 ref="formRef"
186 :model="formData" 187 :model="formData"
187 :rules="rules" 188 :rules="rules"
188 - :label-col="labelCol"  
189 - :wrapper-col="wrapperCol" 189 + :label-col="{ span: 5 }"
  190 + :wrapper-col="{ span: 18 }"
190 > 191 >
191 #foreach($column in $columns) 192 #foreach($column in $columns)
192 #if ($column.createOperation || $column.updateOperation) 193 #if ($column.createOperation || $column.updateOperation)
@@ -207,9 +208,17 @@ const [Modal, modalApi] = useVbenModal({ @@ -207,9 +208,17 @@ const [Modal, modalApi] = useVbenModal({
207 v-model:value="formData.${javaField}" 208 v-model:value="formData.${javaField}"
208 :treeData="${classNameVar}Tree" 209 :treeData="${classNameVar}Tree"
209 #if ($treeNameColumn.javaField == "name") 210 #if ($treeNameColumn.javaField == "name")
210 - :fieldNames="defaultProps" 211 + :fieldNames="{
  212 + label: 'name',
  213 + value: 'id',
  214 + children: 'children',
  215 + }"
211 #else 216 #else
212 - :fieldNames="{...defaultProps, label: '$treeNameColumn.javaField'}" 217 + :fieldNames="{
  218 + label: '$treeNameColumn.javaField',
  219 + value: 'id',
  220 + children: 'children',
  221 + }"
213 #end 222 #end
214 checkable 223 checkable
215 treeDefaultExpandAll 224 treeDefaultExpandAll
@@ -239,9 +248,10 @@ const [Modal, modalApi] = useVbenModal({ @@ -239,9 +248,10 @@ const [Modal, modalApi] = useVbenModal({
239 <Select.Option 248 <Select.Option
240 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')" 249 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
241 :key="dict.value" 250 :key="dict.value"
242 - :label="dict.label"  
243 :value="dict.value" 251 :value="dict.value"
244 - /> 252 + >
  253 + {{ dict.label }}
  254 + </Select.Option>
245 #else##没数据字典 255 #else##没数据字典
246 <Select.Option label="请选择字典生成" value="" /> 256 <Select.Option label="请选择字典生成" value="" />
247 #end 257 #end
@@ -254,9 +264,10 @@ const [Modal, modalApi] = useVbenModal({ @@ -254,9 +264,10 @@ const [Modal, modalApi] = useVbenModal({
254 <Checkbox 264 <Checkbox
255 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')" 265 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
256 :key="dict.value" 266 :key="dict.value"
257 - :label="dict.label"  
258 :value="dict.value" 267 :value="dict.value"
259 - /> 268 + >
  269 + {{ dict.label }}
  270 + </Checkbox>
260 #else##没数据字典 271 #else##没数据字典
261 <Checkbox label="请选择字典生成" /> 272 <Checkbox label="请选择字典生成" />
262 #end 273 #end
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +import type { VxeTableInstance } from 'vxe-table';
3 4
4 import { Page, useVbenModal } from '@vben/common-ui'; 5 import { Page, useVbenModal } from '@vben/common-ui';
5 -import { formatDateTime } from '@vben/utils'; 6 +import { cloneDeep, formatDateTime } from '@vben/utils';
6 import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue'; 7 import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue';
7 import { DictTag } from '#/components/dict-tag'; 8 import { DictTag } from '#/components/dict-tag';
8 import { DICT_TYPE, getDictOptions } from '#/utils/dict'; 9 import { DICT_TYPE, getDictOptions } from '#/utils/dict';
@@ -10,6 +11,7 @@ import ${simpleClassName}Form from &#39;./modules/form.vue&#39;; @@ -10,6 +11,7 @@ import ${simpleClassName}Form from &#39;./modules/form.vue&#39;;
10 import { Download, Plus, RefreshCw, Search } from '@vben/icons'; 11 import { Download, Plus, RefreshCw, Search } from '@vben/icons';
11 import { ContentWrap } from "#/components/content-wrap"; 12 import { ContentWrap } from "#/components/content-wrap";
12 import { VxeColumn, VxeTable } from 'vxe-table'; 13 import { VxeColumn, VxeTable } from 'vxe-table';
  14 +import { TableToolbar } from '#/components/table-toolbar';
13 import { getRangePickerDefaultProps } from '#/utils/date'; 15 import { getRangePickerDefaultProps } from '#/utils/date';
14 16
15 ## 特殊:主子表专属逻辑 17 ## 特殊:主子表专属逻辑
@@ -21,10 +23,10 @@ import { getRangePickerDefaultProps } from &#39;#/utils/date&#39;; @@ -21,10 +23,10 @@ import { getRangePickerDefaultProps } from &#39;#/utils/date&#39;;
21 #end 23 #end
22 #end 24 #end
23 25
24 -import { ref, h, reactive,onMounted } from 'vue'; 26 +import { ref, h, reactive,onMounted,nextTick } from 'vue';
25 import { $t } from '#/locales'; 27 import { $t } from '#/locales';
26 #if (${table.templateType} == 2)## 树表接口 28 #if (${table.templateType} == 2)## 树表接口
27 -import { handleTree } from '@/utils/tree' 29 +import { handleTree,isEmpty } from '@vben/utils'
28 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 30 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
29 #else## 标准表接口 31 #else## 标准表接口
30 import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 32 import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
@@ -36,11 +38,19 @@ import { downloadByData } from &#39;#/utils/download&#39;; @@ -36,11 +38,19 @@ import { downloadByData } from &#39;#/utils/download&#39;;
36 const subTabsName = ref('$subClassNameVars.get(0)') 38 const subTabsName = ref('$subClassNameVars.get(0)')
37 #if ($table.templateType == 11) 39 #if ($table.templateType == 11)
38 const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>(); 40 const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
  41 +async function onCellClick({ row }: { row: ${simpleClassName}Api.${simpleClassName} }) {
  42 + select${simpleClassName}.value = row
  43 +}
39 #end 44 #end
40 #end 45 #end
41 46
42 const loading = ref(true) // 列表的加载中 47 const loading = ref(true) // 列表的加载中
  48 +#if ( $table.templateType == 2 )
  49 +const list = ref<any[]>([]) // 树列表的数据
  50 +#else
43 const list = ref<${simpleClassName}Api.${simpleClassName}[]>([]) // 列表的数据 51 const list = ref<${simpleClassName}Api.${simpleClassName}[]>([]) // 列表的数据
  52 +#end
  53 +
44 ## 特殊:树表专属逻辑(树不需要分页接口) 54 ## 特殊:树表专属逻辑(树不需要分页接口)
45 #if ( $table.templateType != 2 ) 55 #if ( $table.templateType != 2 )
46 const total = ref(0) // 列表的总页数 56 const total = ref(0) // 列表的总页数
@@ -69,12 +79,21 @@ const exportLoading = ref(false) // 导出的加载中 @@ -69,12 +79,21 @@ const exportLoading = ref(false) // 导出的加载中
69 const getList = async () => { 79 const getList = async () => {
70 loading.value = true 80 loading.value = true
71 try { 81 try {
  82 + const params = cloneDeep(queryParams) as any;
  83 + #foreach ($column in $columns)
  84 + #if ($column.listOperation)
  85 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  86 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  87 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  88 + }
  89 + #end
  90 + #end
  91 + #end
72 ## 特殊:树表专属逻辑(树不需要分页接口) 92 ## 特殊:树表专属逻辑(树不需要分页接口)
73 #if ( $table.templateType == 2 ) 93 #if ( $table.templateType == 2 )
74 - const data = await get${simpleClassName}List(queryParams)  
75 - list.value = handleTree(data, 'id', '${treeParentColumn.javaField}') 94 + list.value = await get${simpleClassName}List(params);
76 #else 95 #else
77 - const data = await get${simpleClassName}Page(queryParams) 96 + const data = await get${simpleClassName}Page(params)
78 list.value = data.list 97 list.value = data.list
79 total.value = data.total 98 total.value = data.total
80 #end 99 #end
@@ -85,7 +104,9 @@ const getList = async () =&gt; { @@ -85,7 +104,9 @@ const getList = async () =&gt; {
85 104
86 /** 搜索按钮操作 */ 105 /** 搜索按钮操作 */
87 const handleQuery = () => { 106 const handleQuery = () => {
  107 +#if ( $table.templateType != 2 )
88 queryParams.pageNo = 1 108 queryParams.pageNo = 1
  109 +#end
89 getList() 110 getList()
90 } 111 }
91 112
@@ -147,20 +168,40 @@ try { @@ -147,20 +168,40 @@ try {
147 } 168 }
148 } 169 }
149 170
150 -/** 初始化 **/  
151 -onMounted(() => {  
152 - getList()  
153 -}) 171 +/** 隐藏搜索栏 */
  172 +const hiddenSearchBar = ref(false);
  173 +const tableToolbarRef = ref<InstanceType<typeof TableToolbar>>();
  174 +const tableRef = ref<VxeTableInstance>();
  175 +
  176 +#if (${table.templateType} == 2)
  177 +/** 切换树形展开/收缩状态 */
  178 +const isExpanded = ref(true);
  179 +function toggleExpand() {
  180 + isExpanded.value = !isExpanded.value;
  181 + tableRef.value?.setAllTreeExpand(isExpanded.value);
  182 +}
  183 +#end
  184 +
  185 +/** 初始化 */
  186 +onMounted(async () => {
  187 + await getList();
  188 + await nextTick();
  189 + // 挂载 toolbar 工具栏
  190 + const table = tableRef.value;
  191 + const tableToolbar = tableToolbarRef.value;
  192 + if (table && tableToolbar) {
  193 + await table.connect(tableToolbar.getToolbarRef()!);
  194 + }
  195 +});
154 </script> 196 </script>
155 197
156 <template> 198 <template>
157 <Page auto-content-height> 199 <Page auto-content-height>
158 <FormModal @success="getList" /> 200 <FormModal @success="getList" />
159 201
160 - <ContentWrap> 202 + <ContentWrap v-if="!hiddenSearchBar">
161 <!-- 搜索工作栏 --> 203 <!-- 搜索工作栏 -->
162 <Form 204 <Form
163 - class="-mb-15px"  
164 :model="queryParams" 205 :model="queryParams"
165 ref="queryFormRef" 206 ref="queryFormRef"
166 layout="inline" 207 layout="inline"
@@ -185,7 +226,7 @@ onMounted(() =&gt; { @@ -185,7 +226,7 @@ onMounted(() =&gt; {
185 placeholder="请输入${comment}" 226 placeholder="请输入${comment}"
186 allowClear 227 allowClear
187 @pressEnter="handleQuery" 228 @pressEnter="handleQuery"
188 - class="!w-240px" 229 + class="w-full"
189 /> 230 />
190 </Form.Item> 231 </Form.Item>
191 #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox") 232 #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
@@ -194,15 +235,16 @@ onMounted(() =&gt; { @@ -194,15 +235,16 @@ onMounted(() =&gt; {
194 v-model:value="queryParams.${javaField}" 235 v-model:value="queryParams.${javaField}"
195 placeholder="请选择${comment}" 236 placeholder="请选择${comment}"
196 allowClear 237 allowClear
197 - class="!w-240px" 238 + class="w-full"
198 > 239 >
199 #if ("" != $dictType)## 设置了 dictType 数据字典的情况 240 #if ("" != $dictType)## 设置了 dictType 数据字典的情况
200 <Select.Option 241 <Select.Option
201 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')" 242 v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
202 :key="dict.value" 243 :key="dict.value"
203 - :label="dict.label"  
204 :value="dict.value" 244 :value="dict.value"
205 - /> 245 + >
  246 + {{ dict.label }}
  247 + </Select.Option>
206 #else## 未设置 dictType 数据字典的情况 248 #else## 未设置 dictType 数据字典的情况
207 <Select.Option label="请选择字典生成" value="" /> 249 <Select.Option label="请选择字典生成" value="" />
208 #end 250 #end
@@ -216,7 +258,7 @@ onMounted(() =&gt; { @@ -216,7 +258,7 @@ onMounted(() =&gt; {
216 valueFormat="YYYY-MM-DD" 258 valueFormat="YYYY-MM-DD"
217 placeholder="选择${comment}" 259 placeholder="选择${comment}"
218 allowClear 260 allowClear
219 - class="!w-240px" 261 + class="w-full"
220 /> 262 />
221 </Form.Item> 263 </Form.Item>
222 #else## 范围 264 #else## 范围
@@ -224,7 +266,7 @@ onMounted(() =&gt; { @@ -224,7 +266,7 @@ onMounted(() =&gt; {
224 <RangePicker 266 <RangePicker
225 v-model:value="queryParams.${javaField}" 267 v-model:value="queryParams.${javaField}"
226 v-bind="getRangePickerDefaultProps()" 268 v-bind="getRangePickerDefaultProps()"
227 - class="!w-220px" 269 + class="w-full"
228 /> 270 />
229 </Form.Item> 271 </Form.Item>
230 #end 272 #end
@@ -232,8 +274,26 @@ onMounted(() =&gt; { @@ -232,8 +274,26 @@ onMounted(() =&gt; {
232 #end 274 #end
233 #end 275 #end
234 <Form.Item> 276 <Form.Item>
235 - <Button class="ml-2" @click="handleQuery" :icon="h(Search)">搜索</Button>  
236 - <Button class="ml-2" @click="resetQuery" :icon="h(RefreshCw)">重置</Button> 277 + <Button class="ml-2" @click="resetQuery"> 重置 </Button>
  278 + <Button class="ml-2" @click="handleQuery" type="primary">
  279 + 搜索
  280 + </Button>
  281 + </Form.Item>
  282 + </Form>
  283 + </ContentWrap>
  284 +
  285 + <!-- 列表 -->
  286 + <ContentWrap title="${table.classComment}">
  287 + <template #extra>
  288 + <TableToolbar
  289 + ref="tableToolbarRef"
  290 + v-model:hidden-search="hiddenSearchBar"
  291 + >
  292 + #if (${table.templateType} == 2)
  293 + <Button @click="toggleExpand" class="mr-2">
  294 + {{ isExpanded ? '收缩' : '展开' }}
  295 + </Button>
  296 + #end
237 <Button 297 <Button
238 class="ml-2" 298 class="ml-2"
239 :icon="h(Plus)" 299 :icon="h(Plus)"
@@ -241,7 +301,7 @@ onMounted(() =&gt; { @@ -241,7 +301,7 @@ onMounted(() =&gt; {
241 @click="onCreate" 301 @click="onCreate"
242 v-access:code="['${permissionPrefix}:create']" 302 v-access:code="['${permissionPrefix}:create']"
243 > 303 >
244 - {{ $t('ui.actionTitle.create', ['示例联系人']) }} 304 + {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
245 </Button> 305 </Button>
246 <Button 306 <Button
247 :icon="h(Download)" 307 :icon="h(Download)"
@@ -253,13 +313,31 @@ onMounted(() =&gt; { @@ -253,13 +313,31 @@ onMounted(() =&gt; {
253 > 313 >
254 {{ $t('ui.actionTitle.export') }} 314 {{ $t('ui.actionTitle.export') }}
255 </Button> 315 </Button>
256 - </Form.Item>  
257 - </Form>  
258 - </ContentWrap>  
259 -  
260 - <!-- 列表 -->  
261 - <ContentWrap>  
262 - <vxe-table :data="list" show-overflow :loading="loading"> 316 + </TableToolbar>
  317 + </template>
  318 + <vxe-table
  319 + ref="tableRef"
  320 + :data="list"
  321 + #if ( $table.templateType == 2 )
  322 + :tree-config="{
  323 + parentField: '${treeParentColumn.javaField}',
  324 + rowField: 'id',
  325 + transform: true,
  326 + expandAll: true,
  327 + reserve: true,
  328 + }"
  329 + #end
  330 +#if ($table.templateType == 11) ## erp情况
  331 + @cell-click="onCellClick"
  332 + :row-config="{
  333 + keyField: 'id',
  334 + isHover: true,
  335 + isCurrent: true,
  336 + }"
  337 +#end
  338 + show-overflow
  339 + :loading="loading"
  340 + >
263 ## 特殊:主子表专属逻辑 341 ## 特殊:主子表专属逻辑
264 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 ) 342 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
265 <!-- 子表的列表 --> 343 <!-- 子表的列表 -->
@@ -298,6 +376,8 @@ onMounted(() =&gt; { @@ -298,6 +376,8 @@ onMounted(() =&gt; {
298 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" /> 376 <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
299 </template> 377 </template>
300 </vxe-column> 378 </vxe-column>
  379 + #elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
  380 + <vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
301 #else 381 #else
302 <vxe-column field="${javaField}" title="${comment}" align="center" /> 382 <vxe-column field="${javaField}" title="${comment}" align="center" />
303 #end 383 #end
@@ -305,6 +385,16 @@ onMounted(() =&gt; { @@ -305,6 +385,16 @@ onMounted(() =&gt; {
305 #end 385 #end
306 <vxe-column field="operation" title="操作" align="center"> 386 <vxe-column field="operation" title="操作" align="center">
307 <template #default="{row}"> 387 <template #default="{row}">
  388 +#if ( $table.templateType == 2 )
  389 + <Button
  390 + size="small"
  391 + type="link"
  392 + @click="onAppend(row as any)"
  393 + v-access:code="['${permissionPrefix}:create']"
  394 + >
  395 + 新增下级
  396 + </Button>
  397 +#end
308 <Button 398 <Button
309 size="small" 399 size="small"
310 type="link" 400 type="link"
@@ -316,7 +406,11 @@ onMounted(() =&gt; { @@ -316,7 +406,11 @@ onMounted(() =&gt; {
316 <Button 406 <Button
317 size="small" 407 size="small"
318 type="link" 408 type="link"
  409 + danger
319 class="ml-2" 410 class="ml-2"
  411 + #if ( $table.templateType == 2 )
  412 + :disabled="!isEmpty(row?.children)"
  413 + #end
320 @click="onDelete(row as any)" 414 @click="onDelete(row as any)"
321 v-access:code="['${permissionPrefix}:delete']" 415 v-access:code="['${permissionPrefix}:delete']"
322 > 416 >
@@ -325,6 +419,7 @@ onMounted(() =&gt; { @@ -325,6 +419,7 @@ onMounted(() =&gt; {
325 </template> 419 </template>
326 </vxe-column> 420 </vxe-column>
327 </vxe-table> 421 </vxe-table>
  422 +#if ( $table.templateType != 2 )
328 <!-- 分页 --> 423 <!-- 分页 -->
329 <div class="mt-2 flex justify-end"> 424 <div class="mt-2 flex justify-end">
330 <Pagination 425 <Pagination
@@ -335,6 +430,7 @@ onMounted(() =&gt; { @@ -335,6 +430,7 @@ onMounted(() =&gt; {
335 @change="getList" 430 @change="getList"
336 /> 431 />
337 </div> 432 </div>
  433 +#end
338 </ContentWrap> 434 </ContentWrap>
339 435
340 #if ($table.templateType == 11) ## erp情况 436 #if ($table.templateType == 11) ## erp情况
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm
@@ -4,49 +4,54 @@ @@ -4,49 +4,54 @@
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 <script lang="ts" setup> 5 <script lang="ts" setup>
6 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 6 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  7 + import type { Rule } from 'ant-design-vue/es/form';
7 8
8 import { useVbenModal } from '@vben/common-ui'; 9 import { useVbenModal } from '@vben/common-ui';
9 - import { message } from 'ant-design-vue'; 10 + import { Tinymce as RichTextarea } from '#/components/tinymce';
  11 + import { ImageUpload, FileUpload } from "#/components/upload";
  12 + import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
  13 + import { DICT_TYPE, getDictOptions } from '#/utils/dict';
10 14
11 import { computed, ref } from 'vue'; 15 import { computed, ref } from 'vue';
12 import { $t } from '#/locales'; 16 import { $t } from '#/locales';
13 - import { useVbenForm } from '#/adapter/form';  
14 - import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
15 17
16 - import { use${subSimpleClassName}FormSchema } from '../data'; 18 + import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
17 19
18 const emit = defineEmits(['success']); 20 const emit = defineEmits(['success']);
19 - const formData = ref<${simpleClassName}Api.${subSimpleClassName}>();  
20 const getTitle = computed(() => { 21 const getTitle = computed(() => {
21 return formData.value?.id 22 return formData.value?.id
22 ? $t('ui.actionTitle.edit', ['${subTable.classComment}']) 23 ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
23 : $t('ui.actionTitle.create', ['${subTable.classComment}']); 24 : $t('ui.actionTitle.create', ['${subTable.classComment}']);
24 }); 25 });
25 26
26 - const [Form, formApi] = useVbenForm({  
27 - commonConfig: {  
28 - componentProps: {  
29 - class: 'w-full',  
30 - },  
31 - formItemClass: 'col-span-2',  
32 - labelWidth: 80,  
33 - },  
34 - layout: 'horizontal',  
35 - schema: use${subSimpleClassName}FormSchema(),  
36 - showDefaultActions: false 27 + const formRef = ref();
  28 + const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
  29 + #foreach ($column in $subColumns)
  30 + #if ($column.createOperation || $column.updateOperation)
  31 + #if ($column.htmlType == "checkbox")
  32 + $column.javaField: [],
  33 + #else
  34 + $column.javaField: undefined,
  35 + #end
  36 + #end
  37 + #end
37 }); 38 });
  39 + const rules: Record<string, Rule[]> = {
  40 + #foreach ($column in $subColumns)
  41 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  42 + #set($comment=$column.columnComment)
  43 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  44 + #end
  45 + #end
  46 + };
38 47
39 const [Modal, modalApi] = useVbenModal({ 48 const [Modal, modalApi] = useVbenModal({
40 async onConfirm() { 49 async onConfirm() {
41 - const { valid } = await formApi.validate();  
42 - if (!valid) {  
43 - return;  
44 - } 50 + await formRef.value?.validate();
45 51
46 modalApi.lock(); 52 modalApi.lock();
47 // 提交表单 53 // 提交表单
48 - const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName};  
49 - data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField}; 54 + const data = formData.value as ${simpleClassName}Api.${subSimpleClassName};
50 try { 55 try {
51 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data)); 56 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
52 // 关闭并提示 57 // 关闭并提示
@@ -62,7 +67,7 @@ @@ -62,7 +67,7 @@
62 }, 67 },
63 async onOpenChange(isOpen: boolean) { 68 async onOpenChange(isOpen: boolean) {
64 if (!isOpen) { 69 if (!isOpen) {
65 - formData.value = undefined; 70 + resetForm()
66 return; 71 return;
67 } 72 }
68 73
@@ -81,13 +86,127 @@ @@ -81,13 +86,127 @@
81 } 86 }
82 // 设置到 values 87 // 设置到 values
83 formData.value = data; 88 formData.value = data;
84 - await formApi.setValues(formData.value);  
85 }, 89 },
86 }); 90 });
  91 +
  92 + /** 重置表单 */
  93 + const resetForm = () => {
  94 + formData.value = {
  95 + #foreach ($column in $subColumns)
  96 + #if ($column.createOperation || $column.updateOperation)
  97 + #if ($column.htmlType == "checkbox")
  98 + $column.javaField: [],
  99 + #else
  100 + $column.javaField: undefined,
  101 + #end
  102 + #end
  103 + #end
  104 + };
  105 + formRef.value?.resetFields();
  106 + }
87 </script> 107 </script>
88 108
89 <template> 109 <template>
90 <Modal :title="getTitle"> 110 <Modal :title="getTitle">
91 - <Form class="mx-4" /> 111 + <Form
  112 + ref="formRef"
  113 + :model="formData"
  114 + :rules="rules"
  115 + :label-col="{ span: 5 }"
  116 + :wrapper-col="{ span: 18 }"
  117 + >
  118 + #foreach($column in $subColumns)
  119 + #if ($column.createOperation || $column.updateOperation)
  120 + #set ($dictType = $column.dictType)
  121 + #set ($javaField = $column.javaField)
  122 + #set ($javaType = $column.javaType)
  123 + #set ($comment = $column.columnComment)
  124 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  125 + #set ($dictMethod = "number")
  126 + #elseif ($javaType == "String")
  127 + #set ($dictMethod = "string")
  128 + #elseif ($javaType == "Boolean")
  129 + #set ($dictMethod = "boolean")
  130 + #end
  131 + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  132 + <Form.Item label="${comment}" name="${javaField}">
  133 + <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  134 + </Form.Item>
  135 + #elseif($column.htmlType == "imageUpload")## 图片上传
  136 + <Form.Item label="${comment}" name="${javaField}">
  137 + <ImageUpload v-model:value="formData.${javaField}" />
  138 + </Form.Item>
  139 + #elseif($column.htmlType == "fileUpload")## 文件上传
  140 + <Form.Item label="${comment}" name="${javaField}">
  141 + <FileUpload v-model:value="formData.${javaField}" />
  142 + </Form.Item>
  143 + #elseif($column.htmlType == "editor")## 文本编辑器
  144 + <Form.Item label="${comment}" name="${javaField}">
  145 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  146 + </Form.Item>
  147 + #elseif($column.htmlType == "select")## 下拉框
  148 + <Form.Item label="${comment}" name="${javaField}">
  149 + <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
  150 + #if ("" != $dictType)## 有数据字典
  151 + <Select.Option
  152 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  153 + :key="dict.value"
  154 + :value="dict.value"
  155 + >
  156 + {{ dict.label }}
  157 + </Select.Option>
  158 + #else##没数据字典
  159 + <Select.Option label="请选择字典生成" value="" />
  160 + #end
  161 + </Select>
  162 + </Form.Item>
  163 + #elseif($column.htmlType == "checkbox")## 多选框
  164 + <Form.Item label="${comment}" name="${javaField}">
  165 + <CheckboxGroup v-model:value="formData.${javaField}">
  166 + #if ("" != $dictType)## 有数据字典
  167 + <Checkbox
  168 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  169 + :key="dict.value"
  170 + :value="dict.value"
  171 + >
  172 + {{ dict.label }}
  173 + </Checkbox>
  174 + #else##没数据字典
  175 + <Checkbox label="请选择字典生成" />
  176 + #end
  177 + </CheckboxGroup>
  178 + </Form.Item>
  179 + #elseif($column.htmlType == "radio")## 单选框
  180 + <Form.Item label="${comment}" name="${javaField}">
  181 + <RadioGroup v-model:value="formData.${javaField}">
  182 + #if ("" != $dictType)## 有数据字典
  183 + <Radio
  184 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  185 + :key="dict.value"
  186 + :value="dict.value"
  187 + >
  188 + {{ dict.label }}
  189 + </Radio>
  190 + #else##没数据字典
  191 + <Radio value="1">请选择字典生成</Radio>
  192 + #end
  193 + </RadioGroup>
  194 + </Form.Item>
  195 + #elseif($column.htmlType == "datetime")## 时间框
  196 + <Form.Item label="${comment}" name="${javaField}">
  197 + <DatePicker
  198 + v-model:value="formData.${javaField}"
  199 + valueFormat="x"
  200 + placeholder="选择${comment}"
  201 + />
  202 + </Form.Item>
  203 + #elseif($column.htmlType == "textarea")## 文本框
  204 + <Form.Item label="${comment}" name="${javaField}">
  205 + <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  206 + </Form.Item>
  207 + #end
  208 + #end
  209 + #end
  210 + </Form>
92 </Modal> 211 </Modal>
93 </template> 212 </template>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_inner.vue.vm
1 ## 主表的 normal 和 inner 使用相同的 form 表单 1 ## 主表的 normal 和 inner 使用相同的 form 表单
2 -#parse("codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm")  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +#parse("codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm")
4 \ No newline at end of file 4 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm
@@ -7,19 +7,19 @@ @@ -7,19 +7,19 @@
7 <script lang="ts" setup> 7 <script lang="ts" setup>
8 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 8 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
9 9
  10 + import { message, Tabs, Form, Input, Textarea,Button, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue';
10 import { computed, ref, h, onMounted,watch,nextTick } from 'vue'; 11 import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
11 import { $t } from '#/locales'; 12 import { $t } from '#/locales';
  13 + import { DICT_TYPE, getDictOptions } from '#/utils/dict';
12 14
13 #if ($subTable.subJoinMany) ## 一对多 15 #if ($subTable.subJoinMany) ## 一对多
  16 +import type { VxeTableInstance } from 'vxe-table';
14 import { Plus } from "@vben/icons"; 17 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}GridEditColumns } from '../data'; 18 +import { VxeColumn, VxeTable } from 'vxe-table';
19 import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 19 import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
20 #else 20 #else
21 -import { useVbenForm } from '#/adapter/form';  
22 -import { use${subSimpleClassName}FormSchema } from '../data'; 21 +import type { Rule } from 'ant-design-vue/es/form';
  22 +import { Tinymce as RichTextarea } from '#/components/tinymce';
23 import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 23 import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
24 #end 24 #end
25 25
@@ -28,57 +28,27 @@ const props = defineProps&lt;{ @@ -28,57 +28,27 @@ const props = defineProps&lt;{
28 }>() 28 }>()
29 29
30 #if ($subTable.subJoinMany) ## 一对多 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;  
40 - }  
41 - }  
42 -}  
43 -  
44 -const [Grid, gridApi] = useVbenVxeGrid({  
45 -gridOptions: {  
46 - columns: use${subSimpleClassName}GridEditColumns(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 -});  
62 - 31 +const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
  32 +const tableRef = ref<VxeTableInstance>();
63 /** 添加${subTable.classComment} */ 33 /** 添加${subTable.classComment} */
64 const onAdd = async () => { 34 const onAdd = async () => {
65 - await gridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1); 35 + await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
66 } 36 }
67 37
68 /** 删除${subTable.classComment} */ 38 /** 删除${subTable.classComment} */
69 const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => { 39 const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
70 - await gridApi.grid.remove(row); 40 + await tableRef.value?.remove(row);
71 } 41 }
72 42
73 /** 提供获取表格数据的方法供父组件调用 */ 43 /** 提供获取表格数据的方法供父组件调用 */
74 defineExpose({ 44 defineExpose({
75 getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => { 45 getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
76 - const data = gridApi.grid.getData() as ${simpleClassName}Api.${subSimpleClassName}[];  
77 - const removeRecords = gridApi.grid.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];  
78 - const insertRecords = gridApi.grid.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 46 + const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[];
  47 + const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  48 + const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
79 return data 49 return data
80 .filter((row) => !removeRecords.some((removed) => removed.id === row.id)) 50 .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
81 - .concat(insertRecords.map((row: any) => ({ ...row, id: undefined }))); 51 + ?.concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
82 }, 52 },
83 }); 53 });
84 54
@@ -89,32 +59,35 @@ watch( @@ -89,32 +59,35 @@ watch(
89 if (!val) { 59 if (!val) {
90 return; 60 return;
91 } 61 }
92 - await nextTick();  
93 - await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!)); 62 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
94 }, 63 },
95 { immediate: true }, 64 { immediate: true },
96 ); 65 );
97 #else 66 #else
98 -const [Form, formApi] = useVbenForm({  
99 - commonConfig: {  
100 - componentProps: {  
101 - class: 'w-full',  
102 - },  
103 - formItemClass: 'col-span-2',  
104 - labelWidth: 80,  
105 - },  
106 - layout: 'horizontal',  
107 - schema: use${subSimpleClassName}FormSchema(),  
108 - showDefaultActions: false 67 +const formRef = ref();
  68 +const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
  69 + #foreach ($column in $subColumns)
  70 + #if ($column.createOperation || $column.updateOperation)
  71 + #if ($column.htmlType == "checkbox")
  72 + $column.javaField: [],
  73 + #else
  74 + $column.javaField: undefined,
  75 + #end
  76 + #end
  77 + #end
109 }); 78 });
110 - 79 +const rules: Record<string, Rule[]> = {
  80 + #foreach ($column in $subColumns)
  81 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  82 + #set($comment=$column.columnComment)
  83 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  84 + #end
  85 + #end
  86 +};
111 /** 暴露出表单校验方法和表单值获取方法 */ 87 /** 暴露出表单校验方法和表单值获取方法 */
112 defineExpose({ 88 defineExpose({
113 - validate: async () => {  
114 - const { valid } = await formApi.validate();  
115 - return valid;  
116 - },  
117 - getValues: formApi.getValues, 89 + validate: async () => await formRef.value?.validate(),
  90 + getValues: ()=> formData.value,
118 }); 91 });
119 92
120 /** 监听主表的关联字段的变化,加载对应的子表数据 */ 93 /** 监听主表的关联字段的变化,加载对应的子表数据 */
@@ -125,7 +98,7 @@ watch( @@ -125,7 +98,7 @@ watch(
125 return; 98 return;
126 } 99 }
127 await nextTick(); 100 await nextTick();
128 - await formApi.setValues(await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)); 101 + formData.value = await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
129 }, 102 },
130 { immediate: true }, 103 { immediate: true },
131 ); 104 );
@@ -134,66 +107,232 @@ watch( @@ -134,66 +107,232 @@ watch(
134 107
135 <template> 108 <template>
136 #if ($subTable.subJoinMany) ## 一对多 109 #if ($subTable.subJoinMany) ## 一对多
137 - <Grid class="mx-4"> 110 + <vxe-table ref="tableRef" :data="list" show-overflow class="mx-4">
138 #foreach($column in $subColumns) 111 #foreach($column in $subColumns)
139 #if ($column.createOperation || $column.updateOperation) 112 #if ($column.createOperation || $column.updateOperation)
  113 + #set ($comment = $column.columnComment)
140 #set ($javaField = $column.javaField) 114 #set ($javaField = $column.javaField)
  115 + #set ($javaType = $column.javaType)
  116 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  117 + #set ($dictMethod = "number")
  118 + #elseif ($javaType == "String")
  119 + #set ($dictMethod = "string")
  120 + #elseif ($javaType == "Boolean")
  121 + #set ($dictMethod = "boolean")
  122 + #end
141 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写 123 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
142 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 124 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
143 - <template #${javaField}="{ row }">  
144 - <Input v-model:value="row.${javaField}" />  
145 - </template> 125 + <vxe-column field="${javaField}" title="${comment}" align="center">
  126 + <template #default="{row}">
  127 + <Input v-model:value="row.${javaField}" />
  128 + </template>
  129 + </vxe-column>
  130 + #elseif($column.htmlType == "imageUpload")## 图片上传
  131 + <vxe-column field="${javaField}" title="${comment}" align="center">
  132 + <template #default="{row}">
  133 + <ImageUpload v-model:value="row.${javaField}" />
  134 + </template>
  135 + </vxe-column>
  136 + #elseif($column.htmlType == "fileUpload")## 文件上传
  137 + <vxe-column field="${javaField}" title="${comment}" align="center">
  138 + <template #default="{row}">
  139 + <FileUpload v-model:value="row.${javaField}" />
  140 + </template>
  141 + </vxe-column>
  142 + #elseif($column.htmlType == "select")## 下拉框
  143 + <vxe-column field="${javaField}" title="${comment}" align="center">
  144 + <template #default="{row}">
  145 + <Select v-model:value="row.${javaField}" placeholder="请选择${comment}">
  146 + #if ("" != $dictType)## 有数据字典
  147 + <Select.Option
  148 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  149 + :key="dict.value"
  150 + :value="dict.value"
  151 + >
  152 + {{ dict.label }}
  153 + </Select.Option>
  154 + #else##没数据字典
  155 + <Select.Option label="请选择字典生成" value="" />
  156 + #end
  157 + </Select>
  158 + </template>
  159 + </vxe-column>
  160 + #elseif($column.htmlType == "checkbox")## 多选框
  161 + <vxe-column field="${javaField}" title="${comment}" align="center">
  162 + <template #default="{row}">
  163 + <CheckboxGroup v-model:value="row.${javaField}">
  164 + #if ("" != $dictType)## 有数据字典
  165 + <Checkbox
  166 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  167 + :key="dict.value"
  168 + :value="dict.value"
  169 + >
  170 + {{ dict.label }}
  171 + </Checkbox>
  172 + #else##没数据字典
  173 + <Checkbox label="请选择字典生成" />
  174 + #end
  175 + </CheckboxGroup>
  176 + </template>
  177 + </vxe-column>
  178 + #elseif($column.htmlType == "radio")## 单选框
  179 + <vxe-column field="${javaField}" title="${comment}" align="center">
  180 + <template #default="{row}">
  181 + <RadioGroup v-model:value="row.${javaField}">
  182 + #if ("" != $dictType)## 有数据字典
  183 + <Radio
  184 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  185 + :key="dict.value"
  186 + :value="dict.value"
  187 + >
  188 + {{ dict.label }}
  189 + </Radio>
  190 + #else##没数据字典
  191 + <Radio value="1">请选择字典生成</Radio>
  192 + #end
  193 + </RadioGroup>
  194 + </template>
  195 + </vxe-column>
  196 + #elseif($column.htmlType == "datetime")## 时间框
  197 + <vxe-column field="${javaField}" title="${comment}" align="center">
  198 + <template #default="{row}">
  199 + <DatePicker
  200 + v-model:value="row.${javaField}"
  201 + :showTime="true"
  202 + format="YYYY-MM-DD HH:mm:ss"
  203 + valueFormat='x'
  204 + />
  205 + </template>
  206 + </vxe-column>
  207 + #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
  208 + <vxe-column field="${javaField}" title="${comment}" align="center">
  209 + <template #default="{row}">
  210 + <Textarea v-model:value="row.${javaField}" />
  211 + </template>
  212 + </vxe-column>
  213 + #end
  214 + #end
  215 + #end
  216 + <vxe-column field="operation" title="操作" align="center">
  217 + <template #default="{row}">
  218 + <Button
  219 + size="small"
  220 + type="link"
  221 + danger
  222 + @click="onDelete(row as any)"
  223 + v-access:code="['${permissionPrefix}:delete']"
  224 + >
  225 + {{ $t('ui.actionTitle.delete') }}
  226 + </Button>
  227 + </template>
  228 + </vxe-column>
  229 + </vxe-table>
  230 + <div class="flex justify-center mt-4">
  231 + <Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${permissionPrefix}:create']">
  232 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  233 + </Button>
  234 + </div>
  235 +#else
  236 + <Form
  237 + ref="formRef"
  238 + class="mx-4"
  239 + :model="formData"
  240 + :rules="rules"
  241 + :label-col="{ span: 5 }"
  242 + :wrapper-col="{ span: 18 }"
  243 + >
  244 + #foreach($column in $subColumns)
  245 + #if ($column.createOperation || $column.updateOperation)
  246 + #set ($dictType = $column.dictType)
  247 + #set ($javaField = $column.javaField)
  248 + #set ($javaType = $column.javaType)
  249 + #set ($comment = $column.columnComment)
  250 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  251 + #set ($dictMethod = "number")
  252 + #elseif ($javaType == "String")
  253 + #set ($dictMethod = "string")
  254 + #elseif ($javaType == "Boolean")
  255 + #set ($dictMethod = "boolean")
  256 + #end
  257 + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  258 + <Form.Item label="${comment}" name="${javaField}">
  259 + <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  260 + </Form.Item>
146 #elseif($column.htmlType == "imageUpload")## 图片上传 261 #elseif($column.htmlType == "imageUpload")## 图片上传
147 - <template #${javaField}="{ row }">  
148 - <UploadImg v-model:value="row.${javaField}" />  
149 - </template> 262 + <Form.Item label="${comment}" name="${javaField}">
  263 + <ImageUpload v-model:value="formData.${javaField}" />
  264 + </Form.Item>
150 #elseif($column.htmlType == "fileUpload")## 文件上传 265 #elseif($column.htmlType == "fileUpload")## 文件上传
151 - <template #${javaField}="{ row }">  
152 - <UploadFile v-model:value="row.${javaField}" />  
153 - </template> 266 + <Form.Item label="${comment}" name="${javaField}">
  267 + <FileUpload v-model:value="formData.${javaField}" />
  268 + </Form.Item>
154 #elseif($column.htmlType == "editor")## 文本编辑器 269 #elseif($column.htmlType == "editor")## 文本编辑器
155 - <template #${javaField}="{ row }">  
156 - <Textarea v-model:value="row.${javaField}" />  
157 - </template> 270 + <Form.Item label="${comment}" name="${javaField}">
  271 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  272 + </Form.Item>
158 #elseif($column.htmlType == "select")## 下拉框 273 #elseif($column.htmlType == "select")## 下拉框
159 - <template #${javaField}="{ row, column }">  
160 - <Select v-model:value="row.${javaField}" class="w-full">  
161 - <Select.Option v-for="option in column.params.options" :key="option.value" :value="option.value">  
162 - {{ option.label }}  
163 - </Select.Option> 274 + <Form.Item label="${comment}" name="${javaField}">
  275 + <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
  276 + #if ("" != $dictType)## 有数据字典
  277 + <Select.Option
  278 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  279 + :key="dict.value"
  280 + :value="dict.value"
  281 + >
  282 + {{ dict.label }}
  283 + </Select.Option>
  284 + #else##没数据字典
  285 + <Select.Option label="请选择字典生成" value="" />
  286 + #end
164 </Select> 287 </Select>
165 - </template> 288 + </Form.Item>
166 #elseif($column.htmlType == "checkbox")## 多选框 289 #elseif($column.htmlType == "checkbox")## 多选框
167 - <template #${javaField}="{ row, column }">  
168 - <CheckboxGroup v-model:value="row.${javaField}" :options="column.params.options" />  
169 - </template> 290 + <Form.Item label="${comment}" name="${javaField}">
  291 + <CheckboxGroup v-model:value="formData.${javaField}">
  292 + #if ("" != $dictType)## 有数据字典
  293 + <Checkbox
  294 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  295 + :key="dict.value"
  296 + :value="dict.value"
  297 + >
  298 + {{ dict.label }}
  299 + </Checkbox>
  300 + #else##没数据字典
  301 + <Checkbox label="请选择字典生成" />
  302 + #end
  303 + </CheckboxGroup>
  304 + </Form.Item>
170 #elseif($column.htmlType == "radio")## 单选框 305 #elseif($column.htmlType == "radio")## 单选框
171 - <template #${javaField}="{ row, column }">  
172 - <RadioGroup v-model:value="row.${javaField}" :options="column.params.options" />  
173 - </template> 306 + <Form.Item label="${comment}" name="${javaField}">
  307 + <RadioGroup v-model:value="formData.${javaField}">
  308 + #if ("" != $dictType)## 有数据字典
  309 + <Radio
  310 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  311 + :key="dict.value"
  312 + :value="dict.value"
  313 + >
  314 + {{ dict.label }}
  315 + </Radio>
  316 + #else##没数据字典
  317 + <Radio value="1">请选择字典生成</Radio>
  318 + #end
  319 + </RadioGroup>
  320 + </Form.Item>
174 #elseif($column.htmlType == "datetime")## 时间框 321 #elseif($column.htmlType == "datetime")## 时间框
175 - <template #${javaField}="{ row }"> 322 + <Form.Item label="${comment}" name="${javaField}">
176 <DatePicker 323 <DatePicker
177 - v-model:value="row.${javaField}"  
178 - :showTime="true"  
179 - format="YYYY-MM-DD HH:mm:ss"  
180 - valueFormat='x' 324 + v-model:value="formData.${javaField}"
  325 + valueFormat="x"
  326 + placeholder="选择${comment}"
181 /> 327 />
182 - </template> 328 + </Form.Item>
183 #elseif($column.htmlType == "textarea")## 文本框 329 #elseif($column.htmlType == "textarea")## 文本框
184 - <template #${javaField}="{ row }">  
185 - <Textarea v-model:value="row.${javaField}" />  
186 - </template> 330 + <Form.Item label="${comment}" name="${javaField}">
  331 + <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  332 + </Form.Item>
187 #end 333 #end
188 #end 334 #end
189 #end 335 #end
190 - </Grid>  
191 - <div class="flex justify-center -mt-4">  
192 - <Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${subTable.moduleName}:${simpleClassName_strikeCase}:create']">  
193 - {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}  
194 - </Button>  
195 - </div>  
196 -#else  
197 - <Form class="mx-4" /> 336 + </Form>
198 #end 337 #end
199 </template> 338 </template>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm
@@ -6,30 +6,37 @@ @@ -6,30 +6,37 @@
6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex)) 6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
8 <script lang="ts" setup> 8 <script lang="ts" setup>
9 - import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-table';  
10 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 9 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  10 + import type { VxeTableInstance } from 'vxe-table';
  11 +
  12 + import { DictTag } from '#/components/dict-tag';
  13 + import { DICT_TYPE, getDictOptions } from '#/utils/dict';
  14 + import { VxeColumn, VxeTable } from 'vxe-table';
  15 + import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
  16 + import { cloneDeep, formatDateTime } from '@vben/utils';
  17 + import { ContentWrap } from "#/components/content-wrap";
11 18
12 #if ($table.templateType == 11) ## erp 19 #if ($table.templateType == 11) ## erp
13 - import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue' 20 + import { useVbenModal } from '@vben/common-ui';
  21 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  22 + import { Tinymce as RichTextarea } from '#/components/tinymce';
  23 + import { ImageUpload, FileUpload } from "#/components/upload";
  24 + import { message,Button, Tabs,Pagination, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox,RangePicker, DatePicker, TreeSelect } from 'ant-design-vue';
  25 + import { DICT_TYPE, getDictOptions } from '#/utils/dict';
  26 + import { Plus } from '@vben/icons';
  27 + import { $t } from '#/locales';
  28 + import { TableToolbar } from '#/components/table-toolbar';
  29 + import { getRangePickerDefaultProps } from '#/utils/date';
14 #end 30 #end
15 - import { useVbenModal } from '@vben/common-ui';  
16 - import { Button, message } from 'ant-design-vue';  
17 - import { Plus } from '@vben/icons';  
18 - import { #if($table.templateType != 11)ref,#end h, nextTick,watch } from 'vue';  
19 - import { $t } from '#/locales';  
20 - import { useVbenVxeGrid } from '#/adapter/vxe-table';  
21 -  
22 31
23 #if ($table.templateType == 11) ## erp 32 #if ($table.templateType == 11) ## erp
24 import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 33 import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
25 - import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';  
26 #else 34 #else
27 #if ($subTable.subJoinMany) ## 一对多 35 #if ($subTable.subJoinMany) ## 一对多
28 import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 36 import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
29 #else 37 #else
30 import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 38 import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
31 #end 39 #end
32 - import { use${subSimpleClassName}GridColumns } from '../data';  
33 #end 40 #end
34 41
35 const props = defineProps<{ 42 const props = defineProps<{
@@ -69,90 +76,81 @@ async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { @@ -69,90 +76,81 @@ async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
69 content: $t('ui.actionMessage.deleteSuccess', [row.id]), 76 content: $t('ui.actionMessage.deleteSuccess', [row.id]),
70 key: 'action_process_msg', 77 key: 'action_process_msg',
71 }); 78 });
72 - onRefresh(); 79 + getList();
73 } catch { 80 } catch {
74 hideLoading(); 81 hideLoading();
75 } 82 }
76 } 83 }
77 -  
78 -/** 表格操作按钮的回调函数 */  
79 -function onActionClick({  
80 - code,  
81 - row,  
82 -}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) {  
83 - switch (code) {  
84 - case 'edit': {  
85 - onEdit(row);  
86 - break;  
87 - }  
88 - case 'delete': {  
89 - onDelete(row);  
90 - break;  
91 - }  
92 - }  
93 -}  
94 -  
95 -#end  
96 - const [Grid, gridApi] = useVbenVxeGrid({  
97 -#if ($table.templateType == 11)  
98 - formOptions: {  
99 - schema: use${subSimpleClassName}GridFormSchema(),  
100 - },  
101 -#end  
102 - gridOptions: {  
103 -#if ($table.templateType == 11)  
104 - columns: use${subSimpleClassName}GridColumns(onActionClick),  
105 - proxyConfig: {  
106 - ajax: {  
107 - query: async ({ page }, formValues) => {  
108 - if (!props.${subJoinColumn.javaField}){  
109 - return []  
110 - }  
111 - return await get${subSimpleClassName}Page({  
112 - pageNo: page.currentPage,  
113 - pageSize: page.pageSize,  
114 - ${subJoinColumn.javaField}: props.${subJoinColumn.javaField},  
115 - ...formValues,  
116 - });  
117 - },  
118 - },  
119 - },  
120 - pagerConfig: {  
121 - enabled: true,  
122 - },  
123 - toolbarConfig: {  
124 - refresh: { code: 'query' },  
125 - search: true,  
126 - },  
127 -#else  
128 - columns: use${subSimpleClassName}GridColumns(),  
129 - pagerConfig: {  
130 - enabled: false,  
131 - },  
132 - toolbarConfig: {  
133 - enabled: false,  
134 - },  
135 #end 84 #end
136 - height: '600px',  
137 - rowConfig: {  
138 - keyField: 'id',  
139 - isHover: true,  
140 - },  
141 - } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>,  
142 - });  
143 85
144 -/** 刷新表格 */  
145 -const onRefresh = async ()=> { 86 + const loading = ref(true) // 列表的加载中
  87 + const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
146 #if ($table.templateType == 11) ## erp 88 #if ($table.templateType == 11) ## erp
147 - await gridApi.query();  
148 -#else  
149 - #if ($subTable.subJoinMany) ## 一对多  
150 - await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));  
151 - #else  
152 - await gridApi.grid.loadData([await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)]);  
153 - #end 89 + const total = ref(0) // 列表的总页数
154 #end 90 #end
  91 +#if ($table.templateType == 11) ## erp
  92 + const queryFormRef = ref() // 搜索的表单
  93 + const queryParams = reactive({
  94 + pageNo: 1,
  95 + pageSize: 10,
  96 + #foreach ($column in $subColumns)
  97 + #if ($column.listOperation)
  98 + #if ($column.listOperationCondition != 'BETWEEN')
  99 + $column.javaField: undefined,
  100 + #end
  101 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  102 + $column.javaField: undefined,
  103 + #end
  104 + #end
  105 + #end
  106 + })
  107 +
  108 +/** 搜索按钮操作 */
  109 +const handleQuery = () => {
  110 + queryParams.pageNo = 1
  111 + getList()
  112 +}
  113 +
  114 +/** 重置按钮操作 */
  115 +const resetQuery = () => {
  116 + queryFormRef.value.resetFields()
  117 + handleQuery()
155 } 118 }
  119 +#end
  120 + /** 查询列表 */
  121 + const getList = async () => {
  122 + loading.value = true
  123 + try {
  124 + if (!props.${subJoinColumn.javaField}){
  125 + return []
  126 + }
  127 + ## 特殊:树表专属逻辑(树不需要分页接口)
  128 + #if ($table.templateType == 11) ## erp
  129 + const params = cloneDeep(queryParams) as any;
  130 + #foreach ($column in $columns)
  131 + #if ($column.listOperation)
  132 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  133 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  134 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  135 + }
  136 + #end
  137 + #end
  138 + #end
  139 + params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};
  140 + const data = await get${subSimpleClassName}Page(params)
  141 + list.value = data.list
  142 + total.value = data.total
  143 + #else
  144 + #if ($subTable.subJoinMany) ## 一对多
  145 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  146 + #else
  147 + list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];
  148 + #end
  149 + #end
  150 + } finally {
  151 + loading.value = false
  152 + }
  153 + }
156 154
157 /** 监听主表的关联字段的变化,加载对应的子表数据 */ 155 /** 监听主表的关联字段的变化,加载对应的子表数据 */
158 watch( 156 watch(
@@ -162,23 +160,231 @@ const onRefresh = async ()=&gt; { @@ -162,23 +160,231 @@ const onRefresh = async ()=&gt; {
162 return; 160 return;
163 } 161 }
164 await nextTick(); 162 await nextTick();
165 - await onRefresh() 163 + await getList()
166 }, 164 },
167 { immediate: true }, 165 { immediate: true },
168 ); 166 );
  167 +
  168 +#if ($table.templateType == 11) ## erp
  169 +/** 隐藏搜索栏 */
  170 +const hiddenSearchBar = ref(false);
  171 +const tableToolbarRef = ref<InstanceType<typeof TableToolbar>>();
  172 +const tableRef = ref<VxeTableInstance>();
  173 +
  174 +/** 初始化 */
  175 +onMounted(async () => {
  176 + await getList();
  177 + await nextTick();
  178 + // 挂载 toolbar 工具栏
  179 + const table = tableRef.value;
  180 + const tableToolbar = tableToolbarRef.value;
  181 + if (table && tableToolbar) {
  182 + await table.connect(tableToolbar.getToolbarRef()!);
  183 + }
  184 +});
  185 +#end
169 </script> 186 </script>
170 187
171 <template> 188 <template>
172 #if ($table.templateType == 11) ## erp 189 #if ($table.templateType == 11) ## erp
173 - <FormModal @success="onRefresh" />  
174 - <Grid table-title="${subTable.classComment}列表">  
175 - <template #toolbar-tools>  
176 - <Button :icon="h(Plus)" type="primary" @click="onCreate" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:create']">  
177 - {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}  
178 - </Button>  
179 - </template>  
180 - </Grid> 190 + <FormModal @success="getList" />
  191 + <div class="h-[600px]">
  192 + <ContentWrap v-if="!hiddenSearchBar">
  193 + <!-- 搜索工作栏 -->
  194 + <Form
  195 + :model="queryParams"
  196 + ref="queryFormRef"
  197 + layout="inline"
  198 + >
  199 + #foreach($column in $subColumns)
  200 + #if ($column.listOperation)
  201 + #set ($dictType = $column.dictType)
  202 + #set ($javaField = $column.javaField)
  203 + #set ($javaType = $column.javaType)
  204 + #set ($comment = $column.columnComment)
  205 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  206 + #set ($dictMethod = "number")
  207 + #elseif ($javaType == "String")
  208 + #set ($dictMethod = "string")
  209 + #elseif ($javaType == "Boolean")
  210 + #set ($dictMethod = "boolean")
  211 + #end
  212 + #if ($column.htmlType == "input")
  213 + <Form.Item label="${comment}" name="${javaField}">
  214 + <Input
  215 + v-model:value="queryParams.${javaField}"
  216 + placeholder="请输入${comment}"
  217 + allowClear
  218 + @pressEnter="handleQuery"
  219 + class="w-full"
  220 + />
  221 + </Form.Item>
  222 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
  223 + <Form.Item label="${comment}" name="${javaField}">
  224 + <Select
  225 + v-model:value="queryParams.${javaField}"
  226 + placeholder="请选择${comment}"
  227 + allowClear
  228 + class="w-full"
  229 + >
  230 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  231 + <Select.Option
  232 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  233 + :key="dict.value"
  234 + :value="dict.value"
  235 + >
  236 + {{ dict.label }}
  237 + </Select.Option>
  238 + #else## 未设置 dictType 数据字典的情况
  239 + <Select.Option label="请选择字典生成" value="" />
  240 + #end
  241 + </Select>
  242 + </Form.Item>
  243 + #elseif($column.htmlType == "datetime")
  244 + #if ($column.listOperationCondition != "BETWEEN")## 非范围
  245 + <Form.Item label="${comment}" name="${javaField}">
  246 + <DatePicker
  247 + v-model:value="queryParams.${javaField}"
  248 + valueFormat="YYYY-MM-DD"
  249 + placeholder="选择${comment}"
  250 + allowClear
  251 + class="w-full"
  252 + />
  253 + </Form.Item>
  254 + #else## 范围
  255 + <Form.Item label="${comment}" name="${javaField}">
  256 + <RangePicker
  257 + v-model:value="queryParams.${javaField}"
  258 + v-bind="getRangePickerDefaultProps()"
  259 + class="w-full"
  260 + />
  261 + </Form.Item>
  262 + #end
  263 + #end
  264 + #end
  265 + #end
  266 + <Form.Item>
  267 + <Button class="ml-2" @click="resetQuery"> 重置 </Button>
  268 + <Button class="ml-2" @click="handleQuery" type="primary">
  269 + 搜索
  270 + </Button>
  271 + </Form.Item>
  272 + </Form>
  273 + </ContentWrap>
  274 +
  275 + <!-- 列表 -->
  276 + <ContentWrap title="${table.classComment}">
  277 + <template #extra>
  278 + <TableToolbar
  279 + ref="tableToolbarRef"
  280 + v-model:hidden-search="hiddenSearchBar"
  281 + >
  282 + <Button
  283 + class="ml-2"
  284 + :icon="h(Plus)"
  285 + type="primary"
  286 + @click="onCreate"
  287 + v-access:code="['${permissionPrefix}:create']"
  288 + >
  289 + {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
  290 + </Button>
  291 + </TableToolbar>
  292 + </template>
  293 + <vxe-table
  294 + ref="tableRef"
  295 + :data="list"
  296 + show-overflow
  297 + :loading="loading"
  298 + >
  299 + #foreach($column in $subColumns)
  300 + #if ($column.listOperationResult)
  301 + #set ($dictType=$column.dictType)
  302 + #set ($javaField = $column.javaField)
  303 + #set ($comment=$column.columnComment)
  304 + #if ($column.javaType == "LocalDateTime")## 时间类型
  305 + <vxe-column field="${javaField}" title="${comment}" align="center">
  306 + <template #default="{row}">
  307 + {{formatDateTime(row.${javaField})}}
  308 + </template>
  309 + </vxe-column>
  310 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  311 + <vxe-column field="${javaField}" title="${comment}" align="center">
  312 + <template #default="{row}">
  313 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  314 + </template>
  315 + </vxe-column>
  316 + #elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
  317 + <vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
  318 + #else
  319 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  320 + #end
  321 + #end
  322 + #end
  323 + <vxe-column field="operation" title="操作" align="center">
  324 + <template #default="{row}">
  325 + <Button
  326 + size="small"
  327 + type="link"
  328 + @click="onEdit(row as any)"
  329 + v-access:code="['${permissionPrefix}:update']"
  330 + >
  331 + {{ $t('ui.actionTitle.edit') }}
  332 + </Button>
  333 + <Button
  334 + size="small"
  335 + type="link"
  336 + danger
  337 + class="ml-2"
  338 + @click="onDelete(row as any)"
  339 + v-access:code="['${permissionPrefix}:delete']"
  340 + >
  341 + {{ $t('ui.actionTitle.delete') }}
  342 + </Button>
  343 + </template>
  344 + </vxe-column>
  345 + </vxe-table>
  346 + <!-- 分页 -->
  347 + <div class="mt-2 flex justify-end">
  348 + <Pagination
  349 + :total="total"
  350 + v-model:current="queryParams.pageNo"
  351 + v-model:page-size="queryParams.pageSize"
  352 + show-size-changer
  353 + @change="getList"
  354 + />
  355 + </div>
  356 + </ContentWrap>
  357 + </div>
181 #else 358 #else
182 - <Grid table-title="${subTable.classComment}列表" /> 359 + <ContentWrap title="${subTable.classComment}列表">
  360 + <vxe-table
  361 + :data="list"
  362 + show-overflow
  363 + :loading="loading"
  364 + >
  365 + #foreach($column in $subColumns)
  366 + #if ($column.listOperationResult)
  367 + #set ($dictType=$column.dictType)
  368 + #set ($javaField = $column.javaField)
  369 + #set ($comment=$column.columnComment)
  370 + #if ($column.javaType == "LocalDateTime")## 时间类型
  371 + <vxe-column field="${javaField}" title="${comment}" align="center">
  372 + <template #default="{row}">
  373 + {{formatDateTime(row.${javaField})}}
  374 + </template>
  375 + </vxe-column>
  376 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  377 + <vxe-column field="${javaField}" title="${comment}" align="center">
  378 + <template #default="{row}">
  379 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  380 + </template>
  381 + </vxe-column>
  382 + #else
  383 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  384 + #end
  385 + #end
  386 + #end
  387 + </vxe-table>
  388 + </ContentWrap>
183 #end 389 #end
184 </template> 390 </template>
185 \ No newline at end of file 391 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_inner.vue.vm
1 ## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点: 1 ## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
2 ## 1)inner 使用 list 不分页,erp 使用 page 分页 2 ## 1)inner 使用 list 不分页,erp 使用 page 分页
3 ## 2)erp 支持单个子表的新增、修改、删除,inner 不支持 3 ## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
4 -#parse("codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm")  
5 \ No newline at end of file 4 \ No newline at end of file
  5 +#parse("codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm")
6 \ No newline at end of file 6 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/api/api.ts.vm
1 import type { PageParam, PageResult } from '@vben/request'; 1 import type { PageParam, PageResult } from '@vben/request';
  2 +import type { Dayjs } from 'dayjs';
2 3
3 import { requestClient } from '#/api/request'; 4 import { requestClient } from '#/api/request';
4 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}") 5 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
@@ -16,7 +17,7 @@ export namespace ${simpleClassName}Api { @@ -16,7 +17,7 @@ export namespace ${simpleClassName}Api {
16 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") 17 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
17 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment} 18 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
18 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime") 19 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
19 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment} 20 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
20 #else 21 #else
21 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment} 22 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
22 #end 23 #end
@@ -32,7 +33,7 @@ export namespace ${simpleClassName}Api { @@ -32,7 +33,7 @@ export namespace ${simpleClassName}Api {
32 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") 33 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
33 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment} 34 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
34 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime") 35 #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
35 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment} 36 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
36 #else 37 #else
37 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment} 38 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
38 #end 39 #end
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
@@ -21,24 +21,11 @@ import { useFormSchema } from &#39;../data&#39;; @@ -21,24 +21,11 @@ import { useFormSchema } from &#39;../data&#39;;
21 21
22 const emit = defineEmits(['success']); 22 const emit = defineEmits(['success']);
23 const formData = ref<${simpleClassName}Api.${simpleClassName}>(); 23 const formData = ref<${simpleClassName}Api.${simpleClassName}>();
24 -#if (${table.templateType} == 2)## 树表特有:父ID处理  
25 -const parentId = ref<number>(); // 新增下级时的父级 ID  
26 -  
27 -const getTitle = computed(() => {  
28 - if (formData.value?.id) {  
29 - return $t('ui.actionTitle.edit', ['${table.classComment}']);  
30 - }  
31 - return parentId.value  
32 - ? $t('ui.actionTitle.create', ['下级${table.classComment}'])  
33 - : $t('ui.actionTitle.create', ['${table.classComment}']);  
34 -});  
35 -#else## 标准表标题  
36 const getTitle = computed(() => { 24 const getTitle = computed(() => {
37 return formData.value?.id 25 return formData.value?.id
38 ? $t('ui.actionTitle.edit', ['${table.classComment}']) 26 ? $t('ui.actionTitle.edit', ['${table.classComment}'])
39 : $t('ui.actionTitle.create', ['${table.classComment}']); 27 : $t('ui.actionTitle.create', ['${table.classComment}']);
40 }); 28 });
41 -#end  
42 29
43 ## 特殊:主子表专属逻辑 30 ## 特殊:主子表专属逻辑
44 #if ( $table.templateType == 10 || $table.templateType == 12 ) 31 #if ( $table.templateType == 10 || $table.templateType == 12 )
@@ -128,7 +115,6 @@ const [Modal, modalApi] = useVbenModal({ @@ -128,7 +115,6 @@ const [Modal, modalApi] = useVbenModal({
128 formData.value = undefined; 115 formData.value = undefined;
129 return; 116 return;
130 } 117 }
131 -  
132 // 加载数据 118 // 加载数据
133 let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>(); 119 let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
134 if (!data) { 120 if (!data) {
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 #if ($subTable.subJoinMany) ## 一对多 13 #if ($subTable.subJoinMany) ## 一对多
14 import { Plus } from "@vben/icons"; 14 import { Plus } from "@vben/icons";
15 import { Button, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue'; 15 import { Button, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  16 +import { ImageUpload, FileUpload } from "#/components/upload";
16 import type { OnActionClickParams } from '#/adapter/vxe-table'; 17 import type { OnActionClickParams } from '#/adapter/vxe-table';
17 import { useVbenVxeGrid } from '#/adapter/vxe-table'; 18 import { useVbenVxeGrid } from '#/adapter/vxe-table';
18 import { use${subSimpleClassName}GridEditColumns } from '../data'; 19 import { use${subSimpleClassName}GridEditColumns } from '../data';
@@ -145,15 +146,11 @@ watch( @@ -145,15 +146,11 @@ watch(
145 </template> 146 </template>
146 #elseif($column.htmlType == "imageUpload")## 图片上传 147 #elseif($column.htmlType == "imageUpload")## 图片上传
147 <template #${javaField}="{ row }"> 148 <template #${javaField}="{ row }">
148 - <UploadImg v-model:value="row.${javaField}" /> 149 + <ImageUpload v-model:value="row.${javaField}" />
149 </template> 150 </template>
150 #elseif($column.htmlType == "fileUpload")## 文件上传 151 #elseif($column.htmlType == "fileUpload")## 文件上传
151 <template #${javaField}="{ row }"> 152 <template #${javaField}="{ row }">
152 - <UploadFile v-model:value="row.${javaField}" />  
153 - </template>  
154 - #elseif($column.htmlType == "editor")## 文本编辑器  
155 - <template #${javaField}="{ row }">  
156 - <Textarea v-model:value="row.${javaField}" /> 153 + <FileUpload v-model:value="row.${javaField}" />
157 </template> 154 </template>
158 #elseif($column.htmlType == "select")## 下拉框 155 #elseif($column.htmlType == "select")## 下拉框
159 <template #${javaField}="{ row, column }"> 156 <template #${javaField}="{ row, column }">
@@ -180,7 +177,7 @@ watch( @@ -180,7 +177,7 @@ watch(
180 valueFormat='x' 177 valueFormat='x'
181 /> 178 />
182 </template> 179 </template>
183 - #elseif($column.htmlType == "textarea")## 文本框 180 + #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
184 <template #${javaField}="{ row }"> 181 <template #${javaField}="{ row }">
185 <Textarea v-model:value="row.${javaField}" /> 182 <Textarea v-model:value="row.${javaField}" />
186 </template> 183 </template>