feat 自动分账调试, 数据加密方式改为类型处理器模式

This commit is contained in:
DaxPay
2024-05-07 20:31:39 +08:00
parent d133957e63
commit 8047c85ed6
13 changed files with 146 additions and 45 deletions

View File

@@ -0,0 +1,83 @@
package cn.bootx.platform.daxpay.service.common.typehandler;
import cn.bootx.platform.starter.data.perm.configuration.DataPermProperties;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.extra.spring.SpringUtil;
import lombok.Setter;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 字段加密处理类
* @author xxm
* @since 2024/5/7
*/
public class DecryptTypeHandler extends BaseTypeHandler<String> {
@Setter
private static DataPermProperties dataPermProperties;
/**
* 加密
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, this.encryptValue(parameter));
}
/**
* 解密
*/
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
String columnValue = rs.getString(columnName);
return StrUtil.isBlank(columnValue) ? columnValue : this.decryptValue(columnValue);
}
/**
* 解密
*/
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String columnValue = rs.getString(columnIndex);
return StrUtil.isBlank(columnValue) ? columnValue : this.decryptValue(columnValue);
}
/**
* 解密
*/
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String columnValue = cs.getString(columnIndex);
return StrUtil.isBlank(columnValue) ? columnValue : this.decryptValue(columnValue);
}
/**
* 对象值加密
*/
public String encryptValue(String fieldValue) {
AES aes = SecureUtil.aes(dataPermProperties.getFieldDecryptKey().getBytes(StandardCharsets.UTF_8));
return aes.encryptBase64(fieldValue);
}
/**
* 对具体的值进行解码
*/
public String decryptValue(String fieldValue) {
AES aes = SecureUtil.aes(dataPermProperties.getFieldDecryptKey().getBytes(StandardCharsets.UTF_8));
return new String(aes.decrypt(Base64.decode(fieldValue)), StandardCharsets.UTF_8);
}
}

View File

@@ -0,0 +1,22 @@
package cn.bootx.platform.daxpay.service.common.typehandler;
import cn.bootx.platform.starter.data.perm.configuration.DataPermProperties;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/**
*
* @author xxm
* @since 2024/5/7
*/
@Configuration
public class TypeHandlerConfig {
@PostConstruct
public void init(){
DataPermProperties permProperties = SpringUtil.getBean(DataPermProperties.class);
DecryptTypeHandler.setDataPermProperties(permProperties);
}
}

View File

@@ -1,11 +1,11 @@
package cn.bootx.platform.daxpay.service.core.channel.alipay.entity;
import cn.bootx.platform.common.core.annotation.BigField;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.common.mybatisplus.handler.StringListTypeHandler;
import cn.bootx.platform.daxpay.service.code.AliPayCode;
import cn.bootx.platform.daxpay.service.common.typehandler.DecryptTypeHandler;
import cn.bootx.platform.daxpay.service.core.channel.alipay.convert.AlipayConvert;
import cn.bootx.platform.daxpay.service.dto.channel.alipay.AliPayConfigDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -85,41 +85,41 @@ public class AliPayConfig extends MpBaseEntity implements EntityBaseFunction<Ali
/**
* 是商家与支付宝签约后,商家获得的支付宝商家唯一识别码,以 2088 开头的 16 位数字组成,在开放平台中账户中心获取
*/
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbColumn(comment = "合作者身份ID")
private String alipayUserId;
/** 支付宝公钥 */
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "支付宝公钥")
public String alipayPublicKey;
/** 私钥 */
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "私钥")
private String privateKey;
/** 应用公钥证书 */
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "应用公钥证书")
private String appCert;
/** 支付宝公钥证书 */
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "支付宝公钥证书")
private String alipayCert;
/** 支付宝CA根证书 */
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbColumn(comment = "支付宝CA根证书")
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
private String alipayRootCert;

View File

@@ -125,7 +125,9 @@ public class AliPayAllocationService {
// 如果是完成, 更新时间
if (AllocDetailResultEnum.SUCCESS.getCode().equals(detail.getResult())){
LocalDateTime finishTime = LocalDateTimeUtil.of(receiver.getExecuteDt());
detail.setFinishTime(finishTime);
detail.setFinishTime(finishTime)
.setErrorMsg(null)
.setErrorCode(null);
}
}
}

View File

@@ -1,11 +1,11 @@
package cn.bootx.platform.daxpay.service.core.channel.union.entity;
import cn.bootx.platform.common.core.annotation.BigField;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.common.mybatisplus.handler.StringListTypeHandler;
import cn.bootx.platform.daxpay.service.code.UnionPaySignTypeEnum;
import cn.bootx.platform.daxpay.service.common.typehandler.DecryptTypeHandler;
import cn.bootx.platform.daxpay.service.core.channel.union.convert.UnionPayConvert;
import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayConfigDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -69,14 +69,14 @@ public class UnionPayConfig extends MpBaseEntity implements EntityBaseFunction<U
*/
@DbColumn(comment = "应用私钥证书")
@BigField
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
private String keyPrivateCert;
/**
* 私钥证书对应的密码
*/
@DbColumn(comment = "私钥证书对应的密码")
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
private String keyPrivateCertPwd;
/**
@@ -84,16 +84,15 @@ public class UnionPayConfig extends MpBaseEntity implements EntityBaseFunction<U
*/
@DbColumn(comment = "中级证书")
@BigField
@EncryptionField
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@TableField(typeHandler = DecryptTypeHandler.class)
private String acpMiddleCert;
/**
* 根证书
*/
@DbColumn(comment = "根证书")
@BigField
@EncryptionField
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@TableField(typeHandler = DecryptTypeHandler.class)
private String acpRootCert;
/** 是否沙箱环境 */

View File

@@ -1,11 +1,11 @@
package cn.bootx.platform.daxpay.service.core.channel.wechat.entity;
import cn.bootx.platform.common.core.annotation.BigField;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.common.mybatisplus.handler.StringListTypeHandler;
import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
import cn.bootx.platform.daxpay.service.common.typehandler.DecryptTypeHandler;
import cn.bootx.platform.daxpay.service.core.channel.wechat.convert.WeChatConvert;
import cn.bootx.platform.daxpay.service.dto.channel.wechat.WeChatPayConfigDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -80,29 +80,25 @@ public class WeChatPayConfig extends MpBaseEntity implements EntityBaseFunction<
private String apiVersion;
/** 商户平台「API安全」中的 APIv2 密钥 */
@TableField(updateStrategy = FieldStrategy.ALWAYS)
@TableField(updateStrategy = FieldStrategy.ALWAYS,typeHandler = DecryptTypeHandler.class)
@BigField
@EncryptionField
@DbColumn(comment = "APIv2 密钥")
private String apiKeyV2;
/** 商户平台「API安全」中的 APIv3 密钥 */
@TableField(updateStrategy = FieldStrategy.ALWAYS)
@TableField(updateStrategy = FieldStrategy.ALWAYS,typeHandler = DecryptTypeHandler.class)
@BigField
@EncryptionField
@DbColumn(comment = "APIv3 密钥")
private String apiKeyV3;
/** APPID对应的接口密码用于获取微信公众号jsapi支付时使用 */
@TableField(updateStrategy = FieldStrategy.ALWAYS)
@EncryptionField
@TableField(updateStrategy = FieldStrategy.ALWAYS,typeHandler = DecryptTypeHandler.class)
@DbColumn(comment = "APPID对应的接口密码")
private String appSecret;
/** API证书中p12证书Base64 */
@TableField(updateStrategy = FieldStrategy.ALWAYS)
@TableField(updateStrategy = FieldStrategy.ALWAYS,typeHandler = DecryptTypeHandler.class)
@BigField
@EncryptionField
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "API证书中p12证书Base64")
private String p12;

View File

@@ -1,14 +1,15 @@
package cn.bootx.platform.daxpay.service.core.order.allocation.entity;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.AllocDetailResultEnum;
import cn.bootx.platform.daxpay.code.AllocReceiverTypeEnum;
import cn.bootx.platform.daxpay.service.common.typehandler.DecryptTypeHandler;
import cn.bootx.platform.daxpay.service.core.order.allocation.convert.AllocationConvert;
import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDetailDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -25,7 +26,7 @@ import java.time.LocalDateTime;
@Data
@Accessors(chain = true)
@DbTable(comment = "分账订单明细")
@TableName("pay_allocation_order_detail")
@TableName(value = "pay_allocation_order_detail",autoResultMap = true)
public class AllocationOrderDetail extends MpBaseEntity implements EntityBaseFunction<AllocationOrderDetailDto> {
/** 分账订单ID */
@@ -53,7 +54,7 @@ public class AllocationOrderDetail extends MpBaseEntity implements EntityBaseFun
/** 接收方账号 */
@DbColumn(comment = "接收方账号")
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
private String receiverAccount;
/** 接收方姓名 */

View File

@@ -23,7 +23,6 @@ import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDeta
import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDto;
import cn.bootx.platform.daxpay.service.param.order.AllocationOrderQuery;
import cn.bootx.platform.daxpay.util.OrderNoGenerateUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -136,16 +135,9 @@ public class AllocationOrderService {
payOrder.setAllocationStatus(PayOrderAllocStatusEnum.ALLOCATION.getCode());
payOrderManager.updateById(payOrder);
// 因为加密后字段值会发生变更, 所以在保存前备份一下
List<AllocationOrderDetail> detailsBack = details.stream()
.map(o -> {
AllocationOrderDetail allocationOrderDetail = new AllocationOrderDetail();
BeanUtil.copyProperties(o, allocationOrderDetail);
return allocationOrderDetail;
})
.collect(Collectors.toList());
allocationOrderDetailManager.saveAll(details);
allocationOrderManager.save(allocationOrder);
return new OrderAndDetail().setOrder(allocationOrder).setDetails(detailsBack);
return new OrderAndDetail().setOrder(allocationOrder).setDetails(details);
}
}

View File

@@ -86,7 +86,7 @@ public class PayOrderQueryService {
throw new ValidationFailedException("业务号或支付单ID不能都为空");
}
// 查询支付单
PayOrder payOrder = this.findByBizOrOrderNo(param.getBizOrderNoeNo(), param.getOrderNo())
PayOrder payOrder = this.findByBizOrOrderNo(param.getOrderNo(), param.getBizOrderNoeNo())
.orElseThrow(() -> new DataNotExistException("未查询到支付订单"));
// 查询扩展数据
payOrderExtraManager.findById(payOrder.getId())

View File

@@ -24,6 +24,9 @@ import java.util.Optional;
@RequiredArgsConstructor
public class AllocationGroupManager extends BaseManager<AllocationGroupMapper,AllocationGroup> {
/**
* 分页
*/
public Page<AllocationGroup> page(PageParam pageParam, AllocationGroupParam query) {
Page<AllocationGroup> mpPage = MpUtil.getMpPage(pageParam, AllocationGroup.class);
QueryWrapper<AllocationGroup> generator = QueryGenerator.generator(query);
@@ -44,6 +47,9 @@ public class AllocationGroupManager extends BaseManager<AllocationGroupMapper,Al
* 获取默认分账组
*/
public Optional<AllocationGroup> findDefaultGroup(String channel) {
return findByField(AllocationGroup::getChannel,channel);
return this.lambdaQuery()
.eq(AllocationGroup::getChannel,channel)
.eq(AllocationGroup::isDefaultGroup,true)
.oneOpt();
}
}

View File

@@ -1,11 +1,11 @@
package cn.bootx.platform.daxpay.service.core.payment.allocation.entity;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.AllocReceiverTypeEnum;
import cn.bootx.platform.daxpay.code.AllocRelationTypeEnum;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.common.typehandler.DecryptTypeHandler;
import cn.bootx.platform.daxpay.service.core.payment.allocation.convert.AllocationReceiverConvert;
import cn.bootx.platform.daxpay.service.dto.allocation.AllocationReceiverDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -26,7 +26,7 @@ import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@DbTable(comment = "分账接收方")
@TableName("pay_allocation_receiver")
@TableName(value = "pay_allocation_receiver",autoResultMap = true)
public class AllocationReceiver extends MpBaseEntity implements EntityBaseFunction<AllocationReceiverDto> {
@DbColumn(comment = "账号别名")
@@ -48,7 +48,7 @@ public class AllocationReceiver extends MpBaseEntity implements EntityBaseFuncti
@DbColumn(comment = "接收方账号")
@EncryptionField
@TableField(typeHandler = DecryptTypeHandler.class)
private String receiverAccount;
/** 接收方姓名 */

View File

@@ -230,11 +230,11 @@ public class AllocationService {
// 获取分账订单
AllocationOrder allocationOrder = null;
if (Objects.nonNull(param.getAllocationNo())){
allocationOrder = allocationOrderManager.findById(param.getBizAllocationNo())
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
if (Objects.isNull(allocationOrder)){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
allocationOrder = allocationOrderManager.findByAllocationNo(param.getBizAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
this.sync(allocationOrder);