Commit 80db28ee5bccf8612394e48b9f9d6e9c58d42da7

Authored by puhui999
1 parent 737ea463

代码生成:重构 vue2 模版,适配树表和主子表

yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -104,6 +104,18 @@ public class CodegenEngine { @@ -104,6 +104,18 @@ public class CodegenEngine {
104 vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) 104 vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
105 .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"), 105 .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"),
106 vueFilePath("api/${table.moduleName}/${classNameVar}.js")) 106 vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
  107 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/form.vue"),
  108 + vueFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Form.vue"))
  109 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_normal.vue"), // 特殊:主子表专属逻辑
  110 + vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
  111 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_inner.vue"), // 特殊:主子表专属逻辑
  112 + vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
  113 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_erp.vue"), // 特殊:主子表专属逻辑
  114 + vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
  115 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/list_sub_inner.vue"), // 特殊:主子表专属逻辑
  116 + vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
  117 + .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/list_sub_erp.vue"), // 特殊:主子表专属逻辑
  118 + vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
107 // Vue3 标准模版 119 // Vue3 标准模版
108 .put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"), 120 .put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"),
109 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) 121 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
@@ -452,7 +464,7 @@ public class CodegenEngine { @@ -452,7 +464,7 @@ public class CodegenEngine {
452 } 464 }
453 465
454 private static String vueFilePath(String path) { 466 private static String vueFilePath(String path) {
455 - return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录 467 + return "yudao-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
456 "src/" + path; 468 "src/" + path;
457 } 469 }
458 470
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/components/form_sub_erp.vue.vm
@@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
4 <template> 4 <template>
5 <div class="app-container"> 5 <div class="app-container">
6 <!-- 对话框(添加 / 修改) --> 6 <!-- 对话框(添加 / 修改) -->
7 - <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" v-dialogDrag append-to-body>  
8 - <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="80px"> 7 + <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
  8 + <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
9 #foreach($column in $subColumns) 9 #foreach($column in $subColumns)
10 #if ($column.createOperation || $column.updateOperation) 10 #if ($column.createOperation || $column.updateOperation)
11 #set ($dictType = $column.dictType) 11 #set ($dictType = $column.dictType)
@@ -13,30 +13,29 @@ @@ -13,30 +13,29 @@
13 #set ($javaType = $column.javaType) 13 #set ($javaType = $column.javaType)
14 #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) 14 #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
15 #set ($comment = $column.columnComment) 15 #set ($comment = $column.columnComment)
16 - #if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 TODO 芋艿:这里要忽略下 join 字段;  
17 - #if (!$column.primaryKey)## 忽略主键,不用在表单里  
18 - <el-form-item label="${comment}" prop="${javaField}">  
19 - <el-input v-model="form.${javaField}" placeholder="请输入${comment}" />  
20 - </el-form-item>  
21 - #end 16 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  17 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  18 + <el-form-item label="${comment}" prop="${javaField}">
  19 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  20 + </el-form-item>
22 #elseif($column.htmlType == "imageUpload")## 图片上传 21 #elseif($column.htmlType == "imageUpload")## 图片上传
23 #set ($hasImageUploadColumn = true) 22 #set ($hasImageUploadColumn = true)
24 - <el-form-item label="${comment}">  
25 - <ImageUpload v-model="form.${javaField}"/> 23 + <el-form-item label="${comment}" prop="${javaField}">
  24 + <ImageUpload v-model="formData.${javaField}"/>
26 </el-form-item> 25 </el-form-item>
27 #elseif($column.htmlType == "fileUpload")## 文件上传 26 #elseif($column.htmlType == "fileUpload")## 文件上传
28 #set ($hasFileUploadColumn = true) 27 #set ($hasFileUploadColumn = true)
29 - <el-form-item label="${comment}">  
30 - <FileUpload v-model="form.${javaField}"/> 28 + <el-form-item label="${comment}" prop="${javaField}">
  29 + <FileUpload v-model="formData.${javaField}"/>
31 </el-form-item> 30 </el-form-item>
32 #elseif($column.htmlType == "editor")## 文本编辑器 31 #elseif($column.htmlType == "editor")## 文本编辑器
33 #set ($hasEditorColumn = true) 32 #set ($hasEditorColumn = true)
34 - <el-form-item label="${comment}">  
35 - <editor v-model="form.${javaField}" :min-height="192"/> 33 + <el-form-item label="${comment}" prop="${javaField}">
  34 + <editor v-model="formData.${javaField}" :min-height="192"/>
36 </el-form-item> 35 </el-form-item>
37 #elseif($column.htmlType == "select")## 下拉框 36 #elseif($column.htmlType == "select")## 下拉框
38 <el-form-item label="${comment}" prop="${javaField}"> 37 <el-form-item label="${comment}" prop="${javaField}">
39 - <el-select v-model="form.${javaField}" placeholder="请选择${comment}"> 38 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
40 #if ("" != $dictType)## 有数据字典 39 #if ("" != $dictType)## 有数据字典
41 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 40 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
42 :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end /> 41 :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
@@ -47,7 +46,7 @@ @@ -47,7 +46,7 @@
47 </el-form-item> 46 </el-form-item>
48 #elseif($column.htmlType == "checkbox")## 多选框 47 #elseif($column.htmlType == "checkbox")## 多选框
49 <el-form-item label="${comment}" prop="${javaField}"> 48 <el-form-item label="${comment}" prop="${javaField}">
50 - <el-checkbox-group v-model="form.${javaField}"> 49 + <el-checkbox-group v-model="formData.${javaField}">
51 #if ("" != $dictType)## 有数据字典 50 #if ("" != $dictType)## 有数据字典
52 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 51 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
53 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox> 52 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
@@ -58,7 +57,7 @@ @@ -58,7 +57,7 @@
58 </el-form-item> 57 </el-form-item>
59 #elseif($column.htmlType == "radio")## 单选框 58 #elseif($column.htmlType == "radio")## 单选框
60 <el-form-item label="${comment}" prop="${javaField}"> 59 <el-form-item label="${comment}" prop="${javaField}">
61 - <el-radio-group v-model="form.${javaField}"> 60 + <el-radio-group v-model="formData.${javaField}">
62 #if ("" != $dictType)## 有数据字典 61 #if ("" != $dictType)## 有数据字典
63 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 62 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
64 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)" 63 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
@@ -70,11 +69,11 @@ @@ -70,11 +69,11 @@
70 </el-form-item> 69 </el-form-item>
71 #elseif($column.htmlType == "datetime")## 时间框 70 #elseif($column.htmlType == "datetime")## 时间框
72 <el-form-item label="${comment}" prop="${javaField}"> 71 <el-form-item label="${comment}" prop="${javaField}">
73 - <el-date-picker clearable v-model="form.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" /> 72 + <el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
74 </el-form-item> 73 </el-form-item>
75 #elseif($column.htmlType == "textarea")## 文本框 74 #elseif($column.htmlType == "textarea")## 文本框
76 <el-form-item label="${comment}" prop="${javaField}"> 75 <el-form-item label="${comment}" prop="${javaField}">
77 - <el-input v-model="form.${javaField}" type="textarea" placeholder="请输入内容" /> 76 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
78 </el-form-item> 77 </el-form-item>
79 #end 78 #end
80 #end 79 #end
@@ -100,7 +99,7 @@ @@ -100,7 +99,7 @@
100 import Editor from '@/components/Editor'; 99 import Editor from '@/components/Editor';
101 #end 100 #end
102 export default { 101 export default {
103 - name: "${simpleClassName}", 102 + name: "${subSimpleClassName}Form",
104 components: { 103 components: {
105 #if ($hasImageUploadColumn) 104 #if ($hasImageUploadColumn)
106 ImageUpload, 105 ImageUpload,
@@ -122,7 +121,7 @@ @@ -122,7 +121,7 @@
122 formLoading: false, 121 formLoading: false,
123 // 表单参数 122 // 表单参数
124 formData: { 123 formData: {
125 - #foreach ($column in $columns) 124 + #foreach ($column in $subColumns)
126 #if ($column.createOperation || $column.updateOperation) 125 #if ($column.createOperation || $column.updateOperation)
127 #if ($column.htmlType == "checkbox") 126 #if ($column.htmlType == "checkbox")
128 $column.javaField: [], 127 $column.javaField: [],
@@ -134,7 +133,7 @@ @@ -134,7 +133,7 @@
134 }, 133 },
135 // 表单校验 134 // 表单校验
136 formRules: { 135 formRules: {
137 - #foreach ($column in $columns) 136 + #foreach ($column in $subColumns)
138 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键 137 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
139 #set($comment=$column.columnComment) 138 #set($comment=$column.columnComment)
140 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }], 139 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
@@ -144,39 +143,25 @@ @@ -144,39 +143,25 @@
144 }; 143 };
145 }, 144 },
146 methods: { 145 methods: {
147 - /** 表单重置 */  
148 - reset() {  
149 - this.formData = {  
150 - #foreach ($column in $columns)  
151 - #if ($column.createOperation || $column.updateOperation)  
152 - #if ($column.htmlType == "checkbox")  
153 - $column.javaField: [],  
154 - #else  
155 - $column.javaField: undefined,  
156 - #end  
157 - #end  
158 - #end  
159 - };  
160 - this.resetForm("formRef");  
161 - },  
162 /** 打开弹窗 */ 146 /** 打开弹窗 */
163 - open(id) { 147 + open(id, ${subJoinColumn.javaField}) {
164 this.dialogVisible = true; 148 this.dialogVisible = true;
165 this.reset(); 149 this.reset();
166 const that = this; 150 const that = this;
  151 + this.formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField};
167 // 修改时,设置数据 152 // 修改时,设置数据
168 if (id) { 153 if (id) {
169 this.formLoading = true; 154 this.formLoading = true;
170 try { 155 try {
171 ${simpleClassName}Api.get${subSimpleClassName}(id).then(res=>{ 156 ${simpleClassName}Api.get${subSimpleClassName}(id).then(res=>{
172 that.formData = res.data; 157 that.formData = res.data;
173 - that.title = "修改${table.classComment}"; 158 + that.dialogTitle = "修改${table.classComment}";
174 }) 159 })
175 } finally { 160 } finally {
176 this.formLoading = false; 161 this.formLoading = false;
177 } 162 }
178 } 163 }
179 - this.title = "新增${table.classComment}"; 164 + this.dialogTitle = "新增${table.classComment}";
180 }, 165 },
181 /** 提交按钮 */ 166 /** 提交按钮 */
182 submitForm() { 167 submitForm() {
@@ -189,7 +174,7 @@ @@ -189,7 +174,7 @@
189 } 174 }
190 // 修改的提交 175 // 修改的提交
191 if (data.${primaryColumn.javaField}) { 176 if (data.${primaryColumn.javaField}) {
192 - ${simpleClassName}Api.update${simpleClassName}(data).then(response => { 177 + ${simpleClassName}Api.update${subSimpleClassName}(data).then(response => {
193 this.#[[$modal]]#.msgSuccess("修改成功"); 178 this.#[[$modal]]#.msgSuccess("修改成功");
194 this.dialogVisible = false; 179 this.dialogVisible = false;
195 this.#[[$]]#emit('success'); 180 this.#[[$]]#emit('success');
@@ -197,7 +182,7 @@ @@ -197,7 +182,7 @@
197 return; 182 return;
198 } 183 }
199 // 添加的提交 184 // 添加的提交
200 - ${simpleClassName}Api.create${simpleClassName}(data).then(response => { 185 + ${simpleClassName}Api.create${subSimpleClassName}(data).then(response => {
201 this.#[[$modal]]#.msgSuccess("新增成功"); 186 this.#[[$modal]]#.msgSuccess("新增成功");
202 this.dialogVisible = false; 187 this.dialogVisible = false;
203 this.#[[$]]#emit('success'); 188 this.#[[$]]#emit('success');
@@ -206,7 +191,22 @@ @@ -206,7 +191,22 @@
206 }finally { 191 }finally {
207 this.formLoading = false 192 this.formLoading = false
208 } 193 }
209 - } 194 + },
  195 + /** 表单重置 */
  196 + reset() {
  197 + this.formData = {
  198 + #foreach ($column in $subColumns)
  199 + #if ($column.createOperation || $column.updateOperation)
  200 + #if ($column.htmlType == "checkbox")
  201 + $column.javaField: [],
  202 + #else
  203 + $column.javaField: undefined,
  204 + #end
  205 + #end
  206 + #end
  207 + };
  208 + this.resetForm("formRef");
  209 + },
210 } 210 }
211 }; 211 };
212 </script> 212 </script>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/components/form_sub_normal.vue.vm
@@ -4,10 +4,8 @@ @@ -4,10 +4,8 @@
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7 -  
8 <template> 7 <template>
9 - <div class="app-container">  
10 -#if ( $subTable.subJoinMany )## 情况一:一对多,table + form 8 + #if ( $subTable.subJoinMany )## 情况一:一对多,table + form
11 <el-form 9 <el-form
12 ref="formRef" 10 ref="formRef"
13 :model="formData" 11 :model="formData"
@@ -16,7 +14,6 @@ @@ -16,7 +14,6 @@
16 label-width="0px" 14 label-width="0px"
17 :inline-message="true" 15 :inline-message="true"
18 > 16 >
19 -## // TODO puhui999: 看看样式是否需要调整  
20 <el-table :data="formData" class="-mt-10px"> 17 <el-table :data="formData" class="-mt-10px">
21 <el-table-column label="序号" type="index" width="100" /> 18 <el-table-column label="序号" type="index" width="100" />
22 #foreach($column in $subColumns) 19 #foreach($column in $subColumns)
@@ -29,7 +26,7 @@ @@ -29,7 +26,7 @@
29 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写 26 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
30 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 27 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
31 <el-table-column label="${comment}" min-width="150"> 28 <el-table-column label="${comment}" min-width="150">
32 - <template slot-scope="{ row, $index }"> 29 + <template v-slot="{ row, $index }">
33 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 30 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
34 <el-input v-model="row.${javaField}" placeholder="请输入${comment}" /> 31 <el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
35 </el-form-item> 32 </el-form-item>
@@ -38,7 +35,7 @@ @@ -38,7 +35,7 @@
38 #elseif($column.htmlType == "imageUpload")## 图片上传 35 #elseif($column.htmlType == "imageUpload")## 图片上传
39 #set ($hasImageUploadColumn = true) 36 #set ($hasImageUploadColumn = true)
40 <el-table-column label="${comment}" min-width="200"> 37 <el-table-column label="${comment}" min-width="200">
41 - <template slot-scope="{ row, $index }"> 38 + <template v-slot="{ row, $index }">
42 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 39 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
43 <ImageUpload v-model="row.${javaField}"/> 40 <ImageUpload v-model="row.${javaField}"/>
44 </el-form-item> 41 </el-form-item>
@@ -47,7 +44,7 @@ @@ -47,7 +44,7 @@
47 #elseif($column.htmlType == "fileUpload")## 文件上传 44 #elseif($column.htmlType == "fileUpload")## 文件上传
48 #set ($hasFileUploadColumn = true) 45 #set ($hasFileUploadColumn = true)
49 <el-table-column label="${comment}" min-width="200"> 46 <el-table-column label="${comment}" min-width="200">
50 - <template slot-scope="{ row, $index }"> 47 + <template v-slot="{ row, $index }">
51 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 48 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
52 <FileUpload v-model="row.${javaField}"/> 49 <FileUpload v-model="row.${javaField}"/>
53 </el-form-item> 50 </el-form-item>
@@ -56,15 +53,15 @@ @@ -56,15 +53,15 @@
56 #elseif($column.htmlType == "editor")## 文本编辑器 53 #elseif($column.htmlType == "editor")## 文本编辑器
57 #set ($hasEditorColumn = true) 54 #set ($hasEditorColumn = true)
58 <el-table-column label="${comment}" min-width="400"> 55 <el-table-column label="${comment}" min-width="400">
59 - <template slot-scope="{ row, $index }"> 56 + <template v-slot="{ row, $index }">
60 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 57 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
61 - <editor v-model="row.${javaField}" :min-height="192"/> 58 + <Editor v-model="row.${javaField}" :min-height="192"/>
62 </el-form-item> 59 </el-form-item>
63 </template> 60 </template>
64 </el-table-column> 61 </el-table-column>
65 #elseif($column.htmlType == "select")## 下拉框 62 #elseif($column.htmlType == "select")## 下拉框
66 <el-table-column label="${comment}" min-width="150"> 63 <el-table-column label="${comment}" min-width="150">
67 - <template slot-scope="{ row, $index }"> 64 + <template v-slot="{ row, $index }">
68 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 65 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
69 <el-select v-model="row.${javaField}" placeholder="请选择${comment}"> 66 <el-select v-model="row.${javaField}" placeholder="请选择${comment}">
70 #if ("" != $dictType)## 有数据字典 67 #if ("" != $dictType)## 有数据字典
@@ -79,7 +76,7 @@ @@ -79,7 +76,7 @@
79 </el-table-column> 76 </el-table-column>
80 #elseif($column.htmlType == "checkbox")## 多选框 77 #elseif($column.htmlType == "checkbox")## 多选框
81 <el-table-column label="${comment}" min-width="150"> 78 <el-table-column label="${comment}" min-width="150">
82 - <template slot-scope="{ row, $index }"> 79 + <template v-slot="{ row, $index }">
83 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 80 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
84 <el-checkbox-group v-model="row.${javaField}"> 81 <el-checkbox-group v-model="row.${javaField}">
85 #if ("" != $dictType)## 有数据字典 82 #if ("" != $dictType)## 有数据字典
@@ -94,7 +91,7 @@ @@ -94,7 +91,7 @@
94 </el-table-column> 91 </el-table-column>
95 #elseif($column.htmlType == "radio")## 单选框 92 #elseif($column.htmlType == "radio")## 单选框
96 <el-table-column label="${comment}" min-width="150"> 93 <el-table-column label="${comment}" min-width="150">
97 - <template slot-scope="{ row, $index }"> 94 + <template v-slot="{ row, $index }">
98 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 95 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
99 <el-radio-group v-model="row.${javaField}"> 96 <el-radio-group v-model="row.${javaField}">
100 #if ("" != $dictType)## 有数据字典 97 #if ("" != $dictType)## 有数据字典
@@ -110,20 +107,15 @@ @@ -110,20 +107,15 @@
110 </el-table-column> 107 </el-table-column>
111 #elseif($column.htmlType == "datetime")## 时间框 108 #elseif($column.htmlType == "datetime")## 时间框
112 <el-table-column label="${comment}" min-width="150"> 109 <el-table-column label="${comment}" min-width="150">
113 - <template slot-scope="{ row, $index }"> 110 + <template v-slot="{ row, $index }">
114 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 111 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
115 - <el-date-picker  
116 - v-model="row.${javaField}"  
117 - type="date"  
118 - value-format="x"  
119 - placeholder="选择${comment}"  
120 - /> 112 + <el-date-picker clearable v-model="row.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
121 </el-form-item> 113 </el-form-item>
122 </template> 114 </template>
123 </el-table-column> 115 </el-table-column>
124 #elseif($column.htmlType == "textarea")## 文本框 116 #elseif($column.htmlType == "textarea")## 文本框
125 <el-table-column label="${comment}" min-width="200"> 117 <el-table-column label="${comment}" min-width="200">
126 - <template slot-scope="{ row, $index }"> 118 + <template v-slot="{ row, $index }">
127 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!"> 119 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
128 <el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" /> 120 <el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
129 </el-form-item> 121 </el-form-item>
@@ -133,17 +125,97 @@ @@ -133,17 +125,97 @@
133 #end 125 #end
134 #end 126 #end
135 <el-table-column align="center" fixed="right" label="操作" width="60"> 127 <el-table-column align="center" fixed="right" label="操作" width="60">
136 - <template slot-scope="{ $index }">  
137 - <el-button @click="handleDelete($index)" link>—</el-button> 128 + <template v-slot="{ $index }">
  129 + <el-link @click="handleDelete($index)">—</el-link>
138 </template> 130 </template>
139 </el-table-column> 131 </el-table-column>
140 </el-table> 132 </el-table>
141 </el-form> 133 </el-form>
142 - <el-row justify="center" class="mt-3">  
143 - <el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>  
144 - </el-row>  
145 -#end  
146 - </div> 134 + <el-row justify="center" class="mt-3">
  135 + <el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
  136 + </el-row>
  137 + #else## 情况二:一对一,form
  138 + <el-form
  139 + ref="formRef"
  140 + :model="formData"
  141 + :rules="formRules"
  142 + label-width="100px"
  143 + v-loading="formLoading"
  144 + >
  145 + #foreach($column in $subColumns)
  146 + #if ($column.createOperation || $column.updateOperation)
  147 + #set ($dictType = $column.dictType)
  148 + #set ($javaField = $column.javaField)
  149 + #set ($javaType = $column.javaType)
  150 + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  151 + #set ($comment = $column.columnComment)
  152 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  153 + #elseif ($column.htmlType == "input" && !$column.primaryKey)
  154 + <el-form-item label="${comment}" prop="${javaField}">
  155 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  156 + </el-form-item>
  157 + #elseif($column.htmlType == "imageUpload")## 图片上传
  158 + #set ($hasImageUploadColumn = true)
  159 + <el-form-item label="${comment}">
  160 + <ImageUpload v-model="formData.${javaField}"/>
  161 + </el-form-item>
  162 + #elseif($column.htmlType == "fileUpload")## 文件上传
  163 + #set ($hasFileUploadColumn = true)
  164 + <el-form-item label="${comment}">
  165 + <FileUpload v-model="formData.${javaField}"/>
  166 + </el-form-item>
  167 + #elseif($column.htmlType == "editor")## 文本编辑器
  168 + #set ($hasEditorColumn = true)
  169 + <el-form-item label="${comment}">
  170 + <Editor v-model="formData.${javaField}" :min-height="192"/>
  171 + </el-form-item>
  172 + #elseif($column.htmlType == "select")## 下拉框
  173 + <el-form-item label="${comment}" prop="${javaField}">
  174 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  175 + #if ("" != $dictType)## 有数据字典
  176 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
  177 + :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
  178 + #else##没数据字典
  179 + <el-option label="请选择字典生成" value="" />
  180 + #end
  181 + </el-select>
  182 + </el-form-item>
  183 + #elseif($column.htmlType == "checkbox")## 多选框
  184 + <el-form-item label="${comment}" prop="${javaField}">
  185 + <el-checkbox-group v-model="formData.${javaField}">
  186 + #if ("" != $dictType)## 有数据字典
  187 + <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
  188 + :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
  189 + #else##没数据字典
  190 + <el-checkbox>请选择字典生成</el-checkbox>
  191 + #end
  192 + </el-checkbox-group>
  193 + </el-form-item>
  194 + #elseif($column.htmlType == "radio")## 单选框
  195 + <el-form-item label="${comment}" prop="${javaField}">
  196 + <el-radio-group v-model="formData.${javaField}">
  197 + #if ("" != $dictType)## 有数据字典
  198 + <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
  199 + :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
  200 + #else:label="dict.value"#end>{{dict.label}}</el-radio>
  201 + #else##没数据字典
  202 + <el-radio label="1">请选择字典生成</el-radio>
  203 + #end
  204 + </el-radio-group>
  205 + </el-form-item>
  206 + #elseif($column.htmlType == "datetime")## 时间框
  207 + <el-form-item label="${comment}" prop="${javaField}">
  208 + <el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
  209 + </el-form-item>
  210 + #elseif($column.htmlType == "textarea")## 文本框
  211 + <el-form-item label="${comment}" prop="${javaField}">
  212 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  213 + </el-form-item>
  214 + #end
  215 + #end
  216 + #end
  217 + </el-form>
  218 + #end
147 </template> 219 </template>
148 220
149 <script> 221 <script>
@@ -158,7 +230,7 @@ @@ -158,7 +230,7 @@
158 import Editor from '@/components/Editor'; 230 import Editor from '@/components/Editor';
159 #end 231 #end
160 export default { 232 export default {
161 - name: "${simpleClassName}", 233 + name: "${subSimpleClassName}Form",
162 components: { 234 components: {
163 #if ($hasImageUploadColumn) 235 #if ($hasImageUploadColumn)
164 ImageUpload, 236 ImageUpload,
@@ -170,29 +242,18 @@ @@ -170,29 +242,18 @@
170 Editor, 242 Editor,
171 #end 243 #end
172 }, 244 },
  245 + props:[
  246 + '${subJoinColumn.javaField}'
  247 + ],// ${subJoinColumn.columnComment}(主表的关联字段)
173 data() { 248 data() {
174 return { 249 return {
175 - // 弹出层标题  
176 - dialogTitle: "",  
177 - // 是否显示弹出层  
178 - dialogVisible: false,  
179 // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 250 // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
180 formLoading: false, 251 formLoading: false,
181 // 表单参数 252 // 表单参数
182 - formData: {  
183 - #foreach ($column in $columns)  
184 - #if ($column.createOperation || $column.updateOperation)  
185 - #if ($column.htmlType == "checkbox")  
186 - $column.javaField: [],  
187 - #else  
188 - $column.javaField: undefined,  
189 - #end  
190 - #end  
191 - #end  
192 - }, 253 + formData: [],
193 // 表单校验 254 // 表单校验
194 formRules: { 255 formRules: {
195 - #foreach ($column in $columns) 256 + #foreach ($column in $subColumns)
196 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键 257 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
197 #set($comment=$column.columnComment) 258 #set($comment=$column.columnComment)
198 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }], 259 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
@@ -201,14 +262,56 @@ @@ -201,14 +262,56 @@
201 }, 262 },
202 }; 263 };
203 }, 264 },
204 - props:{  
205 - ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段) 265 + watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
  266 + ${subJoinColumn.javaField}:{
  267 + handler(val) {
  268 + // 1. 重置表单
  269 + #if ( $subTable.subJoinMany )
  270 + this.formData = []
  271 + #else
  272 + this.formData = {
  273 + #foreach ($column in $subColumns)
  274 + #if ($column.createOperation || $column.updateOperation)
  275 + #if ($column.htmlType == "checkbox")
  276 + $column.javaField: [],
  277 + #else
  278 + $column.javaField: undefined,
  279 + #end
  280 + #end
  281 + #end
  282 + }
  283 + #end
  284 + // 2. val 非空,则加载数据
  285 + if (!val) {
  286 + return;
  287 + }
  288 + try {
  289 + this.formLoading = true;
  290 + const that = this;
  291 + #if ( $subTable.subJoinMany )
  292 + ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val).then(res=>{
  293 + that.formData = res.data;
  294 + })
  295 + #else
  296 + ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val).then(res=>{
  297 + const data = res.data;
  298 + if (!data) {
  299 + return
  300 + }
  301 + that.formData = data;
  302 + })
  303 + #end
  304 + } finally {
  305 + this.formLoading = false;
  306 + }
  307 + },
  308 + immediate: true
  309 + }
206 }, 310 },
207 methods: { 311 methods: {
208 #if ( $subTable.subJoinMany ) 312 #if ( $subTable.subJoinMany )
209 -  
210 /** 新增按钮操作 */ 313 /** 新增按钮操作 */
211 - handleAdd(){ 314 + handleAdd() {
212 const row = { 315 const row = {
213 #foreach ($column in $subColumns) 316 #foreach ($column in $subColumns)
214 #if ($column.createOperation || $column.updateOperation) 317 #if ($column.createOperation || $column.updateOperation)
@@ -223,19 +326,18 @@ @@ -223,19 +326,18 @@
223 row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField} 326 row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField}
224 this.formData.push(row) 327 this.formData.push(row)
225 }, 328 },
226 -  
227 /** 删除按钮操作 */ 329 /** 删除按钮操作 */
228 - handleDelete(index) { 330 + handleDelete(index) {
229 this.formData.splice(index, 1) 331 this.formData.splice(index, 1)
230 }, 332 },
231 #end 333 #end
  334 + /** 表单校验 */
  335 + validate(){
  336 + return this.#[[$]]#refs["formRef"].validate()
  337 + },
232 /** 表单值 */ 338 /** 表单值 */
233 - getData() { 339 + getData(){
234 return this.formData 340 return this.formData
235 - },  
236 - /** 表单校验 */  
237 - validate() {  
238 -  
239 } 341 }
240 } 342 }
241 }; 343 };
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/components/list_sub_erp.vue.vm
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 ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写  
7 <template> 1 <template>
8 - <!-- 列表 -->  
9 - <ContentWrap> 2 + <div class="app-container">
10 #if ($table.templateType == 11) 3 #if ($table.templateType == 11)
11 - <el-button  
12 - type="primary"  
13 - plain  
14 - @click="openForm('create')"  
15 - v-hasPermi="['${permissionPrefix}:create']"  
16 - >  
17 - <Icon icon="ep:plus" class="mr-5px" /> 新增  
18 - </el-button> 4 + <!-- 操作工具栏 -->
  5 + <el-row :gutter="10" class="mb8">
  6 + <el-col :span="1.5">
  7 + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
  8 + v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
  9 + </el-col>
  10 + </el-row>
19 #end 11 #end
20 - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">  
21 - #foreach($column in $subColumns)  
22 - #if ($column.listOperationResult)  
23 - #set ($dictType=$column.dictType)  
24 - #set ($javaField = $column.javaField)  
25 - #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
26 - #set ($comment=$column.columnComment)  
27 - #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写  
28 - #elseif ($column.javaType == "LocalDateTime")## 时间类型  
29 - <el-table-column  
30 - label="${comment}"  
31 - align="center"  
32 - prop="${javaField}"  
33 - :formatter="dateFormatter"  
34 - width="180px"  
35 - />  
36 - #elseif($column.dictType && "" != $column.dictType)## 数据字典  
37 - <el-table-column label="${comment}" align="center" prop="${javaField}">  
38 - <template #default="scope">  
39 - <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />  
40 - </template>  
41 - </el-table-column>  
42 - #else  
43 - <el-table-column label="${comment}" align="center" prop="${javaField}" />  
44 - #end 12 + ## 列表
  13 + <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  14 + #foreach($column in $subColumns)
  15 + #if ($column.listOperationResult)
  16 + #set ($dictType=$column.dictType)
  17 + #set ($javaField = $column.javaField)
  18 + #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  19 + #set ($comment=$column.columnComment)
  20 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  21 + #elseif ($column.javaType == "LocalDateTime")## 时间类型
  22 + <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
  23 + <template v-slot="scope">
  24 + <span>{{ parseTime(scope.row.${javaField}) }}</span>
  25 + </template>
  26 + </el-table-column>
  27 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  28 + <el-table-column label="${comment}" align="center" prop="${javaField}">
  29 + <template v-slot="scope">
  30 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
  31 + </template>
  32 + </el-table-column>
  33 + #else
  34 + <el-table-column label="${comment}" align="center" prop="${javaField}" />
  35 + #end
  36 + #end
45 #end 37 #end
46 - #end  
47 - #if ($table.templateType == 11)  
48 - <el-table-column label="操作" align="center">  
49 - <template #default="scope">  
50 - <el-button  
51 - link  
52 - type="primary"  
53 - @click="openForm('update', scope.row.id)"  
54 - v-hasPermi="['${permissionPrefix}:update']"  
55 - >  
56 - 编辑  
57 - </el-button>  
58 - <el-button  
59 - link  
60 - type="danger"  
61 - @click="handleDelete(scope.row.id)"  
62 - v-hasPermi="['${permissionPrefix}:delete']"  
63 - >  
64 - 删除  
65 - </el-button>  
66 - </template>  
67 - </el-table-column>  
68 - #end  
69 - </el-table>  
70 - #if ($table.templateType == 11)  
71 - <!-- 分页 -->  
72 - <Pagination  
73 - :total="total"  
74 - v-model:page="queryParams.pageNo"  
75 - v-model:limit="queryParams.pageSize"  
76 - @pagination="getList"  
77 - />  
78 - #end  
79 - </ContentWrap> 38 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  39 + <template v-slot="scope">
  40 + <el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
  41 + v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
  42 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  43 + v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
  44 + </template>
  45 + </el-table-column>
  46 + </el-table>
80 #if ($table.templateType == 11) 47 #if ($table.templateType == 11)
81 - <!-- 表单弹窗:添加/修改 -->  
82 - <${subSimpleClassName}Form ref="formRef" @success="getList" /> 48 + <!-- 分页组件 -->
  49 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  50 + @pagination="getList"/>
  51 + <!-- 对话框(添加 / 修改) -->
  52 + <${subSimpleClassName}Form ref="formRef" @success="getList" />
83 #end 53 #end
  54 + </div>
84 </template> 55 </template>
85 -<script setup lang="ts">  
86 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
87 -import { dateFormatter } from '@/utils/formatTime'  
88 -import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'  
89 -#if ($table.templateType == 11)  
90 -import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'  
91 -#end  
92 -  
93 -const { t } = useI18n() // 国际化  
94 -const message = useMessage() // 消息弹窗  
95 -  
96 -const props = defineProps<{  
97 - ${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)  
98 -}>()  
99 -const loading = ref(false) // 列表的加载中  
100 -const list = ref([]) // 列表的数据  
101 -#if ($table.templateType == 11)  
102 -const total = ref(0) // 列表的总页数  
103 -const queryParams = reactive({  
104 - pageNo: 1,  
105 - pageSize: 10,  
106 - ${subJoinColumn.javaField}: undefined  
107 -})  
108 56
109 -/** 监听主表的关联字段的变化,加载对应的子表数据 */  
110 -watch(  
111 - () => props.${subJoinColumn.javaField},  
112 - (val) => {  
113 - queryParams.${subJoinColumn.javaField} = val  
114 - handleQuery()  
115 - },  
116 - { immediate: false }  
117 -)  
118 -#end  
119 -  
120 -/** 查询列表 */  
121 -const getList = async () => {  
122 - loading.value = true  
123 - try {  
124 -#if ($table.templateType == 11)  
125 - const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)  
126 - list.value = data.list  
127 - total.value = data.total  
128 -#else  
129 - #if ( $subTable.subJoinMany )  
130 - list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})  
131 - #else  
132 - const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})  
133 - if (!data) {  
134 - return  
135 - }  
136 - list.value.push(data) 57 +<script>
  58 + import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
  59 + #if ($table.templateType == 11)
  60 + import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
137 #end 61 #end
  62 + export default {
  63 + name: "${subSimpleClassName}List",
  64 +#if ($table.templateType == 11)
  65 + components: {
  66 + ${subSimpleClassName}Form
  67 + },
138 #end 68 #end
139 - } finally {  
140 - loading.value = false  
141 - }  
142 -}  
143 -  
144 -/** 搜索按钮操作 */  
145 -const handleQuery = () => {  
146 - queryParams.pageNo = 1  
147 - getList()  
148 -} 69 + props:[
  70 + '${subJoinColumn.javaField}'
  71 + ],// ${subJoinColumn.columnComment}(主表的关联字段)
  72 + data() {
  73 + return {
  74 + // 遮罩层
  75 + loading: true,
  76 + // 列表的数据
  77 + list: [],
149 #if ($table.templateType == 11) 78 #if ($table.templateType == 11)
150 -  
151 -/** 添加/修改操作 */  
152 -const formRef = ref()  
153 -const openForm = (type: string, id?: number) => {  
154 - if (!props.${subJoinColumn.javaField}) {  
155 - message.error('请选择一个${table.classComment}')  
156 - return  
157 - }  
158 - formRef.value.open(type, id, props.${subJoinColumn.javaField})  
159 -}  
160 -  
161 -/** 删除按钮操作 */  
162 -const handleDelete = async (id: number) => {  
163 - try {  
164 - // 删除的二次确认  
165 - await message.delConfirm()  
166 - // 发起删除  
167 - await ${simpleClassName}Api.delete${subSimpleClassName}(id)  
168 - message.success(t('common.delSuccess'))  
169 - // 刷新列表  
170 - await getList()  
171 - } catch {}  
172 -} 79 + // 列表的总页数
  80 + total: 0,
  81 + // 查询参数
  82 + queryParams: {
  83 + pageNo: 1,
  84 + pageSize: 10,
  85 + ${subJoinColumn.javaField}: undefined
  86 + }
173 #end 87 #end
  88 + };
  89 + },
174 #if ($table.templateType != 11) 90 #if ($table.templateType != 11)
175 -  
176 -/** 初始化 **/  
177 -onMounted(() => {  
178 - getList()  
179 -}) 91 + created() {
  92 + this.getList();
  93 + },
  94 +#end
  95 + watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
  96 + ${subJoinColumn.javaField}:{
  97 + handler(val) {
  98 + this.queryParams.${subJoinColumn.javaField} = val
  99 + this.handleQuery()
  100 + },
  101 + immediate: true
  102 + }
  103 + },
  104 + methods: {
  105 + /** 查询列表 */
  106 + getList() {
  107 + try {
  108 + this.loading = true;
  109 + const that = this;
  110 + #if ($table.templateType == 11)
  111 + ${simpleClassName}Api.get${subSimpleClassName}Page(this.queryParams).then(response => {
  112 + that.list = response.data.list;
  113 + that.total = response.data.total;
  114 + });
  115 + #else
  116 + #if ( $subTable.subJoinMany )
  117 + ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(this.${subJoinColumn.javaField}).then(response=>{
  118 + that.list = response.data;
  119 + })
  120 + #else
  121 + ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(this.${subJoinColumn.javaField}).then(response=>{
  122 + const data = response.data;
  123 + if (!data) {
  124 + return
  125 + }
  126 + that.list.push(data)
  127 + })
  128 + #end
  129 + #end
  130 + } finally {
  131 + this.loading = false;
  132 + }
  133 + },
  134 + /** 搜索按钮操作 */
  135 + handleQuery() {
  136 + this.queryParams.pageNo = 1;
  137 + this.getList();
  138 + },
  139 +#if ($table.templateType == 11)
  140 + /** 添加/修改操作 */
  141 + openForm(id) {
  142 + if (!this.${subJoinColumn.javaField}) {
  143 + that.#[[$modal]]#.msgError('请选择一个${table.classComment}');
  144 + return;
  145 + }
  146 + this.#[[$]]#refs["formRef"].open(id, this.${subJoinColumn.javaField});
  147 + },
  148 + /** 删除按钮操作 */
  149 + handleDelete(row) {
  150 + const that = this;
  151 + try {
  152 + const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
  153 + this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?').then(()=>{
  154 + return ${simpleClassName}Api.delete${subSimpleClassName}(${primaryColumn.javaField});
  155 + }).then(() => {
  156 + that.getList();
  157 + that.#[[$modal]]#.msgSuccess("删除成功");
  158 + }).catch(() => {});
  159 + } catch {}
  160 + },
  161 + }
180 #end 162 #end
181 -</script>  
182 \ No newline at end of file 163 \ No newline at end of file
  164 + };
  165 +</script>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/form.vue.vm
1 <template> 1 <template>
2 <div class="app-container"> 2 <div class="app-container">
3 <!-- 对话框(添加 / 修改) --> 3 <!-- 对话框(添加 / 修改) -->
4 - <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" v-dialogDrag append-to-body>  
5 - <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="80px"> 4 + <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
  5 + <el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
6 #foreach($column in $columns) 6 #foreach($column in $columns)
7 #if ($column.createOperation || $column.updateOperation) 7 #if ($column.createOperation || $column.updateOperation)
8 #set ($dictType = $column.dictType) 8 #set ($dictType = $column.dictType)
@@ -11,37 +11,35 @@ @@ -11,37 +11,35 @@
11 #set ($comment = $column.columnComment) 11 #set ($comment = $column.columnComment)
12 #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id ) 12 #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
13 <el-form-item label="${comment}" prop="${javaField}"> 13 <el-form-item label="${comment}" prop="${javaField}">
14 - <treeselect 14 + <TreeSelect
15 v-model="formData.${javaField}" 15 v-model="formData.${javaField}"
16 :options="${classNameVar}Tree" 16 :options="${classNameVar}Tree"
17 :normalizer="normalizer" 17 :normalizer="normalizer"
18 placeholder="请选择${comment}" 18 placeholder="请选择${comment}"
19 /> 19 />
20 </el-form-item> 20 </el-form-item>
21 - #elseif ($column.htmlType == "input" && !$column.primaryKey)  
22 - #if (!$column.primaryKey)## 忽略主键,不用在表单里  
23 - <el-form-item label="${comment}" prop="${javaField}">  
24 - <el-input v-model="form.${javaField}" placeholder="请输入${comment}" />  
25 - </el-form-item>  
26 - #end 21 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  22 + <el-form-item label="${comment}" prop="${javaField}">
  23 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  24 + </el-form-item>
27 #elseif($column.htmlType == "imageUpload")## 图片上传 25 #elseif($column.htmlType == "imageUpload")## 图片上传
28 #set ($hasImageUploadColumn = true) 26 #set ($hasImageUploadColumn = true)
29 <el-form-item label="${comment}"> 27 <el-form-item label="${comment}">
30 - <imageUpload v-model="form.${javaField}"/> 28 + <ImageUpload v-model="formData.${javaField}"/>
31 </el-form-item> 29 </el-form-item>
32 #elseif($column.htmlType == "fileUpload")## 文件上传 30 #elseif($column.htmlType == "fileUpload")## 文件上传
33 #set ($hasFileUploadColumn = true) 31 #set ($hasFileUploadColumn = true)
34 <el-form-item label="${comment}"> 32 <el-form-item label="${comment}">
35 - <fileUpload v-model="form.${javaField}"/> 33 + <FileUpload v-model="formData.${javaField}"/>
36 </el-form-item> 34 </el-form-item>
37 #elseif($column.htmlType == "editor")## 文本编辑器 35 #elseif($column.htmlType == "editor")## 文本编辑器
38 #set ($hasEditorColumn = true) 36 #set ($hasEditorColumn = true)
39 <el-form-item label="${comment}"> 37 <el-form-item label="${comment}">
40 - <editor v-model="form.${javaField}" :min-height="192"/> 38 + <Editor v-model="formData.${javaField}" :min-height="192"/>
41 </el-form-item> 39 </el-form-item>
42 #elseif($column.htmlType == "select")## 下拉框 40 #elseif($column.htmlType == "select")## 下拉框
43 <el-form-item label="${comment}" prop="${javaField}"> 41 <el-form-item label="${comment}" prop="${javaField}">
44 - <el-select v-model="form.${javaField}" placeholder="请选择${comment}"> 42 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
45 #if ("" != $dictType)## 有数据字典 43 #if ("" != $dictType)## 有数据字典
46 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 44 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
47 :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end /> 45 :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
@@ -52,7 +50,7 @@ @@ -52,7 +50,7 @@
52 </el-form-item> 50 </el-form-item>
53 #elseif($column.htmlType == "checkbox")## 多选框 51 #elseif($column.htmlType == "checkbox")## 多选框
54 <el-form-item label="${comment}" prop="${javaField}"> 52 <el-form-item label="${comment}" prop="${javaField}">
55 - <el-checkbox-group v-model="form.${javaField}"> 53 + <el-checkbox-group v-model="formData.${javaField}">
56 #if ("" != $dictType)## 有数据字典 54 #if ("" != $dictType)## 有数据字典
57 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 55 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
58 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox> 56 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
@@ -63,7 +61,7 @@ @@ -63,7 +61,7 @@
63 </el-form-item> 61 </el-form-item>
64 #elseif($column.htmlType == "radio")## 单选框 62 #elseif($column.htmlType == "radio")## 单选框
65 <el-form-item label="${comment}" prop="${javaField}"> 63 <el-form-item label="${comment}" prop="${javaField}">
66 - <el-radio-group v-model="form.${javaField}"> 64 + <el-radio-group v-model="formData.${javaField}">
67 #if ("" != $dictType)## 有数据字典 65 #if ("" != $dictType)## 有数据字典
68 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())" 66 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
69 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)" 67 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
@@ -75,18 +73,18 @@ @@ -75,18 +73,18 @@
75 </el-form-item> 73 </el-form-item>
76 #elseif($column.htmlType == "datetime")## 时间框 74 #elseif($column.htmlType == "datetime")## 时间框
77 <el-form-item label="${comment}" prop="${javaField}"> 75 <el-form-item label="${comment}" prop="${javaField}">
78 - <el-date-picker clearable v-model="form.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" /> 76 + <el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
79 </el-form-item> 77 </el-form-item>
80 #elseif($column.htmlType == "textarea")## 文本框 78 #elseif($column.htmlType == "textarea")## 文本框
81 <el-form-item label="${comment}" prop="${javaField}"> 79 <el-form-item label="${comment}" prop="${javaField}">
82 - <el-input v-model="form.${javaField}" type="textarea" placeholder="请输入内容" /> 80 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
83 </el-form-item> 81 </el-form-item>
84 #end 82 #end
85 #end 83 #end
86 #end 84 #end
87 </el-form> 85 </el-form>
88 ## 特殊:主子表专属逻辑 86 ## 特殊:主子表专属逻辑
89 - #if ( $subTables && $subTables.size() > 0 ) 87 + #if ( $table.templateType == 10 || $table.templateType == 12 )
90 <!-- 子表的表单 --> 88 <!-- 子表的表单 -->
91 <el-tabs v-model="subTabsName"> 89 <el-tabs v-model="subTabsName">
92 #foreach ($subTable in $subTables) 90 #foreach ($subTable in $subTables)
@@ -121,17 +119,17 @@ @@ -121,17 +119,17 @@
121 #end 119 #end
122 ## 特殊:树表专属逻辑 120 ## 特殊:树表专属逻辑
123 #if ( $table.templateType == 2 ) 121 #if ( $table.templateType == 2 )
124 - import Treeselect from "@riophae/vue-treeselect"; 122 + import TreeSelect from "@riophae/vue-treeselect";
125 import "@riophae/vue-treeselect/dist/vue-treeselect.css"; 123 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
126 #end 124 #end
127 ## 特殊:主子表专属逻辑 125 ## 特殊:主子表专属逻辑
128 - #if ( $subTables && $subTables.size() > 0 )  
129 - #foreach ($subSimpleClassName in $subSimpleClassNames)  
130 - import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'  
131 - #end 126 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  127 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  128 + import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
  129 + #end
132 #end 130 #end
133 export default { 131 export default {
134 - name: "${simpleClassName}", 132 + name: "${simpleClassName}Form",
135 components: { 133 components: {
136 #if ($hasImageUploadColumn) 134 #if ($hasImageUploadColumn)
137 ImageUpload, 135 ImageUpload,
@@ -144,13 +142,13 @@ @@ -144,13 +142,13 @@
144 #end 142 #end
145 ## 特殊:树表专属逻辑 143 ## 特殊:树表专属逻辑
146 #if ( $table.templateType == 2 ) 144 #if ( $table.templateType == 2 )
147 - Treeselect, 145 + TreeSelect,
148 #end 146 #end
149 ## 特殊:主子表专属逻辑 147 ## 特殊:主子表专属逻辑
150 - #if ( $subTables && $subTables.size() > 0 )  
151 - #foreach ($subSimpleClassName in $subSimpleClassNames)  
152 - ${subSimpleClassName}Form,  
153 - #end 148 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  149 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  150 + ${subSimpleClassName}Form,
  151 + #end
154 #end 152 #end
155 }, 153 },
156 data() { 154 data() {
@@ -178,7 +176,7 @@ @@ -178,7 +176,7 @@
178 #foreach ($column in $columns) 176 #foreach ($column in $columns)
179 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键 177 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
180 #set($comment=$column.columnComment) 178 #set($comment=$column.columnComment)
181 - $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }], 179 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
182 #end 180 #end
183 #end 181 #end
184 }, 182 },
@@ -186,43 +184,16 @@ @@ -186,43 +184,16 @@
186 #if ( $table.templateType == 2 ) 184 #if ( $table.templateType == 2 )
187 ${classNameVar}Tree: [], // 树形结构 185 ${classNameVar}Tree: [], // 树形结构
188 #end 186 #end
189 - ## 特殊:主子表专属逻辑  
190 - #if ( $subTables && $subTables.size() > 0 ) 187 + ## 特殊:主子表专属逻辑
  188 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  189 + #if ( $subTables && $subTables.size() > 0 )
191 /** 子表的表单 */ 190 /** 子表的表单 */
192 subTabsName: '$subClassNameVars.get(0)' 191 subTabsName: '$subClassNameVars.get(0)'
193 - #end 192 + #end
  193 + #end
194 }; 194 };
195 }, 195 },
196 methods: { 196 methods: {
197 - ## 特殊:树表专属逻辑  
198 - #if ( $table.templateType == 2 )  
199 - /** 转换${table.classComment}数据结构 */  
200 - normalizer(node) {  
201 - if (node.children && !node.children.length) {  
202 - delete node.children;  
203 - }  
204 - return {  
205 - id: node.id,  
206 - label: node.name,  
207 - children: node.children  
208 - };  
209 - },  
210 - #end  
211 - /** 表单重置 */  
212 - reset() {  
213 - this.formData = {  
214 - #foreach ($column in $columns)  
215 - #if ($column.createOperation || $column.updateOperation)  
216 - #if ($column.htmlType == "checkbox")  
217 - $column.javaField: [],  
218 - #else  
219 - $column.javaField: undefined,  
220 - #end  
221 - #end  
222 - #end  
223 - };  
224 - this.resetForm("formRef");  
225 - },  
226 /** 打开弹窗 */ 197 /** 打开弹窗 */
227 open(id) { 198 open(id) {
228 this.dialogVisible = true; 199 this.dialogVisible = true;
@@ -246,88 +217,151 @@ @@ -246,88 +217,151 @@
246 this.get${simpleClassName}Tree() 217 this.get${simpleClassName}Tree()
247 #end 218 #end
248 }, 219 },
249 - ## 特殊:树表专属逻辑  
250 - #if ( $table.templateType == 2 )  
251 - /** 获得${table.classComment}树 */  
252 - get${simpleClassName}Tree() {  
253 - const that = this;  
254 - that.${classNameVar}Tree = [];  
255 - ${simpleClassName}Api.get${simpleClassName}List().then(res=>{  
256 - const root = { id: 0, name: '顶级${table.classComment}', children: [] };  
257 - root.children = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}')  
258 - that.${classNameVar}Tree.push(root)  
259 - });  
260 - },  
261 - #end  
262 -  
263 /** 提交按钮 */ 220 /** 提交按钮 */
264 submitForm() { 221 submitForm() {
265 this.formLoading = true; 222 this.formLoading = true;
266 try { 223 try {
267 - let data = this.formData;  
268 -## 特殊:主子表专属逻辑  
269 -#if ( $subTables && $subTables.size() > 0 )  
270 - // 需要校验的表单 ref  
271 - const validFormRefArr = [  
272 - #foreach ($subTable in $subTables)  
273 - #set ($index = $foreach.count - 1)  
274 - #set ($subClassNameVar = $subClassNameVars.get($index))  
275 - "${subClassNameVar}FormRef",  
276 - #end  
277 - ];  
278 -  
279 - const validArr = []; // 校验  
280 const that = this; 224 const that = this;
281 - validFormRefArr.forEach((item, index) => {  
282 - validArr.push(new Promise((resolve, reject) => {  
283 - that.getRef(item).validate(valid => {  
284 - if (valid){ // 校验成功  
285 - resolve()  
286 - }else {  
287 - reject(item.replace("FormRef","")) // 校验失败返回对应的表单  
288 - }  
289 - })  
290 - }))})  
291 - Promise.all(validArr).then(() => { 225 + let data = this.formData;
  226 + let validate = false;
  227 + // 校验主表
  228 + this.getRef("formRef").validate(valid => {
  229 + validate = valid;
  230 + });
  231 + ## 特殊:主子表专属逻辑
  232 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  233 + #if ( $subTables && $subTables.size() > 0 )
  234 + // 校验子表
  235 + this.validateSubFrom01().then(() => {
292 // 全部校验通过-拼接子表的数据 236 // 全部校验通过-拼接子表的数据
293 // 拼接子表的数据 237 // 拼接子表的数据
294 #foreach ($subTable in $subTables) 238 #foreach ($subTable in $subTables)
295 #set ($index = $foreach.count - 1) 239 #set ($index = $foreach.count - 1)
296 #set ($subClassNameVar = $subClassNameVars.get($index)) 240 #set ($subClassNameVar = $subClassNameVars.get($index))
297 - data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = that.getRef(${subClassNameVar}FormRef).getData() 241 + data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = that.getRef('${subClassNameVar}FormRef').getData();
298 #end 242 #end
299 - }).catch((err)=>{  
300 - that.subTabsName = err  
301 - })  
302 -#end  
303 -  
304 - this.getRef("formRef").validate(valid => {  
305 - if (!valid) { 243 + }).catch((err) => {
  244 + validate = false
  245 + that.subTabsName = err.replace("FormRef", ""); // 定位到没有校验通过的子表单
  246 + })
  247 + #end
  248 + #end
  249 + // 所有表单校验通过后方可提交
  250 + if (!validate) {
306 return; 251 return;
307 } 252 }
308 // 修改的提交 253 // 修改的提交
309 if (data.${primaryColumn.javaField}) { 254 if (data.${primaryColumn.javaField}) {
310 - ${simpleClassName}Api.update${simpleClassName}(data).then(response => {  
311 - this.#[[$modal]]#.msgSuccess("修改成功");  
312 - this.dialogVisible = false;  
313 - this.#[[$]]#emit('success'); 255 + ${simpleClassName}Api.update${simpleClassName}(data).then(response => {
  256 + that.#[[$modal]]#.msgSuccess("修改成功");
  257 + that.dialogVisible = false;
  258 + that.#[[$]]#emit('success');
314 }); 259 });
315 return; 260 return;
316 } 261 }
317 // 添加的提交 262 // 添加的提交
318 ${simpleClassName}Api.create${simpleClassName}(data).then(response => { 263 ${simpleClassName}Api.create${simpleClassName}(data).then(response => {
319 - this.#[[$modal]]#.msgSuccess("新增成功");  
320 - this.dialogVisible = false;  
321 - this.#[[$]]#emit('success'); 264 + that.#[[$modal]]#.msgSuccess("新增成功");
  265 + that.dialogVisible = false;
  266 + that.#[[$]]#emit('success');
322 }); 267 });
323 - });  
324 }finally { 268 }finally {
325 this.formLoading = false 269 this.formLoading = false
326 } 270 }
327 }, 271 },
328 - getRef(refName){  
329 - this.#[[$]]#refs[refName]  
330 - } 272 + getRef(refName){ // TODO puhui999: 获得表单 ref,提取出来的目的呢是解决 #[[$]]# 在 if 中 end闭合不了的问题,代码生成后可删除此方法
  273 + return this.#[[$]]#refs[refName]
  274 + },
  275 +## 特殊:主子表专属逻辑
  276 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  277 +#if ( $subTables && $subTables.size() > 0 )
  278 + /** 校验子表单 */
  279 + validateSubFrom(item) {
  280 + return new Promise((resolve, reject) => {
  281 + this.$refs[item].validate()
  282 + .then(() => {
  283 + resolve()
  284 + })
  285 + .catch(() => {
  286 + reject(item)
  287 + })
  288 + })
  289 + },
  290 + /** 校验所有子表单 */
  291 + validateSubFrom01() {
  292 + // 需要校验的表单 ref
  293 + const validFormRefArr = [
  294 + #foreach ($subTable in $subTables)
  295 + #set ($index = $foreach.count - 1)
  296 + #set ($subClassNameVar = $subClassNameVars.get($index))
  297 + "${subClassNameVar}FormRef",
  298 + #end
  299 + ];
  300 + const validArr = []; // 校验
  301 + for (const item of validFormRefArr) {
  302 + validArr.push(this.validateSubFrom(item))
  303 + }
  304 + return new Promise((resolve, reject) => {
  305 + // 校验所有
  306 + Promise.all(validArr).then(() => {
  307 + resolve()
  308 + }).catch((err) => {
  309 + reject(err)
  310 + })
  311 + })
  312 + },
  313 +#end
  314 +#end
  315 + ## 特殊:树表专属逻辑
  316 + #if ( $table.templateType == 2 )
  317 + /** 获得${table.classComment}树 */
  318 + get${simpleClassName}Tree() {
  319 + const that = this;
  320 + that.${classNameVar}Tree = [];
  321 + ${simpleClassName}Api.get${simpleClassName}List().then(res=>{
  322 + const root = { id: 0, name: '顶级${table.classComment}', children: [] };
  323 + root.children = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}')
  324 + that.${classNameVar}Tree.push(root)
  325 + });
  326 + },
  327 + #end
  328 + ## 特殊:树表专属逻辑
  329 + #if ( $table.templateType == 2 )
  330 + /** 转换${table.classComment}数据结构 */
  331 + normalizer(node) {
  332 + if (node.children && !node.children.length) {
  333 + delete node.children;
  334 + }
  335 + #if ($treeNameColumn.javaField == "name")
  336 + return {
  337 + id: node.id,
  338 + label: node.name,
  339 + children: node.children
  340 + };
  341 + #else
  342 + return {
  343 + id: node.id,
  344 + label: node['$treeNameColumn.javaField'],
  345 + children: node.children
  346 + };
  347 + #end
  348 + },
  349 + #end
  350 + /** 表单重置 */
  351 + reset() {
  352 + this.formData = {
  353 + #foreach ($column in $columns)
  354 + #if ($column.createOperation || $column.updateOperation)
  355 + #if ($column.htmlType == "checkbox")
  356 + $column.javaField: [],
  357 + #else
  358 + $column.javaField: undefined,
  359 + #end
  360 + #end
  361 + #end
  362 + };
  363 + this.resetForm("formRef");
  364 + },
331 } 365 }
332 }; 366 };
333 </script> 367 </script>
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/index.vue.vm
@@ -54,6 +54,7 @@ @@ -54,6 +54,7 @@
54 <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" 54 <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
55 v-hasPermi="['${permissionPrefix}:export']">导出</el-button> 55 v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
56 </el-col> 56 </el-col>
  57 + ## 特殊:树表专属逻辑
57 #if ( $table.templateType == 2 ) 58 #if ( $table.templateType == 2 )
58 <el-col :span="1.5"> 59 <el-col :span="1.5">
59 <el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll"> 60 <el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
@@ -64,7 +65,7 @@ @@ -64,7 +65,7 @@
64 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> 65 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
65 </el-row> 66 </el-row>
66 67
67 - ## 特殊:主子表专属逻辑 TODO puhui999: 普通模式 68 + ## 特殊:主子表专属逻辑
68 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 ) 69 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
69 <el-table 70 <el-table
70 v-loading="loading" 71 v-loading="loading"
@@ -89,7 +90,7 @@ @@ -89,7 +90,7 @@
89 #else 90 #else
90 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> 91 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
91 #end 92 #end
92 - ## 特殊:主子表专属逻辑 TODO puhui999: 内嵌模式 93 + ## 特殊:主子表专属逻辑
93 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 ) 94 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
94 <!-- 子表的列表 --> 95 <!-- 子表的列表 -->
95 <el-table-column type="expand"> 96 <el-table-column type="expand">
@@ -140,13 +141,15 @@ @@ -140,13 +141,15 @@
140 </template> 141 </template>
141 </el-table-column> 142 </el-table-column>
142 </el-table> 143 </el-table>
  144 +## 特殊:树表专属逻辑(树不需要分页)
  145 +#if ( $table.templateType != 2 )
143 <!-- 分页组件 --> 146 <!-- 分页组件 -->
144 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" 147 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
145 @pagination="getList"/> 148 @pagination="getList"/>
146 - 149 +#end
147 <!-- 对话框(添加 / 修改) --> 150 <!-- 对话框(添加 / 修改) -->
148 <${simpleClassName}Form ref="formRef" @success="getList" /> 151 <${simpleClassName}Form ref="formRef" @success="getList" />
149 - ## 特殊:主子表专属逻辑 TODO puhui999: ERP 模式 152 + ## 特殊:主子表专属逻辑
150 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 ) 153 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
151 <!-- 子表的列表 --> 154 <!-- 子表的列表 -->
152 <el-tabs model-value="$subClassNameVars.get(0)"> 155 <el-tabs model-value="$subClassNameVars.get(0)">
@@ -177,21 +180,25 @@ import FileUpload from &#39;@/components/FileUpload&#39;; @@ -177,21 +180,25 @@ import FileUpload from &#39;@/components/FileUpload&#39;;
177 import Editor from '@/components/Editor'; 180 import Editor from '@/components/Editor';
178 #end 181 #end
179 ## 特殊:主子表专属逻辑 182 ## 特殊:主子表专属逻辑
  183 +#if ( $table.templateType != 10 )
180 #if ( $subTables && $subTables.size() > 0 ) 184 #if ( $subTables && $subTables.size() > 0 )
181 #foreach ($subSimpleClassName in $subSimpleClassNames) 185 #foreach ($subSimpleClassName in $subSimpleClassNames)
182 import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue' 186 import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
183 #end 187 #end
184 #end 188 #end
  189 +#end
185 export default { 190 export default {
186 name: "${simpleClassName}", 191 name: "${simpleClassName}",
187 components: { 192 components: {
188 ${simpleClassName}Form, 193 ${simpleClassName}Form,
189 ## 特殊:主子表专属逻辑 194 ## 特殊:主子表专属逻辑
  195 +#if ( $table.templateType != 10 )
190 #if ( $subTables && $subTables.size() > 0 ) 196 #if ( $subTables && $subTables.size() > 0 )
191 #foreach ($subSimpleClassName in $subSimpleClassNames) 197 #foreach ($subSimpleClassName in $subSimpleClassNames)
192 ${subSimpleClassName}List, 198 ${subSimpleClassName}List,
193 #end 199 #end
194 #end 200 #end
  201 +#end
195 #if ($hasImageUploadColumn) 202 #if ($hasImageUploadColumn)
196 ImageUpload, 203 ImageUpload,
197 #end 204 #end
@@ -210,9 +217,9 @@ export default { @@ -210,9 +217,9 @@ export default {
210 exportLoading: false, 217 exportLoading: false,
211 // 显示搜索条件 218 // 显示搜索条件
212 showSearch: true, 219 showSearch: true,
213 - // 总条数  
214 ## 特殊:树表专属逻辑(树不需要分页接口) 220 ## 特殊:树表专属逻辑(树不需要分页接口)
215 #if ( $table.templateType != 2 ) 221 #if ( $table.templateType != 2 )
  222 + // 总条数
216 total: 0, 223 total: 0,
217 #end 224 #end
218 // ${table.classComment}列表 225 // ${table.classComment}列表
@@ -235,7 +242,7 @@ export default { @@ -235,7 +242,7 @@ export default {
235 #if ($column.listOperationCondition != 'BETWEEN') 242 #if ($column.listOperationCondition != 'BETWEEN')
236 $column.javaField: null, 243 $column.javaField: null,
237 #end 244 #end
238 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN") 245 + #if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
239 $column.javaField: [], 246 $column.javaField: [],
240 #end 247 #end
241 #end 248 #end
@@ -253,7 +260,7 @@ export default { @@ -253,7 +260,7 @@ export default {
253 this.loading = true; 260 this.loading = true;
254 ## 特殊:树表专属逻辑(树不需要分页接口) 261 ## 特殊:树表专属逻辑(树不需要分页接口)
255 #if ( $table.templateType == 2 ) 262 #if ( $table.templateType == 2 )
256 - ${simpleClassName}Api.get${simpleClassName}List(queryParams).then(response => { 263 + ${simpleClassName}Api.get${simpleClassName}List(this.queryParams).then(response => {
257 this.list = this.handleTree(response.data, 'id', '${treeParentColumn.javaField}'); 264 this.list = this.handleTree(response.data, 'id', '${treeParentColumn.javaField}');
258 }) 265 })
259 #else 266 #else
@@ -302,14 +309,14 @@ export default { @@ -302,14 +309,14 @@ export default {
302 return ${simpleClassName}Api.export${simpleClassName}Excel(params); 309 return ${simpleClassName}Api.export${simpleClassName}Excel(params);
303 }).then(response => { 310 }).then(response => {
304 that.#[[$]]#download.excel(response, '${table.classComment}.xls'); 311 that.#[[$]]#download.excel(response, '${table.classComment}.xls');
305 - })); 312 + });
306 } catch { 313 } catch {
307 } finally { 314 } finally {
308 that.exportLoading = false; 315 that.exportLoading = false;
309 } 316 }
310 }, 317 },
311 ## 特殊:主子表专属逻辑 318 ## 特殊:主子表专属逻辑
312 - #if ( $subTables && $subTables.size() > 0 ) 319 + #if ( $table.templateType == 11 )
313 /** 选中行操作 */ 320 /** 选中行操作 */
314 handleCurrentChange(row) { 321 handleCurrentChange(row) {
315 this.currentRow = row 322 this.currentRow = row
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/form.vue.vm
1 <template> 1 <template>
2 <Dialog :title="dialogTitle" v-model="dialogVisible"> 2 <Dialog :title="dialogTitle" v-model="dialogVisible">
3 <el-form 3 <el-form
4 - ref="formRef"  
5 - :model="formData"  
6 - :rules="formRules"  
7 - label-width="100px"  
8 - v-loading="formLoading" 4 + ref="formRef"
  5 + :model="formData"
  6 + :rules="formRules"
  7 + label-width="100px"
  8 + v-loading="formLoading"
9 > 9 >
10 -#foreach($column in $columns)  
11 - #if ($column.createOperation || $column.updateOperation)  
12 - #set ($dictType = $column.dictType)  
13 - #set ($javaField = $column.javaField)  
14 - #set ($javaType = $column.javaType)  
15 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
16 - #set ($comment = $column.columnComment)  
17 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
18 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
19 - #set ($dictMethod = "getIntDictOptions")  
20 - #elseif ($javaType == "String")  
21 - #set ($dictMethod = "getStrDictOptions")  
22 - #elseif ($javaType == "Boolean")  
23 - #set ($dictMethod = "getBoolDictOptions")  
24 - #end  
25 - #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )  
26 - <el-form-item label="${comment}" prop="${javaField}">  
27 - <el-tree-select  
28 - v-model="formData.${javaField}"  
29 - :data="${classNameVar}Tree"  
30 - #if ($treeNameColumn.javaField == "name")  
31 - :props="defaultProps"  
32 - #else  
33 - :props="{...defaultProps, label: '$treeNameColumn.javaField'}"  
34 - #end  
35 - check-strictly  
36 - default-expand-all  
37 - placeholder="请选择${comment}"  
38 - />  
39 - </el-form-item>  
40 - #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里  
41 - <el-form-item label="${comment}" prop="${javaField}">  
42 - <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />  
43 - </el-form-item>  
44 - #elseif($column.htmlType == "imageUpload")## 图片上传  
45 - <el-form-item label="${comment}" prop="${javaField}">  
46 - <UploadImg v-model="formData.${javaField}" />  
47 - </el-form-item>  
48 - #elseif($column.htmlType == "fileUpload")## 文件上传  
49 - <el-form-item label="${comment}" prop="${javaField}">  
50 - <UploadFile v-model="formData.${javaField}" />  
51 - </el-form-item>  
52 - #elseif($column.htmlType == "editor")## 文本编辑器  
53 - <el-form-item label="${comment}" prop="${javaField}">  
54 - <Editor v-model="formData.${javaField}" height="150px" />  
55 - </el-form-item>  
56 - #elseif($column.htmlType == "select")## 下拉框  
57 - <el-form-item label="${comment}" prop="${javaField}">  
58 - <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">  
59 - #if ("" != $dictType)## 有数据字典  
60 - <el-option  
61 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
62 - :key="dict.value"  
63 - :label="dict.label"  
64 - :value="dict.value"  
65 - />  
66 - #else##没数据字典  
67 - <el-option label="请选择字典生成" value="" /> 10 + #foreach($column in $columns)
  11 + #if ($column.createOperation || $column.updateOperation)
  12 + #set ($dictType = $column.dictType)
  13 + #set ($javaField = $column.javaField)
  14 + #set ($javaType = $column.javaType)
  15 + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  16 + #set ($comment = $column.columnComment)
  17 + #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
  18 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  19 + #set ($dictMethod = "getIntDictOptions")
  20 + #elseif ($javaType == "String")
  21 + #set ($dictMethod = "getStrDictOptions")
  22 + #elseif ($javaType == "Boolean")
  23 + #set ($dictMethod = "getBoolDictOptions")
68 #end 24 #end
69 - </el-select>  
70 - </el-form-item>  
71 - #elseif($column.htmlType == "checkbox")## 多选框  
72 - <el-form-item label="${comment}" prop="${javaField}">  
73 - <el-checkbox-group v-model="formData.${javaField}">  
74 - #if ("" != $dictType)## 有数据字典  
75 - <el-checkbox  
76 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
77 - :key="dict.value"  
78 - :label="dict.value"  
79 - >  
80 - {{ dict.label }}  
81 - </el-checkbox>  
82 - #else##没数据字典  
83 - <el-checkbox>请选择字典生成</el-checkbox> 25 + #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
  26 + <el-form-item label="${comment}" prop="${javaField}">
  27 + <el-tree-select
  28 + v-model="formData.${javaField}"
  29 + :data="${classNameVar}Tree"
  30 + #if ($treeNameColumn.javaField == "name")
  31 + :props="defaultProps"
  32 + #else
  33 + :props="{...defaultProps, label: '$treeNameColumn.javaField'}"
  34 + #end
  35 + check-strictly
  36 + default-expand-all
  37 + placeholder="请选择${comment}"
  38 + />
  39 + </el-form-item>
  40 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  41 + <el-form-item label="${comment}" prop="${javaField}">
  42 + <el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
  43 + </el-form-item>
  44 + #elseif($column.htmlType == "imageUpload")## 图片上传
  45 + <el-form-item label="${comment}" prop="${javaField}">
  46 + <UploadImg v-model="formData.${javaField}" />
  47 + </el-form-item>
  48 + #elseif($column.htmlType == "fileUpload")## 文件上传
  49 + <el-form-item label="${comment}" prop="${javaField}">
  50 + <UploadFile v-model="formData.${javaField}" />
  51 + </el-form-item>
  52 + #elseif($column.htmlType == "editor")## 文本编辑器
  53 + <el-form-item label="${comment}" prop="${javaField}">
  54 + <Editor v-model="formData.${javaField}" height="150px" />
  55 + </el-form-item>
  56 + #elseif($column.htmlType == "select")## 下拉框
  57 + <el-form-item label="${comment}" prop="${javaField}">
  58 + <el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
  59 + #if ("" != $dictType)## 有数据字典
  60 + <el-option
  61 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  62 + :key="dict.value"
  63 + :label="dict.label"
  64 + :value="dict.value"
  65 + />
  66 + #else##没数据字典
  67 + <el-option label="请选择字典生成" value="" />
  68 + #end
  69 + </el-select>
  70 + </el-form-item>
  71 + #elseif($column.htmlType == "checkbox")## 多选框
  72 + <el-form-item label="${comment}" prop="${javaField}">
  73 + <el-checkbox-group v-model="formData.${javaField}">
  74 + #if ("" != $dictType)## 有数据字典
  75 + <el-checkbox
  76 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  77 + :key="dict.value"
  78 + :label="dict.value"
  79 + >
  80 + {{ dict.label }}
  81 + </el-checkbox>
  82 + #else##没数据字典
  83 + <el-checkbox>请选择字典生成</el-checkbox>
  84 + #end
  85 + </el-checkbox-group>
  86 + </el-form-item>
  87 + #elseif($column.htmlType == "radio")## 单选框
  88 + <el-form-item label="${comment}" prop="${javaField}">
  89 + <el-radio-group v-model="formData.${javaField}">
  90 + #if ("" != $dictType)## 有数据字典
  91 + <el-radio
  92 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  93 + :key="dict.value"
  94 + :label="dict.value"
  95 + >
  96 + {{ dict.label }}
  97 + </el-radio>
  98 + #else##没数据字典
  99 + <el-radio label="1">请选择字典生成</el-radio>
  100 + #end
  101 + </el-radio-group>
  102 + </el-form-item>
  103 + #elseif($column.htmlType == "datetime")## 时间框
  104 + <el-form-item label="${comment}" prop="${javaField}">
  105 + <el-date-picker
  106 + v-model="formData.${javaField}"
  107 + type="date"
  108 + value-format="x"
  109 + placeholder="选择${comment}"
  110 + />
  111 + </el-form-item>
  112 + #elseif($column.htmlType == "textarea")## 文本框
  113 + <el-form-item label="${comment}" prop="${javaField}">
  114 + <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
  115 + </el-form-item>
84 #end 116 #end
85 - </el-checkbox-group>  
86 - </el-form-item>  
87 - #elseif($column.htmlType == "radio")## 单选框  
88 - <el-form-item label="${comment}" prop="${javaField}">  
89 - <el-radio-group v-model="formData.${javaField}">  
90 - #if ("" != $dictType)## 有数据字典  
91 - <el-radio  
92 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
93 - :key="dict.value"  
94 - :label="dict.value"  
95 - >  
96 - {{ dict.label }}  
97 - </el-radio>  
98 - #else##没数据字典  
99 - <el-radio label="1">请选择字典生成</el-radio>  
100 - #end  
101 - </el-radio-group>  
102 - </el-form-item>  
103 - #elseif($column.htmlType == "datetime")## 时间框  
104 - <el-form-item label="${comment}" prop="${javaField}">  
105 - <el-date-picker  
106 - v-model="formData.${javaField}"  
107 - type="date"  
108 - value-format="x"  
109 - placeholder="选择${comment}"  
110 - />  
111 - </el-form-item>  
112 - #elseif($column.htmlType == "textarea")## 文本框  
113 - <el-form-item label="${comment}" prop="${javaField}">  
114 - <el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />  
115 - </el-form-item> 117 + #end
116 #end 118 #end
117 - #end  
118 -#end  
119 </el-form> 119 </el-form>
120 -## 特殊:主子表专属逻辑  
121 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
122 - <!-- 子表的表单 -->  
123 - <el-tabs v-model="subTabsName">  
124 - #foreach ($subTable in $subTables)  
125 - #set ($index = $foreach.count - 1)  
126 - #set ($subClassNameVar = $subClassNameVars.get($index))  
127 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
128 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
129 - <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">  
130 - <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />  
131 - </el-tab-pane>  
132 - #end  
133 - </el-tabs>  
134 -#end 120 + ## 特殊:主子表专属逻辑
  121 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  122 + <!-- 子表的表单 -->
  123 + <el-tabs v-model="subTabsName">
  124 + #foreach ($subTable in $subTables)
  125 + #set ($index = $foreach.count - 1)
  126 + #set ($subClassNameVar = $subClassNameVars.get($index))
  127 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  128 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  129 + <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
  130 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
  131 + </el-tab-pane>
  132 + #end
  133 + </el-tabs>
  134 + #end
135 <template #footer> 135 <template #footer>
136 <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> 136 <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
137 <el-button @click="dialogVisible = false">取 消</el-button> 137 <el-button @click="dialogVisible = false">取 消</el-button>
@@ -139,160 +139,160 @@ @@ -139,160 +139,160 @@
139 </Dialog> 139 </Dialog>
140 </template> 140 </template>
141 <script setup lang="ts"> 141 <script setup lang="ts">
142 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
143 -import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'  
144 -## 特殊:树表专属逻辑  
145 -#if ( $table.templateType == 2 )  
146 -import { defaultProps, handleTree } from '@/utils/tree'  
147 -#end  
148 -## 特殊:主子表专属逻辑  
149 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
150 -#foreach ($subSimpleClassName in $subSimpleClassNames)  
151 -import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'  
152 -#end  
153 -#end 142 + import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
  143 + import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
  144 + ## 特殊:树表专属逻辑
  145 + #if ( $table.templateType == 2 )
  146 + import { defaultProps, handleTree } from '@/utils/tree'
  147 + #end
  148 + ## 特殊:主子表专属逻辑
  149 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  150 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  151 + import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
  152 + #end
  153 + #end
154 154
155 -const { t } = useI18n() // 国际化  
156 -const message = useMessage() // 消息弹窗 155 + const { t } = useI18n() // 国际化
  156 + const message = useMessage() // 消息弹窗
  157 +
  158 + const dialogVisible = ref(false) // 弹窗的是否展示
  159 + const dialogTitle = ref('') // 弹窗的标题
  160 + const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  161 + const formType = ref('') // 表单的类型:create - 新增;update - 修改
  162 + const formData = ref({
  163 + #foreach ($column in $columns)
  164 + #if ($column.createOperation || $column.updateOperation)
  165 + #if ($column.htmlType == "checkbox")
  166 + $column.javaField: [],
  167 + #else
  168 + $column.javaField: undefined,
  169 + #end
  170 + #end
  171 + #end
  172 + })
  173 + const formRules = reactive({
  174 + #foreach ($column in $columns)
  175 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  176 + #set($comment=$column.columnComment)
  177 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  178 + #end
  179 + #end
  180 + })
  181 + const formRef = ref() // 表单 Ref
  182 + ## 特殊:树表专属逻辑
  183 + #if ( $table.templateType == 2 )
  184 + const ${classNameVar}Tree = ref() // 树形结构
  185 + #end
  186 + ## 特殊:主子表专属逻辑
  187 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  188 + #if ( $subTables && $subTables.size() > 0 )
157 189
158 -const dialogVisible = ref(false) // 弹窗的是否展示  
159 -const dialogTitle = ref('') // 弹窗的标题  
160 -const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用  
161 -const formType = ref('') // 表单的类型:create - 新增;update - 修改  
162 -const formData = ref({  
163 -#foreach ($column in $columns)  
164 - #if ($column.createOperation || $column.updateOperation)  
165 - #if ($column.htmlType == "checkbox")  
166 - $column.javaField: [],  
167 - #else  
168 - $column.javaField: undefined, 190 + /** 子表的表单 */
  191 + const subTabsName = ref('$subClassNameVars.get(0)')
  192 + #foreach ($subClassNameVar in $subClassNameVars)
  193 + const ${subClassNameVar}FormRef = ref()
  194 + #end
  195 + #end
169 #end 196 #end
170 - #end  
171 -#end  
172 -})  
173 -const formRules = reactive({  
174 -#foreach ($column in $columns)  
175 - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键  
176 - #set($comment=$column.columnComment)  
177 - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],  
178 - #end  
179 -#end  
180 -})  
181 -const formRef = ref() // 表单 Ref  
182 -## 特殊:树表专属逻辑  
183 -#if ( $table.templateType == 2 )  
184 -const ${classNameVar}Tree = ref() // 树形结构  
185 -#end  
186 -## 特殊:主子表专属逻辑  
187 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
188 -#if ( $subTables && $subTables.size() > 0 )  
189 197
190 -/** 子表的表单 */  
191 -const subTabsName = ref('$subClassNameVars.get(0)')  
192 -#foreach ($subClassNameVar in $subClassNameVars)  
193 -const ${subClassNameVar}FormRef = ref()  
194 -#end  
195 -#end  
196 -#end 198 + /** 打开弹窗 */
  199 + const open = async (type: string, id?: number) => {
  200 + dialogVisible.value = true
  201 + dialogTitle.value = t('action.' + type)
  202 + formType.value = type
  203 + resetForm()
  204 + // 修改时,设置数据
  205 + if (id) {
  206 + formLoading.value = true
  207 + try {
  208 + formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
  209 + } finally {
  210 + formLoading.value = false
  211 + }
  212 + }
  213 + ## 特殊:树表专属逻辑
  214 + #if ( $table.templateType == 2 )
  215 + await get${simpleClassName}Tree()
  216 + #end
  217 + }
  218 + defineExpose({ open }) // 提供 open 方法,用于打开弹窗
197 219
198 -/** 打开弹窗 */  
199 -const open = async (type: string, id?: number) => {  
200 - dialogVisible.value = true  
201 - dialogTitle.value = t('action.' + type)  
202 - formType.value = type  
203 - resetForm()  
204 - // 修改时,设置数据  
205 - if (id) { 220 + /** 提交表单 */
  221 + const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  222 + const submitForm = async () => {
  223 + // 校验表单
  224 + await formRef.value.validate()
  225 + ## 特殊:主子表专属逻辑
  226 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  227 + #if ( $subTables && $subTables.size() > 0 )
  228 + // 校验子表单
  229 + #foreach ($subTable in $subTables)
  230 + #set ($index = $foreach.count - 1)
  231 + #set ($subClassNameVar = $subClassNameVars.get($index))
  232 + try {
  233 + await ${subClassNameVar}FormRef.value.validate()
  234 + } catch (e) {
  235 + subTabsName.value = '${subClassNameVar}'
  236 + return
  237 + }
  238 + #end
  239 + #end
  240 + #end
  241 + // 提交请求
206 formLoading.value = true 242 formLoading.value = true
207 try { 243 try {
208 - formData.value = await ${simpleClassName}Api.get${simpleClassName}(id) 244 + const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
  245 + ## 特殊:主子表专属逻辑
  246 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  247 + #if ( $subTables && $subTables.size() > 0 )
  248 + // 拼接子表的数据
  249 + #foreach ($subTable in $subTables)
  250 + #set ($index = $foreach.count - 1)
  251 + #set ($subClassNameVar = $subClassNameVars.get($index))
  252 + data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
  253 + #end
  254 + #end
  255 + #end
  256 + if (formType.value === 'create') {
  257 + await ${simpleClassName}Api.create${simpleClassName}(data)
  258 + message.success(t('common.createSuccess'))
  259 + } else {
  260 + await ${simpleClassName}Api.update${simpleClassName}(data)
  261 + message.success(t('common.updateSuccess'))
  262 + }
  263 + dialogVisible.value = false
  264 + // 发送操作成功的事件
  265 + emit('success')
209 } finally { 266 } finally {
210 formLoading.value = false 267 formLoading.value = false
211 } 268 }
212 } 269 }
213 -## 特殊:树表专属逻辑  
214 -#if ( $table.templateType == 2 )  
215 - await get${simpleClassName}Tree()  
216 -#end  
217 -}  
218 -defineExpose({ open }) // 提供 open 方法,用于打开弹窗  
219 270
220 -/** 提交表单 */  
221 -const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调  
222 -const submitForm = async () => {  
223 - // 校验表单  
224 - await formRef.value.validate()  
225 -## 特殊:主子表专属逻辑  
226 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
227 -#if ( $subTables && $subTables.size() > 0 )  
228 - // 校验子表单  
229 - #foreach ($subTable in $subTables)  
230 - #set ($index = $foreach.count - 1)  
231 - #set ($subClassNameVar = $subClassNameVars.get($index))  
232 - try {  
233 - await ${subClassNameVar}FormRef.value.validate()  
234 - } catch (e) {  
235 - subTabsName.value = '${subClassNameVar}'  
236 - return  
237 - }  
238 - #end  
239 -#end  
240 -#end  
241 - // 提交请求  
242 - formLoading.value = true  
243 - try {  
244 - const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO  
245 -## 特殊:主子表专属逻辑  
246 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
247 -#if ( $subTables && $subTables.size() > 0 )  
248 - // 拼接子表的数据  
249 - #foreach ($subTable in $subTables)  
250 - #set ($index = $foreach.count - 1)  
251 - #set ($subClassNameVar = $subClassNameVars.get($index))  
252 - data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()  
253 - #end  
254 -#end  
255 -#end  
256 - if (formType.value === 'create') {  
257 - await ${simpleClassName}Api.create${simpleClassName}(data)  
258 - message.success(t('common.createSuccess'))  
259 - } else {  
260 - await ${simpleClassName}Api.update${simpleClassName}(data)  
261 - message.success(t('common.updateSuccess')) 271 + /** 重置表单 */
  272 + const resetForm = () => {
  273 + formData.value = {
  274 + #foreach ($column in $columns)
  275 + #if ($column.createOperation || $column.updateOperation)
  276 + #if ($column.htmlType == "checkbox")
  277 + $column.javaField: [],
  278 + #else
  279 + $column.javaField: undefined,
  280 + #end
  281 + #end
  282 + #end
262 } 283 }
263 - dialogVisible.value = false  
264 - // 发送操作成功的事件  
265 - emit('success')  
266 - } finally {  
267 - formLoading.value = false 284 + formRef.value?.resetFields()
268 } 285 }
269 -} 286 + ## 特殊:树表专属逻辑
  287 + #if ( $table.templateType == 2 )
270 288
271 -/** 重置表单 */  
272 -const resetForm = () => {  
273 - formData.value = {  
274 -#foreach ($column in $columns)  
275 - #if ($column.createOperation || $column.updateOperation)  
276 - #if ($column.htmlType == "checkbox")  
277 - $column.javaField: [],  
278 - #else  
279 - $column.javaField: undefined, 289 + /** 获得${table.classComment}树 */
  290 + const get${simpleClassName}Tree = async () => {
  291 + ${classNameVar}Tree.value = []
  292 + const data = await ${simpleClassName}Api.get${simpleClassName}List()
  293 + const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
  294 + root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
  295 + ${classNameVar}Tree.value.push(root)
  296 + }
280 #end 297 #end
281 - #end  
282 -#end  
283 - }  
284 - formRef.value?.resetFields()  
285 -}  
286 -## 特殊:树表专属逻辑  
287 -#if ( $table.templateType == 2 )  
288 -  
289 -/** 获得${table.classComment}树 */  
290 -const get${simpleClassName}Tree = async () => {  
291 - ${classNameVar}Tree.value = []  
292 - const data = await ${simpleClassName}Api.get${simpleClassName}List()  
293 - const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }  
294 - root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')  
295 - ${classNameVar}Tree.value.push(root)  
296 -}  
297 -#end  
298 </script> 298 </script>
299 \ No newline at end of file 299 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
@@ -2,372 +2,375 @@ @@ -2,372 +2,375 @@
2 <ContentWrap> 2 <ContentWrap>
3 <!-- 搜索工作栏 --> 3 <!-- 搜索工作栏 -->
4 <el-form 4 <el-form
5 - class="-mb-15px"  
6 - :model="queryParams"  
7 - ref="queryFormRef"  
8 - :inline="true"  
9 - label-width="68px" 5 + class="-mb-15px"
  6 + :model="queryParams"
  7 + ref="queryFormRef"
  8 + :inline="true"
  9 + label-width="68px"
10 > 10 >
11 - #foreach($column in $columns)  
12 - #if ($column.listOperation)  
13 - #set ($dictType = $column.dictType)  
14 - #set ($javaField = $column.javaField)  
15 - #set ($javaType = $column.javaType)  
16 - #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
17 - #set ($comment = $column.columnComment)  
18 - #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法  
19 - #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")  
20 - #set ($dictMethod = "getIntDictOptions")  
21 - #elseif ($javaType == "String")  
22 - #set ($dictMethod = "getStrDictOptions")  
23 - #elseif ($javaType == "Boolean")  
24 - #set ($dictMethod = "getBoolDictOptions")  
25 - #end  
26 - #if ($column.htmlType == "input")  
27 - <el-form-item label="${comment}" prop="${javaField}">  
28 - <el-input  
29 - v-model="queryParams.${javaField}"  
30 - placeholder="请输入${comment}"  
31 - clearable  
32 - @keyup.enter="handleQuery"  
33 - class="!w-240px"  
34 - />  
35 - </el-form-item>  
36 - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")  
37 - <el-form-item label="${comment}" prop="${javaField}">  
38 - <el-select  
39 - v-model="queryParams.${javaField}"  
40 - placeholder="请选择${comment}"  
41 - clearable  
42 - class="!w-240px"  
43 - >  
44 - #if ("" != $dictType)## 设置了 dictType 数据字典的情况  
45 - <el-option  
46 - v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"  
47 - :key="dict.value"  
48 - :label="dict.label"  
49 - :value="dict.value"  
50 - />  
51 - #else## 未设置 dictType 数据字典的情况  
52 - <el-option label="请选择字典生成" value="" /> 11 + #foreach($column in $columns)
  12 + #if ($column.listOperation)
  13 + #set ($dictType = $column.dictType)
  14 + #set ($javaField = $column.javaField)
  15 + #set ($javaType = $column.javaType)
  16 + #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  17 + #set ($comment = $column.columnComment)
  18 + #set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
  19 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  20 + #set ($dictMethod = "getIntDictOptions")
  21 + #elseif ($javaType == "String")
  22 + #set ($dictMethod = "getStrDictOptions")
  23 + #elseif ($javaType == "Boolean")
  24 + #set ($dictMethod = "getBoolDictOptions")
53 #end 25 #end
54 - </el-select>  
55 - </el-form-item>  
56 - #elseif($column.htmlType == "datetime")  
57 - #if ($column.listOperationCondition != "BETWEEN")## 非范围  
58 - <el-form-item label="${comment}" prop="${javaField}">  
59 - <el-date-picker  
60 - v-model="queryParams.${javaField}"  
61 - value-format="YYYY-MM-DD"  
62 - type="date"  
63 - placeholder="选择${comment}"  
64 - clearable  
65 - class="!w-240px"  
66 - />  
67 - </el-form-item>  
68 - #else## 范围  
69 - <el-form-item label="${comment}" prop="${javaField}">  
70 - <el-date-picker  
71 - v-model="queryParams.${javaField}"  
72 - value-format="YYYY-MM-DD HH:mm:ss"  
73 - type="daterange"  
74 - start-placeholder="开始日期"  
75 - end-placeholder="结束日期"  
76 - :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"  
77 - class="!w-240px"  
78 - />  
79 - </el-form-item>  
80 - #end  
81 - #end  
82 - #end  
83 - #end 26 + #if ($column.htmlType == "input")
  27 + <el-form-item label="${comment}" prop="${javaField}">
  28 + <el-input
  29 + v-model="queryParams.${javaField}"
  30 + placeholder="请输入${comment}"
  31 + clearable
  32 + @keyup.enter="handleQuery"
  33 + class="!w-240px"
  34 + />
  35 + </el-form-item>
  36 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  37 + <el-form-item label="${comment}" prop="${javaField}">
  38 + <el-select
  39 + v-model="queryParams.${javaField}"
  40 + placeholder="请选择${comment}"
  41 + clearable
  42 + class="!w-240px"
  43 + >
  44 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  45 + <el-option
  46 + v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
  47 + :key="dict.value"
  48 + :label="dict.label"
  49 + :value="dict.value"
  50 + />
  51 + #else## 未设置 dictType 数据字典的情况
  52 + <el-option label="请选择字典生成" value="" />
  53 + #end
  54 + </el-select>
  55 + </el-form-item>
  56 + #elseif($column.htmlType == "datetime")
  57 + #if ($column.listOperationCondition != "BETWEEN")## 非范围
  58 + <el-form-item label="${comment}" prop="${javaField}">
  59 + <el-date-picker
  60 + v-model="queryParams.${javaField}"
  61 + value-format="YYYY-MM-DD"
  62 + type="date"
  63 + placeholder="选择${comment}"
  64 + clearable
  65 + class="!w-240px"
  66 + />
  67 + </el-form-item>
  68 + #else## 范围
  69 + <el-form-item label="${comment}" prop="${javaField}">
  70 + <el-date-picker
  71 + v-model="queryParams.${javaField}"
  72 + value-format="YYYY-MM-DD HH:mm:ss"
  73 + type="daterange"
  74 + start-placeholder="开始日期"
  75 + end-placeholder="结束日期"
  76 + :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  77 + class="!w-240px"
  78 + />
  79 + </el-form-item>
  80 + #end
  81 + #end
  82 + #end
  83 + #end
84 <el-form-item> 84 <el-form-item>
85 <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> 85 <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
86 <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> 86 <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
87 <el-button 87 <el-button
88 - type="primary"  
89 - plain  
90 - @click="openForm('create')"  
91 - v-hasPermi="['${permissionPrefix}:create']" 88 + type="primary"
  89 + plain
  90 + @click="openForm('create')"
  91 + v-hasPermi="['${permissionPrefix}:create']"
92 > 92 >
93 <Icon icon="ep:plus" class="mr-5px" /> 新增 93 <Icon icon="ep:plus" class="mr-5px" /> 新增
94 </el-button> 94 </el-button>
95 <el-button 95 <el-button
96 - type="success"  
97 - plain  
98 - @click="handleExport"  
99 - :loading="exportLoading"  
100 - v-hasPermi="['${permissionPrefix}:export']" 96 + type="success"
  97 + plain
  98 + @click="handleExport"
  99 + :loading="exportLoading"
  100 + v-hasPermi="['${permissionPrefix}:export']"
101 > 101 >
102 <Icon icon="ep:download" class="mr-5px" /> 导出 102 <Icon icon="ep:download" class="mr-5px" /> 导出
103 </el-button> 103 </el-button>
104 -## 特殊:树表专属逻辑  
105 -#if ( $table.templateType == 2 )  
106 - <el-button type="danger" plain @click="toggleExpandAll">  
107 - <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠  
108 - </el-button>  
109 -#end 104 + ## 特殊:树表专属逻辑
  105 + #if ( $table.templateType == 2 )
  106 + <el-button type="danger" plain @click="toggleExpandAll">
  107 + <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
  108 + </el-button>
  109 + #end
110 </el-form-item> 110 </el-form-item>
111 </el-form> 111 </el-form>
112 </ContentWrap> 112 </ContentWrap>
113 113
114 <!-- 列表 --> 114 <!-- 列表 -->
115 <ContentWrap> 115 <ContentWrap>
116 -## 特殊:主子表专属逻辑 TODO puhui999: 普通模式  
117 -#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )  
118 - <el-table  
119 - v-loading="loading"  
120 - :data="list"  
121 - :stripe="true"  
122 - :show-overflow-tooltip="true"  
123 - highlight-current-row  
124 - @current-change="handleCurrentChange"  
125 - >  
126 -## 特殊:树表专属逻辑  
127 -#elseif ( $table.templateType == 2 )  
128 - <el-table  
129 - v-loading="loading"  
130 - :data="list"  
131 - :stripe="true"  
132 - :show-overflow-tooltip="true"  
133 - row-key="id"  
134 - :default-expand-all="isExpandAll"  
135 - v-if="refreshTable"  
136 - >  
137 -#else  
138 - <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">  
139 -#end  
140 -## 特殊:主子表专属逻辑 TODO puhui999: 内嵌模式  
141 -#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )  
142 - <!-- 子表的列表 -->  
143 - <el-table-column type="expand">  
144 - <template #default="scope">  
145 - <el-tabs model-value="$subClassNameVars.get(0)">  
146 - #foreach ($subTable in $subTables)  
147 - #set ($index = $foreach.count - 1)  
148 - #set ($subClassNameVar = $subClassNameVars.get($index))  
149 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
150 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
151 - <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">  
152 - <${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />  
153 - </el-tab-pane>  
154 - #end  
155 - </el-tabs>  
156 - </template>  
157 - </el-table-column>  
158 -#end 116 + ## 特殊:主子表专属逻辑
  117 + #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
  118 + <el-table
  119 + v-loading="loading"
  120 + :data="list"
  121 + :stripe="true"
  122 + :show-overflow-tooltip="true"
  123 + highlight-current-row
  124 + @current-change="handleCurrentChange"
  125 + >
  126 + ## 特殊:树表专属逻辑
  127 + #elseif ( $table.templateType == 2 )
  128 + <el-table
  129 + v-loading="loading"
  130 + :data="list"
  131 + :stripe="true"
  132 + :show-overflow-tooltip="true"
  133 + row-key="id"
  134 + :default-expand-all="isExpandAll"
  135 + v-if="refreshTable"
  136 + >
  137 + #else
  138 + <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  139 + #end
  140 + ## 特殊:主子表专属逻辑
  141 + #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
  142 + <!-- 子表的列表 -->
  143 + <el-table-column type="expand">
  144 + <template #default="scope">
  145 + <el-tabs model-value="$subClassNameVars.get(0)">
  146 + #foreach ($subTable in $subTables)
  147 + #set ($index = $foreach.count - 1)
  148 + #set ($subClassNameVar = $subClassNameVars.get($index))
  149 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  150 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  151 + <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
  152 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
  153 + </el-tab-pane>
  154 + #end
  155 + </el-tabs>
  156 + </template>
  157 + </el-table-column>
  158 + #end
159 #foreach($column in $columns) 159 #foreach($column in $columns)
160 - #if ($column.listOperationResult)  
161 - #set ($dictType=$column.dictType)  
162 - #set ($javaField = $column.javaField)  
163 - #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})  
164 - #set ($comment=$column.columnComment)  
165 - #if ($column.javaType == "LocalDateTime")## 时间类型  
166 - <el-table-column  
167 - label="${comment}"  
168 - align="center"  
169 - prop="${javaField}"  
170 - :formatter="dateFormatter"  
171 - width="180px"  
172 - />  
173 - #elseif($column.dictType && "" != $column.dictType)## 数据字典  
174 - <el-table-column label="${comment}" align="center" prop="${javaField}">  
175 - <template #default="scope">  
176 - <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />  
177 - </template>  
178 - </el-table-column>  
179 - #else  
180 - <el-table-column label="${comment}" align="center" prop="${javaField}" />  
181 - #end 160 + #if ($column.listOperationResult)
  161 + #set ($dictType=$column.dictType)
  162 + #set ($javaField = $column.javaField)
  163 + #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  164 + #set ($comment=$column.columnComment)
  165 + #if ($column.javaType == "LocalDateTime")## 时间类型
  166 + <el-table-column
  167 + label="${comment}"
  168 + align="center"
  169 + prop="${javaField}"
  170 + :formatter="dateFormatter"
  171 + width="180px"
  172 + />
  173 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  174 + <el-table-column label="${comment}" align="center" prop="${javaField}">
  175 + <template #default="scope">
  176 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
  177 + </template>
  178 + </el-table-column>
  179 + #else
  180 + <el-table-column label="${comment}" align="center" prop="${javaField}" />
  181 + #end
  182 + #end
182 #end 183 #end
183 - #end  
184 - <el-table-column label="操作" align="center">  
185 - <template #default="scope">  
186 - <el-button 184 + <el-table-column label="操作" align="center">
  185 + <template #default="scope">
  186 + <el-button
187 link 187 link
188 type="primary" 188 type="primary"
189 @click="openForm('update', scope.row.id)" 189 @click="openForm('update', scope.row.id)"
190 v-hasPermi="['${permissionPrefix}:update']" 190 v-hasPermi="['${permissionPrefix}:update']"
191 - >  
192 - 编辑  
193 - </el-button>  
194 - <el-button 191 + >
  192 + 编辑
  193 + </el-button>
  194 + <el-button
195 link 195 link
196 type="danger" 196 type="danger"
197 @click="handleDelete(scope.row.id)" 197 @click="handleDelete(scope.row.id)"
198 v-hasPermi="['${permissionPrefix}:delete']" 198 v-hasPermi="['${permissionPrefix}:delete']"
199 - >  
200 - 删除  
201 - </el-button>  
202 - </template>  
203 - </el-table-column>  
204 - </el-table> 199 + >
  200 + 删除
  201 + </el-button>
  202 + </template>
  203 + </el-table-column>
  204 + </el-table>
  205 +## 特殊:树表专属逻辑(树不需要分页)
  206 +#if ( $table.templateType != 2 )
205 <!-- 分页 --> 207 <!-- 分页 -->
206 <Pagination 208 <Pagination
207 - :total="total"  
208 - v-model:page="queryParams.pageNo"  
209 - v-model:limit="queryParams.pageSize"  
210 - @pagination="getList" 209 + :total="total"
  210 + v-model:page="queryParams.pageNo"
  211 + v-model:limit="queryParams.pageSize"
  212 + @pagination="getList"
211 /> 213 />
  214 +#end
212 </ContentWrap> 215 </ContentWrap>
213 216
214 <!-- 表单弹窗:添加/修改 --> 217 <!-- 表单弹窗:添加/修改 -->
215 <${simpleClassName}Form ref="formRef" @success="getList" /> 218 <${simpleClassName}Form ref="formRef" @success="getList" />
216 -## 特殊:主子表专属逻辑 TODO puhui999: ERP 模式  
217 -#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )  
218 - <!-- 子表的列表 -->  
219 - <ContentWrap>  
220 - <el-tabs model-value="$subClassNameVars.get(0)">  
221 - #foreach ($subTable in $subTables)  
222 - #set ($index = $foreach.count - 1)  
223 - #set ($subClassNameVar = $subClassNameVars.get($index))  
224 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
225 - #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
226 - <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">  
227 - <${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />  
228 - </el-tab-pane>  
229 - #end  
230 - </el-tabs>  
231 - </ContentWrap>  
232 -#end 219 + ## 特殊:主子表专属逻辑
  220 + #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
  221 + <!-- 子表的列表 -->
  222 + <ContentWrap>
  223 + <el-tabs model-value="$subClassNameVars.get(0)">
  224 + #foreach ($subTable in $subTables)
  225 + #set ($index = $foreach.count - 1)
  226 + #set ($subClassNameVar = $subClassNameVars.get($index))
  227 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  228 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  229 + <el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
  230 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />
  231 + </el-tab-pane>
  232 + #end
  233 + </el-tabs>
  234 + </ContentWrap>
  235 + #end
233 </template> 236 </template>
234 237
235 <script setup lang="ts"> 238 <script setup lang="ts">
236 -import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'  
237 -import { dateFormatter } from '@/utils/formatTime'  
238 -## 特殊:树表专属逻辑  
239 -#if ( $table.templateType == 2 )  
240 -import { handleTree } from '@/utils/tree'  
241 -#end  
242 -import download from '@/utils/download'  
243 -import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'  
244 -import ${simpleClassName}Form from './${simpleClassName}Form.vue'  
245 -## 特殊:主子表专属逻辑  
246 -#if ( $subTables && $subTables.size() > 0 )  
247 -#foreach ($subSimpleClassName in $subSimpleClassNames)  
248 -import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'  
249 -#end  
250 -#end 239 + import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
  240 + import { dateFormatter } from '@/utils/formatTime'
  241 + ## 特殊:树表专属逻辑
  242 + #if ( $table.templateType == 2 )
  243 + import { handleTree } from '@/utils/tree'
  244 + #end
  245 + import download from '@/utils/download'
  246 + import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
  247 + import ${simpleClassName}Form from './${simpleClassName}Form.vue'
  248 + ## 特殊:主子表专属逻辑
  249 + #if ( $table.templateType != 10 )
  250 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  251 + import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
  252 + #end
  253 + #end
251 254
252 -defineOptions({ name: '${table.className}' }) 255 + defineOptions({ name: '${table.className}' })
253 256
254 -const message = useMessage() // 消息弹窗  
255 -const { t } = useI18n() // 国际化 257 + const message = useMessage() // 消息弹窗
  258 + const { t } = useI18n() // 国际化
256 259
257 -const loading = ref(true) // 列表的加载中  
258 -const list = ref([]) // 列表的数据  
259 -## 特殊:树表专属逻辑(树不需要分页接口)  
260 -#if ( $table.templateType != 2 )  
261 -const total = ref(0) // 列表的总页数  
262 -#end  
263 -const queryParams = reactive({  
264 -## 特殊:树表专属逻辑(树不需要分页接口)  
265 -#if ( $table.templateType != 2 )  
266 - pageNo: 1,  
267 - pageSize: 10,  
268 -#end  
269 - #foreach ($column in $columns)  
270 - #if ($column.listOperation)  
271 - #if ($column.listOperationCondition != 'BETWEEN')  
272 - $column.javaField: null,  
273 - #end  
274 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
275 - $column.javaField: [], 260 + const loading = ref(true) // 列表的加载中
  261 + const list = ref([]) // 列表的数据
  262 + ## 特殊:树表专属逻辑(树不需要分页接口)
  263 + #if ( $table.templateType != 2 )
  264 + const total = ref(0) // 列表的总页数
276 #end 265 #end
277 - #end  
278 - #end  
279 -})  
280 -const queryFormRef = ref() // 搜索的表单  
281 -const exportLoading = ref(false) // 导出的加载中 266 + const queryParams = reactive({
  267 + ## 特殊:树表专属逻辑(树不需要分页接口)
  268 + #if ( $table.templateType != 2 )
  269 + pageNo: 1,
  270 + pageSize: 10,
  271 + #end
  272 + #foreach ($column in $columns)
  273 + #if ($column.listOperation)
  274 + #if ($column.listOperationCondition != 'BETWEEN')
  275 + $column.javaField: null,
  276 + #end
  277 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  278 + $column.javaField: [],
  279 + #end
  280 + #end
  281 + #end
  282 + })
  283 + const queryFormRef = ref() // 搜索的表单
  284 + const exportLoading = ref(false) // 导出的加载中
282 285
283 -/** 查询列表 */  
284 -const getList = async () => {  
285 - loading.value = true  
286 - try {  
287 -## 特殊:树表专属逻辑(树不需要分页接口)  
288 - #if ( $table.templateType == 2 )  
289 - const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)  
290 - list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')  
291 - #else  
292 - const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)  
293 - list.value = data.list  
294 - total.value = data.total  
295 - #end  
296 - } finally {  
297 - loading.value = false 286 + /** 查询列表 */
  287 + const getList = async () => {
  288 + loading.value = true
  289 + try {
  290 + ## 特殊:树表专属逻辑(树不需要分页接口)
  291 + #if ( $table.templateType == 2 )
  292 + const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)
  293 + list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
  294 + #else
  295 + const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
  296 + list.value = data.list
  297 + total.value = data.total
  298 + #end
  299 + } finally {
  300 + loading.value = false
  301 + }
298 } 302 }
299 -}  
300 303
301 -/** 搜索按钮操作 */  
302 -const handleQuery = () => {  
303 - queryParams.pageNo = 1  
304 - getList()  
305 -} 304 + /** 搜索按钮操作 */
  305 + const handleQuery = () => {
  306 + queryParams.pageNo = 1
  307 + getList()
  308 + }
306 309
307 -/** 重置按钮操作 */  
308 -const resetQuery = () => {  
309 - queryFormRef.value.resetFields()  
310 - handleQuery()  
311 -} 310 + /** 重置按钮操作 */
  311 + const resetQuery = () => {
  312 + queryFormRef.value.resetFields()
  313 + handleQuery()
  314 + }
312 315
313 -/** 添加/修改操作 */  
314 -const formRef = ref()  
315 -const openForm = (type: string, id?: number) => {  
316 - formRef.value.open(type, id)  
317 -} 316 + /** 添加/修改操作 */
  317 + const formRef = ref()
  318 + const openForm = (type: string, id?: number) => {
  319 + formRef.value.open(type, id)
  320 + }
318 321
319 -/** 删除按钮操作 */  
320 -const handleDelete = async (id: number) => {  
321 - try {  
322 - // 删除的二次确认  
323 - await message.delConfirm()  
324 - // 发起删除  
325 - await ${simpleClassName}Api.delete${simpleClassName}(id)  
326 - message.success(t('common.delSuccess'))  
327 - // 刷新列表  
328 - await getList()  
329 - } catch {}  
330 -} 322 + /** 删除按钮操作 */
  323 + const handleDelete = async (id: number) => {
  324 + try {
  325 + // 删除的二次确认
  326 + await message.delConfirm()
  327 + // 发起删除
  328 + await ${simpleClassName}Api.delete${simpleClassName}(id)
  329 + message.success(t('common.delSuccess'))
  330 + // 刷新列表
  331 + await getList()
  332 + } catch {}
  333 + }
331 334
332 -/** 导出按钮操作 */  
333 -const handleExport = async () => {  
334 - try {  
335 - // 导出的二次确认  
336 - await message.exportConfirm()  
337 - // 发起导出  
338 - exportLoading.value = true  
339 - const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)  
340 - download.excel(data, '${table.classComment}.xls')  
341 - } catch {  
342 - } finally {  
343 - exportLoading.value = false 335 + /** 导出按钮操作 */
  336 + const handleExport = async () => {
  337 + try {
  338 + // 导出的二次确认
  339 + await message.exportConfirm()
  340 + // 发起导出
  341 + exportLoading.value = true
  342 + const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
  343 + download.excel(data, '${table.classComment}.xls')
  344 + } catch {
  345 + } finally {
  346 + exportLoading.value = false
  347 + }
344 } 348 }
345 -} 349 + ## 特殊:主子表专属逻辑
  350 + #if ( $table.templateType == 11 )
346 351
347 -## 特殊:主子表专属逻辑  
348 -#if ( $subTables && $subTables.size() > 0 )  
349 -/** 选中行操作 */  
350 -const currentRow = ref({}) // 选中行  
351 -const handleCurrentChange = (row) => {  
352 - currentRow.value = row  
353 -}  
354 -#end  
355 -## 特殊:树表专属逻辑  
356 -#if ( $table.templateType == 2 ) 352 + /** 选中行操作 */
  353 + const currentRow = ref({}) // 选中行
  354 + const handleCurrentChange = (row) => {
  355 + currentRow.value = row
  356 + }
  357 + #end
  358 + ## 特殊:树表专属逻辑
  359 + #if ( $table.templateType == 2 )
357 360
358 -/** 展开/折叠操作 */  
359 -const isExpandAll = ref(true) // 是否展开,默认全部展开  
360 -const refreshTable = ref(true) // 重新渲染表格状态  
361 -const toggleExpandAll = async () => {  
362 - refreshTable.value = false  
363 - isExpandAll.value = !isExpandAll.value  
364 - await nextTick()  
365 - refreshTable.value = true  
366 -}  
367 -#end 361 + /** 展开/折叠操作 */
  362 + const isExpandAll = ref(true) // 是否展开,默认全部展开
  363 + const refreshTable = ref(true) // 重新渲染表格状态
  364 + const toggleExpandAll = async () => {
  365 + refreshTable.value = false
  366 + isExpandAll.value = !isExpandAll.value
  367 + await nextTick()
  368 + refreshTable.value = true
  369 + }
  370 + #end
368 371
369 -/** 初始化 **/  
370 -onMounted(() => {  
371 - getList()  
372 -}) 372 + /** 初始化 **/
  373 + onMounted(() => {
  374 + getList()
  375 + })
373 </script> 376 </script>
374 \ No newline at end of file 377 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineVue2Test.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.codegen.inner;
  2 +
  3 +import cn.hutool.core.io.FileUtil;
  4 +import cn.hutool.core.io.IoUtil;
  5 +import cn.hutool.core.io.resource.ResourceUtil;
  6 +import cn.hutool.core.map.MapUtil;
  7 +import cn.hutool.core.util.StrUtil;
  8 +import cn.hutool.core.util.ZipUtil;
  9 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
  12 +import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
  13 +import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
  14 +import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
  15 +import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
  16 +import org.junit.jupiter.api.BeforeEach;
  17 +import org.junit.jupiter.api.Test;
  18 +import org.mockito.InjectMocks;
  19 +import org.mockito.Spy;
  20 +
  21 +import java.io.ByteArrayInputStream;
  22 +import java.io.ByteArrayOutputStream;
  23 +import java.util.*;
  24 +
  25 +import static org.junit.jupiter.api.Assertions.assertEquals;
  26 +
  27 +/**
  28 + * {@link CodegenEngine} 的单元测试
  29 + *
  30 + * @author 芋道源码
  31 + */
  32 +public class CodegenEngineVue2Test extends BaseMockitoUnitTest {
  33 +
  34 + @InjectMocks
  35 + private CodegenEngine codegenEngine;
  36 +
  37 + @Spy
  38 + private CodegenProperties codegenProperties = new CodegenProperties()
  39 + .setBasePackage("cn.iocoder.yudao");
  40 +
  41 + @BeforeEach
  42 + public void setUp() {
  43 + codegenEngine.initGlobalBindingMap();
  44 + }
  45 +
  46 + @Test
  47 + public void testExecute_vue2_one() {
  48 + // 准备参数
  49 + CodegenTableDO table = getTable("student")
  50 + .setFrontType(CodegenFrontTypeEnum.VUE2.getType())
  51 + .setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
  52 + List<CodegenColumnDO> columns = getColumnList("student");
  53 +
  54 + // 调用
  55 + Map<String, String> result = codegenEngine.execute(table, columns, null, null);
  56 + // 断言
  57 + assertResult(result, "codegen/vue2_one");
  58 +// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_one");
  59 + }
  60 +
  61 + @Test
  62 + public void testExecute_vue2_tree() {
  63 + // 准备参数
  64 + CodegenTableDO table = getTable("category")
  65 + .setFrontType(CodegenFrontTypeEnum.VUE2.getType())
  66 + .setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
  67 + List<CodegenColumnDO> columns = getColumnList("category");
  68 +
  69 + // 调用
  70 + Map<String, String> result = codegenEngine.execute(table, columns, null, null);
  71 + // 断言
  72 + assertResult(result, "codegen/vue2_tree");
  73 +// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue2_tree");
  74 +// writeFile(result, "/Users/yunai/test/demo66.zip");
  75 + }
  76 +
  77 + @Test
  78 + public void testExecute_vue2_master_normal() {
  79 + testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue2_master_normal");
  80 + }
  81 +
  82 + @Test
  83 + public void testExecute_vue2_master_erp() {
  84 + testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue2_master_erp");
  85 + }
  86 +
  87 + @Test
  88 + public void testExecute_vue2_master_inner() {
  89 + testExecute_vue2_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue2_master_inner");
  90 + }
  91 +
  92 + private void testExecute_vue2_master(CodegenTemplateTypeEnum templateType,
  93 + String path) {
  94 + // 准备参数
  95 + CodegenTableDO table = getTable("student")
  96 + .setFrontType(CodegenFrontTypeEnum.VUE2.getType())
  97 + .setTemplateType(templateType.getType());
  98 + List<CodegenColumnDO> columns = getColumnList("student");
  99 + // 准备参数(子表)
  100 + CodegenTableDO contactTable = getTable("contact")
  101 + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
  102 + .setFrontType(CodegenFrontTypeEnum.VUE2.getType())
  103 + .setSubJoinColumnId(100L).setSubJoinMany(true);
  104 + List<CodegenColumnDO> contactColumns = getColumnList("contact");
  105 + // 准备参数(班主任)
  106 + CodegenTableDO teacherTable = getTable("teacher")
  107 + .setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
  108 + .setFrontType(CodegenFrontTypeEnum.VUE2.getType())
  109 + .setSubJoinColumnId(200L).setSubJoinMany(false);
  110 + List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
  111 +
  112 + // 调用
  113 + Map<String, String> result = codegenEngine.execute(table, columns,
  114 + Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
  115 + // 断言
  116 + assertResult(result, path);
  117 +// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
  118 +// writeFile(result, "/Users/yunai/test/demo11.zip");
  119 + }
  120 +
  121 + private static CodegenTableDO getTable(String name) {
  122 + String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
  123 + return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
  124 + }
  125 +
  126 + private static List<CodegenColumnDO> getColumnList(String name) {
  127 + String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
  128 + List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
  129 + list.forEach(column -> {
  130 + if (column.getNullable() == null) {
  131 + column.setNullable(false);
  132 + }
  133 + if (column.getCreateOperation() == null) {
  134 + column.setCreateOperation(false);
  135 + }
  136 + if (column.getUpdateOperation() == null) {
  137 + column.setUpdateOperation(false);
  138 + }
  139 + if (column.getListOperation() == null) {
  140 + column.setListOperation(false);
  141 + }
  142 + if (column.getListOperationResult() == null) {
  143 + column.setListOperationResult(false);
  144 + }
  145 + });
  146 + return list;
  147 + }
  148 +
  149 + @SuppressWarnings("rawtypes")
  150 + private static void assertResult(Map<String, String> result, String path) {
  151 + String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
  152 + List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
  153 + assertEquals(asserts.size(), result.size());
  154 + // 校验每个文件
  155 + asserts.forEach(assertMap -> {
  156 + String contentPath = (String) assertMap.get("contentPath");
  157 + String filePath = (String) assertMap.get("filePath");
  158 + String content = ResourceUtil.readUtf8Str(path + "/" + contentPath);
  159 + assertEquals(content, result.get(filePath), filePath + ":不匹配");
  160 + });
  161 + }
  162 +
  163 + // ==================== 调试专用 ====================
  164 +
  165 + /**
  166 + * 【调试使用】将生成的代码,写入到文件
  167 + *
  168 + * @param result 生成的代码
  169 + * @param path 写入文件的路径
  170 + */
  171 + private void writeFile(Map<String, String> result, String path) {
  172 + // 生成压缩包
  173 + String[] paths = result.keySet().toArray(new String[0]);
  174 + ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
  175 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  176 + ZipUtil.zip(outputStream, paths, ins);
  177 + // 写入文件
  178 + FileUtil.writeBytes(outputStream.toByteArray(), path);
  179 + }
  180 +
  181 + /**
  182 + * 【调试使用】将生成的结果,写入到文件
  183 + *
  184 + * @param result 生成的代码
  185 + * @param basePath 写入文件的路径(绝对路径)
  186 + */
  187 + private void writeResult(Map<String, String> result, String basePath) {
  188 + // 写入文件内容
  189 + List<Map<String, String>> asserts = new ArrayList<>();
  190 + result.forEach((filePath, fileContent) -> {
  191 + String lastFilePath = StrUtil.subAfter(filePath, '/', true);
  192 + String contentPath = StrUtil.subAfter(lastFilePath, '.', true)
  193 + + '/' + StrUtil.subBefore(lastFilePath, '.', true);
  194 + asserts.add(MapUtil.<String, String>builder().put("filePath", filePath)
  195 + .put("contentPath", contentPath).build());
  196 + FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
  197 + });
  198 + // 写入 assert.json 文件
  199 + FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json");
  200 + }
  201 +
  202 +}