Explorar o código

合同关联代码调整

fuyuchuan hai 7 horas
pai
achega
be834dc538

+ 40 - 20
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppContractServiceImpl.java

@@ -26,6 +26,7 @@ import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.client.RestTemplate;
 
 import javax.servlet.ServletOutputStream;
@@ -62,6 +63,7 @@ public class VppContractServiceImpl implements VppContractService {
     private final RestTemplate restTemplate = new RestTemplate();
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean create(VppContractRequestVO vo) {
         if (StringUtils.isBlank(vo.getContractNo())) {
             throw new BusinessException("合同编号不能为空!");
@@ -69,11 +71,14 @@ public class VppContractServiceImpl implements VppContractService {
         VppContractTemplate template = getTemplateById(vo.getTemplateId());
         String contractNo = vo.getContractNo().trim();
         checkContractNoUnique(contractNo, null);
+        // 关联校验必须在入库前完成,避免失败后留下脏数据导致“合同编号已存在”
+        validateRelatedContract(null, vo.getRelatedContractId(), template);
 
         VppContract contract = new VppContract();
         contract.setContractNo(contractNo);
         contract.setCustomerId(vo.getCustomerId());
         contract.setTemplateId(vo.getTemplateId());
+        contract.setRelatedContractId(vo.getRelatedContractId());
         contract.setContractType(vo.getContractType());
         contract.setContractName(vo.getContractName());
         contract.setPartyA(vo.getPartyA());
@@ -93,13 +98,14 @@ public class VppContractServiceImpl implements VppContractService {
 
         VppAuditHelper.fillCreate(contract);
         int insert = vppContractMapper.insert(contract);
-        if (insert > 0) {
-            bindRelatedContract(contract, vo.getRelatedContractId(), template, null);
+        if (insert > 0 && vo.getRelatedContractId() != null) {
+            syncPeerRelated(contract.getId(), vo.getRelatedContractId(), null);
         }
         return insert > 0;
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean update(VppContractRequestVO vo) {
         if (vo.getId() == null) {
             throw new BusinessException("主键ID不能为空!");
@@ -177,11 +183,19 @@ public class VppContractServiceImpl implements VppContractService {
         existingRecord.setContractStatus(VppContractStatusHelper.resolveForPersist(
                 requestedStatus, existingRecord.getEffectiveDate(), existingRecord.getExpireDate()));
 
+        // 关联变更:入库前先校验;写入 relatedContractId 后同步对端
+        boolean relatedChanged = vo.getRelatedContractId() != null
+                && !Objects.equals(vo.getRelatedContractId(), previousRelatedId);
+        if (relatedChanged) {
+            VppContractTemplate template = getTemplateById(existingRecord.getTemplateId());
+            validateRelatedContract(existingRecord.getId(), vo.getRelatedContractId(), template);
+            existingRecord.setRelatedContractId(vo.getRelatedContractId());
+        }
+
         VppAuditHelper.fillUpdate(existingRecord);
         int result = vppContractMapper.updateById(existingRecord);
-        if (result > 0 && vo.getRelatedContractId() != null) {
-            VppContractTemplate template = getTemplateById(existingRecord.getTemplateId());
-            bindRelatedContract(existingRecord, vo.getRelatedContractId(), template, previousRelatedId);
+        if (result > 0 && relatedChanged) {
+            syncPeerRelated(existingRecord.getId(), vo.getRelatedContractId(), previousRelatedId);
         }
         return result > 0;
     }
@@ -445,14 +459,13 @@ public class VppContractServiceImpl implements VppContractService {
     }
 
     /**
-     * 居间/普通一对一双向关联
+     * 关联校验(入库前调用):跨类、一对一占用、不能关联自身
      */
-    private void bindRelatedContract(VppContract self, Long relatedId,
-                                     VppContractTemplate selfTemplate, Long previousRelatedId) {
+    private void validateRelatedContract(Long selfId, Long relatedId, VppContractTemplate selfTemplate) {
         if (relatedId == null) {
             return;
         }
-        if (self.getId() != null && relatedId.equals(self.getId())) {
+        if (selfId != null && relatedId.equals(selfId)) {
             throw new BusinessException("不能关联合同自身!");
         }
         if (selfTemplate == null || selfTemplate.getTemplateKind() == null) {
@@ -476,29 +489,36 @@ public class VppContractServiceImpl implements VppContractService {
             throw new BusinessException("仅允许居间合同与普通合同互相一对一关联!");
         }
 
-        // 目标合同已被其他合同占用
         if (related.getRelatedContractId() != null
-                && self.getId() != null
-                && !related.getRelatedContractId().equals(self.getId())) {
+                && (selfId == null || !related.getRelatedContractId().equals(selfId))) {
             throw new BusinessException("目标合同已被其他合同关联,请先解除原关联!");
         }
         Integer occupied = vppContractMapper.selectCount(new LambdaQueryWrapper<VppContract>()
                 .eq(VppContract::getRelatedContractId, relatedId)
                 .eq(VppContract::getDeleteFlag, 0)
-                .ne(self.getId() != null, VppContract::getId, self.getId()));
+                .ne(selfId != null, VppContract::getId, selfId));
         if (occupied != null && occupied > 0) {
             throw new BusinessException("目标合同已被其他合同关联,请先解除原关联!");
         }
+    }
 
+    /**
+     * 同步对端一对一关联(调用前须已完成 validateRelatedContract)
+     */
+    private void syncPeerRelated(Long selfId, Long relatedId, Long previousRelatedId) {
         if (previousRelatedId != null && !previousRelatedId.equals(relatedId)) {
-            clearRelatedLink(self.getId(), previousRelatedId);
+            clearRelatedLink(selfId, previousRelatedId);
         }
-
-        self.setRelatedContractId(relatedId);
-        VppAuditHelper.fillUpdate(self);
-        vppContractMapper.updateById(self);
-
-        related.setRelatedContractId(self.getId());
+        if (relatedId == null || selfId == null) {
+            return;
+        }
+        VppContract related = vppContractMapper.selectOne(new LambdaQueryWrapper<VppContract>()
+                .eq(VppContract::getId, relatedId)
+                .eq(VppContract::getDeleteFlag, 0));
+        if (related == null) {
+            throw new BusinessException("关联合同不存在或已被删除!");
+        }
+        related.setRelatedContractId(selfId);
         VppAuditHelper.fillUpdate(related);
         vppContractMapper.updateById(related);
     }