diff --git a/sql/ry_20240629.sql b/sql/ry_20240629.sql index f59af41f7..6fb278b0c 100644 --- a/sql/ry_20240629.sql +++ b/sql/ry_20240629.sql @@ -2818,6 +2818,7 @@ CREATE TABLE `finance_bill` `business_amount` decimal(18, 2) NOT NULL COMMENT '业务金额', `trans_amount` decimal(18, 2) NOT NULL COMMENT '交易金额', `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `ext_info` varchar(2048) DEFAULT NULL COMMENT '扩展信息', `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', @@ -4252,6 +4253,11 @@ CREATE TABLE `user_subscriptions` PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户关注u档口' ROW_FORMAT = DYNAMIC; +-- 快递费用初始化(测试,上线前根据实际费用调整) +INSERT INTO express_fee_config ( express_id, region_code, first_item_amount, next_item_amount ) +SELECT 1, region_code, 5, 5 FROM express_region WHERE region_level = 1; +INSERT INTO express_fee_config ( express_id, region_code, first_item_amount, next_item_amount ) +SELECT 2, region_code, 5, 5 FROM express_region WHERE region_level = 1; diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/FinanceBill.java b/xkt/src/main/java/com/ruoyi/xkt/domain/FinanceBill.java index 368c91c48..86df3a2aa 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/FinanceBill.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/FinanceBill.java @@ -78,6 +78,10 @@ public class FinanceBill extends SimpleEntity { * 备注 */ private String remark; + /** + * 扩展信息 + */ + private String extInfo; /** * 版本号 */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillDTO.java index 45e9c1e98..727bca4df 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillDTO.java @@ -77,6 +77,10 @@ public class FinanceBillDTO { * 备注 */ private String remark; + /** + * 扩展信息 + */ + private String extInfo; /** * 删除标志(0代表存在 2代表删除) */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillExtInfo.java b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillExtInfo.java new file mode 100644 index 000000000..e0e6d3974 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/FinanceBillExtInfo.java @@ -0,0 +1,47 @@ +package com.ruoyi.xkt.dto.finance; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author liangyq + * @date 2025-08-21 + */ +public class FinanceBillExtInfo { + + private FinanceBillExtInfo() { + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class PaymentWithdraw { + /** + * 支付渠道 + * {@link com.ruoyi.xkt.enums.EPayChannel} + */ + private Integer payChannel; + /** + * 账户 + */ + private String accountOwnerNumber; + /** + * 真实姓名 + */ + private String accountOwnerName; + /** + * 手机号 + */ + private String accountOwnerPhoneNumber; + + public static PaymentWithdraw parse(String jsonStr) { + return JSONUtil.toBean(jsonStr, PaymentWithdraw.class); + } + + public String toJsonStr() { + return JSONUtil.toJsonStr(this); + } + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AssetServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AssetServiceImpl.java index bb68a66aa..6974d184b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AssetServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AssetServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; +import cn.hutool.json.JSONUtil; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.ruoyi.common.constant.CacheConstants; @@ -21,10 +22,7 @@ import com.ruoyi.xkt.domain.FinanceBill; import com.ruoyi.xkt.domain.InternalAccount; import com.ruoyi.xkt.domain.Store; import com.ruoyi.xkt.dto.account.*; -import com.ruoyi.xkt.dto.finance.FinanceBillDTO; -import com.ruoyi.xkt.dto.finance.FinanceBillExt; -import com.ruoyi.xkt.dto.finance.RechargeAddDTO; -import com.ruoyi.xkt.dto.finance.RechargeAddResult; +import com.ruoyi.xkt.dto.finance.*; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.mapper.StoreMapper; @@ -90,12 +88,14 @@ public class AssetServiceImpl implements IAssetService { throw new ServiceException("支付密码错误"); } FinanceBillExt financeBillExt = financeBillService.createWithdrawPaymentBill(storeId, amount, payChannel); + FinanceBillExtInfo.PaymentWithdraw extInfo = FinanceBillExtInfo.PaymentWithdraw + .parse(financeBillExt.getFinanceBill().getExtInfo()); return new WithdrawPrepareResult(financeBillExt.getFinanceBill().getId(), financeBillExt.getFinanceBill().getBillNo(), financeBillExt.getFinanceBill().getTransAmount(), - externalAccount.getAccountOwnerNumber(), - externalAccount.getAccountOwnerName(), - externalAccount.getAccountOwnerPhoneNumber()); + extInfo.getAccountOwnerNumber(), + extInfo.getAccountOwnerName(), + extInfo.getAccountOwnerPhoneNumber()); } @Transactional(rollbackFor = Exception.class) @@ -218,7 +218,7 @@ public class AssetServiceImpl implements IAssetService { Assert.notNull(internalAccount); Page page = PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize(), "iatd.trans_time DESC"); - TransDetailQueryDTO tdq = BeanUtil.toBean(queryDTO,TransDetailQueryDTO.class); + TransDetailQueryDTO tdq = BeanUtil.toBean(queryDTO, TransDetailQueryDTO.class); tdq.setInternalAccountId(internalAccount.getId()); internalAccountService.listStoreTransDetailPageItem(tdq); return page; @@ -229,7 +229,7 @@ public class AssetServiceImpl implements IAssetService { Assert.notNull(queryDTO.getUserId()); Page page = PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize(), "fb.create_time DESC"); - TransDetailQueryDTO tdq = BeanUtil.toBean(queryDTO,TransDetailQueryDTO.class); + TransDetailQueryDTO tdq = BeanUtil.toBean(queryDTO, TransDetailQueryDTO.class); tdq.setUserId(queryDTO.getUserId()); internalAccountService.listUserTransDetailPageItem(tdq); return page; @@ -325,23 +325,24 @@ public class AssetServiceImpl implements IAssetService { @Override public Map> getNeedContinueWithdrawGroupMap(Integer count) { - //TODO 付款单据没有支付渠道和账户快照 + Map> rtn = new HashMap<>(EPayChannel.values().length); List bills = financeBillService.listByStatus(EFinBillStatus.PROCESSING, EFinBillType.PAYMENT, EFinBillSrcType.WITHDRAW, count); - List results = new ArrayList<>(bills.size()); for (FinanceBillDTO bill : bills) { - Long storeId = bill.getSrcId(); - ExternalAccount externalAccount = externalAccountService.getAccountAndCheck(storeId, - EAccountOwnerType.STORE, EAccountType.ALI_PAY); - results.add(new WithdrawPrepareResult(bill.getId(), - bill.getBillNo(), - bill.getTransAmount(), - externalAccount.getAccountOwnerNumber(), - externalAccount.getAccountOwnerName(), - externalAccount.getAccountOwnerPhoneNumber())); + if (StrUtil.isEmpty(bill.getExtInfo())) { + continue; + } + FinanceBillExtInfo.PaymentWithdraw withdrawInfo = FinanceBillExtInfo.PaymentWithdraw + .parse(bill.getExtInfo()); + EPayChannel payChannel = EPayChannel.of(withdrawInfo.getPayChannel()); + rtn.computeIfAbsent(payChannel, k -> new ArrayList<>()) + .add(new WithdrawPrepareResult(bill.getId(), + bill.getBillNo(), + bill.getTransAmount(), + withdrawInfo.getAccountOwnerNumber(), + withdrawInfo.getAccountOwnerName(), + withdrawInfo.getAccountOwnerPhoneNumber())); } - Map> rtn = new HashMap<>(1); - rtn.put(EPayChannel.ALI_PAY, results); return rtn; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java index 664e2fdbd..e53293683 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java @@ -25,10 +25,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -116,34 +113,28 @@ public class ExpressServiceImpl implements IExpressService { Assert.notEmpty(provinceCode); Assert.notEmpty(cityCode); Assert.notEmpty(countyCode); - //TODO mock -// Map map = expressFeeConfigMapper.selectList(Wrappers.lambdaQuery(ExpressFeeConfig.class) -// .eq(ExpressFeeConfig::getExpressId, expressId) -// .in(ExpressFeeConfig::getRegionCode, Arrays.asList(provinceCode, cityCode, countyCode))) -// .stream() -// //过滤掉已被删除的配置 -// .filter(BeanValidators::exists) -// .collect(Collectors.toMap(o -> o.getRegionCode(), o -> o, (n, o) -> n)); -// ExpressFeeConfig expressFeeConfig = null; -// if (CollUtil.isNotEmpty(map)) { -// if (map.size() == 1) { -// expressFeeConfig = CollUtil.getFirst(map.values()); -// } else { -// expressFeeConfig = map.get(countyCode); -// //按区市省从小到大去匹配 -// if (expressFeeConfig == null) { -// expressFeeConfig = map.get(cityCode); -// if (expressFeeConfig == null) { -// expressFeeConfig = map.get(provinceCode); -// } -// } -// } -// } - ExpressFeeConfig expressFeeConfig = new ExpressFeeConfig(); - expressFeeConfig.setExpressId(expressId); - expressFeeConfig.setFirstItemAmount(BigDecimal.valueOf(5)); - expressFeeConfig.setNextItemAmount(BigDecimal.valueOf(5)); - expressFeeConfig.setDelFlag(Constants.UNDELETED); + Map map = expressFeeConfigMapper.selectList(Wrappers.lambdaQuery(ExpressFeeConfig.class) + .eq(ExpressFeeConfig::getExpressId, expressId) + .in(ExpressFeeConfig::getRegionCode, Arrays.asList(provinceCode, cityCode, countyCode))) + .stream() + //过滤掉已被删除的配置 + .filter(BeanValidators::exists) + .collect(Collectors.toMap(ExpressFeeConfig::getRegionCode, o -> o, (o, n) -> n)); + ExpressFeeConfig expressFeeConfig = null; + if (CollUtil.isNotEmpty(map)) { + if (map.size() == 1) { + expressFeeConfig = CollUtil.getFirst(map.values()); + } else { + expressFeeConfig = map.get(countyCode); + //按区市省从小到大去匹配 + if (expressFeeConfig == null) { + expressFeeConfig = map.get(cityCode); + if (expressFeeConfig == null) { + expressFeeConfig = map.get(provinceCode); + } + } + } + } return expressFeeConfig; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java index ede0ebb1f..1b7e05afa 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java @@ -16,12 +16,10 @@ import com.ruoyi.common.core.domain.SimpleEntity; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.bean.BeanValidators; -import com.ruoyi.xkt.domain.FinanceBill; -import com.ruoyi.xkt.domain.FinanceBillDetail; -import com.ruoyi.xkt.domain.InternalAccount; -import com.ruoyi.xkt.domain.StoreOrderDetail; +import com.ruoyi.xkt.domain.*; import com.ruoyi.xkt.dto.finance.FinanceBillDTO; import com.ruoyi.xkt.dto.finance.FinanceBillExt; +import com.ruoyi.xkt.dto.finance.FinanceBillExtInfo; import com.ruoyi.xkt.dto.finance.TransInfo; import com.ruoyi.xkt.dto.order.StoreOrderExt; import com.ruoyi.xkt.enums.*; @@ -408,13 +406,18 @@ public class FinanceBillServiceImpl implements IFinanceBillService { bill.setBusinessUniqueKey(businessUniqueKey); Long outputInternalAccountId = internalAccountService.getAccountAndCheck(storeId, EAccountOwnerType.STORE) .getId(); - Long inputExternalAccountId = externalAccountService.getAccountAndCheck(storeId, EAccountOwnerType.STORE, - EAccountType.getByChannel(payChannel)).getId(); + ExternalAccount inputExternalAccount = externalAccountService.getAccountAndCheck(storeId, + EAccountOwnerType.STORE, EAccountType.getByChannel(payChannel)); + FinanceBillExtInfo.PaymentWithdraw extInfo = new FinanceBillExtInfo.PaymentWithdraw(payChannel.getValue(), + inputExternalAccount.getAccountOwnerNumber(), inputExternalAccount.getAccountOwnerName(), + inputExternalAccount.getAccountOwnerPhoneNumber()); + bill.setExtInfo(extInfo.toJsonStr()); + Long inputExternalAccountId = inputExternalAccount.getId(); bill.setOutputInternalAccountId(outputInternalAccountId); bill.setInputExternalAccountId(inputExternalAccountId); bill.setOutputExternalAccountId(payChannel.getPlatformExternalAccountId()); bill.setBusinessAmount(amount); - //支付宝服务费 TODO 再次确认 + //支付宝服务费 BigDecimal aliServiceFee = NumberUtil.mul(amount, Constants.ALI_SERVICE_FEE_RATE) .setScale(2, RoundingMode.HALF_UP); bill.setTransAmount(NumberUtil.sub(amount, aliServiceFee));