package jnpf.bizcommon.onlyoffice.service.impl; import cn.hutool.crypto.digest.DigestUtil; import jnpf.exception.DataException; import lombok.RequiredArgsConstructor; import org.redisson.api.RBucket; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** 跨实例保存响应丢失后的冻结取消意图,阻止迟到请求重新取得 fence。 */ @Component @RequiredArgsConstructor class OnlyOfficeFreezeCancellationStore { private static final String KEY_PREFIX = "jnpf:onlyoffice:record-freeze-cancel:"; private static final long RETENTION_DAYS = 7L; private final RedissonClient redissonClient; void cancel(String tenantId, String recordId, String fileId, String fileType, String token) { try { bucket(tenantId, recordId, fileId, fileType, token) .set("1", RETENTION_DAYS, TimeUnit.DAYS); } catch (RuntimeException e) { throw new DataException("记录冻结取消状态写入失败,已拒绝继续处理"); } } boolean isCancelled(String tenantId, String recordId, String fileId, String fileType, String token) { try { return bucket(tenantId, recordId, fileId, fileType, token).get() != null; } catch (RuntimeException e) { throw new DataException("记录冻结取消状态读取失败,已拒绝继续处理"); } } private RBucket bucket(String tenantId, String recordId, String fileId, String fileType, String token) { String identity = tenantId + '\u001f' + recordId + '\u001f' + fileId + '\u001f' + fileType + '\u001f' + token; return redissonClient.getBucket(KEY_PREFIX + DigestUtil.sha256Hex(identity)); } }