Merge remote-tracking branch 'origin/master' into feature/REQ-2649

This commit is contained in:
zhangran 2024-09-03 18:43:27 +08:00
commit ee636375fa
39 changed files with 2506 additions and 1 deletions

View File

@ -6,6 +6,7 @@ import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandlerRepository;
import cn.axzo.framework.rocketmq.EventProducer;
import cn.axzo.framework.rocketmq.RocketMQEventProducer;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
@ -34,9 +35,10 @@ public class RocketMQEventConfiguration {
private String topic;
@Bean
public RocketMQTemplate ser(){
public RocketMQTemplate ser() {
return new RocketMQTemplate();
}
@Bean
EventProducer eventProducer(RocketMQTemplate rocketMQTemplate) {
return new RocketMQEventProducer(rocketMQTemplate,
@ -87,4 +89,157 @@ public class RocketMQEventConfiguration {
log.warn("MQ, handle warning {}", logText, ex);
});
}
/**
* 添加人员
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_organizational_${spring.profiles.active}",
consumerGroup = "GID_node_user_create_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class EditOrganizationalListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("CreateNodeUser onMessage,message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 班组加入项目
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_labour_${spring.profiles.active}",
consumerGroup = "GID_team_join_workspace_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class TeamJoinWorkspaceListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("teamJoinWorkspaceListener onMessage nanopart,message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 工人加入项目
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_labour_worker_join_workspace_${spring.profiles.active}",
consumerGroup = "GID_labour_worker_join_workspace__${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class WorkerJoinWorkspaceListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("workerJoinWorkspaceListener onMessage nanopart,message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 项目创建工程
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_workspace_project_change_${spring.profiles.active}",
consumerGroup = "GID_create_engineering_project_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class CreateEngineeringProjectListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("CreateEngineeringProjectListener onMessage nanopart,message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 创建施工区域
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_construction_area_${spring.profiles.active}",
consumerGroup = "GID_construction_area_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}")
public static class ConstructionAreaListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("ConstructionAreaListener onMessage nanopart, message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 上传交底
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_disclosure_${spring.profiles.active}",
consumerGroup = "GID_disclosure_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class DisclosureListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("DisclosureListener onMessage nanopart, message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
/**
* 创建项目
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = "topic_upsert_workspace_${spring.profiles.active}",
consumerGroup = "GID_topic_upsert_workspace_${spring.application.name}_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY,
nameServer = "${rocketmq.name-server}"
)
public static class UpsertWorkspaceListener extends BaseListener implements RocketMQListener<MessageExt> {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onMessage(MessageExt message) {
log.info("UpsertWorkspaceListener onMessage nanopart, message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}
}

View File

@ -0,0 +1,28 @@
package cn.axzo.op.api;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.op.api.request.GuideProcedureTemplateCreateReq;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:44
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface GuideProcedureTemplateApi {
/**
* 创建引导步骤
*
* @param req {@link GuideProcedureTemplateCreateReq}
* @return id
*/
@PostMapping("/api/guideProcedureTemplate/create")
ApiResult<Long> create(@RequestBody @Valid GuideProcedureTemplateCreateReq req);
}

View File

@ -0,0 +1,51 @@
package cn.axzo.op.api;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.op.api.request.GuideTenantProcedureStatusCreateReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusListReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusUpdateReq;
import cn.axzo.op.api.response.GuideTenantProcedureStatusListResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.util.List;
/**
* 操作步骤状态相关API
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 15:30
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface GuideTenantProcedureStatusApi {
/**
* 创建操作步骤状态
*
* @param req {@link GuideTenantProcedureStatusCreateReq}
* @return id
*/
@PostMapping("/api/guideTenantProcedureStatus/create")
ApiResult<Long> create(@RequestBody @Valid GuideTenantProcedureStatusCreateReq req);
/**
* 获取操作步骤状态列表
*
* @param req {@link GuideTenantProcedureStatusListReq}
* @return {@link GuideTenantProcedureStatusListResp}
*/
@PostMapping("/api/guideTenantProcedureStatus/list")
ApiResult<List<GuideTenantProcedureStatusListResp>> list(@RequestBody @Valid GuideTenantProcedureStatusListReq req);
/**
* 更新租户操作步骤状态
*
* @param req {@link GuideTenantProcedureStatusUpdateReq}
* @return void
*/
@PostMapping("/api/guideTenantProcedureStatus/updateStatus")
ApiResult<Void> updateStatus(@RequestBody @Valid GuideTenantProcedureStatusUpdateReq req);
}

View File

@ -0,0 +1,53 @@
package cn.axzo.op.api.enums;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.Getter;
/**
* 新手指引操作分类
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 10:39
*/
@Getter
public enum GuideProcedureCategoryEnum {
CREATE_ENT_STRUCTURE("createEntStructure", "搭建企业组织架构", GuideProcedureTypeEnum.ENT, 1),
CREATE_PROJECT_STRUCTURE("createProjectStructure", "搭建项目架构", GuideProcedureTypeEnum.PROJECT, 1),
CONSTRUCTOR_FOUNDATION_CONFIG("constructorFoundationConfig", "施工基础配置", GuideProcedureTypeEnum.PROJECT, 2),
CONSTRUCTOR_RULES_CONFIG("constructorRulesConfig", "施工规则配置", GuideProcedureTypeEnum.PROJECT, 3);
private final String code;
private final String desc;
private final GuideProcedureTypeEnum type;
/**
* 在各自type中的排序
*/
private final Integer sort;
GuideProcedureCategoryEnum(String code, String desc, GuideProcedureTypeEnum type, Integer sort) {
this.code = code;
this.desc = desc;
this.type = type;
this.sort = sort;
}
public static GuideProcedureCategoryEnum getByCode(String code) {
if (CharSequenceUtil.isBlank(code)) {
return null;
}
for (GuideProcedureCategoryEnum value : GuideProcedureCategoryEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@ -0,0 +1,42 @@
package cn.axzo.op.api.enums;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.Getter;
/**
* 新手引导操作状态
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:09
*/
@Getter
public enum GuideProcedureStatus {
FINISHED("FINISHED", "已完成"),
TODO("TODO", "未完成"),
;
private final String code;
private final String desc;
GuideProcedureStatus(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static GuideProcedureStatus getByCode(String code) {
if (CharSequenceUtil.isBlank(code)) {
return null;
}
for (GuideProcedureStatus value : GuideProcedureStatus.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@ -0,0 +1,41 @@
package cn.axzo.op.api.enums;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.Getter;
/**
* 新手指引操作类型
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 10:57
*/
@Getter
public enum GuideProcedureTypeEnum {
ENT("ent", "企业"),
PROJECT("project", "项目");
private final String code;
private final String desc;
GuideProcedureTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static GuideProcedureTypeEnum getByCode(String code) {
if (CharSequenceUtil.isBlank(code)) {
return null;
}
for (GuideProcedureTypeEnum value : GuideProcedureTypeEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@ -0,0 +1,73 @@
package cn.axzo.op.api.request;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:23
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideProcedureTemplateCreateReq {
/**
* 步骤所属分类
*
* @see GuideProcedureCategoryEnum
*/
@NotNull(message = "步骤所属分类不能为空")
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤名称
*/
@NotBlank(message = "步骤名称不能为空")
private String name;
/**
* 步骤描述
*/
private String description;
/**
* 是否必须默认为否
*/
private Boolean isMust = false;
/**
* 权限码
*/
private String[] authCode;
/**
* 跳转页面路由
*/
private String jumpUrl;
/**
* 跳转是否上报默认否
*/
private Boolean jumpReport;
/**
* 步骤顺序, 默认为0
*/
private Integer sort = 0;
/**
* 更新人
*/
private Long updateBy;
}

View File

@ -0,0 +1,56 @@
package cn.axzo.op.api.request;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 创建操作步骤状态请求参数
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 15:33
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideTenantProcedureStatusCreateReq {
/**
* 租户id
*/
@NotNull(message = "workspaceId不能为空")
private Long workspaceId;
/**
* 步骤所属分类
*/
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤id
*/
@NotNull(message = "操作步骤id不能为空")
private Long procedureId;
/**
* 步骤名称
*/
private String procedureName;
/**
* 完成状态默认未完成
*/
private GuideProcedureStatus status;
private Long createBy;
}

View File

@ -0,0 +1,49 @@
package cn.axzo.op.api.request;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 查询租户操作步骤状态列表
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 15:35
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideTenantProcedureStatusListReq {
/**
* 租户id
*/
@NotNull(message = "workspaceId不能为空")
private Long workspaceId;
/**
* 步骤类型
*/
private GuideProcedureTypeEnum type;
/**
* 步骤所属分类
*/
private GuideProcedureCategoryEnum categoryCode;
/**
* 完成状态
*/
private GuideProcedureStatus status;
}

View File

@ -0,0 +1,49 @@
package cn.axzo.op.api.request;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/5 10:08
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideTenantProcedureStatusUpdateReq {
/**
* 租户id
*/
@NotNull(message = "workspaceId不能为空")
private Long workspaceId;
/**
* 步骤id
*/
@NotNull(message = "步骤id不能为空")
private Long procedureId;
/**
* 完成状态
*/
@NotNull(message = "状态不能为空")
private GuideProcedureStatus status;
private Long updateBy;
/**
* 来源1-用户操作2-系统监听MQ处理
* 该字段仅用于区分系统监听MQ处理正常使用可不管该字段
*/
private Integer from;
}

View File

@ -0,0 +1,72 @@
package cn.axzo.op.api.response;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 17:38
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideProcedureTemplateResp {
/**
* 步骤id
*/
private Long id;
/**
* 步骤类型
*/
private GuideProcedureTypeEnum type;
/**
* 步骤所属分类
*/
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤名称
*/
private String name;
/**
* 步骤描述
*/
private String description;
/**
* 是否必须
*/
private Boolean isMust;
/**
* 权限码
*/
private String[] authCode;
/**
* 跳转页面路由
*/
private String jumpUrl;
/**
* 跳转是否上报
*/
private Boolean jumpReport;
/**
* 步骤顺序
*/
private Integer sort;
}

View File

@ -0,0 +1,84 @@
package cn.axzo.op.api.response;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 15:42
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GuideTenantProcedureStatusListResp {
/**
* 租户id
*/
private Long workspaceId;
/**
* 步骤类型
*/
private GuideProcedureTypeEnum type;
/**
* 步骤所属分类
*/
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤id
*/
private Long procedureId;
/**
* 步骤名称
*/
private String procedureName;
/**
* 步骤描述
*/
private String description;
/**
* 是否必须
*/
private Boolean isMust;
/**
* 权限码
*/
private String[] authCode;
/**
* 跳转页面路由
*/
private String jumpUrl;
/**
* 跳转是否上报
*/
private Boolean jumpReport;
/**
* 步骤顺序
*/
private Integer sort;
/**
* 完成状态
*/
private GuideProcedureStatus status;
}

View File

@ -95,5 +95,10 @@
<artifactId>msg-center-api</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.axzo.apollo</groupId>
<artifactId>apollo-workspace-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,27 @@
package cn.axzo.nanopart.server.controller;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.server.service.GuideProcedureTemplateService;
import cn.axzo.op.api.GuideProcedureTemplateApi;
import cn.axzo.op.api.request.GuideProcedureTemplateCreateReq;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
/**
* 新手指引操作步骤接口
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:21
*/
@RestController
@RequiredArgsConstructor
public class GuideProcedureTemplateController implements GuideProcedureTemplateApi {
private final GuideProcedureTemplateService guideProcedureTemplateService;
@Override
public ApiResult<Long> create(GuideProcedureTemplateCreateReq req) {
return ApiResult.ok(guideProcedureTemplateService.create(req));
}
}

View File

@ -0,0 +1,41 @@
package cn.axzo.nanopart.server.controller;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.server.service.GuideTenantProcedureStatusService;
import cn.axzo.op.api.GuideTenantProcedureStatusApi;
import cn.axzo.op.api.request.GuideTenantProcedureStatusCreateReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusListReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusUpdateReq;
import cn.axzo.op.api.response.GuideTenantProcedureStatusListResp;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 15:50
*/
@RestController
@RequiredArgsConstructor
public class GuideTenantProcedureStatusController implements GuideTenantProcedureStatusApi {
private final GuideTenantProcedureStatusService guideTenantProcedureStatusService;
@Override
public ApiResult<Long> create(GuideTenantProcedureStatusCreateReq req) {
return ApiResult.ok(guideTenantProcedureStatusService.create(req));
}
@Override
public ApiResult<List<GuideTenantProcedureStatusListResp>> list(GuideTenantProcedureStatusListReq req) {
return ApiResult.ok(guideTenantProcedureStatusService.list(req));
}
@Override
public ApiResult<Void> updateStatus(GuideTenantProcedureStatusUpdateReq req) {
guideTenantProcedureStatusService.updateStatus(req);
return ApiResult.ok();
}
}

View File

@ -0,0 +1,91 @@
package cn.axzo.nanopart.server.domain;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 9:47
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "guide_procedure_template", autoResultMap = true)
public class GuideProcedureTemplate extends BaseEntity<GuideProcedureTemplate> {
/**
* 步骤所属分类
*/
@TableField("category_code")
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤类型
*/
@TableField("type")
private GuideProcedureTypeEnum type;
/**
* 步骤名称
*/
@TableField("name")
private String name;
/**
* 步骤描述
*/
@TableField("description")
private String description;
/**
* 是否必须
*/
@TableField("is_must")
private Boolean isMust;
/**
* 权限码
*/
@TableField(value = "auth_code", typeHandler = FastjsonTypeHandler.class)
private String[] authCode;
/**
* 跳转页面路由
*/
@TableField("jump_url")
private String jumpUrl;
/**
* 跳转是否上报默认否
*/
@TableField("jump_report")
private Boolean jumpReport;
/**
* 步骤顺序
*/
@TableField("sort")
private Integer sort;
/**
* 创建人
*/
@TableField("create_by")
private Long creatBy;
/**
* 更新人
*/
@TableField("update_by")
private Long updateBy;
}

View File

@ -0,0 +1,75 @@
package cn.axzo.nanopart.server.domain;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* 新手引导步骤租户完成状态
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:04
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "guide_tenant_procedure_status", autoResultMap = true)
public class GuideTenantProcedureStatus extends BaseEntity<GuideTenantProcedureStatus> {
/**
* 租户id
*/
@TableField("workspace_id")
private Long workspaceId;
/**
* 步骤类型
*/
@TableField("type")
private GuideProcedureTypeEnum type;
/**
* 步骤所属分类
*/
@TableField("category_code")
private GuideProcedureCategoryEnum categoryCode;
/**
* 步骤id
*/
@TableField("procedure_id")
private Long procedureId;
/**
* 步骤名称
*/
@TableField("procedure_name")
private String procedureName;
/**
* 完成状态
*/
@TableField("status")
private GuideProcedureStatus status;
/**
* 创建人
*/
@TableField("create_by")
private Long creatBy;
/**
* 更新人
*/
@TableField("update_by")
private Long updateBy;
}

View File

@ -0,0 +1,70 @@
package cn.axzo.nanopart.server.enums;
import cn.axzo.basics.common.util.NumberUtil;
import cn.axzo.nanopart.server.domain.GuideProcedureTemplate;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import lombok.Getter;
/**
* 操作步骤模板枚举
* <p>
* 对应 数据库表 guide_procedure_template为减少整体枚举值的数量
* 只记录需要进行异步状态更新的操作步骤前端上报状态变更的操作步骤不进行枚举
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 16:38
* @see GuideProcedureTemplate
*/
@Getter
public enum GuideProcedureEnum {
ADD_NODE_USR(2L, GuideProcedureTypeEnum.ENT, "添加人员"),
CREATE_PROJECT(3L, GuideProcedureTypeEnum.ENT, "创建项目"),
CREATE_ENGINEERING_ENT(4L, GuideProcedureTypeEnum.ENT, "创建工程"),
CREATE_ENGINEERING_PROJECT(5L, GuideProcedureTypeEnum.PROJECT, "创建工程"),
INVITE_TEAM(6L, GuideProcedureTypeEnum.PROJECT, "邀请参建单位&班组"),
INVITE_PARTICIPANT(7L, GuideProcedureTypeEnum.PROJECT, "邀请从业人员"),
CREATE_CONSTRUCTION_AREA(8L, GuideProcedureTypeEnum.PROJECT, "创建施工区"),
DISCLOSURE(10L, GuideProcedureTypeEnum.PROJECT, "上传交底");
/**
* 对应步骤模板的id
*/
private final Long code;
/**
* 对应步骤模板的type
*/
private final GuideProcedureTypeEnum type;
/**
* 对应步骤模板的name
*/
private final String desc;
GuideProcedureEnum(Long code, GuideProcedureTypeEnum type, String desc) {
this.code = code;
this.type = type;
this.desc = desc;
}
public static GuideProcedureEnum getByCode(Long code) {
if (NumberUtil.isPositiveNumber(code)) {
return null;
}
for (GuideProcedureEnum value : GuideProcedureEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@ -0,0 +1,39 @@
package cn.axzo.nanopart.server.event;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.service.GuideTenantProcedureStatusService;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.request.GuideTenantProcedureStatusUpdateReq;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 16:52
*/
@Slf4j
@Component
public class AbstractTenantProcedureStatusHandler {
@Autowired
private GuideTenantProcedureStatusService guideTenantProcedureService;
/**
* 更新步骤状态
*
* @param workspaceId 租户id
* @param procedure 操作步骤id
*/
protected void updateTenantStatus(Long workspaceId, GuideProcedureEnum procedure) {
GuideTenantProcedureStatusUpdateReq updateReq = new GuideTenantProcedureStatusUpdateReq();
updateReq.setWorkspaceId(workspaceId);
updateReq.setProcedureId(procedure.getCode());
updateReq.setStatus(GuideProcedureStatus.FINISHED);
updateReq.setFrom(2);
guideTenantProcedureService.updateStatus(updateReq);
log.info("系统监听MQ更新操作状态{}", JSONUtil.toJsonStr(updateReq));
}
}

View File

@ -0,0 +1,44 @@
package cn.axzo.nanopart.server.event.apollo;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.axzo.nanopart.server.event.payload.ConstructionAreaPayload;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 15:16
*/
@Slf4j
@Component
public class ConstructionAreaHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("ConstructionAreaHandler onEvent, event: {}", JSONUtil.toJsonStr(event));
// 解析数据
ConstructionAreaPayload constructionAreaPayload = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()), ConstructionAreaPayload.class);
log.info("ConstructionAreaHandler onEvent, payload: {}", JSONUtil.toJsonStr(constructionAreaPayload));
// 业务处理更新对应workspaceId下创建施工区域操作的完成状态
updateTenantStatus(constructionAreaPayload.getWorkspaceId(), GuideProcedureEnum.CREATE_CONSTRUCTION_AREA);
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.CONSTRUCTION_AREA.getModel(), MQEventEnum.CONSTRUCTION_AREA.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,43 @@
package cn.axzo.nanopart.server.event.data_collection;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.axzo.nanopart.server.event.payload.DisclosurePayload;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 16:05
*/
@Slf4j
@Component
public class DisclosureHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("DisclosureHandler onEvent, event: {}", JSONUtil.toJsonStr(event));
// 解析数据
DisclosurePayload disclosurePayload = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()), DisclosurePayload.class);
log.info("DisclosureHandler onEvent, payload: {}", JSONUtil.toJsonStr(disclosurePayload));
// 业务处理更新对应workspaceId下上传交底操作的完成状态
updateTenantStatus(disclosurePayload.getWorkspaceId(), GuideProcedureEnum.DISCLOSURE);
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.DISCLOSURE.getModel(), MQEventEnum.DISCLOSURE.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,60 @@
package cn.axzo.nanopart.server.event.enums;
import cn.axzo.framework.rocketmq.Event;
import lombok.Getter;
@Getter
public enum MQEventEnum {
NODE_CREATE("node", "node-create", "节点创建"),
NODE_UPDATE("node", "node-update", "节点修改"),
NODE_DELETE("node", "node-delete", "节点删除"),
NODE_USER_CREATE("node-user", "node-user-create", "节点用户创建"),
NODE_USER_UPDATE("node-user", "node-user-update", "节点用户修改"),
NODE_USER_DELETE("node-user", "node-user-delete", "节点用户删除"),
NODE_USER_VERIFY("profile", "verify-success", "节点用户实名认证"),
UNIT_CREATE("unit", "unit-create", "单位创建"),
UNIT_UPDATE("unit", "unit-update", "单位修改"),
// updated 事件会将 oldnew发出来
UNIT_UPDATED("unit", "unit-updated", "单位修改"),
UNIT_DELETE("unit", "unit-delete", "单位删除"),
INDUSTRY_DICT_CHANGE("industry-dict", "industry-dict-change", "行业字典变更"),
COOPERATE_SHIP_CREATE_OR_UPDATE("cooperate-ship", "cooperate-ship-create-or-update", "创建或更新协作关系"),
COOPERATE_SHIP_RESIGN("cooperate-ship", "cooperate-ship-resign", "退场"),
PERSON_TAG_BATCH_UPDATED("person-tag", "person-tag-batch-upserted", "批量修改用户标签"),
TEAM_JOIN_WORKSPACE_NOTICE("labour", "team_join_workspace_notice", "班组加入项目通知"),
BUSINESS("BUSINESS", "BUSINESS", "BUSINESS"),
WORKSPACE("WORKSPACE", "WORKSPACE", "WORKSPACE"),
LABOUR("LABOUR", "LABOUR", "LABOUR"),
CONSTRUCTION_AREA("construction_area", "construction_area", "创建施工区域"),
DISCLOSURE("disclosure", "disclosure", "上传交底"),
UPSERT_WORKSPACE("upsert_workspace", "upsert_workspace", "创建租户"),
;
private final String model;
private final String tag;
private final String desc;
private final Event.EventCode eventCode;
MQEventEnum(String model, String tag, String desc) {
this.eventCode = Event.EventCode.builder()
.module(model)
.name(tag)
.build();
this.model = model;
this.tag = tag;
this.desc = desc;
}
}

View File

@ -0,0 +1,106 @@
package cn.axzo.nanopart.server.event.organizational;
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.request.OrganizationalNodeUserSearchReq;
import cn.axzo.maokai.api.vo.response.CooperateShipResp;
import cn.axzo.maokai.api.vo.response.OrganizationalNodeUserVO;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 创建NodeUser事件通知
*
* @author: xudawei@axzo.cn
* @date: 2024/08/06
*/
@Slf4j
@Component
@RefreshScope
public class CreateNodeUserHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Autowired
private CooperateShipQueryApi cooperateShipQueryApi;
@Autowired
private OrganizationalNodeUserApi organizationalNodeUserApi;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("createNodeUser-start mq,eventModule:{},eventName:{}, event:{}", event.getEventCode().getModule(), event.getEventCode().getName(), JSON.toJSONString(event));
//解析数据
OrganizationalNodeUser nodeUser = event.normalizedData(OrganizationalNodeUser.class);
log.info("CreateNodeUserHandler,nodeUser:{}", JSON.toJSONString(nodeUser));
// 获取该人员加入的workspacId即是单位的部门还是项目的部门
CooperateShipQueryReq shipQueryReq = new CooperateShipQueryReq();
shipQueryReq.setOuId(nodeUser.getOrganizationalUnitId());
shipQueryReq.setOrganizationNodeIds(Collections.singletonList(nodeUser.getTopNodeId()));
shipQueryReq.setWorkspaceType(null);
List<CooperateShipResp> cooperateShips = cooperateShipQueryApi.genericQuery(shipQueryReq).getData();
if (CollUtil.isEmpty(cooperateShips)) {
log.info("createNodeUser,cooperateShips is empty, ouId: {}, topNodeId: {}", nodeUser.getOrganizationalUnitId(), nodeUser.getTopNodeId());
return;
}
// 理论上只有一个workspaceId
Map<Long, Integer> workspaceIdTypeMap = cooperateShips.stream().collect(Collectors.toMap(CooperateShipResp::getWorkspaceId, CooperateShipResp::getWorkspaceType, (k1, k2) -> k1));
workspaceIdTypeMap.forEach((key, value) -> {
List<Long> topNodeIds = Lists.newArrayList();
GuideProcedureEnum procedureType = null;
// 单位只有一个对应的topNodeId项目可能对应多个topNodeId
if (Objects.equals(WorkspaceTypeEnum.GENERAL_ENT.value, value)) {
topNodeIds.add(nodeUser.getTopNodeId());
procedureType = GuideProcedureEnum.ADD_NODE_USR;
} else if (Objects.equals(WorkspaceTypeEnum.GENERAL_PROJECT.value, value)) {
// 根据workspaceId获取该项目下所有的topNodeId
CooperateShipQueryReq queryReq = new CooperateShipQueryReq();
queryReq.setWorkspaceId(key);
queryReq.setWorkspaceType(WorkspaceTypeEnum.GENERAL_PROJECT.value);
List<CooperateShipResp> workspaceShips = cooperateShipQueryApi.genericQuery(shipQueryReq).getData();
topNodeIds.addAll(workspaceShips.stream().map(CooperateShipResp::getOrganizationalNodeId).distinct().collect(Collectors.toList()));
procedureType = GuideProcedureEnum.INVITE_PARTICIPANT;
} else {
log.info("createNodeUser,workspaceType is error, workspaceId: {}, workspaceType: {}", key, value);
return;
}
// 查询单位/项目下所有的人员
OrganizationalNodeUserSearchReq searchReq = new OrganizationalNodeUserSearchReq();
searchReq.setTopNodeIdList(topNodeIds);
List<OrganizationalNodeUserVO> nodeUserVOList = organizationalNodeUserApi.list(searchReq).getData();
if (CollUtil.isEmpty(nodeUserVOList) || nodeUserVOList.size() < 2) {
log.info("WorkerJoinWorkspaceHandler,person number less than 2, workspaceId:{}, workspaceType: {}, topNodeIds: {}",
key, value, topNodeIds);
return;
}
updateTenantStatus(key, procedureType);
});
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.NODE_USER_CREATE.getModel(), MQEventEnum.NODE_USER_CREATE.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,160 @@
package cn.axzo.nanopart.server.event.organizational;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class OrganizationalNodeUser {
/**
* id
*/
private Long id;
/**
* identity_id
*/
private Long identityId;
/**
* 身份类型 0-无效类型, 1-工人, 2-班组长, 3-从业人员, 4-政务人员5-运营人员
*/
private Integer identityType;
/**
* 自然人id
*/
private Long personId;
/**
* 主电话
*/
private String phone;
/**
* 名字
*/
private String realName;
/**
* 身份证号
*/
private String idNumber;
/**
* 单位id
*/
private Long organizationalUnitId;
/**
* 组织节点id
*/
private Long organizationalNodeId;
/**
* 岗位id
*/
private Long organizationalJobId;
/**
* 是否是主岗位
* 0:普通岗位1:主岗位
*/
private Integer primaryJob;
/**
* 是否允许进入工地 1.允许 2.不允许
*/
private Integer isAllowed;
/**
* 加入时间
*/
private Date joinAt;
/**
* 是否是部门管理员
*/
private Boolean manager;
/**
* 离开时间
*/
private Date leaveAt;
/**
* 迁移数据临时源id
*/
private Long tempSourceId;
/**
* 顶级节点的nodeId
*/
private Long topNodeId;
/** 数据同步ID **/
private Long syncDataId;
/** 工号 - 需要作为查询条件和排序 不使用扩展字段**/
private String jobNumber;
/**
* workspace id
*/
private Long workspaceId;
/** 扩展字段 **/
private OrgNodeUserExtra extra;
private Date createAt;
private Date updateAt;
private Long isDelete = 0L;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class OrgNodeUserExtra {
/**
* 职位
**/
private String title;
/**
* 直属主管姓名
**/
private String directManager;
/**
* 直属主管identityId
* TODO oms的直属主管还在使用IdentityId
**/
@Deprecated
private Long directManagerId;
/**
* 直属主管 identityType
* TODO oms的直属主管还在使用IdentityId
**/
@Deprecated
private Integer directManagerType;
/**
* 直属主管personId
*/
private Long directManagerPersonId;
/**
* 工作台id
*/
private Long workspaceId;
}
}

View File

@ -0,0 +1,34 @@
package cn.axzo.nanopart.server.event.payload;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 施工区域消息体
*
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 15:18
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ConstructionAreaPayload implements Serializable {
private static final long serialVersionUID = -1L;
private Long id;
private String name;
private Long workspaceId;
private Long projectId;
}

View File

@ -0,0 +1,53 @@
package cn.axzo.nanopart.server.event.payload;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/9 15:21
*/
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DisclosurePayload implements Serializable {
private static final long serialVersionUID = 1L;
private Long workspaceId;
private Long templateId;
/**
*任务项编码
*/
private String taskContentCode;
/**
* 交底编码
*/
private Long code;
/**
* 区域名称
*/
private String name;
/**
* 分类1分项交底2作业交底
*/
private Integer category;
/**
* 类别1技术2安全
*/
private Integer type;
}

View File

@ -0,0 +1,107 @@
package cn.axzo.nanopart.server.event.workspace;
import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi;
import cn.axzo.apollo.workspace.api.workspace.req.GetSimpleWorkspaceReq;
import cn.axzo.apollo.workspace.api.workspace.res.SimpleWorkspaceRes;
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
import cn.axzo.basics.common.util.NumberUtil;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.response.CooperateShipResp;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.axzo.nanopart.server.event.workspace.vo.CreateProjectMsgVO;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* 项目创建工程事件通知
*
* @author: xudawei@axzo.cn
* @date: 2024/08/06
*/
@Slf4j
@Component
@RefreshScope
public class CreateEngineeringProjectHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Autowired
private CooperateShipQueryApi cooperateShipQueryApi;
@Autowired
private WorkspaceApi workspaceApi;
@Override
@Transactional(rollbackFor = Exception.class)
public void onEvent(Event event, EventConsumer.Context context) {
log.info("CreateEngineeringProjectHandler-start mq,eventModule:{},eventName:{}, event:{}", event.getEventCode().getModule(), event.getEventCode().getName(), JSON.toJSONString(event));
//解析数据
CreateProjectMsgVO createProjectMsgVO = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()), CreateProjectMsgVO.class);
log.info("CreateEngineeringProjectHandler,createProjectMsgVO:{}", JSON.toJSONString(createProjectMsgVO));
// 业务处理创建工程更新对应项目和该项目下所有企业的创建工程步骤状态
Long workspaceId = createProjectMsgVO.getWorkspaceId();
if (NumberUtil.isNotPositiveNumber(workspaceId)) {
log.warn("CreateEngineeringProjectHandler, workspaceId error, workspaceId: {}", workspaceId);
return;
}
updateTenantStatus(workspaceId, GuideProcedureEnum.CREATE_ENGINEERING_PROJECT);
// 获取项目下所有企业
CooperateShipQueryReq req = new CooperateShipQueryReq();
req.setWorkspaceId(workspaceId);
req.setWorkspaceType(WorkspaceTypeEnum.GENERAL_PROJECT.getValue());
List<Long> ouIds = cooperateShipQueryApi.genericQuery(req)
.getData().stream()
.map(CooperateShipResp::getOrganizationalUnitId)
.distinct()
.collect(Collectors.toList());
if (CollUtil.isEmpty(ouIds)) {
log.info("CreateEngineeringProjectHandler, ouIds is empty, workspaceId: {}", workspaceId);
return;
}
// 获取企业对应workspaceId
GetSimpleWorkspaceReq workspaceReq = new GetSimpleWorkspaceReq();
workspaceReq.setType(WorkspaceTypeEnum.GENERAL_ENT.value);
workspaceReq.setOuId(ouIds);
List<SimpleWorkspaceRes> ouWorkspaceIds = workspaceApi.getList(workspaceReq).getData();
if (CollUtil.isEmpty(ouWorkspaceIds)) {
log.info("CreateEngineeringProjectHandler, ouWorkspaceIds is empty, ouIds: {}", ouIds);
return;
}
ouWorkspaceIds.forEach(ouWorkspaceId -> updateTenantStatus(ouWorkspaceId.getId(), GuideProcedureEnum.CREATE_ENGINEERING_ENT));
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.WORKSPACE.getModel(), MQEventEnum.WORKSPACE.getTag());
eventConsumer.registerHandler(eventCode, this);
}
public static void main(String[] args) {
String str = "{\"categoryCode\":\"1000000000\",\"projectId\":731,\"projectName\":\"6\",\"saasTenantId\":174,\"singleCodes\":[\"1010000000\"],\"workspaceId\":442}";
if (str.contains("\\\"")) {
str = str.replaceAll("\\\\\"", "\\\"");
}
CreateProjectMsgVO evenJSON = JSONObject.parseObject(str, CreateProjectMsgVO.class);
System.out.println("evenJSON = " + evenJSON);
}
}

View File

@ -0,0 +1,50 @@
package cn.axzo.nanopart.server.event.workspace;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.maokai.api.labour.dto.mq.LabourProjectTeamMqMsg;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* 班组加入项目事件通知
*
* @author: xudawei@axzo.cn
* @date: 2024/08/06
*/
@Slf4j
@Component
@RefreshScope
public class TeamJoinWorkspaceHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("teamJoinWorkspace-start mq,eventModule:{},eventName:{}, event:{}", event.getEventCode().getModule(), event.getEventCode().getName(), JSON.toJSONString(event));
//解析数据
LabourProjectTeamMqMsg labourProjectTeamMqMsg = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()), LabourProjectTeamMqMsg.class);
log.info("TeamJoinWorkspace,nodeUser:{}", JSON.toJSONString(labourProjectTeamMqMsg));
Long workspaceId = labourProjectTeamMqMsg.getWorkspaceId();
updateTenantStatus(workspaceId, GuideProcedureEnum.INVITE_TEAM);
// 班组长默认添加到项目所以此处检查项目人员总数是否超过2人理论上不需要查询此时一定超过两人理由如下创建项目时会将管理员添加到项目此时班组长默认添加到项目人数为2
updateTenantStatus(workspaceId, GuideProcedureEnum.INVITE_PARTICIPANT);
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.TEAM_JOIN_WORKSPACE_NOTICE.getModel(), MQEventEnum.TEAM_JOIN_WORKSPACE_NOTICE.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,70 @@
package cn.axzo.nanopart.server.event.workspace;
import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi;
import cn.axzo.apollo.workspace.api.workspace.req.GetWorkspaceDetailReq;
import cn.axzo.apollo.workspace.api.workspace.res.GetWorkspaceDetailRes;
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.axzo.nanopart.server.event.workspace.vo.UpsertWorkspaceMQ;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
* 创建项目租户事件
*
* @author: xudawei@axzo.cn
* @date: 2024/08/06
*/
@Slf4j
@Component
@RefreshScope
public class UpsertWorkspaceHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Autowired
private WorkspaceApi workspaceApi;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("UpsertWorkspaceHandler-start mq,eventModule:{},eventName:{}, event:{}", event.getEventCode().getModule(), event.getEventCode().getName(), JSON.toJSONString(event));
//解析数据
UpsertWorkspaceMQ upsertWorkspaceMQ = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()), UpsertWorkspaceMQ.class);
log.info("UpsertWorkspaceHandler data,upsertWorkspaceMQ:{}", upsertWorkspaceMQ);
if (Objects.equals(upsertWorkspaceMQ.getWorkspaceType(), WorkspaceTypeEnum.GENERAL_PROJECT.value)) {
// 获取单位对应的workspaceId
GetWorkspaceDetailReq detailReq = new GetWorkspaceDetailReq();
detailReq.setOrganizationUnitId(upsertWorkspaceMQ.getOuId());
detailReq.setType(WorkspaceTypeEnum.GENERAL_ENT.value);
List<GetWorkspaceDetailRes> workspace = workspaceApi.getWorkspace(detailReq).getData();
if (CollUtil.isEmpty(workspace)) {
log.info("UpsertWorkspaceHandler ouId {} mapping workspaceId not exist", upsertWorkspaceMQ.getOuId());
return;
}
updateTenantStatus(workspace.get(0).getId(), GuideProcedureEnum.CREATE_PROJECT);
return;
}
log.info("UpsertWorkspaceHandlerA tenant is created. But no action is required. Tenant type is {}", upsertWorkspaceMQ.getWorkspaceType());
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.UPSERT_WORKSPACE.getModel(), MQEventEnum.UPSERT_WORKSPACE.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,81 @@
package cn.axzo.nanopart.server.event.workspace;
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
import cn.axzo.maokai.api.labour.dto.mq.WorkerJoinWorkspaceMqMsg;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.request.OrganizationalNodeUserSearchReq;
import cn.axzo.maokai.api.vo.response.OrganizationalNodeUserVO;
import cn.axzo.nanopart.server.enums.GuideProcedureEnum;
import cn.axzo.nanopart.server.event.AbstractTenantProcedureStatusHandler;
import cn.axzo.nanopart.server.event.enums.MQEventEnum;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 工人加入项目事件通知
* @author: xudawei@axzo.cn
* @date: 2024/08/06
*/
@Slf4j
@Component
@RefreshScope
public class WorkerJoinWorkspaceHandler extends AbstractTenantProcedureStatusHandler implements EventHandler, InitializingBean {
@Autowired
private EventConsumer eventConsumer;
@Autowired
private CooperateShipQueryApi cooperateShipQueryApi;
@Autowired
private OrganizationalNodeUserApi organizationalNodeUserApi;
@Override
public void onEvent(Event event, EventConsumer.Context context) {
log.info("WorkerJoinWorkspaceHandler-start mq,eventModule:{},eventName:{}, event:{}", event.getEventCode().getModule(), event.getEventCode().getName(), JSON.toJSONString(event));
//解析数据
WorkerJoinWorkspaceMqMsg labourProjectTeamMqMsg = JSONUtil.toBean(JSONUtil.toJsonStr(event.getData()),WorkerJoinWorkspaceMqMsg.class);
log.info("WorkerJoinWorkspaceHandler,nodeUser:{}", JSON.toJSONString(labourProjectTeamMqMsg));
Long workspaceId = labourProjectTeamMqMsg.getWorkspaceId();
// 查询租户下人员数量若项目下总人数大于2则更新步骤完成状态
// 获取项目下所有企业的顶级节点
CooperateShipQueryReq shipQueryReq = new CooperateShipQueryReq();
shipQueryReq.setWorkspaceId(workspaceId);
shipQueryReq.setWorkspaceType(WorkspaceTypeEnum.GENERAL_PROJECT.value);
List<Long> topNodeIds = cooperateShipQueryApi.genericQuery(shipQueryReq)
.getData().stream()
.map(item -> item.getOrganizationalNodeId())
.distinct()
.collect(Collectors.toList());
// 获取所有顶级节点下人员
OrganizationalNodeUserSearchReq searchReq = new OrganizationalNodeUserSearchReq();
searchReq.setTopNodeIdList(topNodeIds);
List<OrganizationalNodeUserVO> nodeUserVOList = organizationalNodeUserApi.list(searchReq).getData();
if (CollUtil.isEmpty(nodeUserVOList) || nodeUserVOList.size() < 2){
log.info("WorkerJoinWorkspaceHandler,person number less than 2, workspaceId:{}", workspaceId);
return;
}
updateTenantStatus(workspaceId, GuideProcedureEnum.INVITE_PARTICIPANT);
}
@Override
public void afterPropertiesSet() throws Exception {
Event.EventCode eventCode = new Event.EventCode(MQEventEnum.LABOUR.getModel(), MQEventEnum.LABOUR.getTag());
eventConsumer.registerHandler(eventCode, this);
}
}

View File

@ -0,0 +1,40 @@
package cn.axzo.nanopart.server.event.workspace.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.Set;
@Data
public class CreateProjectMsgVO implements Serializable {
/**
* 租户id
*/
private Long saasTenantId;
/**
* 工作台id
*/
private Long workspaceId;
/**
* 项目id
*/
private Long projectId;
/**
* 项目名称
*/
private String projectName;
/**
* 项目分类code
*/
private String categoryCode;
/**
* 单项工程编码集
*/
private Set<String> singleCodes;
}

View File

@ -0,0 +1,61 @@
package cn.axzo.nanopart.server.event.workspace.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 企业自注册通过后衔接企业入驻流程
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UpsertWorkspaceMQ implements Serializable {
private Long workspaceId;
/**
* 租户类型
*/
private Integer workspaceType;
/**
* 主体单位
*/
private Long ouId;
/**
* 省份code
*/
private String provinceCode;
/**
* 城市code
*/
private String cityCode;
/**
* 区code
*/
private String areaCode;
/**
* 省份名称
*/
private String provinceName;
/**
* 城市名称
*/
private String cityName;
/**
* 区名称
*/
private String areaName;
}

View File

@ -0,0 +1,14 @@
package cn.axzo.nanopart.server.mapper;
import cn.axzo.nanopart.server.domain.GuideProcedureTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:15
*/
@Mapper
public interface GuideProcedureTemplateMapper extends BaseMapper<GuideProcedureTemplate> {
}

View File

@ -0,0 +1,14 @@
package cn.axzo.nanopart.server.mapper;
import cn.axzo.nanopart.server.domain.GuideTenantProcedureStatus;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:16
*/
@Mapper
public interface GuideTenantProcedureStatusMapper extends BaseMapper<GuideTenantProcedureStatus> {
}

View File

@ -0,0 +1,21 @@
package cn.axzo.nanopart.server.service;
import cn.axzo.op.api.response.GuideProcedureTemplateResp;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.axzo.op.api.request.GuideProcedureTemplateCreateReq;
import java.util.List;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:18
*/
public interface GuideProcedureTemplateService {
Long create(GuideProcedureTemplateCreateReq req);
List<GuideProcedureTemplateResp> getByCategoryCodeOrType(GuideProcedureCategoryEnum categoryCode, GuideProcedureTypeEnum type);
GuideProcedureTemplateResp getByProcedureId(Long procedureId);
}

View File

@ -0,0 +1,21 @@
package cn.axzo.nanopart.server.service;
import cn.axzo.op.api.request.GuideTenantProcedureStatusCreateReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusListReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusUpdateReq;
import cn.axzo.op.api.response.GuideTenantProcedureStatusListResp;
import java.util.List;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:17
*/
public interface GuideTenantProcedureStatusService {
List<GuideTenantProcedureStatusListResp> list(GuideTenantProcedureStatusListReq req);
void updateStatus(GuideTenantProcedureStatusUpdateReq req);
Long create(GuideTenantProcedureStatusCreateReq req);
}

View File

@ -0,0 +1,75 @@
package cn.axzo.nanopart.server.service.impl;
import cn.axzo.nanopart.server.domain.GuideProcedureTemplate;
import cn.axzo.nanopart.server.mapper.GuideProcedureTemplateMapper;
import cn.axzo.nanopart.server.service.GuideProcedureTemplateService;
import cn.axzo.op.api.enums.GuideProcedureCategoryEnum;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.axzo.op.api.request.GuideProcedureTemplateCreateReq;
import cn.axzo.op.api.response.GuideProcedureTemplateResp;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:18
*/
@Service
public class GuideProcedureTemplateServiceImpl extends ServiceImpl<GuideProcedureTemplateMapper, GuideProcedureTemplate> implements GuideProcedureTemplateService {
@Override
@Transactional(rollbackFor = Exception.class)
public Long create(GuideProcedureTemplateCreateReq req) {
// 新增操作步骤
GuideProcedureTemplate template = BeanUtil.copyProperties(req, GuideProcedureTemplate.class);
// 步骤类型补充
template.setType(template.getCategoryCode().getType());
// 对所有顺序在新插入操作后的操作的顺序进行+1
lambdaUpdate()
.setSql("sort = sort + 1")
.eq(GuideProcedureTemplate::getCategoryCode, template.getCategoryCode())
.eq(GuideProcedureTemplate::getType, template.getType())
.ge(GuideProcedureTemplate::getSort, req.getSort())
.update();
save(template);
return template.getId();
}
/**
* 根据分类或类型获取操作步骤
*
* @param categoryCode 分类code {@link GuideProcedureCategoryEnum}
* @param type 类型 {@link GuideProcedureTypeEnum}
* @return {@link GuideProcedureTemplateResp}
*/
@Override
public List<GuideProcedureTemplateResp> getByCategoryCodeOrType(GuideProcedureCategoryEnum categoryCode, GuideProcedureTypeEnum type) {
if (Objects.isNull(categoryCode) && Objects.isNull(type)) {
return Collections.emptyList();
}
List<GuideProcedureTemplate> templateList = lambdaQuery()
.eq(Objects.nonNull(categoryCode), GuideProcedureTemplate::getCategoryCode, categoryCode)
.eq(Objects.nonNull(type), GuideProcedureTemplate::getType, type)
.list();
return BeanUtil.copyToList(templateList, GuideProcedureTemplateResp.class);
}
/**
* 根据步骤id获取步骤
*
* @param procedureId 步骤id
* @return 步骤信息
*/
@Override
public GuideProcedureTemplateResp getByProcedureId(Long procedureId) {
return BeanUtil.copyProperties(getById(procedureId), GuideProcedureTemplateResp.class);
}
}

View File

@ -0,0 +1,162 @@
package cn.axzo.nanopart.server.service.impl;
import cn.axzo.basics.common.util.NumberUtil;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.nanopart.server.domain.GuideTenantProcedureStatus;
import cn.axzo.nanopart.server.mapper.GuideTenantProcedureStatusMapper;
import cn.axzo.nanopart.server.service.GuideProcedureTemplateService;
import cn.axzo.nanopart.server.service.GuideTenantProcedureStatusService;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.axzo.op.api.request.GuideTenantProcedureStatusCreateReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusListReq;
import cn.axzo.op.api.request.GuideTenantProcedureStatusUpdateReq;
import cn.axzo.op.api.response.GuideProcedureTemplateResp;
import cn.axzo.op.api.response.GuideTenantProcedureStatusListResp;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author chenwenjian
* @version 1.0
* @date 2024/8/2 14:18
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTenantProcedureStatusMapper, GuideTenantProcedureStatus> implements GuideTenantProcedureStatusService {
private final GuideProcedureTemplateService procedureTemplateService;
@Override
public List<GuideTenantProcedureStatusListResp> list(GuideTenantProcedureStatusListReq req) {
// 获取操作状态
List<GuideTenantProcedureStatus> procedureStatusList = lambdaQuery()
.eq(NumberUtil.isPositiveNumber(req.getWorkspaceId()), GuideTenantProcedureStatus::getWorkspaceId, req.getWorkspaceId())
.eq(Objects.nonNull(req.getCategoryCode()), GuideTenantProcedureStatus::getCategoryCode, req.getCategoryCode())
.eq(Objects.nonNull(req.getStatus()), GuideTenantProcedureStatus::getStatus, req.getStatus())
.list();
GuideProcedureTypeEnum type = req.getType();
if (Objects.isNull(type) && CollUtil.isNotEmpty(procedureStatusList)) {
type = procedureStatusList.get(0).getType();
}
List<GuideTenantProcedureStatusListResp> respList = BeanUtil.copyToList(procedureStatusList, GuideTenantProcedureStatusListResp.class);
// 获取操作模板
List<GuideProcedureTemplateResp> templateList = procedureTemplateService.getByCategoryCodeOrType(req.getCategoryCode(), type);
if (CollUtil.isEmpty(templateList)) {
return Collections.emptyList();
}
// 将租户操作步骤数量与模板操作步骤数量进行对比如果模板操作步骤数量大于租户操作步骤数量则根据模板为租户初始化新步骤点
if (templateList.size() > procedureStatusList.size()) {
// 将该租户未初始化的步骤点进行初始化
List<Long> procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).collect(Collectors.toList());
respList.addAll(templateList.stream()
.filter(t -> !procedureStatusIdList.contains(t.getId()))
.map(t -> {
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
createReq.setWorkspaceId(req.getWorkspaceId());
createReq.setCategoryCode(t.getCategoryCode());
createReq.setProcedureId(t.getId());
createReq.setProcedureName(t.getName());
createReq.setStatus(GuideProcedureStatus.TODO);
create(createReq);
return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class);
})
.collect(Collectors.toList()));
} else if (templateList.size() < procedureStatusList.size()) {
log.warn("操作步骤模板:{},租户&分类:{},租户操作步骤状态:{}", JSONUtil.toJsonStr(templateList), JSONUtil.toJsonStr(req), JSONUtil.toJsonStr(procedureStatusList));
throw new ServiceException("数据异常,操作步骤不存在,请联系管理人员");
}
// 对租户操作步骤的权限码和跳转链接进行补充
Map<Long, GuideProcedureTemplateResp> templateMap = templateList.stream().collect(Collectors.toMap(GuideProcedureTemplateResp::getId, Function.identity(), (v1, v2) -> v1));
respList.forEach(r -> {
GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId());
r.setDescription(t.getDescription());
r.setIsMust(t.getIsMust());
r.setAuthCode(t.getAuthCode());
r.setJumpUrl(t.getJumpUrl());
r.setJumpReport(t.getJumpReport());
r.setSort(t.getSort());
});
return respList;
}
@Override
public void updateStatus(GuideTenantProcedureStatusUpdateReq req) {
GuideTenantProcedureStatus tenantProcedure = lambdaQuery()
.eq(GuideTenantProcedureStatus::getWorkspaceId, req.getWorkspaceId())
.eq(GuideTenantProcedureStatus::getProcedureId, req.getProcedureId())
.eq(GuideTenantProcedureStatus::getIsDelete, 0)
.last("limit 1")
.one();
if (Objects.isNull(tenantProcedure)) {
GuideProcedureTemplateResp byProcedureId = procedureTemplateService.getByProcedureId(req.getProcedureId());
// 步骤模板不存在
if (Objects.isNull(byProcedureId)) {
log.error("步骤模板不存在步骤id{}", req.getProcedureId());
return;
} else {
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
createReq.setWorkspaceId(req.getWorkspaceId());
createReq.setCategoryCode(byProcedureId.getCategoryCode());
createReq.setProcedureId(req.getProcedureId());
createReq.setProcedureName(byProcedureId.getName());
createReq.setStatus(req.getStatus());
create(createReq);
return;
}
}
if (Objects.equals(req.getFrom(), 2) && Objects.equals(tenantProcedure.getStatus(), GuideProcedureStatus.FINISHED)) {
log.info("步骤已完成无需重复操作workspaceId: {}, procedureId{}", req.getWorkspaceId(), req.getProcedureId());
return;
}
tenantProcedure.setStatus(req.getStatus());
updateById(tenantProcedure);
}
@Override
public Long create(GuideTenantProcedureStatusCreateReq req) {
// 若操作所属分类或操作名称为空则从对应模板获取
if (Objects.isNull(req.getCategoryCode()) || CharSequenceUtil.isBlank(req.getProcedureName())) {
GuideProcedureTemplateResp byProcedureId = procedureTemplateService.getByProcedureId(req.getProcedureId());
if (Objects.isNull(byProcedureId)) {
throw new ServiceException("操作步骤不存在,请联系管理人员");
}
req.setCategoryCode(byProcedureId.getCategoryCode());
req.setProcedureName(byProcedureId.getName());
}
GuideTenantProcedureStatus procedureStatus = lambdaQuery()
.eq(GuideTenantProcedureStatus::getWorkspaceId, req.getWorkspaceId())
.eq(GuideTenantProcedureStatus::getProcedureId, req.getProcedureId())
.eq(GuideTenantProcedureStatus::getIsDelete, 0)
.last("limit 1")
.one();
if (Objects.nonNull(procedureStatus)) {
log.warn("操作步骤已存在无需重复创建workspaceId: {}, procedureId{}", req.getWorkspaceId(), req.getProcedureId());
return procedureStatus.getId();
}
GuideTenantProcedureStatus tenantProcedureStatus = BeanUtil.copyProperties(req, GuideTenantProcedureStatus.class);
tenantProcedureStatus.setType(req.getCategoryCode().getType());
tenantProcedureStatus.setUpdateBy(req.getCreateBy());
save(tenantProcedureStatus);
return tenantProcedureStatus.getId();
}
}

View File

@ -0,0 +1,188 @@
package cn.axzo.nanopart.server.xxljob;
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
import cn.axzo.basics.common.BeanMapper;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.vo.request.CooperateShipQueryReq;
import cn.axzo.maokai.api.vo.response.CooperateShipResp;
import cn.axzo.nanopart.server.domain.GuideProcedureTemplate;
import cn.axzo.nanopart.server.domain.GuideTenantProcedureStatus;
import cn.axzo.nanopart.server.mapper.GuideProcedureTemplateMapper;
import cn.axzo.nanopart.server.mapper.GuideTenantProcedureStatusMapper;
import cn.axzo.op.api.enums.GuideProcedureStatus;
import cn.axzo.op.api.enums.GuideProcedureTypeEnum;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@RefreshScope
@Slf4j
@Component
@RequiredArgsConstructor
public class HistoryWorkspaceGuideProcedureJob extends IJobHandler {
private final GuideProcedureTemplateMapper procedureTemplateMapper;
private final GuideTenantProcedureStatusMapper guideTenantProcedureStatusMapper;
private final CooperateShipQueryApi cooperateShipQueryApi;
private final GuideCardProperties guideCardProperties;
/**
* 已存在项目操作步骤初始化
*
* @param s 已拥有任务单的项目的workspaceId
* @return 结果
* @throws Exception 异常
*/
@Override
@XxlJob("historyWorkspaceGuideProcedureJob")
public ReturnT<String> execute(String s) throws Exception {
// 解析项目id
if (CharSequenceUtil.isBlank(s)) {
log.info("获取参数为空s: {}", s);
return ReturnT.SUCCESS;
}
String[] workspaceIdStrs = s.split(",");
List<Long> workspaceIds = Arrays.stream(workspaceIdStrs)
.map(Long::parseLong)
.distinct()
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(guideCardProperties.getExcludeIds())){
workspaceIds = workspaceIds.stream()
.filter(w -> !guideCardProperties.getExcludeIds().contains(w))
.collect(Collectors.toList());
}
log.info("开始初始化项目操作步骤workspaceIds: {}, excludeIds: {}", JSONUtil.toJsonStr(workspaceIds), JSONUtil.toJsonStr(guideCardProperties.getExcludeIds()));
// 初始化项目的操作步骤全部初始化为已完成
List<GuideProcedureTemplate> projectTemplates = getProcedureTemplates(GuideProcedureTypeEnum.PROJECT);
workspaceIds.forEach(w -> initializeWorkspaceProcedureStatus(projectTemplates, w));
// 通过项目获取所有参建单位
CooperateShipQueryReq shipQueryReq = new CooperateShipQueryReq();
shipQueryReq.setWorkspaceType(WorkspaceTypeEnum.GENERAL_PROJECT.value);
shipQueryReq.setWorkspaceIds(workspaceIds);
List<CooperateShipResp> cooperateShipResps = cooperateShipQueryApi.genericQuery(shipQueryReq).getData();
if (CollUtil.isEmpty(cooperateShipResps)) {
return ReturnT.SUCCESS;
}
List<Long> ouIds = cooperateShipResps.stream()
.map(CooperateShipResp::getOrganizationalUnitId)
.distinct()
.collect(Collectors.toList());
log.info("通过项目获取所有参建单位ouIds: {}", JSONUtil.toJsonStr(ouIds));
// 获取参建单位的workspaceId
shipQueryReq = new CooperateShipQueryReq();
shipQueryReq.setWorkspaceType(WorkspaceTypeEnum.GENERAL_ENT.value);
shipQueryReq.setOuIdList(ouIds);
cooperateShipResps = cooperateShipQueryApi.genericQuery(shipQueryReq).getData();
if (CollUtil.isEmpty(cooperateShipResps)) {
return ReturnT.SUCCESS;
}
workspaceIds = cooperateShipResps.stream()
.map(CooperateShipResp::getWorkspaceId)
.distinct()
.collect(Collectors.toList());
log.info("通过参建单位ouId获取所有单位workspaceIdworkspaceIds: {}", JSONUtil.toJsonStr(workspaceIds));
// 通过单位workspaceId初始化单位的操作步骤全部初始化为已完成
List<GuideProcedureTemplate> entTemplates = getProcedureTemplates(GuideProcedureTypeEnum.ENT);
workspaceIds.forEach(w -> initializeWorkspaceProcedureStatus(entTemplates, w));
return ReturnT.SUCCESS;
}
private void initializeWorkspaceProcedureStatus(List<GuideProcedureTemplate> templates, Long w) {
List<GuideProcedureTemplate> needCreateProcedures = templates;
// 获取该租户已初始化的操作步骤
LambdaQueryWrapper<GuideTenantProcedureStatus> statusQueryWrapper = new LambdaQueryWrapper<>();
statusQueryWrapper.eq(GuideTenantProcedureStatus::getWorkspaceId, w);
statusQueryWrapper.eq(GuideTenantProcedureStatus::getIsDelete, 0);
List<GuideTenantProcedureStatus> procedureStatuses = guideTenantProcedureStatusMapper.selectList(statusQueryWrapper);
List<Long> todoProcedureIds = Collections.emptyList();
if (CollUtil.isNotEmpty(procedureStatuses)) {
// 获取已初始化的操作步骤
List<Long> procedureIds = procedureStatuses.stream().map(GuideTenantProcedureStatus::getProcedureId).collect(Collectors.toList());
// 获取未完成的操作步骤
todoProcedureIds = procedureStatuses.stream()
.filter(p -> Objects.equals(p.getStatus(), GuideProcedureStatus.TODO))
.map(GuideTenantProcedureStatus::getProcedureId)
.collect(Collectors.toList());
// 获取待初始化的操作步骤
needCreateProcedures = templates.stream()
.filter(t -> !procedureIds.contains(t.getId()))
.collect(Collectors.toList());
}
// 创建待初始化的操作步骤
if (CollUtil.isNotEmpty(needCreateProcedures)) {
List<GuideTenantProcedureStatus> createStatusList = BeanMapper.copyList(needCreateProcedures, GuideTenantProcedureStatus.class, (s, t) -> {
t.setWorkspaceId(w);
t.setProcedureId(s.getId());
t.setProcedureName(s.getName());
t.setStatus(GuideProcedureStatus.FINISHED);
});
createStatusList.forEach(c -> {
guideTenantProcedureStatusMapper.insert(c);
log.info("创建操作步骤: workspaceId: {}, procedure{}", w, JSONUtil.toJsonStr(c));
});
}
// 更新未完成的操作步骤为已完成
if (CollUtil.isNotEmpty(todoProcedureIds)) {
LambdaUpdateWrapper<GuideTenantProcedureStatus> statusLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
statusLambdaUpdateWrapper.set(GuideTenantProcedureStatus::getStatus, GuideProcedureStatus.FINISHED)
.eq(GuideTenantProcedureStatus::getWorkspaceId, w)
.in(GuideTenantProcedureStatus::getProcedureId, todoProcedureIds)
.eq(GuideTenantProcedureStatus::getIsDelete, 0);
guideTenantProcedureStatusMapper.update(null, statusLambdaUpdateWrapper);
log.info("更新操作步骤状态: workspaceId: {}, procedureIds{}", w, JSONUtil.toJsonStr(todoProcedureIds));
}
}
/**
* 获取操作步骤模板
*
* @param type 操作步骤类型 {@link GuideProcedureTypeEnum}
* @return 操作步骤列表
*/
private List<GuideProcedureTemplate> getProcedureTemplates(GuideProcedureTypeEnum type) {
LambdaQueryWrapper<GuideProcedureTemplate> templateQueryWrapper = new LambdaQueryWrapper<>();
templateQueryWrapper.eq(GuideProcedureTemplate::getType, type);
templateQueryWrapper.eq(GuideProcedureTemplate::getIsDelete, 0);
return procedureTemplateMapper.selectList(templateQueryWrapper);
}
@Data
@RefreshScope
@Component
@ConfigurationProperties(prefix = "nanopart.guidecard")
public class GuideCardProperties {
private List<Long> excludeIds;
}
}