|
|
|
@ -7,25 +7,36 @@ import cn.org.bjca.seal.esspdf.client.tools.AnySignClientTool;
|
|
|
|
|
import cn.org.bjca.seal.esspdf.client.utils.ClientUtil;
|
|
|
|
|
import com.emr.dao.ArchiveDetailCaCopyMapper;
|
|
|
|
|
import com.emr.dao.Archive_Detail_ca_reqParamMapper;
|
|
|
|
|
import com.emr.dao.CaDepartIdMapper;
|
|
|
|
|
import com.emr.dao.CaSignatureMapper;
|
|
|
|
|
import com.emr.dto.Archive_DetailPdfPathDto;
|
|
|
|
|
import com.emr.entity.Archive_Detail_caSign;
|
|
|
|
|
import com.emr.entity.Archive_Detail_ca_reqParam;
|
|
|
|
|
import com.emr.entity.Power_User;
|
|
|
|
|
import com.emr.service.Archive_DetailService;
|
|
|
|
|
import com.emr.util.Msg;
|
|
|
|
|
import com.emr.vo.CaDepartIdVo;
|
|
|
|
|
import com.lowagie.text.Rectangle;
|
|
|
|
|
import com.lowagie.text.pdf.PdfReader;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import okhttp3.OkHttpClient;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
|
|
import org.springframework.scheduling.annotation.EnableAsync;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
import okhttp3.*;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.net.HttpURLConnection;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.nio.file.Files;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Base64;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
@ -61,6 +72,17 @@ public class CaSignServiceImpl {
|
|
|
|
|
private CaSignatureMapper caSignatureMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ArchiveDetailCaCopyMapper archiveDetailCaCopyMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private CaDepartIdMapper caDepartIdMapper;
|
|
|
|
|
@Value("${synDepartUrl}")
|
|
|
|
|
private String synDepartUrl;
|
|
|
|
|
@Value("${signUrl}")
|
|
|
|
|
private String signUrl;
|
|
|
|
|
|
|
|
|
|
@Value("${clientId}")
|
|
|
|
|
private String clientId;
|
|
|
|
|
@Value("${clientSecret}")
|
|
|
|
|
private String clientSecret;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Description: caSignByMasterId方法是根据masterId查询所有文件进行ca签章
|
|
|
|
@ -69,17 +91,29 @@ public class CaSignServiceImpl {
|
|
|
|
|
* @author 曾文和
|
|
|
|
|
* @createTime 2023/7/25 15:52
|
|
|
|
|
*/
|
|
|
|
|
@Async
|
|
|
|
|
public void caSignByMasterId(String masterId) {
|
|
|
|
|
public Msg caSignByMasterId(String masterId, Power_User user) {
|
|
|
|
|
if (isCaOpen == 0) {
|
|
|
|
|
return;
|
|
|
|
|
return Msg.success();
|
|
|
|
|
}
|
|
|
|
|
//根据masterId查询文件集合
|
|
|
|
|
try {
|
|
|
|
|
List<Archive_DetailPdfPathDto> pdfPathList = archiveDetailService.getPdfPathByMasterId(masterId);
|
|
|
|
|
if (!CollectionUtils.isEmpty(pdfPathList)) {
|
|
|
|
|
//判断该部门是否存在签章
|
|
|
|
|
CaDepartIdVo caDepartIdVo = caDepartIdMapper.getDepartId(user.getRemark());
|
|
|
|
|
//没有保存部门签章id时需要请求获取一个新的departId
|
|
|
|
|
if (caDepartIdVo==null){
|
|
|
|
|
//请求医院科室在医网信标识id
|
|
|
|
|
String departId = getDepartId(user);
|
|
|
|
|
caDepartIdMapper.addDepartId(user.getRemark(),departId);
|
|
|
|
|
return Msg.fail("该用户科室没有在医信网平台申请部门签章请联系医信网人员");
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isBlank(caDepartIdVo.getDataId())) {
|
|
|
|
|
return Msg.fail("部门标识为空");
|
|
|
|
|
}
|
|
|
|
|
String dataId = caDepartIdVo.getDataId();
|
|
|
|
|
//保存文件表数据list
|
|
|
|
|
List<Archive_DetailPdfPathDto> list=new ArrayList<>();
|
|
|
|
|
List<Archive_DetailPdfPathDto> list = new ArrayList<>();
|
|
|
|
|
//签章后保存目录
|
|
|
|
|
String newPath = newPdfPath + File.separator + masterId;
|
|
|
|
|
//没有目录创建目录
|
|
|
|
@ -94,25 +128,29 @@ public class CaSignServiceImpl {
|
|
|
|
|
List<String> failIdList = new ArrayList<>();
|
|
|
|
|
//遍历文件集合
|
|
|
|
|
for (Archive_DetailPdfPathDto dto : pdfPathList) {
|
|
|
|
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
|
|
|
|
//获取今天日期
|
|
|
|
|
String todayDate = fmt.format(new Date());
|
|
|
|
|
//签章后地址
|
|
|
|
|
String newPdfPath = newPath + File.separator + todayDate+".pdf";
|
|
|
|
|
//获取文件路径
|
|
|
|
|
String pdfPath = dto.getPdfPath();
|
|
|
|
|
File file = new File(pdfPath);
|
|
|
|
|
if (file.isFile()) {
|
|
|
|
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
|
|
|
|
//获取今天日期
|
|
|
|
|
String todayDate = fmt.format(new Date());
|
|
|
|
|
//签章后地址
|
|
|
|
|
String newpdfPath = newPath + File.separator + todayDate+".pdf";
|
|
|
|
|
backupsPdf(pdfPath,newpdfPath);
|
|
|
|
|
//进行签章
|
|
|
|
|
boolean isSign = caSign(newpdfPath, caReqParam);
|
|
|
|
|
if (isSign) {
|
|
|
|
|
idList.add(dto.getId());
|
|
|
|
|
dto.setPdfPath(newpdfPath);
|
|
|
|
|
} else {
|
|
|
|
|
failIdList.add(dto.getId());
|
|
|
|
|
dto.setPdfPath(newpdfPath);
|
|
|
|
|
String pdfPathString = pdfToBase64(pdfPath);
|
|
|
|
|
PdfReader pdfReader = new PdfReader(pdfPath);
|
|
|
|
|
int pageCount = pdfReader.getNumberOfPages();
|
|
|
|
|
Msg msg = sign(pdfPathString, dataId,caReqParam,pageCount);
|
|
|
|
|
if (msg.getCode()!=100){
|
|
|
|
|
return Msg.fail();
|
|
|
|
|
}
|
|
|
|
|
String newPdfPathBase64 = msg.getMsg();
|
|
|
|
|
if (!convertBase64ToPdf(newPdfPathBase64, newPdfPath)){
|
|
|
|
|
return Msg.fail();
|
|
|
|
|
}
|
|
|
|
|
dto.setPdfPath(newPdfPath);
|
|
|
|
|
} else {
|
|
|
|
|
return Msg.fail();
|
|
|
|
|
}
|
|
|
|
|
list.add(dto);
|
|
|
|
|
}
|
|
|
|
@ -120,8 +158,9 @@ public class CaSignServiceImpl {
|
|
|
|
|
updateCaFileState(idList, failIdList, masterId);
|
|
|
|
|
//判断是否存在,存在在先删除
|
|
|
|
|
int caMasterId = caSignatureMapper.getCaMasterId(masterId, 1);
|
|
|
|
|
if (caMasterId>0){
|
|
|
|
|
if (caMasterId > 0) {
|
|
|
|
|
archiveDetailCaCopyMapper.updateByMasterID(masterId);
|
|
|
|
|
caSignatureMapper.delCaMasterId(masterId);
|
|
|
|
|
}
|
|
|
|
|
//签章完后保存新的文件表
|
|
|
|
|
archiveDetailCaCopyMapper.addArchiveDetailCaCopyMapper(list);
|
|
|
|
@ -130,19 +169,161 @@ public class CaSignServiceImpl {
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return Msg.fail("请求失败");
|
|
|
|
|
}
|
|
|
|
|
return Msg.success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将pdf文件base64方法
|
|
|
|
|
public static String pdfToBase64(String filePath) throws IOException {
|
|
|
|
|
File file = new File(filePath);
|
|
|
|
|
// 读取文件内容到字节数组
|
|
|
|
|
byte[] fileContent = Files.readAllBytes(file.toPath());
|
|
|
|
|
// 将字节数组编码为Base64字符串
|
|
|
|
|
return Base64.getEncoder().encodeToString(fileContent);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//将base64转为pdf方法
|
|
|
|
|
public Boolean convertBase64ToPdf(String base64String, String filePath) {
|
|
|
|
|
try {
|
|
|
|
|
// 解码Base64字符串
|
|
|
|
|
byte[] decodedBytes = Base64.getDecoder().decode(base64String);
|
|
|
|
|
|
|
|
|
|
// 将解码后的数据写入PDF文件
|
|
|
|
|
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
|
|
|
|
fos.write(decodedBytes);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
private void backupsPdf(String pdfPath,String newpdfPath){
|
|
|
|
|
try (InputStream inputStream = new FileInputStream(pdfPath);
|
|
|
|
|
OutputStream outputStream = new FileOutputStream(newpdfPath)) {
|
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
|
int bytesRead;
|
|
|
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
|
|
outputStream.write(buffer, 0, bytesRead);
|
|
|
|
|
//签章接口
|
|
|
|
|
private Msg sign(String pdfPathString,String departId,Archive_Detail_ca_reqParam caReqParam,int pageCount) {
|
|
|
|
|
// 创建OkHttpClient实例
|
|
|
|
|
OkHttpClient client = new OkHttpClient();
|
|
|
|
|
// 定义请求的URL
|
|
|
|
|
String url = signUrl;
|
|
|
|
|
String pdfSignBase64="";
|
|
|
|
|
// 创建请求体
|
|
|
|
|
String json = "{"
|
|
|
|
|
+ "\"head\": {"
|
|
|
|
|
+ "\"clientId\": \"" + clientId + "\","
|
|
|
|
|
+ "\"clientSecret\": \"" + clientSecret + "\","
|
|
|
|
|
+ "},"
|
|
|
|
|
+ "\"body\": {"
|
|
|
|
|
+ "\"pdfBase64\": \"" + pdfPathString + "\","
|
|
|
|
|
+ "\"departId\": \"" + departId + "\","
|
|
|
|
|
// + "\"keyword\": \"医师签名\","
|
|
|
|
|
// + "\"moveType\": \"1\","
|
|
|
|
|
// + "\"searchOrder\": \"2\","
|
|
|
|
|
// + "\"scale\": \"0.4\","
|
|
|
|
|
// + "\"fileType\": \"2\","
|
|
|
|
|
+ "\"locationPage\": \"" + pageCount + "\","
|
|
|
|
|
+ "\"x\": \"" + caReqParam.getSignTop() + "\","
|
|
|
|
|
+ "\"y\": \"" + caReqParam.getSignLeft() + "\","
|
|
|
|
|
+ "}"
|
|
|
|
|
+ "}";
|
|
|
|
|
// 创建RequestBody
|
|
|
|
|
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
|
|
|
|
|
|
|
|
|
|
// 创建Request
|
|
|
|
|
Request request = new Request.Builder()
|
|
|
|
|
.url(url)
|
|
|
|
|
.post(requestBody)
|
|
|
|
|
.build();
|
|
|
|
|
try {
|
|
|
|
|
// 执行请求
|
|
|
|
|
Response response = client.newCall(request).execute();
|
|
|
|
|
|
|
|
|
|
// 检查响应状态码
|
|
|
|
|
if (response.isSuccessful()) {
|
|
|
|
|
// 获取响应体
|
|
|
|
|
String responseData = response.body().string();
|
|
|
|
|
|
|
|
|
|
// 解析JSON响应
|
|
|
|
|
JSONObject jsonResponse = new JSONObject(responseData);
|
|
|
|
|
|
|
|
|
|
// 获取返回的参数
|
|
|
|
|
pdfSignBase64 = jsonResponse.getJSONObject("data").getString("pdfSignBase64");
|
|
|
|
|
String status = jsonResponse.getString("status");
|
|
|
|
|
if (!status.equals("0")){
|
|
|
|
|
return Msg.fail("请求失败");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("请求失败,状态码:" + response.code());
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return Msg.fail();
|
|
|
|
|
}
|
|
|
|
|
return Msg.success(pdfSignBase64);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//请求医信网标识id
|
|
|
|
|
private String getDepartId(Power_User user) {
|
|
|
|
|
// 创建OkHttpClient实例
|
|
|
|
|
OkHttpClient client = new OkHttpClient();
|
|
|
|
|
|
|
|
|
|
// 定义请求的URL
|
|
|
|
|
String url = synDepartUrl;
|
|
|
|
|
String dataId = "";
|
|
|
|
|
// 创建请求体
|
|
|
|
|
String json = "{"
|
|
|
|
|
+ "\"head\": {"
|
|
|
|
|
+ "\"clientId\": \"" + clientId + "\","
|
|
|
|
|
+ "\"clientSecret\": \"" + clientSecret + "\","
|
|
|
|
|
+ "},"
|
|
|
|
|
+ "\"body\": {"
|
|
|
|
|
+ "\"thirdDepartId\": \"3040000\","
|
|
|
|
|
+ "\"departName\": \"病案室\","
|
|
|
|
|
+ "\"departPhone\": \"" + user.getUserEmail() + "\","
|
|
|
|
|
+ "\"departPerson\": \"" + user.getUserPosition() + "\","
|
|
|
|
|
+ "\"clientOrgCode\": \"BAS\","
|
|
|
|
|
+ "\"clientOrgType\": \"ORG\""
|
|
|
|
|
+ "}"
|
|
|
|
|
+ "}";
|
|
|
|
|
|
|
|
|
|
// 创建RequestBody
|
|
|
|
|
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
|
|
|
|
|
|
|
|
|
|
// 创建Request
|
|
|
|
|
Request request = new Request.Builder()
|
|
|
|
|
.url(url)
|
|
|
|
|
.post(requestBody)
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 执行请求
|
|
|
|
|
Response response = client.newCall(request).execute();
|
|
|
|
|
|
|
|
|
|
// 检查响应状态码
|
|
|
|
|
if (response.isSuccessful()) {
|
|
|
|
|
// 获取响应体
|
|
|
|
|
String responseData = response.body().string();
|
|
|
|
|
|
|
|
|
|
// 解析JSON响应
|
|
|
|
|
JSONObject jsonResponse = new JSONObject(responseData);
|
|
|
|
|
|
|
|
|
|
// 获取返回的参数
|
|
|
|
|
dataId = jsonResponse.getJSONObject("data").getString("departId");
|
|
|
|
|
String message = jsonResponse.getString("message");
|
|
|
|
|
String status = jsonResponse.getString("status");
|
|
|
|
|
boolean successful = jsonResponse.getBoolean("successful");
|
|
|
|
|
|
|
|
|
|
// 输出解析结果
|
|
|
|
|
System.out.println("DepartId: " + dataId);
|
|
|
|
|
System.out.println("Message: " + message);
|
|
|
|
|
System.out.println("Status: " + status);
|
|
|
|
|
System.out.println("Successful: " + successful);
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("请求失败,状态码:" + response.code());
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
return dataId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -182,96 +363,4 @@ public class CaSignServiceImpl {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Description: caCopyFile方法是备份ca前文件
|
|
|
|
|
* @param: [pdfPath]
|
|
|
|
|
* @return: void
|
|
|
|
|
* @author 曾文和
|
|
|
|
|
* @createTime 2023/7/25 15:51
|
|
|
|
|
*/
|
|
|
|
|
private void caCopyFile(String pdfPath, String todayDate, String masterId) {
|
|
|
|
|
String newPath = caCopyPath + File.separator + todayDate + File.separator + masterId;
|
|
|
|
|
if (!new File(newPath).isDirectory()) {
|
|
|
|
|
new File(newPath).mkdirs();
|
|
|
|
|
}
|
|
|
|
|
String newSrc = newPath + File.separator + new File(pdfPath).getName();
|
|
|
|
|
try (InputStream inputStream = new FileInputStream(pdfPath);
|
|
|
|
|
OutputStream outputStream = new FileOutputStream(newSrc)) {
|
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
|
int bytesRead;
|
|
|
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
|
|
outputStream.write(buffer, 0, bytesRead);
|
|
|
|
|
}
|
|
|
|
|
System.out.println("文件拷贝完成");
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Description: caSign方法是根据pdf文件路径调用ca接口进行每页签章
|
|
|
|
|
* @param: [fileSrc]
|
|
|
|
|
* @return: void
|
|
|
|
|
* @author 曾文和
|
|
|
|
|
* @createTime 2023/7/25 10:30
|
|
|
|
|
*
|
|
|
|
|
* z:docus/caTemp/masterId/病案首页
|
|
|
|
|
*/
|
|
|
|
|
private boolean caSign(String newpdfPath, Archive_Detail_ca_reqParam caReqParam) throws Exception {
|
|
|
|
|
//定义是否成功
|
|
|
|
|
boolean flag = false;
|
|
|
|
|
PdfReader pdfReader = null;
|
|
|
|
|
try {
|
|
|
|
|
pdfReader = new PdfReader(newpdfPath);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
if (pdfReader != null) {
|
|
|
|
|
try {
|
|
|
|
|
anySignClientTool = new AnySignClientTool(caServerIp, caServerPort);
|
|
|
|
|
File file = new File(newpdfPath);
|
|
|
|
|
byte[] pdfBty = ClientUtil.readFileToByteArray(file);
|
|
|
|
|
//pdf验章
|
|
|
|
|
ChannelMessage messageExist = anySignClientTool.pdfVerify(pdfBty);
|
|
|
|
|
if (!StringUtils.isEmpty(messageExist.getStatusInfo()) && "pdf文档未签章".equals(messageExist.getStatusInfo())) {
|
|
|
|
|
RectangleBean bean = new RectangleBean();
|
|
|
|
|
int numberOfPages = pdfReader.getNumberOfPages();
|
|
|
|
|
for (int i = 0; i < numberOfPages; i++) {
|
|
|
|
|
if (i != 0) {
|
|
|
|
|
pdfBty = ClientUtil.readFileToByteArray(file);
|
|
|
|
|
}
|
|
|
|
|
bean.setPageNo(i + 1);
|
|
|
|
|
ChannelMessage message = null;
|
|
|
|
|
//获取pdf的高宽
|
|
|
|
|
Rectangle pageSize = pdfReader.getPageSizeWithRotation(i + 1);
|
|
|
|
|
// 获取页面的宽度和高度
|
|
|
|
|
float width = pageSize.getWidth();
|
|
|
|
|
float height = pageSize.getHeight();
|
|
|
|
|
// System.out.println("pdf尺寸:width:" + width + ",height:" + height);
|
|
|
|
|
bean.setLeft(Float.valueOf(width - caReqParam.getSignLeft()));
|
|
|
|
|
bean.setTop(Float.valueOf(caReqParam.getSignTop()));
|
|
|
|
|
bean.setRight(Float.valueOf(width));
|
|
|
|
|
bean.setBottom(Float.valueOf(caReqParam.getSignBottom()));
|
|
|
|
|
// System.out.println("左:" + bean.getLeft() + ",上:" + bean.getTop() + ",右:" + bean.getRight() + ",下:" + bean.getBottom());
|
|
|
|
|
message = anySignClientTool.pdfSignByParam(pdfBty, signNo, bean);
|
|
|
|
|
if ("200".equals(message.getStatusCode())) {//成功
|
|
|
|
|
ClientUtil.writeByteArrayToFile(new File(newpdfPath), message.getBody());
|
|
|
|
|
// System.out.println("签章成功");
|
|
|
|
|
} else {
|
|
|
|
|
String statusCode = message.getStatusCode();
|
|
|
|
|
String statusInfo = message.getStatusInfo();
|
|
|
|
|
log.error("statusCode=" + statusCode + ";statusInfo=" + statusInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
flag = true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
log.error("进行签章pdf:" + newpdfPath + "不存在或损坏");
|
|
|
|
|
}
|
|
|
|
|
System.out.println("完成");
|
|
|
|
|
return flag;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|