79 lines
3.7 KiB
Java
79 lines
3.7 KiB
Java
package com.yunhai.flowcenter.controller.open;
|
||
|
||
import com.yunhai.flowcenter.entity.FlwInstance;
|
||
import com.yunhai.flowcenter.model.FlowModels;
|
||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||
import com.yunhai.flowcenter.service.DiagramImageService;
|
||
import com.yunhai.flowcenter.service.DiagramTokenService;
|
||
import com.yunhai.flowcenter.service.FlowDiagramService;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.http.HttpStatus;
|
||
import org.springframework.http.MediaType;
|
||
import org.springframework.http.ResponseEntity;
|
||
import org.springframework.web.bind.annotation.GetMapping;
|
||
import org.springframework.web.bind.annotation.RequestMapping;
|
||
import org.springframework.web.bind.annotation.RequestParam;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
/**
|
||
* 免签图片流端点(/open/flow/**,用户拍板 2026-09-16,"CAS 验证码式"嵌入)。
|
||
* <p>
|
||
* 故意不落 /api/**(CAS 会话)也不落 /oapi/**(app-sign):<img src> 两者都带不了鉴权头;
|
||
* 免签资格由 10 分钟短时 token 承担(DiagramTokenService,token 由 app-sign 的
|
||
* GET /oapi/flow/diagram/url 签发)。token 分发点之外,本端点不接受任何业务参数直接定位——
|
||
* 免签面收窄到"只认 token",定位与可见性全在签发侧(OapiFlowService.diagramUrl)完成。
|
||
*/
|
||
@Slf4j
|
||
@RestController
|
||
@RequestMapping("/open/flow")
|
||
@RequiredArgsConstructor
|
||
public class OpenDiagramImageController {
|
||
|
||
private final DiagramTokenService tokenService;
|
||
private final DiagramImageService imageService;
|
||
private final FlwInstanceRepository instanceRepository;
|
||
private final FlwDefRepository defRepository;
|
||
private final FlowDiagramService diagramService;
|
||
|
||
@GetMapping("/diagram/img")
|
||
public ResponseEntity<byte[]> diagramImg(@RequestParam("token") String token) {
|
||
DiagramTokenService.TokenEntry entry = tokenService.resolve(token);
|
||
if (entry == null) {
|
||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||
.contentType(MediaType.TEXT_PLAIN)
|
||
.body("流程图已过期,请刷新页面重新获取".getBytes());
|
||
}
|
||
// 办件口径:节点带运行时状态(token 已收 schId,出图前再二次比对防漂移)
|
||
if (entry.getInstanceId() != null) {
|
||
FlwInstance instance = instanceRepository.findById(entry.getInstanceId()).orElse(null);
|
||
if (instance == null || !entry.getSchId().equals(instance.getSchId())) {
|
||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||
.contentType(MediaType.TEXT_PLAIN)
|
||
.body("办件不存在".getBytes());
|
||
}
|
||
return png(diagramService.byInstance(instance, entry.getMode()));
|
||
}
|
||
// 定义口径(flowGuid 预览)
|
||
return defRepository.findById(entry.getDefId())
|
||
.map(def -> entry.getSchId().equals(def.getSchId())
|
||
? png(diagramService.build(def, null, entry.getMode()))
|
||
: notFound("流程不存在"))
|
||
.orElseGet(() -> notFound("流程不存在"));
|
||
}
|
||
|
||
private ResponseEntity<byte[]> png(FlowModels.DiagramVo vo) {
|
||
return ResponseEntity.ok()
|
||
.contentType(MediaType.IMAGE_PNG)
|
||
.cacheControl(org.springframework.http.CacheControl.noStore())
|
||
.body(imageService.renderPng(vo));
|
||
}
|
||
|
||
private ResponseEntity<byte[]> notFound(String msg) {
|
||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||
.contentType(MediaType.TEXT_PLAIN)
|
||
.body(msg.getBytes());
|
||
}
|
||
}
|