Commit bb11fdd3fa4b006df1c7b675753eddc15fcf7fc3
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/iot
# Conflicts: # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http
Showing
68 changed files
with
703 additions
and
355 deletions
script/idea/http-client.env.json
| ... | ... | @@ -2,16 +2,16 @@ |
| 2 | 2 | "local": { |
| 3 | 3 | "baseUrl": "http://127.0.0.1:48080/admin-api", |
| 4 | 4 | "token": "test1", |
| 5 | - "adminTenentId": "1", | |
| 5 | + "adminTenantId": "1", | |
| 6 | 6 | |
| 7 | 7 | "appApi": "http://127.0.0.1:48080/app-api", |
| 8 | 8 | "appToken": "test247", |
| 9 | - "appTenentId": "1" | |
| 9 | + "appTenantId": "1" | |
| 10 | 10 | }, |
| 11 | 11 | "gateway": { |
| 12 | 12 | "baseUrl": "http://127.0.0.1:8888/admin-api", |
| 13 | 13 | "token": "test1", |
| 14 | - "adminTenentId": "1", | |
| 14 | + "adminTenantId": "1", | |
| 15 | 15 | |
| 16 | 16 | "appApi": "http://127.0.0.1:8888/app-api", |
| 17 | 17 | "appToken": "test1", | ... | ... |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/json/JsonUtils.java
| ... | ... | @@ -199,4 +199,12 @@ public class JsonUtils { |
| 199 | 199 | return JSONUtil.isTypeJSON(text); |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | + /** | |
| 203 | + * 判断字符串是否为 JSON 类型的字符串 | |
| 204 | + * @param str 字符串 | |
| 205 | + */ | |
| 206 | + public static boolean isJsonObject(String str) { | |
| 207 | + return JSONUtil.isTypeJSONObject(str); | |
| 208 | + } | |
| 209 | + | |
| 202 | 210 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java
| ... | ... | @@ -20,8 +20,8 @@ public abstract class ApiRequestFilter extends OncePerRequestFilter { |
| 20 | 20 | @Override |
| 21 | 21 | protected boolean shouldNotFilter(HttpServletRequest request) { |
| 22 | 22 | // 只过滤 API 请求的地址 |
| 23 | - return !StrUtil.startWithAny(request.getRequestURI(), webProperties.getAdminApi().getPrefix(), | |
| 24 | - webProperties.getAppApi().getPrefix()); | |
| 23 | + String apiUri = request.getRequestURI().substring(request.getContextPath().length()); | |
| 24 | + return !StrUtil.startWithAny(apiUri, webProperties.getAdminApi().getPrefix(), webProperties.getAppApi().getPrefix()); | |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | } | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{baseUrl}}/ai/chat/message/send |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "conversationId": "1781604279872581724", |
| ... | ... | @@ -13,7 +13,7 @@ tenant-id: {{adminTenentId}} |
| 13 | 13 | POST {{baseUrl}}/ai/chat/message/send-stream |
| 14 | 14 | Content-Type: application/json |
| 15 | 15 | Authorization: {{token}} |
| 16 | -tenant-id: {{adminTenentId}} | |
| 16 | +tenant-id: {{adminTenantId}} | |
| 17 | 17 | |
| 18 | 18 | { |
| 19 | 19 | "conversationId": "1781604279872581724", | ... | ... |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTriggerTypeEnum.java
| ... | ... | @@ -16,7 +16,8 @@ import java.util.Arrays; |
| 16 | 16 | @AllArgsConstructor |
| 17 | 17 | public enum BpmTriggerTypeEnum implements ArrayValuable<Integer> { |
| 18 | 18 | |
| 19 | - HTTP_REQUEST(1, "发起 HTTP 请求"); | |
| 19 | + HTTP_REQUEST(1, "发起 HTTP 请求"), | |
| 20 | + UPDATE_NORMAL_FORM(2, "更新流程表单"); // TODO @jason:FORM_UPDATE | |
| 20 | 21 | |
| 21 | 22 | /** |
| 22 | 23 | * 触发器执行动作类型 | ... | ... |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
| 1 | 1 | package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.core.KeyValue; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | 5 | import cn.iocoder.yudao.module.bpm.enums.definition.*; |
| 5 | 6 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; |
| ... | ... | @@ -157,6 +158,7 @@ public class BpmSimpleModelNodeVO { |
| 157 | 158 | @Schema(description = "值", example = "xxx") |
| 158 | 159 | @NotEmpty(message = "值不能为空") |
| 159 | 160 | private String value; |
| 161 | + | |
| 160 | 162 | } |
| 161 | 163 | |
| 162 | 164 | @Schema(description = "审批节点拒绝处理策略") |
| ... | ... | @@ -343,6 +345,13 @@ public class BpmSimpleModelNodeVO { |
| 343 | 345 | @Valid |
| 344 | 346 | private HttpRequestTriggerSetting httpRequestSetting; |
| 345 | 347 | |
| 348 | + // TODO @jason:这个要不直接叫 formSetting,更好理解一点哈 | |
| 349 | + // TODO @jason:如果搞成 List<NormalFormTriggerSetting>,是不是可以做条件组了?微信讨论哈 | |
| 350 | + /** | |
| 351 | + * 流程表单触发器设置 | |
| 352 | + */ | |
| 353 | + private NormalFormTriggerSetting normalFormSetting; | |
| 354 | + | |
| 346 | 355 | @Schema(description = "http 请求触发器设置", example = "{}") |
| 347 | 356 | @Data |
| 348 | 357 | public static class HttpRequestTriggerSetting { |
| ... | ... | @@ -359,6 +368,26 @@ public class BpmSimpleModelNodeVO { |
| 359 | 368 | @Schema(description = "请求头参数设置", example = "[]") |
| 360 | 369 | @Valid |
| 361 | 370 | private List<HttpRequestParam> body; |
| 371 | + | |
| 372 | + // TODO @json:可能未来看情况,搞个 HttpResponseParam;得看看有没别的业务需要,抽象统一 | |
| 373 | + /** | |
| 374 | + * 请求返回处理设置,用于修改流程表单值 | |
| 375 | + * <p> | |
| 376 | + * key:表示要修改的流程表单字段名(name) | |
| 377 | + * value:接口返回的字段名 | |
| 378 | + */ | |
| 379 | + @Schema(description = "请求返回处理设置", example = "[]") | |
| 380 | + private List<KeyValue<String, String>> response; | |
| 381 | + | |
| 382 | + } | |
| 383 | + | |
| 384 | + @Schema(description = "流程表单触发器设置", example = "{}") | |
| 385 | + @Data | |
| 386 | + public static class NormalFormTriggerSetting { | |
| 387 | + | |
| 388 | + @Schema(description = "修改的表单字段", example = "userName") | |
| 389 | + private Map<String, Object> updateFormFields; | |
| 390 | + | |
| 362 | 391 | } |
| 363 | 392 | |
| 364 | 393 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
| ... | ... | @@ -9,7 +9,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 9 | 9 | import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; |
| 10 | 10 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc.BpmProcessInstanceCopyRespVO; |
| 11 | 11 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO; |
| 12 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; | |
| 12 | 13 | import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO; |
| 14 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | |
| 15 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; | |
| 13 | 16 | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService; |
| 14 | 17 | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; |
| 15 | 18 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| ... | ... | @@ -42,6 +45,8 @@ public class BpmProcessInstanceCopyController { |
| 42 | 45 | private BpmProcessInstanceCopyService processInstanceCopyService; |
| 43 | 46 | @Resource |
| 44 | 47 | private BpmProcessInstanceService processInstanceService; |
| 48 | + @Resource | |
| 49 | + private BpmProcessDefinitionService processDefinitionService; | |
| 45 | 50 | |
| 46 | 51 | @Resource |
| 47 | 52 | private AdminUserApi adminUserApi; |
| ... | ... | @@ -62,6 +67,8 @@ public class BpmProcessInstanceCopyController { |
| 62 | 67 | convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId)); |
| 63 | 68 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(), |
| 64 | 69 | copy -> Stream.of(copy.getStartUserId(), Long.parseLong(copy.getCreator())))); |
| 70 | + Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap = processDefinitionService.getProcessDefinitionInfoMap( | |
| 71 | + convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessDefinitionId)); | |
| 65 | 72 | return success(convertPage(pageResult, copy -> { |
| 66 | 73 | BpmProcessInstanceCopyRespVO copyVO = BeanUtils.toBean(copy, BpmProcessInstanceCopyRespVO.class); |
| 67 | 74 | MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), |
| ... | ... | @@ -69,7 +76,12 @@ public class BpmProcessInstanceCopyController { |
| 69 | 76 | MapUtils.findAndThen(userMap, copy.getStartUserId(), |
| 70 | 77 | user -> copyVO.setCreateUser(BeanUtils.toBean(user, UserSimpleBaseVO.class))); |
| 71 | 78 | MapUtils.findAndThen(processInstanceMap, copyVO.getProcessInstanceId(), |
| 72 | - processInstance -> copyVO.setProcessInstanceStartTime(DateUtils.of(processInstance.getStartTime()))); | |
| 79 | + processInstance -> { | |
| 80 | + copyVO.setSummary(FlowableUtils.getSummary( | |
| 81 | + processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), | |
| 82 | + processInstance.getProcessVariables())); | |
| 83 | + copyVO.setProcessInstanceStartTime(DateUtils.of(processInstance.getStartTime())); | |
| 84 | + }); | |
| 73 | 85 | return copyVO; |
| 74 | 86 | })); |
| 75 | 87 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java
| 1 | 1 | package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.core.KeyValue; | |
| 3 | 4 | import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; |
| 4 | 5 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | |
| 7 | 8 | import java.time.LocalDateTime; |
| 9 | +import java.util.List; | |
| 8 | 10 | |
| 9 | 11 | @Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO") |
| 10 | 12 | @Data |
| ... | ... | @@ -40,4 +42,7 @@ public class BpmProcessInstanceCopyRespVO { |
| 40 | 42 | @Schema(description = "抄送时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 41 | 43 | private LocalDateTime createTime; |
| 42 | 44 | |
| 45 | + @Schema(description = "流程摘要", example = "[]") | |
| 46 | + private List<KeyValue<String, String>> summary; | |
| 47 | + | |
| 43 | 48 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java
| ... | ... | @@ -32,7 +32,14 @@ public class BpmProcessInstancePageReqVO extends PageParam { |
| 32 | 32 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 33 | 33 | private LocalDateTime[] createTime; |
| 34 | 34 | |
| 35 | + @Schema(description = "结束时间") | |
| 36 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 37 | + private LocalDateTime[] endTime; | |
| 38 | + | |
| 35 | 39 | @Schema(description = "发起用户编号", example = "1024") |
| 36 | 40 | private Long startUserId; // 注意,只有在【流程实例】菜单,才使用该参数 |
| 37 | 41 | |
| 42 | + @Schema(description = "动态表单字段查询 JSON Str", example = "{}") | |
| 43 | + private String formFieldsParams; // SpringMVC 在 get 请求下,无法方便的定义 Map 类型的参数,所以通过 String 接收后,逻辑里面转换 | |
| 44 | + | |
| 38 | 45 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
| ... | ... | @@ -85,10 +85,6 @@ public class BpmTaskRespVO { |
| 85 | 85 | @Schema(description = "是否填写审批意见", example = "false") |
| 86 | 86 | private Boolean reasonRequire; |
| 87 | 87 | |
| 88 | - // TODO @lesan:要不放到 processInstance 里面?因为摘要是流程实例的,不是流程任务的 | |
| 89 | - @Schema(description = "流程摘要", example = "[]") | |
| 90 | - private List<KeyValue<String, String>> summary; // 只有流程表单,才有摘要! | |
| 91 | - | |
| 92 | 88 | @Data |
| 93 | 89 | @Schema(description = "流程实例") |
| 94 | 90 | public static class ProcessInstance { |
| ... | ... | @@ -105,6 +101,9 @@ public class BpmTaskRespVO { |
| 105 | 101 | @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") |
| 106 | 102 | private String processDefinitionId; |
| 107 | 103 | |
| 104 | + @Schema(description = "流程摘要", example = "[]") | |
| 105 | + private List<KeyValue<String, String>> summary; // 只有流程表单,才有摘要! | |
| 106 | + | |
| 108 | 107 | /** |
| 109 | 108 | * 发起人的用户信息 |
| 110 | 109 | */ | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
| ... | ... | @@ -80,6 +80,8 @@ public interface BpmProcessInstanceConvert { |
| 80 | 80 | // 摘要 |
| 81 | 81 | respVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(respVO.getProcessDefinitionId()), |
| 82 | 82 | pageResult.getList().get(i).getProcessVariables())); |
| 83 | + // 表单 | |
| 84 | + respVO.setFormVariables(pageResult.getList().get(i).getProcessVariables()); | |
| 83 | 85 | } |
| 84 | 86 | return vpPageResult; |
| 85 | 87 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
| ... | ... | @@ -54,7 +54,7 @@ public interface BpmTaskConvert { |
| 54 | 54 | AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); |
| 55 | 55 | taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); |
| 56 | 56 | // 摘要 |
| 57 | - taskVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), | |
| 57 | + taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), | |
| 58 | 58 | processInstance.getProcessVariables())); |
| 59 | 59 | }); |
| 60 | 60 | } |
| ... | ... | @@ -80,7 +80,7 @@ public interface BpmTaskConvert { |
| 80 | 80 | taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class)); |
| 81 | 81 | taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); |
| 82 | 82 | // 摘要 |
| 83 | - taskVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), | |
| 83 | + taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), | |
| 84 | 84 | processInstance.getProcessVariables())); |
| 85 | 85 | } |
| 86 | 86 | return taskVO; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java
| ... | ... | @@ -50,6 +50,12 @@ public class BpmProcessInstanceCopyDO extends BaseDO { |
| 50 | 50 | */ |
| 51 | 51 | private String processInstanceId; |
| 52 | 52 | /** |
| 53 | + * 流程实例的流程定义编号 | |
| 54 | + * | |
| 55 | + * 关联 ProcessInstance 的 processDefinitionId 属性 | |
| 56 | + */ | |
| 57 | + private String processDefinitionId; | |
| 58 | + /** | |
| 53 | 59 | * 流程分类 |
| 54 | 60 | * |
| 55 | 61 | * 冗余 ProcessInstance 的 category 字段 | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/BpmProcessIdRedisDAO.java
| 1 | 1 | package cn.iocoder.yudao.module.bpm.dal.redis; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.date.DateUtil; |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 4 | 5 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; |
| 5 | 6 | import jakarta.annotation.Resource; |
| 6 | 7 | import org.springframework.data.redis.core.StringRedisTemplate; |
| ... | ... | @@ -48,7 +49,10 @@ public class BpmProcessIdRedisDAO { |
| 48 | 49 | String noPrefix = processIdRule.getPrefix() + infix + processIdRule.getPostfix(); |
| 49 | 50 | String key = RedisKeyConstants.BPM_PROCESS_ID + noPrefix; |
| 50 | 51 | Long no = stringRedisTemplate.opsForValue().increment(key); |
| 51 | - stringRedisTemplate.expire(key, Duration.ofDays(1L)); | |
| 52 | + if (StrUtil.isEmpty(infix)) { | |
| 53 | + // 特殊:没有前缀,则不能过期,不能每次都是从 0 开始 | |
| 54 | + stringRedisTemplate.expire(key, Duration.ofDays(1L)); | |
| 55 | + } | |
| 52 | 56 | return noPrefix + String.format("%0" + processIdRule.getLength() + "d", no); |
| 53 | 57 | } |
| 54 | 58 | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
| ... | ... | @@ -64,6 +64,13 @@ public class BpmnModelUtils { |
| 64 | 64 | addExtensionElement(element, name, String.valueOf(value)); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | + public static void addExtensionElementJson(FlowElement element, String name, Object value) { | |
| 68 | + if (value == null) { | |
| 69 | + return; | |
| 70 | + } | |
| 71 | + addExtensionElement(element, name, JsonUtils.toJsonString(value)); | |
| 72 | + } | |
| 73 | + | |
| 67 | 74 | public static void addExtensionElement(FlowElement element, String name, Map<String, String> attributes) { |
| 68 | 75 | if (attributes == null) { |
| 69 | 76 | return; | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
| ... | ... | @@ -26,6 +26,9 @@ import org.flowable.task.api.TaskInfo; |
| 26 | 26 | |
| 27 | 27 | import java.util.*; |
| 28 | 28 | import java.util.concurrent.Callable; |
| 29 | +import java.util.stream.Collectors; | |
| 30 | + | |
| 31 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 29 | 32 | |
| 30 | 33 | /** |
| 31 | 34 | * Flowable 相关的工具方法 |
| ... | ... | @@ -193,7 +196,6 @@ public class FlowableUtils { |
| 193 | 196 | BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES); |
| 194 | 197 | } |
| 195 | 198 | |
| 196 | - // TODO @lesan:如果值是 null 的情况,可能要调研下飞书、钉钉,是不是不返回哈! | |
| 197 | 199 | /** |
| 198 | 200 | * 获得流程实例的摘要 |
| 199 | 201 | * |
| ... | ... | @@ -206,53 +208,40 @@ public class FlowableUtils { |
| 206 | 208 | */ |
| 207 | 209 | public static List<KeyValue<String, String>> getSummary(BpmProcessDefinitionInfoDO processDefinitionInfo, |
| 208 | 210 | Map<String, Object> processVariables) { |
| 209 | - // TODO @lesan:建议 if return,减少 { 层级 | |
| 210 | - if (ObjectUtil.isNotNull(processDefinitionInfo) | |
| 211 | - && BpmModelFormTypeEnum.NORMAL.getType().equals(processDefinitionInfo.getFormType())) { | |
| 212 | - List<KeyValue<String, String>> summaryList = new ArrayList<>(); | |
| 213 | - // TODO @lesan:可以使用 CollUtils.convertMap 简化工作量哈。 | |
| 214 | - Map<String, BpmFormFieldVO> formFieldsMap = new HashMap<>(); | |
| 215 | - processDefinitionInfo.getFormFields().forEach(formFieldStr -> { | |
| 216 | - BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class); | |
| 211 | + // 只有流程表单才会显示摘要! | |
| 212 | + if (ObjectUtil.isNull(processDefinitionInfo) | |
| 213 | + || !BpmModelFormTypeEnum.NORMAL.getType().equals(processDefinitionInfo.getFormType())) { | |
| 214 | + return null; | |
| 215 | + } | |
| 216 | + | |
| 217 | + // 解析表单配置 | |
| 218 | + Map<String, BpmFormFieldVO> formFieldsMap = new HashMap<>(); | |
| 219 | + processDefinitionInfo.getFormFields().forEach(formFieldStr -> { | |
| 220 | + BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class); | |
| 221 | + if (formField != null) { | |
| 222 | + formFieldsMap.put(formField.getField(), formField); | |
| 223 | + } | |
| 224 | + }); | |
| 225 | + | |
| 226 | + // 情况一:当自定义了摘要 | |
| 227 | + if (ObjectUtil.isNotNull(processDefinitionInfo.getSummarySetting()) | |
| 228 | + && Boolean.TRUE.equals(processDefinitionInfo.getSummarySetting().getEnable())) { | |
| 229 | + return convertList(processDefinitionInfo.getSummarySetting().getSummary(), item -> { | |
| 230 | + BpmFormFieldVO formField = formFieldsMap.get(item); | |
| 217 | 231 | if (formField != null) { |
| 218 | - formFieldsMap.put(formField.getField(), formField); | |
| 232 | + return new KeyValue<String, String>(formField.getTitle(), | |
| 233 | + processVariables.getOrDefault(item, "").toString()); | |
| 219 | 234 | } |
| 235 | + return null; | |
| 220 | 236 | }); |
| 221 | - | |
| 222 | - // TODO @lesan:这里也可以 if return,还是为了减少括号哈。这样,就可以写注释,情况一:;情况二: | |
| 223 | - if (ObjectUtil.isNotNull(processDefinitionInfo.getSummarySetting()) | |
| 224 | - && Boolean.TRUE.equals(processDefinitionInfo.getSummarySetting().getEnable())) { | |
| 225 | - // TODO @lesan:这里,也可以通过 CollUtils.convertList 简化哈。 | |
| 226 | - for (String item : processDefinitionInfo.getSummarySetting().getSummary()) { | |
| 227 | - BpmFormFieldVO formField = formFieldsMap.get(item); | |
| 228 | - if (formField != null) { | |
| 229 | - summaryList.add(new KeyValue<>(formField.getTitle(), | |
| 230 | - processVariables.getOrDefault(item, "").toString())); | |
| 231 | - } | |
| 232 | - } | |
| 233 | - } else { | |
| 234 | - // 默认展示前三个 | |
| 235 | - /* TODO @lesan:stream 简化 | |
| 236 | - * summaryList.addAll(formFieldsMap.entrySet().stream() | |
| 237 | - * .limit(3) | |
| 238 | - * .map(entry -> new KeyValue<>(entry.getValue().getTitle(), | |
| 239 | - * processVariables.getOrDefault(entry.getValue().getField(), "").toString())) | |
| 240 | - * .collect(Collectors.toList())); | |
| 241 | - */ | |
| 242 | - int j = 0; | |
| 243 | - for (Map.Entry<String, BpmFormFieldVO> entry : formFieldsMap.entrySet()) { | |
| 244 | - BpmFormFieldVO formField = entry.getValue(); | |
| 245 | - if (j > 2) { | |
| 246 | - break; | |
| 247 | - } | |
| 248 | - summaryList.add(new KeyValue<>(formField.getTitle(), | |
| 249 | - processVariables.getOrDefault(formField.getField(), "").toString())); | |
| 250 | - j++; | |
| 251 | - } | |
| 252 | - } | |
| 253 | - return summaryList; | |
| 254 | 237 | } |
| 255 | - return null; | |
| 238 | + | |
| 239 | + // 情况二:默认摘要展示前三个表单字段 | |
| 240 | + return formFieldsMap.entrySet().stream() | |
| 241 | + .limit(3) | |
| 242 | + .map(entry -> new KeyValue<>(entry.getValue().getTitle(), | |
| 243 | + processVariables.getOrDefault(entry.getValue().getField(), "").toString())) | |
| 244 | + .collect(Collectors.toList()); | |
| 256 | 245 | } |
| 257 | 246 | |
| 258 | 247 | // ========== Task 相关的工具方法 ========== |
| ... | ... | @@ -317,9 +306,9 @@ public class FlowableUtils { |
| 317 | 306 | |
| 318 | 307 | private static Object getExpressionValue(VariableContainer variableContainer, String expressionString, |
| 319 | 308 | ProcessEngineConfigurationImpl processEngineConfiguration) { |
| 320 | - assert processEngineConfiguration!= null; | |
| 309 | + assert processEngineConfiguration != null; | |
| 321 | 310 | ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager(); |
| 322 | - assert expressionManager!= null; | |
| 311 | + assert expressionManager != null; | |
| 323 | 312 | Expression expression = expressionManager.createExpression(expressionString); |
| 324 | 313 | return expression.getValue(variableContainer); |
| 325 | 314 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| ... | ... | @@ -5,7 +5,6 @@ import cn.hutool.core.lang.Assert; |
| 5 | 5 | import cn.hutool.core.map.MapUtil; |
| 6 | 6 | import cn.hutool.core.util.*; |
| 7 | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 8 | -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 9 | 8 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 10 | 9 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups; |
| 11 | 10 | import cn.iocoder.yudao.module.bpm.enums.definition.*; |
| ... | ... | @@ -626,54 +625,50 @@ public class SimpleModelUtils { |
| 626 | 625 | |
| 627 | 626 | public static SequenceFlow buildSequenceFlow(String sourceId, String targetId, |
| 628 | 627 | BpmSimpleModelNodeVO node) { |
| 629 | - String conditionExpression = buildConditionExpression(node); | |
| 628 | + String conditionExpression = buildConditionExpression(node.getConditionSetting()); | |
| 630 | 629 | return buildBpmnSequenceFlow(sourceId, targetId, node.getId(), node.getName(), conditionExpression); |
| 631 | 630 | } |
| 631 | + } | |
| 632 | 632 | |
| 633 | - /** | |
| 634 | - * 构造条件表达式 | |
| 635 | - * | |
| 636 | - * @param node 条件节点 | |
| 637 | - */ | |
| 638 | - public static String buildConditionExpression(BpmSimpleModelNodeVO node) { | |
| 639 | - return buildConditionExpression(node.getConditionSetting().getConditionType(), node.getConditionSetting().getConditionExpression(), | |
| 640 | - node.getConditionSetting().getConditionGroups()); | |
| 641 | - } | |
| 633 | + /** | |
| 634 | + * 构造条件表达式 | |
| 635 | + */ | |
| 636 | + public static String buildConditionExpression(BpmSimpleModelNodeVO.ConditionSetting conditionSetting) { | |
| 637 | + return buildConditionExpression(conditionSetting.getConditionType(), conditionSetting.getConditionExpression(), | |
| 638 | + conditionSetting.getConditionGroups()); | |
| 639 | + } | |
| 642 | 640 | |
| 643 | - public static String buildConditionExpression(BpmSimpleModelNodeVO.RouterSetting router) { | |
| 644 | - return buildConditionExpression(router.getConditionType(), router.getConditionExpression(), | |
| 645 | - router.getConditionGroups()); | |
| 646 | - } | |
| 641 | + public static String buildConditionExpression(BpmSimpleModelNodeVO.RouterSetting routerSetting) { | |
| 642 | + return buildConditionExpression(routerSetting.getConditionType(), routerSetting.getConditionExpression(), | |
| 643 | + routerSetting.getConditionGroups()); | |
| 644 | + } | |
| 647 | 645 | |
| 648 | - public static String buildConditionExpression(Integer conditionType, String conditionExpression, | |
| 649 | - ConditionGroups conditionGroups) { | |
| 650 | - BpmSimpleModeConditionTypeEnum conditionTypeEnum = BpmSimpleModeConditionTypeEnum.valueOf(conditionType); | |
| 651 | - if (conditionTypeEnum == BpmSimpleModeConditionTypeEnum.EXPRESSION) { | |
| 652 | - return conditionExpression; | |
| 646 | + public static String buildConditionExpression(Integer conditionType, String conditionExpression, ConditionGroups conditionGroups) { | |
| 647 | + BpmSimpleModeConditionTypeEnum conditionTypeEnum = BpmSimpleModeConditionTypeEnum.valueOf(conditionType); | |
| 648 | + if (conditionTypeEnum == BpmSimpleModeConditionTypeEnum.EXPRESSION) { | |
| 649 | + return conditionExpression; | |
| 650 | + } | |
| 651 | + if (conditionTypeEnum == BpmSimpleModeConditionTypeEnum.RULE) { | |
| 652 | + if (conditionGroups == null || CollUtil.isEmpty(conditionGroups.getConditions())) { | |
| 653 | + return null; | |
| 653 | 654 | } |
| 654 | - if (conditionTypeEnum == BpmSimpleModeConditionTypeEnum.RULE) { | |
| 655 | - if (conditionGroups == null || CollUtil.isEmpty(conditionGroups.getConditions())) { | |
| 656 | - return null; | |
| 655 | + List<String> strConditionGroups = CollectionUtils.convertList(conditionGroups.getConditions(), item -> { | |
| 656 | + if (CollUtil.isEmpty(item.getRules())) { | |
| 657 | + return ""; | |
| 657 | 658 | } |
| 658 | - List<String> strConditionGroups = CollectionUtils.convertList(conditionGroups.getConditions(), item -> { | |
| 659 | - if (CollUtil.isEmpty(item.getRules())) { | |
| 660 | - return ""; | |
| 661 | - } | |
| 662 | - // 构造规则表达式 | |
| 663 | - List<String> list = CollectionUtils.convertList(item.getRules(), (rule) -> { | |
| 664 | - String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() | |
| 665 | - : "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号 | |
| 666 | - return String.format(" %s %s var:convertByType(%s,%s)", rule.getLeftSide(), rule.getOpCode(), rule.getLeftSide(), rightSide); | |
| 667 | - }); | |
| 668 | - // 构造条件组的表达式 | |
| 669 | - Boolean and = item.getAnd(); | |
| 670 | - return "(" + CollUtil.join(list, and ? " && " : " || ") + ")"; | |
| 659 | + // 构造规则表达式 | |
| 660 | + List<String> list = CollectionUtils.convertList(item.getRules(), (rule) -> { | |
| 661 | + String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() | |
| 662 | + : "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号 | |
| 663 | + return String.format(" %s %s var:convertByType(%s,%s)", rule.getLeftSide(), rule.getOpCode(), rule.getLeftSide(), rightSide); | |
| 671 | 664 | }); |
| 672 | - return String.format("${%s}", CollUtil.join(strConditionGroups, conditionGroups.getAnd() ? " && " : " || ")); | |
| 673 | - } | |
| 674 | - return null; | |
| 665 | + // 构造条件组的表达式 | |
| 666 | + Boolean and = item.getAnd(); | |
| 667 | + return "(" + CollUtil.join(list, and ? " && " : " || ") + ")"; | |
| 668 | + }); | |
| 669 | + return String.format("${%s}", CollUtil.join(strConditionGroups, conditionGroups.getAnd() ? " && " : " || ")); | |
| 675 | 670 | } |
| 676 | - | |
| 671 | + return null; | |
| 677 | 672 | } |
| 678 | 673 | |
| 679 | 674 | public static class DelayTimerNodeConvert implements NodeConvert { |
| ... | ... | @@ -727,9 +722,10 @@ public class SimpleModelUtils { |
| 727 | 722 | if (node.getTriggerSetting() != null) { |
| 728 | 723 | addExtensionElement(serviceTask, TRIGGER_TYPE, node.getTriggerSetting().getType()); |
| 729 | 724 | if (node.getTriggerSetting().getHttpRequestSetting() != null) { |
| 730 | - // TODO @jason:加个 addExtensionElementJson 方法,方便设置 JSON 类型的属性 | |
| 731 | - addExtensionElement(serviceTask, TRIGGER_PARAM, | |
| 732 | - JsonUtils.toJsonString(node.getTriggerSetting().getHttpRequestSetting())); | |
| 725 | + addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getHttpRequestSetting()); | |
| 726 | + } | |
| 727 | + if (node.getTriggerSetting().getNormalFormSetting() != null) { | |
| 728 | + addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getNormalFormSetting()); | |
| 733 | 729 | } |
| 734 | 730 | } |
| 735 | 731 | return serviceTask; |
| ... | ... | @@ -760,7 +756,7 @@ public class SimpleModelUtils { |
| 760 | 756 | } |
| 761 | 757 | |
| 762 | 758 | public static SequenceFlow buildSequenceFlow(String nodeId, BpmSimpleModelNodeVO.RouterSetting router) { |
| 763 | - String conditionExpression = ConditionNodeConvert.buildConditionExpression(router); | |
| 759 | + String conditionExpression = SimpleModelUtils.buildConditionExpression(router); | |
| 764 | 760 | return buildBpmnSequenceFlow(nodeId, router.getNodeId(), null, null, conditionExpression); |
| 765 | 761 | } |
| 766 | 762 | |
| ... | ... | @@ -804,7 +800,7 @@ public class SimpleModelUtils { |
| 804 | 800 | // 查找满足条件的 BpmSimpleModelNodeVO 节点 |
| 805 | 801 | BpmSimpleModelNodeVO matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), |
| 806 | 802 | conditionNode -> !BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow()) |
| 807 | - && evalConditionExpress(variables, conditionNode)); | |
| 803 | + && evalConditionExpress(variables, conditionNode.getConditionSetting())); | |
| 808 | 804 | if (matchConditionNode == null) { |
| 809 | 805 | matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), |
| 810 | 806 | conditionNode -> BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow())); |
| ... | ... | @@ -819,7 +815,7 @@ public class SimpleModelUtils { |
| 819 | 815 | // 查找满足条件的 BpmSimpleModelNodeVO 节点 |
| 820 | 816 | Collection<BpmSimpleModelNodeVO> matchConditionNodes = CollUtil.filterNew(currentNode.getConditionNodes(), |
| 821 | 817 | conditionNode -> !BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow()) |
| 822 | - && evalConditionExpress(variables, conditionNode)); | |
| 818 | + && evalConditionExpress(variables, conditionNode.getConditionSetting())); | |
| 823 | 819 | if (CollUtil.isEmpty(matchConditionNodes)) { |
| 824 | 820 | matchConditionNodes = CollUtil.filterNew(currentNode.getConditionNodes(), |
| 825 | 821 | conditionNode -> BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow())); |
| ... | ... | @@ -841,16 +837,17 @@ public class SimpleModelUtils { |
| 841 | 837 | simulateNextNode(currentNode.getChildNode(), variables, resultNodes); |
| 842 | 838 | } |
| 843 | 839 | |
| 844 | - public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO conditionNode) { | |
| 845 | - return BpmnModelUtils.evalConditionExpress(variables, ConditionNodeConvert.buildConditionExpression(conditionNode)); | |
| 840 | + public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO.ConditionSetting conditionSetting) { | |
| 841 | + return BpmnModelUtils.evalConditionExpress(variables, buildConditionExpression(conditionSetting)); | |
| 846 | 842 | } |
| 847 | 843 | |
| 848 | 844 | // TODO @芋艿:【高】要不要优化下,抽个 HttpUtils |
| 845 | + | |
| 849 | 846 | /** |
| 850 | 847 | * 添加 HTTP 请求参数。请求头或者请求体 |
| 851 | 848 | * |
| 852 | - * @param params HTTP 请求参数 | |
| 853 | - * @param paramSettings HTTP 请求参数设置 | |
| 849 | + * @param params HTTP 请求参数 | |
| 850 | + * @param paramSettings HTTP 请求参数设置 | |
| 854 | 851 | * @param processVariables 流程变量 |
| 855 | 852 | */ |
| 856 | 853 | public static void addHttpRequestParam(MultiValueMap<String, String> params, | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
| ... | ... | @@ -86,6 +86,7 @@ public class BpmModelServiceImpl implements BpmModelService { |
| 86 | 86 | if (StrUtil.isNotEmpty(name)) { |
| 87 | 87 | modelQuery.modelNameLike("%" + name + "%"); |
| 88 | 88 | } |
| 89 | + modelQuery.modelTenantId(FlowableUtils.getTenantId()); | |
| 89 | 90 | return modelQuery.list(); |
| 90 | 91 | } |
| 91 | 92 | |
| ... | ... | @@ -288,8 +289,7 @@ public class BpmModelServiceImpl implements BpmModelService { |
| 288 | 289 | // 2.3 清理所有 Task |
| 289 | 290 | List<Task> tasks = taskService.createTaskQuery() |
| 290 | 291 | .processDefinitionKey(model.getKey()).list(); |
| 291 | - // TODO @lesan:貌似传递一个 reason 会好点! | |
| 292 | - tasks.forEach(task -> taskService.deleteTask(task.getId())); | |
| 292 | + tasks.forEach(task -> taskService.deleteTask(task.getId(),BpmReasonEnum.CANCEL_BY_PROCESS_CLEAN.getReason())); | |
| 293 | 293 | } |
| 294 | 294 | |
| 295 | 295 | @Override | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java
| ... | ... | @@ -77,7 +77,8 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy |
| 77 | 77 | .setUserId(userId).setReason(reason).setStartUserId(Long.valueOf(processInstance.getStartUserId())) |
| 78 | 78 | .setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName()) |
| 79 | 79 | .setCategory(processDefinition.getCategory()).setTaskId(taskId) |
| 80 | - .setActivityId(activityId).setActivityName(activityName)); | |
| 80 | + .setActivityId(activityId).setActivityName(activityName) | |
| 81 | + .setProcessDefinitionId(processInstance.getProcessDefinitionId())); | |
| 81 | 82 | processInstanceCopyMapper.insertBatch(copyList); |
| 82 | 83 | } |
| 83 | 84 | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
| ... | ... | @@ -157,4 +157,12 @@ public interface BpmProcessInstanceService { |
| 157 | 157 | */ |
| 158 | 158 | void processProcessInstanceCompleted(ProcessInstance instance); |
| 159 | 159 | |
| 160 | + /** | |
| 161 | + * 更新 ProcessInstance 的变量 | |
| 162 | + * | |
| 163 | + * @param id 流程编号 | |
| 164 | + * @param variables 流程变量 | |
| 165 | + */ | |
| 166 | + void updateProcessInstanceVariables(String id, Map<String, Object> variables); | |
| 167 | + | |
| 160 | 168 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
| ... | ... | @@ -133,56 +133,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 133 | 133 | |
| 134 | 134 | @Override |
| 135 | 135 | public HistoricProcessInstance getHistoricProcessInstance(String id) { |
| 136 | - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult(); | |
| 136 | + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables() | |
| 137 | + .singleResult(); | |
| 137 | 138 | } |
| 138 | 139 | |
| 139 | 140 | @Override |
| 140 | 141 | public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { |
| 141 | - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables().list(); | |
| 142 | + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables() | |
| 143 | + .list(); | |
| 142 | 144 | } |
| 143 | 145 | |
| 144 | - @Override | |
| 145 | - public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId, | |
| 146 | - BpmProcessInstancePageReqVO pageReqVO) { | |
| 147 | - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 | |
| 148 | - HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery() | |
| 149 | - .includeProcessVariables() | |
| 150 | - .processInstanceTenantId(FlowableUtils.getTenantId()) | |
| 151 | - .orderByProcessInstanceStartTime().desc(); | |
| 152 | - if (userId != null) { // 【我的流程】菜单时,需要传递该字段 | |
| 153 | - processInstanceQuery.startedBy(String.valueOf(userId)); | |
| 154 | - } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段 | |
| 155 | - processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId())); | |
| 156 | - } | |
| 157 | - if (StrUtil.isNotEmpty(pageReqVO.getName())) { | |
| 158 | - processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); | |
| 159 | - } | |
| 160 | - if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) { | |
| 161 | - processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey()); | |
| 162 | - } | |
| 163 | - if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { | |
| 164 | - processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); | |
| 165 | - } | |
| 166 | - if (pageReqVO.getStatus() != null) { | |
| 167 | - processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus()); | |
| 168 | - } | |
| 169 | - if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { | |
| 170 | - processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); | |
| 171 | - processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); | |
| 172 | - } | |
| 173 | - // 查询数量 | |
| 174 | - long processInstanceCount = processInstanceQuery.count(); | |
| 175 | - if (processInstanceCount == 0) { | |
| 176 | - return PageResult.empty(processInstanceCount); | |
| 177 | - } | |
| 178 | - // 查询列表 | |
| 179 | - List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize()); | |
| 180 | - return new PageResult<>(processInstanceList, processInstanceCount); | |
| 181 | - } | |
| 182 | - | |
| 183 | - | |
| 184 | 146 | private Map<String, String> getFormFieldsPermission(BpmnModel bpmnModel, |
| 185 | - String activityId, String taskId) { | |
| 147 | + String activityId, String taskId) { | |
| 186 | 148 | // 1. 获取流程活动编号。流程活动 Id 为空事,从流程任务中获取流程活动 Id |
| 187 | 149 | if (StrUtil.isEmpty(activityId) && StrUtil.isNotEmpty(taskId)) { |
| 188 | 150 | activityId = Optional.ofNullable(taskService.getHistoricTask(taskId)) |
| ... | ... | @@ -215,8 +177,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 215 | 177 | } |
| 216 | 178 | // 1.3 读取其它相关数据 |
| 217 | 179 | ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition( |
| 218 | - historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() : reqVO.getProcessDefinitionId()); | |
| 219 | - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(processDefinition.getId()); | |
| 180 | + historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() | |
| 181 | + : reqVO.getProcessDefinitionId()); | |
| 182 | + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService | |
| 183 | + .getProcessDefinitionInfo(processDefinition.getId()); | |
| 220 | 184 | BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId()); |
| 221 | 185 | |
| 222 | 186 | // 2.1 已结束 + 进行中的活动节点 |
| ... | ... | @@ -225,24 +189,29 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 225 | 189 | List<HistoricActivityInstance> activities = null; // 流程实例列表 |
| 226 | 190 | if (reqVO.getProcessInstanceId() != null) { |
| 227 | 191 | activities = taskService.getActivityListByProcessInstanceId(reqVO.getProcessInstanceId()); |
| 228 | - List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(), true); | |
| 192 | + List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(), | |
| 193 | + true); | |
| 229 | 194 | endActivityNodes = getEndActivityNodeList(startUserId, bpmnModel, processDefinitionInfo, |
| 230 | 195 | historicProcessInstance, processInstanceStatus, activities, tasks); |
| 231 | - runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables, activities, tasks); | |
| 196 | + runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables, | |
| 197 | + activities, tasks); | |
| 232 | 198 | } |
| 233 | 199 | |
| 234 | 200 | // 2.2 流程已经结束,直接 return,无需预测 |
| 235 | 201 | if (BpmProcessInstanceStatusEnum.isProcessEndStatus(processInstanceStatus)) { |
| 236 | - return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo, historicProcessInstance, | |
| 202 | + return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo, | |
| 203 | + historicProcessInstance, | |
| 237 | 204 | processInstanceStatus, endActivityNodes, runActivityNodes, null, null); |
| 238 | 205 | } |
| 239 | 206 | |
| 240 | 207 | // 3.1 计算当前登录用户的待办任务 |
| 241 | - // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到 B,会不会表单权限不一致哈。 | |
| 208 | + // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到 | |
| 209 | + // B,会不会表单权限不一致哈。 | |
| 242 | 210 | BpmTaskRespVO todoTask = taskService.getFirstTodoTask(loginUserId, reqVO.getProcessInstanceId()); |
| 243 | 211 | |
| 244 | 212 | // 3.2 预测未运行节点的审批信息 |
| 245 | - List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel, processDefinitionInfo, | |
| 213 | + List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel, | |
| 214 | + processDefinitionInfo, | |
| 246 | 215 | processVariables, activities); |
| 247 | 216 | |
| 248 | 217 | // 4. 拼接最终数据 |
| ... | ... | @@ -250,34 +219,93 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 250 | 219 | processInstanceStatus, endActivityNodes, runActivityNodes, simulateActivityNodes, todoTask); |
| 251 | 220 | } |
| 252 | 221 | |
| 222 | + @Override | |
| 223 | + @SuppressWarnings("unchecked") | |
| 224 | + public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId, | |
| 225 | + BpmProcessInstancePageReqVO pageReqVO) { | |
| 226 | + // 1. 构建查询条件 | |
| 227 | + HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery() | |
| 228 | + .includeProcessVariables() | |
| 229 | + .processInstanceTenantId(FlowableUtils.getTenantId()) | |
| 230 | + .orderByProcessInstanceStartTime().desc(); | |
| 231 | + if (userId != null) { // 【我的流程】菜单时,需要传递该字段 | |
| 232 | + processInstanceQuery.startedBy(String.valueOf(userId)); | |
| 233 | + } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段 | |
| 234 | + processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId())); | |
| 235 | + } | |
| 236 | + if (StrUtil.isNotEmpty(pageReqVO.getName())) { | |
| 237 | + processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); | |
| 238 | + } | |
| 239 | + if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) { | |
| 240 | + processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey()); | |
| 241 | + } | |
| 242 | + if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { | |
| 243 | + processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); | |
| 244 | + } | |
| 245 | + if (pageReqVO.getStatus() != null) { | |
| 246 | + processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, | |
| 247 | + pageReqVO.getStatus()); | |
| 248 | + } | |
| 249 | + if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { | |
| 250 | + processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); | |
| 251 | + processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); | |
| 252 | + } | |
| 253 | + if (ArrayUtil.isNotEmpty(pageReqVO.getEndTime())) { | |
| 254 | + processInstanceQuery.finishedAfter(DateUtils.of(pageReqVO.getEndTime()[0])); | |
| 255 | + processInstanceQuery.finishedBefore(DateUtils.of(pageReqVO.getEndTime()[1])); | |
| 256 | + } | |
| 257 | + // 表单字段查询 | |
| 258 | + Map<String, Object> formFieldsParams = JsonUtils.parseObject(pageReqVO.getFormFieldsParams(), Map.class); | |
| 259 | + if (CollUtil.isNotEmpty(formFieldsParams)) { | |
| 260 | + formFieldsParams.forEach((key, value) -> { | |
| 261 | + if (StrUtil.isEmpty(String.valueOf(value))) { | |
| 262 | + return; | |
| 263 | + } | |
| 264 | + // TODO @lesan:应支持多种类型的查询方式,目前只有字符串全等 | |
| 265 | + processInstanceQuery.variableValueEquals(key, value); | |
| 266 | + }); | |
| 267 | + } | |
| 268 | + | |
| 269 | + // 2.1 查询数量 | |
| 270 | + long processInstanceCount = processInstanceQuery.count(); | |
| 271 | + if (processInstanceCount == 0) { | |
| 272 | + return PageResult.empty(processInstanceCount); | |
| 273 | + } | |
| 274 | + // 2.2 查询列表 | |
| 275 | + List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), | |
| 276 | + pageReqVO.getPageSize()); | |
| 277 | + return new PageResult<>(processInstanceList, processInstanceCount); | |
| 278 | + } | |
| 279 | + | |
| 253 | 280 | /** |
| 254 | 281 | * 拼接审批详情的最终数据 |
| 255 | 282 | * <p> |
| 256 | 283 | * 主要是,拼接审批人的用户信息、部门信息 |
| 257 | 284 | */ |
| 258 | 285 | private BpmApprovalDetailRespVO buildApprovalDetail(BpmApprovalDetailReqVO reqVO, |
| 259 | - BpmnModel bpmnModel, | |
| 260 | - ProcessDefinition processDefinition, | |
| 261 | - BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 262 | - HistoricProcessInstance processInstance, | |
| 263 | - Integer processInstanceStatus, | |
| 264 | - List<ActivityNode> endApprovalNodeInfos, | |
| 265 | - List<ActivityNode> runningApprovalNodeInfos, | |
| 266 | - List<ActivityNode> simulateApprovalNodeInfos, | |
| 267 | - BpmTaskRespVO todoTask) { | |
| 286 | + BpmnModel bpmnModel, | |
| 287 | + ProcessDefinition processDefinition, | |
| 288 | + BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 289 | + HistoricProcessInstance processInstance, | |
| 290 | + Integer processInstanceStatus, | |
| 291 | + List<ActivityNode> endApprovalNodeInfos, | |
| 292 | + List<ActivityNode> runningApprovalNodeInfos, | |
| 293 | + List<ActivityNode> simulateApprovalNodeInfos, | |
| 294 | + BpmTaskRespVO todoTask) { | |
| 268 | 295 | // 1. 获取所有需要读取用户信息的 userIds |
| 269 | - List<ActivityNode> approveNodes = newArrayList(asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos)); | |
| 296 | + List<ActivityNode> approveNodes = newArrayList( | |
| 297 | + asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos)); | |
| 270 | 298 | Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds(processInstance, approveNodes, todoTask); |
| 271 | 299 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); |
| 272 | 300 | Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); |
| 273 | 301 | |
| 274 | - | |
| 275 | 302 | // 2. 表单权限 |
| 276 | 303 | String taskId = reqVO.getTaskId() == null && todoTask != null ? todoTask.getId() : reqVO.getTaskId(); |
| 277 | 304 | Map<String, String> formFieldsPermission = getFormFieldsPermission(bpmnModel, reqVO.getActivityId(), taskId); |
| 278 | 305 | |
| 279 | 306 | // 3. 拼接数据 |
| 280 | - return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition, processDefinitionInfo, processInstance, | |
| 307 | + return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition, | |
| 308 | + processDefinitionInfo, processInstance, | |
| 281 | 309 | processInstanceStatus, approveNodes, todoTask, formFieldsPermission, userMap, deptMap); |
| 282 | 310 | } |
| 283 | 311 | |
| ... | ... | @@ -285,17 +313,19 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 285 | 313 | * 获得【已结束】的活动节点们 |
| 286 | 314 | */ |
| 287 | 315 | private List<ActivityNode> getEndActivityNodeList(Long startUserId, BpmnModel bpmnModel, |
| 288 | - BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 289 | - HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus, | |
| 290 | - List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) { | |
| 316 | + BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 317 | + HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus, | |
| 318 | + List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) { | |
| 291 | 319 | // 遍历 tasks 列表,只处理已结束的 UserTask |
| 292 | - // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点 | |
| 320 | + // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities | |
| 321 | + // 的话,它无法成为一个节点 | |
| 293 | 322 | List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null); |
| 294 | 323 | List<ActivityNode> approvalNodes = convertList(endTasks, task -> { |
| 295 | 324 | FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); |
| 296 | 325 | ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName()) |
| 297 | - .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey()) ? | |
| 298 | - BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType() : BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()) | |
| 326 | + .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey()) | |
| 327 | + ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType() | |
| 328 | + : BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()) | |
| 299 | 329 | .setStatus(FlowableUtils.getTaskStatus(task)) |
| 300 | 330 | .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode)) |
| 301 | 331 | .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime())) |
| ... | ... | @@ -320,7 +350,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 320 | 350 | .setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName()) |
| 321 | 351 | .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()) |
| 322 | 352 | .setStatus(startTask.getStatus()).setTasks(ListUtil.of(startTask)) |
| 323 | - .setStartTime(DateUtils.of(activity.getStartTime())).setEndTime(DateUtils.of(activity.getEndTime())); | |
| 353 | + .setStartTime(DateUtils.of(activity.getStartTime())) | |
| 354 | + .setEndTime(DateUtils.of(activity.getEndTime())); | |
| 324 | 355 | approvalNodes.add(0, startNode); |
| 325 | 356 | return; |
| 326 | 357 | } |
| ... | ... | @@ -333,7 +364,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 333 | 364 | ActivityNode endNode = new ActivityNode().setId(activity.getId()) |
| 334 | 365 | .setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName()) |
| 335 | 366 | .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType()).setStatus(processInstanceStatus) |
| 336 | - .setStartTime(DateUtils.of(activity.getStartTime())).setEndTime(DateUtils.of(activity.getEndTime())); | |
| 367 | + .setStartTime(DateUtils.of(activity.getStartTime())) | |
| 368 | + .setEndTime(DateUtils.of(activity.getEndTime())); | |
| 337 | 369 | String reason = FlowableUtils.getProcessInstanceReason(historicProcessInstance); |
| 338 | 370 | if (StrUtil.isNotEmpty(reason)) { |
| 339 | 371 | endNode.setTasks(singletonList(new ActivityNodeTask().setId(endNode.getId()) |
| ... | ... | @@ -349,15 +381,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 349 | 381 | * 获得【进行中】的活动节点们 |
| 350 | 382 | */ |
| 351 | 383 | private List<ActivityNode> getRunApproveNodeList(Long startUserId, |
| 352 | - BpmnModel bpmnModel, | |
| 353 | - ProcessDefinition processDefinition, | |
| 354 | - Map<String, Object> processVariables, | |
| 355 | - List<HistoricActivityInstance> activities, | |
| 356 | - List<HistoricTaskInstance> tasks) { | |
| 384 | + BpmnModel bpmnModel, | |
| 385 | + ProcessDefinition processDefinition, | |
| 386 | + Map<String, Object> processVariables, | |
| 387 | + List<HistoricActivityInstance> activities, | |
| 388 | + List<HistoricTaskInstance> tasks) { | |
| 357 | 389 | // 构建运行中的任务,基于 activityId 分组 |
| 358 | 390 | List<HistoricActivityInstance> runActivities = filterList(activities, activity -> activity.getEndTime() == null |
| 359 | 391 | && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_TASK_USER))); |
| 360 | - Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities, HistoricActivityInstance::getActivityId); | |
| 392 | + Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities, | |
| 393 | + HistoricActivityInstance::getActivityId); | |
| 361 | 394 | |
| 362 | 395 | // 按照 activityId 分组,构建 ApprovalNodeInfo 节点 |
| 363 | 396 | Map<String, HistoricTaskInstance> taskMap = convertMap(tasks, HistoricTaskInstance::getId); |
| ... | ... | @@ -367,8 +400,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 367 | 400 | // 构建活动节点 |
| 368 | 401 | FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, activityId); |
| 369 | 402 | HistoricActivityInstance firstActivity = CollUtil.getFirst(taskActivities); // 取第一个任务,会签/或签的任务,开始时间相同 |
| 370 | - ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId()).setName(firstActivity.getActivityName()) | |
| 371 | - .setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()).setStatus(BpmTaskStatusEnum.RUNNING.getStatus()) | |
| 403 | + ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId()) | |
| 404 | + .setName(firstActivity.getActivityName()) | |
| 405 | + .setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()) | |
| 406 | + .setStatus(BpmTaskStatusEnum.RUNNING.getStatus()) | |
| 372 | 407 | .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode)) |
| 373 | 408 | .setStartTime(DateUtils.of(CollUtil.getFirst(taskActivities).getStartTime())) |
| 374 | 409 | .setTasks(new ArrayList<>()); |
| ... | ... | @@ -381,7 +416,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 381 | 416 | taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks), |
| 382 | 417 | childTask -> childTask.getEndTime() == null); |
| 383 | 418 | if (CollUtil.isNotEmpty(childrenTasks)) { |
| 384 | - activityNode.getTasks().addAll(convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo)); | |
| 419 | + activityNode.getTasks().addAll( | |
| 420 | + convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo)); | |
| 385 | 421 | } |
| 386 | 422 | } |
| 387 | 423 | // 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task |
| ... | ... | @@ -391,8 +427,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 391 | 427 | // 截取当前审批人位置后面的候选人,不包含当前审批人 |
| 392 | 428 | ActivityNodeTask approvalTaskInfo = CollUtil.getFirst(activityNode.getTasks()); |
| 393 | 429 | Assert.notNull(approvalTaskInfo, "任务不能为空"); |
| 394 | - int index = CollUtil.indexOf(candidateUserIds, userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(), | |
| 395 | - approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner | |
| 430 | + int index = CollUtil.indexOf(candidateUserIds, | |
| 431 | + userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(), | |
| 432 | + approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner | |
| 396 | 433 | activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size())); |
| 397 | 434 | } |
| 398 | 435 | return activityNode; |
| ... | ... | @@ -403,10 +440,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 403 | 440 | * 获得【预测(未来)】的活动节点们 |
| 404 | 441 | */ |
| 405 | 442 | private List<ActivityNode> getSimulateApproveNodeList(Long startUserId, BpmnModel bpmnModel, |
| 406 | - BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 407 | - Map<String, Object> processVariables, | |
| 408 | - List<HistoricActivityInstance> activities) { | |
| 409 | - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance 包括了历史的操作,不是只有 startEvent 到当前节点的记录 | |
| 443 | + BpmProcessDefinitionInfoDO processDefinitionInfo, | |
| 444 | + Map<String, Object> processVariables, | |
| 445 | + List<HistoricActivityInstance> activities) { | |
| 446 | + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance | |
| 447 | + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录 | |
| 410 | 448 | Set<String> runActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId); |
| 411 | 449 | // 情况一:BPMN 设计器 |
| 412 | 450 | if (Objects.equals(BpmModelTypeEnum.BPMN.getType(), processDefinitionInfo.getModelType())) { |
| ... | ... | @@ -416,7 +454,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 416 | 454 | } |
| 417 | 455 | // 情况二:SIMPLE 设计器 |
| 418 | 456 | if (Objects.equals(BpmModelTypeEnum.SIMPLE.getType(), processDefinitionInfo.getModelType())) { |
| 419 | - BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class); | |
| 457 | + BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), | |
| 458 | + BpmSimpleModelNodeVO.class); | |
| 420 | 459 | List<BpmSimpleModelNodeVO> simpleNodes = SimpleModelUtils.simulateProcess(simpleModel, processVariables); |
| 421 | 460 | return convertList(simpleNodes, simpleNode -> buildNotRunApproveNodeForSimple(startUserId, bpmnModel, |
| 422 | 461 | processDefinitionInfo, processVariables, simpleNode, runActivityIds)); |
| ... | ... | @@ -425,9 +464,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 425 | 464 | } |
| 426 | 465 | |
| 427 | 466 | private ActivityNode buildNotRunApproveNodeForSimple(Long startUserId, BpmnModel bpmnModel, |
| 428 | - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables, | |
| 429 | - BpmSimpleModelNodeVO node, Set<String> runActivityIds) { | |
| 430 | - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance 包括了历史的操作,不是只有 startEvent 到当前节点的记录 | |
| 467 | + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables, | |
| 468 | + BpmSimpleModelNodeVO node, Set<String> runActivityIds) { | |
| 469 | + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance | |
| 470 | + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录 | |
| 431 | 471 | if (runActivityIds.contains(node.getId())) { |
| 432 | 472 | return null; |
| 433 | 473 | } |
| ... | ... | @@ -460,12 +500,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 460 | 500 | } |
| 461 | 501 | |
| 462 | 502 | private ActivityNode buildNotRunApproveNodeForBpmn(Long startUserId, BpmnModel bpmnModel, |
| 463 | - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables, | |
| 464 | - FlowElement node, Set<String> runActivityIds) { | |
| 503 | + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables, | |
| 504 | + FlowElement node, Set<String> runActivityIds) { | |
| 465 | 505 | if (runActivityIds.contains(node.getId())) { |
| 466 | 506 | return null; |
| 467 | 507 | } |
| 468 | - ActivityNode activityNode = new ActivityNode().setId(node.getId()).setStatus(BpmTaskStatusEnum.NOT_START.getStatus()); | |
| 508 | + ActivityNode activityNode = new ActivityNode().setId(node.getId()) | |
| 509 | + .setStatus(BpmTaskStatusEnum.NOT_START.getStatus()); | |
| 469 | 510 | |
| 470 | 511 | // 1. 开始节点 |
| 471 | 512 | if (node instanceof StartEvent) { |
| ... | ... | @@ -491,7 +532,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 491 | 532 | } |
| 492 | 533 | |
| 493 | 534 | private List<Long> getTaskCandidateUserList(BpmnModel bpmnModel, String activityId, |
| 494 | - Long startUserId, String processDefinitionId, Map<String, Object> processVariables) { | |
| 535 | + Long startUserId, String processDefinitionId, Map<String, Object> processVariables) { | |
| 495 | 536 | Set<Long> userIds = taskCandidateInvoker.calculateUsersByActivity(bpmnModel, activityId, |
| 496 | 537 | startUserId, processDefinitionId, processVariables); |
| 497 | 538 | return new ArrayList<>(userIds); |
| ... | ... | @@ -505,14 +546,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 505 | 546 | return null; |
| 506 | 547 | } |
| 507 | 548 | // 1.2 获得流程定义 |
| 508 | - BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()); | |
| 549 | + BpmnModel bpmnModel = processDefinitionService | |
| 550 | + .getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()); | |
| 509 | 551 | if (bpmnModel == null) { |
| 510 | 552 | return null; |
| 511 | 553 | } |
| 512 | 554 | BpmSimpleModelNodeVO simpleModel = null; |
| 513 | 555 | BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo( |
| 514 | 556 | processInstance.getProcessDefinitionId()); |
| 515 | - if (processDefinitionInfo != null && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) { | |
| 557 | + if (processDefinitionInfo != null | |
| 558 | + && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) { | |
| 516 | 559 | simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class); |
| 517 | 560 | } |
| 518 | 561 | // 1.3 获得流程实例对应的活动实例列表 + 任务列表 |
| ... | ... | @@ -524,10 +567,12 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 524 | 567 | activityInstance -> activityInstance.getEndTime() == null); |
| 525 | 568 | Set<String> finishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId, |
| 526 | 569 | activityInstance -> activityInstance.getEndTime() != null |
| 527 | - && ObjectUtil.notEqual(activityInstance.getActivityType(), BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW)); | |
| 570 | + && ObjectUtil.notEqual(activityInstance.getActivityType(), | |
| 571 | + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW)); | |
| 528 | 572 | Set<String> finishedSequenceFlowActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId, |
| 529 | 573 | activityInstance -> activityInstance.getEndTime() != null |
| 530 | - && ObjectUtil.equals(activityInstance.getActivityType(), BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW)); | |
| 574 | + && ObjectUtil.equals(activityInstance.getActivityType(), | |
| 575 | + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW)); | |
| 531 | 576 | // 特殊:会签情况下,会有部分已完成(审批)、部分未完成(待审批),此时需要 finishedTaskActivityIds 移除掉 |
| 532 | 577 | finishedTaskActivityIds.removeAll(unfinishedTaskActivityIds); |
| 533 | 578 | // 特殊:如果流程实例被拒绝,则需要计算是哪个活动节点。 |
| ... | ... | @@ -545,8 +590,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 545 | 590 | Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds02(processInstance, tasks); |
| 546 | 591 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); |
| 547 | 592 | Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); |
| 548 | - return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel, simpleModel, | |
| 549 | - unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds, rejectTaskActivityIds, | |
| 593 | + return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel, | |
| 594 | + simpleModel, | |
| 595 | + unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds, | |
| 596 | + rejectTaskActivityIds, | |
| 550 | 597 | userMap, deptMap); |
| 551 | 598 | } |
| 552 | 599 | |
| ... | ... | @@ -556,7 +603,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 556 | 603 | @Transactional(rollbackFor = Exception.class) |
| 557 | 604 | public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { |
| 558 | 605 | // 获得流程定义 |
| 559 | - ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); | |
| 606 | + ProcessDefinition definition = processDefinitionService | |
| 607 | + .getProcessDefinition(createReqVO.getProcessDefinitionId()); | |
| 560 | 608 | // 发起流程 |
| 561 | 609 | return createProcessInstance0(userId, definition, createReqVO.getVariables(), null, |
| 562 | 610 | createReqVO.getStartUserSelectAssignees()); |
| ... | ... | @@ -566,16 +614,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 566 | 614 | public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { |
| 567 | 615 | return FlowableUtils.executeAuthenticatedUserId(userId, () -> { |
| 568 | 616 | // 获得流程定义 |
| 569 | - ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); | |
| 617 | + ProcessDefinition definition = processDefinitionService | |
| 618 | + .getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); | |
| 570 | 619 | // 发起流程 |
| 571 | - return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(), | |
| 620 | + return createProcessInstance0(userId, definition, createReqDTO.getVariables(), | |
| 621 | + createReqDTO.getBusinessKey(), | |
| 572 | 622 | createReqDTO.getStartUserSelectAssignees()); |
| 573 | 623 | }); |
| 574 | 624 | } |
| 575 | 625 | |
| 576 | 626 | private String createProcessInstance0(Long userId, ProcessDefinition definition, |
| 577 | - Map<String, Object> variables, String businessKey, | |
| 578 | - Map<String, List<Long>> startUserSelectAssignees) { | |
| 627 | + Map<String, Object> variables, String businessKey, | |
| 628 | + Map<String, List<Long>> startUserSelectAssignees) { | |
| 579 | 629 | // 1.1 校验流程定义 |
| 580 | 630 | if (definition == null) { |
| 581 | 631 | throw exception(PROCESS_DEFINITION_NOT_EXISTS); |
| ... | ... | @@ -583,7 +633,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 583 | 633 | if (definition.isSuspended()) { |
| 584 | 634 | throw exception(PROCESS_DEFINITION_IS_SUSPENDED); |
| 585 | 635 | } |
| 586 | - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(definition.getId()); | |
| 636 | + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService | |
| 637 | + .getProcessDefinitionInfo(definition.getId()); | |
| 587 | 638 | if (processDefinitionInfo == null) { |
| 588 | 639 | throw exception(PROCESS_DEFINITION_NOT_EXISTS); |
| 589 | 640 | } |
| ... | ... | @@ -602,9 +653,12 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 602 | 653 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置流程变量,发起人 ID |
| 603 | 654 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中 |
| 604 | 655 | BpmProcessInstanceStatusEnum.RUNNING.getStatus()); |
| 605 | - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 true,不影响没配置 skipExpression 的节点 | |
| 656 | + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 | |
| 657 | + // true,不影响没配置 | |
| 658 | + // skipExpression 的节点 | |
| 606 | 659 | if (CollUtil.isNotEmpty(startUserSelectAssignees)) { |
| 607 | - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees); | |
| 660 | + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, | |
| 661 | + startUserSelectAssignees); | |
| 608 | 662 | } |
| 609 | 663 | |
| 610 | 664 | // 3. 创建流程 |
| ... | ... | @@ -634,7 +688,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 634 | 688 | return instance.getId(); |
| 635 | 689 | } |
| 636 | 690 | |
| 637 | - private void validateStartUserSelectAssignees(ProcessDefinition definition, Map<String, List<Long>> startUserSelectAssignees) { | |
| 691 | + private void validateStartUserSelectAssignees(ProcessDefinition definition, | |
| 692 | + Map<String, List<Long>> startUserSelectAssignees) { | |
| 638 | 693 | // 1. 获得发起人自选审批人的 UserTask/ServiceTask 列表 |
| 639 | 694 | BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(definition.getId()); |
| 640 | 695 | List<Task> tasks = BpmTaskCandidateStartUserSelectStrategy.getStartUserSelectTaskList(bpmnModel); |
| ... | ... | @@ -669,7 +724,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 669 | 724 | throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); |
| 670 | 725 | } |
| 671 | 726 | // 1.3 校验允许撤销审批中的申请 |
| 672 | - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(instance.getProcessDefinitionId()); | |
| 727 | + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService | |
| 728 | + .getProcessDefinitionInfo(instance.getProcessDefinitionId()); | |
| 673 | 729 | Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo); |
| 674 | 730 | if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消 |
| 675 | 731 | && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) { |
| ... | ... | @@ -707,9 +763,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 707 | 763 | |
| 708 | 764 | @Override |
| 709 | 765 | public void updateProcessInstanceReject(ProcessInstance processInstance, String reason) { |
| 710 | - runtimeService.setVariable(processInstance.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, | |
| 766 | + runtimeService.setVariable(processInstance.getProcessInstanceId(), | |
| 767 | + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, | |
| 711 | 768 | BpmProcessInstanceStatusEnum.REJECT.getStatus()); |
| 712 | - runtimeService.setVariable(processInstance.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, | |
| 769 | + runtimeService.setVariable(processInstance.getProcessInstanceId(), | |
| 770 | + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, | |
| 713 | 771 | BpmReasonEnum.REJECT_TASK.format(reason)); |
| 714 | 772 | } |
| 715 | 773 | |
| ... | ... | @@ -720,18 +778,22 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 720 | 778 | // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号 |
| 721 | 779 | FlowableUtils.execute(instance.getTenantId(), () -> { |
| 722 | 780 | // 1.1 获取当前状态 |
| 723 | - Integer status = (Integer) instance.getProcessVariables().get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS); | |
| 724 | - String reason = (String) instance.getProcessVariables().get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON); | |
| 781 | + Integer status = (Integer) instance.getProcessVariables() | |
| 782 | + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS); | |
| 783 | + String reason = (String) instance.getProcessVariables() | |
| 784 | + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON); | |
| 725 | 785 | // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态 |
| 726 | 786 | // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了 |
| 727 | 787 | if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) { |
| 728 | 788 | status = BpmProcessInstanceStatusEnum.APPROVE.getStatus(); |
| 729 | - runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, status); | |
| 789 | + runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, | |
| 790 | + status); | |
| 730 | 791 | } |
| 731 | 792 | |
| 732 | 793 | // 2. 发送对应的消息通知 |
| 733 | 794 | if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) { |
| 734 | - messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance)); | |
| 795 | + messageService.sendMessageWhenProcessInstanceApprove( | |
| 796 | + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance)); | |
| 735 | 797 | } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) { |
| 736 | 798 | messageService.sendMessageWhenProcessInstanceReject( |
| 737 | 799 | BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason)); |
| ... | ... | @@ -743,4 +805,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 743 | 805 | }); |
| 744 | 806 | } |
| 745 | 807 | |
| 808 | + @Override | |
| 809 | + public void updateProcessInstanceVariables(String id, Map<String, Object> variables) { | |
| 810 | + runtimeService.setVariables(id, variables); | |
| 811 | + } | |
| 812 | + | |
| 746 | 813 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmHttpRequestTrigger.java
| 1 | 1 | package cn.iocoder.yudao.module.bpm.service.task.trigger; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.core.KeyValue; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 3 | 7 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 4 | 8 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting; |
| 5 | 9 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum; |
| 6 | 10 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils; |
| 7 | 11 | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; |
| 12 | +import com.fasterxml.jackson.core.type.TypeReference; | |
| 8 | 13 | import jakarta.annotation.Resource; |
| 9 | 14 | import lombok.extern.slf4j.Slf4j; |
| 10 | 15 | import org.flowable.engine.runtime.ProcessInstance; |
| ... | ... | @@ -17,6 +22,8 @@ import org.springframework.util.MultiValueMap; |
| 17 | 22 | import org.springframework.web.client.RestClientException; |
| 18 | 23 | import org.springframework.web.client.RestTemplate; |
| 19 | 24 | |
| 25 | +import java.util.HashMap; | |
| 26 | +import java.util.List; | |
| 20 | 27 | import java.util.Map; |
| 21 | 28 | |
| 22 | 29 | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; |
| ... | ... | @@ -63,13 +70,55 @@ public class BpmHttpRequestTrigger implements BpmTrigger { |
| 63 | 70 | // TODO @芋艿:要不要抽象一个 Http 请求的工具类,方便复用呢? |
| 64 | 71 | // 3. 发起请求 |
| 65 | 72 | HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers); |
| 73 | + ResponseEntity<String> responseEntity; | |
| 66 | 74 | try { |
| 67 | - ResponseEntity<String> responseEntity = restTemplate.exchange(setting.getUrl(), HttpMethod.POST, | |
| 75 | + responseEntity = restTemplate.exchange(setting.getUrl(), HttpMethod.POST, | |
| 68 | 76 | requestEntity, String.class); |
| 69 | 77 | log.info("[execute][HTTP 触发器,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity); |
| 70 | 78 | } catch (RestClientException e) { |
| 71 | 79 | log.error("[execute][HTTP 触发器,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage()); |
| 80 | + return; | |
| 81 | + } | |
| 82 | + | |
| 83 | + // 4.1 判断是否需要解析返回值 | |
| 84 | + if (StrUtil.isEmpty(responseEntity.getBody()) | |
| 85 | + || !responseEntity.getStatusCode().is2xxSuccessful() | |
| 86 | + || CollUtil.isEmpty(setting.getResponse())) { | |
| 87 | + return; | |
| 88 | + } | |
| 89 | + // 4.2 解析返回值, 返回值必须符合 CommonResult 规范。 | |
| 90 | + CommonResult<Map<String, Object>> respResult = JsonUtils.parseObjectQuietly( | |
| 91 | + responseEntity.getBody(), new TypeReference<>() {}); | |
| 92 | + if (respResult == null || !respResult.isSuccess()){ | |
| 93 | + return; | |
| 94 | + } | |
| 95 | + // 4.3 获取需要更新的流程变量 | |
| 96 | + Map<String, Object> updateVariables = getNeedUpdatedVariablesFromResponse(respResult.getData(), setting.getResponse()); | |
| 97 | + // 4.4 更新流程变量 | |
| 98 | + if (CollUtil.isNotEmpty(updateVariables)) { | |
| 99 | + processInstanceService.updateProcessInstanceVariables(processInstanceId, updateVariables); | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + /** | |
| 104 | + * 从请求返回值获取需要更新的流程变量 | |
| 105 | + * | |
| 106 | + * @param result 请求返回结果 | |
| 107 | + * @param responseSettings 返回设置 | |
| 108 | + * @return 需要更新的流程变量 | |
| 109 | + */ | |
| 110 | + private Map<String, Object> getNeedUpdatedVariablesFromResponse(Map<String,Object> result, | |
| 111 | + List<KeyValue<String, String>> responseSettings) { | |
| 112 | + Map<String, Object> updateVariables = new HashMap<>(); | |
| 113 | + if (CollUtil.isEmpty(result)) { | |
| 114 | + return updateVariables; | |
| 72 | 115 | } |
| 116 | + responseSettings.forEach(responseSetting -> { | |
| 117 | + if (StrUtil.isNotEmpty(responseSetting.getKey()) && result.containsKey(responseSetting.getValue())) { | |
| 118 | + updateVariables.put(responseSetting.getKey(), result.get(responseSetting.getValue())); | |
| 119 | + } | |
| 120 | + }); | |
| 121 | + return updateVariables; | |
| 73 | 122 | } |
| 74 | 123 | |
| 75 | 124 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmUpdateNormalFormTrigger.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task.trigger; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.NormalFormTriggerSetting; | |
| 6 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | |
| 8 | +import jakarta.annotation.Resource; | |
| 9 | +import lombok.extern.slf4j.Slf4j; | |
| 10 | +import org.springframework.stereotype.Component; | |
| 11 | + | |
| 12 | +// TODO @jason:改成 BpmFormUpdateTrigger | |
| 13 | +/** | |
| 14 | + * BPM 更新流程表单触发器 | |
| 15 | + * | |
| 16 | + * @author jason | |
| 17 | + */ | |
| 18 | +@Component | |
| 19 | +@Slf4j | |
| 20 | +public class BpmUpdateNormalFormTrigger implements BpmTrigger { | |
| 21 | + | |
| 22 | + @Resource | |
| 23 | + private BpmProcessInstanceService processInstanceService; | |
| 24 | + | |
| 25 | + @Override | |
| 26 | + public BpmTriggerTypeEnum getType() { | |
| 27 | + return BpmTriggerTypeEnum.UPDATE_NORMAL_FORM; | |
| 28 | + } | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + public void execute(String processInstanceId, String param) { | |
| 32 | + // 1. 解析更新流程表单配置 | |
| 33 | + NormalFormTriggerSetting setting = JsonUtils.parseObject(param, NormalFormTriggerSetting.class); | |
| 34 | + if (setting == null) { | |
| 35 | + log.error("[execute][流程({}) 更新流程表单触发器配置为空]", processInstanceId); | |
| 36 | + return; | |
| 37 | + } | |
| 38 | + // 2.更新流程变量 | |
| 39 | + if (CollUtil.isNotEmpty(setting.getUpdateFormFields())) { | |
| 40 | + processInstanceService.updateProcessInstanceVariables(processInstanceId, setting.getUpdateFormFields()); | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{baseUrl}}/crm/permission/create |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "userId": 1, |
| ... | ... | @@ -15,7 +15,7 @@ tenant-id: {{adminTenentId}} |
| 15 | 15 | PUT {{baseUrl}}/crm/permission/update |
| 16 | 16 | Content-Type: application/json |
| 17 | 17 | Authorization: Bearer {{token}} |
| 18 | -tenant-id: {{adminTenentId}} | |
| 18 | +tenant-id: {{adminTenantId}} | |
| 19 | 19 | |
| 20 | 20 | { |
| 21 | 21 | "userId": 1, |
| ... | ... | @@ -28,5 +28,5 @@ tenant-id: {{adminTenentId}} |
| 28 | 28 | ### 请求 /delete |
| 29 | 29 | DELETE {{baseUrl}}/crm/permission/delete?bizType=2&bizId=1&id=1 |
| 30 | 30 | Authorization: Bearer {{token}} |
| 31 | -tenant-id: {{adminTenentId}} | |
| 31 | +tenant-id: {{adminTenantId}} | |
| 32 | 32 | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http
| ... | ... | @@ -2,64 +2,64 @@ |
| 2 | 2 | ### 1.1 客户总量分析(按日期) |
| 3 | 3 | GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | ### 1.2 客户总量统计(按用户) |
| 8 | 8 | GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 9 | 9 | Authorization: Bearer {{token}} |
| 10 | -tenant-id: {{adminTenentId}} | |
| 10 | +tenant-id: {{adminTenantId}} | |
| 11 | 11 | |
| 12 | 12 | # == 2. 客户跟进次数分析 == |
| 13 | 13 | ### 2.1 客户跟进次数分析(按日期) |
| 14 | 14 | GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 |
| 15 | 15 | Authorization: Bearer {{token}} |
| 16 | -tenant-id: {{adminTenentId}} | |
| 16 | +tenant-id: {{adminTenantId}} | |
| 17 | 17 | |
| 18 | 18 | ### 2.2 客户总量统计(按用户) |
| 19 | 19 | GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 20 | 20 | Authorization: Bearer {{token}} |
| 21 | -tenant-id: {{adminTenentId}} | |
| 21 | +tenant-id: {{adminTenantId}} | |
| 22 | 22 | |
| 23 | 23 | # == 3. 客户跟进方式分析 == |
| 24 | 24 | ### 3.1 客户跟进方式分析 |
| 25 | 25 | GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-type?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 26 | 26 | Authorization: Bearer {{token}} |
| 27 | -tenant-id: {{adminTenentId}} | |
| 27 | +tenant-id: {{adminTenantId}} | |
| 28 | 28 | |
| 29 | 29 | # == 4. 客户成交周期 == |
| 30 | 30 | ### 4.1 合同摘要信息(客户转化率页面) |
| 31 | 31 | GET {{baseUrl}}/crm/statistics-customer/get-contract-summary?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 32 | 32 | Authorization: Bearer {{token}} |
| 33 | -tenant-id: {{adminTenentId}} | |
| 33 | +tenant-id: {{adminTenantId}} | |
| 34 | 34 | |
| 35 | 35 | # == 5. 客户成交周期 == |
| 36 | 36 | ### 5.1 获取客户公海分析(按日期) |
| 37 | 37 | GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-date?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 38 | 38 | Authorization: Bearer {{token}} |
| 39 | -tenant-id: {{adminTenentId}} | |
| 39 | +tenant-id: {{adminTenantId}} | |
| 40 | 40 | |
| 41 | 41 | ### 5.2 获取客户公海分析(按用户) |
| 42 | 42 | GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 43 | 43 | Authorization: Bearer {{token}} |
| 44 | -tenant-id: {{adminTenentId}} | |
| 44 | +tenant-id: {{adminTenantId}} | |
| 45 | 45 | |
| 46 | 46 | # == 6. 客户成交周期 == |
| 47 | 47 | ### 6.1 客户成交周期(按日期) |
| 48 | 48 | GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 |
| 49 | 49 | Authorization: Bearer {{token}} |
| 50 | -tenant-id: {{adminTenentId}} | |
| 50 | +tenant-id: {{adminTenantId}} | |
| 51 | 51 | |
| 52 | 52 | ### 6.2 获取客户成交周期(按用户) |
| 53 | 53 | GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 54 | 54 | Authorization: Bearer {{token}} |
| 55 | -tenant-id: {{adminTenentId}} | |
| 55 | +tenant-id: {{adminTenantId}} | |
| 56 | 56 | |
| 57 | 57 | ### 6.3 获取客户成交周期(按区域) |
| 58 | 58 | GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-area?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 59 | 59 | Authorization: Bearer {{token}} |
| 60 | -tenant-id: {{adminTenentId}} | |
| 60 | +tenant-id: {{adminTenantId}} | |
| 61 | 61 | |
| 62 | 62 | ### 6.4 获取客户成交周期(按产品) |
| 63 | 63 | GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-product?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 |
| 64 | 64 | Authorization: Bearer {{token}} |
| 65 | -tenant-id: {{adminTenentId}} | |
| 65 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.http
| 1 | 1 | ### 合同金额排行榜 |
| 2 | 2 | GET {{baseUrl}}/crm/statistics-rank/get-contract-price-rank?deptId=100×[0]=2022-12-12 00:00:00×[1]=2024-12-12 23:59:59 |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 回款金额排行榜 |
| 7 | 7 | GET {{baseUrl}}/crm/statistics-rank/get-receivable-price-rank?deptId=100×[0]=2022-12-12 00:00:00×[1]=2024-12-12 23:59:59 |
| 8 | 8 | Authorization: Bearer {{token}} |
| 9 | -tenant-id: {{adminTenentId}} | |
| 10 | 9 | \ No newline at end of file |
| 10 | +tenant-id: {{adminTenantId}} | |
| 11 | 11 | \ No newline at end of file | ... | ... |
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/statistics/ErpSaleStatisticsController.http
| 1 | 1 | ### 请求 /erp/sale-statistics/summary 接口 => 成功 |
| 2 | 2 | GET {{baseUrl}}/erp/sale-statistics/summary |
| 3 | 3 | Content-Type: application/json |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | Authorization: Bearer {{token}} |
| 6 | 6 | |
| 7 | 7 | ### 请求 /erp/sale-statistics/time-summary 接口 => 成功 |
| 8 | 8 | GET {{baseUrl}}/erp/sale-statistics/time-summary |
| 9 | 9 | Content-Type: application/json |
| 10 | -tenant-id: {{adminTenentId}} | |
| 10 | +tenant-id: {{adminTenantId}} | |
| 11 | 11 | Authorization: Bearer {{token}} | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.http
| 1 | 1 | ### 请求 /infra/file-config/create 接口 => 成功 |
| 2 | 2 | POST {{baseUrl}}/infra/file-config/create |
| 3 | 3 | Content-Type: application/json |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | Authorization: Bearer {{token}} |
| 6 | 6 | |
| 7 | 7 | { |
| ... | ... | @@ -21,7 +21,7 @@ Authorization: Bearer {{token}} |
| 21 | 21 | ### 请求 /infra/file-config/update 接口 => 成功 |
| 22 | 22 | PUT {{baseUrl}}/infra/file-config/update |
| 23 | 23 | Content-Type: application/json |
| 24 | -tenant-id: {{adminTenentId}} | |
| 24 | +tenant-id: {{adminTenantId}} | |
| 25 | 25 | Authorization: Bearer {{token}} |
| 26 | 26 | |
| 27 | 27 | { |
| ... | ... | @@ -41,5 +41,5 @@ Authorization: Bearer {{token}} |
| 41 | 41 | ### 请求 /infra/file-config/test 接口 => 成功 |
| 42 | 42 | GET {{baseUrl}}/infra/file-config/test?id=2 |
| 43 | 43 | Content-Type: application/json |
| 44 | -tenant-id: {{adminTenentId}} | |
| 44 | +tenant-id: {{adminTenantId}} | |
| 45 | 45 | Authorization: Bearer {{token}} | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.http
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.http
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http
0 → 100644
| 1 | +### 请求 /iot/think-model-function/create 接口 => 成功 | |
| 2 | +POST {{baseUrl}}/iot/think-model-function/create | |
| 3 | +Content-Type: application/json | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | +Authorization: Bearer {{token}} | |
| 6 | + | |
| 7 | +{ | |
| 8 | + "productId": 1001, | |
| 9 | + "productKey": "smart-sensor-001", | |
| 10 | + "identifier": "Temperature", | |
| 11 | + "name": "温度", | |
| 12 | + "description": "当前温度值", | |
| 13 | + "type": 1, | |
| 14 | + "property": { | |
| 15 | + "identifier": "Temperature", | |
| 16 | + "name": "温度", | |
| 17 | + "accessMode": "r", | |
| 18 | + "required": true, | |
| 19 | + "dataType": { | |
| 20 | + "type": "float", | |
| 21 | + "specs": { | |
| 22 | + "min": -10.0, | |
| 23 | + "max": 100.0, | |
| 24 | + "step": 0.1, | |
| 25 | + "unit": "℃" | |
| 26 | + } | |
| 27 | + }, | |
| 28 | + "description": "当前温度值" | |
| 29 | + } | |
| 30 | +} | |
| 31 | + | |
| 32 | +### 请求 /iot/think-model-function/create 接口 => 成功 | |
| 33 | +POST {{baseUrl}}/iot/think-model-function/create | |
| 34 | +Content-Type: application/json | |
| 35 | +tenant-id: {{adminTenantId}} | |
| 36 | +Authorization: Bearer {{token}} | |
| 37 | + | |
| 38 | +{ | |
| 39 | + "productId": 1001, | |
| 40 | + "productKey": "smart-sensor-001", | |
| 41 | + "identifier": "Humidity", | |
| 42 | + "name": "湿度", | |
| 43 | + "description": "当前湿度值", | |
| 44 | + "type": 1, | |
| 45 | + "property": { | |
| 46 | + "identifier": "Humidity", | |
| 47 | + "name": "湿度", | |
| 48 | + "accessMode": "r", | |
| 49 | + "required": true, | |
| 50 | + "dataType": { | |
| 51 | + "type": "float", | |
| 52 | + "specs": { | |
| 53 | + "min": 0.0, | |
| 54 | + "max": 100.0, | |
| 55 | + "step": 0.1, | |
| 56 | + "unit": "%" | |
| 57 | + } | |
| 58 | + }, | |
| 59 | + "description": "当前湿度值" | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | +### 请求 /iot/think-model-function/update 接口 => 成功 | |
| 67 | +PUT {{baseUrl}}/iot/think-model-function/update | |
| 68 | +Content-Type: application/json | |
| 69 | +tenant-id: {{adminTenantId}} | |
| 70 | +Authorization: Bearer {{token}} | |
| 71 | + | |
| 72 | +{ | |
| 73 | + "id": 11, | |
| 74 | + "productId": 1001, | |
| 75 | + "productKey": "smart-sensor-001", | |
| 76 | + "identifier": "Temperature", | |
| 77 | + "name": "温度", | |
| 78 | + "description": "当前温度值", | |
| 79 | + "type": 1, | |
| 80 | + "property": { | |
| 81 | + "identifier": "Temperature", | |
| 82 | + "name": "温度", | |
| 83 | + "accessMode": "r", | |
| 84 | + "required": true, | |
| 85 | + "dataType": { | |
| 86 | + "type": "float", | |
| 87 | + "specs": { | |
| 88 | + "min": -111.0, | |
| 89 | + "max": 222.0, | |
| 90 | + "step": 0.1, | |
| 91 | + "unit": "℃" | |
| 92 | + } | |
| 93 | + }, | |
| 94 | + "description": "当前温度值" | |
| 95 | + } | |
| 96 | +} | |
| 97 | + | |
| 98 | +### 请求 /iot/think-model-function/delete 接口 => 成功 | |
| 99 | +DELETE {{baseUrl}}/iot/think-model-function/delete?id=7 | |
| 100 | +tenant-id: {{adminTenantId}} | |
| 101 | +Authorization: Bearer {{token}} | |
| 102 | + | |
| 103 | +### 请求 /iot/think-model-function/get 接口 => 成功 | |
| 104 | +GET {{baseUrl}}/iot/think-model-function/get?id=10 | |
| 105 | +tenant-id: {{adminTenantId}} | |
| 106 | +Authorization: Bearer {{token}} | |
| 107 | + | |
| 108 | + | |
| 109 | +### 请求 /iot/think-model-function/list-by-product-id 接口 => 成功 | |
| 110 | +GET {{baseUrl}}/iot/think-model-function/list-by-product-id?productId=1001 | |
| 111 | +tenant-id: {{adminTenantId}} | |
| 112 | +Authorization: Bearer {{token}} | |
| 0 | 113 | \ No newline at end of file | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http
| 1 | 1 | ### 获得订单交易的分页(默认) |
| 2 | 2 | GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10 |
| 3 | 3 | Authorization: Bearer {{appToken}} |
| 4 | -tenant-id: {{appTenentId}} | |
| 4 | +tenant-id: {{appTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 获得订单交易的分页(价格) |
| 7 | 7 | GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10&sortField=price&sortAsc=true |
| 8 | 8 | Authorization: Bearer {{appToken}} |
| 9 | -tenant-id: {{appTenentId}} | |
| 9 | +tenant-id: {{appTenantId}} | |
| 10 | 10 | |
| 11 | 11 | ### 获得订单交易的分页(销售) |
| 12 | 12 | GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10&sortField=salesCount&sortAsc=true |
| 13 | 13 | Authorization: Bearer {{appToken}} |
| 14 | -tenant-id: {{appTenentId}} | |
| 14 | +tenant-id: {{appTenantId}} | |
| 15 | 15 | |
| 16 | 16 | ### 获得商品 SPU 明细 |
| 17 | 17 | GET {{appApi}}/product/spu/get-detail?id=102 |
| 18 | -tenant-id: {{appTenentId}} | |
| 18 | +tenant-id: {{appTenantId}} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.http
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainHelpController.http
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainRecordController.http
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http
| 1 | 1 | ### 获得交易售后分页 => 成功 |
| 2 | 2 | GET {{baseUrl}}/trade/after-sale/page?pageNo=1&pageSize=10 |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 同意售后 => 成功 |
| 7 | 7 | PUT {{baseUrl}}/trade/after-sale/agree?id=7 |
| 8 | 8 | Authorization: Bearer {{token}} |
| 9 | -tenant-id: {{adminTenentId}} | |
| 9 | +tenant-id: {{adminTenantId}} | |
| 10 | 10 | Content-Type: application/json |
| 11 | 11 | |
| 12 | 12 | ### 拒绝售后 => 成功 |
| 13 | 13 | PUT {{baseUrl}}/trade/after-sale/disagree |
| 14 | 14 | Authorization: Bearer {{token}} |
| 15 | -tenant-id: {{adminTenentId}} | |
| 15 | +tenant-id: {{adminTenantId}} | |
| 16 | 16 | Content-Type: application/json |
| 17 | 17 | |
| 18 | 18 | { |
| ... | ... | @@ -23,11 +23,11 @@ Content-Type: application/json |
| 23 | 23 | ### 确认退款 => 成功 |
| 24 | 24 | PUT {{baseUrl}}/trade/after-sale/refund?id=6 |
| 25 | 25 | Authorization: Bearer {{token}} |
| 26 | -tenant-id: {{adminTenentId}} | |
| 26 | +tenant-id: {{adminTenantId}} | |
| 27 | 27 | Content-Type: application/json |
| 28 | 28 | |
| 29 | 29 | ### 确认收货 => 成功 |
| 30 | 30 | PUT {{baseUrl}}/trade/after-sale/receive?id=7 |
| 31 | 31 | Authorization: Bearer {{token}} |
| 32 | -tenant-id: {{adminTenentId}} | |
| 32 | +tenant-id: {{adminTenantId}} | |
| 33 | 33 | Content-Type: application/json | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http
| 1 | 1 | ### 获得交易订单分页 => 成功 |
| 2 | 2 | GET {{baseUrl}}/trade/order/page?pageNo=1&pageSize=10 |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 获得交易订单分页 => 成功 |
| 7 | 7 | GET {{baseUrl}}/trade/order/get-detail?id=21 |
| 8 | 8 | Authorization: Bearer {{token}} |
| 9 | -tenant-id: {{adminTenentId}} | |
| 9 | +tenant-id: {{adminTenantId}} | |
| 10 | 10 | |
| 11 | 11 | ### 获得交易订单的物流轨迹 => 成功 |
| 12 | 12 | GET {{baseUrl}}/trade/order/get-express-track-list?id=21 |
| 13 | 13 | Authorization: Bearer {{token}} |
| 14 | -tenant-id: {{adminTenentId}} | |
| 15 | 14 | \ No newline at end of file |
| 15 | +tenant-id: {{adminTenantId}} | |
| 16 | 16 | \ No newline at end of file | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.http
| 1 | 1 | ### 请求 /trade/cart/add 接口 => 成功 |
| 2 | 2 | POST {{appApi}}/trade/cart/add |
| 3 | -tenant-id: {{appTenentId}} | |
| 3 | +tenant-id: {{appTenantId}} | |
| 4 | 4 | Authorization: Bearer {{appToken}} |
| 5 | 5 | Content-Type: application/json |
| 6 | 6 | |
| ... | ... | @@ -12,7 +12,7 @@ Content-Type: application/json |
| 12 | 12 | |
| 13 | 13 | ### 请求 /trade/cart/update 接口 => 成功 |
| 14 | 14 | PUT {{appApi}}/trade/cart/update |
| 15 | -tenant-id: {{appTenentId}} | |
| 15 | +tenant-id: {{appTenantId}} | |
| 16 | 16 | Authorization: Bearer {{appToken}} |
| 17 | 17 | Content-Type: application/json |
| 18 | 18 | |
| ... | ... | @@ -23,20 +23,20 @@ Content-Type: application/json |
| 23 | 23 | |
| 24 | 24 | ### 请求 /trade/cart/delete 接口 => 成功 |
| 25 | 25 | DELETE {{appApi}}/trade/cart/delete?ids=1 |
| 26 | -tenant-id: {{appTenentId}} | |
| 26 | +tenant-id: {{appTenantId}} | |
| 27 | 27 | Authorization: Bearer {{appToken}} |
| 28 | 28 | |
| 29 | 29 | ### 请求 /trade/cart/get-count 接口 => 成功 |
| 30 | 30 | GET {{appApi}}/trade/cart/get-count |
| 31 | -tenant-id: {{appTenentId}} | |
| 31 | +tenant-id: {{appTenantId}} | |
| 32 | 32 | Authorization: Bearer {{appToken}} |
| 33 | 33 | |
| 34 | 34 | ### 请求 /trade/cart/get-count-map 接口 => 成功 |
| 35 | 35 | GET {{appApi}}/trade/cart/get-count-map |
| 36 | -tenant-id: {{appTenentId}} | |
| 36 | +tenant-id: {{appTenantId}} | |
| 37 | 37 | Authorization: Bearer {{appToken}} |
| 38 | 38 | |
| 39 | 39 | ### 请求 /trade/cart/list 接口 => 成功 |
| 40 | 40 | GET {{appApi}}/trade/cart/list |
| 41 | -tenant-id: {{appTenentId}} | |
| 41 | +tenant-id: {{appTenantId}} | |
| 42 | 42 | Authorization: Bearer {{appToken}} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
| 1 | 1 | ### /trade-order/settlement 获得订单结算信息(基于商品) |
| 2 | 2 | GET {{appApi}}/trade/order/settlement?type=0&items[0].skuId=1&items[0].count=2&items[1].skuId=2&items[1].count=3&couponId=1 |
| 3 | 3 | Authorization: Bearer {{appToken}} |
| 4 | -tenant-id: {{appTenentId}} | |
| 4 | +tenant-id: {{appTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### /trade-order/settlement 获得订单结算信息(基于购物车) |
| 7 | 7 | GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 |
| 8 | 8 | Authorization: Bearer {{appToken}} |
| 9 | -tenant-id: {{appTenentId}} | |
| 9 | +tenant-id: {{appTenantId}} | |
| 10 | 10 | |
| 11 | 11 | ### /trade-order/create 创建订单(基于商品)【快递】 |
| 12 | 12 | POST {{appApi}}/trade/order/create |
| 13 | 13 | Content-Type: application/json |
| 14 | 14 | Authorization: Bearer {{appToken}} |
| 15 | -tenant-id: {{appTenentId}} | |
| 15 | +tenant-id: {{appTenantId}} | |
| 16 | 16 | |
| 17 | 17 | { |
| 18 | 18 | "pointStatus": true, |
| ... | ... | @@ -31,7 +31,7 @@ tenant-id: {{appTenentId}} |
| 31 | 31 | POST {{appApi}}/trade/order/create |
| 32 | 32 | Content-Type: application/json |
| 33 | 33 | Authorization: Bearer {{appToken}} |
| 34 | -tenant-id: {{appTenentId}} | |
| 34 | +tenant-id: {{appTenantId}} | |
| 35 | 35 | |
| 36 | 36 | { |
| 37 | 37 | "pointStatus": true, |
| ... | ... | @@ -51,19 +51,19 @@ tenant-id: {{appTenentId}} |
| 51 | 51 | ### 获得订单交易的分页 |
| 52 | 52 | GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 |
| 53 | 53 | Authorization: Bearer {{appToken}} |
| 54 | -tenant-id: {{appTenentId}} | |
| 54 | +tenant-id: {{appTenantId}} | |
| 55 | 55 | |
| 56 | 56 | ### 获得订单交易的详细 |
| 57 | 57 | GET {{appApi}}/trade/order/get-detail?id=21 |
| 58 | 58 | Authorization: Bearer {{appToken}} |
| 59 | -tenant-id: {{appTenentId}} | |
| 59 | +tenant-id: {{appTenantId}} | |
| 60 | 60 | |
| 61 | 61 | ### 获得交易订单的物流轨迹 |
| 62 | 62 | GET {{appApi}}/trade/order/get-express-track-list?id=70 |
| 63 | 63 | Authorization: Bearer {{appToken}} |
| 64 | -tenant-id: {{appTenentId}} | |
| 64 | +tenant-id: {{appTenantId}} | |
| 65 | 65 | |
| 66 | 66 | ### /trade-order/settlement-product 获得商品结算信息 |
| 67 | 67 | GET {{appApi}}/trade/order/settlement-product?spuIds=633 |
| 68 | 68 | Authorization: Bearer {{appToken}} |
| 69 | -tenant-id: {{appTenentId}} | |
| 70 | 69 | \ No newline at end of file |
| 70 | +tenant-id: {{appTenantId}} | |
| 71 | 71 | \ No newline at end of file | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.http
| 1 | 1 | ### 请求 /create 接口 => 成功 |
| 2 | 2 | POST {{appApi}}//member/address/create |
| 3 | 3 | Content-Type: application/json |
| 4 | -tenant-id: {{appTenentId}} | |
| 4 | +tenant-id: {{appTenantId}} | |
| 5 | 5 | Authorization: Bearer {{appToken}} |
| 6 | 6 | |
| 7 | 7 | { |
| ... | ... | @@ -16,7 +16,7 @@ Authorization: Bearer {{appToken}} |
| 16 | 16 | ### 请求 /update 接口 => 成功 |
| 17 | 17 | PUT {{appApi}}//member/address/update |
| 18 | 18 | Content-Type: application/json |
| 19 | -tenant-id: {{appTenentId}} | |
| 19 | +tenant-id: {{appTenantId}} | |
| 20 | 20 | Authorization: Bearer {{appToken}} |
| 21 | 21 | |
| 22 | 22 | { |
| ... | ... | @@ -32,23 +32,23 @@ Authorization: Bearer {{appToken}} |
| 32 | 32 | ### 请求 /delete 接口 => 成功 |
| 33 | 33 | DELETE {{appApi}}//member/address/delete?id=2 |
| 34 | 34 | Content-Type: application/json |
| 35 | -tenant-id: {{appTenentId}} | |
| 35 | +tenant-id: {{appTenantId}} | |
| 36 | 36 | Authorization: Bearer {{appToken}} |
| 37 | 37 | |
| 38 | 38 | ### 请求 /get 接口 => 成功 |
| 39 | 39 | GET {{appApi}}//member/address/get?id=1 |
| 40 | 40 | Content-Type: application/json |
| 41 | -tenant-id: {{appTenentId}} | |
| 41 | +tenant-id: {{appTenantId}} | |
| 42 | 42 | Authorization: Bearer {{appToken}} |
| 43 | 43 | |
| 44 | 44 | ### 请求 /get-default 接口 => 成功 |
| 45 | 45 | GET {{appApi}}//member/address/get-default |
| 46 | 46 | Content-Type: application/json |
| 47 | -tenant-id: {{appTenentId}} | |
| 47 | +tenant-id: {{appTenantId}} | |
| 48 | 48 | Authorization: Bearer {{appToken}} |
| 49 | 49 | |
| 50 | 50 | ### 请求 /list 接口 => 成功 |
| 51 | 51 | GET {{appApi}}//member/address/list |
| 52 | 52 | Content-Type: application/json |
| 53 | -tenant-id: {{appTenentId}} | |
| 53 | +tenant-id: {{appTenantId}} | |
| 54 | 54 | Authorization: Bearer {{appToken}} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
| 1 | 1 | ### 请求 /login 接口 => 成功 |
| 2 | 2 | POST {{appApi}}/member/auth/login |
| 3 | 3 | Content-Type: application/json |
| 4 | -tenant-id: {{appTenentId}} | |
| 4 | +tenant-id: {{appTenantId}} | |
| 5 | 5 | |
| 6 | 6 | { |
| 7 | 7 | "mobile": "15601691388", |
| ... | ... | @@ -11,7 +11,7 @@ tenant-id: {{appTenentId}} |
| 11 | 11 | ### 请求 /send-sms-code 接口 => 成功 |
| 12 | 12 | POST {{appApi}}/member/auth/send-sms-code |
| 13 | 13 | Content-Type: application/json |
| 14 | -tenant-id: {{appTenentId}} | |
| 14 | +tenant-id: {{appTenantId}} | |
| 15 | 15 | |
| 16 | 16 | { |
| 17 | 17 | "mobile": "15601691388", |
| ... | ... | @@ -21,7 +21,7 @@ tenant-id: {{appTenentId}} |
| 21 | 21 | ### 请求 /sms-login 接口 => 成功 |
| 22 | 22 | POST {{appApi}}/member/auth/sms-login |
| 23 | 23 | Content-Type: application/json |
| 24 | -tenant-id: {{appTenentId}} | |
| 24 | +tenant-id: {{appTenantId}} | |
| 25 | 25 | terminal: 30 |
| 26 | 26 | |
| 27 | 27 | { |
| ... | ... | @@ -32,7 +32,7 @@ terminal: 30 |
| 32 | 32 | ### 请求 /social-login 接口 => 成功 |
| 33 | 33 | POST {{appApi}}/member/auth/social-login |
| 34 | 34 | Content-Type: application/json |
| 35 | -tenant-id: {{appTenentId}} | |
| 35 | +tenant-id: {{appTenantId}} | |
| 36 | 36 | |
| 37 | 37 | { |
| 38 | 38 | "type": 34, |
| ... | ... | @@ -43,7 +43,7 @@ tenant-id: {{appTenentId}} |
| 43 | 43 | ### 请求 /weixin-mini-app-login 接口 => 成功 |
| 44 | 44 | POST {{appApi}}/member/auth/weixin-mini-app-login |
| 45 | 45 | Content-Type: application/json |
| 46 | -tenant-id: {{appTenentId}} | |
| 46 | +tenant-id: {{appTenantId}} | |
| 47 | 47 | |
| 48 | 48 | { |
| 49 | 49 | "phoneCode": "618e6412e0c728f5b8fc7164497463d0158a923c9e7fd86af8bba393b9decbc5", |
| ... | ... | @@ -54,14 +54,14 @@ tenant-id: {{appTenentId}} |
| 54 | 54 | POST {{appApi}}/member/auth/logout |
| 55 | 55 | Content-Type: application/json |
| 56 | 56 | Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66 |
| 57 | -tenant-id: {{appTenentId}} | |
| 57 | +tenant-id: {{appTenantId}} | |
| 58 | 58 | |
| 59 | 59 | ### 请求 /auth/refresh-token 接口 => 成功 |
| 60 | 60 | POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70 |
| 61 | 61 | Content-Type: application/json |
| 62 | -tenant-id: {{appTenentId}} | |
| 62 | +tenant-id: {{appTenantId}} | |
| 63 | 63 | |
| 64 | 64 | ### 请求 /auth/create-weixin-jsapi-signature 接口 => 成功 |
| 65 | 65 | POST {{appApi}}/member/auth/create-weixin-jsapi-signature?url=http://www.iocoder.cn |
| 66 | 66 | Authorization: Bearer {{appToken}} |
| 67 | -tenant-id: {{appTenentId}} | |
| 67 | +tenant-id: {{appTenantId}} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.http
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.http
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{baseUrl}}/mp/menu/save |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "accountId": "1", |
| ... | ... | @@ -37,7 +37,7 @@ tenant-id: {{adminTenentId}} |
| 37 | 37 | POST {{baseUrl}}/mp/menu/save |
| 38 | 38 | Content-Type: application/json |
| 39 | 39 | Authorization: Bearer {{token}} |
| 40 | -tenant-id: {{adminTenentId}} | |
| 40 | +tenant-id: {{adminTenantId}} | |
| 41 | 41 | |
| 42 | 42 | { |
| 43 | 43 | "accountId": "1", |
| ... | ... | @@ -47,4 +47,4 @@ tenant-id: {{adminTenentId}} |
| 47 | 47 | ### 请求 /mp/menu/list 接口 => 成功 |
| 48 | 48 | GET {{baseUrl}}/mp/menu/list?accountId=1 |
| 49 | 49 | Authorization: Bearer {{token}} |
| 50 | -tenant-id: {{adminTenentId}} | |
| 50 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.http
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.http
| ... | ... | @@ -2,13 +2,13 @@ |
| 2 | 2 | GET {{baseUrl}}/mp/message/page?accountId=1&pageNo=1&pageSize=10 |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | ### 请求 /mp/message/send 接口 => 成功(文本) |
| 8 | 8 | POST {{baseUrl}}/mp/message/send |
| 9 | 9 | Content-Type: application/json |
| 10 | 10 | Authorization: Bearer {{token}} |
| 11 | -tenant-id: {{adminTenentId}} | |
| 11 | +tenant-id: {{adminTenantId}} | |
| 12 | 12 | |
| 13 | 13 | { |
| 14 | 14 | "userId": 3, |
| ... | ... | @@ -20,7 +20,7 @@ tenant-id: {{adminTenentId}} |
| 20 | 20 | POST {{baseUrl}}/mp/message/send |
| 21 | 21 | Content-Type: application/json |
| 22 | 22 | Authorization: Bearer {{token}} |
| 23 | -tenant-id: {{adminTenentId}} | |
| 23 | +tenant-id: {{adminTenantId}} | |
| 24 | 24 | |
| 25 | 25 | { |
| 26 | 26 | "userId": 3, | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.http
| ... | ... | @@ -2,13 +2,13 @@ |
| 2 | 2 | GET {{baseUrl}}/mp/draft/page?accountId=1&pageNo=1&pageSize=10 |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | ### 请求 /mp/draft/create 接口 => 成功 |
| 8 | 8 | POST {{baseUrl}}/mp/draft/create?accountId=1 |
| 9 | 9 | Content-Type: application/json |
| 10 | 10 | Authorization: Bearer {{token}} |
| 11 | -tenant-id: {{adminTenentId}} | |
| 11 | +tenant-id: {{adminTenantId}} | |
| 12 | 12 | |
| 13 | 13 | { |
| 14 | 14 | "articles": [ |
| ... | ... | @@ -35,7 +35,7 @@ tenant-id: {{adminTenentId}} |
| 35 | 35 | PUT {{baseUrl}}/mp/draft/update?accountId=1&mediaId=r6ryvl6LrxBU0miaST4Y-q-G9pdsmZw0OYG4FzHQkKfpLfEwIH51wy2bxisx8PvW |
| 36 | 36 | Content-Type: application/json |
| 37 | 37 | Authorization: Bearer {{token}} |
| 38 | -tenant-id: {{adminTenentId}} | |
| 38 | +tenant-id: {{adminTenantId}} | |
| 39 | 39 | |
| 40 | 40 | [{ |
| 41 | 41 | "title": "我是标题(OOO)", | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.http
| ... | ... | @@ -2,12 +2,12 @@ |
| 2 | 2 | GET {{baseUrl}}/mp/free-publish/page?accountId=1&pageNo=1&pageSize=10 |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | ### 请求 /mp/free-publish/submit 接口 => 成功 |
| 8 | 8 | POST {{baseUrl}}/mp/free-publish/submit?accountId=1&mediaId=r6ryvl6LrxBU0miaST4Y-vilmd7iS51D8IPddxflWrau0hIQ2ovY8YanO5jlgUcM |
| 9 | 9 | Content-Type: application/json |
| 10 | 10 | Authorization: Bearer {{token}} |
| 11 | -tenant-id: {{adminTenentId}} | |
| 11 | +tenant-id: {{adminTenantId}} | |
| 12 | 12 | |
| 13 | 13 | {} | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{baseUrl}}/mp/tag/create |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "accountId": "1", |
| ... | ... | @@ -13,7 +13,7 @@ tenant-id: {{adminTenentId}} |
| 13 | 13 | PUT {{baseUrl}}/mp/tag/update |
| 14 | 14 | Content-Type: application/json |
| 15 | 15 | Authorization: Bearer {{token}} |
| 16 | -tenant-id: {{adminTenentId}} | |
| 16 | +tenant-id: {{adminTenantId}} | |
| 17 | 17 | |
| 18 | 18 | { |
| 19 | 19 | "id": "3", |
| ... | ... | @@ -24,16 +24,16 @@ tenant-id: {{adminTenentId}} |
| 24 | 24 | DELETE {{baseUrl}}/mp/tag/delete?id=3 |
| 25 | 25 | Content-Type: application/json |
| 26 | 26 | Authorization: Bearer {{token}} |
| 27 | -tenant-id: {{adminTenentId}} | |
| 27 | +tenant-id: {{adminTenantId}} | |
| 28 | 28 | |
| 29 | 29 | ### 请求 /mp/tag/page 接口 => 成功 |
| 30 | 30 | GET {{baseUrl}}/mp/tag/page?accountId=1&pageNo=1&pageSize=10 |
| 31 | 31 | Content-Type: application/json |
| 32 | 32 | Authorization: Bearer {{token}} |
| 33 | -tenant-id: {{adminTenentId}} | |
| 33 | +tenant-id: {{adminTenantId}} | |
| 34 | 34 | |
| 35 | 35 | ### 请求 /mp/tag/sync 接口 => 成功 |
| 36 | 36 | POST {{baseUrl}}/mp/tag/sync?accountId=1 |
| 37 | 37 | Content-Type: application/json |
| 38 | 38 | Authorization: Bearer {{token}} |
| 39 | -tenant-id: {{adminTenentId}} | |
| 39 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.http
| ... | ... | @@ -2,13 +2,13 @@ |
| 2 | 2 | POST {{baseUrl}}/mp/user/sync?accountId=1 |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{token}} |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | ### 请求 /mp/user/update 接口 => 成功 |
| 8 | 8 | PUT {{baseUrl}}/mp/user/update |
| 9 | 9 | Content-Type: application/json |
| 10 | 10 | Authorization: Bearer {{token}} |
| 11 | -tenant-id: {{adminTenentId}} | |
| 11 | +tenant-id: {{adminTenantId}} | |
| 12 | 12 | |
| 13 | 13 | { |
| 14 | 14 | "id": "3", | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{appApi}}/pay/order/submit |
| 3 | 3 | Content-Type: application/json |
| 4 | 4 | Authorization: Bearer {{appToken}} |
| 5 | -tenant-id: {{appTenentId}} | |
| 5 | +tenant-id: {{appTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "id": 174, |
| ... | ... | @@ -13,7 +13,7 @@ tenant-id: {{appTenentId}} |
| 13 | 13 | POST {{appApi}}/pay/order/submit |
| 14 | 14 | Content-Type: application/json |
| 15 | 15 | Authorization: Bearer {{appToken}} |
| 16 | -tenant-id: {{appTenentId}} | |
| 16 | +tenant-id: {{appTenantId}} | |
| 17 | 17 | |
| 18 | 18 | { |
| 19 | 19 | "id": 202, |
| ... | ... | @@ -27,7 +27,7 @@ tenant-id: {{appTenentId}} |
| 27 | 27 | POST {{appApi}}/pay/order/submit |
| 28 | 28 | Content-Type: application/json |
| 29 | 29 | Authorization: Bearer {{appToken}} |
| 30 | -tenant-id: {{appTenentId}} | |
| 30 | +tenant-id: {{appTenantId}} | |
| 31 | 31 | |
| 32 | 32 | { |
| 33 | 33 | "id": 202, |
| ... | ... | @@ -41,7 +41,7 @@ tenant-id: {{appTenentId}} |
| 41 | 41 | POST {{appApi}}/pay/order/submit |
| 42 | 42 | Content-Type: application/json |
| 43 | 43 | Authorization: Bearer {{appToken}} |
| 44 | -tenant-id: {{appTenentId}} | |
| 44 | +tenant-id: {{appTenantId}} | |
| 45 | 45 | |
| 46 | 46 | { |
| 47 | 47 | "id": 202, |
| ... | ... | @@ -55,7 +55,7 @@ tenant-id: {{appTenentId}} |
| 55 | 55 | POST {{appApi}}/pay/order/submit |
| 56 | 56 | Content-Type: application/json |
| 57 | 57 | Authorization: Bearer {{appToken}} |
| 58 | -tenant-id: {{appTenentId}} | |
| 58 | +tenant-id: {{appTenantId}} | |
| 59 | 59 | |
| 60 | 60 | { |
| 61 | 61 | "id": 202, | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http
| 1 | 1 | ### 请求 /login 接口 => 成功 |
| 2 | 2 | POST {{baseUrl}}/system/auth/login |
| 3 | 3 | Content-Type: application/json |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | tag: Yunai.local |
| 6 | 6 | |
| 7 | 7 | { |
| ... | ... | @@ -14,7 +14,7 @@ tag: Yunai.local |
| 14 | 14 | ### 请求 /login 接口 => 成功(无验证码) |
| 15 | 15 | POST {{baseUrl}}/system/auth/login |
| 16 | 16 | Content-Type: application/json |
| 17 | -tenant-id: {{adminTenentId}} | |
| 17 | +tenant-id: {{adminTenantId}} | |
| 18 | 18 | |
| 19 | 19 | { |
| 20 | 20 | "username": "admin", |
| ... | ... | @@ -24,10 +24,10 @@ tenant-id: {{adminTenentId}} |
| 24 | 24 | ### 请求 /get-permission-info 接口 => 成功 |
| 25 | 25 | GET {{baseUrl}}/system/auth/get-permission-info |
| 26 | 26 | Authorization: Bearer {{token}} |
| 27 | -tenant-id: {{adminTenentId}} | |
| 27 | +tenant-id: {{adminTenantId}} | |
| 28 | 28 | |
| 29 | 29 | ### 请求 /list-menus 接口 => 成功 |
| 30 | 30 | GET {{baseUrl}}/system/list-menus |
| 31 | 31 | Authorization: Bearer {{token}} |
| 32 | 32 | #Authorization: Bearer a6aa7714a2e44c95aaa8a2c5adc2a67a |
| 33 | -tenant-id: {{adminTenentId}} | |
| 33 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.http
| 1 | 1 | ### 请求 /system/oauth2/authorize 接口 => 成功 |
| 2 | 2 | GET {{baseUrl}}/system/oauth2/authorize?clientId=default |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 请求 /system/oauth2/authorize + token 接口 => 成功 |
| 7 | 7 | POST {{baseUrl}}/system/oauth2/authorize |
| 8 | 8 | Content-Type: application/x-www-form-urlencoded |
| 9 | 9 | Authorization: Bearer {{token}} |
| 10 | -tenant-id: {{adminTenentId}} | |
| 10 | +tenant-id: {{adminTenantId}} | |
| 11 | 11 | |
| 12 | 12 | response_type=token&client_id=default&scope={"user.read": true}&redirect_uri=https://www.iocoder.cn&auto_approve=true |
| 13 | 13 | |
| ... | ... | @@ -15,7 +15,7 @@ response_type=token&client_id=default&scope={"user.read": true}&redirect_uri=htt |
| 15 | 15 | POST {{baseUrl}}/system/oauth2/authorize |
| 16 | 16 | Content-Type: application/x-www-form-urlencoded |
| 17 | 17 | Authorization: Bearer {{token}} |
| 18 | -tenant-id: {{adminTenentId}} | |
| 18 | +tenant-id: {{adminTenantId}} | |
| 19 | 19 | |
| 20 | 20 | response_type=code&client_id=default&scope={"user.read": true}&redirect_uri=https://www.iocoder.cn&auto_approve=false |
| 21 | 21 | |
| ... | ... | @@ -23,7 +23,7 @@ response_type=code&client_id=default&scope={"user.read": true}&redirect_uri=http |
| 23 | 23 | POST {{baseUrl}}/system/oauth2/token |
| 24 | 24 | Content-Type: application/x-www-form-urlencoded |
| 25 | 25 | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== |
| 26 | -tenant-id: {{adminTenentId}} | |
| 26 | +tenant-id: {{adminTenantId}} | |
| 27 | 27 | |
| 28 | 28 | grant_type=authorization_code&redirect_uri=https://www.iocoder.cn&code=189956c07a174588a97157eabef2f93a |
| 29 | 29 | |
| ... | ... | @@ -31,7 +31,7 @@ grant_type=authorization_code&redirect_uri=https://www.iocoder.cn&code=189956c07 |
| 31 | 31 | POST {{baseUrl}}/system/oauth2/token |
| 32 | 32 | Content-Type: application/x-www-form-urlencoded |
| 33 | 33 | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== |
| 34 | -tenant-id: {{adminTenentId}} | |
| 34 | +tenant-id: {{adminTenantId}} | |
| 35 | 35 | |
| 36 | 36 | grant_type=password&username=admin&password=admin123&scope=user.read |
| 37 | 37 | |
| ... | ... | @@ -39,16 +39,16 @@ grant_type=password&username=admin&password=admin123&scope=user.read |
| 39 | 39 | POST {{baseUrl}}/system/oauth2/token |
| 40 | 40 | Content-Type: application/x-www-form-urlencoded |
| 41 | 41 | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== |
| 42 | -tenant-id: {{adminTenentId}} | |
| 42 | +tenant-id: {{adminTenantId}} | |
| 43 | 43 | |
| 44 | 44 | grant_type=refresh_token&refresh_token=00895465d6994f72a9d926ceeed0f588 |
| 45 | 45 | |
| 46 | 46 | ### 请求 /system/oauth2/token + DELETE 接口 => 成功 |
| 47 | 47 | DELETE {{baseUrl}}/system/oauth2/token?token=ca8a188f464441d6949c51493a2b7596 |
| 48 | 48 | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== |
| 49 | -tenant-id: {{adminTenentId}} | |
| 49 | +tenant-id: {{adminTenantId}} | |
| 50 | 50 | |
| 51 | 51 | ### 请求 /system/oauth2/check-token 接口 => 成功 |
| 52 | 52 | POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106 |
| 53 | 53 | Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw== |
| 54 | -tenant-id: {{adminTenentId}} | |
| 54 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.http
| 1 | 1 | ### 请求 /system/oauth2/user/get 接口 => 成功 |
| 2 | 2 | GET {{baseUrl}}/system/oauth2/user/get |
| 3 | 3 | Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d |
| 4 | -tenant-id: {{adminTenentId}} | |
| 4 | +tenant-id: {{adminTenantId}} | |
| 5 | 5 | |
| 6 | 6 | ### 请求 /system/oauth2/user/update 接口 => 成功 |
| 7 | 7 | PUT {{baseUrl}}/system/oauth2/user/update |
| 8 | 8 | Content-Type: application/json |
| 9 | 9 | Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d |
| 10 | -tenant-id: {{adminTenentId}} | |
| 10 | +tenant-id: {{adminTenantId}} | |
| 11 | 11 | |
| 12 | 12 | { |
| 13 | 13 | "nickname": "芋道源码" | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.http
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | POST {{baseUrl}}/system/role/create |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | 4 | Content-Type: application/json |
| 5 | -tenant-id: {{adminTenentId}} | |
| 5 | +tenant-id: {{adminTenantId}} | |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | 8 | "name": "测试角色", |
| ... | ... | @@ -14,7 +14,7 @@ tenant-id: {{adminTenentId}} |
| 14 | 14 | POST {{baseUrl}}/system/role/update |
| 15 | 15 | Authorization: Bearer {{token}} |
| 16 | 16 | Content-Type: application/json |
| 17 | -tenant-id: {{adminTenentId}} | |
| 17 | +tenant-id: {{adminTenantId}} | |
| 18 | 18 | |
| 19 | 19 | { |
| 20 | 20 | "id": 100, |
| ... | ... | @@ -26,7 +26,7 @@ tenant-id: {{adminTenentId}} |
| 26 | 26 | POST {{baseUrl}}/system/role/delete |
| 27 | 27 | Content-Type: application/x-www-form-urlencoded |
| 28 | 28 | Authorization: Bearer {{token}} |
| 29 | -tenant-id: {{adminTenentId}} | |
| 29 | +tenant-id: {{adminTenantId}} | |
| 30 | 30 | |
| 31 | 31 | roleId=14 |
| 32 | 32 | |
| ... | ... | @@ -34,9 +34,9 @@ roleId=14 |
| 34 | 34 | GET {{baseUrl}}/system/role/get?id=100 |
| 35 | 35 | Content-Type: application/x-www-form-urlencoded |
| 36 | 36 | Authorization: Bearer {{token}} |
| 37 | -tenant-id: {{adminTenentId}} | |
| 37 | +tenant-id: {{adminTenantId}} | |
| 38 | 38 | |
| 39 | 39 | ### /role/page 成功 |
| 40 | 40 | GET {{baseUrl}}/system/role/page?pageNo=1&pageSize=10 |
| 41 | 41 | Authorization: Bearer {{token}} |
| 42 | -tenant-id: {{adminTenentId}} | |
| 42 | +tenant-id: {{adminTenantId}} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.http
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.http