Commit d5ea9767700fbce791d9f21da71dae835fe41ef4

Authored by 芋道源码
Committed by Gitee
2 parents 045a3361 287b2eab

!1361 优化 vue2、vue3、vben5代码生成模板。新增 vben5-ele 代码生成模板

Merge pull request !1361 from puhui999/master-jdk17
Showing 49 changed files with 4194 additions and 173 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/demo01/Demo01ContactController.java
... ... @@ -65,7 +65,7 @@ public class Demo01ContactController {
65 65 @Operation(summary = "批量删除示例联系人")
66 66 @PreAuthorize("@ss.hasPermission('infra:demo01-contact:delete')")
67 67 public CommonResult<Boolean> deleteDemo0iContactList(@RequestParam("ids") List<Long> ids) {
68   - demo01ContactService.deleteDemo0iContactListByIds(ids);
  68 + demo01ContactService.deleteDemo0iContactList(ids);
69 69 return success(true);
70 70 }
71 71  
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/demo03/erp/Demo03StudentErpController.java
... ... @@ -67,8 +67,7 @@ public class Demo03StudentErpController {
67 67 @Operation(summary = "批量删除学生")
68 68 @PreAuthorize("@ss.hasPermission('infra:demo03-student:delete')")
69 69 public CommonResult<Boolean> deleteDemo03StudentList(@RequestParam("ids") List<Long> ids) {
70   - // TODO @puhui999:deleteDemo03StudentList
71   - demo03StudentErpService.deleteDemo03StudentListByIds(ids);
  70 + demo03StudentErpService.deleteDemo03StudentList(ids);
72 71 return success(true);
73 72 }
74 73  
... ... @@ -142,7 +141,7 @@ public class Demo03StudentErpController {
142 141 @Operation(summary = "批量删除学生课程")
143 142 @PreAuthorize("@ss.hasPermission('infra:demo03-student:delete')")
144 143 public CommonResult<Boolean> deleteDemo03CourseList(@RequestParam("ids") List<Long> ids) {
145   - demo03StudentErpService.deleteDemo03CourseListByIds(ids);
  144 + demo03StudentErpService.deleteDemo03CourseList(ids);
146 145 return success(true);
147 146 }
148 147  
... ... @@ -194,7 +193,7 @@ public class Demo03StudentErpController {
194 193 @Operation(summary = "批量删除学生班级")
195 194 @PreAuthorize("@ss.hasPermission('infra:demo03-student:delete')")
196 195 public CommonResult<Boolean> deleteDemo03GradeList(@RequestParam("ids") List<Long> ids) {
197   - demo03StudentErpService.deleteDemo03GradeListByIds(ids);
  196 + demo03StudentErpService.deleteDemo03GradeList(ids);
198 197 return success(true);
199 198 }
200 199  
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/demo03/inner/Demo03StudentInnerController.java
... ... @@ -67,7 +67,7 @@ public class Demo03StudentInnerController {
67 67 @Operation(summary = "批量删除学生")
68 68 @PreAuthorize("@ss.hasPermission('infra:demo03-student:delete')")
69 69 public CommonResult<Boolean> deleteDemo03StudentList(@RequestParam("ids") List<Long> ids) {
70   - demo03StudentInnerService.deleteDemo03StudentListByIds(ids);
  70 + demo03StudentInnerService.deleteDemo03StudentList(ids);
71 71 return success(true);
72 72 }
73 73  
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/demo03/normal/Demo03StudentNormalController.java
... ... @@ -67,7 +67,7 @@ public class Demo03StudentNormalController {
67 67 @Operation(summary = "批量删除学生")
68 68 @PreAuthorize("@ss.hasPermission('infra:demo03-student:delete')")
69 69 public CommonResult<Boolean> deleteDemo03StudentList(@RequestParam("ids") List<Long> ids) {
70   - demo03StudentNormalService.deleteDemo03StudentListByIds(ids);
  70 + demo03StudentNormalService.deleteDemo03StudentList(ids);
71 71 return success(true);
72 72 }
73 73  
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenFrontTypeEnum.java
... ... @@ -21,6 +21,10 @@ public enum CodegenFrontTypeEnum {
21 21 VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版
22 22  
23 23 VUE3_VBEN5_ANTD_GENERAL(41), // Vue3 VBEN5 + ANTD 标准模版
  24 +
  25 + VUE3_VBEN5_EP_SCHEMA(42), // Vue3 VBEN5 + EP + schema 模版
  26 +
  27 + VUE3_VBEN5_EP_GENERAL(43), // Vue3 VBEN5 + EP 标准模版
24 28 ;
25 29  
26 30 /**
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -182,6 +182,42 @@ public class CodegenEngine {
182 182 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
183 183 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
184 184 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  185 + // VUE3_VBEN5_EP_SCHEMA
  186 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"),
  187 + vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
  188 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/index.vue"),
  189 + vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
  190 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/form.vue"),
  191 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
  192 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("api/api.ts"),
  193 + vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
  194 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
  195 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  196 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
  197 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  198 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
  199 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  200 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
  201 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  202 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
  203 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  204 + // VUE3_VBEN5_EP
  205 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"),
  206 + vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
  207 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/form.vue"),
  208 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
  209 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("api/api.ts"),
  210 + vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
  211 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
  212 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  213 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
  214 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  215 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
  216 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  217 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
  218 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  219 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
  220 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
185 221 .build();
186 222  
187 223 @Resource
... ... @@ -590,6 +626,14 @@ public class CodegenEngine {
590 626 return "codegen/vue3_vben5_antd/general/" + path + ".vm";
591 627 }
592 628  
  629 + private static String vue3Vben5EpSchemaTemplatePath(String path) {
  630 + return "codegen/vue3_vben5_ele/schema/" + path + ".vm";
  631 + }
  632 +
  633 + private static String vue3Vben5EpGeneralTemplatePath(String path) {
  634 + return "codegen/vue3_vben5_ele/general/" + path + ".vm";
  635 + }
  636 +
593 637 private static boolean isSubTemplate(String path) {
594 638 return path.contains("_sub");
595 639 }
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo01/Demo01ContactService.java
... ... @@ -42,7 +42,7 @@ public interface Demo01ContactService {
42 42 *
43 43 * @param ids 编号
44 44 */
45   - void deleteDemo0iContactListByIds(List<Long> ids);
  45 + void deleteDemo0iContactList(List<Long> ids);
46 46  
47 47 /**
48 48 * 获得示例联系人
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo01/Demo01ContactServiceImpl.java
... ... @@ -55,7 +55,7 @@ public class Demo01ContactServiceImpl implements Demo01ContactService {
55 55 }
56 56  
57 57 @Override
58   - public void deleteDemo0iContactListByIds(List<Long> ids) {
  58 + public void deleteDemo0iContactList(List<Long> ids) {
59 59 // 校验存在
60 60 validateDemo01ContactExists(ids);
61 61 // 删除
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/erp/Demo03StudentErpService.java
... ... @@ -45,7 +45,7 @@ public interface Demo03StudentErpService {
45 45 *
46 46 * @param ids 编号
47 47 */
48   - void deleteDemo03StudentListByIds(List<Long> ids);
  48 + void deleteDemo03StudentList(List<Long> ids);
49 49  
50 50 /**
51 51 * 获得学生
... ... @@ -101,7 +101,7 @@ public interface Demo03StudentErpService {
101 101 *
102 102 * @param ids 编号
103 103 */
104   - void deleteDemo03CourseListByIds(List<Long> ids);
  104 + void deleteDemo03CourseList(List<Long> ids);
105 105  
106 106 /**
107 107 * 获得学生课程
... ... @@ -149,7 +149,7 @@ public interface Demo03StudentErpService {
149 149 *
150 150 * @param ids 编号
151 151 */
152   - void deleteDemo03GradeListByIds(List<Long> ids);
  152 + void deleteDemo03GradeList(List<Long> ids);
153 153  
154 154 /**
155 155 * 获得学生班级
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/erp/Demo03StudentErpServiceImpl.java
... ... @@ -71,7 +71,7 @@ public class Demo03StudentErpServiceImpl implements Demo03StudentErpService {
71 71  
72 72 @Override
73 73 @Transactional(rollbackFor = Exception.class)
74   - public void deleteDemo03StudentListByIds(List<Long> ids) {
  74 + public void deleteDemo03StudentList(List<Long> ids) {
75 75 // 校验存在
76 76 validateDemo03StudentExists(ids);
77 77 // 删除
... ... @@ -134,7 +134,7 @@ public class Demo03StudentErpServiceImpl implements Demo03StudentErpService {
134 134 }
135 135  
136 136 @Override
137   - public void deleteDemo03CourseListByIds(List<Long> ids) {
  137 + public void deleteDemo03CourseList(List<Long> ids) {
138 138 // 删除
139 139 demo03CourseErpMapper.deleteByIds(ids);
140 140 }
... ... @@ -192,7 +192,7 @@ public class Demo03StudentErpServiceImpl implements Demo03StudentErpService {
192 192 }
193 193  
194 194 @Override
195   - public void deleteDemo03GradeListByIds(List<Long> ids) {
  195 + public void deleteDemo03GradeList(List<Long> ids) {
196 196 // 删除
197 197 demo03GradeErpMapper.deleteByIds(ids);
198 198 }
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/inner/Demo03StudentInnerService.java
... ... @@ -44,7 +44,7 @@ public interface Demo03StudentInnerService {
44 44 *
45 45 * @param ids 编号
46 46 */
47   - void deleteDemo03StudentListByIds(List<Long> ids);
  47 + void deleteDemo03StudentList(List<Long> ids);
48 48  
49 49 /**
50 50 * 获得学生
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/inner/Demo03StudentInnerServiceImpl.java
... ... @@ -83,7 +83,7 @@ public class Demo03StudentInnerServiceImpl implements Demo03StudentInnerService
83 83  
84 84 @Override
85 85 @Transactional(rollbackFor = Exception.class)
86   - public void deleteDemo03StudentListByIds(List<Long> ids) {
  86 + public void deleteDemo03StudentList(List<Long> ids) {
87 87 // 校验存在
88 88 validateDemo03StudentExists(ids);
89 89 // 删除
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/normal/Demo03StudentNormalService.java
... ... @@ -44,7 +44,7 @@ public interface Demo03StudentNormalService {
44 44 *
45 45 * @param ids 编号
46 46 */
47   - void deleteDemo03StudentListByIds(List<Long> ids);
  47 + void deleteDemo03StudentList(List<Long> ids);
48 48  
49 49 /**
50 50 * 获得学生
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/demo/demo03/normal/Demo03StudentNormalServiceImpl.java
... ... @@ -83,7 +83,7 @@ public class Demo03StudentNormalServiceImpl implements Demo03StudentNormalServic
83 83  
84 84 @Override
85 85 @Transactional(rollbackFor = Exception.class)
86   - public void deleteDemo03StudentListByIds(List<Long> ids) {
  86 + public void deleteDemo03StudentList(List<Long> ids) {
87 87 // 校验存在
88 88 validateDemo03StudentExists(ids);
89 89 // 删除
... ...
yudao-module-infra/src/main/resources/codegen/java/service/serviceImpl.vm
... ... @@ -65,10 +65,13 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
65 65 #end
66 66 // 插入
67 67 #if ($voType == 10)
68   -## TODO @puhui999:insert 也要加下 clean。万一前端乱传递,哈哈哈。这个就是 do 模式的缺点;(只在 do 模式下);看看主子表,是不是也可能存在,insert 的时候;
69 68 ${table.className}DO ${classNameVar} = BeanUtils.toBean(createReqVO, ${table.className}DO.class);
70   -#end
71 69 ${classNameVar}Mapper.insert(${classNameVar});
  70 +#else
  71 + ${saveReqVOVar}.clean() // 清理掉创建、更新时间等相关属性值
  72 + ${classNameVar}Mapper.insert(${saveReqVOVar});
  73 +#end
  74 +
72 75 ## 特殊:主子表专属逻辑(非 ERP 模式)
73 76 #if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
74 77  
... ... @@ -112,6 +115,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
112 115 ${table.className}DO updateObj = BeanUtils.toBean(updateReqVO, ${table.className}DO.class);
113 116 ${classNameVar}Mapper.updateById(updateObj);
114 117 #else
  118 + ${updateReqVOVar}.clean() // 清理掉创建、更新时间等相关属性值
115 119 ${classNameVar}Mapper.updateById(${updateReqVOVar});
116 120 #end
117 121 ## 特殊:主子表专属逻辑(非 ERP 模式)
... ... @@ -320,6 +324,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
320 324 }
321 325 // 插入
322 326 #end
  327 + ${subClassNameVar}.clean() // 清理掉创建、更新时间等相关属性值
323 328 ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
324 329 return ${subClassNameVar}.getId();
325 330 }
... ...
yudao-module-infra/src/main/resources/codegen/vue/api/api.js.vm
... ... @@ -27,6 +27,16 @@ export function delete${simpleClassName}(id) {
27 27 })
28 28 }
29 29  
  30 +#if ( $table.templateType != 2 && $deleteBatchEnable)
  31 +/** 批量删除${table.classComment} */
  32 +export function delete${simpleClassName}List(ids) {
  33 + return request({
  34 + url: `${baseURL}/delete-list?ids=${ids.join(',')}`,
  35 + method: 'delete'
  36 + })
  37 +}
  38 +#end
  39 +
30 40 // 获得${table.classComment}
31 41 export function get${simpleClassName}(id) {
32 42 return request({
... ... @@ -130,6 +140,15 @@ export function export${simpleClassName}Excel(params) {
130 140 method: 'delete'
131 141 })
132 142 }
  143 + #if ($deleteBatchEnable)
  144 + /** 批量删除${subTable.classComment} */
  145 + export function delete${subSimpleClassName}List(ids) {
  146 + return request({
  147 + url: `${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`,
  148 + method: 'delete'
  149 + })
  150 + }
  151 + #end
133 152 // 获得${subTable.classComment}
134 153 export function get${subSimpleClassName}(id) {
135 154 return request({
... ...
yudao-module-infra/src/main/resources/codegen/vue/views/components/list_sub_erp.vue.vm
... ... @@ -13,10 +13,36 @@
13 13 <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
14 14 v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
15 15 </el-col>
  16 + #if ($deleteBatchEnable)
  17 + <el-col :span="1.5">
  18 + <el-button
  19 + type="danger"
  20 + plain
  21 + icon="el-icon-delete"
  22 + size="mini"
  23 + :disabled="isEmpty(checkedIds)"
  24 + @click="handleDeleteBatch"
  25 + v-hasPermi="['${permissionPrefix}:delete']"
  26 + >
  27 + 批量删除
  28 + </el-button>
  29 + </el-col>
  30 + #end
16 31 </el-row>
17 32 #end
18 33 ## 列表
19   - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  34 + <el-table
  35 + v-loading="loading"
  36 + :data="list"
  37 + :stripe="true"
  38 + :show-overflow-tooltip="true"
  39 + #if ($table.templateType == 11 && $deleteBatchEnable)
  40 + @selection-change="handleRowCheckboxChange"
  41 + #end
  42 + >
  43 + #if ($table.templateType == 11 && $deleteBatchEnable)
  44 + <el-table-column type="selection" width="55" />
  45 + #end
20 46 #foreach($column in $subColumns)
21 47 #if ($column.listOperationResult)
22 48 #set ($dictType=$column.dictType)
... ... @@ -82,6 +108,9 @@
82 108 // 列表的数据
83 109 list: [],
84 110 #if ($table.templateType == 11)
  111 + #if ($deleteBatchEnable)
  112 + checkedIds: [],
  113 + #end
85 114 // 列表的总页数
86 115 total: 0,
87 116 // 查询参数
... ... @@ -135,12 +164,27 @@
135 164 this.loading = false;
136 165 }
137 166 },
138   - /** 搜索按钮操作 */
139   - handleQuery() {
140   - this.queryParams.pageNo = 1;
141   - this.getList();
142   - },
  167 + #if ($table.templateType == 11 && $deleteBatchEnable)
  168 + /** 批量删除${table.classComment} */
  169 + async handleDeleteBatch() {
  170 + await this.#[[$modal]]#.confirm('是否确认删除?')
  171 + try {
  172 + await ${simpleClassName}Api.delete${subSimpleClassName}List(this.checkedIds);
  173 + await this.getList();
  174 + this.#[[$modal]]#.msgSuccess("删除成功");
  175 + } catch {}
  176 + },
  177 + handleRowCheckboxChange(records) {
  178 + this.checkedIds = records.map((item) => item.id);
  179 + },
  180 + #end
  181 +
143 182 #if ($table.templateType == 11)
  183 + /** 搜索按钮操作 */
  184 + handleQuery() {
  185 + this.queryParams.pageNo = 1;
  186 + this.getList();
  187 + },
144 188 /** 添加/修改操作 */
145 189 openForm(id) {
146 190 if (!this.${subJoinColumn.javaField}) {
... ...
yudao-module-infra/src/main/resources/codegen/vue/views/index.vue.vm
... ... @@ -53,26 +53,45 @@
53 53 <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
54 54 v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
55 55 </el-col>
56   - ## 特殊:树表专属逻辑
57   - #if ( $table.templateType == 2 )
58   - <el-col :span="1.5">
59   - <el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
60   - 展开/折叠
61   - </el-button>
62   - </el-col>
63   - #end
  56 + ## 特殊:树表专属逻辑
  57 + #if ( $table.templateType == 2 )
  58 + <el-col :span="1.5">
  59 + <el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
  60 + 展开/折叠
  61 + </el-button>
  62 + </el-col>
  63 + #end
  64 + #if ($table.templateType != 2 && $deleteBatchEnable)
  65 + <el-col :span="1.5">
  66 + <el-button
  67 + type="danger"
  68 + plain
  69 + icon="el-icon-delete"
  70 + size="mini"
  71 + :disabled="isEmpty(checkedIds)"
  72 + @click="handleDeleteBatch"
  73 + v-hasPermi="['${permissionPrefix}:delete']"
  74 + >
  75 + 批量删除
  76 + </el-button>
  77 + </el-col>
  78 + #end
64 79 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
65 80 </el-row>
66 81  
67 82 ## 特殊:主子表专属逻辑
68 83 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
69 84 <el-table
  85 + row-key="id"
70 86 v-loading="loading"
71 87 :data="list"
72 88 :stripe="true"
73 89 :highlight-current-row="true"
74 90 :show-overflow-tooltip="true"
75 91 @current-change="handleCurrentChange"
  92 + #if ($deleteBatchEnable)
  93 + @selection-change="handleRowCheckboxChange"
  94 + #end
76 95 >
77 96 ## 特殊:树表专属逻辑
78 97 #elseif ( $table.templateType == 2 )
... ... @@ -87,7 +106,18 @@
87 106 :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
88 107 >
89 108 #else
90   - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  109 + <el-table
  110 + v-loading="loading"
  111 + :data="list"
  112 + :stripe="true"
  113 + :show-overflow-tooltip="true"
  114 + #if ($deleteBatchEnable)
  115 + @selection-change="handleRowCheckboxChange"
  116 + #end
  117 + >
  118 + #end
  119 + #if ($table.templateType != 2 && $deleteBatchEnable)
  120 + <el-table-column type="selection" width="55" />
91 121 #end
92 122 ## 特殊:主子表专属逻辑
93 123 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
... ... @@ -229,6 +259,7 @@ export default {
229 259 refreshTable: true,
230 260 // 选中行
231 261 currentRow: {},
  262 + checkedIds: [],
232 263 // 查询参数
233 264 queryParams: {
234 265 ## 特殊:树表专属逻辑(树不需要分页接口)
... ... @@ -301,6 +332,20 @@ export default {
301 332 this.#[[$modal]]#.msgSuccess("删除成功");
302 333 } catch {}
303 334 },
  335 + #if ($table.templateType != 2 && $deleteBatchEnable)
  336 + /** 批量删除${table.classComment} */
  337 + async handleDeleteBatch() {
  338 + await this.#[[$modal]]#.confirm('是否确认删除?')
  339 + try {
  340 + await ${simpleClassName}Api.delete${simpleClassName}List(this.checkedIds);
  341 + await this.getList();
  342 + this.#[[$modal]]#.msgSuccess("删除成功");
  343 + } catch {}
  344 + },
  345 + handleRowCheckboxChange(records) {
  346 + this.checkedIds = records.map((item) => item.id);
  347 + },
  348 + #end
304 349 /** 导出按钮操作 */
305 350 async handleExport() {
306 351 await this.#[[$modal]]#.confirm('是否确认导出所有${table.classComment}数据项?');
... ...
yudao-module-infra/src/main/resources/codegen/vue3/api/api.ts.vm
1 1 import request from '@/config/axios'
  2 +import type { Dayjs } from 'dayjs';
2 3 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
3 4  
4   -// ${table.classComment} VO
5   -export interface ${simpleClassName}VO {
6   -#foreach ($column in $columns)
7   -#if ($column.createOperation || $column.updateOperation)
8   -#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
9   - ${column.javaField}: number // ${column.columnComment}
10   -#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
11   - ${column.javaField}: Date // ${column.columnComment}
12   -#else
13   - ${column.javaField}: ${column.javaType.toLowerCase()} // ${column.columnComment}
14   -#end
15   -#end
  5 +## 特殊:主子表专属逻辑
  6 +#foreach ($subTable in $subTables)
  7 + #set ($index = $foreach.count - 1)
  8 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  9 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  10 +/** ${subTable.classComment}信息 */
  11 +export interface ${subSimpleClassName} {
  12 + #foreach ($column in $subColumns)
  13 + #if ($column.createOperation || $column.updateOperation)
  14 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  15 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  16 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  17 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  18 + #else
  19 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  20 + #end
  21 + #end
  22 + #end
  23 +}
  24 +
16 25 #end
  26 +/** ${table.classComment}信息 */
  27 +export interface ${simpleClassName} {
  28 + #foreach ($column in $columns)
  29 + #if ($column.createOperation || $column.updateOperation)
  30 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  31 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  32 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  33 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  34 + #else
  35 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  36 + #end
  37 + #end
  38 + #end
  39 + #if ( $table.templateType == 2 )
  40 + children?: ${simpleClassName}[];
  41 + #end
  42 + ## 特殊:主子表专属逻辑
  43 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  44 + #foreach ($subTable in $subTables)
  45 + #set ($index = $foreach.count - 1)
  46 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  47 + #if ( $subTable.subJoinMany )
  48 + ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
  49 + #else
  50 + ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
  51 + #end
  52 + #end
  53 + #end
17 54 }
18 55  
19 56 // ${table.classComment} API
... ... @@ -36,12 +73,12 @@ export const ${simpleClassName}Api = {
36 73 },
37 74  
38 75 // 新增${table.classComment}
39   - create${simpleClassName}: async (data: ${simpleClassName}VO) => {
  76 + create${simpleClassName}: async (data: ${simpleClassName}) => {
40 77 return await request.post({ url: `${baseURL}/create`, data })
41 78 },
42 79  
43 80 // 修改${table.classComment}
44   - update${simpleClassName}: async (data: ${simpleClassName}VO) => {
  81 + update${simpleClassName}: async (data: ${simpleClassName}) => {
45 82 return await request.put({ url: `${baseURL}/update`, data })
46 83 },
47 84  
... ... @@ -50,6 +87,13 @@ export const ${simpleClassName}Api = {
50 87 return await request.delete({ url: `${baseURL}/delete?id=` + id })
51 88 },
52 89  
  90 +#if ( $table.templateType != 2 && $deleteBatchEnable)
  91 + /** 批量删除${table.classComment} */
  92 + delete${simpleClassName}List: async (ids: number[]) => {
  93 + return await request.delete({ url: `${baseURL}/delete-list?ids=${ids.join(',')}` })
  94 + },
  95 +#end
  96 +
53 97 // 导出${table.classComment} Excel
54 98 export${simpleClassName}: async (params) => {
55 99 return await request.download({ url: `${baseURL}/export-excel`, params })
... ... @@ -92,12 +136,12 @@ export const ${simpleClassName}Api = {
92 136 ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
93 137 #if ( $table.templateType == 11 )
94 138 // 新增${subTable.classComment}
95   - create${subSimpleClassName}: async (data) => {
  139 + create${subSimpleClassName}: async (data: ${subSimpleClassName}) => {
96 140 return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
97 141 },
98 142  
99 143 // 修改${subTable.classComment}
100   - update${subSimpleClassName}: async (data) => {
  144 + update${subSimpleClassName}: async (data: ${subSimpleClassName}) => {
101 145 return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
102 146 },
103 147  
... ... @@ -106,6 +150,13 @@ export const ${simpleClassName}Api = {
106 150 return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
107 151 },
108 152  
  153 + #if ($deleteBatchEnable)
  154 + /** 批量删除${subTable.classComment} */
  155 + delete${subSimpleClassName}List: async (ids: number[]) => {
  156 + return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}` })
  157 + },
  158 + #end
  159 +
109 160 // 获得${subTable.classComment}
110 161 get${subSimpleClassName}: async (id: number) => {
111 162 return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
... ...
yudao-module-infra/src/main/resources/codegen/vue3/views/components/form_sub_erp.vue.vm
... ... @@ -113,7 +113,7 @@
113 113 </template>
114 114 <script setup lang="ts">
115 115 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
116   -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
  116 +import { ${simpleClassName}Api, ${subSimpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
117 117  
118 118 const { t } = useI18n() // 国际化
119 119 const message = useMessage() // 消息弹窗
... ... @@ -144,12 +144,12 @@ const formRules = reactive({
144 144 const formRef = ref() // 表单 Ref
145 145  
146 146 /** 打开弹窗 */
147   -const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {
  147 +const open = async (type: string, id?: number, ${subJoinColumn.javaField}?: number) => {
148 148 dialogVisible.value = true
149 149 dialogTitle.value = t('action.' + type)
150 150 formType.value = type
151 151 resetForm()
152   - formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}
  152 + formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField} as any
153 153 // 修改时,设置数据
154 154 if (id) {
155 155 formLoading.value = true
... ... @@ -170,7 +170,7 @@ const submitForm = async () =&gt; {
170 170 // 提交请求
171 171 formLoading.value = true
172 172 try {
173   - const data = formData.value
  173 + const data = formData.value as unknown as ${subSimpleClassName}
174 174 if (formType.value === 'create') {
175 175 await ${simpleClassName}Api.create${subSimpleClassName}(data)
176 176 message.success(t('common.createSuccess'))
... ...
yudao-module-infra/src/main/resources/codegen/vue3/views/components/form_sub_normal.vue.vm
... ... @@ -266,10 +266,10 @@ import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } f
266 266 import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
267 267  
268 268 const props = defineProps<{
269   - ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
  269 + ${subJoinColumn.javaField}: number // ${subJoinColumn.columnComment}(主表的关联字段)
270 270 }>()
271 271 const formLoading = ref(false) // 表单的加载中
272   -const formData = ref([])
  272 +const formData = ref<any#if ( $subTable.subJoinMany )[]#end>(#if ( $subTable.subJoinMany )[]#else{}#end)
273 273 const formRules = reactive({
274 274 #foreach ($column in $subColumns)
275 275 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
... ... @@ -336,7 +336,7 @@ const handleAdd = () =&gt; {
336 336 #end
337 337 #end
338 338 }
339   - row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}
  339 + row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField} as any
340 340 formData.value.push(row)
341 341 }
342 342  
... ...
yudao-module-infra/src/main/resources/codegen/vue3/views/components/list_sub_erp.vue.vm
... ... @@ -16,8 +16,31 @@
16 16 >
17 17 <Icon icon="ep:plus" class="mr-5px" /> 新增
18 18 </el-button>
  19 + #if ($deleteBatchEnable)
  20 + <el-button
  21 + type="danger"
  22 + plain
  23 + :disabled="isEmpty(checkedIds)"
  24 + @click="handleDeleteBatch"
  25 + v-hasPermi="['${permissionPrefix}:delete']"
  26 + >
  27 + <Icon icon="ep:delete" class="mr-5px" /> 批量删除
  28 + </el-button>
  29 + #end
19 30 #end
20   - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  31 + <el-table
  32 + row-key="id"
  33 + v-loading="loading"
  34 + :data="list"
  35 + :stripe="true"
  36 + :show-overflow-tooltip="true"
  37 + #if ($table.templateType == 11 && $deleteBatchEnable)
  38 + @selection-change="handleRowCheckboxChange"
  39 + #end
  40 + >
  41 + #if ($table.templateType == 11 && $deleteBatchEnable)
  42 + <el-table-column type="selection" width="55" />
  43 + #end
21 44 #foreach($column in $subColumns)
22 45 #if ($column.listOperationResult)
23 46 #set ($dictType=$column.dictType)
... ... @@ -85,14 +108,18 @@
85 108 <script setup lang="ts">
86 109 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
87 110 import { dateFormatter } from '@/utils/formatTime'
88   -import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
  111 +#if ($deleteBatchEnable)
  112 +import { isEmpty } from '@/utils/is'
  113 +#end
  114 +import { ${simpleClassName}Api, ${subSimpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
89 115 #if ($table.templateType == 11)
90 116 import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
91 117 #end
92 118  
  119 +#if ($table.templateType == 11)
93 120 const { t } = useI18n() // 国际化
94 121 const message = useMessage() // 消息弹窗
95   -
  122 +#end
96 123 const props = defineProps<{
97 124 ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
98 125 }>()
... ... @@ -144,12 +171,12 @@ const getList = async () =&gt; {
144 171 }
145 172 }
146 173  
  174 +#if ($table.templateType == 11)
147 175 /** 搜索按钮操作 */
148 176 const handleQuery = () => {
149 177 queryParams.pageNo = 1
150 178 getList()
151 179 }
152   -#if ($table.templateType == 11)
153 180  
154 181 /** 添加/修改操作 */
155 182 const formRef = ref()
... ... @@ -173,6 +200,24 @@ const handleDelete = async (id: number) =&gt; {
173 200 await getList()
174 201 } catch {}
175 202 }
  203 +
  204 +#if ($table.templateType == 11 && $deleteBatchEnable)
  205 +/** 批量删除${subTable.classComment} */
  206 +const handleDeleteBatch = async () => {
  207 + try {
  208 + // 删除的二次确认
  209 + await message.delConfirm()
  210 + await ${simpleClassName}Api.delete${subSimpleClassName}List(checkedIds.value);
  211 + message.success(t('common.delSuccess'))
  212 + await getList();
  213 + } catch {}
  214 +}
  215 +
  216 +const checkedIds = ref<number[]>([])
  217 +const handleRowCheckboxChange = (records: ${subSimpleClassName}[]) => {
  218 + checkedIds.value = records.map((item) => item.id);
  219 +}
  220 +#end
176 221 #end
177 222 #if ($table.templateType != 11)
178 223  
... ...
yudao-module-infra/src/main/resources/codegen/vue3/views/form.vue.vm
... ... @@ -139,7 +139,7 @@
139 139 </template>
140 140 <script setup lang="ts">
141 141 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
142   -import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
  142 +import { ${simpleClassName}Api, ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
143 143 ## 特殊:树表专属逻辑
144 144 #if ( $table.templateType == 2 )
145 145 import { defaultProps, handleTree } from '@/utils/tree'
... ... @@ -243,7 +243,7 @@ const submitForm = async () =&gt; {
243 243 // 提交请求
244 244 formLoading.value = true
245 245 try {
246   - const data = formData.value as unknown as ${simpleClassName}VO
  246 + const data = formData.value as unknown as ${simpleClassName}
247 247 ## 特殊:主子表专属逻辑
248 248 #if ( $table.templateType == 10 || $table.templateType == 12 )
249 249 #if ( $subTables && $subTables.size() > 0 )
... ...
yudao-module-infra/src/main/resources/codegen/vue3/views/index.vue.vm
... ... @@ -107,6 +107,17 @@
107 107 <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
108 108 </el-button>
109 109 #end
  110 + #if ($table.templateType != 2 && $deleteBatchEnable)
  111 + <el-button
  112 + type="danger"
  113 + plain
  114 + :disabled="isEmpty(checkedIds)"
  115 + @click="handleDeleteBatch"
  116 + v-hasPermi="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
  117 + >
  118 + <Icon icon="ep:delete" class="mr-5px" /> 批量删除
  119 + </el-button>
  120 + #end
110 121 </el-form-item>
111 122 </el-form>
112 123 </ContentWrap>
... ... @@ -116,12 +127,16 @@
116 127 ## 特殊:主子表专属逻辑
117 128 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
118 129 <el-table
  130 + row-key="id"
119 131 v-loading="loading"
120 132 :data="list"
121 133 :stripe="true"
122 134 :show-overflow-tooltip="true"
123 135 highlight-current-row
124 136 @current-change="handleCurrentChange"
  137 + #if ($deleteBatchEnable)
  138 + @selection-change="handleRowCheckboxChange"
  139 + #end
125 140 >
126 141 ## 特殊:树表专属逻辑
127 142 #elseif ( $table.templateType == 2 )
... ... @@ -135,7 +150,19 @@
135 150 v-if="refreshTable"
136 151 >
137 152 #else
138   - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  153 + <el-table
  154 + row-key="id"
  155 + v-loading="loading"
  156 + :data="list"
  157 + :stripe="true"
  158 + :show-overflow-tooltip="true"
  159 + #if ($deleteBatchEnable)
  160 + @selection-change="handleRowCheckboxChange"
  161 + #end
  162 + >
  163 +#end
  164 +#if ($table.templateType != 2 && $deleteBatchEnable)
  165 + <el-table-column type="selection" width="55" />
139 166 #end
140 167 ## 特殊:主子表专属逻辑
141 168 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
... ... @@ -234,13 +261,14 @@
234 261  
235 262 <script setup lang="ts">
236 263 import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
  264 +import { isEmpty } from '@/utils/is'
237 265 import { dateFormatter } from '@/utils/formatTime'
238 266 ## 特殊:树表专属逻辑
239 267 #if ( $table.templateType == 2 )
240 268 import { handleTree } from '@/utils/tree'
241 269 #end
242 270 import download from '@/utils/download'
243   -import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
  271 +import { ${simpleClassName}Api, ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
244 272 import ${simpleClassName}Form from './${simpleClassName}Form.vue'
245 273 ## 特殊:主子表专属逻辑
246 274 #if ( $table.templateType != 10 )
... ... @@ -256,7 +284,7 @@ const message = useMessage() // 消息弹窗
256 284 const { t } = useI18n() // 国际化
257 285  
258 286 const loading = ref(true) // 列表的加载中
259   -const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
  287 +const list = ref<${simpleClassName}[]>([]) // 列表的数据
260 288 ## 特殊:树表专属逻辑(树不需要分页接口)
261 289 #if ( $table.templateType != 2 )
262 290 const total = ref(0) // 列表的总页数
... ... @@ -330,6 +358,24 @@ const handleDelete = async (id: number) =&gt; {
330 358 } catch {}
331 359 }
332 360  
  361 +#if ($table.templateType != 2 && $deleteBatchEnable)
  362 +/** 批量删除${table.classComment} */
  363 +const handleDeleteBatch = async () => {
  364 + try {
  365 + // 删除的二次确认
  366 + await message.delConfirm()
  367 + await ${simpleClassName}Api.delete${simpleClassName}List(checkedIds.value);
  368 + message.success(t('common.delSuccess'))
  369 + await getList();
  370 + } catch {}
  371 +}
  372 +
  373 +const checkedIds = ref<number[]>([])
  374 +const handleRowCheckboxChange = (records: ${simpleClassName}[]) => {
  375 + checkedIds.value = records.map((item) => item.id);
  376 +}
  377 +#end
  378 +
333 379 /** 导出按钮操作 */
334 380 const handleExport = async () => {
335 381 try {
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/api/api.ts.vm
... ... @@ -91,7 +91,7 @@ export function delete${simpleClassName}(id: number) {
91 91  
92 92 #if ( $table.templateType != 2 && $deleteBatchEnable)
93 93 /** 批量删除${table.classComment} */
94   -export function delete${simpleClassName}ListByIds(ids: number[]) {
  94 +export function delete${simpleClassName}List(ids: number[]) {
95 95 return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`)
96 96 }
97 97 #end
... ... @@ -102,7 +102,6 @@ export function export${simpleClassName}(params: any) {
102 102 }
103 103  
104 104 ## 特殊:主子表专属逻辑
105   -## TODO @puhui999:下面这块缩进调整了,会乱掉么?
106 105 #foreach ($subTable in $subTables)
107 106 #set ($index = $foreach.count - 1)
108 107 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
... ... @@ -115,54 +114,54 @@ export function export${simpleClassName}(params: any) {
115 114  
116 115 // ==================== 子表($subTable.classComment) ====================
117 116  
118   - ## 情况一:MASTER_ERP 时,需要分查询页子表
119   - #if ( $table.templateType == 11 )
120   - /** 获得${subTable.classComment}分页 */
121   - export function get${subSimpleClassName}Page(params: PageParam) {
122   - return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
123   - }
124   - ## 情况二:非 MASTER_ERP 时,需要列表查询子表
125   - #else
126   - #if ( $subTable.subJoinMany )
127   - /** 获得${subTable.classComment}列表 */
128   - export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
129   - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
130   - }
131   - #else
132   - /** 获得${subTable.classComment} */
133   - export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
134   - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
135   - }
136   - #end
137   - #end
138   - ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
139   - #if ( $table.templateType == 11 )
140   - /** 新增${subTable.classComment} */
141   - export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
142   - return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
143   - }
  117 +## 情况一:MASTER_ERP 时,需要分查询页子表
  118 +#if ( $table.templateType == 11 )
  119 +/** 获得${subTable.classComment}分页 */
  120 +export function get${subSimpleClassName}Page(params: PageParam) {
  121 + return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
  122 +}
  123 + ## 情况二:非 MASTER_ERP 时,需要列表查询子表
  124 +#else
  125 +#if ( $subTable.subJoinMany )
  126 +/** 获得${subTable.classComment}列表 */
  127 +export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  128 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  129 +}
  130 +#else
  131 +/** 获得${subTable.classComment} */
  132 +export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  133 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  134 +}
  135 +#end
  136 +#end
  137 +## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
  138 +#if ( $table.templateType == 11 )
  139 +/** 新增${subTable.classComment} */
  140 +export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  141 + return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
  142 +}
144 143  
145   - /** 修改${subTable.classComment} */
146   - export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
147   - return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
148   - }
  144 +/** 修改${subTable.classComment} */
  145 +export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  146 + return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
  147 +}
149 148  
150   - /** 删除${subTable.classComment} */
151   - export function delete${subSimpleClassName}(id: number) {
152   - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
153   - }
  149 +/** 删除${subTable.classComment} */
  150 +export function delete${subSimpleClassName}(id: number) {
  151 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
  152 +}
154 153  
155   - #if ($deleteBatchEnable)
156   - /** 批量删除${subTable.classComment} */
157   - export function delete${subSimpleClassName}ListByIds(ids: number[]) {
158   - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)
159   - }
160   - #end
  154 +#if ($deleteBatchEnable)
  155 +/** 批量删除${subTable.classComment} */
  156 +export function delete${subSimpleClassName}List(ids: number[]) {
  157 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)
  158 +}
  159 +#end
161 160  
162   - /** 获得${subTable.classComment} */
163   - export function get${subSimpleClassName}(id: number) {
164   - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
165   - }
166   - #end
  161 +/** 获得${subTable.classComment} */
  162 +export function get${subSimpleClassName}(id: number) {
  163 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
  164 +}
  165 +#end
167 166 #end
168 167  
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm
... ... @@ -8,7 +8,7 @@ import { ImageUpload, FileUpload } from &quot;#/components/upload&quot;;
8 8 import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
9 9 import { DICT_TYPE, getDictOptions } from '#/utils';
10 10 #if($table.templateType == 2)## 树表需要导入这些
11   -import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
  11 +import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
12 12 import { handleTree } from '@vben/utils'
13 13 #end
14 14 ## 特殊:主子表专属逻辑
... ... @@ -22,7 +22,7 @@ import { handleTree } from &#39;@vben/utils&#39;
22 22  
23 23 import { computed, ref } from 'vue';
24 24 import { $t } from '#/locales';
25   -import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  25 +import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
26 26  
27 27 const emit = defineEmits(['success']);
28 28  
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm
... ... @@ -30,7 +30,7 @@ import { handleTree,isEmpty } from &#39;@vben/utils&#39;
30 30 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
31 31 #else## 标准表接口
32 32 import { isEmpty } from '@vben/utils';
33   -import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}ListByIds,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  33 +import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
34 34 #end
35 35 import { downloadFileFromBlobPart } from '@vben/utils';
36 36  
... ... @@ -123,24 +123,24 @@ const [FormModal, formModalApi] = useVbenModal({
123 123 });
124 124  
125 125 /** 创建${table.classComment} */
126   -function onCreate() {
  126 +function handleCreate() {
127 127 formModalApi.setData({}).open();
128 128 }
129 129  
130 130 /** 编辑${table.classComment} */
131   -function onEdit(row: ${simpleClassName}Api.${simpleClassName}) {
  131 +function handleEdit(row: ${simpleClassName}Api.${simpleClassName}) {
132 132 formModalApi.setData(row).open();
133 133 }
134 134  
135 135 #if (${table.templateType} == 2)## 树表特有:新增下级
136 136 /** 新增下级${table.classComment} */
137   -function onAppend(row: ${simpleClassName}Api.${simpleClassName}) {
  137 +function handleAppend(row: ${simpleClassName}Api.${simpleClassName}) {
138 138 formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
139 139 }
140 140 #end
141 141  
142 142 /** 删除${table.classComment} */
143   -async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
  143 +async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
144 144 const hideLoading = message.loading({
145 145 content: $t('ui.actionMessage.deleting', [row.id]),
146 146 duration: 0,
... ... @@ -160,14 +160,14 @@ async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
160 160  
161 161 #if ($table.templateType != 2 && $deleteBatchEnable)
162 162 /** 批量删除${table.classComment} */
163   -async function onDeleteBatch() {
  163 +async function handleDeleteBatch() {
164 164 const hideLoading = message.loading({
165 165 content: $t('ui.actionMessage.deleting'),
166 166 duration: 0,
167 167 key: 'action_process_msg',
168 168 });
169 169 try {
170   - await delete${simpleClassName}ListByIds(deleteIds.value);
  170 + await delete${simpleClassName}List(checkedIds.value);
171 171 message.success( $t('ui.actionMessage.deleteSuccess') );
172 172 await getList();
173 173 } finally {
... ... @@ -175,13 +175,13 @@ async function onDeleteBatch() {
175 175 }
176 176 }
177 177  
178   -const deleteIds = ref<number[]>([]) // 待删除${table.classComment} ID
179   -function setDeleteIds({
  178 +const checkedIds = ref<number[]>([])
  179 +function handleRowCheckboxChange({
180 180 records,
181 181 }: {
182 182 records: ${simpleClassName}Api.${simpleClassName}[];
183 183 }) {
184   - deleteIds.value = records.map((item) => item.id);
  184 + checkedIds.value = records.map((item) => item.id);
185 185 }
186 186 #end
187 187  
... ... @@ -315,7 +315,7 @@ onMounted(() =&gt; {
315 315 class="ml-2"
316 316 :icon="h(Plus)"
317 317 type="primary"
318   - @click="onCreate"
  318 + @click="handleCreate"
319 319 v-access:code="['${permissionPrefix}:create']"
320 320 >
321 321 {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
... ... @@ -336,8 +336,8 @@ onMounted(() =&gt; {
336 336 type="primary"
337 337 danger
338 338 class="ml-2"
339   - :disabled="isEmpty(deleteIds)"
340   - @click="onDeleteBatch"
  339 + :disabled="isEmpty(checkedIds)"
  340 + @click="handleDeleteBatch"
341 341 v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
342 342 >
343 343 批量删除
... ... @@ -368,8 +368,8 @@ onMounted(() =&gt; {
368 368 show-overflow
369 369 :loading="loading"
370 370 #if ($table.templateType != 2 && $deleteBatchEnable)
371   - @checkboxAll="setDeleteIds"
372   - @checkboxChange="setDeleteIds"
  371 + @checkboxAll="handleRowCheckboxChange"
  372 + @checkboxChange="handleRowCheckboxChange"
373 373 #end
374 374 >
375 375 #if ($table.templateType != 2 && $deleteBatchEnable)
... ... @@ -426,7 +426,7 @@ onMounted(() =&gt; {
426 426 <Button
427 427 size="small"
428 428 type="link"
429   - @click="onAppend(row as any)"
  429 + @click="handleAppend(row as any)"
430 430 v-access:code="['${permissionPrefix}:create']"
431 431 >
432 432 新增下级
... ... @@ -435,7 +435,7 @@ onMounted(() =&gt; {
435 435 <Button
436 436 size="small"
437 437 type="link"
438   - @click="onEdit(row as any)"
  438 + @click="handleEdit(row as any)"
439 439 v-access:code="['${permissionPrefix}:update']"
440 440 >
441 441 {{ $t('ui.actionTitle.edit') }}
... ... @@ -448,7 +448,7 @@ onMounted(() =&gt; {
448 448 #if ( $table.templateType == 2 )
449 449 :disabled="!isEmpty(row?.children)"
450 450 #end
451   - @click="onDelete(row as any)"
  451 + @click="handleDelete(row as any)"
452 452 v-access:code="['${permissionPrefix}:delete']"
453 453 >
454 454 {{ $t('ui.actionTitle.delete') }}
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm
... ... @@ -29,7 +29,7 @@
29 29 #end
30 30  
31 31 #if ($table.templateType == 11) ## erp
32   - import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}ListByIds,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
  32 + import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
33 33 import { isEmpty } from '@vben/utils';
34 34 #else
35 35 #if ($subTable.subJoinMany) ## 一对多
... ... @@ -50,7 +50,7 @@ const props = defineProps&lt;{
50 50 });
51 51  
52 52 /** 创建${subTable.classComment} */
53   -function onCreate() {
  53 +function handleCreate() {
54 54 if (!props.${subJoinColumn.javaField}){
55 55 message.warning("请先选择一个${table.classComment}!")
56 56 return
... ... @@ -59,12 +59,12 @@ function onCreate() {
59 59 }
60 60  
61 61 /** 编辑${subTable.classComment} */
62   -function onEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
  62 +function handleEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
63 63 formModalApi.setData(row).open();
64 64 }
65 65  
66 66 /** 删除${subTable.classComment} */
67   -async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
  67 +async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
68 68 const hideLoading = message.loading({
69 69 content: $t('ui.actionMessage.deleting', [row.id]),
70 70 duration: 0,
... ... @@ -84,14 +84,14 @@ async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
84 84  
85 85 #if ($deleteBatchEnable)
86 86 /** 批量删除${subTable.classComment} */
87   -async function onDeleteBatch() {
  87 +async function handleDeleteBatch() {
88 88 const hideLoading = message.loading({
89 89 content: $t('ui.actionMessage.deleting'),
90 90 duration: 0,
91 91 key: 'action_process_msg',
92 92 });
93 93 try {
94   - await delete${subSimpleClassName}ListByIds(deleteIds.value);
  94 + await delete${subSimpleClassName}List(checkedIds.value);
95 95 message.success( $t('ui.actionMessage.deleteSuccess') );
96 96 await getList();
97 97 } finally {
... ... @@ -99,13 +99,13 @@ async function onDeleteBatch() {
99 99 }
100 100 }
101 101  
102   -const deleteIds = ref<number[]>([]) // 待删除${subTable.classComment} ID
103   -function setDeleteIds({
  102 +const checkedIds = ref<number[]>([])
  103 +function handleRowCheckboxChange({
104 104 records,
105 105 }: {
106 106 records: ${simpleClassName}Api.${subSimpleClassName}[];
107 107 }) {
108   - deleteIds.value = records.map((item) => item.id);
  108 + checkedIds.value = records.map((item) => item.id);
109 109 }
110 110 #end
111 111 #end
... ... @@ -299,7 +299,7 @@ onMounted(() =&gt; {
299 299 class="ml-2"
300 300 :icon="h(Plus)"
301 301 type="primary"
302   - @click="onCreate"
  302 + @click="handleCreate"
303 303 v-access:code="['${permissionPrefix}:create']"
304 304 >
305 305 {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
... ... @@ -310,8 +310,8 @@ onMounted(() =&gt; {
310 310 type="primary"
311 311 danger
312 312 class="ml-2"
313   - :disabled="isEmpty(deleteIds)"
314   - @click="onDeleteBatch"
  313 + :disabled="isEmpty(checkedIds)"
  314 + @click="handleDeleteBatch"
315 315 v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
316 316 >
317 317 批量删除
... ... @@ -325,8 +325,8 @@ onMounted(() =&gt; {
325 325 show-overflow
326 326 :loading="loading"
327 327 #if ($deleteBatchEnable)
328   - @checkboxAll="setDeleteIds"
329   - @checkboxChange="setDeleteIds"
  328 + @checkboxAll="handleRowCheckboxChange"
  329 + @checkboxChange="handleRowCheckboxChange"
330 330 #end
331 331 >
332 332 #if ($deleteBatchEnable)
... ... @@ -361,7 +361,7 @@ onMounted(() =&gt; {
361 361 <Button
362 362 size="small"
363 363 type="link"
364   - @click="onEdit(row as any)"
  364 + @click="handleEdit(row as any)"
365 365 v-access:code="['${permissionPrefix}:update']"
366 366 >
367 367 {{ $t('ui.actionTitle.edit') }}
... ... @@ -371,7 +371,7 @@ onMounted(() =&gt; {
371 371 type="link"
372 372 danger
373 373 class="ml-2"
374   - @click="onDelete(row as any)"
  374 + @click="handleDelete(row as any)"
375 375 v-access:code="['${permissionPrefix}:delete']"
376 376 >
377 377 {{ $t('ui.actionTitle.delete') }}
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/api/api.ts.vm
... ... @@ -91,7 +91,7 @@ export function delete${simpleClassName}(id: number) {
91 91  
92 92 #if ( $table.templateType != 2 && $deleteBatchEnable)
93 93 /** 批量删除${table.classComment} */
94   -export function delete${simpleClassName}ListByIds(ids: number[]) {
  94 +export function delete${simpleClassName}List(ids: number[]) {
95 95 return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`)
96 96 }
97 97 #end
... ... @@ -153,7 +153,7 @@ export function delete${subSimpleClassName}(id: number) {
153 153  
154 154 #if ($deleteBatchEnable)
155 155 /** 批量删除${subTable.classComment} */
156   -export function delete${subSimpleClassName}ListByIds(ids: number[]) {
  156 +export function delete${subSimpleClassName}List(ids: number[]) {
157 157 return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)
158 158 }
159 159 #end
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
... ... @@ -426,9 +426,7 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim
426 426 #else
427 427 #if ($subTable.subJoinMany) ## 一对多
428 428 /** 新增/修改列表的字段 */
429   - export function use${subSimpleClassName}GridEditColumns(
430   - onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,
431   - ): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  429 + export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
432 430 return [
433 431 #foreach($column in $subColumns)
434 432 #if ($column.createOperation || $column.updateOperation)
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm
... ... @@ -21,7 +21,7 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from &#39;#/adapter/vxe-table&#39;;
21 21 #if (${table.templateType} == 2)## 树表接口
22 22 import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
23 23 #else## 标准表接口
24   -import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}ListByIds,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  24 +import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
25 25 #end
26 26 import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
27 27  
... ... @@ -101,7 +101,7 @@ async function handleDeleteBatch() {
101 101 key: 'action_key_msg',
102 102 });
103 103 try {
104   - await delete${simpleClassName}ListByIds(deleteIds.value);
  104 + await delete${simpleClassName}List(checkedIds.value);
105 105 message.success({
106 106 content: $t('ui.actionMessage.deleteSuccess'),
107 107 key: 'action_key_msg',
... ... @@ -112,13 +112,13 @@ async function handleDeleteBatch() {
112 112 }
113 113 }
114 114  
115   -const deleteIds = ref<number[]>([]) // 待删除${table.classComment} ID
116   -function setDeleteIds({
  115 +const checkedIds = ref<number[]>([])
  116 +function handleRowCheckboxChange({
117 117 records,
118 118 }: {
119 119 records: ${simpleClassName}Api.${simpleClassName}[];
120 120 }) {
121   - deleteIds.value = records.map((item) => item.id);
  121 + checkedIds.value = records.map((item) => item.id);
122 122 }
123 123 #end
124 124  
... ... @@ -191,9 +191,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
191 191 select${simpleClassName}.value = row;
192 192 },
193 193 #end
194   - #if($deleteBatchEnable)
195   - checkboxAll: setDeleteIds,
196   - checkboxChange: setDeleteIds,
  194 + #if(${table.templateType} != 2 && $deleteBatchEnable)
  195 + checkboxAll: handleRowCheckboxChange,
  196 + checkboxChange: handleRowCheckboxChange,
197 197 #end
198 198 }
199 199 #end
... ... @@ -254,7 +254,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
254 254 type: 'primary',
255 255 danger: true,
256 256 icon: ACTION_ICON.DELETE,
257   - disabled: isEmpty(deleteIds),
  257 + disabled: isEmpty(checkedIds),
258 258 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
259 259 onClick: handleDeleteBatch,
260 260 },
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm
... ... @@ -19,7 +19,7 @@ import { $t } from &#39;#/locales&#39;;
19 19 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
20 20  
21 21 #if ($table.templateType == 11) ## erp
22   -import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}ListByIds,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
  22 +import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
23 23 import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
24 24 import { isEmpty } from '@vben/utils';
25 25 #else
... ... @@ -81,7 +81,7 @@ async function handleDeleteBatch() {
81 81 key: 'action_key_msg',
82 82 });
83 83 try {
84   - await delete${subSimpleClassName}ListByIds(deleteIds.value);
  84 + await delete${subSimpleClassName}List(checkedIds.value);
85 85 message.success({
86 86 content: $t('ui.actionMessage.deleteSuccess', [row.id]),
87 87 key: 'action_key_msg',
... ... @@ -92,13 +92,13 @@ async function handleDeleteBatch() {
92 92 }
93 93 }
94 94  
95   -const deleteIds = ref<number[]>([]) // 待删除${subTable.classComment} ID
96   -function setDeleteIds({
  95 +const checkedIds = ref<number[]>([])
  96 +function handleRowCheckboxChange({
97 97 records,
98 98 }: {
99 99 records: ${simpleClassName}Api.${subSimpleClassName}[];
100 100 }) {
101   - deleteIds.value = records.map((item) => item.id);
  101 + checkedIds.value = records.map((item) => item.id);
102 102 }
103 103 #end
104 104  
... ... @@ -151,8 +151,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
151 151 } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>,
152 152 #if (${table.templateType} == 11 && $deleteBatchEnable)
153 153 gridEvents:{
154   - checkboxAll: setDeleteIds,
155   - checkboxChange: setDeleteIds,
  154 + checkboxAll: handleRowCheckboxChange,
  155 + checkboxChange: handleRowCheckboxChange,
156 156 }
157 157 #end
158 158 });
... ... @@ -204,7 +204,7 @@ watch(
204 204 type: 'primary',
205 205 danger: true,
206 206 icon: ACTION_ICON.DELETE,
207   - disabled: isEmpty(deleteIds),
  207 + disabled: isEmpty(checkedIds),
208 208 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
209 209 onClick: handleDeleteBatch,
210 210 },
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/api/api.ts.vm 0 → 100644
  1 +import type { PageParam, PageResult } from '@vben/request';
  2 +import type { Dayjs } from 'dayjs';
  3 +
  4 +import { requestClient } from '#/api/request';
  5 +#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
  6 +
  7 +export namespace ${simpleClassName}Api {
  8 + ## 特殊:主子表专属逻辑
  9 + #foreach ($subTable in $subTables)
  10 + #set ($index = $foreach.count - 1)
  11 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  12 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  13 + /** ${subTable.classComment}信息 */
  14 + export interface ${subSimpleClassName} {
  15 + #foreach ($column in $subColumns)
  16 + #if ($column.createOperation || $column.updateOperation)
  17 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  18 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  19 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  20 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  21 + #else
  22 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  23 + #end
  24 + #end
  25 + #end
  26 + }
  27 +
  28 + #end
  29 + /** ${table.classComment}信息 */
  30 + export interface ${simpleClassName} {
  31 + #foreach ($column in $columns)
  32 + #if ($column.createOperation || $column.updateOperation)
  33 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  34 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  35 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  36 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  37 + #else
  38 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  39 + #end
  40 + #end
  41 + #end
  42 + #if ( $table.templateType == 2 )
  43 + children?: ${simpleClassName}[];
  44 + #end
  45 + ## 特殊:主子表专属逻辑
  46 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  47 + #foreach ($subTable in $subTables)
  48 + #set ($index = $foreach.count - 1)
  49 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  50 + #if ( $subTable.subJoinMany )
  51 + ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
  52 + #else
  53 + ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
  54 + #end
  55 + #end
  56 + #end
  57 + }
  58 +}
  59 +
  60 +#if ( $table.templateType != 2 )
  61 +/** 查询${table.classComment}分页 */
  62 +export function get${simpleClassName}Page(params: PageParam) {
  63 + return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params });
  64 +}
  65 +#else
  66 +/** 查询${table.classComment}列表 */
  67 +export function get${simpleClassName}List(params: any) {
  68 + return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params });
  69 +}
  70 +#end
  71 +
  72 +/** 查询${table.classComment}详情 */
  73 +export function get${simpleClassName}(id: number) {
  74 + return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`);
  75 +}
  76 +
  77 +/** 新增${table.classComment} */
  78 +export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  79 + return requestClient.post('${baseURL}/create', data);
  80 +}
  81 +
  82 +/** 修改${table.classComment} */
  83 +export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  84 + return requestClient.put('${baseURL}/update', data);
  85 +}
  86 +
  87 +/** 删除${table.classComment} */
  88 +export function delete${simpleClassName}(id: number) {
  89 + return requestClient.delete(`${baseURL}/delete?id=${id}`);
  90 +}
  91 +
  92 +#if ( $table.templateType != 2 && $deleteBatchEnable)
  93 +/** 批量删除${table.classComment} */
  94 +export function delete${simpleClassName}List(ids: number[]) {
  95 + return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`)
  96 +}
  97 +#end
  98 +
  99 +/** 导出${table.classComment} */
  100 +export function export${simpleClassName}(params: any) {
  101 + return requestClient.download('${baseURL}/export-excel', params);
  102 +}
  103 +
  104 +## 特殊:主子表专属逻辑
  105 +#foreach ($subTable in $subTables)
  106 + #set ($index = $foreach.count - 1)
  107 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  108 + #set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
  109 + #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  110 + #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  111 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  112 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  113 + #set ($subClassNameVar = $subClassNameVars.get($index))
  114 +
  115 +// ==================== 子表($subTable.classComment) ====================
  116 +
  117 +## 情况一:MASTER_ERP 时,需要分查询页子表
  118 +#if ( $table.templateType == 11 )
  119 +/** 获得${subTable.classComment}分页 */
  120 +export function get${subSimpleClassName}Page(params: PageParam) {
  121 + return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
  122 +}
  123 + ## 情况二:非 MASTER_ERP 时,需要列表查询子表
  124 +#else
  125 +#if ( $subTable.subJoinMany )
  126 +/** 获得${subTable.classComment}列表 */
  127 +export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  128 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  129 +}
  130 +#else
  131 +/** 获得${subTable.classComment} */
  132 +export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  133 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  134 +}
  135 +#end
  136 +#end
  137 +## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
  138 +#if ( $table.templateType == 11 )
  139 +/** 新增${subTable.classComment} */
  140 +export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  141 + return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
  142 +}
  143 +
  144 +/** 修改${subTable.classComment} */
  145 +export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  146 + return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
  147 +}
  148 +
  149 +/** 删除${subTable.classComment} */
  150 +export function delete${subSimpleClassName}(id: number) {
  151 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
  152 +}
  153 +
  154 +#if ($deleteBatchEnable)
  155 +/** 批量删除${subTable.classComment} */
  156 +export function delete${subSimpleClassName}List(ids: number[]) {
  157 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)
  158 +}
  159 +#end
  160 +
  161 +/** 获得${subTable.classComment} */
  162 +export function get${subSimpleClassName}(id: number) {
  163 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
  164 +}
  165 +#end
  166 +#end
  167 +
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/form.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +import type { FormRules } from 'element-plus';
  4 +
  5 +import { useVbenModal } from '@vben/common-ui';
  6 +import { Tinymce as RichTextarea } from '#/components/tinymce';
  7 +import { ImageUpload, FileUpload } from "#/components/upload";
  8 +import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus';
  9 +import { DICT_TYPE, getDictOptions } from '#/utils';
  10 +#if($table.templateType == 2)## 树表需要导入这些
  11 +import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  12 +import { handleTree } from '@vben/utils'
  13 +#end
  14 +## 特殊:主子表专属逻辑
  15 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  16 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  17 + #set ($index = $foreach.count - 1)
  18 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  19 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  20 + #end
  21 +#end
  22 +
  23 +import { computed, ref, reactive } from 'vue';
  24 +import { $t } from '#/locales';
  25 +import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  26 +
  27 +const emit = defineEmits(['success']);
  28 +
  29 +const formRef = ref();
  30 +const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({
  31 +#foreach ($column in $columns)
  32 + #if ($column.createOperation || $column.updateOperation)
  33 + #if ($column.htmlType == "checkbox")
  34 + $column.javaField: [],
  35 + #else
  36 + $column.javaField: undefined,
  37 + #end
  38 + #end
  39 +#end
  40 +});
  41 +const rules = reactive<FormRules>({
  42 + #foreach ($column in $columns)
  43 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  44 + #set($comment=$column.columnComment)
  45 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  46 + #end
  47 + #end
  48 +});
  49 +## 特殊:树表专属逻辑
  50 +#if ( $table.templateType == 2 )
  51 +const ${classNameVar}Tree = ref<any[]>([]) // 树形结构
  52 +#end
  53 +const getTitle = computed(() => {
  54 + return formData.value?.id
  55 + ? $t('ui.actionTitle.edit', ['${table.classComment}'])
  56 + : $t('ui.actionTitle.create', ['${table.classComment}']);
  57 +});
  58 +
  59 +## 特殊:主子表专属逻辑
  60 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  61 + #if ( $subTables && $subTables.size() > 0 )
  62 + /** 子表的表单 */
  63 + const subTabsName = ref('$subClassNameVars.get(0)')
  64 + #foreach ($subClassNameVar in $subClassNameVars)
  65 + #set ($index = $foreach.count - 1)
  66 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  67 + const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
  68 + #end
  69 + #end
  70 +#end
  71 +
  72 +/** 重置表单 */
  73 +const resetForm = () => {
  74 + formData.value = {
  75 + #foreach ($column in $columns)
  76 + #if ($column.createOperation || $column.updateOperation)
  77 + #if ($column.htmlType == "checkbox")
  78 + $column.javaField: [],
  79 + #else
  80 + $column.javaField: undefined,
  81 + #end
  82 + #end
  83 + #end
  84 + };
  85 + formRef.value?.resetFields();
  86 +}
  87 +
  88 +## 特殊:树表专属逻辑
  89 +#if ( $table.templateType == 2 )
  90 +/** 获得${table.classComment}树 */
  91 +const get${simpleClassName}Tree = async () => {
  92 + ${classNameVar}Tree.value = []
  93 + const data = await get${simpleClassName}List({});
  94 + data.unshift({
  95 + id: 0,
  96 + name: '顶级${table.classComment}',
  97 + });
  98 + ${classNameVar}Tree.value = handleTree(data);
  99 +}
  100 +#end
  101 +
  102 +const [Modal, modalApi] = useVbenModal({
  103 + async onConfirm() {
  104 + await formRef.value?.validate();
  105 + ## 特殊:主子表专属逻辑
  106 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  107 + #if ( $subTables && $subTables.size() > 0 )
  108 + // 校验子表单
  109 + #foreach ($subTable in $subTables)
  110 + #set ($index = $foreach.count - 1)
  111 + #set ($subClassNameVar = $subClassNameVars.get($index))
  112 + #if ($subTable.subJoinMany) ## 一对多
  113 + ## TODO 列表值校验?
  114 + #else
  115 + try {
  116 + await ${subClassNameVar}FormRef.value?.validate()
  117 + } catch (e) {
  118 + subTabsName.value = '${subClassNameVar}'
  119 + return
  120 + }
  121 + #end
  122 + #end
  123 + #end
  124 + #end
  125 + modalApi.lock();
  126 + // 提交表单
  127 + const data = formData.value as ${simpleClassName}Api.${simpleClassName};
  128 + ## 特殊:主子表专属逻辑
  129 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  130 + #if ( $subTables && $subTables.size() > 0 )
  131 + // 拼接子表的数据
  132 + #foreach ($subTable in $subTables)
  133 + #set ($index = $foreach.count - 1)
  134 + #set ($subClassNameVar = $subClassNameVars.get($index))
  135 + #if ($subTable.subJoinMany)
  136 + data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
  137 + #else
  138 + data.${subClassNameVar} = ${subClassNameVar}FormRef.value?.getValues();
  139 + #end
  140 + #end
  141 + #end
  142 + #end
  143 + try {
  144 + await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
  145 + // 关闭并提示
  146 + await modalApi.close();
  147 + emit('success');
  148 + ElMessage.success($t('ui.actionMessage.operationSuccess'));
  149 + } finally {
  150 + modalApi.unlock();
  151 + }
  152 + },
  153 + async onOpenChange(isOpen: boolean) {
  154 + if (!isOpen) {
  155 + resetForm()
  156 + return;
  157 + }
  158 + // 加载数据
  159 + let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
  160 + if (!data) {
  161 + return;
  162 + }
  163 + if (data.id) {
  164 + modalApi.lock();
  165 + try {
  166 + data = await get${simpleClassName}(data.id);
  167 + } finally {
  168 + modalApi.unlock();
  169 + }
  170 + }
  171 + formData.value = data;
  172 +#if ( $table.templateType == 2 )
  173 + // 加载树数据
  174 + await get${simpleClassName}Tree()
  175 +#end
  176 + },
  177 +});
  178 +</script>
  179 +
  180 +<template>
  181 + <Modal :title="getTitle">
  182 + <el-form
  183 + ref="formRef"
  184 + :model="formData"
  185 + :rules="rules"
  186 + label-width="120px"
  187 + label-position="right"
  188 + >
  189 + #foreach($column in $columns)
  190 + #if ($column.createOperation || $column.updateOperation)
  191 + #set ($dictType = $column.dictType)
  192 + #set ($javaField = $column.javaField)
  193 + #set ($javaType = $column.javaType)
  194 + #set ($comment = $column.columnComment)
  195 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  196 + #set ($dictMethod = "number")
  197 + #elseif ($javaType == "String")
  198 + #set ($dictMethod = "string")
  199 + #elseif ($javaType == "Boolean")
  200 + #set ($dictMethod = "boolean")
  201 + #end
  202 + #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
  203 + <el-form-item label="${comment}" prop="${javaField}">
  204 + <el-tree-select
  205 + v-model="formData.${javaField}"
  206 + :data="${classNameVar}Tree"
  207 + #if ($treeNameColumn.javaField == "name")
  208 + :props="{
  209 + label: 'name',
  210 + value: 'id',
  211 + children: 'children',
  212 + }"
  213 + #else
  214 + :props="{
  215 + label: '$treeNameColumn.javaField',
  216 + value: 'id',
  217 + children: 'children',
  218 + }"
  219 + #end
  220 + check-strictly
  221 + default-expand-all
  222 + placeholder="请选择${comment}"
  223 + />
  224 + </el-form-item>
  225 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  226 + <el-form-item label="${comment}" prop="${javaField}">
  227 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  228 + </el-form-item>
  229 + #elseif($column.htmlType == "imageUpload")## 图片上传
  230 + <el-form-item label="${comment}" prop="${javaField}">
  231 + <ImageUpload v-model="formData.${javaField}" />
  232 + </el-form-item>
  233 + #elseif($column.htmlType == "fileUpload")## 文件上传
  234 + <el-form-item label="${comment}" prop="${javaField}">
  235 + <FileUpload v-model="formData.${javaField}" />
  236 + </el-form-item>
  237 + #elseif($column.htmlType == "editor")## 文本编辑器
  238 + <el-form-item label="${comment}" prop="${javaField}">
  239 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  240 + </el-form-item>
  241 + #elseif($column.htmlType == "select")## 下拉框
  242 + <el-form-item label="${comment}" prop="${javaField}">
  243 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  244 + #if ("" != $dictType)## 有数据字典
  245 + <el-option
  246 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  247 + :key="dict.value"
  248 + :value="dict.value"
  249 + :label="dict.label"
  250 + />
  251 + #else##没数据字典
  252 + <el-option label="请选择字典生成" value="" />
  253 + #end
  254 + </el-select>
  255 + </el-form-item>
  256 + #elseif($column.htmlType == "checkbox")## 多选框
  257 + <el-form-item label="${comment}" prop="${javaField}">
  258 + <el-checkbox-group v-model="formData.${javaField}">
  259 + #if ("" != $dictType)## 有数据字典
  260 + <el-checkbox
  261 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  262 + :key="dict.value"
  263 + :label="dict.value"
  264 + >
  265 + {{ dict.label }}
  266 + </el-checkbox>
  267 + #else##没数据字典
  268 + <el-checkbox label="请选择字典生成" />
  269 + #end
  270 + </el-checkbox-group>
  271 + </el-form-item>
  272 + #elseif($column.htmlType == "radio")## 单选框
  273 + <el-form-item label="${comment}" prop="${javaField}">
  274 + <el-radio-group v-model="formData.${javaField}">
  275 + #if ("" != $dictType)## 有数据字典
  276 + <el-radio
  277 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  278 + :key="dict.value"
  279 + :label="dict.value"
  280 + >
  281 + {{ dict.label }}
  282 + </el-radio>
  283 + #else##没数据字典
  284 + <el-radio :label="1">请选择字典生成</el-radio>
  285 + #end
  286 + </el-radio-group>
  287 + </el-form-item>
  288 + #elseif($column.htmlType == "datetime")## 时间框
  289 + <el-form-item label="${comment}" prop="${javaField}">
  290 + <el-date-picker
  291 + v-model="formData.${javaField}"
  292 + value-format="x"
  293 + placeholder="选择${comment}"
  294 + />
  295 + </el-form-item>
  296 + #elseif($column.htmlType == "textarea")## 文本框
  297 + <el-form-item label="${comment}" prop="${javaField}">
  298 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  299 + </el-form-item>
  300 + #end
  301 + #end
  302 + #end
  303 + </el-form>
  304 + ## 特殊:主子表专属逻辑
  305 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  306 + <!-- 子表的表单 -->
  307 + <el-tabs v-model="subTabsName">
  308 + #foreach ($subTable in $subTables)
  309 + #set ($index = $foreach.count - 1)
  310 + #set ($subClassNameVar = $subClassNameVars.get($index))
  311 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  312 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  313 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  314 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
  315 + </el-tab-pane>
  316 + #end
  317 + </el-tabs>
  318 + #end
  319 + </Modal>
  320 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/index.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +import type { VxeTableInstance } from '#/adapter/vxe-table';
  4 +
  5 +import { Page, useVbenModal } from '@vben/common-ui';
  6 +import { cloneDeep, formatDateTime } from '@vben/utils';
  7 +import { ElButton, ElMessage, ElLoading, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus';
  8 +import { DictTag } from '#/components/dict-tag';
  9 +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
  10 +import ${simpleClassName}Form from './modules/form.vue';
  11 +import { Download, Plus, RefreshCw, Search, Trash2 } from '@vben/icons';
  12 +import { ContentWrap } from '#/components/content-wrap';
  13 +import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
  14 +import { TableToolbar } from '#/components/table-toolbar';
  15 +import { useTableToolbar } from '#/hooks';
  16 +
  17 +## 特殊:主子表专属逻辑
  18 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  19 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  20 + #set ($index = $foreach.count - 1)
  21 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  22 + import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
  23 + #end
  24 +#end
  25 +
  26 +import { ref, h, reactive,onMounted,nextTick } from 'vue';
  27 +import { $t } from '#/locales';
  28 +#if (${table.templateType} == 2)## 树表接口
  29 +import { handleTree,isEmpty } from '@vben/utils'
  30 +import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  31 +#else## 标准表接口
  32 +import { isEmpty } from '@vben/utils';
  33 +import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  34 +#end
  35 +import { downloadFileFromBlobPart } from '@vben/utils';
  36 +
  37 +#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
  38 +/** 子表的列表 */
  39 +const subTabsName = ref('$subClassNameVars.get(0)')
  40 +#if ($table.templateType == 11)
  41 +const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
  42 +async function onCellClick({ row }: { row: ${simpleClassName}Api.${simpleClassName} }) {
  43 + select${simpleClassName}.value = row
  44 +}
  45 +#end
  46 +#end
  47 +
  48 +const loading = ref(true) // 列表的加载中
  49 +#if ( $table.templateType == 2 )
  50 +const list = ref<any[]>([]) // 树列表的数据
  51 +#else
  52 +const list = ref<${simpleClassName}Api.${simpleClassName}[]>([]) // 列表的数据
  53 +#end
  54 +
  55 +## 特殊:树表专属逻辑(树不需要分页接口)
  56 +#if ( $table.templateType != 2 )
  57 +const total = ref(0) // 列表的总页数
  58 +#end
  59 +const queryParams = reactive({
  60 +## 特殊:树表专属逻辑(树不需要分页接口)
  61 +#if ( $table.templateType != 2 )
  62 + pageNo: 1,
  63 + pageSize: 10,
  64 +#end
  65 +#foreach ($column in $columns)
  66 + #if ($column.listOperation)
  67 + #if ($column.listOperationCondition != 'BETWEEN')
  68 + $column.javaField: undefined,
  69 + #end
  70 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  71 + $column.javaField: undefined,
  72 + #end
  73 + #end
  74 +#end
  75 +})
  76 +const queryFormRef = ref() // 搜索的表单
  77 +const exportLoading = ref(false) // 导出的加载中
  78 +
  79 +/** 查询列表 */
  80 +const getList = async () => {
  81 + loading.value = true
  82 + try {
  83 + const params = cloneDeep(queryParams) as any;
  84 + #foreach ($column in $columns)
  85 + #if ($column.listOperation)
  86 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  87 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  88 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  89 + }
  90 + #end
  91 + #end
  92 + #end
  93 + ## 特殊:树表专属逻辑(树不需要分页接口)
  94 + #if ( $table.templateType == 2 )
  95 + list.value = await get${simpleClassName}List(params);
  96 + #else
  97 + const data = await get${simpleClassName}Page(params)
  98 + list.value = data.list
  99 + total.value = data.total
  100 + #end
  101 + } finally {
  102 + loading.value = false
  103 + }
  104 +}
  105 +
  106 +/** 搜索按钮操作 */
  107 +const handleQuery = () => {
  108 +#if ( $table.templateType != 2 )
  109 + queryParams.pageNo = 1
  110 +#end
  111 + getList()
  112 +}
  113 +
  114 +/** 重置按钮操作 */
  115 +const resetQuery = () => {
  116 + queryFormRef.value.resetFields()
  117 + handleQuery()
  118 +}
  119 +
  120 +const [FormModal, formModalApi] = useVbenModal({
  121 + connectedComponent: ${simpleClassName}Form,
  122 + destroyOnClose: true,
  123 +});
  124 +
  125 +/** 创建${table.classComment} */
  126 +function handleCreate() {
  127 + formModalApi.setData({}).open();
  128 +}
  129 +
  130 +/** 编辑${table.classComment} */
  131 +function handleEdit(row: ${simpleClassName}Api.${simpleClassName}) {
  132 + formModalApi.setData(row).open();
  133 +}
  134 +
  135 +#if (${table.templateType} == 2)## 树表特有:新增下级
  136 +/** 新增下级${table.classComment} */
  137 +function handleAppend(row: ${simpleClassName}Api.${simpleClassName}) {
  138 + formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
  139 +}
  140 +#end
  141 +
  142 +/** 删除${table.classComment} */
  143 +async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
  144 + const loadingInstance = ElLoading.service({
  145 + text: $t('ui.actionMessage.deleting', [row.id]),
  146 + background: 'rgba(0, 0, 0, 0.7)',
  147 + });
  148 + try {
  149 + await delete${simpleClassName}(row.id as number);
  150 + ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  151 + await getList();
  152 + } finally {
  153 + loadingInstance.close();
  154 + }
  155 +}
  156 +
  157 +#if ($table.templateType != 2 && $deleteBatchEnable)
  158 +/** 批量删除${table.classComment} */
  159 +async function handleDeleteBatch() {
  160 + const loadingInstance = ElLoading.service({
  161 + text: $t('ui.actionMessage.deleting'),
  162 + background: 'rgba(0, 0, 0, 0.7)',
  163 + });
  164 + try {
  165 + await delete${simpleClassName}List(checkedIds.value);
  166 + ElMessage.success($t('ui.actionMessage.deleteSuccess'));
  167 + await getList();
  168 + } finally {
  169 + loadingInstance.close();
  170 + }
  171 +}
  172 +
  173 +const checkedIds = ref<number[]>([])
  174 +function handleRowCheckboxChange({
  175 + records,
  176 +}: {
  177 + records: ${simpleClassName}Api.${simpleClassName}[];
  178 +}) {
  179 + checkedIds.value = records.map((item) => item.id);
  180 +}
  181 +#end
  182 +
  183 +/** 导出表格 */
  184 +async function onExport() {
  185 +try {
  186 + exportLoading.value = true;
  187 + const data = await export${simpleClassName}(queryParams);
  188 + downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data });
  189 +}finally {
  190 + exportLoading.value = false;
  191 +}
  192 +}
  193 +
  194 +#if (${table.templateType} == 2)
  195 +/** 切换树形展开/收缩状态 */
  196 +const isExpanded = ref(true);
  197 +function toggleExpand() {
  198 + isExpanded.value = !isExpanded.value;
  199 + tableRef.value?.setAllTreeExpand(isExpanded.value);
  200 +}
  201 +#end
  202 +
  203 +/** 初始化 */
  204 +const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
  205 +onMounted(() => {
  206 + getList();
  207 +});
  208 +</script>
  209 +
  210 +<template>
  211 + <Page auto-content-height>
  212 + <FormModal @success="getList" />
  213 +
  214 + <ContentWrap v-if="!hiddenSearchBar">
  215 + <!-- 搜索工作栏 -->
  216 + <el-form
  217 + :model="queryParams"
  218 + ref="queryFormRef"
  219 + inline
  220 + >
  221 + #foreach($column in $columns)
  222 + #if ($column.listOperation)
  223 + #set ($dictType = $column.dictType)
  224 + #set ($javaField = $column.javaField)
  225 + #set ($javaType = $column.javaType)
  226 + #set ($comment = $column.columnComment)
  227 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  228 + #set ($dictMethod = "number")
  229 + #elseif ($javaType == "String")
  230 + #set ($dictMethod = "string")
  231 + #elseif ($javaType == "Boolean")
  232 + #set ($dictMethod = "boolean")
  233 + #end
  234 + #if ($column.htmlType == "input")
  235 + <el-form-item label="${comment}">
  236 + <el-input
  237 + v-model="queryParams.${javaField}"
  238 + placeholder="请输入${comment}"
  239 + clearable
  240 + @keyup.enter="handleQuery"
  241 + class="!w-[240px]"
  242 + />
  243 + </el-form-item>
  244 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
  245 + <el-form-item label="${comment}">
  246 + <el-select
  247 + v-model="queryParams.${javaField}"
  248 + placeholder="请选择${comment}"
  249 + clearable
  250 + class="!w-[240px]"
  251 + >
  252 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  253 + <el-option
  254 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  255 + :key="dict.value"
  256 + :value="dict.value"
  257 + :label="dict.label"
  258 + />
  259 + #else## 未设置 dictType 数据字典的情况
  260 + <el-option label="请选择字典生成" value="" />
  261 + #end
  262 + </el-select>
  263 + </el-form-item>
  264 + #elseif($column.htmlType == "datetime")
  265 + #if ($column.listOperationCondition != "BETWEEN")## 非范围
  266 + <el-form-item label="${comment}">
  267 + <el-date-picker
  268 + v-model="queryParams.${javaField}"
  269 + value-format="YYYY-MM-DD"
  270 + placeholder="选择${comment}"
  271 + clearable
  272 + class="!w-[240px]"
  273 + />
  274 + </el-form-item>
  275 + #else## 范围
  276 + <el-form-item label="${comment}">
  277 + <el-date-picker
  278 + v-model="queryParams.${javaField}"
  279 + type="daterange"
  280 + value-format="YYYY-MM-DD"
  281 + range-separator="至"
  282 + start-placeholder="开始日期"
  283 + end-placeholder="结束日期"
  284 + class="!w-[240px]"
  285 + />
  286 + </el-form-item>
  287 + #end
  288 + #end
  289 + #end
  290 + #end
  291 + <el-form-item>
  292 + <el-button class="ml-2" @click="resetQuery"> 重置 </el-button>
  293 + <el-button class="ml-2" @click="handleQuery" type="primary">
  294 + 搜索
  295 + </el-button>
  296 + </el-form-item>
  297 + </el-form>
  298 + </ContentWrap>
  299 +
  300 + <!-- 列表 -->
  301 + <ContentWrap title="${table.classComment}">
  302 + <template #extra>
  303 + <TableToolbar
  304 + ref="tableToolbarRef"
  305 + v-model:hidden-search="hiddenSearchBar"
  306 + >
  307 + #if (${table.templateType} == 2)
  308 + <el-button @click="toggleExpand" class="mr-2">
  309 + {{ isExpanded ? '收缩' : '展开' }}
  310 + </el-button>
  311 + #end
  312 + <el-button
  313 + class="ml-2"
  314 + :icon="h(Plus)"
  315 + type="primary"
  316 + @click="handleCreate"
  317 + v-access:code="['${permissionPrefix}:create']"
  318 + >
  319 + {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
  320 + </el-button>
  321 + <el-button
  322 + :icon="h(Download)"
  323 + type="primary"
  324 + class="ml-2"
  325 + :loading="exportLoading"
  326 + @click="onExport"
  327 + v-access:code="['${permissionPrefix}:export']"
  328 + >
  329 + {{ $t('ui.actionTitle.export') }}
  330 + </el-button>
  331 + #if ($table.templateType != 2 && $deleteBatchEnable)
  332 + <el-button
  333 + :icon="h(Trash2)"
  334 + type="danger"
  335 + class="ml-2"
  336 + :disabled="isEmpty(checkedIds)"
  337 + @click="handleDeleteBatch"
  338 + v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
  339 + >
  340 + 批量删除
  341 + </el-button>
  342 + #end
  343 + </TableToolbar>
  344 + </template>
  345 + <vxe-table
  346 + ref="tableRef"
  347 + :data="list"
  348 + #if ( $table.templateType == 2 )
  349 + :tree-config="{
  350 + parentField: '${treeParentColumn.javaField}',
  351 + rowField: 'id',
  352 + transform: true,
  353 + expandAll: true,
  354 + reserve: true,
  355 + }"
  356 + #end
  357 +#if ($table.templateType == 11) ## erp情况
  358 + @cell-click="onCellClick"
  359 + :row-config="{
  360 + keyField: 'id',
  361 + isHover: true,
  362 + isCurrent: true,
  363 + }"
  364 +#end
  365 + show-overflow
  366 + :loading="loading"
  367 +#if ($table.templateType != 2 && $deleteBatchEnable)
  368 + @checkboxAll="handleRowCheckboxChange"
  369 + @checkboxChange="handleRowCheckboxChange"
  370 +#end
  371 + >
  372 +#if ($table.templateType != 2 && $deleteBatchEnable)
  373 + <vxe-column type="checkbox" width="40"></vxe-column>
  374 +#end
  375 + ## 特殊:主子表专属逻辑
  376 + #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
  377 + <!-- 子表的列表 -->
  378 + <vxe-column type="expand" width="60">
  379 + <template #content="{ row }">
  380 + <!-- 子表的表单 -->
  381 + <el-tabs v-model="subTabsName" class="mx-8">
  382 + #foreach ($subTable in $subTables)
  383 + #set ($index = $foreach.count - 1)
  384 + #set ($subClassNameVar = $subClassNameVars.get($index))
  385 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  386 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  387 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  388 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
  389 + </el-tab-pane>
  390 + #end
  391 + </el-tabs>
  392 + </template>
  393 + </vxe-column>
  394 + #end
  395 + #foreach($column in $columns)
  396 + #if ($column.listOperationResult)
  397 + #set ($dictType=$column.dictType)
  398 + #set ($javaField = $column.javaField)
  399 + #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  400 + #set ($comment=$column.columnComment)
  401 + #if ($column.javaType == "LocalDateTime")## 时间类型
  402 + <vxe-column field="${javaField}" title="${comment}" align="center">
  403 + <template #default="{row}">
  404 + {{formatDateTime(row.${javaField})}}
  405 + </template>
  406 + </vxe-column>
  407 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  408 + <vxe-column field="${javaField}" title="${comment}" align="center">
  409 + <template #default="{row}">
  410 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  411 + </template>
  412 + </vxe-column>
  413 + #elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
  414 + <vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
  415 + #else
  416 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  417 + #end
  418 + #end
  419 + #end
  420 + <vxe-column field="operation" title="操作" align="center">
  421 + <template #default="{row}">
  422 +#if ( $table.templateType == 2 )
  423 + <el-button
  424 + size="small"
  425 + type="primary"
  426 + link
  427 + @click="handleAppend(row as any)"
  428 + v-access:code="['${permissionPrefix}:create']"
  429 + >
  430 + 新增下级
  431 + </el-button>
  432 +#end
  433 + <el-button
  434 + size="small"
  435 + type="primary"
  436 + link
  437 + @click="handleEdit(row as any)"
  438 + v-access:code="['${permissionPrefix}:update']"
  439 + >
  440 + {{ $t('ui.actionTitle.edit') }}
  441 + </el-button>
  442 + <el-button
  443 + size="small"
  444 + type="danger"
  445 + link
  446 + class="ml-2"
  447 + #if ( $table.templateType == 2 )
  448 + :disabled="!isEmpty(row?.children)"
  449 + #end
  450 + @click="handleDelete(row as any)"
  451 + v-access:code="['${permissionPrefix}:delete']"
  452 + >
  453 + {{ $t('ui.actionTitle.delete') }}
  454 + </el-button>
  455 + </template>
  456 + </vxe-column>
  457 + </vxe-table>
  458 +#if ( $table.templateType != 2 )
  459 + <!-- 分页 -->
  460 + <div class="mt-2 flex justify-end">
  461 + <el-pagination
  462 + :total="total"
  463 + v-model:current-page="queryParams.pageNo"
  464 + v-model:page-size="queryParams.pageSize"
  465 + :page-sizes="[10, 20, 50, 100]"
  466 + layout="total, sizes, prev, pager, next, jumper"
  467 + @size-change="getList"
  468 + @current-change="getList"
  469 + />
  470 + </div>
  471 +#end
  472 + </ContentWrap>
  473 +#if ($table.templateType == 11) ## erp情况
  474 + <ContentWrap>
  475 + <!-- 子表的表单 -->
  476 + <el-tabs v-model="subTabsName">
  477 + #foreach ($subTable in $subTables)
  478 + #set ($index = $foreach.count - 1)
  479 + #set ($subClassNameVar = $subClassNameVars.get($index))
  480 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  481 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  482 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  483 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
  484 + </el-tab-pane>
  485 + #end
  486 + </el-tabs>
  487 + </ContentWrap>
  488 +#end
  489 + </Page>
  490 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/form_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +<script lang="ts" setup>
  6 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  7 + import type { FormRules } from 'element-plus';
  8 +
  9 + import { useVbenModal } from '@vben/common-ui';
  10 + import { Tinymce as RichTextarea } from '#/components/tinymce';
  11 + import { ImageUpload, FileUpload } from "#/components/upload";
  12 + import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus';
  13 + import { DICT_TYPE, getDictOptions } from '#/utils';
  14 +
  15 + import { computed, ref, reactive } from 'vue';
  16 + import { $t } from '#/locales';
  17 +
  18 + import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  19 +
  20 + const emit = defineEmits(['success']);
  21 + const getTitle = computed(() => {
  22 + return formData.value?.id
  23 + ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
  24 + : $t('ui.actionTitle.create', ['${subTable.classComment}']);
  25 + });
  26 +
  27 + const formRef = ref();
  28 + const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
  29 + #foreach ($column in $subColumns)
  30 + #if ($column.createOperation || $column.updateOperation)
  31 + #if ($column.htmlType == "checkbox")
  32 + $column.javaField: [],
  33 + #else
  34 + $column.javaField: undefined,
  35 + #end
  36 + #end
  37 + #end
  38 + });
  39 + const rules = reactive<FormRules>({
  40 + #foreach ($column in $subColumns)
  41 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  42 + #set($comment=$column.columnComment)
  43 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  44 + #end
  45 + #end
  46 + });
  47 +
  48 + const [Modal, modalApi] = useVbenModal({
  49 + async onConfirm() {
  50 + await formRef.value?.validate();
  51 +
  52 + modalApi.lock();
  53 + // 提交表单
  54 + const data = formData.value as ${simpleClassName}Api.${subSimpleClassName};
  55 + try {
  56 + await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
  57 + // 关闭并提示
  58 + await modalApi.close();
  59 + emit('success');
  60 + ElMessage.success($t('ui.actionMessage.operationSuccess'));
  61 + } finally {
  62 + modalApi.unlock();
  63 + }
  64 + },
  65 + async onOpenChange(isOpen: boolean) {
  66 + if (!isOpen) {
  67 + resetForm()
  68 + return;
  69 + }
  70 +
  71 + // 加载数据
  72 + let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
  73 + if (!data) {
  74 + return;
  75 + }
  76 + if (data.id) {
  77 + modalApi.lock();
  78 + try {
  79 + data = await get${subSimpleClassName}(data.id);
  80 + } finally {
  81 + modalApi.unlock();
  82 + }
  83 + }
  84 + // 设置到 values
  85 + formData.value = data;
  86 + },
  87 + });
  88 +
  89 + /** 重置表单 */
  90 + const resetForm = () => {
  91 + formData.value = {
  92 + #foreach ($column in $subColumns)
  93 + #if ($column.createOperation || $column.updateOperation)
  94 + #if ($column.htmlType == "checkbox")
  95 + $column.javaField: [],
  96 + #else
  97 + $column.javaField: undefined,
  98 + #end
  99 + #end
  100 + #end
  101 + };
  102 + formRef.value?.resetFields();
  103 + }
  104 +</script>
  105 +
  106 +<template>
  107 + <Modal :title="getTitle">
  108 + <el-form
  109 + ref="formRef"
  110 + :model="formData"
  111 + :rules="rules"
  112 + label-width="120px"
  113 + label-position="right"
  114 + >
  115 + #foreach($column in $subColumns)
  116 + #if ($column.createOperation || $column.updateOperation)
  117 + #set ($dictType = $column.dictType)
  118 + #set ($javaField = $column.javaField)
  119 + #set ($javaType = $column.javaType)
  120 + #set ($comment = $column.columnComment)
  121 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  122 + #set ($dictMethod = "number")
  123 + #elseif ($javaType == "String")
  124 + #set ($dictMethod = "string")
  125 + #elseif ($javaType == "Boolean")
  126 + #set ($dictMethod = "boolean")
  127 + #end
  128 + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  129 + <el-form-item label="${comment}" prop="${javaField}">
  130 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  131 + </el-form-item>
  132 + #elseif($column.htmlType == "imageUpload")## 图片上传
  133 + <el-form-item label="${comment}" prop="${javaField}">
  134 + <ImageUpload v-model="formData.${javaField}" />
  135 + </el-form-item>
  136 + #elseif($column.htmlType == "fileUpload")## 文件上传
  137 + <el-form-item label="${comment}" prop="${javaField}">
  138 + <FileUpload v-model="formData.${javaField}" />
  139 + </el-form-item>
  140 + #elseif($column.htmlType == "editor")## 文本编辑器
  141 + <el-form-item label="${comment}" prop="${javaField}">
  142 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  143 + </el-form-item>
  144 + #elseif($column.htmlType == "select")## 下拉框
  145 + <el-form-item label="${comment}" prop="${javaField}">
  146 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  147 + #if ("" != $dictType)## 有数据字典
  148 + <el-option
  149 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  150 + :key="dict.value"
  151 + :value="dict.value"
  152 + :label="dict.label"
  153 + />
  154 + #else##没数据字典
  155 + <el-option label="请选择字典生成" value="" />
  156 + #end
  157 + </el-select>
  158 + </el-form-item>
  159 + #elseif($column.htmlType == "checkbox")## 多选框
  160 + <el-form-item label="${comment}" prop="${javaField}">
  161 + <el-checkbox-group v-model="formData.${javaField}">
  162 + #if ("" != $dictType)## 有数据字典
  163 + <el-checkbox
  164 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  165 + :key="dict.value"
  166 + :label="dict.value"
  167 + >
  168 + {{ dict.label }}
  169 + </el-checkbox>
  170 + #else##没数据字典
  171 + <el-checkbox label="请选择字典生成" />
  172 + #end
  173 + </el-checkbox-group>
  174 + </el-form-item>
  175 + #elseif($column.htmlType == "radio")## 单选框
  176 + <el-form-item label="${comment}" prop="${javaField}">
  177 + <el-radio-group v-model="formData.${javaField}">
  178 + #if ("" != $dictType)## 有数据字典
  179 + <el-radio
  180 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  181 + :key="dict.value"
  182 + :label="dict.value"
  183 + >
  184 + {{ dict.label }}
  185 + </el-radio>
  186 + #else##没数据字典
  187 + <el-radio :label="1">请选择字典生成</el-radio>
  188 + #end
  189 + </el-radio-group>
  190 + </el-form-item>
  191 + #elseif($column.htmlType == "datetime")## 时间框
  192 + <el-form-item label="${comment}" prop="${javaField}">
  193 + <el-date-picker
  194 + v-model="formData.${javaField}"
  195 + value-format="x"
  196 + placeholder="选择${comment}"
  197 + />
  198 + </el-form-item>
  199 + #elseif($column.htmlType == "textarea")## 文本框
  200 + <el-form-item label="${comment}" prop="${javaField}">
  201 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  202 + </el-form-item>
  203 + #end
  204 + #end
  205 + #end
  206 + </el-form>
  207 + </Modal>
  208 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/form_sub_inner.vue.vm 0 → 100644
  1 +## 主表的 normal 和 inner 使用相同的 form 表单
  2 +#parse("codegen/vue3_vben5_ele/general/views/modules/form_sub_normal.vue.vm")
0 3 \ No newline at end of file
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/form_sub_normal.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
  6 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  7 +<script lang="ts" setup>
  8 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  9 +
  10 + import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElButton, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker } from 'element-plus';
  11 + import { computed, ref, reactive, h, onMounted,watch,nextTick } from 'vue';
  12 + import { $t } from '#/locales';
  13 + import { DICT_TYPE, getDictOptions } from '#/utils';
  14 +
  15 +#if ($subTable.subJoinMany) ## 一对多
  16 +import type { VxeTableInstance } from '#/adapter/vxe-table';
  17 +import { Plus } from "@vben/icons";
  18 +import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
  19 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  20 +#else
  21 +import type { FormRules } from 'element-plus';
  22 +import { Tinymce as RichTextarea } from '#/components/tinymce';
  23 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  24 +#end
  25 +
  26 +const props = defineProps<{
  27 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  28 +}>()
  29 +
  30 +#if ($subTable.subJoinMany) ## 一对多
  31 +const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
  32 +const tableRef = ref<VxeTableInstance>();
  33 +/** 添加${subTable.classComment} */
  34 +const onAdd = async () => {
  35 + await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
  36 +}
  37 +
  38 +/** 删除${subTable.classComment} */
  39 +const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
  40 + await tableRef.value?.remove(row);
  41 +}
  42 +
  43 +/** 提供获取表格数据的方法供父组件调用 */
  44 +defineExpose({
  45 + getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
  46 + const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[];
  47 + const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  48 + const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  49 + return data
  50 + .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
  51 + ?.concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
  52 + },
  53 +});
  54 +
  55 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  56 +watch(
  57 + () => props.${subJoinColumn.javaField},
  58 + async (val) => {
  59 + if (!val) {
  60 + return;
  61 + }
  62 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  63 + },
  64 + { immediate: true },
  65 +);
  66 +#else
  67 +const formRef = ref();
  68 +const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
  69 + #foreach ($column in $subColumns)
  70 + #if ($column.createOperation || $column.updateOperation)
  71 + #if ($column.htmlType == "checkbox")
  72 + $column.javaField: [],
  73 + #else
  74 + $column.javaField: undefined,
  75 + #end
  76 + #end
  77 + #end
  78 +});
  79 +const rules = reactive<FormRules>({
  80 + #foreach ($column in $subColumns)
  81 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  82 + #set($comment=$column.columnComment)
  83 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  84 + #end
  85 + #end
  86 +});
  87 +/** 暴露出表单校验方法和表单值获取方法 */
  88 +defineExpose({
  89 + validate: async () => await formRef.value?.validate(),
  90 + getValues: ()=> formData.value,
  91 +});
  92 +
  93 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  94 +watch(
  95 + () => props.${subJoinColumn.javaField},
  96 + async (val) => {
  97 + if (!val) {
  98 + return;
  99 + }
  100 + await nextTick();
  101 + formData.value = await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  102 + },
  103 + { immediate: true },
  104 +);
  105 +#end
  106 +</script>
  107 +
  108 +<template>
  109 +#if ($subTable.subJoinMany) ## 一对多
  110 + <vxe-table ref="tableRef" :data="list" show-overflow class="mx-4">
  111 + #foreach($column in $subColumns)
  112 + #if ($column.createOperation || $column.updateOperation)
  113 + #set ($comment = $column.columnComment)
  114 + #set ($javaField = $column.javaField)
  115 + #set ($javaType = $column.javaType)
  116 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  117 + #set ($dictMethod = "number")
  118 + #elseif ($javaType == "String")
  119 + #set ($dictMethod = "string")
  120 + #elseif ($javaType == "Boolean")
  121 + #set ($dictMethod = "boolean")
  122 + #end
  123 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  124 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  125 + <vxe-column field="${javaField}" title="${comment}" align="center">
  126 + <template #default="{row}">
  127 + <el-input v-model="row.${javaField}" />
  128 + </template>
  129 + </vxe-column>
  130 + #elseif($column.htmlType == "imageUpload")## 图片上传
  131 + <vxe-column field="${javaField}" title="${comment}" align="center">
  132 + <template #default="{row}">
  133 + <ImageUpload v-model="row.${javaField}" />
  134 + </template>
  135 + </vxe-column>
  136 + #elseif($column.htmlType == "fileUpload")## 文件上传
  137 + <vxe-column field="${javaField}" title="${comment}" align="center">
  138 + <template #default="{row}">
  139 + <FileUpload v-model="row.${javaField}" />
  140 + </template>
  141 + </vxe-column>
  142 + #elseif($column.htmlType == "select")## 下拉框
  143 + <vxe-column field="${javaField}" title="${comment}" align="center">
  144 + <template #default="{row}">
  145 + <el-select v-model="row.${javaField}" placeholder="请选择${comment}">
  146 + #if ("" != $dictType)## 有数据字典
  147 + <el-option
  148 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  149 + :key="dict.value"
  150 + :value="dict.value"
  151 + :label="dict.label"
  152 + />
  153 + #else##没数据字典
  154 + <el-option label="请选择字典生成" value="" />
  155 + #end
  156 + </el-select>
  157 + </template>
  158 + </vxe-column>
  159 + #elseif($column.htmlType == "checkbox")## 多选框
  160 + <vxe-column field="${javaField}" title="${comment}" align="center">
  161 + <template #default="{row}">
  162 + <el-checkbox-group v-model="row.${javaField}">
  163 + #if ("" != $dictType)## 有数据字典
  164 + <el-checkbox
  165 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  166 + :key="dict.value"
  167 + :label="dict.value"
  168 + >
  169 + {{ dict.label }}
  170 + </el-checkbox>
  171 + #else##没数据字典
  172 + <el-checkbox label="请选择字典生成" />
  173 + #end
  174 + </el-checkbox-group>
  175 + </template>
  176 + </vxe-column>
  177 + #elseif($column.htmlType == "radio")## 单选框
  178 + <vxe-column field="${javaField}" title="${comment}" align="center">
  179 + <template #default="{row}">
  180 + <el-radio-group v-model="row.${javaField}">
  181 + #if ("" != $dictType)## 有数据字典
  182 + <el-radio
  183 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  184 + :key="dict.value"
  185 + :label="dict.value"
  186 + >
  187 + {{ dict.label }}
  188 + </el-radio>
  189 + #else##没数据字典
  190 + <el-radio :label="1">请选择字典生成</el-radio>
  191 + #end
  192 + </el-radio-group>
  193 + </template>
  194 + </vxe-column>
  195 + #elseif($column.htmlType == "datetime")## 时间框
  196 + <vxe-column field="${javaField}" title="${comment}" align="center">
  197 + <template #default="{row}">
  198 + <el-date-picker
  199 + v-model="row.${javaField}"
  200 + type="datetime"
  201 + value-format="x"
  202 + format="YYYY-MM-DD HH:mm:ss"
  203 + />
  204 + </template>
  205 + </vxe-column>
  206 + #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
  207 + <vxe-column field="${javaField}" title="${comment}" align="center">
  208 + <template #default="{row}">
  209 + <el-input v-model="row.${javaField}" type="textarea" />
  210 + </template>
  211 + </vxe-column>
  212 + #end
  213 + #end
  214 + #end
  215 + <vxe-column field="operation" title="操作" align="center">
  216 + <template #default="{row}">
  217 + <el-button
  218 + size="small"
  219 + type="danger"
  220 + link
  221 + @click="onDelete(row as any)"
  222 + v-access:code="['${permissionPrefix}:delete']"
  223 + >
  224 + {{ $t('ui.actionTitle.delete') }}
  225 + </el-button>
  226 + </template>
  227 + </vxe-column>
  228 + </vxe-table>
  229 + <div class="flex justify-center mt-4">
  230 + <el-button :icon="h(Plus)" type="primary" plain @click="onAdd" v-access:code="['${permissionPrefix}:create']">
  231 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  232 + </el-button>
  233 + </div>
  234 +#else
  235 + <el-form
  236 + ref="formRef"
  237 + class="mx-4"
  238 + :model="formData"
  239 + :rules="rules"
  240 + label-width="120px"
  241 + label-position="right"
  242 + >
  243 + #foreach($column in $subColumns)
  244 + #if ($column.createOperation || $column.updateOperation)
  245 + #set ($dictType = $column.dictType)
  246 + #set ($javaField = $column.javaField)
  247 + #set ($javaType = $column.javaType)
  248 + #set ($comment = $column.columnComment)
  249 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  250 + #set ($dictMethod = "number")
  251 + #elseif ($javaType == "String")
  252 + #set ($dictMethod = "string")
  253 + #elseif ($javaType == "Boolean")
  254 + #set ($dictMethod = "boolean")
  255 + #end
  256 + #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  257 + <el-form-item label="${comment}" prop="${javaField}">
  258 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  259 + </el-form-item>
  260 + #elseif($column.htmlType == "imageUpload")## 图片上传
  261 + <el-form-item label="${comment}" prop="${javaField}">
  262 + <ImageUpload v-model="formData.${javaField}" />
  263 + </el-form-item>
  264 + #elseif($column.htmlType == "fileUpload")## 文件上传
  265 + <el-form-item label="${comment}" prop="${javaField}">
  266 + <FileUpload v-model="formData.${javaField}" />
  267 + </el-form-item>
  268 + #elseif($column.htmlType == "editor")## 文本编辑器
  269 + <el-form-item label="${comment}" prop="${javaField}">
  270 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  271 + </el-form-item>
  272 + #elseif($column.htmlType == "select")## 下拉框
  273 + <el-form-item label="${comment}" prop="${javaField}">
  274 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  275 + #if ("" != $dictType)## 有数据字典
  276 + <el-option
  277 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  278 + :key="dict.value"
  279 + :value="dict.value"
  280 + :label="dict.label"
  281 + />
  282 + #else##没数据字典
  283 + <el-option label="请选择字典生成" value="" />
  284 + #end
  285 + </el-select>
  286 + </el-form-item>
  287 + #elseif($column.htmlType == "checkbox")## 多选框
  288 + <el-form-item label="${comment}" prop="${javaField}">
  289 + <el-checkbox-group v-model="formData.${javaField}">
  290 + #if ("" != $dictType)## 有数据字典
  291 + <el-checkbox
  292 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  293 + :key="dict.value"
  294 + :label="dict.value"
  295 + >
  296 + {{ dict.label }}
  297 + </el-checkbox>
  298 + #else##没数据字典
  299 + <el-checkbox label="请选择字典生成" />
  300 + #end
  301 + </el-checkbox-group>
  302 + </el-form-item>
  303 + #elseif($column.htmlType == "radio")## 单选框
  304 + <el-form-item label="${comment}" prop="${javaField}">
  305 + <el-radio-group v-model="formData.${javaField}">
  306 + #if ("" != $dictType)## 有数据字典
  307 + <el-radio
  308 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  309 + :key="dict.value"
  310 + :label="dict.value"
  311 + >
  312 + {{ dict.label }}
  313 + </el-radio>
  314 + #else##没数据字典
  315 + <el-radio :label="1">请选择字典生成</el-radio>
  316 + #end
  317 + </el-radio-group>
  318 + </el-form-item>
  319 + #elseif($column.htmlType == "datetime")## 时间框
  320 + <el-form-item label="${comment}" prop="${javaField}">
  321 + <el-date-picker
  322 + v-model="formData.${javaField}"
  323 + value-format="x"
  324 + placeholder="选择${comment}"
  325 + />
  326 + </el-form-item>
  327 + #elseif($column.htmlType == "textarea")## 文本框
  328 + <el-form-item label="${comment}" prop="${javaField}">
  329 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  330 + </el-form-item>
  331 + #end
  332 + #end
  333 + #end
  334 + </el-form>
  335 +#end
  336 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/list_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
  7 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  8 +<script lang="ts" setup>
  9 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  10 + import type { VxeTableInstance } from '#/adapter/vxe-table';
  11 +
  12 + import { DictTag } from '#/components/dict-tag';
  13 + import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
  14 + import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
  15 + import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
  16 + import { cloneDeep, formatDateTime } from '@vben/utils';
  17 + import { ContentWrap } from '#/components/content-wrap';
  18 +
  19 +#if ($table.templateType == 11) ## erp
  20 + import { useVbenModal } from '@vben/common-ui';
  21 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  22 + import { Tinymce as RichTextarea } from '#/components/tinymce';
  23 + import { ImageUpload, FileUpload } from "#/components/upload";
  24 + import { ElMessage, ElLoading, ElButton, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus';
  25 + import { Plus, Trash2 } from '@vben/icons';
  26 + import { $t } from '#/locales';
  27 + import { TableToolbar } from '#/components/table-toolbar';
  28 + import { useTableToolbar } from '#/hooks';
  29 +#end
  30 +
  31 +#if ($table.templateType == 11) ## erp
  32 + import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  33 + import { isEmpty } from '@vben/utils';
  34 + #else
  35 + #if ($subTable.subJoinMany) ## 一对多
  36 + import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  37 + #else
  38 + import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  39 + #end
  40 +#end
  41 +
  42 +const props = defineProps<{
  43 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  44 +}>()
  45 +
  46 +#if ($table.templateType == 11) ## erp
  47 + const [FormModal, formModalApi] = useVbenModal({
  48 + connectedComponent: ${subSimpleClassName}Form,
  49 + destroyOnClose: true,
  50 + });
  51 +
  52 +/** 创建${subTable.classComment} */
  53 +function handleCreate() {
  54 + if (!props.${subJoinColumn.javaField}){
  55 + ElMessage.warning("请先选择一个${table.classComment}!")
  56 + return
  57 + }
  58 + formModalApi.setData({${subJoinColumn.javaField}: props.${subJoinColumn.javaField}}).open();
  59 +}
  60 +
  61 +/** 编辑${subTable.classComment} */
  62 +function handleEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
  63 + formModalApi.setData(row).open();
  64 +}
  65 +
  66 +/** 删除${subTable.classComment} */
  67 +async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
  68 + const loadingInstance = ElLoading.service({
  69 + text: $t('ui.actionMessage.deleting', [row.id]),
  70 + background: 'rgba(0, 0, 0, 0.7)',
  71 + });
  72 + try {
  73 + await delete${subSimpleClassName}(row.id as number);
  74 + ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  75 + await getList();
  76 + } finally {
  77 + loadingInstance.close();
  78 + }
  79 +}
  80 +
  81 +#if ($deleteBatchEnable)
  82 +/** 批量删除${subTable.classComment} */
  83 +async function handleDeleteBatch() {
  84 + const loadingInstance = ElLoading.service({
  85 + text: $t('ui.actionMessage.deleting'),
  86 + background: 'rgba(0, 0, 0, 0.7)',
  87 + });
  88 + try {
  89 + await delete${subSimpleClassName}List(checkedIds.value);
  90 + ElMessage.success($t('ui.actionMessage.deleteSuccess'));
  91 + await getList();
  92 + } finally {
  93 + loadingInstance.close();
  94 + }
  95 +}
  96 +
  97 +const checkedIds = ref<number[]>([])
  98 +function handleRowCheckboxChange({
  99 + records,
  100 +}: {
  101 + records: ${simpleClassName}Api.${subSimpleClassName}[];
  102 +}) {
  103 + checkedIds.value = records.map((item) => item.id);
  104 +}
  105 +#end
  106 +#end
  107 +
  108 + const loading = ref(true) // 列表的加载中
  109 + const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
  110 +#if ($table.templateType == 11) ## erp
  111 + const total = ref(0) // 列表的总页数
  112 +#end
  113 +#if ($table.templateType == 11) ## erp
  114 + const queryFormRef = ref() // 搜索的表单
  115 + const queryParams = reactive({
  116 + pageNo: 1,
  117 + pageSize: 10,
  118 + #foreach ($column in $subColumns)
  119 + #if ($column.listOperation)
  120 + #if ($column.listOperationCondition != 'BETWEEN')
  121 + $column.javaField: undefined,
  122 + #end
  123 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  124 + $column.javaField: undefined,
  125 + #end
  126 + #end
  127 + #end
  128 + })
  129 +
  130 +/** 搜索按钮操作 */
  131 +const handleQuery = () => {
  132 + queryParams.pageNo = 1
  133 + getList()
  134 +}
  135 +
  136 +/** 重置按钮操作 */
  137 +const resetQuery = () => {
  138 + queryFormRef.value.resetFields()
  139 + handleQuery()
  140 +}
  141 +#end
  142 + /** 查询列表 */
  143 + const getList = async () => {
  144 + loading.value = true
  145 + try {
  146 + if (!props.${subJoinColumn.javaField}){
  147 + return []
  148 + }
  149 + ## 特殊:树表专属逻辑(树不需要分页接口)
  150 + #if ($table.templateType == 11) ## erp
  151 + const params = cloneDeep(queryParams) as any;
  152 + #foreach ($column in $columns)
  153 + #if ($column.listOperation)
  154 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  155 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  156 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  157 + }
  158 + #end
  159 + #end
  160 + #end
  161 + params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};
  162 + const data = await get${subSimpleClassName}Page(params)
  163 + list.value = data.list
  164 + total.value = data.total
  165 + #else
  166 + #if ($subTable.subJoinMany) ## 一对多
  167 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  168 + #else
  169 + list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];
  170 + #end
  171 + #end
  172 + } finally {
  173 + loading.value = false
  174 + }
  175 + }
  176 +
  177 + /** 监听主表的关联字段的变化,加载对应的子表数据 */
  178 + watch(
  179 + () => props.${subJoinColumn.javaField},
  180 + async (val) => {
  181 + if (!val) {
  182 + return;
  183 + }
  184 + await nextTick();
  185 + await getList()
  186 + },
  187 + { immediate: true },
  188 + );
  189 +
  190 +#if ($table.templateType == 11) ## erp
  191 +/** 初始化 */
  192 +const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
  193 +onMounted(() => {
  194 + getList();
  195 +});
  196 +#end
  197 +</script>
  198 +
  199 +<template>
  200 + #if ($table.templateType == 11) ## erp
  201 + <FormModal @success="getList" />
  202 + <div class="h-[600px]">
  203 + <ContentWrap v-if="!hiddenSearchBar">
  204 + <!-- 搜索工作栏 -->
  205 + <el-form
  206 + :model="queryParams"
  207 + ref="queryFormRef"
  208 + inline
  209 + >
  210 + #foreach($column in $subColumns)
  211 + #if ($column.listOperation)
  212 + #set ($dictType = $column.dictType)
  213 + #set ($javaField = $column.javaField)
  214 + #set ($javaType = $column.javaType)
  215 + #set ($comment = $column.columnComment)
  216 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  217 + #set ($dictMethod = "number")
  218 + #elseif ($javaType == "String")
  219 + #set ($dictMethod = "string")
  220 + #elseif ($javaType == "Boolean")
  221 + #set ($dictMethod = "boolean")
  222 + #end
  223 + #if ($column.htmlType == "input")
  224 + <el-form-item label="${comment}">
  225 + <el-input
  226 + v-model="queryParams.${javaField}"
  227 + placeholder="请输入${comment}"
  228 + clearable
  229 + @keyup.enter="handleQuery"
  230 + class="!w-[240px]"
  231 + />
  232 + </el-form-item>
  233 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
  234 + <el-form-item label="${comment}">
  235 + <el-select
  236 + v-model="queryParams.${javaField}"
  237 + placeholder="请选择${comment}"
  238 + clearable
  239 + class="!w-[240px]"
  240 + >
  241 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  242 + <el-option
  243 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  244 + :key="dict.value"
  245 + :value="dict.value"
  246 + :label="dict.label"
  247 + />
  248 + #else## 未设置 dictType 数据字典的情况
  249 + <el-option label="请选择字典生成" value="" />
  250 + #end
  251 + </el-select>
  252 + </el-form-item>
  253 + #elseif($column.htmlType == "datetime")
  254 + #if ($column.listOperationCondition != "BETWEEN")## 非范围
  255 + <el-form-item label="${comment}">
  256 + <el-date-picker
  257 + v-model="queryParams.${javaField}"
  258 + value-format="YYYY-MM-DD"
  259 + placeholder="选择${comment}"
  260 + clearable
  261 + class="!w-[240px]"
  262 + />
  263 + </el-form-item>
  264 + #else## 范围
  265 + <el-form-item label="${comment}">
  266 + <el-date-picker
  267 + v-model="queryParams.${javaField}"
  268 + type="daterange"
  269 + value-format="YYYY-MM-DD"
  270 + range-separator="至"
  271 + start-placeholder="开始日期"
  272 + end-placeholder="结束日期"
  273 + class="!w-[240px]"
  274 + />
  275 + </el-form-item>
  276 + #end
  277 + #end
  278 + #end
  279 + #end
  280 + <el-form-item>
  281 + <el-button class="ml-2" @click="resetQuery"> 重置 </el-button>
  282 + <el-button class="ml-2" @click="handleQuery" type="primary">
  283 + 搜索
  284 + </el-button>
  285 + </el-form-item>
  286 + </el-form>
  287 + </ContentWrap>
  288 +
  289 + <!-- 列表 -->
  290 + <ContentWrap title="${table.classComment}">
  291 + <template #extra>
  292 + <TableToolbar
  293 + ref="tableToolbarRef"
  294 + v-model:hidden-search="hiddenSearchBar"
  295 + >
  296 + <el-button
  297 + class="ml-2"
  298 + :icon="h(Plus)"
  299 + type="primary"
  300 + @click="handleCreate"
  301 + v-access:code="['${permissionPrefix}:create']"
  302 + >
  303 + {{ $t('ui.actionTitle.create', ['${table.classComment}']) }}
  304 + </el-button>
  305 + #if ($deleteBatchEnable)
  306 + <el-button
  307 + :icon="h(Trash2)"
  308 + type="danger"
  309 + class="ml-2"
  310 + :disabled="isEmpty(checkedIds)"
  311 + @click="handleDeleteBatch"
  312 + v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:delete']"
  313 + >
  314 + 批量删除
  315 + </el-button>
  316 + #end
  317 + </TableToolbar>
  318 + </template>
  319 + <vxe-table
  320 + ref="tableRef"
  321 + :data="list"
  322 + show-overflow
  323 + :loading="loading"
  324 + #if ($deleteBatchEnable)
  325 + @checkboxAll="handleRowCheckboxChange"
  326 + @checkboxChange="handleRowCheckboxChange"
  327 + #end
  328 + >
  329 + #if ($deleteBatchEnable)
  330 + <vxe-column type="checkbox" width="40"></vxe-column>
  331 + #end
  332 + #foreach($column in $subColumns)
  333 + #if ($column.listOperationResult)
  334 + #set ($dictType=$column.dictType)
  335 + #set ($javaField = $column.javaField)
  336 + #set ($comment=$column.columnComment)
  337 + #if ($column.javaType == "LocalDateTime")## 时间类型
  338 + <vxe-column field="${javaField}" title="${comment}" align="center">
  339 + <template #default="{row}">
  340 + {{formatDateTime(row.${javaField})}}
  341 + </template>
  342 + </vxe-column>
  343 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  344 + <vxe-column field="${javaField}" title="${comment}" align="center">
  345 + <template #default="{row}">
  346 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  347 + </template>
  348 + </vxe-column>
  349 + #elseif ($table.templateType == 2 && $javaField == $treeNameColumn.javaField)
  350 + <vxe-column field="${javaField}" title="${comment}" align="center" tree-node/>
  351 + #else
  352 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  353 + #end
  354 + #end
  355 + #end
  356 + <vxe-column field="operation" title="操作" align="center">
  357 + <template #default="{row}">
  358 + <el-button
  359 + size="small"
  360 + type="primary"
  361 + link
  362 + @click="handleEdit(row as any)"
  363 + v-access:code="['${permissionPrefix}:update']"
  364 + >
  365 + {{ $t('ui.actionTitle.edit') }}
  366 + </el-button>
  367 + <el-button
  368 + size="small"
  369 + type="danger"
  370 + link
  371 + class="ml-2"
  372 + @click="handleDelete(row as any)"
  373 + v-access:code="['${permissionPrefix}:delete']"
  374 + >
  375 + {{ $t('ui.actionTitle.delete') }}
  376 + </el-button>
  377 + </template>
  378 + </vxe-column>
  379 + </vxe-table>
  380 + <!-- 分页 -->
  381 + <div class="mt-2 flex justify-end">
  382 + <el-pagination
  383 + :total="total"
  384 + v-model:current-page="queryParams.pageNo"
  385 + v-model:page-size="queryParams.pageSize"
  386 + :page-sizes="[10, 20, 50, 100]"
  387 + layout="total, sizes, prev, pager, next, jumper"
  388 + @size-change="getList"
  389 + @current-change="getList"
  390 + />
  391 + </div>
  392 + </ContentWrap>
  393 + </div>
  394 + #else
  395 + <ContentWrap title="${subTable.classComment}列表">
  396 + <vxe-table
  397 + :data="list"
  398 + show-overflow
  399 + :loading="loading"
  400 + >
  401 + #foreach($column in $subColumns)
  402 + #if ($column.listOperationResult)
  403 + #set ($dictType=$column.dictType)
  404 + #set ($javaField = $column.javaField)
  405 + #set ($comment=$column.columnComment)
  406 + #if ($column.javaType == "LocalDateTime")## 时间类型
  407 + <vxe-column field="${javaField}" title="${comment}" align="center">
  408 + <template #default="{row}">
  409 + {{formatDateTime(row.${javaField})}}
  410 + </template>
  411 + </vxe-column>
  412 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  413 + <vxe-column field="${javaField}" title="${comment}" align="center">
  414 + <template #default="{row}">
  415 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  416 + </template>
  417 + </vxe-column>
  418 + #else
  419 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  420 + #end
  421 + #end
  422 + #end
  423 + </vxe-table>
  424 + </ContentWrap>
  425 + #end
  426 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/list_sub_inner.vue.vm 0 → 100644
  1 +## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
  2 +## 1)inner 使用 list 不分页,erp 使用 page 分页
  3 +## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
  4 +#parse("codegen/vue3_vben5_ele/general/views/modules/list_sub_erp.vue.vm")
0 5 \ No newline at end of file
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/api/api.ts.vm 0 → 100644
  1 +import type { PageParam, PageResult } from '@vben/request';
  2 +import type { Dayjs } from 'dayjs';
  3 +
  4 +import { requestClient } from '#/api/request';
  5 +#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
  6 +
  7 +export namespace ${simpleClassName}Api {
  8 +## 特殊:主子表专属逻辑
  9 +#foreach ($subTable in $subTables)
  10 + #set ($index = $foreach.count - 1)
  11 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  12 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  13 + /** ${subTable.classComment}信息 */
  14 + export interface ${subSimpleClassName} {
  15 + #foreach ($column in $subColumns)
  16 + #if ($column.createOperation || $column.updateOperation)
  17 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  18 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  19 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  20 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  21 + #else
  22 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  23 + #end
  24 + #end
  25 + #end
  26 + }
  27 +
  28 +#end
  29 + /** ${table.classComment}信息 */
  30 + export interface ${simpleClassName} {
  31 +#foreach ($column in $columns)
  32 +#if ($column.createOperation || $column.updateOperation)
  33 +#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  34 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  35 +#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  36 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}
  37 +#else
  38 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  39 +#end
  40 +#end
  41 +#end
  42 +#if ( $table.templateType == 2 )
  43 + children?: ${simpleClassName}[];
  44 +#end
  45 +## 特殊:主子表专属逻辑
  46 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  47 + #foreach ($subTable in $subTables)
  48 + #set ($index = $foreach.count - 1)
  49 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  50 + #if ( $subTable.subJoinMany )
  51 + ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
  52 + #else
  53 + ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
  54 + #end
  55 + #end
  56 +#end
  57 + }
  58 +}
  59 +
  60 +#if ( $table.templateType != 2 )
  61 +/** 查询${table.classComment}分页 */
  62 +export function get${simpleClassName}Page(params: PageParam) {
  63 + return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params });
  64 +}
  65 +#else
  66 +/** 查询${table.classComment}列表 */
  67 +export function get${simpleClassName}List(params: any) {
  68 + return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params });
  69 +}
  70 +#end
  71 +
  72 +/** 查询${table.classComment}详情 */
  73 +export function get${simpleClassName}(id: number) {
  74 + return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`);
  75 +}
  76 +
  77 +/** 新增${table.classComment} */
  78 +export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  79 + return requestClient.post('${baseURL}/create', data);
  80 +}
  81 +
  82 +/** 修改${table.classComment} */
  83 +export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  84 + return requestClient.put('${baseURL}/update', data);
  85 +}
  86 +
  87 +/** 删除${table.classComment} */
  88 +export function delete${simpleClassName}(id: number) {
  89 + return requestClient.delete(`${baseURL}/delete?id=${id}`);
  90 +}
  91 +
  92 +#if ( $table.templateType != 2 && $deleteBatchEnable)
  93 +/** 批量删除${table.classComment} */
  94 +export function delete${simpleClassName}List(ids: number[]) {
  95 + return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`)
  96 +}
  97 +#end
  98 +
  99 +/** 导出${table.classComment} */
  100 +export function export${simpleClassName}(params: any) {
  101 + return requestClient.download('${baseURL}/export-excel', params);
  102 +}
  103 +
  104 +## 特殊:主子表专属逻辑
  105 +#foreach ($subTable in $subTables)
  106 +#set ($index = $foreach.count - 1)
  107 +#set ($subSimpleClassName = $subSimpleClassNames.get($index))
  108 +#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
  109 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  110 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  111 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  112 +#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  113 +#set ($subClassNameVar = $subClassNameVars.get($index))
  114 +
  115 +// ==================== 子表($subTable.classComment) ====================
  116 +
  117 +## 情况一:MASTER_ERP 时,需要分查询页子表
  118 +#if ( $table.templateType == 11 )
  119 +/** 获得${subTable.classComment}分页 */
  120 +export function get${subSimpleClassName}Page(params: PageParam) {
  121 + return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
  122 +}
  123 +## 情况二:非 MASTER_ERP 时,需要列表查询子表
  124 +#else
  125 + #if ( $subTable.subJoinMany )
  126 +/** 获得${subTable.classComment}列表 */
  127 +export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  128 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  129 +}
  130 + #else
  131 +/** 获得${subTable.classComment} */
  132 +export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  133 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  134 +}
  135 + #end
  136 +#end
  137 +## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
  138 +#if ( $table.templateType == 11 )
  139 +/** 新增${subTable.classComment} */
  140 +export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  141 + return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
  142 +}
  143 +
  144 +/** 修改${subTable.classComment} */
  145 +export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  146 + return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
  147 +}
  148 +
  149 +/** 删除${subTable.classComment} */
  150 +export function delete${subSimpleClassName}(id: number) {
  151 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
  152 +}
  153 +
  154 +#if ($deleteBatchEnable)
  155 +/** 批量删除${subTable.classComment} */
  156 +export function delete${subSimpleClassName}List(ids: number[]) {
  157 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)
  158 +}
  159 +#end
  160 +
  161 +/** 获得${subTable.classComment} */
  162 +export function get${subSimpleClassName}(id: number) {
  163 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
  164 +}
  165 +#end
  166 +#end
  167 +
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm 0 → 100644
  1 +import type { VbenFormSchema } from '#/adapter/form';
  2 +import type { VxeTableGridOptions } from '#/adapter/vxe-table';
  3 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  4 +
  5 +import { z } from '#/adapter/form';
  6 +import {
  7 + DICT_TYPE,
  8 + getDictOptions,
  9 + getRangePickerDefaultProps,
  10 +} from '#/utils';
  11 +#if(${table.templateType} == 2)## 树表需要导入这些
  12 +import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
  13 +import { handleTree } from '@vben/utils';
  14 +#end
  15 +
  16 +/** 新增/修改的表单 */
  17 +export function useFormSchema(): VbenFormSchema[] {
  18 + return [
  19 + {
  20 + fieldName: 'id',
  21 + component: 'Input',
  22 + dependencies: {
  23 + triggerFields: [''],
  24 + show: () => false,
  25 + },
  26 + },
  27 +#if(${table.templateType} == 2)## 树表特有字段:上级
  28 + {
  29 + fieldName: '${treeParentColumn.javaField}',
  30 + label: '上级${table.classComment}',
  31 + component: 'ApiTreeSelect',
  32 + componentProps: {
  33 + allowClear: true,
  34 + api: async () => {
  35 + const data = await get${simpleClassName}List({});
  36 + data.unshift({
  37 + id: 0,
  38 + ${treeNameColumn.javaField}: '顶级${table.classComment}',
  39 + });
  40 + return handleTree(data);
  41 + },
  42 + labelField: '${treeNameColumn.javaField}',
  43 + valueField: 'id',
  44 + childrenField: 'children',
  45 + placeholder: '请选择上级${table.classComment}',
  46 + treeDefaultExpandAll: true,
  47 + },
  48 + rules: 'selectRequired',
  49 + },
  50 +#end
  51 +#foreach($column in $columns)
  52 +#if ($column.createOperation || $column.updateOperation)
  53 +#if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
  54 + #set ($dictType = $column.dictType)
  55 + #set ($javaType = $column.javaType)
  56 + #set ($javaField = $column.javaField)
  57 + #set ($comment = $column.columnComment)
  58 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  59 + #set ($dictMethod = "number")
  60 + #elseif ($javaType == "String")
  61 + #set ($dictMethod = "string")
  62 + #elseif ($javaType == "Boolean")
  63 + #set ($dictMethod = "boolean")
  64 + #end
  65 + {
  66 + fieldName: '${javaField}',
  67 + label: '${comment}',
  68 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  69 + rules: 'required',
  70 + #end
  71 + #if ($column.htmlType == "input")
  72 + component: 'Input',
  73 + componentProps: {
  74 + placeholder: '请输入${comment}',
  75 + },
  76 + #elseif($column.htmlType == "imageUpload")## 图片上传
  77 + component: 'ImageUpload',
  78 + #elseif($column.htmlType == "fileUpload")## 文件上传
  79 + component: 'FileUpload',
  80 + #elseif($column.htmlType == "editor")## 文本编辑器
  81 + component: 'RichTextarea',
  82 + #elseif($column.htmlType == "select")## 下拉框
  83 + component: 'Select',
  84 + componentProps: {
  85 + #if ("" != $dictType)## 有数据字典
  86 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  87 + #else##没数据字典
  88 + options: [],
  89 + #end
  90 + placeholder: '请选择${comment}',
  91 + },
  92 + #elseif($column.htmlType == "checkbox")## 多选框
  93 + component: 'Checkbox',
  94 + componentProps: {
  95 + #if ("" != $dictType)## 有数据字典
  96 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  97 + #else##没数据字典
  98 + options: [],
  99 + #end
  100 + },
  101 + #elseif($column.htmlType == "radio")## 单选框
  102 + component: 'RadioGroup',
  103 + componentProps: {
  104 + #if ("" != $dictType)## 有数据字典
  105 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  106 + #else##没数据字典
  107 + options: [],
  108 + #end
  109 + buttonStyle: 'solid',
  110 + optionType: 'button',
  111 + },
  112 + #elseif($column.htmlType == "datetime")## 时间框
  113 + component: 'DatePicker',
  114 + componentProps: {
  115 + showTime: true,
  116 + format: 'YYYY-MM-DD HH:mm:ss',
  117 + valueFormat: 'x',
  118 + },
  119 + #elseif($column.htmlType == "textarea")## 文本域
  120 + component: 'Textarea',
  121 + componentProps: {
  122 + placeholder: '请输入${comment}',
  123 + },
  124 + #elseif($column.htmlType == "inputNumber")## 数字输入框
  125 + component: 'InputNumber',
  126 + componentProps: {
  127 + min: 0,
  128 + controlsPosition: 'right',
  129 + placeholder: '请输入${comment}',
  130 + },
  131 + #end
  132 + },
  133 +#end
  134 +#end
  135 +#end
  136 + ];
  137 +}
  138 +
  139 +/** 列表的搜索表单 */
  140 +export function useGridFormSchema(): VbenFormSchema[] {
  141 + return [
  142 +#foreach($column in $columns)
  143 +#if ($column.listOperation)
  144 + #set ($dictType = $column.dictType)
  145 + #set ($javaType = $column.javaType)
  146 + #set ($javaField = $column.javaField)
  147 + #set ($comment = $column.columnComment)
  148 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  149 + #set ($dictMethod = "number")
  150 + #elseif ($javaType == "String")
  151 + #set ($dictMethod = "string")
  152 + #elseif ($javaType == "Boolean")
  153 + #set ($dictMethod = "boolean")
  154 + #end
  155 + {
  156 + fieldName: '${javaField}',
  157 + label: '${comment}',
  158 + #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
  159 + component: 'Input',
  160 + componentProps: {
  161 + allowClear: true,
  162 + placeholder: '请输入${comment}',
  163 + },
  164 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  165 + component: 'Select',
  166 + componentProps: {
  167 + allowClear: true,
  168 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  169 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  170 + #else## 未设置 dictType 数据字典的情况
  171 + options: [],
  172 + #end
  173 + placeholder: '请选择${comment}',
  174 + },
  175 + #elseif($column.htmlType == "datetime")
  176 + component: 'RangePicker',
  177 + componentProps: {
  178 + ...getRangePickerDefaultProps(),
  179 + allowClear: true,
  180 + },
  181 + #end
  182 + },
  183 +#end
  184 +#end
  185 + ];
  186 +}
  187 +
  188 +/** 列表的字段 */
  189 +export function useGridColumns(): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] {
  190 + return [
  191 +#if ($table.templateType != 2 && $deleteBatchEnable)
  192 + { type: 'checkbox', width: 40 },
  193 +#end
  194 +#if ($table.templateType == 12) ## 内嵌情况
  195 + { type: 'expand', width: 80, slots: { content: 'expand_content' } },
  196 +#end
  197 +#foreach($column in $columns)
  198 +#if ($column.listOperationResult)
  199 + #set ($dictType = $column.dictType)
  200 + #set ($javaField = $column.javaField)
  201 + #set ($comment = $column.columnComment)
  202 + {
  203 + field: '${javaField}',
  204 + title: '${comment}',
  205 + minWidth: 120,
  206 + #if ($column.javaType == "LocalDateTime")## 时间类型
  207 + formatter: 'formatDateTime',
  208 + #elseif("" != $dictType)## 数据字典
  209 + cellRender: {
  210 + name: 'CellDict',
  211 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  212 + },
  213 + #end
  214 + #if (${table.templateType} == 2 && $column.id == $treeNameColumn.id)## 树表特有:标记树节点列
  215 + treeNode: true,
  216 + #end
  217 + },
  218 +#end
  219 +#end
  220 + {
  221 + title: '操作',
  222 + width: 200,
  223 + fixed: 'right',
  224 + slots: { default: 'actions' },
  225 + },
  226 + ];
  227 +}
  228 +
  229 +## 标准模式和内嵌模式时,主子关系一对一则生成表单schema,一对多则生成列表schema(内嵌模式时表单schema也要生成)。erp 模式时都生成
  230 +## 特殊:主子表专属逻辑
  231 +#foreach ($subTable in $subTables)
  232 + #set ($index = $foreach.count - 1)
  233 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  234 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  235 + #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  236 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  237 +// ==================== 子表($subTable.classComment) ====================
  238 +
  239 +#if ($table.templateType == 11) ## erp 情况
  240 +/** 新增/修改的表单 */
  241 +export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
  242 + return [
  243 + {
  244 + fieldName: 'id',
  245 + component: 'Input',
  246 + dependencies: {
  247 + triggerFields: [''],
  248 + show: () => false,
  249 + },
  250 + },
  251 + #foreach($column in $subColumns)
  252 + #if ($column.createOperation || $column.updateOperation)
  253 + #if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
  254 + #set ($dictType = $column.dictType)
  255 + #set ($javaType = $column.javaType)
  256 + #set ($javaField = $column.javaField)
  257 + #set ($comment = $column.columnComment)
  258 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  259 + #set ($dictMethod = "number")
  260 + #elseif ($javaType == "String")
  261 + #set ($dictMethod = "string")
  262 + #elseif ($javaType == "Boolean")
  263 + #set ($dictMethod = "boolean")
  264 + #end
  265 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  266 + #else
  267 + {
  268 + fieldName: '${javaField}',
  269 + label: '${comment}',
  270 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  271 + rules: 'required',
  272 + #end
  273 + #if ($column.htmlType == "input")
  274 + component: 'Input',
  275 + componentProps: {
  276 + placeholder: '请输入${comment}',
  277 + },
  278 + #elseif($column.htmlType == "imageUpload")## 图片上传
  279 + component: 'ImageUpload',
  280 + #elseif($column.htmlType == "fileUpload")## 文件上传
  281 + component: 'FileUpload',
  282 + #elseif($column.htmlType == "editor")## 文本编辑器
  283 + component: 'RichTextarea',
  284 + #elseif($column.htmlType == "select")## 下拉框
  285 + component: 'Select',
  286 + componentProps: {
  287 + #if ("" != $dictType)## 有数据字典
  288 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  289 + #else##没数据字典
  290 + options: [],
  291 + #end
  292 + placeholder: '请选择${comment}',
  293 + },
  294 + #elseif($column.htmlType == "checkbox")## 多选框
  295 + component: 'Checkbox',
  296 + componentProps: {
  297 + #if ("" != $dictType)## 有数据字典
  298 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  299 + #else##没数据字典
  300 + options: [],
  301 + #end
  302 + },
  303 + #elseif($column.htmlType == "radio")## 单选框
  304 + component: 'RadioGroup',
  305 + componentProps: {
  306 + #if ("" != $dictType)## 有数据字典
  307 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  308 + #else##没数据字典
  309 + options: [],
  310 + #end
  311 + buttonStyle: 'solid',
  312 + optionType: 'button',
  313 + },
  314 + #elseif($column.htmlType == "datetime")## 时间框
  315 + component: 'DatePicker',
  316 + componentProps: {
  317 + showTime: true,
  318 + format: 'YYYY-MM-DD HH:mm:ss',
  319 + valueFormat: 'x',
  320 + },
  321 + #elseif($column.htmlType == "textarea")## 文本域
  322 + component: 'Textarea',
  323 + componentProps: {
  324 + placeholder: '请输入${comment}',
  325 + },
  326 + #elseif($column.htmlType == "inputNumber")## 数字输入框
  327 + component: 'InputNumber',
  328 + componentProps: {
  329 + min: 0,
  330 + controlsPosition: 'right',
  331 + placeholder: '请输入${comment}',
  332 + },
  333 + #end
  334 + },
  335 + #end
  336 + #end
  337 + #end
  338 + #end
  339 + ];
  340 +}
  341 +
  342 +/** 列表的搜索表单 */
  343 +export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
  344 + return [
  345 + #foreach($column in $subColumns)
  346 + #if ($column.listOperation)
  347 + #set ($dictType = $column.dictType)
  348 + #set ($javaType = $column.javaType)
  349 + #set ($javaField = $column.javaField)
  350 + #set ($comment = $column.columnComment)
  351 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  352 + #set ($dictMethod = "number")
  353 + #elseif ($javaType == "String")
  354 + #set ($dictMethod = "string")
  355 + #elseif ($javaType == "Boolean")
  356 + #set ($dictMethod = "boolean")
  357 + #end
  358 + {
  359 + fieldName: '${javaField}',
  360 + label: '${comment}',
  361 + #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
  362 + component: 'Input',
  363 + componentProps: {
  364 + allowClear: true,
  365 + placeholder: '请输入${comment}',
  366 + },
  367 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  368 + component: 'Select',
  369 + componentProps: {
  370 + allowClear: true,
  371 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  372 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  373 + #else## 未设置 dictType 数据字典的情况
  374 + options: [],
  375 + #end
  376 + placeholder: '请选择${comment}',
  377 + },
  378 + #elseif($column.htmlType == "datetime")
  379 + component: 'RangePicker',
  380 + componentProps: {
  381 + ...getRangePickerDefaultProps(),
  382 + allowClear: true,
  383 + },
  384 + #end
  385 + },
  386 + #end
  387 + #end
  388 + ];
  389 +}
  390 +
  391 +/** 列表的字段 */
  392 +export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  393 + return [
  394 + #if ($table.templateType != 2 && $deleteBatchEnable)
  395 + { type: 'checkbox', width: 40 },
  396 + #end
  397 + #foreach($column in $subColumns)
  398 + #if ($column.listOperationResult)
  399 + #set ($dictType = $column.dictType)
  400 + #set ($javaField = $column.javaField)
  401 + #set ($comment = $column.columnComment)
  402 + {
  403 + field: '${javaField}',
  404 + title: '${comment}',
  405 + minWidth: 120,
  406 + #if ($column.javaType == "LocalDateTime")## 时间类型
  407 + formatter: 'formatDateTime',
  408 + #elseif("" != $dictType)## 数据字典
  409 + cellRender: {
  410 + name: 'CellDict',
  411 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  412 + },
  413 + #end
  414 + },
  415 + #end
  416 + #end
  417 + {
  418 + title: '操作',
  419 + width: 200,
  420 + fixed: 'right',
  421 + slots: { default: 'actions' },
  422 + },
  423 + ];
  424 +}
  425 +
  426 +#else
  427 + #if ($subTable.subJoinMany) ## 一对多
  428 + /** 新增/修改列表的字段 */
  429 + export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  430 + return [
  431 + #foreach($column in $subColumns)
  432 + #if ($column.createOperation || $column.updateOperation)
  433 + #if (!$column.primaryKey && $column.listOperationResult && $column.id != $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  434 + #set ($dictType = $column.dictType)
  435 + #set ($javaField = $column.javaField)
  436 + #set ($comment = $column.columnComment)
  437 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  438 + #set ($dictMethod = "number")
  439 + #elseif ($javaType == "String")
  440 + #set ($dictMethod = "string")
  441 + #elseif ($javaType == "Boolean")
  442 + #set ($dictMethod = "boolean")
  443 + #end
  444 + {
  445 + field: '${javaField}',
  446 + title: '${comment}',
  447 + minWidth: 120,
  448 + slots: { default: '${javaField}' },
  449 + #if ($column.htmlType == "select" || $column.htmlType == "checkbox" || $column.htmlType == "radio")
  450 + #if ("" != $dictType)## 有数据字典
  451 + params: {
  452 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  453 + },
  454 + #else
  455 + params: {
  456 + options: [],
  457 + },
  458 + #end
  459 + #end
  460 + },
  461 + #end
  462 + #end
  463 + #end
  464 + {
  465 + title: '操作',
  466 + width: 200,
  467 + fixed: 'right',
  468 + slots: { default: 'actions' },
  469 + },
  470 + ];
  471 + }
  472 +
  473 + #else
  474 + /** 新增/修改的表单 */
  475 + export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
  476 + return [
  477 + {
  478 + fieldName: 'id',
  479 + component: 'Input',
  480 + dependencies: {
  481 + triggerFields: [''],
  482 + show: () => false,
  483 + },
  484 + },
  485 + #foreach($column in $subColumns)
  486 + #if ($column.createOperation || $column.updateOperation)
  487 + #if (!$column.primaryKey && ($table.templateType != 2 || ($table.templateType == 2 && $column.id != $treeParentColumn.id)))## 树表中已经添加了父ID字段,这里排除
  488 + #set ($dictType = $column.dictType)
  489 + #set ($javaType = $column.javaType)
  490 + #set ($javaField = $column.javaField)
  491 + #set ($comment = $column.columnComment)
  492 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  493 + #set ($dictMethod = "number")
  494 + #elseif ($javaType == "String")
  495 + #set ($dictMethod = "string")
  496 + #elseif ($javaType == "Boolean")
  497 + #set ($dictMethod = "boolean")
  498 + #end
  499 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  500 + #else
  501 + {
  502 + fieldName: '${javaField}',
  503 + label: '${comment}',
  504 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  505 + rules: 'required',
  506 + #end
  507 + #if ($column.htmlType == "input")
  508 + component: 'Input',
  509 + componentProps: {
  510 + placeholder: '请输入${comment}',
  511 + },
  512 + #elseif($column.htmlType == "imageUpload")## 图片上传
  513 + component: 'ImageUpload',
  514 + #elseif($column.htmlType == "fileUpload")## 文件上传
  515 + component: 'FileUpload',
  516 + #elseif($column.htmlType == "editor")## 文本编辑器
  517 + component: 'RichTextarea',
  518 + #elseif($column.htmlType == "select")## 下拉框
  519 + component: 'Select',
  520 + componentProps: {
  521 + #if ("" != $dictType)## 有数据字典
  522 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  523 + #else##没数据字典
  524 + options: [],
  525 + #end
  526 + placeholder: '请选择${comment}',
  527 + },
  528 + #elseif($column.htmlType == "checkbox")## 多选框
  529 + component: 'Checkbox',
  530 + componentProps: {
  531 + #if ("" != $dictType)## 有数据字典
  532 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  533 + #else##没数据字典
  534 + options: [],
  535 + #end
  536 + },
  537 + #elseif($column.htmlType == "radio")## 单选框
  538 + component: 'RadioGroup',
  539 + componentProps: {
  540 + #if ("" != $dictType)## 有数据字典
  541 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  542 + #else##没数据字典
  543 + options: [],
  544 + #end
  545 + buttonStyle: 'solid',
  546 + optionType: 'button',
  547 + },
  548 + #elseif($column.htmlType == "datetime")## 时间框
  549 + component: 'DatePicker',
  550 + componentProps: {
  551 + showTime: true,
  552 + format: 'YYYY-MM-DD HH:mm:ss',
  553 + valueFormat: 'x',
  554 + },
  555 + #elseif($column.htmlType == "textarea")## 文本域
  556 + component: 'Textarea',
  557 + componentProps: {
  558 + placeholder: '请输入${comment}',
  559 + },
  560 + #elseif($column.htmlType == "inputNumber")## 数字输入框
  561 + component: 'InputNumber',
  562 + componentProps: {
  563 + min: 0,
  564 + controlsPosition: 'right',
  565 + placeholder: '请输入${comment}',
  566 + },
  567 + #end
  568 + },
  569 + #end
  570 + #end
  571 + #end
  572 + #end
  573 + ];
  574 + }
  575 +
  576 + #end
  577 + #if ($table.templateType == 12) ## 内嵌情况
  578 + /** 列表的字段 */
  579 + export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  580 + return [
  581 + #foreach($column in $subColumns)
  582 + #if ($column.listOperationResult)
  583 + #set ($dictType = $column.dictType)
  584 + #set ($javaField = $column.javaField)
  585 + #set ($comment = $column.columnComment)
  586 + {
  587 + field: '${javaField}',
  588 + title: '${comment}',
  589 + minWidth: 120,
  590 + #if ($column.javaType == "LocalDateTime")## 时间类型
  591 + formatter: 'formatDateTime',
  592 + #elseif("" != $dictType)## 数据字典
  593 + cellRender: {
  594 + name: 'CellDict',
  595 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  596 + },
  597 + #end
  598 + },
  599 + #end
  600 + #end
  601 + ];
  602 + }
  603 + #end
  604 +#end
  605 +#end
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  3 +
  4 +import { useVbenModal } from '@vben/common-ui';
  5 +import { ElMessage, ElTabs, ElTabPane, ElCheckbox, ElInput, ElSelect, ElRadioGroup, ElCheckboxGroup, ElDatePicker } from 'element-plus';
  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}/${table.businessName}';
  19 +
  20 +import { useFormSchema } from '../data';
  21 +
  22 +const emit = defineEmits(['success']);
  23 +const formData = ref<${simpleClassName}Api.${simpleClassName}>();
  24 +const getTitle = computed(() => {
  25 + return formData.value?.id
  26 + ? $t('ui.actionTitle.edit', ['${table.classComment}'])
  27 + : $t('ui.actionTitle.create', ['${table.classComment}']);
  28 +});
  29 +
  30 +## 特殊:主子表专属逻辑
  31 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  32 + #if ( $subTables && $subTables.size() > 0 )
  33 +
  34 + /** 子表的表单 */
  35 + const subTabsName = ref('$subClassNameVars.get(0)')
  36 + #foreach ($subClassNameVar in $subClassNameVars)
  37 + #set ($index = $foreach.count - 1)
  38 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  39 + const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
  40 + #end
  41 + #end
  42 +#end
  43 +
  44 +const [Form, formApi] = useVbenForm({
  45 + commonConfig: {
  46 + componentProps: {
  47 + class: 'w-full',
  48 + },
  49 + formItemClass: 'col-span-2',
  50 + labelWidth: 80,
  51 + },
  52 + layout: 'horizontal',
  53 + schema: useFormSchema(),
  54 + showDefaultActions: false
  55 +});
  56 +
  57 +const [Modal, modalApi] = useVbenModal({
  58 + async onConfirm() {
  59 + const { valid } = await formApi.validate();
  60 + if (!valid) {
  61 + return;
  62 + }
  63 + ## 特殊:主子表专属逻辑
  64 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  65 + #if ( $subTables && $subTables.size() > 0 )
  66 + // 校验子表单
  67 + #foreach ($subTable in $subTables)
  68 + #set ($index = $foreach.count - 1)
  69 + #set ($subClassNameVar = $subClassNameVars.get($index))
  70 + #if ($subTable.subJoinMany) ## 一对多
  71 + ## TODO 列表值校验?
  72 + #else
  73 + const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();
  74 + if (!${subClassNameVar}Valid) {
  75 + subTabsName.value = '${subClassNameVar}';
  76 + return;
  77 + }
  78 + #end
  79 + #end
  80 + #end
  81 + #end
  82 + modalApi.lock();
  83 + // 提交表单
  84 + const data = (await formApi.getValues()) as ${simpleClassName}Api.${simpleClassName};
  85 + ## 特殊:主子表专属逻辑
  86 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  87 + #if ( $subTables && $subTables.size() > 0 )
  88 + // 拼接子表的数据
  89 + #foreach ($subTable in $subTables)
  90 + #set ($index = $foreach.count - 1)
  91 + #set ($subClassNameVar = $subClassNameVars.get($index))
  92 + #if ($subTable.subJoinMany)
  93 + data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
  94 + #else
  95 + data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues();
  96 + #end
  97 + #end
  98 + #end
  99 + #end
  100 + try {
  101 + await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
  102 + // 关闭并提示
  103 + await modalApi.close();
  104 + emit('success');
  105 + ElMessage.success($t('ui.actionMessage.operationSuccess'));
  106 + } finally {
  107 + modalApi.unlock();
  108 + }
  109 + },
  110 + async onOpenChange(isOpen: boolean) {
  111 + if (!isOpen) {
  112 + formData.value = undefined;
  113 + return;
  114 + }
  115 + // 加载数据
  116 + let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
  117 + if (!data) {
  118 + return;
  119 + }
  120 + if (data.id) {
  121 + modalApi.lock();
  122 + try {
  123 + data = await get${simpleClassName}(data.id);
  124 + } finally {
  125 + modalApi.unlock();
  126 + }
  127 + }
  128 + // 设置到 values
  129 + formData.value = data;
  130 + await formApi.setValues(formData.value);
  131 + },
  132 +});
  133 +</script>
  134 +
  135 +<template>
  136 + <Modal :title="getTitle">
  137 + <Form class="mx-4" />
  138 + ## 特殊:主子表专属逻辑
  139 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  140 + <!-- 子表的表单 -->
  141 + <el-tabs v-model="subTabsName">
  142 + #foreach ($subTable in $subTables)
  143 + #set ($index = $foreach.count - 1)
  144 + #set ($subClassNameVar = $subClassNameVars.get($index))
  145 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  146 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  147 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  148 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
  149 + </el-tab-pane>
  150 + #end
  151 + </el-tabs>
  152 + #end
  153 + </Modal>
  154 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/index.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { VxeTableGridOptions } from '#/adapter/vxe-table';
  3 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  4 +
  5 +import { Page, useVbenModal } from '@vben/common-ui';
  6 +import { ElMessage, ElTabs, ElTabPane, ElLoading } from 'element-plus';
  7 +import Form from './modules/form.vue';
  8 +
  9 +## 特殊:主子表专属逻辑
  10 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  11 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  12 + #set ($index = $foreach.count - 1)
  13 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  14 +import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
  15 + #end
  16 +#end
  17 +
  18 +import { ref, computed } from 'vue';
  19 +import { $t } from '#/locales';
  20 +import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
  21 +#if (${table.templateType} == 2)## 树表接口
  22 +import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  23 +#else## 标准表接口
  24 +import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  25 +#end
  26 +import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
  27 +
  28 +import { useGridColumns, useGridFormSchema } from './data';
  29 +
  30 +#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
  31 +/** 子表的列表 */
  32 +const subTabsName = ref('$subClassNameVars.get(0)')
  33 +#if ($table.templateType == 11)
  34 +const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
  35 +#end
  36 +#end
  37 +
  38 +const [FormModal, formModalApi] = useVbenModal({
  39 + connectedComponent: Form,
  40 + destroyOnClose: true,
  41 +});
  42 +
  43 +#if (${table.templateType} == 2)## 树表特有:控制表格展开收缩
  44 +/** 切换树形展开/收缩状态 */
  45 +const isExpanded = ref(true);
  46 +function toggleExpand() {
  47 + isExpanded.value = !isExpanded.value;
  48 + gridApi.grid.setAllTreeExpand(isExpanded.value);
  49 +}
  50 +#end
  51 +
  52 +/** 刷新表格 */
  53 +function onRefresh() {
  54 +#if ($table.templateType == 12) ## 内嵌情况
  55 + gridApi.reload();
  56 +#else
  57 + gridApi.query();
  58 +#end
  59 +}
  60 +
  61 +/** 创建${table.classComment} */
  62 +function handleCreate() {
  63 + formModalApi.setData({}).open();
  64 +}
  65 +
  66 +/** 编辑${table.classComment} */
  67 +function handleEdit(row: ${simpleClassName}Api.${simpleClassName}) {
  68 + formModalApi.setData(row).open();
  69 +}
  70 +
  71 +#if (${table.templateType} == 2)## 树表特有:新增下级
  72 +/** 新增下级${table.classComment} */
  73 +function handleAppend(row: ${simpleClassName}Api.${simpleClassName}) {
  74 + formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
  75 +}
  76 +#end
  77 +
  78 +/** 删除${table.classComment} */
  79 +async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
  80 + const loadingInstance = ElLoading.service({
  81 + text: $t('ui.actionMessage.deleting', [row.id]),
  82 + background: 'rgba(0, 0, 0, 0.7)',
  83 + });
  84 + try {
  85 + await delete${simpleClassName}(row.id as number);
  86 + ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  87 + onRefresh();
  88 + } finally {
  89 + loadingInstance.close();
  90 + }
  91 +}
  92 +
  93 +#if ($table.templateType != 2 && $deleteBatchEnable)
  94 +/** 批量删除${table.classComment} */
  95 +async function handleDeleteBatch() {
  96 + const loadingInstance = ElLoading.service({
  97 + text: $t('ui.actionMessage.deleting'),
  98 + background: 'rgba(0, 0, 0, 0.7)',
  99 + });
  100 + try {
  101 + await delete${simpleClassName}List(checkedIds.value);
  102 + ElMessage.success($t('ui.actionMessage.deleteSuccess'));
  103 + onRefresh();
  104 + } finally {
  105 + loadingInstance.close();
  106 + }
  107 +}
  108 +
  109 +const checkedIds = ref<number[]>([])
  110 +function handleRowCheckboxChange({
  111 + records,
  112 +}: {
  113 + records: ${simpleClassName}Api.${simpleClassName}[];
  114 +}) {
  115 + checkedIds.value = records.map((item) => item.id);
  116 +}
  117 +#end
  118 +
  119 +/** 导出表格 */
  120 +async function handleExport() {
  121 + const data = await export${simpleClassName}(await gridApi.formApi.getValues());
  122 + downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data });
  123 +}
  124 +
  125 +const [Grid, gridApi] = useVbenVxeGrid({
  126 + formOptions: {
  127 + schema: useGridFormSchema(),
  128 + },
  129 + gridOptions: {
  130 + columns: useGridColumns(),
  131 +#if (${table.templateType} == 11)
  132 + height: '600px',
  133 +#else
  134 + height: 'auto',
  135 +#end
  136 +#if (${table.templateType} == 2)## 树表设置
  137 + treeConfig: {
  138 + parentField: '${treeParentColumn.javaField}',
  139 + rowField: 'id',
  140 + transform: true,
  141 + expandAll: true,
  142 + reserve: true,
  143 + },
  144 + pagerConfig: {
  145 + enabled: false,
  146 + },
  147 +#else## 标准表设置
  148 + pagerConfig: {
  149 + enabled: true,
  150 + },
  151 +#end
  152 + proxyConfig: {
  153 + ajax: {
  154 +#if (${table.templateType} == 2)## 树表数据加载
  155 + query: async (_, formValues) => {
  156 + return await get${simpleClassName}List(formValues);
  157 + },
  158 +#else## 标准表数据加载
  159 + query: async ({ page }, formValues) => {
  160 + return await get${simpleClassName}Page({
  161 + pageNo: page.currentPage,
  162 + pageSize: page.pageSize,
  163 + ...formValues,
  164 + });
  165 + },
  166 +#end
  167 + },
  168 + },
  169 + rowConfig: {
  170 + keyField: 'id',
  171 + isHover: true,
  172 +#if (${table.templateType} == 11)
  173 + isCurrent: true,
  174 +#end
  175 + },
  176 + toolbarConfig: {
  177 + refresh: { code: 'query' },
  178 + search: true,
  179 + },
  180 + } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,
  181 +#if (${table.templateType} == 11 || $deleteBatchEnable)
  182 + gridEvents:{
  183 + #if(${table.templateType} == 11)
  184 + cellClick: ({ row }: { row: ${simpleClassName}Api.${simpleClassName}}) => {
  185 + select${simpleClassName}.value = row;
  186 + },
  187 + #end
  188 + #if(${table.templateType} != 2 && $deleteBatchEnable)
  189 + checkboxAll: handleRowCheckboxChange,
  190 + checkboxChange: handleRowCheckboxChange,
  191 + #end
  192 + }
  193 +#end
  194 +});
  195 +</script>
  196 +
  197 +<template>
  198 + <Page auto-content-height>
  199 + <FormModal @success="onRefresh" />
  200 +
  201 +#if ($table.templateType == 11) ## erp情况
  202 + <div>
  203 +#end
  204 + <Grid table-title="${table.classComment}列表">
  205 + #if ($table.templateType == 12) ## 内嵌情况
  206 + <template #expand_content="{ row }">
  207 + <!-- 子表的表单 -->
  208 + <el-tabs v-model="subTabsName" class="mx-8">
  209 + #foreach ($subTable in $subTables)
  210 + #set ($index = $foreach.count - 1)
  211 + #set ($subClassNameVar = $subClassNameVars.get($index))
  212 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  213 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  214 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  215 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
  216 + </el-tab-pane>
  217 + #end
  218 + </el-tabs>
  219 + </template>
  220 + #end
  221 + <template #toolbar-tools>
  222 + <TableAction
  223 + :actions="[
  224 + #if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
  225 + {
  226 + label: isExpanded ? '收缩' : '展开',
  227 + type: 'primary',
  228 + onClick: toggleExpand,
  229 + },
  230 + #end
  231 + {
  232 + label: $t('ui.actionTitle.create', ['${table.classComment}']),
  233 + type: 'primary',
  234 + icon: ACTION_ICON.ADD,
  235 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
  236 + onClick: handleCreate,
  237 + },
  238 + {
  239 + label: $t('ui.actionTitle.export'),
  240 + type: 'primary',
  241 + icon: ACTION_ICON.DOWNLOAD,
  242 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:export'],
  243 + onClick: handleExport,
  244 + },
  245 + #if ($table.templateType != 2 && $deleteBatchEnable)
  246 + {
  247 + label: $t('ui.actionTitle.deleteBatch'),
  248 + type: 'danger',
  249 + icon: ACTION_ICON.DELETE,
  250 + disabled: isEmpty(checkedIds),
  251 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  252 + onClick: handleDeleteBatch,
  253 + },
  254 + #end
  255 + ]"
  256 + />
  257 + </template>
  258 + <template #actions="{ row }">
  259 + <TableAction
  260 + :actions="[
  261 + #if (${table.templateType} == 2)## 树表特有:新增下级
  262 + {
  263 + label: '新增下级',
  264 + type: 'text',
  265 + icon: ACTION_ICON.ADD,
  266 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
  267 + onClick: handleAppend.bind(null, row),
  268 + },
  269 + #end
  270 + {
  271 + label: $t('common.edit'),
  272 + type: 'text',
  273 + icon: ACTION_ICON.EDIT,
  274 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'],
  275 + onClick: handleEdit.bind(null, row),
  276 + },
  277 + {
  278 + label: $t('common.delete'),
  279 + type: 'danger',
  280 + text: true,
  281 + icon: ACTION_ICON.DELETE,
  282 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  283 + popConfirm: {
  284 + title: $t('ui.actionMessage.deleteConfirm', [row.id]),
  285 + confirm: handleDelete.bind(null, row),
  286 + },
  287 + },
  288 + ]"
  289 + />
  290 + </template>
  291 + </Grid>
  292 +
  293 +#if ($table.templateType == 11) ## erp情况
  294 + <!-- 子表的表单 -->
  295 + <el-tabs v-model="subTabsName" class="mt-2">
  296 + #foreach ($subTable in $subTables)
  297 + #set ($index = $foreach.count - 1)
  298 + #set ($subClassNameVar = $subClassNameVars.get($index))
  299 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  300 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  301 + <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}">
  302 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
  303 + </el-tab-pane>
  304 + #end
  305 + </el-tabs>
  306 + </div>
  307 +#end
  308 + </Page>
  309 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/form_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +<script lang="ts" setup>
  6 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  7 +
  8 + import { useVbenModal } from '@vben/common-ui';
  9 + import { ElMessage } from 'element-plus';
  10 +
  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}/${table.businessName}';
  15 +
  16 + import { use${subSimpleClassName}FormSchema } from '../data';
  17 +
  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 + });
  25 +
  26 + const [Form, formApi] = useVbenForm({
  27 + commonConfig: {
  28 + componentProps: {
  29 + class: 'w-full',
  30 + },
  31 + formItemClass: 'col-span-2',
  32 + labelWidth: 80,
  33 + },
  34 + layout: 'horizontal',
  35 + schema: use${subSimpleClassName}FormSchema(),
  36 + showDefaultActions: false
  37 + });
  38 +
  39 + const [Modal, modalApi] = useVbenModal({
  40 + async onConfirm() {
  41 + const { valid } = await formApi.validate();
  42 + if (!valid) {
  43 + return;
  44 + }
  45 +
  46 + modalApi.lock();
  47 + // 提交表单
  48 + const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName};
  49 + data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
  50 + try {
  51 + await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
  52 + // 关闭并提示
  53 + await modalApi.close();
  54 + emit('success');
  55 + ElMessage.success($t('ui.actionMessage.operationSuccess'));
  56 + } finally {
  57 + modalApi.unlock();
  58 + }
  59 + },
  60 + async onOpenChange(isOpen: boolean) {
  61 + if (!isOpen) {
  62 + formData.value = undefined;
  63 + return;
  64 + }
  65 +
  66 + // 加载数据
  67 + let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
  68 + if (!data) {
  69 + return;
  70 + }
  71 + if (data.id) {
  72 + modalApi.lock();
  73 + try {
  74 + data = await get${subSimpleClassName}(data.id);
  75 + } finally {
  76 + modalApi.unlock();
  77 + }
  78 + }
  79 + // 设置到 values
  80 + formData.value = data;
  81 + await formApi.setValues(formData.value);
  82 + },
  83 + });
  84 +</script>
  85 +
  86 +<template>
  87 + <Modal :title="getTitle">
  88 + <Form class="mx-4" />
  89 + </Modal>
  90 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/form_sub_inner.vue.vm 0 → 100644
  1 +## 主表的 normal 和 inner 使用相同的 form 表单
  2 +#parse("codegen/vue3_vben5_ele/schema/views/modules/form_sub_normal.vue.vm")
0 3 \ No newline at end of file
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/form_sub_normal.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
  6 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  7 +<script lang="ts" setup>
  8 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  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 { ElButton, ElTabs, ElTabPane, ElCheckbox, ElInput, ElSelect, ElOption, ElRadioGroup, ElCheckboxGroup, ElDatePicker } from 'element-plus';
  16 +import { ImageUpload, FileUpload } from "#/components/upload";
  17 +import type { OnActionClickParams } from '#/adapter/vxe-table';
  18 +import { useVbenVxeGrid } from '#/adapter/vxe-table';
  19 +import { use${subSimpleClassName}GridEditColumns } from '../data';
  20 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
  21 +#else
  22 +import { useVbenForm } from '#/adapter/form';
  23 +import { use${subSimpleClassName}FormSchema } from '../data';
  24 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
  25 +#end
  26 +
  27 +const props = defineProps<{
  28 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  29 +}>()
  30 +
  31 +#if ($subTable.subJoinMany) ## 一对多
  32 +/** 表格操作按钮的回调函数 */
  33 +function onActionClick({
  34 + code,
  35 + row,
  36 +}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) {
  37 + switch (code) {
  38 + case 'delete': {
  39 + onDelete(row);
  40 + break;
  41 + }
  42 + }
  43 +}
  44 +
  45 +const [Grid, gridApi] = useVbenVxeGrid({
  46 +gridOptions: {
  47 + columns: use${subSimpleClassName}GridEditColumns(onActionClick),
  48 + border: true,
  49 + showOverflow: true,
  50 + autoResize: true,
  51 + keepSource: true,
  52 + rowConfig: {
  53 + keyField: 'id',
  54 + },
  55 + pagerConfig: {
  56 + enabled: false,
  57 + },
  58 + toolbarConfig: {
  59 + enabled: false,
  60 + },
  61 +},
  62 +});
  63 +
  64 +/** 添加${subTable.classComment} */
  65 +const onAdd = async () => {
  66 + await gridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
  67 +}
  68 +
  69 +/** 删除${subTable.classComment} */
  70 +const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
  71 + await gridApi.grid.remove(row);
  72 +}
  73 +
  74 +/** 提供获取表格数据的方法供父组件调用 */
  75 +defineExpose({
  76 + getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
  77 + const data = gridApi.grid.getData() as ${simpleClassName}Api.${subSimpleClassName}[];
  78 + const removeRecords = gridApi.grid.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  79 + const insertRecords = gridApi.grid.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  80 + return data
  81 + .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
  82 + .concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
  83 + },
  84 +});
  85 +
  86 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  87 +watch(
  88 + () => props.${subJoinColumn.javaField},
  89 + async (val) => {
  90 + if (!val) {
  91 + return;
  92 + }
  93 + await nextTick();
  94 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  95 + },
  96 + { immediate: true },
  97 +);
  98 +#else
  99 +const [Form, formApi] = useVbenForm({
  100 + commonConfig: {
  101 + componentProps: {
  102 + class: 'w-full',
  103 + },
  104 + formItemClass: 'col-span-2',
  105 + labelWidth: 80,
  106 + },
  107 + layout: 'horizontal',
  108 + schema: use${subSimpleClassName}FormSchema(),
  109 + showDefaultActions: false
  110 +});
  111 +
  112 +/** 暴露出表单校验方法和表单值获取方法 */
  113 +defineExpose({
  114 + validate: async () => {
  115 + const { valid } = await formApi.validate();
  116 + return valid;
  117 + },
  118 + getValues: formApi.getValues,
  119 +});
  120 +
  121 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  122 +watch(
  123 + () => props.${subJoinColumn.javaField},
  124 + async (val) => {
  125 + if (!val) {
  126 + return;
  127 + }
  128 + await nextTick();
  129 + await formApi.setValues(await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  130 + },
  131 + { immediate: true },
  132 +);
  133 +#end
  134 +</script>
  135 +
  136 +<template>
  137 +#if ($subTable.subJoinMany) ## 一对多
  138 + <Grid class="mx-4">
  139 + #foreach($column in $subColumns)
  140 + #if ($column.createOperation || $column.updateOperation)
  141 + #set ($javaField = $column.javaField)
  142 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  143 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  144 + <template #${javaField}="{ row }">
  145 + <el-input v-model="row.${javaField}" />
  146 + </template>
  147 + #elseif($column.htmlType == "imageUpload")## 图片上传
  148 + <template #${javaField}="{ row }">
  149 + <ImageUpload v-model="row.${javaField}" />
  150 + </template>
  151 + #elseif($column.htmlType == "fileUpload")## 文件上传
  152 + <template #${javaField}="{ row }">
  153 + <FileUpload v-model="row.${javaField}" />
  154 + </template>
  155 + #elseif($column.htmlType == "select")## 下拉框
  156 + <template #${javaField}="{ row, column }">
  157 + <el-select v-model="row.${javaField}" class="w-full">
  158 + <el-option v-for="option in column.params.options" :key="option.value" :value="option.value" :label="option.label" />
  159 + </el-select>
  160 + </template>
  161 + #elseif($column.htmlType == "checkbox")## 多选框
  162 + <template #${javaField}="{ row, column }">
  163 + <el-checkbox-group v-model="row.${javaField}">
  164 + <el-checkbox v-for="option in column.params.options" :key="option.value" :label="option.value">
  165 + {{ option.label }}
  166 + </el-checkbox>
  167 + </el-checkbox-group>
  168 + </template>
  169 + #elseif($column.htmlType == "radio")## 单选框
  170 + <template #${javaField}="{ row, column }">
  171 + <el-radio-group v-model="row.${javaField}">
  172 + <el-radio v-for="option in column.params.options" :key="option.value" :label="option.value">
  173 + {{ option.label }}
  174 + </el-radio>
  175 + </el-radio-group>
  176 + </template>
  177 + #elseif($column.htmlType == "datetime")## 时间框
  178 + <template #${javaField}="{ row }">
  179 + <el-date-picker
  180 + v-model="row.${javaField}"
  181 + type="datetime"
  182 + value-format="x"
  183 + format="YYYY-MM-DD HH:mm:ss"
  184 + />
  185 + </template>
  186 + #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
  187 + <template #${javaField}="{ row }">
  188 + <el-input v-model="row.${javaField}" type="textarea" />
  189 + </template>
  190 + #end
  191 + #end
  192 + #end
  193 + </Grid>
  194 + <div class="flex justify-center -mt-4">
  195 + <el-button :icon="Plus" type="primary" plain @click="onAdd" v-access:code="['${subTable.moduleName}:${simpleClassName_strikeCase}:create']">
  196 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  197 + </el-button>
  198 + </div>
  199 +#else
  200 + <Form class="mx-4" />
  201 +#end
  202 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/list_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
  7 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  8 +<script lang="ts" setup>
  9 +import type { VxeTableGridOptions } from '#/adapter/vxe-table';
  10 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
  11 +
  12 +#if ($table.templateType == 11) ## erp
  13 +import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  14 +#end
  15 +import { useVbenModal } from '@vben/common-ui';
  16 +import { ElMessage, ElLoading } from 'element-plus';
  17 +import { ref, computed, nextTick,watch } from 'vue';
  18 +import { $t } from '#/locales';
  19 +import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
  20 +
  21 +#if ($table.templateType == 11) ## erp
  22 +import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
  23 +import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
  24 +import { isEmpty } from '@vben/utils';
  25 +#else
  26 +#if ($subTable.subJoinMany) ## 一对多
  27 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
  28 +#else
  29 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
  30 +#end
  31 +import { use${subSimpleClassName}GridColumns } from '../data';
  32 +#end
  33 +
  34 +const props = defineProps<{
  35 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  36 +}>()
  37 +
  38 +#if ($table.templateType == 11) ## erp
  39 +const [FormModal, formModalApi] = useVbenModal({
  40 + connectedComponent: ${subSimpleClassName}Form,
  41 + destroyOnClose: true,
  42 +});
  43 +
  44 +/** 创建${subTable.classComment} */
  45 +function handleCreate() {
  46 + if (!props.${subJoinColumn.javaField}){
  47 + ElMessage.warning("请先选择一个${table.classComment}!")
  48 + return
  49 + }
  50 + formModalApi.setData({${subJoinColumn.javaField}: props.${subJoinColumn.javaField}}).open();
  51 +}
  52 +
  53 +/** 编辑${subTable.classComment} */
  54 +function handleEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
  55 + formModalApi.setData(row).open();
  56 +}
  57 +
  58 +/** 删除${subTable.classComment} */
  59 +async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
  60 + const loadingInstance = ElLoading.service({
  61 + text: $t('ui.actionMessage.deleting', [row.id]),
  62 + background: 'rgba(0, 0, 0, 0.7)',
  63 + });
  64 + try {
  65 + await delete${subSimpleClassName}(row.id as number);
  66 + ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  67 + onRefresh();
  68 + } finally {
  69 + loadingInstance.close();
  70 + }
  71 +}
  72 +
  73 +#if ($deleteBatchEnable)
  74 +/** 批量删除${subTable.classComment} */
  75 +async function handleDeleteBatch() {
  76 + const loadingInstance = ElLoading.service({
  77 + text: $t('ui.actionMessage.deleting'),
  78 + background: 'rgba(0, 0, 0, 0.7)',
  79 + });
  80 + try {
  81 + await delete${subSimpleClassName}List(checkedIds.value);
  82 + ElMessage.success($t('ui.actionMessage.deleteSuccess'));
  83 + onRefresh();
  84 + } finally {
  85 + loadingInstance.close();
  86 + }
  87 +}
  88 +
  89 +const checkedIds = ref<number[]>([])
  90 +function handleRowCheckboxChange({
  91 + records,
  92 +}: {
  93 + records: ${simpleClassName}Api.${subSimpleClassName}[];
  94 +}) {
  95 + checkedIds.value = records.map((item) => item.id);
  96 +}
  97 +#end
  98 +
  99 +#end
  100 +const [Grid, gridApi] = useVbenVxeGrid({
  101 +#if ($table.templateType == 11)
  102 + formOptions: {
  103 + schema: use${subSimpleClassName}GridFormSchema(),
  104 + },
  105 +#end
  106 + gridOptions: {
  107 +#if ($table.templateType == 11)
  108 + columns: use${subSimpleClassName}GridColumns(),
  109 + proxyConfig: {
  110 + ajax: {
  111 + query: async ({ page }, formValues) => {
  112 + if (!props.${subJoinColumn.javaField}){
  113 + return []
  114 + }
  115 + return await get${subSimpleClassName}Page({
  116 + pageNo: page.currentPage,
  117 + pageSize: page.pageSize,
  118 + ${subJoinColumn.javaField}: props.${subJoinColumn.javaField},
  119 + ...formValues,
  120 + });
  121 + },
  122 + },
  123 + },
  124 + pagerConfig: {
  125 + enabled: true,
  126 + },
  127 + toolbarConfig: {
  128 + refresh: { code: 'query' },
  129 + search: true,
  130 + },
  131 +#else
  132 + columns: use${subSimpleClassName}GridColumns(),
  133 + pagerConfig: {
  134 + nabled: false,
  135 + },
  136 + toolbarConfig: {
  137 + enabled: false,
  138 + },
  139 +#end
  140 + height: '600px',
  141 + rowConfig: {
  142 + keyField: 'id',
  143 + isHover: true,
  144 + },
  145 + } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>,
  146 + #if (${table.templateType} == 11 && $deleteBatchEnable)
  147 + gridEvents:{
  148 + checkboxAll: handleRowCheckboxChange,
  149 + checkboxChange: handleRowCheckboxChange,
  150 + }
  151 + #end
  152 +});
  153 +
  154 +/** 刷新表格 */
  155 +async function onRefresh() {
  156 +#if ($table.templateType == 11) ## erp
  157 + await gridApi.query();
  158 +#else
  159 + #if ($subTable.subJoinMany) ## 一对多
  160 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  161 + #else
  162 + await gridApi.grid.loadData([await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)]);
  163 + #end
  164 +#end
  165 +}
  166 +
  167 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  168 +watch(
  169 + () => props.${subJoinColumn.javaField},
  170 + async (val) => {
  171 + if (!val) {
  172 + return;
  173 + }
  174 + await nextTick();
  175 + await onRefresh()
  176 + },
  177 + { immediate: true },
  178 +);
  179 +</script>
  180 +
  181 +<template>
  182 + #if ($table.templateType == 11) ## erp
  183 + <FormModal @success="onRefresh" />
  184 + <Grid table-title="${subTable.classComment}列表">
  185 + <template #toolbar-tools>
  186 + <TableAction
  187 + :actions="[
  188 + {
  189 + label: $t('ui.actionTitle.create', ['${table.classComment}']),
  190 + type: 'primary',
  191 + icon: ACTION_ICON.ADD,
  192 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
  193 + onClick: handleCreate,
  194 + },
  195 + #if ($table.templateType == 11 && $deleteBatchEnable)
  196 + {
  197 + label: $t('ui.actionTitle.deleteBatch'),
  198 + type: 'danger',
  199 + icon: ACTION_ICON.DELETE,
  200 + disabled: isEmpty(checkedIds),
  201 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  202 + onClick: handleDeleteBatch,
  203 + },
  204 + #end
  205 + ]"
  206 + />
  207 + </template>
  208 + <template #actions="{ row }">
  209 + <TableAction
  210 + :actions="[
  211 + {
  212 + label: $t('common.edit'),
  213 + type: 'text',
  214 + icon: ACTION_ICON.EDIT,
  215 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'],
  216 + onClick: handleEdit.bind(null, row),
  217 + },
  218 + {
  219 + label: $t('common.delete'),
  220 + type: 'danger',
  221 + text: true,
  222 + icon: ACTION_ICON.DELETE,
  223 + auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  224 + popConfirm: {
  225 + title: $t('ui.actionMessage.deleteConfirm', [row.id]),
  226 + confirm: handleDelete.bind(null, row),
  227 + },
  228 + },
  229 + ]"
  230 + />
  231 + </template>
  232 + </Grid>
  233 + #else
  234 + <Grid table-title="${subTable.classComment}列表" />
  235 + #end
  236 +</template>
... ...
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/list_sub_inner.vue.vm 0 → 100644
  1 +## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
  2 +## 1)inner 使用 list 不分页,erp 使用 page 分页
  3 +## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
  4 +#parse("codegen/vue3_vben5_ele/schema/views/modules/list_sub_erp.vue.vm")
0 5 \ No newline at end of file
... ...