From e1ff7d4b9e1a6566881593b3667da146e6026a26 Mon Sep 17 00:00:00 2001 From: wyn <1074145239@qq.com> Date: Fri, 3 Jul 2026 17:06:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=20=E5=9B=9E=E6=89=AB=E5=8E=BB=E6=8E=89=E9=80=80?= =?UTF-8?q?=E6=AC=BE=E5=92=8C=E9=80=80=E6=AC=BE=E4=B8=AD=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9=EF=BC=8C=E6=8A=A5=E8=A1=A8=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dao/BuyOrderBatchDeliveryItemDao.java | 9 ++++ .../dao/BuyOrderBatchDeliveryTaskDao.java | 23 ++++++++++ .../service/impl/UserVipLogServiceImpl.java | 24 +++++++--- .../controller/StatisticsController.java | 1 - .../service/impl/WxpayServiceImpl.java | 2 +- .../mapper/master/UserCourseBuyDao.xml | 44 +++++++++++++------ .../resources/mapper/master/UserVipLogDao.xml | 7 ++- 7 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryItemDao.java create mode 100644 src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryTaskDao.java diff --git a/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryItemDao.java b/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryItemDao.java new file mode 100644 index 0000000..fd320e9 --- /dev/null +++ b/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryItemDao.java @@ -0,0 +1,9 @@ +package com.peanut.modules.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.peanut.modules.common.entity.BuyOrderBatchDeliveryItem; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface BuyOrderBatchDeliveryItemDao extends BaseMapper { +} diff --git a/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryTaskDao.java b/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryTaskDao.java new file mode 100644 index 0000000..f36e04e --- /dev/null +++ b/src/main/java/com/peanut/modules/common/dao/BuyOrderBatchDeliveryTaskDao.java @@ -0,0 +1,23 @@ +package com.peanut.modules.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.peanut.modules.common.entity.BuyOrderBatchDeliveryTask; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface BuyOrderBatchDeliveryTaskDao extends BaseMapper { + + @Select("") + List findBusyOrderIds(@Param("orderIds") List orderIds); +} diff --git a/src/main/java/com/peanut/modules/common/service/impl/UserVipLogServiceImpl.java b/src/main/java/com/peanut/modules/common/service/impl/UserVipLogServiceImpl.java index 3f37e9c..e5a511e 100644 --- a/src/main/java/com/peanut/modules/common/service/impl/UserVipLogServiceImpl.java +++ b/src/main/java/com/peanut/modules/common/service/impl/UserVipLogServiceImpl.java @@ -116,7 +116,9 @@ public class UserVipLogServiceImpl extends ServiceImpl> getUserVipLogInfo(String date) { + // date:报表截止日期,如 2026-06-30;从 DAO 查出未删除 + 已退款(del_flag=-1)的 VIP 明细及摊销 List> list = this.baseMapper.getUserVipLogInfo(date); + // 以 uvlId 为 key,缓存「本月发生退款」的订单,供后续匹配主列表并生成退款行 Map> refundMap = new HashMap<>(); for (Map refund : this.baseMapper.getMonthRefund(date)) { Object uvlId = refund.get("uvlId"); @@ -124,37 +126,47 @@ public class UserVipLogServiceImpl extends ServiceImpl> result = new ArrayList<>(); + // 记录已在主列表中处理过的退款 uvlId,避免第二步重复追加 Set matchedUvlIds = new HashSet<>(); for (Map row : list) { + // 主列表默认标记为已付款 row.put("orderStatus", "已付款"); Object uvlId = row.get("uvlId"); + // 若该 VIP 记录在本月有退款,则 refund 非空 Map refund = uvlId == null ? null : refundMap.get(uvlId.toString()); if (refund != null) { + // 本月退款的订单:原「已付款」行当月/剩余摊销清零(退款单独成行体现) row.put("currentTanxiao",BigDecimal.ZERO); row.put("notyetTanxiao",BigDecimal.ZERO); String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; String payMonth = getPayMonth(row); + // 本月付本月退:保留原已付款行(金额为正),再追加一条负金额退款行 if (exportMonth.equals(payMonth)){ result.add(row); } matchedUvlIds.add(uvlId.toString()); + // 追加「已退款」行,金额/摊销按 buildRefundRow 规则处理 result.add(buildRefundRow(row, refund, date)); }else{ + // 无本月退款:原样加入结果 result.add(row); } } - //其他月份下单、指定月份退款:主列表里没有对应行(user_vip_log已删除),单独追加到列表最下面 + // 其他月份下单、指定月份退款:主列表里没有对应行(user_vip_log已删除),单独追加到列表最下面 String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; for (Map refund : refundMap.values()) { Object uvlId = refund.get("uvlId"); + // 已在主列表匹配过的跳过 if (uvlId != null && matchedUvlIds.contains(uvlId.toString())) { continue; } String payMonth = getPayMonth(refund); + // 早月付款、本月退款且主列表无行:仅用 refund 数据构造一条退款行 if (!payMonth.isEmpty() && !exportMonth.equals(payMonth)) { result.add(buildRefundRow(refund, refund, date)); } @@ -162,18 +174,18 @@ public class UserVipLogServiceImpl extends ServiceImpl buildRefundRow(Map row, Map refund, String date) { + // 复制原订单行作为退款行模板 Map refundRow = new HashMap<>(row); - log.info("n======o"+(refund.get("refund_no")==null?"":refund.get("refund_no").toString())); refundRow.put("orderStatus", "已退款"); + // 支付时间改为退款时间,便于导出展示 refundRow.put("payTime", refund.get("refundTime")); refundRow.put("refund_no", refund.get("refund_no")); String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; String payMonth = getPayMonth(row); BigDecimal dayAmount = toBigDecimal(row.get("dayAmount")); - log.info(date+":=====p:"+payMonth+",e:"+exportMonth+","+refund.get("orderSn").toString()); if (exportMonth.equals(payMonth)) { - //当月订单当月退款:金额为负,当月/剩余摊销为0 + // 当月订单当月退款:金额为负,当月/剩余摊销为0 refundRow.put("price", toBigDecimal(row.get("price")).negate()); refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); refundRow.put("alreadyDays", 0); @@ -183,7 +195,7 @@ public class UserVipLogServiceImpl extends ServiceImpl one : monthRefundMap) { String payMonth = userVipLogService.getPayMonth(one); if (exportMonth.equals(payMonth)) { diff --git a/src/main/java/com/peanut/modules/pay/weChatPay/service/impl/WxpayServiceImpl.java b/src/main/java/com/peanut/modules/pay/weChatPay/service/impl/WxpayServiceImpl.java index 343a414..bde57c5 100644 --- a/src/main/java/com/peanut/modules/pay/weChatPay/service/impl/WxpayServiceImpl.java +++ b/src/main/java/com/peanut/modules/pay/weChatPay/service/impl/WxpayServiceImpl.java @@ -185,7 +185,7 @@ public class WxpayServiceImpl extends ServiceImpl().eq("order_sn", orderNo)); - if ("3".equals(order.getOrderStatus())){ + if ("3".equals(order.getOrderStatus())||"6".equals(order.getOrderStatus())||"7".equals(order.getOrderStatus())){ return; } //使用优惠券 diff --git a/src/main/resources/mapper/master/UserCourseBuyDao.xml b/src/main/resources/mapper/master/UserCourseBuyDao.xml index 3b5305a..16f9969 100644 --- a/src/main/resources/mapper/master/UserCourseBuyDao.xml +++ b/src/main/resources/mapper/master/UserCourseBuyDao.xml @@ -7,11 +7,11 @@ select r.* ,ROUND(fee-alreadyTanxiao-currentTanxiao,2) surplusTanxiao from (select e.* - ,ROUND(if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)),2) currentTanxiao + ,ROUND(if(CHAR_LENGTH(IFNULL(endTime,'')) < 10, if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)), if(DATEDIFF(#{date}, LEFT(endTime,10)) >= 0, 0, if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)))),2) currentTanxiao from (select w.name,w.tel,w.ctitle,w.cctitle,if(w.startTime is null,'',w.startTime) startTime,if(w.endTime is null,'',w.endTime) endTime,w.totalDays ,w.type,w.payType,w.payTime,w.orderSn,w.zfbOrder,w.days,w.fee,w.remark,w.dayAmount,w.alreadyDay,w.currentDay ,IF(beginDay=0,startTime,IF(startTime is NULL,startTime,DATE_ADD(startTime,INTERVAL beginDay-1 day))) startTanxiaoTime - ,ROUND(if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)),2) alreadyTanxiao + ,ROUND(if(CHAR_LENGTH(IFNULL(endTime,'')) < 10, if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)), if(DATEDIFF(#{date}, LEFT(endTime,10)) >= 0, fee, if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)))),2) alreadyTanxiao from ( select q.*,alreadyDay*dayAmount alreadyDayAmount ,IF(days-alreadyDay=0,0,IF(beginDay=0,IF(startTime is NULL,0,IF(days-alreadyDay>=monthDays,if(DATE_FORMAT(startTime,'%Y-%m')=SUBSTR(#{date},1,7),DATEDIFF(#{date},startTime)+1,if(DATE_FORMAT(startTime,'%Y-%m')>SUBSTR(#{date},1,7),0,monthDays)),if(DATE_FORMAT(startTime, '%Y-%m')=SUBSTR(#{date},1,7),if(DATEDIFF(#{date},startTime)+1>days,days,DATEDIFF(#{date},startTime)+1),if(DATE_FORMAT(startTime, '%Y-%m') < SUBSTR(#{date},1,7),days-alreadyDay,0)))), if(alreadyTotalDay+monthDays>beginDay,if(alreadyDay>0,if(days-alreadyDay>monthDays,monthDays,monthDays-(days-alreadyDay)),monthDays-(totalDays-days-alreadyTotalDay)),0) )) currentDay @@ -41,12 +41,28 @@ @@ -79,11 +95,11 @@ and DATE_FORMAT(IF(bo.success_time is null,bo.create_time,bo.success_time),'%Y-%m') = SUBSTR(#{date},1,7) and (bo.user_id not in (select id from user where tester_flag = 1) or (bo.user_id in (select id from user where tester_flag = 1) and bo.payment_method in ('1','2') and bo.create_time>='2026-05-06 00:00:00')) - and exists ( + and (bo.order_type = 'relearn' or exists ( select 1 from buy_order_product bop inner join shop_product sp on sp.product_id = bop.product_id where bop.order_id = bo.order_id and sp.goods_type = '05' - ) + )) ) t GROUP BY pay_type @@ -159,11 +175,11 @@ select r.* ,ROUND(fee-alreadyTanxiao-currentTanxiao,2) surplusTanxiao from (select e.* - ,ROUND(if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)),2) currentTanxiao + ,ROUND(if(CHAR_LENGTH(IFNULL(endTime,'')) < 10, if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)), if(DATEDIFF(#{date}, LEFT(endTime,10)) >= 0, 0, if(alreadyDay+currentDay>=days,fee-alreadyTanxiao,if(alreadyTanxiao+currentDay*dayAmount>fee,fee-alreadyTanxiao,currentDay*dayAmount)))),2) currentTanxiao from (select w.name,w.tel,w.ctitle,w.cctitle,if(w.startTime is null,'',w.startTime) startTime,if(w.endTime is null,'',w.endTime) endTime,w.totalDays ,w.type,w.payType,w.payTime,w.orderSn,w.zfbOrder,w.days,w.fee,w.remark,w.dayAmount,w.alreadyDay,w.currentDay ,IF(beginDay=0,startTime,IF(startTime is NULL,startTime,DATE_ADD(startTime,INTERVAL beginDay-1 day))) startTanxiaoTime - ,ROUND(if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)),2) alreadyTanxiao + ,ROUND(if(CHAR_LENGTH(IFNULL(endTime,'')) < 10, if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)), if(DATEDIFF(#{date}, LEFT(endTime,10)) >= 0, fee, if(alreadyDay=days,fee,if(alreadyDayAmount>fee,fee,alreadyDayAmount)))),2) alreadyTanxiao from ( select q.*,alreadyDay*dayAmount alreadyDayAmount ,IF(days-alreadyDay=0,0,IF(beginDay=0,IF(startTime is NULL,0,IF(days-alreadyDay>=monthDays,if(DATE_FORMAT(startTime,'%Y-%m')=SUBSTR(#{date},1,7),DATEDIFF(#{date},startTime)+1,if(DATE_FORMAT(startTime,'%Y-%m')>SUBSTR(#{date},1,7),0,monthDays)),if(DATE_FORMAT(startTime, '%Y-%m')=SUBSTR(#{date},1,7),if(DATEDIFF(#{date},startTime)+1>days,days,DATEDIFF(#{date},startTime)+1),if(DATE_FORMAT(startTime, '%Y-%m') < SUBSTR(#{date},1,7),days-alreadyDay,0)))), if(alreadyTotalDay+monthDays>beginDay,if(alreadyDay>0,if(days-alreadyDay>monthDays,monthDays,monthDays-(days-alreadyDay)),monthDays-(totalDays-days-alreadyTotalDay)),0) )) currentDay diff --git a/src/main/resources/mapper/master/UserVipLogDao.xml b/src/main/resources/mapper/master/UserVipLogDao.xml index 7dd1bdb..ac575ae 100644 --- a/src/main/resources/mapper/master/UserVipLogDao.xml +++ b/src/main/resources/mapper/master/UserVipLogDao.xml @@ -15,10 +15,12 @@ IF(DATE_FORMAT(uvl.start_time, '%Y-%m') > SUBSTR(#{date},1,7),0,IF(DATE_FORMAT(uvl.end_time, '%Y-%m') < SUBSTR(#{date},1,7),0,IF(DATE_FORMAT(uvl.end_time, '%Y-%m') > SUBSTR(#{date},1,7),if(DATE_FORMAT(uvl.start_time, '%Y-%m') = SUBSTR(#{date},1,7),DATEDIFF(#{date},uvl.start_time)+1,DAY(#{date})),DATEDIFF(uvl.end_time,concat(SUBSTR(#{date},1,7),'-01'))+1))) currentDays, IF(DATE_FORMAT(uvl.start_time, '%Y-%m') > SUBSTR(#{date},1,7),DATEDIFF(uvl.end_time,uvl.start_time)+1,(IF(DATE_FORMAT(uvl.end_time, '%Y-%m') <= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays from user_vip_log uvl LEFT JOIN buy_order a ON a.order_sn=uvl.order_sn + LEFT JOIN buy_order_refund b ON a.order_id=b.order_id left join user_vip uv on uv.id = uvl.user_vip_id left join user u on u.id = uvl.user_id left join pay_zfb_order pzo on pzo.relevanceOid = uvl.order_sn and pzo.trade_no is not null where u.del_flag = 0 and (uvl.del_flag = 0 or (uvl.del_flag = -1 and a.order_status=6)) + and (DATE_FORMAT(b.create_time, '%Y-%m')>=SUBSTR(#{date},1,7) || ISNULL(b.create_time)) AND (uv.del_flag = 0 OR (uv.del_flag = -1 AND a.order_status=6)) and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') <= SUBSTR(#{date},1,7) and @@ -264,7 +266,8 @@ left join user_vip uv on uv.id = uvl.user_vip_id left join user u on u.id = uvl.user_id left join pay_zfb_order pzo on pzo.relevanceOid = uvl.order_sn and pzo.trade_no is not null - where u.del_flag = 0 and uvl.del_flag = 0 and uv.del_flag = 0 and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') <= SUBSTR(#{date},1,7) and u.id not in (select id from user where tester_flag = 1) + where u.del_flag = 0 and uvl.del_flag = 0 and uv.del_flag = 0 and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') <= SUBSTR(#{date},1,7) + and (u.id not in (select id from user where tester_flag = 1) or (u.id in (select id from user where tester_flag = 1) and (uvl.pay_type in('微信','支付宝') and uvl.create_time>='2026-05-06 00:00:00'))) order by uvl.end_time asc ) t order by currentDays desc ) s @@ -299,7 +302,7 @@