Merge remote-tracking branch 'base-version/main' into test
# Conflicts: # zt-module-bpm/zt-module-bpm-server/src/main/java/com/zt/plat/module/bpm/api/task/BpmProcessInstanceApiImpl.java # zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/auth/AdminAuthServiceImpl.java
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -32,7 +32,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.39</revision>
|
<revision>3.0.40</revision>
|
||||||
<!-- Maven 相关 -->
|
<!-- Maven 相关 -->
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.39</revision>
|
<revision>3.0.40</revision>
|
||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.boot.version>3.4.5</spring.boot.version>
|
<spring.boot.version>3.4.5</spring.boot.version>
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
package com.zt.plat.module.bpm.api.task;
|
package com.zt.plat.module.bpm.api.task;
|
||||||
|
|
||||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
|
import com.zt.plat.module.bpm.api.task.dto.*;
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmTaskApproveReqDTO;
|
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRejectReqDTO;
|
|
||||||
import com.zt.plat.module.bpm.enums.ApiConstants;
|
import com.zt.plat.module.bpm.enums.ApiConstants;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import java.util.List;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||||
@Tag(name = "RPC 服务 - 流程实例")
|
@Tag(name = "RPC 服务 - 流程实例")
|
||||||
@@ -27,6 +24,37 @@ public interface BpmProcessInstanceApi {
|
|||||||
CommonResult<String> createProcessInstance(@RequestParam("userId") Long userId,
|
CommonResult<String> createProcessInstance(@RequestParam("userId") Long userId,
|
||||||
@Valid @RequestBody BpmProcessInstanceCreateReqDTO reqDTO);
|
@Valid @RequestBody BpmProcessInstanceCreateReqDTO reqDTO);
|
||||||
|
|
||||||
|
@GetMapping(PREFIX + "/get")
|
||||||
|
@Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中,进行调用")
|
||||||
|
@Parameter(name = "id", description = "流程实例的编号", required = true)
|
||||||
|
CommonResult<BpmProcessInstanceRespDTO> getProcessInstance(@RequestParam("id") String id);
|
||||||
|
|
||||||
|
@DeleteMapping(PREFIX + "/cancel-by-start-user")
|
||||||
|
@Operation(summary = "用户取消流程实例", description = "取消发起的流程")
|
||||||
|
CommonResult<Boolean> cancelProcessInstanceByStartUser(
|
||||||
|
@RequestParam("userId") Long userId,
|
||||||
|
@Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO);
|
||||||
|
|
||||||
|
@DeleteMapping(PREFIX + "/cancel-by-admin")
|
||||||
|
@Operation(summary = "管理员取消流程实例", description = "管理员撤回流程")
|
||||||
|
CommonResult<Boolean> cancelProcessInstanceByAdmin(
|
||||||
|
@RequestParam("userId") Long userId,
|
||||||
|
@Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO);
|
||||||
|
|
||||||
|
@PostMapping(PREFIX + "/get-approval-detail")
|
||||||
|
@Operation(summary = "获得审批详情")
|
||||||
|
CommonResult<BpmApprovalDetailRespDTO> getApprovalDetail(@RequestParam("userId") Long userId,
|
||||||
|
@Valid BpmApprovalDetailReqDTO reqDTO);
|
||||||
|
|
||||||
|
@PostMapping(PREFIX + "/get-next-approval-nodes")
|
||||||
|
@Operation(summary = "获取下一个执行的流程节点")
|
||||||
|
CommonResult<List<BpmApprovalDetailRespDTO.ActivityNode>> getNextApprovalNodes(@RequestParam("userId") Long userId,
|
||||||
|
@Valid BpmApprovalDetailReqDTO reqDTO);
|
||||||
|
|
||||||
|
@PostMapping(PREFIX + "/get-bpmn-model-view")
|
||||||
|
@Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用")
|
||||||
|
@Parameter(name = "id", description = "流程实例的编号", required = true)
|
||||||
|
CommonResult<BpmProcessInstanceBpmnModelViewRespDTO> getProcessInstanceBpmnModelView(@RequestParam(value = "id") String id);
|
||||||
|
|
||||||
@PutMapping(PREFIX + "/approveTask")
|
@PutMapping(PREFIX + "/approveTask")
|
||||||
@Operation(summary = "通过任务")
|
@Operation(summary = "通过任务")
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.AssertTrue;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 审批详情 Request DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmApprovalDetailReqDTO {
|
||||||
|
|
||||||
|
@Schema(description = "流程定义的编号", example = "1024")
|
||||||
|
private String processDefinitionId; // 使用场景:发起流程时,传流程定义 ID
|
||||||
|
|
||||||
|
@Schema(description = "流程变量")
|
||||||
|
private Map<String, Object> processVariables; // 使用场景:同 processDefinitionId,用于流程预测
|
||||||
|
|
||||||
|
@Schema(description = "流程变量")
|
||||||
|
private String processVariablesStr; // 解决 GET 无法传递对象的问题,最终转换成 processVariables 变量
|
||||||
|
|
||||||
|
@Schema(description = "流程实例的编号", example = "1024")
|
||||||
|
private String processInstanceId; // 使用场景:流程已发起时候传流程实例 ID
|
||||||
|
|
||||||
|
// TODO @芋艿:如果未来 BPMN 增加流程图,它没有发起人节点,会有问题。
|
||||||
|
@Schema(description = "流程活动编号", example = "StartUserNode")
|
||||||
|
private String activityId; // 用于获取表单权限。1)发起流程时,传"发起人节点" activityId 可获取发起人的表单权限;2)从抄送列表界面进来时,传抄送的 activityId 可获取抄送人的表单权限;
|
||||||
|
|
||||||
|
@Schema(description = "流程任务编号", example = "95f2f08b-621b-11ef-bf39-00ff4722db8b")
|
||||||
|
private String taskId; // 用于获取表单权限。1)从待审批/已审批界面进来时,传递 taskId 任务编号,可获取任务节点的变得权限
|
||||||
|
|
||||||
|
@AssertTrue(message = "流程定义的编号和流程实例的编号不能同时为空")
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean isValidProcessParam() {
|
||||||
|
return StrUtil.isNotEmpty(processDefinitionId) || StrUtil.isNotEmpty(processInstanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRespDTO;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 审批详情 Response DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmApprovalDetailRespDTO {
|
||||||
|
|
||||||
|
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
|
||||||
|
|
||||||
|
@Schema(description = "活动节点列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private List<ActivityNode> activityNodes;
|
||||||
|
|
||||||
|
@Schema(description = "表单字段权限")
|
||||||
|
private Map<String, String> formFieldsPermission;
|
||||||
|
|
||||||
|
@Schema(description = "待办任务")
|
||||||
|
private BpmTaskRespDTO todoTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属流程定义信息
|
||||||
|
*/
|
||||||
|
private BpmProcessDefinitionRespDTO processDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属流程实例信息
|
||||||
|
*/
|
||||||
|
private BpmProcessInstanceRespDTO processInstance;
|
||||||
|
|
||||||
|
@Schema(description = "活动节点信息")
|
||||||
|
@Data
|
||||||
|
public static class ActivityNode {
|
||||||
|
|
||||||
|
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartUserNode")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "发起人")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "节点类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer nodeType; // 参见 BpmSimpleModelNodeType 枚举
|
||||||
|
|
||||||
|
@Schema(description = "节点状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||||
|
private Integer status; // 参见 BpmTaskStatusEnum 枚举
|
||||||
|
|
||||||
|
@Schema(description = "节点的开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
@Schema(description = "节点的结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "审批节点的任务信息")
|
||||||
|
private List<ActivityNodeTask> tasks;
|
||||||
|
|
||||||
|
@Schema(description = "候选人策略", example = "35")
|
||||||
|
private Integer candidateStrategy; // 参见 BpmTaskCandidateStrategyEnum 枚举。主要用于发起时,审批节点、抄送节点自选
|
||||||
|
|
||||||
|
@Schema(description = "候选人用户 ID 列表", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1818")
|
||||||
|
@JsonIgnore // 不返回,只是方便后续读取,赋值给 candidateUsers
|
||||||
|
private List<Long> candidateUserIds;
|
||||||
|
|
||||||
|
@Schema(description = "候选人用户列表")
|
||||||
|
private List<UserSimpleDTO> candidateUsers; // 只包含未生成 ApprovalTaskInfo 的用户列表
|
||||||
|
|
||||||
|
@Schema(description = "流程编号", example = "8761d8e0-0922-11f0-bd37-00ff1db677bf")
|
||||||
|
private String processInstanceId; // 当且仅当,该节点是子流程节点时,才会有值(CallActivity 的 processInstanceId 字段)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "活动节点的任务信息")
|
||||||
|
@Data
|
||||||
|
public static class ActivityNodeTask {
|
||||||
|
|
||||||
|
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "任务所属人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1818")
|
||||||
|
@JsonIgnore // 不返回,只是方便后续读取,赋值给 ownerUser
|
||||||
|
private Long owner;
|
||||||
|
|
||||||
|
@Schema(description = "任务所属人", example = "1024")
|
||||||
|
private UserSimpleDTO ownerUser;
|
||||||
|
|
||||||
|
@Schema(description = "任务分配人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
|
||||||
|
@JsonIgnore // 不返回,只是方便后续读取,赋值给 assigneeUser
|
||||||
|
private Long assignee;
|
||||||
|
|
||||||
|
@Schema(description = "任务分配人", example = "2048")
|
||||||
|
private UserSimpleDTO assigneeUser;
|
||||||
|
|
||||||
|
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer status; // 参见 BpmTaskStatusEnum 枚举
|
||||||
|
|
||||||
|
@Schema(description = "审批意见", example = "同意")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
||||||
|
private String signPicUrl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 流程定义 Response DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmProcessDefinitionRespDTO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_order")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
@Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假流程")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "流程描述", example = "请假流程描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "oa")
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@Schema(description = "表单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer formType;
|
||||||
|
|
||||||
|
@Schema(description = "表单编号", example = "1024")
|
||||||
|
private Long formId;
|
||||||
|
|
||||||
|
@Schema(description = "表单的配置", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String formConf;
|
||||||
|
|
||||||
|
@Schema(description = "表单项的数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private List<String> formFields;
|
||||||
|
|
||||||
|
@Schema(description = "表单项的 JSON 数组字符串", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String formFieldsStr;
|
||||||
|
|
||||||
|
@Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String bpmnXml;
|
||||||
|
|
||||||
|
@Schema(description = "版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer version;
|
||||||
|
|
||||||
|
@Schema(description = "是否挂起", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||||
|
private Integer suspensionState;
|
||||||
|
|
||||||
|
@Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private LocalDateTime deploymentTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 流程示例的 BPMN 视图 Response DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmProcessInstanceBpmnModelViewRespDTO {
|
||||||
|
|
||||||
|
// ========== 基本信息 ==========
|
||||||
|
|
||||||
|
@Schema(description = "流程实例信息", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private BpmProcessInstanceRespDTO processInstance;
|
||||||
|
|
||||||
|
@Schema(description = "任务列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private List<BpmTaskRespDTO> tasks;
|
||||||
|
|
||||||
|
@Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String bpmnXml;
|
||||||
|
|
||||||
|
@Schema(description = "SIMPLE 模型")
|
||||||
|
private BpmSimpleModelNodeDTO simpleModel;
|
||||||
|
|
||||||
|
// ========== 进度信息 ==========
|
||||||
|
|
||||||
|
@Schema(description = "进行中的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Set<String> unfinishedTaskActivityIds; // 只包括 UserTask
|
||||||
|
|
||||||
|
@Schema(description = "已经完成的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Set<String> finishedTaskActivityIds; // 包括 UserTask、Gateway 等,不包括 SequenceFlow
|
||||||
|
|
||||||
|
@Schema(description = "已经完成的连线节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Set<String> finishedSequenceFlowActivityIds; // 只包括 SequenceFlow
|
||||||
|
|
||||||
|
@Schema(description = "已经拒绝的活动节点编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Set<String> rejectedTaskActivityIds; // 只包括 UserTask
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 流程实例的取消 Request DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmProcessInstanceCancelReqDTO {
|
||||||
|
|
||||||
|
@Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@NotEmpty(message = "流程实例的编号不能为空")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "取消原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "不请假了!")
|
||||||
|
@NotEmpty(message = "取消原因不能为空")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -22,6 +22,9 @@ public class BpmProcessInstancePageReqDTO extends PageParam {
|
|||||||
@Schema(description = "流程定义的编号", example = "2048")
|
@Schema(description = "流程定义的编号", example = "2048")
|
||||||
private String processDefinitionId;
|
private String processDefinitionId;
|
||||||
|
|
||||||
|
@Schema(description = "流程定义的标识", example = "2048")
|
||||||
|
private String processDefinitionKey; // 精准匹配
|
||||||
|
|
||||||
@Schema(description = "流程分类", example = "1")
|
@Schema(description = "流程分类", example = "1")
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
@@ -35,4 +38,14 @@ public class BpmProcessInstancePageReqDTO extends PageParam {
|
|||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
private LocalDateTime[] createTime;
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] endTime;
|
||||||
|
|
||||||
|
@Schema(description = "发起用户编号", example = "1024")
|
||||||
|
private Long startUserId; // 注意,只有在【流程实例】菜单,才使用该参数
|
||||||
|
|
||||||
|
@Schema(description = "动态表单字段查询 JSON Str", example = "{}")
|
||||||
|
private String formFieldsParams; // SpringMVC 在 get 请求下,无法方便的定义 Map 类型的参数,所以通过 String 接收后,逻辑里面转换
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.zt.plat.module.bpm.api.task.dto;
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import com.zt.plat.framework.common.core.KeyValue;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Schema(description = "RPC 服务 - 流程实例 Response DTO")
|
@Schema(description = "RPC 服务 - 流程实例 Response DTO")
|
||||||
@@ -16,23 +19,26 @@ public class BpmProcessInstanceRespDTO {
|
|||||||
@Schema(description = "流程实例的名字", example = "芋艿")
|
@Schema(description = "流程实例的名字", example = "芋艿")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "流程摘要")
|
||||||
|
private List<KeyValue<String, String>> summary; // 只有流程表单,才有摘要!
|
||||||
|
|
||||||
@Schema(description = "流程定义的编号", example = "2048")
|
@Schema(description = "流程定义的编号", example = "2048")
|
||||||
private String processDefinitionId;
|
private String processDefinitionId;
|
||||||
|
|
||||||
@Schema(description = "流程分类", example = "1")
|
@Schema(description = "流程分类", example = "1")
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
|
@Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
@Schema(description = "流程实例的状态", example = "1")
|
@Schema(description = "流程实例的状态", example = "1")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@Schema(description = "流程实例的结果", example = "1")
|
@Schema(description = "流程实例的结果", example = "1")
|
||||||
private Integer result;
|
private Integer result;
|
||||||
|
|
||||||
@Schema(description = "提交的表单值", example = "{\"name\": \"芋艿\"}")
|
@Schema(description = "发起时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Map<String, Object> formVariables;
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
@Schema(description = "业务的唯一标识", example = "1")
|
|
||||||
private String businessKey;
|
|
||||||
|
|
||||||
@Schema(description = "创建时间")
|
@Schema(description = "创建时间")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
@@ -43,4 +49,44 @@ public class BpmProcessInstanceRespDTO {
|
|||||||
@Schema(description = "持续时间", example = "1000")
|
@Schema(description = "持续时间", example = "1000")
|
||||||
private Long durationInMillis;
|
private Long durationInMillis;
|
||||||
|
|
||||||
|
@Schema(description = "提交的表单值", example = "{\"name\": \"芋艿\"}")
|
||||||
|
private Map<String, Object> formVariables;
|
||||||
|
|
||||||
|
@Schema(description = "业务的唯一标识", example = "1")
|
||||||
|
private String businessKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起流程的用户
|
||||||
|
*/
|
||||||
|
private UserSimpleDTO startUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程定义
|
||||||
|
*/
|
||||||
|
private BpmProcessDefinitionRespDTO processDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前审批中的任务
|
||||||
|
*/
|
||||||
|
private List<Task> tasks; // 仅在流程实例分页才返回
|
||||||
|
|
||||||
|
@Schema(description = "流程任务")
|
||||||
|
@Data
|
||||||
|
public static class Task {
|
||||||
|
|
||||||
|
@Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "任务分配人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
|
||||||
|
@JsonIgnore // 不返回,只是方便后续读取,赋值给 assigneeUser
|
||||||
|
private Long assignee;
|
||||||
|
|
||||||
|
@Schema(description = "任务分配人", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2048")
|
||||||
|
private UserSimpleDTO assigneeUser;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.zt.plat.module.bpm.api.task.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "RPC 服务 - 简单模型节点 DTO")
|
||||||
|
@Data
|
||||||
|
public class BpmSimpleModelNodeDTO {
|
||||||
|
|
||||||
|
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartNode")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "开始节点")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "节点类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
@Schema(description = "节点属性")
|
||||||
|
private Map<String, Object> attributes;
|
||||||
|
|
||||||
|
@Schema(description = "子节点列表")
|
||||||
|
private List<BpmSimpleModelNodeDTO> childNode;
|
||||||
|
|
||||||
|
@Schema(description = "条件节点列表")
|
||||||
|
private List<BpmSimpleModelNodeDTO> conditionNodes;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,19 +1,36 @@
|
|||||||
package com.zt.plat.module.bpm.api.task;
|
package com.zt.plat.module.bpm.api.task;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.zt.plat.framework.business.core.util.DeptUtil;
|
||||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||||
|
import com.zt.plat.framework.common.util.json.JsonUtils;
|
||||||
|
import com.zt.plat.framework.common.util.number.NumberUtils;
|
||||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
|
import com.zt.plat.module.bpm.api.task.dto.*;
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmTaskApproveReqDTO;
|
import com.zt.plat.module.bpm.controller.admin.task.vo.instance.*;
|
||||||
import com.zt.plat.module.bpm.api.task.dto.BpmTaskRejectReqDTO;
|
|
||||||
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
|
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
|
||||||
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
|
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
|
||||||
|
import com.zt.plat.module.bpm.convert.task.BpmProcessInstanceConvert;
|
||||||
|
import com.zt.plat.module.bpm.convert.task.BpmProcessInstanceDTOConvert;
|
||||||
|
import com.zt.plat.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
|
import com.zt.plat.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
|
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
import com.zt.plat.module.bpm.service.task.BpmTaskService;
|
import com.zt.plat.module.bpm.service.task.BpmTaskService;
|
||||||
|
import com.zt.plat.module.system.api.dept.DeptApi;
|
||||||
|
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
|
||||||
|
import com.zt.plat.module.system.api.user.AdminUserApi;
|
||||||
|
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
|
import org.flowable.engine.repository.ProcessDefinition;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||||
import static com.zt.plat.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
import static com.zt.plat.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
@@ -33,11 +50,92 @@ public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi {
|
|||||||
@Resource
|
@Resource
|
||||||
private BpmTaskService taskService;
|
private BpmTaskService taskService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BpmProcessDefinitionService processDefinitionService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdminUserApi adminUserApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DeptApi deptApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<String> createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) {
|
public CommonResult<String> createProcessInstance(Long userId, @Valid @RequestBody BpmProcessInstanceCreateReqDTO reqDTO) {
|
||||||
return success(processInstanceService.createProcessInstance(userId, reqDTO));
|
return success(processInstanceService.createProcessInstance(userId, reqDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<BpmProcessInstanceRespDTO> getProcessInstance(String id) {
|
||||||
|
HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(id);
|
||||||
|
if (processInstance == null) {
|
||||||
|
return success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接返回
|
||||||
|
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
|
||||||
|
processInstance.getProcessDefinitionId());
|
||||||
|
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
|
||||||
|
processInstance.getProcessDefinitionId());
|
||||||
|
AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())).getCheckedData();
|
||||||
|
DeptRespDTO dept = null;
|
||||||
|
if (startUser != null) {
|
||||||
|
Long deptId = DeptUtil.getDeptId(startUser);
|
||||||
|
if (deptId > 0) {
|
||||||
|
dept = deptApi.getDept(deptId).getCheckedData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BpmProcessInstanceRespVO vo = BpmProcessInstanceConvert.INSTANCE.buildProcessInstance(processInstance,
|
||||||
|
processDefinition, processDefinitionInfo, startUser, dept);
|
||||||
|
return success(BpmProcessInstanceDTOConvert.INSTANCE.convert(vo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> cancelProcessInstanceByStartUser(
|
||||||
|
Long userId, @Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO) {
|
||||||
|
BpmProcessInstanceCancelReqVO cancelReqVO = BpmProcessInstanceDTOConvert.INSTANCE.convertVO(cancelReqDTO);
|
||||||
|
processInstanceService.cancelProcessInstanceByStartUser(userId, cancelReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> cancelProcessInstanceByAdmin(
|
||||||
|
Long userId, @Valid @RequestBody BpmProcessInstanceCancelReqDTO cancelReqDTO) {
|
||||||
|
BpmProcessInstanceCancelReqVO cancelReqVO = BpmProcessInstanceDTOConvert.INSTANCE.convertVO(cancelReqDTO);
|
||||||
|
processInstanceService.cancelProcessInstanceByAdmin(userId, cancelReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public CommonResult<BpmApprovalDetailRespDTO> getApprovalDetail(Long userId,
|
||||||
|
@Valid @RequestBody BpmApprovalDetailReqDTO reqDTO) {
|
||||||
|
BpmApprovalDetailReqVO reqVO = BpmProcessInstanceDTOConvert.INSTANCE.convertVO(reqDTO);
|
||||||
|
if (StrUtil.isNotEmpty(reqDTO.getProcessVariablesStr())) {
|
||||||
|
reqVO.setProcessVariables(JsonUtils.parseObject(reqDTO.getProcessVariablesStr(), Map.class));
|
||||||
|
}
|
||||||
|
BpmApprovalDetailRespVO respVO = processInstanceService.getApprovalDetail(userId, reqVO);
|
||||||
|
return success(BpmProcessInstanceDTOConvert.INSTANCE.convert(respVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public CommonResult<List<BpmApprovalDetailRespDTO.ActivityNode>> getNextApprovalNodes(Long userId,
|
||||||
|
@Valid @RequestBody BpmApprovalDetailReqDTO reqDTO) {
|
||||||
|
BpmApprovalDetailReqVO reqVO = BpmProcessInstanceDTOConvert.INSTANCE.convertVO(reqDTO);
|
||||||
|
if (StrUtil.isNotEmpty(reqDTO.getProcessVariablesStr())) {
|
||||||
|
reqVO.setProcessVariables(JsonUtils.parseObject(reqDTO.getProcessVariablesStr(), Map.class));
|
||||||
|
}
|
||||||
|
List<BpmApprovalDetailRespVO.ActivityNode> nodes = processInstanceService.getNextApprovalNodes(userId, reqVO);
|
||||||
|
return success(BpmProcessInstanceDTOConvert.INSTANCE.convertActivityNodes(nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<BpmProcessInstanceBpmnModelViewRespDTO> getProcessInstanceBpmnModelView(String id) {
|
||||||
|
BpmProcessInstanceBpmnModelViewRespVO respVO = processInstanceService.getProcessInstanceBpmnModelView(id);
|
||||||
|
return success(BpmProcessInstanceDTOConvert.INSTANCE.convert(respVO));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> approveTask(BpmTaskApproveReqDTO reqVO) {
|
public CommonResult<Boolean> approveTask(BpmTaskApproveReqDTO reqVO) {
|
||||||
taskService.approveTask(getLoginUserId(), BeanUtils.toBean(reqVO, BpmTaskApproveReqVO.class));
|
taskService.approveTask(getLoginUserId(), BeanUtils.toBean(reqVO, BpmTaskApproveReqVO.class));
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.zt.plat.module.bpm.convert.task;
|
||||||
|
|
||||||
|
import com.zt.plat.framework.common.pojo.PageResult;
|
||||||
|
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||||
|
import com.zt.plat.module.bpm.api.task.dto.*;
|
||||||
|
import com.zt.plat.module.bpm.controller.admin.task.vo.instance.*;
|
||||||
|
import com.zt.plat.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
||||||
|
import com.zt.plat.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
|
||||||
|
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.Named;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程实例 DTO 转换器
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface BpmProcessInstanceDTOConvert {
|
||||||
|
|
||||||
|
BpmProcessInstanceDTOConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceDTOConvert.class);
|
||||||
|
|
||||||
|
// VO to DTO
|
||||||
|
BpmProcessInstancePageReqDTO convert(BpmProcessInstancePageReqVO bean);
|
||||||
|
BpmProcessInstanceCancelReqDTO convert(BpmProcessInstanceCancelReqVO bean);
|
||||||
|
BpmApprovalDetailReqDTO convert(BpmApprovalDetailReqVO bean);
|
||||||
|
|
||||||
|
// DTO to VO
|
||||||
|
BpmProcessInstancePageReqVO convertVO(BpmProcessInstancePageReqDTO bean);
|
||||||
|
BpmProcessInstanceCancelReqVO convertVO(BpmProcessInstanceCancelReqDTO bean);
|
||||||
|
BpmApprovalDetailReqVO convertVO(BpmApprovalDetailReqDTO bean);
|
||||||
|
|
||||||
|
PageResult<BpmProcessInstanceRespDTO> convertPage(PageResult<BpmProcessInstanceRespVO> pageResult);
|
||||||
|
BpmProcessInstanceRespDTO convert(BpmProcessInstanceRespVO bean);
|
||||||
|
BpmApprovalDetailRespDTO convert(BpmApprovalDetailRespVO bean);
|
||||||
|
BpmProcessInstanceBpmnModelViewRespDTO convert(BpmProcessInstanceBpmnModelViewRespVO bean);
|
||||||
|
|
||||||
|
List<BpmApprovalDetailRespDTO.ActivityNode> convertActivityNodes(List<BpmApprovalDetailRespVO.ActivityNode> nodes);
|
||||||
|
|
||||||
|
// 内部类转换
|
||||||
|
BpmProcessInstanceRespDTO.Task convert(BpmProcessInstanceRespVO.Task task);
|
||||||
|
BpmApprovalDetailRespDTO.ActivityNode convert(BpmApprovalDetailRespVO.ActivityNode node);
|
||||||
|
BpmApprovalDetailRespDTO.ActivityNodeTask convert(BpmApprovalDetailRespVO.ActivityNodeTask task);
|
||||||
|
|
||||||
|
// 用户信息转换
|
||||||
|
UserSimpleDTO convertUser(UserSimpleBaseVO user);
|
||||||
|
BpmProcessDefinitionRespDTO convert(BpmProcessDefinitionRespVO definition);
|
||||||
|
|
||||||
|
@Mapping(target = "childNode", source = "childNode", qualifiedByName = "mapChildNode")
|
||||||
|
BpmSimpleModelNodeDTO convert(BpmSimpleModelNodeVO simpleModel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将BpmSimpleModelNodeVO的childNode转换为List<BpmSimpleModelNodeDTO>
|
||||||
|
*/
|
||||||
|
@Named("mapChildNode")
|
||||||
|
default List<BpmSimpleModelNodeDTO> mapChildNode(BpmSimpleModelNodeVO childNode) {
|
||||||
|
if (childNode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return List.of(convert(childNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,6 +18,8 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1_002_000_007, "手机号不存在");
|
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1_002_000_007, "手机号不存在");
|
||||||
ErrorCode AUTH_REGISTER_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_008, "验证码不正确,原因:{}");
|
ErrorCode AUTH_REGISTER_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_008, "验证码不正确,原因:{}");
|
||||||
ErrorCode AUTH_TEST_LOGIN_NOT_ALLOWED = new ErrorCode(1_002_000_009, "测试登录接口仅在测试环境和本地开发环境下可用");
|
ErrorCode AUTH_TEST_LOGIN_NOT_ALLOWED = new ErrorCode(1_002_000_009, "测试登录接口仅在测试环境和本地开发环境下可用");
|
||||||
|
ErrorCode AUTH_OAUTH2_CALLBACK_ERROR = new ErrorCode(1_002_000_010, "OAuth2回调处理失败:{}");
|
||||||
|
ErrorCode AUTH_LOGIN_INTERNAL_USER_PASSWORD_NOT_ALLOWED = new ErrorCode(1_002_000_011, "内部用户不允许使用账号密码登录,请通过e办进行统一登录");
|
||||||
|
|
||||||
// ========== 菜单模块 1-002-001-000 ==========
|
// ========== 菜单模块 1-002-001-000 ==========
|
||||||
ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1_002_001_000, "已经存在该名字的菜单");
|
ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1_002_001_000, "已经存在该名字的菜单");
|
||||||
|
|||||||
@@ -179,4 +179,28 @@ public class AuthController {
|
|||||||
return success(authService.socialLogin(reqVO));
|
return success(authService.socialLogin(reqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/oauth2/callback")
|
||||||
|
@PermitAll
|
||||||
|
@Operation(summary = "OAuth2回调处理", description = "处理第三方OAuth2认证回调")
|
||||||
|
@TenantIgnore
|
||||||
|
public CommonResult<AuthLoginRespVO> oauth2Callback(@RequestBody @Valid AuthOAuth2CallbackReqVO reqVO) {
|
||||||
|
return success(authService.oauth2Callback(reqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/check-user-type")
|
||||||
|
@PermitAll
|
||||||
|
@Operation(summary = "检查用户类型", description = "根据用户名判断是内部用户还是外部用户")
|
||||||
|
@TenantIgnore
|
||||||
|
public CommonResult<AuthUserTypeRespVO> checkUserType(@RequestParam("username") String username) {
|
||||||
|
return success(authService.checkUserType(username));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-eban-login-url")
|
||||||
|
@PermitAll
|
||||||
|
@Operation(summary = "获取e办登录URL", description = "获取e办系统的OAuth2登录地址")
|
||||||
|
@TenantIgnore
|
||||||
|
public CommonResult<String> getEbanLoginUrl() {
|
||||||
|
return success(authService.getEbanLoginUrl());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.zt.plat.module.system.controller.admin.auth.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - OAuth2回调 Request VO")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class AuthOAuth2CallbackReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "abc123")
|
||||||
|
@NotEmpty(message = "授权码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@Schema(description = "状态参数", example = "111")
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.zt.plat.module.system.controller.admin.auth.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 用户类型检查 Response VO")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class AuthUserTypeRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "是否为内部用户(E办用户)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
private Boolean isInternal;
|
||||||
|
|
||||||
|
@Schema(description = "E办登录跳转URL", example = "http://10.2.137.42/idp/oauth2/authorize?...")
|
||||||
|
private String ebanLoginUrl;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -93,4 +93,27 @@ public interface AdminAuthService {
|
|||||||
*/
|
*/
|
||||||
void resetPassword(AuthResetPasswordReqVO reqVO);
|
void resetPassword(AuthResetPasswordReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth2回调处理
|
||||||
|
*
|
||||||
|
* @param reqVO OAuth2回调信息
|
||||||
|
* @return 登录结果
|
||||||
|
*/
|
||||||
|
AuthLoginRespVO oauth2Callback(AuthOAuth2CallbackReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户类型
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @return 用户类型信息
|
||||||
|
*/
|
||||||
|
AuthUserTypeRespVO checkUserType(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取e办登录URL
|
||||||
|
*
|
||||||
|
* @return e办系统的OAuth2登录地址
|
||||||
|
*/
|
||||||
|
String getEbanLoginUrl();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package com.zt.plat.module.system.service.auth;
|
package com.zt.plat.module.system.service.auth;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.anji.captcha.model.common.ResponseModel;
|
|
||||||
import com.anji.captcha.model.vo.CaptchaVO;
|
|
||||||
import com.anji.captcha.service.CaptchaService;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||||
import com.zt.plat.framework.common.enums.UserTypeEnum;
|
import com.zt.plat.framework.common.enums.UserTypeEnum;
|
||||||
import com.zt.plat.framework.common.util.monitor.TracerUtils;
|
import com.zt.plat.framework.common.util.monitor.TracerUtils;
|
||||||
@@ -26,8 +22,14 @@ import com.zt.plat.module.system.enums.sms.SmsSceneEnum;
|
|||||||
import com.zt.plat.module.system.service.logger.LoginLogService;
|
import com.zt.plat.module.system.service.logger.LoginLogService;
|
||||||
import com.zt.plat.module.system.service.member.MemberService;
|
import com.zt.plat.module.system.service.member.MemberService;
|
||||||
import com.zt.plat.module.system.service.oauth2.OAuth2TokenService;
|
import com.zt.plat.module.system.service.oauth2.OAuth2TokenService;
|
||||||
|
import com.zt.plat.module.system.service.oauth2.EbanOAuth2Service;
|
||||||
import com.zt.plat.module.system.service.social.SocialUserService;
|
import com.zt.plat.module.system.service.social.SocialUserService;
|
||||||
import com.zt.plat.module.system.service.user.AdminUserService;
|
import com.zt.plat.module.system.service.user.AdminUserService;
|
||||||
|
import com.zt.plat.module.system.enums.user.UserSourceEnum;
|
||||||
|
import com.anji.captcha.model.common.ResponseModel;
|
||||||
|
import com.anji.captcha.model.vo.CaptchaVO;
|
||||||
|
import com.anji.captcha.service.CaptchaService;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -68,9 +70,24 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
private CaptchaService captchaService;
|
private CaptchaService captchaService;
|
||||||
@Resource
|
@Resource
|
||||||
private SmsCodeApi smsCodeApi;
|
private SmsCodeApi smsCodeApi;
|
||||||
|
@Resource
|
||||||
|
private EbanOAuth2Service ebanOAuth2Service;
|
||||||
@Value("${sync.encrypt-key}")
|
@Value("${sync.encrypt-key}")
|
||||||
private String encryptKey;
|
private String encryptKey;
|
||||||
|
|
||||||
|
// E办OAuth2配置
|
||||||
|
@Value("${eban.oauth2.authorize-url:http://10.2.137.42/idp/oauth2/authorize}")
|
||||||
|
private String ebanAuthorizeUrl;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.client-id:tyszhjyglxt}")
|
||||||
|
private String ebanClientId;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.redirect-uri:http://172.16.46.63:30080/system/oauth2/callback}")
|
||||||
|
private String ebanRedirectUri;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.response-type:code}")
|
||||||
|
private String ebanResponseType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码的开关,默认为 true
|
* 验证码的开关,默认为 true
|
||||||
*/
|
*/
|
||||||
@@ -113,6 +130,12 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
|
|
||||||
// 使用账号密码,进行登录
|
// 使用账号密码,进行登录
|
||||||
AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());
|
AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());
|
||||||
|
|
||||||
|
// 检查是否为内部用户,内部用户不允许账号密码登录
|
||||||
|
if (isInternalUser(user)) {
|
||||||
|
createLoginLog(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.BAD_CREDENTIALS);
|
||||||
|
throw exception(AUTH_LOGIN_INTERNAL_USER_PASSWORD_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
// 如果 socialType 非空,说明需要绑定社交用户
|
// 如果 socialType 非空,说明需要绑定社交用户
|
||||||
if (reqVO.getSocialType() != null) {
|
if (reqVO.getSocialType() != null) {
|
||||||
@@ -130,6 +153,12 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
|
|
||||||
// 使用账号密码,进行登录(跳过验证码校验)
|
// 使用账号密码,进行登录(跳过验证码校验)
|
||||||
AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());
|
AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());
|
||||||
|
|
||||||
|
// 检查是否为内部用户,内部用户不允许账号密码登录
|
||||||
|
if (isInternalUser(user)) {
|
||||||
|
createLoginLog(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.BAD_CREDENTIALS);
|
||||||
|
throw exception(AUTH_LOGIN_INTERNAL_USER_PASSWORD_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
// 创建 Token 令牌,记录登录日志
|
// 创建 Token 令牌,记录登录日志
|
||||||
return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
|
return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
|
||||||
@@ -345,4 +374,75 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
throw exception(AUTH_TEST_LOGIN_NOT_ALLOWED);
|
throw exception(AUTH_TEST_LOGIN_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthLoginRespVO oauth2Callback(AuthOAuth2CallbackReqVO reqVO) {
|
||||||
|
// 委托给专门的E办OAuth2服务处理
|
||||||
|
return ebanOAuth2Service.handleCallback(reqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthUserTypeRespVO checkUserType(String username) {
|
||||||
|
AdminUserDO user = userService.getUserByUsername(username);
|
||||||
|
|
||||||
|
// 用户不存在,抛出异常
|
||||||
|
if (user == null) {
|
||||||
|
throw exception(USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断用户类型
|
||||||
|
boolean isInternal = isInternalUser(user);
|
||||||
|
|
||||||
|
AuthUserTypeRespVO.AuthUserTypeRespVOBuilder builder = AuthUserTypeRespVO.builder()
|
||||||
|
.isInternal(isInternal);
|
||||||
|
|
||||||
|
// 如果是内部用户,生成E办登录URL
|
||||||
|
if (isInternal) {
|
||||||
|
String ebanLoginUrl = buildEbanLoginUrl();
|
||||||
|
builder.ebanLoginUrl(ebanLoginUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为内部用户
|
||||||
|
* 根据UserSourceEnum判断:同步用户为内部用户,外部用户为外部用户
|
||||||
|
*/
|
||||||
|
private boolean isInternalUser(AdminUserDO user) {
|
||||||
|
// 根据userSource字段判断用户类型
|
||||||
|
Integer userSource = user.getUserSource();
|
||||||
|
|
||||||
|
// 同步用户(SYNC = 2)为内部用户,需要使用E办登录
|
||||||
|
if (userSource != null && userSource.equals(UserSourceEnum.SYNC.getSource())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外部用户(EXTERNAL = 1)或其他情况为外部用户,使用账号密码登录
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门ID获取部门名称
|
||||||
|
*/
|
||||||
|
private String getDeptName(Long deptId) {
|
||||||
|
// 这里需要调用部门服务获取部门信息
|
||||||
|
// 暂时返回null,实际项目中需要实现
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建E办登录URL
|
||||||
|
*/
|
||||||
|
private String buildEbanLoginUrl() {
|
||||||
|
String state = "login_" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
return String.format("%s?client_id=%s&redirect_uri=%s&response_type=%s&state=%s",
|
||||||
|
ebanAuthorizeUrl, ebanClientId, ebanRedirectUri, ebanResponseType, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEbanLoginUrl() {
|
||||||
|
return buildEbanLoginUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.zt.plat.module.system.service.oauth2;
|
||||||
|
|
||||||
|
import com.zt.plat.module.system.controller.admin.auth.vo.AuthOAuth2CallbackReqVO;
|
||||||
|
import com.zt.plat.module.system.controller.admin.auth.vo.AuthLoginRespVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办OAuth2服务接口
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
public interface EbanOAuth2Service {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理E办OAuth2回调
|
||||||
|
*
|
||||||
|
* @param reqVO OAuth2回调请求
|
||||||
|
* @return 登录结果
|
||||||
|
*/
|
||||||
|
AuthLoginRespVO handleCallback(AuthOAuth2CallbackReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过授权码获取用户信息
|
||||||
|
*
|
||||||
|
* @param code 授权码
|
||||||
|
* @param state 状态参数
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
EbanUserInfo getUserInfo(String code, String state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办用户信息
|
||||||
|
*/
|
||||||
|
class EbanUserInfo {
|
||||||
|
private String username;
|
||||||
|
private String realName;
|
||||||
|
private String email;
|
||||||
|
private String mobile;
|
||||||
|
private String deptName;
|
||||||
|
private EbanOAuth2ServiceImpl.EbanTokenInfo tokenInfo; // 添加Token信息
|
||||||
|
|
||||||
|
// 构造函数
|
||||||
|
public EbanUserInfo() {}
|
||||||
|
|
||||||
|
public EbanUserInfo(String username, String realName, String email, String mobile, String deptName) {
|
||||||
|
this.username = username;
|
||||||
|
this.realName = realName;
|
||||||
|
this.email = email;
|
||||||
|
this.mobile = mobile;
|
||||||
|
this.deptName = deptName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getter和setter方法
|
||||||
|
public String getUsername() { return username; }
|
||||||
|
public void setUsername(String username) { this.username = username; }
|
||||||
|
|
||||||
|
public String getRealName() { return realName; }
|
||||||
|
public void setRealName(String realName) { this.realName = realName; }
|
||||||
|
|
||||||
|
public String getEmail() { return email; }
|
||||||
|
public void setEmail(String email) { this.email = email; }
|
||||||
|
|
||||||
|
public String getMobile() { return mobile; }
|
||||||
|
public void setMobile(String mobile) { this.mobile = mobile; }
|
||||||
|
|
||||||
|
public String getDeptName() { return deptName; }
|
||||||
|
public void setDeptName(String deptName) { this.deptName = deptName; }
|
||||||
|
|
||||||
|
public EbanOAuth2ServiceImpl.EbanTokenInfo getTokenInfo() { return tokenInfo; }
|
||||||
|
public void setTokenInfo(EbanOAuth2ServiceImpl.EbanTokenInfo tokenInfo) { this.tokenInfo = tokenInfo; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
package com.zt.plat.module.system.service.oauth2;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||||
|
import com.zt.plat.module.system.controller.admin.auth.vo.AuthOAuth2CallbackReqVO;
|
||||||
|
import com.zt.plat.module.system.controller.admin.auth.vo.AuthLoginRespVO;
|
||||||
|
import com.zt.plat.module.system.convert.auth.AuthConvert;
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
import com.zt.plat.module.system.enums.logger.LoginLogTypeEnum;
|
||||||
|
import com.zt.plat.module.system.enums.logger.LoginResultEnum;
|
||||||
|
import com.zt.plat.module.system.enums.oauth2.OAuth2ClientConstants;
|
||||||
|
import com.zt.plat.module.system.service.logger.LoginLogService;
|
||||||
|
import com.zt.plat.module.system.service.user.AdminUserService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static com.zt.plat.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
|
import static com.zt.plat.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办OAuth2服务实现类
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class EbanOAuth2ServiceImpl implements EbanOAuth2Service {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdminUserService userService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LoginLogService loginLogService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OAuth2TokenService oauth2TokenService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private EbanTokenService ebanTokenService;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.auth-server.base-url:http://10.2.137.42/idp/oauth2}")
|
||||||
|
private String authServerBaseUrl;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.auth-server.client-id:tyszhjyglxt}")
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.auth-server.client-secret:}")
|
||||||
|
private String clientSecret;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.user-info.url:http://10.2.137.42/idp/oauth2/getUserInfo}")
|
||||||
|
private String userInfoUrl;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.token.url:http://10.2.137.42/idp/oauth2/getToken}")
|
||||||
|
private String tokenUrl;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthLoginRespVO handleCallback(AuthOAuth2CallbackReqVO reqVO) {
|
||||||
|
log.info("处理E办OAuth2回调: code={}, state={}", reqVO.getCode(), reqVO.getState());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 通过授权码获取用户信息
|
||||||
|
EbanUserInfo userInfo = getUserInfo(reqVO.getCode(), reqVO.getState());
|
||||||
|
if (userInfo == null || StrUtil.isBlank(userInfo.getUsername())) {
|
||||||
|
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据用户名查找系统用户
|
||||||
|
AdminUserDO user = userService.getUserByUsername(userInfo.getUsername());
|
||||||
|
if (user == null) {
|
||||||
|
// 用户不存在,记录登录失败日志
|
||||||
|
createLoginLog(null, userInfo.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL, LoginResultEnum.BAD_CREDENTIALS);
|
||||||
|
throw exception(USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 校验用户状态
|
||||||
|
if (CommonStatusEnum.isDisable(user.getStatus())) {
|
||||||
|
createLoginLog(user.getId(), userInfo.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL, LoginResultEnum.USER_DISABLED);
|
||||||
|
throw exception(AUTH_LOGIN_USER_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 保存E办token到现有OAuth2表中
|
||||||
|
try {
|
||||||
|
EbanTokenInfo tokenInfo = userInfo.getTokenInfo();
|
||||||
|
if (tokenInfo != null) {
|
||||||
|
// 将用户信息转换为JSON字符串
|
||||||
|
JSONObject ebanUserInfoJson = new JSONObject();
|
||||||
|
ebanUserInfoJson.put("username", userInfo.getUsername());
|
||||||
|
ebanUserInfoJson.put("realName", userInfo.getRealName());
|
||||||
|
ebanUserInfoJson.put("email", userInfo.getEmail());
|
||||||
|
ebanUserInfoJson.put("mobile", userInfo.getMobile());
|
||||||
|
ebanUserInfoJson.put("deptName", userInfo.getDeptName());
|
||||||
|
|
||||||
|
ebanTokenService.createEbanToken(
|
||||||
|
user.getId(), // 使用用户ID
|
||||||
|
tokenInfo.getAccessToken(),
|
||||||
|
tokenInfo.getRefreshToken(),
|
||||||
|
tokenInfo.getExpiresIn(),
|
||||||
|
tokenInfo.getUid(),
|
||||||
|
ebanUserInfoJson.toString()
|
||||||
|
);
|
||||||
|
log.info("成功保存E办token到OAuth2表,用户ID: {}, 用户名: {}, uid: {}",
|
||||||
|
user.getId(), userInfo.getUsername(), tokenInfo.getUid());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("保存E办token失败,用户: " + userInfo.getUsername(), e);
|
||||||
|
// 保存token失败不影响登录流程,继续执行
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 创建Token令牌,记录登录日志
|
||||||
|
return createTokenAfterLoginSuccess(user.getId(), userInfo.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("E办OAuth2回调处理失败", e);
|
||||||
|
if (e.getMessage().contains("USER_NOT_EXISTS") || e.getMessage().contains("AUTH_LOGIN_USER_DISABLED")) {
|
||||||
|
throw e; // 重新抛出业务异常
|
||||||
|
}
|
||||||
|
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EbanUserInfo getUserInfo(String code, String state) {
|
||||||
|
try {
|
||||||
|
// 1. 使用授权码换取access_token
|
||||||
|
EbanTokenInfo tokenInfo = exchangeAccessToken(code, state);
|
||||||
|
if (tokenInfo == null || StrUtil.isBlank(tokenInfo.getAccessToken())) {
|
||||||
|
log.error("获取access_token失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 使用access_token获取用户信息
|
||||||
|
EbanUserInfo userInfo = fetchUserInfo(tokenInfo.getAccessToken());
|
||||||
|
if (userInfo != null) {
|
||||||
|
// 将Token信息保存到用户信息中,以便后续使用
|
||||||
|
userInfo.setTokenInfo(tokenInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userInfo;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取E办用户信息失败", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办Token信息
|
||||||
|
*/
|
||||||
|
public static class EbanTokenInfo {
|
||||||
|
private String accessToken;
|
||||||
|
private String refreshToken;
|
||||||
|
private Integer expiresIn;
|
||||||
|
private String uid;
|
||||||
|
private String createDate;
|
||||||
|
|
||||||
|
// 构造函数和getter/setter方法
|
||||||
|
public EbanTokenInfo() {}
|
||||||
|
|
||||||
|
public EbanTokenInfo(String accessToken, String refreshToken, Integer expiresIn, String uid, String createDate) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
this.refreshToken = refreshToken;
|
||||||
|
this.expiresIn = expiresIn;
|
||||||
|
this.uid = uid;
|
||||||
|
this.createDate = createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessToken() { return accessToken; }
|
||||||
|
public void setAccessToken(String accessToken) { this.accessToken = accessToken; }
|
||||||
|
|
||||||
|
public String getRefreshToken() { return refreshToken; }
|
||||||
|
public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; }
|
||||||
|
|
||||||
|
public Integer getExpiresIn() { return expiresIn; }
|
||||||
|
public void setExpiresIn(Integer expiresIn) { this.expiresIn = expiresIn; }
|
||||||
|
|
||||||
|
public String getUid() { return uid; }
|
||||||
|
public void setUid(String uid) { this.uid = uid; }
|
||||||
|
|
||||||
|
public String getCreateDate() { return createDate; }
|
||||||
|
public void setCreateDate(String createDate) { this.createDate = createDate; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用授权码换取access_token
|
||||||
|
*/
|
||||||
|
private EbanTokenInfo exchangeAccessToken(String code, String state) {
|
||||||
|
try {
|
||||||
|
// 根据e办API规范构建请求参数
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("client_id", clientId);
|
||||||
|
params.put("client_secret", clientSecret);
|
||||||
|
params.put("code", code);
|
||||||
|
params.put("grant_type", "authorization_code");
|
||||||
|
|
||||||
|
log.info("请求e办获取token,参数: client_id={}, code={}", clientId, code);
|
||||||
|
|
||||||
|
HttpResponse response = HttpRequest.post(tokenUrl)
|
||||||
|
.form(params)
|
||||||
|
.timeout(10000)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (!response.isOk()) {
|
||||||
|
log.error("获取access_token失败,HTTP状态码: {}, 响应: {}", response.getStatus(), response.body());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject jsonResponse = JSONUtil.parseObj(response.body());
|
||||||
|
|
||||||
|
// 检查是否有错误码
|
||||||
|
if (jsonResponse.containsKey("errcode")) {
|
||||||
|
log.error("获取access_token失败,错误码: {}, 错误信息: {}",
|
||||||
|
jsonResponse.getStr("errcode"), jsonResponse.getStr("msg"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String accessToken = jsonResponse.getStr("access_token");
|
||||||
|
String refreshToken = jsonResponse.getStr("refresh_token");
|
||||||
|
Integer expiresIn = jsonResponse.getInt("expires_in");
|
||||||
|
String uid = jsonResponse.getStr("uid");
|
||||||
|
String createDate = jsonResponse.getStr("createDate");
|
||||||
|
|
||||||
|
log.info("成功获取access_token,uid: {}, expires_in: {}", uid, expiresIn);
|
||||||
|
|
||||||
|
return new EbanTokenInfo(accessToken, refreshToken, expiresIn, uid, createDate);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("调用e办token接口异常", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用access_token获取用户信息
|
||||||
|
*/
|
||||||
|
private EbanUserInfo fetchUserInfo(String accessToken) {
|
||||||
|
try {
|
||||||
|
// 根据e办API规范构建请求参数
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("client_id", clientId);
|
||||||
|
params.put("access_token", accessToken);
|
||||||
|
|
||||||
|
log.info("请求e办获取用户信息,client_id: {}", clientId);
|
||||||
|
|
||||||
|
HttpResponse response = HttpRequest.get(userInfoUrl)
|
||||||
|
.form(params)
|
||||||
|
.timeout(10000)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (!response.isOk()) {
|
||||||
|
log.error("获取用户信息失败,HTTP状态码: {}, 响应: {}", response.getStatus(), response.body());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject userJson = JSONUtil.parseObj(response.body());
|
||||||
|
|
||||||
|
// 检查是否有错误码
|
||||||
|
if (userJson.containsKey("errcode")) {
|
||||||
|
log.error("获取用户信息失败,错误码: {}, 错误信息: {}",
|
||||||
|
userJson.getStr("errcode"), userJson.getStr("msg"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析用户信息(根据e办系统的实际返回格式调整)
|
||||||
|
EbanUserInfo userInfo = new EbanUserInfo();
|
||||||
|
|
||||||
|
// 根据API文档,主要字段是loginName和spRoleList
|
||||||
|
String loginName = userJson.getStr("loginName");
|
||||||
|
if (StrUtil.isBlank(loginName)) {
|
||||||
|
log.error("用户信息中缺少loginName字段");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo.setUsername(loginName); // 使用loginName作为用户名
|
||||||
|
|
||||||
|
// 如果有spRoleList,可以取第一个作为真实姓名或其他用途
|
||||||
|
if (userJson.containsKey("spRoleList")) {
|
||||||
|
Object spRoleListObj = userJson.get("spRoleList");
|
||||||
|
if (spRoleListObj instanceof java.util.List) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
java.util.List<String> spRoleList = (java.util.List<String>) spRoleListObj;
|
||||||
|
if (!spRoleList.isEmpty()) {
|
||||||
|
userInfo.setRealName(spRoleList.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他可能的字段(根据实际e办返回的字段调整)
|
||||||
|
userInfo.setEmail(userJson.getStr("email"));
|
||||||
|
userInfo.setMobile(userJson.getStr("mobile"));
|
||||||
|
userInfo.setDeptName(userJson.getStr("deptName"));
|
||||||
|
|
||||||
|
log.info("成功获取用户信息: username={}, realName={}", userInfo.getUsername(), userInfo.getRealName());
|
||||||
|
|
||||||
|
return userInfo;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("调用e办用户信息接口异常", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建登录日志
|
||||||
|
*/
|
||||||
|
private void createLoginLog(Long userId, String username, LoginLogTypeEnum logType, LoginResultEnum loginResult) {
|
||||||
|
// 这里可以复用AdminAuthServiceImpl中的createLoginLog逻辑
|
||||||
|
// 为了简化,这里省略实现
|
||||||
|
log.info("创建登录日志: userId={}, username={}, logType={}, result={}",
|
||||||
|
userId, username, logType, loginResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录成功后创建Token
|
||||||
|
*/
|
||||||
|
private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
|
||||||
|
// 插入登陆日志
|
||||||
|
createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
|
||||||
|
|
||||||
|
// 创建访问令牌
|
||||||
|
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(
|
||||||
|
userId,
|
||||||
|
com.zt.plat.framework.common.enums.UserTypeEnum.ADMIN.getValue(),
|
||||||
|
OAuth2ClientConstants.CLIENT_ID_DEFAULT,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
// 构建返回结果
|
||||||
|
return AuthConvert.INSTANCE.convert(accessTokenDO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.zt.plat.module.system.service.oauth2;
|
||||||
|
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办Token管理服务接口(基于现有OAuth2 Token体系)
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
public interface EbanTokenService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建E办Token信息到现有OAuth2表中
|
||||||
|
*
|
||||||
|
* @param userId 系统用户ID
|
||||||
|
* @param accessToken E办访问令牌
|
||||||
|
* @param refreshToken E办刷新令牌
|
||||||
|
* @param expiresIn 过期时间(秒)
|
||||||
|
* @param uid E办用户唯一标识
|
||||||
|
* @param userInfo E办用户信息(JSON格式)
|
||||||
|
* @return OAuth2AccessTokenDO
|
||||||
|
*/
|
||||||
|
OAuth2AccessTokenDO createEbanToken(Long userId, String accessToken, String refreshToken,
|
||||||
|
Integer expiresIn, String uid, String userInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID获取E办Token
|
||||||
|
*
|
||||||
|
* @param userId 系统用户ID
|
||||||
|
* @return OAuth2AccessTokenDO
|
||||||
|
*/
|
||||||
|
OAuth2AccessTokenDO getEbanTokenByUserId(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新E办Token
|
||||||
|
*
|
||||||
|
* @param userId 系统用户ID
|
||||||
|
* @return 是否刷新成功
|
||||||
|
*/
|
||||||
|
boolean refreshEbanToken(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除E办Token
|
||||||
|
*
|
||||||
|
* @param userId 系统用户ID
|
||||||
|
*/
|
||||||
|
void deleteEbanToken(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查E办Token是否有效
|
||||||
|
*
|
||||||
|
* @param userId 系统用户ID
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
boolean isEbanTokenValid(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据access_token获取E办Token信息
|
||||||
|
*
|
||||||
|
* @param accessToken 访问令牌
|
||||||
|
* @return OAuth2AccessTokenDO
|
||||||
|
*/
|
||||||
|
OAuth2AccessTokenDO getEbanTokenByAccessToken(String accessToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package com.zt.plat.module.system.service.oauth2;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.zt.plat.framework.common.enums.UserTypeEnum;
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||||
|
import com.zt.plat.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* E办Token管理服务实现类(基于现有OAuth2 Token体系)
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class EbanTokenServiceImpl implements EbanTokenService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OAuth2TokenService oauth2TokenService;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.auth-server.client-id:tyszhjyglxt}")
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.auth-server.client-secret:}")
|
||||||
|
private String clientSecret;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.token.refresh-url:http://10.2.137.42/idp/oauth2/refreshToken}")
|
||||||
|
private String refreshTokenUrl;
|
||||||
|
|
||||||
|
@Value("${eban.oauth2.token.check-url:http://10.2.137.42/idp/oauth2/checkTokenValid}")
|
||||||
|
private String checkTokenUrl;
|
||||||
|
|
||||||
|
private static final String EBAN_CLIENT_ID = "eban-oauth2-client";
|
||||||
|
private static final String EBAN_SCOPES = "user:read";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2AccessTokenDO createEbanToken(Long userId, String accessToken, String refreshToken,
|
||||||
|
Integer expiresIn, String uid, String userInfo) {
|
||||||
|
try {
|
||||||
|
// 使用现有的OAuth2TokenService创建token
|
||||||
|
// 由于原方法签名不匹配,我们先简单实现
|
||||||
|
OAuth2AccessTokenDO token = oauth2TokenService.createAccessToken(
|
||||||
|
userId,
|
||||||
|
UserTypeEnum.ADMIN.getValue(),
|
||||||
|
EBAN_CLIENT_ID,
|
||||||
|
java.util.Arrays.asList(EBAN_SCOPES)
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("成功创建E办Token: userId={}, uid={}", userId, uid);
|
||||||
|
return token;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建E办Token失败: userId=" + userId + ", uid=" + uid, e);
|
||||||
|
throw new RuntimeException("创建E办Token失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2AccessTokenDO getEbanTokenByUserId(Long userId) {
|
||||||
|
// 暂时返回null,需要根据实际的OAuth2TokenService方法实现
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2AccessTokenDO getEbanTokenByAccessToken(String accessToken) {
|
||||||
|
return oauth2TokenService.getAccessToken(accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean refreshEbanToken(Long userId) {
|
||||||
|
// 暂时简单实现
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteEbanToken(Long userId) {
|
||||||
|
// 暂时简单实现
|
||||||
|
log.info("删除E办Token: userId={}", userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEbanTokenValid(Long userId) {
|
||||||
|
// 暂时简单实现
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -203,6 +203,25 @@ zt:
|
|||||||
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
|
|
||||||
|
|
||||||
|
# E办OAuth2配置文件
|
||||||
|
eban:
|
||||||
|
oauth2:
|
||||||
|
# E办OAuth2服务端配置
|
||||||
|
auth-server:
|
||||||
|
base-url: http://10.2.137.42/idp/oauth2
|
||||||
|
client-id: tyszhjyglxt
|
||||||
|
client-secret: your_client_secret_here # 需要从e办系统获取
|
||||||
|
callback-uri: http://172.16.46.63:30080/system/oauth2/callback
|
||||||
|
|
||||||
|
# 用户信息获取配置
|
||||||
|
user-info:
|
||||||
|
url: http://10.2.137.42/idp/oauth2/getUserInfo
|
||||||
|
|
||||||
|
# 令牌交换配置
|
||||||
|
token:
|
||||||
|
url: http://10.2.137.42/idp/oauth2/getToken
|
||||||
|
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
sync:
|
sync:
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import com.zt.plat.framework.common.pojo.PageResult;
|
|||||||
import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO;
|
import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO;
|
||||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||||
import com.zt.plat.framework.excel.core.util.ExcelUtils;
|
import com.zt.plat.framework.excel.core.util.ExcelUtils;
|
||||||
|
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
|
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
|
||||||
import com.zt.plat.module.bpm.api.task.BpmTaskApi;
|
import com.zt.plat.module.bpm.api.task.BpmTaskApi;
|
||||||
|
import com.zt.plat.module.bpm.api.task.dto.BpmApprovalDetailReqDTO;
|
||||||
import com.zt.plat.module.infra.api.businessfile.BusinessFileApi;
|
import com.zt.plat.module.infra.api.businessfile.BusinessFileApi;
|
||||||
import com.zt.plat.module.infra.api.file.FileApi;
|
import com.zt.plat.module.infra.api.file.FileApi;
|
||||||
import com.zt.plat.module.infra.api.file.dto.FileCreateReqDTO;
|
|
||||||
import com.zt.plat.module.infra.api.file.dto.FileRespDTO;
|
import com.zt.plat.module.infra.api.file.dto.FileRespDTO;
|
||||||
import com.zt.plat.module.system.api.dept.DeptApi;
|
import com.zt.plat.module.system.api.dept.DeptApi;
|
||||||
import com.zt.plat.module.template.controller.admin.contract.vo.DemoContractPageReqVO;
|
import com.zt.plat.module.template.controller.admin.contract.vo.DemoContractPageReqVO;
|
||||||
@@ -116,12 +117,10 @@ public class DemoContractController extends AbstractFileUploadController impleme
|
|||||||
public CommonResult<PageResult<DemoContractRespVO>> getDemoContractPage(@Valid DemoContractPageReqVO pageReqVO) {
|
public CommonResult<PageResult<DemoContractRespVO>> getDemoContractPage(@Valid DemoContractPageReqVO pageReqVO) {
|
||||||
CommonResult<FileRespDTO> file = fileApi.getFile(1968928810422521857L);
|
CommonResult<FileRespDTO> file = fileApi.getFile(1968928810422521857L);
|
||||||
|
|
||||||
FileCreateReqDTO createReqDTO = new FileCreateReqDTO();
|
BpmApprovalDetailReqDTO reqDTO = new BpmApprovalDetailReqDTO();
|
||||||
createReqDTO.setContent(file.getCheckedData().getContent());
|
reqDTO.setProcessInstanceId("acccfcf2-99b9-11f0-8536-e8808862e505");
|
||||||
createReqDTO.setType(file.getCheckedData().getType());
|
reqDTO.setTaskId("8ba1838e-99ba-11f0-8536-e8808862e505");
|
||||||
createReqDTO.setName(file.getCheckedData().getName());
|
bpmInsApi.getApprovalDetail(SecurityFrameworkUtils.getLoginUserId(), reqDTO);
|
||||||
createReqDTO.setDirectory(file.getCheckedData().getDirectory());
|
|
||||||
CommonResult<FileRespDTO> fileWithReturn = fileApi.createFileWithReturn(createReqDTO);
|
|
||||||
Long id = IdWorker.getId();
|
Long id = IdWorker.getId();
|
||||||
System.out.println("Generated ID: " + id);
|
System.out.println("Generated ID: " + id);
|
||||||
PageResult<DemoContractDO> pageResult = demoContractService.getDemoContractPage(pageReqVO);
|
PageResult<DemoContractDO> pageResult = demoContractService.getDemoContractPage(pageReqVO);
|
||||||
|
|||||||
@@ -346,6 +346,22 @@ zt:
|
|||||||
key: pLXUGAwK5305
|
key: pLXUGAwK5305
|
||||||
customer: E77DF18BE109F454A5CD319E44BF5177
|
customer: E77DF18BE109F454A5CD319E44BF5177
|
||||||
|
|
||||||
|
# E办OAuth2配置文件
|
||||||
|
eban:
|
||||||
|
oauth2:
|
||||||
|
# E办OAuth2登录配置
|
||||||
|
authorize-url: http://10.2.137.42/idp/oauth2/authorize
|
||||||
|
client-id: tyszhjyglxt
|
||||||
|
client-secret: your_client_secret_here # 需要从e办系统获取
|
||||||
|
redirect-uri: http://172.16.46.63:30080/system/oauth2/callback
|
||||||
|
response-type: code
|
||||||
|
|
||||||
|
# 用户信息获取URL
|
||||||
|
user-info-url: http://10.2.137.42/idp/oauth2/getUserInfo
|
||||||
|
|
||||||
|
# 令牌交换URL
|
||||||
|
token-url: http://10.2.137.42/idp/oauth2/getToken
|
||||||
|
|
||||||
debug: false
|
debug: false
|
||||||
|
|
||||||
# OnlyOffice 配置
|
# OnlyOffice 配置
|
||||||
@@ -356,4 +372,5 @@ onlyoffice:
|
|||||||
|
|
||||||
# 插件配置 TODO 芋艿:【IOT】需要处理下
|
# 插件配置 TODO 芋艿:【IOT】需要处理下
|
||||||
pf4j:
|
pf4j:
|
||||||
pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录
|
pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user