package jnpf.dmsService.impl; import jnpf.base.UserInfo; import jnpf.dmsEntity.DmsWenjianBanbenEntity; import jnpf.dmsEntity.DmsWenjianBianhaoEntity; import jnpf.dmsEntity.DmsWenjianGuanxiEntity; import jnpf.dmsEntity.DmsWenjianXinzengShenheEntity; import jnpf.dmsEntity.DmsWenjianXiudingShenheEntity; import jnpf.dmsEntity.DmsWenjianXiudingShenheJiluMingxiEntity; import jnpf.dmsEntity.DmsWenjianXiudingShenqingEntity; import jnpf.dmsEntity.DmsWenjianXiudingShenqingZixiangEntity; import jnpf.dmsEntity.banben.DmsWenjianBanbenJiesuanModel; import jnpf.dmsEntity.banben.vo.DmsWenjianBanbenQueryVO; import jnpf.dmsEntity.banben.vo.DmsWenjianZhongxinBanbenVO; import jnpf.dmsEntity.wenjianbianhao.DmsFlowEventType; import jnpf.dmsMapper.DmsWenjianBianhaoMapper; import jnpf.dmsMapper.DmsWenjianBanbenMapper; import jnpf.dmsMapper.DmsWenjianGuanlianMingxiMapper; import jnpf.dmsMapper.DmsWenjianGuanxiMapper; import jnpf.dmsMapper.DmsWenjianXinzengShenheJiluMingxiMapper; import jnpf.dmsMapper.DmsWenjianXinzengShenheMapper; import jnpf.dmsMapper.DmsWenjianXiudingShenheJiluMingxiMapper; import jnpf.dmsMapper.DmsWenjianXiudingShenheMapper; import jnpf.dmsMapper.DmsWenjianXiudingShenqingMapper; import jnpf.dmsMapper.DmsWenjianXiudingShenqingZixiangMapper; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.dmsService.DmsWenjianFenfaService; import jnpf.dmsService.DmsWenjianYewuBanbenService; import jnpf.exception.DataException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.Collections; import java.util.Date; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class DmsWenjianBanbenServiceImplTest { private static final String TENANT_ID = "tenant-1"; private static final String FLOW_ID = "flow-1"; private static final String TASK_ID = "task-1"; @Mock private jnpf.dmsService.DmsXiudingKanwuService revisionErrata; @Mock private DmsCurrentIdentity identity; @Mock private jnpf.dmsService.DmsBusinessLifecycleGuard businessOccupancy; @Mock private DmsWenjianBanbenMapper versionMapper; @Mock private DmsWenjianBianhaoMapper numberMapper; @Mock private DmsWenjianXinzengShenheMapper newAuditMapper; @Mock private DmsWenjianXinzengShenheJiluMingxiMapper newAuditRecordMapper; @Mock private DmsWenjianXiudingShenqingMapper revisionRequestMapper; @Mock private DmsWenjianXiudingShenqingZixiangMapper revisionDetailMapper; @Mock private DmsWenjianXiudingShenheMapper revisionAuditMapper; @Mock private DmsWenjianXiudingShenheJiluMingxiMapper revisionAuditRecordMapper; @Mock private DmsWenjianGuanlianMingxiMapper relatedDetailMapper; @Mock private DmsWenjianGuanxiMapper relationMapper; @Mock private DmsWenjianYewuBanbenService businessVersionService; @Mock private DmsWenjianFenfaService distributionService; @Mock private jnpf.dmsService.DmsApprovedFileProjection centerProjection; @Mock private jnpf.dmsMapper.DmsApprovedBatchMapper acceptanceMapper; @Mock private jnpf.dmsService.DmsApprovedAuditSource approvedSource; @org.mockito.Spy private jnpf.dmsService.DmsQianpiyeRenderSnapshotService qianpiyeSnapshots = new jnpf.dmsService.DmsQianpiyeRenderSnapshotService(null, null, null, null, new com.fasterxml.jackson.databind.ObjectMapper()); @InjectMocks private DmsWenjianBanbenServiceImpl service; @BeforeEach void setUpIdentity() { UserInfo user = new UserInfo(); user.setUserId("operator-1"); user.setTenantId(TENANT_ID); org.mockito.Mockito.lenient().when(identity.requireUser()).thenReturn(user); org.mockito.Mockito.lenient().when(identity.tenantId(user)).thenReturn(TENANT_ID); } @Test void getsFileCenterVersionIdFromBusinessVersion() throws Exception { DmsWenjianBanbenEntity version = new DmsWenjianBanbenEntity(); version.setWenjianZhongxinBanbenId("file-center-version-1"); when(versionMapper.selectById(TENANT_ID, "version-1")).thenReturn(version); DmsWenjianZhongxinBanbenVO result = service.getWenjianZhongxinBanben(" version-1 "); assertEquals("file-center-version-1", result.getWenjianZhongxinBanbenId()); verify(versionMapper).selectById(TENANT_ID, "version-1"); } @Test void getsVersionIdentifiersByFileAndVersionLabel() throws Exception { DmsWenjianBanbenEntity version = new DmsWenjianBanbenEntity(); version.setId("version-1"); version.setWenjianZhongxinBanbenId("file-center-version-1"); version.setWenjianZhongxinWenjianId("file-center-file-1"); when(versionMapper.selectByFileAndVersionLabel(TENANT_ID, "file-1", "D(01)")) .thenReturn(version); DmsWenjianBanbenQueryVO result = service.getByWenjianIdAndBanbenhao( " file-1 ", " D(01) "); assertEquals("version-1", result.getId()); assertEquals("file-center-version-1", result.getWenjianZhongxinBanbenId()); assertEquals("file-center-file-1", result.getWenjianZhongxinWenjianId()); verify(versionMapper).selectByFileAndVersionLabel(TENANT_ID, "file-1", "D(01)"); } @Test void rejectsMissingFileAndVersionLabelMatch() { when(versionMapper.selectByFileAndVersionLabel(TENANT_ID, "file-1", "D(99)")) .thenReturn(null); DataException exception = assertThrows(DataException.class, () -> service.getByWenjianIdAndBanbenhao("file-1", "D(99)")); assertEquals("未找到对应的业务文件版本", exception.getMessage()); } @Test void newAuditCreatesUnifiedInitialVersionAndWritesStableIds() throws Exception { DmsWenjianXinzengShenheEntity audit = newAudit(); DmsWenjianBianhaoEntity number = number(); DmsWenjianBanbenEntity version = version("file-1", "version-1", null, 0, "[]"); when(newAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID)) .thenReturn(Collections.singletonList(audit)); when(numberMapper.selectActiveByIdForUpdate(TENANT_ID, "number-1")).thenReturn(number); when(businessVersionService.createInitialVersion(any())).thenReturn(version); when(newAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); applyApproved("xinzeng_shenhe"); ArgumentCaptor captor = ArgumentCaptor.forClass(DmsWenjianBanbenJiesuanModel.class); verify(businessVersionService).createInitialVersion(captor.capture()); assertEquals("number-1", captor.getValue().getWenjianBianhaoId()); assertEquals("DOC-001", captor.getValue().getWenjianBianhao()); assertEquals("zhuwenjian", captor.getValue().getWenjianLeixing()); assertEquals("file-1", audit.getWenjianId()); assertEquals("version-1", audit.getShengxiaoWenjianBanbenId()); verify(distributionService).ensureNewPrintTasks( TENANT_ID, "new-audit-1", "file-1", "operator-1"); } @Test void revisionUpgradeUsesSourceVersionIdAndCreatesVersionRow() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("shengji", "new-content"); audit.setWenjianId("file-1"); audit.setYuanWenjianBanbenId("version-1"); DmsWenjianXiudingShenqingZixiangEntity detail = revisionDetail(); DmsWenjianBanbenEntity version = version( "file-1", "version-2", "version-1", 2, "new-content"); arrangeRevision(audit, detail); when(businessVersionService.createRevisionVersion(any())).thenReturn(version); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective( TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); applyApproved("xiuding_shenhe"); ArgumentCaptor captor = ArgumentCaptor.forClass(DmsWenjianBanbenJiesuanModel.class); verify(businessVersionService).createRevisionVersion(captor.capture()); assertEquals("version-1", captor.getValue().getYuanWenjianBanbenId()); assertEquals("file-1", captor.getValue().getWenjianId()); assertEquals("version-2", audit.getShengxiaoWenjianBanbenId()); org.mockito.InOrder order = org.mockito.Mockito.inOrder(revisionDetailMapper, revisionErrata, acceptanceMapper,businessOccupancy); order.verify(revisionDetailMapper).markEffective(TENANT_ID, "revision-zixiang-1", "revision-audit-1"); order.verify(revisionErrata).complete(eq(TENANT_ID), eq("revision-audit-1"), anyList()); order.verify(acceptanceMapper).applied(eq(TENANT_ID), any()); order.verify(businessOccupancy).completeExecution(anyList()); } @Test void unchangedMainReusesCurrentVersionWithoutCreatingVersion() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("wubianhua", "old-content"); DmsWenjianXiudingShenqingZixiangEntity detail = revisionDetail(); DmsWenjianBanbenEntity current = version( "file-1", "version-1", null, 1, "old-content"); arrangeRevision(audit, detail); when(businessVersionService.reuseCurrentVersion( TENANT_ID, "file-1", "version-1")).thenReturn(current); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective( TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); applyApproved("xiuding_shenhe"); verify(businessVersionService, never()).createRevisionVersion(any()); assertEquals("version-1", audit.getShengxiaoWenjianBanbenId()); } @Test void removalWithoutFrozenApprovalIsRejected() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("wubianhua", "old-content"); DmsWenjianXiudingShenqingZixiangEntity detail = revisionDetail(); arrangeRevision(audit, detail); when(businessVersionService.reuseCurrentVersion( TENANT_ID, "file-1", "version-1")) .thenReturn(version("file-1", "version-1", null, 1, "old-content")); DmsWenjianGuanxiEntity relation = new DmsWenjianGuanxiEntity(); relation.setGuanlianWenjianId("record-file-1"); when(relationMapper.selectEffectiveByMainAndType(TENANT_ID, "file-1", "jilu")) .thenReturn(Collections.singletonList(relation)); DataException exception = assertThrows(DataException.class, () -> applyApproved("xiuding_shenhe")); assertEquals("记录归属已变化,存在未经批准移除的记录", exception.getMessage()); verify(revisionAuditMapper, never()).updateEffectiveVersion(any()); } @Test void approvedRemovalSettlesFrozenRecordWithoutDeletingContent() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("wubianhua", "old-content"); arrangeRevision(audit, revisionDetail()); when(businessVersionService.reuseCurrentVersion(TENANT_ID, "file-1", "version-1")) .thenReturn(version("file-1", "version-1", null, 1, "old-content")); jnpf.dmsEntity.storage.approval.DmsApprovedItem removed = new jnpf.dmsEntity.storage.approval.DmsApprovedItem(); removed.setChangeType("RETIRE"); removed.setFileId("record-file-1"); removed.setBusinessVersionId("record-version-1"); when(acceptanceMapper.items(org.mockito.ArgumentMatchers.eq(TENANT_ID), any())) .thenReturn(Collections.singletonList(removed)); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective(TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); applyApproved("xiuding_shenhe"); verify(businessVersionService).retireRecord(TENANT_ID, "file-1", "record-file-1", "record-version-1", "operator-1"); verify(businessVersionService, never()).createRevisionVersion(any()); } @Test void recordUpgradeSettlesItsOwnVersionWithoutUpgradingMain() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("wubianhua", "old-content"); DmsWenjianXiudingShenqingZixiangEntity detail = revisionDetail(); arrangeRevision(audit, detail); when(businessVersionService.reuseCurrentVersion( TENANT_ID, "file-1", "version-1")) .thenReturn(version("file-1", "version-1", null, 1, "old-content")); DmsWenjianXiudingShenheJiluMingxiEntity record = new DmsWenjianXiudingShenheJiluMingxiEntity(); record.setId("record-row-1"); record.setTenantId(TENANT_ID); record.setWenjianMuluId("folder-1"); record.setBiangengFangshi("shengji"); record.setJiluWenjianId("record-file-1"); record.setYuanWenjianBanbenId("record-version-1"); record.setJiluWenjian("record-new-content"); when(revisionAuditRecordMapper.selectByAuditForUpdate( TENANT_ID, "revision-audit-1")) .thenReturn(Collections.singletonList(record)); when(businessVersionService.createRevisionVersion(any())) .thenReturn(version( "record-file-1", "record-version-2", "record-version-1", 2, "record-new-content")); when(revisionAuditRecordMapper.updateSettlement(record)).thenReturn(1); DmsWenjianGuanxiEntity relation = new DmsWenjianGuanxiEntity(); relation.setGuanlianWenjianId("record-file-1"); when(relationMapper.selectEffectiveByMainAndType(TENANT_ID, "file-1", "jilu")) .thenReturn(Collections.singletonList(relation)); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective( TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); applyApproved("xiuding_shenhe"); assertEquals("record-version-2", record.getShengxiaoWenjianBanbenId()); verify(businessVersionService).reuseCurrentVersion( TENANT_ID, "file-1", "version-1"); verify(businessVersionService).createRevisionVersion(any()); } @Test void recordReuseSynchronizesModeWithoutUpgradingEitherAttachment() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("wubianhua", "old-content"); DmsWenjianXiudingShenqingZixiangEntity detail = revisionDetail(); arrangeRevision(audit, detail); when(businessVersionService.reuseCurrentVersion( TENANT_ID, "file-1", "version-1")) .thenReturn(version("file-1", "version-1", null, 1, "old-content")); DmsWenjianXiudingShenheJiluMingxiEntity record = new DmsWenjianXiudingShenheJiluMingxiEntity(); record.setId("record-row-1"); record.setTenantId(TENANT_ID); record.setWenjianMuluId("folder-1"); record.setBiangengFangshi("wubianhua"); record.setShifouShoukong("yes"); record.setFujianMingcheng("updated record"); record.setGuishuBumenId("department"); record.setJiluWenjianId("record-file-1"); record.setYuanWenjianBanbenId("record-version-1"); record.setJiluWenjian(attachment("record-original-content")); when(revisionAuditRecordMapper.selectByAuditForUpdate( TENANT_ID, "revision-audit-1")) .thenReturn(Collections.singletonList(record)); var original=version("record-file-1","record-version-1",null,0,"record-original-content"); original.setWenjianZhongxinBanbenId("center-record"); when(businessVersionService.reuseCurrentVersion(TENANT_ID,"record-file-1","record-version-1")).thenReturn(original); when(businessVersionService.updateReusedRecordMetadata(any())).thenReturn(original); when(revisionAuditRecordMapper.updateSettlement(record)).thenReturn(1); DmsWenjianGuanxiEntity relation = new DmsWenjianGuanxiEntity(); relation.setGuanlianWenjianId("record-file-1"); when(relationMapper.selectEffectiveByMainAndType(TENANT_ID, "file-1", "jilu")) .thenReturn(Collections.singletonList(relation)); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective( TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); applyApproved("xiuding_shenhe"); assertEquals("record-version-1", record.getShengxiaoWenjianBanbenId()); verify(businessVersionService).reuseCurrentVersion( TENANT_ID, "file-1", "version-1"); var captor=org.mockito.ArgumentCaptor.forClass(DmsWenjianBanbenJiesuanModel.class); verify(businessVersionService).updateReusedRecordMetadata(captor.capture()); assertEquals("yes",captor.getValue().getShifouShoukong()); assertEquals("updated record",captor.getValue().getWenjianMingcheng()); assertEquals("center-record",captor.getValue().getCenterVersionId()); verify(businessVersionService,never()).createRevisionVersion(any()); } @Test void incompleteTrainingBlocksRevisionSettlement() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("shengji", "new-content"); audit.setShifouPeixun("peixun"); arrangeRevision(audit, revisionDetail()); DataException exception = assertThrows(DataException.class, () -> applyApproved("xiuding_shenhe")); assertEquals("文件培训尚未完成,不能生效", exception.getMessage()); verify(businessVersionService, never()).createRevisionVersion(any()); verify(revisionAuditMapper, never()).updateEffectiveVersion(any()); } @Test void changedSourceWithApprovalPageDoesNotWriteBusinessVersions() { DataException error = assertThrows(DataException.class, () -> applyApproved("xinzeng_shenhe", "changed-content")); assertEquals("批准内容发生变化,停止业务回写", error.getMessage()); verify(businessVersionService, never()).createInitialVersion(any()); verify(acceptanceMapper, never()).applied(any(), any()); } @Test void errataFailurePreventsAppliedReceipt() throws Exception { DmsWenjianXiudingShenheEntity audit = revisionAudit("shengji", "new-content"); audit.setWenjianId("file-1"); audit.setYuanWenjianBanbenId("version-1"); arrangeRevision(audit, revisionDetail()); when(businessVersionService.createRevisionVersion(any())).thenReturn(version("file-1", "version-2", "version-1", 2, "new-content")); when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1); when(revisionDetailMapper.markEffective(TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); org.mockito.Mockito.doThrow(new DataException("closure failed")).when(revisionErrata).complete(any(), any(), anyList()); assertThrows(DataException.class, () -> applyApproved("xiuding_shenhe")); verify(acceptanceMapper, never()).applied(any(), any()); } @Test void inactiveAndAlreadyAppliedReceiptsNeverCloseErrata() { jnpf.dmsEntity.storage.approval.DmsApprovedBatch receipt = new jnpf.dmsEntity.storage.approval.DmsApprovedBatch(); receipt.setId(java.util.UUID.randomUUID()); receipt.setTenantId(TENANT_ID); when(acceptanceMapper.lock(TENANT_ID, receipt.getId())).thenReturn(receipt); for (String state : java.util.List.of("STAGED", "APPROVED", "FAILED")) { receipt.setStatus(state); assertThrows(DataException.class, () -> service.applyApproved(receipt)); } receipt.setStatus("APPLIED"); service.applyApproved(receipt); org.mockito.Mockito.verifyNoInteractions(revisionErrata, approvedSource); } private void applyApproved(String type) { applyApproved(type, "original-content"); } private void applyApproved(String type, String currentDigest) { jnpf.dmsEntity.storage.approval.DmsApprovedBatch receipt = new jnpf.dmsEntity.storage.approval.DmsApprovedBatch(); receipt.setId(java.util.UUID.randomUUID()); receipt.setTenantId(TENANT_ID); receipt.setTaskId(TASK_ID); receipt.setFlowId(FLOW_ID); receipt.setAuditType(type); receipt.setAuditId("revision-audit-1"); receipt.setActorId("operator-1"); receipt.setStatus("EFFECTIVE"); receipt.setActivatedAt(new Date()); jnpf.dmsEntity.storage.approval.DmsApprovedItem main = new jnpf.dmsEntity.storage.approval.DmsApprovedItem(); main.setSourceKey(type + ":audit:zhuwenjian"); main.setChangeType("CREATE"); main.setApprovalPageFileJson("[{\"fileId\":\"page.docx\"}]"); receipt.setItems(Collections.singletonList(main)); receipt.setSourceDigest("original-content"); String snapshot = "{\"protocolVersion\":1,\"taskId\":\"" + TASK_ID + "\",\"flowId\":\"" + FLOW_ID + "\",\"valuesByTag\":{\"dms.qianpiye.flow.approve-1.approver\":\"审核人\"}}"; qianpiyeSnapshots.attach(receipt, snapshot, "creator", new Date()); jnpf.dmsEntity.storage.approval.DmsApprovedBatch currentSource = new jnpf.dmsEntity.storage.approval.DmsApprovedBatch(); currentSource.setTaskId(TASK_ID); currentSource.setFlowId(FLOW_ID); currentSource.setSourceDigest(currentDigest); currentSource.setItems(Collections.singletonList(main)); when(acceptanceMapper.lock(TENANT_ID, receipt.getId())).thenReturn(receipt); org.mockito.Mockito.lenient().when(acceptanceMapper.find(any(), any(), any())).thenReturn(receipt); when(approvedSource.load(TENANT_ID, FLOW_ID, TASK_ID, type, "operator-1", null)) .thenReturn(new jnpf.dmsService.DmsApprovedAuditSource.Source(currentSource, "creator", new Date(), false)); org.mockito.Mockito.lenient().when(acceptanceMapper.applied(TENANT_ID, receipt.getId())).thenReturn(1); service.applyApproved(receipt); } private void arrangeRevision(DmsWenjianXiudingShenheEntity audit, DmsWenjianXiudingShenqingZixiangEntity detail) { DmsWenjianXiudingShenqingEntity request = new DmsWenjianXiudingShenqingEntity(); request.setId("revision-request-1"); request.setFlowState(2); when(revisionAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID)) .thenReturn(Collections.singletonList(audit)); when(revisionRequestMapper.selectByIdForUpdate(TENANT_ID, "revision-request-1")) .thenReturn(request); when(revisionDetailMapper.selectByIdForUpdate(TENANT_ID, "revision-zixiang-1")) .thenReturn(detail); when(revisionDetailMapper.claim( TENANT_ID, "revision-zixiang-1", "revision-audit-1")).thenReturn(1); } private DmsWenjianXinzengShenheEntity newAudit() { DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity(); audit.setId("new-audit-1"); audit.setTenantId(TENANT_ID); audit.setWenjianMuluId("folder-1"); audit.setFlowState(2); audit.setWenjianBianhaoId("number-1"); audit.setWenjianMingcheng("SOP文件"); audit.setWenjian("[]"); audit.setShifouPeixun("buPeixun"); return audit; } private DmsWenjianBianhaoEntity number() { DmsWenjianBianhaoEntity number = new DmsWenjianBianhaoEntity(); number.setId("number-1"); number.setWenjianBianhao("DOC-001"); number.setDangqianWenjianMingcheng("SOP文件"); number.setBizStatus("using"); return number; } private DmsWenjianXiudingShenheEntity revisionAudit(String changeType, String content) { DmsWenjianXiudingShenheEntity audit = new DmsWenjianXiudingShenheEntity(); audit.setId("revision-audit-1"); audit.setTenantId(TENANT_ID); audit.setWenjianMuluId("folder-1"); audit.setFlowState(2); audit.setXiudingShenqingZixiangId("revision-zixiang-1"); audit.setBiangengFangshi(changeType); audit.setWenjian(attachment(content)); audit.setShifouPeixun("buPeixun"); return audit; } private DmsWenjianXiudingShenqingZixiangEntity revisionDetail() { DmsWenjianXiudingShenqingZixiangEntity detail = new DmsWenjianXiudingShenqingZixiangEntity(); detail.setId("revision-zixiang-1"); detail.setForeignId("revision-request-1"); detail.setWenjianId("file-1"); detail.setYuanWenjianBanbenId("version-1"); detail.setBizStatus("available"); return detail; } private DmsWenjianBanbenEntity version(String fileId, String versionId, String sourceVersionId, int sequence, String content) { DmsWenjianBanbenEntity version = new DmsWenjianBanbenEntity(); version.setId(versionId); version.setWenjianId(fileId); version.setYuanWenjianBanbenId(sourceVersionId); version.setBanbenXuhao(sequence); version.setBanbenhao(DmsWenjianBanbenServiceImpl.formatVersion(sequence)); version.setWenjianNeirong(attachment(content)); version.setShengxiaoShijian(new Date()); version.setBizStatus("effective"); return version; } private static String attachment(String id) { return "[{\"fileId\":\"" + id + "\",\"url\":\"/api/file/Image/annex/" + id + ".docx\"}]"; } }