diff --git a/pmapi/pom.xml b/pmapi/pom.xml index ed54cc1..d32a0a6 100644 --- a/pmapi/pom.xml +++ b/pmapi/pom.xml @@ -43,7 +43,10 @@ org.springframework.session spring-session-data-redis - + + org.springframework.boot + spring-boot-starter-freemarker + org.apache.commons diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/util/WordUtil.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/WordUtil.java new file mode 100644 index 0000000..b6d173d --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/WordUtil.java @@ -0,0 +1,119 @@ +package com.ningdatech.pmapi.common.util; + +import com.ningdatech.pmapi.meeting.entity.dto.ExpertFeeExportDTO; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import org.springframework.core.io.ByteArrayResource; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; + +/** + *

+ * WordUtil + *

+ * + * @author WendyYang + * @since 2023/7/24 + **/ +public class WordUtil { + + private static final Configuration CONFIGURATION = new Configuration(Configuration.VERSION_2_3_31); + + static { + CONFIGURATION.setDefaultEncoding("UTF-8"); + CONFIGURATION.setClassForTemplateLoading(WordUtil.class, "/template"); + } + + /** + * 生成word文件 + * + * @param dataMap word中需要展示的动态数据,用map集合来保存 + * @param templateName word模板名称,例如:test.ftl + * @param filePath 文件生成的目标路径,例如:D:/wordFile/ + * @param fileName 生成的文件名称,例如:test.doc + */ + public static void create(Object dataMap, String templateName, String filePath, String fileName) { + try { + + + //获取模板 + Template template = CONFIGURATION.getTemplate(templateName); + + //输出文件 + File outFile = new File(filePath + File.separator + fileName); + + //如果输出目标文件夹不存在,则创建 + if (!outFile.getParentFile().exists()) { + boolean ignore = outFile.getParentFile().mkdirs(); + } + + //将模板和数据模型合并生成文件 + Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outFile.toPath()), StandardCharsets.UTF_8)); + + //生成文件 + template.process(dataMap, out); + + //关闭流 + out.flush(); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void export(String fileName, Object data, HttpServletResponse response, String templateName) throws TemplateException, IOException { + Template template = CONFIGURATION.getTemplate(templateName); + StringWriter out = new StringWriter(); + Writer writer = new BufferedWriter(out, 4096); + template.process(data, writer); + InputStream fin = new ByteArrayResource(out.toString().getBytes(StandardCharsets.UTF_8)).getInputStream(); + ServletOutputStream outputStream; + response.setCharacterEncoding(StandardCharsets.UTF_8.displayName()); + response.setContentType("application/json"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8")); + outputStream = response.getOutputStream(); + // 缓冲区 + byte[] buffer = new byte[1024]; + int bytesToRead; + // 通过循环将读入的Word文件的内容输出到浏览器中 + while ((bytesToRead = fin.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesToRead); + } + if (outputStream != null) { + outputStream.close(); + } + fin.close(); + } + + public static void main(String[] args) { + ExpertFeeExportDTO dto = new ExpertFeeExportDTO(); + dto.setMeetingAddress("杭州市滨江区海创还能到我当时防守打法十大发放"); + dto.setMeetingTime("2023-01-01 12:20"); + dto.setProjectName("阿萨法舒服舒服舒服舒服送达方"); + dto.setTableData(new ArrayList<>()); + for (int i = 0; i < 100; i++) { + ExpertFeeExportDTO.ExpertInfoDTO expert = new ExpertFeeExportDTO.ExpertInfoDTO(); + expert.setNo(i); + expert.setBank("中国建设银行"); + expert.setMobile("17839192616"); + expert.setBankNo("121212121212121212"); + expert.setCompany("宁大科技有限公司"); + expert.setFee(BigDecimal.valueOf(500)); + expert.setName("张三"); + expert.setSex("男"); + expert.setIdcard("121212121121"); + dto.getTableData().add(expert); + } + create(dto, "专家费.ftl", "/Users/wendy/Desktop/", "专家费.doc"); + } + + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingExportController.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingExportController.java new file mode 100644 index 0000000..0ac0126 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/MeetingExportController.java @@ -0,0 +1,44 @@ +package com.ningdatech.pmapi.meeting.controller; + +import com.ningdatech.pmapi.meeting.manage.ExpertExportManage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; + +/** + *

+ * MeetingExportController + *

+ * + * @author WendyYang + * @since 2023/7/24 + **/ +@Api(tags = "会议信息导出") +@RestController +@AllArgsConstructor +@RequestMapping("/api/v1/meeting/export") +public class MeetingExportController { + + + private final ExpertExportManage expertExportManage; + + + @GetMapping("/feeForExpert/{meetingId}") + @ApiOperation("专家费用单导出") + public void exportFeeForExpert(@PathVariable Long meetingId, HttpServletResponse response) { + expertExportManage.exportFeeForExpert(meetingId, response); + } + + @GetMapping("/expertReviewTable/{meetingId}") + @ApiOperation("专家评审单导出") + public void expertReviewTable(@PathVariable Long meetingId, HttpServletResponse response) { + expertExportManage.expertReviewTable(meetingId, response); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertFeeExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertFeeExportDTO.java new file mode 100644 index 0000000..68b2e64 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertFeeExportDTO.java @@ -0,0 +1,52 @@ +package com.ningdatech.pmapi.meeting.entity.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.security.SecureRandom; +import java.util.List; + +/** + *

+ * ExpertFeeExportDTO + *

+ * + * @author WendyYang + * @since 2023/7/24 + **/ +@Data +public class ExpertFeeExportDTO { + + private String projectName; + + private String meetingAddress; + + private String meetingTime; + + private List tableData; + + @Data + public static class ExpertInfoDTO { + + private Integer no; + + private String name; + + private String bank; + + private String bankNo; + + private String mobile; + + private String sex; + + private String company; + + private BigDecimal fee; + + private String idcard; + + } + + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertReviewTableDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertReviewTableDTO.java new file mode 100644 index 0000000..e5c10d7 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/entity/dto/ExpertReviewTableDTO.java @@ -0,0 +1,24 @@ +package com.ningdatech.pmapi.meeting.entity.dto; + +import lombok.Data; + +/** + *

+ * ExpertReviewTableDTO + *

+ * + * @author WendyYang + * @since 2023/7/24 + **/ +@Data +public class ExpertReviewTableDTO { + + private String projectName; + + private String meetingTime; + + private String meetingAddress; + + private String holdOrg; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertExportManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertExportManage.java new file mode 100644 index 0000000..a5239b6 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/ExpertExportManage.java @@ -0,0 +1,132 @@ +package com.ningdatech.pmapi.meeting.manage; + +import cn.hutool.core.lang.UUID; +import cn.hutool.core.util.StrUtil; +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.basic.util.CollUtils; +import com.ningdatech.pmapi.common.util.WordUtil; +import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; +import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; +import com.ningdatech.pmapi.meeting.entity.domain.Meeting; +import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert; +import com.ningdatech.pmapi.meeting.entity.domain.MeetingInnerProject; +import com.ningdatech.pmapi.meeting.entity.domain.MeetingOuterProject; +import com.ningdatech.pmapi.meeting.entity.dto.ExpertFeeExportDTO; +import com.ningdatech.pmapi.meeting.entity.dto.ExpertReviewTableDTO; +import com.ningdatech.pmapi.meeting.service.IMeetingExpertService; +import com.ningdatech.pmapi.meeting.service.IMeetingInnerProjectService; +import com.ningdatech.pmapi.meeting.service.IMeetingOuterProjectService; +import com.ningdatech.pmapi.meeting.service.IMeetingService; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import com.ningdatech.pmapi.sms.utils.DateUtil; +import freemarker.template.TemplateException; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + *

+ * ExpertExportManage + *

+ * + * @author WendyYang + * @since 2023/7/24 + **/ +@Slf4j +@Component +@AllArgsConstructor +public class ExpertExportManage { + + private final IMeetingService meetingService; + private final IMeetingExpertService meetingExpertService; + private final IMeetingInnerProjectService meetingInnerProjectService; + private final IMeetingOuterProjectService meetingOuterProjectService; + private final IExpertUserFullInfoService expertUserInfoService; + private final IProjectService projectService; + + public void exportFeeForExpert(Long meetingId, HttpServletResponse response) { + final String template = "专家费.ftl"; + String fileName = UUID.randomUUID().toString(true) + ".doc"; + try { + Meeting meeting = meetingService.getById(meetingId); + ExpertFeeExportDTO data = new ExpertFeeExportDTO(); + data.setMeetingTime(DateUtil.localDateTimeFormat(meeting.getStartTime(), "yyyy-MM-dd HH:mm")); + data.setMeetingAddress(meeting.getMeetingAddress()); + List projectNames = new ArrayList<>(); + if (meeting.getIsInnerProject()) { + List inners = meetingInnerProjectService.listByMeetingId(meetingId); + List projectIds = CollUtils.fieldList(inners, MeetingInnerProject::getProjectId); + List projects = projectService.listByIds(projectIds); + projects.forEach(w -> projectNames.add(w.getProjectName())); + } else { + List inners = meetingOuterProjectService.listByMeetingId(meetingId); + inners.forEach(w -> projectNames.add(w.getProjectName())); + } + data.setProjectName(StrUtil.join("、", projectNames)); + data.setTableData(new ArrayList<>()); + // 设置专家信息 + List experts = meetingExpertService.listAgreedExperts(meetingId); + List expertIds = CollUtils.fieldList(experts, MeetingExpert::getExpertId); + List expertInfos = expertUserInfoService.listByUserId(expertIds); + Map expertMap = CollUtils.listToMap(expertInfos, ExpertUserFullInfo::getUserId); + AtomicInteger integer = new AtomicInteger(0); + experts.forEach(w -> { + ExpertFeeExportDTO.ExpertInfoDTO expert = new ExpertFeeExportDTO.ExpertInfoDTO(); + expert.setNo(integer.incrementAndGet()); + expert.setFee(BigDecimal.valueOf(500)); + expert.setName(w.getExpertName()); + expert.setMobile(w.getMobile()); + ExpertUserFullInfo expertUser = expertMap.get(w.getExpertId()); + if (expertUser != null) { + expert.setIdcard(expertUser.getIdCard()); + expert.setBankNo(expertUser.getBankNo()); + expert.setBank(expertUser.getBank()); + expert.setCompany(expertUser.getCompany()); + expert.setSex(expertUser.getGender()); + } + data.getTableData().add(expert); + }); + WordUtil.export(fileName, data, response, template); + } catch (TemplateException | IOException e) { + log.error("专家费用单导出异常:{}", meetingId, e); + throw BizException.wrap("专家费用单导出失败"); + } + } + + public void expertReviewTable(Long meetingId, HttpServletResponse response) { + final String template = "专家评审单.ftl"; + String fileName = UUID.randomUUID().toString(true) + ".doc"; + try { + Meeting meeting = meetingService.getById(meetingId); + ExpertReviewTableDTO data = new ExpertReviewTableDTO(); + data.setMeetingTime(DateUtil.localDateTimeFormat(meeting.getStartTime(), "yyyy年M月d日")); + data.setMeetingAddress(meeting.getMeetingAddress()); + data.setHoldOrg(meeting.getHoldOrg()); + List projectNames = new ArrayList<>(); + if (meeting.getIsInnerProject()) { + List inners = meetingInnerProjectService.listByMeetingId(meetingId); + List projectIds = CollUtils.fieldList(inners, MeetingInnerProject::getProjectId); + List projects = projectService.listByIds(projectIds); + projects.forEach(w -> projectNames.add(w.getProjectName())); + } else { + List inners = meetingOuterProjectService.listByMeetingId(meetingId); + inners.forEach(w -> projectNames.add(w.getProjectName())); + } + data.setProjectName(StrUtil.join("、", projectNames)); + WordUtil.export(fileName, data, response, template); + } catch (TemplateException | IOException e) { + log.error("专家评审单导出异常:{}", meetingId, e); + throw BizException.wrap("专家评审单导出失败"); + } + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index c3766e9..92d63ef 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -1554,7 +1554,6 @@ public class TodoCenterManage { } public Long getSealedPdf(SealInfoDTO req) { - Long projectId = req.getProjectId(); Long notSealedFileId = req.getNotSealedFileId(); Project declaredProject = projectService.getById(projectId); diff --git a/pmapi/src/main/resources/template/专家评审单.ftl b/pmapi/src/main/resources/template/专家评审单.ftl new file mode 100644 index 0000000..849cb3c --- /dev/null +++ b/pmapi/src/main/resources/template/专家评审单.ftl @@ -0,0 +1,799 @@ + + + + Data + 潦草迷茫 + 2023-07-21T08:04:00Z + 2023-07-24T20:44:34Z + 12960 + 14 + + + wqlLaW5nc29mdCBQREYgdG8gV1BTIDkw + 2023-07-24T17:28:04Z + 2052-5.5.1.7991 + 1DC93F630FB80A5D3272BE6472F2ECEB_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${projectName} + + + + + + + + + + 专家评审意见 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${meetingTime},${holdOrg}组织专家在${meetingAddress}对${projectName}进行评审。专家组认真听取了项目业主方、建设方的情况汇报,审阅了项目材料,实地查看了设备及平台演示,专家组织质询、讨论后提出以下意见: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 专家组 + + + + + + + + + + + + + + + + + + (签名 + + + + + + + + + ): + + + + + + + + + \ No newline at end of file diff --git a/pmapi/src/main/resources/template/专家费.ftl b/pmapi/src/main/resources/template/专家费.ftl new file mode 100644 index 0000000..19f61e9 --- /dev/null +++ b/pmapi/src/main/resources/template/专家费.ftl @@ -0,0 +1,1243 @@ + + + + Data + 潦草迷茫 + 2023-07-21T08:03:00Z + 2023-07-24T19:10:05Z + 14400 + 14 + + + wqlLaW5nc29mdCBQREYgdG8gV1BTIDkw + 2023-07-24T17:28:04Z + 2052-5.5.1.7991 + 29D84B9F4F9152F50D5CBE647D58FE28_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 丽水市大数据局信息化项目专家费 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 项目名称: + + + + + + + + ${projectName} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 验收地点: + + + + + + + + ${meetingAddress} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 日 期: + + + + + + + + ${meetingTime} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 姓名 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 身份证号 + + + + + + + + + + + + + + + + + + + + 单位 + + + + + + + + + + + + + + + + + + + + 联系电话 + + + + + + + + + + + + + + + + + + + + 评审费 + + + + + + + + + + + + + + + + + + + + 开户行 + + + + + + + + + + + + + + + + + + + + + 账号 + + + + + + + + + + + + + + + + + + + + + 签名 + + + + + <#list tableData as rowData> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.no} + + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.name} + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.sex} + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.idcard} + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.company} + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.mobile} + + + + + + + + + + + + + + + + + + + + + + + + ${rowData.fee} + + + + + + + + + + + + + + + + + + + + + + + + + ${(rowData.bank)!} + + + + + + + + + + + + + + + + + + + + + + + ${rowData.bankNo} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 经办人 + + + + + + + + + + + + (签字 + + + + + + ): + + + + + + + + + \ No newline at end of file