You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digital-rmb-backend/src/main/java/com/yau/digitalrmb/walletopening/application/WalletOpeningService.java

163 lines
9.5 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.yau.digitalrmb.walletopening.application;
import com.yau.digitalrmb.institutionidentity.application.InstitutionKeySubject;
import com.yau.digitalrmb.institutionidentity.infrastructure.InstitutionIdentifierApplicationEntity;
import com.yau.digitalrmb.institutionidentity.infrastructure.InstitutionIdentifierApplicationMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yau.digitalrmb.security.context.JwtUser;
import com.yau.digitalrmb.shared.api.ErrorCode;
import com.yau.digitalrmb.shared.exception.BusinessException;
import com.yau.digitalrmb.walletopening.domain.BankReceivedApplication;
import com.yau.digitalrmb.walletopening.domain.BankReceivedApplicationRepository;
import com.yau.digitalrmb.walletopening.domain.WalletApplication;
import com.yau.digitalrmb.walletopening.domain.WalletApplicationRepository;
import com.yau.digitalrmb.walletopening.interfaces.rest.dto.WalletApplicationRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
public class WalletOpeningService {
private static final DateTimeFormatter TIMESTAMP_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
@Resource
private WalletApplicationRepository walletRepository;
@Resource
private BankReceivedApplicationRepository bankReceivedRepository;
@Resource
private InstitutionIdentifierApplicationMapper institutionIdentifierMapper;
@Transactional(readOnly = true)
public UserWalletPageResult getPage(InstitutionKeySubject subject, JwtUser jwtUser) {
WalletApplication app = walletRepository.findLatest(subject.getUserId(), subject.getSchoolId(), subject.getClassId())
.orElseGet(() -> {
// 未创建记录时返回一个只包含JWT用户信息的临时对象不保存到数据库
WalletApplication temp = WalletApplication.create(
subject.getUserId(), subject.getSchoolId(), subject.getClassId(),
jwtUser.getUserName(), jwtUser.getPhone());
return temp;
});
return new UserWalletPageResult(app);
}
@Transactional
public FaceRecognitionResult updateFaceRecognition(InstitutionKeySubject subject, JwtUser jwtUser, int status) {
WalletApplication app = walletRepository.findLatest(subject.getUserId(), subject.getSchoolId(), subject.getClassId())
.orElseGet(() -> {
// 首次人脸识别时创建记录
WalletApplication newApp = WalletApplication.create(
subject.getUserId(), subject.getSchoolId(), subject.getClassId(),
jwtUser.getUserName(), jwtUser.getPhone());
return walletRepository.save(newApp);
});
app.updateFaceRecognition(status);
walletRepository.update(app);
return new FaceRecognitionResult(status);
}
@Transactional
public WalletApplicationMessageResult outputApplication(InstitutionKeySubject subject, JwtUser jwtUser, WalletApplicationRequest request) {
WalletApplication app = walletRepository.findLatest(subject.getUserId(), subject.getSchoolId(), subject.getClassId())
.orElseGet(() -> {
// 首次输出申请报文时创建记录
WalletApplication newApp = WalletApplication.create(
subject.getUserId(), subject.getSchoolId(), subject.getClassId(),
jwtUser.getUserName(), jwtUser.getPhone());
return walletRepository.save(newApp);
});
if (app.getStatus() != null && app.getStatus().ordinal() >= WalletApplication.Status.OUTPUT.ordinal()) {
throw new BusinessException(ErrorCode.VALIDATION_ERROR, "申请报文已输出,请勿重复操作");
}
if (app.getFaceRecognitionStatus() == null || app.getFaceRecognitionStatus() != 2) {
throw new BusinessException(ErrorCode.VALIDATION_ERROR, "请先完成人脸识别");
}
if (request.getWalletType() == null || request.getWalletType().trim().isEmpty()) {
throw new BusinessException(ErrorCode.VALIDATION_ERROR, "请选择数字钱包类型");
}
// 输出申请报文时才存储身份证号、银行卡号等敏感信息
app.fillForm(request.getSelectedBank(), request.getWalletType(), request.getInputPhone(),
request.getInputIdNumber(), request.getInputBankCardNumber(), request.getSignaturePhotoPath(),
request.getIdNumber(), request.getAccountBank(), request.getBankCardNumber(), request.getAccountBalance());
String applyTime = LocalDateTime.now().format(TIMESTAMP_FORMAT);
String applicationId = "APP_" + applyTime;
String concatenatedMessage = buildConcatenatedMessage(app, applyTime);
String applicationMessage = buildApplicationMessage(app, applicationId, applyTime);
app.outputApplication(applicationId, concatenatedMessage, applicationMessage, applyTime);
walletRepository.update(app);
return new WalletApplicationMessageResult(app);
}
@Transactional
public WalletSendResult sendApplication(InstitutionKeySubject subject, JwtUser jwtUser) {
WalletApplication app = walletRepository.findLatest(subject.getUserId(), subject.getSchoolId(), subject.getClassId())
.orElseThrow(() -> new BusinessException(ErrorCode.RESOURCE_NOT_FOUND, "钱包申请不存在,请先输出申请报文"));
if (app.getStatus() == null || app.getStatus().ordinal() < WalletApplication.Status.OUTPUT.ordinal()) {
throw new BusinessException(ErrorCode.VALIDATION_ERROR, "请先输出申请报文");
}
if (app.getStatus() == WalletApplication.Status.SUBMITTED) {
throw new BusinessException(ErrorCode.VALIDATION_ERROR, "申请已发送,请勿重复操作");
}
app.submit();
walletRepository.update(app);
String receiveTime = LocalDateTime.now().format(TIMESTAMP_FORMAT);
String receiveId = "BK_RECEIVE_" + receiveTime;
String orgCode = resolveOrgCode(subject);
String effectiveIdNumber = app.getInputIdNumber() != null ? app.getInputIdNumber() : app.getIdNumber();
String effectivePhone = app.getInputPhone() != null ? app.getInputPhone() : app.getPhone();
String effectiveBankCardNumber = app.getInputBankCardNumber() != null ? app.getInputBankCardNumber() : app.getBankCardNumber();
BankReceivedApplication received = BankReceivedApplication.receive(
subject.getUserId(), subject.getSchoolId(), subject.getClassId(),
receiveId, app.getApplicationId(), orgCode, receiveTime,
app.getUserName(), effectiveIdNumber, effectivePhone,
effectiveBankCardNumber, app.getWalletType(), app.getApplyTime());
bankReceivedRepository.save(received);
return new WalletSendResult("已提交");
}
private String resolveOrgCode(InstitutionKeySubject subject) {
InstitutionIdentifierApplicationEntity entity = institutionIdentifierMapper.selectOne(
new LambdaQueryWrapper<InstitutionIdentifierApplicationEntity>()
.eq(InstitutionIdentifierApplicationEntity::getUserId, subject.getUserId())
.eq(InstitutionIdentifierApplicationEntity::getSchoolId, subject.getSchoolId())
.eq(InstitutionIdentifierApplicationEntity::getClassId, subject.getClassId())
.eq(InstitutionIdentifierApplicationEntity::getDeleted, false)
.isNotNull(InstitutionIdentifierApplicationEntity::getInstitutionIdentifier)
.orderByDesc(InstitutionIdentifierApplicationEntity::getCreatedAt)
.last("LIMIT 1"));
return entity == null ? null : entity.getBankCode();
}
private String buildConcatenatedMessage(WalletApplication app, String applyTime) {
String idNumber = app.getInputIdNumber() != null ? app.getInputIdNumber() : app.getIdNumber();
String phone = app.getInputPhone() != null ? app.getInputPhone() : app.getPhone();
String bankCardNumber = app.getInputBankCardNumber() != null ? app.getInputBankCardNumber() : app.getBankCardNumber();
return "APPLY|" + app.getUserName() + "|" + idNumber + "|" + phone + "|"
+ bankCardNumber + "|" + app.getWalletType() + "|" + applyTime;
}
private String buildApplicationMessage(WalletApplication app, String applicationId, String applyTime) {
String idNumber = app.getInputIdNumber() != null ? app.getInputIdNumber() : app.getIdNumber();
String phone = app.getInputPhone() != null ? app.getInputPhone() : app.getPhone();
String bankCardNumber = app.getInputBankCardNumber() != null ? app.getInputBankCardNumber() : app.getBankCardNumber();
return "{\"applicationId\":\"" + applicationId + "\","
+ "\"userName\":\"" + app.getUserName() + "\","
+ "\"idNumber\":\"" + idNumber + "\","
+ "\"phone\":\"" + phone + "\","
+ "\"bankCardNumber\":\"" + bankCardNumber + "\","
+ "\"walletType\":\"" + app.getWalletType() + "\","
+ "\"applyTime\":\"" + applyTime + "\","
+ "\"status\":\"已提交\"}";
}
}