feat(service): 添加交易报表功能, 微信Jsapi默认加密方式调整

This commit is contained in:
DaxPay
2024-11-18 18:48:32 +08:00
parent 96215b51f0
commit a10ae1d1c0
8 changed files with 329 additions and 3 deletions

View File

@@ -11,7 +11,8 @@
- [x] 微信通道添加单独的认证跳转地址, 处理它的特殊情况 - [x] 微信通道添加单独的认证跳转地址, 处理它的特殊情况
## bugs ## bugs
- [ ] 修复 BigDecimal 类型数据序列化和签名异常问题 - [x] 修复 BigDecimal 类型数据序列化和签名异常问题
- [x] 获取是否订阅消息通知类型查询范围错误问题
## 任务池 ## 任务池

View File

@@ -66,7 +66,7 @@ public class AliPayService {
if (Objects.equals(payOrder.getMethod(), PayMethodEnum.WAP.getCode())) { if (Objects.equals(payOrder.getMethod(), PayMethodEnum.WAP.getCode())) {
payBody = this.wapPay(amount, payOrder); payBody = this.wapPay(amount, payOrder);
} }
// 程序支付 // APP支付
else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.APP.getCode())) { else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.APP.getCode())) {
payBody = this.appPay(amount, payOrder); payBody = this.appPay(amount, payOrder);
} }

View File

@@ -184,7 +184,7 @@ public class WechatPayV3Service {
packageParams.put("package", result.getPackageValue()); packageParams.put("package", result.getPackageValue());
String signType = result.getSignType(); String signType = result.getSignType();
if (result.getSignType() == null) { if (result.getSignType() == null) {
signType = "MD5"; signType = "RSA";
} }
packageParams.put("signType", signType); packageParams.put("signType", signType);
packageParams.put("paySign", result.getPaySign()); packageParams.put("paySign", result.getPaySign());

View File

@@ -0,0 +1,66 @@
package org.dromara.daxpay.service.controller.report;
import cn.bootx.platform.core.annotation.RequestPath;
import cn.bootx.platform.core.rest.Res;
import cn.bootx.platform.core.rest.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.dromara.daxpay.service.param.report.TradeReportQuery;
import org.dromara.daxpay.service.result.report.TradeReportResult;
import org.dromara.daxpay.service.service.report.IndexTradeReportService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 首页交易报表
* @author xxm
* @since 2024/11/17
*/
@Tag(name = "首页交易报表")
@RestController
@RequestMapping("/report/index")
@RequiredArgsConstructor
public class IndexTradeReportController {
private final IndexTradeReportService tradeReportService;
@RequestPath("支付交易信息统计")
@Operation(summary = "支付交易信息统计")
@GetMapping("/pay")
public Result<TradeReportResult> pryTradeReport(TradeReportQuery query){
return Res.ok(tradeReportService.pryTradeReport(query));
}
@RequestPath("退款交易信息统计")
@Operation(summary = "退款交易信息统计")
@GetMapping("/refund")
public Result<TradeReportResult> refundTradeReport(TradeReportQuery query){
return Res.ok(tradeReportService.refundTradeReport(query));
}
@RequestPath("支付交易通道统计")
@Operation(summary = "支付交易通道统计")
@GetMapping("/payChannel")
public Result<List<TradeReportResult>> payChannelReport(TradeReportQuery query){
return Res.ok(tradeReportService.payChannelReport(query));
}
@RequestPath("退款交易通道统计")
@Operation(summary = "退款交易通道统计")
@GetMapping("/refundChannel")
public Result<List<TradeReportResult>> refundChannelReport(TradeReportQuery query){
return Res.ok(tradeReportService.refundChannelReport(query));
}
@RequestPath("支付交易方式统计")
@Operation(summary = "支付交易方式统计")
@GetMapping("/payMethod")
public Result<List<TradeReportResult>> payMethodReport(TradeReportQuery query){
return Res.ok(tradeReportService.payMethodReport(query));
}
}

View File

@@ -0,0 +1,96 @@
package org.dromara.daxpay.service.dao.report;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.dromara.daxpay.service.param.report.TradeReportQuery;
import org.dromara.daxpay.service.result.report.TradeReportResult;
import java.util.List;
/**
* 首页报表数据库查询接口
* @author xxm
* @since 2024/11/17
*/
@Mapper
public interface IndexTradeReportMapper {
/**
* 支付订单
*/
@Select("""
select
sum(amount) as tradeAmount,
count(amount) as tradeCount,
max(amount) as maxAmount,
avg(amount) as avgAmount
from pay_order
${ew.customSqlSegment}
""")
TradeReportResult payTradeReport(@Param(Constants.WRAPPER) QueryWrapper<TradeReportQuery> param);
/**
* 退款订单
*/
@Select("""
select
sum(amount) as tradeAmount,
count(amount) as tradeCount,
max(amount) as maxAmount,
avg(amount) as avgAmount
from pay_refund_order
${ew.customSqlSegment}
""")
TradeReportResult refundTradeReport(@Param(Constants.WRAPPER) QueryWrapper<TradeReportQuery> param);
/**
* 支付通道
*/
@Select("""
select
channel as title,
sum(amount) as tradeAmount,
count(amount) as tradeCount,
max(amount) as maxAmount,
avg(amount) as avgAmount
from pay_order
${ew.customSqlSegment}
""")
List<TradeReportResult> payChannelReport(@Param(Constants.WRAPPER) QueryWrapper<TradeReportQuery> param);
/**
* 退款通道
*/
@Select("""
select
channel as title,
sum(amount) as tradeAmount,
count(amount) as tradeCount,
max(amount) as maxAmount,
avg(amount) as avgAmount
from pay_refund_order
${ew.customSqlSegment}
""")
List<TradeReportResult> refundChannelReport(@Param(Constants.WRAPPER) QueryWrapper<TradeReportQuery> param);
/**
* 支付方式统计
*/
@Select("""
select
method as title,
sum(amount) as tradeAmount,
count(amount) as tradeCount,
max(amount) as maxAmount,
avg(amount) as avgAmount
from pay_order
${ew.customSqlSegment}
""")
List<TradeReportResult> payMethodReport(@Param(Constants.WRAPPER) QueryWrapper<TradeReportQuery> param);
}

View File

@@ -0,0 +1,26 @@
package org.dromara.daxpay.service.param.report;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDate;
/**
* 交易报表查询参数
* @author xxm
* @since 2024/11/17
*/
@Data
@Accessors(chain = true)
@Schema(title = "交易报表查询参数")
public class TradeReportQuery {
/** 开始日期 */
@Schema(title = "开始日期")
private LocalDate startDate;
/** 结束日期 */
@Schema(title = "结束日期")
private LocalDate endDate;
}

View File

@@ -0,0 +1,35 @@
package org.dromara.daxpay.service.result.report;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 交易报表结果
* @author xxm
* @since 2024/11/17
*/
@Data
@Accessors(chain = true)
@Schema(title = "交易报表结果")
public class TradeReportResult {
@Schema(title = "标题")
private String title;
@Schema(title = "交易金额")
private BigDecimal tradeAmount;
@Schema(title = "交易笔数")
private Integer tradeCount;
@Schema(title = "最大单笔金额")
private BigDecimal maxAmount;
@Schema(title = "平均单笔金额")
private BigDecimal avgAmount;
}

View File

@@ -0,0 +1,102 @@
package org.dromara.daxpay.service.service.report;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.daxpay.core.enums.PayStatusEnum;
import org.dromara.daxpay.core.enums.RefundStatusEnum;
import org.dromara.daxpay.service.dao.report.IndexTradeReportMapper;
import org.dromara.daxpay.service.entity.order.pay.PayOrder;
import org.dromara.daxpay.service.entity.order.refund.RefundOrder;
import org.dromara.daxpay.service.param.report.TradeReportQuery;
import org.dromara.daxpay.service.result.report.TradeReportResult;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 交易类报表
* @author xxm
* @since 2024/11/16
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class IndexTradeReportService {
private final IndexTradeReportMapper tradeReportMapper;
/**
* 支付交易统计: 笔数, 金额
*/
public TradeReportResult pryTradeReport(TradeReportQuery query){
QueryWrapper<TradeReportQuery> param = new QueryWrapper<>();
// 获取开始时间和结束时间
var startTime = LocalDateTimeUtil.beginOfDay(query.getStartDate());
var endTime = LocalDateTimeUtil.endOfDay(query.getEndDate());
param.between(MpUtil.getColumnName(PayOrder::getPayTime), startTime, endTime)
.eq(MpUtil.getColumnName(PayOrder::getStatus), PayStatusEnum.SUCCESS);
return tradeReportMapper.payTradeReport(param);
}
/**
* 退款交易统计: 笔数, 金额
*/
public TradeReportResult refundTradeReport(TradeReportQuery query){
QueryWrapper<TradeReportQuery> param = new QueryWrapper<>();
// 获取开始时间和结束时间
var startTime = LocalDateTimeUtil.beginOfDay(query.getStartDate());
var endTime = LocalDateTimeUtil.endOfDay(query.getEndDate());
param.between(MpUtil.getColumnName(RefundOrder::getFinishTime),startTime, endTime)
.eq(MpUtil.getColumnName(RefundOrder::getStatus), RefundStatusEnum.SUCCESS);
return tradeReportMapper.refundTradeReport(param);
}
/**
* 支付通道统计
*/
public List<TradeReportResult> payChannelReport(TradeReportQuery query){
QueryWrapper<TradeReportQuery> param = new QueryWrapper<>();
// 获取开始时间和结束时间
var startTime = LocalDateTimeUtil.beginOfDay(query.getStartDate());
var endTime = LocalDateTimeUtil.endOfDay(query.getEndDate());
param.between(MpUtil.getColumnName(PayOrder::getPayTime),startTime, endTime)
.eq(MpUtil.getColumnName(PayOrder::getStatus), PayStatusEnum.SUCCESS)
.groupBy(MpUtil.getColumnName(PayOrder::getChannel));
return tradeReportMapper.payChannelReport(param);
}
/**
* 退款通道统计
*/
public List<TradeReportResult> refundChannelReport(TradeReportQuery query){
QueryWrapper<TradeReportQuery> param = new QueryWrapper<>();
// 获取开始时间和结束时间
var startTime = LocalDateTimeUtil.beginOfDay(query.getStartDate());
var endTime = LocalDateTimeUtil.endOfDay(query.getEndDate());
param.between(MpUtil.getColumnName(RefundOrder::getFinishTime),startTime, endTime)
.groupBy(MpUtil.getColumnName(RefundOrder::getChannel))
.eq(MpUtil.getColumnName(RefundOrder::getStatus), RefundStatusEnum.SUCCESS);
return tradeReportMapper.refundChannelReport(param);
}
/**
* 支付方式统计
*/
public List<TradeReportResult> payMethodReport(TradeReportQuery query){
QueryWrapper<TradeReportQuery> param = new QueryWrapper<>();
// 获取开始时间和结束时间
var startTime = LocalDateTimeUtil.beginOfDay(query.getStartDate());
var endTime = LocalDateTimeUtil.endOfDay(query.getEndDate());
param.between(MpUtil.getColumnName(PayOrder::getPayTime),startTime, endTime)
.eq(MpUtil.getColumnName(PayOrder::getStatus), PayStatusEnum.SUCCESS)
.groupBy(MpUtil.getColumnName(PayOrder::getMethod));
return tradeReportMapper.payMethodReport(param);
}
}