feat(embed): 新增办件进度嵌入页签发端点与免签数据端点
build / build-push (push) Successful in 10m1s

This commit is contained in:
chenxing
2026-10-03 16:42:21 +08:00
parent 1d2f4a0cb2
commit d28b5d1161
6 changed files with 251 additions and 0 deletions
@@ -0,0 +1,64 @@
package com.yunhai.flowcenter.controller.open;
import com.yunhai.flowcenter.entity.FlwInstance;
import com.yunhai.flowcenter.model.FlowModels;
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
import com.yunhai.flowcenter.service.DiagramTokenService;
import com.yunhai.flowcenter.service.FlowQueryService;
import lombok.RequiredArgsConstructor;
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/embed/**,与图片流 /open/flow/diagram/img 同纪律)。
* <p>
* {@code <iframe src>} 进不了 /api(CAS)也进不了 /oapi(app-sign):免签资格由 10 分钟
* 短时 token 承担(与换图共用 DiagramTokenService 同一 token 池,token 由 app-sign 的
* GET /oapi/flow/embed/url 签发)。token 分发点之外,本端点不接受任何业务参数直接定位——
* 免签面收窄到"只认 token",定位与可见性全在签发侧(OapiFlowService.embedUrl)完成。
* 出参复用管理面办件详情 InstanceDetail 整体(viewerId=null,本人待办字段自然为空),
* 不新造 VO——嵌入页信息量与管理面一致,单点维护。
*/
@RestController
@RequestMapping("/open/flow/embed")
@RequiredArgsConstructor
public class OpenEmbedController {
private final DiagramTokenService tokenService;
private final FlowQueryService flowQueryService;
private final FlwInstanceRepository instanceRepository;
@GetMapping("/data")
public ResponseEntity<?> embedData(@RequestParam(value = "token", required = false) String token) {
DiagramTokenService.TokenEntry entry = tokenService.resolve(token);
if (entry == null) {
return notFound("链接已过期,请重新打开");
}
// 办件口径收窄:defId 口径的换图 token(flowGuid 预览)没有办件,不在此消费
if (entry.getInstanceId() == null) {
return notFound("链接已过期,请重新打开");
}
// token 已收 schId,出数据前再二次比对防漂移(同图片流口径,token 无法跨校探数据)
FlwInstance instance = instanceRepository.findById(entry.getInstanceId()).orElse(null);
if (instance == null || !entry.getSchId().equals(instance.getSchId())) {
return notFound("办件不存在");
}
FlowModels.InstanceDetail detail =
flowQueryService.detail(entry.getSchId(), entry.getInstanceId(), null);
return ResponseEntity.ok()
.cacheControl(org.springframework.http.CacheControl.noStore())
.body(detail);
}
private ResponseEntity<String> notFound(String msg) {
// 显式 UTF-8:text/plain 缺 charset 时浏览器/客户端按 ISO-8859-1 解码中文必乱码
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.contentType(new MediaType("text", "plain", java.nio.charset.StandardCharsets.UTF_8))
.body(msg);
}
}