diff --git a/ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java b/ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java index 4cea706..3e1ed7f 100644 --- a/ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java +++ b/ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java @@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { } public static void main(String[] args) { - generate("WendyYang", "projectlib", PATH_YYD, "nd_project_application"); + generate("Lierbao", "organization", PATH_LXX, "ding_organization"); } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java index 34ccd97..a107a7a 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java @@ -44,15 +44,15 @@ public class GovDingProperties { GovDingProperties.appAuthsecret = appAuthsecret; } - @Value("${ding.app-sso-auth-key}") - public void setAppSsoAuthKey(String appSsoAuthkey) { - GovDingProperties.appSsoAuthkey = appSsoAuthkey; - } - - @Value("${ding.app-sso-auth-secret}") - public void setAppSsoAuthsecret(String appSsoAuthsecret) { - GovDingProperties.appSsoAuthsecret = appSsoAuthsecret; - } +// @Value("${ding.app-sso-auth-key}") +// public void setAppSsoAuthKey(String appSsoAuthkey) { +// GovDingProperties.appSsoAuthkey = appSsoAuthkey; +// } +// +// @Value("${ding.app-sso-auth-secret}") +// public void setAppSsoAuthsecret(String appSsoAuthsecret) { +// GovDingProperties.appSsoAuthsecret = appSsoAuthsecret; +// } @Value("${ding.tenantId}") public void setTenantId(Long tenantId) { diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/event/ProjectStatusChangeEvent.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/event/ProjectStatusChangeEvent.java index 4d05c41..7c5fd11 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/event/ProjectStatusChangeEvent.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/event/ProjectStatusChangeEvent.java @@ -26,43 +26,43 @@ public enum ProjectStatusChangeEvent { /** * 项目申报提交(项目状态进入:单位内部审核中) */ - PROJECT_APPLICATION_SUBMIT(1015,null,null), + PROJECT_APPLICATION_SUBMIT(10015,null,null), /** * 单位内部审核驳回(项目状态进入:单位内部审核不通过) */ - UNDER_INTERNAL_REJECT(null,1001,null), + UNDER_INTERNAL_REJECT(null,10001,null), /** * 单位内部审核通过(项目状态进入:待预审) */ - UNDER_INTERNAL_PASS(1001,null,null), + UNDER_INTERNAL_PASS(10001,null,null), /** * 预审申报(项目状态进入:待预审选择,有判断条件:市级项目且申报金额大于1000万项目状态变为:省级部门联审中;否则项目状态变为:预审中) */ - PRELIMINARY_REVIEW_DECLARE(1003,null,null), + PRELIMINARY_REVIEW_DECLARE(10003,null,null), /** * 省级部门联审不通过(项目状态变为:省级部门联审不通过) */ - PROVINCIAL_DEPARTMENT_REVIEW_REJECT(null,1004,null), + PROVINCIAL_DEPARTMENT_REVIEW_REJECT(null,10004,null), /** * 省级部门联审通过(项目状态变为:预审中) */ - PROVINCIAL_DEPARTMENT_REVIEW_PASS(1004,null,null), + PROVINCIAL_DEPARTMENT_REVIEW_PASS(10004,null,null), /** * 预审驳回(项目状态变为:预审不通过) */ - PRELIMINARY_REVIEW_REJECT(null,1006,null), + PRELIMINARY_REVIEW_REJECT(null,10006,null), /** * 预审通过(项目状态变为:部门联审中) */ - PRELIMINARY_REVIEW_PASS(1006,null,null), + PRELIMINARY_REVIEW_PASS(10006,null,null), /** * 部门联审驳回(项目状态变为:部门联审不通过) */ - DEPARTMENT_UNITED_REVIEW_REJECT(null,1008,null), + DEPARTMENT_UNITED_REVIEW_REJECT(null,10008,null), /** * 部门联审通过(项目状态变为:年度计划中) */ - DEPARTMENT_UNITED_REVIEW_PASS(1008,null,null), + DEPARTMENT_UNITED_REVIEW_PASS(10008,null,null), /** * 年度计划暂缓(项目状态变为:被暂缓) */ diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/ding/model/DingOrgInfoTreeDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/ding/model/DingOrgInfoTreeDTO.java new file mode 100644 index 0000000..7040ce1 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/ding/model/DingOrgInfoTreeDTO.java @@ -0,0 +1,29 @@ +package com.ningdatech.pmapi.ding.model; + +import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO; +import lombok.Data; + +import java.util.List; + +/** + * @author liuxinxin + * @date 2022/8/24 上午11:06 + * 钉钉组织结构树状结构 + */ +@Data +public class DingOrgInfoTreeDTO { + + /** + * 钉钉code码 + */ + private String code; + + /** + * 组织信息 + */ + private DingOrgInfoDTO dingOrgInfoDTO; + /** + * 子节点code + */ + private List childCodes; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/OrganizationBatchGetTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/OrganizationBatchGetTask.java new file mode 100644 index 0000000..9095702 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/OrganizationBatchGetTask.java @@ -0,0 +1,171 @@ + +package com.ningdatech.pmapi.ding.task; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.google.common.collect.Lists; +import com.ningdatech.basic.model.GenericResult; +import com.ningdatech.pmapi.ding.model.DingOrgInfoTreeDTO; +import com.ningdatech.pmapi.organization.entity.DingOrganization; +import com.ningdatech.pmapi.organization.service.IDingOrganizationService; +import com.ningdatech.zwdd.client.ZwddAuthClient; +import com.ningdatech.zwdd.client.ZwddClient; +import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO; +import com.ningdatech.zwdd.model.dto.DingScopesV2DTO; +import com.ningdatech.zwdd.model.dto.PageSubOrganizationCodeDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author liuxinxin + * @date 2023/2/7 上午10:15 + */ + +@Slf4j +@Component +public class OrganizationBatchGetTask { + + @Autowired + private ZwddClient zwddClient; + + @Autowired + private ZwddAuthClient zwddAuthClient; + + private static final Integer GROUP_SIZE = 100; + + @Autowired + private IDingOrganizationService iDingOrganizationService; + + /** + * 获取浙政钉组织架构 + */ + @Transactional(rollbackFor = Exception.class) + public void batchGetOrganizationTask() { +// List allList = iDingOrganizationService.list(); +// List currentAllOrganizationCodeList = allList.stream().map(DingOrganization::getOrganizationCode).collect(Collectors.toList()); + // 全量删除 + // iDingOrganizationService.remove(Wrappers.lambdaQuery(DingOrganization.class).isNotNull(DingOrganization::getId)); + // 获取顶级组织code + GenericResult scopesV2Result = zwddClient.getScopesV2(); + DingScopesV2DTO scopesV2 = scopesV2Result.getData(); + + if (Objects.nonNull(scopesV2)) { + // 顶级组织code + List deptVisibleScopes = scopesV2.getDeptVisibleScopes(); + log.info("顶级组织code: size = " + deptVisibleScopes.size() + "列表:" + JSONObject.toJSONString(deptVisibleScopes)); + // 获取顶级节点信息 + GenericResult> listGenericResult = zwddClient.listOrganizationsByCodes(deptVisibleScopes); + List dingOrgInfoDtos = listGenericResult.getData(); + for (String orgCode : deptVisibleScopes) { +// if (currentAllOrganizationCodeList.contains(orgCode)) { +// log.info("已存在组织架构---{}", orgCode); +// continue; +// } + List treeDTOList = new ArrayList<>(); + + DingOrgInfoTreeDTO childDingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); + //设置节点详情 + if (dingOrgInfoDtos != null && !dingOrgInfoDtos.isEmpty()) { + for (DingOrgInfoDTO orgInfo : dingOrgInfoDtos) { + if (orgInfo.getOrganizationCode().equals(orgCode)) { + childDingOrgInfoTreeDTO.setDingOrgInfoDTO(orgInfo); + } + } + } + childDingOrgInfoTreeDTO.setCode(orgCode); + childDingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); + getDingOrgChild(childDingOrgInfoTreeDTO); + treeDTOList.add(childDingOrgInfoTreeDTO); + + if (CollectionUtils.isNotEmpty(treeDTOList)) { + List saveRecordList = new ArrayList<>(); + buildSaveRecordList(treeDTOList, saveRecordList); + + // 批量保存 + if (saveRecordList.size() <= GROUP_SIZE) { + iDingOrganizationService.saveBatch(saveRecordList); + } else { + List> split = Lists.partition(saveRecordList, GROUP_SIZE); + for (List segment : split) { + iDingOrganizationService.saveBatch(segment); + } + } + } + log.info("----拉取浙政钉组织结构结束---,顶级code:" + orgCode); + } + } + } + + private void buildSaveRecordList(List treeDTOList, List saveRecordList) { + if (CollectionUtils.isEmpty(treeDTOList)) { + return; + } + for (DingOrgInfoTreeDTO dingOrgInfoTreeDTO : treeDTOList) { + DingOrganization saveRecord = new DingOrganization(); + DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO(); + List childCodes = dingOrgInfoTreeDTO.getChildCodes(); + saveRecord.setDisplayOrder(dingOrgInfoDTO.getDisplayOrder()); +// saveRecord.setEnabled("1"); + saveRecord.setParentCode(dingOrgInfoDTO.getParentCode()); + saveRecord.setOrganizationCode(dingOrgInfoDTO.getOrganizationCode()); +// saveRecord.setSubCount((long) dingOrgInfoTreeDTO.getChildCodes().size()); + saveRecord.setOrganizationName(dingOrgInfoDTO.getOrganizationName()); + saveRecordList.add(saveRecord); + if (CollectionUtils.isNotEmpty(childCodes)) { + buildSaveRecordList(childCodes, saveRecordList); + } + } + + } + + private void getDingOrgChild(DingOrgInfoTreeDTO parentDingOrgInfoTreeDTO) { + String parentOrgCode = parentDingOrgInfoTreeDTO.getCode(); + DingOrgInfoDTO orgInfoDTO = parentDingOrgInfoTreeDTO.getDingOrgInfoDTO(); + boolean leaf = orgInfoDTO.getLeaf(); + if (!leaf) { + int currentPage = 1; + int pageSize = 100; + GenericResult pageSubOrganizationCodeDTOGenericResult = zwddClient.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); + PageSubOrganizationCodeDTO pageSubOrganizationCodeDTO = pageSubOrganizationCodeDTOGenericResult.getData(); + + if (CollUtil.isNotEmpty(pageSubOrganizationCodeDTO.getSubOrganizationCodeList())) { + List subOrganizationCodeList = new ArrayList<>(pageSubOrganizationCodeDTO.getSubOrganizationCodeList()); + Long totalSize = pageSubOrganizationCodeDTO.getTotalSize(); + + while (totalSize > (long) currentPage * pageSize) { + GenericResult subPageSubOrganizationCodeDTOGenericResult = zwddClient + .pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); + PageSubOrganizationCodeDTO subOrganizationCodeDTO = subPageSubOrganizationCodeDTOGenericResult.getData(); + if (CollectionUtils.isNotEmpty(subOrganizationCodeDTO.getSubOrganizationCodeList())) { + subOrganizationCodeList.addAll(subOrganizationCodeDTO.getSubOrganizationCodeList()); + } + } + + if (CollectionUtils.isNotEmpty(subOrganizationCodeList)) { + GenericResult> listGenericResult = zwddClient + .listOrganizationsByCodes(subOrganizationCodeList); + List dingOrgInfoDtos = listGenericResult.getData(); + List dingOrgInfoTreeDTOList = dingOrgInfoDtos.stream().map(r -> { + DingOrgInfoTreeDTO dingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); + dingOrgInfoTreeDTO.setCode(r.getOrganizationCode()); + dingOrgInfoTreeDTO.setDingOrgInfoDTO(r); + dingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); + getDingOrgChild(dingOrgInfoTreeDTO); + return dingOrgInfoTreeDTO; + }).collect(Collectors.toList()); + parentDingOrgInfoTreeDTO.setChildCodes(dingOrgInfoTreeDTOList); + } + } + } + } + +} + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/controller/DingOrganizationController.java b/pmapi/src/main/java/com/ningdatech/pmapi/organization/controller/DingOrganizationController.java new file mode 100644 index 0000000..c86682d --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/controller/DingOrganizationController.java @@ -0,0 +1,20 @@ +package com.ningdatech.pmapi.organization.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.stereotype.Controller; + +/** + *

+ * 前端控制器 + *

+ * + * @author Lierbao + * @since 2023-02-09 + */ +@Controller +@RequestMapping("/pmapi.organization/ding-organization") +public class DingOrganizationController { + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/entity/DingOrganization.java b/pmapi/src/main/java/com/ningdatech/pmapi/organization/entity/DingOrganization.java new file mode 100644 index 0000000..25296fd --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/entity/DingOrganization.java @@ -0,0 +1,55 @@ +package com.ningdatech.pmapi.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author Lierbao + * @since 2023-02-09 + */ +@TableName("ding_organization") +@ApiModel(value = "DingOrganization对象", description = "") +@Data +public class DingOrganization implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String institutionLevelCode; + + private String address; + + private String organizationName; + + private Long displayOrder; + + private Long typeName; + + private Integer leaf; + + private LocalDateTime gmtCreate; + + private String typeCode; + + private String divisionCode; + + private String parentName; + + private String parentCode; + + private String organizationCode; + + private String businessStripCodes; + + private String status; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.java b/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.java new file mode 100644 index 0000000..b3fee77 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.java @@ -0,0 +1,16 @@ +package com.ningdatech.pmapi.organization.mapper; + +import com.ningdatech.pmapi.organization.entity.DingOrganization; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author Lierbao + * @since 2023-02-09 + */ +public interface DingOrganizationMapper extends BaseMapper { + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.xml b/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.xml new file mode 100644 index 0000000..e3e5708 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/mapper/DingOrganizationMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/IDingOrganizationService.java b/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/IDingOrganizationService.java new file mode 100644 index 0000000..b1b5ce3 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/IDingOrganizationService.java @@ -0,0 +1,16 @@ +package com.ningdatech.pmapi.organization.service; + +import com.ningdatech.pmapi.organization.entity.DingOrganization; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author Lierbao + * @since 2023-02-09 + */ +public interface IDingOrganizationService extends IService { + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/impl/DingOrganizationServiceImpl.java b/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/impl/DingOrganizationServiceImpl.java new file mode 100644 index 0000000..4c154cb --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/organization/service/impl/DingOrganizationServiceImpl.java @@ -0,0 +1,20 @@ +package com.ningdatech.pmapi.organization.service.impl; + +import com.ningdatech.pmapi.organization.entity.DingOrganization; +import com.ningdatech.pmapi.organization.mapper.DingOrganizationMapper; +import com.ningdatech.pmapi.organization.service.IDingOrganizationService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author Lierbao + * @since 2023-02-09 + */ +@Service +public class DingOrganizationServiceImpl extends ServiceImpl implements IDingOrganizationService { + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessComment.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessComment.java index 23a3e03..6a55fb4 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessComment.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessComment.java @@ -1,5 +1,6 @@ package com.ningdatech.pmapi.todocenter.bean.entity; +import com.ningdatech.pmapi.common.model.FileBasicInfo; import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; import lombok.AllArgsConstructor; import lombok.Builder; @@ -26,9 +27,9 @@ public class ProcessComment { /** * 评论附件 */ - protected List attachments; + protected List attachments; - public ProcessComment(String text, List attachments) { + public ProcessComment(String text, List attachments) { this.text = text; this.attachments = null == attachments ? Collections.emptyList() : attachments; } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java index fa2e2f7..db6e911 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java @@ -1,11 +1,10 @@ package com.ningdatech.pmapi.todocenter.bean.entity; import com.ningdatech.pmapi.todocenter.bean.vo.ProgressNodeAuditInfoVo; -import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; -import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; import com.wflow.workflow.bean.process.OrgUser; import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; import com.wflow.workflow.bean.process.enums.NodeTypeEnum; +import com.wflow.workflow.enums.ProcessHandlerEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java index f4c4f2f..2d1a8f0 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java @@ -128,5 +128,28 @@ public class TodoCenterController { ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportMySubmittedProjectList); } + /** + * 待办中心-抄送我的项目列表查询 + * @param param + * @return + */ + @GetMapping("/query-CcMe-list") + public ApiResponse> queryCcMeProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ + PageVo result = todoCenterManage.queryCcMeProjectList(param); + return ApiResponse.ofSuccess(result); + } + + /** + * 待办中心-抄送我的项目列表导出 + * + * @param param + * @param response + * @return void + */ + @GetMapping("/exportCcMe") + public void exportCcMeProjectList(ReqToBeProcessedDTO param, HttpServletResponse response){ + ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportCcMeProjectList); + } + } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessHandlerEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessHandlerEnum.java deleted file mode 100644 index bd67d5c..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessHandlerEnum.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.ningdatech.pmapi.todocenter.enums; - -import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.apache.commons.lang3.StringUtils; - -import java.util.Objects; - -/** - * 流程处理类型 - * @author CMM - * @since 2023/02/01 16:58 - */ -@Getter -@AllArgsConstructor -@NoArgsConstructor -@ApiModel(value = "ProcessHandlerEnum", description = "流程处理类型-枚举") -public enum ProcessHandlerEnum { - /** - * 通过 - */ - - PASS(1, "通过"), - - /** - * 盖章并通过 - */ - SEAL_PASS(2, "盖章并通过"), - - /** - * 退回 - */ - BACK(3,"退回"), - - /** - * 撤回 - */ - WITHDRAW(4,"撤回"), - /** - * 驳回 - */ - REJECT(5,"驳回"); - - - private Integer code; - private String desc; - - public String getDesc() { - return desc; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public static String getDescByCode(Integer code) { - if(Objects.isNull(code)){ - return StringUtils.EMPTY; - } - for (ProcessHandlerEnum t : ProcessHandlerEnum.values()) { - if (code.equals(t.getCode())) { - return t.desc; - } - } - return StringUtils.EMPTY; - } - - public static Integer getCodeByDesc(String desc) { - if(Objects.isNull(desc)){ - return null; - } - for (ProcessHandlerEnum t : ProcessHandlerEnum.values()) { - if (desc.equals(t.getCode())) { - return t.code; - } - } - return null; - } - - public static ProcessHandlerEnum getEnumByValue(Integer code) { - if(Objects.isNull(code)){ - return null; - } - for (ProcessHandlerEnum t : ProcessHandlerEnum.values()) { - if (code.equals(t.getCode())) { - return t; - } - } - return null; - } - - public boolean eq(String val) { - return this.name().equals(val); - } -} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java index 09872ea..ffe691d 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java @@ -4,7 +4,7 @@ import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; -import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; +import com.wflow.workflow.enums.ProcessHandlerEnum; import lombok.RequiredArgsConstructor; import org.assertj.core.util.Sets; import org.flowable.bpmn.model.FlowNode; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/SaveCommentCmd.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/SaveCommentCmd.java new file mode 100644 index 0000000..b5f18da --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/SaveCommentCmd.java @@ -0,0 +1,104 @@ +package com.ningdatech.pmapi.todocenter.extension.cmd; + +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.api.FlowableObjectNotFoundException; +import org.flowable.common.engine.impl.identity.Authentication; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.compatibility.Flowable5CompatibilityHandler; +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.persistence.entity.CommentEntity; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.impl.util.Flowable5Util; +import org.flowable.engine.runtime.Execution; +import org.flowable.engine.task.Comment; +import org.flowable.task.api.Task; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +/** + * 保存评论 + * + * @author CMM + * @since 2023/02/09 11:43 + */ + +public class SaveCommentCmd implements Command { + + protected String taskId; + protected String processInstanceId; + protected String userId; + protected String message; + protected String type; + + + public SaveCommentCmd(String taskId, String processInstanceId, String userId , String message) { + this.taskId = taskId; + this.processInstanceId = processInstanceId; + this.userId = userId; + this.message = message; + } + + @Override + public Comment execute(CommandContext commandContext) { + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); + TaskEntity task = null; + if (this.taskId != null) { + task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(this.taskId); + if (task == null) { + throw new FlowableObjectNotFoundException("Cannot find task with id " + this.taskId, Task.class); + } + + if (task.isSuspended()) { + throw new FlowableException(this.getSuspendedTaskException()); + } + } + + ExecutionEntity execution = null; + if (this.processInstanceId != null) { + execution = (ExecutionEntity)processEngineConfiguration.getExecutionEntityManager().findById(this.processInstanceId); + if (execution == null) { + throw new FlowableObjectNotFoundException("execution " + this.processInstanceId + " doesn't exist", Execution.class); + } + + if (execution.isSuspended()) { + throw new FlowableException(this.getSuspendedExceptionMessage()); + } + } + + String processDefinitionId = null; + if (execution != null) { + processDefinitionId = execution.getProcessDefinitionId(); + } else if (task != null) { + processDefinitionId = task.getProcessDefinitionId(); + } + + if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, processDefinitionId)) { + Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler(); + return compatibilityHandler.addComment(this.taskId, this.processInstanceId, this.type, this.message); + } else { + CommentEntity comment = (CommentEntity)processEngineConfiguration.getCommentEntityManager().create(); + comment.setUserId(userId); + comment.setType(this.type == null ? "comment" : this.type); + comment.setTime(processEngineConfiguration.getClock().getCurrentTime()); + comment.setTaskId(this.taskId); + comment.setProcessInstanceId(this.processInstanceId); + comment.setAction("AddComment"); + String eventMessage = this.message.replaceAll("\\s+", " "); + if (eventMessage.length() > 163) { + eventMessage = eventMessage.substring(0, 160) + "..."; + } + + comment.setMessage(eventMessage); + comment.setFullMessage(this.message); + processEngineConfiguration.getCommentEntityManager().insert(comment); + return comment; + } + } + protected String getSuspendedTaskException() { + return "Cannot add a comment to a suspended task"; + } + protected String getSuspendedExceptionMessage() { + return "Cannot add a comment to a suspended execution"; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index 42c8ebb..9274167 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -19,7 +19,6 @@ import com.ningdatech.basic.exception.BizException; import com.ningdatech.basic.model.PageVo; import com.ningdatech.basic.util.NdDateUtils; import com.ningdatech.pmapi.common.constant.DingConstant; -import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants; import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.common.util.ExcelExportStyle; @@ -31,15 +30,12 @@ import com.ningdatech.pmapi.todocenter.bean.entity.ProgressNode; import com.ningdatech.pmapi.todocenter.bean.vo.ProcessProgressDetailVo; import com.ningdatech.pmapi.todocenter.constant.HisProInsEndActId; import com.ningdatech.pmapi.todocenter.enums.IsAppendProjectEnum; -import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; import com.ningdatech.pmapi.todocenter.enums.ProcessStatusEnum; import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; +import com.ningdatech.pmapi.todocenter.extension.cmd.SaveCommentCmd; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedDTO; -import com.ningdatech.pmapi.todocenter.model.dto.res.ResHandledExportDTO; -import com.ningdatech.pmapi.todocenter.model.dto.res.ResMySubmittedExportDTO; -import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO; -import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeExportDTO; +import com.ningdatech.pmapi.todocenter.model.dto.res.*; import com.ningdatech.pmapi.todocenter.zwdd.model.MessageContent; import com.ningdatech.pmapi.todocenter.zwdd.model.MessageText; import com.ningdatech.pmapi.user.entity.UserInfo; @@ -63,9 +59,9 @@ import com.wflow.workflow.bean.process.form.Form; import com.wflow.workflow.bean.process.props.ApprovalProps; import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; import com.wflow.workflow.bean.vo.ProcessInstanceVo; -import com.wflow.workflow.bean.vo.ProcessProgressVo; import com.wflow.workflow.bean.vo.ProcessTaskVo; import com.wflow.workflow.config.WflowGlobalVarDef; +import com.wflow.workflow.enums.ProcessHandlerEnum; import com.wflow.workflow.service.FormService; import com.wflow.workflow.service.*; import com.wflow.workflow.utils.Executor; @@ -79,6 +75,7 @@ import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.impl.util.ProcessDefinitionUtil; +import org.flowable.engine.runtime.ActivityInstance; import org.flowable.engine.runtime.Execution; import org.flowable.task.api.Task; import org.flowable.task.api.TaskInfo; @@ -86,6 +83,7 @@ import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; import org.flowable.variable.api.history.HistoricVariableInstance; +import org.flowable.variable.api.history.NativeHistoricVariableInstanceQuery; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Component; @@ -233,7 +231,7 @@ public class TodoCenterManage { .sheet(fileName) .doWrite(collect); } catch (IOException e) { - throw new RuntimeException(e); + throw new BizException("导出失败!"); } } /** @@ -244,28 +242,32 @@ public class TodoCenterManage { * @since 2023/02/01 17:43 */ public void handler(ReqProcessHandlerDTO param) { - Long userId = LoginUserUtil.getUserId(); + + // 获取登录用户ID + // Long userId = LoginUserUtil.getUserId(); + + Long userId = 381496L; + Task task = taskService.createTaskQuery().taskId(param.getTaskId()).active().singleResult(); HashMap formData = new HashMap<>(32); if (Objects.isNull(task)) { throw new BizException("任务不存在"); } - if (hasComment(param.getAuditInfo())) { - taskService.addComment(param.getTaskId(), param.getInstanceId(), JSONObject.toJSONString(param.getAuditInfo())); - } switch (param.getAction()) { // 通过 case PASS: formService.updateInstanceFormData(param.getInstanceId(), formData); - doPass(task, param); + doPass(task, userId, param); + break; // 盖章并通过 case SEAL_PASS: formService.updateInstanceFormData(param.getInstanceId(), formData); - doSealPass(task, param); + doSealPass(task, userId, param); + break; // 驳回 case REJECT: formService.updateInstanceFormData(param.getInstanceId(), formData); - doReject(task, param); + doReject(task, userId, param); break; // 退回 case BACK: @@ -274,7 +276,7 @@ public class TodoCenterManage { break; // 撤回 case WITHDRAW: - doWithDrawProcess(task); + doWithDrawProcess(task,userId); break; default: throw new IllegalStateException("Unexpected value: " + param.getAction()); @@ -283,16 +285,22 @@ public class TodoCenterManage { /** * 审批任务:驳回 + * * @param task 当前任务 - * @param param 参数 + * @param userId + * @param param 参数 */ - private void doReject(Task task, ReqProcessHandlerDTO param) { + private void doReject(Task task, Long userId, ReqProcessHandlerDTO param) { + // 获取当前申报项目 + Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) + .eq(Project::getInstCode, task.getProcessInstanceId())); + String projectName = declaredProject.getProjectName(); + Map var = new HashMap<>(16); var.put("approve_" + task.getId(), param.getAction()); // TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 //获取流程定义 Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); - String projectName = getProjectName(task); // 获取根节点即流程发起节点 FlowNode rootNode = (FlowNode) process.getFlowElement("root", true); // TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 @@ -350,68 +358,83 @@ public class TodoCenterManage { /** * 审批任务:盖章并通过 + * * @param task 当前任务 - * @param param 参数 + * @param userId + * @param param 参数 */ - private void doSealPass(Task task, ReqProcessHandlerDTO param) { + private void doSealPass(Task task, Long userId, ReqProcessHandlerDTO param) { Map var = new HashMap<>(16); var.put("approve_" + task.getId(), param.getAction()); + // TODO 判断项目申报单位级别,区县单位申报有上级主管单位意见栏,市级单位没有 // TODO 市级单位:为大数据局;区县单位:为大数据中心(根据附件区分?) - + // 获取当前申报项目 + Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) + .eq(Project::getInstCode, task.getProcessInstanceId())); // 更新项目状态到下一个状态 - updatePassProjectStatus(task); + updatePassProjectStatus(task, userId, declaredProject); taskService.complete(param.getTaskId(), var); } /** * 审批任务:通过 + * * @param task 当前任务 - * @param param 参数 + * @param userId + * @param param 参数 */ - private void doPass(Task task, ReqProcessHandlerDTO param) { + private void doPass(Task task, Long userId, ReqProcessHandlerDTO param) { + String processInstanceId = task.getProcessInstanceId(); + // 获取当前申报项目 + Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) + .eq(Project::getInstCode, task.getProcessInstanceId())); + String projectName = declaredProject.getProjectName(); - String projectName = getProjectName(task); Map var = new HashMap<>(16); var.put("approve_" + task.getId(), param.getAction()); - //获取流程定义 - Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); - // 获取当前节点 - FlowNode currentNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey(), true); - // 获取流程下一个节点浙政钉用户ID - String nextUserId = getNextUserId(currentNode); + // 保存审核意见 + if (hasComment(param.getAuditInfo())) { + //执行自定义的保存评论的功能 + managementService.executeCommand(new SaveCommentCmd(param.getTaskId(),param.getInstanceId(),String.valueOf(userId),JSONObject.toJSONString(param.getAuditInfo()))); + } + updatePassProjectStatus(task,userId,declaredProject); + taskService.complete(param.getTaskId(), var); + + // 获取bpm对象 + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + //传节点定义key 获取当前节点 + FlowNode currentNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey()); + + // 获取流程下一个节点的审核用户ID + String nextUserId = getNextUserId(currentNode,processInstanceId); // 若有下一个审核人,向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 if (Objects.nonNull(nextUserId)){ UserInfo auditUserInfo = userInfoService.getById(Long.valueOf(nextUserId)); - // TODO 向其发送浙政钉工作通知 + // TODO 获取浙政钉用户dingKey,向其发送浙政钉工作通知 String msg = String.format(PASS_MSG_TEMPLATE,null,projectName); - sendWorkNotice(auditUserInfo,msg); + // sendWorkNotice(auditUserInfo,msg); }else { // 若没有,向发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 // TODO 向其发送浙政钉工作通知 获取根节点的孩子节点(即发起人节点),向其发送浙政钉工作通知 // 获取根节点即流程发起节点 - FlowNode rootNode = (FlowNode) process.getFlowElement("root", true); - sendWorkNoticeToStartUser(task, projectName, rootNode); + FlowNode rootNode = (FlowNode) bpmnModel.getFlowElement("root"); + // sendWorkNoticeToStartUser(task, projectName, rootNode); } - - updatePassProjectStatus(task); - taskService.complete(param.getTaskId(), var); } /** * 当为通过操作时,更新项目表中项目状态 - * @param task 当前任务 + * + * @param task 当前任务 + * @param userId + * @param declaredProject * @return void * @author CMM * @since 2023/02/08 20:38 */ - private void updatePassProjectStatus(Task task) { - // 获取当前登录用户 - Long userId = LoginUserUtil.getUserId(); - // 获取当前申报项目 - Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) - .eq(Project::getInstCode, task.getProcessInstanceId())); + private void updatePassProjectStatus(Task task, Long userId, Project declaredProject) { // 获取当前流程项目状态 Integer projectStatusSecond = declaredProject.getProjectStatusSecond(); // 根据当前状态获取对应的通过事件 @@ -474,13 +497,15 @@ public class TodoCenterManage { } /** - * 获取当前节点的下一个节点的浙政钉用户ID - * @param currentNode 当前节点 + * 获取当前节点的下一个节点的审核用户ID + * + * @param currentNode 当前节点 + * @param processInstanceId * @return java.lang.String 下一个节点的浙政钉用户ID * @author CMM * @since 2023/02/02 16:49 */ - private String getNextUserId(FlowNode currentNode) { + private String getNextUserId(FlowNode currentNode, String processInstanceId) { String nextUserId = null; // 输出连线 List outgoingFlows = currentNode.getOutgoingFlows(); @@ -488,32 +513,25 @@ public class TodoCenterManage { for (SequenceFlow currentOutgoingFlow : outgoingFlows) { // 类型自己判断 FlowElement targetFlowElement = currentOutgoingFlow.getTargetFlowElement(); + // 如果下个审批节点为结束节点,那么跳过该节点 + if (targetFlowElement instanceof EndEvent){ + continue; + } // TODO 若要会签需判断候选人 // 用户任务 if (targetFlowElement instanceof UserTask) { - UserTask userTask = (UserTask) targetFlowElement; - nextUserId = userTask.getAssignee(); + String actId = targetFlowElement.getId(); + ActivityInstance activityInstance = runtimeService.createActivityInstanceQuery() + .processInstanceId(processInstanceId) + .activityId(actId).singleResult(); + String executionId = activityInstance.getExecutionId(); + nextUserId = runtimeService.getVariable(executionId, "assignee", String.class); break; } } return nextUserId; } /** - * 获取任务节点的申报项目名称 - * @param task 当前任务 - * @return java.lang.String 项目名称 - * @author CMM - * @since 2023/02/01 17:27 - */ - private String getProjectName(Task task) { - String nodeId = task.getTaskDefinitionKey(); - String instanceId = task.getProcessInstanceId(); - ProcessProgressVo instanceProgress = processService.getInstanceProgress(nodeId, instanceId); - Map formData = instanceProgress.getFormData(); - String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); - return projectName; - } - /** * 判断处理操作是否含有审核意见 * @param comment 审核意见 * @return boolean @@ -563,9 +581,10 @@ public class TodoCenterManage { /** * 撤销流程处理 * - * @param task 当前任务 + * @param task 当前任务 + * @param userId */ - private void doWithDrawProcess(Task task) { + private void doWithDrawProcess(Task task, Long userId) { //获取流程定义 Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); // 获取当前运行流程的发起人节点信息 @@ -574,7 +593,6 @@ public class TodoCenterManage { FlowNode currentNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey(), true); String rootUserId = getRootUserId(rootNode); // 判断当前登录用户是否是流程发起人 - Long userId = LoginUserUtil.getUserId(); if (rootUserId.equals(String.valueOf(userId))){ // TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 updateWithdrawProjectStatus(task, userId); @@ -618,7 +636,7 @@ public class TodoCenterManage { /** * 当为撤回操作时,更新项目表中的项目状态为前一个状态 - * @param task + * @param task 当前任务 * @param userId * @return void * @author CMM @@ -652,8 +670,10 @@ public class TodoCenterManage { * @param param 参数 */ private void doBackTask(Task task, Long userId, ReqProcessHandlerDTO param) { - // 获取项目名称 - String projectName = getProjectName(task); + // 获取当前申报项目 + Project declaredProject = projectService.getOne(Wrappers.lambdaQuery(Project.class) + .eq(Project::getInstCode, task.getProcessInstanceId())); + String projectName = declaredProject.getProjectName(); //获取流程定义 Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); // 获取根节点即流程发起节点 @@ -679,7 +699,7 @@ public class TodoCenterManage { HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult(); List formDatas = historyService.createHistoricVariableInstanceQuery() - .processInstanceId(instanceId).variableNameLike("field%").list(); + .processInstanceId(instanceId).list(); // 取节点设置 HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); @@ -944,7 +964,7 @@ public class TodoCenterManage { .sheet(fileName) .doWrite(collect); } catch (IOException e) { - throw new RuntimeException(e); + throw new BizException("导出失败!"); } } @@ -1087,8 +1107,87 @@ public class TodoCenterManage { .sheet(fileName) .doWrite(collect); } catch (IOException e) { - throw new RuntimeException(e); + throw new BizException("导出失败!"); } } + + public PageVo queryCcMeProjectList(ReqToBeProcessedDTO param) { + // 获取当前登录用户ID + // Long userId = LoginUserUtil.getUserId(); + + Long userId = 381496L; + Page page = param.page(); + Set staterUsers = new HashSet<>(); + List ccTasks = ccTasksMapper.selectList(Wrappers.lambdaQuery(WflowCcTasks.class) + .eq(WflowCcTasks::getUserId, String.valueOf(userId)) + .orderByDesc(WflowCcTasks::getCreateTime)); + + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(Project.class); + wrapper.like(StrUtil.isNotBlank(param.getProjectName()),Project::getProjectName,param.getProjectName()) + .like(StrUtil.isNotBlank(param.getBuildUnitName()),Project::getBuildUnitName,param.getBuildUnitName()) + .eq(Objects.nonNull(param.getProjectYear()),Project::getProjectYear,param.getProjectYear()) + .eq(Objects.nonNull(param.getIsSupplement()),Project::getIsTemporaryAugment,param.getIsSupplement()) + .ge(Objects.nonNull(param.getProcessLaunchStartTime()),Project::getBeginTime,param.getProcessLaunchStartTime()) + .le(Objects.nonNull(param.getProcessLaunchEndTime()),Project::getEndTime,param.getProcessLaunchEndTime()); + projectService.page(page,wrapper); + + // 将抄送我的流程实例一次性取出来,减少查询次数 + Map instanceMap = CollectionUtil.isNotEmpty(ccTasks) ? + historyService.createHistoricProcessInstanceQuery().processInstanceIds(ccTasks.stream() + .map(WflowCcTasks::getInstanceId).collect(Collectors.toSet())) + .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) : new HashMap<>(); + List processInsIds = ccTasks.stream().map(WflowCcTasks::getInstanceId).collect(Collectors.toList()); + List resVos = page.getRecords().stream().filter(d -> processInsIds.contains(d.getInstCode())).map(d -> { + ResToBeProcessedDTO res = new ResToBeProcessedDTO(); + BeanUtils.copyProperties(d, res); + res.setProcessStatusName(ProcessStatusEnum.getDescByCode(d.getProcessStatus())); + LocalDateTime processLaunchTime = d.getCreateOn(); + String launchTimeFormat = NdDateUtils.format(processLaunchTime, "yyyy-MM-dd HH:mm"); + LocalDateTime launchTime = LocalDateTime.parse(launchTimeFormat, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + res.setProcessLaunchTime(launchTime); + HistoricProcessInstance ist = instanceMap.get(d.getInstCode()); + staterUsers.add(ist.getStartUserId()); + ProcessInstanceVo processInstanceVo = getProcessInstanceVos(ist); + res.setProcessInstanceInfo(processInstanceVo); + return res; + }).collect(Collectors.toList()); + + if (CollectionUtil.isNotEmpty(staterUsers)) { + Map userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); + resVos.stream().map(v -> { + v.getProcessInstanceInfo().setStaterUser(userMap.get(v.getProcessInstanceInfo().getStaterUserId())); + return v; + }).collect(Collectors.toList()); + } + + //if (CollectionUtil.isNotEmpty(staterUsers)) { + // Map userMap = userInfoService.getUserMapByIds(staterUsers); + // resVos.stream().peek(v -> v.setOwner(userMap.get(startUserId))) + // .collect(Collectors.toList()); + //} + return PageVo.of(resVos,resVos.size()); + } + + public void exportCcMeProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { + PageVo page = queryCcMeProjectList(param); + List collect = (List) page.getRecords(); + String fileName = null; + if (IsAppendProjectEnum.APPEND_PROJECT.getCode().equals(param.getIsSupplement())){ + fileName = "待办中心_抄送我的_增补项目列表"; + }else if (IsAppendProjectEnum.NOT_APPEND_PROJECT.getCode().equals(param.getIsSupplement())){ + fileName = "待办中心_抄送我的_非增补项目列表"; + } + ExcelDownUtil.setFileName(fileName,response); + //数据导出处理函数 + try { + EasyExcel.write(response.getOutputStream(), ResCcMeExportDTO.class) + .autoCloseStream(false) + .registerWriteHandler(ExcelExportStyle.formalStyle()) + .sheet(fileName) + .doWrite(collect); + } catch (IOException e) { + throw new BizException("导出失败!"); + } + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java index 3a8bbb1..c6c307c 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java @@ -1,11 +1,10 @@ package com.ningdatech.pmapi.todocenter.model.dto.req; -import com.ningdatech.pmapi.common.model.FileBasicInfo; + import com.ningdatech.pmapi.todocenter.bean.entity.ProcessComment; -import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; +import com.wflow.workflow.enums.ProcessHandlerEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; /** * 流程处理操作参数实体 @@ -47,43 +46,4 @@ public class ReqProcessHandlerDTO { * 审核信息 */ private ProcessComment auditInfo; - ///** - // * 审核通过意见 - // */ - //private String auditPassOpinion; - // - ///** - // * 审核通过附件 - // */ - //private FileBasicInfo auditPassAppendix; - ///** - // * 盖章通过意见 - // */ - //private String sealPassOpinion; - // - ///** - // * 盖章通过附件 - // */ - //private FileBasicInfo sealPassAppendix; - ///** - // * 审核退回意见 - // */ - //private String auditBackOpinion; - ///** - // * 审核退回附件 - // */ - //private FileBasicInfo auditBackAppendix; - ///** - // * 审核驳回意见 - // */ - //private String auditRejectOpinion; - // - ///** - // * 审核驳回附件 - // */ - //private FileBasicInfo auditRejectAppendix; - //public enum Action{ - // //通过、盖章并通过、退回、撤回、驳回 - // pass, seal_pass ,back, withdraw, reject; - //} } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResCcMeExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResCcMeExportDTO.java new file mode 100644 index 0000000..5c43aee --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResCcMeExportDTO.java @@ -0,0 +1,41 @@ +package com.ningdatech.pmapi.todocenter.model.dto.res; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 待办中心抄送我的项目列表导出实体 + * + * @author CMM + * @since 2023/01/19 16:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ResCcMeExportDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ExcelProperty("项目名称") + private String projectName; + + @ExcelProperty("申报单位") + private String reportUnitName; + + @ExcelProperty("申报金额") + private Integer reportAmount; + + @ExcelProperty("预算年度") + private Integer budgetYear; + + @ExcelProperty("流程状态") + private String processStatusName; + + @ExcelProperty("发起时间") + private LocalDateTime processLaunchTime; +} diff --git a/pmapi/src/main/resources/application-dev.yml b/pmapi/src/main/resources/application-dev.yml index 64e12f0..e0ddb64 100644 --- a/pmapi/src/main/resources/application-dev.yml +++ b/pmapi/src/main/resources/application-dev.yml @@ -158,12 +158,9 @@ sa-token: #专有钉钉 ding: #扫码 - app-auth-key: file-manage_dingoa-zte2LbiAfIj - app-auth-secret: H794aFZf271QbfUr50pbBpBTlXSrWIP71q9RTR34 - #扫码 - app-sso-auth-key: fgdn_wjlzjkxt_hz - app-sso-auth-secret: dafe1e6f7d424032acb81f5c2a797a1f - #免登/获取信息 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 app-key: file-manage-4Mjx9358wuxjyYFjY3 app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 diff --git a/pmapi/src/main/resources/integration/zwdd-dev.yml b/pmapi/src/main/resources/integration/zwdd-dev.yml new file mode 100644 index 0000000..2acb0d9 --- /dev/null +++ b/pmapi/src/main/resources/integration/zwdd-dev.yml @@ -0,0 +1,20 @@ +#专有钉钉 +integration: + zzd: + #扫码 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 + # app-key: file-manage-4Mjx9358wuxjyYFjY3 + # app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + app-key: ls_rebuild-10c8n5X0707yFV7jURr + app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn + +# integration.zzd.enabled=true +# #扫码 +# integration.zzd.app-auth-key=file-manage_dingoa-zte2LbiAfIj +# integration.zzd.app-auth-secret=H794aFZf271QbfUr50pbBpBTlXSrWIP71q9RTR34 +# integration.zzd.domain=openplatform.dg-work.cn \ No newline at end of file diff --git a/pmapi/src/main/resources/integration/zwdd-prod.yml b/pmapi/src/main/resources/integration/zwdd-prod.yml new file mode 100644 index 0000000..0073994 --- /dev/null +++ b/pmapi/src/main/resources/integration/zwdd-prod.yml @@ -0,0 +1,11 @@ +#专有钉钉 +ding: + #扫码 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 + app-key: file-manage-4Mjx9358wuxjyYFjY3 + app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn \ No newline at end of file diff --git a/pmapi/src/test/java/com/ningdatech/pmapi/organization/OrganizationTest.java b/pmapi/src/test/java/com/ningdatech/pmapi/organization/OrganizationTest.java new file mode 100644 index 0000000..0fd3585 --- /dev/null +++ b/pmapi/src/test/java/com/ningdatech/pmapi/organization/OrganizationTest.java @@ -0,0 +1,31 @@ +package com.ningdatech.pmapi.organization; + +import com.ningdatech.pmapi.AppTests; +import com.ningdatech.pmapi.ding.task.OrganizationBatchGetTask; +import com.ningdatech.zwdd.client.ZwddAuthClient; +import com.ningdatech.zwdd.client.ZwddClient; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author liuxinxin + * @date 2023/2/9 下午3:54 + */ + +class OrganizationTest extends AppTests { + + @Autowired + private ZwddClient zwddClient; + + @Autowired + private ZwddAuthClient zwddAuthClient; + + @Autowired + private OrganizationBatchGetTask organizationBatchGetTask; + + @Test + public void testBatchGetOrganization() { + organizationBatchGetTask.batchGetOrganizationTask(); + } + +} diff --git a/pmapi/src/test/resources/application-dev.yml b/pmapi/src/test/resources/application-dev.yml new file mode 100644 index 0000000..7727198 --- /dev/null +++ b/pmapi/src/test/resources/application-dev.yml @@ -0,0 +1,168 @@ +server: + port: 28888 + servlet: + context-path: /pm + +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + session: + store-type: redis + redis: + namespace: "spring:session" + redis: + timeout: 5000 + host: 47.98.125.47 + port: 26379 + database: 0 + password: Ndkj1234 + jedis: + pool: + max-active: 200 + max-idle: 500 + min-idle: 8 + max-wait: 10000 + application: + name: pm + jackson: + default-property-inclusion: non_null + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + jpa: + properties: + hibernate: + default_schema: PUBLIC + hbm2ddl: + auto: update + show_sql: true + show-sql: true + hibernate: + ddl-auto: update + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.kingbase8.Driver + # 数据源 + druid: + url: jdbc:kingbase8://120.26.44.207:54321/nd_project_management?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8 + username: SYSTEM + password: Ndkj1234 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + #mysql使用:SELECT 1 FROM DUAL + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: admin + login-password: admin + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + global-config: + db-config: + logic-delete-value: true + logic-not-delete-value: false +logging: + config: classpath:logback-spring.xml +#日志配置 + level: + root: info + file: + path: logs +nd: + log: + enabled: true + type: DB +# 日志文件配置 +log: + path: ./logs + info: + file-size: 50MB + max-size: 5 + total-size: 200MB + error: + file-size: 10MB + max-size: 5 + total-size: 50MB + +swagger: + enabled: true + +flowable: + async-executor-activate: true + #关闭一些不需要的功能服务 + rest-api-enabled: false + idm: + enabled: false + common: + enabled: false + dmn: + enabled: false + form: + enabled: false + app: + enabled: false + +wflow: + file: + max-size: 20 #最大文件上传大小,MB + +sa-token: + # token 名称 (同时也是cookie名称) + token-name: wflowToken + # token 有效期,单位s 默认30天, -1代表永不过期 + timeout: 172800 + # token 临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 + activity-timeout: -1 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: false + # token风格 + token-style: uuid + # 是否输出操作日志 + is-log: false + +#专有钉钉 +ding: + #扫码 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 + app-key: file-manage-4Mjx9358wuxjyYFjY3 + app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn \ No newline at end of file diff --git a/pmapi/src/test/resources/application-prod.yml b/pmapi/src/test/resources/application-prod.yml new file mode 100644 index 0000000..e69de29 diff --git a/pmapi/src/test/resources/application.yml b/pmapi/src/test/resources/application.yml new file mode 100644 index 0000000..3d7808a --- /dev/null +++ b/pmapi/src/test/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev diff --git a/pmapi/src/test/resources/integration/zwdd-dev.yml b/pmapi/src/test/resources/integration/zwdd-dev.yml new file mode 100644 index 0000000..b2bbff9 --- /dev/null +++ b/pmapi/src/test/resources/integration/zwdd-dev.yml @@ -0,0 +1,14 @@ +#专有钉钉 +integration: + zwdd: + #扫码 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 +# app-key: file-manage-4Mjx9358wuxjyYFjY3 +# app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + app-key: ls_rebuild-10c8n5X0707yFV7jURr + app-secret: gN8J3WazyXLMWKDuFmx6C4yaH5lFUY41x8rYLLo6 + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn \ No newline at end of file diff --git a/pmapi/src/test/resources/integration/zwdd-prod.yml b/pmapi/src/test/resources/integration/zwdd-prod.yml new file mode 100644 index 0000000..0073994 --- /dev/null +++ b/pmapi/src/test/resources/integration/zwdd-prod.yml @@ -0,0 +1,11 @@ +#专有钉钉 +ding: + #扫码 + app-auth-key: expert-base_dingoa-c5nnefYVnie + app-auth-secret: nm8qtST8uK431HYrjr7srcE23sT4889QgMcYFM3L + # #免登/获取信息 + app-key: file-manage-4Mjx9358wuxjyYFjY3 + app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn \ No newline at end of file diff --git a/pmapi/src/test/resources/logback-spring.xml b/pmapi/src/test/resources/logback-spring.xml new file mode 100644 index 0000000..75f5472 --- /dev/null +++ b/pmapi/src/test/resources/logback-spring.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + ${logPath}/info.log + + ${logPath}/info-%d{yyyyMMdd}-%i.log + + ${infoFileSize} + + ${infoMaxSize} + ${infoTotalSize} + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n + + + UTF-8 + + + + + + ERROR + + ${logPath}/error.log + + ${logPath}/error-%d{yyyyMMdd}-%i.log + + ${errorFileSize} + + ${errorMaxSize} + ${errorTotalSize} + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n + + + UTF-8 + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n + + UTF-8 + + + DEBUG + + + + + + + + + diff --git a/pmapi/src/test/resources/security/auth-dev.yml b/pmapi/src/test/resources/security/auth-dev.yml new file mode 100644 index 0000000..448ffa2 --- /dev/null +++ b/pmapi/src/test/resources/security/auth-dev.yml @@ -0,0 +1,52 @@ +security: + auth: + auth-require-url: /api/v1/user/auth/auth-require + invalid-session-url: /api/v1/user/auth/invalid-session + password-login-url: /api/v1/user/auth/login/password + logout-url: /api/v1/user/auth/logout + ignore-auth-urls: + - /v2/api-docs + - /swagger-ui.html + - /webjars/** + - /swagger-resources/** + - /webjars/ + - /api/v1/user/auth/register + - /api/v1/user/auth/auth-require + - /api/v1/user/auth/invalid-session + - /api/v1/user/auth/login/password + - /api/v1/user/auth/forget-password + - /api/v1/** + - /doc.html + - /ok.html + - /open/api/** + - /oa/** + - /wflow/** + - /sys/** + ignore-csrf-urls: + - /api/v1/user/auth/** + - /v2/api-docs + - /swagger-ui.html + - /webjars/** + - /swagger-resources/** + - /webjars/ + - /doc.html + - /ok.html + - /api/v1/** + - /file/** + - /optLog/** + - /dict/** + - /oa/** + - /wflow/** + - /sys/** + role-map: + "engineer": + "project_manager": + - /api/v1/user-info/kick-off/** + "enterprise_admin": + "regional_general_manager": + "driver": + "super_admin": + - /api/v1/user-info/save + - /api/v1/user-info/del + - /api/v1/user-info/kick-off/** + - /api/v1/user-info/password/mod \ No newline at end of file diff --git a/pmapi/src/test/resources/security/auth-prod.yml b/pmapi/src/test/resources/security/auth-prod.yml new file mode 100644 index 0000000..37e3281 --- /dev/null +++ b/pmapi/src/test/resources/security/auth-prod.yml @@ -0,0 +1,41 @@ +security: + auth: + auth-require-url: /api/v1/user/auth/auth-require + invalid-session-url: /api/v1/user/auth/invalid-session + password-login-url: /api/v1/user/auth/login/password + logout-url: /api/v1/user/auth/logout + ignore-auth-urls: + - /v2/api-docs + - /swagger-ui.html + - /webjars/** + - /swagger-resources/** + - /webjars/ + - /api/v1/user/auth/register + - /api/v1/user/auth/login/password + - /api/v1/user/auth/forget-password + - /doc.html + - /ok.html + ignore-csrf-urls: + - /api/v1/user/auth/** + - /v2/api-docs + - /swagger-ui.html + - /webjars/** + - /swagger-resources/** + - /webjars/ + - /doc.html + - /ok.html + - /api/v1/** + - /file/** + - /optLog/** + - /dict/** + role-map: + "engineer": + "project_manager": + "enterprise_admin": + "regional_general_manager": + "driver": + "super_admin": + - /api/v1/user-info/save + - /api/v1/user-info/del + - /api/v1/user-info/kick-off/** + - /api/v1/user-info/password/mod \ No newline at end of file