Commit bb11fdd3fa4b006df1c7b675753eddc15fcf7fc3

Authored by YunaiV
2 parents bc9b3715 949fa225

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
... ... @@ -32,6 +32,7 @@ public enum BpmReasonEnum {
32 32 ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"),
33 33 APPROVE_TYPE_AUTO_APPROVE("非人工审核,自动通过"),
34 34 APPROVE_TYPE_AUTO_REJECT("非人工审核,自动不通过"),
  35 + CANCEL_BY_PROCESS_CLEAN("进程清理自动取消"),
35 36 ;
36 37  
37 38 private final String reason;
... ...
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&times[0]=2024-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2024-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2024-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2023-01-01 00:00:00&times[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&times[0]=2022-12-12 00:00:00&times[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&times[0]=2022-12-12 00:00:00&times[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
1 1 ### 请求 /infra/job/sync 接口 => 成功
2 2 POST {{baseUrl}}/infra/job/sync
3 3 Content-Type: application/json
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
5 5 Authorization: Bearer {{token}}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.http
1 1 ### 请求 /infra/redis/get-monitor-info 接口 => 成功
2 2 GET {{baseUrl}}/infra/redis/get-monitor-info
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...
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
1 1 ### 获得商品 SPU 明细
2 2 GET {{baseUrl}}/product/spu/get-detail?id=4
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...
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
... ... @@ -2,4 +2,4 @@
2 2 GET {{appApi}}/promotion/activity/list-by-spu-ids?spuIds=222&spuIds=633
3 3 Authorization: Bearer {{appToken}}
4 4 Content-Type: application/json
5   -tenant-id: {{appTenentId}}
  5 +tenant-id: {{appTenantId}}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainHelpController.http
... ... @@ -2,7 +2,7 @@
2 2 POST {{appApi}}/promotion/bargain-help/create
3 3 Authorization: Bearer test248
4 4 Content-Type: application/json
5   -tenant-id: {{appTenentId}}
  5 +tenant-id: {{appTenantId}}
6 6  
7 7 {
8 8 "recordId": 26
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainRecordController.http
... ... @@ -2,7 +2,7 @@
2 2 POST {{appApi}}/promotion/bargain-record/create
3 3 Authorization: Bearer {{appToken}}
4 4 Content-Type: application/json
5   -tenant-id: {{appTenentId}}
  5 +tenant-id: {{appTenantId}}
6 6  
7 7 {
8 8 "activityId": 1
... ...
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
1 1 ### 请求 /member/user/profile/get 接口 => 没有权限
2 2 GET {{appApi}}/member/user/get
3 3 Authorization: Bearer test245
4   -tenant-id: {{appTenentId}}
  4 +tenant-id: {{appTenantId}}
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.http
... ... @@ -2,4 +2,4 @@
2 2 GET {{baseUrl}}/mp/material/page?permanent=true&pageNo=1&pageSize=10
3 3 Content-Type: application/json
4 4 Authorization: Bearer {{token}}
5   -tenant-id: {{adminTenentId}}
  5 +tenant-id: {{adminTenantId}}
... ...
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
... ... @@ -2,4 +2,4 @@
2 2 GET {{baseUrl}}/mp/auto-reply/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}}
... ...
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
1 1 ### 请求 /menu/list 接口 => 成功
2 2 GET {{baseUrl}}/system/dict-data/list-all-simple
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.http
1 1 ### 获得地区树
2 2 GET {{baseUrl}}/system/area/tree
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
5 5  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.http
1 1 ### 请求 /system/operate-log/page 接口 => 成功
2 2 GET {{baseUrl}}/system/operate-log/page
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.http
... ... @@ -2,7 +2,7 @@
2 2 POST {{baseUrl}}/system/mail-template/send-mail
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 "templateCode": "test_01",
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.http
... ... @@ -2,7 +2,7 @@
2 2 POST {{baseUrl}}/system/oauth2-client/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 "id": "1",
... ...
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&amp;client_id=default&amp;scope={&quot;user.read&quot;: true}&amp;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&amp;client_id=default&amp;scope={&quot;user.read&quot;: true}&amp;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&amp;redirect_uri=https://www.iocoder.cn&amp;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&amp;username=admin&amp;password=admin123&amp;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
1 1 ### 请求 /menu/list 接口 => 成功
2 2 GET {{baseUrl}}/system/menu/list
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...
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
... ... @@ -2,7 +2,7 @@
2 2 POST {{baseUrl}}/system/sms-template/send-sms
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 "templateCode": "test_01",
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.http
... ... @@ -3,7 +3,7 @@ POST {{baseUrl}}/system/social-client/send-subscribe-message
3 3 Authorization: Bearer {{token}}
4 4 Content-Type: application/json
5 5 #Authorization: Bearer test100
6   -tenant-id: {{adminTenentId}}
  6 +tenant-id: {{adminTenantId}}
7 7  
8 8 {
9 9 "userId": 247,
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.http
... ... @@ -5,7 +5,7 @@ GET {{baseUrl}}/system/tenant/get-id-by-name?name=芋道源码
5 5 POST {{baseUrl}}/system/tenant/create
6 6 Content-Type: application/json
7 7 Authorization: Bearer {{token}}
8   -tenant-id: {{adminTenentId}}
  8 +tenant-id: {{adminTenantId}}
9 9  
10 10 {
11 11 "name": "芋道",
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.http
... ... @@ -2,4 +2,4 @@
2 2 GET {{baseUrl}}/system/user/page?pageNo=1&pageSize=10
3 3 Authorization: Bearer {{token}}
4 4 #Authorization: Bearer test100
5   -tenant-id: {{adminTenentId}}
  5 +tenant-id: {{adminTenantId}}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.http
1 1 ### 请求 /system/user/profile/get 接口 => 没有权限
2 2 GET {{baseUrl}}/system/user/profile/get
3 3 Authorization: Bearer {{token}}
4   -tenant-id: {{adminTenentId}}
  4 +tenant-id: {{adminTenantId}}
... ...