@@ -229,6 +229,25 @@ | |||||
<groupId>org.springframework.statemachine</groupId> | <groupId>org.springframework.statemachine</groupId> | ||||
<artifactId>spring-statemachine-core</artifactId> | <artifactId>spring-statemachine-core</artifactId> | ||||
</dependency> | </dependency> | ||||
<!-- PDF生成 --> | |||||
<dependency> | |||||
<groupId>com.itextpdf</groupId> | |||||
<artifactId>itextpdf</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.itextpdf</groupId> | |||||
<artifactId>itext-asian</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.itextpdf.tool</groupId> | |||||
<artifactId>xmlworker</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.xhtmlrenderer</groupId> | |||||
<artifactId>flying-saucer-pdf-itext5</artifactId> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
<!-- 打包 --> | <!-- 打包 --> | ||||
<!--配置环境的profile--> | <!--配置环境的profile--> | ||||
@@ -0,0 +1,22 @@ | |||||
package com.ningdatech.pmapi.common.enumeration; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Getter; | |||||
/** | |||||
* @author zpf | |||||
* @date 2023/3/12 上午9:21 | |||||
*/ | |||||
@AllArgsConstructor | |||||
@Getter | |||||
public enum CommonEnum { | |||||
/** | |||||
* 公共的一些枚举 | |||||
*/ | |||||
YES(1,"是"), | |||||
NO(0,"否"); | |||||
private Integer code; | |||||
private String desc; | |||||
} |
@@ -45,14 +45,14 @@ public class ReviewTemplateSettingsController { | |||||
} | } | ||||
@GetMapping("/template") | @GetMapping("/template") | ||||
@ApiModelProperty("根据模版ID获取评审模版") | |||||
@ApiOperation("根据模版ID获取评审模版") | |||||
@ApiImplicitParam(name = "templateId", defaultValue = "模版ID") | @ApiImplicitParam(name = "templateId", defaultValue = "模版ID") | ||||
public ReviewTemplateVO getTemplateById(@RequestParam Long templateId) { | public ReviewTemplateVO getTemplateById(@RequestParam Long templateId) { | ||||
return reviewTemplateSettingsManage.getReviewTemplateSettings(templateId); | return reviewTemplateSettingsManage.getReviewTemplateSettings(templateId); | ||||
} | } | ||||
@GetMapping("/templates") | @GetMapping("/templates") | ||||
@ApiModelProperty("(批量)根据模版ID获取评审模版") | |||||
@ApiOperation("(批量)根据模版ID获取评审模版") | |||||
@ApiImplicitParam(name = "templateIds", defaultValue = "模版ID集合") | @ApiImplicitParam(name = "templateIds", defaultValue = "模版ID集合") | ||||
public List<ReviewTemplateVO> getTemplateById(@RequestParam List<Long> templateIds) { | public List<ReviewTemplateVO> getTemplateById(@RequestParam List<Long> templateIds) { | ||||
return reviewTemplateSettingsManage.listReviewTemplateSettings(templateIds); | return reviewTemplateSettingsManage.listReviewTemplateSettings(templateIds); | ||||
@@ -209,7 +209,7 @@ public class MeetingManage { | |||||
Assert.isTrue(checkCount >= inviteCount, "可供抽取的专家数量不足"); | Assert.isTrue(checkCount >= inviteCount, "可供抽取的专家数量不足"); | ||||
} | } | ||||
expertInviteManage.expertInviteByMeetingCreate(meeting, randomRules, avoidInfo); | expertInviteManage.expertInviteByMeetingCreate(meeting, randomRules, avoidInfo); | ||||
expertInviteTask.addInviteExpertTaskByMeetingCreate(meeting.getId(), 5); | |||||
expertInviteTask.addInviteTaskByMeetingCreate(meeting.getId(), 5); | |||||
LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class); | LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class); | ||||
update.set(Meeting::getInviteStatus, false); | update.set(Meeting::getInviteStatus, false); | ||||
update.eq(Meeting::getId, meeting.getId()); | update.eq(Meeting::getId, meeting.getId()); | ||||
@@ -74,22 +74,22 @@ | |||||
<sql id="reviewedByHeadman"> | <sql id="reviewedByHeadman"> | ||||
<if test="p.reviewed"> | <if test="p.reviewed"> | ||||
and exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
me.expert_id and is_final = true) | me.expert_id and is_final = true) | ||||
</if> | </if> | ||||
<if test="!p.reviewed"> | <if test="!p.reviewed"> | ||||
and not exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
not exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
me.expert_id and is_final = true) | me.expert_id and is_final = true) | ||||
</if> | </if> | ||||
</sql> | </sql> | ||||
<sql id="reviewedByNotHeadman"> | <sql id="reviewedByNotHeadman"> | ||||
<if test="p.reviewed"> | <if test="p.reviewed"> | ||||
and exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
me.expert_id) | me.expert_id) | ||||
</if> | </if> | ||||
<if test="!p.reviewed"> | <if test="!p.reviewed"> | ||||
and not exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
not exists(select 1 from nd_expert_review ner where ner.project_id = np.id and ner.create_by = | |||||
me.expert_id) | me.expert_id) | ||||
</if> | </if> | ||||
</sql> | </sql> | ||||
@@ -104,7 +104,7 @@ | |||||
inner join meeting_expert me on m.id = me.meeting_id | inner join meeting_expert me on m.id = me.meeting_id | ||||
where m.is_inner_project = true | where m.is_inner_project = true | ||||
<if test="p.reviewed != null"> | <if test="p.reviewed != null"> | ||||
if(me.is_headman,<include refid="reviewedByHeadman"/>,<include refid="reviewedByNotHeadman"/>) | |||||
and if(me.is_headman,<include refid="reviewedByHeadman"/>,<include refid="reviewedByNotHeadman"/>) | |||||
</if> | </if> | ||||
and me.expert_id = #{p.userId} | and me.expert_id = #{p.userId} | ||||
<if test="p.projectName != null and p.projectName.length > 0"> | <if test="p.projectName != null and p.projectName.length > 0"> | ||||
@@ -78,9 +78,9 @@ public class ExpertInviteTask { | |||||
private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | private final YxtCallOrSmsHelper yxtCallOrSmsHelper; | ||||
/** | /** | ||||
* 用来存入线程执行情况, 方便于停止定时任务时使用 | |||||
* 用来存入线程执行句柄, 停止定时任务时使用 | |||||
*/ | */ | ||||
protected static final ConcurrentMap<Long, ScheduledFuture<?>> INVITE_MAP = new ConcurrentHashMap<>(); | |||||
private static final ConcurrentMap<Long, ScheduledFuture<?>> INVITE_TASK_MAP = new ConcurrentHashMap<>(); | |||||
public ExpertInviteTask currProxy() { | public ExpertInviteTask currProxy() { | ||||
return (ExpertInviteTask) AopContext.currentProxy(); | return (ExpertInviteTask) AopContext.currentProxy(); | ||||
@@ -109,7 +109,7 @@ public class ExpertInviteTask { | |||||
return; | return; | ||||
} | } | ||||
for (InviteCacheDTO cache : caches.values()) { | for (InviteCacheDTO cache : caches.values()) { | ||||
addInviteExpertTask(cache.getMeetingId(), true, properties.getInviteDelay(), cache.getInvitedRefused()); | |||||
addInviteTask(cache.getMeetingId(), true, properties.getInviteDelay(), cache.getInvitedRefused()); | |||||
} | } | ||||
} | } | ||||
@@ -155,8 +155,8 @@ public class ExpertInviteTask { | |||||
if (ArrayUtil.isNotEmpty(invitedRefused)) { | if (ArrayUtil.isNotEmpty(invitedRefused)) { | ||||
tmpInvitedRefused = invitedRefused[0]; | tmpInvitedRefused = invitedRefused[0]; | ||||
} | } | ||||
if (!INVITE_MAP.containsKey(meetingId)) { | |||||
addInviteExpertTask(meetingId, false, properties.getInviteDelay(), tmpInvitedRefused); | |||||
if (!INVITE_TASK_MAP.containsKey(meetingId)) { | |||||
addInviteTask(meetingId, false, properties.getInviteDelay(), tmpInvitedRefused); | |||||
log.info("重置会议的随机抽取状态:{}", meetingId); | log.info("重置会议的随机抽取状态:{}", meetingId); | ||||
LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class); | LambdaUpdateWrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class); | ||||
update.set(Meeting::getInviteStatus, false); | update.set(Meeting::getInviteStatus, false); | ||||
@@ -176,7 +176,7 @@ public class ExpertInviteTask { | |||||
* @param invitedRefused 是否可以邀请被拒绝的专家 | * @param invitedRefused 是否可以邀请被拒绝的专家 | ||||
* @author WendyYang | * @author WendyYang | ||||
**/ | **/ | ||||
public void addInviteExpertTask(Long meetingId, boolean checked, int delayedMinutes, boolean invitedRefused) { | |||||
public void addInviteTask(Long meetingId, boolean checked, int delayedMinutes, boolean invitedRefused) { | |||||
if (checked && !inviteCountCheck(meetingId)) { | if (checked && !inviteCountCheck(meetingId)) { | ||||
// 如果抽取数量满足直接返回 | // 如果抽取数量满足直接返回 | ||||
return; | return; | ||||
@@ -190,7 +190,7 @@ public class ExpertInviteTask { | |||||
log.error("执行专家邀请任务异常:{}", meetingId, e); | log.error("执行专家邀请任务异常:{}", meetingId, e); | ||||
} | } | ||||
}, startTime, Duration.ofMinutes(properties.getInviteFixedRate())); | }, startTime, Duration.ofMinutes(properties.getInviteFixedRate())); | ||||
INVITE_MAP.putIfAbsent(meetingId, future); | |||||
INVITE_TASK_MAP.putIfAbsent(meetingId, future); | |||||
log.info("添加专家抽取后台任务:{}", meetingId); | log.info("添加专家抽取后台任务:{}", meetingId); | ||||
} | } | ||||
@@ -201,13 +201,19 @@ public class ExpertInviteTask { | |||||
* @param delayedMinutes 延迟时间 | * @param delayedMinutes 延迟时间 | ||||
* @author WendyYang | * @author WendyYang | ||||
**/ | **/ | ||||
public void addInviteExpertTaskByMeetingCreate(Long meetingId, int delayedMinutes) { | |||||
public void addInviteTaskByMeetingCreate(Long meetingId, int delayedMinutes) { | |||||
Assert.isTrue(properties.getEnable(), "随机邀请已关闭"); | Assert.isTrue(properties.getEnable(), "随机邀请已关闭"); | ||||
addInviteExpertTask(meetingId, false, delayedMinutes, false); | |||||
addInviteTask(meetingId, false, delayedMinutes, false); | |||||
InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, false); | InviteCacheDTO cacheVal = InviteCacheDTO.of(meetingId, false); | ||||
cachePlusOps.hSet(getCacheKey(meetingId), cacheVal); | cachePlusOps.hSet(getCacheKey(meetingId), cacheVal); | ||||
} | } | ||||
/** | |||||
* 抽取过程 | |||||
* | |||||
* @param meetingId 会议ID | |||||
* @param invitedRefused 是否可以邀请已拒绝的专家 | |||||
*/ | |||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public void invite(Long meetingId, Boolean invitedRefused) { | public void invite(Long meetingId, Boolean invitedRefused) { | ||||
log.info("开始进行专家后台抽取:{}", meetingId); | log.info("开始进行专家后台抽取:{}", meetingId); | ||||
@@ -269,9 +275,9 @@ public class ExpertInviteTask { | |||||
log.info("终止专家抽取:{}", meetingId); | log.info("终止专家抽取:{}", meetingId); | ||||
meetingService.stopRandomInvite(meetingId); | meetingService.stopRandomInvite(meetingId); | ||||
cachePlusOps.hDel(getCacheKey(meetingId)); | cachePlusOps.hDel(getCacheKey(meetingId)); | ||||
ScheduledFuture<?> future = INVITE_MAP.get(meetingId); | |||||
ScheduledFuture<?> future = INVITE_TASK_MAP.get(meetingId); | |||||
if (future != null) { | if (future != null) { | ||||
INVITE_MAP.remove(meetingId); | |||||
INVITE_TASK_MAP.remove(meetingId); | |||||
if (!future.isCancelled()) { | if (!future.isCancelled()) { | ||||
future.cancel(true); | future.cancel(true); | ||||
} | } | ||||
@@ -12,6 +12,7 @@ import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.basic.util.NdDateUtils; | import com.ningdatech.basic.util.NdDateUtils; | ||||
import com.ningdatech.pmapi.common.constant.CommonConst; | import com.ningdatech.pmapi.common.constant.CommonConst; | ||||
import com.ningdatech.pmapi.common.constant.RegionConst; | import com.ningdatech.pmapi.common.constant.RegionConst; | ||||
import com.ningdatech.pmapi.common.enumeration.CommonEnum; | |||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | ||||
import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | import com.ningdatech.pmapi.common.helper.RegionCacheHelper; | ||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
@@ -115,6 +116,12 @@ public class DeclaredProjectManage { | |||||
projectInfo.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | projectInfo.setBuildOrgCode(userInfoDetails.getOrganizationCode()); | ||||
projectInfo.setBuildOrgName(userInfoDetails.getOrganizationName()); | projectInfo.setBuildOrgName(userInfoDetails.getOrganizationName()); | ||||
//如果主管单位没有 那么主管单位就是自己 | |||||
if(CommonEnum.NO.getCode().equals(projectInfo.getIsSuperOrg())){ | |||||
projectInfo.setSuperOrgCode(userInfoDetails.getOrganizationCode()); | |||||
projectInfo.setSuperOrg(userInfoDetails.getOrganizationName()); | |||||
} | |||||
//如果是重新提交的话 判断下 项目是否存在 | //如果是重新提交的话 判断下 项目是否存在 | ||||
if(Objects.nonNull(projectInfo.getId())){ | if(Objects.nonNull(projectInfo.getId())){ | ||||
Project oldProject = projectService.getById(projectInfo.getId()); | Project oldProject = projectService.getById(projectInfo.getId()); | ||||
@@ -1,29 +1,41 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.manage; | package com.ningdatech.pmapi.projectdeclared.manage; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.ningdatech.basic.function.VUtils; | import com.ningdatech.basic.function.VUtils; | ||||
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum; | |||||
import com.ningdatech.pmapi.common.helper.UserInfoHelper; | import com.ningdatech.pmapi.common.helper.UserInfoHelper; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||||
import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | import com.ningdatech.pmapi.organization.model.entity.DingOrganization; | ||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.ProjectConditionDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | |||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
import com.wflow.bean.entity.WflowOrgModels; | import com.wflow.bean.entity.WflowOrgModels; | ||||
import com.wflow.enums.OrgTypeEnum; | import com.wflow.enums.OrgTypeEnum; | ||||
import com.wflow.enums.ProcessDefTypeEnum; | import com.wflow.enums.ProcessDefTypeEnum; | ||||
import com.wflow.exception.BusinessException; | |||||
import com.wflow.service.OrgProcdefService; | import com.wflow.service.OrgProcdefService; | ||||
import com.wflow.workflow.bean.dto.OrgInfoDTO; | import com.wflow.workflow.bean.dto.OrgInfoDTO; | ||||
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | import com.wflow.workflow.bean.dto.ProcessInstanceUserDto; | ||||
import com.wflow.workflow.bean.vo.ProcessStartParamsVo; | |||||
import com.wflow.workflow.service.ProcessInstanceService; | |||||
import com.wflow.workflow.service.ProcessModelService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Objects; | |||||
import java.time.LocalDateTime; | |||||
import java.util.*; | |||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
/** | /** | ||||
@@ -45,6 +57,14 @@ public class DefaultDeclaredProjectManage { | |||||
private final IDingOrganizationService dingOrganizationService; | private final IDingOrganizationService dingOrganizationService; | ||||
private final OrgProcdefService orgProcdefService; | private final OrgProcdefService orgProcdefService; | ||||
private final ProcessModelService processModelService; | |||||
private final ProcessInstanceService processService; | |||||
private final IProjectInstService projectInstService; | |||||
private final StateMachineUtils stateMachineUtils; | |||||
//项目名称去重 | //项目名称去重 | ||||
public void checkDuplication(ProjectDTO project){ | public void checkDuplication(ProjectDTO project){ | ||||
VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | VUtils.isTrue(projectService.count(Wrappers.lambdaQuery(Project.class) | ||||
@@ -120,4 +140,68 @@ public class DefaultDeclaredProjectManage { | |||||
orgMap.put(OrgTypeEnum.TARGET_LABEL.name(),orgInfoDTO); | orgMap.put(OrgTypeEnum.TARGET_LABEL.name(),orgInfoDTO); | ||||
return orgMap; | return orgMap; | ||||
} | } | ||||
//直接提交预审方法 提取 在省级联审通过的时候 也可以用 | |||||
public String directStartProcess(Project projectInfo,Long userId){ | |||||
VUtils.isTrue(Objects.isNull(userId)) | |||||
.throwMessage("发起人Id 不能为空!"); | |||||
ProcessStartParamsVo params = new ProcessStartParamsVo(); | |||||
params.setUser(buildUser(userId)); | |||||
params.setProcessUsers(Collections.emptyMap()); | |||||
//放入条件判断的项目字段 | |||||
ProjectConditionDTO conditionDto = new ProjectConditionDTO(); | |||||
BeanUtils.copyProperties(projectInfo, conditionDto); | |||||
params.setFormData(JSON.parseObject(JSON.toJSONString(conditionDto), new TypeReference<Map<String, Object>>() { | |||||
})); | |||||
String regionCode = projectInfo.getAreaCode(); | |||||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | |||||
.eq(WflowModels::getRegionCode, regionCode) | |||||
.eq(WflowModels::getProcessType, ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()) | |||||
.last("limit 1")); | |||||
if (Objects.isNull(model)) { | |||||
log.error("此 【{}】区域找不到 预审流程配置", regionCode); | |||||
throw new BusinessException(String.format("此 【%s】区域找不到 预审流程配置", regionCode)); | |||||
} | |||||
// 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 | |||||
Map<String, OrgInfoDTO> orgModelMap = getOrgModelInfo(userId,projectInfo); | |||||
String instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); | |||||
log.info("提交预审项目成功 【{}】", instanceId); | |||||
//保存预审项目 | |||||
preModifyProject(projectInfo, instanceId); | |||||
return instanceId; | |||||
} | |||||
/** | |||||
* 提交预审项目 时 更新信息 | |||||
* | |||||
* @param project | |||||
* @param instanceId | |||||
*/ | |||||
private void preModifyProject(Project project, String instanceId) { | |||||
//流程启动之后 入库项目 重要业务信息 用于列表查询 展示 | |||||
try { | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
project.setInstCode(instanceId); | |||||
projectService.updateById(project); | |||||
//保存项目和实例的关系 | |||||
ProjectInst projectInst = new ProjectInst(); | |||||
projectInst.setProjectId(project.getId()); | |||||
projectInst.setInstCode(instanceId); | |||||
projectInst.setCreatOn(LocalDateTime.now()); | |||||
projectInst.setUpdateOn(LocalDateTime.now()); | |||||
projectInst.setInstType(ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()); | |||||
projectInstService.save(projectInst); | |||||
} catch (Exception e) { | |||||
log.error("提交预审 项目信息修改 错误 ", e); | |||||
throw new BusinessException("提交预审 项目信息修改 错误 :" + e.getMessage()); | |||||
} | |||||
} | |||||
} | } |
@@ -33,6 +33,7 @@ import com.ningdatech.pmapi.projectlib.service.IProjectInstService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | import com.ningdatech.pmapi.staging.service.IProjectStagingService; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | |||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.wflow.bean.entity.WflowModels; | import com.wflow.bean.entity.WflowModels; | ||||
import com.wflow.exception.BusinessException; | import com.wflow.exception.BusinessException; | ||||
@@ -70,12 +71,6 @@ public class PrequalificationDeclaredProjectManage { | |||||
private final StateMachineUtils stateMachineUtils; | private final StateMachineUtils stateMachineUtils; | ||||
private final ProcessInstanceService processService; | |||||
private final ProcessModelService processModelService; | |||||
private final IProjectInstService projectInstService; | |||||
private final IProjectStagingService projectStagingService; | private final IProjectStagingService projectStagingService; | ||||
private final ProjectLibManage projectLibManage; | private final ProjectLibManage projectLibManage; | ||||
@@ -94,7 +89,8 @@ public class PrequalificationDeclaredProjectManage { | |||||
*/ | */ | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public String startTheProcess(DefaultDeclaredDTO dto) { | public String startTheProcess(DefaultDeclaredDTO dto) { | ||||
Long userId = LoginUserUtil.getUserId(); | |||||
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail(); | |||||
Long userId = userInfoDetails.getUserId(); | |||||
VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!"); | VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!"); | ||||
ProjectDTO projectDto = dto.getProjectInfo(); | ProjectDTO projectDto = dto.getProjectInfo(); | ||||
@@ -102,17 +98,9 @@ public class PrequalificationDeclaredProjectManage { | |||||
Project projectInfo = projectService.getById(projectDto.getId()); | Project projectInfo = projectService.getById(projectDto.getId()); | ||||
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!"); | ||||
String regionCode = projectInfo.getAreaCode(); | |||||
WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) | |||||
.eq(WflowModels::getRegionCode, regionCode) | |||||
.eq(WflowModels::getProcessType, ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()) | |||||
.last("limit 1")); | |||||
if (Objects.isNull(model)) { | |||||
log.error("此 【{}】区域找不到 预审流程配置", regionCode); | |||||
throw new BusinessException(String.format("此 【%s】区域找不到 预审流程配置", regionCode)); | |||||
} | |||||
//要判断 当前操作人 是不是项目主管单位的人 | |||||
VUtils.isTrue(!userInfoDetails.getOrganizationCode().equals(projectInfo.getSuperOrgCode())) | |||||
.throwMessage(String.format("只有主管单位 【%s】的人 才能够提交",projectInfo.getSuperOrg())); | |||||
//首先要判断 项目当前状态 是不是 待预审 | //首先要判断 项目当前状态 是不是 待预审 | ||||
VUtils.isTrue(!ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode().equals(projectInfo.getStatus()) || | VUtils.isTrue(!ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode().equals(projectInfo.getStatus()) || | ||||
@@ -128,6 +116,8 @@ public class PrequalificationDeclaredProjectManage { | |||||
.getCode().equals(projectInfo.getStatus())){ | .getCode().equals(projectInfo.getStatus())){ | ||||
//入库暂存表 后续处理 对接外部接口 | //入库暂存表 后续处理 对接外部接口 | ||||
projectInfo.setUpdateOn(LocalDateTime.now()); | projectInfo.setUpdateOn(LocalDateTime.now()); | ||||
//保存一下 当前的主管单位发起人 | |||||
projectInfo.setPreStartUserId(userId); | |||||
if(projectStagingService.addByProject(projectInfo,"省级部门联审") | if(projectStagingService.addByProject(projectInfo,"省级部门联审") | ||||
&& projectService.updateById(projectInfo)){ | && projectService.updateById(projectInfo)){ | ||||
return "提交省级部门联审成功"; | return "提交省级部门联审成功"; | ||||
@@ -136,26 +126,7 @@ public class PrequalificationDeclaredProjectManage { | |||||
}else if(ProjectStatusEnum.PRE_APPLYING | }else if(ProjectStatusEnum.PRE_APPLYING | ||||
.getCode().equals(projectInfo.getStatus())){ | .getCode().equals(projectInfo.getStatus())){ | ||||
//如果是非省级联审的项目 直接提交 预审 | //如果是非省级联审的项目 直接提交 预审 | ||||
ProcessStartParamsVo params = new ProcessStartParamsVo(); | |||||
params.setUser(declaredProjectManage.buildUser(userId)); | |||||
params.setProcessUsers(Collections.emptyMap()); | |||||
//放入条件判断的项目字段 | |||||
ProjectConditionDTO conditionDto = new ProjectConditionDTO(); | |||||
BeanUtils.copyProperties(projectInfo, conditionDto); | |||||
dto.getFormData().putAll( | |||||
JSON.parseObject(JSON.toJSONString(conditionDto), new TypeReference<Map<String, Object>>() { | |||||
}) | |||||
); | |||||
params.setFormData(dto.getFormData()); | |||||
// 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息 | |||||
Map<String, OrgInfoDTO> orgModelMap = defaultDeclaredProjectManage.getOrgModelInfo(userId,projectInfo); | |||||
instanceId = processService.newStartProcess(model.getProcessDefId(),model.getFormId(), params,orgModelMap); | |||||
log.info("提交预审项目成功 【{}】", instanceId); | |||||
//保存预审项目 | |||||
modifyProject(projectInfo, instanceId); | |||||
instanceId = defaultDeclaredProjectManage.directStartProcess(projectInfo,userId); | |||||
}else{ | }else{ | ||||
throw new BusinessException("项目状态 错误 project :" + JSON.toJSONString(projectInfo)); | throw new BusinessException("项目状态 错误 project :" + JSON.toJSONString(projectInfo)); | ||||
} | } | ||||
@@ -164,35 +135,6 @@ public class PrequalificationDeclaredProjectManage { | |||||
} | } | ||||
/** | /** | ||||
* 提交预审项目 时 更新信息 | |||||
* | |||||
* @param project | |||||
* @param instanceId | |||||
*/ | |||||
private void modifyProject(Project project, String instanceId) { | |||||
//流程启动之后 入库项目 重要业务信息 用于列表查询 展示 | |||||
try { | |||||
project.setUpdateOn(LocalDateTime.now()); | |||||
project.setInstCode(instanceId); | |||||
//调用状态机 进入下一个通过状态 | |||||
stateMachineUtils.pass(project); | |||||
projectService.updateById(project); | |||||
//保存项目和实例的关系 | |||||
ProjectInst projectInst = new ProjectInst(); | |||||
projectInst.setProjectId(project.getId()); | |||||
projectInst.setInstCode(instanceId); | |||||
projectInst.setCreatOn(LocalDateTime.now()); | |||||
projectInst.setUpdateOn(LocalDateTime.now()); | |||||
projectInst.setInstType(ProjectProcessStageEnum.PROJECT_PREQUALIFICATION_APPROVAL_PROCESS.getCode()); | |||||
projectInstService.save(projectInst); | |||||
} catch (Exception e) { | |||||
log.error("提交预审 项目信息修改 错误 ", e); | |||||
throw new BusinessException("提交预审 项目信息修改 错误 :" + e.getMessage()); | |||||
} | |||||
} | |||||
/** | |||||
* 查询项目库 | * 查询项目库 | ||||
* @param preReq | * @param preReq | ||||
* @return | * @return | ||||
@@ -207,8 +149,8 @@ public class PrequalificationDeclaredProjectManage { | |||||
Long userId = LoginUserUtil.getUserId(); | Long userId = LoginUserUtil.getUserId(); | ||||
VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!"); | VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!"); | ||||
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId); | UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId); | ||||
//放入用户的单位 | |||||
req.setBuildOrgCode(userFullInfo.getOrganizationCode()); | |||||
//放入用户的主管单位 | |||||
req.setSuperOrgCode(userFullInfo.getOrganizationCode()); | |||||
return projectLibManage.projectLibList(req); | return projectLibManage.projectLibList(req); | ||||
} | } | ||||
@@ -51,8 +51,6 @@ public class ReviewByDeptJointManage { | |||||
private final ProcessInstanceService processService; | private final ProcessInstanceService processService; | ||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final UserInfoHelper userInfoHelper; | |||||
private final DefaultDeclaredProjectManage declaredProjectManage; | private final DefaultDeclaredProjectManage declaredProjectManage; | ||||
private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | private final DefaultDeclaredProjectManage defaultDeclaredProjectManage; | ||||
@@ -63,8 +61,8 @@ public class ReviewByDeptJointManage { | |||||
*/ | */ | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public Boolean startTheProcess(Project project) { | public Boolean startTheProcess(Project project) { | ||||
Long userId = LoginUserUtil.getUserId(); | |||||
VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!"); | |||||
//这里是任务发起的 所以用项目发起人 | |||||
Long userId = project.getSponsor(); | |||||
VUtils.isTrue(Objects.isNull(project.getId())).throwMessage("提交失败 缺少项目ID!"); | VUtils.isTrue(Objects.isNull(project.getId())).throwMessage("提交失败 缺少项目ID!"); | ||||
Project projectInfo = projectService.getById(project.getId()); | Project projectInfo = projectService.getById(project.getId()); | ||||
@@ -122,8 +120,6 @@ public class ReviewByDeptJointManage { | |||||
try { | try { | ||||
project.setUpdateOn(LocalDateTime.now()); | project.setUpdateOn(LocalDateTime.now()); | ||||
project.setInstCode(instanceId); | project.setInstCode(instanceId); | ||||
project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode()); | |||||
project.setStatus(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()); | |||||
projectService.updateById(project); | projectService.updateById(project); | ||||
//保存项目和实例的关系 | //保存项目和实例的关系 | ||||
ProjectInst projectInst = new ProjectInst(); | ProjectInst projectInst = new ProjectInst(); | ||||
@@ -1,11 +1,15 @@ | |||||
package com.ningdatech.pmapi.projectdeclared.manage; | package com.ningdatech.pmapi.projectdeclared.manage; | ||||
import com.ningdatech.basic.function.VUtils; | import com.ningdatech.basic.function.VUtils; | ||||
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; | |||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
@@ -23,6 +27,10 @@ public class ReviewByProvincialDeptManage { | |||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final StateMachineUtils stateMachineUtils; | |||||
private final DefaultDeclaredProjectManage defaultProjectManage; | |||||
/** | /** | ||||
* 省级部门联审 | * 省级部门联审 | ||||
* @param project | * @param project | ||||
@@ -40,10 +48,16 @@ public class ReviewByProvincialDeptManage { | |||||
!ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) | !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage())) | ||||
.throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段"); | .throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段"); | ||||
// TODO 对接省级联审的接口 | // TODO 对接省级联审的接口 | ||||
Boolean sucessProvince = Boolean.FALSE; | |||||
Boolean sucessProvince = Boolean.TRUE; | |||||
if(sucessProvince){ | if(sucessProvince){ | ||||
//成功了后 | |||||
//测试先成功 | |||||
stateMachineUtils.pass(project); | |||||
projectService.updateById(project); | |||||
//直接去预审 | |||||
if(StringUtils.isNotBlank(defaultProjectManage | |||||
.directStartProcess(project,project.getPreStartUserId()))){ | |||||
return Boolean.TRUE; | |||||
} | |||||
} | } | ||||
return Boolean.FALSE; | return Boolean.FALSE; | ||||
@@ -45,6 +45,7 @@ public class ProjectHelper { | |||||
.like(req.getBuildOrg() != null, Project::getBuildOrgName, req.getBuildOrg()) | .like(req.getBuildOrg() != null, Project::getBuildOrgName, req.getBuildOrg()) | ||||
.eq(req.getBuildOrgCode() != null, Project::getBuildOrgCode, req.getBuildOrgCode()) | .eq(req.getBuildOrgCode() != null, Project::getBuildOrgCode, req.getBuildOrgCode()) | ||||
.eq(req.getSuperOrgCode() != null, Project::getSuperOrgCode, req.getSuperOrgCode()) | |||||
.eq(req.getIsTemporaryAugment() != null, Project::getIsTemporaryAugment, req.getIsTemporaryAugment()) | .eq(req.getIsTemporaryAugment() != null, Project::getIsTemporaryAugment, req.getIsTemporaryAugment()) | ||||
//状态 阶段 list | //状态 阶段 list | ||||
.in(CollUtil.isNotEmpty(req.getStageList()),Project::getStage,req.getStageList()) | .in(CollUtil.isNotEmpty(req.getStageList()),Project::getStage,req.getStageList()) | ||||
@@ -222,15 +222,14 @@ public class AnnualPlanLibManage { | |||||
public void exportList(ProjectListReq param, HttpServletResponse response) { | public void exportList(ProjectListReq param, HttpServletResponse response) { | ||||
param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER); | param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER); | ||||
param.setPageSize(CommonConst.EXPORT_PAGE_SIZE); | param.setPageSize(CommonConst.EXPORT_PAGE_SIZE); | ||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | |||||
Integer isTemporaryAugment = param.getIsTemporaryAugment(); | Integer isTemporaryAugment = param.getIsTemporaryAugment(); | ||||
if (Objects.isNull(isTemporaryAugment)) { | if (Objects.isNull(isTemporaryAugment)) { | ||||
throw new BizException("请传入是否临时增补标志!"); | throw new BizException("请传入是否临时增补标志!"); | ||||
} | } | ||||
query.eq(Project::getIsTemporaryAugment, isTemporaryAugment); | |||||
query.eq(Project::getIsTemporaryAugment, 0); | |||||
param.setIsTemporaryAugment(isTemporaryAugment); | |||||
param.setStatusList(CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | |||||
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param); | |||||
query.orderByDesc(Project::getAnnualPlanAddTime); | query.orderByDesc(Project::getAnnualPlanAddTime); | ||||
query.in(Project::getStatus, CollUtils.fieldList(ANNUAL_PLAN_LIST_STATUS, ProjectStatusEnum::getCode)); | |||||
List<Project> projects = projectService.list(query); | List<Project> projects = projectService.list(query); | ||||
ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ExcelExportWriter excelExportWriter = new ExcelExportWriter(); | ||||
@@ -282,6 +282,9 @@ public class ProjectDTO implements Serializable { | |||||
@ApiModelProperty("项目发起人") | @ApiModelProperty("项目发起人") | ||||
private Long sponsor; | private Long sponsor; | ||||
@ApiModelProperty("上级条线单位审核意见") | |||||
private String higherLineSuperOrgReviewComments; | |||||
private Map<String,Object> dynamicForm; | private Map<String,Object> dynamicForm; | ||||
} | } |
@@ -297,10 +297,19 @@ public class Project implements Serializable { | |||||
@ApiModelProperty("项目发起人 用户id") | @ApiModelProperty("项目发起人 用户id") | ||||
private Long sponsor; | private Long sponsor; | ||||
@ApiModelProperty("预审发起人 用户id") | |||||
private Long preStartUserId; | |||||
@ApiModelProperty("上级条线单位审核意见") | |||||
private String higherLineSuperOrgReviewComments; | |||||
@TableField(fill = FieldFill.INSERT) | @TableField(fill = FieldFill.INSERT) | ||||
private Long createBy; | private Long createBy; | ||||
@TableField(fill = FieldFill.INSERT_UPDATE) | @TableField(fill = FieldFill.INSERT_UPDATE) | ||||
private Long updateBy; | private Long updateBy; | ||||
@ApiModelProperty("项目预审申请单文件ID") | |||||
private Long pretrialFileId; | |||||
} | } |
@@ -39,6 +39,9 @@ public class ProjectListReq extends PagePo { | |||||
@ApiModelProperty("申报单位code") | @ApiModelProperty("申报单位code") | ||||
private String buildOrgCode; | private String buildOrgCode; | ||||
@ApiModelProperty("主管单位code") | |||||
private String superOrgCode; | |||||
@ApiModelProperty("项目类型") | @ApiModelProperty("项目类型") | ||||
private Integer projectType; | private Integer projectType; | ||||
@@ -289,6 +289,9 @@ public class ProjectDetailVO { | |||||
@ApiModelProperty("项目发起人id") | @ApiModelProperty("项目发起人id") | ||||
private Long sponsor; | private Long sponsor; | ||||
@ApiModelProperty("上级条线单位审核意见") | |||||
private String higherLineSuperOrgReviewComments; | |||||
private String projectTypeName; | private String projectTypeName; | ||||
public String getProjectTypeName() { | public String getProjectTypeName() { | ||||
@@ -82,7 +82,7 @@ public class ProjectStatusFlowTask { | |||||
projectStagingService.removeById(projectStaging); | projectStagingService.removeById(projectStaging); | ||||
} | } | ||||
}catch (Exception e){ | }catch (Exception e){ | ||||
log.error("项目流转 异常 projectId:【" + projectStaging.getProjectId() + "】 异常内容:" + e); | |||||
log.error("项目流转 异常 projectId:【" + projectStaging.getProjectId() + "】 异常内容:" + e.getMessage()); | |||||
}finally { | }finally { | ||||
//增加重试的次数 和下次扫描时间 | //增加重试的次数 和下次扫描时间 | ||||
projectStagingService.addRetryTimes(projectStaging); | projectStagingService.addRetryTimes(projectStaging); | ||||
@@ -7,6 +7,6 @@ | |||||
set retry_times = #{retryTimes}, | set retry_times = #{retryTimes}, | ||||
next_time = #{nextRetryTime}, | next_time = #{nextRetryTime}, | ||||
dead = #{dead} | dead = #{dead} | ||||
where id = #{id} and retry_times = #{retryTimes - 1} | |||||
where id = #{id} and retry_times = #{retryTimes} - 1 | |||||
</update> | </update> | ||||
</mapper> | </mapper> |
@@ -7,6 +7,6 @@ | |||||
set retry_times = #{retryTimes}, | set retry_times = #{retryTimes}, | ||||
next_time = #{nextRetryTime}, | next_time = #{nextRetryTime}, | ||||
dead = #{dead} | dead = #{dead} | ||||
where id = #{id} and retry_times = #{retryTimes - 1} | |||||
where id = #{id} and retry_times = #{retryTimes} - 1 | |||||
</update> | </update> | ||||
</mapper> | </mapper> |
@@ -2,7 +2,6 @@ package com.ningdatech.pmapi.staging.service.impl; | |||||
import com.ningdatech.pmapi.staging.contants.StagingContant; | import com.ningdatech.pmapi.staging.contants.StagingContant; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | ||||
import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | |||||
import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | ||||
import com.ningdatech.pmapi.staging.mapper.NdWorkNoticeStagingMapper; | import com.ningdatech.pmapi.staging.mapper.NdWorkNoticeStagingMapper; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | ||||
@@ -1,23 +1,9 @@ | |||||
package com.ningdatech.pmapi.staging.utils; | package com.ningdatech.pmapi.staging.utils; | ||||
import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.function.Function; | |||||
import javax.annotation.PostConstruct; | import javax.annotation.PostConstruct; | ||||
import com.ningdatech.pmapi.common.util.SendWorkNoticeUtil; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | |||||
import com.ningdatech.pmapi.staging.model.entity.WorkNoticeStaging; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||
import com.ningdatech.pmapi.projectdeclared.manage.ReviewByDeptJointManage; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.ReviewByProvincialDeptManage; | |||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
/** | /** | ||||
@@ -29,41 +15,11 @@ import lombok.RequiredArgsConstructor; | |||||
@Component | @Component | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class WorkNoticeFlowMapUtil { | public class WorkNoticeFlowMapUtil { | ||||
//public Map<Integer, Function<WorkNoticeInfo,Boolean>> workNoticeFlowFunctionMap = Maps.newHashMap(); | |||||
/** | /** | ||||
* key 重试的次数 , value 是增加是描述 | * key 重试的次数 , value 是增加是描述 | ||||
*/ | */ | ||||
public Map<Integer, Integer> intervalTimeMap = Maps.newHashMap(); | public Map<Integer, Integer> intervalTimeMap = Maps.newHashMap(); | ||||
///** | |||||
// * 初始化工作通知分派逻辑,代替了if-else部分 | |||||
// * key: 枚举 消息类型 | |||||
// * value: lambda表达式,最终会获取发送工作通知的函数 | |||||
// */ | |||||
//@PostConstruct | |||||
//public void workNoticeFlowFunctionInit(){ | |||||
// // 待审核 | |||||
// workNoticeFlowFunctionMap.put(MsgTypeEnum.AUDIT.getCode(), | |||||
// workNoticeInfos-> SendWorkNoticeUtil.sendWorkNotice(workNoticeInfos)); | |||||
// | |||||
// // 审核通过 | |||||
// workNoticeFlowFunctionMap.put(MsgTypeEnum.PASS.getCode(), | |||||
// workNoticeInfos-> SendWorkNoticeUtil.sendWorkNotice(workNoticeInfos)); | |||||
// | |||||
// // 被驳回 | |||||
// workNoticeFlowFunctionMap.put(MsgTypeEnum.REJECTED.getCode(), | |||||
// workNoticeInfos-> SendWorkNoticeUtil.sendWorkNotice(workNoticeInfos)); | |||||
// | |||||
// // 被退回 | |||||
// workNoticeFlowFunctionMap.put(MsgTypeEnum.BACKED.getCode(), | |||||
// workNoticeInfos-> SendWorkNoticeUtil.sendWorkNotice(workNoticeInfos)); | |||||
// | |||||
// // 被驳回 | |||||
// workNoticeFlowFunctionMap.put(MsgTypeEnum.REJECTED.getCode(), | |||||
// workNoticeInfos-> SendWorkNoticeUtil.sendWorkNotice(workNoticeInfos)); | |||||
// | |||||
//} | |||||
/** | /** | ||||
* 扫描的间隔越来越长 秒数 | * 扫描的间隔越来越长 秒数 | ||||
*/ | */ | ||||
@@ -32,6 +32,7 @@ import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | import com.ningdatech.pmapi.projectlib.service.IProjectService; | ||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | ||||
import com.ningdatech.pmapi.staging.service.IProjectStagingService; | |||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.AdjustHandleDTO; | import com.ningdatech.pmapi.todocenter.model.dto.AdjustHandleDTO; | ||||
import com.ningdatech.pmapi.todocenter.model.vo.ProcessProgressDetailVo; | import com.ningdatech.pmapi.todocenter.model.vo.ProcessProgressDetailVo; | ||||
@@ -105,6 +106,8 @@ public class TodoCenterManage { | |||||
private final UserInfoHelper userInfoHelper; | private final UserInfoHelper userInfoHelper; | ||||
private final BuildUserUtils buildUserUtils; | private final BuildUserUtils buildUserUtils; | ||||
private final IProjectStagingService projectStagingService; | |||||
/** | /** | ||||
* 待办中心待我处理项目列表查询 | * 待办中心待我处理项目列表查询 | ||||
@@ -229,8 +232,6 @@ public class TodoCenterManage { | |||||
Integer projectStatus = declaredProject.getStatus(); | Integer projectStatus = declaredProject.getStatus(); | ||||
// 获取当前未处理流程详情 | // 获取当前未处理流程详情 | ||||
ProcessProgressVo currentInstanceDetail = processInstanceService.getProgressInstanceDetail(null, processInstanceId); | ProcessProgressVo currentInstanceDetail = processInstanceService.getProgressInstanceDetail(null, processInstanceId); | ||||
// 获取当前未处理流程状态 | |||||
String currentProcessStatus = currentInstanceDetail.getStatus(); | |||||
// 获取当前要处理的流程实例 | // 获取当前要处理的流程实例 | ||||
HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery() | ||||
@@ -256,7 +257,7 @@ public class TodoCenterManage { | |||||
// 获取流程通过后当前审核人信息,向其发送工作通知 | // 获取流程通过后当前审核人信息,向其发送工作通知 | ||||
List<ProgressNode> newProgressInfo = newInstanceDetail.getProgressInfo(); | List<ProgressNode> newProgressInfo = newInstanceDetail.getProgressInfo(); | ||||
ProgressNode currentNode = newProgressInfo.get(newProgressInfo.size() - 1); | ProgressNode currentNode = newProgressInfo.get(newProgressInfo.size() - 1); | ||||
UserInfo auditUserInfo = null; | |||||
UserInfo auditUserInfo; | |||||
// 说明当前节点是子流程节点 | // 说明当前节点是子流程节点 | ||||
if (currentNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | if (currentNode.getNodeType().name().equals(NodeTypeEnum.SUB.name())) { | ||||
List<ProgressNode> children = currentNode.getChildren(); | List<ProgressNode> children = currentNode.getChildren(); | ||||
@@ -267,31 +268,25 @@ public class TodoCenterManage { | |||||
auditUserInfo = userInfoService.getById(Long.valueOf(currentNode.getUserId())); | auditUserInfo = userInfoService.getById(Long.valueOf(currentNode.getUserId())); | ||||
} | } | ||||
// 如果流程状态是被退回状态,流程通过后,进入下一个审核人, | |||||
// 当前通过审核人一定不是最后一个审核人(下一个审核人至多是最后一个) | |||||
if (ProcessStatusEnum.BE_BACKED.getDesc().equals(currentProcessStatus)) { | |||||
// 获取发送浙政钉工作通知必要信息 | |||||
WorkNoticeInfo passWorkNoticeInfo = getSendWorkNoticeInfo(auditUserInfo); | |||||
String passMsg = String.format(PASS_MSG_TEMPLATE, passWorkNoticeInfo.getOrganizationName(), projectName); | |||||
passWorkNoticeInfo.setMsg(passMsg); | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | |||||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.AUDIT); | |||||
return; | |||||
} | |||||
// 若不是被退回状态,流程通过后,判断当前登录用户是不是最后一个审核人 | |||||
// 流程通过后,判断当前登录用户是不是最后一个审核人 | |||||
// 若当前登录用户是最后一个审批人,需更新流程状态为审核完成,项目状态到下个状态 | // 若当前登录用户是最后一个审批人,需更新流程状态为审核完成,项目状态到下个状态 | ||||
// 并向流程发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | // 并向流程发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 | ||||
if (HisProInsEndActId.END.equals(newInstance.getEndActivityId())) { | if (HisProInsEndActId.END.equals(newInstance.getEndActivityId())) { | ||||
switch (Objects.requireNonNull(ProjectStatusEnum.getValue(projectStatus))) { | switch (Objects.requireNonNull(ProjectStatusEnum.getValue(projectStatus))) { | ||||
// 当前项目状态是预审中 | |||||
case PRE_APPLYING: | |||||
//先修改项目状态 | |||||
updatePassProjectStatus(userId, declaredProject); | |||||
//然后入库暂存库 | |||||
projectStagingService.addByProject(declaredProject,"暂存入库 待提交部门联审"); | |||||
break; | |||||
// 当前项目状态是单位内部审核中 | // 当前项目状态是单位内部审核中 | ||||
case UNDER_INTERNAL_AUDIT: | case UNDER_INTERNAL_AUDIT: | ||||
// 当前项目状态是预审中 | |||||
case PRE_APPLYING: | |||||
// 当前项目状态是部门联审中 | |||||
// 当前项目状态是部门联审中 | |||||
case DEPARTMENT_JOINT_REVIEW: | case DEPARTMENT_JOINT_REVIEW: | ||||
// 当前项目状态是方案评审中 | |||||
// 当前项目状态是方案评审中 | |||||
case SCHEME_UNDER_REVIEW: | case SCHEME_UNDER_REVIEW: | ||||
// 当前项目状态是终验审核中 | |||||
// 当前项目状态是终验审核中 | |||||
case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | case FINAL_ACCEPTANCE_IS_UNDER_REVIEW: | ||||
updatePassProjectStatus(userId, declaredProject); | updatePassProjectStatus(userId, declaredProject); | ||||
break; | break; | ||||
@@ -0,0 +1,140 @@ | |||||
package com.ningdatech.pmapi.todocenter.model.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.math.BigDecimal; | |||||
/** | |||||
* pdf生成实体 | |||||
* | |||||
* @author CMM | |||||
* @since 2023/03/13 14:24 | |||||
*/ | |||||
@Data | |||||
public class PdfGenerateDTO { | |||||
@ApiModelProperty("应用ID") | |||||
private Long id; | |||||
@ApiModelProperty("项目名称") | |||||
private String projectName; | |||||
@ApiModelProperty("是否临时增补 0:否 1:是") | |||||
private String isTemporaryAugment; | |||||
@ApiModelProperty("项目负责人") | |||||
private String responsibleMan; | |||||
@ApiModelProperty("负责人手机号码") | |||||
private String responsibleManMobile; | |||||
@ApiModelProperty("项目联系人") | |||||
private String contactName; | |||||
@ApiModelProperty("项目联系人手机号码") | |||||
private String contactPhone; | |||||
@ApiModelProperty("建设单位名称") | |||||
private String buildOrgName; | |||||
@ApiModelProperty("建设单位统一社会信用代码") | |||||
private String orgCreditCode; | |||||
@ApiModelProperty("项目类型 1:建设 2:运维") | |||||
private String projectType; | |||||
@ApiModelProperty("是否首次新建 0:否 1:是") | |||||
private String isFirst; | |||||
@ApiModelProperty("项目预算年度") | |||||
private Integer projectYear; | |||||
@ApiModelProperty("项目建设起止时间") | |||||
private String beginAndEndTime; | |||||
@ApiModelProperty("四大体系 1:业务应用 2:应用支撑 3:数据资源 4:基础设施") | |||||
private String fourSystems; | |||||
@ApiModelProperty("是否数字化改革项目 0:否 1:是") | |||||
private String isDigitalReform; | |||||
@ApiModelProperty("综合业务领域") | |||||
private String bizDomain; | |||||
@ApiModelProperty("立项依据") | |||||
private String buildBasis; | |||||
@ApiModelProperty("是否上云 0:否 1:是") | |||||
private String isCloud; | |||||
private String cloudType; | |||||
@ApiModelProperty("等保级别 1:一级 2:二级 3:三级 4:四级 5:五级") | |||||
private Integer protectionLevel; | |||||
@ApiModelProperty("是否密评 0:否 1:是") | |||||
private Integer isSecretComments; | |||||
@ApiModelProperty("项目简介") | |||||
private String projectIntroduction; | |||||
@ApiModelProperty("资金申报情况-申报金额(万元)") | |||||
private BigDecimal declareAmount; | |||||
@ApiModelProperty("资金申报情况-自有金额(万元)") | |||||
private BigDecimal declareHaveAmount; | |||||
@ApiModelProperty("资金申报情况-政府投资-本级财政资金(万元)") | |||||
private BigDecimal declareGovOwnFinanceAmount; | |||||
@ApiModelProperty("资金申报情况-政府投资-上级补助资金(万元)") | |||||
private BigDecimal declareGovSuperiorFinanceAmount; | |||||
@ApiModelProperty("银行贷款(万元)") | |||||
private BigDecimal declareBankLendingAmount; | |||||
@ApiModelProperty("其它资金(万元)") | |||||
private BigDecimal declareOtherAmount; | |||||
@ApiModelProperty("资金分配情况-软件开发(万元)") | |||||
private BigDecimal softwareDevelopmentAmount; | |||||
@ApiModelProperty("资金分配情况-云资源、硬件购置(万元)") | |||||
private BigDecimal cloudHardwarePurchaseAmount; | |||||
@ApiModelProperty("资金分配情况-第三方服务(万元)") | |||||
private BigDecimal thirdPartyAmount; | |||||
@ApiModelProperty("年度支付计划-年度支付计划(万元)") | |||||
private BigDecimal annualPlanAmount; | |||||
@ApiModelProperty("年度支付计划-自有金额(万元)") | |||||
private BigDecimal annualPlanHaveAmount; | |||||
@ApiModelProperty("年度支付计划-政府投资-本级财政资金(万元)") | |||||
private BigDecimal annualPlanGovOwnFinanceAmount; | |||||
@ApiModelProperty("年度支付计划-政府投资-上级补助资金(万元)") | |||||
private BigDecimal annualPlanGovSuperiorFinanceAmount; | |||||
@ApiModelProperty("年度支付计划-银行贷款(万元)") | |||||
private BigDecimal annualPlanBankLendingAmount; | |||||
@ApiModelProperty("年度支付计划-其它资金(万元)") | |||||
private BigDecimal annualPlanOtherAmount; | |||||
@ApiModelProperty("备注") | |||||
private String projectRemarks; | |||||
@ApiModelProperty("附件-是否开启 false:关闭 true:开启") | |||||
private Boolean isAccessories; | |||||
@ApiModelProperty("备注-是否开启 false:关闭 true:开启") | |||||
private Boolean isRemarks; | |||||
@ApiModelProperty("年度支付计划-是否开启 false:关闭 true:开启") | |||||
private Boolean isAnnualPlanAmount; | |||||
@ApiModelProperty("一地创新全省共享项目-是否开启 false:关闭 true:开启") | |||||
private Boolean isInnovateWholeProvinceShare; | |||||
} |
@@ -0,0 +1,140 @@ | |||||
package com.ningdatech.pmapi.todocenter.utils; | |||||
import com.itextpdf.text.Image; | |||||
import com.itextpdf.text.Rectangle; | |||||
import com.itextpdf.text.pdf.*; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import java.io.*; | |||||
import java.util.*; | |||||
/** | |||||
* pdf 生成工具 | |||||
* | |||||
* @author CMM | |||||
* @since 2023/03/13 13:41 | |||||
*/ | |||||
@Slf4j | |||||
public class PdfGenerateUtil { | |||||
private PdfGenerateUtil() { | |||||
} | |||||
/** | |||||
* 生成填充了模板参数的pdf | |||||
* | |||||
* @param templatePdfInputStream 模板pdf流 | |||||
* @param paramsMap 填充参数 | |||||
* @return | |||||
*/ | |||||
public static byte[] generatePdf(InputStream templatePdfInputStream,Map<String, Object> paramsMap) throws IOException { | |||||
byte[] templatePdfByteArray = readBytes(templatePdfInputStream); | |||||
return generatePdf(templatePdfByteArray, paramsMap); | |||||
} | |||||
/** | |||||
* 生成填充了模板参数的pdf | |||||
* | |||||
* @param templatePdfByteArray 模板pdf字节数组 | |||||
* @param paramsMap 填充参数 | |||||
* @return | |||||
*/ | |||||
public static byte[] generatePdf(byte[] templatePdfByteArray, Map<String, Object> paramsMap) { | |||||
PdfReader reader = null; | |||||
ByteArrayOutputStream bos = null; | |||||
try { | |||||
//创建书写器,用于往document中书写信息 | |||||
// 通过本地文件路径获取资源 | |||||
reader = new PdfReader(templatePdfByteArray); | |||||
bos = new ByteArrayOutputStream(); | |||||
PdfStamper stamper = new PdfStamper(reader, bos); | |||||
//使用中文字体 | |||||
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); | |||||
ArrayList<BaseFont> fontList = new ArrayList<>(); | |||||
fontList.add(baseFont); | |||||
AcroFields form = stamper.getAcroFields(); | |||||
form.setSubstitutionFonts(fontList); | |||||
for (String fieldName : paramsMap.keySet()) { | |||||
if (paramsMap.get(fieldName) == null) { | |||||
continue; | |||||
} | |||||
if (fieldName.indexOf("Image") > 0) { | |||||
String imgPath = paramsMap.get(fieldName).toString(); | |||||
int pageNo = form.getFieldPositions(fieldName).get(0).page; | |||||
Rectangle rectangle = form.getFieldPositions(fieldName).get(0).position; | |||||
float x = rectangle.getLeft(); | |||||
float y = rectangle.getTop(); | |||||
//根据路径读取图片 | |||||
Image image = Image.getInstance(imgPath); | |||||
//获取图片页面 | |||||
PdfContentByte under = stamper.getOverContent(pageNo); | |||||
//图片大小自适应 | |||||
image.scaleToFit(rectangle.getWidth(), rectangle.getHeight()); | |||||
//添加图片 | |||||
image.setAbsolutePosition(x, y - rectangle.getHeight()); | |||||
under.addImage(image); | |||||
} else { | |||||
// 设置占位字段 | |||||
form.setField(fieldName, paramsMap.get(fieldName).toString()); | |||||
} | |||||
} | |||||
stamper.setFormFlattening(false); | |||||
stamper.close(); | |||||
} catch (Exception e) { | |||||
log.error("通过模板生成PDF失败", e.getMessage()); | |||||
return null; | |||||
} finally { | |||||
try { | |||||
if (null != reader) { | |||||
reader.close(); | |||||
} | |||||
if (null != bos) { | |||||
bos.close(); | |||||
} | |||||
} catch (IOException e) { | |||||
log.error("close resource error", e.getMessage()); | |||||
} | |||||
} | |||||
return bos.toByteArray(); | |||||
} | |||||
/** | |||||
* 读取输入流到字节数组 | |||||
* | |||||
* @param in | |||||
* @return | |||||
* @throws IOException | |||||
*/ | |||||
private static byte[] readBytes(InputStream in) throws IOException { | |||||
//读取字节的缓冲 | |||||
byte[] buffer = new byte[1024]; | |||||
//最终的数据 | |||||
byte[] result = new byte[0]; | |||||
int size = 0; | |||||
while ((size = in.read(buffer)) != -1) { | |||||
int oldLen = result.length; | |||||
byte[] tmp = new byte[oldLen + size]; | |||||
if (oldLen > 0) {//copy 旧字节 | |||||
System.arraycopy(result, 0, tmp, 0, oldLen); | |||||
} | |||||
//copy 新字节 | |||||
System.arraycopy(buffer, 0, tmp, oldLen, size); | |||||
result = tmp; | |||||
} | |||||
return result; | |||||
} | |||||
} | |||||
@@ -0,0 +1,153 @@ | |||||
package com.ningdatech.pmapi.todocenter.utils; | |||||
import com.itextpdf.text.DocumentException; | |||||
import com.itextpdf.text.pdf.*; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Propagation; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import org.xhtmlrenderer.pdf.ITextFontResolver; | |||||
import org.xhtmlrenderer.pdf.ITextRenderer; | |||||
import java.io.*; | |||||
import java.nio.charset.StandardCharsets; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Paths; | |||||
import java.util.Map; | |||||
import java.util.UUID; | |||||
/** | |||||
* pdf生成工具类 | |||||
* | |||||
* @author CMM | |||||
* @since 2023/03/13 17:01 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
public class PdfUtils { | |||||
/** | |||||
* 生成PDF文件 | |||||
* | |||||
* @return int | |||||
* @author CMM | |||||
* @since 2023/03/13 17:07 | |||||
*/ | |||||
public byte[] generatePdf(InputStream templateHtmlInputStream, Map<String, Object> paramsMap){ | |||||
FileInputStream inputStream = null; | |||||
try { | |||||
File directory = new File(""); | |||||
//pdf输出路径 | |||||
String absolutePath = directory.getAbsolutePath(); | |||||
String linkPath = "\\src\\main\\resources"; | |||||
String filePath = absolutePath + linkPath + "\\template\\fileout"; | |||||
if(!new File(filePath).exists()){ | |||||
new File(filePath).mkdir(); | |||||
} | |||||
//字体格式 | |||||
String FONT = absolutePath + linkPath + "\\template\\simsun.ttc"; | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(templateHtmlInputStream, StandardCharsets.UTF_8)); | |||||
String line; | |||||
while ((line = bufferedReader.readLine()) != null) { | |||||
stringBuilder.append(line); | |||||
} | |||||
String htmlInfo = stringBuilder.toString(); | |||||
//替换参数、多个参数多次替换 | |||||
for (String fieldName : paramsMap.keySet()) { | |||||
if (paramsMap.get(fieldName) == null) { | |||||
continue; | |||||
} | |||||
// 设置占位字段 | |||||
htmlInfo = htmlInfo.replace("#" + fieldName + "#", paramsMap.get(fieldName).toString()); | |||||
} | |||||
//生成临时文件 | |||||
String htmlFileName = UUID.randomUUID().toString().replace("-","") + ".html"; | |||||
String htmlFilePath = filePath + File.separator + htmlFileName; | |||||
File file = new File(htmlFilePath); | |||||
FileOutputStream fop = new FileOutputStream(file); | |||||
if (!file.exists()) { | |||||
file.createNewFile(); | |||||
} | |||||
byte[] contentInBytes = htmlInfo.getBytes(); | |||||
fop.write(contentInBytes); | |||||
fop.flush(); | |||||
fop.close(); | |||||
//生成pdf | |||||
String fileName = UUID.randomUUID().toString().replace("-","") + ".pdf"; | |||||
String pdfFilePath = filePath + File.separator + fileName; | |||||
String url = new File(htmlFilePath).toURI().toURL().toString(); | |||||
OutputStream os = Files.newOutputStream(Paths.get(pdfFilePath)); | |||||
ITextRenderer renderer = new ITextRenderer(); | |||||
renderer.setDocument(url); | |||||
ITextFontResolver fontResolver = renderer.getFontResolver(); | |||||
fontResolver.addFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); | |||||
renderer.layout(); | |||||
renderer.createPDF(os); | |||||
os.flush(); | |||||
os.close(); | |||||
inputStream = new FileInputStream(pdfFilePath); | |||||
//删除临时文件 | |||||
File delFile = new File(pdfFilePath); | |||||
if(delFile.exists()){ | |||||
delFile.delete(); | |||||
} | |||||
File delHtmlFile = new File(htmlFilePath); | |||||
if(delHtmlFile.exists()){ | |||||
delHtmlFile.delete(); | |||||
} | |||||
// 返回生成的pdf文件字节数组 | |||||
return readBytes(inputStream); | |||||
} catch (IOException e) { | |||||
throw new BizException("生成pdf文件失败!"); | |||||
} catch (DocumentException e) { | |||||
throw new BizException("生成pdf文件失败!"); | |||||
} finally { | |||||
try { | |||||
if (null != inputStream) { | |||||
inputStream.close(); | |||||
} | |||||
} catch (IOException e) { | |||||
log.error("close resource error", e.getMessage()); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* 读取输入流到字节数组 | |||||
* | |||||
* @param in | |||||
* @return | |||||
* @throws IOException | |||||
*/ | |||||
private byte[] readBytes(InputStream in) throws IOException { | |||||
//读取字节的缓冲 | |||||
byte[] buffer = new byte[1024]; | |||||
//最终的数据 | |||||
byte[] result = new byte[0]; | |||||
int size = 0; | |||||
while ((size = in.read(buffer)) != -1) { | |||||
int oldLen = result.length; | |||||
byte[] tmp = new byte[oldLen + size]; | |||||
if (oldLen > 0) {//copy 旧字节 | |||||
System.arraycopy(result, 0, tmp, 0, oldLen); | |||||
} | |||||
//copy 新字节 | |||||
System.arraycopy(buffer, 0, tmp, oldLen, size); | |||||
result = tmp; | |||||
} | |||||
return result; | |||||
} | |||||
} |
@@ -1,5 +1,6 @@ | |||||
package com.ningdatech.pmapi.user.model.vo; | package com.ningdatech.pmapi.user.model.vo; | ||||
import com.ningdatech.pmapi.common.constant.RegionConst; | |||||
import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||
import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||
import lombok.Data; | import lombok.Data; | ||||
@@ -48,4 +49,13 @@ public class ResUserDetailVO { | |||||
@ApiModelProperty("更新时间") | @ApiModelProperty("更新时间") | ||||
private LocalDateTime updateTime; | private LocalDateTime updateTime; | ||||
//是否是市级单位 | |||||
public Boolean getIsMunicipalOrg(){ | |||||
//如果是丽水市本级的code 就是 | |||||
if(RegionConst.RC_LS.equals(this.regionCode)){ | |||||
return Boolean.TRUE; | |||||
} | |||||
return Boolean.FALSE; | |||||
} | |||||
} | } |
@@ -0,0 +1,254 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8" /> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||||
<title>Document</title> | |||||
<style> | |||||
html, | |||||
body { | |||||
padding: 0; | |||||
margin: 0; | |||||
} | |||||
.pdf { | |||||
margin: 0 auto; | |||||
padding: 10px 0 30px; | |||||
text-align: center; | |||||
} | |||||
.title { | |||||
padding: 0 0 40px 0; | |||||
font-size: 34px; | |||||
margin: 40px 0 0 0; | |||||
} | |||||
.tab { | |||||
padding: 0 20px; | |||||
} | |||||
.projectId { | |||||
color: #999999; | |||||
text-align: left; | |||||
margin-bottom: 8px; | |||||
} | |||||
.projectId > .time { | |||||
float: right; | |||||
} | |||||
table { | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
font-size: 16px; | |||||
table-layout: fixed; | |||||
word-break: break-all; | |||||
text-align: left; | |||||
} | |||||
td { | |||||
padding: 15px 8px; | |||||
border: 1px solid; | |||||
} | |||||
.tabTit { | |||||
background-color: #eee; | |||||
} | |||||
.label { | |||||
width: 150px; | |||||
} | |||||
.sealTd { | |||||
height: 200px; | |||||
position: relative; | |||||
} | |||||
.seal { | |||||
position: absolute; | |||||
right: 20px; | |||||
bottom: 30px; | |||||
width: 150px; | |||||
} | |||||
.seal > .time { | |||||
text-align: right; | |||||
} | |||||
.content { | |||||
height: 150px; | |||||
} | |||||
.text { | |||||
min-height: 150px; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div class="pdf"> | |||||
<p class="title"> | |||||
【 | |||||
<span></span> | |||||
】预审申请单 | |||||
</p> | |||||
<div class="tab"> | |||||
<p class="projectId"> | |||||
<span> | |||||
项目编号: | |||||
<span></span> | |||||
</span> | |||||
<span class="time"></span> | |||||
</p> | |||||
<table> | |||||
<tbody> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">项目基本信息</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目名称</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否临时增补</td> | |||||
<td></td> | |||||
<td class="label">是否一地创新全省共享项目</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目负责人</td> | |||||
<td></td> | |||||
<td class="label">负责人手机号</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目联系人</td> | |||||
<td></td> | |||||
<td class="label">项目联系人手机号</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">建设单位</td> | |||||
<td></td> | |||||
<td class="label">建设单位统一社会信用代码</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目类型</td> | |||||
<td></td> | |||||
<td class="label">是否首次新建</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">预算年度</td> | |||||
<td></td> | |||||
<td class="label">建设起止时间</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">四大体系</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否数字化改革项目</td> | |||||
<td></td> | |||||
<td class="label">综合业务领域</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">立项依据</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否上云</td> | |||||
<td></td> | |||||
<td class="label">云类型</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目简介</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">资金申报情况</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">申报金额</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">自有资金</td> | |||||
<td></td> | |||||
<td class="label">政府投资-本级财政资金</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">政府投资-上级补助资金</td> | |||||
<td></td> | |||||
<td class="label">银行贷款</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">自有资金</td> | |||||
<td></td> | |||||
<td class="label">政府投资-本级财政资金</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">其他资金</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">2021年计划投资(万元)</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">资金分配情况</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">软件开发</td> | |||||
<td></td> | |||||
<td class="label">云资源、硬件购置</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">第三方服务</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">年度支付计划</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">年度支付金额</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">自有资金</td> | |||||
<td></td> | |||||
<td class="label">政府投资-本级财政资金</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">政府投资-上级补助资金</td> | |||||
<td></td> | |||||
<td class="label">银行贷款</td> | |||||
<td></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">其他资金</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">备注</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">备注</td> | |||||
<td colspan="3"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">单位意见</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">本级主管单位意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">上级主管单位意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">{本地区大数据局的名称}意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,249 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:font-family="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta charset="UTF-8" /> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||||
<title>Document</title> | |||||
<style> | |||||
html, | |||||
body { | |||||
padding: 0; | |||||
margin: 0; | |||||
font-family:SimSun; | |||||
} | |||||
.pdf { | |||||
margin: 0 auto; | |||||
padding: 10px 0 30px; | |||||
text-align: center; | |||||
} | |||||
.title { | |||||
padding: 0 0 40px 0; | |||||
font-size: 34px; | |||||
margin: 40px 0 0 0; | |||||
font-family:SimSun; | |||||
} | |||||
.tab { | |||||
padding: 0 20px; | |||||
} | |||||
.projectId { | |||||
color: #999999; | |||||
text-align: left; | |||||
margin-bottom: 8px; | |||||
} | |||||
.projectId > .time { | |||||
float: right; | |||||
} | |||||
table { | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
font-size: 16px; | |||||
table-layout: fixed; | |||||
word-break: break-all; | |||||
word-wrap: break-word; | |||||
text-align: left; | |||||
} | |||||
td { | |||||
padding: 15px 8px; | |||||
border: 1px solid; | |||||
} | |||||
.tabTit { | |||||
background-color: #eee; | |||||
} | |||||
.label { | |||||
width: 150px; | |||||
} | |||||
.sealTd { | |||||
height: 200px; | |||||
position: relative; | |||||
} | |||||
.seal { | |||||
position: absolute; | |||||
right: 20px; | |||||
bottom: 30px; | |||||
width: 150px; | |||||
} | |||||
.seal > .time { | |||||
text-align: right; | |||||
} | |||||
.content { | |||||
height: 150px; | |||||
} | |||||
.text { | |||||
min-height: 150px; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div class="pdf"> | |||||
<p class="title"> | |||||
预审申请单 | |||||
</p> | |||||
<div class="tab"> | |||||
<p class="projectId"> | |||||
<span> | |||||
项目编号: | |||||
<span>#projectNo#</span> | |||||
</span> | |||||
<span class="time">#time#</span> | |||||
</p> | |||||
<table> | |||||
<tbody> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">项目基本信息</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目名称</td> | |||||
<td colspan="3" align="center">#projectName#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否临时增补</td> | |||||
<td align="center">#isTemporaryAugment#</td> | |||||
<td class="label">是否一地创新全省共享项目</td> | |||||
<td align="center">#isInnovateWholeProvinceShare#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目负责人</td> | |||||
<td align="center">#responsibleMan#</td> | |||||
<td class="label">负责人手机号</td> | |||||
<td align="center">#responsibleManMobile#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目联系人</td> | |||||
<td align="center">#contactName#</td> | |||||
<td class="label">项目联系人手机号</td> | |||||
<td align="center">#contactPhone#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">建设单位</td> | |||||
<td align="center">#buildOrgName#</td> | |||||
<td class="label">建设单位统一社会信用代码</td> | |||||
<td align="center">#orgCreditCode#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目类型</td> | |||||
<td align="center">#projectType#</td> | |||||
<td class="label">是否首次新建</td> | |||||
<td align="center">#isFirst#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">预算年度</td> | |||||
<td align="center">#projectYear#</td> | |||||
<td class="label">建设起止时间</td> | |||||
<td align="center">#beginAndEndTime#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">四大体系</td> | |||||
<td colspan="3" align="center">#fourSystems#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否数字化改革项目</td> | |||||
<td align="center">#isDigitalReform#</td> | |||||
<td class="label">综合业务领域</td> | |||||
<td align="center">#bizDomain#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">立项依据</td> | |||||
<td colspan="3" align="center">#buildBasis#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">是否上云</td> | |||||
<td align="center">#isCloud#</td> | |||||
<td class="label">云类型</td> | |||||
<td align="center">#cloudType#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">项目简介</td> | |||||
<td colspan="3" align="center">#projectIntroduction#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">资金申报情况</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">申报金额</td> | |||||
<td colspan="3" align="center">#declareAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">自有资金</td> | |||||
<td align="center">#declareHaveAmount#</td> | |||||
<td class="label">政府投资-本级财政资金</td> | |||||
<td align="center">#declareGovOwnFinanceAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">政府投资-上级补助资金</td> | |||||
<td align="center">#declareGovSuperiorFinanceAmount#</td> | |||||
<td class="label">银行贷款</td> | |||||
<td align="center">#declareBankLendingAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">其他资金</td> | |||||
<td colspan="3" align="center">#declareOtherAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">本年计划投资(万元)</td> | |||||
<td colspan="3" align="center">#yearPlanInvest#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">资金分配情况</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">软件开发</td> | |||||
<td align="center">#softwareDevelopmentAmount#</td> | |||||
<td class="label">云资源、硬件购置</td> | |||||
<td align="center">#cloudHardwarePurchaseAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">第三方服务</td> | |||||
<td colspan="3" align="center">#thirdPartyAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">年度支付计划</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">年度支付金额</td> | |||||
<td colspan="3" align="center">#annualPlanAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">自有资金</td> | |||||
<td align="center">#annualPlanHaveAmount#</td> | |||||
<td class="label">政府投资-本级财政资金</td> | |||||
<td align="center">#annualPlanGovOwnFinanceAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">政府投资-上级补助资金</td> | |||||
<td align="center">#annualPlanGovSuperiorFinanceAmount#</td> | |||||
<td class="label">银行贷款</td> | |||||
<td align="center">#annualPlanBankLendingAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">其他资金</td> | |||||
<td colspan="3" align="center">#annualPlanOtherAmount#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">备注</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">备注</td> | |||||
<td colspan="3" align="center">#projectRemarks#</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="tabTit" colspan="4">单位意见</td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">本级主管单位意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">上级主管单位意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
<tr> | |||||
<td class="label">{本地区大数据局的名称}意见(盖章)</td> | |||||
<td colspan="3" class="text content"></td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@@ -1,18 +1,38 @@ | |||||
package com.ningdatech.pmapi.todocenter; | package com.ningdatech.pmapi.todocenter; | ||||
import cn.hutool.core.util.StrUtil; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.ningdatech.basic.model.GenericResult; | import com.ningdatech.basic.model.GenericResult; | ||||
import com.ningdatech.basic.util.NdDateUtils; | |||||
import com.ningdatech.file.entity.vo.result.FileResultVO; | |||||
import com.ningdatech.file.service.FileService; | |||||
import com.ningdatech.pmapi.AppTests; | import com.ningdatech.pmapi.AppTests; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; | |||||
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | |||||
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO; | |||||
import com.ningdatech.pmapi.projectlib.service.IProjectService; | |||||
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; | ||||
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; | ||||
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; | ||||
import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage; | import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage; | ||||
import com.ningdatech.pmapi.todocenter.model.dto.PdfGenerateDTO; | |||||
import com.ningdatech.pmapi.todocenter.utils.PdfGenerateUtil; | |||||
import com.ningdatech.pmapi.todocenter.utils.PdfUtils; | |||||
import com.ningdatech.pmapi.user.entity.UserInfo; | import com.ningdatech.pmapi.user.entity.UserInfo; | ||||
import com.ningdatech.pmapi.user.service.IUserInfoService; | import com.ningdatech.pmapi.user.service.IUserInfoService; | ||||
import com.ningdatech.zwdd.client.ZwddClient; | import com.ningdatech.zwdd.client.ZwddClient; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.mock.web.MockMultipartFile; | |||||
import org.springframework.web.multipart.MultipartFile; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.time.LocalDateTime; | |||||
import java.util.concurrent.*; | import java.util.concurrent.*; | ||||
import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE; | import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE; | ||||
@@ -25,10 +45,6 @@ import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPL | |||||
*/ | */ | ||||
@Slf4j | @Slf4j | ||||
public class TodoCenterTest extends AppTests { | public class TodoCenterTest extends AppTests { | ||||
//@Autowired | |||||
//private TaskExecutor executor; | |||||
@Autowired | @Autowired | ||||
private TodoCenterManage todoCenterManage; | private TodoCenterManage todoCenterManage; | ||||
@Autowired | @Autowired | ||||
@@ -37,6 +53,14 @@ public class TodoCenterTest extends AppTests { | |||||
private ZwddClient zwddClient; | private ZwddClient zwddClient; | ||||
@Autowired | @Autowired | ||||
private INdWorkNoticeStagingService workNoticeStagingService; | private INdWorkNoticeStagingService workNoticeStagingService; | ||||
@Autowired | |||||
private ProjectLibManage projectLibManage; | |||||
@Autowired | |||||
private FileService fileService; | |||||
@Autowired | |||||
private IProjectService projectService; | |||||
@Autowired | |||||
private PdfUtils pdfUtils; | |||||
@Test | @Test | ||||
public void sendWorkNoticeTest() throws ExecutionException, InterruptedException { | public void sendWorkNoticeTest() throws ExecutionException, InterruptedException { | ||||
//String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-00-测试项目"); | //String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-00-测试项目"); | ||||
@@ -98,4 +122,58 @@ public class TodoCenterTest extends AppTests { | |||||
// 放入工作通知暂存表中,通过扫表异步发送 | // 放入工作通知暂存表中,通过扫表异步发送 | ||||
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.AUDIT); | workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.AUDIT); | ||||
} | } | ||||
@Test | |||||
public void GeneratePdf(){ | |||||
// 获取本地目录的pdf模板 | |||||
String fileName = "预审申请单"; | |||||
InputStream pdfInputStream = | |||||
this.getClass().getClassLoader().getResourceAsStream("template/" + fileName + ".html"); | |||||
// 获取表单数据 | |||||
ProjectDetailVO projectDetail = projectLibManage.getProjectDetail(44L); | |||||
PdfGenerateDTO pdfGenerateDTO = new PdfGenerateDTO(); | |||||
BeanUtils.copyProperties(projectDetail, pdfGenerateDTO); | |||||
// 设置pdf模板参数 | |||||
JSONObject paramsMap = JSONObject.parseObject(JSONObject.toJSONString(pdfGenerateDTO)); | |||||
paramsMap.put("time", NdDateUtils.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm")); | |||||
paramsMap.put("isTemporaryAugment", "否"); | |||||
Integer projectType = projectDetail.getProjectType(); | |||||
paramsMap.put("projectType", ProjectTypeEnum.getDesc(projectType)); | |||||
Integer isFirst = projectDetail.getIsFirst(); | |||||
paramsMap.put("isFirst", "是"); | |||||
Boolean isInnovateWholeProvinceShare = projectDetail.getIsInnovateWholeProvinceShare(); | |||||
paramsMap.put("isInnovateWholeProvinceShare", Boolean.TRUE.equals(isInnovateWholeProvinceShare) ? "是" : "否"); | |||||
String beginTime = projectDetail.getBeginTime(); | |||||
String endTime = projectDetail.getEndTime(); | |||||
String beginAndEndTime = beginTime + StrUtil.DASHED + endTime; | |||||
paramsMap.put("beginAndEndTime", beginAndEndTime); | |||||
Integer fourSystems = projectDetail.getFourSystems(); | |||||
paramsMap.put("fourSystems", "业务应用"); | |||||
Integer isDigitalReform = projectDetail.getIsDigitalReform(); | |||||
paramsMap.put("isDigitalReform", "否"); | |||||
Integer isCloud = projectDetail.getIsCloud(); | |||||
paramsMap.put("isCloud", "否"); | |||||
// 生成pdf字节数组 | |||||
byte[] pdf = pdfUtils.generatePdf(pdfInputStream, paramsMap); | |||||
// 转换成MultipartFile | |||||
MultipartFile multipartFile = new MockMultipartFile("file", fileName + ".pdf", "application/pdf", pdf); | |||||
// 上传OSS | |||||
FileResultVO resultVO = fileService.upload(multipartFile, "default"); | |||||
// 将返回的文件ID保存到项目库中 | |||||
Project project = projectService.getById(44L); | |||||
project.setPretrialFileId(resultVO.getId()); | |||||
try { | |||||
if (null != pdfInputStream) { | |||||
pdfInputStream.close(); | |||||
} | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | } |
@@ -148,6 +148,28 @@ | |||||
<artifactId>spring-statemachine-core</artifactId> | <artifactId>spring-statemachine-core</artifactId> | ||||
<version>2.0.1.RELEASE</version> | <version>2.0.1.RELEASE</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.itextpdf</groupId> | |||||
<artifactId>itextpdf</artifactId> | |||||
<version>5.5.9</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.itextpdf</groupId> | |||||
<artifactId>itext-asian</artifactId> | |||||
<version>5.2.0</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.itextpdf.tool</groupId> | |||||
<artifactId>xmlworker</artifactId> | |||||
<version>5.5.9</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.xhtmlrenderer</groupId> | |||||
<artifactId>flying-saucer-pdf-itext5</artifactId> | |||||
<version>9.0.3</version> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</dependencyManagement> | </dependencyManagement> | ||||
@@ -165,6 +187,8 @@ | |||||
</snapshots> | </snapshots> | ||||
</repository> | </repository> | ||||
</repositories> | </repositories> | ||||
<pluginRepositories> | <pluginRepositories> | ||||
<!--阿里云代理Spring 插件仓库--> | <!--阿里云代理Spring 插件仓库--> | ||||
<pluginRepository> | <pluginRepository> | ||||