刘光辉
3 小时以前 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
86
87
88
89
90
91
92
93
94
95
96
package jnpf.dmsService;
 
import jnpf.audit.sdk.annotation.AuditLog;
import jnpf.base.UserInfo;
import jnpf.dmsEntity.fenfa.DmsWenjianDayinJiluEntity;
import jnpf.dmsEntity.fenfa.form.DmsWenjianGuidangForm;
import jnpf.dmsEntity.fenfa.vo.DmsWenjianHuishouMingxiVO;
import jnpf.dmsMapper.DmsWenjianFenfaMapper;
import jnpf.dmsMapper.DmsWenjianGuidangMapper;
import jnpf.dmsPermission.DmsCurrentIdentity;
import jnpf.exception.DataException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.*;
 
/** 复用档案存档申请及接收,文件副本状态始终以打印记录为准。 */
@Service
@RequiredArgsConstructor
public class DmsWenjianGuidangService {
    private final DmsCurrentIdentity identity;
    private final DmsWenjianChongdaGuard reprintGuard;
    private final DmsWenjianFenfaMapper fenfaMapper;
    private final DmsWenjianGuidangMapper mapper;
 
    @Transactional(rollbackFor = Exception.class)
    @AuditLog(action = "FILE_ARCHIVE_CONFIRM", label = "文件确认归档", bizModule = "文件归档",
            bizType = "DMS_FILE_ARCHIVE", bizCodeExpr = "", bizCodeRequired = false,
            targetTable = "dms_wenjian_dayin_jilu", targetIdsExpr = "#p0.dayinJiluIds",
            targetIdExpr = "#p0.dayinJiluIds[0]", reasonExpr = "#p0.beizhuShuoming",
            extraExpr = "{'dayin_jilu_ids': #p0.dayinJiluIds, 'before_statuses': #p0.beforeStatuses, 'after_status': 'daiguidang'}",
            diff = false, entityClass = DmsWenjianDayinJiluEntity.class)
    public int confirm(DmsWenjianGuidangForm form) throws DataException {
        if (form == null || blank(form.getBizSign())) throw new DataException("确认归档签名不能为空");
        List<String> ids = resolveIds(form.getDayinJiluIds());
        UserInfo user = identity.requireUser();
        String tenantId = identity.tenantId(user);
        List<DmsWenjianHuishouMingxiVO> prints = fenfaMapper.selectRecyclePrintsForUpdate(tenantId, ids);
        if (prints.size() != ids.size()) throw new DataException("存在不存在、已删除或跨租户的文件副本");
        Map<String, String> beforeStatuses = new LinkedHashMap<>();
        Map<String, List<String>> byStatus = new TreeMap<>();
        for (DmsWenjianHuishouMingxiVO print : prints) {
            DmsWenjianHuishouPolicy.requireEligible(print);
            reprintGuard.requireUnlocked(tenantId, print.getDayinJiluId());
            beforeStatuses.put(print.getDayinJiluId(), print.getBizStatus());
            byStatus.computeIfAbsent(print.getBizStatus(), key -> new ArrayList<>()).add(print.getDayinJiluId());
        }
        form.setBeforeStatuses(beforeStatuses);
        Date now = new Date();
        int count = 0;
        for (Map.Entry<String, List<String>> group : byStatus.entrySet()) {
            int updated = mapper.changeStatus(tenantId, group.getValue(), group.getKey(), "daiguidang", user.getUserId(), now);
            if (updated != group.getValue().size()) throw new DataException("文件状态已变化,请刷新后重试");
            count += updated;
        }
        DmsWenjianHuishouPolicy.completeDistributions(fenfaMapper, tenantId, prints, user.getUserId(), now);
        return count;
    }
 
    /** 发起申请前返回服务端可信的名称、编号、版本和流水号。 */
    @Transactional(rollbackFor = Exception.class)
    public List<DmsWenjianHuishouMingxiVO> prepare(DmsWenjianGuidangForm form) throws DataException {
        if (form == null) throw new DataException("归档申请参数不能为空");
        List<String> ids = resolveIds(form.getDayinJiluIds());
        String tenantId = identity.tenantId();
        List<DmsWenjianHuishouMingxiVO> prints = lockPrints(tenantId, ids, "daiguidang");
        ensureNoConflict(tenantId, ids, blank(form.getShenqingId()) ? null : form.getShenqingId().trim());
        return prints;
    }
 
    private List<DmsWenjianHuishouMingxiVO> lockPrints(String tenantId, List<String> ids, String expected)
            throws DataException {
        List<DmsWenjianHuishouMingxiVO> prints = fenfaMapper.selectRecyclePrintsForUpdate(tenantId, ids);
        if (prints.size() != ids.size()) throw new DataException("存在不存在、已删除或跨租户的文件副本");
        for (DmsWenjianHuishouMingxiVO print : prints)
            if (!expected.equals(print.getBizStatus())) throw new DataException("文件状态不允许本次归档操作:" + print.getDayinLiushuihao());
        return prints;
    }
 
    private void ensureNoConflict(String tenantId, List<String> ids, String applicationId) throws DataException {
        if (!mapper.selectConflicts(tenantId, ids, applicationId).isEmpty())
            throw new DataException("文件已存在有效归档申请,请处理原申请,勿重复发起");
    }
 
    private List<String> resolveIds(List<String> values) throws DataException {
        if (values == null || values.isEmpty()) throw new DataException("请至少选择一条文件副本");
        Set<String> ids = new TreeSet<>();
        for (String id : values) {
            if (blank(id) || !ids.add(id.trim())) throw new DataException("文件副本ID不能为空或重复");
        }
        return new ArrayList<>(ids);
    }
 
    private boolean blank(String value) { return value == null || value.trim().isEmpty(); }
}