feat 支付记录相关

This commit is contained in:
xxm1995
2023-06-16 17:14:15 +08:00
parent 802c381876
commit 6bb42bdaaf
21 changed files with 71 additions and 53 deletions

View File

@@ -35,4 +35,7 @@ public interface MchAndAppCode {
/** 停用 */ /** 停用 */
String PAY_CONFIG_STATE_FORBIDDEN = "forbidden"; String PAY_CONFIG_STATE_FORBIDDEN = "forbidden";
/** 封禁 */
String PAY_CONFIG_STATE_BANNED = "banned";
} }

View File

@@ -73,8 +73,8 @@ public class MchApplicationController {
@Operation(summary = "关联支付配置列表") @Operation(summary = "关联支付配置列表")
@GetMapping("/findAllConfig") @GetMapping("/findAllConfig")
public ResResult<List<MchAppPayConfigResult>> findAllConfig(Long appId) { public ResResult<List<MchAppPayConfigResult>> findAllConfig(String appCode) {
return Res.ok(appPayConfigService.ListByAppId(appId)); return Res.ok(appPayConfigService.ListByAppId(appCode));
} }
} }

View File

@@ -37,19 +37,19 @@ public class PayCallbackController {
@SneakyThrows @SneakyThrows
@Operation(summary = "支付宝回调") @Operation(summary = "支付宝回调")
@PostMapping("/alipay/{appCode}") @PostMapping("/alipay/{mchCode}/{appCode}")
public String aliPay(@PathVariable String appCode, HttpServletRequest request) { public String aliPay(@PathVariable String mchCode,@PathVariable String appCode, HttpServletRequest request) {
Map<String, String> stringStringMap = AliPayApi.toMap(request); Map<String, String> stringStringMap = AliPayApi.toMap(request);
return aliPayCallbackService.payCallback(appCode, stringStringMap); return aliPayCallbackService.payCallback(mchCode, appCode, stringStringMap);
} }
@SneakyThrows @SneakyThrows
@Operation(summary = "微信支付回调") @Operation(summary = "微信支付回调")
@PostMapping("/wechat/{appCode}") @PostMapping("/wechat/{mchCode}/{appCode}")
public String wechat(@PathVariable String appCode, HttpServletRequest request) { public String wechat(@PathVariable String mchCode, @PathVariable String appCode, HttpServletRequest request) {
String xmlMsg = HttpKit.readData(request); String xmlMsg = HttpKit.readData(request);
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg); Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
return weChatPayCallbackService.payCallback(appCode, params); return weChatPayCallbackService.payCallback(mchCode, appCode, params);
} }
} }

View File

@@ -4,8 +4,8 @@ import cn.bootx.platform.common.core.annotation.IgnoreAuth;
import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.Res;
import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.rest.ResResult;
import cn.bootx.platform.common.core.rest.param.OrderParam;
import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.query.entity.QueryOrder;
import cn.bootx.platform.common.query.entity.QueryParams; import cn.bootx.platform.common.query.entity.QueryParams;
import cn.bootx.platform.daxpay.core.payment.service.PaymentQueryService; import cn.bootx.platform.daxpay.core.payment.service.PaymentQueryService;
import cn.bootx.platform.daxpay.dto.payment.PayChannelInfo; import cn.bootx.platform.daxpay.dto.payment.PayChannelInfo;
@@ -38,8 +38,8 @@ public class PaymentController {
@Operation(summary = "分页查询") @Operation(summary = "分页查询")
@GetMapping("/page") @GetMapping("/page")
public ResResult<PageResult<PaymentDto>> page(PageParam pageParam, PaymentQuery param, OrderParam orderParam) { public ResResult<PageResult<PaymentDto>> page(PageParam pageParam, PaymentQuery param, QueryOrder queryOrder) {
return Res.ok(paymentQueryService.page(pageParam, param, orderParam)); return Res.ok(paymentQueryService.page(pageParam, param, queryOrder));
} }
@Operation(summary = "分页查询(超级查询)") @Operation(summary = "分页查询(超级查询)")

View File

@@ -119,7 +119,10 @@ public class AlipayConfig extends MpBaseEntity implements EntityBaseFunction<Ali
@DbColumn(comment = "可用支付方式") @DbColumn(comment = "可用支付方式")
private String payWays; private String payWays;
/** 状态 */ /**
* 状态
* @see cn.bootx.platform.daxpay.code.MchAndAppCode#PAY_CONFIG_STATE_NORMAL
*/
@DbColumn(comment = "状态") @DbColumn(comment = "状态")
private String state; private String state;

View File

@@ -6,6 +6,7 @@ import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.dto.KeyValue; import cn.bootx.platform.common.core.rest.dto.KeyValue;
import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil; import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.code.MchAndAppCode;
import cn.bootx.platform.daxpay.code.pay.PayChannelEnum; import cn.bootx.platform.daxpay.code.pay.PayChannelEnum;
import cn.bootx.platform.daxpay.code.paymodel.AliPayWay; import cn.bootx.platform.daxpay.code.paymodel.AliPayWay;
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AlipayConfigManager; import cn.bootx.platform.daxpay.core.channel.alipay.dao.AlipayConfigManager;
@@ -50,10 +51,11 @@ public class AlipayConfigService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void add(AlipayConfigParam param) { public void add(AlipayConfigParam param) {
// 是否有管理关系判断 // 是否有管理关系判断
if (mchAppService.checkMatch(param.getMchCode(), param.getMchAppCode())) { if (!mchAppService.checkMatch(param.getMchCode(), param.getMchAppCode())) {
throw new BizException("应用信息与商户信息不匹配"); throw new BizException("应用信息与商户信息不匹配");
} }
AlipayConfig alipayConfig = AlipayConfig.init(param); AlipayConfig alipayConfig = AlipayConfig.init(param);
alipayConfig.setState(MchAndAppCode.PAY_CONFIG_STATE_NORMAL);
alipayConfigManager.save(alipayConfig); alipayConfigManager.save(alipayConfig);
// 保存关联关系 // 保存关联关系

View File

@@ -6,6 +6,7 @@ import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.dto.KeyValue; import cn.bootx.platform.common.core.rest.dto.KeyValue;
import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil; import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.code.MchAndAppCode;
import cn.bootx.platform.daxpay.code.pay.PayChannelEnum; import cn.bootx.platform.daxpay.code.pay.PayChannelEnum;
import cn.bootx.platform.daxpay.code.paymodel.WeChatPayWay; import cn.bootx.platform.daxpay.code.paymodel.WeChatPayWay;
import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPayConfigManager; import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPayConfigManager;
@@ -48,11 +49,12 @@ public class WeChatPayConfigService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void add(WeChatPayConfigParam param) { public void add(WeChatPayConfigParam param) {
// 是否有管理关系判断 // 是否有管理关系判断
if (mchAppService.checkMatch(param.getMchCode(), param.getMchAppCode())) { if (!mchAppService.checkMatch(param.getMchCode(), param.getMchAppCode())) {
throw new BizException("应用信息与商户信息不匹配"); throw new BizException("应用信息与商户信息不匹配");
} }
WeChatPayConfig weChatPayConfig = WeChatPayConfig.init(param); WeChatPayConfig weChatPayConfig = WeChatPayConfig.init(param);
weChatPayConfig.setState(MchAndAppCode.PAY_CONFIG_STATE_NORMAL);
weChatPayConfigManager.save(weChatPayConfig); weChatPayConfigManager.save(weChatPayConfig);
// 保存关联关系 // 保存关联关系
MchAppPayConfig mchAppPayConfig = new MchAppPayConfig().setAppCode(weChatPayConfig.getMchAppCode()) MchAppPayConfig mchAppPayConfig = new MchAppPayConfig().setAppCode(weChatPayConfig.getMchAppCode())

View File

@@ -23,8 +23,8 @@ import lombok.experimental.Accessors;
public class MchAppPayConfig extends MpBaseEntity { public class MchAppPayConfig extends MpBaseEntity {
/** 关联应用编码 */ /** 关联应用编码 */
@DbMySqlIndex(comment = "关联应用编码索引") @DbMySqlIndex(comment = "关联商户应用编码索引")
@DbColumn(comment = "关联应用编码") @DbColumn(comment = "关联商户应用编码")
private String appCode; private String appCode;
/** 关联配置ID */ /** 关联配置ID */

View File

@@ -40,12 +40,12 @@ public class MchAppPayConfigService {
/** /**
* 支付通道配置列表 * 支付通道配置列表
*/ */
public List<MchAppPayConfigResult> ListByAppId(Long appId) { public List<MchAppPayConfigResult> ListByAppId(String appCode) {
// 首先查询系统中配置的支付通道进行排序 // 首先查询系统中配置的支付通道进行排序
List<PayChannelConfig> channels = channelConfigManager.findAllByOrder(); List<PayChannelConfig> channels = channelConfigManager.findAllByOrder();
// 查询当前应用所拥有的配置, 进行合并生成相关信息 // 查询当前应用所拥有的配置, 进行合并生成相关信息
val mchAppPayConfigMap = mchAppPayConfigManager.findAllByField(MchAppPayConfig::getAppCode, appId) val mchAppPayConfigMap = mchAppPayConfigManager.findAllByField(MchAppPayConfig::getAppCode, appCode)
.stream() .stream()
.collect(Collectors.toMap(MchAppPayConfig::getChannel, Function.identity())); .collect(Collectors.toMap(MchAppPayConfig::getChannel, Function.identity()));
// 进行排序并返回 // 进行排序并返回

View File

@@ -34,6 +34,10 @@ public class PayNotifyRecord extends MpBaseEntity implements EntityBaseFunction<
@DbComment("支付记录id") @DbComment("支付记录id")
private Long paymentId; private Long paymentId;
/** 商户编码 */
@DbComment("商户编码")
private String mchCode;
/** 商户应用编码 */ /** 商户应用编码 */
@DbComment("商户应用编码") @DbComment("商户应用编码")
private String mchAppCode; private String mchAppCode;

View File

@@ -36,7 +36,7 @@ public abstract class AbsPayCallbackStrategy {
/** /**
* 支付回调 * 支付回调
*/ */
public String payCallback(String appCode, Map<String, String> params) { public String payCallback(String mchCode,String appCode, Map<String, String> params) {
PARAMS.set(params); PARAMS.set(params);
try { try {
log.info("支付回调处理: {}", params); log.info("支付回调处理: {}", params);
@@ -49,10 +49,10 @@ public abstract class AbsPayCallbackStrategy {
return this.getReturnMsg(); return this.getReturnMsg();
} }
// 调用统一回调处理 // 调用统一回调处理
PayCallbackResult result = payCallbackService.callback(appCode, this.getPaymentId(), this.getTradeStatus(), PayCallbackResult result = payCallbackService.callback(this.getPaymentId(), this.getTradeStatus(),
params); params);
// 记录回调记录 // 记录回调记录
this.saveNotifyRecord(appCode, result); this.saveNotifyRecord(mchCode,appCode, result);
} }
finally { finally {
PARAMS.remove(); PARAMS.remove();
@@ -100,14 +100,15 @@ public abstract class AbsPayCallbackStrategy {
/** /**
* 保存回调记录 * 保存回调记录
*/ */
public void saveNotifyRecord(String appCode, PayCallbackResult result) { public void saveNotifyRecord(String mchCode,String appCode, PayCallbackResult result) {
PayNotifyRecord payNotifyRecord = new PayNotifyRecord().setNotifyInfo(JSONUtil.toJsonStr(PARAMS.get())) PayNotifyRecord payNotifyRecord = new PayNotifyRecord().setNotifyInfo(JSONUtil.toJsonStr(PARAMS.get()))
.setNotifyTime(LocalDateTime.now()) .setNotifyTime(LocalDateTime.now())
.setPaymentId(this.getPaymentId()) .setPaymentId(this.getPaymentId())
.setMchAppCode(appCode) .setMchAppCode(appCode)
.setPayChannel(this.getPayChannel().getCode()) .setMchCode(mchCode)
.setStatus(result.getCode()) .setPayChannel(this.getPayChannel().getCode())
.setMsg(result.getMsg()); .setStatus(result.getCode())
.setMsg(result.getMsg());
payNotifyRecordManager.save(payNotifyRecord); payNotifyRecordManager.save(payNotifyRecord);
} }

View File

@@ -44,11 +44,10 @@ public class PayCallbackService {
/** /**
* 统一回调处理 * 统一回调处理
* @param appCode
* @param tradeStatus 支付状态 * @param tradeStatus 支付状态
* @see PayStatusCode * @see PayStatusCode
*/ */
public PayCallbackResult callback(String appCode, Long paymentId, String tradeStatus, Map<String, String> map) { public PayCallbackResult callback(Long paymentId, String tradeStatus, Map<String, String> map) {
// 获取payment和paymentParam数据 // 获取payment和paymentParam数据
Payment payment = paymentService.findById(paymentId).orElse(null); Payment payment = paymentService.findById(paymentId).orElse(null);

View File

@@ -1,14 +1,13 @@
package cn.bootx.platform.daxpay.core.payment.dao; package cn.bootx.platform.daxpay.core.payment.dao;
import cn.bootx.platform.common.core.rest.param.OrderParam;
import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager; import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil; import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.entity.QueryOrder;
import cn.bootx.platform.common.query.entity.QueryParams; import cn.bootx.platform.common.query.entity.QueryParams;
import cn.bootx.platform.common.query.generator.QueryGenerator; import cn.bootx.platform.common.query.generator.QueryGenerator;
import cn.bootx.platform.daxpay.core.payment.entity.Payment; import cn.bootx.platform.daxpay.core.payment.entity.Payment;
import cn.bootx.platform.daxpay.param.payment.PaymentQuery; import cn.bootx.platform.daxpay.param.payment.PaymentQuery;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -18,7 +17,6 @@ import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import static cn.bootx.platform.daxpay.code.CachingCode.PAYMENT_BUSINESS_ID; import static cn.bootx.platform.daxpay.code.CachingCode.PAYMENT_BUSINESS_ID;
@@ -52,20 +50,14 @@ public class PaymentManager extends BaseManager<PaymentMapper, Payment> {
/** /**
* 分页查询 * 分页查询
*/ */
public Page<Payment> page(PageParam pageParam, PaymentQuery param, OrderParam orderParam) { public Page<Payment> page(PageParam pageParam, PaymentQuery param, QueryOrder queryOrder) {
Page<Payment> mpPage = MpUtil.getMpPage(pageParam, Payment.class); Page<Payment> mpPage = MpUtil.getMpPage(pageParam, Payment.class);
return query().select(Payment.class, MpUtil::excludeBigField) QueryWrapper<Payment> wrapper = QueryGenerator.generator(param, queryOrder);
.orderBy(Objects.nonNull(orderParam.getSortField()), orderParam.isAsc(), return this.page(mpPage,wrapper);
StrUtil.toUnderlineCase(orderParam.getSortField()))
.like(Objects.nonNull(param.getPaymentId()), MpUtil.getColumnName(Payment::getId), param.getPaymentId())
.like(Objects.nonNull(param.getBusinessId()), MpUtil.getColumnName(Payment::getBusinessId),
param.getBusinessId())
.like(Objects.nonNull(param.getTitle()), MpUtil.getColumnName(Payment::getTitle), param.getTitle())
.page(mpPage);
} }
/** /**
* 分页查询 * 超级分页查询
*/ */
public Page<Payment> superPage(PageParam pageParam, QueryParams queryParams) { public Page<Payment> superPage(PageParam pageParam, QueryParams queryParams) {
QueryWrapper<Payment> wrapper = QueryGenerator.generator(queryParams); QueryWrapper<Payment> wrapper = QueryGenerator.generator(queryParams);

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.core.payment.entity; package cn.bootx.platform.daxpay.core.payment.entity;
import cn.bootx.mybatis.table.modify.annotation.DbColumn; import cn.bootx.mybatis.table.modify.annotation.DbColumn;
import cn.bootx.mybatis.table.modify.annotation.DbComment;
import cn.bootx.mybatis.table.modify.annotation.DbTable; import cn.bootx.mybatis.table.modify.annotation.DbTable;
import cn.bootx.platform.common.core.annotation.BigField; import cn.bootx.platform.common.core.annotation.BigField;
import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.core.function.EntityBaseFunction;
@@ -31,6 +32,7 @@ import java.util.List;
@DbTable(isAppend = true) @DbTable(isAppend = true)
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@DbComment("支付记录")
@FieldNameConstants @FieldNameConstants
@Accessors(chain = true) @Accessors(chain = true)
@TableName(value = "pay_payment", autoResultMap = true) @TableName(value = "pay_payment", autoResultMap = true)

View File

@@ -2,9 +2,9 @@ package cn.bootx.platform.daxpay.core.payment.service;
import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.OrderParam;
import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil; import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.entity.QueryOrder;
import cn.bootx.platform.common.query.entity.QueryParams; import cn.bootx.platform.common.query.entity.QueryParams;
import cn.bootx.platform.daxpay.core.payment.dao.PaymentManager; import cn.bootx.platform.daxpay.core.payment.dao.PaymentManager;
import cn.bootx.platform.daxpay.core.payment.entity.Payment; import cn.bootx.platform.daxpay.core.payment.entity.Payment;
@@ -64,8 +64,8 @@ public class PaymentQueryService {
/** /**
* 分页 * 分页
*/ */
public PageResult<PaymentDto> page(PageParam pageParam, PaymentQuery param, OrderParam orderParam) { public PageResult<PaymentDto> page(PageParam pageParam, PaymentQuery param, QueryOrder queryOrder) {
return MpUtil.convert2DtoPageResult(paymentManager.page(pageParam, param, orderParam)); return MpUtil.convert2DtoPageResult(paymentManager.page(pageParam, param, queryOrder));
} }
/** /**

View File

@@ -25,7 +25,7 @@ public class MchApplicationDto extends BaseDto {
private String name; private String name;
@Schema(description = "商户号") @Schema(description = "商户号")
private String mchNo; private String mchCode;
@Schema(description = "状态类型") @Schema(description = "状态类型")
private String state; private String state;

View File

@@ -28,7 +28,7 @@ public class PaymentDto extends BaseDto implements Serializable {
private String businessId; private String businessId;
@Schema(description = "商户编码") @Schema(description = "商户编码")
private String mchNo; private String mchCode;
@Schema(description = "商户应用编码") @Schema(description = "商户应用编码")
private String mchAppNo; private String mchAppNo;

View File

@@ -82,7 +82,7 @@ public class WeChatPayConfigParam {
private Boolean activity; private Boolean activity;
@Schema(description = "状态") @Schema(description = "状态")
private Integer state; private String state;
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;

View File

@@ -1,5 +1,6 @@
package cn.bootx.platform.daxpay.param.merchant; package cn.bootx.platform.daxpay.param.merchant;
import cn.bootx.platform.common.core.annotation.QueryParam;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -11,6 +12,7 @@ import lombok.experimental.Accessors;
* @date 2023-05-19 * @date 2023-05-19
*/ */
@Data @Data
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Schema(title = "商户应用") @Schema(title = "商户应用")
@Accessors(chain = true) @Accessors(chain = true)
public class MchApplicationParam { public class MchApplicationParam {
@@ -19,13 +21,13 @@ public class MchApplicationParam {
private Long id; private Long id;
@Schema(description = "应用编码") @Schema(description = "应用编码")
private String appNo; private String code;
@Schema(description = "名称") @Schema(description = "名称")
private String name; private String name;
@Schema(description = "商户号") @Schema(description = "商户号")
private String mchNo; private String mchCode;
@Schema(description = "状态类型") @Schema(description = "状态类型")
private String state; private String state;

View File

@@ -1,5 +1,6 @@
package cn.bootx.platform.daxpay.param.payment; package cn.bootx.platform.daxpay.param.payment;
import cn.bootx.platform.common.core.annotation.QueryParam;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -12,6 +13,7 @@ import java.io.Serializable;
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Schema(title = "支付记录查询参数") @Schema(title = "支付记录查询参数")
public class PaymentQuery implements Serializable { public class PaymentQuery implements Serializable {
@@ -23,7 +25,13 @@ public class PaymentQuery implements Serializable {
@Schema(description = "关联的业务id") @Schema(description = "关联的业务id")
private String businessId; private String businessId;
@Schema(description = "关联的业务id") @Schema(description = "标题")
private String title; private String title;
@Schema(description = "商户编码")
private String mchCode;
@Schema(description = "商户编应用码")
private String mchAppCode;
} }

View File

@@ -27,7 +27,7 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
<!-- 二方库版本 --> <!-- 二方库版本 -->
<bootx-platform.version>1.3.0</bootx-platform.version> <bootx-platform.version>1.3.1</bootx-platform.version>
<!-- 三方库 --> <!-- 三方库 -->
<hutool.version>5.8.15</hutool.version> <hutool.version>5.8.15</hutool.version>
<oshi.version>6.4.0</oshi.version> <oshi.version>6.4.0</oshi.version>