feat 钱包/储值卡/现金管理

This commit is contained in:
bootx
2024-02-18 21:37:08 +08:00
parent 47ed8e9265
commit 2c8d9aa386
51 changed files with 896 additions and 361 deletions

View File

@@ -0,0 +1,29 @@
package cn.bootx.platform.daxpay.service.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 现金记录类型
* @author xxm
* @since 2024/2/18
*/
@Getter
@AllArgsConstructor
public enum CashrRecordTypeEnum {
/** 支付 */
PAY("pay", "支付"),
/** 退款 */
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
private final String code;
private final String name;
}

View File

@@ -0,0 +1,32 @@
package cn.bootx.platform.daxpay.service.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 储值卡记录类型
* @author xxm
* @since 2024/2/18
*/
@Getter
@AllArgsConstructor
public enum VoucherRecordTypeEnum {
/** 导入 */
IMPORT("import", "导入"),
/** 支付 */
PAY("pay", "支付"),
/** 退款 */
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
private final String code;
private final String name;
}

View File

@@ -0,0 +1,32 @@
package cn.bootx.platform.daxpay.service.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 钱包记录类型
* @author xxm
* @since 2024/2/18
*/
@Getter
@AllArgsConstructor
public enum WalletRecordTypeEnum {
/** 创建 */
CREATE("create", "创建"),
/** 支付 */
PAY("pay", "支付"),
/** 退款 */
REFUND("refund", "退款"),
/** 支付关闭 */
CLOSE_PAY("close_pay", "支付关闭"),
/** 退款关闭 */
CLOSE_REFUND("close_refund", "退款关闭");
private final String code;
private final String name;
}

View File

@@ -37,7 +37,7 @@ public class AliPayConfig extends MpBaseEntity implements EntityBaseFunction<Ali
@DbColumn(comment = "支付宝商户appId")
private String appId;
/** 是否启用 */
/** 是否启用, 只影响支付和退款操作 */
@DbColumn(comment = "是否启用")
private Boolean enable;

View File

@@ -4,6 +4,7 @@ import cn.bootx.platform.common.core.exception.BizException;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.dto.LabelValue;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.service.code.AliPayCode;
import cn.bootx.platform.daxpay.service.code.AliPayWay;
import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliPayConfigManager;
@@ -72,6 +73,17 @@ public class AliPayConfigService {
return alipayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("支付宝配置不存在"));
}
/**
* 获取并检查支付配置
*/
public AliPayConfig getAndCheckConfig() {
AliPayConfig alipayConfig = this.getConfig();
if (!alipayConfig.getEnable()){
throw new PayFailureException("支付宝支付方式未启用");
}
return alipayConfig;
}
/**
* 初始化IJPay服务

View File

@@ -1,7 +1,9 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.convert;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashConfig;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashRecord;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashPayConfigDto;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashRecordDto;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -16,4 +18,6 @@ public interface CashPayConfigConvert {
CashPayConfigDto convert(CashConfig in);
CashRecordDto convert(CashRecord in);
}

View File

@@ -0,0 +1,33 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.dao;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.generator.QueryGenerator;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashRecord;
import cn.bootx.platform.daxpay.service.param.channel.cash.CashRecordQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
/**
*
* @author xxm
* @since 2024/2/18
*/
@Slf4j
@Repository
@RequiredArgsConstructor
public class CashRecordManager extends BaseManager<CashRecordMapper, CashRecord> {
/**
* 分页
*/
public Page<CashRecord> page(PageParam pageParam, CashRecordQuery param){
Page<CashRecord> mpPage = MpUtil.getMpPage(pageParam, CashRecord.class);
QueryWrapper<CashRecord> generator = QueryGenerator.generator(param);
return this.page(mpPage, generator);
}
}

View File

@@ -0,0 +1,14 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.dao;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
*
* @author xxm
* @since 2024/2/18
*/
@Mapper
public interface CashRecordMapper extends BaseMapper<CashRecord> {
}

View File

@@ -0,0 +1,60 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.bootx.platform.daxpay.service.code.VoucherRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.convert.CashPayConfigConvert;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashRecordDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 现金记录
* @author xxm
* @since 2024/2/17
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@DbTable(comment = "现金记录")
public class CashRecord extends MpCreateEntity implements EntityBaseFunction<CashRecordDto> {
/** 储值卡id */
@DbMySqlIndex(comment = "储值卡ID")
@DbColumn(comment = "储值卡id")
private Long voucherId;
/**
* 业务类型
* @see VoucherRecordTypeEnum
*/
@DbColumn(comment = "业务类型")
private String type;
/** 金额 */
@DbColumn(comment = "金额")
private Integer amount;
/**
* 交易订单号
* 支付订单/退款订单
*/
@DbColumn(comment = "交易订单号")
private String orderId;
/** 终端ip */
@DbColumn(comment = "终端ip")
private String ip;
/**
* 转换
*/
@Override
public CashRecordDto toDto() {
return CashPayConfigConvert.CONVERT.convert(this);
}
}

View File

@@ -0,0 +1,39 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.cash.dao.CashRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.cash.entity.CashRecord;
import cn.bootx.platform.daxpay.service.dto.channel.cash.CashRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.cash.CashRecordQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 现金记录
*
* @author xxm
* @since 2021/6/23
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CashRecordService {
private final CashRecordManager manager;
/**
* 分页查询
*/
public PageResult<CashRecordDto> page(PageParam pageParam, CashRecordQuery param) {
return MpUtil.convert2DtoPageResult(manager.page(pageParam, param));
}
/**
* 查询详情
*/
public CashRecordDto findById(Long id){
return manager.findById(id).map(CashRecord::toDto).orElseGet(CashRecordDto::new);
}
}

View File

@@ -1,24 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.cash.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 现金支付
*
* @author xxm
* @since 2021/6/23
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CashService {
/**
* 退款
*/
public void refund(Long paymentId, int amount) {
}
}

View File

@@ -2,10 +2,10 @@ package cn.bootx.platform.daxpay.service.core.channel.voucher.convert;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherConfig;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherLog;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherConfigDto;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherDto;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherLogDto;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherBatchImportParam;
import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherImportParam;
import org.mapstruct.Mapper;
@@ -22,9 +22,9 @@ public interface VoucherConvert {
VoucherDto convert(Voucher in);
VoucherConfigDto convert(VoucherConfig in);
VoucherRecordDto convert(VoucherRecord in);
VoucherLogDto convert(VoucherLog in);
VoucherConfigDto convert(VoucherConfig in);
Voucher convert(VoucherImportParam in);

View File

@@ -1,33 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.dao;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherLog;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
/**
* @author xxm
* @since 2022/3/19
*/
@Slf4j
@Repository
@RequiredArgsConstructor
public class VoucherLogManager extends BaseManager<VoucherLogMapper, VoucherLog> {
/**
* 根据储值卡id进行分页
*/
public Page<VoucherLog> pageByVoucherId(PageParam pageParam, Long voucherId) {
Page<VoucherLog> mpPage = MpUtil.getMpPage(pageParam,VoucherLog.class);
return lambdaQuery()
.eq(VoucherLog::getVoucherId, voucherId)
.orderByDesc(MpIdEntity::getId)
.page(mpPage);
}
}

View File

@@ -0,0 +1,33 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.dao;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.generator.QueryGenerator;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherRecordQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
/**
*
* @author xxm
* @since 2024/2/18
*/
@Slf4j
@Repository
@RequiredArgsConstructor
public class VoucherRecordManager extends BaseManager<VoucherRecordMapper, VoucherRecord> {
/**
* 分页
*/
public Page<VoucherRecord> page(PageParam pageParam, VoucherRecordQuery param){
Page<VoucherRecord> mpPage = MpUtil.getMpPage(pageParam, VoucherRecord.class);
QueryWrapper<VoucherRecord> generator = QueryGenerator.generator(param);
return this.page(mpPage, generator);
}
}

View File

@@ -1,14 +1,14 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.dao;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherLog;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
*
* @author xxm
* @since 2022/3/19
* @since 2024/2/18
*/
@Mapper
public interface VoucherLogMapper extends BaseMapper<VoucherLog> {
public interface VoucherRecordMapper extends BaseMapper<VoucherRecord> {
}

View File

@@ -41,7 +41,6 @@ public class Voucher extends MpBaseEntity implements EntityBaseFunction<VoucherD
@DbColumn(comment = "余额")
private Integer balance;
/** 是否长期有效 */
@DbColumn(comment = "是否长期有效")
private boolean enduring;

View File

@@ -1,68 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.service.code.VoucherCode;
import cn.bootx.platform.daxpay.service.core.channel.voucher.convert.VoucherConvert;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherLogDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 储值卡日志
*
* @author xxm
* @since 2022/3/17
*/
@EqualsAndHashCode(callSuper = true)
@Data
@DbTable(comment = "储值卡日志")
@Accessors(chain = true)
@TableName("pay_voucher_log")
public class VoucherLog extends MpBaseEntity implements EntityBaseFunction<VoucherLogDto> {
/** 储值卡id */
@DbMySqlIndex(comment = "储值卡ID")
@DbColumn(comment = "储值卡id")
private Long voucherId;
/** 储值卡号 */
@DbColumn(comment = "储值卡号")
private String voucherNo;
/** 金额 */
@DbColumn(comment = "金额")
private Integer amount;
/**
* 类型
* @see VoucherCode#LOG_PAY
*/
@DbColumn(comment = "类型")
private String type;
/** 交易记录ID */
@DbColumn(comment = "交易记录ID")
private Long paymentId;
/** 业务ID */
@DbColumn(comment = "业务ID")
private String businessId;
/** 备注 */
@DbColumn(comment = "备注")
private String remark;
/**
* 转换
*/
@Override
public VoucherLogDto toDto() {
return VoucherConvert.CONVERT.convert(this);
}
}

View File

@@ -1,20 +1,70 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.bootx.platform.daxpay.service.code.VoucherRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.voucher.convert.VoucherConvert;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherRecordDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 储值卡扣款记录列表
* 储值卡记录
* @author xxm
* @since 2023/6/29
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
public class VoucherRecord {
@TableName(value = "pay_voucher_record")
@DbTable(comment = "储值卡记录")
public class VoucherRecord extends MpCreateEntity implements EntityBaseFunction<VoucherRecordDto> {
/** 卡号 */
private String cardNo;
/** 储值卡id */
@DbMySqlIndex(comment = "储值卡ID")
@DbColumn(comment = "储值卡id")
private Long voucherId;
/** 扣款金额 */
/**
* 业务类型
* @see VoucherRecordTypeEnum
*/
@DbColumn(comment = "业务类型")
private String type;
/** 金额 */
@DbColumn(comment = "金额")
private Integer amount;
/** 变动之前的金额 */
@DbColumn(comment = "变动之前的金额")
private Integer oldAmount;
/** 变动之后的金额 */
@DbColumn(comment = "变动之后的金额")
private Integer newAmount;
/**
* 交易订单号
* 支付订单/退款订单
*/
@DbColumn(comment = "交易订单号")
private String orderId;
/** 终端ip */
@DbColumn(comment = "终端ip")
private String ip;
/**
* 转换
*/
@Override
public VoucherRecordDto toDto() {
return VoucherConvert.CONVERT.convert(this);
}
}

View File

@@ -1,32 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherLogManager;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherLogDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 储值卡日志
*
* @author xxm
* @since 2022/3/19
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class VoucherLogService {
private final VoucherLogManager voucherLogManager;
/**
* 储值卡日志分页
*/
public PageResult<VoucherLogDto> pageByVoucherId(PageParam pageParam, Long voucherId){
return MpUtil.convert2DtoPageResult(voucherLogManager.pageByVoucherId(pageParam,voucherId));
}
}

View File

@@ -53,14 +53,20 @@ public class VoucherQueryService {
.orElseThrow(() -> new DataNotExistException("储值卡不存在"));
}
/**
* 判断卡号是否存在
*/
public boolean existsByCardNo(String cardNo){
return voucherManager.existsByCardNo(cardNo);
}
/**
* 获取并判断卡状态
*/
public VoucherDto getAndJudgeVoucher(String cardNo){
Voucher voucher = voucherManager.findByCardNo(cardNo)
.orElseThrow(() -> new DataNotExistException("储值卡不存在"));
Voucher voucher = voucherManager.findByCardNo(cardNo).orElseThrow(() -> new DataNotExistException("储值卡不存在"));
// 过期
String checkMsg = check(voucher);
String checkMsg = this.check(voucher);
if (StrUtil.isNotBlank(checkMsg)){
throw new PayFailureException(checkMsg);
}

View File

@@ -0,0 +1,38 @@
package cn.bootx.platform.daxpay.service.core.channel.voucher.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.voucher.dao.VoucherRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.service.dto.channel.voucher.VoucherRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.voucher.VoucherRecordQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 储值卡记录
* @author xxm
* @since 2024/2/18
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class VoucherRecordService {
private final VoucherRecordManager manager;
/**
* 分页查询
*/
public PageResult<VoucherRecordDto> page(PageParam pageParam, VoucherRecordQuery param) {
return MpUtil.convert2DtoPageResult(manager.page(pageParam, param));
}
/**
* 查询详情
*/
public VoucherRecordDto findById(Long id){
return manager.findById(id).map(VoucherRecord::toDto).orElseGet(VoucherRecordDto::new);
}
}

View File

@@ -28,15 +28,15 @@ public class VoucherService {
private final VoucherManager voucherManager;
/**
* 导入
*/
@Transactional(rollbackFor = Exception.class)
public void voucherImport(VoucherImportParam param){
Voucher voucher = VoucherConvert.CONVERT.convert(param);
// 判断重复
if (voucherManager.existsByCardNo(param.getCardNo())) {
throw new BizException("钱包已经开通");
throw new BizException("储值卡已存在");
}
voucherManager.save(voucher);
}

View File

@@ -3,9 +3,11 @@ package cn.bootx.platform.daxpay.service.core.channel.wallet.convert;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletConfig;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletLog;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord;
import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletConfigDto;
import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletDto;
import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletLogDto;
import cn.bootx.platform.daxpay.service.dto.channel.wechat.WalletRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.wechat.WalletConfigParam;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -29,4 +31,6 @@ public interface WalletConvert {
WalletConfig convert(WalletConfigParam in);
WalletRecordDto convert(WalletRecord in);
}

View File

@@ -1,56 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.dao;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletLog;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletLogQueryParam;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.Objects;
/**
* 钱包日志
*
* @author xxm
* @since 2020/12/8
*/
@Repository
@RequiredArgsConstructor
public class WalletLogManager extends BaseManager<WalletLogMapper, WalletLog> {
/**
* 分页查询指定用户的钱包日志
*/
public Page<WalletLog> pageByUserId(PageParam pageParam, WalletLogQueryParam param, Long userId) {
Page<WalletLog> mpPage = MpUtil.getMpPage(pageParam, WalletLog.class);
return this.lambdaQuery().orderByDesc(MpIdEntity::getId).eq(WalletLog::getUserId, userId).page(mpPage);
}
/**
* 分页查询
*/
public Page<WalletLog> page(PageParam pageParam, WalletLogQueryParam query) {
Page<WalletLog> mpPage = MpUtil.getMpPage(pageParam, WalletLog.class);
return this.lambdaQuery()
.orderByDesc(MpIdEntity::getId)
.like(Objects.nonNull(query.getUserId()), WalletLog::getUserId, query.getUserId())
.like(Objects.nonNull(query.getWalletId()), WalletLog::getWalletId, query.getWalletId())
.page(mpPage);
}
/**
* 分页查询 根据钱包id
*/
public Page<WalletLog> pageByWalletId(PageParam pageParam, WalletLogQueryParam param) {
Page<WalletLog> mpPage = MpUtil.getMpPage(pageParam, WalletLog.class);
return this.lambdaQuery()
.orderByDesc(MpIdEntity::getId)
.eq(WalletLog::getWalletId, param.getWalletId())
.page(mpPage);
}
}

View File

@@ -5,7 +5,7 @@ import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.generator.QueryGenerator;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletQueryParam;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
@@ -44,7 +44,7 @@ public class WalletManager extends BaseManager<WalletMapper, Wallet> {
/**
* 分页查询
*/
public Page<Wallet> page(PageParam pageParam, WalletQueryParam param) {
public Page<Wallet> page(PageParam pageParam, WalletQuery param) {
QueryWrapper<Wallet> wrapper = QueryGenerator.generator(param);
Page<Wallet> mpPage = MpUtil.getMpPage(pageParam, Wallet.class);
return this.page(mpPage, wrapper);

View File

@@ -0,0 +1,33 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.dao;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.common.query.generator.QueryGenerator;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletRecordQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
/**
*
* @author xxm
* @since 2024/2/18
*/
@Slf4j
@Repository
@RequiredArgsConstructor
public class WalletRecordManager extends BaseManager<WalletRecordMapper, WalletRecord> {
/**
* 分页
*/
public Page<WalletRecord> page(PageParam pageParam, WalletRecordQuery param){
Page<WalletRecord> mpPage = MpUtil.getMpPage(pageParam, WalletRecord.class);
QueryWrapper<WalletRecord> generator = QueryGenerator.generator(param);
return this.page(mpPage, generator);
}
}

View File

@@ -1,16 +1,14 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.dao;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletLog;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 钱包日志
*
* @author xxm
* @since 2020/12/8
* @since 2024/2/18
*/
@Mapper
public interface WalletLogMapper extends BaseMapper<WalletLog> {
public interface WalletRecordMapper extends BaseMapper<WalletRecord> {
}

View File

@@ -0,0 +1,70 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.bootx.platform.daxpay.service.code.WalletRecordTypeEnum;
import cn.bootx.platform.daxpay.service.core.channel.wallet.convert.WalletConvert;
import cn.bootx.platform.daxpay.service.dto.channel.wechat.WalletRecordDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 钱包记录
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@DbTable(comment = "钱包记录")
@TableName("pay_wallet_record")
public class WalletRecord extends MpCreateEntity implements EntityBaseFunction<WalletRecordDto> {
/** 钱包id */
@DbMySqlIndex(comment = "钱包ID")
@DbColumn(comment = "钱包id")
private Long walletId;
/**
* 业务类型
* @see WalletRecordTypeEnum
*/
@DbColumn(comment = "业务类型")
private String type;
/** 金额 */
@DbColumn(comment = "金额")
private Integer amount;
/** 变动之前的金额 */
@DbColumn(comment = "变动之前的金额")
private Integer oldAmount;
/** 变动之后的金额 */
@DbColumn(comment = "变动之后的金额")
private Integer newAmount;
/**
* 交易订单号
* 支付订单/退款订单
*/
@DbColumn(comment = "交易订单号")
private String orderId;
/** 终端ip */
@DbColumn(comment = "终端ip")
private String ip;
/**
* 转换
*/
@Override
public WalletRecordDto toDto() {
return WalletConvert.CONVERT.convert(this);
}
}

View File

@@ -1,49 +0,0 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.service;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletLogManager;
import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletLogDto;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletLogQueryParam;
import cn.bootx.platform.starter.auth.util.SecurityUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 钱包日志
*
* @author xxm
* @since 2020/12/8
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WalletLogService {
private final WalletLogManager walletLogManager;
/**
* 个人钱包日志分页
*/
public PageResult<WalletLogDto> pageByPersonal(PageParam pageParam, WalletLogQueryParam param) {
Long userId = SecurityUtil.getUserId();
return MpUtil.convert2DtoPageResult(walletLogManager.pageByUserId(pageParam, param, userId));
}
/**
* 钱包日志分页
*/
public PageResult<WalletLogDto> page(PageParam pageParam, WalletLogQueryParam param) {
return MpUtil.convert2DtoPageResult(walletLogManager.page(pageParam, param));
}
/**
* 根据钱包id查询钱包日志(分页)
*/
public PageResult<WalletLogDto> pageByWalletId(PageParam pageParam, WalletLogQueryParam param) {
return MpUtil.convert2DtoPageResult(walletLogManager.pageByWalletId(pageParam, param));
}
}

View File

@@ -8,7 +8,7 @@ import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletManager;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet;
import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletDto;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletQueryParam;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -52,7 +52,7 @@ public class WalletQueryService {
/**
* 分页
*/
public PageResult<WalletDto> page(PageParam pageParam, WalletQueryParam param) {
public PageResult<WalletDto> page(PageParam pageParam, WalletQuery param) {
return MpUtil.convert2DtoPageResult(walletManager.page(pageParam, param));
}

View File

@@ -0,0 +1,40 @@
package cn.bootx.platform.daxpay.service.core.channel.wallet.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletRecordManager;
import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord;
import cn.bootx.platform.daxpay.service.dto.channel.wechat.WalletRecordDto;
import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletRecordQuery;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 钱包记录服务类
* @author xxm
* @since 2024/2/18
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WalletRecordService {
private final WalletRecordManager walletRecordManager;
/**
* 分页
*/
public PageResult<WalletRecordDto> page(PageParam pageParam, WalletRecordQuery param) {
return MpUtil.convert2DtoPageResult(walletRecordManager.page(pageParam, param));
}
/**
* 查询详情
*/
public WalletRecordDto findById(Long id){
return walletRecordManager.findById(id).map(WalletRecord::toDto).orElseThrow(DataNotExistException::new);
}
}

View File

@@ -93,7 +93,7 @@ public class WalletService {
if (Objects.isNull(wallet)){
wallet = walletManager.findByUser(param.getUserId()).orElseThrow(DataNotExistException::new);
}
if (wallet.getBalance() > param.getAmount()){
if (wallet.getBalance() < param.getAmount()){
throw new BizException("余额不足");
}
wallet.setBalance(wallet.getBalance() - param.getAmount());

View File

@@ -57,6 +57,17 @@ public class WeChatPayConfigService {
return weChatPayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("微信支付配置不存在"));
}
/**
* 获取并检查配置
*/
public WeChatPayConfig getAndCheckConfig(){
WeChatPayConfig weChatPayConfig = getConfig();
if (!weChatPayConfig.getEnable()){
throw new PayFailureException("微信支付配置未启用");
}
return weChatPayConfig;
}
/**
* 微信支持支付方式

View File

@@ -104,7 +104,7 @@ public class AliPayStrategy extends AbsPayStrategy {
*/
private void initAlipayConfig() {
// 获取并初始化支付宝支付配置
this.alipayConfig = alipayConfigService.getConfig();
this.alipayConfig = alipayConfigService.getAndCheckConfig();
alipayConfigService.initConfig(this.alipayConfig);
}

View File

@@ -99,7 +99,7 @@ public class WeChatPayStrategy extends AbsPayStrategy {
* 初始化微信支付
*/
private void initWeChatPayConfig() {
this.weChatPayConfig = weChatPayConfigService.getConfig();
this.weChatPayConfig = weChatPayConfigService.getAndCheckConfig();
}
}

View File

@@ -43,7 +43,7 @@ public class AliPayRefundStrategy extends AbsRefundStrategy {
*/
@Override
public void doBeforeRefundHandler() {
AliPayConfig config = alipayConfigService.getConfig();
AliPayConfig config = alipayConfigService.getAndCheckConfig();
alipayConfigService.initConfig(config);
}

View File

@@ -47,7 +47,7 @@ public class WeChatPayRefundStrategy extends AbsRefundStrategy {
*/
@Override
public void doBeforeRefundHandler() {
this.weChatPayConfig = weChatPayConfigService.getConfig();
this.weChatPayConfig = weChatPayConfigService.getAndCheckConfig();
}

View File

@@ -0,0 +1,19 @@
package cn.bootx.platform.daxpay.service.dto.channel.cash;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 现金记录
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@Schema(title = "现金记录")
public class CashRecordDto extends BaseDto {
}

View File

@@ -20,18 +20,9 @@ import java.time.LocalDateTime;
@Schema(title = "储值卡")
public class VoucherDto extends BaseDto {
@Schema(description = "商户编码")
private String mchCode;
@Schema(description = "商户应用编码")
private String mchAppCode;
@Schema(description = "卡号")
private String cardNo;
@Schema(description = "生成批次号")
private Long batchNo;
@Schema(description = "面值")
private BigDecimal faceValue;

View File

@@ -0,0 +1,54 @@
package cn.bootx.platform.daxpay.service.dto.channel.voucher;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.service.code.VoucherRecordTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 储值卡记录
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@Schema(title = "储值卡记录")
public class VoucherRecordDto extends BaseDto {
/** 储值卡id */
@Schema(description = "储值卡id")
private Long voucherId;
/**
* 业务类型
* @see VoucherRecordTypeEnum
*/
@Schema(description = "业务类型")
private String type;
/** 金额 */
@Schema(description = "金额")
private Integer amount;
/** 变动之前的金额 */
@Schema(description = "变动之前的金额")
private Integer oldAmount;
/** 变动之后的金额 */
@Schema(description = "变动之后的金额")
private Integer newAmount;
/**
* 交易订单号
* 支付订单/退款订单
*/
@Schema(description = "交易订单号")
private String orderId;
/** 终端ip */
@Schema(description = "终端ip")
private String ip;
}

View File

@@ -0,0 +1,54 @@
package cn.bootx.platform.daxpay.service.dto.channel.wechat;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.service.code.WalletRecordTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 钱包记录
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@Schema(title = "钱包记录")
public class WalletRecordDto extends BaseDto {
/** 钱包id */
@Schema(description = "钱包id")
private Long walletId;
/**
* 业务类型
* @see WalletRecordTypeEnum
*/
@Schema(description = "业务类型")
private String type;
/** 金额 */
@Schema(description = "金额")
private Integer amount;
/** 变动之前的金额 */
@Schema(description = "变动之前的金额")
private Integer oldAmount;
/** 变动之后的金额 */
@Schema(description = "变动之后的金额")
private Integer newAmount;
/**
* 交易订单号
* 支付订单/退款订单
*/
@Schema(description = "交易订单号")
private String orderId;
/** 终端ip */
@Schema(description = "终端ip")
private String ip;
}

View File

@@ -0,0 +1,21 @@
package cn.bootx.platform.daxpay.service.param.channel.cash;
import cn.bootx.platform.common.core.annotation.QueryParam;
import cn.bootx.platform.common.core.rest.param.QueryOrder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
*
* @author xxm
* @since 2024/2/18
*/
@QueryParam
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@Schema(title = "现金记录查询参数")
public class CashRecordQuery extends QueryOrder {
}

View File

@@ -18,4 +18,12 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
@Schema(title = "储值卡查询参数")
public class VoucherQuery extends QueryOrder {
@Schema(description = "卡号")
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
private String cardNo;
@Schema(description = "面值")
private Integer faceValue;
}

View File

@@ -0,0 +1,24 @@
package cn.bootx.platform.daxpay.service.param.channel.voucher;
import cn.bootx.platform.common.core.annotation.QueryParam;
import cn.bootx.platform.common.core.rest.param.QueryOrder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 储值卡查询参数
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@QueryParam
@Data
@Accessors(chain = true)
@Schema(title = "储值卡查询参数")
public class VoucherRecordQuery extends QueryOrder {
@Schema(description = "储值卡id")
private Long voucherId;
}

View File

@@ -1,43 +0,0 @@
package cn.bootx.platform.daxpay.service.param.channel.wallet;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author xxm
* @since 2020/12/8
*/
@Data
@Accessors(chain = true)
@Schema(title = "钱包日志查询参数")
public class WalletLogQueryParam implements Serializable {
private static final long serialVersionUID = -4046664021959786637L;
@Schema(description = "钱包ID (与userId至少存在一个)")
private Long walletId;
@Schema(description = "用户ID (钱包至少存在一个)")
private Long userId;
@Schema(description = "商户编码")
private String mchCode;
@Schema(description = "商户应用编码")
private String mchAppCode;
@Schema(description = "开始日期")
private LocalDateTime startDate;
@Schema(description = "结束日期")
private LocalDateTime endDate;
@Schema(description = "日志类型,不传则查询全部")
private List<Integer> type;
}

View File

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Accessors(chain = true)
@Schema(title = "钱包查询参数")
public class WalletQueryParam extends QueryOrder {
public class WalletQuery extends QueryOrder {
@Schema(description = "钱包ID")
private Long walletId;

View File

@@ -0,0 +1,24 @@
package cn.bootx.platform.daxpay.service.param.channel.wallet;
import cn.bootx.platform.common.core.annotation.QueryParam;
import cn.bootx.platform.common.core.rest.param.QueryOrder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 钱包记录查询参数
* @author xxm
* @since 2024/2/18
*/
@EqualsAndHashCode(callSuper = true)
@QueryParam
@Data
@Accessors(chain = true)
@Schema(title = "钱包记录查询参数")
public class WalletRecordQuery extends QueryOrder {
@Schema(description = "钱包id")
private Long walletId;
}