Commit ef2d0b354a5ff5ef4552aafb7c59d92cee361690

Authored by puhui999
1 parent c26a46da

【功能新增】INFRA:代码生成 vben5 antd 模版 50%

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -164,22 +164,24 @@ public class CodegenEngine { @@ -164,22 +164,24 @@ 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.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"), 167 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"),
  168 + vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
  169 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"),
168 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) 170 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
169 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),  
170 - vue3FilePath("views/${table.moduleName}/${table.businessName}/form.vue"))  
171 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑 171 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"),
  172 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
  173 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"),
  174 + vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
  175 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
172 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) 176 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
173 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑 177 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
174 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) 178 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
175 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑 179 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
176 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) 180 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
177 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑 181 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
178 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) 182 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
179 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 183 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
180 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) 184 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
181 - .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"),  
182 - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))  
183 .build(); 185 .build();
184 186
185 @Resource 187 @Resource
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/api/api.ts.vm
@@ -4,30 +4,14 @@ import { requestClient } from '#/api/request'; @@ -4,30 +4,14 @@ import { requestClient } from '#/api/request';
4 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}") 4 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
5 5
6 export namespace ${simpleClassName}Api { 6 export namespace ${simpleClassName}Api {
7 - ## 特殊:主子表专属逻辑  
8 - #foreach ($subTable in $subTables)  
9 - #set ($index = $foreach.count - 1)  
10 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
11 - #set ($subColumns = $subColumnsList.get($index))##当前字段数组  
12 - /** ${subTable.classComment}信息 */  
13 - export interface ${subSimpleClassName} {  
14 - #foreach ($column in $subColumns)  
15 - #if ($column.createOperation || $column.updateOperation)  
16 - #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 - #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 - #else  
21 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}  
22 - #end  
23 - #end  
24 - #end  
25 - }  
26 -  
27 - #end  
28 - /** ${table.classComment}信息 */  
29 - export interface ${simpleClassName} {  
30 - #foreach ($column in $columns) 7 +## 特殊:主子表专属逻辑
  8 +#foreach ($subTable in $subTables)
  9 + #set ($index = $foreach.count - 1)
  10 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  11 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  12 + /** ${subTable.classComment}信息 */
  13 + export interface ${subSimpleClassName} {
  14 + #foreach ($column in $subColumns)
31 #if ($column.createOperation || $column.updateOperation) 15 #if ($column.createOperation || $column.updateOperation)
32 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal") 16 #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} 17 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
@@ -38,21 +22,37 @@ export namespace ${simpleClassName}Api { @@ -38,21 +22,37 @@ export namespace ${simpleClassName}Api {
38 #end 22 #end
39 #end 23 #end
40 #end 24 #end
41 - #if ( $table.templateType == 2 )  
42 - children?: ${simpleClassName}[];  
43 - #end  
44 - ## 特殊:主子表专属逻辑  
45 - #if ( $table.templateType == 10 || $table.templateType == 12 )  
46 - #foreach ($subTable in $subTables)  
47 - #set ($index = $foreach.count - 1)  
48 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
49 - #if ( $subTable.subJoinMany )  
50 - ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]  
51 - #else  
52 - ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}  
53 - #end  
54 - #end 25 + }
  26 +
  27 +#end
  28 + /** ${table.classComment}信息 */
  29 + export interface ${simpleClassName} {
  30 +#foreach ($column in $columns)
  31 +#if ($column.createOperation || $column.updateOperation)
  32 +#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 +#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 +#else
  37 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  38 +#end
  39 +#end
  40 +#end
  41 +#if ( $table.templateType == 2 )
  42 + children?: ${simpleClassName}[];
  43 +#end
  44 +## 特殊:主子表专属逻辑
  45 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  46 + #foreach ($subTable in $subTables)
  47 + #set ($index = $foreach.count - 1)
  48 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  49 + #if ( $subTable.subJoinMany )
  50 + ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
  51 + #else
  52 + ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
55 #end 53 #end
  54 + #end
  55 +#end
56 } 56 }
57 } 57 }
58 58
@@ -95,57 +95,58 @@ export function export${simpleClassName}(params: any) { @@ -95,57 +95,58 @@ export function export${simpleClassName}(params: any) {
95 95
96 ## 特殊:主子表专属逻辑 96 ## 特殊:主子表专属逻辑
97 #foreach ($subTable in $subTables) 97 #foreach ($subTable in $subTables)
98 - #set ($index = $foreach.count - 1)  
99 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
100 - #set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段  
101 - #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段  
102 - #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写  
103 - #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))  
104 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
105 - #set ($subClassNameVar = $subClassNameVars.get($index)) 98 +#set ($index = $foreach.count - 1)
  99 +#set ($subSimpleClassName = $subSimpleClassNames.get($index))
  100 +#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
  101 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  102 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  103 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  104 +#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  105 +#set ($subClassNameVar = $subClassNameVars.get($index))
106 106
107 // ==================== 子表($subTable.classComment) ==================== 107 // ==================== 子表($subTable.classComment) ====================
108 108
109 - ## 情况一:MASTER_ERP 时,需要分查询页子表  
110 - #if ( $table.templateType == 11 )  
111 - /** 获得${subTable.classComment}分页 */  
112 - export function get${subSimpleClassName}Page(params: PageParam) {  
113 - return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });  
114 - }  
115 - ## 情况二:非 MASTER_ERP 时,需要列表查询子表 109 +## 情况一:MASTER_ERP 时,需要分查询页子表
  110 +#if ( $table.templateType == 11 )
  111 +/** 获得${subTable.classComment}分页 */
  112 +export function get${subSimpleClassName}Page(params: PageParam) {
  113 + return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
  114 +}
  115 +## 情况二:非 MASTER_ERP 时,需要列表查询子表
  116 +#else
  117 + #if ( $subTable.subJoinMany )
  118 +/** 获得${subTable.classComment}列表 */
  119 +export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  120 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  121 +}
116 #else 122 #else
117 - #if ( $subTable.subJoinMany )  
118 - /** 获得${subTable.classComment}列表 */  
119 - export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {  
120 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);  
121 - }  
122 - #else  
123 - /** 获得${subTable.classComment} */  
124 - export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {  
125 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);  
126 - }  
127 - #end 123 +/** 获得${subTable.classComment} */
  124 +export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  125 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  126 +}
128 #end 127 #end
129 - ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作  
130 - #if ( $table.templateType == 11 )  
131 - /** 新增${subTable.classComment} */  
132 - export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {  
133 - return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);  
134 - } 128 +#end
  129 +## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
  130 +#if ( $table.templateType == 11 )
  131 +/** 新增${subTable.classComment} */
  132 +export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  133 + return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
  134 +}
135 135
136 - /** 修改${subTable.classComment} */  
137 - export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {  
138 - return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);  
139 - } 136 +/** 修改${subTable.classComment} */
  137 +export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  138 + return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
  139 +}
140 140
141 - /** 删除${subTable.classComment} */  
142 - export function delete${subSimpleClassName}(id: number) {  
143 - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);  
144 - } 141 +/** 删除${subTable.classComment} */
  142 +export function delete${subSimpleClassName}(id: number) {
  143 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
  144 +}
  145 +
  146 +/** 获得${subTable.classComment} */
  147 +export function get${subSimpleClassName}(id: number) {
  148 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
  149 +}
  150 +#end
  151 +#end
145 152
146 - /** 获得${subTable.classComment} */  
147 - export function get${subSimpleClassName}(id: number) {  
148 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);  
149 - }  
150 - #end  
151 -#end  
152 \ No newline at end of file 153 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/data.ts.vm 0 → 100644
  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
0 \ No newline at end of file 350 \ 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
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +
  4 +import { useVbenModal } from '@vben/common-ui';
  5 +import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  6 +## 特殊:主子表专属逻辑
  7 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  8 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  9 + #set ($index = $foreach.count - 1)
  10 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  11 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  12 + #end
  13 +#end
  14 +
  15 +import { computed, ref } from 'vue';
  16 +import { $t } from '#/locales';
  17 +import { useVbenForm } from '#/adapter/form';
  18 +import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  19 +
  20 +import { useFormSchema } from '../data';
  21 +
  22 +const emit = defineEmits(['success']);
  23 +const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({
  24 +#foreach ($column in $columns)
  25 + #if ($column.createOperation || $column.updateOperation)
  26 + #if ($column.htmlType == "checkbox")
  27 + $column.javaField: [],
  28 + #else
  29 + $column.javaField: undefined,
  30 + #end
  31 + #end
  32 +#end
  33 +});
  34 +#if (${table.templateType} == 2)## 树表特有:父ID处理
  35 +const parentId = ref<number>(); // 新增下级时的父级 ID
  36 +
  37 +const getTitle = computed(() => {
  38 + if (formData.value?.id) {
  39 + return $t('ui.actionTitle.edit', ['${table.classComment}']);
  40 + }
  41 + return parentId.value
  42 + ? $t('ui.actionTitle.create', ['下级${table.classComment}'])
  43 + : $t('ui.actionTitle.create', ['${table.classComment}']);
  44 +});
  45 +#else## 标准表标题
  46 +const getTitle = computed(() => {
  47 + return formData.value?.id
  48 + ? $t('ui.actionTitle.edit', ['${table.classComment}'])
  49 + : $t('ui.actionTitle.create', ['${table.classComment}']);
  50 +});
  51 +#end
  52 +
  53 +## 特殊:主子表专属逻辑
  54 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  55 + #if ( $subTables && $subTables.size() > 0 )
  56 +
  57 + /** 子表的表单 */
  58 + const subTabsName = ref('$subClassNameVars.get(0)')
  59 + #foreach ($subClassNameVar in $subClassNameVars)
  60 + #set ($index = $foreach.count - 1)
  61 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  62 + const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
  63 + #end
  64 + #end
  65 +#end
  66 +
  67 +const [Modal, modalApi] = useVbenModal({
  68 + async onConfirm() {
  69 + const { valid } = await formApi.validate();
  70 + if (!valid) {
  71 + return;
  72 + }
  73 + ## 特殊:主子表专属逻辑
  74 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  75 + #if ( $subTables && $subTables.size() > 0 )
  76 + // 校验子表单
  77 + #foreach ($subTable in $subTables)
  78 + #set ($index = $foreach.count - 1)
  79 + #set ($subClassNameVar = $subClassNameVars.get($index))
  80 + #if ($subTable.subJoinMany) ## 一对多
  81 + ## TODO 列表值校验?
  82 + #else
  83 + const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();
  84 + if (!${subClassNameVar}Valid) {
  85 + subTabsName.value = '${subClassNameVar}';
  86 + return;
  87 + }
  88 + #end
  89 + #end
  90 + #end
  91 + #end
  92 + modalApi.lock();
  93 + // 提交表单
  94 + const data = formData.value;
  95 + ## 特殊:主子表专属逻辑
  96 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  97 + #if ( $subTables && $subTables.size() > 0 )
  98 + // 拼接子表的数据
  99 + #foreach ($subTable in $subTables)
  100 + #set ($index = $foreach.count - 1)
  101 + #set ($subClassNameVar = $subClassNameVars.get($index))
  102 + #if ($subTable.subJoinMany)
  103 + data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
  104 + #else
  105 + data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues();
  106 + #end
  107 + #end
  108 + #end
  109 + #end
  110 + try {
  111 + await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
  112 + // 关闭并提示
  113 + await modalApi.close();
  114 + emit('success');
  115 + message.success({
  116 + content: $t('ui.actionMessage.operationSuccess'),
  117 + key: 'action_process_msg',
  118 + });
  119 + } finally {
  120 + modalApi.lock(false);
  121 + }
  122 + },
  123 + async onOpenChange(isOpen: boolean) {
  124 + if (!isOpen) {
  125 + formData.value = {
  126 + #foreach ($column in $columns)
  127 + #if ($column.createOperation || $column.updateOperation)
  128 + #if ($column.htmlType == "checkbox")
  129 + $column.javaField: [],
  130 + #else
  131 + $column.javaField: undefined,
  132 + #end
  133 + #end
  134 + #end
  135 + };
  136 + return;
  137 + }
  138 +
  139 + // 加载数据
  140 + let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
  141 + if (!data) {
  142 + return;
  143 + }
  144 + if (data.id) {
  145 + modalApi.lock();
  146 + try {
  147 + data = await get${simpleClassName}(data.id);
  148 + } finally {
  149 + modalApi.lock(false);
  150 + }
  151 + }
  152 + // 设置到 values
  153 + formData.value = data;
  154 + await formApi.setValues(formData.value);
  155 + },
  156 +});
  157 +</script>
  158 +
1 <template> 159 <template>
2 - <Dialog :title="dialogTitle" v-model="dialogVisible"> 160 + <Modal :title="getTitle">
3 <Form 161 <Form
4 ref="formRef" 162 ref="formRef"
5 :model="formData" 163 :model="formData"
@@ -7,294 +165,128 @@ @@ -7,294 +165,128 @@
7 label-col="{ span: 6 }" 165 label-col="{ span: 6 }"
8 :loading="formLoading" 166 :loading="formLoading"
9 > 167 >
10 -#foreach($column in $columns)  
11 - #if ($column.createOperation || $column.updateOperation)  
12 - #set ($dictType = $column.dictType)  
13 - #set ($javaField = $column.javaField)  
14 - #set ($javaType = $column.javaType)  
15 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
16 - #set ($comment = $column.columnComment)  
17 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
18 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short") 168 + #foreach($column in $columns)
  169 + #if ($column.createOperation || $column.updateOperation)
  170 + #set ($dictType = $column.dictType)
  171 + #set ($javaField = $column.javaField)
  172 + #set ($javaType = $column.javaType)
  173 + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  174 + #set ($comment = $column.columnComment)
  175 + #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
  176 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
19 #set ($dictMethod = "getIntDictOptions") 177 #set ($dictMethod = "getIntDictOptions")
20 - #elseif ($javaType == "String") 178 + #elseif ($javaType == "String")
21 #set ($dictMethod = "getStrDictOptions") 179 #set ($dictMethod = "getStrDictOptions")
22 - #elseif ($javaType == "Boolean") 180 + #elseif ($javaType == "Boolean")
23 #set ($dictMethod = "getBoolDictOptions") 181 #set ($dictMethod = "getBoolDictOptions")
24 - #end  
25 - #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )  
26 - <FormItem label="${comment}" name="${javaField}">  
27 - <TreeSelect  
28 - v-model:value="formData.${javaField}"  
29 - :treeData="${classNameVar}Tree"  
30 - #if ($treeNameColumn.javaField == "name")  
31 - :fieldNames="defaultProps"  
32 - #else  
33 - :fieldNames="{...defaultProps, label: '$treeNameColumn.javaField'}"  
34 #end 182 #end
35 - checkable  
36 - treeDefaultExpandAll  
37 - placeholder="请选择${comment}"  
38 - />  
39 - </FormItem>  
40 - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里  
41 - <FormItem label="${comment}" name="${javaField}">  
42 - <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
43 - </FormItem>  
44 - #elseif($column.htmlType == "imageUpload")## 图片上传  
45 - <FormItem label="${comment}" name="${javaField}">  
46 - <UploadImg v-model:value="formData.${javaField}" />  
47 - </FormItem>  
48 - #elseif($column.htmlType == "fileUpload")## 文件上传  
49 - <FormItem label="${comment}" name="${javaField}">  
50 - <UploadFile v-model:value="formData.${javaField}" />  
51 - </FormItem>  
52 - #elseif($column.htmlType == "editor")## 文本编辑器  
53 - <FormItem label="${comment}" name="${javaField}">  
54 - <Editor v-model:value="formData.${javaField}" height="150px" />  
55 - </FormItem>  
56 - #elseif($column.htmlType == "select")## 下拉框  
57 - <FormItem label="${comment}" name="${javaField}">  
58 - <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}"> 183 + #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
  184 + <FormItem label="${comment}" name="${javaField}">
  185 + <TreeSelect
  186 + v-model:value="formData.${javaField}"
  187 + :treeData="${classNameVar}Tree"
  188 + #if ($treeNameColumn.javaField == "name")
  189 + :fieldNames="defaultProps"
  190 + #else
  191 + :fieldNames="{...defaultProps, label: '$treeNameColumn.javaField'}"
  192 + #end
  193 + checkable
  194 + treeDefaultExpandAll
  195 + placeholder="请选择${comment}"
  196 + />
  197 + </FormItem>
  198 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  199 + <FormItem label="${comment}" name="${javaField}">
  200 + <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  201 + </FormItem>
  202 + #elseif($column.htmlType == "imageUpload")## 图片上传
  203 + <FormItem label="${comment}" name="${javaField}">
  204 + <UploadImg v-model:value="formData.${javaField}" />
  205 + </FormItem>
  206 + #elseif($column.htmlType == "fileUpload")## 文件上传
  207 + <FormItem label="${comment}" name="${javaField}">
  208 + <UploadFile v-model:value="formData.${javaField}" />
  209 + </FormItem>
  210 + #elseif($column.htmlType == "editor")## 文本编辑器
  211 + <FormItem label="${comment}" name="${javaField}">
  212 + <Editor v-model:value="formData.${javaField}" height="150px" />
  213 + </FormItem>
  214 + #elseif($column.htmlType == "select")## 下拉框
  215 + <FormItem label="${comment}" name="${javaField}">
  216 + <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
59 #if ("" != $dictType)## 有数据字典 217 #if ("" != $dictType)## 有数据字典
60 - <SelectOption  
61 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
62 - :key="dict.value"  
63 - :label="dict.label"  
64 - :value="dict.value"  
65 - /> 218 + <SelectOption
  219 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  220 + :key="dict.value"
  221 + :label="dict.label"
  222 + :value="dict.value"
  223 + />
66 #else##没数据字典 224 #else##没数据字典
67 - <SelectOption label="请选择字典生成" value="" /> 225 + <SelectOption label="请选择字典生成" value="" />
68 #end 226 #end
69 - </Select>  
70 - </FormItem>  
71 - #elseif($column.htmlType == "checkbox")## 多选框  
72 - <FormItem label="${comment}" name="${javaField}">  
73 - <CheckboxGroup v-model:value="formData.${javaField}"> 227 + </Select>
  228 + </FormItem>
  229 + #elseif($column.htmlType == "checkbox")## 多选框
  230 + <FormItem label="${comment}" name="${javaField}">
  231 + <CheckboxGroup v-model:value="formData.${javaField}">
74 #if ("" != $dictType)## 有数据字典 232 #if ("" != $dictType)## 有数据字典
75 - <Checkbox  
76 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
77 - :key="dict.value"  
78 - :label="dict.label"  
79 - :value="dict.value"  
80 - /> 233 + <Checkbox
  234 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  235 + :key="dict.value"
  236 + :label="dict.label"
  237 + :value="dict.value"
  238 + />
81 #else##没数据字典 239 #else##没数据字典
82 - <Checkbox label="请选择字典生成" /> 240 + <Checkbox label="请选择字典生成" />
83 #end 241 #end
84 - </CheckboxGroup>  
85 - </FormItem>  
86 - #elseif($column.htmlType == "radio")## 单选框  
87 - <FormItem label="${comment}" name="${javaField}">  
88 - <RadioGroup v-model:value="formData.${javaField}"> 242 + </CheckboxGroup>
  243 + </FormItem>
  244 + #elseif($column.htmlType == "radio")## 单选框
  245 + <FormItem label="${comment}" name="${javaField}">
  246 + <RadioGroup v-model:value="formData.${javaField}">
89 #if ("" != $dictType)## 有数据字典 247 #if ("" != $dictType)## 有数据字典
90 - <Radio  
91 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
92 - :key="dict.value"  
93 - :value="dict.value"  
94 - >  
95 - {{ dict.label }}  
96 - </Radio> 248 + <Radio
  249 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  250 + :key="dict.value"
  251 + :value="dict.value"
  252 + >
  253 + {{ dict.label }}
  254 + </Radio>
97 #else##没数据字典 255 #else##没数据字典
98 - <Radio value="1">请选择字典生成</Radio> 256 + <Radio value="1">请选择字典生成</Radio>
99 #end 257 #end
100 - </RadioGroup>  
101 - </FormItem>  
102 - #elseif($column.htmlType == "datetime")## 时间框  
103 - <FormItem label="${comment}" name="${javaField}">  
104 - <DatePicker  
105 - v-model:value="formData.${javaField}"  
106 - valueFormat="x"  
107 - placeholder="选择${comment}"  
108 - />  
109 - </FormItem>  
110 - #elseif($column.htmlType == "textarea")## 文本框  
111 - <FormItem label="${comment}" name="${javaField}">  
112 - <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
113 - </FormItem> 258 + </RadioGroup>
  259 + </FormItem>
  260 + #elseif($column.htmlType == "datetime")## 时间框
  261 + <FormItem label="${comment}" name="${javaField}">
  262 + <DatePicker
  263 + v-model:value="formData.${javaField}"
  264 + valueFormat="x"
  265 + placeholder="选择${comment}"
  266 + />
  267 + </FormItem>
  268 + #elseif($column.htmlType == "textarea")## 文本框
  269 + <FormItem label="${comment}" name="${javaField}">
  270 + <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  271 + </FormItem>
  272 + #end
114 #end 273 #end
115 - #end  
116 -#end 274 + #end
117 </Form> 275 </Form>
118 -## 特殊:主子表专属逻辑  
119 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
120 - <!-- 子表的表单 -->  
121 - <Tabs v-model:activeKey="subTabsName">  
122 - #foreach ($subTable in $subTables)  
123 - #set ($index = $foreach.count - 1)  
124 - #set ($subClassNameVar = $subClassNameVars.get($index))  
125 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
126 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
127 - <TabPane key="$subClassNameVar" tab="${subTable.classComment}">  
128 - <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />  
129 - </TabPane> 276 + ## 特殊:主子表专属逻辑
  277 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  278 + <!-- 子表的表单 -->
  279 + <Tabs v-model:active-key="subTabsName">
  280 + #foreach ($subTable in $subTables)
  281 + #set ($index = $foreach.count - 1)
  282 + #set ($subClassNameVar = $subClassNameVars.get($index))
  283 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  284 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  285 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  286 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
  287 + </Tabs.TabPane>
  288 + #end
  289 + </Tabs>
130 #end 290 #end
131 - </Tabs>  
132 -#end  
133 - <template #footer>  
134 - <Button @click="submitForm" type="primary" :loading="formLoading">确 定</Button>  
135 - <Button @click="dialogVisible = false">取 消</Button>  
136 - </template>  
137 - </Dialog> 291 + </Modal>
138 </template> 292 </template>
139 -<script setup lang="ts">  
140 -import { Form, FormItem, Input, Button, Select, SelectOption, DatePicker, Textarea, Checkbox, CheckboxGroup, Radio, RadioGroup, Tabs, TabPane, TreeSelect } from 'ant-design-vue'  
141 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
142 -import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'  
143 -## 特殊:树表专属逻辑  
144 -#if ( $table.templateType == 2 )  
145 -import { defaultProps, handleTree } from '@/utils/tree'  
146 -#end  
147 -## 特殊:主子表专属逻辑  
148 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
149 -#foreach ($subSimpleClassName in $subSimpleClassNames)  
150 -import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'  
151 -#end  
152 -#end  
153 -  
154 -/** ${table.classComment} 表单 */  
155 -defineOptions({ name: '${simpleClassName}Form' })  
156 -  
157 -const { t } = useI18n() // 国际化  
158 -const message = useMessage() // 消息弹窗  
159 -  
160 -const dialogVisible = ref(false) // 弹窗的是否展示  
161 -const dialogTitle = ref('') // 弹窗的标题  
162 -const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用  
163 -const formType = ref('') // 表单的类型:create - 新增;update - 修改  
164 -const formData = ref({  
165 -#foreach ($column in $columns)  
166 - #if ($column.createOperation || $column.updateOperation)  
167 - #if ($column.htmlType == "checkbox")  
168 - $column.javaField: [],  
169 - #else  
170 - $column.javaField: undefined,  
171 - #end  
172 - #end  
173 -#end  
174 -})  
175 -const formRules = reactive({  
176 -#foreach ($column in $columns)  
177 - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键  
178 - #set($comment=$column.columnComment)  
179 - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],  
180 - #end  
181 -#end  
182 -})  
183 -const formRef = ref() // 表单 Ref  
184 -## 特殊:树表专属逻辑  
185 -#if ( $table.templateType == 2 )  
186 -const ${classNameVar}Tree = ref([]) // 树形结构  
187 -#end  
188 -## 特殊:主子表专属逻辑  
189 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
190 -#if ( $subTables && $subTables.size() > 0 )  
191 -  
192 -/** 子表的表单 */  
193 -const subTabsName = ref('$subClassNameVars.get(0)')  
194 -#foreach ($subClassNameVar in $subClassNameVars)  
195 -const ${subClassNameVar}FormRef = ref()  
196 -#end  
197 -#end  
198 -#end  
199 -  
200 -/** 打开弹窗 */  
201 -const open = async (type: string, id?: number) => {  
202 - dialogVisible.value = true  
203 - dialogTitle.value = t('action.' + type)  
204 - formType.value = type  
205 - resetForm()  
206 - // 修改时,设置数据  
207 - if (id) {  
208 - formLoading.value = true  
209 - try {  
210 - formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)  
211 - } finally {  
212 - formLoading.value = false  
213 - }  
214 - }  
215 -## 特殊:树表专属逻辑  
216 -#if ( $table.templateType == 2 )  
217 - await get${simpleClassName}Tree()  
218 -#end  
219 -}  
220 -defineExpose({ open }) // 提供 open 方法,用于打开弹窗  
221 -  
222 -/** 提交表单 */  
223 -const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调  
224 -const submitForm = async () => {  
225 - // 校验表单  
226 - await formRef.value.validate()  
227 -## 特殊:主子表专属逻辑  
228 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
229 -#if ( $subTables && $subTables.size() > 0 )  
230 - // 校验子表单  
231 - #foreach ($subTable in $subTables)  
232 - #set ($index = $foreach.count - 1)  
233 - #set ($subClassNameVar = $subClassNameVars.get($index))  
234 - try {  
235 - await ${subClassNameVar}FormRef.value.validate()  
236 - } catch (e) {  
237 - subTabsName.value = '${subClassNameVar}'  
238 - return  
239 - }  
240 - #end  
241 -#end  
242 -#end  
243 - // 提交请求  
244 - formLoading.value = true  
245 - try {  
246 - const data = formData.value as unknown as ${simpleClassName}VO  
247 -## 特殊:主子表专属逻辑  
248 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
249 -#if ( $subTables && $subTables.size() > 0 )  
250 - // 拼接子表的数据  
251 - #foreach ($subTable in $subTables)  
252 - #set ($index = $foreach.count - 1)  
253 - #set ($subClassNameVar = $subClassNameVars.get($index))  
254 - data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()  
255 - #end  
256 -#end  
257 -#end  
258 - if (formType.value === 'create') {  
259 - await ${simpleClassName}Api.create${simpleClassName}(data)  
260 - message.success(t('common.createSuccess'))  
261 - } else {  
262 - await ${simpleClassName}Api.update${simpleClassName}(data)  
263 - message.success(t('common.updateSuccess'))  
264 - }  
265 - dialogVisible.value = false  
266 - // 发送操作成功的事件  
267 - emit('success')  
268 - } finally {  
269 - formLoading.value = false  
270 - }  
271 -}  
272 -  
273 -/** 重置表单 */  
274 -const resetForm = () => {  
275 - formData.value = {  
276 -#foreach ($column in $columns)  
277 - #if ($column.createOperation || $column.updateOperation)  
278 - #if ($column.htmlType == "checkbox")  
279 - $column.javaField: [],  
280 - #else  
281 - $column.javaField: undefined,  
282 - #end  
283 - #end  
284 -#end  
285 - }  
286 - formRef.value?.resetFields()  
287 -}  
288 -## 特殊:树表专属逻辑  
289 -#if ( $table.templateType == 2 )  
290 -  
291 -/** 获得${table.classComment}树 */  
292 -const get${simpleClassName}Tree = async () => {  
293 - ${classNameVar}Tree.value = []  
294 - const data = await ${simpleClassName}Api.get${simpleClassName}List()  
295 - const root = { id: 0, name: '顶级${table.classComment}', children: [] }  
296 - root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')  
297 - ${classNameVar}Tree.value.push(root)  
298 -}  
299 -#end  
300 -</script>  
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm
1 -<template>  
2 - <ContentWrap>  
3 - <!-- 搜索工作栏 -->  
4 - <Form  
5 - class="-mb-15px"  
6 - :model="queryParams"  
7 - ref="queryFormRef"  
8 - layout="inline"  
9 - label-col="68px"  
10 - >  
11 - #foreach($column in $columns)  
12 - #if ($column.listOperation)  
13 - #set ($dictType = $column.dictType)  
14 - #set ($javaField = $column.javaField)  
15 - #set ($javaType = $column.javaType)  
16 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
17 - #set ($comment = $column.columnComment)  
18 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
19 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
20 - #set ($dictMethod = "getIntDictOptions")  
21 - #elseif ($javaType == "String")  
22 - #set ($dictMethod = "getStrDictOptions")  
23 - #elseif ($javaType == "Boolean")  
24 - #set ($dictMethod = "getBoolDictOptions")  
25 - #end  
26 - #if ($column.htmlType == "input")  
27 - <FormItem label="${comment}" name="${javaField}">  
28 - <Input  
29 - v-model:value="queryParams.${javaField}"  
30 - placeholder="请输入${comment}"  
31 - allowClear  
32 - @pressEnter="handleQuery"  
33 - class="!w-240px"  
34 - />  
35 - </FormItem>  
36 - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")  
37 - <FormItem label="${comment}" name="${javaField}">  
38 - <Select  
39 - v-model:value="queryParams.${javaField}"  
40 - placeholder="请选择${comment}"  
41 - allowClear  
42 - class="!w-240px"  
43 - >  
44 - #if ("" != $dictType)## 设置了 dictType 数据字典的情况  
45 - <SelectOption  
46 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
47 - :key="dict.value"  
48 - :label="dict.label"  
49 - :value="dict.value"  
50 - />  
51 - #else## 未设置 dictType 数据字典的情况  
52 - <SelectOption label="请选择字典生成" value="" />  
53 - #end  
54 - </Select>  
55 - </FormItem>  
56 - #elseif($column.htmlType == "datetime")  
57 - #if ($column.listOperationCondition != "BETWEEN")## 非范围  
58 - <FormItem label="${comment}" name="${javaField}">  
59 - <DatePicker  
60 - v-model:value="queryParams.${javaField}"  
61 - valueFormat="YYYY-MM-DD"  
62 - placeholder="选择${comment}"  
63 - allowClear  
64 - class="!w-240px"  
65 - />  
66 - </FormItem>  
67 - #else## 范围  
68 - <FormItem label="${comment}" name="${javaField}">  
69 - <RangePicker  
70 - v-model:value="queryParams.${javaField}"  
71 - v-bind="getRangePickerDefaultProps()"  
72 - class="!w-220px"  
73 - />  
74 - </FormItem>  
75 - #end  
76 - #end  
77 - #end  
78 - #end  
79 - <FormItem>  
80 - <Button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</Button>  
81 - <Button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</Button>  
82 - <Button  
83 - type="primary"  
84 - ghost  
85 - @click="openForm('create')"  
86 - v-hasPermi="['${permissionPrefix}:create']"  
87 - >  
88 - <Icon icon="ep:plus" class="mr-5px" /> 新增  
89 - </Button>  
90 - <Button  
91 - type="success"  
92 - ghost  
93 - @click="handleExport"  
94 - :loading="exportLoading"  
95 - v-hasPermi="['${permissionPrefix}:export']"  
96 - >  
97 - <Icon icon="ep:download" class="mr-5px" /> 导出  
98 - </Button>  
99 -## 特殊:树表专属逻辑  
100 -#if ( $table.templateType == 2 )  
101 - <Button type="danger" ghost @click="toggleExpandAll">  
102 - <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠  
103 - </Button>  
104 -#end  
105 - </FormItem>  
106 - </Form>  
107 - </ContentWrap> 1 +<script lang="ts" setup>
  2 +import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-table';
  3 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
108 4
109 - <!-- 列表 -->  
110 - <ContentWrap>  
111 -## 特殊:主子表专属逻辑  
112 -#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )  
113 - <Table  
114 - :loading="loading"  
115 - :dataSource="list"  
116 - :bordered="true"  
117 - :rowClassName="() => 'editable-row'"  
118 - @change="handleCurrentChange"  
119 - >  
120 -## 特殊:树表专属逻辑  
121 -#elseif ( $table.templateType == 2 )  
122 - <Table  
123 - :loading="loading"  
124 - :dataSource="list"  
125 - :bordered="true"  
126 - rowKey="id"  
127 - :expandAllRows="isExpandAll"  
128 - v-if="refreshTable"  
129 - >  
130 -#else  
131 - <Table :loading="loading" :dataSource="list" :bordered="true">  
132 -#end  
133 -## 特殊:主子表专属逻辑  
134 -#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )  
135 - <!-- 子表的列表 -->  
136 - <template #expandedRowRender="{ record }">  
137 - <Tabs defaultActiveKey="$subClassNameVars.get(0)">  
138 - #foreach ($subTable in $subTables)  
139 - #set ($index = $foreach.count - 1)  
140 - #set ($subClassNameVar = $subClassNameVars.get($index))  
141 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
142 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
143 - <TabPane key="$subClassNameVar" tab="${subTable.classComment}">  
144 - <${subSimpleClassName}List :${subJoinColumn_strikeCase}="record.id" />  
145 - </TabPane>  
146 - #end  
147 - </Tabs>  
148 - </template>  
149 -#end  
150 - #foreach($column in $columns)  
151 - #if ($column.listOperationResult)  
152 - #set ($dictType=$column.dictType)  
153 - #set ($javaField = $column.javaField)  
154 - #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
155 - #set ($comment=$column.columnComment)  
156 - #if ($column.javaType == "LocalDateTime")## 时间类型  
157 - <Column  
158 - title="${comment}"  
159 - align="center"  
160 - dataIndex="${javaField}"  
161 - :customRender="({ text }) => dateFormatter(text)"  
162 - width="180px"  
163 - />  
164 - #elseif($column.dictType && "" != $column.dictType)## 数据字典  
165 - <Column title="${comment}" align="center" dataIndex="${javaField}">  
166 - <template #default="{ text, record }">  
167 - <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="record.${column.javaField}" />  
168 - </template>  
169 - </Column>  
170 - #else  
171 - <Column title="${comment}" align="center" dataIndex="${javaField}" />  
172 - #end  
173 - #end  
174 - #end  
175 - <Column title="操作" align="center" key="action" :width="120">  
176 - <template #default="{ record }">  
177 - <Button  
178 - type="link"  
179 - @click="openForm('update', record.id)"  
180 - v-hasPermi="['${permissionPrefix}:update']"  
181 - >  
182 - 编辑  
183 - </Button>  
184 - <Button  
185 - type="link"  
186 - danger  
187 - @click="handleDelete(record.id)"  
188 - v-hasPermi="['${permissionPrefix}:delete']"  
189 - >  
190 - 删除  
191 - </Button>  
192 - </template>  
193 - </Column>  
194 - </Table>  
195 - <!-- 分页 -->  
196 - <Pagination  
197 - :total="total"  
198 - v-model:current="queryParams.pageNo"  
199 - v-model:pageSize="queryParams.pageSize"  
200 - @change="getList"  
201 - />  
202 - </ContentWrap> 5 +import { Page, useVbenModal } from '@vben/common-ui';
  6 +import { Button, message,Tabs } from 'ant-design-vue';
  7 +import { Download, Plus } from '@vben/icons';
  8 +import Form from './modules/form.vue';
203 9
204 - <!-- 表单弹窗:添加/修改 -->  
205 - <${simpleClassName}Form ref="formRef" @success="getList" />  
206 ## 特殊:主子表专属逻辑 10 ## 特殊:主子表专属逻辑
207 -#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )  
208 - <!-- 子表的列表 -->  
209 - <ContentWrap>  
210 - <Tabs defaultActiveKey="$subClassNameVars.get(0)">  
211 - #foreach ($subTable in $subTables)  
212 - #set ($index = $foreach.count - 1)  
213 - #set ($subClassNameVar = $subClassNameVars.get($index))  
214 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
215 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
216 - <TabPane key="$subClassNameVar" tab="${subTable.classComment}">  
217 - <${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />  
218 - </TabPane>  
219 - #end  
220 - </Tabs>  
221 - </ContentWrap> 11 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  12 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  13 + #set ($index = $foreach.count - 1)
  14 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  15 + import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
  16 + #end
222 #end 17 #end
223 -</template>  
224 18
225 -<script setup lang="ts">  
226 -import { Form, FormItem, Input, Button, Table, Column, Select, SelectOption, DatePicker, RangePicker, Tabs, TabPane } from 'ant-design-vue'  
227 -import dayjs from 'dayjs'  
228 -import { getRangePickerDefaultProps } from '@vben/utils'  
229 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
230 -import { dateFormatter } from '@/utils/formatTime'  
231 -## 特殊:树表专属逻辑  
232 -#if ( $table.templateType == 2 )  
233 -import { handleTree } from '@/utils/tree'  
234 -#end  
235 -import download from '@/utils/download'  
236 -import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'  
237 -import ${simpleClassName}Form from './${simpleClassName}Form.vue'  
238 -## 特殊:主子表专属逻辑  
239 -#if ( $table.templateType != 10 )  
240 -#foreach ($subSimpleClassName in $subSimpleClassNames)  
241 -import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue' 19 +import { ref, h } from 'vue';
  20 +import { $t } from '#/locales';
  21 +import { useVbenVxeGrid } from '#/adapter/vxe-table';
  22 +#if (${table.templateType} == 2)## 树表接口
  23 +import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  24 +#else## 标准表接口
  25 +import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
242 #end 26 #end
243 -#end  
244 -  
245 -/** ${table.classComment} 列表 */  
246 -defineOptions({ name: '${table.className}' }) 27 +import { downloadByData } from '#/utils/download';
247 28
248 -const message = useMessage() // 消息弹窗  
249 -const { t } = useI18n() // 国际化 29 +import { useGridColumns, useGridFormSchema } from './data';
250 30
251 -const loading = ref(true) // 列表的加载中  
252 -const list = ref<${simpleClassName}VO[]>([]) // 列表的数据  
253 -## 特殊:树表专属逻辑(树不需要分页接口)  
254 -#if ( $table.templateType != 2 )  
255 -const total = ref(0) // 列表的总页数 31 +#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
  32 +/** 子表的列表 */
  33 +const subTabsName = ref('$subClassNameVars.get(0)')
  34 +#if ($table.templateType == 11)
  35 +const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
256 #end 36 #end
257 -const queryParams = reactive({  
258 -## 特殊:树表专属逻辑(树不需要分页接口)  
259 -#if ( $table.templateType != 2 )  
260 - pageNo: 1,  
261 - pageSize: 10,  
262 #end 37 #end
263 - #foreach ($column in $columns)  
264 - #if ($column.listOperation)  
265 - #if ($column.listOperationCondition != 'BETWEEN')  
266 - $column.javaField: undefined,  
267 - #end  
268 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
269 - $column.javaField: [],  
270 - #end  
271 - #end  
272 - #end  
273 -})  
274 -const queryFormRef = ref() // 搜索的表单  
275 -const exportLoading = ref(false) // 导出的加载中  
276 38
277 -/** 查询列表 */  
278 -const getList = async () => {  
279 - loading.value = true  
280 - try {  
281 -## 特殊:树表专属逻辑(树不需要分页接口)  
282 - #if ( $table.templateType == 2 )  
283 - const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)  
284 - list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')  
285 - #else  
286 - const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)  
287 - list.value = data.list  
288 - total.value = data.total  
289 - #end  
290 - } finally {  
291 - loading.value = false  
292 - } 39 +const [FormModal, formModalApi] = useVbenModal({
  40 + connectedComponent: Form,
  41 + destroyOnClose: true,
  42 +});
  43 +
  44 +#if (${table.templateType} == 2)## 树表特有:控制表格展开收缩
  45 +/** 切换树形展开/收缩状态 */
  46 +const isExpanded = ref(true);
  47 +function toggleExpand() {
  48 + isExpanded.value = !isExpanded.value;
  49 + gridApi.grid.setAllTreeExpand(isExpanded.value);
293 } 50 }
  51 +#end
294 52
295 -/** 搜索按钮操作 */  
296 -const handleQuery = () => {  
297 - queryParams.pageNo = 1  
298 - getList() 53 +/** 刷新表格 */
  54 +function onRefresh() {
  55 +#if ($table.templateType == 12) ## 内嵌情况
  56 + gridApi.reload();
  57 +#else
  58 + gridApi.query();
  59 +#end
299 } 60 }
300 61
301 -/** 重置按钮操作 */  
302 -const resetQuery = () => {  
303 - queryFormRef.value.resetFields()  
304 - handleQuery() 62 +/** 创建${table.classComment} */
  63 +function onCreate() {
  64 + formModalApi.setData({}).open();
305 } 65 }
306 66
307 -/** 添加/修改操作 */  
308 -const formRef = ref()  
309 -const openForm = (type: string, id?: number) => {  
310 - formRef.value.open(type, id) 67 +/** 编辑${table.classComment} */
  68 +function onEdit(row: ${simpleClassName}Api.${simpleClassName}) {
  69 + formModalApi.setData(row).open();
311 } 70 }
312 71
313 -/** 删除按钮操作 */  
314 -const handleDelete = async (id: number) => {  
315 - try {  
316 - // 删除的二次确认  
317 - await message.delConfirm()  
318 - // 发起删除  
319 - await ${simpleClassName}Api.delete${simpleClassName}(id)  
320 - message.success(t('common.delSuccess'))  
321 - // 刷新列表  
322 - await getList()  
323 - } catch {} 72 +#if (${table.templateType} == 2)## 树表特有:新增下级
  73 +/** 新增下级${table.classComment} */
  74 +function onAppend(row: ${simpleClassName}Api.${simpleClassName}) {
  75 + formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
324 } 76 }
  77 +#end
325 78
326 -/** 导出按钮操作 */  
327 -const handleExport = async () => { 79 +/** 删除${table.classComment} */
  80 +async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
  81 + const hideLoading = message.loading({
  82 + content: $t('ui.actionMessage.deleting', [row.id]),
  83 + duration: 0,
  84 + key: 'action_process_msg',
  85 + });
328 try { 86 try {
329 - // 导出的二次确认  
330 - await message.exportConfirm()  
331 - // 发起导出  
332 - exportLoading.value = true  
333 - const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)  
334 - download.excel(data, '${table.classComment}.xls') 87 + await delete${simpleClassName}(row.id as number);
  88 + message.success({
  89 + content: $t('ui.actionMessage.deleteSuccess', [row.id]),
  90 + key: 'action_process_msg',
  91 + });
  92 + onRefresh();
335 } catch { 93 } catch {
336 - } finally {  
337 - exportLoading.value = false 94 + hideLoading();
338 } 95 }
339 } 96 }
340 -## 特殊:主子表专属逻辑  
341 -#if ( $table.templateType == 11 )  
342 97
343 -/** 选中行操作 */  
344 -const currentRow = ref({}) // 选中行  
345 -const handleCurrentChange = (row) => {  
346 - currentRow.value = row 98 +/** 导出表格 */
  99 +async function onExport() {
  100 + const data = await export${simpleClassName}(await gridApi.formApi.getValues());
  101 + downloadByData(data, '${table.classComment}.xls');
347 } 102 }
348 -#end  
349 -## 特殊:树表专属逻辑  
350 -#if ( $table.templateType == 2 )  
351 103
352 -/** 展开/折叠操作 */  
353 -const isExpandAll = ref(true) // 是否展开,默认全部展开  
354 -const refreshTable = ref(true) // 重新渲染表格状态  
355 -const toggleExpandAll = async () => {  
356 - refreshTable.value = false  
357 - isExpandAll.value = !isExpandAll.value  
358 - await nextTick()  
359 - refreshTable.value = true 104 +/** 表格操作按钮的回调函数 */
  105 +function onActionClick({
  106 + code,
  107 + row,
  108 +}: OnActionClickParams<${simpleClassName}Api.${simpleClassName}>) {
  109 + switch (code) {
  110 + #if (${table.templateType} == 2)## 树表特有:新增下级
  111 + case 'append': {
  112 + onAppend(row);
  113 + break;
  114 + }
  115 + #end
  116 + case 'edit': {
  117 + onEdit(row);
  118 + break;
  119 + }
  120 + case 'delete': {
  121 + onDelete(row);
  122 + break;
  123 + }
  124 + }
360 } 125 }
361 -#end  
362 126
363 -/** 初始化 **/  
364 -onMounted(() => {  
365 - getList()  
366 -}) 127 +const [Grid, gridApi] = useVbenVxeGrid({
  128 + formOptions: {
  129 + schema: useGridFormSchema(),
  130 + },
  131 + gridOptions: {
  132 + columns: useGridColumns(onActionClick),
  133 +#if (${table.templateType} == 11)
  134 + height: '600px',
  135 +#else
  136 + height: 'auto',
  137 +#end
  138 +#if (${table.templateType} == 2)## 树表设置
  139 + treeConfig: {
  140 + parentField: '${treeParentColumn.javaField}',
  141 + rowField: 'id',
  142 + transform: true,
  143 + expandAll: true,
  144 + reserve: true,
  145 + },
  146 + pagerConfig: {
  147 + enabled: false,
  148 + },
  149 +#else## 标准表设置
  150 + pagerConfig: {
  151 + enabled: true,
  152 + },
  153 +#end
  154 + proxyConfig: {
  155 + ajax: {
  156 +#if (${table.templateType} == 2)## 树表数据加载
  157 + query: async (_, formValues) => {
  158 + return await get${simpleClassName}List(formValues);
  159 + },
  160 +#else## 标准表数据加载
  161 + query: async ({ page }, formValues) => {
  162 + return await get${simpleClassName}Page({
  163 + pageNo: page.currentPage,
  164 + pageSize: page.pageSize,
  165 + ...formValues,
  166 + });
  167 + },
  168 +#end
  169 + },
  170 + },
  171 + rowConfig: {
  172 + keyField: 'id',
  173 + isHover: true,
  174 +#if (${table.templateType} == 11)
  175 + isCurrent: true,
  176 +#end
  177 + },
  178 + toolbarConfig: {
  179 + refresh: { code: 'query' },
  180 + search: true,
  181 + },
  182 + } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,
  183 +#if (${table.templateType} == 11)
  184 + gridEvents:{
  185 + cellClick: ({ row }: { row: ${simpleClassName}Api.${simpleClassName}}) => {
  186 + select${simpleClassName}.value = row;
  187 + },
  188 + }
  189 +#end
  190 +});
367 </script> 191 </script>
  192 +
  193 +<template>
  194 + <Page auto-content-height>
  195 + <FormModal @success="onRefresh" />
  196 +
  197 +#if ($table.templateType == 11) ## erp情况
  198 + <div>
  199 +#end
  200 + <Grid table-title="${table.classComment}列表">
  201 + #if ($table.templateType == 12) ## 内嵌情况
  202 + <template #expand_content="{ row }">
  203 + <!-- 子表的表单 -->
  204 + <Tabs v-model:active-key="subTabsName" class="mx-8">
  205 + #foreach ($subTable in $subTables)
  206 + #set ($index = $foreach.count - 1)
  207 + #set ($subClassNameVar = $subClassNameVars.get($index))
  208 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  209 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  210 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  211 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
  212 + </Tabs.TabPane>
  213 + #end
  214 + </Tabs>
  215 + </template>
  216 + #end
  217 + <template #toolbar-tools>
  218 +#if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
  219 + <Button @click="toggleExpand" class="mr-2">
  220 + {{ isExpanded ? '收缩' : '展开' }}
  221 + </Button>
  222 +#end
  223 + <Button :icon="h(Plus)" type="primary" @click="onCreate" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:create']">
  224 + {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
  225 + </Button>
  226 + <Button
  227 + :icon="h(Download)"
  228 + type="primary"
  229 + class="ml-2"
  230 + @click="onExport"
  231 + v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:export']"
  232 + >
  233 + {{ $t('ui.actionTitle.export') }}
  234 + </Button>
  235 + </template>
  236 + </Grid>
  237 +
  238 +#if ($table.templateType == 11) ## erp情况
  239 + <!-- 子表的表单 -->
  240 + <Tabs v-model:active-key="subTabsName" class="mt-2">
  241 + #foreach ($subTable in $subTables)
  242 + #set ($index = $foreach.count - 1)
  243 + #set ($subClassNameVar = $subClassNameVars.get($index))
  244 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  245 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  246 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  247 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
  248 + </Tabs.TabPane>
  249 + #end
  250 + </Tabs>
  251 + </div>
  252 +#end
  253 + </Page>
  254 +</template>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
1 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
2 -#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))  
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 -<template>  
5 - <Dialog :title="dialogTitle" v-model="dialogVisible">  
6 - <Form  
7 - ref="formRef"  
8 - :model="formData"  
9 - :rules="formRules"  
10 - label-col="{ span: 6 }"  
11 - :loading="formLoading"  
12 - >  
13 -#foreach($column in $subColumns)  
14 - #if ($column.createOperation || $column.updateOperation)  
15 - #set ($dictType = $column.dictType)  
16 - #set ($javaField = $column.javaField)  
17 - #set ($javaType = $column.javaType)  
18 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
19 - #set ($comment = $column.columnComment)  
20 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
21 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
22 - #set ($dictMethod = "getIntDictOptions")  
23 - #elseif ($javaType == "String")  
24 - #set ($dictMethod = "getStrDictOptions")  
25 - #elseif ($javaType == "Boolean")  
26 - #set ($dictMethod = "getBoolDictOptions")  
27 - #end  
28 - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
29 - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里  
30 - <FormItem label="${comment}" name="${javaField}">  
31 - <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
32 - </FormItem>  
33 - #elseif($column.htmlType == "imageUpload")## 图片上传  
34 - <FormItem label="${comment}" name="${javaField}">  
35 - <UploadImg v-model:value="formData.${javaField}" />  
36 - </FormItem>  
37 - #elseif($column.htmlType == "fileUpload")## 文件上传  
38 - <FormItem label="${comment}" name="${javaField}">  
39 - <UploadFile v-model:value="formData.${javaField}" />  
40 - </FormItem>  
41 - #elseif($column.htmlType == "editor")## 文本编辑器  
42 - <FormItem label="${comment}" name="${javaField}">  
43 - <Editor v-model:value="formData.${javaField}" height="150px" />  
44 - </FormItem>  
45 - #elseif($column.htmlType == "select")## 下拉框  
46 - <FormItem label="${comment}" name="${javaField}">  
47 - <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">  
48 - #if ("" != $dictType)## 有数据字典  
49 - <SelectOption  
50 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
51 - :key="dict.value"  
52 - :label="dict.label"  
53 - :value="dict.value"  
54 - />  
55 - #else##没数据字典  
56 - <SelectOption label="请选择字典生成" value="" />  
57 - #end  
58 - </Select>  
59 - </FormItem>  
60 - #elseif($column.htmlType == "checkbox")## 多选框  
61 - <FormItem label="${comment}" name="${javaField}">  
62 - <CheckboxGroup v-model:value="formData.${javaField}">  
63 - #if ("" != $dictType)## 有数据字典  
64 - <Checkbox  
65 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
66 - :key="dict.value"  
67 - :label="dict.label"  
68 - :value="dict.value"  
69 - />  
70 - #else##没数据字典  
71 - <Checkbox label="请选择字典生成" />  
72 - #end  
73 - </CheckboxGroup>  
74 - </FormItem>  
75 - #elseif($column.htmlType == "radio")## 单选框  
76 - <FormItem label="${comment}" name="${javaField}">  
77 - <RadioGroup v-model:value="formData.${javaField}">  
78 - #if ("" != $dictType)## 有数据字典  
79 - <Radio  
80 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
81 - :key="dict.value"  
82 - :value="dict.value"  
83 - >  
84 - {{ dict.label }}  
85 - </Radio>  
86 - #else##没数据字典  
87 - <Radio value="1">请选择字典生成</Radio>  
88 - #end  
89 - </RadioGroup>  
90 - </FormItem>  
91 - #elseif($column.htmlType == "datetime")## 时间框  
92 - <FormItem label="${comment}" name="${javaField}">  
93 - <DatePicker  
94 - v-model:value="formData.${javaField}"  
95 - valueFormat="x"  
96 - placeholder="选择${comment}"  
97 - />  
98 - </FormItem>  
99 - #elseif($column.htmlType == "textarea")## 文本框  
100 - <FormItem label="${comment}" name="${javaField}">  
101 - <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
102 - </FormItem>  
103 - #end  
104 - #end  
105 -#end  
106 - </Form>  
107 - <template #footer>  
108 - <Button @click="submitForm" type="primary" :loading="formLoading">确 定</Button>  
109 - <Button @click="dialogVisible = false">取 消</Button>  
110 - </template>  
111 - </Dialog>  
112 -</template>  
113 -<script setup lang="ts">  
114 -import { Form, FormItem, Input, Button, Select, SelectOption, DatePicker, Textarea, Checkbox, CheckboxGroup, Radio, RadioGroup } from 'ant-design-vue'  
115 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
116 -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}' 4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +<script lang="ts" setup>
  6 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  7 +
  8 + import { useVbenModal } from '@vben/common-ui';
  9 + import { message } from 'ant-design-vue';
117 10
118 -const { t } = useI18n() // 国际化  
119 -const message = useMessage() // 消息弹窗 11 + import { computed, ref } from 'vue';
  12 + import { $t } from '#/locales';
  13 + import { useVbenForm } from '#/adapter/form';
  14 + import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
120 15
121 -const dialogVisible = ref(false) // 弹窗的是否展示  
122 -const dialogTitle = ref('') // 弹窗的标题  
123 -const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用  
124 -const formType = ref('') // 表单的类型:create - 新增;update - 修改  
125 -const formData = ref({  
126 -#foreach ($column in $subColumns)  
127 - #if ($column.createOperation || $column.updateOperation)  
128 - #if ($column.htmlType == "checkbox")  
129 - $column.javaField: [],  
130 - #else  
131 - $column.javaField: undefined,  
132 - #end  
133 - #end  
134 -#end  
135 -})  
136 -const formRules = reactive({  
137 -#foreach ($column in $subColumns)  
138 - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键  
139 - #set($comment=$column.columnComment)  
140 - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],  
141 - #end  
142 -#end  
143 -})  
144 -const formRef = ref() // 表单 Ref 16 + import { use${subSimpleClassName}FormSchema } from '../data';
145 17
146 -/** 打开弹窗 */  
147 -const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {  
148 - dialogVisible.value = true  
149 - dialogTitle.value = t('action.' + type)  
150 - formType.value = type  
151 - resetForm()  
152 - formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}  
153 - // 修改时,设置数据  
154 - if (id) {  
155 - formLoading.value = true  
156 - try {  
157 - formData.value = await ${simpleClassName}Api.get${subSimpleClassName}(id)  
158 - } finally {  
159 - formLoading.value = false  
160 - }  
161 - }  
162 -}  
163 -defineExpose({ open }) // 提供 open 方法,用于打开弹窗 18 + const emit = defineEmits(['success']);
  19 + const formData = ref<${simpleClassName}Api.${subSimpleClassName}>();
  20 + const getTitle = computed(() => {
  21 + return formData.value?.id
  22 + ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
  23 + : $t('ui.actionTitle.create', ['${subTable.classComment}']);
  24 + });
164 25
165 -/** 提交表单 */  
166 -const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调  
167 -const submitForm = async () => {  
168 - // 校验表单  
169 - await formRef.value.validate()  
170 - // 提交请求  
171 - formLoading.value = true  
172 - try {  
173 - const data = formData.value  
174 - if (formType.value === 'create') {  
175 - await ${simpleClassName}Api.create${subSimpleClassName}(data)  
176 - message.success(t('common.createSuccess'))  
177 - } else {  
178 - await ${simpleClassName}Api.update${subSimpleClassName}(data)  
179 - message.success(t('common.updateSuccess'))  
180 - }  
181 - dialogVisible.value = false  
182 - // 发送操作成功的事件  
183 - emit('success')  
184 - } finally {  
185 - formLoading.value = false  
186 - }  
187 -} 26 + const [Form, formApi] = useVbenForm({
  27 + layout: 'horizontal',
  28 + schema: use${subSimpleClassName}FormSchema(),
  29 + showDefaultActions: false
  30 + });
188 31
189 -/** 重置表单 */  
190 -const resetForm = () => {  
191 - formData.value = {  
192 -#foreach ($column in $subColumns)  
193 - #if ($column.createOperation || $column.updateOperation)  
194 - #if ($column.htmlType == "checkbox")  
195 - $column.javaField: [],  
196 - #else  
197 - $column.javaField: undefined,  
198 - #end  
199 - #end  
200 -#end  
201 - }  
202 - formRef.value?.resetFields()  
203 -} 32 + const [Modal, modalApi] = useVbenModal({
  33 + async onConfirm() {
  34 + const { valid } = await formApi.validate();
  35 + if (!valid) {
  36 + return;
  37 + }
  38 +
  39 + modalApi.lock();
  40 + // 提交表单
  41 + const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName};
  42 + data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
  43 + try {
  44 + await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
  45 + // 关闭并提示
  46 + await modalApi.close();
  47 + emit('success');
  48 + message.success({
  49 + content: $t('ui.actionMessage.operationSuccess'),
  50 + key: 'action_process_msg',
  51 + });
  52 + } finally {
  53 + modalApi.lock(false);
  54 + }
  55 + },
  56 + async onOpenChange(isOpen: boolean) {
  57 + if (!isOpen) {
  58 + formData.value = undefined;
  59 + return;
  60 + }
  61 +
  62 + // 加载数据
  63 + let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
  64 + if (!data) {
  65 + return;
  66 + }
  67 + if (data.id) {
  68 + modalApi.lock();
  69 + try {
  70 + data = await get${subSimpleClassName}(data.id);
  71 + } finally {
  72 + modalApi.lock(false);
  73 + }
  74 + }
  75 + // 设置到 values
  76 + formData.value = data;
  77 + await formApi.setValues(formData.value);
  78 + },
  79 + });
204 </script> 80 </script>
  81 +
  82 +<template>
  83 + <Modal :title="getTitle">
  84 + <Form class="mx-4" />
  85 + </Modal>
  86 +</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/general/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/schema/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
@@ -2,361 +2,191 @@ @@ -2,361 +2,191 @@
2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 -#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7 -<template>  
8 -#if ( $subTable.subJoinMany )## 情况一:一对多,table + form  
9 - <Form  
10 - ref="formRef"  
11 - :model="formData"  
12 - :rules="formRules"  
13 - :loading="formLoading"  
14 - label-col="{ span: 0 }"  
15 - >  
16 - <Table :dataSource="formData" class="-mt-10px">  
17 - <Column title="序号" width="100">  
18 - <template #customRender="{ index }">  
19 - {{ index + 1 }}  
20 - </template>  
21 - </Column>  
22 -#foreach($column in $subColumns)  
23 - #if ($column.createOperation || $column.updateOperation)  
24 - #set ($dictType = $column.dictType)  
25 - #set ($javaField = $column.javaField)  
26 - #set ($javaType = $column.javaType)  
27 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
28 - #set ($comment = $column.columnComment)  
29 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
30 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
31 - #set ($dictMethod = "getIntDictOptions")  
32 - #elseif ($javaType == "String")  
33 - #set ($dictMethod = "getStrDictOptions")  
34 - #elseif ($javaType == "Boolean")  
35 - #set ($dictMethod = "getBoolDictOptions")  
36 - #end  
37 - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
38 - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里  
39 - <Column title="${comment}" :minWidth="150">  
40 - <template #customRender="{ record, index }">  
41 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
42 - <Input v-model:value="record.${javaField}" placeholder="请输入${comment}" />  
43 - </FormItem>  
44 - </template>  
45 - </Column>  
46 - #elseif($column.htmlType == "imageUpload")## 图片上传  
47 - <Column title="${comment}" :minWidth="200">  
48 - <template #customRender="{ record, index }">  
49 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
50 - <UploadImg v-model:value="record.${javaField}" />  
51 - </FormItem>  
52 - </template>  
53 - </Column>  
54 - #elseif($column.htmlType == "fileUpload")## 文件上传  
55 - <Column title="${comment}" :minWidth="200">  
56 - <template #customRender="{ record, index }">  
57 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
58 - <UploadFile v-model:value="record.${javaField}" />  
59 - </FormItem>  
60 - </template>  
61 - </Column>  
62 - #elseif($column.htmlType == "editor")## 文本编辑器  
63 - <Column title="${comment}" :minWidth="400">  
64 - <template #customRender="{ record, index }">  
65 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
66 - <Editor v-model:value="record.${javaField}" height="150px" />  
67 - </FormItem>  
68 - </template>  
69 - </Column>  
70 - #elseif($column.htmlType == "select")## 下拉框  
71 - <Column title="${comment}" :minWidth="150">  
72 - <template #customRender="{ record, index }">  
73 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
74 - <Select v-model:value="record.${javaField}" placeholder="请选择${comment}">  
75 - #if ("" != $dictType)## 有数据字典  
76 - <SelectOption  
77 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
78 - :key="dict.value"  
79 - :label="dict.label"  
80 - :value="dict.value"  
81 - />  
82 - #else##没数据字典  
83 - <SelectOption label="请选择字典生成" value="" />  
84 - #end  
85 - </Select>  
86 - </FormItem>  
87 - </template>  
88 - </Column>  
89 - #elseif($column.htmlType == "checkbox")## 多选框  
90 - <Column title="${comment}" :minWidth="150">  
91 - <template #customRender="{ record, index }">  
92 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
93 - <CheckboxGroup v-model:value="record.${javaField}">  
94 - #if ("" != $dictType)## 有数据字典  
95 - <Checkbox  
96 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
97 - :key="dict.value"  
98 - :label="dict.label"  
99 - :value="dict.value"  
100 - />  
101 - #else##没数据字典  
102 - <Checkbox label="请选择字典生成" />  
103 - #end  
104 - </CheckboxGroup>  
105 - </FormItem>  
106 - </template>  
107 - </Column>  
108 - #elseif($column.htmlType == "radio")## 单选框  
109 - <Column title="${comment}" :minWidth="150">  
110 - <template #customRender="{ record, index }">  
111 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
112 - <RadioGroup v-model:value="record.${javaField}">  
113 - #if ("" != $dictType)## 有数据字典  
114 - <Radio  
115 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
116 - :key="dict.value"  
117 - :value="dict.value"  
118 - >  
119 - {{ dict.label }}  
120 - </Radio>  
121 - #else##没数据字典  
122 - <Radio value="1">请选择字典生成</Radio>  
123 - #end  
124 - </RadioGroup>  
125 - </FormItem>  
126 - </template>  
127 - </Column>  
128 - #elseif($column.htmlType == "datetime")## 时间框  
129 - <Column title="${comment}" :minWidth="150">  
130 - <template #customRender="{ record, index }">  
131 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
132 - <DatePicker  
133 - v-model:value="record.${javaField}"  
134 - valueFormat="x"  
135 - placeholder="选择${comment}"  
136 - />  
137 - </FormItem>  
138 - </template>  
139 - </Column>  
140 - #elseif($column.htmlType == "textarea")## 文本框  
141 - <Column title="${comment}" :minWidth="200">  
142 - <template #customRender="{ record, index }">  
143 - <FormItem :name="[index, '${javaField}']" :rules="formRules.${javaField}" class="mb-0px!">  
144 - <Textarea v-model:value="record.${javaField}" placeholder="请输入${comment}" />  
145 - </FormItem>  
146 - </template>  
147 - </Column>  
148 - #end  
149 - #end  
150 -#end  
151 - <Column align="center" fixed="right" title="操作" width="60">  
152 - <template #customRender="{ index }">  
153 - <Button @click="handleDelete(index)" type="link">—</Button>  
154 - </template>  
155 - </Column>  
156 - </Table>  
157 - </Form>  
158 - <Row justify="center" class="mt-3">  
159 - <Button @click="handleAdd" shape="round">+ 添加${subTable.classComment}</Button>  
160 - </Row>  
161 -#else## 情况二:一对一,form  
162 - <Form  
163 - ref="formRef"  
164 - :model="formData"  
165 - :rules="formRules"  
166 - label-col="{ span: 6 }"  
167 - :loading="formLoading"  
168 - >  
169 -#foreach($column in $subColumns)  
170 - #if ($column.createOperation || $column.updateOperation)  
171 - #set ($dictType = $column.dictType)  
172 - #set ($javaField = $column.javaField)  
173 - #set ($javaType = $column.javaType)  
174 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
175 - #set ($comment = $column.columnComment)  
176 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
177 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
178 - #set ($dictMethod = "getIntDictOptions")  
179 - #elseif ($javaType == "String")  
180 - #set ($dictMethod = "getStrDictOptions")  
181 - #elseif ($javaType == "Boolean")  
182 - #set ($dictMethod = "getBoolDictOptions")  
183 - #end  
184 - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
185 - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里  
186 - <FormItem label="${comment}" name="${javaField}">  
187 - <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
188 - </FormItem>  
189 - #elseif($column.htmlType == "imageUpload")## 图片上传  
190 - <FormItem label="${comment}" name="${javaField}">  
191 - <UploadImg v-model:value="formData.${javaField}" />  
192 - </FormItem>  
193 - #elseif($column.htmlType == "fileUpload")## 文件上传  
194 - <FormItem label="${comment}" name="${javaField}">  
195 - <UploadFile v-model:value="formData.${javaField}" />  
196 - </FormItem>  
197 - #elseif($column.htmlType == "editor")## 文本编辑器  
198 - <FormItem label="${comment}" name="${javaField}">  
199 - <Editor v-model:value="formData.${javaField}" height="150px" />  
200 - </FormItem>  
201 - #elseif($column.htmlType == "select")## 下拉框  
202 - <FormItem label="${comment}" name="${javaField}">  
203 - <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">  
204 - #if ("" != $dictType)## 有数据字典  
205 - <SelectOption  
206 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
207 - :key="dict.value"  
208 - :label="dict.label"  
209 - :value="dict.value"  
210 - />  
211 - #else##没数据字典  
212 - <SelectOption label="请选择字典生成" value="" />  
213 - #end  
214 - </Select>  
215 - </FormItem>  
216 - #elseif($column.htmlType == "checkbox")## 多选框  
217 - <FormItem label="${comment}" name="${javaField}">  
218 - <CheckboxGroup v-model:value="formData.${javaField}">  
219 - #if ("" != $dictType)## 有数据字典  
220 - <Checkbox  
221 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
222 - :key="dict.value"  
223 - :label="dict.label"  
224 - :value="dict.value"  
225 - />  
226 - #else##没数据字典  
227 - <Checkbox label="请选择字典生成" />  
228 - #end  
229 - </CheckboxGroup>  
230 - </FormItem>  
231 - #elseif($column.htmlType == "radio")## 单选框  
232 - <FormItem label="${comment}" name="${javaField}">  
233 - <RadioGroup v-model:value="formData.${javaField}">  
234 - #if ("" != $dictType)## 有数据字典  
235 - <Radio  
236 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
237 - :key="dict.value"  
238 - :value="dict.value"  
239 - >  
240 - {{ dict.label }}  
241 - </Radio>  
242 - #else##没数据字典  
243 - <Radio value="1">请选择字典生成</Radio>  
244 - #end  
245 - </RadioGroup>  
246 - </FormItem>  
247 - #elseif($column.htmlType == "datetime")## 时间框  
248 - <FormItem label="${comment}" name="${javaField}">  
249 - <DatePicker  
250 - v-model:value="formData.${javaField}"  
251 - valueFormat="x"  
252 - placeholder="选择${comment}"  
253 - />  
254 - </FormItem>  
255 - #elseif($column.htmlType == "textarea")## 文本框  
256 - <FormItem label="${comment}" name="${javaField}">  
257 - <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />  
258 - </FormItem>  
259 - #end  
260 - #end  
261 -#end  
262 - </Form> 7 +<script lang="ts" setup>
  8 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  9 +
  10 + import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  11 + import { $t } from '#/locales';
  12 +
  13 +#if ($subTable.subJoinMany) ## 一对多
  14 +import { Plus } from "@vben/icons";
  15 +import { Button, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  16 +import type { OnActionClickParams } from '#/adapter/vxe-table';
  17 +import { useVbenVxeGrid } from '#/adapter/vxe-table';
  18 +import { use${subSimpleClassName}GridEditColumns } from '../data';
  19 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  20 +#else
  21 +import { useVbenForm } from '#/adapter/form';
  22 +import { use${subSimpleClassName}FormSchema } from '../data';
  23 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
263 #end 24 #end
264 -</template>  
265 -<script setup lang="ts">  
266 -import { Form, FormItem, Input, Button, Table, Column, Select, SelectOption, DatePicker, Textarea, Checkbox, CheckboxGroup, Radio, RadioGroup, Row } from 'ant-design-vue'  
267 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
268 -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'  
269 25
270 const props = defineProps<{ 26 const props = defineProps<{
271 - ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) 27 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
272 }>() 28 }>()
273 -const formLoading = ref(false) // 表单的加载中  
274 -const formData = ref([])  
275 -const formRules = reactive({  
276 -#foreach ($column in $subColumns)  
277 - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键  
278 - #set($comment=$column.columnComment)  
279 - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],  
280 - #end  
281 -#end  
282 -})  
283 -const formRef = ref() // 表单 Ref  
284 29
285 -/** 监听主表的关联字段的变化,加载对应的子表数据 */  
286 -watch(  
287 - () => props.${subJoinColumn.javaField},  
288 - async (val) => {  
289 - // 1. 重置表单  
290 -#if ( $subTable.subJoinMany )  
291 - formData.value = []  
292 -#else  
293 - formData.value = {  
294 - #foreach ($column in $subColumns)  
295 - #if ($column.createOperation || $column.updateOperation)  
296 - #if ($column.htmlType == "checkbox")  
297 - $column.javaField: [],  
298 - #else  
299 - $column.javaField: undefined,  
300 - #end  
301 - #end  
302 - #end 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;
303 } 40 }
304 -#end  
305 - // 2. val 非空,则加载数据  
306 - if (!val) {  
307 - return;  
308 - }  
309 - try {  
310 - formLoading.value = true  
311 -#if ( $subTable.subJoinMany )  
312 - formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)  
313 -#else  
314 - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)  
315 - if (!data) {  
316 - return  
317 - }  
318 - formData.value = data  
319 -#end  
320 - } finally {  
321 - formLoading.value = false  
322 - }  
323 - },  
324 - { immediate: true }  
325 -)  
326 -#if ( $subTable.subJoinMany )  
327 -  
328 -/** 新增按钮操作 */  
329 -const handleAdd = () => {  
330 - const row = {  
331 -#foreach ($column in $subColumns)  
332 - #if ($column.createOperation || $column.updateOperation)  
333 - #if ($column.htmlType == "checkbox")  
334 - $column.javaField: [],  
335 - #else  
336 - $column.javaField: undefined,  
337 - #end  
338 - #end  
339 -#end  
340 } 41 }
341 - row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}  
342 - formData.value.push(row)  
343 } 42 }
344 43
345 -/** 删除按钮操作 */  
346 -const handleDelete = (index) => {  
347 - formData.value.splice(index, 1)  
348 -}  
349 -#end 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 +});
350 62
351 -/** 表单校验 */  
352 -const validate = () => {  
353 - return formRef.value.validate() 63 +/** 添加${subTable.classComment} */
  64 +const onAdd = async () => {
  65 + await gridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
354 } 66 }
355 67
356 -/** 表单值 */  
357 -const getData = () => {  
358 - return formData.value 68 +/** 删除${subTable.classComment} */
  69 +const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
  70 + await gridApi.grid.remove(row);
359 } 71 }
360 72
361 -defineExpose({ validate, getData }) 73 +/** 提供获取表格数据的方法供父组件调用 */
  74 +defineExpose({
  75 + 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}[];
  79 + return data
  80 + .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
  81 + .concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
  82 + },
  83 +});
  84 +
  85 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  86 +watch(
  87 + () => props.${subJoinColumn.javaField},
  88 + async (val) => {
  89 + if (!val) {
  90 + return;
  91 + }
  92 + await nextTick();
  93 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  94 + },
  95 + { immediate: true },
  96 +);
  97 +#else
  98 +const [Form, formApi] = useVbenForm({
  99 +layout: 'horizontal',
  100 +schema: use${subSimpleClassName}FormSchema(),
  101 +showDefaultActions: false
  102 +});
  103 +
  104 +/** 暴露出表单校验方法和表单值获取方法 */
  105 +defineExpose({
  106 + validate: async () => {
  107 + const { valid } = await formApi.validate();
  108 + return valid;
  109 + },
  110 + getValues: formApi.getValues,
  111 +});
  112 +
  113 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  114 +watch(
  115 + () => props.${subJoinColumn.javaField},
  116 + async (val) => {
  117 + if (!val) {
  118 + return;
  119 + }
  120 + await nextTick();
  121 + await formApi.setValues(await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  122 + },
  123 + { immediate: true },
  124 +);
  125 +#end
362 </script> 126 </script>
  127 +
  128 +<template>
  129 +#if ($subTable.subJoinMany) ## 一对多
  130 + <Grid class="mx-4">
  131 + #foreach($column in $subColumns)
  132 + #if ($column.createOperation || $column.updateOperation)
  133 + #set ($javaField = $column.javaField)
  134 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  135 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  136 + <template #${javaField}="{ row }">
  137 + <Input v-model:value="row.${javaField}" />
  138 + </template>
  139 + #elseif($column.htmlType == "imageUpload")## 图片上传
  140 + <template #${javaField}="{ row }">
  141 + <UploadImg v-model:value="row.${javaField}" />
  142 + </template>
  143 + #elseif($column.htmlType == "fileUpload")## 文件上传
  144 + <template #${javaField}="{ row }">
  145 + <UploadFile v-model:value="row.${javaField}" />
  146 + </template>
  147 + #elseif($column.htmlType == "editor")## 文本编辑器
  148 + <template #${javaField}="{ row }">
  149 + <Textarea v-model:value="row.${javaField}" />
  150 + </template>
  151 + #elseif($column.htmlType == "select")## 下拉框
  152 + <template #${javaField}="{ row, column }">
  153 + <Select v-model:value="row.${javaField}" class="w-full">
  154 + <Select.Option v-for="option in column.params.options" :key="option.value" :value="option.value">
  155 + {{ option.label }}
  156 + </Select.Option>
  157 + </Select>
  158 + </template>
  159 + #elseif($column.htmlType == "checkbox")## 多选框
  160 + <template #${javaField}="{ row, column }">
  161 + <CheckboxGroup v-model:value="row.${javaField}" :options="column.params.options" />
  162 + </template>
  163 + #elseif($column.htmlType == "radio")## 单选框
  164 + <template #${javaField}="{ row, column }">
  165 + <RadioGroup v-model:value="row.${javaField}" :options="column.params.options" />
  166 + </template>
  167 + #elseif($column.htmlType == "datetime")## 时间框
  168 + <template #${javaField}="{ row }">
  169 + <DatePicker
  170 + v-model:value="row.${javaField}"
  171 + :showTime="true"
  172 + format="YYYY-MM-DD HH:mm:ss"
  173 + valueFormat='x'
  174 + />
  175 + </template>
  176 + #elseif($column.htmlType == "textarea")## 文本框
  177 + <template #${javaField}="{ row }">
  178 + <Textarea v-model:value="row.${javaField}" />
  179 + </template>
  180 + #end
  181 + #end
  182 + #end
  183 + </Grid>
  184 + <div class="flex justify-center -mt-4">
  185 + <Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${subTable.moduleName}:${simpleClassName_strikeCase}:create']">
  186 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  187 + </Button>
  188 + </div>
  189 +#else
  190 + <Form class="mx-4" />
  191 +#end
  192 +</template>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm
@@ -3,181 +3,182 @@ @@ -3,181 +3,182 @@
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
6 #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)})##首字母大写
7 -<template>  
8 - <!-- 列表 -->  
9 - <ContentWrap>  
10 -#if ($table.templateType == 11)  
11 - <Button  
12 - type="primary"  
13 - @click="openForm('create')"  
14 - v-hasPermi="['${permissionPrefix}:create']"  
15 - >  
16 - <Icon icon="ep:plus" class="mr-5px" /> 新增  
17 - </Button>  
18 -#end  
19 - <Table :loading="loading" :dataSource="list" :rowKey="(record) => record.id" :bordered="true">  
20 - #foreach($column in $subColumns)  
21 - #if ($column.listOperationResult)  
22 - #set ($dictType=$column.dictType)  
23 - #set ($javaField = $column.javaField)  
24 - #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
25 - #set ($comment=$column.columnComment)  
26 - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
27 - #elseif ($column.javaType == "LocalDateTime")## 时间类型  
28 - <Column  
29 - title="${comment}"  
30 - align="center"  
31 - dataIndex="${javaField}"  
32 - :customRender="({ text }) => dateFormatter(text)"  
33 - width="180px"  
34 - />  
35 - #elseif($column.dictType && "" != $column.dictType)## 数据字典  
36 - <Column title="${comment}" align="center" dataIndex="${javaField}">  
37 - <template #customRender="{ text }">  
38 - <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="text" />  
39 - </template>  
40 - </Column>  
41 - #else  
42 - <Column title="${comment}" align="center" dataIndex="${javaField}" />  
43 - #end  
44 - #end  
45 - #end  
46 - #if ($table.templateType == 11)  
47 - <Column title="操作" align="center">  
48 - <template #customRender="{ record }">  
49 - <Button  
50 - type="link"  
51 - @click="openForm('update', record.id)"  
52 - v-hasPermi="['${permissionPrefix}:update']"  
53 - >  
54 - 编辑  
55 - </Button>  
56 - <Button  
57 - type="link"  
58 - danger  
59 - @click="handleDelete(record.id)"  
60 - v-hasPermi="['${permissionPrefix}:delete']"  
61 - >  
62 - 删除  
63 - </Button>  
64 - </template>  
65 - </Column>  
66 - #end  
67 - </Table>  
68 - #if ($table.templateType == 11)  
69 - <!-- 分页 -->  
70 - <Pagination  
71 - :total="total"  
72 - v-model:current="queryParams.pageNo"  
73 - v-model:pageSize="queryParams.pageSize"  
74 - @change="handleQuery"  
75 - />  
76 - #end  
77 - </ContentWrap>  
78 -#if ($table.templateType == 11)  
79 - <!-- 表单弹窗:添加/修改 -->  
80 - <${subSimpleClassName}Form ref="formRef" @success="getList" />  
81 -#end  
82 -</template>  
83 -<script setup lang="ts">  
84 -import { Table, Column, Button, Pagination } from 'ant-design-vue'  
85 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
86 -import { dateFormatter } from '@/utils/formatTime'  
87 -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'  
88 -#if ($table.templateType == 11)  
89 -import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue' 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}';
  11 +
  12 +#if ($table.templateType == 11) ## erp
  13 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
90 #end 14 #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';
91 21
92 -const { t } = useI18n() // 国际化  
93 -const message = useMessage() // 消息弹窗 22 +
  23 +#if ($table.templateType == 11) ## erp
  24 + import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  25 + import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
  26 + #else
  27 + #if ($subTable.subJoinMany) ## 一对多
  28 + import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  29 + #else
  30 + import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  31 + #end
  32 + import { use${subSimpleClassName}GridColumns } from '../data';
  33 +#end
94 34
95 const props = defineProps<{ 35 const props = defineProps<{
96 - ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段) 36 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
97 }>() 37 }>()
98 -const loading = ref(false) // 列表的加载中  
99 -const list = ref([]) // 列表的数据  
100 -#if ($table.templateType == 11)  
101 -const total = ref(0) // 列表的总页数  
102 -const queryParams = reactive({  
103 - pageNo: 1,  
104 - pageSize: 10,  
105 - ${subJoinColumn.javaField}: undefined as unknown  
106 -})  
107 38
108 -/** 监听主表的关联字段的变化,加载对应的子表数据 */  
109 -watch(  
110 - () => props.${subJoinColumn.javaField},  
111 - (val: number) => {  
112 - if (!val) {  
113 - return  
114 - }  
115 - queryParams.${subJoinColumn.javaField} = val  
116 - handleQuery()  
117 - },  
118 - { immediate: true, deep: true }  
119 -)  
120 -#end 39 +#if ($table.templateType == 11) ## erp
  40 + const [FormModal, formModalApi] = useVbenModal({
  41 + connectedComponent: ${subSimpleClassName}Form,
  42 + destroyOnClose: true,
  43 + });
121 44
122 -/** 查询列表 */  
123 -const getList = async () => {  
124 - loading.value = true  
125 - try {  
126 -#if ($table.templateType == 11)  
127 - const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)  
128 - list.value = data.list  
129 - total.value = data.total  
130 -#else  
131 - #if ( $subTable.subJoinMany )  
132 - list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})  
133 - #else  
134 - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})  
135 - if (!data) {  
136 - return  
137 - }  
138 - list.value.push(data)  
139 - #end  
140 -#end  
141 - } finally {  
142 - loading.value = false 45 +/** 创建${subTable.classComment} */
  46 +function onCreate() {
  47 + if (!props.${subJoinColumn.javaField}){
  48 + message.warning("请先选择一个${table.classComment}!")
  49 + return
143 } 50 }
  51 + formModalApi.setData({${subJoinColumn.javaField}: props.${subJoinColumn.javaField}}).open();
144 } 52 }
145 53
146 -/** 搜索按钮操作 */  
147 -const handleQuery = () => {  
148 - queryParams.pageNo = 1  
149 - getList() 54 +/** 编辑${subTable.classComment} */
  55 +function onEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
  56 + formModalApi.setData(row).open();
150 } 57 }
151 -#if ($table.templateType == 11)  
152 58
153 -/** 添加/修改操作 */  
154 -const formRef = ref()  
155 -const openForm = (type: string, id?: number) => {  
156 - if (!props.${subJoinColumn.javaField}) {  
157 - message.error('请选择一个${table.classComment}')  
158 - return 59 +/** 删除${subTable.classComment} */
  60 +async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
  61 + const hideLoading = message.loading({
  62 + content: $t('ui.actionMessage.deleting', [row.id]),
  63 + duration: 0,
  64 + key: 'action_process_msg',
  65 + });
  66 + try {
  67 + await delete${subSimpleClassName}(row.id as number);
  68 + message.success({
  69 + content: $t('ui.actionMessage.deleteSuccess', [row.id]),
  70 + key: 'action_process_msg',
  71 + });
  72 + onRefresh();
  73 + } catch {
  74 + hideLoading();
159 } 75 }
160 - formRef.value.open(type, id, props.${subJoinColumn.javaField})  
161 } 76 }
162 77
163 -/** 删除按钮操作 */  
164 -const handleDelete = async (id: number) => {  
165 - try {  
166 - // 删除的二次确认  
167 - await message.delConfirm()  
168 - // 发起删除  
169 - await ${simpleClassName}Api.delete${subSimpleClassName}(id)  
170 - message.success(t('common.delSuccess'))  
171 - // 刷新列表  
172 - await getList()  
173 - } catch {} 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 + }
174 } 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 + },
175 #end 135 #end
176 -#if ($table.templateType != 11) 136 + height: '600px',
  137 + rowConfig: {
  138 + keyField: 'id',
  139 + isHover: true,
  140 + },
  141 + } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>,
  142 + });
177 143
178 -/** 初始化 **/  
179 -onMounted(() => {  
180 - getList()  
181 -}) 144 +/** 刷新表格 */
  145 +const onRefresh = async ()=> {
  146 +#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
182 #end 154 #end
  155 +}
  156 +
  157 + /** 监听主表的关联字段的变化,加载对应的子表数据 */
  158 + watch(
  159 + () => props.${subJoinColumn.javaField},
  160 + async (val) => {
  161 + if (!val) {
  162 + return;
  163 + }
  164 + await nextTick();
  165 + await onRefresh()
  166 + },
  167 + { immediate: true },
  168 + );
183 </script> 169 </script>
  170 +
  171 +<template>
  172 + #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>
  181 + #else
  182 + <Grid table-title="${subTable.classComment}列表" />
  183 + #end
  184 +</template>
184 \ No newline at end of file 185 \ 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/general/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/schema/views/modules/list_sub_erp.vue.vm")
6 \ No newline at end of file 6 \ No newline at end of file