@@ -1,4 +1,4 @@ | |||||
package com.ningdatech.pmapi.file; | |||||
package com.ningdatech.pmapi.common.util; | |||||
import org.springframework.core.io.InputStreamResource; | import org.springframework.core.io.InputStreamResource; | ||||
@@ -4,6 +4,8 @@ import cn.hutool.core.bean.BeanUtil; | |||||
import cn.hutool.core.bean.copier.CopyOptions; | import cn.hutool.core.bean.copier.CopyOptions; | ||||
import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||
import com.alibaba.fastjson.JSON; | 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.conditions.query.LambdaQueryWrapper; | ||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 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.gov.service.*; | ||||
import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil; | import com.ningdatech.pmapi.projectdeclared.utils.GenerateProjectCodeUtil; | ||||
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; | 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.sys.model.entity.Role; | ||||
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum; | import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum; | ||||
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails; | ||||
import com.ningdatech.pmapi.user.util.LoginUserUtil; | import com.ningdatech.pmapi.user.util.LoginUserUtil; | ||||
import com.ningdatech.pmapi.wps.manage.WpsConvertManage; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -39,11 +43,9 @@ import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import org.springframework.web.client.RestTemplate; | import org.springframework.web.client.RestTemplate; | ||||
import java.lang.reflect.Field; | |||||
import java.time.LocalDateTime; | 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; | import java.util.stream.Collectors; | ||||
/** | /** | ||||
@@ -76,6 +78,8 @@ public class GovProjectCollectionManage { | |||||
private final RestTemplate restTemplate; | private final RestTemplate restTemplate; | ||||
private final WpsConvertManage wpsConvertManage; | |||||
@Value("${project.push-url}") | @Value("${project.push-url}") | ||||
private String pushUrl; | private String pushUrl; | ||||
@@ -425,7 +429,9 @@ public class GovProjectCollectionManage { | |||||
saveApply.setBizTime(LocalDateTime.now()); | saveApply.setBizTime(LocalDateTime.now()); | ||||
saveApply.setUpdateBy(user.getUsername()); | saveApply.setUpdateBy(user.getUsername()); | ||||
saveApply.setUpdateOn(LocalDateTime.now()); | saveApply.setUpdateOn(LocalDateTime.now()); | ||||
projectApplyService.saveOrUpdate(saveApply); | |||||
if(projectApplyService.saveOrUpdate(saveApply)){ | |||||
uploadFileToProvincialOss(apply,oldApply,saveApply); | |||||
} | |||||
} | } | ||||
// 3.保存 审批信息 | // 3.保存 审批信息 | ||||
@@ -657,6 +663,8 @@ public class GovProjectCollectionManage { | |||||
//改正逻辑删除 | //改正逻辑删除 | ||||
baseinfo.setDeleted(Boolean.TRUE); | baseinfo.setDeleted(Boolean.TRUE); | ||||
baseinfo.setUpdateBy(username); | |||||
baseinfo.setUpdateOn(LocalDateTime.now()); | |||||
baseinfoService.updateById(baseinfo); | baseinfoService.updateById(baseinfo); | ||||
projectApplyService.update(Wrappers.lambdaUpdate(GovBizProjectApply.class) | projectApplyService.update(Wrappers.lambdaUpdate(GovBizProjectApply.class) | ||||
.eq(GovBizProjectApply::getBaseProjId,projId) | .eq(GovBizProjectApply::getBaseProjId,projId) | ||||
@@ -779,4 +787,55 @@ public class GovProjectCollectionManage { | |||||
log.info("推送删除失败,{}", e.getMessage()); | 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; | |||||
} | |||||
} | } |
@@ -149,4 +149,7 @@ public class GovBizProjectApply implements Serializable { | |||||
@ApiModelProperty("最后修改人") | @ApiModelProperty("最后修改人") | ||||
private String updateBy; | private String updateBy; | ||||
@ApiModelProperty("立项依据材料PDF版") | |||||
private String baseProjBasisFilePdf; | |||||
} | } |
@@ -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"; | |||||
} | |||||
} |
@@ -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(); | |||||
} | |||||
} |
@@ -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; | |||||
} |
@@ -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); | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -96,6 +96,11 @@ public class WpsConvertManage { | |||||
downloadAndToPdf(file, response); | 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) { | 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()); | OSS oss = new OSSClientBuilder().build(fileServerProperties.getAli().getEndpoint(), fileServerProperties.getAli().getAccessKeyId(), fileServerProperties.getAli().getAccessKeySecret()); | ||||
AtomAgent ha = new AtomAgent(WpsContant.WPS_CONVERT_URL_ONLINE); | 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) { | public static void convert(InputStream inputStream, String filePath) { | ||||
try { | try { | ||||
File file = new File(filePath); | File file = new File(filePath); | ||||
@@ -1,7 +1,6 @@ | |||||
package com.ningdatech.pmapi.file; | 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.junit.Test; | ||||
import org.springframework.http.HttpEntity; | import org.springframework.http.HttpEntity; | ||||
import org.springframework.http.HttpHeaders; | import org.springframework.http.HttpHeaders; | ||||
@@ -12,11 +11,10 @@ import org.springframework.util.LinkedMultiValueMap; | |||||
import org.springframework.util.MultiValueMap; | import org.springframework.util.MultiValueMap; | ||||
import org.springframework.web.client.RestTemplate; | import org.springframework.web.client.RestTemplate; | ||||
import org.springframework.web.multipart.MultipartFile; | import org.springframework.web.multipart.MultipartFile; | ||||
import org.springframework.web.multipart.commons.CommonsMultipartFile; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
import org.springframework.web.multipart.MultipartFile; | |||||
import org.springframework.mock.web.MockMultipartFile; | |||||
import org.apache.http.entity.ContentType; | import org.apache.http.entity.ContentType; | ||||
import java.io.*; | import java.io.*; | ||||
@@ -43,7 +41,7 @@ public class ProvinceOssTest { | |||||
headers.setContentType(type); | headers.setContentType(type); | ||||
HttpEntity<MultiValueMap> formEntity = new HttpEntity(params, headers); | HttpEntity<MultiValueMap> formEntity = new HttpEntity(params, headers); | ||||
ResponseEntity<String> res = restTemplate.postForEntity(url, formEntity, String.class); | ResponseEntity<String> res = restTemplate.postForEntity(url, formEntity, String.class); | ||||
System.out.println(res); | |||||
System.out.println(res.getBody()); | |||||
} | } | ||||
public static MultipartFile getMultipartFile(File file) { | public static MultipartFile getMultipartFile(File file) { | ||||