pull/1121/head
梁宇奇 2025-08-21 16:13:37 +08:00
parent 5ef0e1ef5c
commit 11cb532cf6
7 changed files with 117 additions and 61 deletions

View File

@ -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;

View File

@ -78,6 +78,10 @@ public class FinanceBill extends SimpleEntity {
*
*/
private String remark;
/**
*
*/
private String extInfo;
/**
*
*/

View File

@ -77,6 +77,10 @@ public class FinanceBillDTO {
*
*/
private String remark;
/**
*
*/
private String extInfo;
/**
* 0 2
*/

View File

@ -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);
}
}
}

View File

@ -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<TransDetailStorePageItemDTO> 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<TransDetailUserPageItemDTO> 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<EPayChannel, List<WithdrawPrepareResult>> getNeedContinueWithdrawGroupMap(Integer count) {
//TODO 付款单据没有支付渠道和账户快照
Map<EPayChannel, List<WithdrawPrepareResult>> rtn = new HashMap<>(EPayChannel.values().length);
List<FinanceBillDTO> bills = financeBillService.listByStatus(EFinBillStatus.PROCESSING,
EFinBillType.PAYMENT, EFinBillSrcType.WITHDRAW, count);
List<WithdrawPrepareResult> 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<EPayChannel, List<WithdrawPrepareResult>> rtn = new HashMap<>(1);
rtn.put(EPayChannel.ALI_PAY, results);
return rtn;
}

View File

@ -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<String, ExpressFeeConfig> 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<String, ExpressFeeConfig> 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;
}

View File

@ -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));