Browse Source

Merge remote-tracking branch 'origin/master'

master
WendyYang 1 year ago
parent
commit
36d8facbd0
36 changed files with 1493 additions and 138 deletions
  1. +24
    -0
      pmapi/pom.xml
  2. +3
    -3
      pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java
  3. +31
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/expert/manage/ExpertManage.java
  4. +27
    -3
      pmapi/src/main/java/com/ningdatech/pmapi/organization/controller/GovBusinessStripController.java
  5. +10
    -9
      pmapi/src/main/java/com/ningdatech/pmapi/organization/entity/GovBusinessStrip.java
  6. +42
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/organization/manage/GovBusinessStripManage.java
  7. +28
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/organization/model/vo/GovBusinessStripTreeVO.java
  8. +113
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/converter/ApplicationConverter.java
  9. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java
  10. +7
    -12
      pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java
  11. +4
    -9
      pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ProjectAdjustmentManage.java
  12. +31
    -11
      pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByProvincialDeptManage.java
  13. +3
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/Project.java
  14. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectApplication.java
  15. +11
    -4
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/controller/TestController.java
  16. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/dto/ProvincialApplicationDTO.java
  17. +4
    -3
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/dto/ProvincialProjectDTO.java
  18. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/service/IJoinReviewProvincialBureauService.java
  19. +11
    -4
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/service/impl/JoinReviewProvincialBureauServiceImpl.java
  20. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/sms/controller/VerificationCodeController.java
  21. +62
    -59
      pmapi/src/main/java/com/ningdatech/pmapi/sms/manage/SmsManage.java
  22. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRegionService.java
  23. +3
    -3
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RegionServiceImpl.java
  24. +140
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/PdfGenerateDTO.java
  25. +140
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfGenerateUtil.java
  26. +153
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfUtils.java
  27. +5
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/user/service/IUserInfoService.java
  28. +17
    -4
      pmapi/src/main/java/com/ningdatech/pmapi/user/service/impl/UserInfoServiceImpl.java
  29. +2
    -0
      pmapi/src/main/resources/security/auth-dev.yml
  30. BIN
      pmapi/src/main/resources/template/fileout/c34f631755a04532a0116494fd5f99ac.pdf
  31. BIN
      pmapi/src/main/resources/template/simsun.ttc
  32. +254
    -0
      pmapi/src/main/resources/template/盖章文件.html
  33. +249
    -0
      pmapi/src/main/resources/template/预审申请单.html
  34. BIN
      pmapi/src/main/resources/template/预审申请单.pdf
  35. +82
    -4
      pmapi/src/test/java/com/ningdatech/pmapi/todocenter/TodoCenterTest.java
  36. +24
    -0
      pom.xml

+ 24
- 0
pmapi/pom.xml View File

@@ -191,6 +191,11 @@
<artifactId>nd-basic</artifactId>
</dependency>
<dependency>
<groupId>com.ningdatech</groupId>
<artifactId>nd-yxt-starter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel-core</artifactId>
</dependency>
@@ -229,6 +234,25 @@
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
</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>
<!-- 打包 -->
<!--配置环境的profile-->


+ 3
- 3
pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java View File

@@ -44,9 +44,9 @@ public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
// ConverterType是StringHttpMessageConverter这个类型转换,
// 由于将结果封装成了自定义的ApiResponse类型,所以有ApiResponse转换成String报错
// 所以需要对String类型的返回值单独进行处理
if (o instanceof String) {
return JSONUtil.toJsonStr(apiResponse);
}
// if (o instanceof String) {
// return JSONUtil.toJsonStr(apiResponse);
// }
return ApiResponse.ofSuccess(o);
// return o;
}


+ 31
- 1
pmapi/src/main/java/com/ningdatech/pmapi/expert/manage/ExpertManage.java View File

@@ -22,11 +22,16 @@ import com.ningdatech.pmapi.expert.service.ExpertInfoService;
import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService;
import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum;
import com.ningdatech.pmapi.meta.model.ExpertRegionInfo;
import com.ningdatech.pmapi.user.constant.UserAvailableEnum;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -47,6 +52,7 @@ public class ExpertManage {
private final ExpertInfoCommonHelper expertInfoCommonHelper;
private final FileService fileService;
private final ExpertUserInfoAssembler expertUserInfoAssembler;
private final IUserInfoService iUserInfoService;


/**
@@ -56,8 +62,11 @@ public class ExpertManage {
*/
public void expertBasicInfoSubmit(ExpertUserBasicInfoSubmitRequest request) {
// 用户id
Long userId = LoginUserUtil.getUserId();
// Long userId = LoginUserUtil.getUserId();
ExpertBasicInfo basicInfo = request.getBasicInfo();
Long userId = generateOrGetUserId(basicInfo);


// 校验区域编码合法性 校验履职意向编码合法性
ExpertRegionInfo expertRegionInfo = basicInfo.getExpertRegionInfo();
expertManageHelper.expertRegionInfoCheck(expertRegionInfo);
@@ -137,4 +146,25 @@ public class ExpertManage {
List<AttachFileVo> attachFiles = fileService.getByIds(fileIdList);
return expertUserInfoAssembler.buildExpertFullInfoVO(attachFiles, expertUserFullInfoAll);
}

@Transactional(rollbackFor = Exception.class)
public Long generateOrGetUserId(ExpertBasicInfo basicInfo) {
String phoneNo = basicInfo.getPhoneNo();
UserInfo userInfo = iUserInfoService.getUserInfoByPhoneNo(phoneNo);
if (Objects.isNull(userInfo)) {
userInfo = UserInfo.builder()
// .accountId(dingEmployeeInfo.getAccountId())
.username(basicInfo.getName())
.realName(basicInfo.getName())
// .employeeCode(dingEmployeeInfo.getEmployeeCode())
.available(UserAvailableEnum.DISABLE.name())
.createBy(LoginUserUtil.getUserId())
.updateBy(LoginUserUtil.getUserId())
.createOn(LocalDateTime.now())
.updateOn(LocalDateTime.now())
.build();
iUserInfoService.save(userInfo);
}
return userInfo.getId();
}
}

+ 27
- 3
pmapi/src/main/java/com/ningdatech/pmapi/organization/controller/GovBusinessStripController.java View File

@@ -1,20 +1,44 @@
package com.ningdatech.pmapi.organization.controller;


import com.ningdatech.pmapi.organization.manage.GovBusinessStripManage;
import com.ningdatech.pmapi.organization.model.vo.GovBusinessStripTreeVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import org.springframework.stereotype.Controller;
import java.util.List;

/**
* <p>
* 前端控制器
* 前端控制器
* </p>
*
* @author Liuxinxin
* @since 2023-03-08
*/
@Controller
@RequestMapping("/pmapi.organization/gov-business-strip")
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@Api(value = "GovBusinessStripController", tags = "条线管理")
@RequestMapping("/api/v1/gov-business-strip")
public class GovBusinessStripController {

private final GovBusinessStripManage govBusinessStripManage;

@GetMapping("/get-child-list")
@ApiOperation("获取条线标签的的树状结构")
public List<GovBusinessStripTreeVO> getChildOrganizationList(@RequestParam(value = "parentCode", required = false) String parentCode) {
return govBusinessStripManage.getChildOrganizationList(parentCode);
}

}

+ 10
- 9
pmapi/src/main/java/com/ningdatech/pmapi/organization/entity/GovBusinessStrip.java View File

@@ -5,7 +5,6 @@ import io.swagger.annotations.ApiModel;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
* <p>
@@ -24,14 +23,6 @@ public class GovBusinessStrip implements Serializable {

private Long id;

private LocalDateTime createOn;

private LocalDateTime updateOn;

private Long createBy;

private Long updateBy;

/**
* 条线code
*/
@@ -41,4 +32,14 @@ public class GovBusinessStrip implements Serializable {
* 条线名称
*/
private String businessStripName;

/**
* 父级条线code
*/
private String parentCode;

/**
* 父级条线名称
*/
private String parentName;
}

+ 42
- 0
pmapi/src/main/java/com/ningdatech/pmapi/organization/manage/GovBusinessStripManage.java View File

@@ -0,0 +1,42 @@
package com.ningdatech.pmapi.organization.manage;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.pmapi.organization.entity.GovBusinessStrip;
import com.ningdatech.pmapi.organization.model.vo.GovBusinessStripTreeVO;
import com.ningdatech.pmapi.organization.service.IGovBusinessStripService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author liuxinxin
* @date 2023/3/14 下午4:48
*/

@Component
@RequiredArgsConstructor
public class GovBusinessStripManage {

private final IGovBusinessStripService iGovBusinessStripService;


public List<GovBusinessStripTreeVO> getChildOrganizationList(String parentCode) {
if (Objects.isNull(parentCode)) {
parentCode = "-1";
}
List<GovBusinessStrip> govBusinessStripList = iGovBusinessStripService.list(Wrappers.lambdaQuery(GovBusinessStrip.class)
.eq(GovBusinessStrip::getParentCode, parentCode));

return govBusinessStripList.stream().map(r -> {
GovBusinessStripTreeVO govBusinessStripTreeVO = new GovBusinessStripTreeVO();
govBusinessStripTreeVO.setBusinessStripCode(r.getBusinessStripCode());
govBusinessStripTreeVO.setBusinessStripName(r.getBusinessStripName());
govBusinessStripTreeVO.setParentCode(r.getParentCode());
govBusinessStripTreeVO.setParentName(r.getParentName());
return govBusinessStripTreeVO;
}).collect(Collectors.toList());
}
}

+ 28
- 0
pmapi/src/main/java/com/ningdatech/pmapi/organization/model/vo/GovBusinessStripTreeVO.java View File

@@ -0,0 +1,28 @@
package com.ningdatech.pmapi.organization.model.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* @author Liuxinxin
* @since 2023-03-08
*/
@Data
@ApiModel(value = "条线树形 responseVO", description = "")
public class GovBusinessStripTreeVO {

private Long id;

@ApiModelProperty("条线code")
private String businessStripCode;

@ApiModelProperty("条线名称")
private String businessStripName;

@ApiModelProperty("父级条线code")
private String parentCode;

@ApiModelProperty("父级条线名称")
private String parentName;
}

+ 113
- 0
pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/converter/ApplicationConverter.java View File

@@ -0,0 +1,113 @@
package com.ningdatech.pmapi.projectdeclared.converter;

import cn.hutool.core.collection.CollUtil;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialApplicationDTO;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO;
import org.assertj.core.util.Lists;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* @Classname ApplicationConverter
* @Description
* @Date 2023/3/13 17:38
* @Author PoffyZhang
*/
public class ApplicationConverter {

public static ProvincialProjectDTO convertProject(Project projectInfo,List<ProjectApplication> applications) {
return ProvincialProjectDTO.builder()
.regionCode(projectInfo.getAreaCode())
.regionName(projectInfo.getArea())
.projectName(projectInfo.getProjectName())
.projectId(String.valueOf(projectInfo.getId()))
.projectType(projectInfo.getProjectType())
.totalMoney(projectInfo.getDeclareAmount())
.yearBudget(projectInfo.getAnnualPlanAmount())
.budgetFrom(projectInfo.getDeclareHaveAmount() + "," +
projectInfo.getDeclareGovOwnFinanceAmount() + ","
+ projectInfo.getDeclareGovSuperiorFinanceAmount())
.year(String.valueOf(projectInfo.getProjectYear()))
.financialCode(projectInfo.getFinancialCode())
.developCode(projectInfo.getDevelopCode())
.beginTime(projectInfo.getBeginTime())
.endTime(projectInfo.getEndTime())
.buildBasis("立项依据")
.buildBasisFile(projectInfo.getBuildBasis())
.projectSummary(projectInfo.getProjectIntroduction())
.responsibleMan(projectInfo.getResponsibleMan())
.responsibleManPhone(projectInfo.getResponsibleManMobile())
.contactName(projectInfo.getContactName())
.contactPhone(projectInfo.getContactPhone())
.buildUnit(projectInfo.getBuildOrgName())
.buildUnitCode(projectInfo.getBuildOrgCode())
.superUnit(projectInfo.getSuperOrg())
.superUnitCode(projectInfo.getSuperOrgCode())
.projectApplyFile(projectInfo.getProjectPdf())
.projectEstimateFile(projectInfo.getCalculationTotalInvestmentFile())
.unitThreePlan(projectInfo.getMainResponsibilitiesApplicantFile())
.otherFile(projectInfo.getPreliminaryPlanFile())
.projectRemark(projectInfo.getProjectRemarks())
.includeApplication(projectInfo.getIncludeApplication())
.applicationInfo(convertApplications(applications))
.build();
}

//放入项目 app
private static List<ProvincialApplicationDTO> convertApplications(List<ProjectApplication> applications) {
if(CollUtil.isEmpty(applications)){
Collections.emptyList();
}

return applications.stream().map(ApplicationConverter::convertApp).collect(Collectors.toList());
}

private static ProvincialApplicationDTO convertApp(ProjectApplication projectApplication) {
return ProvincialApplicationDTO.builder()
.clouds(convertCloud(projectApplication))
.isFirst(projectApplication.getIsFirst())
.applicationName(projectApplication.getApplicationName())
.applicationCode(projectApplication.getRelatedExistsApplicationCode())
.relatedExistsApplication(projectApplication.getRelatedExistsApplication())
.applicationType(2)
.buildLevel(projectApplication.getBuildLevel())
.isUniteBuild(projectApplication.getIsUniteBuild())
.unionBuildKind(projectApplication.getUnionBuildKind())
.applicationSummary(projectApplication.getApplicationSummary())
.applicationRemark(projectApplication.getApplicationRemark())
.applicationEstimateFile(projectApplication.getApplicationEstimateFile())
.isFiveDomain(projectApplication.getIsDigitalModification())
.fiveDomain(projectApplication.getDigitalModification())
.bizDomain(projectApplication.getBizDomain())
.isBizCooperate(projectApplication.getIsBizCooperate())
.userRange(projectApplication.getUsesRangeRemark())
.useGovCloud(projectApplication.getUseGovCloud())
.nationalITSpec(projectApplication.getNationalItSpec())
.netEnv(String.valueOf(projectApplication.getNetEnv()))
.secrecyGrade(projectApplication.getSecrecyGrade())
.passwordGrade(projectApplication.getPasswordGrade())
.accountAppName(projectApplication.getAccountAppName())
.brainAccountAppName(projectApplication.getDomainBrainAccount())
.useCommonData(projectApplication.getUseCommonData())
.dataName(projectApplication.getDataName())
.commonComponents(projectApplication.getCommonComponents())
.useCommonComponent(projectApplication.getUseCommonComponent())
.isProduceCommonComponent(projectApplication.getProduceCommonComponent())
.produceCommonComponent(projectApplication.getProduceCommonComponents())
.publishSide(projectApplication.getPublishSide())
.build();
}

private static List<ProvincialApplicationDTO.Cloud> convertCloud(ProjectApplication projectApplication) {
return Lists.newArrayList(ProvincialApplicationDTO.Cloud.builder()
.cloudType(projectApplication.getCloudsType())
.cloudNums(projectApplication.getCloudsNumber())
.cloudBasicSpec(projectApplication.getCloudsFoundationSpecifications())
.cloudUseDescription(projectApplication.getCloudsDescription())
.build());
}

}

+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ConstructionPlanManage.java View File

@@ -102,7 +102,7 @@ public class ConstructionPlanManage {
VUtils.isTrue(Objects.isNull(projectDto.getId())).throwMessage("提交失败 缺少项目ID!");
Project projectInfo = projectService.getById(projectDto.getId());
VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!");
VUtils.isTrue(StringUtils.isBlank(projectInfo.getConstructionPlanFile())).throwMessage("提交失败 请提交建设方案!");
VUtils.isTrue(StringUtils.isBlank(projectDto.getConstructionPlanFile())).throwMessage("提交失败 请提交建设方案!");

String regionCode = projectInfo.getAreaCode();



+ 7
- 12
pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/DeclaredProjectManage.java View File

@@ -64,6 +64,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
@@ -375,19 +376,15 @@ public class DeclaredProjectManage {
}

public void exportList(HttpServletResponse response, ProjectListReq param) {
Long userId = LoginUserUtil.getUserId();
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail();
Long userId = userInfoDetails.getUserId();
VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!");
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId);
//放入用户的单位
param.setBuildOrgCode(userFullInfo.getOrganizationCode());
param.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER);
param.setPageSize(CommonConst.EXPORT_PAGE_SIZE);

param.setBuildOrgCode(userInfoDetails.getOrganizationCode());
LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(param);
Page<Project> page = projectService.page(param.page(), query);
List<Project> records = page.getRecords();

List<Project> records = projectService.list(query);

AtomicInteger serialNumber = new AtomicInteger(0);
List<DeclaredProjectExportDTO> collect = records.stream().map(r -> {
DeclaredProjectExportDTO exportDTO = new DeclaredProjectExportDTO();
BeanUtils.copyProperties(r, exportDTO);
@@ -395,11 +392,9 @@ public class DeclaredProjectManage {
exportDTO.setStatusName(ProjectStatusEnum.getDesc(r.getStatus()));
String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm");
exportDTO.setCreateOn(createOnStr);
exportDTO.setSerialNumber(serialNumber.incrementAndGet());
return exportDTO;
}).collect(Collectors.toList());
for (int i = 0; i < collect.size(); i++) {
collect.get(i).setSerialNumber(i + 1);
}
String fileName = "项目申报列表";
ExcelDownUtil.setFileName(fileName,response);
//数据导出处理函数


+ 4
- 9
pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ProjectAdjustmentManage.java View File

@@ -43,6 +43,7 @@ import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

@@ -163,13 +164,9 @@ public class ProjectAdjustmentManage {
req.setBuildOrgCode(userFullInfo.getOrganizationCode());

LambdaQueryWrapper<Project> query = ProjectHelper.projectQuery(req);
Page<Project> page = projectService.page(req.page(), query);

req.setPageNumber(CommonConst.EXPORT_PAGE_NUMBER);
req.setPageSize(CommonConst.EXPORT_PAGE_SIZE);
List<Project> records = page.getRecords();

List<Project> records = projectService.list(query);

AtomicInteger serialNumber = new AtomicInteger(0);
List<ProjectAdjustmentExportDTO> collect = records.stream().map(r -> {
ProjectAdjustmentExportDTO exportDTO = new ProjectAdjustmentExportDTO();
BeanUtils.copyProperties(r, exportDTO);
@@ -177,11 +174,9 @@ public class ProjectAdjustmentManage {
exportDTO.setStatusName(ProjectStatusEnum.getDesc(r.getStatus()));
String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm");
exportDTO.setCreateOn(createOnStr);
exportDTO.setSerialNumber(serialNumber.incrementAndGet());
return exportDTO;
}).collect(Collectors.toList());
for (int i = 0; i < collect.size(); i++) {
collect.get(i).setSerialNumber(i + 1);
}
String fileName = "项目内容调整列表";
ExcelDownUtil.setFileName(fileName,response);
//数据导出处理函数


+ 31
- 11
pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/ReviewByProvincialDeptManage.java View File

@@ -1,18 +1,30 @@
package com.ningdatech.pmapi.projectdeclared.manage;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils;
import com.ningdatech.pmapi.projectdeclared.converter.ApplicationConverter;
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO;
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.ProjectApplication;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialApplicationDTO;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO;
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @Classname ReviewByProvincialDeptManage
@@ -31,6 +43,10 @@ public class ReviewByProvincialDeptManage {

private final DefaultDeclaredProjectManage defaultProjectManage;

private final IJoinReviewProvincialBureauService joinReviewProvincialBureauService;

private final IProjectApplicationService applicationService;

/**
* 省级部门联审
* @param project
@@ -47,17 +63,21 @@ public class ReviewByProvincialDeptManage {
VUtils.isTrue(!ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode().equals(projectInfo.getStatus()) ||
!ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage()))
.throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段");
// TODO 对接省级联审的接口
Boolean sucessProvince = Boolean.TRUE;
if(sucessProvince){
//测试先成功
stateMachineUtils.pass(project);
projectService.updateById(project);
//直接去预审
if(StringUtils.isNotBlank(defaultProjectManage
.directStartProcess(project,project.getPreStartUserId()))){
return Boolean.TRUE;
}

// 对接省级联审的接口
List<ProjectApplication> applications = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class)
.eq(ProjectApplication::getProjectId, projectInfo.getId()));
if(joinReviewProvincialBureauService.pushImportProject(
ApplicationConverter.convertProject(projectInfo,applications))){
return Boolean.TRUE;
// //测试先成功
// stateMachineUtils.pass(project);
// projectService.updateById(project);
// //直接去预审
// if(StringUtils.isNotBlank(defaultProjectManage
// .directStartProcess(project,project.getPreStartUserId()))){
// return Boolean.TRUE;
// }
}

return Boolean.FALSE;


+ 3
- 0
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/Project.java View File

@@ -309,4 +309,7 @@ public class Project implements Serializable {
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateBy;

@ApiModelProperty("项目预审申请单文件ID")
private Long pretrialFileId;

}

+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/ProjectApplication.java View File

@@ -67,7 +67,7 @@ public class ProjectApplication implements Serializable {
@ApiModelProperty("是否数改系统 0:否 1:是")
private Integer isDigitalModification;

@ApiModelProperty("数改系统")
@ApiModelProperty("数改系统 1: '党政机关整体智治',2: '数字政府',3: '数字经济',4: '数字社会',7: '数字文化',5: '数字法治',6: '一体化智能化公共数据平台', 8: '基层智治' 多个用英文,分隔")
private String digitalModification;

@ApiModelProperty("业务领域")


+ 11
- 4
pmapi/src/main/java/com/ningdatech/pmapi/provincial/controller/TestController.java View File

@@ -1,5 +1,7 @@
package com.ningdatech.pmapi.provincial.controller;

import com.ningdatech.pmapi.projectdeclared.manage.ReviewByProvincialDeptManage;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO;
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService;
import io.swagger.annotations.Api;
@@ -24,14 +26,19 @@ public class TestController {
@Autowired
private IJoinReviewProvincialBureauService joinReviewProvincialBureauService;

@PostMapping("/push")
@Autowired
private ReviewByProvincialDeptManage provincialDeptManage;

@GetMapping("/push")
@ApiOperation("测试推送")
private String push(@Valid @RequestBody ProvincialProjectDTO project){
return joinReviewProvincialBureauService.pushImportProject(project);
private Boolean push(@Valid @RequestParam Long projectId){
Project project = new Project();
project.setId(projectId);
return provincialDeptManage.startTheProcess(project);
}

@GetMapping("/detail")
@ApiOperation("测试推送")
@ApiOperation("测试获取详情")
private String detail(@RequestParam String projectId){
return joinReviewProvincialBureauService.processInfo(projectId);
}


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/dto/ProvincialApplicationDTO.java View File

@@ -1,11 +1,13 @@
package com.ningdatech.pmapi.provincial.model.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
@@ -17,7 +19,9 @@ import java.util.List;
@Data
@Builder
@ApiModel(value = "ProvincialApplicationDTO", description = "")
public class ProvincialApplicationDTO {
public class ProvincialApplicationDTO implements Serializable {


//云 信息
private List<Cloud> clouds;
//是否初次建设 1是 2不是
@@ -85,7 +89,9 @@ public class ProvincialApplicationDTO {
//发布端 '浙里办','浙政钉','数字化改革门户','支付宝','微信','网页','PC客户端','APP端'
private String publishSide;

public static class Cloud {
@Builder
@JsonIgnoreProperties(value = { "handler"})
public static class Cloud implements Serializable {
//云资源台数 11
private Integer cloudNums;
//云资源类型 云服务器(ECS)


+ 4
- 3
pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/dto/ProvincialProjectDTO.java View File

@@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

@@ -21,7 +22,7 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "ProvincialProjectDTO", description = "")
public class ProvincialProjectDTO {
public class ProvincialProjectDTO implements Serializable {

@ApiModelProperty("区域code")
private String regionCode;
@@ -114,10 +115,10 @@ public class ProvincialProjectDTO {
private String projectRemark;

@ApiModelProperty("是否有效 1有效 2无效 3撤回")
private String isEffective;
private Integer isEffective;

@ApiModelProperty("是否包含应用 1包含")
private String includeApplication;
private Integer includeApplication;

@ApiModelProperty("app信息")
private List<ProvincialApplicationDTO> applicationInfo;


+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/provincial/service/IJoinReviewProvincialBureauService.java View File

@@ -14,7 +14,7 @@ public interface IJoinReviewProvincialBureauService {
* 推送/保存 重大接口到 省局联审
* @return
*/
String pushImportProject(ProvincialProjectDTO project);
Boolean pushImportProject(ProvincialProjectDTO project);


/**


+ 11
- 4
pmapi/src/main/java/com/ningdatech/pmapi/provincial/service/impl/JoinReviewProvincialBureauServiceImpl.java View File

@@ -2,6 +2,8 @@ package com.ningdatech.pmapi.provincial.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.ningdatech.basic.model.ApiResponse;
import com.ningdatech.pmapi.common.config.ProvincialProperties;
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO;
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService;
@@ -35,12 +37,12 @@ public class JoinReviewProvincialBureauServiceImpl implements IJoinReviewProvinc
* @return
*/
@Override
public String pushImportProject(ProvincialProjectDTO project){
public Boolean pushImportProject(ProvincialProjectDTO project){
Long timeStamp = System.currentTimeMillis()/1000;
String url = provincialProperties.getHost() + provincialProperties.getPushUrl()
+ "?timestamp=" + timeStamp;
log.info("省局推送联审url {}",url);
ResponseEntity<String> responseEntity = null;
ResponseEntity<ApiResponse> responseEntity = null;

String signature = getSha256(timeStamp,provincialProperties.getPushUrl(),
HttpMethod.POST.name());
@@ -55,14 +57,19 @@ public class JoinReviewProvincialBureauServiceImpl implements IJoinReviewProvinc
.accept(MediaType.APPLICATION_JSON)
.body(project);

log.info("省局联审 提交 :{}", requestEntity);
log.info("省局联审 提交body :{}", JSON.toJSONString(requestEntity.getBody()));
try {
responseEntity = restTemplate.exchange(requestEntity,String.class);
responseEntity = restTemplate.exchange(requestEntity, ApiResponse.class);
log.info("省局联审 响应 :{}",responseEntity);
if(responseEntity.getBody().getCode().equals(200)){
return Boolean.TRUE;
}
} catch (Exception e) {
log.error("[省局联审] http request error", e);
}

return responseEntity.getBody();
return Boolean.FALSE;
}

/**


+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/sms/controller/VerificationCodeController.java View File

@@ -35,7 +35,7 @@ public class VerificationCodeController {
@ApiOperation(value = "发送验证码", notes = "发送验证码")
@PostMapping(value = "/send")
public void send(@Validated @RequestBody ReqVerificationCodePO request) {
// smsManage.sendVerificationCode(request);
smsManage.sendVerificationCode(request);
}

}

+ 62
- 59
pmapi/src/main/java/com/ningdatech/pmapi/sms/manage/SmsManage.java View File

@@ -11,6 +11,9 @@ import com.ningdatech.pmapi.sms.model.dto.VerifyCodeCacheDTO;
import com.ningdatech.pmapi.sms.model.po.ReqVerificationCodePO;
import com.ningdatech.pmapi.sms.utils.DateUtil;
import com.ningdatech.pmapi.sms.utils.SmsRedisKeyUtils;
import com.ningdatech.yxt.client.YxtClient;
import com.ningdatech.yxt.constants.YxtSmsSignEnum;
import com.ningdatech.yxt.model.cmd.SendSmsCmd;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -29,65 +32,65 @@ import java.util.Collections;
@Component
@RequiredArgsConstructor
public class SmsManage {
//
// private final YxtClient yxtClient;
// private final CachePlusOps cachePlusOps;
//
// public void sendVerificationCode(ReqVerificationCodePO request) {
// Assert.isTrue(PhoneUtil.isMobile(request.getMobile()), "手机号码格式不正确");
// String verificationType = request.getVerificationType();
// VerificationCodeType verificationCodeTypeEnum = VerificationCodeType.of(verificationType);
//
// // 验证是否被锁定
// String lockKey = SmsRedisKeyUtils.smsSendLockKey(verificationCodeTypeEnum, request.getMobile());
// if (StringUtils.isNotBlank(cachePlusOps.get(lockKey))) {
// throw BizException.wrap("今日" + verificationCodeTypeEnum.getDesc() + "的验证码发送次数过多,已被锁定");
// }
// // 验证发送间隔
// String cacheKey = SmsRedisKeyUtils.smsCodeVerifyKey(verificationCodeTypeEnum, request.getMobile());
// VerifyCodeCacheDTO preCache = (VerifyCodeCacheDTO) cachePlusOps.get(cacheKey);
// if (preCache != null) {
// if (LocalDateTime.now().minusMinutes(verificationCodeTypeEnum.getSendInterval())
// .isBefore(preCache.getSendTime())) {
// throw BizException.wrap(verificationCodeTypeEnum.getSendInterval() + "分钟之内已发送过验证码,请稍后重试");
// }
// }
// String code = RandomUtil.randomNumbers(6);
// VerifyCodeCacheDTO cache = VerifyCodeCacheDTO.builder()
// .code(code)
// .sendTime(LocalDateTime.now())
// .mobile(request.getMobile())
// .build();
//
// // 创建短信内容
// SendSmsCmd sendSmsCmd = new SendSmsCmd();
// switch (verificationCodeTypeEnum) {
// case LOGIN:
// SendSmsCmd.SendSmsContext sendSmsContext = new SendSmsCmd.SendSmsContext();
// sendSmsContext.setReceiveNumber(request.getMobile());
// sendSmsContext.setContent(String.format(YxtSmsTemplateConst.SMS_LOGIN_TEMPLATE, code, verificationCodeTypeEnum.getExpireTime()));
// sendSmsCmd.setContextList(Collections.singletonList(sendSmsContext));
// sendSmsCmd.setSmsSignEnum(YxtSmsSignEnum.ZJS_ELECTRONIC_EXPERT_LIB);
// break;
// default:
// throw new IllegalArgumentException("非法的短信发送类型");
// }
// // 发送 短信
// yxtClient.submitSmsTask(sendSmsCmd);
// log.info("send verificationCode mobile = {},code = {}", request.getMobile(), code);
//
// cachePlusOps.set(new CacheKey(cacheKey, Duration.ofMinutes(verificationCodeTypeEnum.getExpireTime())), cache);
// String limitKey = SmsRedisKeyUtils.smsSendLimitKey(verificationCodeTypeEnum, request.getMobile());
// if (StringUtils.isNotBlank(cachePlusOps.get(limitKey))) {
// long limitCount = cachePlusOps.incr(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())));
// // 超出单日发送次数之后直接锁定
// if (limitCount >= verificationCodeTypeEnum.getSendTimesByDay().longValue()) {
// cachePlusOps.set(new CacheKey(lockKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), request.getMobile());
// }
// } else {
// cachePlusOps.set(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), 1);
// }
// }
private final YxtClient yxtClient;
private final CachePlusOps cachePlusOps;
public void sendVerificationCode(ReqVerificationCodePO request) {
Assert.isTrue(PhoneUtil.isMobile(request.getMobile()), "手机号码格式不正确");
String verificationType = request.getVerificationType();
VerificationCodeType verificationCodeTypeEnum = VerificationCodeType.of(verificationType);
// 验证是否被锁定
String lockKey = SmsRedisKeyUtils.smsSendLockKey(verificationCodeTypeEnum, request.getMobile());
if (StringUtils.isNotBlank(cachePlusOps.get(lockKey))) {
throw BizException.wrap("今日" + verificationCodeTypeEnum.getDesc() + "的验证码发送次数过多,已被锁定");
}
// 验证发送间隔
String cacheKey = SmsRedisKeyUtils.smsCodeVerifyKey(verificationCodeTypeEnum, request.getMobile());
VerifyCodeCacheDTO preCache = (VerifyCodeCacheDTO) cachePlusOps.get(cacheKey);
if (preCache != null) {
if (LocalDateTime.now().minusMinutes(verificationCodeTypeEnum.getSendInterval())
.isBefore(preCache.getSendTime())) {
throw BizException.wrap(verificationCodeTypeEnum.getSendInterval() + "分钟之内已发送过验证码,请稍后重试");
}
}
String code = RandomUtil.randomNumbers(6);
VerifyCodeCacheDTO cache = VerifyCodeCacheDTO.builder()
.code(code)
.sendTime(LocalDateTime.now())
.mobile(request.getMobile())
.build();
// 创建短信内容
SendSmsCmd sendSmsCmd = new SendSmsCmd();
switch (verificationCodeTypeEnum) {
case LOGIN:
SendSmsCmd.SendSmsContext sendSmsContext = new SendSmsCmd.SendSmsContext();
sendSmsContext.setReceiveNumber(request.getMobile());
sendSmsContext.setContent(String.format(YxtSmsTemplateConst.SMS_LOGIN_TEMPLATE, code, verificationCodeTypeEnum.getExpireTime()));
sendSmsCmd.setContextList(Collections.singletonList(sendSmsContext));
sendSmsCmd.setSmsSignEnum(YxtSmsSignEnum.ZJS_ELECTRONIC_EXPERT_LIB);
break;
default:
throw new IllegalArgumentException("非法的短信发送类型");
}
// 发送 短信
yxtClient.submitSmsTask(sendSmsCmd);
log.info("send verificationCode mobile = {},code = {}", request.getMobile(), code);
cachePlusOps.set(new CacheKey(cacheKey, Duration.ofMinutes(verificationCodeTypeEnum.getExpireTime())), cache);
String limitKey = SmsRedisKeyUtils.smsSendLimitKey(verificationCodeTypeEnum, request.getMobile());
if (StringUtils.isNotBlank(cachePlusOps.get(limitKey))) {
long limitCount = cachePlusOps.incr(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())));
// 超出单日发送次数之后直接锁定
if (limitCount >= verificationCodeTypeEnum.getSendTimesByDay().longValue()) {
cachePlusOps.set(new CacheKey(lockKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), request.getMobile());
}
} else {
cachePlusOps.set(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())), 1);
}
}


}

+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRegionService.java View File

@@ -1,8 +1,8 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Region;

import java.util.List;



+ 3
- 3
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RegionServiceImpl.java View File

@@ -52,9 +52,9 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
@Override
public Long getRegionIdByParentIdWithSameRegionCode(Long parentId, String regionCode) {
return baseMapper.selectOne(Wrappers.lambdaQuery(Region.class)
.eq(Region::getParentId, parentId)
.eq(Region::getRegionCode, regionCode)
.eq(Region::getDeleted, false))
.eq(Region::getParentId, parentId)
.eq(Region::getRegionCode, regionCode)
.eq(Region::getDeleted, false))
.getId();
}



+ 140
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/PdfGenerateDTO.java View File

@@ -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;
}

+ 140
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfGenerateUtil.java View File

@@ -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;
}
}



+ 153
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfUtils.java View File

@@ -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;
}

}

+ 5
- 2
pmapi/src/main/java/com/ningdatech/pmapi/user/service/IUserInfoService.java View File

@@ -1,7 +1,7 @@
package com.ningdatech.pmapi.user.service;

import com.ningdatech.pmapi.user.entity.UserInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto;

import java.util.Map;
@@ -9,7 +9,7 @@ import java.util.Set;

/**
* <p>
* 服务类
* 服务类
* </p>
*
* @author Lierbao
@@ -19,4 +19,7 @@ public interface IUserInfoService extends IService<UserInfo> {
Map<String, ProcessInstanceUserDto> getUserMapByIds(Set<String> staterUsers);

ProcessInstanceUserDto getUserInfo(String userId);

UserInfo getUserInfoByPhoneNo(String phoneNo);

}

+ 17
- 4
pmapi/src/main/java/com/ningdatech/pmapi/user/service/impl/UserInfoServiceImpl.java View File

@@ -12,6 +12,7 @@ import com.ningdatech.pmapi.user.mapper.NdUserInfoMapper;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
@@ -22,7 +23,7 @@ import java.util.stream.Collectors;

/**
* <p>
* 服务实现类
* 服务实现类
* </p>
*
* @author Lierbao
@@ -36,6 +37,7 @@ public class UserInfoServiceImpl extends ServiceImpl<NdUserInfoMapper, UserInfo>
private final IDingEmployeeInfoService dingEmployeeInfoService;

private final IDingOrganizationService dingOrganizationService;

@Override
public Map<String, ProcessInstanceUserDto> getUserMapByIds(Set<String> staterUsers) {
List<UserInfo> userInfos = userInfoMapper.selectBatchIds(staterUsers);
@@ -44,13 +46,13 @@ public class UserInfoServiceImpl extends ServiceImpl<NdUserInfoMapper, UserInfo>
userInfo.setUserId(String.valueOf(u.getId()));
userInfo.setUserName(u.getRealName());
Long accountId = u.getAccountId();
if (Objects.isNull(accountId)){
if (Objects.isNull(accountId)) {
throw new BizException("该用户没有录入浙政钉用户信息!");
}
// 根据浙政钉用户ID获取单位code
DingEmployeeInfo employeeInfo = dingEmployeeInfoService.getOne(Wrappers.lambdaQuery(DingEmployeeInfo.class)
.eq(DingEmployeeInfo::getAccountId, accountId)
.eq(DingEmployeeInfo::getMainJob,String.valueOf(Boolean.TRUE))
.eq(DingEmployeeInfo::getMainJob, String.valueOf(Boolean.TRUE))
.last("limit 1"));
String organizationCode = employeeInfo.getOrganizationCode();
// 根据 单位code获取单位名称
@@ -70,7 +72,7 @@ public class UserInfoServiceImpl extends ServiceImpl<NdUserInfoMapper, UserInfo>
processInstanceUserDto.setUserId(String.valueOf(userInfo.getId()));
processInstanceUserDto.setUserName(userInfo.getRealName());
Long accountId = userInfo.getAccountId();
if (Objects.isNull(accountId)){
if (Objects.isNull(accountId)) {
throw new BizException("该用户没有录入浙政钉用户信息!");
}
// 根据浙政钉用户ID获取部门code
@@ -85,4 +87,15 @@ public class UserInfoServiceImpl extends ServiceImpl<NdUserInfoMapper, UserInfo>
processInstanceUserDto.setOrgName(organizationName);
return processInstanceUserDto;
}

@Override
public UserInfo getUserInfoByPhoneNo(String phoneNo) {
if (StringUtils.isEmpty(phoneNo)) {
return null;
}
UserInfo userInfo = userInfoMapper
.selectOne(Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getMobile, phoneNo));
return userInfo;
}
}

+ 2
- 0
pmapi/src/main/resources/security/auth-dev.yml View File

@@ -21,6 +21,7 @@ security:
- /oa/**
- /wflow/**
- /sys/**
- /api/v1/verification/**
ignore-csrf-urls:
- /api/v1/user/auth/**
- /v2/api-docs
@@ -37,6 +38,7 @@ security:
- /oa/**
- /wflow/**
- /sys/**
- /api/v1/verification/**
role-map:
"engineer":
"project_manager":


BIN
pmapi/src/main/resources/template/fileout/c34f631755a04532a0116494fd5f99ac.pdf View File


BIN
pmapi/src/main/resources/template/simsun.ttc View File


+ 254
- 0
pmapi/src/main/resources/template/盖章文件.html View File

@@ -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>

+ 249
- 0
pmapi/src/main/resources/template/预审申请单.html View File

@@ -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>

BIN
pmapi/src/main/resources/template/预审申请单.pdf View File


+ 82
- 4
pmapi/src/test/java/com/ningdatech/pmapi/todocenter/TodoCenterTest.java View File

@@ -1,18 +1,38 @@
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.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.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.service.INdWorkNoticeStagingService;
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo;
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.service.IUserInfoService;
import com.ningdatech.zwdd.client.ZwddClient;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
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 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
public class TodoCenterTest extends AppTests {

//@Autowired
//private TaskExecutor executor;

@Autowired
private TodoCenterManage todoCenterManage;
@Autowired
@@ -37,6 +53,14 @@ public class TodoCenterTest extends AppTests {
private ZwddClient zwddClient;
@Autowired
private INdWorkNoticeStagingService workNoticeStagingService;
@Autowired
private ProjectLibManage projectLibManage;
@Autowired
private FileService fileService;
@Autowired
private IProjectService projectService;
@Autowired
private PdfUtils pdfUtils;
@Test
public void sendWorkNoticeTest() throws ExecutionException, InterruptedException {
//String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-00-测试项目");
@@ -98,4 +122,58 @@ public class TodoCenterTest extends AppTests {
// 放入工作通知暂存表中,通过扫表异步发送
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();
}
}
}

+ 24
- 0
pom.xml View File

@@ -148,6 +148,28 @@
<artifactId>spring-statemachine-core</artifactId>
<version>2.0.1.RELEASE</version>
</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>
</dependencyManagement>

@@ -165,6 +187,8 @@
</snapshots>
</repository>
</repositories>


<pluginRepositories>
<!--阿里云代理Spring 插件仓库-->
<pluginRepository>


Loading…
Cancel
Save