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 104 vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
105 105 .put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"),
106 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 119 // Vue3 标准模版
108 120 .put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"),
109 121 vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
... ... @@ -452,7 +464,7 @@ public class CodegenEngine {
452 464 }
453 465  
454 466 private static String vueFilePath(String path) {
455   - return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
  467 + return "yudao-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
456 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 4 <template>
5 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 9 #foreach($column in $subColumns)
10 10 #if ($column.createOperation || $column.updateOperation)
11 11 #set ($dictType = $column.dictType)
... ... @@ -13,30 +13,29 @@
13 13 #set ($javaType = $column.javaType)
14 14 #set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
15 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 21 #elseif($column.htmlType == "imageUpload")## 图片上传
23 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 25 </el-form-item>
27 26 #elseif($column.htmlType == "fileUpload")## 文件上传
28 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 30 </el-form-item>
32 31 #elseif($column.htmlType == "editor")## 文本编辑器
33 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 35 </el-form-item>
37 36 #elseif($column.htmlType == "select")## 下拉框
38 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 39 #if ("" != $dictType)## 有数据字典
41 40 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
42 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 46 </el-form-item>
48 47 #elseif($column.htmlType == "checkbox")## 多选框
49 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 50 #if ("" != $dictType)## 有数据字典
52 51 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
53 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 57 </el-form-item>
59 58 #elseif($column.htmlType == "radio")## 单选框
60 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 61 #if ("" != $dictType)## 有数据字典
63 62 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
64 63 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
... ... @@ -70,11 +69,11 @@
70 69 </el-form-item>
71 70 #elseif($column.htmlType == "datetime")## 时间框
72 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 73 </el-form-item>
75 74 #elseif($column.htmlType == "textarea")## 文本框
76 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 77 </el-form-item>
79 78 #end
80 79 #end
... ... @@ -100,7 +99,7 @@
100 99 import Editor from '@/components/Editor';
101 100 #end
102 101 export default {
103   - name: "${simpleClassName}",
  102 + name: "${subSimpleClassName}Form",
104 103 components: {
105 104 #if ($hasImageUploadColumn)
106 105 ImageUpload,
... ... @@ -122,7 +121,7 @@
122 121 formLoading: false,
123 122 // 表单参数
124 123 formData: {
125   - #foreach ($column in $columns)
  124 + #foreach ($column in $subColumns)
126 125 #if ($column.createOperation || $column.updateOperation)
127 126 #if ($column.htmlType == "checkbox")
128 127 $column.javaField: [],
... ... @@ -134,7 +133,7 @@
134 133 },
135 134 // 表单校验
136 135 formRules: {
137   - #foreach ($column in $columns)
  136 + #foreach ($column in $subColumns)
138 137 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
139 138 #set($comment=$column.columnComment)
140 139 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
... ... @@ -144,39 +143,25 @@
144 143 };
145 144 },
146 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 148 this.dialogVisible = true;
165 149 this.reset();
166 150 const that = this;
  151 + this.formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField};
167 152 // 修改时,设置数据
168 153 if (id) {
169 154 this.formLoading = true;
170 155 try {
171 156 ${simpleClassName}Api.get${subSimpleClassName}(id).then(res=>{
172 157 that.formData = res.data;
173   - that.title = "修改${table.classComment}";
  158 + that.dialogTitle = "修改${table.classComment}";
174 159 })
175 160 } finally {
176 161 this.formLoading = false;
177 162 }
178 163 }
179   - this.title = "新增${table.classComment}";
  164 + this.dialogTitle = "新增${table.classComment}";
180 165 },
181 166 /** 提交按钮 */
182 167 submitForm() {
... ... @@ -189,7 +174,7 @@
189 174 }
190 175 // 修改的提交
191 176 if (data.${primaryColumn.javaField}) {
192   - ${simpleClassName}Api.update${simpleClassName}(data).then(response => {
  177 + ${simpleClassName}Api.update${subSimpleClassName}(data).then(response => {
193 178 this.#[[$modal]]#.msgSuccess("修改成功");
194 179 this.dialogVisible = false;
195 180 this.#[[$]]#emit('success');
... ... @@ -197,7 +182,7 @@
197 182 return;
198 183 }
199 184 // 添加的提交
200   - ${simpleClassName}Api.create${simpleClassName}(data).then(response => {
  185 + ${simpleClassName}Api.create${subSimpleClassName}(data).then(response => {
201 186 this.#[[$modal]]#.msgSuccess("新增成功");
202 187 this.dialogVisible = false;
203 188 this.#[[$]]#emit('success');
... ... @@ -206,7 +191,22 @@
206 191 }finally {
207 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 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 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
6 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7   -
8 7 <template>
9   - <div class="app-container">
10   -#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
  8 + #if ( $subTable.subJoinMany )## 情况一:一对多,table + form
11 9 <el-form
12 10 ref="formRef"
13 11 :model="formData"
... ... @@ -16,7 +14,6 @@
16 14 label-width="0px"
17 15 :inline-message="true"
18 16 >
19   -## // TODO puhui999: 看看样式是否需要调整
20 17 <el-table :data="formData" class="-mt-10px">
21 18 <el-table-column label="序号" type="index" width="100" />
22 19 #foreach($column in $subColumns)
... ... @@ -29,7 +26,7 @@
29 26 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
30 27 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
31 28 <el-table-column label="${comment}" min-width="150">
32   - <template slot-scope="{ row, $index }">
  29 + <template v-slot="{ row, $index }">
33 30 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
34 31 <el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
35 32 </el-form-item>
... ... @@ -38,7 +35,7 @@
38 35 #elseif($column.htmlType == "imageUpload")## 图片上传
39 36 #set ($hasImageUploadColumn = true)
40 37 <el-table-column label="${comment}" min-width="200">
41   - <template slot-scope="{ row, $index }">
  38 + <template v-slot="{ row, $index }">
42 39 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
43 40 <ImageUpload v-model="row.${javaField}"/>
44 41 </el-form-item>
... ... @@ -47,7 +44,7 @@
47 44 #elseif($column.htmlType == "fileUpload")## 文件上传
48 45 #set ($hasFileUploadColumn = true)
49 46 <el-table-column label="${comment}" min-width="200">
50   - <template slot-scope="{ row, $index }">
  47 + <template v-slot="{ row, $index }">
51 48 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
52 49 <FileUpload v-model="row.${javaField}"/>
53 50 </el-form-item>
... ... @@ -56,15 +53,15 @@
56 53 #elseif($column.htmlType == "editor")## 文本编辑器
57 54 #set ($hasEditorColumn = true)
58 55 <el-table-column label="${comment}" min-width="400">
59   - <template slot-scope="{ row, $index }">
  56 + <template v-slot="{ row, $index }">
60 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 59 </el-form-item>
63 60 </template>
64 61 </el-table-column>
65 62 #elseif($column.htmlType == "select")## 下拉框
66 63 <el-table-column label="${comment}" min-width="150">
67   - <template slot-scope="{ row, $index }">
  64 + <template v-slot="{ row, $index }">
68 65 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
69 66 <el-select v-model="row.${javaField}" placeholder="请选择${comment}">
70 67 #if ("" != $dictType)## 有数据字典
... ... @@ -79,7 +76,7 @@
79 76 </el-table-column>
80 77 #elseif($column.htmlType == "checkbox")## 多选框
81 78 <el-table-column label="${comment}" min-width="150">
82   - <template slot-scope="{ row, $index }">
  79 + <template v-slot="{ row, $index }">
83 80 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
84 81 <el-checkbox-group v-model="row.${javaField}">
85 82 #if ("" != $dictType)## 有数据字典
... ... @@ -94,7 +91,7 @@
94 91 </el-table-column>
95 92 #elseif($column.htmlType == "radio")## 单选框
96 93 <el-table-column label="${comment}" min-width="150">
97   - <template slot-scope="{ row, $index }">
  94 + <template v-slot="{ row, $index }">
98 95 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
99 96 <el-radio-group v-model="row.${javaField}">
100 97 #if ("" != $dictType)## 有数据字典
... ... @@ -110,20 +107,15 @@
110 107 </el-table-column>
111 108 #elseif($column.htmlType == "datetime")## 时间框
112 109 <el-table-column label="${comment}" min-width="150">
113   - <template slot-scope="{ row, $index }">
  110 + <template v-slot="{ row, $index }">
114 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 113 </el-form-item>
122 114 </template>
123 115 </el-table-column>
124 116 #elseif($column.htmlType == "textarea")## 文本框
125 117 <el-table-column label="${comment}" min-width="200">
126   - <template slot-scope="{ row, $index }">
  118 + <template v-slot="{ row, $index }">
127 119 <el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
128 120 <el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
129 121 </el-form-item>
... ... @@ -133,17 +125,97 @@
133 125 #end
134 126 #end
135 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 130 </template>
139 131 </el-table-column>
140 132 </el-table>
141 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 219 </template>
148 220  
149 221 <script>
... ... @@ -158,7 +230,7 @@
158 230 import Editor from '@/components/Editor';
159 231 #end
160 232 export default {
161   - name: "${simpleClassName}",
  233 + name: "${subSimpleClassName}Form",
162 234 components: {
163 235 #if ($hasImageUploadColumn)
164 236 ImageUpload,
... ... @@ -170,29 +242,18 @@
170 242 Editor,
171 243 #end
172 244 },
  245 + props:[
  246 + '${subJoinColumn.javaField}'
  247 + ],// ${subJoinColumn.columnComment}(主表的关联字段)
173 248 data() {
174 249 return {
175   - // 弹出层标题
176   - dialogTitle: "",
177   - // 是否显示弹出层
178   - dialogVisible: false,
179 250 // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
180 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 255 formRules: {
195   - #foreach ($column in $columns)
  256 + #foreach ($column in $subColumns)
196 257 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
197 258 #set($comment=$column.columnComment)
198 259 $column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
... ... @@ -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 311 methods: {
208 312 #if ( $subTable.subJoinMany )
209   -
210 313 /** 新增按钮操作 */
211   - handleAdd(){
  314 + handleAdd() {
212 315 const row = {
213 316 #foreach ($column in $subColumns)
214 317 #if ($column.createOperation || $column.updateOperation)
... ... @@ -223,19 +326,18 @@
223 326 row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField}
224 327 this.formData.push(row)
225 328 },
226   -
227 329 /** 删除按钮操作 */
228   - handleDelete(index) {
  330 + handleDelete(index) {
229 331 this.formData.splice(index, 1)
230 332 },
231 333 #end
  334 + /** 表单校验 */
  335 + validate(){
  336 + return this.#[[$]]#refs["formRef"].validate()
  337 + },
232 338 /** 表单值 */
233   - getData() {
  339 + getData(){
234 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 1 <template>
8   - <!-- 列表 -->
9   - <ContentWrap>
  2 + <div class="app-container">
10 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 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 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 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 53 #end
  54 + </div>
84 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 61 #end
  62 + export default {
  63 + name: "${subSimpleClassName}List",
  64 +#if ($table.templateType == 11)
  65 + components: {
  66 + ${subSimpleClassName}Form
  67 + },
138 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 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 87 #end
  88 + };
  89 + },
174 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 162 #end
181   -</script>
182 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 1 <template>
2 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 6 #foreach($column in $columns)
7 7 #if ($column.createOperation || $column.updateOperation)
8 8 #set ($dictType = $column.dictType)
... ... @@ -11,37 +11,35 @@
11 11 #set ($comment = $column.columnComment)
12 12 #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
13 13 <el-form-item label="${comment}" prop="${javaField}">
14   - <treeselect
  14 + <TreeSelect
15 15 v-model="formData.${javaField}"
16 16 :options="${classNameVar}Tree"
17 17 :normalizer="normalizer"
18 18 placeholder="请选择${comment}"
19 19 />
20 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 25 #elseif($column.htmlType == "imageUpload")## 图片上传
28 26 #set ($hasImageUploadColumn = true)
29 27 <el-form-item label="${comment}">
30   - <imageUpload v-model="form.${javaField}"/>
  28 + <ImageUpload v-model="formData.${javaField}"/>
31 29 </el-form-item>
32 30 #elseif($column.htmlType == "fileUpload")## 文件上传
33 31 #set ($hasFileUploadColumn = true)
34 32 <el-form-item label="${comment}">
35   - <fileUpload v-model="form.${javaField}"/>
  33 + <FileUpload v-model="formData.${javaField}"/>
36 34 </el-form-item>
37 35 #elseif($column.htmlType == "editor")## 文本编辑器
38 36 #set ($hasEditorColumn = true)
39 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 39 </el-form-item>
42 40 #elseif($column.htmlType == "select")## 下拉框
43 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 43 #if ("" != $dictType)## 有数据字典
46 44 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
47 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 50 </el-form-item>
53 51 #elseif($column.htmlType == "checkbox")## 多选框
54 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 54 #if ("" != $dictType)## 有数据字典
57 55 <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
58 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 61 </el-form-item>
64 62 #elseif($column.htmlType == "radio")## 单选框
65 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 65 #if ("" != $dictType)## 有数据字典
68 66 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
69 67 :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
... ... @@ -75,18 +73,18 @@
75 73 </el-form-item>
76 74 #elseif($column.htmlType == "datetime")## 时间框
77 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 77 </el-form-item>
80 78 #elseif($column.htmlType == "textarea")## 文本框
81 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 81 </el-form-item>
84 82 #end
85 83 #end
86 84 #end
87 85 </el-form>
88 86 ## 特殊:主子表专属逻辑
89   - #if ( $subTables && $subTables.size() > 0 )
  87 + #if ( $table.templateType == 10 || $table.templateType == 12 )
90 88 <!-- 子表的表单 -->
91 89 <el-tabs v-model="subTabsName">
92 90 #foreach ($subTable in $subTables)
... ... @@ -121,17 +119,17 @@
121 119 #end
122 120 ## 特殊:树表专属逻辑
123 121 #if ( $table.templateType == 2 )
124   - import Treeselect from "@riophae/vue-treeselect";
  122 + import TreeSelect from "@riophae/vue-treeselect";
125 123 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
126 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 130 #end
133 131 export default {
134   - name: "${simpleClassName}",
  132 + name: "${simpleClassName}Form",
135 133 components: {
136 134 #if ($hasImageUploadColumn)
137 135 ImageUpload,
... ... @@ -144,13 +142,13 @@
144 142 #end
145 143 ## 特殊:树表专属逻辑
146 144 #if ( $table.templateType == 2 )
147   - Treeselect,
  145 + TreeSelect,
148 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 152 #end
155 153 },
156 154 data() {
... ... @@ -178,7 +176,7 @@
178 176 #foreach ($column in $columns)
179 177 #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
180 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 180 #end
183 181 #end
184 182 },
... ... @@ -186,43 +184,16 @@
186 184 #if ( $table.templateType == 2 )
187 185 ${classNameVar}Tree: [], // 树形结构
188 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 191 subTabsName: '$subClassNameVars.get(0)'
193   - #end
  192 + #end
  193 + #end
194 194 };
195 195 },
196 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 198 open(id) {
228 199 this.dialogVisible = true;
... ... @@ -246,88 +217,151 @@
246 217 this.get${simpleClassName}Tree()
247 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 221 submitForm() {
265 222 this.formLoading = true;
266 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 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 238 #foreach ($subTable in $subTables)
295 239 #set ($index = $foreach.count - 1)
296 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 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 251 return;
307 252 }
308 253 // 修改的提交
309 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 260 return;
316 261 }
317 262 // 添加的提交
318 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 268 }finally {
325 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 367 </script>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/views/index.vue.vm
... ... @@ -54,6 +54,7 @@
54 54 <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
55 55 v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
56 56 </el-col>
  57 + ## 特殊:树表专属逻辑
57 58 #if ( $table.templateType == 2 )
58 59 <el-col :span="1.5">
59 60 <el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
... ... @@ -64,7 +65,7 @@
64 65 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
65 66 </el-row>
66 67  
67   - ## 特殊:主子表专属逻辑 TODO puhui999: 普通模式
  68 + ## 特殊:主子表专属逻辑
68 69 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
69 70 <el-table
70 71 v-loading="loading"
... ... @@ -89,7 +90,7 @@
89 90 #else
90 91 <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
91 92 #end
92   - ## 特殊:主子表专属逻辑 TODO puhui999: 内嵌模式
  93 + ## 特殊:主子表专属逻辑
93 94 #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
94 95 <!-- 子表的列表 -->
95 96 <el-table-column type="expand">
... ... @@ -140,13 +141,15 @@
140 141 </template>
141 142 </el-table-column>
142 143 </el-table>
  144 +## 特殊:树表专属逻辑(树不需要分页)
  145 +#if ( $table.templateType != 2 )
143 146 <!-- 分页组件 -->
144 147 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
145 148 @pagination="getList"/>
146   -
  149 +#end
147 150 <!-- 对话框(添加 / 修改) -->
148 151 <${simpleClassName}Form ref="formRef" @success="getList" />
149   - ## 特殊:主子表专属逻辑 TODO puhui999: ERP 模式
  152 + ## 特殊:主子表专属逻辑
150 153 #if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
151 154 <!-- 子表的列表 -->
152 155 <el-tabs model-value="$subClassNameVars.get(0)">
... ... @@ -177,21 +180,25 @@ import FileUpload from &#39;@/components/FileUpload&#39;;
177 180 import Editor from '@/components/Editor';
178 181 #end
179 182 ## 特殊:主子表专属逻辑
  183 +#if ( $table.templateType != 10 )
180 184 #if ( $subTables && $subTables.size() > 0 )
181 185 #foreach ($subSimpleClassName in $subSimpleClassNames)
182 186 import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
183 187 #end
184 188 #end
  189 +#end
185 190 export default {
186 191 name: "${simpleClassName}",
187 192 components: {
188 193 ${simpleClassName}Form,
189 194 ## 特殊:主子表专属逻辑
  195 +#if ( $table.templateType != 10 )
190 196 #if ( $subTables && $subTables.size() > 0 )
191 197 #foreach ($subSimpleClassName in $subSimpleClassNames)
192 198 ${subSimpleClassName}List,
193 199 #end
194 200 #end
  201 +#end
195 202 #if ($hasImageUploadColumn)
196 203 ImageUpload,
197 204 #end
... ... @@ -210,9 +217,9 @@ export default {
210 217 exportLoading: false,
211 218 // 显示搜索条件
212 219 showSearch: true,
213   - // 总条数
214 220 ## 特殊:树表专属逻辑(树不需要分页接口)
215 221 #if ( $table.templateType != 2 )
  222 + // 总条数
216 223 total: 0,
217 224 #end
218 225 // ${table.classComment}列表
... ... @@ -235,7 +242,7 @@ export default {
235 242 #if ($column.listOperationCondition != 'BETWEEN')
236 243 $column.javaField: null,
237 244 #end
238   - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  245 + #if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
239 246 $column.javaField: [],
240 247 #end
241 248 #end
... ... @@ -253,7 +260,7 @@ export default {
253 260 this.loading = true;
254 261 ## 特殊:树表专属逻辑(树不需要分页接口)
255 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 264 this.list = this.handleTree(response.data, 'id', '${treeParentColumn.javaField}');
258 265 })
259 266 #else
... ... @@ -302,14 +309,14 @@ export default {
302 309 return ${simpleClassName}Api.export${simpleClassName}Excel(params);
303 310 }).then(response => {
304 311 that.#[[$]]#download.excel(response, '${table.classComment}.xls');
305   - }));
  312 + });
306 313 } catch {
307 314 } finally {
308 315 that.exportLoading = false;
309 316 }
310 317 },
311 318 ## 特殊:主子表专属逻辑
312   - #if ( $subTables && $subTables.size() > 0 )
  319 + #if ( $table.templateType == 11 )
313 320 /** 选中行操作 */
314 321 handleCurrentChange(row) {
315 322 this.currentRow = row
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/form.vue.vm
1 1 <template>
2 2 <Dialog :title="dialogTitle" v-model="dialogVisible">
3 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 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 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 118 #end
117   - #end
118   -#end
119 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 135 <template #footer>
136 136 <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
137 137 <el-button @click="dialogVisible = false">取 消</el-button>
... ... @@ -139,160 +139,160 @@
139 139 </Dialog>
140 140 </template>
141 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 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 242 formLoading.value = true
207 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 266 } finally {
210 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 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 298 </script>
299 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 2 <ContentWrap>
3 3 <!-- 搜索工作栏 -->
4 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 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 84 <el-form-item>
85 85 <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
86 86 <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
87 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 93 <Icon icon="ep:plus" class="mr-5px" /> 新增
94 94 </el-button>
95 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 102 <Icon icon="ep:download" class="mr-5px" /> 导出
103 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 110 </el-form-item>
111 111 </el-form>
112 112 </ContentWrap>
113 113  
114 114 <!-- 列表 -->
115 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 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 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 187 link
188 188 type="primary"
189 189 @click="openForm('update', scope.row.id)"
190 190 v-hasPermi="['${permissionPrefix}:update']"
191   - >
192   - 编辑
193   - </el-button>
194   - <el-button
  191 + >
  192 + 编辑
  193 + </el-button>
  194 + <el-button
195 195 link
196 196 type="danger"
197 197 @click="handleDelete(scope.row.id)"
198 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 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 215 </ContentWrap>
213 216  
214 217 <!-- 表单弹窗:添加/修改 -->
215 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 236 </template>
234 237  
235 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 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 376 </script>
374 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 +}
... ...