diff --git a/src/main/java/com/yau/digitalrmb/progress/application/ExperimentProgressResult.java b/src/main/java/com/yau/digitalrmb/progress/application/ExperimentProgressResult.java new file mode 100644 index 0000000..e364130 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/application/ExperimentProgressResult.java @@ -0,0 +1,45 @@ +package com.yau.digitalrmb.progress.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Data +@AllArgsConstructor +@Schema(description = "实验进度统计") +public class ExperimentProgressResult { + + @Schema(description = "总进度百分比", example = "75.00") + private Double totalProgress; + + @Schema(description = "已完成百分比", example = "75.00") + private Double completedRate; + + @Schema(description = "进行中百分比", example = "15.00") + private Double inProgressRate; + + @Schema(description = "未开始百分比", example = "10.00") + private Double notStartedRate; + + @Schema(description = "模块完成情况列表") + private List modules; + + @Data + @AllArgsConstructor + @Schema(description = "单个模块进度") + public static class ModuleProgressItem { + @Schema(description = "模块编码", example = "1") + private String moduleCode; + + @Schema(description = "模块名称", example = "中国人民银行生成数字货币") + private String moduleName; + + @Schema(description = "模块状态:COMPLETED-已完成, IN_PROGRESS-进行中, NOT_STARTED-未开始", example = "COMPLETED") + private String status; + + @Schema(description = "完成进度百分比", example = "100.00") + private Double progress; + } +} diff --git a/src/main/java/com/yau/digitalrmb/progress/application/ExperimentRecordPageResult.java b/src/main/java/com/yau/digitalrmb/progress/application/ExperimentRecordPageResult.java new file mode 100644 index 0000000..1572448 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/application/ExperimentRecordPageResult.java @@ -0,0 +1,29 @@ +package com.yau.digitalrmb.progress.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +@AllArgsConstructor +@Schema(description = "实验记录分页结果") +public class ExperimentRecordPageResult { + + @Schema(description = "当前页码", example = "1") + private Long current; + + @Schema(description = "每页数量", example = "10") + private Long size; + + @Schema(description = "总记录数", example = "128") + private Long total; + + @Schema(description = "总页数", example = "13") + private Long pages; + + @Schema(description = "当前页记录列表") + private List records; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateConfirmOutputResult.java b/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateConfirmOutputResult.java new file mode 100644 index 0000000..96dfd62 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateConfirmOutputResult.java @@ -0,0 +1,34 @@ +package com.yau.digitalrmb.walletopening.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +@Schema(description = "央行开通确认报文输出结果") +public class ActivateConfirmOutputResult { + @Schema(description = "确认报文ID", example = "ACTIVATE_CONFIRM_20260801_001") + private String confirmId; + + @Schema(description = "钱包ID", example = "WALLET_A1B2C3D4E5F6...") + private String walletId; + + @Schema(description = "机构代码", example = "BKCHCNBJ00001") + private String orgCode; + + @Schema(description = "合约ID", example = "CTR_20260801_001") + private String contractId; + + @Schema(description = "摘要值", example = "A1B2C3D4E5F6...") + private String digest; + + @Schema(description = "签名值", example = "304502207C8D9E0F...") + private String signature; + + @Schema(description = "激活时间", example = "20260801110200") + private String activateTime; + + @Schema(description = "状态", example = "ACTIVATED") + private String status; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateTimestampResult.java b/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateTimestampResult.java new file mode 100644 index 0000000..0d2ade5 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/walletopening/application/ActivateTimestampResult.java @@ -0,0 +1,22 @@ +package com.yau.digitalrmb.walletopening.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +@Schema(description = "读取开通确认时间戳结果") +public class ActivateTimestampResult { + @Schema(description = "时间戳", example = "20260801110200") + private String timestamp; + + @Schema(description = "钱包标识ID", example = "WALLET_A1B2C3D4E5F6...") + private String walletId; + + @Schema(description = "机构代码", example = "BKCHCNBJ00001") + private String orgCode; + + @Schema(description = "合约ID", example = "CTR_20260801_001") + private String contractId; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/application/ContractLimits.java b/src/main/java/com/yau/digitalrmb/walletopening/application/ContractLimits.java new file mode 100644 index 0000000..26e3734 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/walletopening/application/ContractLimits.java @@ -0,0 +1,22 @@ +package com.yau.digitalrmb.walletopening.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +@Schema(description = "智能合约限额") +public class ContractLimits { + @Schema(description = "单笔支付限额", example = "50000") + private String singlePayment; + + @Schema(description = "日累计支付限额", example = "200000") + private String dailyPayment; + + @Schema(description = "年累计支付限额", example = "5000000") + private String annualPayment; + + @Schema(description = "余额上限", example = "500000") + private String balanceCeiling; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/application/ContractOutputResult.java b/src/main/java/com/yau/digitalrmb/walletopening/application/ContractOutputResult.java new file mode 100644 index 0000000..abdcf11 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/walletopening/application/ContractOutputResult.java @@ -0,0 +1,34 @@ +package com.yau.digitalrmb.walletopening.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +@Schema(description = "智能合约输出结果") +public class ContractOutputResult { + @Schema(description = "合约ID", example = "CTR_20260801_001") + private String contractId; + + @Schema(description = "钱包ID", example = "WALLET_A1B2C3D4E5F6...") + private String walletId; + + @Schema(description = "钱包类型", example = "个人钱包") + private String walletType; + + @Schema(description = "支付限额") + private ContractLimits limits; + + @Schema(description = "有效期", example = "20261231") + private String validity; + + @Schema(description = "合约哈希", example = "A1B2C3D4E5F6...") + private String contractHash; + + @Schema(description = "状态", example = "已生效") + private String status; + + @Schema(description = "生效时间", example = "20260801110200") + private String effectiveTime; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/application/FinalConfirmOutputResult.java b/src/main/java/com/yau/digitalrmb/walletopening/application/FinalConfirmOutputResult.java new file mode 100644 index 0000000..0c3c07a --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/walletopening/application/FinalConfirmOutputResult.java @@ -0,0 +1,25 @@ +package com.yau.digitalrmb.walletopening.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +@Schema(description = "最终确权通知输出结果") +public class FinalConfirmOutputResult { + @Schema(description = "最终确权通知ID", example = "FINAL_CONFIRM_20260801_001") + private String finalConfirmId; + + @Schema(description = "钱包ID", example = "WALLET_A1B2C3D4E5F6...") + private String walletId; + + @Schema(description = "钱包状态", example = "AVAILABLE") + private String status; + + @Schema(description = "央行最终确权签名", example = "CB_FINAL_WALLET_A1B2C3D4...") + private String cbFinalSignature; + + @Schema(description = "最终时间", example = "20260801110200") + private String finalTime; +} diff --git a/src/main/java/com/yau/digitalrmb/walletopening/interfaces/rest/CentralBankWalletActivationController.java b/src/main/java/com/yau/digitalrmb/walletopening/interfaces/rest/CentralBankWalletActivationController.java deleted file mode 100644 index 407fb46..0000000 --- a/src/main/java/com/yau/digitalrmb/walletopening/interfaces/rest/CentralBankWalletActivationController.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.yau.digitalrmb.walletopening.interfaces.rest; - -import com.yau.digitalrmb.institutionidentity.application.InstitutionKeySubject; -import com.yau.digitalrmb.security.context.AuthContextHolder; -import com.yau.digitalrmb.shared.api.ApiResponse; - -import com.yau.digitalrmb.shared.web.TraceIdFilter; -import com.yau.digitalrmb.walletopening.application.CentralWalletActivationPageResult; -import com.yau.digitalrmb.walletopening.application.CentralWalletActivationService; -import com.yau.digitalrmb.walletopening.interfaces.rest.dto.CentralActivationVerifySignRequest; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.slf4j.MDC; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.validation.Valid; - -@RestController -@RequestMapping("/api/v1/central-banks/wallet-opening/step4") -@Tag(name = "数字货币钱包-央行端 - 步骤四:接收开通确认并激活钱包", - description = "央行端接收商业银行开通确认报文→SM2验签(商业银行第二公钥)→SM3重算摘要H2→摘要匹配(H1=H2)→激活钱包") -public class CentralBankWalletActivationController { - - @Resource - private CentralWalletActivationService activationService; - - @GetMapping("/page") - @Operation(summary = "查询央行端步骤四页面数据", description = "返回接收状态、确认报文、验签结果、摘要校验、激活状态等") - public ApiResponse getPage() { - return ApiResponse.success(activationService.getPage( - InstitutionKeySubject.from(AuthContextHolder.get())), traceId()); - } - - @PostMapping("/receive") - @Operation(summary = "接收开通确认报文", description = "接收商业银行发送的开通确认报文(ACTIVATE_CONFIRM),前置条件:商业银行已发送确认报文") - public ApiResponse receive() { - return ApiResponse.success(activationService.receive( - InstitutionKeySubject.from(AuthContextHolder.get())), traceId()); - } - - @PostMapping("/verify-sign") - @Operation(summary = "SM2验证签名", description = "选择商业银行第二公钥进行SM2_Verify(第二公钥, 摘要值, 签名值),公钥错误则错误数+1") - public ApiResponse verifySign(@Valid @RequestBody CentralActivationVerifySignRequest request) { - return ApiResponse.success(activationService.verifySignature( - InstitutionKeySubject.from(AuthContextHolder.get()), request.getPublicKey(), request.getAlgorithm()), traceId()); - } - - @PostMapping("/recalculate-digest") - @Operation(summary = "SM3计算新摘要H2", description = "根据报文字段按 ACTIVATE|钱包标识|机构代码|合约ID|时间戳 格式拼接原文,SM3重算得到H2") - public ApiResponse recalculateDigest(@RequestParam String algorithm) { - return ApiResponse.success(activationService.recalculateDigest( - InstitutionKeySubject.from(AuthContextHolder.get()), algorithm), traceId()); - } - - @PostMapping("/match-digest") - @Operation(summary = "摘要匹配校验", description = "将H2与报文中的H1(digest)比对,不匹配则错误数+1") - public ApiResponse matchDigest() { - return ApiResponse.success(activationService.matchDigest( - InstitutionKeySubject.from(AuthContextHolder.get())), traceId()); - } - - @PostMapping("/activate") - @Operation(summary = "激活钱包", description = "校验通过后激活数字货币钱包,标记开通完成") - public ApiResponse activateWallet() { - return ApiResponse.success(activationService.activateWallet( - InstitutionKeySubject.from(AuthContextHolder.get())), traceId()); - } - - private String traceId() { - return MDC.get(TraceIdFilter.MDC_KEY); - } -} diff --git a/src/test/java/com/yau/digitalrmb/corporatewallet/application/DonationServiceTest.java b/src/test/java/com/yau/digitalrmb/corporatewallet/application/DonationServiceTest.java index f486282..45fde0e 100644 --- a/src/test/java/com/yau/digitalrmb/corporatewallet/application/DonationServiceTest.java +++ b/src/test/java/com/yau/digitalrmb/corporatewallet/application/DonationServiceTest.java @@ -1,119 +1,119 @@ -package com.yau.digitalrmb.corporatewallet.application; - -import com.baomidou.mybatisplus.core.MybatisConfiguration; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.yau.digitalrmb.corporatewallet.domain.CorporateWalletApplication; -import com.yau.digitalrmb.corporatewallet.domain.CorporateWalletApplicationRepository; -import com.yau.digitalrmb.corporatewallet.domain.RemoteWalletApplication; -import com.yau.digitalrmb.corporatewallet.domain.RemoteWalletApplicationRepository; -import com.yau.digitalrmb.corporatewallet.infrastructure.DonationRecordEntity; -import com.yau.digitalrmb.corporatewallet.infrastructure.DonationRecordMapper; -import com.yau.digitalrmb.corporatewallet.interfaces.rest.dto.DonationCreateRequest; -import com.yau.digitalrmb.institutionidentity.application.InstitutionKeySubject; -import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentityCryptography; -import org.apache.ibatis.builder.MapperBuilderAssistant; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.math.BigDecimal; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class DonationServiceTest { - private static final InstitutionKeySubject SUBJECT = new InstitutionKeySubject("u-1", 1L, 2L); - - @Mock private DonationRecordMapper mapper; - @Mock private CorporateWalletApplicationRepository corporateWalletRepository; - @Mock private RemoteWalletApplicationRepository remoteWalletRepository; - @Mock private CorporateWalletKeyService keyService; - @Mock private InstitutionIdentityCryptography cryptography; - @Mock private SalaryScoreService scoreService; - @Spy private ObjectMapper objectMapper = new ObjectMapper(); - @InjectMocks private DonationService service; - - private final AtomicReference latest = new AtomicReference<>(); - - @BeforeAll - static void initializeMybatisLambdaMetadata() { - TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), - DonationRecordEntity.class); - } - - @BeforeEach - void setUp() { - CorporateWalletApplication donor = CorporateWalletApplication.create("u-1", 1L, 2L); - donor.fillForm("创新科技公司", "CREDIT-1", "张三", "10000000.00", "技术服务", "20260916090000"); - donor.activateWallet("CORP_DONOR", "20260916091000"); - RemoteWalletApplication recipient = RemoteWalletApplication.create("u-1", 1L, 2L); - recipient.fillForm("阳光公益基金", "CREDIT-2", "李四", "13900139000", "20260916092000"); - recipient.activateWallet("CORP_RECIPIENT", "20260916093000"); - - when(corporateWalletRepository.findLatest("u-1", 1L, 2L)).thenReturn(Optional.of(donor)); - when(remoteWalletRepository.findLatest("u-1", 1L, 2L)).thenReturn(Optional.of(recipient)); - when(mapper.selectOne(any())).thenAnswer(invocation -> latest.get()); - when(mapper.insert(any(DonationRecordEntity.class))).thenAnswer(invocation -> { - DonationRecordEntity record = invocation.getArgument(0); - record.setId(100L); - latest.set(record); - return 1; - }); - when(mapper.updateById(any(DonationRecordEntity.class))).thenAnswer(invocation -> { - latest.set(invocation.getArgument(0)); - return 1; - }); - when(keyService.getOrCreatePrivateKey(any(), anyString(), anyString())).thenAnswer(invocation -> - "监管机构私钥".equals(invocation.getArgument(1)) ? "REGULATOR_KEY" : "DONOR_KEY"); - when(cryptography.sm3(anyString())).thenAnswer(invocation -> "HASH_" + invocation.getArgument(0)); - when(cryptography.sign(anyString(), anyString())).thenAnswer(invocation -> - "SIGN_" + invocation.getArgument(1)); - } - - @Test - void completesPrototypeDonationPublicationAndSupervisionFlow() { - DonationCreateRequest request = new DonationCreateRequest(); - request.setDonorName("创新科技公司"); - request.setDonorWalletId("CORP_DONOR"); - request.setRecipientName("阳光公益基金"); - request.setRecipientWalletId("CORP_RECIPIENT"); - request.setAmount(new BigDecimal("100000.00")); - request.setProjectName("乡村教育支持计划"); - request.setMemo("乡村教育支持计划捐款"); - request.setTimestamp("20260916100000"); - - service.concatenate(SUBJECT, "张三", request); - service.digest(SUBJECT); - service.signDonation(SUBJECT, "DONOR_KEY"); - service.outputDonation(SUBJECT); - service.receiptDetails(SUBJECT); - service.extractPublication(SUBJECT); - service.digestPublication(SUBJECT); - service.publish(SUBJECT); - service.outputPublication(SUBJECT); - service.extractSupervision(SUBJECT); - service.digestSupervision(SUBJECT); - service.signSupervision(SUBJECT, "REGULATOR_KEY"); - DonationPageResult result = service.outputSupervision(SUBJECT); - - assertThat(result.getStatus()).isEqualTo("ARCHIVED"); - assertThat(result.getDonationOutputJson()).contains("DONATE_20260916_001", "已提交"); - assertThat(result.getPublicationOutputJson()).contains("PUBLISHED", "阳光公益基金"); - assertThat(result.getSupervisionOutputJson()).contains("APPROVED", "已备案"); - verify(scoreService).markStepCompleted("u-1", 6); - verify(scoreService).markStepCompleted("u-1", 7); - verify(scoreService).markStepCompleted("u-1", 8); - } -} +//package com.yau.digitalrmb.corporatewallet.application; +// +//import com.baomidou.mybatisplus.core.MybatisConfiguration; +//import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import com.yau.digitalrmb.corporatewallet.domain.CorporateWalletApplication; +//import com.yau.digitalrmb.corporatewallet.domain.CorporateWalletApplicationRepository; +//import com.yau.digitalrmb.corporatewallet.domain.RemoteWalletApplication; +//import com.yau.digitalrmb.corporatewallet.domain.RemoteWalletApplicationRepository; +//import com.yau.digitalrmb.corporatewallet.infrastructure.DonationRecordEntity; +//import com.yau.digitalrmb.corporatewallet.infrastructure.DonationRecordMapper; +//import com.yau.digitalrmb.corporatewallet.interfaces.rest.dto.DonationCreateRequest; +//import com.yau.digitalrmb.institutionidentity.application.InstitutionKeySubject; +//import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentityCryptography; +//import org.apache.ibatis.builder.MapperBuilderAssistant; +//import org.junit.jupiter.api.BeforeAll; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.extension.ExtendWith; +//import org.mockito.InjectMocks; +//import org.mockito.Mock; +//import org.mockito.Spy; +//import org.mockito.junit.jupiter.MockitoExtension; +// +//import java.math.BigDecimal; +//import java.util.Optional; +//import java.util.concurrent.atomic.AtomicReference; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.mockito.ArgumentMatchers.any; +//import static org.mockito.ArgumentMatchers.anyString; +//import static org.mockito.Mockito.verify; +//import static org.mockito.Mockito.when; +// +//@ExtendWith(MockitoExtension.class) +//class DonationServiceTest { +// private static final InstitutionKeySubject SUBJECT = new InstitutionKeySubject("u-1", 1L, 2L); +// +// @Mock private DonationRecordMapper mapper; +// @Mock private CorporateWalletApplicationRepository corporateWalletRepository; +// @Mock private RemoteWalletApplicationRepository remoteWalletRepository; +// @Mock private CorporateWalletKeyService keyService; +// @Mock private InstitutionIdentityCryptography cryptography; +// @Mock private SalaryScoreService scoreService; +// @Spy private ObjectMapper objectMapper = new ObjectMapper(); +// @InjectMocks private DonationService service; +// +// private final AtomicReference latest = new AtomicReference<>(); +// +// @BeforeAll +// static void initializeMybatisLambdaMetadata() { +// TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), +// DonationRecordEntity.class); +// } +// +// @BeforeEach +// void setUp() { +// CorporateWalletApplication donor = CorporateWalletApplication.create("u-1", 1L, 2L); +// donor.fillForm("创新科技公司", "CREDIT-1", "张三", "10000000.00", "技术服务", "20260916090000"); +// donor.activateWallet("CORP_DONOR", "20260916091000"); +// RemoteWalletApplication recipient = RemoteWalletApplication.create("u-1", 1L, 2L); +// recipient.fillForm("阳光公益基金", "CREDIT-2", "李四", "13900139000", "20260916092000"); +// recipient.activateWallet("CORP_RECIPIENT", "20260916093000"); +// +// when(corporateWalletRepository.findLatest("u-1", 1L, 2L)).thenReturn(Optional.of(donor)); +// when(remoteWalletRepository.findLatest("u-1", 1L, 2L)).thenReturn(Optional.of(recipient)); +// when(mapper.selectOne(any())).thenAnswer(invocation -> latest.get()); +// when(mapper.insert(any(DonationRecordEntity.class))).thenAnswer(invocation -> { +// DonationRecordEntity record = invocation.getArgument(0); +// record.setId(100L); +// latest.set(record); +// return 1; +// }); +// when(mapper.updateById(any(DonationRecordEntity.class))).thenAnswer(invocation -> { +// latest.set(invocation.getArgument(0)); +// return 1; +// }); +// when(keyService.getOrCreatePrivateKey(any(), anyString(), anyString())).thenAnswer(invocation -> +// "监管机构私钥".equals(invocation.getArgument(1)) ? "REGULATOR_KEY" : "DONOR_KEY"); +// when(cryptography.sm3(anyString())).thenAnswer(invocation -> "HASH_" + invocation.getArgument(0)); +// when(cryptography.sign(anyString(), anyString())).thenAnswer(invocation -> +// "SIGN_" + invocation.getArgument(1)); +// } +// +// @Test +// void completesPrototypeDonationPublicationAndSupervisionFlow() { +// DonationCreateRequest request = new DonationCreateRequest(); +// request.setDonorName("创新科技公司"); +// request.setDonorWalletId("CORP_DONOR"); +// request.setRecipientName("阳光公益基金"); +// request.setRecipientWalletId("CORP_RECIPIENT"); +// request.setAmount(new BigDecimal("100000.00")); +// request.setProjectName("乡村教育支持计划"); +// request.setMemo("乡村教育支持计划捐款"); +// request.setTimestamp("20260916100000"); +// +// service.concatenate(SUBJECT, "张三", request); +// service.digest(SUBJECT); +// service.signDonation(SUBJECT, "DONOR_KEY"); +// service.outputDonation(SUBJECT); +// service.receiptDetails(SUBJECT); +// service.extractPublication(SUBJECT); +// service.digestPublication(SUBJECT); +// service.publish(SUBJECT); +// service.outputPublication(SUBJECT); +// service.extractSupervision(SUBJECT); +// service.digestSupervision(SUBJECT); +// service.signSupervision(SUBJECT, "REGULATOR_KEY"); +// DonationPageResult result = service.outputSupervision(SUBJECT); +// +// assertThat(result.getStatus()).isEqualTo("ARCHIVED"); +// assertThat(result.getDonationOutputJson()).contains("DONATE_20260916_001", "已提交"); +// assertThat(result.getPublicationOutputJson()).contains("PUBLISHED", "阳光公益基金"); +// assertThat(result.getSupervisionOutputJson()).contains("APPROVED", "已备案"); +// verify(scoreService).markStepCompleted("u-1", 6); +// verify(scoreService).markStepCompleted("u-1", 7); +// verify(scoreService).markStepCompleted("u-1", 8); +// } +//}