diff --git a/deployment-dev.yaml b/deployment-dev.yaml index 12bfa41..0871a9f 100644 --- a/deployment-dev.yaml +++ b/deployment-dev.yaml @@ -39,6 +39,10 @@ spec: - name: log hostPath: path: /var/lib/docker/log/349553515466-test/default-group/all #开发环境 + - name: storage + persistentVolumeClaim: + claimName: file-pvc + readOnly: false # 必选,Pod中容器列表 containers: - name: biz-service-ebtp-extend @@ -47,6 +51,8 @@ spec: volumeMounts: - name: log mountPath: /log + - name: storage + mountPath: /storage # 需要暴露的端口库号列表 ports: - containerPort: 18018 diff --git a/deployment-master.yaml b/deployment-master.yaml index 04c5d8d..8bd9734 100644 --- a/deployment-master.yaml +++ b/deployment-master.yaml @@ -39,6 +39,10 @@ spec: - name: log hostPath: path: /var/lib/docker/log/349553515466-prod/default-group/30days + - name: storage + persistentVolumeClaim: + claimName: file-pvc + readOnly: false affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -57,6 +61,8 @@ spec: volumeMounts: - name: log mountPath: /log + - name: storage + mountPath: /storage ports: - containerPort: 18018 livenessProbe: diff --git a/deployment-sim.yaml b/deployment-sim.yaml index 6d1ff47..7e5c941 100644 --- a/deployment-sim.yaml +++ b/deployment-sim.yaml @@ -39,6 +39,10 @@ spec: - name: log hostPath: path: /var/lib/docker/log/349553515466-preprod/default-group/all #开发环境 + - name: storage + persistentVolumeClaim: + claimName: file-pvc + readOnly: false affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -57,6 +61,8 @@ spec: volumeMounts: - name: log mountPath: /log + - name: storage + mountPath: /storage ports: - containerPort: 18018 resources: diff --git a/deployment-uat.yaml b/deployment-uat.yaml index c166313..c75f587 100644 --- a/deployment-uat.yaml +++ b/deployment-uat.yaml @@ -40,7 +40,10 @@ spec: - name: log hostPath: path: /var/lib/docker/log/349553515466-uat/default-group/all #开发环境 - + - name: storage + persistentVolumeClaim: + claimName: file-pvc + readOnly: false # 必选,Pod中容器列表 containers: - name: biz-service-ebtp-extend @@ -49,6 +52,8 @@ spec: volumeMounts: - name: log mountPath: /log + - name: storage + mountPath: /storage # 需要暴露的端口库号列表 ports: - containerPort: 18018 diff --git a/lib/aspose-words-16.8.0-javadoc.jar b/lib/aspose-words-16.8.0-javadoc.jar new file mode 100644 index 0000000..075f5dd Binary files /dev/null and b/lib/aspose-words-16.8.0-javadoc.jar differ diff --git a/lib/aspose-words-16.8.0-jdk16.jar b/lib/aspose-words-16.8.0-jdk16.jar new file mode 100644 index 0000000..8433d9e Binary files /dev/null and b/lib/aspose-words-16.8.0-jdk16.jar differ diff --git a/pom.xml b/pom.xml index 2a0b67f..80857ba 100644 --- a/pom.xml +++ b/pom.xml @@ -54,13 +54,13 @@ poi 4.1.2 - + org.apache.poi poi-ooxml 4.1.2 - + org.apache.poi poi-ooxml-schemas @@ -71,6 +71,7 @@ commons-httpclient 3.1 + jit.vstk jit-vstk @@ -78,6 +79,21 @@ system ${basedir}/lib/jit-vstk-jdk15-2.0.50-20150603.060911-1.jar + + aspose.javadoc + aspose.javadoc + 16.8.0 + system + ${basedir}/lib/aspose-words-16.8.0-javadoc.jar + + + aspose.jdk16 + aspose.jdk16 + 16.8.0 + system + ${basedir}/lib/aspose-words-16.8.0-jdk16.jar + + org.apache.velocity velocity-tools @@ -89,7 +105,11 @@ - + + e-iceblue + spire.doc.free + 3.9.0 + @@ -105,6 +125,11 @@ always + + + com.e-iceblue + http://repo.e-iceblue.cn/repository/maven-public/ + diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/controller/ExpertSignatureController.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/controller/ExpertSignatureController.java new file mode 100644 index 0000000..ecd4d83 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/controller/ExpertSignatureController.java @@ -0,0 +1,41 @@ +package com.chinaunicom.mall.ebtp.extend.signature.controller; + +import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse; +import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature; +import com.chinaunicom.mall.ebtp.extend.signature.service.ExpertSignatureService; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@RestController +@Api(tags = "") +@RequestMapping("/v1/sign") +public class ExpertSignatureController { + + + @Autowired + private ExpertSignatureService expertSignatureService; + + /** + * 追加专家签名 + * + * @param signature + * @param request + * @param response + */ + @PreAuthorize("hasAnyAuthority('ebtp-purchase','ebtp-agency-project-manager')") + @PostMapping(value = "") + public BaseResponse export(@RequestBody ExpertSignature signature, HttpServletRequest request, HttpServletResponse response) { + return BaseResponse.success(expertSignatureService.addSignature(signature)); + } + + +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertInfo.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertInfo.java new file mode 100644 index 0000000..c1f55f5 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertInfo.java @@ -0,0 +1,15 @@ +package com.chinaunicom.mall.ebtp.extend.signature.entity; + + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class ExpertInfo { + + private String expertId; + + private String expertSign; + +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertSignature.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertSignature.java new file mode 100644 index 0000000..5d46958 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/entity/ExpertSignature.java @@ -0,0 +1,18 @@ +package com.chinaunicom.mall.ebtp.extend.signature.entity; + + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +public class ExpertSignature { + + private String assessRoomId; + + private String bid; + + private List experts; +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/ExpertSignatureService.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/ExpertSignatureService.java new file mode 100644 index 0000000..569e110 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/ExpertSignatureService.java @@ -0,0 +1,15 @@ +package com.chinaunicom.mall.ebtp.extend.signature.service; + +import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature; + +public interface ExpertSignatureService { + + + /** + * 追加专家签名 + * + * @param signature + * @return + */ + String addSignature(ExpertSignature signature); +} diff --git a/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/impl/ExpertSignatureServiceImpl.java b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/impl/ExpertSignatureServiceImpl.java new file mode 100644 index 0000000..0fc5d68 --- /dev/null +++ b/src/main/java/com/chinaunicom/mall/ebtp/extend/signature/service/impl/ExpertSignatureServiceImpl.java @@ -0,0 +1,228 @@ +package com.chinaunicom.mall.ebtp.extend.signature.service.impl; + + +import cn.hutool.core.io.FileUtil; +import com.aspose.words.License; +import com.aspose.words.SaveFormat; +import com.chinaunicom.ebtp.mall.cloud.attachment.sdk.api.AttachmentClient; +import com.chinaunicom.ebtp.mall.cloud.attachment.sdk.model.AttachmentEntity; +import com.chinaunicom.mall.ebtp.common.util.PropertyUtils; +import com.chinaunicom.mall.ebtp.extend.export.service.templateFile.TemplateFileService; +import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature; +import com.chinaunicom.mall.ebtp.extend.signature.service.ExpertSignatureService; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.data.PictureRenderData; +import com.spire.doc.Document; +import com.spire.doc.DocumentObject; +import com.spire.doc.FileFormat; +import com.spire.doc.Section; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import sun.misc.BASE64Decoder; + +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Service +public class ExpertSignatureServiceImpl implements ExpertSignatureService { + + @Autowired + private AttachmentClient attachmentClient; + + @Autowired + private TemplateFileService templateFileService; + + @Value("${mconfig.file.upload-address}") + private String uploadAddress; + + + private String getUploadAddress(String assessRoomId) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return uploadAddress + File.separator + sdf.format(System.currentTimeMillis()) + File.separator + assessRoomId + File.separator; + } + + /** + * 追加专家签名 + * + * @param signature + * @return + */ + @Override + public String addSignature(ExpertSignature signature) { + //获取临时存储地址 + String path = this.getUploadAddress(signature.getAssessRoomId()); + //获取专家签名文件 + InputStream expertSign = getExpertSign(signature, path); + //获取bid的word文件 + AttachmentEntity entity = attachmentClient.findByObjectId(signature.getBid()).orElse(new AttachmentEntity()); + + byte[] bytes = attachmentClient.downloadFileByObjectId(signature.getBid()).orElse(new byte[0]); + InputStream word = new ByteArrayInputStream(bytes); + + //合并word 转为pdf + byte[] pdf = null; + try { + pdf = mergeWord(word, expertSign, path); + } catch (IOException e) { + e.printStackTrace(); + } + + //上传pdf到文档中心 + String pdfId = PropertyUtils.getSnowflakeId(); + attachmentClient.upload(pdfId, entity.getFilename(), pdf); + return pdfId; + } + + /** + * 合并word + * + * @param source + * @param addObj + * @param path + * @throws IOException + */ + private byte[] mergeWord(InputStream source, InputStream addObj, String path) throws IOException { + Document d1 = new Document(source); + Document d2 = new Document(addObj); + + //获取文档1的最后一节 + Section lastsec = d1.getLastSection(); + + //遍历文档2的所有段落内容,添加到文档1 + for (Section section : (Iterable
) d2.getSections()) { + for (DocumentObject obj : (Iterable) section.getBody().getChildObjects() + ) { + lastsec.getBody().getChildObjects().add(obj.deepClone()); + } + } + + //保存合并后的文档 + d1.saveToFile(path + "/merged.docx", FileFormat.Docx_2010); + + //转为pdf + long l = System.currentTimeMillis(); + if (!getLicense()) { + return null; + } + + File f = new File(path + "/merged.pdf"); + FileOutputStream fos = new FileOutputStream(f); + + try { + com.aspose.words.Document doc = new com.aspose.words.Document(path + "/merged.docx"); + doc.save(fos, SaveFormat.PDF); + } catch (Exception e) { + e.printStackTrace(); + } finally { + source.close(); + addObj.close(); + fos.flush(); + fos.close(); + } + + long l1 = System.currentTimeMillis(); + log.info(" ======= " + (l1 - l) + " ======= "); + + return IOUtils.toByteArray(new FileInputStream(f)); + } + + private boolean getLicense() { + boolean result = false; + InputStream is = ExpertSignatureServiceImpl.class.getClassLoader().getResourceAsStream("/license/aspose-license.xml"); +// String licenseStr = +// "\n" + +// " \n" + +// " \n" + +// " Aspose.Total for Java\n" + +// " Aspose.Words for Java\n" + +// " \n" + +// " Enterprise\n" + +// " 20991231\n" + +// " 20991231\n" + +// " 8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7\n" + +// " \n" + +// " sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=\n" + +// ""; +// InputStream is = null; +// is = new ByteArrayInputStream(licenseStr.getBytes(StandardCharsets.UTF_8)); + License license = new License(); + try { + license.setLicense(is); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + private FileInputStream getExpertSign(ExpertSignature signature, final String path) { + String imgPath = path + "/imgs/"; + if (!FileUtil.exist(imgPath)) { + FileUtil.mkdir(imgPath); + } + List pics = new ArrayList<>(); + signature.getExperts().forEach(l -> { + base64ToImage(l.getExpertSign(), imgPath + l.getExpertId()); + + pics.add(new PictureRenderData(130, 100, imgPath + l.getExpertId())); + }); + + //获取签名模版 + InputStream file = templateFileService.getExportTemplet("expertSignature"); + + //生成签名word + Map all = new HashMap() {{ + put("imgs", pics); + }}; + XWPFTemplate template = XWPFTemplate.compile(file).render(all); + FileInputStream fis = null; + try { + String docPath = path + "/expertSignature.docx"; + template.writeToFile(docPath); + fis = new FileInputStream(new File(docPath)); + } catch (IOException e) { + e.printStackTrace(); + } + + return fis; + } + + + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + */ + private void base64ToImage(String imgStr, String imgFilePath) { + if (StringUtils.isEmpty(imgStr)) { + return; + } + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + OutputStream out = new FileOutputStream(imgFilePath); + out.write(b); + out.flush(); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 6d6acc0..ef4944f 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -172,9 +172,13 @@ mconfig: tender: biz-service-ebtp-tender #投标服务 documentcenter: core-service-document-center #文档中心 usercenter: core-service-usercenter-public #用户中心 + file: + upload-address: /storage/reviewReport/ document: clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749 + + # 用户暴露给 prometheus 的健康数据 management: endpoints: diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 4e95ae0..4f3a9c1 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -3,18 +3,18 @@ server: servlet: context-path: / -# 对应 apollo 配置中心的应用名 -app: - id: biz-service-ebtp-extend - -# Apollo 配置信息 -apollo: - meta: http://10.242.37.148:6001/ - bootstrap: - namespace: application - enabled: true - eagerLoad: - enabled: true +## 对应 apollo 配置中心的应用名 +#app: +# id: biz-service-ebtp-extend +# +## Apollo 配置信息 +#apollo: +# meta: http://10.242.37.148:6001/ +# bootstrap: +# namespace: application +# enabled: true +# eagerLoad: +# enabled: true seata: service: @@ -164,7 +164,8 @@ mconfig: tender: biz-service-ebtp-tender #投标服务 documentcenter: core-service-document-center #文档中心 usercenter: core-service-usercenter-public #用户中心 - + file: + upload-address: /storage/reviewReport/ document: clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749 diff --git a/src/main/resources/application-mster.yml b/src/main/resources/application-mster.yml index 9ea52e4..aacb2f2 100644 --- a/src/main/resources/application-mster.yml +++ b/src/main/resources/application-mster.yml @@ -167,6 +167,8 @@ mconfig: tender: biz-service-ebtp-tender #投标服务 documentcenter: core-service-document-center #文档中心 usercenter: core-service-usercenter-public #用户中心 + file: + upload-address: /storage/reviewReport/ document: clientHttpUrl: http://10.238.25.112:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749 diff --git a/src/main/resources/application-uat.yml b/src/main/resources/application-uat.yml index 9df047a..5d1ae5c 100644 --- a/src/main/resources/application-uat.yml +++ b/src/main/resources/application-uat.yml @@ -167,6 +167,8 @@ mconfig: tender: biz-service-ebtp-tender #投标服务 documentcenter: core-service-document-center #文档中心 usercenter: core-service-usercenter-public #用户中心 + file: + upload-address: /storage/reviewReport/ document: clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749 diff --git a/src/main/resources/license/aspose-license.xml b/src/main/resources/license/aspose-license.xml new file mode 100644 index 0000000..3ebca6c --- /dev/null +++ b/src/main/resources/license/aspose-license.xml @@ -0,0 +1,16 @@ + + + + + Aspose.Total for Java + Aspose.Words for Java + + Enterprise + 20991231 + 20991231 + 8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7 + + + sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU= + + \ No newline at end of file