@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { | |||||
} | } | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
generate("WendyYang", "projectlib", PATH_YYD, "nd_project_application"); | |||||
generate("Lierbao", "organization", PATH_LXX, "ding_organization"); | |||||
} | } | ||||
} | } |
@@ -44,15 +44,15 @@ public class GovDingProperties { | |||||
GovDingProperties.appAuthsecret = appAuthsecret; | 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}") | @Value("${ding.tenantId}") | ||||
public void setTenantId(Long tenantId) { | public void setTenantId(Long tenantId) { | ||||
@@ -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万项目状态变为:省级部门联审中;否则项目状态变为:预审中) | * 预审申报(项目状态进入:待预审选择,有判断条件:市级项目且申报金额大于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), | |||||
/** | /** | ||||
* 年度计划暂缓(项目状态变为:被暂缓) | * 年度计划暂缓(项目状态变为:被暂缓) | ||||
*/ | */ | ||||
@@ -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<DingOrgInfoTreeDTO> childCodes; | |||||
} |
@@ -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<DingOrganization> allList = iDingOrganizationService.list(); | |||||
// List<String> currentAllOrganizationCodeList = allList.stream().map(DingOrganization::getOrganizationCode).collect(Collectors.toList()); | |||||
// 全量删除 | |||||
// iDingOrganizationService.remove(Wrappers.lambdaQuery(DingOrganization.class).isNotNull(DingOrganization::getId)); | |||||
// 获取顶级组织code | |||||
GenericResult<DingScopesV2DTO> scopesV2Result = zwddClient.getScopesV2(); | |||||
DingScopesV2DTO scopesV2 = scopesV2Result.getData(); | |||||
if (Objects.nonNull(scopesV2)) { | |||||
// 顶级组织code | |||||
List<String> deptVisibleScopes = scopesV2.getDeptVisibleScopes(); | |||||
log.info("顶级组织code: size = " + deptVisibleScopes.size() + "列表:" + JSONObject.toJSONString(deptVisibleScopes)); | |||||
// 获取顶级节点信息 | |||||
GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient.listOrganizationsByCodes(deptVisibleScopes); | |||||
List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
for (String orgCode : deptVisibleScopes) { | |||||
// if (currentAllOrganizationCodeList.contains(orgCode)) { | |||||
// log.info("已存在组织架构---{}", orgCode); | |||||
// continue; | |||||
// } | |||||
List<DingOrgInfoTreeDTO> 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<DingOrganization> saveRecordList = new ArrayList<>(); | |||||
buildSaveRecordList(treeDTOList, saveRecordList); | |||||
// 批量保存 | |||||
if (saveRecordList.size() <= GROUP_SIZE) { | |||||
iDingOrganizationService.saveBatch(saveRecordList); | |||||
} else { | |||||
List<List<DingOrganization>> split = Lists.partition(saveRecordList, GROUP_SIZE); | |||||
for (List<DingOrganization> segment : split) { | |||||
iDingOrganizationService.saveBatch(segment); | |||||
} | |||||
} | |||||
} | |||||
log.info("----拉取浙政钉组织结构结束---,顶级code:" + orgCode); | |||||
} | |||||
} | |||||
} | |||||
private void buildSaveRecordList(List<DingOrgInfoTreeDTO> treeDTOList, List<DingOrganization> saveRecordList) { | |||||
if (CollectionUtils.isEmpty(treeDTOList)) { | |||||
return; | |||||
} | |||||
for (DingOrgInfoTreeDTO dingOrgInfoTreeDTO : treeDTOList) { | |||||
DingOrganization saveRecord = new DingOrganization(); | |||||
DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||||
List<DingOrgInfoTreeDTO> 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<PageSubOrganizationCodeDTO> pageSubOrganizationCodeDTOGenericResult = zwddClient.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
PageSubOrganizationCodeDTO pageSubOrganizationCodeDTO = pageSubOrganizationCodeDTOGenericResult.getData(); | |||||
if (CollUtil.isNotEmpty(pageSubOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
List<String> subOrganizationCodeList = new ArrayList<>(pageSubOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
Long totalSize = pageSubOrganizationCodeDTO.getTotalSize(); | |||||
while (totalSize > (long) currentPage * pageSize) { | |||||
GenericResult<PageSubOrganizationCodeDTO> subPageSubOrganizationCodeDTOGenericResult = zwddClient | |||||
.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
PageSubOrganizationCodeDTO subOrganizationCodeDTO = subPageSubOrganizationCodeDTOGenericResult.getData(); | |||||
if (CollectionUtils.isNotEmpty(subOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
subOrganizationCodeList.addAll(subOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
} | |||||
} | |||||
if (CollectionUtils.isNotEmpty(subOrganizationCodeList)) { | |||||
GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient | |||||
.listOrganizationsByCodes(subOrganizationCodeList); | |||||
List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
List<DingOrgInfoTreeDTO> 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); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.organization.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-09 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.organization/ding-organization") | |||||
public class DingOrganizationController { | |||||
} |
@@ -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; | |||||
/** | |||||
* <p> | |||||
* | |||||
* </p> | |||||
* | |||||
* @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; | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.organization.mapper; | |||||
import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
/** | |||||
* <p> | |||||
* Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-09 | |||||
*/ | |||||
public interface DingOrganizationMapper extends BaseMapper<DingOrganization> { | |||||
} |
@@ -0,0 +1,5 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<mapper namespace="com.ningdatech.pmapi.organization.mapper.DingOrganizationMapper"> | |||||
</mapper> |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.organization.service; | |||||
import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
/** | |||||
* <p> | |||||
* 服务类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-09 | |||||
*/ | |||||
public interface IDingOrganizationService extends IService<DingOrganization> { | |||||
} |
@@ -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; | |||||
/** | |||||
* <p> | |||||
* 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-09 | |||||
*/ | |||||
@Service | |||||
public class DingOrganizationServiceImpl extends ServiceImpl<DingOrganizationMapper, DingOrganization> implements IDingOrganizationService { | |||||
} |
@@ -1,5 +1,6 @@ | |||||
package com.ningdatech.pmapi.todocenter.bean.entity; | package com.ningdatech.pmapi.todocenter.bean.entity; | ||||
import com.ningdatech.pmapi.common.model.FileBasicInfo; | |||||
import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; | import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; | ||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.Builder; | import lombok.Builder; | ||||
@@ -26,9 +27,9 @@ public class ProcessComment { | |||||
/** | /** | ||||
* 评论附件 | * 评论附件 | ||||
*/ | */ | ||||
protected List<Attachment> attachments; | |||||
protected List<FileBasicInfo> attachments; | |||||
public ProcessComment(String text, List<Attachment> attachments) { | |||||
public ProcessComment(String text, List<FileBasicInfo> attachments) { | |||||
this.text = text; | this.text = text; | ||||
this.attachments = null == attachments ? Collections.emptyList() : attachments; | this.attachments = null == attachments ? Collections.emptyList() : attachments; | ||||
} | } | ||||
@@ -1,11 +1,10 @@ | |||||
package com.ningdatech.pmapi.todocenter.bean.entity; | package com.ningdatech.pmapi.todocenter.bean.entity; | ||||
import com.ningdatech.pmapi.todocenter.bean.vo.ProgressNodeAuditInfoVo; | 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.OrgUser; | ||||
import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; | import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; | ||||
import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | import com.wflow.workflow.bean.process.enums.NodeTypeEnum; | ||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.Builder; | import lombok.Builder; | ||||
import lombok.Data; | import lombok.Data; | ||||
@@ -128,5 +128,28 @@ public class TodoCenterController { | |||||
ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportMySubmittedProjectList); | ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportMySubmittedProjectList); | ||||
} | } | ||||
/** | |||||
* 待办中心-抄送我的项目列表查询 | |||||
* @param param | |||||
* @return | |||||
*/ | |||||
@GetMapping("/query-CcMe-list") | |||||
public ApiResponse<PageVo<ResToBeProcessedDTO>> queryCcMeProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ | |||||
PageVo<ResToBeProcessedDTO> 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); | |||||
} | |||||
} | } |
@@ -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); | |||||
} | |||||
} |
@@ -4,7 +4,7 @@ import java.io.Serializable; | |||||
import java.util.*; | import java.util.*; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; | |||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.assertj.core.util.Sets; | import org.assertj.core.util.Sets; | ||||
import org.flowable.bpmn.model.FlowNode; | import org.flowable.bpmn.model.FlowNode; | ||||
@@ -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<Comment> { | |||||
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"; | |||||
} | |||||
} |
@@ -19,7 +19,6 @@ import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.model.PageVo; | import com.ningdatech.basic.model.PageVo; | ||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.common.constant.DingConstant; | 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.statemachine.util.StateMachineUtils; | ||||
import com.ningdatech.pmapi.common.util.ExcelDownUtil; | import com.ningdatech.pmapi.common.util.ExcelDownUtil; | ||||
import com.ningdatech.pmapi.common.util.ExcelExportStyle; | 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.bean.vo.ProcessProgressDetailVo; | ||||
import com.ningdatech.pmapi.todocenter.constant.HisProInsEndActId; | import com.ningdatech.pmapi.todocenter.constant.HisProInsEndActId; | ||||
import com.ningdatech.pmapi.todocenter.enums.IsAppendProjectEnum; | 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.enums.ProcessStatusEnum; | ||||
import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; | 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.ReqProcessHandlerDTO; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedDTO; | 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.MessageContent; | ||||
import com.ningdatech.pmapi.todocenter.zwdd.model.MessageText; | import com.ningdatech.pmapi.todocenter.zwdd.model.MessageText; | ||||
import com.ningdatech.pmapi.user.entity.UserInfo; | 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.process.props.ApprovalProps; | ||||
import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; | import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; | ||||
import com.wflow.workflow.bean.vo.ProcessInstanceVo; | 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.bean.vo.ProcessTaskVo; | ||||
import com.wflow.workflow.config.WflowGlobalVarDef; | import com.wflow.workflow.config.WflowGlobalVarDef; | ||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||||
import com.wflow.workflow.service.FormService; | import com.wflow.workflow.service.FormService; | ||||
import com.wflow.workflow.service.*; | import com.wflow.workflow.service.*; | ||||
import com.wflow.workflow.utils.Executor; | 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.HistoricProcessInstance; | ||||
import org.flowable.engine.history.HistoricProcessInstanceQuery; | import org.flowable.engine.history.HistoricProcessInstanceQuery; | ||||
import org.flowable.engine.impl.util.ProcessDefinitionUtil; | import org.flowable.engine.impl.util.ProcessDefinitionUtil; | ||||
import org.flowable.engine.runtime.ActivityInstance; | |||||
import org.flowable.engine.runtime.Execution; | import org.flowable.engine.runtime.Execution; | ||||
import org.flowable.task.api.Task; | import org.flowable.task.api.Task; | ||||
import org.flowable.task.api.TaskInfo; | 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.api.history.HistoricTaskInstance; | ||||
import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; | import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; | ||||
import org.flowable.variable.api.history.HistoricVariableInstance; | import org.flowable.variable.api.history.HistoricVariableInstance; | ||||
import org.flowable.variable.api.history.NativeHistoricVariableInstanceQuery; | |||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -233,7 +231,7 @@ public class TodoCenterManage { | |||||
.sheet(fileName) | .sheet(fileName) | ||||
.doWrite(collect); | .doWrite(collect); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new RuntimeException(e); | |||||
throw new BizException("导出失败!"); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
@@ -244,28 +242,32 @@ public class TodoCenterManage { | |||||
* @since 2023/02/01 17:43 | * @since 2023/02/01 17:43 | ||||
*/ | */ | ||||
public void handler(ReqProcessHandlerDTO param) { | 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(); | Task task = taskService.createTaskQuery().taskId(param.getTaskId()).active().singleResult(); | ||||
HashMap<String, Object> formData = new HashMap<>(32); | HashMap<String, Object> formData = new HashMap<>(32); | ||||
if (Objects.isNull(task)) { | if (Objects.isNull(task)) { | ||||
throw new BizException("任务不存在"); | throw new BizException("任务不存在"); | ||||
} | } | ||||
if (hasComment(param.getAuditInfo())) { | |||||
taskService.addComment(param.getTaskId(), param.getInstanceId(), JSONObject.toJSONString(param.getAuditInfo())); | |||||
} | |||||
switch (param.getAction()) { | switch (param.getAction()) { | ||||
// 通过 | // 通过 | ||||
case PASS: | case PASS: | ||||
formService.updateInstanceFormData(param.getInstanceId(), formData); | formService.updateInstanceFormData(param.getInstanceId(), formData); | ||||
doPass(task, param); | |||||
doPass(task, userId, param); | |||||
break; | |||||
// 盖章并通过 | // 盖章并通过 | ||||
case SEAL_PASS: | case SEAL_PASS: | ||||
formService.updateInstanceFormData(param.getInstanceId(), formData); | formService.updateInstanceFormData(param.getInstanceId(), formData); | ||||
doSealPass(task, param); | |||||
doSealPass(task, userId, param); | |||||
break; | |||||
// 驳回 | // 驳回 | ||||
case REJECT: | case REJECT: | ||||
formService.updateInstanceFormData(param.getInstanceId(), formData); | formService.updateInstanceFormData(param.getInstanceId(), formData); | ||||
doReject(task, param); | |||||
doReject(task, userId, param); | |||||
break; | break; | ||||
// 退回 | // 退回 | ||||
case BACK: | case BACK: | ||||
@@ -274,7 +276,7 @@ public class TodoCenterManage { | |||||
break; | break; | ||||
// 撤回 | // 撤回 | ||||
case WITHDRAW: | case WITHDRAW: | ||||
doWithDrawProcess(task); | |||||
doWithDrawProcess(task,userId); | |||||
break; | break; | ||||
default: | default: | ||||
throw new IllegalStateException("Unexpected value: " + param.getAction()); | throw new IllegalStateException("Unexpected value: " + param.getAction()); | ||||
@@ -283,16 +285,22 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 审批任务:驳回 | * 审批任务:驳回 | ||||
* | |||||
* @param task 当前任务 | * @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<String, Object> var = new HashMap<>(16); | Map<String, Object> var = new HashMap<>(16); | ||||
var.put("approve_" + task.getId(), param.getAction()); | var.put("approve_" + task.getId(), param.getAction()); | ||||
// TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | // TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | ||||
//获取流程定义 | //获取流程定义 | ||||
Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); | Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); | ||||
String projectName = getProjectName(task); | |||||
// 获取根节点即流程发起节点 | // 获取根节点即流程发起节点 | ||||
FlowNode rootNode = (FlowNode) process.getFlowElement("root", true); | FlowNode rootNode = (FlowNode) process.getFlowElement("root", true); | ||||
// TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | // TODO 中止流程并使项目进入对应状态,给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 | ||||
@@ -350,68 +358,83 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 审批任务:盖章并通过 | * 审批任务:盖章并通过 | ||||
* | |||||
* @param task 当前任务 | * @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<String, Object> var = new HashMap<>(16); | Map<String, Object> var = new HashMap<>(16); | ||||
var.put("approve_" + task.getId(), param.getAction()); | var.put("approve_" + task.getId(), param.getAction()); | ||||
// TODO 判断项目申报单位级别,区县单位申报有上级主管单位意见栏,市级单位没有 | // TODO 判断项目申报单位级别,区县单位申报有上级主管单位意见栏,市级单位没有 | ||||
// 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); | taskService.complete(param.getTaskId(), var); | ||||
} | } | ||||
/** | /** | ||||
* 审批任务:通过 | * 审批任务:通过 | ||||
* | |||||
* @param task 当前任务 | * @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<String, Object> var = new HashMap<>(16); | Map<String, Object> var = new HashMap<>(16); | ||||
var.put("approve_" + task.getId(), param.getAction()); | 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)){ | if (Objects.nonNull(nextUserId)){ | ||||
UserInfo auditUserInfo = userInfoService.getById(Long.valueOf(nextUserId)); | UserInfo auditUserInfo = userInfoService.getById(Long.valueOf(nextUserId)); | ||||
// TODO 向其发送浙政钉工作通知 | |||||
// TODO 获取浙政钉用户dingKey,向其发送浙政钉工作通知 | |||||
String msg = String.format(PASS_MSG_TEMPLATE,null,projectName); | String msg = String.format(PASS_MSG_TEMPLATE,null,projectName); | ||||
sendWorkNotice(auditUserInfo,msg); | |||||
// sendWorkNotice(auditUserInfo,msg); | |||||
}else { | }else { | ||||
// 若没有,向发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | // 若没有,向发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | ||||
// TODO 向其发送浙政钉工作通知 获取根节点的孩子节点(即发起人节点),向其发送浙政钉工作通知 | // 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 | * @return void | ||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/08 20:38 | * @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(); | Integer projectStatusSecond = declaredProject.getProjectStatusSecond(); | ||||
// 根据当前状态获取对应的通过事件 | // 根据当前状态获取对应的通过事件 | ||||
@@ -474,13 +497,15 @@ public class TodoCenterManage { | |||||
} | } | ||||
/** | /** | ||||
* 获取当前节点的下一个节点的浙政钉用户ID | |||||
* @param currentNode 当前节点 | |||||
* 获取当前节点的下一个节点的审核用户ID | |||||
* | |||||
* @param currentNode 当前节点 | |||||
* @param processInstanceId | |||||
* @return java.lang.String 下一个节点的浙政钉用户ID | * @return java.lang.String 下一个节点的浙政钉用户ID | ||||
* @author CMM | * @author CMM | ||||
* @since 2023/02/02 16:49 | * @since 2023/02/02 16:49 | ||||
*/ | */ | ||||
private String getNextUserId(FlowNode currentNode) { | |||||
private String getNextUserId(FlowNode currentNode, String processInstanceId) { | |||||
String nextUserId = null; | String nextUserId = null; | ||||
// 输出连线 | // 输出连线 | ||||
List<SequenceFlow> outgoingFlows = currentNode.getOutgoingFlows(); | List<SequenceFlow> outgoingFlows = currentNode.getOutgoingFlows(); | ||||
@@ -488,32 +513,25 @@ public class TodoCenterManage { | |||||
for (SequenceFlow currentOutgoingFlow : outgoingFlows) { | for (SequenceFlow currentOutgoingFlow : outgoingFlows) { | ||||
// 类型自己判断 | // 类型自己判断 | ||||
FlowElement targetFlowElement = currentOutgoingFlow.getTargetFlowElement(); | FlowElement targetFlowElement = currentOutgoingFlow.getTargetFlowElement(); | ||||
// 如果下个审批节点为结束节点,那么跳过该节点 | |||||
if (targetFlowElement instanceof EndEvent){ | |||||
continue; | |||||
} | |||||
// TODO 若要会签需判断候选人 | // TODO 若要会签需判断候选人 | ||||
// 用户任务 | // 用户任务 | ||||
if (targetFlowElement instanceof UserTask) { | 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; | break; | ||||
} | } | ||||
} | } | ||||
return nextUserId; | 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<String, Object> formData = instanceProgress.getFormData(); | |||||
String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); | |||||
return projectName; | |||||
} | |||||
/** | |||||
* 判断处理操作是否含有审核意见 | * 判断处理操作是否含有审核意见 | ||||
* @param comment 审核意见 | * @param comment 审核意见 | ||||
* @return boolean | * @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()); | Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); | ||||
// 获取当前运行流程的发起人节点信息 | // 获取当前运行流程的发起人节点信息 | ||||
@@ -574,7 +593,6 @@ public class TodoCenterManage { | |||||
FlowNode currentNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey(), true); | FlowNode currentNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey(), true); | ||||
String rootUserId = getRootUserId(rootNode); | String rootUserId = getRootUserId(rootNode); | ||||
// 判断当前登录用户是否是流程发起人 | // 判断当前登录用户是否是流程发起人 | ||||
Long userId = LoginUserUtil.getUserId(); | |||||
if (rootUserId.equals(String.valueOf(userId))){ | if (rootUserId.equals(String.valueOf(userId))){ | ||||
// TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 | // TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 | ||||
updateWithdrawProjectStatus(task, userId); | updateWithdrawProjectStatus(task, userId); | ||||
@@ -618,7 +636,7 @@ public class TodoCenterManage { | |||||
/** | /** | ||||
* 当为撤回操作时,更新项目表中的项目状态为前一个状态 | * 当为撤回操作时,更新项目表中的项目状态为前一个状态 | ||||
* @param task | |||||
* @param task 当前任务 | |||||
* @param userId | * @param userId | ||||
* @return void | * @return void | ||||
* @author CMM | * @author CMM | ||||
@@ -652,8 +670,10 @@ public class TodoCenterManage { | |||||
* @param param 参数 | * @param param 参数 | ||||
*/ | */ | ||||
private void doBackTask(Task task, Long userId, ReqProcessHandlerDTO 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()); | Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); | ||||
// 获取根节点即流程发起节点 | // 获取根节点即流程发起节点 | ||||
@@ -679,7 +699,7 @@ public class TodoCenterManage { | |||||
HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() | HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() | ||||
.processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult(); | .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult(); | ||||
List<HistoricVariableInstance> formDatas = historyService.createHistoricVariableInstanceQuery() | List<HistoricVariableInstance> formDatas = historyService.createHistoricVariableInstanceQuery() | ||||
.processInstanceId(instanceId).variableNameLike("field%").list(); | |||||
.processInstanceId(instanceId).list(); | |||||
// 取节点设置 | // 取节点设置 | ||||
HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() | HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() | ||||
.processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); | .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); | ||||
@@ -944,7 +964,7 @@ public class TodoCenterManage { | |||||
.sheet(fileName) | .sheet(fileName) | ||||
.doWrite(collect); | .doWrite(collect); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new RuntimeException(e); | |||||
throw new BizException("导出失败!"); | |||||
} | } | ||||
} | } | ||||
@@ -1087,8 +1107,87 @@ public class TodoCenterManage { | |||||
.sheet(fileName) | .sheet(fileName) | ||||
.doWrite(collect); | .doWrite(collect); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new RuntimeException(e); | |||||
throw new BizException("导出失败!"); | |||||
} | } | ||||
} | } | ||||
public PageVo<ResToBeProcessedDTO> queryCcMeProjectList(ReqToBeProcessedDTO param) { | |||||
// 获取当前登录用户ID | |||||
// Long userId = LoginUserUtil.getUserId(); | |||||
Long userId = 381496L; | |||||
Page<Project> page = param.page(); | |||||
Set<String> staterUsers = new HashSet<>(); | |||||
List<WflowCcTasks> ccTasks = ccTasksMapper.selectList(Wrappers.lambdaQuery(WflowCcTasks.class) | |||||
.eq(WflowCcTasks::getUserId, String.valueOf(userId)) | |||||
.orderByDesc(WflowCcTasks::getCreateTime)); | |||||
LambdaQueryWrapper<Project> 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<String, HistoricProcessInstance> 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<String> processInsIds = ccTasks.stream().map(WflowCcTasks::getInstanceId).collect(Collectors.toList()); | |||||
List<ResToBeProcessedDTO> 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<String, OrgUser> 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<Long, UserInfo> 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<ResToBeProcessedDTO> page = queryCcMeProjectList(param); | |||||
List<ResToBeProcessedDTO> collect = (List<ResToBeProcessedDTO>) 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("导出失败!"); | |||||
} | |||||
} | |||||
} | } |
@@ -1,11 +1,10 @@ | |||||
package com.ningdatech.pmapi.todocenter.model.dto.req; | 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.bean.entity.ProcessComment; | ||||
import com.ningdatech.pmapi.todocenter.enums.ProcessHandlerEnum; | |||||
import com.wflow.workflow.enums.ProcessHandlerEnum; | |||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
import java.time.LocalDateTime; | |||||
/** | /** | ||||
* 流程处理操作参数实体 | * 流程处理操作参数实体 | ||||
@@ -47,43 +46,4 @@ public class ReqProcessHandlerDTO { | |||||
* 审核信息 | * 审核信息 | ||||
*/ | */ | ||||
private ProcessComment auditInfo; | 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; | |||||
//} | |||||
} | } |
@@ -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; | |||||
} |
@@ -158,12 +158,9 @@ sa-token: | |||||
#专有钉钉 | #专有钉钉 | ||||
ding: | 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-key: file-manage-4Mjx9358wuxjyYFjY3 | ||||
app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O | app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O | ||||
#专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 | ||||
@@ -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 |
@@ -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 |
@@ -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(); | |||||
} | |||||
} |
@@ -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 |
@@ -0,0 +1,3 @@ | |||||
spring: | |||||
profiles: | |||||
active: dev |
@@ -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 |
@@ -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 |
@@ -0,0 +1,68 @@ | |||||
<configuration scan="true" scanPeriod="10 seconds"> | |||||
<springProperty name="logPath" scope="context" source="log.path" defaultValue="./logs"/> | |||||
<springProperty name="infoFileSize" scope="context" source="log.info.file-size"/> | |||||
<springProperty name="infoMaxSize" scope="context" source="log.info.max-size"/> | |||||
<springProperty name="infoTotalSize" scope="context" source="log.info.total-size"/> | |||||
<springProperty name="errorFileSize" scope="context" source="log.error.file-size"/> | |||||
<springProperty name="errorMaxSize" scope="context" source="log.error.max-size"/> | |||||
<springProperty name="errorTotalSize" scope="context" source="log.error.total-size"/> | |||||
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<File>${logPath}/info.log</File> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<fileNamePattern>${logPath}/info-%d{yyyyMMdd}-%i.log</fileNamePattern> | |||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||||
<maxFileSize>${infoFileSize}</maxFileSize> | |||||
</timeBasedFileNamingAndTriggeringPolicy> | |||||
<maxHistory>${infoMaxSize}</maxHistory> | |||||
<totalSizeCap>${infoTotalSize}</totalSizeCap> | |||||
</rollingPolicy> | |||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | |||||
<layout class="ch.qos.logback.classic.PatternLayout"> | |||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n | |||||
</Pattern> | |||||
</layout> | |||||
<charset>UTF-8</charset> | |||||
</encoder> | |||||
</appender> | |||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | |||||
<level>ERROR</level> | |||||
</filter> | |||||
<File>${logPath}/error.log</File> | |||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||||
<fileNamePattern>${logPath}/error-%d{yyyyMMdd}-%i.log</fileNamePattern> | |||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||||
<maxFileSize>${errorFileSize}</maxFileSize> | |||||
</timeBasedFileNamingAndTriggeringPolicy> | |||||
<maxHistory>${errorMaxSize}</maxHistory> | |||||
<totalSizeCap>${errorTotalSize}</totalSizeCap> | |||||
</rollingPolicy> | |||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | |||||
<layout class="ch.qos.logback.classic.PatternLayout"> | |||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n | |||||
</Pattern> | |||||
</layout> | |||||
<charset>UTF-8</charset> | |||||
</encoder> | |||||
</appender> | |||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | |||||
<encoder> | |||||
<pattern> | |||||
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n | |||||
</pattern> | |||||
<charset>UTF-8</charset> | |||||
</encoder> | |||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | |||||
<level>DEBUG</level> | |||||
</filter> | |||||
</appender> | |||||
<root level="INFO"> | |||||
<appender-ref ref="INFO_FILE"/> | |||||
<appender-ref ref="ERROR_FILE"/> | |||||
<appender-ref ref="STDOUT"/> | |||||
</root> | |||||
</configuration> |
@@ -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 |
@@ -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 |