diff --git a/src/main/java/com/peanut/modules/book/service/BuyOrderService.java b/src/main/java/com/peanut/modules/book/service/BuyOrderService.java index 599319f..c29d79c 100644 --- a/src/main/java/com/peanut/modules/book/service/BuyOrderService.java +++ b/src/main/java/com/peanut/modules/book/service/BuyOrderService.java @@ -69,7 +69,9 @@ public interface BuyOrderService extends IService { List getOrderCourse(String orderSn); - void addCourseToUser(String payType,BuyOrder orderEntity); + void removeCourseToUser(BuyOrder orderEntity); + + void addCourseToUser(String payType, BuyOrder orderEntity); boolean checkWlOrder(String orderSn); diff --git a/src/main/java/com/peanut/modules/book/service/impl/BuyOrderServiceImpl.java b/src/main/java/com/peanut/modules/book/service/impl/BuyOrderServiceImpl.java index 4e82c22..e2047b7 100644 --- a/src/main/java/com/peanut/modules/book/service/impl/BuyOrderServiceImpl.java +++ b/src/main/java/com/peanut/modules/book/service/impl/BuyOrderServiceImpl.java @@ -743,15 +743,12 @@ public class BuyOrderServiceImpl extends ServiceImpl impl List shopProductCourseEntities = this.getBaseMapper().selectJoinList(ShopProductCourseEntity.class, wrapper); return shopProductCourseEntities; } + @Override public void removeCourseToUser(BuyOrder orderEntity){ QueryWrapper buyLogQueryWrapper = new QueryWrapper<>(); buyLogQueryWrapper.eq("order_sn",orderEntity.getOrderSn()); - log.info("order+sn===="+orderEntity.getOrderSn()); List userCourseBuyLogList = userCourseBuyLogDao.selectList(buyLogQueryWrapper); - log.info("size===="+userCourseBuyLogList.size()); for (UserCourseBuyLog userCourseBuyLog:userCourseBuyLogList){ - log.info("===delete====="+userCourseBuyLog.getUserCourseBuyId()); - log.info("===delete2====="+userCourseBuyLog.getId()); userCourseBuyDao.realDeleteById(userCourseBuyLog.getUserCourseBuyId()); userCourseBuyLogDao.realDeleteById(userCourseBuyLog.getId()); } diff --git a/src/main/java/com/peanut/modules/common/dao/BuyOrderDao.java b/src/main/java/com/peanut/modules/common/dao/BuyOrderDao.java index 253fc31..6cbc488 100644 --- a/src/main/java/com/peanut/modules/common/dao/BuyOrderDao.java +++ b/src/main/java/com/peanut/modules/common/dao/BuyOrderDao.java @@ -22,8 +22,12 @@ public interface BuyOrderDao extends MPJBaseMapper { List> getPhysicalBuyOrderTotal(@Param("date") String date,@Param("orderType") String orderType); + List> getRefund(@Param("date") String date,@Param("orderType") String orderType); + List> exportPhysicalBuyOrderInfo(@Param("date") String date,@Param("orderType") String orderType); + List> exportPhysicalBuyOrderRefundInfo(@Param("date") String date,@Param("orderType") String orderType); + List orderList(BuyOrderListRequestVo requestVo); int orderListCount(BuyOrderListRequestVo requestVo); diff --git a/src/main/java/com/peanut/modules/common/dao/TransactionDetailsDao.java b/src/main/java/com/peanut/modules/common/dao/TransactionDetailsDao.java index 7ed806a..6512340 100644 --- a/src/main/java/com/peanut/modules/common/dao/TransactionDetailsDao.java +++ b/src/main/java/com/peanut/modules/common/dao/TransactionDetailsDao.java @@ -23,4 +23,6 @@ public interface TransactionDetailsDao extends BaseMapper> getTransactionDetailsTotal(@Param("date") String date); List> getTransactionDetailsInfo(@Param("date") String date); + + List> getRefundTransactionDetails(@Param("date") String date); } diff --git a/src/main/java/com/peanut/modules/common/dao/UserCourseBuyDao.java b/src/main/java/com/peanut/modules/common/dao/UserCourseBuyDao.java index 1c2142f..5673af6 100644 --- a/src/main/java/com/peanut/modules/common/dao/UserCourseBuyDao.java +++ b/src/main/java/com/peanut/modules/common/dao/UserCourseBuyDao.java @@ -18,8 +18,14 @@ public interface UserCourseBuyDao extends MPJBaseMapper { List> getIncome(@Param("date") String date); + List> getRefund(@Param("date") String date); + + List> getSameMonthRefund(@Param("date") String date); + List> getCoursePurchaseDetails(int courseId,int catalogueId,Integer limit,Integer offset); @Delete("DELETE FROM user_course_buy WHERE id = #{userCourseBuyId}") int realDeleteById(int userCourseBuyId); + + List> getRefundInfo(@Param("date") String date); } diff --git a/src/main/java/com/peanut/modules/common/dao/UserVipLogDao.java b/src/main/java/com/peanut/modules/common/dao/UserVipLogDao.java index 58e5bd1..f35fa94 100644 --- a/src/main/java/com/peanut/modules/common/dao/UserVipLogDao.java +++ b/src/main/java/com/peanut/modules/common/dao/UserVipLogDao.java @@ -5,6 +5,7 @@ import com.peanut.modules.common.entity.UserVipLog; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; import java.util.List; import java.util.Map; @@ -15,5 +16,24 @@ public interface UserVipLogDao extends MPJBaseMapper { Map getUserVipLogInfoTotal(@Param("date") String date); + BigDecimal getUserVipRefundFeeTotal(@Param("date") String date); + + BigDecimal getUserVipSameMonthRefundFeeTotal(@Param("date") String date); + + List> getUserVipRefundLogInfo(@Param("date") String date); + + List> getAllUserVipLogInfo(@Param("date") String date); + List> getUserVipRefundInfo(@Param("date") String last_l_date,@Param("date") String last_date); + + List> getLastMonthRefund(@Param("date") String date); + + BigDecimal getLastMonthRefundFee(@Param("date") String date); + + List> getMonthRefund(@Param("date") String date); + + List> getCurrMonthOtherRefund(@Param("date") String date); + + List> getNextNMonthRefund(@Param("date") String date); + } diff --git a/src/main/java/com/peanut/modules/common/service/BuyOrderService.java b/src/main/java/com/peanut/modules/common/service/BuyOrderService.java index 5ac7b99..bab20aa 100644 --- a/src/main/java/com/peanut/modules/common/service/BuyOrderService.java +++ b/src/main/java/com/peanut/modules/common/service/BuyOrderService.java @@ -26,5 +26,7 @@ public interface BuyOrderService extends IService { List> getPhysicalBuyOrderTotal(String date, String orderType); + List> getRefund(String date, String orderType); + List> exportPhysicalBuyOrderInfo(String date, String orderType); } diff --git a/src/main/java/com/peanut/modules/common/service/TransactionDetailsService.java b/src/main/java/com/peanut/modules/common/service/TransactionDetailsService.java index d164322..2139e4e 100644 --- a/src/main/java/com/peanut/modules/common/service/TransactionDetailsService.java +++ b/src/main/java/com/peanut/modules/common/service/TransactionDetailsService.java @@ -12,5 +12,7 @@ public interface TransactionDetailsService extends IService> getTransactionDetailsTotal(String date); + List> getRefundTransactionDetails(String date); + List> getTransactionDetailsInfo(String date); } diff --git a/src/main/java/com/peanut/modules/common/service/UserVipLogService.java b/src/main/java/com/peanut/modules/common/service/UserVipLogService.java index 381e41a..95c4d6d 100644 --- a/src/main/java/com/peanut/modules/common/service/UserVipLogService.java +++ b/src/main/java/com/peanut/modules/common/service/UserVipLogService.java @@ -20,10 +20,26 @@ public interface UserVipLogService extends IService { BigDecimal countDayAmount(UserVipLog userVipLog); + BigDecimal getLastMonthRefundFee(String date); + + List> getCurrMonthOtherRefund(String date); + + List> getNextNMonthRefund(String date); + + List> getMonthRefund(String date); + List> getUserVipLogInfo(String date); + String getPayMonth(Map row); + List> getUserVipRefundInfo(String last_l_date, String last_date); Map getUserVipLogInfoTotal(String date); + BigDecimal getUserVipRefundFeeTotal(String date); + + BigDecimal getUserVipSameMonthRefundFeeTotal(String date); + + List> getLastMonthRefund(String date); + } diff --git a/src/main/java/com/peanut/modules/common/service/impl/BuyOrderServiceImpl.java b/src/main/java/com/peanut/modules/common/service/impl/BuyOrderServiceImpl.java index 1e7b015..3a5965e 100644 --- a/src/main/java/com/peanut/modules/common/service/impl/BuyOrderServiceImpl.java +++ b/src/main/java/com/peanut/modules/common/service/impl/BuyOrderServiceImpl.java @@ -19,6 +19,7 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -252,29 +253,82 @@ public class BuyOrderServiceImpl extends ServiceImpl impl @Override public List> getPhysicalBuyOrderTotal(String date,String orderType) { - return this.baseMapper.getPhysicalBuyOrderTotal(date, orderType); + List> incomeList = this.baseMapper.getPhysicalBuyOrderTotal(date, orderType); + List> refundList = this.baseMapper.getRefund(date, orderType); + Map> merged = new LinkedHashMap<>(); + for (Map income : incomeList) { + String payType = income.get("payType").toString(); + Map row = new HashMap<>(); + row.put("payType", payType); + row.put("count", income.get("count")); + row.put("totalPrice", income.get("totalPrice")); + row.put("refundCount", 0); + row.put("refundTotalPrice", 0); + merged.put(payType, row); + } + for (Map refund : refundList) { + String payType = refund.get("payType").toString(); + Map row = merged.computeIfAbsent(payType, k -> { + Map r = new HashMap<>(); + r.put("payType", payType); + r.put("count", 0); + r.put("totalPrice", 0); + return r; + }); + row.put("refundCount", refund.get("count")); + row.put("refundTotalPrice", refund.get("totalPrice")); + } + for (Map row : merged.values()) { + if (!row.containsKey("refundCount")) { + row.put("refundCount", 0); + row.put("refundTotalPrice", 0); + } + BigDecimal totalPrice = toBigDecimal(row.get("totalPrice")); + BigDecimal refundTotalPrice = toBigDecimal(row.get("refundTotalPrice")); + row.put("netTotalPrice", totalPrice.subtract(refundTotalPrice)); + } + return new ArrayList<>(merged.values()); + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + return new BigDecimal(value.toString()); + } + + @Override + public List> getRefund(String date, String orderType) { + return this.baseMapper.getRefund(date, orderType); } @Override public List> exportPhysicalBuyOrderInfo(String date,String orderType) { - List> list = this.baseMapper.exportPhysicalBuyOrderInfo(date, orderType); - List> newList = new ArrayList<>(); - for (Map map:list){ + List> purchaseList = this.baseMapper.exportPhysicalBuyOrderInfo(date, orderType); + List> refundList = this.baseMapper.exportPhysicalBuyOrderRefundInfo(date, orderType); - if(map.get("orderStatus").toString().equals("已退款")){ - Map newMap = new HashMap<>(map); - map.put("orderStatus","已付款"); - newList.add(map); - - newMap.put("orderPrice","-"+map.get("orderPrice").toString()); - newMap.put("price","-"+map.get("price").toString()); - newList.add(newMap); - }else{ - newList.add(map); + List> result = new ArrayList<>(); + for (Map map : purchaseList) { + //本月下单即为本月收入,已退款订单的购买行也展示(退款行按退款月份在对应报表中体现) + if ("已退款".equals(map.get("orderStatus").toString())) { + Map purchaseRow = new HashMap<>(map); + purchaseRow.put("orderStatus", "已付款"); + result.add(purchaseRow); + } else { + result.add(map); } - } - return newList; + for (Map refund : refundList) { + Map refundRow = new HashMap<>(refund); + refundRow.put("orderPrice", toBigDecimal(refund.get("orderPrice")).abs().negate()); + refundRow.put("price", toBigDecimal(refund.get("price")).abs().negate()); + result.add(refundRow); + } + result.sort(Comparator.comparing(m -> m.get("createTime").toString())); + return result; } @Override diff --git a/src/main/java/com/peanut/modules/common/service/impl/TransactionDetailsServiceImpl.java b/src/main/java/com/peanut/modules/common/service/impl/TransactionDetailsServiceImpl.java index 76e89ce..b5cbf3c 100644 --- a/src/main/java/com/peanut/modules/common/service/impl/TransactionDetailsServiceImpl.java +++ b/src/main/java/com/peanut/modules/common/service/impl/TransactionDetailsServiceImpl.java @@ -24,6 +24,11 @@ public class TransactionDetailsServiceImpl extends ServiceImpl> getRefundTransactionDetails(String date) { + return this.baseMapper.getRefundTransactionDetails(date); + } + @Override public List> getTransactionDetailsInfo(String date) { return this.baseMapper.getTransactionDetailsInfo(date); 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 354f88f..cebb526 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 @@ -11,9 +11,16 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service; import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; @Slf4j @Service("commonUserVipLogService") @@ -87,10 +94,157 @@ public class UserVipLogServiceImpl extends ServiceImpl> getLastMonthRefund(String date){ + return this.baseMapper.getLastMonthRefund(date); + } + @Override + public List> getCurrMonthOtherRefund(String date){ + return this.baseMapper.getCurrMonthOtherRefund(date); + } + @Override + public List> getNextNMonthRefund(String date){ + return this.baseMapper.getNextNMonthRefund(date); + } + @Override + public List> getMonthRefund(String date){ + return this.baseMapper.getMonthRefund(date); + } @Override public List> getUserVipLogInfo(String date) { - return this.baseMapper.getUserVipLogInfo(date); + List> list = this.baseMapper.getUserVipLogInfo(date); + Map> refundMap = new HashMap<>(); + for (Map refund : this.baseMapper.getMonthRefund(date)) { + Object uvlId = refund.get("uvlId"); + if (uvlId != null) { + refundMap.put(uvlId.toString(), refund); + } + } + List> result = new ArrayList<>(); + Set matchedUvlIds = new HashSet<>(); + for (Map row : list) { + row.put("orderStatus", "已付款"); + + Object uvlId = row.get("uvlId"); + 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()); + result.add(buildRefundRow(row, refund, date)); + + }else{ + result.add(row); + } + + } + //其他月份下单、指定月份退款:主列表里没有对应行(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); + if (!payMonth.isEmpty() && !exportMonth.equals(payMonth)) { + result.add(buildRefundRow(refund, refund, date)); + } + } + return result; + } + public Map 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 + refundRow.put("price", toBigDecimal(row.get("price")).negate()); + refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); + refundRow.put("alreadyDays", 0); + refundRow.put("currentDays", 0); + refundRow.put("notyetDays", 0); + refundRow.put("alreadyTanxiao", BigDecimal.ZERO); + refundRow.put("currentTanxiao", BigDecimal.ZERO); + refundRow.put("notyetTanxiao", BigDecimal.ZERO); + } else if (!payMonth.isEmpty() && !exportMonth.equals(payMonth)) { + //其他月份下单、指定月份退款:订单金额为0,冲回已摊销部分 + int alreadyDays = calcAlreadyDaysToPrevMonthEnd(row, date); + BigDecimal alreadyTanxiao = dayAmount.multiply(new BigDecimal(alreadyDays)).setScale(2, RoundingMode.HALF_UP); + refundRow.put("price", toBigDecimal(row.get("price")).negate()); + refundRow.put("fee", toBigDecimal(row.get("price")).negate()); + refundRow.put("alreadyDays", alreadyDays); + refundRow.put("currentDays", 0); + refundRow.put("notyetDays", 0); + refundRow.put("alreadyTanxiao", 0); + refundRow.put("currentTanxiao", alreadyTanxiao.negate()); + refundRow.put("notyetTanxiao", 0); + } else { + refundRow.put("price", toBigDecimal(row.get("price")).negate()); + refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); + refundRow.put("alreadyDays", row.get("alreadyDays")); + refundRow.put("currentDays", 0); + refundRow.put("notyetDays", 0); + refundRow.put("alreadyTanxiao", toBigDecimal(row.get("alreadyTanxiao"))); + refundRow.put("currentTanxiao", toBigDecimal(row.get("alreadyTanxiao")).negate()); + refundRow.put("notyetTanxiao", BigDecimal.ZERO); + } + return refundRow; + } + + @Override + public String getPayMonth(Map row) { + Object payTime = row.get("payTime"); + if (payTime != null && !payTime.toString().isEmpty()) { + return payTime.toString().substring(0, 7); + } + Object startTime = row.get("startTime"); + if (startTime != null && !startTime.toString().isEmpty()) { + return startTime.toString().substring(0, 7); + } + return ""; + } + + private int calcAlreadyDaysToPrevMonthEnd(Map row, String date) { + Object payTime = row.get("payTime"); + String payDateStr = payTime != null && !payTime.toString().isEmpty() + ? payTime.toString() + : (row.get("startTime") != null ? row.get("startTime").toString() : ""); + if (payDateStr.length() < 10) { + return 0; + } + LocalDate payDate = LocalDate.parse(payDateStr.substring(0, 10)); + String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; + LocalDate prevMonthEnd = LocalDate.parse(exportMonth + "-01").minusDays(1); + if (payDate.isAfter(prevMonthEnd)) { + return 0; + } + return (int) ChronoUnit.DAYS.between(payDate, prevMonthEnd) + 1; + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + return new BigDecimal(value.toString()); } @Override @@ -102,4 +256,14 @@ public class UserVipLogServiceImpl extends ServiceImpl getUserVipLogInfoTotal(String date) { return this.baseMapper.getUserVipLogInfoTotal(date); } + + @Override + public BigDecimal getUserVipRefundFeeTotal(String date) { + return this.baseMapper.getUserVipRefundFeeTotal(date); + } + + @Override + public BigDecimal getUserVipSameMonthRefundFeeTotal(String date) { + return this.baseMapper.getUserVipSameMonthRefundFeeTotal(date); + } } diff --git a/src/main/java/com/peanut/modules/common/service/impl/UserVipServiceImpl.java b/src/main/java/com/peanut/modules/common/service/impl/UserVipServiceImpl.java index c14e529..4d531f4 100644 --- a/src/main/java/com/peanut/modules/common/service/impl/UserVipServiceImpl.java +++ b/src/main/java/com/peanut/modules/common/service/impl/UserVipServiceImpl.java @@ -302,8 +302,8 @@ public class UserVipServiceImpl extends ServiceImpl impleme } List userVipList = userVipDao.selectList(new LambdaQueryWrapper() .eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getType,i).orderByDesc(UserVip::getEndTime)); - UserVip userVip = userVipList.get(0); - if (userVip.getState()==0) { + UserVip userVip = userVipList.isEmpty() ? null : userVipList.get(0); + if (userVipList.size()>0 && userVip != null && (userVip.getState() == null || userVip.getState() == 0)) { Date startTime = userVip.getEndTime(); Date endTime = DateUtils.addYears(userVip.getEndTime(),vipBuyConfigEntity.getYear()); userVip.setEndTime(endTime); @@ -354,8 +354,8 @@ public class UserVipServiceImpl extends ServiceImpl impleme for (int i=7;i<9;i++){ List userVipList = userVipDao.selectList(new LambdaQueryWrapper() .eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getType,i).orderByDesc(UserVip::getEndTime)); - UserVip userVip = userVipList.get(0); - if (userVip.getState()==0) { + UserVip userVip = userVipList.isEmpty() ? null : userVipList.get(0); + if (userVip != null && (userVip.getState() == null || userVip.getState() == 0)) { Date startTime = userVip.getEndTime(); Date endTime = DateUtils.addYears(userVip.getEndTime(),vipBuyConfigEntity.getYear()); userVip.setEndTime(endTime); @@ -388,8 +388,8 @@ public class UserVipServiceImpl extends ServiceImpl impleme .eq(UserVip::getUserId,buyOrder.getUserId()) .eq(UserVip::getType,vipBuyConfigEntity.getType().toString().substring(0,vipBuyConfigEntity.getType()==101?2:1)) .orderByDesc(UserVip::getEndTime)); - UserVip userVip = userVipList.get(0); - if (userVip.getState()==0) { + UserVip userVip = userVipList.isEmpty() ? null : userVipList.get(0); + if (userVip != null && (userVip.getState() == null || userVip.getState() == 0)) { Date startTime = userVip.getEndTime(); Date endTime = DateUtils.addYears(userVip.getEndTime(),vipBuyConfigEntity.getYear()); userVip.setEndTime(endTime); diff --git a/src/main/java/com/peanut/modules/master/controller/StatisticsBusinessVipController.java b/src/main/java/com/peanut/modules/master/controller/StatisticsBusinessVipController.java index dd303ac..3dcf652 100644 --- a/src/main/java/com/peanut/modules/master/controller/StatisticsBusinessVipController.java +++ b/src/main/java/com/peanut/modules/master/controller/StatisticsBusinessVipController.java @@ -71,7 +71,7 @@ public class StatisticsBusinessVipController { reBuyRules.put("国学", Arrays.asList(7)); reBuyRules.put("心理学", Arrays.asList(8)); reBuyRules.put("中西汇通学", Arrays.asList(9)); - reBuyRules.put("妇幼生殖", Arrays.asList(10)); + reBuyRules.put("妇幼生殖学", Arrays.asList(10)); // 判断是否复购 List required = reBuyRules.get(vipType); if (required != null && state1UserVips.containsAll(required)) { @@ -142,8 +142,8 @@ public class StatisticsBusinessVipController { row5.createCell(0).setCellValue("肿瘤学");row5.createCell(1).setCellValue(state1Counts.getOrDefault("肿瘤学", 0).toString()); row5.createCell(2).setCellValue("肿瘤学");row5.createCell(3).setCellValue(state0Counts.getOrDefault("肿瘤学", 0).toString()); Row row6 = sheet.createRow(rowNum++); - row6.createCell(0).setCellValue("妇幼生殖");row6.createCell(1).setCellValue(state1Counts.getOrDefault("妇幼生殖",0).toString()); - row6.createCell(2).setCellValue("妇幼生殖");row6.createCell(3).setCellValue(state0Counts.getOrDefault("妇幼生殖", 0).toString()); + row6.createCell(0).setCellValue("妇幼生殖学");row6.createCell(1).setCellValue(state1Counts.getOrDefault("妇幼生殖学",0).toString()); + row6.createCell(2).setCellValue("妇幼生殖学");row6.createCell(3).setCellValue(state0Counts.getOrDefault("妇幼生殖学", 0).toString()); Row row7 = sheet.createRow(rowNum++); row7.createCell(0).setCellValue("国学");row7.createCell(1).setCellValue(state1Counts.getOrDefault("国学",0).toString()); row7.createCell(2).setCellValue("国学");row7.createCell(3).setCellValue(state0Counts.getOrDefault("国学", 0).toString()); @@ -296,8 +296,8 @@ public class StatisticsBusinessVipController { Row row1 = sheet.createRow(rowNum++); Map state1Counts = (Map) r.get("banTypeTotalCounts"); Map state0Counts = (Map) r.get("yanTypeTotalCounts"); - row1.createCell(0).setCellValue("医学超级");row1.createCell(1).setCellValue(state1Counts.get("医学超级").toString()); - row1.createCell(2).setCellValue("医学超级");row1.createCell(3).setCellValue(state0Counts.get("医学超级").toString()); + row1.createCell(0).setCellValue("医学超级");row1.createCell(1).setCellValue(state1Counts.containsKey("医学超级")?state1Counts.get("医学超级").toString():""); + row1.createCell(2).setCellValue("医学超级");row1.createCell(3).setCellValue(state0Counts.containsKey("医学超级")?state0Counts.get("医学超级").toString():""); row1.createCell(4).setCellValue("总延期金额");row1.createCell(5).setCellValue(r.get("yanTotalPrice").toString()); BigDecimal b = new BigDecimal(r.get("yanTotalCount").toString()).subtract(new BigDecimal(r2.get("yanTotalCount").toString())).divide(new BigDecimal(r.get("yanTotalCount").toString()), 4, RoundingMode.HALF_UP); row1.createCell(6).setCellValue("延期总人数同比增长率:");row1.createCell(7).setCellValue(df.format(b)); @@ -320,8 +320,8 @@ public class StatisticsBusinessVipController { row5.createCell(0).setCellValue("肿瘤学");row5.createCell(1).setCellValue(state1Counts.getOrDefault("肿瘤学", 0).toString()); row5.createCell(2).setCellValue("肿瘤学");row5.createCell(3).setCellValue(state0Counts.getOrDefault("肿瘤学", 0).toString()); Row row6 = sheet.createRow(rowNum++); - row6.createCell(0).setCellValue("妇幼生殖");row6.createCell(1).setCellValue(state1Counts.getOrDefault("妇幼生殖",0).toString()); - row6.createCell(2).setCellValue("妇幼生殖");row6.createCell(3).setCellValue(state0Counts.getOrDefault("妇幼生殖", 0).toString()); + row6.createCell(0).setCellValue("妇幼生殖学");row6.createCell(1).setCellValue(state1Counts.getOrDefault("妇幼生殖学",0).toString()); + row6.createCell(2).setCellValue("妇幼生殖学");row6.createCell(3).setCellValue(state0Counts.getOrDefault("妇幼生殖学", 0).toString()); Row row7 = sheet.createRow(rowNum++); row7.createCell(0).setCellValue("国学");row7.createCell(1).setCellValue(state1Counts.getOrDefault("国学",0).toString()); row7.createCell(2).setCellValue("国学");row7.createCell(3).setCellValue(state0Counts.getOrDefault("国学", 0).toString()); @@ -346,7 +346,7 @@ public class StatisticsBusinessVipController { fillRow(sheet.createRow(rowNum++), 0, "中医学", banCounts, yanCounts); fillRow(sheet.createRow(rowNum++), 0, "针灸学", banCounts, yanCounts); fillRow(sheet.createRow(rowNum++), 0, "肿瘤学", banCounts, yanCounts); - fillRow(sheet.createRow(rowNum++), 0, "妇幼生殖", banCounts, yanCounts); + fillRow(sheet.createRow(rowNum++), 0, "妇幼生殖学", banCounts, yanCounts); fillRow(sheet.createRow(rowNum++), 0, "国学", banCounts, yanCounts); fillRow(sheet.createRow(rowNum++), 0, "心理学", banCounts, yanCounts); fillRow(sheet.createRow(rowNum++), 0, "中西汇通学", banCounts, yanCounts); @@ -360,7 +360,7 @@ public class StatisticsBusinessVipController { sheet.createRow(rowNum++).createCell(0).setCellValue("中医学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("中医学",0).toString()); sheet.createRow(rowNum++).createCell(0).setCellValue("针灸学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("针灸学",0).toString()); sheet.createRow(rowNum++).createCell(0).setCellValue("肿瘤学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("肿瘤学",0).toString()); - sheet.createRow(rowNum++).createCell(0).setCellValue("妇幼生殖");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("妇幼生殖",0).toString()); + sheet.createRow(rowNum++).createCell(0).setCellValue("妇幼生殖学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("妇幼生殖学",0).toString()); sheet.createRow(rowNum++).createCell(0).setCellValue("国学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("国学",0).toString()); sheet.createRow(rowNum++).createCell(0).setCellValue("心理学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("心理学",0).toString()); sheet.createRow(rowNum++).createCell(0).setCellValue("中西汇通学");sheet.getRow(rowNum-1).createCell(1).setCellValue(banTypeRatios.getOrDefault("中西汇通学",0).toString()); @@ -443,14 +443,17 @@ public class StatisticsBusinessVipController { row5.createCell(1).setCellValue("肿瘤学");row5.createCell(2).setCellValue(state1Counts.get("zlCount").toString()); row5.createCell(4).setCellValue("肿瘤学");row5.createCell(5).setCellValue(state0Counts.get("zlCount").toString()); Row row6 = sheet.createRow(rowNum++); - row6.createCell(1).setCellValue("国学");row6.createCell(2).setCellValue(state1Counts.get("gxCount").toString()); - row6.createCell(4).setCellValue("国学");row6.createCell(5).setCellValue(state0Counts.get("gxCount").toString()); + row6.createCell(1).setCellValue("妇幼生殖学");row6.createCell(2).setCellValue(state1Counts.get("fyszCount").toString()); + row6.createCell(4).setCellValue("妇幼生殖学");row6.createCell(5).setCellValue(state0Counts.get("fyszCount").toString()); Row row7 = sheet.createRow(rowNum++); - row7.createCell(1).setCellValue("心理学");row7.createCell(2).setCellValue(state1Counts.get("xlCount").toString()); - row7.createCell(4).setCellValue("心理学");row7.createCell(5).setCellValue(state0Counts.get("xlCount").toString()); + row7.createCell(1).setCellValue("国学");row7.createCell(2).setCellValue(state1Counts.get("gxCount").toString()); + row7.createCell(4).setCellValue("国学");row7.createCell(5).setCellValue(state0Counts.get("gxCount").toString()); Row row8 = sheet.createRow(rowNum++); - row8.createCell(1).setCellValue("中西汇通学");row8.createCell(2).setCellValue(state1Counts.get("zxhtCount").toString()); - row8.createCell(4).setCellValue("中西汇通学");row8.createCell(5).setCellValue(state0Counts.get("zxhtCount").toString()); + row8.createCell(1).setCellValue("心理学");row8.createCell(2).setCellValue(state1Counts.get("xlCount").toString()); + row8.createCell(4).setCellValue("心理学");row8.createCell(5).setCellValue(state0Counts.get("xlCount").toString()); + Row row9 = sheet.createRow(rowNum++); + row9.createCell(1).setCellValue("中西汇通学");row9.createCell(2).setCellValue(state1Counts.get("zxhtCount").toString()); + row9.createCell(4).setCellValue("中西汇通学");row9.createCell(5).setCellValue(state0Counts.get("zxhtCount").toString()); export(wb,sheet,fileName,++rowNum,response,headers,cellValues, (List>) r.get("resultList")); } @@ -489,7 +492,8 @@ public class StatisticsBusinessVipController { "6","肿瘤学", "7","国学", "8","心理学", - "9","中西汇通学" + "9","中西汇通学", + "10","妇幼生殖学" ); // 封装统计结果 @@ -510,6 +514,7 @@ public class StatisticsBusinessVipController { result.counts.put("gxCount",0); result.counts.put("xlCount",0); result.counts.put("zxhtCount",0); + result.counts.put("fyszCount",0); for (Map map : userVips) { String[] types = map.get("type").toString().split(","); @@ -517,7 +522,7 @@ public class StatisticsBusinessVipController { int yxFlag = 0; int gxFlag = 0; // 超级类型 - if (typeSet.containsAll(Arrays.asList("4","5","6","9"))) { + if (typeSet.containsAll(Arrays.asList("4","5","6","9","10"))) { yxFlag = 1; Map copy = new HashMap<>(map); copy.put("vipType","医学超级"); @@ -545,7 +550,7 @@ public class StatisticsBusinessVipController { else if ("7".equals(type) && gxFlag==0) { copy.put("vipType","国学"); result.counts.computeIfPresent("gxCount",(k,v)->v+1); } else if ("8".equals(type) && gxFlag==0) { copy.put("vipType","心理学"); result.counts.computeIfPresent("xlCount",(k,v)->v+1); } else if ("9".equals(type) && yxFlag==0) { copy.put("vipType","中西汇通学"); result.counts.computeIfPresent("zxhtCount",(k,v)->v+1); } - + else if ("10".equals(type) && yxFlag==0) { copy.put("vipType","妇幼生殖学"); result.counts.computeIfPresent("fyszCount",(k,v)->v+1); } if (copy.get("vipType") != null) { result.resultList.add(copy); result.total.add(map.get("tel").toString()); diff --git a/src/main/java/com/peanut/modules/master/controller/StatisticsController.java b/src/main/java/com/peanut/modules/master/controller/StatisticsController.java index 8403d2e..761f296 100644 --- a/src/main/java/com/peanut/modules/master/controller/StatisticsController.java +++ b/src/main/java/com/peanut/modules/master/controller/StatisticsController.java @@ -367,9 +367,13 @@ public class StatisticsController { @RequestMapping("/getUserCourseBuyInfoTotal") public R getUserCourseBuyInfoTotal(@RequestBody Map params) { - List> tanxiaoTotal = userCourseBuyService.getUserCourseBuyInfoTotal(params.get("date").toString()); - List> income = userCourseBuyService.getIncome(params.get("date").toString()); - return R.ok().put("tanxiaoTotal", tanxiaoTotal).put("income", income); + String date = params.get("date").toString(); + List> tanxiaoTotal = userCourseBuyService.getUserCourseBuyInfoTotal(date); + List> monthRefund = userCourseBuyService.getSameMonthRefund(date); + List> income = mergeIncomeWithMonthRefund( + userCourseBuyService.getIncome(date), monthRefund); + List> refund = userCourseBuyService.getRefund(date); + return R.ok().put("tanxiaoTotal", tanxiaoTotal).put("income", income).put("monthRefund", monthRefund).put("refund", refund); } //课程明细 @@ -390,42 +394,46 @@ public class StatisticsController { titleRow.createCell(8).setCellValue("支付类型"); titleRow.createCell(9).setCellValue("支付时间"); titleRow.createCell(10).setCellValue("订单编号"); - titleRow.createCell(11).setCellValue("支付宝号"); - titleRow.createCell(12).setCellValue("天数"); - titleRow.createCell(13).setCellValue("金额"); - titleRow.createCell(14).setCellValue("备注"); - titleRow.createCell(15).setCellValue("开始摊销时间"); - titleRow.createCell(16).setCellValue("每日摊销"); - titleRow.createCell(17).setCellValue("已摊销天数"); - titleRow.createCell(18).setCellValue("本期天数"); - titleRow.createCell(19).setCellValue("已摊销金额"); - titleRow.createCell(20).setCellValue("本期摊销金额"); - titleRow.createCell(21).setCellValue("剩余金额"); + titleRow.createCell(11).setCellValue("订单类型"); + titleRow.createCell(12).setCellValue("支付宝号"); + titleRow.createCell(13).setCellValue("天数"); + titleRow.createCell(14).setCellValue("金额"); + titleRow.createCell(15).setCellValue("备注"); + titleRow.createCell(16).setCellValue("开始摊销时间"); + titleRow.createCell(17).setCellValue("每日摊销"); + titleRow.createCell(18).setCellValue("已摊销天数"); + titleRow.createCell(19).setCellValue("本期天数"); + titleRow.createCell(20).setCellValue("已摊销金额"); + titleRow.createCell(21).setCellValue("本期摊销金额"); + titleRow.createCell(22).setCellValue("剩余金额"); + titleRow.createCell(23).setCellValue("退款单号"); int cell = 1; for (Map map : maps) { Row row = sheet.createRow(cell); - row.createCell(0).setCellValue(map.get("name").toString()); - row.createCell(1).setCellValue(map.get("tel").toString()); - row.createCell(2).setCellValue(map.get("ctitle").toString()); - row.createCell(3).setCellValue(map.get("cctitle").toString()); - row.createCell(4).setCellValue(map.get("startTime").toString()); - row.createCell(5).setCellValue(map.get("endTime").toString()); - row.createCell(6).setCellValue(map.get("totalDays").toString()); - row.createCell(7).setCellValue(map.get("type").toString()); - row.createCell(8).setCellValue(map.get("payType").toString()); - row.createCell(9).setCellValue(map.get("payTime").toString()); - row.createCell(10).setCellValue(map.get("orderSn").toString()); - row.createCell(11).setCellValue(map.get("zfbOrder")==null?"":map.get("zfbOrder").toString()); - row.createCell(12).setCellValue(map.get("days").toString()); - row.createCell(13).setCellValue(map.get("fee").toString()); - row.createCell(14).setCellValue(map.get("remark").toString()); - row.createCell(15).setCellValue(map.get("startTanxiaoTime")==null?"":map.get("startTanxiaoTime").toString()); - row.createCell(16).setCellValue(map.get("dayAmount").toString()); - row.createCell(17).setCellValue(map.get("alreadyDay").toString()); - row.createCell(18).setCellValue(map.get("currentDay").toString()); - row.createCell(19).setCellValue(map.get("alreadyTanxiao").toString()); - row.createCell(20).setCellValue(map.get("currentTanxiao").toString()); - row.createCell(21).setCellValue(map.get("surplusTanxiao").toString()); + row.createCell(0).setCellValue(cellStr(map.get("name"))); + row.createCell(1).setCellValue(cellStr(map.get("tel"))); + row.createCell(2).setCellValue(cellStr(map.get("ctitle"))); + row.createCell(3).setCellValue(cellStr(map.get("cctitle"))); + row.createCell(4).setCellValue(cellStr(map.get("startTime"))); + row.createCell(5).setCellValue(cellStr(map.get("endTime"))); + row.createCell(6).setCellValue(cellStr(map.get("totalDays"))); + row.createCell(7).setCellValue(cellStr(map.get("type"))); + row.createCell(8).setCellValue(cellStr(map.get("payType"))); + row.createCell(9).setCellValue(cellStr(map.get("payTime"))); + row.createCell(10).setCellValue(cellStr(map.get("orderSn"))); + row.createCell(11).setCellValue(cellStr(map.get("orderStatus"))); + row.createCell(12).setCellValue(cellStr(map.get("zfbOrder"))); + row.createCell(13).setCellValue(cellStr(map.get("days"))); + row.createCell(14).setCellValue(cellStr(map.get("fee"))); + row.createCell(15).setCellValue(cellStr(map.get("remark"))); + row.createCell(16).setCellValue(cellStr(map.get("startTanxiaoTime"))); + row.createCell(17).setCellValue(cellStr(map.get("dayAmount"))); + row.createCell(18).setCellValue(cellStr(map.get("alreadyDay"))); + row.createCell(19).setCellValue(cellStr(map.get("currentDay"))); + row.createCell(20).setCellValue(cellStr(map.get("alreadyTanxiao"))); + row.createCell(21).setCellValue(cellStr(map.get("currentTanxiao"))); + row.createCell(22).setCellValue(cellStr(map.get("surplusTanxiao"))); + row.createCell(22).setCellValue(cellStr(map.get("refund_no"))); //序号自增 cell++; } @@ -456,7 +464,8 @@ public class StatisticsController { public R getTransactionDetailsTotal(@RequestBody Map params) { Map map = transactionDetailsService.getUserSurplusPeanutCoin(params.get("date").toString()+" 23:59:59"); List> list = transactionDetailsService.getTransactionDetailsTotal(params.get("date").toString()+" 23:59:59"); - return R.ok().put("total", list).put("surplus", map); + List> refundList = transactionDetailsService.getRefundTransactionDetails(params.get("date").toString()+" 23:59:59"); + return R.ok().put("total", list).put("surplus", map).put("refundInfo", refundList); } //导出实物订单明细 @@ -523,7 +532,8 @@ public class StatisticsController { @RequestMapping("/getPhysicalBuyOrderInfoTotal") public R getPhysicalBuyOrderInfoTotal(@RequestBody Map params) { - List> list = buyOrderService.getPhysicalBuyOrderTotal(params.get("date").toString(),params.get("orderType").toString()); + List> list = buyOrderService.getPhysicalBuyOrderTotal( + params.get("date").toString(), params.get("orderType").toString()); return R.ok().put("total", list); } @@ -548,6 +558,7 @@ public class StatisticsController { titleRow.createCell(9).setCellValue("商品名称"); titleRow.createCell(10).setCellValue("数量"); titleRow.createCell(11).setCellValue("备注"); + titleRow.createCell(12).setCellValue("退款单号"); //序号,默认为1 int cell = 1; //遍历 @@ -560,11 +571,12 @@ public class StatisticsController { row.createCell(4).setCellValue(map.get("zfbOrder")==null?"":map.get("zfbOrder").toString()); row.createCell(5).setCellValue(map.get("orderStatus").toString()); row.createCell(6).setCellValue(map.get("payType").toString()); - row.createCell(7).setCellValue(map.get("orderPrice").toString()); - row.createCell(8).setCellValue(map.get("price").toString()); + row.createCell(7).setCellValue(toAmount(map.get("orderPrice")).doubleValue()); + row.createCell(8).setCellValue(toAmount(map.get("price")).doubleValue()); row.createCell(9).setCellValue(map.get("productName").toString()); row.createCell(10).setCellValue(map.get("quantity").toString()); row.createCell(11).setCellValue(map.get("remark").toString()); + row.createCell(12).setCellValue(map.get("refund_no")!=null?map.get("refund_no").toString():""); //序号自增 cell++; } @@ -593,7 +605,40 @@ public class StatisticsController { @RequestMapping("/getUserVipLogInfoTotal") public R getUserVipLogInfoTotal(@RequestBody Map params) { - Map map = userVipLogService.getUserVipLogInfoTotal(params.get("date").toString()); + String date = params.get("date").toString(); + //有效订单 + Map map = userVipLogService.getUserVipLogInfoTotal(date); + //本月退款金额 + BigDecimal refundFee = userVipLogService.getUserVipRefundFeeTotal(date); + //本月退款的订单 + List> monthRefundMap = userVipLogService.getMonthRefund(date); + String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; + BigDecimal refundFeeToSR = BigDecimal.ZERO; + BigDecimal refundMonthTX = BigDecimal.ZERO; + BigDecimal refundYetTX = BigDecimal.ZERO; + if(date.equals("2026-04-30"))log.info("currentTanxiao======="+map.get("currentTanxiao").toString()); + for (Map one : monthRefundMap) { + String payMonth = userVipLogService.getPayMonth(one); + if (exportMonth.equals(payMonth)) { + refundFeeToSR = refundFeeToSR.add(new BigDecimal(one.get("fee").toString())); + }else if (!payMonth.isEmpty() && !exportMonth.equals(payMonth)) { + refundMonthTX = refundMonthTX.subtract(new BigDecimal(one.get("alreadyTanxiao").toString())); + //refundYetTX = refundYetTX.subtract(new BigDecimal(one.get("currentTanxiao").toString())).subtract(new BigDecimal(one.get("notyetTanxiao").toString())); + } + } + //当月未退款,下月之后退款的订单 + List> monthNextNRefundMap = userVipLogService.getNextNMonthRefund(date); + for (Map two : monthNextNRefundMap) { + System.out.println(two); + refundFeeToSR = refundFeeToSR.add(new BigDecimal(two.get("fee").toString())); + refundMonthTX = refundMonthTX.add(new BigDecimal(two.get("currentTanxiao").toString())); + if(date.equals("2026-04-30"))log.info("refundMonthTX======="+two.get("currentTanxiao").toString()+"/"+refundMonthTX); + refundYetTX = refundYetTX.add(new BigDecimal(two.get("notyetTanxiao").toString())); + } + map.put("fee", toAmount(map.get("fee")).add(refundFeeToSR)); + map.put("currentTanxiao", toAmount(map.get("currentTanxiao")).add(refundMonthTX)); + map.put("notyetTanxiao", toAmount(map.get("notyetTanxiao")).add(refundYetTX)); + map.put("refundFee", refundFee); return R.ok().put("total", map); } @@ -613,19 +658,21 @@ public class StatisticsController { titleRow.createCell(4).setCellValue("结束时间"); titleRow.createCell(5).setCellValue("支付时间"); titleRow.createCell(6).setCellValue("订单号"); - titleRow.createCell(7).setCellValue("支付宝号"); - titleRow.createCell(8).setCellValue("支付方式"); - titleRow.createCell(9).setCellValue("备注"); - titleRow.createCell(10).setCellValue("缴费金额"); - titleRow.createCell(11).setCellValue("摊销计算金额"); - titleRow.createCell(12).setCellValue("总天数"); - titleRow.createCell(13).setCellValue("每日摊销"); - titleRow.createCell(14).setCellValue("已摊销天数"); - titleRow.createCell(15).setCellValue("当月摊销天数"); - titleRow.createCell(16).setCellValue("未摊销天数"); - titleRow.createCell(17).setCellValue("已摊销金额"); - titleRow.createCell(18).setCellValue("当月摊销金额"); - titleRow.createCell(19).setCellValue("剩余摊销金额"); + titleRow.createCell(7).setCellValue("订单类型"); + titleRow.createCell(8).setCellValue("支付宝号"); + titleRow.createCell(9).setCellValue("支付方式"); + titleRow.createCell(10).setCellValue("备注"); + titleRow.createCell(11).setCellValue("缴费金额"); + titleRow.createCell(12).setCellValue("摊销计算金额"); + titleRow.createCell(13).setCellValue("总天数"); + titleRow.createCell(14).setCellValue("每日摊销"); + titleRow.createCell(15).setCellValue("已摊销天数"); + titleRow.createCell(16).setCellValue("当月摊销天数"); + titleRow.createCell(17).setCellValue("未摊销天数"); + titleRow.createCell(18).setCellValue("已摊销金额"); + titleRow.createCell(19).setCellValue("当月摊销金额"); + titleRow.createCell(20).setCellValue("剩余摊销金额"); + titleRow.createCell(21).setCellValue("退款单号"); //序号,默认为1 int cell = 1; //遍历 @@ -638,19 +685,21 @@ public class StatisticsController { row.createCell(4).setCellValue(map.get("endTime").toString()); row.createCell(5).setCellValue(map.get("payTime").toString()); row.createCell(6).setCellValue(map.get("orderSn").toString()); - row.createCell(7).setCellValue(map.get("zfbOrder")==null?"":map.get("zfbOrder").toString()); - row.createCell(8).setCellValue(map.get("payType").toString()); - row.createCell(9).setCellValue(map.get("remark").toString()); - row.createCell(10).setCellValue(map.get("price").toString()); - row.createCell(11).setCellValue(map.get("fee").toString()); - row.createCell(12).setCellValue(map.get("totalDays").toString()); - row.createCell(13).setCellValue(map.get("dayAmount").toString()); - row.createCell(14).setCellValue(map.get("alreadyDays").toString()); - row.createCell(15).setCellValue(map.get("currentDays").toString()); - row.createCell(16).setCellValue(map.get("notyetDays").toString()); - row.createCell(17).setCellValue(map.get("alreadyTanxiao").toString()); - row.createCell(18).setCellValue(map.get("currentTanxiao").toString()); - row.createCell(19).setCellValue(map.get("notyetTanxiao").toString()); + row.createCell(7).setCellValue(map.get("orderStatus").toString()); + row.createCell(8).setCellValue(map.get("zfbOrder")==null?"":map.get("zfbOrder").toString()); + row.createCell(9).setCellValue(map.get("payType").toString()); + row.createCell(10).setCellValue(map.get("remark").toString()); + row.createCell(11).setCellValue(map.get("price").toString()); + row.createCell(12).setCellValue(map.get("fee").toString()); + row.createCell(13).setCellValue(map.get("totalDays").toString()); + row.createCell(14).setCellValue(map.get("dayAmount").toString()); + row.createCell(15).setCellValue(map.get("alreadyDays").toString()); + row.createCell(16).setCellValue(map.get("currentDays").toString()); + row.createCell(17).setCellValue(map.get("notyetDays").toString()); + row.createCell(18).setCellValue(map.get("alreadyTanxiao").toString()); + row.createCell(19).setCellValue(map.get("currentTanxiao").toString()); + row.createCell(20).setCellValue(map.get("notyetTanxiao").toString()); + row.createCell(21).setCellValue(map.get("refund_no")!=null?map.get("refund_no").toString():""); //序号自增 cell++; } @@ -677,6 +726,50 @@ public class StatisticsController { } } + private BigDecimal toAmount(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + return new BigDecimal(value.toString()); + } + private List> mergeIncomeWithMonthRefund(List> income, + List> monthRefund) { + Map feeMap = new LinkedHashMap<>(); + for (Map row : income) { + String payType = normalizeCoursePayType(row.get("pay_type")); + feeMap.merge(payType, toAmount(row.get("fee")), BigDecimal::add); + } + for (Map row : monthRefund) { + String payType = normalizeCoursePayType(row.get("pay_type")); + feeMap.merge(payType, toAmount(row.get("fee")), BigDecimal::add); + } + List> result = new ArrayList<>(); + for (Map.Entry entry : feeMap.entrySet()) { + Map map = new HashMap<>(); + map.put("pay_type", entry.getKey()); + map.put("fee", entry.getValue()); + result.add(map); + } + return result; + } + + private String normalizeCoursePayType(Object payType) { + if (payType == null) { + return ""; + } + String type = payType.toString(); + if (type.startsWith("App")) { + return type.substring(3); + } + return type; + } + + private static String cellStr(Object value) { + return value == null ? "" : value.toString(); + } } diff --git a/src/main/java/com/peanut/modules/master/controller/UserCertificateController.java b/src/main/java/com/peanut/modules/master/controller/UserCertificateController.java index 2c55064..1b11914 100644 --- a/src/main/java/com/peanut/modules/master/controller/UserCertificateController.java +++ b/src/main/java/com/peanut/modules/master/controller/UserCertificateController.java @@ -288,7 +288,11 @@ public class UserCertificateController { ClassEntity classEntity = classEntityService.getById(params.get("classId").toString()); String type = params.get("type").toString(); List certificateNoList = new ArrayList<>(); - Map classCourseInfo = classEntityService.getClassCourseInfoByClassId(classEntity.getId(),0); + int courseId = 0; + if(params.containsKey("courseId")){ + courseId = Integer.parseInt(params.get("courseId").toString()); + } + Map classCourseInfo = classEntityService.getClassCourseInfoByClassId(classEntity.getId(),courseId); String pinyin = classCourseInfo.get("titleAbbr").toString(); String tels = params.get("tels").toString(); @@ -309,26 +313,26 @@ public class UserCertificateController { userCertificate.setCertificateNo(certificateNo); userCertificate.setCourseId((Integer) classCourseInfo.get("courseId")); - if (StringUtils.isNotEmpty(user.getPhoto())&&StringUtils.isNotEmpty(user.getName())){ - String startYear = DateUtil.year(classEntity.getStartTime())+""; - String startMonth = DateUtil.month(classEntity.getStartTime())+1+""; - String startDay = DateUtil.dayOfMonth(classEntity.getStartTime())+""; - String endYear = DateUtil.year(classEntity.getEndTime())+""; - String endMonth = DateUtil.month(classEntity.getEndTime())+1+""; - String endDay = DateUtil.dayOfMonth(classEntity.getEndTime())+""; - double keshiTotal = (double)classCourseInfo.get("keshi"); - String keshi = (keshiTotal+"").replace(".0",""); - String courseTitle = classCourseInfo.get("courseTitle").toString(); - if (courseTitle.contains("【")){ - courseTitle = courseTitle.substring(0,courseTitle.indexOf("【")); - } - String[] des = {startYear,startMonth,startDay,endYear,endMonth,endDay, - classEntity.getTitle(),courseTitle,keshi}; - String[] edes = {classCourseInfo.get("courseETitle").toString(),keshi}; - String url = userCertificateService.generateCertificate(type,certificateNo,user.getPhoto(),user.getName(), - des, edes, endYear,endMonth,endDay); - userCertificate.setCertificateUrl(url); - } +// if (StringUtils.isNotEmpty(user.getPhoto())&&StringUtils.isNotEmpty(user.getName())){ +// String startYear = DateUtil.year(classEntity.getStartTime())+""; +// String startMonth = DateUtil.month(classEntity.getStartTime())+1+""; +// String startDay = DateUtil.dayOfMonth(classEntity.getStartTime())+""; +// String endYear = DateUtil.year(classEntity.getEndTime())+""; +// String endMonth = DateUtil.month(classEntity.getEndTime())+1+""; +// String endDay = DateUtil.dayOfMonth(classEntity.getEndTime())+""; +// double keshiTotal = (double)classCourseInfo.get("keshi"); +// String keshi = (keshiTotal+"").replace(".0",""); +// String courseTitle = classCourseInfo.get("courseTitle").toString(); +// if (courseTitle.contains("【")){ +// courseTitle = courseTitle.substring(0,courseTitle.indexOf("【")); +// } +// String[] des = {startYear,startMonth,startDay,endYear,endMonth,endDay, +// classEntity.getTitle(),courseTitle,keshi}; +// String[] edes = {classCourseInfo.get("courseETitle").toString(),keshi}; +// String url = userCertificateService.generateCertificate(type,certificateNo,user.getPhoto(),user.getName(), +// des, edes, endYear,endMonth,endDay); +// userCertificate.setCertificateUrl(url); +// } userCertificateService.save(userCertificate); certificateNoList.add(user.getTel()); } diff --git a/src/main/java/com/peanut/modules/master/controller/UserVipController.java b/src/main/java/com/peanut/modules/master/controller/UserVipController.java index ceaae34..5a72ec0 100644 --- a/src/main/java/com/peanut/modules/master/controller/UserVipController.java +++ b/src/main/java/com/peanut/modules/master/controller/UserVipController.java @@ -221,7 +221,8 @@ public class UserVipController { "5".equals(params.get("type").toString())?"延期针灸学VIP": "6".equals(params.get("type").toString())?"延期肿瘤学VIP": "7".equals(params.get("type").toString())?"延期国学VIP": - "8".equals(params.get("type").toString())?"延期心理学VIP":"延期中西汇通VIP"; + "8".equals(params.get("type").toString())?"延期心理学VIP": + "10".equals(params.get("type").toString())?"妇幼生殖学VIP":"延期中西汇通VIP"; if(fee.compareTo(BigDecimal.ZERO)>0){ user.setPeanutCoin(user.getPeanutCoin().subtract(fee)); TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity(); @@ -249,8 +250,8 @@ public class UserVipController { List typeList = new ArrayList<>(); int count = 1; if ("11".equals(params.get("type").toString())) {//超v - count = 6; - for (int i=4;i<10;i++){ + count = 7; + for (int i=4;i<=10;i++){ typeList.add(i); } }else if ("12".equals(params.get("type").toString())) {//简易超v @@ -262,11 +263,12 @@ public class UserVipController { typeList.add(i); } }else if ("1".equals(params.get("type").toString())) {//医学超级 - count = 4; - for (int i=4;i<8;i++){ + count = 5; + for (int i=4;i<=10;i++){ if (i==7){ i = 9; } + log.info("=========000000===="+i); typeList.add(i); } }else if ("2".equals(params.get("type").toString())) {//国心超级 diff --git a/src/main/java/com/peanut/modules/master/service/UserCourseBuyService.java b/src/main/java/com/peanut/modules/master/service/UserCourseBuyService.java index d37ffc8..1db83c4 100644 --- a/src/main/java/com/peanut/modules/master/service/UserCourseBuyService.java +++ b/src/main/java/com/peanut/modules/master/service/UserCourseBuyService.java @@ -24,6 +24,12 @@ public interface UserCourseBuyService extends IService { List> getIncome(String date); + List> getRefund(String date); + + List> getSameMonthRefund(String date); + + List> getRefundInfo(String date); + List> getUserCourseBuyInfoTotal(String date); List> getUserCourseBuyInfo(String date); diff --git a/src/main/java/com/peanut/modules/master/service/impl/UserCourseBuyServiceImpl.java b/src/main/java/com/peanut/modules/master/service/impl/UserCourseBuyServiceImpl.java index 0b054d0..e738d52 100644 --- a/src/main/java/com/peanut/modules/master/service/impl/UserCourseBuyServiceImpl.java +++ b/src/main/java/com/peanut/modules/master/service/impl/UserCourseBuyServiceImpl.java @@ -20,8 +20,11 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; +import java.math.RoundingMode; import java.net.URL; import java.net.URLConnection; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; import java.util.*; @Slf4j @@ -186,6 +189,21 @@ public class UserCourseBuyServiceImpl extends ServiceImpl> getRefund(String date) { + return this.baseMapper.getRefund(date); + } + + @Override + public List> getSameMonthRefund(String date) { + return this.baseMapper.getSameMonthRefund(date); + } + + @Override + public List> getRefundInfo(String date) { + return this.baseMapper.getRefundInfo(date); + } + @Override public List> getUserCourseBuyInfoTotal(String date) { return this.baseMapper.getUserCourseBuyInfoTotal(date); @@ -193,7 +211,165 @@ public class UserCourseBuyServiceImpl extends ServiceImpl> getUserCourseBuyInfo(String date) { - return this.baseMapper.getUserCourseBuyInfo(date); + List> list = this.baseMapper.getUserCourseBuyInfo(date); + Map> refundMap = new HashMap<>(); + for (Map refund : this.baseMapper.getRefundInfo(date)) { + refundMap.put(refundKey(refund), refund); + } + List> result = new ArrayList<>(); + Set matchedKeys = new HashSet<>(); + String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; + for (Map row : list) { + row.put("orderStatus", "已付款"); + Map refund = refundMap.get(refundKey(row)); + if (refund != null) { + if (exportMonth.equals(getPayMonth(row))) { + row.put("currentDay", 0); + row.put("currentTanxiao", BigDecimal.ZERO); + row.put("surplusTanxiao", BigDecimal.ZERO); + result.add(row); + } + matchedKeys.add(refundKey(row)); + result.add(buildRefundRow(row, refund, date)); + } else { + result.add(row); + } + } + for (Map refund : refundMap.values()) { + String key = refundKey(refund); + if (matchedKeys.contains(key)) { + continue; + } + String payMonth = getPayMonth(refund); + if (exportMonth.equals(payMonth)) { + Map paidRow = buildPaidRowFromRefund(refund); + result.add(paidRow); + result.add(buildRefundRow(paidRow, refund, date)); + } else if (!payMonth.isEmpty() && payMonth.compareTo(exportMonth) < 0) { + result.add(buildRefundRow(buildBaseRowFromRefund(refund), refund, date)); + } + } + return result; + } + + private String refundKey(Map row) { + return String.valueOf(row.get("orderSn")) + "|" + String.valueOf(row.get("ctitle")) + "|" + String.valueOf(row.get("cctitle")); + } + + private Map buildPaidRowFromRefund(Map refund) { + Map row = new HashMap<>(refund); + row.remove("refundTime"); + row.remove("orderStatus"); + fillAmortizationFields(row); + row.put("alreadyDay", 0); + row.put("currentDay", 0); + row.put("alreadyTanxiao", BigDecimal.ZERO); + row.put("currentTanxiao", BigDecimal.ZERO); + row.put("surplusTanxiao", BigDecimal.ZERO); + row.put("orderStatus", "已付款"); + return row; + } + + private Map buildBaseRowFromRefund(Map refund) { + Map row = new HashMap<>(refund); + row.remove("refundTime"); + row.remove("orderStatus"); + fillAmortizationFields(row); + return row; + } + + private void fillAmortizationFields(Map row) { + BigDecimal fee = toBigDecimal(row.get("fee")); + int days = toInt(row.get("days")); + Object startTime = row.get("startTime"); + boolean hasStartTime = startTime != null && !startTime.toString().isEmpty(); + row.put("dayAmount", hasStartTime && days > 0 + ? fee.divide(new BigDecimal(days), 2, RoundingMode.HALF_UP) + : BigDecimal.ZERO); + row.put("startTanxiaoTime", hasStartTime ? startTime.toString() : ""); + } + + private Map buildRefundRow(Map row, Map refund, String date) { + Map refundRow = new HashMap<>(row); + refundRow.put("orderStatus", "已退款"); + refundRow.put("payTime", refund.get("refundTime")); + + String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; + String payMonth = getPayMonth(row); + BigDecimal dayAmount = toBigDecimal(row.get("dayAmount")); + + if (exportMonth.equals(payMonth)) { + refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); + refundRow.put("alreadyDay", 0); + refundRow.put("currentDay", 0); + refundRow.put("alreadyTanxiao", BigDecimal.ZERO); + refundRow.put("currentTanxiao", BigDecimal.ZERO); + refundRow.put("surplusTanxiao", BigDecimal.ZERO); + } else if (payMonth.compareTo(exportMonth) < 0) { + int alreadyDay = calcAlreadyDaysToPrevMonthEnd(row, date); + BigDecimal alreadyTanxiao = dayAmount.multiply(new BigDecimal(alreadyDay)).setScale(2, RoundingMode.HALF_UP); + refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); + refundRow.put("alreadyDay", alreadyDay); + refundRow.put("currentDay", 0); + refundRow.put("alreadyTanxiao", BigDecimal.ZERO); + refundRow.put("currentTanxiao", alreadyTanxiao.negate()); + refundRow.put("surplusTanxiao", BigDecimal.ZERO); + } else { + refundRow.put("fee", toBigDecimal(row.get("fee")).negate()); + refundRow.put("currentDay", 0); + refundRow.put("currentTanxiao", toBigDecimal(row.get("alreadyTanxiao")).negate()); + refundRow.put("surplusTanxiao", BigDecimal.ZERO); + } + return refundRow; + } + + private String getPayMonth(Map row) { + Object payTime = row.get("payTime"); + if (payTime != null && !payTime.toString().isEmpty()) { + return payTime.toString().substring(0, 7); + } + Object startTime = row.get("startTime"); + if (startTime != null && !startTime.toString().isEmpty()) { + return startTime.toString().substring(0, 7); + } + return ""; + } + + private int calcAlreadyDaysToPrevMonthEnd(Map row, String date) { + Object payTime = row.get("payTime"); + String payDateStr = payTime != null && !payTime.toString().isEmpty() + ? payTime.toString() + : (row.get("startTime") != null ? row.get("startTime").toString() : ""); + if (payDateStr.length() < 10) { + return 0; + } + LocalDate payDate = LocalDate.parse(payDateStr.substring(0, 10)); + String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date; + LocalDate prevMonthEnd = LocalDate.parse(exportMonth + "-01").minusDays(1); + if (payDate.isAfter(prevMonthEnd)) { + return 0; + } + return (int) ChronoUnit.DAYS.between(payDate, prevMonthEnd) + 1; + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + return new BigDecimal(value.toString()); + } + + private int toInt(Object value) { + if (value == null) { + return 0; + } + if (value instanceof Number) { + return ((Number) value).intValue(); + } + return Integer.parseInt(value.toString()); } @Override diff --git a/src/main/resources/mapper/book/BuyOrderDao.xml b/src/main/resources/mapper/book/BuyOrderDao.xml index 19bca0e..feb3e85 100644 --- a/src/main/resources/mapper/book/BuyOrderDao.xml +++ b/src/main/resources/mapper/book/BuyOrderDao.xml @@ -67,7 +67,7 @@ left join shop_product sp on sp.product_id = bop.product_id where ( 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 (bo.payment_method='1' or bo.payment_method='2') and bo.create_time>='2026-05-06 00:00:00') ) - and bo.order_status in (1,2,3,4) and sp.goods_type != '05' and bo.real_money > 0 + and bo.order_status in (1,2,3,4,6) and sp.goods_type != '05' and bo.real_money > 0 and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >= 37867)) @@ -90,7 +90,47 @@ ) s group by payType - + + + + - + + + + + + + + + + @@ -35,7 +255,7 @@ dayAmount*currentDays currentTanxiao, fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao from ( - select u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,IF(uv.type=4,'中医学',IF(uv.type=5,'针灸学',IF(uv.type=6,'肿瘤学',IF(uv.type=7,'国学',IF(uv.type=8,'心理学','中西汇通学'))))) type, + select u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,IF(uv.type=4,'中医学',IF(uv.type=5,'针灸学',IF(uv.type=6,'肿瘤学',IF(uv.type=7,'国学',IF(uv.type=8,'心理学',IF(uv.type=10,'妇幼生殖学','中西汇通学')))))) type, uvl.start_time startTime,uvl.end_time endTime,if(uvl.pay_time is null,'',uvl.pay_time) payTime,uvl.order_sn orderSn,pzo.trade_no zfbOrder,uvl.pay_type payType,uvl.remark,uvl.price,uvl.fee,DATEDIFF(uvl.end_time,uvl.start_time)+1 totalDays,ROUND(uvl.fee/(DATEDIFF(uvl.end_time,uvl.start_time)+1),2) dayAmount, IF(DATE_FORMAT(uvl.end_time, '%Y-%m') < SUBSTR(#{date},1,7),DATEDIFF(uvl.end_time,uvl.start_time)+1,IF(DATE_FORMAT(uvl.start_time, '%Y-%m') > SUBSTR(#{date},1,7),0,IF(DATE_FORMAT(uvl.start_time, '%Y-%m') < SUBSTR(#{date},1,7),DATEDIFF(concat(SUBSTR(#{date},1,7),'-01'),uvl.start_time),0))) alreadyDays, 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, @@ -50,12 +270,56 @@ ) s + + + + +