Commit c2f9bad3ad745713a665b718501cb7b3c75922ce

Authored by jason
2 parents 8be3a3f8 e7be2a03

Merge remote-tracking branch 'origin/develop' into develop

Showing 39 changed files with 923 additions and 852 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/enums/DbTypeEnum.java
@@ -60,6 +60,12 @@ public enum DbTypeEnum { @@ -60,6 +60,12 @@ public enum DbTypeEnum {
60 * 人大金仓 60 * 人大金仓
61 */ 61 */
62 KINGBASE_ES(DbType.KINGBASE_ES, "KingbaseES", "POSITION('#{value}' IN #{column}) <> 0"), 62 KINGBASE_ES(DbType.KINGBASE_ES, "KingbaseES", "POSITION('#{value}' IN #{column}) <> 0"),
  63 +
  64 + /**
  65 + * OceanBase
  66 + */
  67 + OCEAN_BASE(DbType.OCEAN_BASE, "OceanBase", "FIND_IN_SET('#{value}', #{column}) <> 0")
  68 +
63 ; 69 ;
64 70
65 public static final Map<String, DbTypeEnum> MAP_BY_NAME = Arrays.stream(values()) 71 public static final Map<String, DbTypeEnum> MAP_BY_NAME = Arrays.stream(values())
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
@@ -100,6 +100,10 @@ public class BpmModelMetaInfoVO { @@ -100,6 +100,10 @@ public class BpmModelMetaInfoVO {
100 @Schema(description = "任务后置通知设置", example = "{}") 100 @Schema(description = "任务后置通知设置", example = "{}")
101 private HttpRequestSetting taskAfterTriggerSetting; 101 private HttpRequestSetting taskAfterTriggerSetting;
102 102
  103 + @Schema(description = "自定义打印模板设置", example = "{}")
  104 + @Valid
  105 + private PrintTemplateSetting printTemplateSetting;
  106 +
103 @Schema(description = "流程 ID 规则") 107 @Schema(description = "流程 ID 规则")
104 @Data 108 @Data
105 @Valid 109 @Valid
@@ -180,4 +184,17 @@ public class BpmModelMetaInfoVO { @@ -180,4 +184,17 @@ public class BpmModelMetaInfoVO {
180 184
181 } 185 }
182 186
  187 + @Schema(description = "自定义打印模板设置")
  188 + @Data
  189 + public static class PrintTemplateSetting {
  190 +
  191 + @Schema(description = "是否自定义打印模板", example = "false")
  192 + @NotNull(message = "是否自定义打印模板不能为空")
  193 + private Boolean enable;
  194 +
  195 + @Schema(description = "打印模板", example = "<p></p>")
  196 + private String template;
  197 +
  198 + }
  199 +
183 } 200 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
9 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; 10 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
10 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; 11 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
11 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@@ -26,6 +27,7 @@ import jakarta.validation.Valid; @@ -26,6 +27,7 @@ import jakarta.validation.Valid;
26 import org.flowable.engine.history.HistoricProcessInstance; 27 import org.flowable.engine.history.HistoricProcessInstance;
27 import org.flowable.engine.repository.ProcessDefinition; 28 import org.flowable.engine.repository.ProcessDefinition;
28 import org.flowable.task.api.Task; 29 import org.flowable.task.api.Task;
  30 +import org.flowable.task.api.history.HistoricTaskInstance;
29 import org.springframework.security.access.prepost.PreAuthorize; 31 import org.springframework.security.access.prepost.PreAuthorize;
30 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
31 import org.springframework.web.bind.annotation.*; 33 import org.springframework.web.bind.annotation.*;
@@ -34,9 +36,11 @@ import java.util.List; @@ -34,9 +36,11 @@ import java.util.List;
34 import java.util.Map; 36 import java.util.Map;
35 import java.util.Set; 37 import java.util.Set;
36 38
  39 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
37 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 40 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
38 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
39 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 42 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  43 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
40 44
41 @Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” 45 @Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
42 @RestController 46 @RestController
@@ -192,8 +196,30 @@ public class BpmProcessInstanceController { @@ -192,8 +196,30 @@ public class BpmProcessInstanceController {
192 @GetMapping("/get-bpmn-model-view") 196 @GetMapping("/get-bpmn-model-view")
193 @Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用") 197 @Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用")
194 @Parameter(name = "id", description = "流程实例的编号", required = true) 198 @Parameter(name = "id", description = "流程实例的编号", required = true)
195 - public CommonResult<BpmProcessInstanceBpmnModelViewRespVO> getProcessInstanceBpmnModelView(@RequestParam(value = "id") String id) { 199 + public CommonResult<BpmProcessInstanceBpmnModelViewRespVO> getProcessInstanceBpmnModelView(
  200 + @RequestParam(value = "id") String id) {
196 return success(processInstanceService.getProcessInstanceBpmnModelView(id)); 201 return success(processInstanceService.getProcessInstanceBpmnModelView(id));
197 } 202 }
198 203
  204 + @GetMapping("/get-print-data")
  205 + @Operation(summary = "获得流程实例的打印数据")
  206 + @Parameter(name = "id", description = "流程实例的编号", required = true)
  207 + @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
  208 + public CommonResult<BpmProcessPrintDataRespVO> getProcessInstancePrintData(
  209 + @RequestParam("processInstanceId") String processInstanceId) {
  210 + HistoricProcessInstance historicProcessInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
  211 + if (historicProcessInstance == null) {
  212 + throw exception(PROCESS_INSTANCE_NOT_EXISTS);
  213 + }
  214 + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(historicProcessInstance.getStartUserId()));
  215 + DeptRespDTO dept = deptApi.getDept(startUser.getDeptId());
  216 + List<HistoricTaskInstance> tasks = taskService.getFinishedTaskListByProcessInstanceIdWithoutCancel(processInstanceId);
  217 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  218 + convertSet(tasks, item -> Long.valueOf(item.getAssignee())));
  219 + return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePrintData(historicProcessInstance,
  220 + processDefinitionService.getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId()),
  221 + tasks, userMap,
  222 + new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName())));
  223 + }
  224 +
199 } 225 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessPrintDataRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "管理后台 - 流程实例的打印数据 Response VO")
  9 +@Data
  10 +public class BpmProcessPrintDataRespVO {
  11 +
  12 + @Schema(description = "流程实例数据")
  13 + private BpmProcessInstanceRespVO processInstance;
  14 +
  15 + @Schema(description = "是否开启自定义打印模板", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  16 + private Boolean printTemplateEnable;
  17 +
  18 + @Schema(description = "自定义打印模板 HTML")
  19 + private String printTemplateHtml;
  20 +
  21 + @Schema(description = "审批任务列表")
  22 + private List<Task> tasks;
  23 +
  24 + @Schema(description = "流程任务")
  25 + @Data
  26 + public static class Task {
  27 +
  28 + @Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  29 + private String id;
  30 +
  31 + @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
  32 + private String name;
  33 +
  34 + @Schema(description = "签名 URL", example = "https://www.iocoder.cn/sign.png")
  35 + private String signPicUrl;
  36 +
  37 + @Schema(description = "任务描述", requiredMode = Schema.RequiredMode.REQUIRED)
  38 + private String description; // 该字段由后端拼接
  39 +
  40 + }
  41 +
  42 +}
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
1 package cn.iocoder.yudao.module.bpm.convert.task; 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.date.DateUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; 8 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  9 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 11 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; 12 import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
  13 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; 14 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; 15 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
13 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO; 16 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO;
14 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceBpmnModelViewRespVO; 17 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceBpmnModelViewRespVO;
15 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; 18 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
  19 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessPrintDataRespVO;
16 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; 20 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
17 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; 21 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
18 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; 22 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
19 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; 23 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
20 import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; 24 import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
  25 +import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
  26 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
21 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; 27 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
22 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; 28 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
23 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; 29 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
@@ -35,10 +41,7 @@ import org.mapstruct.Mapping; @@ -35,10 +41,7 @@ import org.mapstruct.Mapping;
35 import org.mapstruct.MappingTarget; 41 import org.mapstruct.MappingTarget;
36 import org.mapstruct.factory.Mappers; 42 import org.mapstruct.factory.Mappers;
37 43
38 -import java.util.HashSet;  
39 -import java.util.List;  
40 -import java.util.Map;  
41 -import java.util.Set; 44 +import java.util.*;
42 45
43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
44 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -292,4 +295,47 @@ public interface BpmProcessInstanceConvert { @@ -292,4 +295,47 @@ public interface BpmProcessInstanceConvert {
292 .setActivityNodes(activityNodes); 295 .setActivityNodes(activityNodes);
293 } 296 }
294 297
  298 + default BpmProcessPrintDataRespVO buildProcessInstancePrintData(HistoricProcessInstance historicProcessInstance,
  299 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  300 + List<HistoricTaskInstance> tasks,
  301 + Map<Long, AdminUserRespDTO> userMap,
  302 + UserSimpleBaseVO startUser) {
  303 + BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting = processDefinitionInfo.getPrintTemplateSetting();
  304 + BpmProcessPrintDataRespVO printData = new BpmProcessPrintDataRespVO();
  305 + // 打印模板是否开启
  306 + printData.setPrintTemplateEnable(printTemplateSetting != null && Boolean.TRUE.equals(printTemplateSetting.getEnable()));
  307 + // 流程相关数据
  308 + BpmProcessInstanceRespVO processInstance = new BpmProcessInstanceRespVO()
  309 + .setId(historicProcessInstance.getId()).setName(historicProcessInstance.getName())
  310 + .setBusinessKey(historicProcessInstance.getBusinessKey())
  311 + .setStartTime(DateUtils.of(historicProcessInstance.getStartTime()))
  312 + .setEndTime(DateUtils.of(historicProcessInstance.getEndTime()))
  313 + .setStartUser(startUser).setStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance))
  314 + .setFormVariables(historicProcessInstance.getProcessVariables())
  315 + .setProcessDefinition(BeanUtils.toBean(processDefinitionInfo, BpmProcessDefinitionRespVO.class));
  316 + printData.setProcessInstance(processInstance);
  317 + // 审批历史
  318 + List<BpmProcessPrintDataRespVO.Task> approveTasks = new ArrayList<>(tasks.size());
  319 + tasks.forEach(item -> {
  320 + Map<String, Object> taskLocalVariables = item.getTaskLocalVariables();
  321 + BpmProcessPrintDataRespVO.Task approveTask = new BpmProcessPrintDataRespVO.Task();
  322 + approveTask.setName(item.getName());
  323 + approveTask.setId(item.getId());
  324 + approveTask.setSignPicUrl((String) taskLocalVariables.get(BpmnVariableConstants.TASK_SIGN_PIC_URL));
  325 + approveTask.setDescription(StrUtil.format("{} / {} / {} / {} / {}",
  326 + userMap.get(Long.valueOf(item.getAssignee())).getNickname(),
  327 + item.getName(),
  328 + DateUtil.formatDateTime(item.getEndTime()),
  329 + BpmTaskStatusEnum.valueOf((Integer) taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_STATUS)).getName(),
  330 + taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_REASON)));
  331 + approveTasks.add(approveTask);
  332 + });
  333 + printData.setTasks(approveTasks);
  334 + // 自定义模板
  335 + if (printData.getPrintTemplateEnable() && printTemplateSetting != null) {
  336 + printData.setPrintTemplateHtml(printTemplateSetting.getTemplate());
  337 + }
  338 + return printData;
  339 + }
  340 +
295 } 341 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
@@ -224,4 +224,10 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -224,4 +224,10 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
224 @TableField(typeHandler = JacksonTypeHandler.class) 224 @TableField(typeHandler = JacksonTypeHandler.class)
225 private BpmModelMetaInfoVO.HttpRequestSetting taskAfterTriggerSetting; 225 private BpmModelMetaInfoVO.HttpRequestSetting taskAfterTriggerSetting;
226 226
  227 + /**
  228 + * 自定义打印模板设置
  229 + */
  230 + @TableField(typeHandler = JacksonTypeHandler.class)
  231 + private BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting;
  232 +
227 } 233 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
1 package cn.iocoder.yudao.module.bpm.enums.task; 1 package cn.iocoder.yudao.module.bpm.enums.task;
2 2
  3 +import cn.hutool.core.util.ArrayUtil;
3 import cn.iocoder.yudao.framework.common.core.ArrayValuable; 4 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
4 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 5 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
5 import lombok.AllArgsConstructor; 6 import lombok.AllArgsConstructor;
@@ -47,4 +48,8 @@ public enum BpmProcessInstanceStatusEnum implements ArrayValuable&lt;Integer&gt; { @@ -47,4 +48,8 @@ public enum BpmProcessInstanceStatusEnum implements ArrayValuable&lt;Integer&gt; {
47 APPROVE.getStatus(), REJECT.getStatus(), CANCEL.getStatus()); 48 APPROVE.getStatus(), REJECT.getStatus(), CANCEL.getStatus());
48 } 49 }
49 50
  51 + public static BpmProcessInstanceStatusEnum valueOf(Integer status) {
  52 + return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
  53 + }
  54 +
50 } 55 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java
1 package cn.iocoder.yudao.module.bpm.enums.task; 1 package cn.iocoder.yudao.module.bpm.enums.task;
2 2
  3 +import cn.hutool.core.util.ArrayUtil;
3 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
4 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 5 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
5 import lombok.AllArgsConstructor; 6 import lombok.AllArgsConstructor;
@@ -68,4 +69,8 @@ public enum BpmTaskStatusEnum { @@ -68,4 +69,8 @@ public enum BpmTaskStatusEnum {
68 return ObjUtil.equal(status, CANCEL.getStatus()); 69 return ObjUtil.equal(status, CANCEL.getStatus());
69 } 70 }
70 71
  72 + public static BpmTaskStatusEnum valueOf(Integer status) {
  73 + return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
  74 + }
  75 +
71 } 76 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
  5 +import cn.hutool.core.date.DatePattern;
5 import cn.hutool.core.date.DateUtil; 6 import cn.hutool.core.date.DateUtil;
6 import cn.hutool.core.lang.Assert; 7 import cn.hutool.core.lang.Assert;
7 import cn.hutool.core.map.MapUtil; 8 import cn.hutool.core.map.MapUtil;
@@ -13,6 +14,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -13,6 +14,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
13 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 14 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
14 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 15 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
15 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; 16 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
  17 +import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
16 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; 18 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
17 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; 19 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
18 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; 20 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
@@ -974,7 +976,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -974,7 +976,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
974 status); 976 status);
975 } 977 }
976 978
977 - // 1.3 如果子流程拒绝, 设置其父流程也为拒绝状态且结束父流程 979 + // 1.3 如果子流程拒绝,设置其父流程也为拒绝状态,且结束父流程
  980 + // 相关问题链接:https://t.zsxq.com/kZhyb
978 if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus()) 981 if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())
979 && StrUtil.isNotBlank(instance.getSuperExecutionId())) { 982 && StrUtil.isNotBlank(instance.getSuperExecutionId())) {
980 // 1.3.1 获取父流程实例 并标记为不通过 983 // 1.3.1 获取父流程实例 并标记为不通过
@@ -984,6 +987,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -984,6 +987,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
984 987
985 // 1.3.2 结束父流程。需要在子流程结束事务提交后执行 988 // 1.3.2 结束父流程。需要在子流程结束事务提交后执行
986 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 989 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  990 +
987 @Override 991 @Override
988 public void afterCompletion(int transactionStatus) { 992 public void afterCompletion(int transactionStatus) {
989 // 回滚情况,直接返回 993 // 回滚情况,直接返回
@@ -1043,7 +1047,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -1043,7 +1047,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
1043 runtimeService.setProcessInstanceName(instance.getProcessInstanceId(), name); 1047 runtimeService.setProcessInstanceName(instance.getProcessInstanceId(), name);
1044 } 1048 }
1045 1049
1046 - // 流程前置通知:需要在流程启动后(事务提交后)。variables 已设置。或者放在 PROCESS_STARTED 事件中处理,先放这里。 1050 + // 流程前置通知:需要在流程启动后(事务提交后),保证 variables 已设置
  1051 + // 相关问题链接:https://t.zsxq.com/DF7Kq
1047 if (ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) { 1052 if (ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
1048 return; 1053 return;
1049 } 1054 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
@@ -176,6 +176,14 @@ public interface BpmTaskService { @@ -176,6 +176,14 @@ public interface BpmTaskService {
176 */ 176 */
177 List<HistoricActivityInstance> getHistoricActivityListByExecutionId(String executionId); 177 List<HistoricActivityInstance> getHistoricActivityListByExecutionId(String executionId);
178 178
  179 + /**
  180 + * 获得指定流程实例的已完成的流程任务列表,不包含取消状态
  181 + *
  182 + * @param processInstanceId 流程实例的编号
  183 + * @return 流程任务列表
  184 + */
  185 + List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId);
  186 +
179 // ========== Update 写入相关方法 ========== 187 // ========== Update 写入相关方法 ==========
180 188
181 /** 189 /**
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -492,6 +492,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -492,6 +492,17 @@ public class BpmTaskServiceImpl implements BpmTaskService {
492 return historyService.createHistoricActivityInstanceQuery().executionId(executionId).list(); 492 return historyService.createHistoricActivityInstanceQuery().executionId(executionId).list();
493 } 493 }
494 494
  495 + @Override
  496 + public List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId) {
  497 + return historyService.createHistoricTaskInstanceQuery()
  498 + .finished()
  499 + .includeTaskLocalVariables()
  500 + .processInstanceId(processInstanceId)
  501 + .taskVariableValueNotEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS,
  502 + BpmTaskStatusEnum.CANCEL.getStatus())
  503 + .orderByHistoricTaskInstanceStartTime().asc().list();
  504 + }
  505 +
495 /** 506 /**
496 * 判断指定用户,是否是当前任务的审批人 507 * 判断指定用户,是否是当前任务的审批人
497 * 508 *
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenFrontTypeEnum.java
@@ -21,9 +21,8 @@ public enum CodegenFrontTypeEnum { @@ -21,9 +21,8 @@ public enum CodegenFrontTypeEnum {
21 VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版 21 VUE3_VBEN5_ANTD_SCHEMA(40), // Vue3 VBEN5 + ANTD + schema 模版
22 VUE3_VBEN5_ANTD_GENERAL(41), // Vue3 VBEN5 + ANTD 标准模版 22 VUE3_VBEN5_ANTD_GENERAL(41), // Vue3 VBEN5 + ANTD 标准模版
23 23
24 - // TODO @puhui999::50、51 会好点;  
25 - VUE3_VBEN5_EP_SCHEMA(42), // Vue3 VBEN5 + EP + schema 模版  
26 - VUE3_VBEN5_EP_GENERAL(43), // Vue3 VBEN5 + EP 标准模版 24 + VUE3_VBEN5_EP_SCHEMA(50), // Vue3 VBEN5 + EP + schema 模版
  25 + VUE3_VBEN5_EP_GENERAL(51), // Vue3 VBEN5 + EP 标准模版
27 ; 26 ;
28 27
29 /** 28 /**
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -343,7 +343,7 @@ public class CodegenEngine { @@ -343,7 +343,7 @@ public class CodegenEngine {
343 filePath = formatFilePath(filePath, bindingMap); 343 filePath = formatFilePath(filePath, bindingMap);
344 String content = templateEngine.getTemplate(vmPath).render(bindingMap); 344 String content = templateEngine.getTemplate(vmPath).render(bindingMap);
345 // 格式化代码 345 // 格式化代码
346 - content = prettyCode(content); 346 + content = prettyCode(content, vmPath);
347 result.put(filePath, content); 347 result.put(filePath, content);
348 } 348 }
349 349
@@ -383,11 +383,14 @@ public class CodegenEngine { @@ -383,11 +383,14 @@ public class CodegenEngine {
383 * 如果不处理,Vue 的 Pretty 格式校验可能会报错 383 * 如果不处理,Vue 的 Pretty 格式校验可能会报错
384 * 384 *
385 * @param content 格式化前的代码 385 * @param content 格式化前的代码
  386 + * @param vmPath 模板路径
386 * @return 格式化后的代码 387 * @return 格式化后的代码
387 */ 388 */
388 - private String prettyCode(String content) {  
389 - // Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错  
390 - content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }"); 389 + private String prettyCode(String content, String vmPath) {
  390 + // Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(需要排除 vben5)
  391 + if (!StrUtil.contains(vmPath, "vben5")) {
  392 + content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
  393 + }
391 // Vue 界面:去除多的 dateFormatter,只有一个的情况下,说明没使用到 394 // Vue 界面:去除多的 dateFormatter,只有一个的情况下,说明没使用到
392 if (StrUtil.count(content, "dateFormatter") == 1) { 395 if (StrUtil.count(content, "dateFormatter") == 1) {
393 content = StrUtils.removeLineContains(content, "dateFormatter"); 396 content = StrUtils.removeLineContains(content, "dateFormatter");
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/api/api.ts.vm
@@ -98,7 +98,7 @@ export function delete${simpleClassName}List(ids: number[]) { @@ -98,7 +98,7 @@ export function delete${simpleClassName}List(ids: number[]) {
98 98
99 /** 导出${table.classComment} */ 99 /** 导出${table.classComment} */
100 export function export${simpleClassName}(params: any) { 100 export function export${simpleClassName}(params: any) {
101 - return requestClient.download('${baseURL}/export-excel', params); 101 + return requestClient.download('${baseURL}/export-excel', { params });
102 } 102 }
103 103
104 ## 特殊:主子表专属逻辑 104 ## 特殊:主子表专属逻辑
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm
1 <script lang="ts" setup> 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'; 2 import type { Rule } from 'ant-design-vue/es/form';
  3 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  4 +
  5 +import { computed, ref } from 'vue';
4 6
5 import { useVbenModal } from '@vben/common-ui'; 7 import { useVbenModal } from '@vben/common-ui';
  8 +import { DICT_TYPE } from '@vben/constants';
  9 +import { getDictOptions } from '@vben/hooks';
6 import { Tinymce as RichTextarea } from '#/components/tinymce'; 10 import { Tinymce as RichTextarea } from '#/components/tinymce';
7 import { ImageUpload, FileUpload } from "#/components/upload"; 11 import { ImageUpload, FileUpload } from "#/components/upload";
8 import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue'; 12 import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
9 -import { DICT_TYPE, getDictOptions } from '#/utils';  
10 #if($table.templateType == 2)## 树表需要导入这些 13 #if($table.templateType == 2)## 树表需要导入这些
11 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 14 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
12 import { handleTree } from '@vben/utils' 15 import { handleTree } from '@vben/utils'
@@ -20,7 +23,6 @@ import { handleTree } from &#39;@vben/utils&#39; @@ -20,7 +23,6 @@ import { handleTree } from &#39;@vben/utils&#39;
20 #end 23 #end
21 #end 24 #end
22 25
23 -import { computed, ref } from 'vue';  
24 import { $t } from '#/locales'; 26 import { $t } from '#/locales';
25 import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 27 import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
26 28
@@ -70,7 +72,7 @@ const getTitle = computed(() =&gt; { @@ -70,7 +72,7 @@ const getTitle = computed(() =&gt; {
70 #end 72 #end
71 73
72 /** 重置表单 */ 74 /** 重置表单 */
73 -const resetForm = () => { 75 +function resetForm() {
74 formData.value = { 76 formData.value = {
75 #foreach ($column in $columns) 77 #foreach ($column in $columns)
76 #if ($column.createOperation || $column.updateOperation) 78 #if ($column.createOperation || $column.updateOperation)
@@ -88,7 +90,7 @@ const resetForm = () =&gt; { @@ -88,7 +90,7 @@ const resetForm = () =&gt; {
88 ## 特殊:树表专属逻辑 90 ## 特殊:树表专属逻辑
89 #if ( $table.templateType == 2 ) 91 #if ( $table.templateType == 2 )
90 /** 获得${table.classComment}树 */ 92 /** 获得${table.classComment}树 */
91 -const get${simpleClassName}Tree = async () => { 93 +async function get${simpleClassName}Tree() {
92 ${classNameVar}Tree.value = [] 94 ${classNameVar}Tree.value = []
93 const data = await get${simpleClassName}List({}); 95 const data = await get${simpleClassName}List({});
94 data.unshift({ 96 data.unshift({
@@ -147,7 +149,6 @@ const [Modal, modalApi] = useVbenModal({ @@ -147,7 +149,6 @@ const [Modal, modalApi] = useVbenModal({
147 emit('success'); 149 emit('success');
148 message.success({ 150 message.success({
149 content: $t('ui.actionMessage.operationSuccess'), 151 content: $t('ui.actionMessage.operationSuccess'),
150 - key: 'action_process_msg',  
151 }); 152 });
152 } finally { 153 } finally {
153 modalApi.unlock(); 154 modalApi.unlock();
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
3 -import type { VxeTableInstance } from '#/adapter/vxe-table'; 3 +
  4 +import { ref, h, reactive, onMounted, nextTick } from 'vue';
4 5
5 import { Page, useVbenModal } from '@vben/common-ui'; 6 import { Page, useVbenModal } from '@vben/common-ui';
6 -import { cloneDeep, formatDateTime } from '@vben/utils'; 7 +import { DICT_TYPE } from '@vben/constants';
  8 +import { getDictOptions } from '@vben/hooks';
  9 +import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
  10 +import { cloneDeep, downloadFileFromBlobPart, formatDateTime } from '@vben/utils';
7 import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue'; 11 import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue';
8 -import { DictTag } from '#/components/dict-tag';  
9 -import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';  
10 import ${simpleClassName}Form from './modules/form.vue'; 12 import ${simpleClassName}Form from './modules/form.vue';
11 import { Download, Plus, RefreshCw, Search, Trash2 } from '@vben/icons'; 13 import { Download, Plus, RefreshCw, Search, Trash2 } from '@vben/icons';
12 import { ContentWrap } from '#/components/content-wrap'; 14 import { ContentWrap } from '#/components/content-wrap';
13 import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; 15 import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
14 -import { TableToolbar } from '#/components/table-toolbar';  
15 -import { useTableToolbar } from '#/hooks';  
16 16
17 ## 特殊:主子表专属逻辑 17 ## 特殊:主子表专属逻辑
18 #if ( $table.templateType == 11 || $table.templateType == 12 ) 18 #if ( $table.templateType == 11 || $table.templateType == 12 )
@@ -23,7 +23,6 @@ import { useTableToolbar } from &#39;#/hooks&#39;; @@ -23,7 +23,6 @@ import { useTableToolbar } from &#39;#/hooks&#39;;
23 #end 23 #end
24 #end 24 #end
25 25
26 -import { ref, h, reactive,onMounted,nextTick } from 'vue';  
27 import { $t } from '#/locales'; 26 import { $t } from '#/locales';
28 #if (${table.templateType} == 2)## 树表接口 27 #if (${table.templateType} == 2)## 树表接口
29 import { handleTree,isEmpty } from '@vben/utils' 28 import { handleTree,isEmpty } from '@vben/utils'
@@ -77,7 +76,7 @@ const queryFormRef = ref() // 搜索的表单 @@ -77,7 +76,7 @@ const queryFormRef = ref() // 搜索的表单
77 const exportLoading = ref(false) // 导出的加载中 76 const exportLoading = ref(false) // 导出的加载中
78 77
79 /** 查询列表 */ 78 /** 查询列表 */
80 -const getList = async () => { 79 +async function getList() {
81 loading.value = true 80 loading.value = true
82 try { 81 try {
83 const params = cloneDeep(queryParams) as any; 82 const params = cloneDeep(queryParams) as any;
@@ -104,7 +103,7 @@ const getList = async () =&gt; { @@ -104,7 +103,7 @@ const getList = async () =&gt; {
104 } 103 }
105 104
106 /** 搜索按钮操作 */ 105 /** 搜索按钮操作 */
107 -const handleQuery = () => { 106 +function handleQuery() {
108 #if ( $table.templateType != 2 ) 107 #if ( $table.templateType != 2 )
109 queryParams.pageNo = 1 108 queryParams.pageNo = 1
110 #end 109 #end
@@ -112,7 +111,7 @@ const handleQuery = () =&gt; { @@ -112,7 +111,7 @@ const handleQuery = () =&gt; {
112 } 111 }
113 112
114 /** 重置按钮操作 */ 113 /** 重置按钮操作 */
115 -const resetQuery = () => { 114 +function resetQuery() {
116 queryFormRef.value.resetFields() 115 queryFormRef.value.resetFields()
117 handleQuery() 116 handleQuery()
118 } 117 }
@@ -144,14 +143,10 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) { @@ -144,14 +143,10 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
144 const hideLoading = message.loading({ 143 const hideLoading = message.loading({
145 content: $t('ui.actionMessage.deleting', [row.id]), 144 content: $t('ui.actionMessage.deleting', [row.id]),
146 duration: 0, 145 duration: 0,
147 - key: 'action_process_msg',  
148 }); 146 });
149 try { 147 try {
150 - await delete${simpleClassName}(row.id as number);  
151 - message.success({  
152 - content: $t('ui.actionMessage.deleteSuccess', [row.id]),  
153 - key: 'action_process_msg',  
154 - }); 148 + await delete${simpleClassName}(row.id!);
  149 + message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
155 await getList(); 150 await getList();
156 } finally { 151 } finally {
157 hideLoading(); 152 hideLoading();
@@ -164,12 +159,11 @@ async function handleDeleteBatch() { @@ -164,12 +159,11 @@ async function handleDeleteBatch() {
164 const hideLoading = message.loading({ 159 const hideLoading = message.loading({
165 content: $t('ui.actionMessage.deleting'), 160 content: $t('ui.actionMessage.deleting'),
166 duration: 0, 161 duration: 0,
167 - key: 'action_process_msg',  
168 }); 162 });
169 try { 163 try {
170 await delete${simpleClassName}List(checkedIds.value); 164 await delete${simpleClassName}List(checkedIds.value);
171 checkedIds.value = []; 165 checkedIds.value = [];
172 - message.success( $t('ui.actionMessage.deleteSuccess') ); 166 + message.success($t('ui.actionMessage.deleteSuccess'));
173 await getList(); 167 await getList();
174 } finally { 168 } finally {
175 hideLoading(); 169 hideLoading();
@@ -187,7 +181,7 @@ function handleRowCheckboxChange({ @@ -187,7 +181,7 @@ function handleRowCheckboxChange({
187 #end 181 #end
188 182
189 /** 导出表格 */ 183 /** 导出表格 */
190 -async function onExport() { 184 +async function handleExport() {
191 try { 185 try {
192 exportLoading.value = true; 186 exportLoading.value = true;
193 const data = await export${simpleClassName}(queryParams); 187 const data = await export${simpleClassName}(queryParams);
@@ -200,7 +194,7 @@ try { @@ -200,7 +194,7 @@ try {
200 #if (${table.templateType} == 2) 194 #if (${table.templateType} == 2)
201 /** 切换树形展开/收缩状态 */ 195 /** 切换树形展开/收缩状态 */
202 const isExpanded = ref(true); 196 const isExpanded = ref(true);
203 -function toggleExpand() { 197 +function handleExpand() {
204 isExpanded.value = !isExpanded.value; 198 isExpanded.value = !isExpanded.value;
205 tableRef.value?.setAllTreeExpand(isExpanded.value); 199 tableRef.value?.setAllTreeExpand(isExpanded.value);
206 } 200 }
@@ -303,12 +297,12 @@ onMounted(() =&gt; { @@ -303,12 +297,12 @@ onMounted(() =&gt; {
303 <!-- 列表 --> 297 <!-- 列表 -->
304 <ContentWrap title="${table.classComment}"> 298 <ContentWrap title="${table.classComment}">
305 <template #extra> 299 <template #extra>
306 - <TableToolbar 300 + <VbenVxeTableToolbar
307 ref="tableToolbarRef" 301 ref="tableToolbarRef"
308 v-model:hidden-search="hiddenSearchBar" 302 v-model:hidden-search="hiddenSearchBar"
309 > 303 >
310 #if (${table.templateType} == 2) 304 #if (${table.templateType} == 2)
311 - <Button @click="toggleExpand" class="mr-2"> 305 + <Button @click="handleExpand" class="mr-2">
312 {{ isExpanded ? '收缩' : '展开' }} 306 {{ isExpanded ? '收缩' : '展开' }}
313 </Button> 307 </Button>
314 #end 308 #end
@@ -326,7 +320,7 @@ onMounted(() =&gt; { @@ -326,7 +320,7 @@ onMounted(() =&gt; {
326 type="primary" 320 type="primary"
327 class="ml-2" 321 class="ml-2"
328 :loading="exportLoading" 322 :loading="exportLoading"
329 - @click="onExport" 323 + @click="handleExport"
330 v-access:code="['${permissionPrefix}:export']" 324 v-access:code="['${permissionPrefix}:export']"
331 > 325 >
332 {{ $t('ui.actionTitle.export') }} 326 {{ $t('ui.actionTitle.export') }}
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm
@@ -3,107 +3,109 @@ @@ -3,107 +3,109 @@
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 <script lang="ts" setup> 5 <script lang="ts" setup>
6 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
7 - import type { Rule } from 'ant-design-vue/es/form'; 6 +import type { Rule } from 'ant-design-vue/es/form';
  7 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
8 8
9 - import { useVbenModal } from '@vben/common-ui';  
10 - import { Tinymce as RichTextarea } from '#/components/tinymce';  
11 - import { ImageUpload, FileUpload } from "#/components/upload";  
12 - import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';  
13 - import { DICT_TYPE, getDictOptions } from '#/utils'; 9 +import { computed, ref } from 'vue';
14 10
15 - import { computed, ref } from 'vue';  
16 - import { $t } from '#/locales'; 11 +import { useVbenModal } from '@vben/common-ui';
  12 +import { DICT_TYPE } from '@vben/constants';
  13 +import { getDictOptions } from '@vben/hooks';
  14 +import { cloneDeep, formatDateTime } from '@vben/utils';
  15 +import { Tinymce as RichTextarea } from '#/components/tinymce';
  16 +import { ImageUpload, FileUpload } from "#/components/upload";
  17 +import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
17 18
18 - import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 19 +import { $t } from '#/locales';
19 20
20 - const emit = defineEmits(['success']);  
21 - const getTitle = computed(() => {  
22 - return formData.value?.id  
23 - ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])  
24 - : $t('ui.actionTitle.create', ['${subTable.classComment}']);  
25 - }); 21 +import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
26 22
27 - const formRef = ref();  
28 - const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({  
29 - #foreach ($column in $subColumns)  
30 - #if ($column.createOperation || $column.updateOperation)  
31 - #if ($column.htmlType == "checkbox")  
32 - $column.javaField: [],  
33 - #else  
34 - $column.javaField: undefined,  
35 - #end 23 +const emit = defineEmits(['success']);
  24 +const getTitle = computed(() => {
  25 + return formData.value?.id
  26 + ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
  27 + : $t('ui.actionTitle.create', ['${subTable.classComment}']);
  28 +});
  29 +
  30 +const formRef = ref();
  31 +const formData = ref<Partial<${simpleClassName}Api.${subSimpleClassName}>>({
  32 + #foreach ($column in $subColumns)
  33 + #if ($column.createOperation || $column.updateOperation)
  34 + #if ($column.htmlType == "checkbox")
  35 + $column.javaField: [],
  36 + #else
  37 + $column.javaField: undefined,
36 #end 38 #end
37 #end 39 #end
38 - });  
39 - const rules: Record<string, Rule[]> = {  
40 - #foreach ($column in $subColumns)  
41 - #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键  
42 - #set($comment=$column.columnComment)  
43 - $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],  
44 - #end 40 + #end
  41 +});
  42 +const rules: Record<string, Rule[]> = {
  43 + #foreach ($column in $subColumns)
  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 }],
45 #end 47 #end
46 - }; 48 + #end
  49 +};
  50 +
  51 +const [Modal, modalApi] = useVbenModal({
  52 + async onConfirm() {
  53 + await formRef.value?.validate();
47 54
48 - const [Modal, modalApi] = useVbenModal({  
49 - async onConfirm() {  
50 - await formRef.value?.validate(); 55 + modalApi.lock();
  56 + // 提交表单
  57 + const data = formData.value as ${simpleClassName}Api.${subSimpleClassName};
  58 + try {
  59 + await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
  60 + // 关闭并提示
  61 + await modalApi.close();
  62 + emit('success');
  63 + message.success({
  64 + content: $t('ui.actionMessage.operationSuccess'),
  65 + });
  66 + } finally {
  67 + modalApi.unlock();
  68 + }
  69 + },
  70 + async onOpenChange(isOpen: boolean) {
  71 + if (!isOpen) {
  72 + resetForm()
  73 + return;
  74 + }
51 75
  76 + // 加载数据
  77 + let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();
  78 + if (!data) {
  79 + return;
  80 + }
  81 + if (data.id) {
52 modalApi.lock(); 82 modalApi.lock();
53 - // 提交表单  
54 - const data = formData.value as ${simpleClassName}Api.${subSimpleClassName};  
55 try { 83 try {
56 - await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));  
57 - // 关闭并提示  
58 - await modalApi.close();  
59 - emit('success');  
60 - message.success({  
61 - content: $t('ui.actionMessage.operationSuccess'),  
62 - key: 'action_process_msg',  
63 - }); 84 + data = await get${subSimpleClassName}(data.id);
64 } finally { 85 } finally {
65 modalApi.unlock(); 86 modalApi.unlock();
66 } 87 }
67 - },  
68 - async onOpenChange(isOpen: boolean) {  
69 - if (!isOpen) {  
70 - resetForm()  
71 - return;  
72 - } 88 + }
  89 + // 设置到 values
  90 + formData.value = data;
  91 + },
  92 +});
73 93
74 - // 加载数据  
75 - let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>();  
76 - if (!data) {  
77 - return;  
78 - }  
79 - if (data.id) {  
80 - modalApi.lock();  
81 - try {  
82 - data = await get${subSimpleClassName}(data.id);  
83 - } finally {  
84 - modalApi.unlock();  
85 - }  
86 - }  
87 - // 设置到 values  
88 - formData.value = data;  
89 - },  
90 - });  
91 -  
92 - /** 重置表单 */  
93 - const resetForm = () => {  
94 - formData.value = {  
95 - #foreach ($column in $subColumns)  
96 - #if ($column.createOperation || $column.updateOperation)  
97 - #if ($column.htmlType == "checkbox")  
98 - $column.javaField: [],  
99 - #else  
100 - $column.javaField: undefined,  
101 - #end 94 +/** 重置表单 */
  95 +function resetForm(){
  96 + formData.value = {
  97 + #foreach ($column in $subColumns)
  98 + #if ($column.createOperation || $column.updateOperation)
  99 + #if ($column.htmlType == "checkbox")
  100 + $column.javaField: [],
  101 + #else
  102 + $column.javaField: undefined,
102 #end 103 #end
103 #end 104 #end
104 - };  
105 - formRef.value?.resetFields();  
106 - } 105 + #end
  106 + };
  107 + formRef.value?.resetFields();
  108 +}
107 </script> 109 </script>
108 110
109 <template> 111 <template>
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm
@@ -5,12 +5,15 @@ @@ -5,12 +5,15 @@
5 #set ($subClassNameVar = $subClassNameVars.get($subIndex)) 5 #set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7 <script lang="ts" setup> 7 <script lang="ts" setup>
8 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 8 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
9 9
10 - import { message, Tabs, Form, Input, Textarea,Button, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue';  
11 - import { computed, ref, h, onMounted,watch,nextTick } from 'vue';  
12 - import { $t } from '#/locales';  
13 - import { DICT_TYPE, getDictOptions } from '#/utils'; 10 +import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  11 +
  12 +import { DICT_TYPE } from '@vben/constants';
  13 +import { getDictOptions } from '@vben/hooks';
  14 +
  15 +import { message, Tabs, Form, Input, Textarea,Button, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue';
  16 +import { $t } from '#/locales';
14 17
15 #if ($subTable.subJoinMany) ## 一对多 18 #if ($subTable.subJoinMany) ## 一对多
16 import type { VxeTableInstance } from '#/adapter/vxe-table'; 19 import type { VxeTableInstance } from '#/adapter/vxe-table';
@@ -30,13 +33,14 @@ const props = defineProps&lt;{ @@ -30,13 +33,14 @@ const props = defineProps&lt;{
30 #if ($subTable.subJoinMany) ## 一对多 33 #if ($subTable.subJoinMany) ## 一对多
31 const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据 34 const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
32 const tableRef = ref<VxeTableInstance>(); 35 const tableRef = ref<VxeTableInstance>();
  36 +
33 /** 添加${subTable.classComment} */ 37 /** 添加${subTable.classComment} */
34 -const onAdd = async () => { 38 +async function handleAdd() {
35 await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1); 39 await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
36 } 40 }
37 41
38 /** 删除${subTable.classComment} */ 42 /** 删除${subTable.classComment} */
39 -const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => { 43 +async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
40 await tableRef.value?.remove(row); 44 await tableRef.value?.remove(row);
41 } 45 }
42 46
@@ -46,9 +50,11 @@ defineExpose({ @@ -46,9 +50,11 @@ defineExpose({
46 const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[]; 50 const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[];
47 const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 51 const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
48 const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 52 const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
49 - return data  
50 - .filter((row) => !removeRecords.some((removed) => removed.id === row.id))  
51 - ?.concat(insertRecords.map((row: any) => ({ ...row, id: undefined }))); 53 + return [
  54 + ...data.filter(
  55 + (row) => !removeRecords.some((removed) => removed.id === row.id),
  56 + ),
  57 + ...insertRecords.map((row: any) => ({ ...row, id: undefined })),
52 }, 58 },
53 }); 59 });
54 60
@@ -123,25 +129,25 @@ watch( @@ -123,25 +129,25 @@ watch(
123 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写 129 #if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
124 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里 130 #elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
125 <vxe-column field="${javaField}" title="${comment}" align="center"> 131 <vxe-column field="${javaField}" title="${comment}" align="center">
126 - <template #default="{row}"> 132 + <template #default="{ row }">
127 <Input v-model:value="row.${javaField}" /> 133 <Input v-model:value="row.${javaField}" />
128 </template> 134 </template>
129 </vxe-column> 135 </vxe-column>
130 #elseif($column.htmlType == "imageUpload")## 图片上传 136 #elseif($column.htmlType == "imageUpload")## 图片上传
131 <vxe-column field="${javaField}" title="${comment}" align="center"> 137 <vxe-column field="${javaField}" title="${comment}" align="center">
132 - <template #default="{row}"> 138 + <template #default="{ row }">
133 <ImageUpload v-model:value="row.${javaField}" /> 139 <ImageUpload v-model:value="row.${javaField}" />
134 </template> 140 </template>
135 </vxe-column> 141 </vxe-column>
136 #elseif($column.htmlType == "fileUpload")## 文件上传 142 #elseif($column.htmlType == "fileUpload")## 文件上传
137 <vxe-column field="${javaField}" title="${comment}" align="center"> 143 <vxe-column field="${javaField}" title="${comment}" align="center">
138 - <template #default="{row}"> 144 + <template #default="{ row }">
139 <FileUpload v-model:value="row.${javaField}" /> 145 <FileUpload v-model:value="row.${javaField}" />
140 </template> 146 </template>
141 </vxe-column> 147 </vxe-column>
142 #elseif($column.htmlType == "select")## 下拉框 148 #elseif($column.htmlType == "select")## 下拉框
143 <vxe-column field="${javaField}" title="${comment}" align="center"> 149 <vxe-column field="${javaField}" title="${comment}" align="center">
144 - <template #default="{row}"> 150 + <template #default="{ row }">
145 <Select v-model:value="row.${javaField}" placeholder="请选择${comment}"> 151 <Select v-model:value="row.${javaField}" placeholder="请选择${comment}">
146 #if ("" != $dictType)## 有数据字典 152 #if ("" != $dictType)## 有数据字典
147 <Select.Option 153 <Select.Option
@@ -159,7 +165,7 @@ watch( @@ -159,7 +165,7 @@ watch(
159 </vxe-column> 165 </vxe-column>
160 #elseif($column.htmlType == "checkbox")## 多选框 166 #elseif($column.htmlType == "checkbox")## 多选框
161 <vxe-column field="${javaField}" title="${comment}" align="center"> 167 <vxe-column field="${javaField}" title="${comment}" align="center">
162 - <template #default="{row}"> 168 + <template #default="{ row }">
163 <CheckboxGroup v-model:value="row.${javaField}"> 169 <CheckboxGroup v-model:value="row.${javaField}">
164 #if ("" != $dictType)## 有数据字典 170 #if ("" != $dictType)## 有数据字典
165 <Checkbox 171 <Checkbox
@@ -177,7 +183,7 @@ watch( @@ -177,7 +183,7 @@ watch(
177 </vxe-column> 183 </vxe-column>
178 #elseif($column.htmlType == "radio")## 单选框 184 #elseif($column.htmlType == "radio")## 单选框
179 <vxe-column field="${javaField}" title="${comment}" align="center"> 185 <vxe-column field="${javaField}" title="${comment}" align="center">
180 - <template #default="{row}"> 186 + <template #default="{ row }">
181 <RadioGroup v-model:value="row.${javaField}"> 187 <RadioGroup v-model:value="row.${javaField}">
182 #if ("" != $dictType)## 有数据字典 188 #if ("" != $dictType)## 有数据字典
183 <Radio 189 <Radio
@@ -195,7 +201,7 @@ watch( @@ -195,7 +201,7 @@ watch(
195 </vxe-column> 201 </vxe-column>
196 #elseif($column.htmlType == "datetime")## 时间框 202 #elseif($column.htmlType == "datetime")## 时间框
197 <vxe-column field="${javaField}" title="${comment}" align="center"> 203 <vxe-column field="${javaField}" title="${comment}" align="center">
198 - <template #default="{row}"> 204 + <template #default="{ row }">
199 <DatePicker 205 <DatePicker
200 v-model:value="row.${javaField}" 206 v-model:value="row.${javaField}"
201 :showTime="true" 207 :showTime="true"
@@ -206,7 +212,7 @@ watch( @@ -206,7 +212,7 @@ watch(
206 </vxe-column> 212 </vxe-column>
207 #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框 213 #elseif($column.htmlType == "textarea" || $column.htmlType == "editor")## 文本框
208 <vxe-column field="${javaField}" title="${comment}" align="center"> 214 <vxe-column field="${javaField}" title="${comment}" align="center">
209 - <template #default="{row}"> 215 + <template #default="{ row }">
210 <Textarea v-model:value="row.${javaField}" /> 216 <Textarea v-model:value="row.${javaField}" />
211 </template> 217 </template>
212 </vxe-column> 218 </vxe-column>
@@ -214,12 +220,12 @@ watch( @@ -214,12 +220,12 @@ watch(
214 #end 220 #end
215 #end 221 #end
216 <vxe-column field="operation" title="操作" align="center"> 222 <vxe-column field="operation" title="操作" align="center">
217 - <template #default="{row}"> 223 + <template #default="{ row }">
218 <Button 224 <Button
219 size="small" 225 size="small"
220 type="link" 226 type="link"
221 danger 227 danger
222 - @click="onDelete(row as any)" 228 + @click="handleDelect(row)"
223 v-access:code="['${permissionPrefix}:delete']" 229 v-access:code="['${permissionPrefix}:delete']"
224 > 230 >
225 {{ $t('ui.actionTitle.delete') }} 231 {{ $t('ui.actionTitle.delete') }}
@@ -228,7 +234,7 @@ watch( @@ -228,7 +234,7 @@ watch(
228 </vxe-column> 234 </vxe-column>
229 </vxe-table> 235 </vxe-table>
230 <div class="flex justify-center mt-4"> 236 <div class="flex justify-center mt-4">
231 - <Button :icon="h(Plus)" type="primary" ghost @click="onAdd" v-access:code="['${permissionPrefix}:create']"> 237 + <Button :icon="h(Plus)" type="primary" ghost @click="handleAdd" v-access:code="['${permissionPrefix}:create']">
232 {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }} 238 {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
233 </Button> 239 </Button>
234 </div> 240 </div>
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm
@@ -6,48 +6,50 @@ @@ -6,48 +6,50 @@
6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex)) 6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
8 <script lang="ts" setup> 8 <script lang="ts" setup>
9 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
10 - import type { VxeTableInstance } from '#/adapter/vxe-table'; 9 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  10 +import type { VxeTableInstance } from '#/adapter/vxe-table';
11 11
12 - import { DictTag } from '#/components/dict-tag';  
13 - import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';  
14 - import { VxeColumn, VxeTable } from '#/adapter/vxe-table';  
15 - import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';  
16 - import { cloneDeep, formatDateTime } from '@vben/utils';  
17 - import { ContentWrap } from '#/components/content-wrap'; 12 +import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
  13 +
  14 +import { DICT_TYPE } from '@vben/constants';
  15 +import { getDictOptions } from '@vben/hooks';
  16 +
  17 +import { DictTag } from '#/components/dict-tag';
  18 +import { getRangePickerDefaultProps } from '#/utils';
  19 +import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
  20 +import { ContentWrap } from '#/components/content-wrap';
18 21
19 #if ($table.templateType == 11) ## erp 22 #if ($table.templateType == 11) ## erp
20 - import { useVbenModal } from '@vben/common-ui';  
21 - import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'  
22 - import { Tinymce as RichTextarea } from '#/components/tinymce';  
23 - import { ImageUpload, FileUpload } from "#/components/upload";  
24 - import { message,Button, Tabs,Pagination, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox,RangePicker, DatePicker, TreeSelect } from 'ant-design-vue';  
25 - import { Plus, Trash2 } from '@vben/icons';  
26 - import { $t } from '#/locales';  
27 - import { TableToolbar } from '#/components/table-toolbar';  
28 - import { useTableToolbar } from '#/hooks'; 23 +import { useVbenModal } from '@vben/common-ui';
  24 +import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
  25 +import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
  26 +import { Tinymce as RichTextarea } from '#/components/tinymce';
  27 +import { ImageUpload, FileUpload } from "#/components/upload";
  28 +import { message,Button, Tabs,Pagination, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox,RangePicker, DatePicker, TreeSelect } from 'ant-design-vue';
  29 +import { Plus, Trash2 } from '@vben/icons';
  30 +import { $t } from '#/locales';
29 #end 31 #end
30 32
31 #if ($table.templateType == 11) ## erp 33 #if ($table.templateType == 11) ## erp
32 - import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
33 - import { isEmpty } from '@vben/utils';  
34 - #else  
35 - #if ($subTable.subJoinMany) ## 一对多  
36 - import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
37 - #else  
38 - import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';  
39 - #end 34 +import { delete${subSimpleClassName},#if ($deleteBatchEnable) delete${subSimpleClassName}List,#end get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  35 +import { isEmpty } from '@vben/utils';
  36 +#else
  37 +#if ($subTable.subJoinMany) ## 一对多
  38 +import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  39 +#else
  40 +import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
  41 +#end
40 #end 42 #end
41 43
42 const props = defineProps<{ 44 const props = defineProps<{
43 - ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段) 45 + ${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
44 }>() 46 }>()
45 47
46 #if ($table.templateType == 11) ## erp 48 #if ($table.templateType == 11) ## erp
47 - const [FormModal, formModalApi] = useVbenModal({  
48 - connectedComponent: ${subSimpleClassName}Form,  
49 - destroyOnClose: true,  
50 - }); 49 +const [FormModal, formModalApi] = useVbenModal({
  50 + connectedComponent: ${subSimpleClassName}Form,
  51 + destroyOnClose: true,
  52 +});
51 53
52 /** 创建${subTable.classComment} */ 54 /** 创建${subTable.classComment} */
53 function handleCreate() { 55 function handleCreate() {
@@ -68,14 +70,10 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { @@ -68,14 +70,10 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
68 const hideLoading = message.loading({ 70 const hideLoading = message.loading({
69 content: $t('ui.actionMessage.deleting', [row.id]), 71 content: $t('ui.actionMessage.deleting', [row.id]),
70 duration: 0, 72 duration: 0,
71 - key: 'action_process_msg',  
72 }); 73 });
73 try { 74 try {
74 - await delete${subSimpleClassName}(row.id as number);  
75 - message.success({  
76 - content: $t('ui.actionMessage.deleteSuccess', [row.id]),  
77 - key: 'action_process_msg',  
78 - }); 75 + await delete${subSimpleClassName}(row.id!);
  76 + message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
79 await getList(); 77 await getList();
80 } finally { 78 } finally {
81 hideLoading(); 79 hideLoading();
@@ -88,12 +86,11 @@ async function handleDeleteBatch() { @@ -88,12 +86,11 @@ async function handleDeleteBatch() {
88 const hideLoading = message.loading({ 86 const hideLoading = message.loading({
89 content: $t('ui.actionMessage.deleting'), 87 content: $t('ui.actionMessage.deleting'),
90 duration: 0, 88 duration: 0,
91 - key: 'action_process_msg',  
92 }); 89 });
93 try { 90 try {
94 await delete${subSimpleClassName}List(checkedIds.value); 91 await delete${subSimpleClassName}List(checkedIds.value);
95 checkedIds.value = []; 92 checkedIds.value = [];
96 - message.success( $t('ui.actionMessage.deleteSuccess') ); 93 + message.success($t('ui.actionMessage.deleteSuccess'));
97 await getList(); 94 await getList();
98 } finally { 95 } finally {
99 hideLoading(); 96 hideLoading();
@@ -111,87 +108,87 @@ function handleRowCheckboxChange({ @@ -111,87 +108,87 @@ function handleRowCheckboxChange({
111 #end 108 #end
112 #end 109 #end
113 110
114 - const loading = ref(true) // 列表的加载中  
115 - const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据 111 +const loading = ref(true) // 列表的加载中
  112 +const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
116 #if ($table.templateType == 11) ## erp 113 #if ($table.templateType == 11) ## erp
117 - const total = ref(0) // 列表的总页数 114 +const total = ref(0) // 列表的总页数
118 #end 115 #end
119 #if ($table.templateType == 11) ## erp 116 #if ($table.templateType == 11) ## erp
120 - const queryFormRef = ref() // 搜索的表单  
121 - const queryParams = reactive({  
122 - pageNo: 1,  
123 - pageSize: 10,  
124 - #foreach ($column in $subColumns)  
125 - #if ($column.listOperation)  
126 - #if ($column.listOperationCondition != 'BETWEEN')  
127 - $column.javaField: undefined,  
128 - #end  
129 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
130 - $column.javaField: undefined,  
131 - #end  
132 - #end 117 +const queryFormRef = ref() // 搜索的表单
  118 +const queryParams = reactive({
  119 + pageNo: 1,
  120 + pageSize: 10,
  121 + #foreach ($column in $subColumns)
  122 + #if ($column.listOperation)
  123 + #if ($column.listOperationCondition != 'BETWEEN')
  124 + $column.javaField: undefined,
133 #end 125 #end
134 - }) 126 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  127 + $column.javaField: undefined,
  128 + #end
  129 + #end
  130 + #end
  131 +})
135 132
136 /** 搜索按钮操作 */ 133 /** 搜索按钮操作 */
137 -const handleQuery = () => { 134 +function handleQuery() {
138 queryParams.pageNo = 1 135 queryParams.pageNo = 1
139 getList() 136 getList()
140 } 137 }
141 138
142 /** 重置按钮操作 */ 139 /** 重置按钮操作 */
143 -const resetQuery = () => { 140 +function resetQuery() {
144 queryFormRef.value.resetFields() 141 queryFormRef.value.resetFields()
145 handleQuery() 142 handleQuery()
146 } 143 }
147 #end 144 #end
148 /** 查询列表 */ 145 /** 查询列表 */
149 - const getList = async () => {  
150 - loading.value = true  
151 - try {  
152 - if (!props.${subJoinColumn.javaField}){  
153 - return []  
154 - }  
155 - ## 特殊:树表专属逻辑(树不需要分页接口)  
156 - #if ($table.templateType == 11) ## erp  
157 - const params = cloneDeep(queryParams) as any;  
158 - #foreach ($column in $columns)  
159 - #if ($column.listOperation)  
160 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
161 - if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {  
162 - params.${column.javaField} = (params.${column.javaField} as string[]).join(',');  
163 - }  
164 - #end  
165 - #end  
166 - #end  
167 - params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};  
168 - const data = await get${subSimpleClassName}Page(params)  
169 - list.value = data.list  
170 - total.value = data.total  
171 - #else  
172 - #if ($subTable.subJoinMany) ## 一对多  
173 - list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);  
174 - #else  
175 - list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];  
176 - #end  
177 - #end  
178 - } finally {  
179 - loading.value = false 146 +async function getList() {
  147 + loading.value = true
  148 + try {
  149 + if (!props.${subJoinColumn.javaField}){
  150 + return []
180 } 151 }
  152 + ## 特殊:树表专属逻辑(树不需要分页接口)
  153 + #if ($table.templateType == 11) ## erp
  154 + const params = cloneDeep(queryParams) as any;
  155 + #foreach ($column in $columns)
  156 + #if ($column.listOperation)
  157 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  158 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  159 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  160 + }
  161 + #end
  162 + #end
  163 + #end
  164 + params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};
  165 + const data = await get${subSimpleClassName}Page(params)
  166 + list.value = data.list
  167 + total.value = data.total
  168 + #else
  169 + #if ($subTable.subJoinMany) ## 一对多
  170 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  171 + #else
  172 + list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];
  173 + #end
  174 + #end
  175 + } finally {
  176 + loading.value = false
181 } 177 }
  178 +}
182 179
183 - /** 监听主表的关联字段的变化,加载对应的子表数据 */  
184 - watch(  
185 - () => props.${subJoinColumn.javaField},  
186 - async (val) => {  
187 - if (!val) {  
188 - return;  
189 - }  
190 - await nextTick();  
191 - await getList()  
192 - },  
193 - { immediate: true },  
194 - ); 180 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  181 +watch(
  182 + () => props.${subJoinColumn.javaField},
  183 + async (val) => {
  184 + if (!val) {
  185 + return;
  186 + }
  187 + await nextTick();
  188 + await getList()
  189 + },
  190 + { immediate: true },
  191 +);
195 192
196 #if ($table.templateType == 11) ## erp 193 #if ($table.templateType == 11) ## erp
197 /** 初始化 */ 194 /** 初始化 */
@@ -292,7 +289,7 @@ onMounted(() =&gt; { @@ -292,7 +289,7 @@ onMounted(() =&gt; {
292 <!-- 列表 --> 289 <!-- 列表 -->
293 <ContentWrap title="${table.classComment}"> 290 <ContentWrap title="${table.classComment}">
294 <template #extra> 291 <template #extra>
295 - <TableToolbar 292 + <VbenVxeTableToolbar
296 ref="tableToolbarRef" 293 ref="tableToolbarRef"
297 v-model:hidden-search="hiddenSearchBar" 294 v-model:hidden-search="hiddenSearchBar"
298 > 295 >
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/api/api.ts.vm
1 -import type { PageParam, PageResult } from '@vben/request';  
2 -import type { Dayjs } from 'dayjs';  
3 -  
4 -import { requestClient } from '#/api/request';  
5 -#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")  
6 -  
7 -export namespace ${simpleClassName}Api {  
8 -## 特殊:主子表专属逻辑  
9 -#foreach ($subTable in $subTables)  
10 - #set ($index = $foreach.count - 1)  
11 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
12 - #set ($subColumns = $subColumnsList.get($index))##当前字段数组  
13 - /** ${subTable.classComment}信息 */  
14 - export interface ${subSimpleClassName} {  
15 - #foreach ($column in $subColumns)  
16 - #if ($column.createOperation || $column.updateOperation)  
17 - #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")  
18 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}  
19 - #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")  
20 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}  
21 - #else  
22 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}  
23 - #end  
24 - #end  
25 - #end  
26 - }  
27 -  
28 -#end  
29 - /** ${table.classComment}信息 */  
30 - export interface ${simpleClassName} {  
31 -#foreach ($column in $columns)  
32 -#if ($column.createOperation || $column.updateOperation)  
33 -#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")  
34 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: number; // ${column.columnComment}  
35 -#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")  
36 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: string | Dayjs; // ${column.columnComment}  
37 -#else  
38 - ${column.javaField}#if($column.updateOperation && !$column.primaryKey && !$column.nullable)?#end: ${column.javaType.toLowerCase()}; // ${column.columnComment}  
39 -#end  
40 -#end  
41 -#end  
42 -#if ( $table.templateType == 2 )  
43 - children?: ${simpleClassName}[];  
44 -#end  
45 -## 特殊:主子表专属逻辑  
46 -#if ( $table.templateType == 10 || $table.templateType == 12 )  
47 - #foreach ($subTable in $subTables)  
48 - #set ($index = $foreach.count - 1)  
49 - #set ($subSimpleClassName = $subSimpleClassNames.get($index))  
50 - #if ( $subTable.subJoinMany )  
51 - ${subSimpleClassName.toLowerCase()}s?: ${subSimpleClassName}[]  
52 - #else  
53 - ${subSimpleClassName.toLowerCase()}?: ${subSimpleClassName}  
54 - #end  
55 - #end  
56 -#end  
57 - }  
58 -}  
59 -  
60 -#if ( $table.templateType != 2 )  
61 -/** 查询${table.classComment}分页 */  
62 -export function get${simpleClassName}Page(params: PageParam) {  
63 - return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params });  
64 -}  
65 -#else  
66 -/** 查询${table.classComment}列表 */  
67 -export function get${simpleClassName}List(params: any) {  
68 - return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params });  
69 -}  
70 -#end  
71 -  
72 -/** 查询${table.classComment}详情 */  
73 -export function get${simpleClassName}(id: number) {  
74 - return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`);  
75 -}  
76 -  
77 -/** 新增${table.classComment} */  
78 -export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {  
79 - return requestClient.post('${baseURL}/create', data);  
80 -}  
81 -  
82 -/** 修改${table.classComment} */  
83 -export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) {  
84 - return requestClient.put('${baseURL}/update', data);  
85 -}  
86 -  
87 -/** 删除${table.classComment} */  
88 -export function delete${simpleClassName}(id: number) {  
89 - return requestClient.delete(`${baseURL}/delete?id=${id}`);  
90 -}  
91 -  
92 -#if ( $table.templateType != 2 && $deleteBatchEnable)  
93 -/** 批量删除${table.classComment} */  
94 -export function delete${simpleClassName}List(ids: number[]) {  
95 - return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`)  
96 -}  
97 -#end  
98 -  
99 -/** 导出${table.classComment} */  
100 -export function export${simpleClassName}(params: any) {  
101 - return requestClient.download('${baseURL}/export-excel', params);  
102 -}  
103 -  
104 -## 特殊:主子表专属逻辑  
105 -#foreach ($subTable in $subTables)  
106 -#set ($index = $foreach.count - 1)  
107 -#set ($subSimpleClassName = $subSimpleClassNames.get($index))  
108 -#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段  
109 -#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段  
110 -#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写  
111 -#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))  
112 -#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))  
113 -#set ($subClassNameVar = $subClassNameVars.get($index))  
114 -  
115 -// ==================== 子表($subTable.classComment) ====================  
116 -  
117 -## 情况一:MASTER_ERP 时,需要分查询页子表  
118 -#if ( $table.templateType == 11 )  
119 -/** 获得${subTable.classComment}分页 */  
120 -export function get${subSimpleClassName}Page(params: PageParam) {  
121 - return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params });  
122 -}  
123 -## 情况二:非 MASTER_ERP 时,需要列表查询子表  
124 -#else  
125 - #if ( $subTable.subJoinMany )  
126 -/** 获得${subTable.classComment}列表 */  
127 -export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {  
128 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);  
129 -}  
130 - #else  
131 -/** 获得${subTable.classComment} */  
132 -export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {  
133 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`);  
134 -}  
135 - #end  
136 -#end  
137 -## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作  
138 -#if ( $table.templateType == 11 )  
139 -/** 新增${subTable.classComment} */  
140 -export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {  
141 - return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);  
142 -}  
143 -  
144 -/** 修改${subTable.classComment} */  
145 -export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) {  
146 - return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);  
147 -}  
148 -  
149 -/** 删除${subTable.classComment} */  
150 -export function delete${subSimpleClassName}(id: number) {  
151 - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete?id=${id}`);  
152 -}  
153 -  
154 -#if ($deleteBatchEnable)  
155 -/** 批量删除${subTable.classComment} */  
156 -export function delete${subSimpleClassName}List(ids: number[]) {  
157 - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`)  
158 -}  
159 -#end  
160 -  
161 -/** 获得${subTable.classComment} */  
162 -export function get${subSimpleClassName}(id: number) {  
163 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`);  
164 -}  
165 -#end  
166 -#end  
167 - 1 +#parse("codegen/vue3_vben5_ele/schema/api/api.ts.vm")
168 \ No newline at end of file 2 \ No newline at end of file
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 import type { VbenFormSchema } from '#/adapter/form'; 2 import type { VbenFormSchema } from '#/adapter/form';
2 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 3 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
3 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 4 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
4 5
5 -import { z } from '#/adapter/form';  
6 -import {  
7 - DICT_TYPE,  
8 - getDictOptions,  
9 - getRangePickerDefaultProps,  
10 -} from '#/utils'; 6 +import { DICT_TYPE } from '@vben/constants';
  7 +import { getDictOptions } from '@vben/hooks';
11 #if(${table.templateType} == 2)## 树表需要导入这些 8 #if(${table.templateType} == 2)## 树表需要导入这些
12 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}'; 9 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
13 import { handleTree } from '@vben/utils'; 10 import { handleTree } from '@vben/utils';
14 #end 11 #end
15 12
  13 +import { getRangePickerDefaultProps } from '#/utils';
  14 +
16 /** 新增/修改的表单 */ 15 /** 新增/修改的表单 */
17 export function useFormSchema(): VbenFormSchema[] { 16 export function useFormSchema(): VbenFormSchema[] {
18 return [ 17 return [
@@ -186,7 +185,7 @@ export function useGridFormSchema(): VbenFormSchema[] { @@ -186,7 +185,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
186 } 185 }
187 186
188 /** 列表的字段 */ 187 /** 列表的字段 */
189 -export function useGridColumns(): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] { 188 +export function useGridColumns(): VxeTableGridOptions<${apiName}.${simpleClassName}>['columns'] {
190 return [ 189 return [
191 #if ($table.templateType != 2 && $deleteBatchEnable) 190 #if ($table.templateType != 2 && $deleteBatchEnable)
192 { type: 'checkbox', width: 40 }, 191 { type: 'checkbox', width: 40 },
@@ -389,7 +388,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] { @@ -389,7 +388,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
389 } 388 }
390 389
391 /** 列表的字段 */ 390 /** 列表的字段 */
392 -export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] { 391 +export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${apiName}.${subSimpleClassName}>['columns'] {
393 return [ 392 return [
394 #if ($table.templateType != 2 && $deleteBatchEnable) 393 #if ($table.templateType != 2 && $deleteBatchEnable)
395 { type: 'checkbox', width: 40 }, 394 { type: 'checkbox', width: 40 },
@@ -426,7 +425,7 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim @@ -426,7 +425,7 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim
426 #else 425 #else
427 #if ($subTable.subJoinMany) ## 一对多 426 #if ($subTable.subJoinMany) ## 一对多
428 /** 新增/修改列表的字段 */ 427 /** 新增/修改列表的字段 */
429 - export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] { 428 + export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${apiName}.${subSimpleClassName}>['columns'] {
430 return [ 429 return [
431 #foreach($column in $subColumns) 430 #foreach($column in $subColumns)
432 #if ($column.createOperation || $column.updateOperation) 431 #if ($column.createOperation || $column.updateOperation)
@@ -602,4 +601,4 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim @@ -602,4 +601,4 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim
602 } 601 }
603 #end 602 #end
604 #end 603 #end
605 -#end 604 -#end
  605 +#end
606 \ No newline at end of file 606 \ No newline at end of file
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 <script lang="ts" setup> 2 <script lang="ts" setup>
2 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 3 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
  4 +
  5 +import { computed, ref } from 'vue';
3 6
4 import { useVbenModal } from '@vben/common-ui'; 7 import { useVbenModal } from '@vben/common-ui';
5 -import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue'; 8 +
  9 +import { message#if ($table.templateType == 11), Tabs#end } from 'ant-design-vue';
  10 +
  11 +import { useVbenForm } from '#/adapter/form';
  12 +import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  13 +import { $t } from '#/locales';
6 ## 特殊:主子表专属逻辑 14 ## 特殊:主子表专属逻辑
7 #if ( $table.templateType == 10 || $table.templateType == 12 ) 15 #if ( $table.templateType == 10 || $table.templateType == 12 )
8 #foreach ($subSimpleClassName in $subSimpleClassNames) 16 #foreach ($subSimpleClassName in $subSimpleClassNames)
@@ -12,21 +20,15 @@ import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGro @@ -12,21 +20,15 @@ import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGro
12 #end 20 #end
13 #end 21 #end
14 22
15 -import { computed, ref } from 'vue';  
16 -import { $t } from '#/locales';  
17 -import { useVbenForm } from '#/adapter/form';  
18 -import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';  
19 -  
20 import { useFormSchema } from '../data'; 23 import { useFormSchema } from '../data';
21 24
22 const emit = defineEmits(['success']); 25 const emit = defineEmits(['success']);
23 -const formData = ref<${simpleClassName}Api.${simpleClassName}>(); 26 +const formData = ref<${apiName}.${simpleClassName}>();
24 const getTitle = computed(() => { 27 const getTitle = computed(() => {
25 return formData.value?.id 28 return formData.value?.id
26 ? $t('ui.actionTitle.edit', ['${table.classComment}']) 29 ? $t('ui.actionTitle.edit', ['${table.classComment}'])
27 : $t('ui.actionTitle.create', ['${table.classComment}']); 30 : $t('ui.actionTitle.create', ['${table.classComment}']);
28 }); 31 });
29 -  
30 ## 特殊:主子表专属逻辑 32 ## 特殊:主子表专属逻辑
31 #if ( $table.templateType == 10 || $table.templateType == 12 ) 33 #if ( $table.templateType == 10 || $table.templateType == 12 )
32 #if ( $subTables && $subTables.size() > 0 ) 34 #if ( $subTables && $subTables.size() > 0 )
@@ -51,7 +53,7 @@ const [Form, formApi] = useVbenForm({ @@ -51,7 +53,7 @@ const [Form, formApi] = useVbenForm({
51 }, 53 },
52 layout: 'horizontal', 54 layout: 'horizontal',
53 schema: useFormSchema(), 55 schema: useFormSchema(),
54 - showDefaultActions: false 56 + showDefaultActions: false,
55 }); 57 });
56 58
57 const [Modal, modalApi] = useVbenModal({ 59 const [Modal, modalApi] = useVbenModal({
@@ -60,8 +62,8 @@ const [Modal, modalApi] = useVbenModal({ @@ -60,8 +62,8 @@ const [Modal, modalApi] = useVbenModal({
60 if (!valid) { 62 if (!valid) {
61 return; 63 return;
62 } 64 }
63 - ## 特殊:主子表专属逻辑  
64 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 65 +## 特殊:主子表专属逻辑
  66 +#if ( $table.templateType == 10 || $table.templateType == 12 )
65 #if ( $subTables && $subTables.size() > 0 ) 67 #if ( $subTables && $subTables.size() > 0 )
66 // 校验子表单 68 // 校验子表单
67 #foreach ($subTable in $subTables) 69 #foreach ($subTable in $subTables)
@@ -78,12 +80,12 @@ const [Modal, modalApi] = useVbenModal({ @@ -78,12 +80,12 @@ const [Modal, modalApi] = useVbenModal({
78 #end 80 #end
79 #end 81 #end
80 #end 82 #end
81 - #end 83 +#end
82 modalApi.lock(); 84 modalApi.lock();
83 // 提交表单 85 // 提交表单
84 - const data = (await formApi.getValues()) as ${simpleClassName}Api.${simpleClassName};  
85 - ## 特殊:主子表专属逻辑  
86 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 86 + const data = (await formApi.getValues()) as ${apiName}.${simpleClassName};
  87 +## 特殊:主子表专属逻辑
  88 +#if ( $table.templateType == 10 || $table.templateType == 12 )
87 #if ( $subTables && $subTables.size() > 0 ) 89 #if ( $subTables && $subTables.size() > 0 )
88 // 拼接子表的数据 90 // 拼接子表的数据
89 #foreach ($subTable in $subTables) 91 #foreach ($subTable in $subTables)
@@ -96,13 +98,13 @@ const [Modal, modalApi] = useVbenModal({ @@ -96,13 +98,13 @@ const [Modal, modalApi] = useVbenModal({
96 #end 98 #end
97 #end 99 #end
98 #end 100 #end
99 - #end 101 +#end
100 try { 102 try {
101 await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data)); 103 await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
102 // 关闭并提示 104 // 关闭并提示
103 await modalApi.close(); 105 await modalApi.close();
104 emit('success'); 106 emit('success');
105 - message.success( $t('ui.actionMessage.operationSuccess') ); 107 + message.success($t('ui.actionMessage.operationSuccess'));
106 } finally { 108 } finally {
107 modalApi.unlock(); 109 modalApi.unlock();
108 } 110 }
@@ -113,21 +115,24 @@ const [Modal, modalApi] = useVbenModal({ @@ -113,21 +115,24 @@ const [Modal, modalApi] = useVbenModal({
113 return; 115 return;
114 } 116 }
115 // 加载数据 117 // 加载数据
116 - let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();  
117 - if (!data) { 118 + const data = modalApi.getData<${apiName}.${simpleClassName}>();
  119 + if (!data || !data.id) {
  120 +#if (${table.templateType} == 2)## 树表特有
  121 + // 设置上级
  122 + await formApi.setValues(data);
  123 +#end
118 return; 124 return;
119 } 125 }
120 - if (data.id) {  
121 - modalApi.lock();  
122 - try {  
123 - data = await get${simpleClassName}(data.id);  
124 - } finally {  
125 - modalApi.unlock(); 126 + modalApi.lock();
  127 + try {
  128 + formData.value = await get${simpleClassName}(data.id);
  129 + // 设置到 values
  130 + if (formData.value) {
  131 + await formApi.setValues(formData.value);
126 } 132 }
  133 + } finally {
  134 + modalApi.unlock();
127 } 135 }
128 - // 设置到 values  
129 - formData.value = data;  
130 - await formApi.setValues(formData.value);  
131 }, 136 },
132 }); 137 });
133 </script> 138 </script>
@@ -135,8 +140,8 @@ const [Modal, modalApi] = useVbenModal({ @@ -135,8 +140,8 @@ const [Modal, modalApi] = useVbenModal({
135 <template> 140 <template>
136 <Modal :title="getTitle"> 141 <Modal :title="getTitle">
137 <Form class="mx-4" /> 142 <Form class="mx-4" />
138 - ## 特殊:主子表专属逻辑  
139 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 143 +## 特殊:主子表专属逻辑
  144 +#if ( $table.templateType == 10 || $table.templateType == 12 )
140 <!-- 子表的表单 --> 145 <!-- 子表的表单 -->
141 <Tabs v-model:active-key="subTabsName"> 146 <Tabs v-model:active-key="subTabsName">
142 #foreach ($subTable in $subTables) 147 #foreach ($subTable in $subTables)
@@ -149,6 +154,6 @@ const [Modal, modalApi] = useVbenModal({ @@ -149,6 +154,6 @@ const [Modal, modalApi] = useVbenModal({
149 </Tabs.TabPane> 154 </Tabs.TabPane>
150 #end 155 #end
151 </Tabs> 156 </Tabs>
152 - #end 157 +#end
153 </Modal> 158 </Modal>
154 </template> 159 </template>
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 <script lang="ts" setup> 2 <script lang="ts" setup>
2 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 3 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
3 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 4 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
4 5
5 -import { Page, useVbenModal } from '@vben/common-ui';  
6 -import { message,Tabs } from 'ant-design-vue';  
7 -import Form from './modules/form.vue'; 6 +import { ref } from 'vue';
8 7
9 -## 特殊:主子表专属逻辑  
10 -#if ( $table.templateType == 11 || $table.templateType == 12 )  
11 - #foreach ($subSimpleClassName in $subSimpleClassNames)  
12 - #set ($index = $foreach.count - 1)  
13 - #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))  
14 -import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'  
15 - #end  
16 -#end 8 +import {#if ($table.templateType != 2 && $deleteBatchEnable) confirm,#end Page, useVbenModal } from '@vben/common-ui';
  9 +import { downloadFileFromBlobPart#if ($table.templateType != 2 && $deleteBatchEnable), isEmpty#end } from '@vben/utils';
  10 +
  11 +import { message#if ($table.templateType == 11), Tabs#end } from 'ant-design-vue';
17 12
18 -import { ref, computed } from 'vue';  
19 -import { $t } from '#/locales';  
20 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; 13 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
21 #if (${table.templateType} == 2)## 树表接口 14 #if (${table.templateType} == 2)## 树表接口
22 -import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}'; 15 +import {
  16 + delete${simpleClassName},
  17 + export${simpleClassName},
  18 + get${simpleClassName}List,
  19 +} from '#/api/${table.moduleName}/${table.businessName}';
23 #else## 标准表接口 20 #else## 标准表接口
24 -import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}'; 21 +import {
  22 + delete${simpleClassName},#if ($deleteBatchEnable)
  23 +
  24 + delete${simpleClassName}List,#end
  25 + export${simpleClassName},
  26 + get${simpleClassName}Page,
  27 +} from '#/api/${table.moduleName}/${table.businessName}';
25 #end 28 #end
26 -import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; 29 +import { $t } from '#/locales';
27 30
28 import { useGridColumns, useGridFormSchema } from './data'; 31 import { useGridColumns, useGridFormSchema } from './data';
  32 +import Form from './modules/form.vue';
  33 +## 特殊:主子表专属逻辑
  34 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  35 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  36 + #set ($index = $foreach.count - 1)
  37 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  38 +import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue';
  39 + #end
  40 +#end
29 41
30 #if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况 42 #if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
31 /** 子表的列表 */ 43 /** 子表的列表 */
32 const subTabsName = ref('$subClassNameVars.get(0)') 44 const subTabsName = ref('$subClassNameVars.get(0)')
33 #if ($table.templateType == 11) 45 #if ($table.templateType == 11)
34 -const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>(); 46 +const select${simpleClassName} = ref<${apiName}.${simpleClassName}>();
35 #end 47 #end
36 #end 48 #end
37 -  
38 const [FormModal, formModalApi] = useVbenModal({ 49 const [FormModal, formModalApi] = useVbenModal({
39 connectedComponent: Form, 50 connectedComponent: Form,
40 destroyOnClose: true, 51 destroyOnClose: true,
41 }); 52 });
42 -  
43 #if (${table.templateType} == 2)## 树表特有:控制表格展开收缩 53 #if (${table.templateType} == 2)## 树表特有:控制表格展开收缩
  54 +
44 /** 切换树形展开/收缩状态 */ 55 /** 切换树形展开/收缩状态 */
45 const isExpanded = ref(true); 56 const isExpanded = ref(true);
46 -function toggleExpand() { 57 +function handleExpand() {
47 isExpanded.value = !isExpanded.value; 58 isExpanded.value = !isExpanded.value;
48 gridApi.grid.setAllTreeExpand(isExpanded.value); 59 gridApi.grid.setAllTreeExpand(isExpanded.value);
49 } 60 }
50 #end 61 #end
51 62
52 /** 刷新表格 */ 63 /** 刷新表格 */
53 -function onRefresh() { 64 +function handleRefresh() {
54 #if ($table.templateType == 12) ## 内嵌情况 65 #if ($table.templateType == 12) ## 内嵌情况
55 gridApi.reload(); 66 gridApi.reload();
56 #else 67 #else
@@ -60,34 +71,31 @@ function onRefresh() { @@ -60,34 +71,31 @@ function onRefresh() {
60 71
61 /** 创建${table.classComment} */ 72 /** 创建${table.classComment} */
62 function handleCreate() { 73 function handleCreate() {
63 - formModalApi.setData({}).open(); 74 + formModalApi.setData(null).open();
64 } 75 }
65 -  
66 -/** 编辑${table.classComment} */  
67 -function handleEdit(row: ${simpleClassName}Api.${simpleClassName}) {  
68 - formModalApi.setData(row).open();  
69 -}  
70 -  
71 #if (${table.templateType} == 2)## 树表特有:新增下级 76 #if (${table.templateType} == 2)## 树表特有:新增下级
72 -/** 新增下级${table.classComment} */  
73 -function handleAppend(row: ${simpleClassName}Api.${simpleClassName}) { 77 +
  78 +/** 添加下级${table.classComment} */
  79 +function handleAppend(row: ${apiName}.${simpleClassName}) {
74 formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open(); 80 formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
75 } 81 }
76 #end 82 #end
77 83
  84 +/** 编辑${table.classComment} */
  85 +function handleEdit(row: ${apiName}.${simpleClassName}) {
  86 + formModalApi.setData(row).open();
  87 +}
  88 +
78 /** 删除${table.classComment} */ 89 /** 删除${table.classComment} */
79 -async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) { 90 +async function handleDelete(row: ${apiName}.${simpleClassName}) {
80 const hideLoading = message.loading({ 91 const hideLoading = message.loading({
81 content: $t('ui.actionMessage.deleting', [row.id]), 92 content: $t('ui.actionMessage.deleting', [row.id]),
82 - key: 'action_key_msg', 93 + duration: 0,
83 }); 94 });
84 try { 95 try {
85 - await delete${simpleClassName}(row.id as number);  
86 - message.success({  
87 - content: $t('ui.actionMessage.deleteSuccess', [row.id]),  
88 - key: 'action_key_msg',  
89 - });  
90 - onRefresh(); 96 + await delete${simpleClassName}(row.id!);
  97 + message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  98 + handleRefresh();
91 } finally { 99 } finally {
92 hideLoading(); 100 hideLoading();
93 } 101 }
@@ -96,30 +104,28 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) { @@ -96,30 +104,28 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
96 #if ($table.templateType != 2 && $deleteBatchEnable) 104 #if ($table.templateType != 2 && $deleteBatchEnable)
97 /** 批量删除${table.classComment} */ 105 /** 批量删除${table.classComment} */
98 async function handleDeleteBatch() { 106 async function handleDeleteBatch() {
  107 + await confirm($t('ui.actionMessage.deleteBatchConfirm'));
99 const hideLoading = message.loading({ 108 const hideLoading = message.loading({
100 - content: $t('ui.actionMessage.deleting'),  
101 - key: 'action_key_msg', 109 + content: $t('ui.actionMessage.deletingBatch'),
  110 + duration: 0,
102 }); 111 });
103 try { 112 try {
104 await delete${simpleClassName}List(checkedIds.value); 113 await delete${simpleClassName}List(checkedIds.value);
105 checkedIds.value = []; 114 checkedIds.value = [];
106 - message.success({  
107 - content: $t('ui.actionMessage.deleteSuccess'),  
108 - key: 'action_key_msg',  
109 - });  
110 - onRefresh(); 115 + message.success($t('ui.actionMessage.deleteSuccess'));
  116 + handleRefresh();
111 } finally { 117 } finally {
112 hideLoading(); 118 hideLoading();
113 } 119 }
114 } 120 }
115 121
116 -const checkedIds = ref<number[]>([]) 122 +const checkedIds = ref<number[]>([]);
117 function handleRowCheckboxChange({ 123 function handleRowCheckboxChange({
118 records, 124 records,
119 }: { 125 }: {
120 - records: ${simpleClassName}Api.${simpleClassName}[]; 126 + records: ${apiName}.${simpleClassName}[];
121 }) { 127 }) {
122 - checkedIds.value = records.map((item) => item.id); 128 + checkedIds.value = records.map((item) => item.id!);
123 } 129 }
124 #end 130 #end
125 131
@@ -141,20 +147,11 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -141,20 +147,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
141 height: 'auto', 147 height: 'auto',
142 #end 148 #end
143 #if (${table.templateType} == 2)## 树表设置 149 #if (${table.templateType} == 2)## 树表设置
144 - treeConfig: {  
145 - parentField: '${treeParentColumn.javaField}',  
146 - rowField: 'id',  
147 - transform: true,  
148 - expandAll: true,  
149 - reserve: true,  
150 - },  
151 - pagerConfig: {  
152 - enabled: false,  
153 - },  
154 -#else## 标准表设置  
155 pagerConfig: { 150 pagerConfig: {
156 - enabled: true, 151 + enabled: false,
157 }, 152 },
  153 +#else## 标准表设置
  154 + keepSource: true,
158 #end 155 #end
159 proxyConfig: { 156 proxyConfig: {
160 ajax: { 157 ajax: {
@@ -184,27 +181,35 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -184,27 +181,35 @@ const [Grid, gridApi] = useVbenVxeGrid({
184 refresh: true, 181 refresh: true,
185 search: true, 182 search: true,
186 }, 183 },
187 - } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,  
188 -#if (${table.templateType} == 11 || $deleteBatchEnable)  
189 - gridEvents:{  
190 - #if(${table.templateType} == 11)  
191 - cellClick: ({ row }: { row: ${simpleClassName}Api.${simpleClassName}}) => { 184 +#if (${table.templateType} == 2)## 树表设置
  185 + treeConfig: {
  186 + parentField: '${treeParentColumn.javaField}',
  187 + rowField: 'id',
  188 + transform: true,
  189 + expandAll: true,
  190 + reserve: true,
  191 + },
  192 +#end
  193 + } as VxeTableGridOptions<${apiName}.${simpleClassName}>,
  194 +#if (${table.templateType} == 11 || (${table.templateType} != 2 && $deleteBatchEnable))
  195 + gridEvents: {
  196 + #if(${table.templateType} == 11)
  197 + cellClick: ({ row }: { row: ${apiName}.${simpleClassName}}) => {
192 select${simpleClassName}.value = row; 198 select${simpleClassName}.value = row;
193 }, 199 },
194 - #end  
195 - #if(${table.templateType} != 2 && $deleteBatchEnable)  
196 - checkboxAll: handleRowCheckboxChange,  
197 - checkboxChange: handleRowCheckboxChange,  
198 - #end  
199 - } 200 + #end
  201 + #if (${table.templateType} != 2 && $deleteBatchEnable)
  202 + checkboxAll: handleRowCheckboxChange,
  203 + checkboxChange: handleRowCheckboxChange,
  204 + #end
  205 + },
200 #end 206 #end
201 }); 207 });
202 </script> 208 </script>
203 209
204 <template> 210 <template>
205 <Page auto-content-height> 211 <Page auto-content-height>
206 - <FormModal @success="onRefresh" />  
207 - 212 + <FormModal @success="handleRefresh" />
208 #if ($table.templateType == 11) ## erp情况 213 #if ($table.templateType == 11) ## erp情况
209 <div> 214 <div>
210 #end 215 #end
@@ -228,13 +233,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -228,13 +233,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
228 <template #toolbar-tools> 233 <template #toolbar-tools>
229 <TableAction 234 <TableAction
230 :actions="[ 235 :actions="[
231 - #if (${table.templateType} == 2)## 树表特有:展开/收缩按钮  
232 - {  
233 - label: isExpanded ? '收缩' : '展开',  
234 - type: 'primary',  
235 - onClick: toggleExpand,  
236 - },  
237 - #end  
238 { 236 {
239 label: $t('ui.actionTitle.create', ['${table.classComment}']), 237 label: $t('ui.actionTitle.create', ['${table.classComment}']),
240 type: 'primary', 238 type: 'primary',
@@ -242,6 +240,13 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -242,6 +240,13 @@ const [Grid, gridApi] = useVbenVxeGrid({
242 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'], 240 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
243 onClick: handleCreate, 241 onClick: handleCreate,
244 }, 242 },
  243 + #if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
  244 + {
  245 + label: isExpanded ? '收缩' : '展开',
  246 + type: 'primary',
  247 + onClick: handleExpand,
  248 + },
  249 + #end
245 { 250 {
246 label: $t('ui.actionTitle.export'), 251 label: $t('ui.actionTitle.export'),
247 type: 'primary', 252 type: 'primary',
@@ -255,8 +260,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -255,8 +260,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
255 type: 'primary', 260 type: 'primary',
256 danger: true, 261 danger: true,
257 icon: ACTION_ICON.DELETE, 262 icon: ACTION_ICON.DELETE,
258 - disabled: isEmpty(checkedIds),  
259 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'], 263 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  264 + disabled: isEmpty(checkedIds),
260 onClick: handleDeleteBatch, 265 onClick: handleDeleteBatch,
261 }, 266 },
262 #end 267 #end
@@ -297,7 +302,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -297,7 +302,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
297 /> 302 />
298 </template> 303 </template>
299 </Grid> 304 </Grid>
300 -  
301 #if ($table.templateType == 11) ## erp情况 305 #if ($table.templateType == 11) ## erp情况
302 <!-- 子表的表单 --> 306 <!-- 子表的表单 -->
303 <Tabs v-model:active-key="subTabsName" class="mt-2"> 307 <Tabs v-model:active-key="subTabsName" class="mt-2">
@@ -314,4 +318,4 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -314,4 +318,4 @@ const [Grid, gridApi] = useVbenVxeGrid({
314 </div> 318 </div>
315 #end 319 #end
316 </Page> 320 </Page>
317 -</template> 321 -</template>
  322 +</template>
318 \ No newline at end of file 323 \ No newline at end of file
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_erp.vue.vm
@@ -2,8 +2,9 @@ @@ -2,8 +2,9 @@
2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
5 <script lang="ts" setup> 6 <script lang="ts" setup>
6 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 7 + import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
7 8
8 import { useVbenModal } from '@vben/common-ui'; 9 import { useVbenModal } from '@vben/common-ui';
9 import { message } from 'ant-design-vue'; 10 import { message } from 'ant-design-vue';
@@ -16,7 +17,7 @@ @@ -16,7 +17,7 @@
16 import { use${subSimpleClassName}FormSchema } from '../data'; 17 import { use${subSimpleClassName}FormSchema } from '../data';
17 18
18 const emit = defineEmits(['success']); 19 const emit = defineEmits(['success']);
19 - const formData = ref<${simpleClassName}Api.${subSimpleClassName}>(); 20 + const formData = ref<${apiName}.${subSimpleClassName}>();
20 const getTitle = computed(() => { 21 const getTitle = computed(() => {
21 return formData.value?.id 22 return formData.value?.id
22 ? $t('ui.actionTitle.edit', ['${subTable.classComment}']) 23 ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
@@ -45,7 +46,7 @@ @@ -45,7 +46,7 @@
45 46
46 modalApi.lock(); 47 modalApi.lock();
47 // 提交表单 48 // 提交表单
48 - const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName}; 49 + const data = (await formApi.getValues()) as ${apiName}.${subSimpleClassName};
49 data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField}; 50 data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
50 try { 51 try {
51 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data)); 52 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
@@ -64,7 +65,7 @@ @@ -64,7 +65,7 @@
64 } 65 }
65 66
66 // 加载数据 67 // 加载数据
67 - let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>(); 68 + let data = modalApi.getData<${apiName}.${subSimpleClassName}>();
68 if (!data) { 69 if (!data) {
69 return; 70 return;
70 } 71 }
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_normal.vue.vm
@@ -4,10 +4,12 @@ @@ -4,10 +4,12 @@
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 #set ($subClassNameVar = $subClassNameVars.get($subIndex)) 5 #set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  7 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
7 <script lang="ts" setup> 8 <script lang="ts" setup>
8 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 9 + import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
9 10
10 import { computed, ref, h, onMounted,watch,nextTick } from 'vue'; 11 import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  12 +
11 import { $t } from '#/locales'; 13 import { $t } from '#/locales';
12 14
13 #if ($subTable.subJoinMany) ## 一对多 15 #if ($subTable.subJoinMany) ## 一对多
@@ -33,7 +35,7 @@ const props = defineProps&lt;{ @@ -33,7 +35,7 @@ const props = defineProps&lt;{
33 function onActionClick({ 35 function onActionClick({
34 code, 36 code,
35 row, 37 row,
36 -}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) { 38 +}: OnActionClickParams<${apiName}.${subSimpleClassName}>) {
37 switch (code) { 39 switch (code) {
38 case 'delete': { 40 case 'delete': {
39 onDelete(row); 41 onDelete(row);
@@ -63,20 +65,20 @@ gridOptions: { @@ -63,20 +65,20 @@ gridOptions: {
63 65
64 /** 添加${subTable.classComment} */ 66 /** 添加${subTable.classComment} */
65 const onAdd = async () => { 67 const onAdd = async () => {
66 - await gridApi.grid.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1); 68 + await gridApi.grid.insertAt({} as ${apiName}.${subSimpleClassName}, -1);
67 } 69 }
68 70
69 /** 删除${subTable.classComment} */ 71 /** 删除${subTable.classComment} */
70 -const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => { 72 +const onDelete = async (row: ${apiName}.${subSimpleClassName}) => {
71 await gridApi.grid.remove(row); 73 await gridApi.grid.remove(row);
72 } 74 }
73 75
74 /** 提供获取表格数据的方法供父组件调用 */ 76 /** 提供获取表格数据的方法供父组件调用 */
75 defineExpose({ 77 defineExpose({
76 - getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {  
77 - const data = gridApi.grid.getData() as ${simpleClassName}Api.${subSimpleClassName}[];  
78 - const removeRecords = gridApi.grid.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];  
79 - const insertRecords = gridApi.grid.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 78 + getData: (): ${apiName}.${subSimpleClassName}[] => {
  79 + const data = gridApi.grid.getData() as ${apiName}.${subSimpleClassName}[];
  80 + const removeRecords = gridApi.grid.getRemoveRecords() as ${apiName}.${subSimpleClassName}[];
  81 + const insertRecords = gridApi.grid.getInsertRecords() as ${apiName}.${subSimpleClassName}[];
80 return data 82 return data
81 .filter((row) => !removeRecords.some((removed) => removed.id === row.id)) 83 .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
82 .concat(insertRecords.map((row: any) => ({ ...row, id: undefined }))); 84 .concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm
@@ -5,9 +5,10 @@ @@ -5,9 +5,10 @@
5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex)) 6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  8 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
8 <script lang="ts" setup> 9 <script lang="ts" setup>
9 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 10 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
10 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 11 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
11 12
12 #if ($table.templateType == 11) ## erp 13 #if ($table.templateType == 11) ## erp
13 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue' 14 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
@@ -51,23 +52,20 @@ function handleCreate() { @@ -51,23 +52,20 @@ function handleCreate() {
51 } 52 }
52 53
53 /** 编辑${subTable.classComment} */ 54 /** 编辑${subTable.classComment} */
54 -function handleEdit(row: ${simpleClassName}Api.${subSimpleClassName}) { 55 +function handleEdit(row: ${apiName}.${subSimpleClassName}) {
55 formModalApi.setData(row).open(); 56 formModalApi.setData(row).open();
56 } 57 }
57 58
58 /** 删除${subTable.classComment} */ 59 /** 删除${subTable.classComment} */
59 -async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { 60 +async function handleDelete(row: ${apiName}.${subSimpleClassName}) {
60 const hideLoading = message.loading({ 61 const hideLoading = message.loading({
61 content: $t('ui.actionMessage.deleting', [row.id]), 62 content: $t('ui.actionMessage.deleting', [row.id]),
62 - key: 'action_process_msg', 63 + duration: 0,
63 }); 64 });
64 try { 65 try {
65 - await delete${subSimpleClassName}(row.id as number);  
66 - message.success({  
67 - content: $t('ui.actionMessage.deleteSuccess', [row.id]),  
68 - key: 'action_key_msg',  
69 - });  
70 - onRefresh(); 66 + await delete${subSimpleClassName}(row.id!);
  67 + message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  68 + handleRefresh();
71 } finally { 69 } finally {
72 hideLoading(); 70 hideLoading();
73 } 71 }
@@ -78,16 +76,13 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { @@ -78,16 +76,13 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
78 async function handleDeleteBatch() { 76 async function handleDeleteBatch() {
79 const hideLoading = message.loading({ 77 const hideLoading = message.loading({
80 content: $t('ui.actionMessage.deleting'), 78 content: $t('ui.actionMessage.deleting'),
81 - key: 'action_key_msg', 79 + duration: 0,
82 }); 80 });
83 try { 81 try {
84 await delete${subSimpleClassName}List(checkedIds.value); 82 await delete${subSimpleClassName}List(checkedIds.value);
85 checkedIds.value = []; 83 checkedIds.value = [];
86 - message.success({  
87 - content: $t('ui.actionMessage.deleteSuccess', [row.id]),  
88 - key: 'action_key_msg',  
89 - });  
90 - onRefresh(); 84 + message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
  85 + handleRefresh();
91 } finally { 86 } finally {
92 hideLoading(); 87 hideLoading();
93 } 88 }
@@ -97,7 +92,7 @@ const checkedIds = ref&lt;number[]&gt;([]) @@ -97,7 +92,7 @@ const checkedIds = ref&lt;number[]&gt;([])
97 function handleRowCheckboxChange({ 92 function handleRowCheckboxChange({
98 records, 93 records,
99 }: { 94 }: {
100 - records: ${simpleClassName}Api.${subSimpleClassName}[]; 95 + records: ${apiName}.${subSimpleClassName}[];
101 }) { 96 }) {
102 checkedIds.value = records.map((item) => item.id); 97 checkedIds.value = records.map((item) => item.id);
103 } 98 }
@@ -149,7 +144,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -149,7 +144,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
149 keyField: 'id', 144 keyField: 'id',
150 isHover: true, 145 isHover: true,
151 }, 146 },
152 - } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>, 147 + } as VxeTableGridOptions<${apiName}.${subSimpleClassName}>,
153 #if (${table.templateType} == 11 && $deleteBatchEnable) 148 #if (${table.templateType} == 11 && $deleteBatchEnable)
154 gridEvents:{ 149 gridEvents:{
155 checkboxAll: handleRowCheckboxChange, 150 checkboxAll: handleRowCheckboxChange,
@@ -159,7 +154,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -159,7 +154,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
159 }); 154 });
160 155
161 /** 刷新表格 */ 156 /** 刷新表格 */
162 -async function onRefresh() { 157 +async function handleRefresh() {
163 #if ($table.templateType == 11) ## erp 158 #if ($table.templateType == 11) ## erp
164 await gridApi.query(); 159 await gridApi.query();
165 #else 160 #else
@@ -179,7 +174,7 @@ watch( @@ -179,7 +174,7 @@ watch(
179 return; 174 return;
180 } 175 }
181 await nextTick(); 176 await nextTick();
182 - await onRefresh() 177 + await handleRefresh()
183 }, 178 },
184 { immediate: true }, 179 { immediate: true },
185 ); 180 );
@@ -187,7 +182,7 @@ watch( @@ -187,7 +182,7 @@ watch(
187 182
188 <template> 183 <template>
189 #if ($table.templateType == 11) ## erp 184 #if ($table.templateType == 11) ## erp
190 - <FormModal @success="onRefresh" /> 185 + <FormModal @success="handleRefresh" />
191 <Grid table-title="${subTable.classComment}列表"> 186 <Grid table-title="${subTable.classComment}列表">
192 <template #toolbar-tools> 187 <template #toolbar-tools>
193 <TableAction 188 <TableAction
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/api/api.ts.vm
@@ -98,7 +98,7 @@ export function delete${simpleClassName}List(ids: number[]) { @@ -98,7 +98,7 @@ export function delete${simpleClassName}List(ids: number[]) {
98 98
99 /** 导出${table.classComment} */ 99 /** 导出${table.classComment} */
100 export function export${simpleClassName}(params: any) { 100 export function export${simpleClassName}(params: any) {
101 - return requestClient.download('${baseURL}/export-excel', params); 101 + return requestClient.download('${baseURL}/export-excel', { params });
102 } 102 }
103 103
104 ## 特殊:主子表专属逻辑 104 ## 特殊:主子表专属逻辑
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/form.vue.vm
@@ -3,10 +3,11 @@ import type { ${simpleClassName}Api } from &#39;#/api/${table.moduleName}/${simpleCl @@ -3,10 +3,11 @@ import type { ${simpleClassName}Api } from &#39;#/api/${table.moduleName}/${simpleCl
3 import type { FormRules } from 'element-plus'; 3 import type { FormRules } from 'element-plus';
4 4
5 import { useVbenModal } from '@vben/common-ui'; 5 import { useVbenModal } from '@vben/common-ui';
  6 +import { DICT_TYPE } from '@vben/constants';
  7 +import { getDictOptions } from '@vben/hooks';
6 import { Tinymce as RichTextarea } from '#/components/tinymce'; 8 import { Tinymce as RichTextarea } from '#/components/tinymce';
7 import { ImageUpload, FileUpload } from "#/components/upload"; 9 import { ImageUpload, FileUpload } from "#/components/upload";
8 import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus'; 10 import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus';
9 -import { DICT_TYPE, getDictOptions } from '#/utils';  
10 #if($table.templateType == 2)## 树表需要导入这些 11 #if($table.templateType == 2)## 树表需要导入这些
11 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 12 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
12 import { handleTree } from '@vben/utils' 13 import { handleTree } from '@vben/utils'
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/index.vue.vm
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 2 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
3 -import type { VxeTableInstance } from '#/adapter/vxe-table'; 3 +
  4 +import { ref, h, reactive, onMounted, nextTick } from 'vue';
4 5
5 import { Page, useVbenModal } from '@vben/common-ui'; 6 import { Page, useVbenModal } from '@vben/common-ui';
6 -import { cloneDeep, formatDateTime } from '@vben/utils'; 7 +import { DICT_TYPE } from '@vben/constants';
  8 +import { getDictOptions } from '@vben/hooks';
  9 +import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
  10 +import { cloneDeep, downloadFileFromBlobPart, formatDateTime } from '@vben/utils';
7 import { ElButton, ElMessage, ElLoading, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus'; 11 import { ElButton, ElMessage, ElLoading, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus';
8 -import { DictTag } from '#/components/dict-tag';  
9 -import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';  
10 import ${simpleClassName}Form from './modules/form.vue'; 12 import ${simpleClassName}Form from './modules/form.vue';
11 import { Download, Plus, RefreshCw, Search, Trash2 } from '@vben/icons'; 13 import { Download, Plus, RefreshCw, Search, Trash2 } from '@vben/icons';
12 import { ContentWrap } from '#/components/content-wrap'; 14 import { ContentWrap } from '#/components/content-wrap';
13 import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; 15 import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
14 -import { TableToolbar } from '#/components/table-toolbar';  
15 -import { useTableToolbar } from '#/hooks';  
16 16
17 ## 特殊:主子表专属逻辑 17 ## 特殊:主子表专属逻辑
18 #if ( $table.templateType == 11 || $table.templateType == 12 ) 18 #if ( $table.templateType == 11 || $table.templateType == 12 )
@@ -23,7 +23,6 @@ import { useTableToolbar } from &#39;#/hooks&#39;; @@ -23,7 +23,6 @@ import { useTableToolbar } from &#39;#/hooks&#39;;
23 #end 23 #end
24 #end 24 #end
25 25
26 -import { ref, h, reactive,onMounted,nextTick } from 'vue';  
27 import { $t } from '#/locales'; 26 import { $t } from '#/locales';
28 #if (${table.templateType} == 2)## 树表接口 27 #if (${table.templateType} == 2)## 树表接口
29 import { handleTree,isEmpty } from '@vben/utils' 28 import { handleTree,isEmpty } from '@vben/utils'
@@ -104,7 +103,7 @@ const getList = async () =&gt; { @@ -104,7 +103,7 @@ const getList = async () =&gt; {
104 } 103 }
105 104
106 /** 搜索按钮操作 */ 105 /** 搜索按钮操作 */
107 -const handleQuery = () => { 106 +function handleQuery() {
108 #if ( $table.templateType != 2 ) 107 #if ( $table.templateType != 2 )
109 queryParams.pageNo = 1 108 queryParams.pageNo = 1
110 #end 109 #end
@@ -112,7 +111,7 @@ const handleQuery = () =&gt; { @@ -112,7 +111,7 @@ const handleQuery = () =&gt; {
112 } 111 }
113 112
114 /** 重置按钮操作 */ 113 /** 重置按钮操作 */
115 -const resetQuery = () => { 114 +function resetQuery() {
116 queryFormRef.value.resetFields() 115 queryFormRef.value.resetFields()
117 handleQuery() 116 handleQuery()
118 } 117 }
@@ -182,7 +181,7 @@ function handleRowCheckboxChange({ @@ -182,7 +181,7 @@ function handleRowCheckboxChange({
182 #end 181 #end
183 182
184 /** 导出表格 */ 183 /** 导出表格 */
185 -async function onExport() { 184 +async function handleExport() {
186 try { 185 try {
187 exportLoading.value = true; 186 exportLoading.value = true;
188 const data = await export${simpleClassName}(queryParams); 187 const data = await export${simpleClassName}(queryParams);
@@ -195,7 +194,7 @@ try { @@ -195,7 +194,7 @@ try {
195 #if (${table.templateType} == 2) 194 #if (${table.templateType} == 2)
196 /** 切换树形展开/收缩状态 */ 195 /** 切换树形展开/收缩状态 */
197 const isExpanded = ref(true); 196 const isExpanded = ref(true);
198 -function toggleExpand() { 197 +function handleExpand() {
199 isExpanded.value = !isExpanded.value; 198 isExpanded.value = !isExpanded.value;
200 tableRef.value?.setAllTreeExpand(isExpanded.value); 199 tableRef.value?.setAllTreeExpand(isExpanded.value);
201 } 200 }
@@ -306,7 +305,7 @@ onMounted(() =&gt; { @@ -306,7 +305,7 @@ onMounted(() =&gt; {
306 v-model:hidden-search="hiddenSearchBar" 305 v-model:hidden-search="hiddenSearchBar"
307 > 306 >
308 #if (${table.templateType} == 2) 307 #if (${table.templateType} == 2)
309 - <el-button @click="toggleExpand" class="mr-2"> 308 + <el-button @click="handleExpand" class="mr-2">
310 {{ isExpanded ? '收缩' : '展开' }} 309 {{ isExpanded ? '收缩' : '展开' }}
311 </el-button> 310 </el-button>
312 #end 311 #end
@@ -324,7 +323,7 @@ onMounted(() =&gt; { @@ -324,7 +323,7 @@ onMounted(() =&gt; {
324 type="primary" 323 type="primary"
325 class="ml-2" 324 class="ml-2"
326 :loading="exportLoading" 325 :loading="exportLoading"
327 - @click="onExport" 326 + @click="handleExport"
328 v-access:code="['${permissionPrefix}:export']" 327 v-access:code="['${permissionPrefix}:export']"
329 > 328 >
330 {{ $t('ui.actionTitle.export') }} 329 {{ $t('ui.actionTitle.export') }}
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/form_sub_erp.vue.vm
@@ -6,13 +6,15 @@ @@ -6,13 +6,15 @@
6 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 6 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
7 import type { FormRules } from 'element-plus'; 7 import type { FormRules } from 'element-plus';
8 8
  9 + import { computed, ref, reactive } from 'vue';
  10 +
9 import { useVbenModal } from '@vben/common-ui'; 11 import { useVbenModal } from '@vben/common-ui';
  12 + import { DICT_TYPE } from '@vben/constants';
  13 + import { getDictOptions } from '@vben/hooks';
10 import { Tinymce as RichTextarea } from '#/components/tinymce'; 14 import { Tinymce as RichTextarea } from '#/components/tinymce';
11 import { ImageUpload, FileUpload } from "#/components/upload"; 15 import { ImageUpload, FileUpload } from "#/components/upload";
12 import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus'; 16 import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker, ElTreeSelect } from 'element-plus';
13 - import { DICT_TYPE, getDictOptions } from '#/utils';  
14 17
15 - import { computed, ref, reactive } from 'vue';  
16 import { $t } from '#/locales'; 18 import { $t } from '#/locales';
17 19
18 import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 20 import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/form_sub_normal.vue.vm
@@ -5,12 +5,15 @@ @@ -5,12 +5,15 @@
5 #set ($subClassNameVar = $subClassNameVars.get($subIndex)) 5 #set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
7 <script lang="ts" setup> 7 <script lang="ts" setup>
8 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 8 +import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
9 9
10 - import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElButton, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker } from 'element-plus';  
11 - import { computed, ref, reactive, h, onMounted,watch,nextTick } from 'vue';  
12 - import { $t } from '#/locales';  
13 - import { DICT_TYPE, getDictOptions } from '#/utils'; 10 +import { computed, ref, reactive, h, onMounted,watch,nextTick } from 'vue';
  11 +
  12 +import { DICT_TYPE } from '@vben/constants';
  13 +import { getDictOptions } from '@vben/hooks';
  14 +
  15 +import { ElMessage, ElTabs, ElTabPane, ElForm, ElFormItem, ElInput, ElButton, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCheckboxGroup, ElCheckbox, ElDatePicker } from 'element-plus';
  16 +import { $t } from '#/locales';
14 17
15 #if ($subTable.subJoinMany) ## 一对多 18 #if ($subTable.subJoinMany) ## 一对多
16 import type { VxeTableInstance } from '#/adapter/vxe-table'; 19 import type { VxeTableInstance } from '#/adapter/vxe-table';
@@ -31,12 +34,12 @@ const props = defineProps&lt;{ @@ -31,12 +34,12 @@ const props = defineProps&lt;{
31 const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据 34 const list = ref<${simpleClassName}Api.${subSimpleClassName}[]>([]) // 列表的数据
32 const tableRef = ref<VxeTableInstance>(); 35 const tableRef = ref<VxeTableInstance>();
33 /** 添加${subTable.classComment} */ 36 /** 添加${subTable.classComment} */
34 -const onAdd = async () => { 37 +async function handleAdd() {
35 await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1); 38 await tableRef.value?.insertAt({} as ${simpleClassName}Api.${subSimpleClassName}, -1);
36 } 39 }
37 40
38 /** 删除${subTable.classComment} */ 41 /** 删除${subTable.classComment} */
39 -const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => { 42 +async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
40 await tableRef.value?.remove(row); 43 await tableRef.value?.remove(row);
41 } 44 }
42 45
@@ -46,9 +49,11 @@ defineExpose({ @@ -46,9 +49,11 @@ defineExpose({
46 const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[]; 49 const data = list.value as ${simpleClassName}Api.${subSimpleClassName}[];
47 const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 50 const removeRecords = tableRef.value?.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
48 const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 51 const insertRecords = tableRef.value?.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[];
49 - return data  
50 - .filter((row) => !removeRecords.some((removed) => removed.id === row.id))  
51 - ?.concat(insertRecords.map((row: any) => ({ ...row, id: undefined }))); 52 + return [
  53 + ...data.filter(
  54 + (row) => !removeRecords.some((removed) => removed.id === row.id),
  55 + ),
  56 + ...insertRecords.map((row: any) => ({ ...row, id: undefined })),
52 }, 57 },
53 }); 58 });
54 59
@@ -227,7 +232,7 @@ watch( @@ -227,7 +232,7 @@ watch(
227 </vxe-column> 232 </vxe-column>
228 </vxe-table> 233 </vxe-table>
229 <div class="flex justify-center mt-4"> 234 <div class="flex justify-center mt-4">
230 - <el-button :icon="h(Plus)" type="primary" plain @click="onAdd" v-access:code="['${permissionPrefix}:create']"> 235 + <el-button :icon="h(Plus)" type="primary" plain @click="handleAdd" v-access:code="['${permissionPrefix}:create']">
231 {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }} 236 {{ $t('ui.actionTitle.create', ['${subTable.classComment}']) }}
232 </el-button> 237 </el-button>
233 </div> 238 </div>
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/general/views/modules/list_sub_erp.vue.vm
@@ -9,23 +9,25 @@ @@ -9,23 +9,25 @@
9 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; 9 import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
10 import type { VxeTableInstance } from '#/adapter/vxe-table'; 10 import type { VxeTableInstance } from '#/adapter/vxe-table';
11 11
  12 + import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
  13 +
  14 + import { DICT_TYPE } from '@vben/constants';
  15 + import { getDictOptions } from '@vben/hooks';
  16 +
12 import { DictTag } from '#/components/dict-tag'; 17 import { DictTag } from '#/components/dict-tag';
13 - import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; 18 + import { getRangePickerDefaultProps } from '#/utils';
14 import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; 19 import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
15 - import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';  
16 - import { cloneDeep, formatDateTime } from '@vben/utils';  
17 import { ContentWrap } from '#/components/content-wrap'; 20 import { ContentWrap } from '#/components/content-wrap';
18 21
19 #if ($table.templateType == 11) ## erp 22 #if ($table.templateType == 11) ## erp
20 import { useVbenModal } from '@vben/common-ui'; 23 import { useVbenModal } from '@vben/common-ui';
  24 + import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
21 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue' 25 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
22 import { Tinymce as RichTextarea } from '#/components/tinymce'; 26 import { Tinymce as RichTextarea } from '#/components/tinymce';
23 import { ImageUpload, FileUpload } from "#/components/upload"; 27 import { ImageUpload, FileUpload } from "#/components/upload";
24 import { ElMessage, ElLoading, ElButton, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus'; 28 import { ElMessage, ElLoading, ElButton, ElTabs, ElTabPane, ElPagination, ElForm, ElFormItem, ElDatePicker, ElSelect, ElOption, ElInput } from 'element-plus';
25 import { Plus, Trash2 } from '@vben/icons'; 29 import { Plus, Trash2 } from '@vben/icons';
26 import { $t } from '#/locales'; 30 import { $t } from '#/locales';
27 - import { TableToolbar } from '#/components/table-toolbar';  
28 - import { useTableToolbar } from '#/hooks';  
29 #end 31 #end
30 32
31 #if ($table.templateType == 11) ## erp 33 #if ($table.templateType == 11) ## erp
@@ -129,64 +131,64 @@ function handleRowCheckboxChange({ @@ -129,64 +131,64 @@ function handleRowCheckboxChange({
129 }) 131 })
130 132
131 /** 搜索按钮操作 */ 133 /** 搜索按钮操作 */
132 -const handleQuery = () => { 134 +function handleQuery() {
133 queryParams.pageNo = 1 135 queryParams.pageNo = 1
134 getList() 136 getList()
135 } 137 }
136 138
137 /** 重置按钮操作 */ 139 /** 重置按钮操作 */
138 -const resetQuery = () => { 140 +function resetQuery() {
139 queryFormRef.value.resetFields() 141 queryFormRef.value.resetFields()
140 handleQuery() 142 handleQuery()
141 } 143 }
142 #end 144 #end
143 - /** 查询列表 */  
144 - const getList = async () => {  
145 - loading.value = true  
146 - try {  
147 - if (!props.${subJoinColumn.javaField}){  
148 - return []  
149 - }  
150 - ## 特殊:树表专属逻辑(树不需要分页接口)  
151 - #if ($table.templateType == 11) ## erp  
152 - const params = cloneDeep(queryParams) as any;  
153 - #foreach ($column in $columns)  
154 - #if ($column.listOperation)  
155 - #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")  
156 - if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {  
157 - params.${column.javaField} = (params.${column.javaField} as string[]).join(',');  
158 - }  
159 - #end  
160 - #end  
161 - #end  
162 - params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};  
163 - const data = await get${subSimpleClassName}Page(params)  
164 - list.value = data.list  
165 - total.value = data.total  
166 - #else  
167 - #if ($subTable.subJoinMany) ## 一对多  
168 - list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);  
169 - #else  
170 - list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];  
171 - #end  
172 - #end  
173 - } finally {  
174 - loading.value = false 145 +/** 查询列表 */
  146 +async function getList() {
  147 + loading.value = true
  148 + try {
  149 + if (!props.${subJoinColumn.javaField}){
  150 + return []
175 } 151 }
  152 + ## 特殊:树表专属逻辑(树不需要分页接口)
  153 + #if ($table.templateType == 11) ## erp
  154 + const params = cloneDeep(queryParams) as any;
  155 + #foreach ($column in $columns)
  156 + #if ($column.listOperation)
  157 + #if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
  158 + if (params.${column.javaField} && Array.isArray(params.${column.javaField})) {
  159 + params.${column.javaField} = (params.${column.javaField} as string[]).join(',');
  160 + }
  161 + #end
  162 + #end
  163 + #end
  164 + params.${subJoinColumn.javaField} = props.${subJoinColumn.javaField};
  165 + const data = await get${subSimpleClassName}Page(params)
  166 + list.value = data.list
  167 + total.value = data.total
  168 + #else
  169 + #if ($subTable.subJoinMany) ## 一对多
  170 + list.value = await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!);
  171 + #else
  172 + list.value = [await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)];
  173 + #end
  174 + #end
  175 + } finally {
  176 + loading.value = false
176 } 177 }
  178 +}
177 179
178 - /** 监听主表的关联字段的变化,加载对应的子表数据 */  
179 - watch(  
180 - () => props.${subJoinColumn.javaField},  
181 - async (val) => {  
182 - if (!val) {  
183 - return;  
184 - }  
185 - await nextTick();  
186 - await getList()  
187 - },  
188 - { immediate: true },  
189 - ); 180 +/** 监听主表的关联字段的变化,加载对应的子表数据 */
  181 +watch(
  182 + () => props.${subJoinColumn.javaField},
  183 + async (val) => {
  184 + if (!val) {
  185 + return;
  186 + }
  187 + await nextTick();
  188 + await getList()
  189 + },
  190 + { immediate: true },
  191 +);
190 192
191 #if ($table.templateType == 11) ## erp 193 #if ($table.templateType == 11) ## erp
192 /** 初始化 */ 194 /** 初始化 */
@@ -290,7 +292,7 @@ onMounted(() =&gt; { @@ -290,7 +292,7 @@ onMounted(() =&gt; {
290 <!-- 列表 --> 292 <!-- 列表 -->
291 <ContentWrap title="${table.classComment}"> 293 <ContentWrap title="${table.classComment}">
292 <template #extra> 294 <template #extra>
293 - <TableToolbar 295 + <VbenVxeTableToolbar
294 ref="tableToolbarRef" 296 ref="tableToolbarRef"
295 v-model:hidden-search="hiddenSearchBar" 297 v-model:hidden-search="hiddenSearchBar"
296 > 298 >
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/api/api.ts.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
  2 +#if ( $table.templateType != 2 )
1 import type { PageParam, PageResult } from '@vben/request'; 3 import type { PageParam, PageResult } from '@vben/request';
  4 +#end
2 import type { Dayjs } from 'dayjs'; 5 import type { Dayjs } from 'dayjs';
3 6
4 import { requestClient } from '#/api/request'; 7 import { requestClient } from '#/api/request';
5 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}") 8 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
6 9
7 -export namespace ${simpleClassName}Api { 10 +export namespace ${apiName} {
8 ## 特殊:主子表专属逻辑 11 ## 特殊:主子表专属逻辑
9 #foreach ($subTable in $subTables) 12 #foreach ($subTable in $subTables)
10 #set ($index = $foreach.count - 1) 13 #set ($index = $foreach.count - 1)
@@ -60,27 +63,35 @@ export namespace ${simpleClassName}Api { @@ -60,27 +63,35 @@ export namespace ${simpleClassName}Api {
60 #if ( $table.templateType != 2 ) 63 #if ( $table.templateType != 2 )
61 /** 查询${table.classComment}分页 */ 64 /** 查询${table.classComment}分页 */
62 export function get${simpleClassName}Page(params: PageParam) { 65 export function get${simpleClassName}Page(params: PageParam) {
63 - return requestClient.get<PageResult<${simpleClassName}Api.${simpleClassName}>>('${baseURL}/page', { params }); 66 + return requestClient.get<PageResult<${apiName}.${simpleClassName}>>(
  67 + '${baseURL}/page',
  68 + { params },
  69 + );
64 } 70 }
65 #else 71 #else
66 /** 查询${table.classComment}列表 */ 72 /** 查询${table.classComment}列表 */
67 export function get${simpleClassName}List(params: any) { 73 export function get${simpleClassName}List(params: any) {
68 - return requestClient.get<${simpleClassName}Api.${simpleClassName}[]>('${baseURL}/list', { params }); 74 + return requestClient.get<${apiName}.${simpleClassName}[]>(
  75 + '${baseURL}/list',
  76 + { params },
  77 + );
69 } 78 }
70 #end 79 #end
71 80
72 /** 查询${table.classComment}详情 */ 81 /** 查询${table.classComment}详情 */
73 export function get${simpleClassName}(id: number) { 82 export function get${simpleClassName}(id: number) {
74 - return requestClient.get<${simpleClassName}Api.${simpleClassName}>(`${baseURL}/get?id=${id}`); 83 + return requestClient.get<${apiName}.${simpleClassName}>(
  84 + `${baseURL}/get?id=${id}`,
  85 + );
75 } 86 }
76 87
77 /** 新增${table.classComment} */ 88 /** 新增${table.classComment} */
78 -export function create${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) { 89 +export function create${simpleClassName}(data: ${apiName}.${simpleClassName}) {
79 return requestClient.post('${baseURL}/create', data); 90 return requestClient.post('${baseURL}/create', data);
80 } 91 }
81 92
82 /** 修改${table.classComment} */ 93 /** 修改${table.classComment} */
83 -export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleClassName}) { 94 +export function update${simpleClassName}(data: ${apiName}.${simpleClassName}) {
84 return requestClient.put('${baseURL}/update', data); 95 return requestClient.put('${baseURL}/update', data);
85 } 96 }
86 97
@@ -88,17 +99,19 @@ export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleCla @@ -88,17 +99,19 @@ export function update${simpleClassName}(data: ${simpleClassName}Api.${simpleCla
88 export function delete${simpleClassName}(id: number) { 99 export function delete${simpleClassName}(id: number) {
89 return requestClient.delete(`${baseURL}/delete?id=${id}`); 100 return requestClient.delete(`${baseURL}/delete?id=${id}`);
90 } 101 }
91 -  
92 #if ( $table.templateType != 2 && $deleteBatchEnable) 102 #if ( $table.templateType != 2 && $deleteBatchEnable)
  103 +
93 /** 批量删除${table.classComment} */ 104 /** 批量删除${table.classComment} */
94 export function delete${simpleClassName}List(ids: number[]) { 105 export function delete${simpleClassName}List(ids: number[]) {
95 - return requestClient.delete(`${baseURL}/delete-list?ids=${ids.join(',')}`) 106 + return requestClient.delete(
  107 + `${baseURL}/delete-list?ids=${ids.join(',')}`,
  108 + );
96 } 109 }
97 #end 110 #end
98 111
99 /** 导出${table.classComment} */ 112 /** 导出${table.classComment} */
100 export function export${simpleClassName}(params: any) { 113 export function export${simpleClassName}(params: any) {
101 - return requestClient.download('${baseURL}/export-excel', params); 114 + return requestClient.download('${baseURL}/export-excel', { params });
102 } 115 }
103 116
104 ## 特殊:主子表专属逻辑 117 ## 特殊:主子表专属逻辑
@@ -118,31 +131,38 @@ export function export${simpleClassName}(params: any) { @@ -118,31 +131,38 @@ export function export${simpleClassName}(params: any) {
118 #if ( $table.templateType == 11 ) 131 #if ( $table.templateType == 11 )
119 /** 获得${subTable.classComment}分页 */ 132 /** 获得${subTable.classComment}分页 */
120 export function get${subSimpleClassName}Page(params: PageParam) { 133 export function get${subSimpleClassName}Page(params: PageParam) {
121 - return requestClient.get<PageResult<${simpleClassName}Api.${subSimpleClassName}>>(`${baseURL}/${subSimpleClassName_strikeCase}/page`, { params }); 134 + return requestClient.get<PageResult<${apiName}.${subSimpleClassName}>>(
  135 + `${baseURL}/${subSimpleClassName_strikeCase}/page`,
  136 + { params },
  137 + );
122 } 138 }
123 ## 情况二:非 MASTER_ERP 时,需要列表查询子表 139 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
124 #else 140 #else
125 #if ( $subTable.subJoinMany ) 141 #if ( $subTable.subJoinMany )
126 /** 获得${subTable.classComment}列表 */ 142 /** 获得${subTable.classComment}列表 */
127 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) { 143 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
128 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}[]>(`${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`); 144 + return requestClient.get<${apiName}.${subSimpleClassName}[]>(
  145 + `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`,
  146 + );
129 } 147 }
130 #else 148 #else
131 /** 获得${subTable.classComment} */ 149 /** 获得${subTable.classComment} */
132 export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) { 150 export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}: number) {
133 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`); 151 + return requestClient.get<${apiName}.${subSimpleClassName}>(
  152 + `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=${${subJoinColumn.javaField}}`,
  153 + );
134 } 154 }
135 #end 155 #end
136 #end 156 #end
137 ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作 157 ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
138 #if ( $table.templateType == 11 ) 158 #if ( $table.templateType == 11 )
139 /** 新增${subTable.classComment} */ 159 /** 新增${subTable.classComment} */
140 -export function create${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) { 160 +export function create${subSimpleClassName}(data: ${apiName}.${subSimpleClassName}) {
141 return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data); 161 return requestClient.post(`${baseURL}/${subSimpleClassName_strikeCase}/create`, data);
142 } 162 }
143 163
144 /** 修改${subTable.classComment} */ 164 /** 修改${subTable.classComment} */
145 -export function update${subSimpleClassName}(data: ${simpleClassName}Api.${subSimpleClassName}) { 165 +export function update${subSimpleClassName}(data: ${apiName}.${subSimpleClassName}) {
146 return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data); 166 return requestClient.put(`${baseURL}/${subSimpleClassName_strikeCase}/update`, data);
147 } 167 }
148 168
@@ -154,13 +174,17 @@ export function delete${subSimpleClassName}(id: number) { @@ -154,13 +174,17 @@ export function delete${subSimpleClassName}(id: number) {
154 #if ($deleteBatchEnable) 174 #if ($deleteBatchEnable)
155 /** 批量删除${subTable.classComment} */ 175 /** 批量删除${subTable.classComment} */
156 export function delete${subSimpleClassName}List(ids: number[]) { 176 export function delete${subSimpleClassName}List(ids: number[]) {
157 - return requestClient.delete(`${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`) 177 + return requestClient.delete(
  178 + `${baseURL}/${subSimpleClassName_strikeCase}/delete-list?ids=${ids.join(',')}`,
  179 + );
158 } 180 }
159 #end 181 #end
160 182
161 /** 获得${subTable.classComment} */ 183 /** 获得${subTable.classComment} */
162 export function get${subSimpleClassName}(id: number) { 184 export function get${subSimpleClassName}(id: number) {
163 - return requestClient.get<${simpleClassName}Api.${subSimpleClassName}>(`${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`); 185 + return requestClient.get<${apiName}.${subSimpleClassName}>(
  186 + `${baseURL}/${subSimpleClassName_strikeCase}/get?id=${id}`,
  187 + );
164 } 188 }
165 #end 189 #end
166 #end 190 #end
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 import type { VbenFormSchema } from '#/adapter/form'; 2 import type { VbenFormSchema } from '#/adapter/form';
2 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 3 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
3 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 4 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
4 5
5 -import { z } from '#/adapter/form';  
6 -import {  
7 - DICT_TYPE,  
8 - getDictOptions,  
9 - getRangePickerDefaultProps,  
10 -} from '#/utils'; 6 +import { DICT_TYPE } from '@vben/constants';
  7 +import { getDictOptions } from '@vben/hooks';
11 #if(${table.templateType} == 2)## 树表需要导入这些 8 #if(${table.templateType} == 2)## 树表需要导入这些
12 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}'; 9 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
13 import { handleTree } from '@vben/utils'; 10 import { handleTree } from '@vben/utils';
14 #end 11 #end
15 12
  13 +import { getRangePickerDefaultProps } from '#/utils';
  14 +
16 /** 新增/修改的表单 */ 15 /** 新增/修改的表单 */
17 export function useFormSchema(): VbenFormSchema[] { 16 export function useFormSchema(): VbenFormSchema[] {
18 return [ 17 return [
@@ -30,7 +29,7 @@ export function useFormSchema(): VbenFormSchema[] { @@ -30,7 +29,7 @@ export function useFormSchema(): VbenFormSchema[] {
30 label: '上级${table.classComment}', 29 label: '上级${table.classComment}',
31 component: 'ApiTreeSelect', 30 component: 'ApiTreeSelect',
32 componentProps: { 31 componentProps: {
33 - allowClear: true, 32 + clearable: true,
34 api: async () => { 33 api: async () => {
35 const data = await get${simpleClassName}List({}); 34 const data = await get${simpleClassName}List({});
36 data.unshift({ 35 data.unshift({
@@ -158,13 +157,13 @@ export function useGridFormSchema(): VbenFormSchema[] { @@ -158,13 +157,13 @@ export function useGridFormSchema(): VbenFormSchema[] {
158 #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor") 157 #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
159 component: 'Input', 158 component: 'Input',
160 componentProps: { 159 componentProps: {
161 - allowClear: true, 160 + clearable: true,
162 placeholder: '请输入${comment}', 161 placeholder: '请输入${comment}',
163 }, 162 },
164 #elseif ($column.htmlType == "select" || $column.htmlType == "radio") 163 #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
165 component: 'Select', 164 component: 'Select',
166 componentProps: { 165 componentProps: {
167 - allowClear: true, 166 + clearable: true,
168 #if ("" != $dictType)## 设置了 dictType 数据字典的情况 167 #if ("" != $dictType)## 设置了 dictType 数据字典的情况
169 options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'), 168 options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
170 #else## 未设置 dictType 数据字典的情况 169 #else## 未设置 dictType 数据字典的情况
@@ -176,7 +175,7 @@ export function useGridFormSchema(): VbenFormSchema[] { @@ -176,7 +175,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
176 component: 'RangePicker', 175 component: 'RangePicker',
177 componentProps: { 176 componentProps: {
178 ...getRangePickerDefaultProps(), 177 ...getRangePickerDefaultProps(),
179 - allowClear: true, 178 + clearable: true,
180 }, 179 },
181 #end 180 #end
182 }, 181 },
@@ -186,7 +185,7 @@ export function useGridFormSchema(): VbenFormSchema[] { @@ -186,7 +185,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
186 } 185 }
187 186
188 /** 列表的字段 */ 187 /** 列表的字段 */
189 -export function useGridColumns(): VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>['columns'] { 188 +export function useGridColumns(): VxeTableGridOptions<${apiName}.${simpleClassName}>['columns'] {
190 return [ 189 return [
191 #if ($table.templateType != 2 && $deleteBatchEnable) 190 #if ($table.templateType != 2 && $deleteBatchEnable)
192 { type: 'checkbox', width: 40 }, 191 { type: 'checkbox', width: 40 },
@@ -361,13 +360,13 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] { @@ -361,13 +360,13 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
361 #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor") 360 #if ($column.htmlType == "input" || $column.htmlType == "textarea" || $column.htmlType == "editor")
362 component: 'Input', 361 component: 'Input',
363 componentProps: { 362 componentProps: {
364 - allowClear: true, 363 + clearable: true,
365 placeholder: '请输入${comment}', 364 placeholder: '请输入${comment}',
366 }, 365 },
367 #elseif ($column.htmlType == "select" || $column.htmlType == "radio") 366 #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
368 component: 'Select', 367 component: 'Select',
369 componentProps: { 368 componentProps: {
370 - allowClear: true, 369 + clearable: true,
371 #if ("" != $dictType)## 设置了 dictType 数据字典的情况 370 #if ("" != $dictType)## 设置了 dictType 数据字典的情况
372 options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'), 371 options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
373 #else## 未设置 dictType 数据字典的情况 372 #else## 未设置 dictType 数据字典的情况
@@ -379,7 +378,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] { @@ -379,7 +378,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
379 component: 'RangePicker', 378 component: 'RangePicker',
380 componentProps: { 379 componentProps: {
381 ...getRangePickerDefaultProps(), 380 ...getRangePickerDefaultProps(),
382 - allowClear: true, 381 + clearable: true,
383 }, 382 },
384 #end 383 #end
385 }, 384 },
@@ -389,7 +388,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] { @@ -389,7 +388,7 @@ export function use${subSimpleClassName}GridFormSchema(): VbenFormSchema[] {
389 } 388 }
390 389
391 /** 列表的字段 */ 390 /** 列表的字段 */
392 -export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] { 391 +export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${apiName}.${subSimpleClassName}>['columns'] {
393 return [ 392 return [
394 #if ($table.templateType != 2 && $deleteBatchEnable) 393 #if ($table.templateType != 2 && $deleteBatchEnable)
395 { type: 'checkbox', width: 40 }, 394 { type: 'checkbox', width: 40 },
@@ -426,7 +425,7 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim @@ -426,7 +425,7 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim
426 #else 425 #else
427 #if ($subTable.subJoinMany) ## 一对多 426 #if ($subTable.subJoinMany) ## 一对多
428 /** 新增/修改列表的字段 */ 427 /** 新增/修改列表的字段 */
429 - export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>['columns'] { 428 + export function use${subSimpleClassName}GridEditColumns(): VxeTableGridOptions<${apiName}.${subSimpleClassName}>['columns'] {
430 return [ 429 return [
431 #foreach($column in $subColumns) 430 #foreach($column in $subColumns)
432 #if ($column.createOperation || $column.updateOperation) 431 #if ($column.createOperation || $column.updateOperation)
@@ -602,4 +601,4 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim @@ -602,4 +601,4 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions&lt;${sim
602 } 601 }
603 #end 602 #end
604 #end 603 #end
605 -#end 604 -#end
  605 +#end
606 \ No newline at end of file 606 \ No newline at end of file
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 <script lang="ts" setup> 2 <script lang="ts" setup>
2 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 3 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
  4 +
  5 +import { computed, ref } from 'vue';
3 6
4 import { useVbenModal } from '@vben/common-ui'; 7 import { useVbenModal } from '@vben/common-ui';
5 -import { ElMessage, ElTabs, ElTabPane, ElCheckbox, ElInput, ElSelect, ElRadioGroup, ElCheckboxGroup, ElDatePicker } from 'element-plus'; 8 +
  9 +import { ElMessage#if ($table.templateType == 11), ElTabs, ElTabPane#end } from 'element-plus';
  10 +
  11 +import { useVbenForm } from '#/adapter/form';
  12 +import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  13 +import { $t } from '#/locales';
6 ## 特殊:主子表专属逻辑 14 ## 特殊:主子表专属逻辑
7 #if ( $table.templateType == 10 || $table.templateType == 12 ) 15 #if ( $table.templateType == 10 || $table.templateType == 12 )
8 #foreach ($subSimpleClassName in $subSimpleClassNames) 16 #foreach ($subSimpleClassName in $subSimpleClassNames)
@@ -12,21 +20,15 @@ import { ElMessage, ElTabs, ElTabPane, ElCheckbox, ElInput, ElSelect, ElRadioGro @@ -12,21 +20,15 @@ import { ElMessage, ElTabs, ElTabPane, ElCheckbox, ElInput, ElSelect, ElRadioGro
12 #end 20 #end
13 #end 21 #end
14 22
15 -import { computed, ref } from 'vue';  
16 -import { $t } from '#/locales';  
17 -import { useVbenForm } from '#/adapter/form';  
18 -import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';  
19 -  
20 import { useFormSchema } from '../data'; 23 import { useFormSchema } from '../data';
21 24
22 const emit = defineEmits(['success']); 25 const emit = defineEmits(['success']);
23 -const formData = ref<${simpleClassName}Api.${simpleClassName}>(); 26 +const formData = ref<${apiName}.${simpleClassName}>();
24 const getTitle = computed(() => { 27 const getTitle = computed(() => {
25 return formData.value?.id 28 return formData.value?.id
26 ? $t('ui.actionTitle.edit', ['${table.classComment}']) 29 ? $t('ui.actionTitle.edit', ['${table.classComment}'])
27 : $t('ui.actionTitle.create', ['${table.classComment}']); 30 : $t('ui.actionTitle.create', ['${table.classComment}']);
28 }); 31 });
29 -  
30 ## 特殊:主子表专属逻辑 32 ## 特殊:主子表专属逻辑
31 #if ( $table.templateType == 10 || $table.templateType == 12 ) 33 #if ( $table.templateType == 10 || $table.templateType == 12 )
32 #if ( $subTables && $subTables.size() > 0 ) 34 #if ( $subTables && $subTables.size() > 0 )
@@ -51,7 +53,7 @@ const [Form, formApi] = useVbenForm({ @@ -51,7 +53,7 @@ const [Form, formApi] = useVbenForm({
51 }, 53 },
52 layout: 'horizontal', 54 layout: 'horizontal',
53 schema: useFormSchema(), 55 schema: useFormSchema(),
54 - showDefaultActions: false 56 + showDefaultActions: false,
55 }); 57 });
56 58
57 const [Modal, modalApi] = useVbenModal({ 59 const [Modal, modalApi] = useVbenModal({
@@ -60,8 +62,8 @@ const [Modal, modalApi] = useVbenModal({ @@ -60,8 +62,8 @@ const [Modal, modalApi] = useVbenModal({
60 if (!valid) { 62 if (!valid) {
61 return; 63 return;
62 } 64 }
63 - ## 特殊:主子表专属逻辑  
64 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 65 +## 特殊:主子表专属逻辑
  66 +#if ( $table.templateType == 10 || $table.templateType == 12 )
65 #if ( $subTables && $subTables.size() > 0 ) 67 #if ( $subTables && $subTables.size() > 0 )
66 // 校验子表单 68 // 校验子表单
67 #foreach ($subTable in $subTables) 69 #foreach ($subTable in $subTables)
@@ -78,12 +80,12 @@ const [Modal, modalApi] = useVbenModal({ @@ -78,12 +80,12 @@ const [Modal, modalApi] = useVbenModal({
78 #end 80 #end
79 #end 81 #end
80 #end 82 #end
81 - #end 83 +#end
82 modalApi.lock(); 84 modalApi.lock();
83 // 提交表单 85 // 提交表单
84 - const data = (await formApi.getValues()) as ${simpleClassName}Api.${simpleClassName};  
85 - ## 特殊:主子表专属逻辑  
86 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 86 + const data = (await formApi.getValues()) as ${apiName}.${simpleClassName};
  87 +## 特殊:主子表专属逻辑
  88 +#if ( $table.templateType == 10 || $table.templateType == 12 )
87 #if ( $subTables && $subTables.size() > 0 ) 89 #if ( $subTables && $subTables.size() > 0 )
88 // 拼接子表的数据 90 // 拼接子表的数据
89 #foreach ($subTable in $subTables) 91 #foreach ($subTable in $subTables)
@@ -96,7 +98,7 @@ const [Modal, modalApi] = useVbenModal({ @@ -96,7 +98,7 @@ const [Modal, modalApi] = useVbenModal({
96 #end 98 #end
97 #end 99 #end
98 #end 100 #end
99 - #end 101 +#end
100 try { 102 try {
101 await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data)); 103 await (formData.value?.id ? update${simpleClassName}(data) : create${simpleClassName}(data));
102 // 关闭并提示 104 // 关闭并提示
@@ -113,21 +115,24 @@ const [Modal, modalApi] = useVbenModal({ @@ -113,21 +115,24 @@ const [Modal, modalApi] = useVbenModal({
113 return; 115 return;
114 } 116 }
115 // 加载数据 117 // 加载数据
116 - let data = modalApi.getData<${simpleClassName}Api.${simpleClassName}>();  
117 - if (!data) { 118 + const data = modalApi.getData<${apiName}.${simpleClassName}>();
  119 + if (!data || !data.id) {
  120 +#if (${table.templateType} == 2)## 树表特有
  121 + // 设置上级
  122 + await formApi.setValues(data);
  123 +#end
118 return; 124 return;
119 } 125 }
120 - if (data.id) {  
121 - modalApi.lock();  
122 - try {  
123 - data = await get${simpleClassName}(data.id);  
124 - } finally {  
125 - modalApi.unlock(); 126 + modalApi.lock();
  127 + try {
  128 + formData.value = await get${simpleClassName}(data.id);
  129 + // 设置到 values
  130 + if (formData.value) {
  131 + await formApi.setValues(formData.value);
126 } 132 }
  133 + } finally {
  134 + modalApi.unlock();
127 } 135 }
128 - // 设置到 values  
129 - formData.value = data;  
130 - await formApi.setValues(formData.value);  
131 }, 136 },
132 }); 137 });
133 </script> 138 </script>
@@ -135,20 +140,20 @@ const [Modal, modalApi] = useVbenModal({ @@ -135,20 +140,20 @@ const [Modal, modalApi] = useVbenModal({
135 <template> 140 <template>
136 <Modal :title="getTitle"> 141 <Modal :title="getTitle">
137 <Form class="mx-4" /> 142 <Form class="mx-4" />
138 - ## 特殊:主子表专属逻辑  
139 - #if ( $table.templateType == 10 || $table.templateType == 12 ) 143 +## 特殊:主子表专属逻辑
  144 +#if ( $table.templateType == 10 || $table.templateType == 12 )
140 <!-- 子表的表单 --> 145 <!-- 子表的表单 -->
141 - <el-tabs v-model="subTabsName"> 146 + <ElTabs v-model="subTabsName">
142 #foreach ($subTable in $subTables) 147 #foreach ($subTable in $subTables)
143 #set ($index = $foreach.count - 1) 148 #set ($index = $foreach.count - 1)
144 #set ($subClassNameVar = $subClassNameVars.get($index)) 149 #set ($subClassNameVar = $subClassNameVars.get($index))
145 #set ($subSimpleClassName = $subSimpleClassNames.get($index)) 150 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
146 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index)) 151 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
147 - <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}"> 152 + <ElTabPane name="$subClassNameVar" label="${subTable.classComment}">
148 <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" /> 153 <${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData?.id" />
149 - </el-tab-pane> 154 + </ElTabPane>
150 #end 155 #end
151 - </el-tabs>  
152 - #end 156 + </ElTabs>
  157 +#end
153 </Modal> 158 </Modal>
154 </template> 159 </template>
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/index.vue.vm
  1 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
1 <script lang="ts" setup> 2 <script lang="ts" setup>
2 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 3 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
3 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 4 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
4 5
5 -import { Page, useVbenModal } from '@vben/common-ui';  
6 -import { ElMessage, ElTabs, ElTabPane, ElLoading } from 'element-plus';  
7 -import Form from './modules/form.vue'; 6 +import { ref } from 'vue';
8 7
9 -## 特殊:主子表专属逻辑  
10 -#if ( $table.templateType == 11 || $table.templateType == 12 )  
11 - #foreach ($subSimpleClassName in $subSimpleClassNames)  
12 - #set ($index = $foreach.count - 1)  
13 - #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))  
14 -import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue'  
15 - #end  
16 -#end 8 +import {#if ($table.templateType != 2 && $deleteBatchEnable) confirm,#end Page, useVbenModal } from '@vben/common-ui';
  9 +import { downloadFileFromBlobPart#if ($table.templateType != 2 && $deleteBatchEnable), isEmpty#end } from '@vben/utils';
  10 +
  11 +import { ElLoading, ElMessage#if ($table.templateType == 11), ElTabs, ElTabPane#end } from 'element-plus';
17 12
18 -import { ref, computed } from 'vue';  
19 -import { $t } from '#/locales';  
20 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; 13 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
21 #if (${table.templateType} == 2)## 树表接口 14 #if (${table.templateType} == 2)## 树表接口
22 -import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}'; 15 +import {
  16 + delete${simpleClassName},
  17 + export${simpleClassName},
  18 + get${simpleClassName}List,
  19 +} from '#/api/${table.moduleName}/${table.businessName}';
23 #else## 标准表接口 20 #else## 标准表接口
24 -import { get${simpleClassName}Page, delete${simpleClassName},#if ($deleteBatchEnable) delete${simpleClassName}List,#end export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}'; 21 +import {
  22 + delete${simpleClassName},#if ($deleteBatchEnable)
  23 +
  24 + delete${simpleClassName}List,#end
  25 + export${simpleClassName},
  26 + get${simpleClassName}Page,
  27 +} from '#/api/${table.moduleName}/${table.businessName}';
25 #end 28 #end
26 -import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; 29 +import { $t } from '#/locales';
27 30
28 import { useGridColumns, useGridFormSchema } from './data'; 31 import { useGridColumns, useGridFormSchema } from './data';
  32 +import Form from './modules/form.vue';
  33 +## 特殊:主子表专属逻辑
  34 +#if ( $table.templateType == 11 || $table.templateType == 12 )
  35 + #foreach ($subSimpleClassName in $subSimpleClassNames)
  36 + #set ($index = $foreach.count - 1)
  37 + #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
  38 +import ${subSimpleClassName}List from './modules/${subSimpleClassName_strikeCase}-list.vue';
  39 + #end
  40 +#end
29 41
30 #if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况 42 #if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况
31 /** 子表的列表 */ 43 /** 子表的列表 */
32 const subTabsName = ref('$subClassNameVars.get(0)') 44 const subTabsName = ref('$subClassNameVars.get(0)')
33 #if ($table.templateType == 11) 45 #if ($table.templateType == 11)
34 -const select${simpleClassName} = ref<${simpleClassName}Api.${simpleClassName}>(); 46 +const select${simpleClassName} = ref<${apiName}.${simpleClassName}>();
35 #end 47 #end
36 #end 48 #end
37 -  
38 const [FormModal, formModalApi] = useVbenModal({ 49 const [FormModal, formModalApi] = useVbenModal({
39 connectedComponent: Form, 50 connectedComponent: Form,
40 destroyOnClose: true, 51 destroyOnClose: true,
41 }); 52 });
42 -  
43 #if (${table.templateType} == 2)## 树表特有:控制表格展开收缩 53 #if (${table.templateType} == 2)## 树表特有:控制表格展开收缩
  54 +
44 /** 切换树形展开/收缩状态 */ 55 /** 切换树形展开/收缩状态 */
45 const isExpanded = ref(true); 56 const isExpanded = ref(true);
46 -function toggleExpand() { 57 +function handleExpand() {
47 isExpanded.value = !isExpanded.value; 58 isExpanded.value = !isExpanded.value;
48 gridApi.grid.setAllTreeExpand(isExpanded.value); 59 gridApi.grid.setAllTreeExpand(isExpanded.value);
49 } 60 }
50 #end 61 #end
51 62
52 /** 刷新表格 */ 63 /** 刷新表格 */
53 -function onRefresh() { 64 +function handleRefresh() {
54 #if ($table.templateType == 12) ## 内嵌情况 65 #if ($table.templateType == 12) ## 内嵌情况
55 gridApi.reload(); 66 gridApi.reload();
56 #else 67 #else
@@ -60,31 +71,30 @@ function onRefresh() { @@ -60,31 +71,30 @@ function onRefresh() {
60 71
61 /** 创建${table.classComment} */ 72 /** 创建${table.classComment} */
62 function handleCreate() { 73 function handleCreate() {
63 - formModalApi.setData({}).open(); 74 + formModalApi.setData(null).open();
64 } 75 }
65 -  
66 -/** 编辑${table.classComment} */  
67 -function handleEdit(row: ${simpleClassName}Api.${simpleClassName}) {  
68 - formModalApi.setData(row).open();  
69 -}  
70 -  
71 #if (${table.templateType} == 2)## 树表特有:新增下级 76 #if (${table.templateType} == 2)## 树表特有:新增下级
72 -/** 新增下级${table.classComment} */  
73 -function handleAppend(row: ${simpleClassName}Api.${simpleClassName}) { 77 +
  78 +/** 添加下级${table.classComment} */
  79 +function handleAppend(row: ${apiName}.${simpleClassName}) {
74 formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open(); 80 formModalApi.setData({ ${treeParentColumn.javaField}: row.id }).open();
75 } 81 }
76 #end 82 #end
77 83
  84 +/** 编辑${table.classComment} */
  85 +function handleEdit(row: ${apiName}.${simpleClassName}) {
  86 + formModalApi.setData(row).open();
  87 +}
  88 +
78 /** 删除${table.classComment} */ 89 /** 删除${table.classComment} */
79 -async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) { 90 +async function handleDelete(row: ${apiName}.${simpleClassName}) {
80 const loadingInstance = ElLoading.service({ 91 const loadingInstance = ElLoading.service({
81 text: $t('ui.actionMessage.deleting', [row.id]), 92 text: $t('ui.actionMessage.deleting', [row.id]),
82 - background: 'rgba(0, 0, 0, 0.7)',  
83 }); 93 });
84 try { 94 try {
85 - await delete${simpleClassName}(row.id as number); 95 + await delete${simpleClassName}(row.id!);
86 ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id])); 96 ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
87 - onRefresh(); 97 + handleRefresh();
88 } finally { 98 } finally {
89 loadingInstance.close(); 99 loadingInstance.close();
90 } 100 }
@@ -93,27 +103,27 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) { @@ -93,27 +103,27 @@ async function handleDelete(row: ${simpleClassName}Api.${simpleClassName}) {
93 #if ($table.templateType != 2 && $deleteBatchEnable) 103 #if ($table.templateType != 2 && $deleteBatchEnable)
94 /** 批量删除${table.classComment} */ 104 /** 批量删除${table.classComment} */
95 async function handleDeleteBatch() { 105 async function handleDeleteBatch() {
  106 + await confirm($t('ui.actionMessage.deleteBatchConfirm'));
96 const loadingInstance = ElLoading.service({ 107 const loadingInstance = ElLoading.service({
97 - text: $t('ui.actionMessage.deleting'),  
98 - background: 'rgba(0, 0, 0, 0.7)', 108 + text: $t('ui.actionMessage.deletingBatch'),
99 }); 109 });
100 try { 110 try {
101 await delete${simpleClassName}List(checkedIds.value); 111 await delete${simpleClassName}List(checkedIds.value);
102 checkedIds.value = []; 112 checkedIds.value = [];
103 ElMessage.success($t('ui.actionMessage.deleteSuccess')); 113 ElMessage.success($t('ui.actionMessage.deleteSuccess'));
104 - onRefresh(); 114 + handleRefresh();
105 } finally { 115 } finally {
106 loadingInstance.close(); 116 loadingInstance.close();
107 } 117 }
108 } 118 }
109 119
110 -const checkedIds = ref<number[]>([]) 120 +const checkedIds = ref<number[]>([]);
111 function handleRowCheckboxChange({ 121 function handleRowCheckboxChange({
112 records, 122 records,
113 }: { 123 }: {
114 - records: ${simpleClassName}Api.${simpleClassName}[]; 124 + records: ${apiName}.${simpleClassName}[];
115 }) { 125 }) {
116 - checkedIds.value = records.map((item) => item.id); 126 + checkedIds.value = records.map((item) => item.id!);
117 } 127 }
118 #end 128 #end
119 129
@@ -135,20 +145,11 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -135,20 +145,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
135 height: 'auto', 145 height: 'auto',
136 #end 146 #end
137 #if (${table.templateType} == 2)## 树表设置 147 #if (${table.templateType} == 2)## 树表设置
138 - treeConfig: {  
139 - parentField: '${treeParentColumn.javaField}',  
140 - rowField: 'id',  
141 - transform: true,  
142 - expandAll: true,  
143 - reserve: true,  
144 - },  
145 - pagerConfig: {  
146 - enabled: false,  
147 - },  
148 -#else## 标准表设置  
149 pagerConfig: { 148 pagerConfig: {
150 - enabled: true, 149 + enabled: false,
151 }, 150 },
  151 +#else## 标准表设置
  152 + keepSource: true,
152 #end 153 #end
153 proxyConfig: { 154 proxyConfig: {
154 ajax: { 155 ajax: {
@@ -178,27 +179,35 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -178,27 +179,35 @@ const [Grid, gridApi] = useVbenVxeGrid({
178 refresh: true, 179 refresh: true,
179 search: true, 180 search: true,
180 }, 181 },
181 - } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,  
182 -#if (${table.templateType} == 11 || $deleteBatchEnable)  
183 - gridEvents:{  
184 - #if(${table.templateType} == 11)  
185 - cellClick: ({ row }: { row: ${simpleClassName}Api.${simpleClassName}}) => { 182 +#if (${table.templateType} == 2)## 树表设置
  183 + treeConfig: {
  184 + parentField: '${treeParentColumn.javaField}',
  185 + rowField: 'id',
  186 + transform: true,
  187 + expandAll: true,
  188 + reserve: true,
  189 + },
  190 +#end
  191 + } as VxeTableGridOptions<${apiName}.${simpleClassName}>,
  192 +#if (${table.templateType} == 11 || (${table.templateType} != 2 && $deleteBatchEnable))
  193 + gridEvents: {
  194 + #if(${table.templateType} == 11)
  195 + cellClick: ({ row }: { row: ${apiName}.${simpleClassName}}) => {
186 select${simpleClassName}.value = row; 196 select${simpleClassName}.value = row;
187 }, 197 },
188 - #end  
189 - #if(${table.templateType} != 2 && $deleteBatchEnable)  
190 - checkboxAll: handleRowCheckboxChange,  
191 - checkboxChange: handleRowCheckboxChange,  
192 - #end  
193 - } 198 + #end
  199 + #if (${table.templateType} != 2 && $deleteBatchEnable)
  200 + checkboxAll: handleRowCheckboxChange,
  201 + checkboxChange: handleRowCheckboxChange,
  202 + #end
  203 + },
194 #end 204 #end
195 }); 205 });
196 </script> 206 </script>
197 207
198 <template> 208 <template>
199 <Page auto-content-height> 209 <Page auto-content-height>
200 - <FormModal @success="onRefresh" />  
201 - 210 + <FormModal @success="handleRefresh" />
202 #if ($table.templateType == 11) ## erp情况 211 #if ($table.templateType == 11) ## erp情况
203 <div> 212 <div>
204 #end 213 #end
@@ -206,29 +215,22 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -206,29 +215,22 @@ const [Grid, gridApi] = useVbenVxeGrid({
206 #if ($table.templateType == 12) ## 内嵌情况 215 #if ($table.templateType == 12) ## 内嵌情况
207 <template #expand_content="{ row }"> 216 <template #expand_content="{ row }">
208 <!-- 子表的表单 --> 217 <!-- 子表的表单 -->
209 - <el-tabs v-model="subTabsName" class="mx-8"> 218 + <ElTabs v-model="subTabsName" class="mx-8">
210 #foreach ($subTable in $subTables) 219 #foreach ($subTable in $subTables)
211 #set ($index = $foreach.count - 1) 220 #set ($index = $foreach.count - 1)
212 #set ($subClassNameVar = $subClassNameVars.get($index)) 221 #set ($subClassNameVar = $subClassNameVars.get($index))
213 #set ($subSimpleClassName = $subSimpleClassNames.get($index)) 222 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
214 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index)) 223 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
215 - <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}"> 224 + <ElTabPane name="$subClassNameVar" label="${subTable.classComment}">
216 <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" /> 225 <${subSimpleClassName}List :${subJoinColumn_strikeCase}="row?.id" />
217 - </el-tab-pane> 226 + </ElTabPane>
218 #end 227 #end
219 - </el-tabs> 228 + </ElTabs>
220 </template> 229 </template>
221 #end 230 #end
222 <template #toolbar-tools> 231 <template #toolbar-tools>
223 <TableAction 232 <TableAction
224 :actions="[ 233 :actions="[
225 - #if (${table.templateType} == 2)## 树表特有:展开/收缩按钮  
226 - {  
227 - label: isExpanded ? '收缩' : '展开',  
228 - type: 'primary',  
229 - onClick: toggleExpand,  
230 - },  
231 - #end  
232 { 234 {
233 label: $t('ui.actionTitle.create', ['${table.classComment}']), 235 label: $t('ui.actionTitle.create', ['${table.classComment}']),
234 type: 'primary', 236 type: 'primary',
@@ -236,6 +238,13 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -236,6 +238,13 @@ const [Grid, gridApi] = useVbenVxeGrid({
236 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'], 238 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
237 onClick: handleCreate, 239 onClick: handleCreate,
238 }, 240 },
  241 + #if (${table.templateType} == 2)## 树表特有:展开/收缩按钮
  242 + {
  243 + label: isExpanded ? '收缩' : '展开',
  244 + type: 'primary',
  245 + onClick: handleExpand,
  246 + },
  247 + #end
239 { 248 {
240 label: $t('ui.actionTitle.export'), 249 label: $t('ui.actionTitle.export'),
241 type: 'primary', 250 type: 'primary',
@@ -248,8 +257,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -248,8 +257,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
248 label: $t('ui.actionTitle.deleteBatch'), 257 label: $t('ui.actionTitle.deleteBatch'),
249 type: 'danger', 258 type: 'danger',
250 icon: ACTION_ICON.DELETE, 259 icon: ACTION_ICON.DELETE,
251 - disabled: isEmpty(checkedIds),  
252 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'], 260 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
  261 + disabled: isEmpty(checkedIds),
253 onClick: handleDeleteBatch, 262 onClick: handleDeleteBatch,
254 }, 263 },
255 #end 264 #end
@@ -262,7 +271,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -262,7 +271,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
262 #if (${table.templateType} == 2)## 树表特有:新增下级 271 #if (${table.templateType} == 2)## 树表特有:新增下级
263 { 272 {
264 label: '新增下级', 273 label: '新增下级',
265 - type: 'text', 274 + type: 'primary',
  275 + link: true,
266 icon: ACTION_ICON.ADD, 276 icon: ACTION_ICON.ADD,
267 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'], 277 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:create'],
268 onClick: handleAppend.bind(null, row), 278 onClick: handleAppend.bind(null, row),
@@ -270,7 +280,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -270,7 +280,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
270 #end 280 #end
271 { 281 {
272 label: $t('common.edit'), 282 label: $t('common.edit'),
273 - type: 'text', 283 + type: 'primary',
  284 + link: true,
274 icon: ACTION_ICON.EDIT, 285 icon: ACTION_ICON.EDIT,
275 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'], 286 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'],
276 onClick: handleEdit.bind(null, row), 287 onClick: handleEdit.bind(null, row),
@@ -278,7 +289,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -278,7 +289,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
278 { 289 {
279 label: $t('common.delete'), 290 label: $t('common.delete'),
280 type: 'danger', 291 type: 'danger',
281 - text: true, 292 + link: true,
282 icon: ACTION_ICON.DELETE, 293 icon: ACTION_ICON.DELETE,
283 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'], 294 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
284 popConfirm: { 295 popConfirm: {
@@ -290,21 +301,20 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -290,21 +301,20 @@ const [Grid, gridApi] = useVbenVxeGrid({
290 /> 301 />
291 </template> 302 </template>
292 </Grid> 303 </Grid>
293 -  
294 #if ($table.templateType == 11) ## erp情况 304 #if ($table.templateType == 11) ## erp情况
295 <!-- 子表的表单 --> 305 <!-- 子表的表单 -->
296 - <el-tabs v-model="subTabsName" class="mt-2"> 306 + <ElTabs v-model="subTabsName" class="mt-2">
297 #foreach ($subTable in $subTables) 307 #foreach ($subTable in $subTables)
298 #set ($index = $foreach.count - 1) 308 #set ($index = $foreach.count - 1)
299 #set ($subClassNameVar = $subClassNameVars.get($index)) 309 #set ($subClassNameVar = $subClassNameVars.get($index))
300 #set ($subSimpleClassName = $subSimpleClassNames.get($index)) 310 #set ($subSimpleClassName = $subSimpleClassNames.get($index))
301 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index)) 311 #set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
302 - <el-tab-pane name="$subClassNameVar" label="${subTable.classComment}"> 312 + <ElTabPane name="$subClassNameVar" label="${subTable.classComment}">
303 <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" /> 313 <${subSimpleClassName}List :${subJoinColumn_strikeCase}="select${simpleClassName}?.id" />
304 - </el-tab-pane> 314 + </ElTabPane>
305 #end 315 #end
306 - </el-tabs> 316 + </ElTabs>
307 </div> 317 </div>
308 #end 318 #end
309 </Page> 319 </Page>
310 -</template> 320 -</template>
  321 +</template>
311 \ No newline at end of file 322 \ No newline at end of file
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/form_sub_erp.vue.vm
@@ -2,21 +2,24 @@ @@ -2,21 +2,24 @@
2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组 2 #set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 3 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
  5 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
5 <script lang="ts" setup> 6 <script lang="ts" setup>
6 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 7 + import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
  8 +
  9 + import { computed, ref } from 'vue';
7 10
8 import { useVbenModal } from '@vben/common-ui'; 11 import { useVbenModal } from '@vben/common-ui';
  12 +
9 import { ElMessage } from 'element-plus'; 13 import { ElMessage } from 'element-plus';
10 14
11 - import { computed, ref } from 'vue';  
12 - import { $t } from '#/locales';  
13 import { useVbenForm } from '#/adapter/form'; 15 import { useVbenForm } from '#/adapter/form';
14 import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${table.businessName}'; 16 import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
  17 + import { $t } from '#/locales';
15 18
16 import { use${subSimpleClassName}FormSchema } from '../data'; 19 import { use${subSimpleClassName}FormSchema } from '../data';
17 20
18 const emit = defineEmits(['success']); 21 const emit = defineEmits(['success']);
19 - const formData = ref<${simpleClassName}Api.${subSimpleClassName}>(); 22 + const formData = ref<${apiName}.${subSimpleClassName}>();
20 const getTitle = computed(() => { 23 const getTitle = computed(() => {
21 return formData.value?.id 24 return formData.value?.id
22 ? $t('ui.actionTitle.edit', ['${subTable.classComment}']) 25 ? $t('ui.actionTitle.edit', ['${subTable.classComment}'])
@@ -45,7 +48,7 @@ @@ -45,7 +48,7 @@
45 48
46 modalApi.lock(); 49 modalApi.lock();
47 // 提交表单 50 // 提交表单
48 - const data = (await formApi.getValues()) as ${simpleClassName}Api.${subSimpleClassName}; 51 + const data = (await formApi.getValues()) as ${apiName}.${subSimpleClassName};
49 data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField}; 52 data.${subJoinColumn.javaField} = formData.value?.${subJoinColumn.javaField};
50 try { 53 try {
51 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data)); 54 await (formData.value?.id ? update${subSimpleClassName}(data) : create${subSimpleClassName}(data));
@@ -64,7 +67,7 @@ @@ -64,7 +67,7 @@
64 } 67 }
65 68
66 // 加载数据 69 // 加载数据
67 - let data = modalApi.getData<${simpleClassName}Api.${subSimpleClassName}>(); 70 + let data = modalApi.getData<${apiName}.${subSimpleClassName}>();
68 if (!data) { 71 if (!data) {
69 return; 72 return;
70 } 73 }
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/form_sub_normal.vue.vm
@@ -4,10 +4,12 @@ @@ -4,10 +4,12 @@
4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex)) 4 #set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
5 #set ($subClassNameVar = $subClassNameVars.get($subIndex)) 5 #set ($subClassNameVar = $subClassNameVars.get($subIndex))
6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 6 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  7 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
7 <script lang="ts" setup> 8 <script lang="ts" setup>
8 - import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 9 + import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
9 10
10 import { computed, ref, h, onMounted,watch,nextTick } from 'vue'; 11 import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
  12 +
11 import { $t } from '#/locales'; 13 import { $t } from '#/locales';
12 14
13 #if ($subTable.subJoinMany) ## 一对多 15 #if ($subTable.subJoinMany) ## 一对多
@@ -33,7 +35,7 @@ const props = defineProps&lt;{ @@ -33,7 +35,7 @@ const props = defineProps&lt;{
33 function onActionClick({ 35 function onActionClick({
34 code, 36 code,
35 row, 37 row,
36 -}: OnActionClickParams<${simpleClassName}Api.${subSimpleClassName}>) { 38 +}: OnActionClickParams<${apiName}.${subSimpleClassName}>) {
37 switch (code) { 39 switch (code) {
38 case 'delete': { 40 case 'delete': {
39 onDelete(row); 41 onDelete(row);
@@ -67,16 +69,16 @@ const onAdd = async () =&gt; { @@ -67,16 +69,16 @@ const onAdd = async () =&gt; {
67 } 69 }
68 70
69 /** 删除${subTable.classComment} */ 71 /** 删除${subTable.classComment} */
70 -const onDelete = async (row: ${simpleClassName}Api.${subSimpleClassName}) => { 72 +const onDelete = async (row: ${apiName}.${subSimpleClassName}) => {
71 await gridApi.grid.remove(row); 73 await gridApi.grid.remove(row);
72 } 74 }
73 75
74 /** 提供获取表格数据的方法供父组件调用 */ 76 /** 提供获取表格数据的方法供父组件调用 */
75 defineExpose({ 77 defineExpose({
76 - getData: (): ${simpleClassName}Api.${subSimpleClassName}[] => {  
77 - const data = gridApi.grid.getData() as ${simpleClassName}Api.${subSimpleClassName}[];  
78 - const removeRecords = gridApi.grid.getRemoveRecords() as ${simpleClassName}Api.${subSimpleClassName}[];  
79 - const insertRecords = gridApi.grid.getInsertRecords() as ${simpleClassName}Api.${subSimpleClassName}[]; 78 + getData: (): ${apiName}.${subSimpleClassName}[] => {
  79 + const data = gridApi.grid.getData() as ${apiName}.${subSimpleClassName}[];
  80 + const removeRecords = gridApi.grid.getRemoveRecords() as ${apiName}.${subSimpleClassName}[];
  81 + const insertRecords = gridApi.grid.getInsertRecords() as ${apiName}.${subSimpleClassName}[];
80 return data 82 return data
81 .filter((row) => !removeRecords.some((removed) => removed.id === row.id)) 83 .filter((row) => !removeRecords.some((removed) => removed.id === row.id))
82 .concat(insertRecords.map((row: any) => ({ ...row, id: undefined }))); 84 .concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/modules/list_sub_erp.vue.vm
@@ -5,9 +5,10 @@ @@ -5,9 +5,10 @@
5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段 5 #set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex)) 6 #set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($subIndex))
7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写 7 #set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
  8 +#set ($apiName = "${table.moduleName.substring(0,1).toUpperCase()}${table.moduleName.substring(1)}${simpleClassName}Api")
8 <script lang="ts" setup> 9 <script lang="ts" setup>
9 import type { VxeTableGridOptions } from '#/adapter/vxe-table'; 10 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
10 -import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}'; 11 +import type { ${apiName} } from '#/api/${table.moduleName}/${table.businessName}';
11 12
12 #if ($table.templateType == 11) ## erp 13 #if ($table.templateType == 11) ## erp
13 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue' 14 import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
@@ -41,6 +42,19 @@ const [FormModal, formModalApi] = useVbenModal({ @@ -41,6 +42,19 @@ const [FormModal, formModalApi] = useVbenModal({
41 destroyOnClose: true, 42 destroyOnClose: true,
42 }); 43 });
43 44
  45 +/** 刷新表格 */
  46 +async function handleRefresh() {
  47 +#if ($table.templateType == 11) ## erp
  48 + await gridApi.query();
  49 +#else
  50 + #if ($subTable.subJoinMany) ## 一对多
  51 + await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));
  52 + #else
  53 + await gridApi.grid.loadData([await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)]);
  54 + #end
  55 +#end
  56 +}
  57 +
44 /** 创建${subTable.classComment} */ 58 /** 创建${subTable.classComment} */
45 function handleCreate() { 59 function handleCreate() {
46 if (!props.${subJoinColumn.javaField}){ 60 if (!props.${subJoinColumn.javaField}){
@@ -51,20 +65,19 @@ function handleCreate() { @@ -51,20 +65,19 @@ function handleCreate() {
51 } 65 }
52 66
53 /** 编辑${subTable.classComment} */ 67 /** 编辑${subTable.classComment} */
54 -function handleEdit(row: ${simpleClassName}Api.${subSimpleClassName}) { 68 +function handleEdit(row: ${apiName}.${subSimpleClassName}) {
55 formModalApi.setData(row).open(); 69 formModalApi.setData(row).open();
56 } 70 }
57 71
58 /** 删除${subTable.classComment} */ 72 /** 删除${subTable.classComment} */
59 -async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { 73 +async function handleDelete(row: ${apiName}.${subSimpleClassName}) {
60 const loadingInstance = ElLoading.service({ 74 const loadingInstance = ElLoading.service({
61 text: $t('ui.actionMessage.deleting', [row.id]), 75 text: $t('ui.actionMessage.deleting', [row.id]),
62 - background: 'rgba(0, 0, 0, 0.7)',  
63 }); 76 });
64 try { 77 try {
65 - await delete${subSimpleClassName}(row.id as number); 78 + await delete${subSimpleClassName}(row.id!);
66 ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id])); 79 ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.id]));
67 - onRefresh(); 80 + handleRefresh();
68 } finally { 81 } finally {
69 loadingInstance.close(); 82 loadingInstance.close();
70 } 83 }
@@ -75,13 +88,12 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { @@ -75,13 +88,12 @@ async function handleDelete(row: ${simpleClassName}Api.${subSimpleClassName}) {
75 async function handleDeleteBatch() { 88 async function handleDeleteBatch() {
76 const loadingInstance = ElLoading.service({ 89 const loadingInstance = ElLoading.service({
77 text: $t('ui.actionMessage.deleting'), 90 text: $t('ui.actionMessage.deleting'),
78 - background: 'rgba(0, 0, 0, 0.7)',  
79 }); 91 });
80 try { 92 try {
81 await delete${subSimpleClassName}List(checkedIds.value); 93 await delete${subSimpleClassName}List(checkedIds.value);
82 checkedIds.value = []; 94 checkedIds.value = [];
83 ElMessage.success($t('ui.actionMessage.deleteSuccess')); 95 ElMessage.success($t('ui.actionMessage.deleteSuccess'));
84 - onRefresh(); 96 + handleRefresh();
85 } finally { 97 } finally {
86 loadingInstance.close(); 98 loadingInstance.close();
87 } 99 }
@@ -91,7 +103,7 @@ const checkedIds = ref&lt;number[]&gt;([]) @@ -91,7 +103,7 @@ const checkedIds = ref&lt;number[]&gt;([])
91 function handleRowCheckboxChange({ 103 function handleRowCheckboxChange({
92 records, 104 records,
93 }: { 105 }: {
94 - records: ${simpleClassName}Api.${subSimpleClassName}[]; 106 + records: ${apiName}.${subSimpleClassName}[];
95 }) { 107 }) {
96 checkedIds.value = records.map((item) => item.id); 108 checkedIds.value = records.map((item) => item.id);
97 } 109 }
@@ -143,7 +155,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -143,7 +155,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
143 keyField: 'id', 155 keyField: 'id',
144 isHover: true, 156 isHover: true,
145 }, 157 },
146 - } as VxeTableGridOptions<${simpleClassName}Api.${subSimpleClassName}>, 158 + } as VxeTableGridOptions<${apiName}.${subSimpleClassName}>,
147 #if (${table.templateType} == 11 && $deleteBatchEnable) 159 #if (${table.templateType} == 11 && $deleteBatchEnable)
148 gridEvents:{ 160 gridEvents:{
149 checkboxAll: handleRowCheckboxChange, 161 checkboxAll: handleRowCheckboxChange,
@@ -152,19 +164,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ @@ -152,19 +164,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
152 #end 164 #end
153 }); 165 });
154 166
155 -/** 刷新表格 */  
156 -async function onRefresh() {  
157 -#if ($table.templateType == 11) ## erp  
158 - await gridApi.query();  
159 -#else  
160 - #if ($subTable.subJoinMany) ## 一对多  
161 - await gridApi.grid.loadData(await get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField}!));  
162 - #else  
163 - await gridApi.grid.loadData([await get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField}!)]);  
164 - #end  
165 -#end  
166 -}  
167 -  
168 /** 监听主表的关联字段的变化,加载对应的子表数据 */ 167 /** 监听主表的关联字段的变化,加载对应的子表数据 */
169 watch( 168 watch(
170 () => props.${subJoinColumn.javaField}, 169 () => props.${subJoinColumn.javaField},
@@ -173,7 +172,7 @@ watch( @@ -173,7 +172,7 @@ watch(
173 return; 172 return;
174 } 173 }
175 await nextTick(); 174 await nextTick();
176 - await onRefresh() 175 + await handleRefresh()
177 }, 176 },
178 { immediate: true }, 177 { immediate: true },
179 ); 178 );
@@ -181,7 +180,7 @@ watch( @@ -181,7 +180,7 @@ watch(
181 180
182 <template> 181 <template>
183 #if ($table.templateType == 11) ## erp 182 #if ($table.templateType == 11) ## erp
184 - <FormModal @success="onRefresh" /> 183 + <FormModal @success="handleRefresh" />
185 <Grid table-title="${subTable.classComment}列表"> 184 <Grid table-title="${subTable.classComment}列表">
186 <template #toolbar-tools> 185 <template #toolbar-tools>
187 <TableAction 186 <TableAction
@@ -211,7 +210,8 @@ watch( @@ -211,7 +210,8 @@ watch(
211 :actions="[ 210 :actions="[
212 { 211 {
213 label: $t('common.edit'), 212 label: $t('common.edit'),
214 - type: 'text', 213 + type: 'primary',
  214 + link: true,
215 icon: ACTION_ICON.EDIT, 215 icon: ACTION_ICON.EDIT,
216 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'], 216 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:update'],
217 onClick: handleEdit.bind(null, row), 217 onClick: handleEdit.bind(null, row),
@@ -219,7 +219,7 @@ watch( @@ -219,7 +219,7 @@ watch(
219 { 219 {
220 label: $t('common.delete'), 220 label: $t('common.delete'),
221 type: 'danger', 221 type: 'danger',
222 - text: true, 222 + link: true,
223 icon: ACTION_ICON.DELETE, 223 icon: ACTION_ICON.DELETE,
224 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'], 224 auth: ['${table.moduleName}:${simpleClassName_strikeCase}:delete'],
225 popConfirm: { 225 popConfirm: {