刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package jnpf.dmsService;
 
import jnpf.audit.sdk.annotation.AuditLog;
import jnpf.base.ActionResultCode;
import jnpf.dmsEntity.storage.DmsTemplateNotification;
import jnpf.dmsMapper.DmsTemplateNotificationMapper;
import jnpf.exception.DataException;
import jnpf.message.SentMessageApi;
import jnpf.message.model.DmsUpgradeMessage;
import jnpf.util.JsonUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.*;
 
/** 与文件登记重试独立;通知重试每次查询模板最新部门,远端按事件/用户幂等落站内信。 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DmsTemplateNotificationService {
    private final DmsTemplateNotificationMapper mapper;
    private final SentMessageApi messages;
 
    @Scheduled(cron = "${dms.template-upgrade-notification.cron:0 * * * * ?}")
    @AuditLog(action = "DMS_TEMPLATE_UPGRADE_NOTIFY", bizCodeExpr = "''", recordSuccess = false)
    public void recover() {
        mapper.discover();
        for (DmsTemplateNotification event : mapper.pending()) deliver(event);
    }
 
    /** 工作流回调即时尝试;失败只留通知重试,不阻塞已有文件登记。 */
    public void approved(String tenant, String task) {
        try {
            mapper.discover();
            DmsTemplateNotification event = mapper.find(tenant, task);
            if (event != null) deliver(event);
        } catch (RuntimeException failure) {
            log.error("升版通知待自动恢复 tenant={} task={}", tenant, task, failure);
        }
    }
 
    void deliver(DmsTemplateNotification event) {
        String token = UUID.randomUUID().toString();
        if (mapper.claim(event, token) != 1) return;
        try {
            Map<String,Object> template = mapper.template(event.getTenantId(), event.getTemplateId());
            if (template == null) throw new DataException("来源模板不存在或已删除");
            List<String> departments = departmentIds(template.get("departments"));
            List<String> users = departments.isEmpty() ? List.of() : mapper.recipients(event.getTenantId(), departments);
            if (!users.isEmpty()) {
                DmsUpgradeMessage request = new DmsUpgradeMessage();
                request.setTenantId(event.getTenantId()); request.setTaskId(event.getTaskId());
                request.setActorId(event.getActorId()); request.setToUserIds(users);
                Map<String,String> parameters = new LinkedHashMap<>();
                parameters.put("DocumentNo", Objects.toString(event.getDocumentNo(), ""));
                parameters.put("DocumentName", Objects.toString(event.getDocumentName(), ""));
                parameters.put("Version", Objects.toString(event.getVersionLabel(), ""));
                parameters.put("TemplateName", Objects.toString(template.get("name"), ""));
                request.setParameters(parameters);
                var result = messages.sendDmsUpgrade(request);
                if (result == null || !ActionResultCode.SUCCESS.getCode().equals(result.getCode())
                        || !Boolean.TRUE.equals(result.getData())) throw new DataException("站内信未返回持久化成功确认");
            }
            if (mapper.finish(event, token, null, users.isEmpty() ? "NO_RECIPIENTS" : "SENT") != 1)
                throw new DataException("通知执行租约已变化");
        } catch (RuntimeException failure) {
            String error = Objects.toString(failure.getMessage(), failure.getClass().getSimpleName());
            mapper.finish(event, token, error.substring(0, Math.min(error.length(), 1000)), "RETRY");
            log.error("升版模板部门通知失败,保留任务待重试 tenant={} task={}", event.getTenantId(), event.getTaskId(), failure);
        }
    }
 
    static List<String> departmentIds(Object value) {
        if (value == null || value instanceof String && ((String) value).isBlank()) return List.of();
        Object parsed = value instanceof String ? JsonUtil.getJsonToBean((String) value, List.class) : value;
        if (!(parsed instanceof List<?>)) throw new DataException("模板提醒部门配置不是数组");
        Set<String> result = new LinkedHashSet<>();
        for (Object id : (List<?>) parsed) {
            if (!(id instanceof String) || ((String) id).isBlank()) throw new DataException("模板提醒部门ID无效");
            result.add((String) id);
        }
        return new ArrayList<>(result);
    }
}