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 ids = resolveIds(form.getDayinJiluIds()); UserInfo user = identity.requireUser(); String tenantId = identity.tenantId(user); List prints = fenfaMapper.selectRecyclePrintsForUpdate(tenantId, ids); if (prints.size() != ids.size()) throw new DataException("存在不存在、已删除或跨租户的文件副本"); Map beforeStatuses = new LinkedHashMap<>(); Map> 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> 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 prepare(DmsWenjianGuidangForm form) throws DataException { if (form == null) throw new DataException("归档申请参数不能为空"); List ids = resolveIds(form.getDayinJiluIds()); String tenantId = identity.tenantId(); List prints = lockPrints(tenantId, ids, "daiguidang"); ensureNoConflict(tenantId, ids, blank(form.getShenqingId()) ? null : form.getShenqingId().trim()); return prints; } private List lockPrints(String tenantId, List ids, String expected) throws DataException { List 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 ids, String applicationId) throws DataException { if (!mapper.selectConflicts(tenantId, ids, applicationId).isEmpty()) throw new DataException("文件已存在有效归档申请,请处理原申请,勿重复发起"); } private List resolveIds(List values) throws DataException { if (values == null || values.isEmpty()) throw new DataException("请至少选择一条文件副本"); Set 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(); } }