From 44df252f9b5bcd93f591b4fc0bf6e25c5c0133b2 Mon Sep 17 00:00:00 2001 From: "jiazheng.zhao" <2624533894@qq.com> Date: Wed, 19 Aug 2026 13:58:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CurrencyGenerationRequestService.java | 4 +- .../CurrencyGenerationVerificationResult.java | 13 ++ ...CurrencyGenerationVerificationService.java | 8 +- .../application/CurrencyRequestResult.java | 5 + .../domain/CurrencyGenerationRequest.java | 15 ++- .../CurrencyGenerationVerification.java | 33 ++++- .../TransactionInformationIdentifier.java | 19 ++- .../CurrencyGenerationRequestEntity.java | 1 + .../CurrencyGenerationVerificationEntity.java | 3 + ...isCurrencyGenerationRequestRepository.java | 5 +- ...rencyGenerationVerificationRepository.java | 15 ++- .../application/StepProgressNewView.java | 18 +++ .../UserStepProgressNewService.java | 77 +++++++++++ .../UserStepProgressNewEntity.java | 41 ++++++ .../UserStepProgressNewMapper.java | 8 ++ .../rest/UserStepProgressController.java | 124 +++++++++--------- .../rest/UserStepProgressNewController.java | 69 ++++++++++ .../rest/dto/StepProgressSaveRequest.java | 24 ++++ .../currency_request_private_key_upgrade.sql | 2 + ...rrency_verification_input_text_upgrade.sql | 2 + .../currency_verification_key_upgrade.sql | 3 + .../institution_identifier_training.sql | 4 + 22 files changed, 407 insertions(+), 86 deletions(-) create mode 100644 src/main/java/com/yau/digitalrmb/progress/application/StepProgressNewView.java create mode 100644 src/main/java/com/yau/digitalrmb/progress/application/UserStepProgressNewService.java create mode 100644 src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewEntity.java create mode 100644 src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewMapper.java create mode 100644 src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressNewController.java create mode 100644 src/main/java/com/yau/digitalrmb/progress/interfaces/rest/dto/StepProgressSaveRequest.java create mode 100644 src/main/resources/db/manual/currency_request_private_key_upgrade.sql create mode 100644 src/main/resources/db/manual/currency_verification_input_text_upgrade.sql create mode 100644 src/main/resources/db/manual/currency_verification_key_upgrade.sql diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationRequestService.java b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationRequestService.java index e523a23..a4fa9f0 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationRequestService.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationRequestService.java @@ -52,7 +52,7 @@ public class CurrencyGenerationRequestService { request = CurrencyGenerationRequest.restore(requestId, input.getIdentifierApplicationId(), input.getInstitutionIdentifier(), input.getFullInstitutionIdentifier(), input.getAmount(), input.getDeliveryNodeCode(), input.getRequestTimestamp(), input.getRequestOriginalText(), - null, null, null, null, input.getStatus()); + null, null, null, null, null, input.getStatus()); } String digest = cryptography.sm3(input.getRequestOriginalText()); CurrencyGenerationRequest.Status expected = request.getStatus(); @@ -77,7 +77,7 @@ public class CurrencyGenerationRequestService { "签名必须使用当前实训主体的商业银行第二私钥,本次实训第" + errorSequence + "次错误"); } - invokeDomain(() -> request.recordSignature(InstitutionKeyService.BANK_SECOND_KEY, signature)); + invokeDomain(() -> request.recordSignature(InstitutionKeyService.BANK_SECOND_KEY, signature, privateKey)); repository.update(request, expected, "SIGN", "使用商业银行第二私钥完成SM2签名", operator); return new CurrencyRequestResult(request); } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationResult.java b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationResult.java index eff2e06..439e55c 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationResult.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationResult.java @@ -51,6 +51,12 @@ public class CurrencyGenerationVerificationResult { private final String confirmationTime; @Schema(description = "央行打包完成的确认报文;尚未点击打包报文时为空") private final String confirmationMessage; + @Schema(description = "用户提交的商业银行第二公钥;尚未验签时为空") + private final String submittedPublicKey; + @Schema(description = "用户提交的央行第一私钥;尚未确权时为空") + private final String submittedPrivateKey; + @Schema(description = "用户在步骤三运算摘要时输入的请求原文;尚未运算时为空") + private final String userInputOriginalText; public CurrencyGenerationVerificationResult() { verificationId = null; requestId = null; status = null; @@ -61,6 +67,8 @@ public class CurrencyGenerationVerificationResult { remainingQuota = null; quotaSufficient = null; centralBankKeyId = null; centralBankSignature = null; confirmationTime = null; confirmationMessage = null; + submittedPublicKey = null; submittedPrivateKey = null; + userInputOriginalText = null; } public CurrencyGenerationVerificationResult(CurrencyGenerationVerification v) { @@ -72,6 +80,8 @@ public class CurrencyGenerationVerificationResult { remainingQuota = v.getRemainingQuota(); quotaSufficient = v.getQuotaSufficient(); centralBankKeyId = v.getCentralBankKeyId(); centralBankSignature = v.getCentralBankSignature(); confirmationTime = v.getConfirmationTime(); confirmationMessage = v.getConfirmationMessage(); + submittedPublicKey = v.getSubmittedPublicKey(); submittedPrivateKey = v.getSubmittedPrivateKey(); + userInputOriginalText = v.getUserInputOriginalText(); } public Long getVerificationId() { return verificationId; } @@ -94,4 +104,7 @@ public class CurrencyGenerationVerificationResult { public String getCentralBankSignature() { return centralBankSignature; } public String getConfirmationTime() { return confirmationTime; } public String getConfirmationMessage() { return confirmationMessage; } + public String getSubmittedPublicKey() { return submittedPublicKey; } + public String getSubmittedPrivateKey() { return submittedPrivateKey; } + public String getUserInputOriginalText() { return userInputOriginalText; } } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationService.java b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationService.java index a8be579..d1d8df8 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationService.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyGenerationVerificationService.java @@ -51,7 +51,7 @@ public class CurrencyGenerationVerificationService { return new CurrencyGenerationVerificationResult(CurrencyGenerationVerification.restore(id, requestId, value.getRequestMessage(), value.getRequestOriginalText(), value.getRequestDigest(), value.getBankSignature(), value.getBankKeyId(), value.getAmount(), null, null, null, - null, null, null, null, null, null, null, null, value.getStatus())); + null, null, null, null, null, null, null, null, null, null, null, value.getStatus())); } @Transactional @@ -67,7 +67,7 @@ public class CurrencyGenerationVerificationService { if (!valid) { throw keyError(subject, "商业银行第二公钥验签未通过"); } - invoke(() -> value.verifySignature(valid)); + invoke(() -> value.verifySignature(valid, publicKey)); repository.update(value, expected, "VERIFY_SIGNATURE", "使用商业银行第二公钥验证SM2签名", operator); return new CurrencyGenerationVerificationResult(value); } @@ -78,7 +78,7 @@ public class CurrencyGenerationVerificationService { CurrencyGenerationVerification value = require(id, subject); CurrencyGenerationVerification.Status expected = value.getStatus(); String digest = cryptography.sm3(requestOriginalText); - invoke(() -> value.calculateDigest(digest)); + invoke(() -> value.calculateDigest(digest, requestOriginalText)); repository.update(value, expected, "CALCULATE_DIGEST", "对用户输入的请求原文计算摘要一", operator); return new CurrencyDigestResult(digest); } @@ -129,7 +129,7 @@ public class CurrencyGenerationVerificationService { return new CurrencyConfirmationSignatureResult(value.getCentralBankSignature()); } String time = LocalDateTime.now().format(TIME); - invoke(() -> value.confirm(InstitutionKeyService.CENTRAL_FIRST_KEY, signature, time)); + invoke(() -> value.confirm(InstitutionKeyService.CENTRAL_FIRST_KEY, signature, time, privateKey)); repository.update(value, expected, "CONFIRM", "校验用户输入请求摘要并使用央行第一私钥完成签名确权", operator); return new CurrencyConfirmationSignatureResult(value.getCentralBankSignature()); } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyRequestResult.java b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyRequestResult.java index 10add23..4d88a1d 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyRequestResult.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/application/CurrencyRequestResult.java @@ -43,6 +43,8 @@ public class CurrencyRequestResult { private final String bankSignature; @Schema(description = "发送给央行的货币生成请求报文;尚未组装时为空") private final String requestMessage; + @Schema(description = "用户提交的商业银行第二私钥;尚未签名时为空") + private final String submittedPrivateKey; @Schema(description = "央行接收状态", example = "NOT_RECEIVED") private final String centralBankReceiveStatus; @@ -63,6 +65,7 @@ public class CurrencyRequestResult { this.signingKeyId = null; this.bankSignature = null; this.requestMessage = null; + this.submittedPrivateKey = null; this.centralBankReceiveStatus = null; } @@ -83,6 +86,7 @@ public class CurrencyRequestResult { this.signingKeyId = request.getSigningKeyId(); this.bankSignature = request.getBankSignature(); this.requestMessage = request.getRequestMessage(); + this.submittedPrivateKey = request.getSubmittedPrivateKey(); this.centralBankReceiveStatus = request.getStatus() == CurrencyGenerationRequest.Status.RECEIVED ? "RECEIVED" : "NOT_RECEIVED"; } @@ -103,5 +107,6 @@ public class CurrencyRequestResult { public String getSigningKeyId() { return signingKeyId; } public String getBankSignature() { return bankSignature; } public String getRequestMessage() { return requestMessage; } + public String getSubmittedPrivateKey() { return submittedPrivateKey; } public String getCentralBankReceiveStatus() { return centralBankReceiveStatus; } } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationRequest.java b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationRequest.java index 03ea1b8..f039085 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationRequest.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationRequest.java @@ -19,12 +19,14 @@ public class CurrencyGenerationRequest { private String bankSignature; private String signingKeyId; private String requestMessage; + private String submittedPrivateKey; private Status status; private CurrencyGenerationRequest(Long id, long identifierApplicationId, String institutionIdentifier, String fullInstitutionIdentifier, BigDecimal amount, String deliveryNodeCode, String requestTimestamp, String requestOriginalText, String requestDigest, - String bankSignature, String signingKeyId, String requestMessage, Status status) { + String bankSignature, String signingKeyId, String requestMessage, + String submittedPrivateKey, Status status) { this.id = id; this.identifierApplicationId = identifierApplicationId; this.institutionIdentifier = institutionIdentifier; @@ -37,6 +39,7 @@ public class CurrencyGenerationRequest { this.bankSignature = bankSignature; this.signingKeyId = signingKeyId; this.requestMessage = requestMessage; + this.submittedPrivateKey = submittedPrivateKey; this.status = status; } @@ -67,7 +70,7 @@ public class CurrencyGenerationRequest { + deliveryNodeCode + "|" + requestTimestamp; return new CurrencyGenerationRequest(null, identifierApplicationId, institutionIdentifier, fullInstitutionIdentifier, normalizedAmount, deliveryNodeCode, requestTimestamp, - originalText, null, null, null, null, Status.CONCATENATED); + originalText, null, null, null, null, null, Status.CONCATENATED); } public static CurrencyGenerationRequest restore(Long id, long identifierApplicationId, @@ -75,10 +78,10 @@ public class CurrencyGenerationRequest { BigDecimal amount, String deliveryNodeCode, String requestTimestamp, String requestOriginalText, String requestDigest, String bankSignature, String signingKeyId, - String requestMessage, Status status) { + String requestMessage, String submittedPrivateKey, Status status) { return new CurrencyGenerationRequest(id, identifierApplicationId, institutionIdentifier, fullInstitutionIdentifier, amount, deliveryNodeCode, requestTimestamp, requestOriginalText, - requestDigest, bankSignature, signingKeyId, requestMessage, status); + requestDigest, bankSignature, signingKeyId, requestMessage, submittedPrivateKey, status); } public void concatenate() { @@ -119,7 +122,7 @@ public class CurrencyGenerationRequest { status = Status.DIGESTED; } - public void recordSignature(String keyId, String signature) { + public void recordSignature(String keyId, String signature, String submittedPrivateKey) { if (requestDigest == null) { throw new IllegalStateException("请先完成SM3摘要计算"); } @@ -128,6 +131,7 @@ public class CurrencyGenerationRequest { } signingKeyId = keyId; bankSignature = signature; + this.submittedPrivateKey = submittedPrivateKey; requestMessage = null; status = Status.SIGNED; } @@ -175,5 +179,6 @@ public class CurrencyGenerationRequest { public String getBankSignature() { return bankSignature; } public String getSigningKeyId() { return signingKeyId; } public String getRequestMessage() { return requestMessage; } + public String getSubmittedPrivateKey() { return submittedPrivateKey; } public Status getStatus() { return status; } } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationVerification.java b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationVerification.java index 820e29a..064fc55 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationVerification.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/CurrencyGenerationVerification.java @@ -27,6 +27,9 @@ public class CurrencyGenerationVerification { private String centralBankSignature; private String confirmationTime; private String confirmationMessage; + private String submittedPublicKey; + private String submittedPrivateKey; + private String userInputOriginalText; private Status status; private CurrencyGenerationVerification(Long id, long requestId, String requestMessage, @@ -37,7 +40,8 @@ public class CurrencyGenerationVerification { BigDecimal usedQuota, BigDecimal remainingQuota, Boolean quotaSufficient, String centralBankKeyId, String centralBankSignature, String confirmationTime, - String confirmationMessage, Status status) { + String confirmationMessage, String submittedPublicKey, + String submittedPrivateKey, String userInputOriginalText, Status status) { this.id = id; this.requestId = requestId; this.requestMessage = requestMessage; @@ -57,6 +61,9 @@ public class CurrencyGenerationVerification { this.centralBankSignature = centralBankSignature; this.confirmationTime = confirmationTime; this.confirmationMessage = confirmationMessage; + this.submittedPublicKey = submittedPublicKey; + this.submittedPrivateKey = submittedPrivateKey; + this.userInputOriginalText = userInputOriginalText; this.status = status; } @@ -70,7 +77,7 @@ public class CurrencyGenerationVerification { } return new CurrencyGenerationVerification(null, requestId, requestMessage, requestOriginalText, requestDigest, bankSignature, bankKeyId, amount, null, null, null, null, null, null, - null, null, null, null, null, Status.RECEIVED); + null, null, null, null, null, null, null, null, Status.RECEIVED); } public static CurrencyGenerationVerification restore(Long id, long requestId, String requestMessage, @@ -81,11 +88,14 @@ public class CurrencyGenerationVerification { BigDecimal usedQuota, BigDecimal remainingQuota, Boolean quotaSufficient, String centralBankKeyId, String centralBankSignature, String confirmationTime, - String confirmationMessage, Status status) { + String confirmationMessage, String submittedPublicKey, + String submittedPrivateKey, String userInputOriginalText, + Status status) { return new CurrencyGenerationVerification(id, requestId, requestMessage, requestOriginalText, requestDigest, bankSignature, bankKeyId, amount, signatureValid, recomputedDigest, digestMatches, totalQuota, usedQuota, remainingQuota, quotaSufficient, centralBankKeyId, centralBankSignature, - confirmationTime, confirmationMessage, status); + confirmationTime, confirmationMessage, submittedPublicKey, submittedPrivateKey, + userInputOriginalText, status); } public void receiveAgain() { @@ -100,21 +110,26 @@ public class CurrencyGenerationVerification { centralBankSignature = null; confirmationTime = null; confirmationMessage = null; + submittedPublicKey = null; + submittedPrivateKey = null; + userInputOriginalText = null; status = Status.RECEIVED; } - public void verifySignature(boolean valid) { + public void verifySignature(boolean valid, String publicKey) { requireBeforeDigestMatch("第二公钥SM2验证"); if (!valid) throw new IllegalArgumentException("商业银行SM2签名验证未通过"); signatureValid = true; + submittedPublicKey = publicKey; status = recomputedDigest == null ? Status.SIGNATURE_VERIFIED : Status.DIGEST_CALCULATED; } - public void calculateDigest(String digest) { + public void calculateDigest(String digest, String userInputOriginalText) { if (digest == null || !digest.matches("[0-9A-F]{64}")) { throw new IllegalArgumentException("重新计算的摘要一格式不正确"); } recomputedDigest = digest; + this.userInputOriginalText = userInputOriginalText; digestMatches = null; if (isBefore(Status.DIGEST_CALCULATED)) { status = Status.DIGEST_CALCULATED; @@ -145,7 +160,7 @@ public class CurrencyGenerationVerification { } } - public void confirm(String keyId, String signature, String time) { + public void confirm(String keyId, String signature, String time, String privateKey) { if (!Boolean.TRUE.equals(quotaSufficient)) { throw new IllegalStateException("请先完成额度检查"); } @@ -155,6 +170,7 @@ public class CurrencyGenerationVerification { centralBankKeyId = keyId; centralBankSignature = signature; confirmationTime = time; + submittedPrivateKey = privateKey; status = Status.CONFIRMED; } @@ -211,5 +227,8 @@ public class CurrencyGenerationVerification { public String getCentralBankSignature() { return centralBankSignature; } public String getConfirmationTime() { return confirmationTime; } public String getConfirmationMessage() { return confirmationMessage; } + public String getSubmittedPublicKey() { return submittedPublicKey; } + public String getSubmittedPrivateKey() { return submittedPrivateKey; } + public String getUserInputOriginalText() { return userInputOriginalText; } public Status getStatus() { return status; } } diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/TransactionInformationIdentifier.java b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/TransactionInformationIdentifier.java index c3fa885..1b25948 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/domain/TransactionInformationIdentifier.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/domain/TransactionInformationIdentifier.java @@ -168,9 +168,22 @@ public class TransactionInformationIdentifier { if (quotaRequestId == null || !quotaRequestId.matches("QR_\\d{8}_\\d{3}")) { throw new IllegalArgumentException("额度请求编号格式不正确"); } - String expectedOriginalText = amount.toPlainString() + "|" + institutionIdentifier - + "|" + transactionIdentifier; - if (!expectedOriginalText.equals(quotaOriginalText)) { + if (quotaOriginalText == null || quotaOriginalText.trim().isEmpty()) { + throw new IllegalArgumentException("额度请求原文不能为空"); + } + String[] parts = quotaOriginalText.split("\\|", -1); + if (parts.length != 3) { + throw new IllegalArgumentException("额度请求原文格式必须为:金额|机构标识|交易信息标识"); + } + BigDecimal inputAmount; + try { + inputAmount = new BigDecimal(parts[0]); + } catch (NumberFormatException exception) { + throw new IllegalArgumentException("额度请求原文中的金额格式不正确"); + } + if (inputAmount.compareTo(amount) != 0 + || !institutionIdentifier.equals(parts[1]) + || !transactionIdentifier.equals(parts[2])) { throw new IllegalArgumentException("额度请求原文与步骤四数据不一致"); } this.quotaRequestId = quotaRequestId; diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationRequestEntity.java b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationRequestEntity.java index 83bed94..2bd98af 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationRequestEntity.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationRequestEntity.java @@ -23,6 +23,7 @@ public class CurrencyGenerationRequestEntity extends AuditableEntity { @TableField("bank_signature") private String bankSignature; @TableField("signing_key_id") private String signingKeyId; @TableField("request_message") private String requestMessage; + @TableField("submitted_private_key") private String submittedPrivateKey; private String status; @TableField("user_id") private String userId; @TableField("school_id") private Long schoolId; diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationVerificationEntity.java b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationVerificationEntity.java index 4ce29e9..daf1903 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationVerificationEntity.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/CurrencyGenerationVerificationEntity.java @@ -30,6 +30,9 @@ public class CurrencyGenerationVerificationEntity extends AuditableEntity { @TableField("central_bank_signature") private String centralBankSignature; @TableField("confirmation_time") private String confirmationTime; @TableField("confirmation_message") private String confirmationMessage; + @TableField("submitted_public_key") private String submittedPublicKey; + @TableField("submitted_private_key") private String submittedPrivateKey; + @TableField("user_input_original_text") private String userInputOriginalText; private String status; @TableField("user_id") private String userId; @TableField("school_id") private Long schoolId; diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationRequestRepository.java b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationRequestRepository.java index ad3fca1..33c3ee5 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationRequestRepository.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationRequestRepository.java @@ -88,6 +88,7 @@ public class MybatisCurrencyGenerationRequestRepository implements CurrencyGener .set(CurrencyGenerationRequestEntity::getBankSignature, request.getBankSignature()) .set(CurrencyGenerationRequestEntity::getSigningKeyId, request.getSigningKeyId()) .set(CurrencyGenerationRequestEntity::getRequestMessage, request.getRequestMessage()) + .set(CurrencyGenerationRequestEntity::getSubmittedPrivateKey, request.getSubmittedPrivateKey()) .set(CurrencyGenerationRequestEntity::getStatus, request.getStatus().name()) .set(CurrencyGenerationRequestEntity::getUpdatedAt, LocalDateTime.now()) .set(CurrencyGenerationRequestEntity::getUpdatedBy, operator); @@ -112,6 +113,7 @@ public class MybatisCurrencyGenerationRequestRepository implements CurrencyGener entity.setBankSignature(request.getBankSignature()); entity.setSigningKeyId(request.getSigningKeyId()); entity.setRequestMessage(request.getRequestMessage()); + entity.setSubmittedPrivateKey(request.getSubmittedPrivateKey()); entity.setStatus(request.getStatus().name()); return entity; } @@ -121,7 +123,8 @@ public class MybatisCurrencyGenerationRequestRepository implements CurrencyGener entity.getInstitutionIdentifier(), entity.getFullInstitutionIdentifier(), entity.getAmount(), entity.getDeliveryNodeCode(), entity.getRequestTimestamp(), entity.getRequestOriginalText(), entity.getRequestDigest(), entity.getBankSignature(), entity.getSigningKeyId(), - entity.getRequestMessage(), CurrencyGenerationRequest.Status.valueOf(entity.getStatus())); + entity.getRequestMessage(), entity.getSubmittedPrivateKey(), + CurrencyGenerationRequest.Status.valueOf(entity.getStatus())); } private void insertLog(Long requestId, String operation, String fromStatus, String toStatus, diff --git a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationVerificationRepository.java b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationVerificationRepository.java index 93b3bf9..345677f 100644 --- a/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationVerificationRepository.java +++ b/src/main/java/com/yau/digitalrmb/institutionidentity/infrastructure/MybatisCurrencyGenerationVerificationRepository.java @@ -82,6 +82,12 @@ public class MybatisCurrencyGenerationVerificationRepository implements Currency .set(CurrencyGenerationVerificationEntity::getConfirmationTime, value.getConfirmationTime()) .set(CurrencyGenerationVerificationEntity::getConfirmationMessage, value.getConfirmationMessage()) + .set(CurrencyGenerationVerificationEntity::getSubmittedPublicKey, + value.getSubmittedPublicKey()) + .set(CurrencyGenerationVerificationEntity::getSubmittedPrivateKey, + value.getSubmittedPrivateKey()) + .set(CurrencyGenerationVerificationEntity::getUserInputOriginalText, + value.getUserInputOriginalText()) .set(CurrencyGenerationVerificationEntity::getStatus, value.getStatus().name()) .set(CurrencyGenerationVerificationEntity::getUpdatedAt, LocalDateTime.now()) .set(CurrencyGenerationVerificationEntity::getUpdatedBy, operator); @@ -101,7 +107,11 @@ public class MybatisCurrencyGenerationVerificationRepository implements Currency e.setUsedQuota(value.getUsedQuota()); e.setRemainingQuota(value.getRemainingQuota()); e.setQuotaSufficient(value.getQuotaSufficient()); e.setCentralBankKeyId(value.getCentralBankKeyId()); e.setCentralBankSignature(value.getCentralBankSignature()); e.setConfirmationTime(value.getConfirmationTime()); - e.setConfirmationMessage(value.getConfirmationMessage()); e.setStatus(value.getStatus().name()); + e.setConfirmationMessage(value.getConfirmationMessage()); + e.setSubmittedPublicKey(value.getSubmittedPublicKey()); + e.setSubmittedPrivateKey(value.getSubmittedPrivateKey()); + e.setUserInputOriginalText(value.getUserInputOriginalText()); + e.setStatus(value.getStatus().name()); return e; } @@ -110,7 +120,8 @@ public class MybatisCurrencyGenerationVerificationRepository implements Currency e.getRequestOriginalText(), e.getRequestDigest(), e.getBankSignature(), e.getBankKeyId(), e.getAmount(), e.getSignatureValid(), e.getRecomputedDigest(), e.getDigestMatches(), e.getTotalQuota(), e.getUsedQuota(), e.getRemainingQuota(), e.getQuotaSufficient(), e.getCentralBankKeyId(), e.getCentralBankSignature(), - e.getConfirmationTime(), e.getConfirmationMessage(), + e.getConfirmationTime(), e.getConfirmationMessage(), e.getSubmittedPublicKey(), + e.getSubmittedPrivateKey(), e.getUserInputOriginalText(), CurrencyGenerationVerification.Status.valueOf(e.getStatus())); } diff --git a/src/main/java/com/yau/digitalrmb/progress/application/StepProgressNewView.java b/src/main/java/com/yau/digitalrmb/progress/application/StepProgressNewView.java new file mode 100644 index 0000000..0d2ed03 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/application/StepProgressNewView.java @@ -0,0 +1,18 @@ +package com.yau.digitalrmb.progress.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "步骤进度查询结果") +public class StepProgressNewView { + + @Schema(description = "模块编码") + private String moduleCode; + + @Schema(description = "步骤编码") + private String stepCode; + + @Schema(description = "前端传入的JSON字符串数据") + private String stepData; +} diff --git a/src/main/java/com/yau/digitalrmb/progress/application/UserStepProgressNewService.java b/src/main/java/com/yau/digitalrmb/progress/application/UserStepProgressNewService.java new file mode 100644 index 0000000..e1f3856 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/application/UserStepProgressNewService.java @@ -0,0 +1,77 @@ +package com.yau.digitalrmb.progress.application; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yau.digitalrmb.progress.infrastructure.UserStepProgressNewEntity; +import com.yau.digitalrmb.progress.infrastructure.UserStepProgressNewMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +@Service +public class UserStepProgressNewService { + + @Resource + private UserStepProgressNewMapper mapper; + + /** + * 保存步骤进度(第一次新增,第二次修改) + */ + @Transactional + public StepProgressNewView save(String userId, String moduleCode, String stepCode, String stepData) { + UserStepProgressNewEntity existing = findOne(userId, moduleCode, stepCode); + LocalDateTime now = LocalDateTime.now(); + if (existing == null) { + UserStepProgressNewEntity entity = new UserStepProgressNewEntity(); + entity.setUserId(userId); + entity.setModuleCode(moduleCode); + entity.setStepCode(stepCode); + entity.setData(stepData); + entity.setCreateTime(now); + entity.setUpdateTime(now); + entity.setDeleted(0); + mapper.insert(entity); + return toView(entity); + } + existing.setData(stepData); + existing.setUpdateTime(now); + mapper.updateById(existing); + return toView(existing); + } + + /** + * 查询步骤进度(按模块和步骤查询) + */ + @Transactional(readOnly = true) + public StepProgressNewView query(String userId, String moduleCode, String stepCode) { + UserStepProgressNewEntity entity = findOne(userId, moduleCode, stepCode); + return entity == null ? null : toView(entity); + } + + /** + * 重新实训:逻辑删除当前模块下所有步骤进度 + */ + @Transactional + public void reset(String userId, String moduleCode) { + mapper.delete(new LambdaQueryWrapper() + .eq(UserStepProgressNewEntity::getUserId, userId) + .eq(UserStepProgressNewEntity::getModuleCode, moduleCode)); + } + + private UserStepProgressNewEntity findOne(String userId, String moduleCode, String stepCode) { + return mapper.selectOne(new LambdaQueryWrapper() + .eq(UserStepProgressNewEntity::getUserId, userId) + .eq(UserStepProgressNewEntity::getModuleCode, moduleCode) + .eq(UserStepProgressNewEntity::getStepCode, stepCode) + .last("LIMIT 1")); + } + + private StepProgressNewView toView(UserStepProgressNewEntity e) { + StepProgressNewView v = new StepProgressNewView(); + v.setModuleCode(e.getModuleCode()); + v.setStepCode(e.getStepCode()); + v.setStepData(e.getData()); + return v; + } +} diff --git a/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewEntity.java b/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewEntity.java new file mode 100644 index 0000000..5191f4b --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewEntity.java @@ -0,0 +1,41 @@ +package com.yau.digitalrmb.progress.infrastructure; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +@TableName("user_step_progress_new") +public class UserStepProgressNewEntity { + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** 前端传入的JSON字符串数据 */ + private String data; + + @TableField("user_id") + private String userId; + + @TableField("create_time") + private LocalDateTime createTime; + + @TableField("update_time") + private LocalDateTime updateTime; + + @TableLogic + private Integer deleted; + + /** 数据库字段名为 moudule_code(建表时的拼写,保持一致) */ + @TableField("moudule_code") + private String moduleCode; + + @TableField("step_code") + private String stepCode; +} diff --git a/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewMapper.java b/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewMapper.java new file mode 100644 index 0000000..f32c1a9 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/infrastructure/UserStepProgressNewMapper.java @@ -0,0 +1,8 @@ +package com.yau.digitalrmb.progress.infrastructure; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface UserStepProgressNewMapper extends BaseMapper { +} diff --git a/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressController.java b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressController.java index 6d14928..61e2fa8 100644 --- a/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressController.java +++ b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressController.java @@ -1,62 +1,62 @@ -package com.yau.digitalrmb.progress.interfaces.rest; - -import com.yau.digitalrmb.progress.application.ModuleProgressView; -import com.yau.digitalrmb.progress.application.StepProgressView; -import com.yau.digitalrmb.progress.application.UserStepProgressService; -import com.yau.digitalrmb.progress.interfaces.rest.dto.CompleteStepRequest; -import com.yau.digitalrmb.security.context.AuthContextHolder; -import com.yau.digitalrmb.security.context.JwtUser; -import com.yau.digitalrmb.shared.api.ApiResponse; -import com.yau.digitalrmb.shared.web.TraceIdFilter; -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.PathVariable; -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.RestController; - -import javax.annotation.Resource; -import javax.validation.Valid; - -@RestController -@RequestMapping("/api/v1/progress") -@Tag(name = "公共模块 - 步骤进度", - description = "提供跨模块的步骤完成进度查询与保存接口,前端可在完成任意模块的任意步骤后调用保存接口记录进度") -public class UserStepProgressController { - - @Resource - private UserStepProgressService progressService; - - @GetMapping("/{moduleCode}") - @Operation(summary = "查询模块步骤进度", - description = "查询当前用户在指定模块下所有步骤的完成状态。moduleCode 由前端约定,如 INSTITUTION_IDENTITY、WALLET_OPENING") - public ApiResponse getModuleProgress(@PathVariable String moduleCode) { - JwtUser user = AuthContextHolder.get(); - return ApiResponse.success( - progressService.getModuleProgress(user.getUserId(), moduleCode), traceId()); - } - - @PostMapping("/complete") - @Operation(summary = "保存步骤完成状态", - description = "标记当前用户在指定模块的某步骤为已完成。幂等接口,重复调用不会重复创建记录。" - + "moduleCode 和 stepCode 由前端传入,stepName 可选用于展示。学校和班级信息自动从token中获取") - public ApiResponse completeStep(@Valid @RequestBody CompleteStepRequest request) { - JwtUser user = AuthContextHolder.get(); - return ApiResponse.success( - progressService.completeStep( - user.getUserId(), - user.getSchoolId(), user.getSchoolName(), - user.getClassId(), user.getClassName(), - request.getModuleCode().trim(), - request.getStepCode().trim(), - request.getStepName()), - traceId()); - } - - private String traceId() { - return MDC.get(TraceIdFilter.MDC_KEY); - } -} +//package com.yau.digitalrmb.progress.interfaces.rest; +// +//import com.yau.digitalrmb.progress.application.ModuleProgressView; +//import com.yau.digitalrmb.progress.application.StepProgressView; +//import com.yau.digitalrmb.progress.application.UserStepProgressService; +//import com.yau.digitalrmb.progress.interfaces.rest.dto.CompleteStepRequest; +//import com.yau.digitalrmb.security.context.AuthContextHolder; +//import com.yau.digitalrmb.security.context.JwtUser; +//import com.yau.digitalrmb.shared.api.ApiResponse; +//import com.yau.digitalrmb.shared.web.TraceIdFilter; +//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.PathVariable; +//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.RestController; +// +//import javax.annotation.Resource; +//import javax.validation.Valid; +// +//@RestController +//@RequestMapping("/api/v1/progress") +//@Tag(name = "公共模块 - 步骤进度", +// description = "提供跨模块的步骤完成进度查询与保存接口,前端可在完成任意模块的任意步骤后调用保存接口记录进度") +//public class UserStepProgressController { +// +// @Resource +// private UserStepProgressService progressService; +// +// @GetMapping("/{moduleCode}") +// @Operation(summary = "查询模块步骤进度", +// description = "查询当前用户在指定模块下所有步骤的完成状态。moduleCode 由前端约定,如 INSTITUTION_IDENTITY、WALLET_OPENING") +// public ApiResponse getModuleProgress(@PathVariable String moduleCode) { +// JwtUser user = AuthContextHolder.get(); +// return ApiResponse.success( +// progressService.getModuleProgress(user.getUserId(), moduleCode), traceId()); +// } +// +// @PostMapping("/complete") +// @Operation(summary = "保存步骤完成状态", +// description = "标记当前用户在指定模块的某步骤为已完成。幂等接口,重复调用不会重复创建记录。" +// + "moduleCode 和 stepCode 由前端传入,stepName 可选用于展示。学校和班级信息自动从token中获取") +// public ApiResponse completeStep(@Valid @RequestBody CompleteStepRequest request) { +// JwtUser user = AuthContextHolder.get(); +// return ApiResponse.success( +// progressService.completeStep( +// user.getUserId(), +// user.getSchoolId(), user.getSchoolName(), +// user.getClassId(), user.getClassName(), +// request.getModuleCode().trim(), +// request.getStepCode().trim(), +// request.getStepName()), +// traceId()); +// } +// +// private String traceId() { +// return MDC.get(TraceIdFilter.MDC_KEY); +// } +//} diff --git a/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressNewController.java b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressNewController.java new file mode 100644 index 0000000..c05ad48 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/UserStepProgressNewController.java @@ -0,0 +1,69 @@ +package com.yau.digitalrmb.progress.interfaces.rest; + +import com.yau.digitalrmb.progress.application.StepProgressNewView; +import com.yau.digitalrmb.progress.application.UserStepProgressNewService; +import com.yau.digitalrmb.progress.interfaces.rest.dto.StepProgressSaveRequest; +import com.yau.digitalrmb.security.context.AuthContextHolder; +import com.yau.digitalrmb.security.context.JwtUser; +import com.yau.digitalrmb.shared.api.ApiResponse; +import com.yau.digitalrmb.shared.web.TraceIdFilter; +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.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +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/step-progress") +@Tag(name = "公共模块 - 步骤进度(新)", + description = "前端传JSON数据直接存储,第一次新增、第二次修改;重新实训时逻辑删除。查询按模块和步骤进行。") +public class UserStepProgressNewController { + + @Resource + private UserStepProgressNewService service; + + @PostMapping + @Operation(summary = "保存步骤进度", + description = "前端传入 moduleCode、stepCode 和 stepData(JSON字符串)。第一次调用为新增,后续调用为修改。") + public ApiResponse save(@Valid @RequestBody StepProgressSaveRequest request) { + JwtUser user = AuthContextHolder.get(); + return ApiResponse.success(service.save( + user.getUserId(), + request.getModuleCode().trim(), + request.getStepCode().trim(), + request.getStepData()), traceId()); + } + + @GetMapping + @Operation(summary = "查询步骤进度", + description = "按 moduleCode 和 stepCode 查询当前用户的步骤数据。") + public ApiResponse query( + @RequestParam String moduleCode, + @RequestParam String stepCode) { + JwtUser user = AuthContextHolder.get(); + return ApiResponse.success(service.query( + user.getUserId(), moduleCode.trim(), stepCode.trim()), traceId()); + } + + @DeleteMapping("/{moduleCode}") + @Operation(summary = "重新实训:逻辑删除模块进度", + description = "逻辑删除当前用户在指定模块下的所有步骤进度记录。") + public ApiResponse reset(@PathVariable String moduleCode) { + JwtUser user = AuthContextHolder.get(); + service.reset(user.getUserId(), moduleCode.trim()); + return ApiResponse.success(null, traceId()); + } + + private String traceId() { + return MDC.get(TraceIdFilter.MDC_KEY); + } +} diff --git a/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/dto/StepProgressSaveRequest.java b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/dto/StepProgressSaveRequest.java new file mode 100644 index 0000000..e6f5787 --- /dev/null +++ b/src/main/java/com/yau/digitalrmb/progress/interfaces/rest/dto/StepProgressSaveRequest.java @@ -0,0 +1,24 @@ +package com.yau.digitalrmb.progress.interfaces.rest.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +@Schema(description = "步骤进度保存参数") +public class StepProgressSaveRequest { + + @NotBlank(message = "模块编码不能为空") + @Schema(description = "模块编码,由前端约定", example = "中国人民银行生成数字货币") + private String moduleCode; + + @NotBlank(message = "步骤编码不能为空") + @Schema(description = "步骤编码", example = "1") + private String stepCode; + + @NotBlank(message = "步骤数据不能为空") + @Schema(description = "前端传入的JSON字符串数据,后端直接存储", + example = "{\"orgCode\":\"BKCHCNBJ00001\",\"timestamp\":\"20260818151432\",\"digest\":\"012DA26EABD3\"}") + private String stepData; +} diff --git a/src/main/resources/db/manual/currency_request_private_key_upgrade.sql b/src/main/resources/db/manual/currency_request_private_key_upgrade.sql new file mode 100644 index 0000000..49d8efc --- /dev/null +++ b/src/main/resources/db/manual/currency_request_private_key_upgrade.sql @@ -0,0 +1,2 @@ +-- 货币生成请求表新增字段:用户提交的私钥(用于页面回显) +ALTER TABLE currency_generation_request ADD COLUMN submitted_private_key VARCHAR(512) COMMENT '用户提交的商业银行第二私钥(用于页面回显)'; diff --git a/src/main/resources/db/manual/currency_verification_input_text_upgrade.sql b/src/main/resources/db/manual/currency_verification_input_text_upgrade.sql new file mode 100644 index 0000000..cca59c7 --- /dev/null +++ b/src/main/resources/db/manual/currency_verification_input_text_upgrade.sql @@ -0,0 +1,2 @@ +-- 货币生成验证表新增字段:用户在步骤三输入的请求原文(用于页面回显) +ALTER TABLE currency_generation_verification ADD COLUMN user_input_original_text VARCHAR(512) COMMENT '用户在步骤三运算摘要时输入的请求原文(用于页面回显)'; diff --git a/src/main/resources/db/manual/currency_verification_key_upgrade.sql b/src/main/resources/db/manual/currency_verification_key_upgrade.sql new file mode 100644 index 0000000..2c90230 --- /dev/null +++ b/src/main/resources/db/manual/currency_verification_key_upgrade.sql @@ -0,0 +1,3 @@ +-- 货币生成验证表新增字段:用户提交的第二公钥和央行第一私钥(用于页面回显) +ALTER TABLE currency_generation_verification ADD COLUMN submitted_public_key VARCHAR(512) COMMENT '用户提交的商业银行第二公钥(用于页面回显)'; +ALTER TABLE currency_generation_verification ADD COLUMN submitted_private_key VARCHAR(512) COMMENT '用户提交的央行第一私钥(用于页面回显)'; diff --git a/src/main/resources/db/manual/institution_identifier_training.sql b/src/main/resources/db/manual/institution_identifier_training.sql index 067f78f..31b3de1 100644 --- a/src/main/resources/db/manual/institution_identifier_training.sql +++ b/src/main/resources/db/manual/institution_identifier_training.sql @@ -122,6 +122,7 @@ CREATE TABLE IF NOT EXISTS currency_generation_request ( bank_signature VARCHAR(512), signing_key_id VARCHAR(64), request_message VARCHAR(2048), + submitted_private_key VARCHAR(512) COMMENT '用户提交的商业银行第二私钥(用于页面回显)', status VARCHAR(32) NOT NULL, user_id VARCHAR(36) NOT NULL, school_id BIGINT NOT NULL, @@ -178,6 +179,9 @@ CREATE TABLE IF NOT EXISTS currency_generation_verification ( central_bank_signature VARCHAR(512), confirmation_time CHAR(14), confirmation_message VARCHAR(2048), + submitted_public_key VARCHAR(512) COMMENT '用户提交的商业银行第二公钥(用于页面回显)', + submitted_private_key VARCHAR(512) COMMENT '用户提交的央行第一私钥(用于页面回显)', + user_input_original_text VARCHAR(512) COMMENT '用户在步骤三运算摘要时输入的请求原文(用于页面回显)', status VARCHAR(32) NOT NULL, user_id VARCHAR(36) NOT NULL, school_id BIGINT NOT NULL,