diff --git a/common/src/main/java/com/sdm/common/entity/req/project/SpdmNodeListReq.java b/common/src/main/java/com/sdm/common/entity/req/project/SpdmNodeListReq.java index b6833317..11d91906 100644 --- a/common/src/main/java/com/sdm/common/entity/req/project/SpdmNodeListReq.java +++ b/common/src/main/java/com/sdm/common/entity/req/project/SpdmNodeListReq.java @@ -47,4 +47,9 @@ public class SpdmNodeListReq { */ private String exeStatus; + /** + * 查询类型,0:所有,1:我关注的,2:我负责的(2026-02-13 逻辑待定) + */ + private Integer type; + } diff --git a/project/src/main/java/com/sdm/project/common/NodeMemberTypeEnum.java b/project/src/main/java/com/sdm/project/common/NodeMemberTypeEnum.java new file mode 100644 index 00000000..bc2c76f8 --- /dev/null +++ b/project/src/main/java/com/sdm/project/common/NodeMemberTypeEnum.java @@ -0,0 +1,22 @@ +package com.sdm.project.common; + +import lombok.Getter; + +@Getter +public enum NodeMemberTypeEnum { + + + MANAGER("项目经理", 0), + ATTENTION("项目关注人", 1); + + + private final String name; + + private final Integer code; + + NodeMemberTypeEnum(String name, Integer code) { + this.name = name; + this.code = code; + } + +} diff --git a/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java index 06f1bba4..0ca193d5 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java @@ -420,5 +420,19 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { return nodeService.getRunListByRunIdList(req); } + @SysLog("关注项目") + @PostMapping("/followProject") + @Operation(summary = "关注项目", description = "关注项目") + public SdmResponse followProject(@RequestBody SpdmProjectFollowReq req) { + return nodeService.followProject(req.getNodeId()); + } + + @SysLog("取消关注项目") + @PostMapping("/unFollowProject") + @Operation(summary = "关注项目", description = "关注项目") + public SdmResponse unFollowProject(@RequestBody SpdmProjectFollowReq req) { + return nodeService.unFollowProject(req.getNodeId()); + } + } diff --git a/project/src/main/java/com/sdm/project/dao/SimulationNodeMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationNodeMapper.java index 08ad6aa1..7035f533 100644 --- a/project/src/main/java/com/sdm/project/dao/SimulationNodeMapper.java +++ b/project/src/main/java/com/sdm/project/dao/SimulationNodeMapper.java @@ -102,12 +102,19 @@ public interface SimulationNodeMapper extends BaseMapper { SpdmNodeVo getNodeByProjectIdAndName(@Param("projectId") String projectId, @Param("projectName") String projectName); - List getPerformanceListByIdList(@Param("taskIdList") List taskIdList); - List queryNodeCodeByTags(@Param("list")List tag1List, @Param("tagKey")String tagKey,@Param("tagValue") String tagValue); List getTaskListByProjectNodeId(@Param("nodeId") String nodeId); List getTaskListByPhaseNodeId(@Param("nodeId") String nodeId); + + List getNodeListByUserId(@Param("nodeType") String nodeType, @Param("nodeSubType") String nodeSubType, @Param("exeStatus") String exeStatus, @Param("nodeCode") String nodeCode, + @Param("manager") String manager, @Param("nodeName") String nodeName, @Param("tenantId") Long tenantId, @Param("pos") int pos, @Param("limit") int limit, @Param("userId") Long userId,@Param("type") Integer type); + + int getNodeListCountByUserId(@Param("nodeType") String nodeType, @Param("nodeSubType") String nodeSubType, @Param("exeStatus") String exeStatus, @Param("nodeCode") String nodeCode, + @Param("manager") String manager, @Param("nodeName") String nodeName, @Param("tenantId") Long tenantId, @Param("userId") Long userId,@Param("type") Integer type); + + List getNodeMemberListByMemberType(@Param("nodeIdList") List nodeIdList,@Param("userId") Long userId,@Param("memberType") Integer memberType); + } diff --git a/project/src/main/java/com/sdm/project/dao/SimulationNodeMemberMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationNodeMemberMapper.java new file mode 100644 index 00000000..75eb24bc --- /dev/null +++ b/project/src/main/java/com/sdm/project/dao/SimulationNodeMemberMapper.java @@ -0,0 +1,10 @@ +package com.sdm.project.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.sdm.project.model.entity.SimulationNodeMember; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SimulationNodeMemberMapper extends BaseMapper { + +} diff --git a/project/src/main/java/com/sdm/project/model/entity/SimulationNodeMember.java b/project/src/main/java/com/sdm/project/model/entity/SimulationNodeMember.java new file mode 100644 index 00000000..a7e75555 --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/entity/SimulationNodeMember.java @@ -0,0 +1,64 @@ +package com.sdm.project.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("simulation_node_member") +@ApiModel(value="SimulationNodeMember", description="") +public class SimulationNodeMember implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键ID") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "节点ID") + @TableField("nodeId") + private String nodeId; + + @ApiModelProperty(value = "身份标识") + @TableField("identity") + private String identity; + + @ApiModelProperty(value = "名称") + @TableField("name") + private String name; + + @ApiModelProperty(value = "用户ID") + @TableField("user_id") + private Long userId; + + @ApiModelProperty(value = "创建人") + @TableField("creator") + private Long creator; + + @ApiModelProperty(value = "创建时间") + @TableField("create_time") + private String createTime; + + @ApiModelProperty(value = "更新人") + @TableField("updater") + private Long updater; + + @ApiModelProperty(value = "更新时间") + @TableField("update_time") + private String updateTime; + + @ApiModelProperty(value = "类型:0:项目经理,1:项目关注人") + @TableField("type") + private Integer type; + +} diff --git a/project/src/main/java/com/sdm/project/model/req/SpdmNodeRelateMemberReq.java b/project/src/main/java/com/sdm/project/model/req/SpdmNodeRelateMemberReq.java index e5cc82d4..f7b6b16d 100644 --- a/project/src/main/java/com/sdm/project/model/req/SpdmNodeRelateMemberReq.java +++ b/project/src/main/java/com/sdm/project/model/req/SpdmNodeRelateMemberReq.java @@ -23,4 +23,7 @@ public class SpdmNodeRelateMemberReq extends BaseEntity { private Long userId; + // 0:项目经理 ,1:项目关注人 + private Integer type; + } diff --git a/project/src/main/java/com/sdm/project/model/req/SpdmProjectFollowReq.java b/project/src/main/java/com/sdm/project/model/req/SpdmProjectFollowReq.java new file mode 100644 index 00000000..b33f195f --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/req/SpdmProjectFollowReq.java @@ -0,0 +1,16 @@ +package com.sdm.project.model.req; + +import com.sdm.common.entity.pojo.BaseEntity; +import lombok.Data; + +import java.util.List; + +@Data +public class SpdmProjectFollowReq extends BaseEntity { + + /** + * 关联的项目节点id + */ + private String nodeId; + +} diff --git a/project/src/main/java/com/sdm/project/model/vo/SpdmAnalysisTaskVo.java b/project/src/main/java/com/sdm/project/model/vo/SpdmAnalysisTaskVo.java index d06d0a4c..00278c41 100644 --- a/project/src/main/java/com/sdm/project/model/vo/SpdmAnalysisTaskVo.java +++ b/project/src/main/java/com/sdm/project/model/vo/SpdmAnalysisTaskVo.java @@ -1,6 +1,7 @@ package com.sdm.project.model.vo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import com.sdm.common.entity.pojo.BaseEntity; import lombok.Data; @@ -67,6 +68,7 @@ public class SpdmAnalysisTaskVo extends BaseEntity { /** * 仿真负责人 */ + @JsonProperty("pMembers") private String pMembers; private String tag1; diff --git a/project/src/main/java/com/sdm/project/model/vo/SpdmNodeVo.java b/project/src/main/java/com/sdm/project/model/vo/SpdmNodeVo.java index 3d1e84b5..b6fec043 100644 --- a/project/src/main/java/com/sdm/project/model/vo/SpdmNodeVo.java +++ b/project/src/main/java/com/sdm/project/model/vo/SpdmNodeVo.java @@ -110,4 +110,10 @@ public class SpdmNodeVo extends BaseEntity { * 当前阶段 */ private String currentPhase; + + /** + * 关注标识,0:未关注,1:已关注,默认为0 + */ + private Integer attentionFlag = 0; + } diff --git a/project/src/main/java/com/sdm/project/service/INodeService.java b/project/src/main/java/com/sdm/project/service/INodeService.java index 90c11b0f..31019b20 100644 --- a/project/src/main/java/com/sdm/project/service/INodeService.java +++ b/project/src/main/java/com/sdm/project/service/INodeService.java @@ -92,4 +92,20 @@ public interface INodeService extends IService { SdmResponse> getRunListByRunIdList(SpdmQueryRunInfoListReq req); + /** + * 关注项目(批量为多个用户添加项目关注关系) + * + * @param nodeId 项目节点ID(uuid) + * @return 统一响应结果 + */ + SdmResponse followProject(String nodeId); + + /** + * 取消关注项目(批量为多个用户删除项目关注关系) + * + * @param nodeId 项目节点ID(uuid) + * @return 统一响应结果 + */ + SdmResponse unFollowProject(String nodeId); + } diff --git a/project/src/main/java/com/sdm/project/service/ISimulationNodeMemberService.java b/project/src/main/java/com/sdm/project/service/ISimulationNodeMemberService.java new file mode 100644 index 00000000..1d61bcbb --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/ISimulationNodeMemberService.java @@ -0,0 +1,8 @@ +package com.sdm.project.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.sdm.project.model.entity.SimulationNodeMember; + +public interface ISimulationNodeMemberService extends IService { + +} diff --git a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java index babf63e8..e88657f6 100644 --- a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java @@ -1,9 +1,13 @@ package com.sdm.project.service.impl; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.sdm.common.common.ResultCode; @@ -25,6 +29,7 @@ import com.sdm.common.entity.resp.PageDataResp; import com.sdm.common.entity.resp.data.BatchCreateNormalDirResp; import com.sdm.common.entity.resp.project.SimulationNodeResp; import com.sdm.common.entity.resp.project.SimulationRunResp; +import com.sdm.common.entity.resp.project.SpdmTaskVo; import com.sdm.common.entity.resp.system.CIDStaffResp; import com.sdm.common.entity.resp.system.CIDUserResp; import com.sdm.common.entity.resp.system.SysUserGroupDetailResp; @@ -40,6 +45,7 @@ import com.sdm.common.utils.excel.ExcelUtil; import com.sdm.outbridge.entity.*; import com.sdm.outbridge.service.lyric.*; import com.sdm.project.common.MemberTypeEnum; +import com.sdm.project.common.NodeMemberTypeEnum; import com.sdm.project.dao.SimulationDemandMapper; import com.sdm.project.dao.SimulationNodeMapper; import com.sdm.project.dao.SimulationProjectMapper; @@ -76,6 +82,7 @@ import javax.annotation.Resource; import java.lang.reflect.Field; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -137,6 +144,9 @@ public class NodeServiceImpl extends ServiceImpl nodeList = nodeMapper.getNodeList(req.getNodeType(), req.getNodeSubType(), req.getExeStatus(), req.getNodeCode(), req.getManager(), req.getNodeName(), - tenantId, pos, limit); + Long userId = ThreadLocalContext.getUserId(); + // 查询类型,0:所有,1:我关注的,2:我负责的 + Integer type = req.getType(); + List nodeList; + int total; + // type=0,查询所有,使用原有查询逻辑 (type=2查询我负责的,逻辑待定,暂时先查询所有) + if (type == null || type == 0 || type == 2) { + nodeList = nodeMapper.getNodeList(req.getNodeType(), req.getNodeSubType(), req.getExeStatus(), req.getNodeCode(), req.getManager(), req.getNodeName(), + tenantId, pos, limit); + // 设置关注标签 + if (CollectionUtils.isNotEmpty(nodeList)) { + List nodeIdList = nodeList.stream().map(SpdmNodeVo::getUuid).toList(); + List nodeMemberList = nodeMapper.getNodeMemberListByMemberType(nodeIdList,userId, NodeMemberTypeEnum.ATTENTION.getCode()); + if (CollectionUtils.isNotEmpty(nodeMemberList)) { + List attentNodeIdList = nodeMemberList.stream().map(SpdmNodeMemberVo::getNodeId).toList(); + for (SpdmNodeVo spdmNodeVo : nodeList) { + if (!attentNodeIdList.contains(spdmNodeVo.getUuid())) { + continue; + } + spdmNodeVo.setAttentionFlag(1); + } + } + } + total = nodeMapper.getNodeListCount(req.getNodeType(), req.getNodeSubType(), req.getExeStatus(), req.getNodeCode(), req.getManager(), req.getNodeName(), tenantId); + }else { + nodeList = nodeMapper.getNodeListByUserId(req.getNodeType(), req.getNodeSubType(), req.getExeStatus(), req.getNodeCode(), req.getManager(), req.getNodeName(), + tenantId, pos, limit,userId,type); + nodeList.forEach(node -> node.setAttentionFlag(1)); + total = nodeMapper.getNodeListCountByUserId(req.getNodeType(), req.getNodeSubType(), req.getExeStatus(), req.getNodeCode(), req.getManager(), req.getNodeName(), tenantId,userId,type); + } + CoreLogger.info("getNodeList param:{},tenantId:{}", JSONObject.toJSONString(req), tenantId); if (CollectionUtils.isEmpty(nodeList)) { JSONObject jsonObject = new JSONObject(); @@ -482,7 +531,7 @@ public class NodeServiceImpl extends ServiceImpl nodeManager.setType(NodeMemberTypeEnum.MANAGER.getCode())); + if (nodeMapper.addNodeMemberBatch(allNodeManagerList) <= 0) { + return null; + } } if (CollectionUtils.isNotEmpty(allExtraList)) { CompletableFuture.runAsync(() -> nodeMapper.addNodeExtraBatch(allExtraList)); @@ -1332,6 +1384,7 @@ public class NodeServiceImpl extends ServiceImpl { node.setCreateTime(curDateStr); node.setCreator(jobNumber); + node.setType(NodeMemberTypeEnum.MANAGER.getCode()); }); if (nodeMapper.addNodeMemberBatch(allNodeManagerList) <= 0) { return false; @@ -3954,6 +4007,152 @@ public class NodeServiceImpl extends ServiceImpl validUserIdList = Collections.singletonList(ThreadLocalContext.getUserId()); + + // 2. 校验幂等性,防止重复关注 + Set existedFollowedUserIdSet = queryExistedFollowedUserIds(nodeId, validUserIdList); + + // 3. 过滤出未关注的用户ID + List toFollowUserIdList = validUserIdList.stream() + .filter(userId -> !existedFollowedUserIdSet.contains(userId)) + .collect(Collectors.toList()); + + // 4. 处理已全部关注的情况 + if (CollectionUtils.isEmpty(toFollowUserIdList)) { + log.info("所有用户均已关注项目,nodeId:{},用户列表:{}", nodeId, validUserIdList); + return SdmResponse.success(ALL_FOLLOWED_MSG); + } + + // 5. 记录重复关注的用户 + List repeatedUserIdList = validUserIdList.stream() + .filter(existedFollowedUserIdSet::contains) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(repeatedUserIdList)) { + log.error("部分用户已关注项目,跳过重复关注,nodeId:{},重复用户ID:{}", nodeId, repeatedUserIdList); + } + + // 6. 构建批量插入的关注关系列表(仅处理未关注用户) + LocalDateTime currentTime = LocalDateTime.now(); + Long currentUserId = ThreadLocalContext.getUserId(); + List attentionList = new ArrayList<>(toFollowUserIdList.size()); + + for (Long userId : toFollowUserIdList) { + SimulationNodeMember member = new SimulationNodeMember(); + member.setNodeId(nodeId); + member.setUserId(userId); + member.setType(NodeMemberTypeEnum.ATTENTION.getCode()); + member.setCreateTime(LocalDateTimeUtil.format(currentTime, DatePattern.NORM_DATETIME_PATTERN)); + member.setCreator(currentUserId); + attentionList.add(member); + } + + // 7. 批量保存未关注的用户关系 + try { + boolean saveResult = simulationNodeMemberService.saveBatch(attentionList); + if (!saveResult) { + log.error("批量保存项目关注关系失败,nodeId:{},待关注用户数:{}", nodeId, toFollowUserIdList.size()); + return SdmResponse.failed(FOLLOW_SAVE_FAIL_MSG); + } + } catch (Exception e) { + log.error("批量保存项目关注关系异常,nodeId:{}", nodeId, e); + return SdmResponse.failed("关注项目失败:" + e.getMessage()); + } + + // 8. 返回结果(区分“全部成功”和“部分成功”) + String successMsg = CollectionUtils.isEmpty(repeatedUserIdList) ? "项目关注成功" : PARTIAL_FOLLOW_SUCCESS_MSG; + return SdmResponse.success(successMsg); + } + + /** + * 取消关注项目(批量为多个用户删除项目关注关系) + * + * @param nodeId 项目节点ID(uuid) + * @return 统一响应结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public SdmResponse unFollowProject(String nodeId) { + // 1. 校验项目是否存在 + SimulationNode projectNode = this.lambdaQuery().eq(SimulationNode::getUuid, nodeId).one(); + if (projectNode == null) { + log.error("取消关注项目失败,根据nodeId:{} 未查询到项目节点", nodeId); + return SdmResponse.failed(UN_FOLLOW_PROJECT_NOT_FOUND_MSG); + } + + List validUserIdList = Collections.singletonList(ThreadLocalContext.getUserId()); + + + // 2. 幂等:先查询已存在的关注关系(仅查询需要删除的记录) + Set existedFollowedUserIdSet = queryExistedFollowedUserIds(nodeId, validUserIdList); + if (CollectionUtils.isEmpty(existedFollowedUserIdSet)) { + log.info("取消关注项目失败,无已关注的用户记录,nodeId:{},用户列表:{}", nodeId, validUserIdList); + return SdmResponse.success(NO_UNFOLLOW_DATA_MSG); + } + + // 3. 仅删除已存在的关注关系(避免无效删除操作) + try { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + .eq(SimulationNodeMember::getNodeId, nodeId) + .in(SimulationNodeMember::getUserId, existedFollowedUserIdSet) // 仅删除存在的记录 + .eq(SimulationNodeMember::getType, NodeMemberTypeEnum.ATTENTION.getCode()); + + // 执行删除 + simulationNodeMemberService.remove(updateWrapper); + } catch (Exception e) { + log.error("取消关注项目删除操作异常,nodeId:{},用户列表:{}", nodeId, existedFollowedUserIdSet, e); + return SdmResponse.failed(UNFOLLOW_DELETE_FAIL_MSG); + } + + // 4. 返回结果 + return SdmResponse.success(UNFOLLOW_SUCCESS_MSG); + } + + /** + * 批量查询已关注指定项目的用户ID + * + * @param nodeId 项目节点ID + * @param validUserIdList 待校验的有效用户ID列表 + * @return 已关注的用户ID集合(便于快速判断) + */ + private Set queryExistedFollowedUserIds(String nodeId, List validUserIdList) { + // 构建查询条件:nodeId匹配 + userId在列表中 + 类型为关注 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(SimulationNodeMember::getNodeId, nodeId) + .in(SimulationNodeMember::getUserId, validUserIdList) + .eq(SimulationNodeMember::getType, NodeMemberTypeEnum.ATTENTION.getCode()); + + // 只查询userId字段 + List existedList = simulationNodeMemberService.list(queryWrapper); + + // 转换为Set,便于快速判断是否存在 + if (CollectionUtils.isEmpty(existedList)) { + return Set.of(); // 返回空集合,避免NPE + } + return existedList.stream() + .map(SimulationNodeMember::getUserId) + .collect(Collectors.toSet()); + } + /** * 通用分组统计方法 - 按指定键分组统计状态数量 * diff --git a/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java index 83aeee3d..1157afc5 100644 --- a/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java @@ -32,6 +32,7 @@ import com.sdm.common.utils.SystemOperate; import com.sdm.common.utils.excel.ExcelUtil; import com.sdm.project.bo.ExportOperate; import com.sdm.project.common.MemberTypeEnum; +import com.sdm.project.common.NodeMemberTypeEnum; import com.sdm.project.common.TaskExeStatusEnum; import com.sdm.project.common.VersionEnum; import com.sdm.project.dao.SimulationNodeMapper; @@ -2044,7 +2045,10 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { } } if (CollectionUtils.isNotEmpty(projectNodeMemberList)) { - projectNodeMemberList.forEach(projectNode -> projectNode.setCreateTime(createTime)); + projectNodeMemberList.forEach(projectNode -> { + projectNode.setCreateTime(createTime); + projectNode.setType(NodeMemberTypeEnum.MANAGER.getCode()); + }); if (mapper.batchAddSimulationNodeMember(projectNodeMemberList) <= 0) { response = SdmResponse.failed("添加节点成员属性失败"); } @@ -2246,7 +2250,10 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { } } if (CollectionUtils.isNotEmpty(projectNodeMemberList)) { - projectNodeMemberList.forEach(projectNode -> projectNode.setCreateTime(createTime)); + projectNodeMemberList.forEach(projectNode -> { + projectNode.setCreateTime(createTime); + projectNode.setType(NodeMemberTypeEnum.MANAGER.getCode()); + }); if (mapper.batchAddSimulationNodeMember(projectNodeMemberList) <= 0) { response = SdmResponse.failed("添加节点成员属性失败"); } diff --git a/project/src/main/java/com/sdm/project/service/impl/SimulationNodeMemberServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationNodeMemberServiceImpl.java new file mode 100644 index 00000000..c0b62350 --- /dev/null +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationNodeMemberServiceImpl.java @@ -0,0 +1,12 @@ +package com.sdm.project.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sdm.project.dao.SimulationNodeMemberMapper; +import com.sdm.project.model.entity.SimulationNodeMember; +import com.sdm.project.service.ISimulationNodeMemberService; +import org.springframework.stereotype.Service; + +@Service +public class SimulationNodeMemberServiceImpl extends ServiceImpl implements ISimulationNodeMemberService { + +} diff --git a/project/src/main/resources/mapper/SimulationNodeMapper.xml b/project/src/main/resources/mapper/SimulationNodeMapper.xml index d405f162..cffc8a82 100644 --- a/project/src/main/resources/mapper/SimulationNodeMapper.xml +++ b/project/src/main/resources/mapper/SimulationNodeMapper.xml @@ -19,9 +19,9 @@ - insert into simulation_node_member (nodeId,identity,name,user_id,creator,create_time) values + insert into simulation_node_member (nodeId,identity,name,user_id,creator,create_time,type) values - (#{addNodeMember.nodeId},#{addNodeMember.identity},#{addNodeMember.name},#{addNodeMember.userId},#{addNodeMember.creator},#{addNodeMember.createTime}) + (#{addNodeMember.nodeId},#{addNodeMember.identity},#{addNodeMember.name},#{addNodeMember.userId},#{addNodeMember.creator},#{addNodeMember.createTime},#{addNodeMember.type}) @@ -780,5 +780,92 @@ select * from simulation_task where tag2 = #{nodeId} + + + + + + \ No newline at end of file diff --git a/system/src/main/java/com/sdm/system/service/impl/SimulationSystemConfigServiceImpl.java b/system/src/main/java/com/sdm/system/service/impl/SimulationSystemConfigServiceImpl.java index b4f57421..9c00ac45 100644 --- a/system/src/main/java/com/sdm/system/service/impl/SimulationSystemConfigServiceImpl.java +++ b/system/src/main/java/com/sdm/system/service/impl/SimulationSystemConfigServiceImpl.java @@ -49,6 +49,10 @@ import java.util.stream.Collectors; @Service public class SimulationSystemConfigServiceImpl extends BaseService implements ISimulationSystemConfigService { + // 是否开启用户自定义配置表单权限开关 true 开 false:关(宜安) + @Value("${formconfigure.selfSysUserConfigButton:true}") + private Boolean selfSysUserConfigButton; + @Value("#{'${formconfigure.admin.role:ROLE_ADMIN}'.split(',')}") private List adminRoleList; @@ -379,6 +383,11 @@ public class SimulationSystemConfigServiceImpl extends BaseService implements IS } private boolean isNormalRole(){ + log.info("isNormalRole selfSysUserConfigButton:{}",selfSysUserConfigButton); + // 自定义表单关闭,直接就都是超管 + if(!selfSysUserConfigButton){ + return false; + } // 查询是否是可以自定义表格的角色,ROLE_ADMIN 是管理员角色 SdmResponse> roleResponse = sysUserService.queryUserRole(ThreadLocalContext.getUserId()); if(!roleResponse.isSuccess()){ diff --git a/system/src/main/resources/application-yian.yml b/system/src/main/resources/application-yian.yml index f699e967..a55832fe 100644 --- a/system/src/main/resources/application-yian.yml +++ b/system/src/main/resources/application-yian.yml @@ -145,7 +145,8 @@ cid: user: listUser: /spdm-user/listUser queryUserDetail: /spdm-user/queryUserDetail - listUserByIds: /dataManager/tree/node/listUserByIds + listUserByIds: /spdm-user/listUserByIds + listUserDetailByIds: /spdm-user/listUserDetailByIds queryUserRole: /spdm-user/queryUserRole queryGroup: /spdm-user/queryGroup queryGroupDetail: /spdm-user/queryGroupDetail @@ -164,6 +165,8 @@ cid: launchApprove: /spdm-flow/startFlow queryFlowTemplate: /spdm-flow/listProcessByGroup queryApproveDetail: /spdm-flow/queryFlowNodeDetail + queryNewApproveDetail: /spdm-flow/queryNewFlowNodeDetail + getTaskIdByNodeId: /spdm-flow/getTaskIdByNodeId stopApproveFlow: /spdm-flow/stopFlow group: SPDM # 单次批量查询cid审批流详情的条数 @@ -189,4 +192,8 @@ security: - /systemLog/saveLog - /tenant/list - /tenant/initNewTenant - - /user/getUserByRoleCode \ No newline at end of file + - /user/getUserByRoleCode + +# 表单配置开关 +formconfigure: + selfSysUserConfigButton: false \ No newline at end of file diff --git a/task/src/main/resources/application-yian.yml b/task/src/main/resources/application-yian.yml new file mode 100644 index 00000000..af2ec426 --- /dev/null +++ b/task/src/main/resources/application-yian.yml @@ -0,0 +1,135 @@ +# 前后端联调使用该配置文件,本地调试使用local +server: + port: 7102 + +spring: + application: + name: task + datasource: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.0.88:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + # 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。 + maximum-pool-size: 20 + # 连接池在空闲时保持的最小连接数。 + minimum-idle: 5 + # 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。 + idle-timeout: 60000 # 1 min + # 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。 + max-lifetime: 1800000 # 30 min(Hikari 默认) + # 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。 + connection-timeout: 30000 # 30s + master: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.0.88:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + slave: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.0.88:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + enable: true + cloud: + nacos: + discovery: + server-addr: 192.168.0.88:8848 + group: DEV_GROUP + # server-addr: 127.0.0.1:8848 + enabled: true + # username: nacos + # password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + data: + redis: + # Redis默认情况下有16个分片(库),这里配置具体使用的分片,默认是0 + database: 0 + # redis服务器地址(填写自己的服务器地址) + host: 192.168.0.88 + # redis端口(默认6379) + port: 6379 + #redis连接超时等待,10秒 + timeout: PT10S + # redis访问密码(默认为空) + password: + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 50 + # 连接池中的最大空闲连接 默认 8 + max-idle: 20 + # 连接池中的最小空闲连接 默认 0 + min-idle: 1 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1,这里配置10s + max-wait: PT10S + # password: + # sentinel: + # master: mymaster + # nodes: 10.18.109.50:26379,10.18.109.51:26379,10.18.109.52:26379 + servlet: + multipart: + # 单个文件的最大值 + max-file-size: 500MB + # 上传文件总的最大值 + max-request-size: 10240MB + +management: + endpoints: + web: + exposure: + include: health,info + endpoint: + health: + show-details: always + group: + readiness: + include: discoveryComposite,ping,refreshScope + health: + redis: + enabled: false + db: + enabled: false + +mybatis-plus: + configuration: + map-underscore-to-camel-case: true + auto-mapping-behavior: full + # cache-enabled: true + # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + mapper-locations: classpath*:mapper/**/*.xml + global-config: + # 逻辑删除配置 + db-config: + # 删除前 + logic-not-delete-value: 1 + # 删除后 + logic-delete-value: 0 + +#showSql +#logging: +# level: +# com.sdm.dao: debug + +lombok: + anyConstructor: + addConstructorProperties: true + +file: + rootPath: /data/home/sdm + scriptPath : /opt/script +approve: + replyUrl: http:192.168.0.88:7102/simulation/task/taskpool/approveHandleNotice +#logging: +# config: ./config/logback.xml + +security: + whitelist: + paths: + - /taskpool/approveHandleNotice + - /taskPerformance/getRunPerformance + +simulationPool: + baseline: baseline + lyric: lyric + chose: lyric \ No newline at end of file