Commit 3d45f92852d78f15c88bbf0515bd407e3ffcc4fd

Authored by YunaiV
2 parents df8593d2 380cc87e

Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into develop

Showing 13 changed files with 1663 additions and 28 deletions
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenFrontTypeEnum.java
... ... @@ -16,6 +16,7 @@ public enum CodegenFrontTypeEnum {
16 16 VUE3_ELEMENT_PLUS(20), // Vue3 Element Plus 标准模版
17 17 VUE3_VBEN2_ANTD_SCHEMA(30), // Vue3 VBEN2 + ANTD + Schema 模版
18 18 VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版
  19 + VUE3_VBEN5_ANTD(50), // Vue3 VBEN5 + ANTD 模版
19 20 ;
20 21  
21 22 /**
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -163,6 +163,25 @@ public class CodegenEngine {
163 163 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
164 164 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
165 165 vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  166 + // VUE3_VBEN5_ANTD
  167 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/data.ts"),
  168 + vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
  169 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
  170 + vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
  171 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),
  172 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
  173 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"),
  174 + vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
  175 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑
  176 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  177 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑
  178 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  179 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑
  180 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
  181 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑
  182 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
  183 + .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑
  184 + vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
166 185 .build();
167 186  
168 187 @Resource
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/api/api.ts.vm 0 → 100644
  1 +import type { PageParam, PageResult } from '@vben/request';
  2 +
  3 +import { requestClient } from '#/api/request';
  4 +#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
  5 +
  6 +export namespace ${simpleClassName}Api {
  7 +## 特殊:主子表专属逻辑
  8 +#foreach ($subTable in $subTables)
  9 + #set ($index = $foreach.count - 1)
  10 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  11 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  12 + /** ${subTable.classComment}信息 */
  13 + export interface ${subSimpleClassName} {
  14 + #foreach ($column in $subColumns)
  15 + #if ($column.createOperation || $column.updateOperation)
  16 + #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  17 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  18 + #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  19 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment}
  20 + #else
  21 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  22 + #end
  23 + #end
  24 + #end
  25 + }
  26 +
  27 +#end
  28 + /** ${table.classComment}信息 */
  29 + export interface ${simpleClassName} {
  30 +#foreach ($column in $columns)
  31 +#if ($column.createOperation || $column.updateOperation)
  32 +#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
  33 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}
  34 +#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
  35 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: Date; // ${column.columnComment}
  36 +#else
  37 + ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}
  38 +#end
  39 +#end
  40 +#end
  41 +#if ( $table.templateType == 2 )
  42 + children?: ${simpleClassName}[];
  43 +#end
  44 +## 特殊:主子表专属逻辑
  45 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  46 + #foreach ($subTable in $subTables)
  47 + #set ($index = $foreach.count - 1)
  48 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  49 + #if ( $subTable.subJoinMany )
  50 + ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]
  51 + #else
  52 + ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}
  53 + #end
  54 + #end
  55 +#end
  56 + }
  57 +}
  58 +
  59 +#if ( $table.templateType != 2 )
  60 +/** 查询${table.classComment}分页 */
  61 +export function get${simpleClassName}Page(params: PageParam) {
  62 + return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params });
  63 +}
  64 +#else
  65 +/** 查询${table.classComment}列表 */
  66 +export function get${simpleClassName}List(params: any) {
  67 + return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params });
  68 +}
  69 +#end
  70 +
  71 +/** 查询${table.classComment}详情 */
  72 +export function get${simpleClassName}(id: number) {
  73 + return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`);
  74 +}
  75 +
  76 +/** 新增${table.classComment} */
  77 +export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  78 + return requestClient.post('${baseURL}/create', data);
  79 +}
  80 +
  81 +/** 修改${table.classComment} */
  82 +export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {
  83 + return requestClient.put('${baseURL}/update', data);
  84 +}
  85 +
  86 +/** 删除${table.classComment} */
  87 +export function delete${simpleClassName}(id: number) {
  88 + return requestClient.delete(`${baseURL}/delete?id=${id}`);
  89 +}
  90 +
  91 +/** 导出${table.classComment} */
  92 +export function export${simpleClassName}(params: any) {
  93 + return requestClient.download('${baseURL}/export-excel', params);
  94 +}
  95 +
  96 +## 特殊:主子表专属逻辑
  97 +#foreach ($subTable in $subTables)
  98 +#set ($index = $foreach.count - 1)
  99 +#set ($subSimpleClassName = $subSimpleClassNames.get($index))
  100 +#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
  101 +#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  102 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  103 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  104 +#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  105 +#set ($subClassNameVar = $subClassNameVars.get($index))
  106 +
  107 +// ==================== 子表($subTable.classComment) ====================
  108 +
  109 +## 情况一:MASTER_ERP 时,需要分查询页子表
  110 +#if ( $table.templateType == 11 )
  111 +/** 获得${subTable.classComment}分页 */
  112 +export function get${subSimpleClassName}Page(params: PageParam) {
  113 + return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });
  114 +}
  115 +## 情况二:非 MASTER_ERP 时,需要列表查询子表
  116 +#else
  117 + #if ( $subTable.subJoinMany )
  118 +/** 获得${subTable.classComment}列表 */
  119 +export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  120 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  121 +}
  122 + #else
  123 +/** 获得${subTable.classComment} */
  124 +export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
  125 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);
  126 +}
  127 + #end
  128 +#end
  129 +## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
  130 +#if ( $table.templateType == 11 )
  131 +/** 新增${subTable.classComment} */
  132 +export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  133 + return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
  134 +}
  135 +
  136 +/** 修改${subTable.classComment} */
  137 +export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {
  138 + return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
  139 +}
  140 +
  141 +/** 删除${subTable.classComment} */
  142 +export function delete${subSimpleClassName}(id: number) {
  143 + return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);
  144 +}
  145 +
  146 +/** 获得${subTable.classComment} */
  147 +export function get${subSimpleClassName}(id: number) {
  148 + return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);
  149 +}
  150 +#end
  151 +#end
  152 +
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/index.vue.vm deleted
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/data.ts.vm 0 → 100644
  1 +import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
  2 +import type { VbenFormSchema } from '#/adapter/form';
  3 +import type { OnActionClickFn } from '#/adapter/vxe-table';
  4 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  5 +
  6 +import { z } from '#/adapter/form';
  7 +#if(${table.templateType} == 2)## 树表需要导入这些
  8 +import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  9 +import { handleTree } from '#/utils/tree';
  10 +#end
  11 +import { DICT_TYPE, getDictOptions } from '#/utils/dict';
  12 +import { getRangePickerDefaultProps } from '#/utils/date';
  13 +import { useAccess } from '@vben/access';
  14 +
  15 +const { hasAccessByCodes } = useAccess();
  16 +
  17 +/** 列表的搜索表单 */
  18 +export function useGridFormSchema(): VbenFormSchema[] {
  19 + return [
  20 +#foreach($column in $columns)
  21 +#if ($column.listOperation)
  22 + #set ($dictType = $column.dictType)
  23 + #set ($javaType = $column.javaType)
  24 + #set ($javaField = $column.javaField)
  25 + #set ($comment = $column.columnComment)
  26 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  27 + #set ($dictMethod = "number")
  28 + #elseif ($javaType == "String")
  29 + #set ($dictMethod = "string")
  30 + #elseif ($javaType == "Boolean")
  31 + #set ($dictMethod = "boolean")
  32 + #end
  33 + {
  34 + fieldName: '${javaField}',
  35 + label: '${comment}',
  36 + #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
  37 + component: 'Input',
  38 + componentProps: {
  39 + allowClear: true,
  40 + placeholder: '请输入${comment}',
  41 + },
  42 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  43 + component: 'Select',
  44 + componentProps: {
  45 + allowClear: true,
  46 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  47 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  48 + #else## 未设置 dictType 数据字典的情况
  49 + options: [],
  50 + #end
  51 + placeholder: '请选择${comment}',
  52 + },
  53 + #elseif($column.htmlType == "datetime")
  54 + component: 'RangePicker',
  55 + componentProps: {
  56 + ...getRangePickerDefaultProps(),
  57 + allowClear: true,
  58 + },
  59 + #end
  60 + },
  61 +#end
  62 +#end
  63 + ];
  64 +}
  65 +
  66 +/** 列表的字段 */
  67 +export function useGridColumns(
  68 + onActionClick?: OnActionClickFn<${simpleClassName}Api.${simpleClassName}>,
  69 +): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] {
  70 + return [
  71 +#if ($table.templateType == 12) ## 内嵌情况
  72 + { type: 'expand', width: 80, slots: { content: 'expand_content' } },
  73 +#end
  74 +#foreach($column in $columns)
  75 +#if ($column.listOperationResult)
  76 + #set ($dictType = $column.dictType)
  77 + #set ($javaField = $column.javaField)
  78 + #set ($comment = $column.columnComment)
  79 + {
  80 + field: '${javaField}',
  81 + title: '${comment}',
  82 + minWidth: 120,
  83 + #if ($column.javaType == "LocalDateTime")## 时间类型
  84 + formatter: 'formatDateTime',
  85 + #elseif("" != $dictType)## 数据字典
  86 + cellRender: {
  87 + name: 'CellDict',
  88 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  89 + },
  90 + #end
  91 + #if (${table.templateType} == 2 && $column.id == $treeNameColumn.id)## 树表特有:标记树节点列
  92 + treeNode: true,
  93 + #end
  94 + },
  95 +#end
  96 +#end
  97 + {
  98 + field: 'operation',
  99 + title: '操作',
  100 + minWidth: 200,
  101 + align: 'center',
  102 + fixed: 'right',
  103 + headerAlign: 'center',
  104 + showOverflow: false,
  105 + cellRender: {
  106 + attrs: {
  107 + nameField: '${columns[0].javaField}',
  108 + nameTitle: '${table.classComment}',
  109 + onClick: onActionClick,
  110 + },
  111 + name: 'CellOperation',
  112 + options: [
  113 +#if (${table.templateType} == 2)## 树表特有操作
  114 + {
  115 + code: 'append',
  116 + text: '新增下级',
  117 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:create']),
  118 + },
  119 +#end
  120 + {
  121 + code: 'edit',
  122 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),
  123 + },
  124 + {
  125 + code: 'delete',
  126 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
  127 +#if (${table.templateType} == 2)## 树表禁止删除带有子节点的数据
  128 + disabled: (row: ${simpleClassName}Api.${simpleClassName}) => {
  129 + return !!(row.children && row.children.length > 0);
  130 + },
  131 +#end
  132 + },
  133 + ],
  134 + },
  135 + },
  136 + ];
  137 +}
  138 +
  139 +## 标准模式和内嵌模式时,主子关系一对一则生成表单schema,一对多则生成列表schema(内嵌模式时表单schema也要生成)。erp 模式时都生成
  140 +## 特殊:主子表专属逻辑
  141 +#foreach ($subTable in $subTables)
  142 + #set ($index = $foreach.count - 1)
  143 + #set ($subColumns = $subColumnsList.get($index))##当前字段数组
  144 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  145 + #set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
  146 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  147 +// ==================== 子表($subTable.classComment) ====================
  148 +
  149 +#if ($table.templateType == 11) ## erp 情况
  150 +/** 列表的搜索表单 */
  151 +export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
  152 + return [
  153 + #foreach($column in $subColumns)
  154 + #if ($column.listOperation)
  155 + #set ($dictType = $column.dictType)
  156 + #set ($javaType = $column.javaType)
  157 + #set ($javaField = $column.javaField)
  158 + #set ($comment = $column.columnComment)
  159 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  160 + #set ($dictMethod = "number")
  161 + #elseif ($javaType == "String")
  162 + #set ($dictMethod = "string")
  163 + #elseif ($javaType == "Boolean")
  164 + #set ($dictMethod = "boolean")
  165 + #end
  166 + {
  167 + fieldName: '${javaField}',
  168 + label: '${comment}',
  169 + #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
  170 + component: 'Input',
  171 + componentProps: {
  172 + allowClear: true,
  173 + placeholder: '请输入${comment}',
  174 + },
  175 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  176 + component: 'Select',
  177 + componentProps: {
  178 + allowClear: true,
  179 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  180 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  181 + #else## 未设置 dictType 数据字典的情况
  182 + options: [],
  183 + #end
  184 + placeholder: '请选择${comment}',
  185 + },
  186 + #elseif($column.htmlType == "datetime")
  187 + component: 'RangePicker',
  188 + componentProps: {
  189 + ...getRangePickerDefaultProps(),
  190 + allowClear: true,
  191 + },
  192 + #end
  193 + },
  194 + #end
  195 + #end
  196 + ];
  197 +}
  198 +
  199 +/** 列表的字段 */
  200 +export function use${subSimpleClassName}GridColumns(
  201 + onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,
  202 +): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  203 + return [
  204 + #foreach($column in $subColumns)
  205 + #if ($column.listOperationResult)
  206 + #set ($dictType = $column.dictType)
  207 + #set ($javaField = $column.javaField)
  208 + #set ($comment = $column.columnComment)
  209 + {
  210 + field: '${javaField}',
  211 + title: '${comment}',
  212 + minWidth: 120,
  213 + #if ($column.javaType == "LocalDateTime")## 时间类型
  214 + formatter: 'formatDateTime',
  215 + #elseif("" != $dictType)## 数据字典
  216 + cellRender: {
  217 + name: 'CellDict',
  218 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  219 + },
  220 + #end
  221 + },
  222 + #end
  223 + #end
  224 + {
  225 + field: 'operation',
  226 + title: '操作',
  227 + minWidth: 200,
  228 + align: 'center',
  229 + fixed: 'right',
  230 + headerAlign: 'center',
  231 + showOverflow: false,
  232 + cellRender: {
  233 + attrs: {
  234 + nameField: '${columns[0].javaField}',
  235 + nameTitle: '${subTable.classComment}',
  236 + onClick: onActionClick,
  237 + },
  238 + name: 'CellOperation',
  239 + options: [
  240 + {
  241 + code: 'edit',
  242 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:update']),
  243 + },
  244 + {
  245 + code: 'delete',
  246 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
  247 + },
  248 + ],
  249 + },
  250 + },
  251 + ];
  252 +}
  253 +
  254 +#else
  255 + #if ($subTable.subJoinMany) ## 一对多
  256 + /** 新增/修改列表的字段 */
  257 + export function use${subSimpleClassName}GridEditColumns(
  258 + onActionClick?: OnActionClickFn<${simpleClassName}Api.${subSimpleClassName}>,
  259 + ): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  260 + return [
  261 + #foreach($column in $subColumns)
  262 + #if ($column.createOperation || $column.updateOperation)
  263 + #if (!$column.primaryKey && $column.listOperationResult && $column.id != $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  264 + #set ($dictType = $column.dictType)
  265 + #set ($javaField = $column.javaField)
  266 + #set ($comment = $column.columnComment)
  267 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  268 + #set ($dictMethod = "number")
  269 + #elseif ($javaType == "String")
  270 + #set ($dictMethod = "string")
  271 + #elseif ($javaType == "Boolean")
  272 + #set ($dictMethod = "boolean")
  273 + #end
  274 + {
  275 + field: '${javaField}',
  276 + title: '${comment}',
  277 + minWidth: 120,
  278 + slots: { default: '${javaField}' },
  279 + #if ($column.htmlType == "select" || $column.htmlType == "checkbox" || $column.htmlType == "radio")
  280 + #if ("" != $dictType)## 有数据字典
  281 + params: {
  282 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
  283 + },
  284 + #else
  285 + params: {
  286 + options: [],
  287 + },
  288 + #end
  289 + #end
  290 + },
  291 + #end
  292 + #end
  293 + #end
  294 + {
  295 + field: 'operation',
  296 + title: '操作',
  297 + minWidth: 60,
  298 + align: 'center',
  299 + fixed: 'right',
  300 + headerAlign: 'center',
  301 + showOverflow: false,
  302 + cellRender: {
  303 + attrs: {
  304 + nameField: '${columns[0].javaField}',
  305 + nameTitle: '${table.classComment}',
  306 + onClick: onActionClick,
  307 + },
  308 + name: 'CellOperation',
  309 + options: [
  310 + {
  311 + code: 'delete',
  312 + show: hasAccessByCodes(['${table.moduleName}:${simpleClassName_strikeCase}:delete']),
  313 + },
  314 + ],
  315 + },
  316 + },
  317 + ];
  318 + }
  319 + #end
  320 + #if ($table.templateType == 12) ## 内嵌情况
  321 + /** 列表的字段 */
  322 + export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] {
  323 + return [
  324 + #foreach($column in $subColumns)
  325 + #if ($column.listOperationResult)
  326 + #set ($dictType = $column.dictType)
  327 + #set ($javaField = $column.javaField)
  328 + #set ($comment = $column.columnComment)
  329 + {
  330 + field: '${javaField}',
  331 + title: '${comment}',
  332 + minWidth: 120,
  333 + #if ($column.javaType == "LocalDateTime")## 时间类型
  334 + formatter: 'formatDateTime',
  335 + #elseif("" != $dictType)## 数据字典
  336 + cellRender: {
  337 + name: 'CellDict',
  338 + props: { type: DICT_TYPE.$dictType.toUpperCase() },
  339 + },
  340 + #end
  341 + },
  342 + #end
  343 + #end
  344 + ];
  345 + }
  346 +
  347 + #end
  348 +#end
  349 +#end
0 350 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +import type { Rule } from 'ant-design-vue/es/form';
  4 +
  5 +import { useVbenModal } from '@vben/common-ui';
  6 +import { Tinymce as RichTextarea } from '#/components/tinymce';
  7 +import { ImageUpload, FileUpload } from "#/components/upload";
  8 +import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue';
  9 +import { DICT_TYPE, getDictOptions } from '#/utils/dict';
  10 +#if($table.templateType == 2)## 树表需要导入这些
  11 +import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  12 +import { handleTree } from '#/utils/tree';
  13 +#end
  14 +## 特殊:主子表专属逻辑
  15 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  16 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  17 + #set ($index = $foreach.count - 1)
  18 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  19 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  20 + #end
  21 +#end
  22 +
  23 +import { computed, ref } from 'vue';
  24 +import { $t } from '#/locales';
  25 +import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  26 +
  27 +const emit = defineEmits(['success']);
  28 +const formRef = ref();
  29 +const labelCol = { span: 5 };
  30 +const wrapperCol = { span: 13 };
  31 +const formData = ref<Partial<${simpleClassName}Api.${simpleClassName}>>({
  32 +#foreach ($column in $columns)
  33 + #if ($column.createOperation || $column.updateOperation)
  34 + #if ($column.htmlType == "checkbox")
  35 + $column.javaField: [],
  36 + #else
  37 + $column.javaField: undefined,
  38 + #end
  39 + #end
  40 +#end
  41 +});
  42 +const rules: Record<string, Rule[]> = {
  43 + #foreach ($column in $columns)
  44 + #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
  45 + #set($comment=$column.columnComment)
  46 + $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
  47 + #end
  48 + #end
  49 +};
  50 +## 特殊:树表专属逻辑
  51 +#if ( $table.templateType == 2 )
  52 +const ${classNameVar}Tree = ref<any[]>([]) // 树形结构
  53 +#end
  54 +const getTitle = computed(() => {
  55 + return formData.value?.id
  56 + ? $t('ui.actionTitle.edit', ['${table.classComment}'])
  57 + : $t('ui.actionTitle.create', ['${table.classComment}']);
  58 +});
  59 +
  60 +## 特殊:主子表专属逻辑
  61 +#if ( $table.templateType == 10 || $table.templateType == 12 )
  62 + #if ( $subTables && $subTables.size() > 0 )
  63 + /** 子表的表单 */
  64 + const subTabsName = ref('$subClassNameVars.get(0)')
  65 + #foreach ($subClassNameVar in $subClassNameVars)
  66 + #set ($index = $foreach.count - 1)
  67 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  68 + const ${subClassNameVar}FormRef = ref<InstanceType<typeof ${subSimpleClassName}Form>>()
  69 + #end
  70 + #end
  71 +#end
  72 +
  73 +/** 重置表单 */
  74 +const resetForm = () => {
  75 + formData.value = {
  76 + #foreach ($column in $columns)
  77 + #if ($column.createOperation || $column.updateOperation)
  78 + #if ($column.htmlType == "checkbox")
  79 + $column.javaField: [],
  80 + #else
  81 + $column.javaField: undefined,
  82 + #end
  83 + #end
  84 + #end
  85 + };
  86 + formRef.value?.resetFields();
  87 +}
  88 +
  89 +## 特殊:树表专属逻辑
  90 +#if ( $table.templateType == 2 )
  91 +/** 获得${table.classComment}树 */
  92 +const get${simpleClassName}Tree = async () => {
  93 + ${classNameVar}Tree.value = []
  94 + const data = await get${simpleClassName}List()
  95 + const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
  96 + root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
  97 + ${classNameVar}Tree.value.push(root)
  98 +}
  99 +#end
  100 +
  101 +const [Modal, modalApi] = useVbenModal({
  102 + async onConfirm() {
  103 + await formRef.value?.validate();
  104 + ## 特殊:主子表专属逻辑
  105 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  106 + #if ( $subTables && $subTables.size() > 0 )
  107 + // 校验子表单
  108 + #foreach ($subTable in $subTables)
  109 + #set ($index = $foreach.count - 1)
  110 + #set ($subClassNameVar = $subClassNameVars.get($index))
  111 + #if ($subTable.subJoinMany) ## 一对多
  112 + ## TODO 列表值校验?
  113 + #else
  114 + const ${subClassNameVar}Valid = await ${subClassNameVar}FormRef.value?.validate();
  115 + if (!${subClassNameVar}Valid) {
  116 + subTabsName.value = '${subClassNameVar}';
  117 + return;
  118 + }
  119 + #end
  120 + #end
  121 + #end
  122 + #end
  123 + modalApi.lock();
  124 + // 提交表单
  125 + const data = formData.value as ${simpleClassName}Api.${simpleClassName};
  126 + ## 特殊:主子表专属逻辑
  127 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  128 + #if ( $subTables && $subTables.size() > 0 )
  129 + // 拼接子表的数据
  130 + #foreach ($subTable in $subTables)
  131 + #set ($index = $foreach.count - 1)
  132 + #set ($subClassNameVar = $subClassNameVars.get($index))
  133 + #if ($subTable.subJoinMany)
  134 + data.${subClassNameVar}s = ${subClassNameVar}FormRef.value?.getData();
  135 + #else
  136 + data.${subClassNameVar} = await ${subClassNameVar}FormRef.value?.getValues();
  137 + #end
  138 + #end
  139 + #end
  140 + #end
  141 + try {
  142 + await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
  143 + // 关闭并提示
  144 + await modalApi.close();
  145 + emit('success');
  146 + message.success({
  147 + content: $t('ui.actionMessage.operationSuccess'),
  148 + key: 'action_process_msg',
  149 + });
  150 + } finally {
  151 + modalApi.lock(false);
  152 + }
  153 + },
  154 + async onOpenChange(isOpen: boolean) {
  155 + if (!isOpen) {
  156 + resetForm()
  157 + return;
  158 + }
  159 +
  160 + // 加载数据
  161 + let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();
  162 + if (!data) {
  163 + return;
  164 + }
  165 + if (data.id) {
  166 + modalApi.lock();
  167 + try {
  168 + data = await get${simpleClassName}(data.id);
  169 + } finally {
  170 + modalApi.lock(false);
  171 + }
  172 + }
  173 + formData.value = data;
  174 +#if ( $table.templateType == 2 )
  175 + // 加载树数据
  176 + await get${simpleClassName}Tree()
  177 +#end
  178 + },
  179 +});
  180 +</script>
  181 +
  182 +<template>
  183 + <Modal :title="getTitle">
  184 + <Form
  185 + ref="formRef"
  186 + :model="formData"
  187 + :rules="rules"
  188 + :label-col="labelCol"
  189 + :wrapper-col="wrapperCol"
  190 + >
  191 + #foreach($column in $columns)
  192 + #if ($column.createOperation || $column.updateOperation)
  193 + #set ($dictType = $column.dictType)
  194 + #set ($javaField = $column.javaField)
  195 + #set ($javaType = $column.javaType)
  196 + #set ($comment = $column.columnComment)
  197 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  198 + #set ($dictMethod = "number")
  199 + #elseif ($javaType == "String")
  200 + #set ($dictMethod = "string")
  201 + #elseif ($javaType == "Boolean")
  202 + #set ($dictMethod = "boolean")
  203 + #end
  204 + #if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
  205 + <Form.Item label="${comment}" name="${javaField}">
  206 + <TreeSelect
  207 + v-model:value="formData.${javaField}"
  208 + :treeData="${classNameVar}Tree"
  209 + #if ($treeNameColumn.javaField == "name")
  210 + :fieldNames="defaultProps"
  211 + #else
  212 + :fieldNames="{...defaultProps, label: '$treeNameColumn.javaField'}"
  213 + #end
  214 + checkable
  215 + treeDefaultExpandAll
  216 + placeholder="请选择${comment}"
  217 + />
  218 + </Form.Item>
  219 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  220 + <Form.Item label="${comment}" name="${javaField}">
  221 + <Input v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  222 + </Form.Item>
  223 + #elseif($column.htmlType == "imageUpload")## 图片上传
  224 + <Form.Item label="${comment}" name="${javaField}">
  225 + <ImageUpload v-model:value="formData.${javaField}" />
  226 + </Form.Item>
  227 + #elseif($column.htmlType == "fileUpload")## 文件上传
  228 + <Form.Item label="${comment}" name="${javaField}">
  229 + <FileUpload v-model:value="formData.${javaField}" />
  230 + </Form.Item>
  231 + #elseif($column.htmlType == "editor")## 文本编辑器
  232 + <Form.Item label="${comment}" name="${javaField}">
  233 + <RichTextarea v-model="formData.${javaField}" height="500px" />
  234 + </Form.Item>
  235 + #elseif($column.htmlType == "select")## 下拉框
  236 + <Form.Item label="${comment}" name="${javaField}">
  237 + <Select v-model:value="formData.${javaField}" placeholder="请选择${comment}">
  238 + #if ("" != $dictType)## 有数据字典
  239 + <Select.Option
  240 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  241 + :key="dict.value"
  242 + :label="dict.label"
  243 + :value="dict.value"
  244 + />
  245 + #else##没数据字典
  246 + <Select.Option label="请选择字典生成" value="" />
  247 + #end
  248 + </Select>
  249 + </Form.Item>
  250 + #elseif($column.htmlType == "checkbox")## 多选框
  251 + <Form.Item label="${comment}" name="${javaField}">
  252 + <CheckboxGroup v-model:value="formData.${javaField}">
  253 + #if ("" != $dictType)## 有数据字典
  254 + <Checkbox
  255 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  256 + :key="dict.value"
  257 + :label="dict.label"
  258 + :value="dict.value"
  259 + />
  260 + #else##没数据字典
  261 + <Checkbox label="请选择字典生成" />
  262 + #end
  263 + </CheckboxGroup>
  264 + </Form.Item>
  265 + #elseif($column.htmlType == "radio")## 单选框
  266 + <Form.Item label="${comment}" name="${javaField}">
  267 + <RadioGroup v-model:value="formData.${javaField}">
  268 + #if ("" != $dictType)## 有数据字典
  269 + <Radio
  270 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  271 + :key="dict.value"
  272 + :value="dict.value"
  273 + >
  274 + {{ dict.label }}
  275 + </Radio>
  276 + #else##没数据字典
  277 + <Radio value="1">请选择字典生成</Radio>
  278 + #end
  279 + </RadioGroup>
  280 + </Form.Item>
  281 + #elseif($column.htmlType == "datetime")## 时间框
  282 + <Form.Item label="${comment}" name="${javaField}">
  283 + <DatePicker
  284 + v-model:value="formData.${javaField}"
  285 + valueFormat="x"
  286 + placeholder="选择${comment}"
  287 + />
  288 + </Form.Item>
  289 + #elseif($column.htmlType == "textarea")## 文本框
  290 + <Form.Item label="${comment}" name="${javaField}">
  291 + <Textarea v-model:value="formData.${javaField}" placeholder="请输入${comment}" />
  292 + </Form.Item>
  293 + #end
  294 + #end
  295 + #end
  296 + </Form>
  297 + ## 特殊:主子表专属逻辑
  298 + #if ( $table.templateType == 10 || $table.templateType == 12 )
  299 + <!-- 子表的表单 -->
  300 + <Tabs v-model:active-key="subTabsName">
  301 + #foreach ($subTable in $subTables)
  302 + #set ($index = $foreach.count - 1)
  303 + #set ($subClassNameVar = $subClassNameVars.get($index))
  304 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  305 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  306 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  307 + <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
  308 + </Tabs.TabPane>
  309 + #end
  310 + </Tabs>
  311 + #end
  312 + </Modal>
  313 +</template>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm 0 → 100644
  1 +<script lang="ts" setup>
  2 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  3 +
  4 +import { Page, useVbenModal } from '@vben/common-ui';
  5 +import { formatDateTime } from '@vben/utils';
  6 +import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue';
  7 +import { DictTag } from '#/components/dict-tag';
  8 +import { DICT_TYPE, getDictOptions } from '#/utils/dict';
  9 +import ${simpleClassName}Form from './modules/form.vue';
  10 +import { Download, Plus, RefreshCw, Search } from '@vben/icons';
  11 +import { ContentWrap } from "#/components/content-wrap";
  12 +import { VxeColumn, VxeTable } from 'vxe-table';
  13 +import { getRangePickerDefaultProps } from '#/utils/date';
  14 +
  15 +## 特殊:主子表专属逻辑
  16 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  17 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  18 + #set ($index = $foreach.count - 1)
  19 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  20 + import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'
  21 + #end
  22 +#end
  23 +
  24 +import { ref, h, reactive,onMounted } from 'vue';
  25 +import { $t } from '#/locales';
  26 +#if (${table.templateType} == 2)## 树表接口
  27 +import { handleTree } from '@/utils/tree'
  28 +import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  29 +#else## 标准表接口
  30 +import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  31 +#end
  32 +import { downloadByData } from '#/utils/download';
  33 +
  34 +#if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
  35 +/** 子表的列表 */
  36 +const subTabsName = ref('$subClassNameVars.get(0)')
  37 +#if ($table.templateType == 11)
  38 +const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>();
  39 +#end
  40 +#end
  41 +
  42 +const loading = ref(true) // 列表的加载中
  43 +const list = ref<${simpleClassName}Api.${simpleClassName}[]>([]) // 列表的数据
  44 +## 特殊:树表专属逻辑(树不需要分页接口)
  45 +#if ( $table.templateType != 2 )
  46 +const total = ref(0) // 列表的总页数
  47 +#end
  48 +const queryParams = reactive({
  49 +## 特殊:树表专属逻辑(树不需要分页接口)
  50 +#if ( $table.templateType != 2 )
  51 + pageNo: 1,
  52 + pageSize: 10,
  53 +#end
  54 +#foreach ($column in $columns)
  55 + #if ($column.listOperation)
  56 + #if ($column.listOperationCondition != 'BETWEEN')
  57 + $column.javaField: undefined,
  58 + #end
  59 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  60 + $column.javaField: undefined,
  61 + #end
  62 + #end
  63 +#end
  64 +})
  65 +const queryFormRef = ref() // 搜索的表单
  66 +const exportLoading = ref(false) // 导出的加载中
  67 +
  68 +/** 查询列表 */
  69 +const getList = async () => {
  70 + loading.value = true
  71 + try {
  72 + ## 特殊:树表专属逻辑(树不需要分页接口)
  73 + #if ( $table.templateType == 2 )
  74 + const data = await get${simpleClassName}List(queryParams)
  75 + list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
  76 + #else
  77 + const data = await get${simpleClassName}Page(queryParams)
  78 + list.value = data.list
  79 + total.value = data.total
  80 + #end
  81 + } finally {
  82 + loading.value = false
  83 + }
  84 +}
  85 +
  86 +/** 搜索按钮操作 */
  87 +const handleQuery = () => {
  88 + queryParams.pageNo = 1
  89 + getList()
  90 +}
  91 +
  92 +/** 重置按钮操作 */
  93 +const resetQuery = () => {
  94 + queryFormRef.value.resetFields()
  95 + handleQuery()
  96 +}
  97 +
  98 +const [FormModal, formModalApi] = useVbenModal({
  99 + connectedComponent: ${simpleClassName}Form,
  100 + destroyOnClose: true,
  101 +});
  102 +
  103 +/** 创建${table.classComment} */
  104 +function onCreate() {
  105 + formModalApi.setData({}).open();
  106 +}
  107 +
  108 +/** 编辑${table.classComment} */
  109 +function onEdit(row: ${simpleClassName}Api.${simpleClassName}) {
  110 + formModalApi.setData(row).open();
  111 +}
  112 +
  113 +#if (${table.templateType} == 2)## 树表特有:新增下级
  114 +/** 新增下级${table.classComment} */
  115 +function onAppend(row: ${simpleClassName}Api.${simpleClassName}) {
  116 + formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
  117 +}
  118 +#end
  119 +
  120 +/** 删除${table.classComment} */
  121 +async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) {
  122 + const hideLoading = message.loading({
  123 + content: $t('ui.actionMessage.deleting', [row.id]),
  124 + duration: 0,
  125 + key: 'action_process_msg',
  126 + });
  127 + try {
  128 + await delete${simpleClassName}(row.id as number);
  129 + message.success({
  130 + content: $t('ui.actionMessage.deleteSuccess', [row.id]),
  131 + key: 'action_process_msg',
  132 + });
  133 + await getList();
  134 + } catch {
  135 + hideLoading();
  136 + }
  137 +}
  138 +
  139 +/** 导出表格 */
  140 +async function onExport() {
  141 +try {
  142 + exportLoading.value = true;
  143 + const data = await export${simpleClassName}(queryParams);
  144 + downloadByData(data, '${table.classComment}.xls');
  145 +}finally {
  146 + exportLoading.value = false;
  147 +}
  148 +}
  149 +
  150 +/** 初始化 **/
  151 +onMounted(() => {
  152 + getList()
  153 +})
  154 +</script>
  155 +
  156 +<template>
  157 + <Page auto-content-height>
  158 + <FormModal @success="getList" />
  159 +
  160 + <ContentWrap>
  161 + <!-- 搜索工作栏 -->
  162 + <Form
  163 + class="-mb-15px"
  164 + :model="queryParams"
  165 + ref="queryFormRef"
  166 + layout="inline"
  167 + >
  168 + #foreach($column in $columns)
  169 + #if ($column.listOperation)
  170 + #set ($dictType = $column.dictType)
  171 + #set ($javaField = $column.javaField)
  172 + #set ($javaType = $column.javaType)
  173 + #set ($comment = $column.columnComment)
  174 + #if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
  175 + #set ($dictMethod = "number")
  176 + #elseif ($javaType == "String")
  177 + #set ($dictMethod = "string")
  178 + #elseif ($javaType == "Boolean")
  179 + #set ($dictMethod = "boolean")
  180 + #end
  181 + #if ($column.htmlType == "input")
  182 + <Form.Item label="${comment}" name="${javaField}">
  183 + <Input
  184 + v-model:value="queryParams.${javaField}"
  185 + placeholder="请输入${comment}"
  186 + allowClear
  187 + @pressEnter="handleQuery"
  188 + class="!w-240px"
  189 + />
  190 + </Form.Item>
  191 + #elseif ($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "checkbox")
  192 + <Form.Item label="${comment}" name="${javaField}">
  193 + <Select
  194 + v-model:value="queryParams.${javaField}"
  195 + placeholder="请选择${comment}"
  196 + allowClear
  197 + class="!w-240px"
  198 + >
  199 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  200 + <Select.Option
  201 + v-for="dict in getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod')"
  202 + :key="dict.value"
  203 + :label="dict.label"
  204 + :value="dict.value"
  205 + />
  206 + #else## 未设置 dictType 数据字典的情况
  207 + <Select.Option label="请选择字典生成" value="" />
  208 + #end
  209 + </Select>
  210 + </Form.Item>
  211 + #elseif($column.htmlType == "datetime")
  212 + #if ($column.listOperationCondition != "BETWEEN")## 非范围
  213 + <Form.Item label="${comment}" name="${javaField}">
  214 + <DatePicker
  215 + v-model:value="queryParams.${javaField}"
  216 + valueFormat="YYYY-MM-DD"
  217 + placeholder="选择${comment}"
  218 + allowClear
  219 + class="!w-240px"
  220 + />
  221 + </Form.Item>
  222 + #else## 范围
  223 + <Form.Item label="${comment}" name="${javaField}">
  224 + <RangePicker
  225 + v-model:value="queryParams.${javaField}"
  226 + v-bind="getRangePickerDefaultProps()"
  227 + class="!w-220px"
  228 + />
  229 + </Form.Item>
  230 + #end
  231 + #end
  232 + #end
  233 + #end
  234 + <Form.Item>
  235 + <Button class="ml-2" @click="handleQuery" :icon="h(Search)">搜索</Button>
  236 + <Button class="ml-2" @click="resetQuery" :icon="h(RefreshCw)">重置</Button>
  237 + <Button
  238 + class="ml-2"
  239 + :icon="h(Plus)"
  240 + type="primary"
  241 + @click="onCreate"
  242 + v-access:code="['${permissionPrefix}:create']"
  243 + >
  244 + {{ $t('ui.actionTitle.create', ['示例联系人']) }}
  245 + </Button>
  246 + <Button
  247 + :icon="h(Download)"
  248 + type="primary"
  249 + class="ml-2"
  250 + :loading="exportLoading"
  251 + @click="onExport"
  252 + v-access:code="['${permissionPrefix}:export']"
  253 + >
  254 + {{ $t('ui.actionTitle.export') }}
  255 + </Button>
  256 + </Form.Item>
  257 + </Form>
  258 + </ContentWrap>
  259 +
  260 + <!-- 列表 -->
  261 + <ContentWrap>
  262 + <vxe-table :data="list" show-overflow :loading="loading">
  263 + ## 特殊:主子表专属逻辑
  264 + #if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
  265 + <!-- 子表的列表 -->
  266 + <vxe-column type="expand" width="60">
  267 + <template #content="{ row }">
  268 + <!-- 子表的表单 -->
  269 + <Tabs v-model:active-key="subTabsName" class="mx-8">
  270 + #foreach ($subTable in $subTables)
  271 + #set ($index = $foreach.count - 1)
  272 + #set ($subClassNameVar = $subClassNameVars.get($index))
  273 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  274 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  275 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  276 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
  277 + </Tabs.TabPane>
  278 + #end
  279 + </Tabs>
  280 + </template>
  281 + </vxe-column>
  282 + #end
  283 + #foreach($column in $columns)
  284 + #if ($column.listOperationResult)
  285 + #set ($dictType=$column.dictType)
  286 + #set ($javaField = $column.javaField)
  287 + #set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
  288 + #set ($comment=$column.columnComment)
  289 + #if ($column.javaType == "LocalDateTime")## 时间类型
  290 + <vxe-column field="${javaField}" title="${comment}" align="center">
  291 + <template #default="{row}">
  292 + {{formatDateTime(row.${javaField})}}
  293 + </template>
  294 + </vxe-column>
  295 + #elseif($column.dictType && "" != $column.dictType)## 数据字典
  296 + <vxe-column field="${javaField}" title="${comment}" align="center">
  297 + <template #default="{row}">
  298 + <dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="row.${javaField}" />
  299 + </template>
  300 + </vxe-column>
  301 + #else
  302 + <vxe-column field="${javaField}" title="${comment}" align="center" />
  303 + #end
  304 + #end
  305 + #end
  306 + <vxe-column field="operation" title="操作" align="center">
  307 + <template #default="{row}">
  308 + <Button
  309 + size="small"
  310 + type="link"
  311 + @click="onEdit(row as any)"
  312 + v-access:code="['${permissionPrefix}:update']"
  313 + >
  314 + {{ $t('ui.actionTitle.edit') }}
  315 + </Button>
  316 + <Button
  317 + size="small"
  318 + type="link"
  319 + class="ml-2"
  320 + @click="onDelete(row as any)"
  321 + v-access:code="['${permissionPrefix}:delete']"
  322 + >
  323 + {{ $t('ui.actionTitle.delete') }}
  324 + </Button>
  325 + </template>
  326 + </vxe-column>
  327 + </vxe-table>
  328 + <!-- 分页 -->
  329 + <div class="mt-2 flex justify-end">
  330 + <Pagination
  331 + :total="total"
  332 + v-model:current="queryParams.pageNo"
  333 + v-model:page-size="queryParams.pageSize"
  334 + show-size-changer
  335 + @change="getList"
  336 + />
  337 + </div>
  338 + </ContentWrap>
  339 +
  340 +#if ($table.templateType == 11) ## erp情况
  341 + <ContentWrap>
  342 + <!-- 子表的表单 -->
  343 + <Tabs v-model:active-key="subTabsName">
  344 + #foreach ($subTable in $subTables)
  345 + #set ($index = $foreach.count - 1)
  346 + #set ($subClassNameVar = $subClassNameVars.get($index))
  347 + #set ($subSimpleClassName = $subSimpleClassNames.get($index))
  348 + #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
  349 + <Tabs.TabPane key="$subClassNameVar" tab="${subTable.classComment}" force-render>
  350 + <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
  351 + </Tabs.TabPane>
  352 + #end
  353 + </Tabs>
  354 + </ContentWrap>
  355 +#end
  356 + </Page>
  357 +</template>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +<script lang="ts" setup>
  6 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  7 +
  8 + import { useVbenModal } from '@vben/common-ui';
  9 + import { message } from 'ant-design-vue';
  10 +
  11 + import { computed, ref } from 'vue';
  12 + import { $t } from '#/locales';
  13 + import { useVbenForm } from '#/adapter/form';
  14 + import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  15 +
  16 + import { use${subSimpleClassName}FormSchema } from '../data';
  17 +
  18 + const emit = defineEmits(['success']);
  19 + const formData = ref<${simpleClassName}Api.${subSimpleClassName}>();
  20 + const getTitle = computed(() => {
  21 + return formData.value?.id
  22 + ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
  23 + : $t('ui.actionTitle.create', ['${subTable.classComment}']);
  24 + });
  25 +
  26 + const [Form, formApi] = useVbenForm({
  27 + layout: 'horizontal',
  28 + schema: use${subSimpleClassName}FormSchema(),
  29 + showDefaultActions: false
  30 + });
  31 +
  32 + const [Modal, modalApi] = useVbenModal({
  33 + async onConfirm() {
  34 + const { valid } = await formApi.validate();
  35 + if (!valid) {
  36 + return;
  37 + }
  38 +
  39 + modalApi.lock();
  40 + // 提交表单
  41 + const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName};
  42 + data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
  43 + try {
  44 + await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
  45 + // 关闭并提示
  46 + await modalApi.close();
  47 + emit('success');
  48 + message.success({
  49 + content: $t('ui.actionMessage.operationSuccess'),
  50 + key: 'action_process_msg',
  51 + });
  52 + } finally {
  53 + modalApi.lock(false);
  54 + }
  55 + },
  56 + async onOpenChange(isOpen: boolean) {
  57 + if (!isOpen) {
  58 + formData.value = undefined;
  59 + return;
  60 + }
  61 +
  62 + // 加载数据
  63 + let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
  64 + if (!data) {
  65 + return;
  66 + }
  67 + if (data.id) {
  68 + modalApi.lock();
  69 + try {
  70 + data = await get${subSimpleClassName}(data.id);
  71 + } finally {
  72 + modalApi.lock(false);
  73 + }
  74 + }
  75 + // 设置到 values
  76 + formData.value = data;
  77 + await formApi.setValues(formData.value);
  78 + },
  79 + });
  80 +</script>
  81 +
  82 +<template>
  83 + <Modal :title="getTitle">
  84 + <Form class="mx-4" />
  85 + </Modal>
  86 +</template>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_inner.vue.vm 0 → 100644
  1 +## 主表的 normal 和 inner 使用相同的 form 表单
  2 +#parse("codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm")
0 3 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subClassNameVar = $subClassNameVars.get($subIndex))
  6 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  7 +<script lang="ts" setup>
  8 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  9 +
  10 + import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  11 + import { $t } from '#/locales';
  12 +
  13 +#if ($subTable.subJoinMany) ## 一对多
  14 +import { Plus } from "@vben/icons";
  15 +import { Button, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
  16 +import type { OnActionClickParams } from '#/adapter/vxe-table';
  17 +import { useVbenVxeGrid } from '#/adapter/vxe-table';
  18 +import { use${subSimpleClassName}GridEditColumns } from '../data';
  19 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  20 +#else
  21 +import { useVbenForm } from '#/adapter/form';
  22 +import { use${subSimpleClassName}FormSchema } from '../data';
  23 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  24 +#end
  25 +
  26 +const props = defineProps<{
  27 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  28 +}>()
  29 +
  30 +#if ($subTable.subJoinMany) ## 一对多
  31 +/** 表格操作按钮的回调函数 */
  32 +function onActionClick({
  33 + code,
  34 + row,
  35 +}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) {
  36 + switch (code) {
  37 + case 'delete': {
  38 + onDelete(row);
  39 + break;
  40 + }
  41 + }
  42 +}
  43 +
  44 +const [Grid, gridApi] = useVbenVxeGrid({
  45 +gridOptions: {
  46 + columns: use${subSimpleClassName}GridEditColumns(onActionClick),
  47 + border: true,
  48 + showOverflow: true,
  49 + autoResize: true,
  50 + keepSource: true,
  51 + rowConfig: {
  52 + keyField: 'id',
  53 + },
  54 + pagerConfig: {
  55 + enabled: false,
  56 + },
  57 + toolbarConfig: {
  58 + enabled: false,
  59 + },
  60 +},
  61 +});
  62 +
  63 +/** 添加${subTable.classComment} */
  64 +const onAdd = async () => {
  65 + await gridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
  66 +}
  67 +
  68 +/** 删除${subTable.classComment} */
  69 +const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => {
  70 + await gridApi.grid.remove(row);
  71 +}
  72 +
  73 +/** 提供获取表格数据的方法供父组件调用 */
  74 +defineExpose({
  75 + getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {
  76 + const data = gridApi.grid.getData() as ${simpleClassName}Api.${subSimpleClassName}[];
  77 + const removeRecords = gridApi.grid.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  78 + const insertRecords = gridApi.grid.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
  79 + return data
  80 + .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
  81 + .concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
  82 + },
  83 +});
  84 +
  85 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  86 +watch(
  87 + () => props.${subJoinColumn.javaField},
  88 + async (val) => {
  89 + if (!val) {
  90 + return;
  91 + }
  92 + await nextTick();
  93 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  94 + },
  95 + { immediate: true },
  96 +);
  97 +#else
  98 +const [Form, formApi] = useVbenForm({
  99 +layout: 'horizontal',
  100 +schema: use${subSimpleClassName}FormSchema(),
  101 +showDefaultActions: false
  102 +});
  103 +
  104 +/** 暴露出表单校验方法和表单值获取方法 */
  105 +defineExpose({
  106 + validate: async () => {
  107 + const { valid } = await formApi.validate();
  108 + return valid;
  109 + },
  110 + getValues: formApi.getValues,
  111 +});
  112 +
  113 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  114 +watch(
  115 + () => props.${subJoinColumn.javaField},
  116 + async (val) => {
  117 + if (!val) {
  118 + return;
  119 + }
  120 + await nextTick();
  121 + await formApi.setValues(await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  122 + },
  123 + { immediate: true },
  124 +);
  125 +#end
  126 +</script>
  127 +
  128 +<template>
  129 +#if ($subTable.subJoinMany) ## 一对多
  130 + <Grid class="mx-4">
  131 + #foreach($column in $subColumns)
  132 + #if ($column.createOperation || $column.updateOperation)
  133 + #set ($javaField = $column.javaField)
  134 + #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
  135 + #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
  136 + <template #${javaField}="{ row }">
  137 + <Input v-model:value="row.${javaField}" />
  138 + </template>
  139 + #elseif($column.htmlType == "imageUpload")## 图片上传
  140 + <template #${javaField}="{ row }">
  141 + <UploadImg v-model:value="row.${javaField}" />
  142 + </template>
  143 + #elseif($column.htmlType == "fileUpload")## 文件上传
  144 + <template #${javaField}="{ row }">
  145 + <UploadFile v-model:value="row.${javaField}" />
  146 + </template>
  147 + #elseif($column.htmlType == "editor")## 文本编辑器
  148 + <template #${javaField}="{ row }">
  149 + <Textarea v-model:value="row.${javaField}" />
  150 + </template>
  151 + #elseif($column.htmlType == "select")## 下拉框
  152 + <template #${javaField}="{ row, column }">
  153 + <Select v-model:value="row.${javaField}" class="w-full">
  154 + <Select.Option v-for="option in column.params.options" :key="option.value" :value="option.value">
  155 + {{ option.label }}
  156 + </Select.Option>
  157 + </Select>
  158 + </template>
  159 + #elseif($column.htmlType == "checkbox")## 多选框
  160 + <template #${javaField}="{ row, column }">
  161 + <CheckboxGroup v-model:value="row.${javaField}" :options="column.params.options" />
  162 + </template>
  163 + #elseif($column.htmlType == "radio")## 单选框
  164 + <template #${javaField}="{ row, column }">
  165 + <RadioGroup v-model:value="row.${javaField}" :options="column.params.options" />
  166 + </template>
  167 + #elseif($column.htmlType == "datetime")## 时间框
  168 + <template #${javaField}="{ row }">
  169 + <DatePicker
  170 + v-model:value="row.${javaField}"
  171 + :showTime="true"
  172 + format="YYYY-MM-DD HH:mm:ss"
  173 + valueFormat='x'
  174 + />
  175 + </template>
  176 + #elseif($column.htmlType == "textarea")## 文本框
  177 + <template #${javaField}="{ row }">
  178 + <Textarea v-model:value="row.${javaField}" />
  179 + </template>
  180 + #end
  181 + #end
  182 + #end
  183 + </Grid>
  184 + <div class="flex justify-center -mt-4">
  185 + <Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${subTable.moduleName}:${simpleClassName_strikeCase}:create']">
  186 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  187 + </Button>
  188 + </div>
  189 +#else
  190 + <Form class="mx-4" />
  191 +#end
  192 +</template>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm 0 → 100644
  1 +#set ($subTable = $subTables.get($subIndex))##当前表
  2 +#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
  3 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  4 +#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
  6 +#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
  7 +#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  8 +<script lang="ts" setup>
  9 + import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-table';
  10 + import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  11 +
  12 +#if ($table.templateType == 11) ## erp
  13 + import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  14 +#end
  15 + import { useVbenModal } from '@vben/common-ui';
  16 + import { Button, message } from 'ant-design-vue';
  17 + import { Plus } from '@vben/icons';
  18 + import { #if($table.templateType != 11)ref,#end h, nextTick,watch } from 'vue';
  19 + import { $t } from '#/locales';
  20 + import { useVbenVxeGrid } from '#/adapter/vxe-table';
  21 +
  22 +
  23 +#if ($table.templateType == 11) ## erp
  24 + import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  25 + import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
  26 + #else
  27 + #if ($subTable.subJoinMany) ## 一对多
  28 + import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  29 + #else
  30 + import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  31 + #end
  32 + import { use${subSimpleClassName}GridColumns } from '../data';
  33 +#end
  34 +
  35 +const props = defineProps<{
  36 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
  37 +}>()
  38 +
  39 +#if ($table.templateType == 11) ## erp
  40 + const [FormModal, formModalApi] = useVbenModal({
  41 + connectedComponent: ${subSimpleClassName}Form,
  42 + destroyOnClose: true,
  43 + });
  44 +
  45 +/** 创建${subTable.classComment} */
  46 +function onCreate() {
  47 + if (!props.${subJoinColumn.javaField}){
  48 + message.warning("请先选择一个${table.classComment}!")
  49 + return
  50 + }
  51 + formModalApi.setData({${subJoinColumn.javaField}: props.${subJoinColumn.javaField}}).open();
  52 +}
  53 +
  54 +/** 编辑${subTable.classComment} */
  55 +function onEdit(row: ${simpleClassName}Api.${subSimpleClassName}) {
  56 + formModalApi.setData(row).open();
  57 +}
  58 +
  59 +/** 删除${subTable.classComment} */
  60 +async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
  61 + const hideLoading = message.loading({
  62 + content: $t('ui.actionMessage.deleting', [row.id]),
  63 + duration: 0,
  64 + key: 'action_process_msg',
  65 + });
  66 + try {
  67 + await delete${subSimpleClassName}(row.id as number);
  68 + message.success({
  69 + content: $t('ui.actionMessage.deleteSuccess', [row.id]),
  70 + key: 'action_process_msg',
  71 + });
  72 + onRefresh();
  73 + } catch {
  74 + hideLoading();
  75 + }
  76 +}
  77 +
  78 +/** 表格操作按钮的回调函数 */
  79 +function onActionClick({
  80 + code,
  81 + row,
  82 +}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) {
  83 + switch (code) {
  84 + case 'edit': {
  85 + onEdit(row);
  86 + break;
  87 + }
  88 + case 'delete': {
  89 + onDelete(row);
  90 + break;
  91 + }
  92 + }
  93 +}
  94 +
  95 +#end
  96 + const [Grid, gridApi] = useVbenVxeGrid({
  97 +#if ($table.templateType == 11)
  98 + formOptions: {
  99 + schema: use${subSimpleClassName}GridFormSchema(),
  100 + },
  101 +#end
  102 + gridOptions: {
  103 +#if ($table.templateType == 11)
  104 + columns: use${subSimpleClassName}GridColumns(onActionClick),
  105 + proxyConfig: {
  106 + ajax: {
  107 + query: async ({ page }, formValues) => {
  108 + if (!props.${subJoinColumn.javaField}){
  109 + return []
  110 + }
  111 + return await get${subSimpleClassName}Page({
  112 + pageNo: page.currentPage,
  113 + pageSize: page.pageSize,
  114 + ${subJoinColumn.javaField}: props.${subJoinColumn.javaField},
  115 + ...formValues,
  116 + });
  117 + },
  118 + },
  119 + },
  120 + pagerConfig: {
  121 + enabled: true,
  122 + },
  123 + toolbarConfig: {
  124 + refresh: { code: 'query' },
  125 + search: true,
  126 + },
  127 +#else
  128 + columns: use${subSimpleClassName}GridColumns(),
  129 + pagerConfig: {
  130 + enabled: false,
  131 + },
  132 + toolbarConfig: {
  133 + enabled: false,
  134 + },
  135 +#end
  136 + height: '600px',
  137 + rowConfig: {
  138 + keyField: 'id',
  139 + isHover: true,
  140 + },
  141 + } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>,
  142 + });
  143 +
  144 +/** 刷新表格 */
  145 +const onRefresh = async ()=> {
  146 +#if ($table.templateType == 11) ## erp
  147 + await gridApi.query();
  148 +#else
  149 + #if ($subTable.subJoinMany) ## 一对多
  150 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  151 + #else
  152 + await gridApi.grid.loadData([await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)]);
  153 + #end
  154 +#end
  155 +}
  156 +
  157 + /** 监听主表的关联字段的变化,加载对应的子表数据 */
  158 + watch(
  159 + () => props.${subJoinColumn.javaField},
  160 + async (val) => {
  161 + if (!val) {
  162 + return;
  163 + }
  164 + await nextTick();
  165 + await onRefresh()
  166 + },
  167 + { immediate: true },
  168 + );
  169 +</script>
  170 +
  171 +<template>
  172 + #if ($table.templateType == 11) ## erp
  173 + <FormModal @success="onRefresh" />
  174 + <Grid table-title="${subTable.classComment}列表">
  175 + <template #toolbar-tools>
  176 + <Button :icon="h(Plus)" type="primary" @click="onCreate" v-access:code="['${table.moduleName}:${simpleClassName_strikeCase}:create']">
  177 + {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
  178 + </Button>
  179 + </template>
  180 + </Grid>
  181 + #else
  182 + <Grid table-title="${subTable.classComment}列表" />
  183 + #end
  184 +</template>
0 185 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_inner.vue.vm 0 → 100644
  1 +## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
  2 +## 1)inner 使用 list 不分页,erp 使用 page 分页
  3 +## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
  4 +#parse("codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm")
0 5 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
... ... @@ -75,18 +75,10 @@ export function useFormSchema(): VbenFormSchema[] {
75 75 componentProps: {
76 76 placeholder: '请输入${comment}',
77 77 },
78   - #elseif($column.htmlType == "imageUpload")## 图片上传 TODO @puhui999:目前分成了图片和文件上传,可以不用 fileType 之类哈,可以用下;
79   - component: 'FileUpload',
80   - componentProps: {
81   - fileType: 'image',
82   - maxCount: 1,
83   - },
  78 + #elseif($column.htmlType == "imageUpload")## 图片上传
  79 + component: 'ImageUpload',
84 80 #elseif($column.htmlType == "fileUpload")## 文件上传
85 81 component: 'FileUpload',
86   - componentProps: {
87   - fileType: 'file',
88   - maxCount: 1,
89   - },
90 82 #elseif($column.htmlType == "editor")## 文本编辑器
91 83 component: 'RichTextarea',
92 84 #elseif($column.htmlType == "select")## 下拉框
... ... @@ -320,17 +312,9 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
320 312 placeholder: '请输入${comment}',
321 313 },
322 314 #elseif($column.htmlType == "imageUpload")## 图片上传
323   - component: 'FileUpload',
324   - componentProps: {
325   - fileType: 'image',
326   - maxCount: 1,
327   - },
  315 + component: 'ImageUpload',
328 316 #elseif($column.htmlType == "fileUpload")## 文件上传
329 317 component: 'FileUpload',
330   - componentProps: {
331   - fileType: 'file',
332   - maxCount: 1,
333   - },
334 318 #elseif($column.htmlType == "editor")## 文本编辑器
335 319 component: 'RichTextarea',
336 320 #elseif($column.htmlType == "select")## 下拉框
... ... @@ -603,17 +587,9 @@ export function use${subSimpleClassName}GridColumns(
603 587 placeholder: '请输入${comment}',
604 588 },
605 589 #elseif($column.htmlType == "imageUpload")## 图片上传
606   - component: 'FileUpload',
607   - componentProps: {
608   - fileType: 'image',
609   - maxCount: 1,
610   - },
  590 + component: 'ImageUpload',
611 591 #elseif($column.htmlType == "fileUpload")## 文件上传
612 592 component: 'FileUpload',
613   - componentProps: {
614   - fileType: 'file',
615   - maxCount: 1,
616   - },
617 593 #elseif($column.htmlType == "editor")## 文本编辑器
618 594 component: 'RichTextarea',
619 595 #elseif($column.htmlType == "select")## 下拉框
... ...