| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package com.malk.huagao.controller;
- import org.springframework.core.io.UrlResource;
- import org.springframework.core.io.Resource;
- import com.alibaba.fastjson.JSON;
- import com.malk.huagao.service.EqbService;
- import com.malk.server.common.McR;
- import com.malk.utils.UtilMap;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.MediaType;
- import org.springframework.http.ResponseEntity;
- import org.springframework.web.bind.annotation.*;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
- import java.util.concurrent.TimeUnit;
- @Slf4j
- @RestController
- @RequestMapping("/eqb")
- public class HgEqbController {
- @Autowired
- private EqbService eqbService;
- @Value(value = "${eqb.downloadFilePath}")
- private String fileStoragePath;
- @PostMapping("/sign")
- public McR sign(@RequestBody Map map){
- eqbService.sign(map);
- return McR.success();
- }
- // 使用ConcurrentHashMap保证线程安全
- private final ConcurrentMap<String, Long> eventList = new ConcurrentHashMap<>();
- // 记录最后一次清理时间
- private volatile long lastCleanTime = System.currentTimeMillis();
- // 清理间隔时间(毫秒)
- private static final long CLEAN_INTERVAL = 60_000;
- @PostMapping("/callback")
- public McR callback(@RequestBody Map map){
- System.out.println(map);
- log.info("e签宝回调: {}", JSON.toJSONString(map));
- //签署回调通知:SIGN_MISSON_COMPLETE 事件订阅-签署流程完成:SIGN_FLOW_FINISH
- String action = UtilMap.getString(map, "action");
- String signFlowId = UtilMap.getString(map, "signFlowId");//e签宝签署流程id
- String info = action + "-" + signFlowId;
- // 定期清理过期记录
- cleanExpiredEvents();
- if (isCallbackProcessed(info)){
- log.info("info:{},重复回调,不做处理",info);
- }else {
- eventList.put(info, System.currentTimeMillis());
- //签署回调结束
- if ("SIGN_MISSON_COMPLETE".equals(action)) {
- int signResult = UtilMap.getInt(map, "signResult");//2 - 签署完成,4 - 拒签
- if (2 == signResult) {
- String processInstanceId = UtilMap.getString(map, "customBizNum");//宜搭审批实例id
- //自动同意审批节点
- eqbService.autoAgree(signFlowId,processInstanceId);
- }
- }
- }
- return McR.success();
- }
- @GetMapping("/files/{fileId}")
- public ResponseEntity<Resource> getFileResource(
- @PathVariable String fileId,
- @RequestParam(defaultValue = "download") String option) throws IOException {
- // 根据fileId获取实际文件路径,这里简化处理,实际可能需要从数据库查询
- Path filePath = Paths.get(fileStoragePath).resolve(fileId).normalize();
- // 检查文件是否存在
- if (!Files.exists(filePath)) {
- return ResponseEntity.notFound().build();
- }
- // 创建Resource对象
- Resource resource = new UrlResource(filePath.toUri());
- // 根据选项设置响应头
- HttpHeaders headers = new HttpHeaders();
- if ("preview".equalsIgnoreCase(option)) {
- // 预览模式 - 尝试确定内容类型
- String contentType = Files.probeContentType(filePath);
- // 强制修正 PDF 的 Content-Type
- if (filePath.toString().toLowerCase().endsWith(".pdf")) {
- contentType = "application/pdf";
- } else if (contentType == null) {
- contentType = "application/octet-stream";
- }
- headers.setContentType(MediaType.parseMediaType(contentType));
- headers.add("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
- headers.add("X-Content-Type-Options", "nosniff"); // 防止浏览器忽略 Content-Type
- } else {
- // 下载模式 - 默认处理
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
- headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
- }
- return ResponseEntity.ok()
- .headers(headers)
- .contentLength(resource.contentLength())
- .body(resource);
- }
- /**
- * 检查并清理过期事件
- */
- private void cleanExpiredEvents() {
- long currentTime = System.currentTimeMillis();
- // 只在达到清理间隔时执行清理
- if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
- synchronized (this) {
- // 双重检查,避免重复清理
- if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
- long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(1);
- eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
- lastCleanTime = currentTime;
- }
- }
- }
- }
- /**
- * 检查该回调事件在一分钟内是否处理过
- */
- private boolean isCallbackProcessed(String detail) {
- return eventList.containsKey(detail);
- }
- }
|