Ver código fonte

文件转PDF上传

master
PoffyZhang 1 ano atrás
pai
commit
c54b2d22c6
10 arquivos alterados com 384 adições e 12 exclusões
  1. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/util/CommonInputStreamResource.java
  2. +64
    -5
      pmapi/src/main/java/com/ningdatech/pmapi/gov/manage/GovProjectCollectionManage.java
  3. +3
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/gov/model/entity/GovBizProjectApply.java
  4. +15
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/contants/ProvincialContant.java
  5. +56
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/manage/ProvincialManage.java
  6. +33
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/res/OssApiData.java
  7. +120
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/res/OssApiResponse.java
  8. +32
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/provincial/utils/FileUtil.java
  9. +56
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/wps/manage/WpsConvertManage.java
  10. +4
    -6
      pmapi/src/test/java/com/ningdatech/pmapi/file/ProvinceOssTest.java

pmapi/src/test/java/com/ningdatech/pmapi/file/CommonInputStreamResource.java → pmapi/src/main/java/com/ningdatech/pmapi/common/util/CommonInputStreamResource.java Ver arquivo

@@ -1,4 +1,4 @@
package com.ningdatech.pmapi.file;
package com.ningdatech.pmapi.common.util;

import org.springframework.core.io.InputStreamResource;


+ 64
- 5
pmapi/src/main/java/com/ningdatech/pmapi/gov/manage/GovProjectCollectionManage.java Ver arquivo

@@ -4,6 +4,8 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -23,10 +25,12 @@ import com.ningdatech.pmapi.gov.model.vo.*;
import com.ningdatech.pmapi.gov.service.*;
import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil;
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq;
import com.ningdatech.pmapi.provincial.manage.ProvincialManage;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.ningdatech.pmapi.wps.manage.WpsConvertManage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -39,11 +43,9 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;

/**
@@ -76,6 +78,8 @@ public class GovProjectCollectionManage {

private final RestTemplate restTemplate;

private final WpsConvertManage wpsConvertManage;

@Value("${project.push-url}")
private String pushUrl;

@@ -425,7 +429,9 @@ public class GovProjectCollectionManage {
saveApply.setBizTime(LocalDateTime.now());
saveApply.setUpdateBy(user.getUsername());
saveApply.setUpdateOn(LocalDateTime.now());
projectApplyService.saveOrUpdate(saveApply);
if(projectApplyService.saveOrUpdate(saveApply)){
uploadFileToProvincialOss(apply,oldApply,saveApply);
}
}

// 3.保存 审批信息
@@ -657,6 +663,8 @@ public class GovProjectCollectionManage {

//改正逻辑删除
baseinfo.setDeleted(Boolean.TRUE);
baseinfo.setUpdateBy(username);
baseinfo.setUpdateOn(LocalDateTime.now());
baseinfoService.updateById(baseinfo);
projectApplyService.update(Wrappers.lambdaUpdate(GovBizProjectApply.class)
.eq(GovBizProjectApply::getBaseProjId,projId)
@@ -779,4 +787,55 @@ public class GovProjectCollectionManage {
log.info("推送删除失败,{}", e.getMessage());
}
}

/**
* 上传项目归集申报的文件到OSS 前提还要先转为PDF
* @param apply
* @param oldApply
*/
private void uploadFileToProvincialOss(GovBizProjectApplyDTO apply,
GovBizProjectApply oldApply,GovBizProjectApply saveApply) {
if(checkFieldHas(apply.getBaseProjBasisFile(),oldApply,"baseProjBasisFile")){
JSONArray fileArray = JSON.parseArray(apply.getBaseProjBasisFile());
StringJoiner sj = new StringJoiner(";");
fileArray.forEach(j -> {
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(j));
byte[] btyes = wpsConvertManage.downloadToPdfStream(jsonObject.getLong("id"));
String oss = ProvincialManage.uploadToOss(btyes, jsonObject.getString("originalFileName"));
sj.add(oss);
});
saveApply.setBaseProjBasisFilePdf(sj.toString());
}
projectApplyService.updateById(saveApply);
}

private Boolean checkFieldHas(String field,GovBizProjectApply oldApply,String fieldName){
if(StringUtils.isBlank(field)){
return Boolean.FALSE;
}

//如果没有老值
if(Objects.isNull(oldApply)){
return Boolean.TRUE;
}

//和老值做个对比 不一样则true
Class<?> clazz = oldApply.getClass();
String oldFiled = StringUtils.EMPTY;
try {
Field fieldDeclared = clazz.getDeclaredField(fieldName);
fieldDeclared.setAccessible(Boolean.TRUE);
oldFiled = Objects.nonNull(fieldDeclared.get(oldApply)) ? String.valueOf(fieldDeclared.get(oldApply)) : null;
} catch (NoSuchFieldException e) {
log.error("转换PDF文件出错" + e);
} catch (IllegalAccessException e) {
log.error("转换PDF文件出错" + e);
}

if(!oldFiled.equals(field)){
return Boolean.TRUE;
}

return Boolean.FALSE;
}
}

+ 3
- 0
pmapi/src/main/java/com/ningdatech/pmapi/gov/model/entity/GovBizProjectApply.java Ver arquivo

@@ -149,4 +149,7 @@ public class GovBizProjectApply implements Serializable {

@ApiModelProperty("最后修改人")
private String updateBy;

@ApiModelProperty("立项依据材料PDF版")
private String baseProjBasisFilePdf;
}

+ 15
- 0
pmapi/src/main/java/com/ningdatech/pmapi/provincial/contants/ProvincialContant.java Ver arquivo

@@ -0,0 +1,15 @@
package com.ningdatech.pmapi.provincial.contants;

/**
* @Classname ProvincialContant
* @Description
* @Date 2023/9/6 9:16
* @Author PoffyZhang
*/
public interface ProvincialContant {

class OssUpload {
public static final String OSS_UPLOAD_URL = "https://pms.zj.gov.cn/prometheus-zhejiang_file_service/api/v1/file/uploadFile";
public static final String MEDIA_TYPE = "multipart/form-data";
}
}

+ 56
- 0
pmapi/src/main/java/com/ningdatech/pmapi/provincial/manage/ProvincialManage.java Ver arquivo

@@ -0,0 +1,56 @@
package com.ningdatech.pmapi.provincial.manage;

import com.alibaba.fastjson.JSON;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.pmapi.common.util.CommonInputStreamResource;
import com.ningdatech.pmapi.provincial.contants.ProvincialContant;
import com.ningdatech.pmapi.provincial.model.res.OssApiData;
import com.ningdatech.pmapi.provincial.model.res.OssApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.ByteArrayInputStream;
import java.util.Objects;

/**
* @Classname ProvincialManage
* @Description
* @Date 2023/9/6 9:08
* @Author PoffyZhang
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class ProvincialManage {

public static String uploadToOss(byte[] fileBytes,String fileName) {
String url = ProvincialContant.OssUpload.OSS_UPLOAD_URL;
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes);
CommonInputStreamResource commonInputStreamResource = new CommonInputStreamResource(inputStream, fileBytes.length, fileName);
params.add("file", commonInputStreamResource);
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType(ProvincialContant.OssUpload.MEDIA_TYPE);
headers.setContentType(type);
HttpEntity<MultiValueMap> formEntity = new HttpEntity(params, headers);
ResponseEntity<OssApiResponse> res = restTemplate.postForEntity(url, formEntity, OssApiResponse.class);
log.info("oss res :{}", res);
OssApiResponse body = res.getBody();
if(Objects.isNull(body)){
throw new BizException("上传省局oss请求失败");
}

if(HttpStatus.OK.value() != body.getRespCode()){
throw new BizException("上传省局oss失败:" + body.getRespMsg());
}

OssApiData ossApiData = JSON.parseObject(JSON.toJSONString(body.getData()), OssApiData.class);

return ossApiData.getAccessUrl();
}
}

+ 33
- 0
pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/res/OssApiData.java Ver arquivo

@@ -0,0 +1,33 @@
package com.ningdatech.pmapi.provincial.model.res;

import com.ningdatech.basic.enumeration.Status;
import com.ningdatech.basic.model.ApiStatus;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* <p>
* OssApiResponse -
* </p>
*
* @author ZPF
* @since 14:29 2022/9/29
*/
@Data
@NoArgsConstructor
public class OssApiData implements Serializable {

private String fileId;

private String fileName;

private String accessUrl;

private Long fileSize;

private String uploadUserCode;

private String ossObject;
}

+ 120
- 0
pmapi/src/main/java/com/ningdatech/pmapi/provincial/model/res/OssApiResponse.java Ver arquivo

@@ -0,0 +1,120 @@
package com.ningdatech.pmapi.provincial.model.res;

import com.ningdatech.basic.enumeration.Status;
import com.ningdatech.basic.model.ApiStatus;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* <p>
* OssApiResponse -
* </p>
*
* @author ZPF
* @since 14:29 2022/9/29
*/
@Data
@NoArgsConstructor
public class OssApiResponse<T> implements Serializable {
private static final long serialVersionUID = 1L;

public static final int SUCCESS_CODE = 200;

public static final String SUCCESS_MSG = "成功";

public static final int ERROR_CODE = 500;

public static final String ERROR_MSG = "Internal server error";

/**
* 状态码
*/
private Integer respCode;

/**
* 返回描述
*/
private String respMsg;

/**
* 返回数据
*/
private T data;

/**
* 全参构造函数
*
* @param respCode 状态码
* @param respMsg 返回内容
* @param data 返回数据
*/
private OssApiResponse(Integer respCode, String respMsg, T data) {
this.respCode = respCode;
this.respMsg = respMsg;
this.data = data;
}

/**
* 构造一个自定义的API返回
*
* @param respCode 状态码
* @param respMsg 返回内容
* @param data 返回数据
* @return ApiResponse
*/
public static <T> OssApiResponse<T> of(Integer respCode, String respMsg, T data) {
return new OssApiResponse<T>(respCode, respMsg, data);
}

/**
* 构造一个成功且不带数据的API返回
*
* @return ApiResponse
*/
public static <T> OssApiResponse<T> ofSuccess() {
return ofSuccess(null);
}

/**
* 构造一个成功且带数据的API返回
*
* @param data 返回数据
* @return ApiResponse
*/
public static <T> OssApiResponse<T> ofSuccess(T data) {
return ofStatus(Status.OK, data);
}

/**
* 构造一个成功且自定义消息的API返回
*
* @param msg 返回内容
* @return ApiResponse
*/
public static <T> OssApiResponse<T> ofMessage(String msg) {
return of(Status.OK.getCode(), msg, null);
}

/**
* 构造一个有状态的API返回
*
* @param status 状态 {@link Status}
* @return ApiResponse
*/
public static <T> OssApiResponse<T> ofStatus(ApiStatus status) {
return ofStatus(status, null);
}

/**
* 构造一个有状态且带数据的API返回
*
* @param status 状态 {@link Status}
* @param data 返回数据
* @return ApiResponse
*/
public static <T> OssApiResponse<T> ofStatus(ApiStatus status, T data) {
return of(status.getCode(), status.getReasonPhrase(), data);
}
}

+ 32
- 0
pmapi/src/main/java/com/ningdatech/pmapi/provincial/utils/FileUtil.java Ver arquivo

@@ -0,0 +1,32 @@
package com.ningdatech.pmapi.provincial.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

/**
* @Classname FileUtil
* @Description
* @Date 2023/9/6 9:09
* @Author PoffyZhang
*/
public class FileUtil {
public static byte[] getBytesByFile(File file) {
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

+ 56
- 0
pmapi/src/main/java/com/ningdatech/pmapi/wps/manage/WpsConvertManage.java Ver arquivo

@@ -96,6 +96,11 @@ public class WpsConvertManage {
downloadAndToPdf(file, response);
}

public byte[] downloadToPdfStream(Long fileId) {
com.ningdatech.file.entity.File file = fileService.getById(fileId);
return downloadAndToPdf(file);
}

private void downloadAndToPdf(com.ningdatech.file.entity.File file, HttpServletResponse response) {
OSS oss = new OSSClientBuilder().build(fileServerProperties.getAli().getEndpoint(), fileServerProperties.getAli().getAccessKeyId(), fileServerProperties.getAli().getAccessKeySecret());
AtomAgent ha = new AtomAgent(WpsContant.WPS_CONVERT_URL_ONLINE);
@@ -154,6 +159,57 @@ public class WpsConvertManage {
}
}

private byte[] downloadAndToPdf(com.ningdatech.file.entity.File file) {
OSS oss = new OSSClientBuilder().build(fileServerProperties.getAli().getEndpoint(), fileServerProperties.getAli().getAccessKeyId(), fileServerProperties.getAli().getAccessKeySecret());
AtomAgent ha = new AtomAgent(WpsContant.WPS_CONVERT_URL_ONLINE);
try (OSSObject ossObject = oss.getObject(file.getBucket(), file.getPath());
InputStream stream = ossObject.getObjectContent();) {
String fileName = null;
byte[] bytes = new byte[4096];
int read;
//测试环境 转不了PDF 请求不了 WPS转换服务器
if(BizConst.DEV.equals(active)){
byte[] byt = new byte[stream.available()];
stream.read(byt);
return byt;
}else if(BizConst.PRE.equals(active) ||
BizConst.PROD.equals(active)){
String filePath = WpsContant.FIX_FILE_PATH + file.getOriginalFileName();
convert(stream,filePath);
//转换PDF
List<File> fileList =new ArrayList<File>();
//2)、定义转换后的pdf文件输出流
OutputStream out = null;
//3)、添加原文件到集合
fileList.add(new File(filePath));
//4)、赋值转换后的pdf文件输出流
File pdfFile = new File(WpsContant.PDF_PATH);
out = new FileOutputStream(pdfFile);
//5)、调用方法,执行将多个文件转为pdf文件
ha.OFDToPDF(fileList, out);
FileInputStream fileInputStream = new FileInputStream(pdfFile);
fileName = URLEncoder.encode(WpsContant.PDF_NAME, CharsetUtil.UTF_8);
for(File f : fileList){
//用完就删
f.deleteOnExit();
}
byte[] byt = new byte[fileInputStream.available()];
fileInputStream.read(byt);
return byt;
}
}catch (Exception e){
log.error(e.getMessage());
}finally {
oss.shutdown();
try {
ha.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
return null;
}

public static void convert(InputStream inputStream, String filePath) {
try {
File file = new File(filePath);


+ 4
- 6
pmapi/src/test/java/com/ningdatech/pmapi/file/ProvinceOssTest.java Ver arquivo

@@ -1,7 +1,6 @@
package com.ningdatech.pmapi.file;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import com.ningdatech.pmapi.common.util.CommonInputStreamResource;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
@@ -12,11 +11,10 @@ import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.FileInputStream;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;

import org.apache.http.entity.ContentType;
import java.io.*;

@@ -43,7 +41,7 @@ public class ProvinceOssTest {
headers.setContentType(type);
HttpEntity<MultiValueMap> formEntity = new HttpEntity(params, headers);
ResponseEntity<String> res = restTemplate.postForEntity(url, formEntity, String.class);
System.out.println(res);
System.out.println(res.getBody());
}

public static MultipartFile getMultipartFile(File file) {


Carregando…
Cancelar
Salvar