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 164 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
165 165 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
166 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 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 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 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 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 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 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 185 .build();
184 186  
185 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 4 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
5 5  
6 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 15 #if ($column.createOperation || $column.updateOperation)
32 16 #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
33 17 ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
... ... @@ -38,21 +22,37 @@ export namespace ${simpleClassName}Api {
38 22 #end
39 23 #end
40 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 53 #end
  54 + #end
  55 +#end
56 56 }
57 57 }
58 58  
... ... @@ -95,57 +95,58 @@ export function export${simpleClassName}(params: any) {
95 95  
96 96 ## 特殊:主子表专属逻辑
97 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 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 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 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 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 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 159 <template>
2   - <Dialog :title="dialogTitle" v-model="dialogVisible">
  160 + <Modal :title="getTitle">
3 161 <Form
4 162 ref="formRef"
5 163 :model="formData"
... ... @@ -7,294 +165,128 @@
7 165 label-col="{ span: 6 }"
8 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 177 #set ($dictMethod = "getIntDictOptions")
20   - #elseif ($javaType == "String")
  178 + #elseif ($javaType == "String")
21 179 #set ($dictMethod = "getStrDictOptions")
22   - #elseif ($javaType == "Boolean")
  180 + #elseif ($javaType == "Boolean")
23 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 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 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 224 #else##没数据字典
67   - <SelectOption label="请选择字典生成" value="" />
  225 + <SelectOption label="请选择字典生成" value="" />
68 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 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 239 #else##没数据字典
82   - <Checkbox label="请选择字典生成" />
  240 + <Checkbox label="请选择字典生成" />
83 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 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 255 #else##没数据字典
98   - <Radio value="1">请选择字典生成</Radio>
  256 + <Radio value="1">请选择字典生成</Radio>
99 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 273 #end
115   - #end
116   -#end
  274 + #end
117 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 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 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 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 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 36 #end
257   -const queryParams = reactive({
258   -## 特殊:树表专属逻辑(树不需要分页接口)
259   -#if ( $table.templateType != 2 )
260   - pageNo: 1,
261   - pageSize: 10,
262 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 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 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 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 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
2   -#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
3 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 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 1 ## 主表的 normal 和 inner 使用相同的 form 表单
2   -#parse("codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm")
3 2 \ No newline at end of file
  3 +#parse("codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm")
4 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 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
3 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5   -#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7   -<template>
8   -#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
9   - <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 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 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 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 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
6 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 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 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 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 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 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 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 1 ## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
2 2 ## 1)inner 使用 list 不分页,erp 使用 page 分页
3 3 ## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
4   -#parse("codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm")
5 4 \ No newline at end of file
  5 +#parse("codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm")
6 6 \ No newline at end of file
... ...