Compare commits

...

30 Commits

Author SHA1 Message Date
wyn
60e507b750 课程复读订单退款(relearn) 2026-06-22 17:23:25 +08:00
wyn
54069c6810 vip报表 退款月份和下单月份不一样的,开始时间设置为退款时间。 2026-06-22 09:25:23 +08:00
wyn
7dc1241064 报表相关 增加退款后,报表中需要体现 2026-06-18 17:37:43 +08:00
wyn
156862a0c5 给指定用户生成制定课程的证书 2026-06-05 15:44:53 +08:00
wyn
5b77220ae5 指定2023预售书只有妇幼生殖vip送积分,其他vip送优惠券 2026-06-03 15:27:02 +08:00
wyn
13b32ccd55 指定2023预售书只有妇幼生殖vip送积分,其他vip送优惠券 2026-06-02 17:53:57 +08:00
wyn
a3ffd72d6e 更新课程考试题 2026-06-02 14:26:13 +08:00
wyn
4e8b479683 退VIP后,如果有延期VIP,需要退掉延期VIP才可以退掉此VIP订单 2026-06-02 14:24:56 +08:00
wyn
24264b82ff Merge remote-tracking branch 'origin/wyn-课程表' into wyn
# Conflicts:
#	src/main/java/com/peanut/modules/common/service/CourseMedicineService.java
2026-05-19 10:42:00 +08:00
wyn
7e39f3f5f9 订单退款 如果是买书的订单,部分发货,不显示申请退款按钮 2026-05-15 16:30:15 +08:00
wyn
99a873993d 管理后台订单 VIP和课程不限制七天,后台都可以退款,app限制七天 2026-05-15 14:42:40 +08:00
wyn
8d0d503700 课程详情添加课程表图片 2026-05-14 18:36:33 +08:00
wyn
032b16aba5 增加妇幼生殖VIP 2026-05-14 18:08:33 +08:00
wyn
d70492031e 增加妇幼生殖VIP 2026-05-12 14:50:58 +08:00
wyn
bc52704f0f 退单 2026-05-08 18:16:00 +08:00
wyn
f58918b179 退单 2026-05-08 13:54:45 +08:00
wyn
d3b25e8078 退单 2026-05-08 09:14:07 +08:00
wyn
e1eecb5cdc 退款 2026-05-07 08:00:15 +08:00
wyn
f47bca3a8b 退单 2026-05-06 18:08:27 +08:00
wyn
7cb2d42662 退款 2026-05-02 20:24:26 +08:00
wyn
5422fe0140 退款 2026-05-02 18:38:51 +08:00
wyn
4e672f7e1d 退款 2026-04-30 23:08:14 +08:00
wyn
594c99b4dc 退单 2026-04-30 19:00:15 +08:00
wyn
a4edccc7de 退单 2026-04-30 09:54:18 +08:00
wyn
6bc3f33d3d 退款 2026-04-28 23:21:29 +08:00
wyn
f50e17aa87 退单 2026-04-28 18:15:23 +08:00
wyn
43d0340593 退单 2026-04-28 17:34:00 +08:00
wyn
f57f5dc9d9 退单 2026-04-28 17:21:51 +08:00
wyn
dca56c9493 退单 2026-04-27 17:53:56 +08:00
wyn
9b8b818ad1 退单 2026-04-27 17:53:41 +08:00
72 changed files with 2675 additions and 244 deletions

View File

@@ -26,6 +26,18 @@ public class Constants {
* 订单状态 - 交易失败
*/
public static final String ORDER_STATUS_FAIL = "4";
/**
* 订单状态 - 交易超时
*/
public static final String ORDER_STATUS_TIMEOUT = "5";
/**
* 订单状态 - 退款
*/
public static final String ORDER_STATUS_REFUND = "6";
/**
* 订单状态 - 退款中
*/
public static final String ORDER_STATUS_REFUNDING = "7";
/**
* 订单状态 - 全部

View File

@@ -6,10 +6,8 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.DateUtils;
import com.peanut.common.utils.PageUtils;
import com.peanut.common.utils.R;
import com.peanut.common.utils.ShiroUtils;
import com.alibaba.fastjson.JSONObject;
import com.peanut.common.utils.*;
import com.peanut.config.Constants;
import com.peanut.config.DelayQueueConfig;
import com.peanut.modules.book.service.*;
@@ -33,11 +31,16 @@ import com.peanut.modules.common.dao.UserCourseBuyDao;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.*;
import com.peanut.modules.master.service.CourseCatalogueService;
import com.peanut.modules.pay.alipay.dto.ReFundDTO;
import com.peanut.modules.pay.alipay.service.AliPayService;
import com.peanut.modules.pay.weChatPay.dto.WeChatRefundInfo;
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
import com.peanut.modules.pay.weChatPay.service.WxpayService;
import com.peanut.modules.sys.entity.SysConfigEntity;
import com.peanut.modules.sys.service.SysConfigService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@@ -118,6 +121,12 @@ public class BuyOrderController {
private UserCourseBuyLogService userCourseBuyLogService;
@Autowired
private CourseCatalogueService courseCatalogueService;
@Autowired
private BuyOrderRefundService buyOrderRefundService;
@Autowired
private BuyOrderRefundLogService buyOrderRefundLogService;
@Autowired
private AliPayService aliPayService;
@RequestMapping(value = "/decomposeShipment", method = RequestMethod.POST)
public R decomposeShipment(@RequestBody BuyOrderListRequestVo requestVo) {
@@ -141,7 +150,9 @@ public class BuyOrderController {
*/
@RequestMapping(path = "/orderList", method = RequestMethod.POST)
public R orderList(@RequestBody BuyOrderListRequestVo requestVo) {
Page<BuyOrder> buyOrderPage = buyOrderService.orderList(requestVo);
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
Boolean isHT = request.getHeader("appType")==null?true:false;
Page<BuyOrder> buyOrderPage = buyOrderService.orderList(requestVo, isHT);
return R.ok().put("result", buyOrderPage);
}
//导出名医精彩订单
@@ -580,7 +591,193 @@ public class BuyOrderController {
result.put("money", totalPrice);
return R.ok(result);
}
//订单退款进度
@RequestMapping("/refundDetail")
public R refundOrderDetail(@RequestBody Map params){
Object orderIdObj = params.get("orderId");
if(orderIdObj == null || orderIdObj.toString().trim().equals("")){
return R.error("orderId不能为空");
}
int order_id = Integer.parseInt(orderIdObj.toString().trim());
QueryWrapper<BuyOrderRefund> wapper = new QueryWrapper<>();
wapper.eq("order_id",order_id);
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(wapper);
if(refundInfo==null){
return R.error("退款信息不存在");
}
QueryWrapper<BuyOrderRefundLog> wapper2 = new QueryWrapper<>();
wapper2.eq("refund_id",refundInfo.getId()).orderByDesc("id");
List<BuyOrderRefundLog> list = buyOrderRefundLogService.list(wapper2);
for (BuyOrderRefundLog log : list){
if(log.getType()==4){
log.setTitle("天医币已退还");
log.setContent("天医币已退还到账户,可在我的->天医币中查看明细");
}else if(log.getType()==5){
log.setTitle("积分已退还");
log.setContent("积分已退还到账户,可在我的->积分中查看明细");
}else if(log.getType()==2){
log.setTitle(log.getStatus()==1?"到账成功":(log.getStatus()==2?"支付宝处理中":"提交支付宝处理"));
log.setContent(log.getStatus()==1?"已退到您的支付宝,到账时间以支付宝处理时间为准,可前往「支付宝-账单」查看":(log.getStatus()==2?"已将退款提交给支付宝处理":"支付宝处理中通常情况下退款会原路退回您的支付账户预计会在1-7天内到账"));
}else if(log.getType()==1){
log.setTitle(log.getStatus()==1?"到账成功":(log.getStatus()==2?"微信处理中":"提交微信处理"));
log.setContent(log.getStatus()==1?"已退到您的微信,到账时间以微信处理时间为准,可前往「微信-账单」查看":(log.getStatus()==2?"已将退款提交给微信处理":"微信处理中通常情况下退款会原路退回您的支付账户预计会在1-7天内到账"));
}else if(log.getType()==0){
log.setTitle("发起退款");
log.setContent("系统会在1-2天内提交处理");
}
}
/* BuyOrderRefundLog log = new BuyOrderRefundLog();
log.setId(0);
log.setRefundId(refundInfo.getId());
log.setType(0);
log.setStatus(1);
log.setCreateTime(refundInfo.getCreateTime());
log.setTitle("发起退款");
log.setContent("系统会在1-2天内提交处理");
list.add(log);*/
Map<String,Object> result = new HashMap<>();
BigDecimal shippingMoney = refundInfo.getDeductShipping()==1?refundInfo.getShippingMoney():BigDecimal.ZERO;
result.put("orderMoney",refundInfo.getFee().add(refundInfo.getJfDeduction().add(shippingMoney)));
result.put("refundFee",refundInfo.getFee());
result.put("payType",refundInfo.getPayType());
result.put("refundJf",refundInfo.getJfDeduction());
result.put("shippingMoney",shippingMoney);
result.put("list",list);
return R.ok().put("info",result);
}
@RequestMapping(value = "/refundOrder", method = RequestMethod.POST)
@Transactional
public R refundOrder(@RequestBody Map<String, Object> params) {
Object orderIdObject = params.get("orderId");
if(orderIdObject == null || orderIdObject.toString().trim().equals("")){
return R.error("orderId不能为空");
}
int orderId = Integer.parseInt(orderIdObject.toString());
QueryWrapper<BuyOrder> queryWapper = new QueryWrapper<>();
queryWapper.eq("order_id",orderId);
BuyOrder buyOrder = buyOrderService.getOne(queryWapper);
if(buyOrder==null){
return R.error("订单不存在");
}
MyUserEntity user = myUserService.getById(buyOrder.getUserId());
if (user == null) {
return R.error("订单对应用户不存在");
}
if(Constants.ORDER_STATUS_REFUND.equals(buyOrder.getOrderStatus())
|| Constants.ORDER_STATUS_REFUNDING.equals(buyOrder.getOrderStatus())){
return R.error("请勿重复提交退款");
}else if (Constants.ORDER_STATUS_TO_BE_PAID.equals(buyOrder.getOrderStatus())
|| Constants.ORDER_STATUS_FAIL.equals(buyOrder.getOrderStatus())
|| Constants.ORDER_STATUS_OUT_OF_TIME.equals(buyOrder.getOrderStatus())) {
return R.error("当前订单状态不支持退单");
}
if(buyOrder.getOrderType().equals("vip")&& buyOrderService.hasYQOrder(buyOrder)){
return R.error("需要先退掉当前VIP下的延期");
}
//设置状态为退款中
buyOrder.setOrderStatus(Constants.ORDER_STATUS_REFUNDING);
buyOrderService.updateById(buyOrder);
BigDecimal refundFee = buyOrder.getRealMoney();
BigDecimal shippingMoney = buyOrder.getShippingMoney()==null?BigDecimal.ZERO:buyOrder.getShippingMoney();
int deductShipping = params.containsKey("deductShipping") && params.get("deductShipping")!=null?Integer.parseInt(params.get("deductShipping").toString()):0;
if(refundFee.compareTo(BigDecimal.ZERO)>0 && shippingMoney.compareTo(BigDecimal.ZERO)>0 && deductShipping==1){
refundFee = refundFee.subtract(shippingMoney);
refundFee = refundFee.compareTo(BigDecimal.ZERO)>0?refundFee:BigDecimal.ZERO;
}
String remark = params.containsKey("remark") && params.get("remark").toString()!=null?params.get("remark").toString():"";
BuyOrderRefund buyOrderRefund = new BuyOrderRefund();
String refundNo = buyOrderRefundService.genRefundNo();
buyOrderRefund.setRefundNo(refundNo);
buyOrderRefund.setOrderId(buyOrder.getOrderId());
buyOrderRefund.setOrderSn(buyOrder.getOrderSn());
buyOrderRefund.setUserId(buyOrder.getUserId());
buyOrderRefund.setType(params.containsKey("deductShipping")?"后台":"线上"); //id
buyOrderRefund.setPayType(buyOrder.getPaymentMethod());
buyOrderRefund.setFee(refundFee);
buyOrderRefund.setJfDeduction(buyOrder.getJfDeduction());
buyOrderRefund.setShippingMoney(deductShipping==1?buyOrder.getShippingMoney():BigDecimal.ZERO);
buyOrderRefund.setDeductShipping(deductShipping);
buyOrderRefund.setRemark(remark);
buyOrderRefundService.save(buyOrderRefund);
buyOrderRefundLogService.insertRefundLog(buyOrderRefund.getId(),0,1);
int refundId = buyOrderRefund.getId();
if (Constants.PAYMENT_METHOD_VIRTUAL.equals(buyOrder.getPaymentMethod())) {
//if(refundFee.compareTo(BigDecimal.ZERO)>0){
//退还虚拟币
transactionDetailsService.refundRecord(buyOrder,user,refundFee);
user.setPeanutCoin(user.getPeanutCoin().add(refundFee));
myUserService.updateById(user);
//记录退款进度
buyOrderRefundLogService.insertRefundLog(refundId,4,1);
//积分、其他权益退回
buyOrderService.refundOrder(buyOrder,user,refundId);
//更改订单状态为已退款
buyOrder.setOrderStatus(Constants.ORDER_STATUS_REFUND);
buyOrderService.updateById(buyOrder);
return R.ok("ok");
//}
} else if (Constants.PAYMENT_METHOD_WECHAT_PAY.equals(buyOrder.getPaymentMethod())) {
buyOrderRefundLogService.insertRefundLog(refundId,1,0);
if (refundFee.compareTo(BigDecimal.ZERO) > 0) {
WeChatRefundInfo weChatRefundInfo = new WeChatRefundInfo();
weChatRefundInfo.setOrderSn(buyOrder.getOrderSn());
weChatRefundInfo.setOrderId(buyOrder.getOrderId());
weChatRefundInfo.setOrderType(buyOrder.getOrderType());
weChatRefundInfo.setRefundNo(buyOrderRefund.getRefundNo());
weChatRefundInfo.setTotalAmount(buyOrder.getRealMoney());
weChatRefundInfo.setRefundAmount(buyOrderRefund.getFee());
weChatRefundInfo.setRemark("用户申请退款");
weChatRefundInfo.setRefundId(buyOrderRefund.getId());
if(buyOrder.getCome()==null||buyOrder.getCome()==0){
weChatRefundInfo.setAppName(buyOrder.getAppName());
} else if (buyOrder.getCome()==2){
weChatRefundInfo.setAppName("wumen");
} else if (buyOrder.getCome()==1) {
weChatRefundInfo.setAppName("zmzm");
} else if (buyOrder.getCome()==3) {
weChatRefundInfo.setAppName("xlkj");
} else if (buyOrder.getCome()==4) {
weChatRefundInfo.setAppName("thyy");
}
try {
wxpayService.refund(weChatRefundInfo);
} catch (Exception e) {
System.out.println("msg=" + e.getMessage());
}
}
}else if (Constants.PAYMENT_METHOD_ALI_PAY.equals(buyOrder.getPaymentMethod())) {
buyOrderRefundLogService.insertRefundLog(refundId,2,0);
if (refundFee.compareTo(BigDecimal.ZERO) > 0) {
aliPayService.refund(buyOrder,user,buyOrderRefund);
}
}
// else if (Constants.PAYMENT_METHOD_ALI_PAY.equals(buyOrder.getPaymentMethod())) {
// buyOrderRefundLogService.insertRefundLog(refundId,2,0);
// if (refundFee.compareTo(BigDecimal.ZERO) > 0) {
// Map<String, Object> refundParams = new HashMap<>();
// refundParams.put("orderSn", buyOrder.getOrderSn());
// refundParams.put("refundFee", refundFee);
// String refundResult = aliPayService.refund(refundParams);
// JSONObject resultJson = JSONObject.parseObject(refundResult);
// JSONObject responseJson = resultJson.getJSONObject("alipay_trade_refund_response");
// if (responseJson == null
// || !"10000".equals(responseJson.getString("code"))
// || !"Y".equals(responseJson.getString("fund_change"))) {
// return R.error("支付宝退款申请失败");
// }else{
// buyOrderRefundLogService.insertRefundLog(refundId,3,2);
// }
// }
// }
return R.ok("ok");
}
@RequestMapping("/llll")
public R ls(){
@@ -1166,7 +1363,7 @@ public class BuyOrderController {
List<Integer> collect = shopProductBookService.getBaseMapper().selectList(new LambdaQueryWrapper<ShopProductBookEntity>()
.eq(ShopProductBookEntity::getProductId, productId)
.eq(ShopProductBookEntity::getDelFlag, 0)).stream().map(ShopProductBookEntity::getBookId).collect(Collectors.toList());
userEbookBuyService.addBookForUser(buyOrder.getUserId(), collect);
userEbookBuyService.addBookForUser(buyOrder, buyOrder.getUserId(), collect);
}
}

View File

@@ -388,10 +388,12 @@ public class ShopProductController {
shopProduct.setBookId("");
}
shopProductService.save(shopProduct);
ShopProductBookEntity shopProductBookEntity = new ShopProductBookEntity();
for (String s : shopProduct.getBookids()) {
String bookIdList = s;
if (bookIdList != null) {
ShopProductBookEntity shopProductBookEntity = new ShopProductBookEntity();
Integer product = shopProduct.getProductId();
shopProductBookEntity.setProductId(product);
shopProductBookEntity.setBookId(Integer.valueOf(bookIdList));

View File

@@ -9,9 +9,11 @@ import com.peanut.modules.book.to.UserOrderDto;
import com.peanut.modules.book.vo.UserOrderVo;
import com.peanut.modules.book.vo.request.BuyOrderListRequestVo;
import com.peanut.modules.book.vo.response.BuyOrderResponseVo;
import com.peanut.modules.common.entity.MyUserEntity;
import com.peanut.modules.common.entity.ShopProductCourseEntity;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@@ -53,6 +55,8 @@ public interface BuyOrderService extends IService<BuyOrder> {
*/
R delivery(String expressCompanyCode, List<Integer> buyOrderDetailId);
Page<BuyOrder> orderList(BuyOrderListRequestVo requestVo, Boolean isHT);
Page<BuyOrder> getUserOrderList(UserOrderDto userOrderDto);
List<BuyOrder> getUserOrderStatusNum(Integer userId);
@@ -65,7 +69,15 @@ public interface BuyOrderService extends IService<BuyOrder> {
List<ShopProductCourseEntity> getOrderCourse(String orderSn);
void addCourseToUser(String payType,BuyOrder orderEntity);
void removeCourseToUser(BuyOrder orderEntity);
void addCourseToUser(String payType, BuyOrder orderEntity);
boolean checkWlOrder(String orderSn);
BigDecimal getRefundFee(Map<String, Object> params, BuyOrder buyOrder);
void refundOrder(BuyOrder buyOrder, MyUserEntity user, int refundId);
boolean hasYQOrder(BuyOrder buyOrder);
}

View File

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.common.utils.PageUtils;
import com.peanut.common.utils.R;
import com.peanut.modules.common.entity.BookForumArticlesEntity;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderProduct;
import com.peanut.modules.common.entity.MyUserEntity;
import java.util.List;
import java.util.Map;
@@ -33,5 +35,8 @@ public interface MyUserService extends IService<MyUserEntity> {
boolean checkUserTelOrEmail(MyUserEntity user);
//void rollbackUserPowers(BuyOrder order, List<BuyOrderProduct> orderProducts);
void rollbackUserPowers(BuyOrder order, MyUserEntity user, List<BuyOrderProduct> orderProducts);
}

View File

@@ -2,6 +2,7 @@ package com.peanut.modules.book.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.common.utils.PageUtils;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.ShopProduct;
import java.math.BigDecimal;
@@ -37,6 +38,6 @@ public interface ShopProductService extends IService<ShopProduct> {
PageUtils queryPageactivityprice(Map<String, Object> params);
void rollbackStock(BuyOrder buyOrder);
}

View File

@@ -27,6 +27,6 @@ public interface TransactionDetailsService extends IService<TransactionDetailsEn
void rechargeRecord(MyUserEntity user,String money,int payXxxOrderId,String AppName,String orderSn);
void refundRecord(BuyOrder buyOrder, MyUserEntity user, BigDecimal totalPrice);
}

View File

@@ -2,6 +2,8 @@ package com.peanut.modules.book.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.common.utils.PageUtils;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderProduct;
import com.peanut.modules.common.entity.UserEbookBuyEntity;
import java.util.List;
@@ -23,6 +25,11 @@ public interface UserEbookBuyService extends IService<UserEbookBuyEntity> {
List<Integer> getUserBookId(Integer userId);
void addBookForUser(Integer userId, List<Integer> bookIds);
void addBookForUser(BuyOrder buyOrder, Integer userId, List<Integer> bookIds);
void rollbackUserEbooks(BuyOrder order, List<BuyOrderProduct> orderProducts);
}

View File

@@ -11,6 +11,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.*;
import com.peanut.config.Constants;
import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.book.service.CityService;
import com.peanut.modules.book.service.CountyService;
import com.peanut.modules.book.service.ExpressOrderService;
import com.peanut.modules.book.service.MyUserService;
import com.peanut.modules.book.service.ProvinceService;
import com.peanut.modules.common.dao.*;
import com.peanut.modules.book.service.*;
import com.peanut.modules.book.to.UserOrderDto;
@@ -19,8 +25,7 @@ import com.peanut.modules.book.vo.UserOrderVo;
import com.peanut.modules.book.vo.request.BuyOrderListRequestVo;
import com.peanut.modules.book.vo.response.*;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.UserVipService;
import com.peanut.modules.common.service.VipBuyConfigService;
import com.peanut.modules.common.service.*;
import com.peanut.modules.common.vo.CourseCatalogueVo;
import com.peanut.modules.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
@@ -35,6 +40,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
@@ -92,8 +98,26 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
private UserCourseBuyDao userCourseBuyDao;
@Autowired
private UserCourseBuyLogDao userCourseBuyLogDao;
@Autowired
private CouponService couponService;
@Autowired
private UserEbookBuyService userEbookBuyService;
protected Logger logger = LoggerFactory.getLogger(BuyOrderServiceImpl.class);
@Autowired
private JfTransactionDetailsService jfTransactionDetailsService;
@Autowired
private BuyOrderRefundLogService buyOrderRefundLogService;
@Autowired
private BuyOrderRefundService buyOrderRefundService;
@Autowired
private UserVipLogService userVipLogService;
@Autowired
private UserVipLogDao userVipLogDao;
@Autowired
private UserVipDao userVipDao;
@Autowired
private VipBuyConfigDao vipBuyConfigDao;
// TODO 新版本上线后删除
@Override
@@ -198,6 +222,8 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
} else if (type.equals("2")) {
orderEntity.setPaymentDate(new Date());
orderEntity.setOrderStatus("3");
}else if (type.equals("6")) {
orderEntity.setOrderStatus("6");
}
updateById(orderEntity);
}
@@ -359,6 +385,15 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
@Override
public Page<BuyOrder> orderList(BuyOrderListRequestVo requestVo) {
Page<BuyOrder> buyOrderPage = this.getOrderList(requestVo,null);
return buyOrderPage;
}
@Override
public Page<BuyOrder> orderList(BuyOrderListRequestVo requestVo, Boolean isHT) {
Page<BuyOrder> buyOrderPage = this.getOrderList(requestVo,isHT);
return buyOrderPage;
}
public Page<BuyOrder> getOrderList(BuyOrderListRequestVo requestVo,Boolean isHT){
MPJLambdaWrapper<BuyOrder> wrapper = new MPJLambdaWrapper<>();
wrapper.selectAll(BuyOrder.class);
wrapper.leftJoin(MyUserEntity.class, MyUserEntity::getId,BuyOrder::getUserId);
@@ -412,20 +447,54 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
user.setUserVips(userVipService.list(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId,user.getId()).eq(UserVip::getState,0)));
b.setUser(user);
boolean refundableStatus = false;
long timestamp = Instant.now().toEpochMilli();
long paymentDateTime = b.getPaymentDate()==null?0: b.getPaymentDate().getTime();
if (b.getVipBuyConfigId()!=0){
if(paymentDateTime > timestamp-7*24*60*60*1000){
refundableStatus = true;
}
refundableStatus = isHT?true:refundableStatus;
b.setVipBuyConfigEntity(vipBuyConfigService.getById(b.getVipBuyConfigId()));
}
//添加商品信息
List<BuyOrderProduct> buyOrderProducts = buyOrderProductDao.selectList(new LambdaQueryWrapper<BuyOrderProduct>().eq(BuyOrderProduct::getOrderId, b.getOrderId()));
for (BuyOrderProduct b1:buyOrderProducts){
MPJLambdaWrapper<ShopProduct> shopProductWrapper = new MPJLambdaWrapper<>();
//关掉本次查询del_flg = 0的条件查询删除商品
shopProductWrapper.disableLogicDel().eq(ShopProduct::getProductId,b1.getProductId());
ShopProduct byId = shopProductService.getOne(shopProductWrapper);
byId.setBooks(shopProductBookService.getBookByProductId(byId.getProductId()));
b1.setProduct(byId);
b1.setExpressOrder(expressOrderDao.selectById(b1.getExpressOrderId()));
if(buyOrderProducts.size()>0){
boolean[] refundableStatusArr = new boolean[buyOrderProducts.size()];
for (int i=0;i<buyOrderProducts.size();i++){
BuyOrderProduct b1 = buyOrderProducts.get(i);
MPJLambdaWrapper<ShopProduct> shopProductWrapper = new MPJLambdaWrapper<>();
//关掉本次查询del_flg = 0的条件查询删除商品
shopProductWrapper.disableLogicDel().eq(ShopProduct::getProductId,b1.getProductId());
ShopProduct byId = shopProductService.getOne(shopProductWrapper);
byId.setBooks(shopProductBookService.getBookByProductId(byId.getProductId()));
b1.setProduct(byId);
b1.setExpressOrder(expressOrderDao.selectById(b1.getExpressOrderId()));
boolean refundableStatusProduct = false;
if(b1.getProduct()!=null && b1.getProduct().getGoodsType().equals("05") && (paymentDateTime > timestamp-7*24*60*60*1000 || isHT)){
refundableStatusProduct = true;
}else if(b1.getProduct()!=null && !b1.getProduct().getGoodsType().equals("05") && b.getOrderStatus().equals("1") && b1.getExpressOrderId()==0){
refundableStatusProduct = true;
}
refundableStatusArr[i] = refundableStatusProduct;
}
for (boolean rs : refundableStatusArr){
if(!rs){
refundableStatus = false;
break;
}else{
refundableStatus = true;
}
}
}else if("relearn".equals(b.getOrderType()) && paymentDateTime > timestamp-7*24*60*60*1000){
refundableStatus = true;
}
if(b.getOrderStatus().equals(Constants.ORDER_STATUS_REFUND)){
BuyOrderRefund refundInfo = buyOrderRefundService.getRefundInfoByOrderId(b.getOrderId());
b.setRefundRemark(refundInfo.getRemark());
}
b.setRefundableStatus(b.getOrderStatus().equals("6")|| b.getOrderStatus().equals("7")?false:refundableStatus);
b.setProductList(buyOrderProducts);
//设置快递信息传递给前端
ConsigneeVo consigneeVo = new ConsigneeVo();
@@ -481,7 +550,7 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
wrapper.eq(BuyOrder::getUserId,userOrderDto.getUserId());
// wrapper.eq(BuyOrder::getOrderType,"order");//这里有点问题
if(userOrderDto.getOrderStatus()==null){
Integer[] sts = {0,1,2,3};
Integer[] sts = {0,1,2,3,6,7};
wrapper.in(BuyOrder::getOrderStatus,sts);
}else{
wrapper.eq(BuyOrder::getOrderStatus,userOrderDto.getOrderStatus());
@@ -497,17 +566,40 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
//组装商品
List<BuyOrderProduct> buyOrderProducts = buyOrderProductService.getBaseMapper().selectList(new LambdaQueryWrapper<BuyOrderProduct>()
.eq(BuyOrderProduct::getOrderId, b.getOrderId()));
for (BuyOrderProduct bb : buyOrderProducts){
bb.setProduct(shopProductService.getOne(new LambdaQueryWrapper<ShopProduct>().select(ShopProduct::getProductId,ShopProduct::getProductName,ShopProduct::getProductImages,ShopProduct::getPrice,ShopProduct::getActivityPrice,ShopProduct::getIsVipPrice,ShopProduct::getGoodsType)
.eq(ShopProduct::getProductId,bb.getProductId())));
UserRecord userRecord = userRecordDao.selectOne(new QueryWrapper<UserRecord>()
.eq("userid", ShiroUtils.getUId())
.eq("orderdid", b.getOrderId())
.eq("product_id", bb.getProductId()));
if (userRecord!=null){
bb.setRecordId(userRecord.getId());
Boolean refundableStatus = false;
long paymentDateTime = b.getPaymentDate()==null?0:b.getPaymentDate().getTime();
long timestamp = Instant.now().toEpochMilli();
if (buyOrderProducts.size() > 0) {
boolean[] refundableStatusArr = new boolean[buyOrderProducts.size()];
for (int i=0;i<buyOrderProducts.size();i++){
BuyOrderProduct bb = buyOrderProducts.get(i);
bb.setProduct(shopProductService.getOne(new LambdaQueryWrapper<ShopProduct>().select(ShopProduct::getProductId, ShopProduct::getProductName, ShopProduct::getProductImages, ShopProduct::getPrice, ShopProduct::getActivityPrice, ShopProduct::getIsVipPrice, ShopProduct::getGoodsType)
.eq(ShopProduct::getProductId, bb.getProductId())));
UserRecord userRecord = userRecordDao.selectOne(new QueryWrapper<UserRecord>()
.eq("userid", ShiroUtils.getUId())
.eq("orderdid", b.getOrderId())
.eq("product_id", bb.getProductId()));
if (userRecord != null) {
bb.setRecordId(userRecord.getId());
}
boolean refundableStatusProduct = false;
if (bb.getProduct()!=null && bb.getProduct().getGoodsType().equals("05") && paymentDateTime > timestamp - 7 * 24 * 60 * 60 * 1000) {
refundableStatusProduct = true;
} else if (bb.getProduct()!=null && !bb.getProduct().getGoodsType().equals("05") && b.getOrderStatus().equals(Constants.ORDER_STATUS_TO_BE_SHIPPED) && bb.getExpressOrderId()==0){
refundableStatusProduct = true;
}
refundableStatusArr[i] = refundableStatusProduct;
}
for (boolean rs : refundableStatusArr){
if(!rs){
refundableStatus = false;
break;
}else{
refundableStatus = true;
}
}
}
b.setRefundableStatus(b.getOrderStatus().equals("6") || b.getOrderStatus().equals("7")?false:refundableStatus);
b.setProductList(buyOrderProducts);
b.setTimestamp(b.getCreateTime().getTime()/1000);
//充值订单填充充值商品信息
@@ -653,7 +745,16 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
List<ShopProductCourseEntity> shopProductCourseEntities = this.getBaseMapper().selectJoinList(ShopProductCourseEntity.class, wrapper);
return shopProductCourseEntities;
}
@Override
public void removeCourseToUser(BuyOrder orderEntity){
QueryWrapper<UserCourseBuyLog> buyLogQueryWrapper = new QueryWrapper<>();
buyLogQueryWrapper.eq("order_sn",orderEntity.getOrderSn());
List<UserCourseBuyLog> userCourseBuyLogList = userCourseBuyLogDao.selectList(buyLogQueryWrapper);
for (UserCourseBuyLog userCourseBuyLog:userCourseBuyLogList){
userCourseBuyDao.realDeleteById(userCourseBuyLog.getUserCourseBuyId());
userCourseBuyLogDao.realDeleteById(userCourseBuyLog.getId());
}
}
@Override
public void addCourseToUser(String payType,BuyOrder orderEntity){
List<ShopProductCourseEntity> orderCourse = getOrderCourse(orderEntity.getOrderSn());
@@ -951,5 +1052,89 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
return responseVo;
}
public BigDecimal getRefundFee(Map<String, Object> params, BuyOrder buyOrder) {
Object userRefundFeeObj = params.get("refundFee");
BigDecimal refundFee = new BigDecimal(0);
if(userRefundFeeObj!=null && !userRefundFeeObj.toString().trim().equals("")){
refundFee = new BigDecimal(userRefundFeeObj.toString().trim());
}
BigDecimal realMoney = buyOrder.getRealMoney() == null ? BigDecimal.ZERO : buyOrder.getRealMoney();
BigDecimal shippingMoney = buyOrder.getShippingMoney() == null ? BigDecimal.ZERO : buyOrder.getShippingMoney();
BigDecimal maxRefundMoney = realMoney.subtract(shippingMoney);
if (maxRefundMoney.compareTo(BigDecimal.ZERO) < 0) {
maxRefundMoney = BigDecimal.ZERO;
}
if(refundFee.compareTo(maxRefundMoney)>0){
refundFee = maxRefundMoney;
}
return refundFee;
}
@Override
public void refundOrder(BuyOrder buyOrder, MyUserEntity user, int refundId){
if(buyOrder.getCouponId()!=null && buyOrder.getCouponId()!=0){
couponService.rollbackCoupon(buyOrder.getCouponId());
}
QueryWrapper<BuyOrderProduct> productQueryWrapper = new QueryWrapper<>();
productQueryWrapper.eq("order_id",buyOrder.getOrderId());
List<BuyOrderProduct> orderProducts = buyOrderProductService.list(productQueryWrapper);
//积分恢复
BigDecimal jf = buyOrder.getJfDeduction()==null?BigDecimal.ZERO : buyOrder.getJfDeduction();
if(jf.compareTo(BigDecimal.ZERO)>0){
jfTransactionDetailsService.refundJfTransaction(buyOrder,user);
user.setJf(jf.add(user.getJf()));
myUserService.updateById(user);
buyOrderRefundLogService.insertRefundLog(refundId,5,1);
}
if(buyOrder.getOrderType().equals("vip")){
userVipService.refundVip(buyOrder);
}else{
//恢复用户权益(点穴/时辰取穴/五运六气/肿瘤古方)
myUserService.rollbackUserPowers(buyOrder,user, orderProducts);
//撤回本订单购买赠送的优惠券
couponService.refundZSCouponHistoryByOrder(buyOrder);
//撤回电子书权限
userEbookBuyService.rollbackUserEbooks(buyOrder, orderProducts);
//撤回课程权限
log.info("====remove========="+buyOrder.getOrderSn());
removeCourseToUser(buyOrder);
//回滚库存
shopProductService.rollbackStock(buyOrder);
}
}
/**
* 判断该VIP后是否办理过延期VIP,退VIP时如果在此VIP后办理过延期需要把延期退掉才可以退此订单
* @param buyOrder
* @return
*/
@Override
public boolean hasYQOrder(BuyOrder buyOrder){
VipBuyConfigEntity vipBuyConfig = vipBuyConfigService.getById(buyOrder.getVipBuyConfigId());
if(vipBuyConfig.getType()<=10){
List<String> typeStrs = new ArrayList<>();
if(vipBuyConfig.getType()==1){
typeStrs.add("41");
typeStrs.add("91");
typeStrs.add("51");
typeStrs.add("41");
typeStrs.add("61");
typeStrs.add("101");
}else if(vipBuyConfig.getType()==2){
typeStrs.add("71");
typeStrs.add("81");
}else{
typeStrs.add(vipBuyConfig.getType()+"1");
}
List<Integer> vipBuyConfigIdList = vipBuyConfigDao.selectList(new LambdaQueryWrapper<VipBuyConfigEntity>().in(VipBuyConfigEntity::getType,typeStrs)).stream().map(VipBuyConfigEntity::getId).collect(Collectors.toList());
Long nums = buyOrderDao.selectCount(new LambdaQueryWrapper<BuyOrder>().in(BuyOrder::getVipBuyConfigId,vipBuyConfigIdList).eq(BuyOrder::getOrderStatus,3).gt(BuyOrder::getCreateTime, buyOrder.getCreateTime()));
log.info("=====hasYQOrder===="+nums);
return nums>0?true:false;
}
return false;
}
}

View File

@@ -102,4 +102,26 @@ public class MyUserServiceImpl extends ServiceImpl<MyUserDao, MyUserEntity> impl
MyUserEntity one = getOne(wrapper);
return one == null;
}
@Override
public void rollbackUserPowers(BuyOrder order, MyUserEntity user, List<BuyOrderProduct> orderProducts) {
if(user == null){
return;
}
for (BuyOrderProduct buyOrderProduct : orderProducts){
Integer productId = buyOrderProduct.getProductId();
if(Arrays.asList(128, 129, 130, 131, 136, 137, 139, 1612).contains(productId)){
user.setPointPower(0);
}
if(Arrays.asList(133, 134, 135).contains(productId)){
user.setTgdzPower(0);
}
if(Arrays.asList(39, 62, 123, 127).contains(productId)){
user.setWylqPower(0);
}
if(Arrays.asList(43, 62, 124).contains(productId)){
user.setPrescriptBPower(0);
}
}
updateById(user);
}
}

View File

@@ -1,6 +1,9 @@
package com.peanut.modules.book.service.impl;
import com.peanut.common.utils.ExcludeEmptyQueryWrapper;
import com.peanut.common.utils.ShiroUtils;
import com.peanut.modules.book.service.BuyOrderProductService;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderProduct;
import com.peanut.modules.common.service.UserVipService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +27,8 @@ public class ShopProductServiceImpl extends ServiceImpl<ShopProductDao, ShopProd
@Autowired
private UserVipService userVipService;
@Autowired
private BuyOrderProductService buyOrderProductService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
@@ -135,5 +140,17 @@ public class ShopProductServiceImpl extends ServiceImpl<ShopProductDao, ShopProd
return new PageUtils(page);
}
@Override
public void rollbackStock(BuyOrder buyOrder){
QueryWrapper<BuyOrderProduct> buyOrderProductQueryWrapper = new QueryWrapper<>();
buyOrderProductQueryWrapper.eq("order_id", buyOrder.getOrderId());
List<BuyOrderProduct> buyOrderProductList = buyOrderProductService.list(buyOrderProductQueryWrapper);
for (BuyOrderProduct buyOrderProduct : buyOrderProductList) {
Integer productId = buyOrderProduct.getProductId();
ShopProduct product = this.getById(productId);
product.setProductStock(product.getProductStock() + buyOrderProduct.getQuantity());
this.updateById(product);
}
}
}

View File

@@ -84,13 +84,19 @@ public class TransactionDetailsServiceImpl extends ServiceImpl<TransactionDetail
getBaseMapper().insert(transactionDetailsEntity);
}
public void refundRecord(BuyOrder buyOrder, MyUserEntity user, BigDecimal refundPrice){
TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity();
transactionDetailsEntity.setUserId(user.getId());
transactionDetailsEntity.setOrderType("订单退款");
transactionDetailsEntity.setPayNo(buyOrder.getOrderSn());
transactionDetailsEntity.setChangeAmount(refundPrice);
transactionDetailsEntity.setUserBalance(user.getPeanutCoin().add(refundPrice));
transactionDetailsEntity.setRelationId(buyOrder.getOrderId());
transactionDetailsEntity.setUserName(user.getNickname());
transactionDetailsEntity.setTel(user.getTel());
transactionDetailsEntity.setNote("订单号:" + buyOrder.getOrderSn() + " 虚拟币退款");
getBaseMapper().insert(transactionDetailsEntity);
}
}

View File

@@ -6,7 +6,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.common.utils.PageUtils;
import com.peanut.common.utils.Query;
import com.peanut.modules.book.service.ShopProductBookService;
import com.peanut.modules.common.dao.UserEbookBuyDao;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderProduct;
import com.peanut.modules.common.entity.ShopProductBookEntity;
import com.peanut.modules.common.entity.UserEbookBuyEntity;
import com.peanut.modules.book.service.UserEbookBuyService;
import lombok.extern.slf4j.Slf4j;
@@ -16,6 +20,7 @@ import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@Service("userEbookBuyService")
@@ -23,6 +28,8 @@ public class UserEbookBuyServiceImpl extends ServiceImpl<UserEbookBuyDao, UserEb
@Autowired
private UserEbookBuyDao userEbookBuyDao;
@Autowired
private ShopProductBookService shopProductBookService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
@@ -68,4 +75,34 @@ public class UserEbookBuyServiceImpl extends ServiceImpl<UserEbookBuyDao, UserEb
}
}
}
public void addBookForUser(BuyOrder buyOrder, Integer userId, List<Integer> bookIds) {
for (Integer i:bookIds){
List<UserEbookBuyEntity> userEbookBuyEntities = this.getBaseMapper().selectList(new LambdaQueryWrapper<UserEbookBuyEntity>().eq(UserEbookBuyEntity::getUserId, userId).eq(UserEbookBuyEntity::getBookId, i));
if(userEbookBuyEntities.size()==0){
UserEbookBuyEntity userEbookBuyEntity = new UserEbookBuyEntity();
userEbookBuyEntity.setUserId(userId);
userEbookBuyEntity.setBookId(i);
userEbookBuyEntity.setPayTime(new Date());
userEbookBuyEntity.setOrdersn(buyOrder.getOrderSn());
this.save(userEbookBuyEntity);
}
}
}
@Override
public void rollbackUserEbooks(BuyOrder order, List<BuyOrderProduct> orderProducts) {
for (BuyOrderProduct buyOrderProduct : orderProducts){
List<Integer> bookIds = shopProductBookService.getBaseMapper().selectList(new LambdaQueryWrapper<ShopProductBookEntity>()
.eq(ShopProductBookEntity::getProductId,buyOrderProduct.getProductId())
.eq(ShopProductBookEntity::getDelFlag,0)
).stream().map(ShopProductBookEntity::getBookId).collect(Collectors.toList());
for (Integer bookId:bookIds){
QueryWrapper<UserEbookBuyEntity> removeWrapper = new QueryWrapper<>();
removeWrapper.eq("user_id", order.getUserId());
removeWrapper.eq("ordersn", order.getOrderSn());
this.remove(removeWrapper);
}
}
}
}

View File

@@ -0,0 +1,44 @@
package com.peanut.modules.book.vo;
import java.io.Serializable;
import java.util.Date;
public class UserVipYearVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Integer year;
private Date endTime;
private Date startTime;
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}

View File

@@ -494,7 +494,6 @@ public class ClassController {
}
}
}
//结班
@RequestMapping("/closeClass")
@Transactional
@@ -641,7 +640,4 @@ public class ClassController {
List<UserCertificate> userCertificate = userCertificateService.list(wrapper);
return R.ok().put("userCertificate",userCertificate);
}
}

View File

@@ -183,6 +183,7 @@ public class CourseRelearnController {
String timeId = IdWorker.getTimeId().substring(0, 32);
buyOrder.setOrderSn(timeId);
buyOrder.setUserId(uid);
buyOrder.setPaymentDate(new Date());
buyOrderService.save(buyOrder);
BigDecimal totalPrice = buyOrder.getRealMoney();
//虚拟币支付

View File

@@ -56,8 +56,8 @@ public class JfTransactionDetailsController {
@Transactional
public R activityDonateJF(){
StringBuffer sb = new StringBuffer();
String startTime = "2025-11-08 00:00:00";
String endTime = "2025-11-13 09:22:00";
String startTime = "2026-06-18 00:00:00";
String endTime = "2026-06-22 10:06:59";
//查询时间段内所有充值的人
List<TransactionDetailsEntity> list = transactionDetailsService.list(new LambdaQueryWrapper<TransactionDetailsEntity>()
.between(TransactionDetailsEntity::getCreateTime,startTime,endTime)
@@ -76,7 +76,7 @@ public class JfTransactionDetailsController {
//时间段内获得的积分
Map<String,Object> jftd = jfService.getMap(new MPJLambdaWrapper<JfTransactionDetails>()
.eq(JfTransactionDetails::getUserId,transactionDetail.getUserId())
.like(JfTransactionDetails::getRemark,"双11")
.like(JfTransactionDetails::getRemark,"618活动充值")
.between(JfTransactionDetails::getCreateTime,startTime,endTime)
.gt(TransactionDetailsEntity::getChangeAmount,0)
.selectSum(TransactionDetailsEntity::getChangeAmount));
@@ -114,19 +114,19 @@ public class JfTransactionDetailsController {
new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(1000))>=0||
new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(500))>=0){
if (new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(5000))>=0){
shouldJf = shouldJf.add(new BigDecimal(2500));
shouldJf = shouldJf.add(new BigDecimal(2000));
changeAmount = changeAmount.subtract(new BigDecimal(5000));
}else if (new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(3000))>=0){
shouldJf = shouldJf.add(new BigDecimal(1300));
shouldJf = shouldJf.add(new BigDecimal(1000));
changeAmount = changeAmount.subtract(new BigDecimal(3000));
}else if (new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(2000))>=0){
shouldJf = shouldJf.add(new BigDecimal(800));
shouldJf = shouldJf.add(new BigDecimal(600));
changeAmount = changeAmount.subtract(new BigDecimal(2000));
}else if (new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(1000))>=0){
shouldJf = shouldJf.add(new BigDecimal(300));
shouldJf = shouldJf.add(new BigDecimal(240));
changeAmount = changeAmount.subtract(new BigDecimal(1000));
}else if (new BigDecimal(changeAmount.toString()).compareTo(new BigDecimal(500))>=0){
shouldJf = shouldJf.add(new BigDecimal(120));
shouldJf = shouldJf.add(new BigDecimal(100));
changeAmount = changeAmount.subtract(new BigDecimal(500));
}
return chgf(changeJf,shouldJf,changeAmount,jf);

View File

@@ -55,7 +55,7 @@ public class TransactionDetailsController {
BuyOrder buyOrder = buyOrderService.getOne(new LambdaQueryWrapper<BuyOrder>()
.eq(BuyOrder::getOrderSn,orderSn));
if (buyOrder!=null){
if ("购买商品".equals(detail.getOrderType())){
if ("购买商品".equals(detail.getOrderType())||"订单退款".equals(detail.getOrderType())){
List<BuyOrderProduct> products = buyOrderProductService.list(new LambdaQueryWrapper<BuyOrderProduct>()
.eq(BuyOrderProduct::getOrderId,buyOrder.getOrderId()));
for (BuyOrderProduct buyOrderProduct : products) {

View File

@@ -27,6 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.transaction.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -70,12 +71,14 @@ public class UserVipController {
List<UserVip> l9 = userVipService.list(new LambdaQueryWrapper<UserVip>().eq(UserVip::getUserId,ShiroUtils.getUId()).eq(UserVip::getType,9).orderByDesc(UserVip::getEndTime));
List<UserVip> l5 = userVipService.list(new LambdaQueryWrapper<UserVip>().eq(UserVip::getUserId,ShiroUtils.getUId()).eq(UserVip::getType,5).orderByDesc(UserVip::getEndTime));
List<UserVip> l6 = userVipService.list(new LambdaQueryWrapper<UserVip>().eq(UserVip::getUserId,ShiroUtils.getUId()).eq(UserVip::getType,6).orderByDesc(UserVip::getEndTime));
if (l4.size()>0&&l9.size()>0&&l5.size()>0&&l6.size()>0){
List<UserVip> l10 = userVipService.list(new LambdaQueryWrapper<UserVip>().eq(UserVip::getUserId,ShiroUtils.getUId()).eq(UserVip::getType,10).orderByDesc(UserVip::getEndTime));
if (l4.size()>0&&l9.size()>0&&l5.size()>0&&l6.size()>0&&l10.size()>0){
Date t4 = l4.get(0).getEndTime();
Date t9 = l9.get(0).getEndTime();
Date t5 = l5.get(0).getEndTime();
Date t6 = l6.get(0).getEndTime();
if (t4.getTime()==t9.getTime()&&t9.getTime()==t5.getTime()&&t5.getTime()==t6.getTime()){
Date t10 = l10.get(0).getEndTime();
if (t4.getTime()==t9.getTime()&&t9.getTime()==t5.getTime()&&t5.getTime()==t6.getTime()&&t6.getTime()==t10.getTime()){
Map map = new HashMap();
map.put("type",1);
map.put("endTime",t4);
@@ -98,6 +101,10 @@ public class UserVipController {
map6.put("type",6);
map6.put("endTime",t6);
tempList.add(map6);
Map map10 = new HashMap();
map10.put("type",10);
map10.put("endTime",t10);
tempList.add(map10);
tempList = tempList.stream().sorted((map1,map2)->{
return Long.compare(((Date)map1.get("endTime")).getTime(),((Date)map2.get("endTime")).getTime());
}).collect(Collectors.toList());
@@ -133,6 +140,13 @@ public class UserVipController {
resList.add(map);
}
if (l10.size()>0){
Map map = new HashMap();
map.put("type",10);
map.put("endTime",l10.get(0).getEndTime());
resList.add(map);
}
}
}
List<UserVip> l7 = userVipService.list(new LambdaQueryWrapper<UserVip>().eq(UserVip::getUserId,ShiroUtils.getUId()).eq(UserVip::getType,7).orderByDesc(UserVip::getEndTime));
@@ -201,6 +215,7 @@ public class UserVipController {
ll.add(Arrays.asList(9));
ll.add(Arrays.asList(5));
ll.add(Arrays.asList(6));
ll.add(Arrays.asList(10));
ll.add(Arrays.asList(2));
ll.add(Arrays.asList(7,8));
}
@@ -311,6 +326,7 @@ public class UserVipController {
ll.add(Arrays.asList(9));
ll.add(Arrays.asList(5));
ll.add(Arrays.asList(6));
ll.add(Arrays.asList(10));
ll.add(Arrays.asList(2));
ll.add(Arrays.asList(7,8));
List<Map<String,Object>> resList = new ArrayList<>();
@@ -345,7 +361,22 @@ public class UserVipController {
@RequestMapping("/ownCourseCatalogueByVip")
public R ownCourseCatalogueByVip(@RequestBody Map<String,Object> params) {
UserVip userVip = userVipService.ownCourseCatalogueByVip(Integer.parseInt(params.get("courseId").toString()));
return R.ok().put("userVip", userVip);
Map<String,Object> userVipInfo = new HashMap<>();
if(userVip!=null){
userVipInfo.put("id",userVip.getId());
userVipInfo.put("userId",userVip.getUserId());
userVipInfo.put("type",userVip.getType());
userVipInfo.put("startTime",userVip.getStartTime());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
userVipInfo.put("endTime",sdf.format(userVip.getEndTime()));
userVipInfo.put("state",userVip.getState());
userVipInfo.put("delFlag",userVip.getDelFlag());
userVipInfo.put("user",userVip.getUser());
userVipInfo.put("userVipLogs",userVip.getUserVipLogs());
}else{
userVipInfo = null;
}
return R.ok().put("userVip", userVipInfo);
}
//当前课程属于什么会员
@@ -369,10 +400,12 @@ public class UserVipController {
public R placeVipOrder(@RequestBody BuyOrder buyOrder){
int uid = ShiroUtils.getUId();
buyOrder.setOrderStatus("0");
buyOrder.setPaymentDate(new Date());
buyOrder.setOrderType("vip");
String timeId = IdWorker.getTimeId().substring(0, 32);
buyOrder.setOrderSn(timeId);
buyOrder.setUserId(uid);
buyOrder.setPaymentDate(new Date());
buyOrderService.save(buyOrder);
BigDecimal totalPrice = buyOrder.getRealMoney();
if (Constants.PAYMENT_METHOD_VIRTUAL.equals(buyOrder.getPaymentMethod())) {
@@ -380,6 +413,7 @@ public class UserVipController {
MyUserEntity user = myUserDao.selectById(buyOrder.getUserId());
if (usePeanutCoin(user, totalPrice)&&useJfCoin(user,buyOrder.getJfDeduction())) {
// 更新订单状态
buyOrder.setPaymentDate(new Date());
buyOrderService.updateOrderStatus(user.getId(), buyOrder.getOrderSn(), "2");
//记录用户虚拟币消费
if(totalPrice.compareTo(BigDecimal.ZERO)>0){
@@ -468,7 +502,7 @@ public class UserVipController {
Map map = new HashMap();
map.put("courseCount",0);
map.put("originalPrice",0);
if ("4".equals(type)||"9".equals(type)||"5".equals(type)||"6".equals(type)){
if ("4".equals(type)||"9".equals(type)||"5".equals(type)||"6".equals(type)||"10".equals(type)){
List list = new ArrayList<>();
if ("4".equals(type)){
userVipService.bottomLabel(1,list);
@@ -478,6 +512,8 @@ public class UserVipController {
userVipService.bottomLabel(2,list);
}else if ("6".equals(type)){
userVipService.bottomLabel(5,list);
}else if ("10".equals(type)){
userVipService.bottomLabel(109,list);
}
if (list.size()>0){
MPJLambdaWrapper<CourseCatalogueEntity> wrapper = new MPJLambdaWrapper();

View File

@@ -22,8 +22,12 @@ public interface BuyOrderDao extends MPJBaseMapper<BuyOrder> {
List<Map<String,Object>> getPhysicalBuyOrderTotal(@Param("date") String date,@Param("orderType") String orderType);
List<Map<String,Object>> getRefund(@Param("date") String date,@Param("orderType") String orderType);
List<Map<String,Object>> exportPhysicalBuyOrderInfo(@Param("date") String date,@Param("orderType") String orderType);
List<Map<String,Object>> exportPhysicalBuyOrderRefundInfo(@Param("date") String date,@Param("orderType") String orderType);
List<BuyOrder> orderList(BuyOrderListRequestVo requestVo);
int orderListCount(BuyOrderListRequestVo requestVo);

View File

@@ -0,0 +1,10 @@
package com.peanut.modules.common.dao;
import com.github.yulichang.base.MPJBaseMapper;
import com.peanut.modules.common.entity.BuyOrderRefund;
import com.peanut.modules.common.entity.BuyOrderRefundLog;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BuyOrderRefundLogDao extends MPJBaseMapper<BuyOrderRefundLog> {
}

View File

@@ -2,9 +2,12 @@ package com.peanut.modules.common.dao;
import com.github.yulichang.base.MPJBaseMapper;
import com.peanut.modules.common.entity.ClassExamOption;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ClassExamOptionDao extends MPJBaseMapper<ClassExamOption> {
@Delete("DELETE FROM class_exam_option WHERE subject_id = #{subjectId}")
int realDeleteClassExamOption(int subjectId);
}

View File

@@ -23,4 +23,6 @@ public interface TransactionDetailsDao extends BaseMapper<TransactionDetailsEnti
List<Map<String,Object>> getTransactionDetailsTotal(@Param("date") String date);
List<Map<String,Object>> getTransactionDetailsInfo(@Param("date") String date);
List<Map<String,Object>> getRefundTransactionDetails(@Param("date") String date);
}

View File

@@ -2,6 +2,7 @@ package com.peanut.modules.common.dao;
import com.github.yulichang.base.MPJBaseMapper;
import com.peanut.modules.common.entity.UserCourseBuyEntity;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -17,5 +18,14 @@ public interface UserCourseBuyDao extends MPJBaseMapper<UserCourseBuyEntity> {
List<Map<String,Object>> getIncome(@Param("date") String date);
List<Map<String,Object>> getRefund(@Param("date") String date);
List<Map<String,Object>> getSameMonthRefund(@Param("date") String date);
List<Map<String,Object>> getCoursePurchaseDetails(int courseId,int catalogueId,Integer limit,Integer offset);
@Delete("DELETE FROM user_course_buy WHERE id = #{userCourseBuyId}")
int realDeleteById(int userCourseBuyId);
List<Map<String,Object>> getRefundInfo(@Param("date") String date);
}

View File

@@ -2,8 +2,11 @@ package com.peanut.modules.common.dao;
import com.github.yulichang.base.MPJBaseMapper;
import com.peanut.modules.common.entity.UserCourseBuyLog;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserCourseBuyLogDao extends MPJBaseMapper<UserCourseBuyLog> {
@Delete("DELETE FROM user_course_buy_log WHERE id = #{userCourseBuyLogId}")
int realDeleteById(int userCourseBuyLogId);
}

View File

@@ -1,17 +1,39 @@
package com.peanut.modules.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
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;
@Mapper
public interface UserVipLogDao extends BaseMapper<UserVipLog> {
public interface UserVipLogDao extends MPJBaseMapper<UserVipLog> {
List<Map<String,Object>> getUserVipLogInfo(@Param("date") String date);
Map<String,Object> getUserVipLogInfoTotal(@Param("date") String date);
BigDecimal getUserVipRefundFeeTotal(@Param("date") String date);
BigDecimal getUserVipSameMonthRefundFeeTotal(@Param("date") String date);
List<Map<String,Object>> getUserVipRefundLogInfo(@Param("date") String date);
List<Map<String,Object>> getAllUserVipLogInfo(@Param("date") String date);
List<Map<String,Object>> getUserVipRefundInfo(@Param("date") String last_l_date,@Param("date") String last_date);
List<Map<String,Object>> getLastMonthRefund(@Param("date") String date);
BigDecimal getLastMonthRefundFee(@Param("date") String date);
List<Map<String,Object>> getMonthRefund(@Param("date") String date);
List<Map<String,Object>> getCurrMonthOtherRefund(@Param("date") String date);
List<Map<String,Object>> getNextNMonthRefund(@Param("date") String date);
}

View File

@@ -124,6 +124,7 @@ public class BuyOrder implements Serializable {
* 3已完成
* 4: 交易失败
* 5: 已过期
* 6: 已退款
*/
private String orderStatus;
/**
@@ -223,4 +224,9 @@ public class BuyOrder implements Serializable {
private BookEntity bookEntity;
@TableField(exist = false)
private String trainingClassIdentity;
@TableField(exist = false)
private Boolean refundableStatus;
@TableField(exist = false)
private String refundRemark;
}

View File

@@ -16,6 +16,7 @@ public class BuyOrderRefund implements Serializable {
@TableId
private Integer id;
private String refundNo;
private Integer userId;
//订单类型 线上 线下
private String type;
@@ -23,8 +24,13 @@ public class BuyOrderRefund implements Serializable {
private String orderSn;
private String payType;
private BigDecimal fee;
private BigDecimal jfDeduction;
private BigDecimal shippingMoney;
private int deductShipping;
//商品名称
private String title;
private int status;
private String remark;
private Date createTime;
private String wxRefundNo;
}

View File

@@ -0,0 +1,37 @@
package com.peanut.modules.common.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 订单退款进度日志表
*
* @author yl
* @email yl328572838@163.com
* @date 2022-08-29 15:27:44
*/
@Data
@TableName("buy_order_refund_log")
public class BuyOrderRefundLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
private Integer id;
private Integer refundId;
private Date createTime;
private int type;
private int status;
private int reason;
@TableField(exist = false)
private String title;
@TableField(exist = false)
private String content;
}

View File

@@ -0,0 +1,10 @@
package com.peanut.modules.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.modules.common.entity.BuyOrderRefund;
import com.peanut.modules.common.entity.BuyOrderRefundLog;
public interface BuyOrderRefundLogService extends IService<BuyOrderRefundLog> {
void insertRefundLog(int buyOrderRefundId, int type, int status);
void insertRefundLog(int buyOrderRefundId, int type, int status, String reason);
}

View File

@@ -1,7 +1,14 @@
package com.peanut.modules.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderRefund;
import java.math.BigDecimal;
public interface BuyOrderRefundService extends IService<BuyOrderRefund> {
int insertBuyOrderRefund(BuyOrder buyOrder, BigDecimal refundFee, int deductShipping,String remark);
String genRefundNo();
BuyOrderRefund getRefundInfoByOrderId(int orderId);
}

View File

@@ -26,5 +26,7 @@ public interface BuyOrderService extends IService<BuyOrder> {
List<Map<String,Object>> getPhysicalBuyOrderTotal(String date, String orderType);
List<Map<String,Object>> getRefund(String date, String orderType);
List<Map<String,Object>> exportPhysicalBuyOrderInfo(String date, String orderType);
}

View File

@@ -105,7 +105,9 @@ public interface ClassEntityService extends IService<ClassEntity> {
List userScoreList(Map<String,Object> params);
List<Map<String,Object>> classCourseInfoClassId(int classId,int courseId);
Map<String,Object> getClassCourseInfoByClassId(int classId, int courseId);
List<Map<String,Object>> classCourseInfoClassId(int classId, int courseId);
R closeClass(Map<String,Object> params);

View File

@@ -20,6 +20,8 @@ public interface CouponService extends IService<CouponEntity> {
R insertCouponHistory(int couponId, int userId,int getType,int status,String remark);
R insertCouponHistory(BuyOrder buyOrder, int couponId, int userId, int getType, int status, String remark);
List<CouponHistory> getCouponListPayment(Map<String,Object> params);
//使用优惠卷
@@ -28,6 +30,8 @@ public interface CouponService extends IService<CouponEntity> {
//回滚优惠卷
void rollbackCoupon(int couponHistoryId);
void refundZSCouponHistoryByOrder(BuyOrder order);
//通过商品发放优惠卷
void insertCouponHistoryByProductId(BuyOrder order);

View File

@@ -0,0 +1,7 @@
package com.peanut.modules.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.modules.common.entity.CourseMedicine;
public interface CourseMedicineService extends IService<CourseMedicine> {
}

View File

@@ -10,4 +10,7 @@ public interface JfTransactionDetailsService extends IService<JfTransactionDetai
void recordJfTransaction(BuyOrder buyOrder, MyUserEntity user, BigDecimal jf);
void refundJfTransaction(BuyOrder buyOrder, MyUserEntity user);
void recordZsJfTransaction(BuyOrder buyOrder, MyUserEntity user, BigDecimal refundJF);
}

View File

@@ -12,5 +12,7 @@ public interface TransactionDetailsService extends IService<TransactionDetailsEn
List<Map<String,Object>> getTransactionDetailsTotal(String date);
List<Map<String,Object>> getRefundTransactionDetails(String date);
List<Map<String,Object>> getTransactionDetailsInfo(String date);
}

View File

@@ -20,8 +20,26 @@ public interface UserVipLogService extends IService<UserVipLog> {
BigDecimal countDayAmount(UserVipLog userVipLog);
BigDecimal getLastMonthRefundFee(String date);
List<Map<String, Object>> getCurrMonthOtherRefund(String date);
List<Map<String, Object>> getNextNMonthRefund(String date);
List<Map<String, Object>> getMonthRefund(String date);
List<Map<String,Object>> getUserVipLogInfo(String date);
String getPayMonth(Map<String, Object> row);
List<Map<String, Object>> getUserVipRefundInfo(String last_l_date, String last_date);
Map<String, Object> getUserVipLogInfoTotal(String date);
BigDecimal getUserVipRefundFeeTotal(String date);
BigDecimal getUserVipSameMonthRefundFeeTotal(String date);
List<Map<String, Object>> getLastMonthRefund(String date);
}

View File

@@ -29,4 +29,5 @@ public interface UserVipService extends IService<UserVip> {
void openVipForUser(BuyOrder buyOrder);
void refundVip(BuyOrder buyOrder);
}

View File

@@ -0,0 +1,31 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.modules.common.dao.BuyOrderRefundLogDao;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderRefund;
import com.peanut.modules.common.entity.BuyOrderRefundLog;
import com.peanut.modules.common.service.BuyOrderRefundLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service("commonBuyOrderRefundLogService")
public class BuyOrderRefundLogServiceImpl extends ServiceImpl<BuyOrderRefundLogDao, BuyOrderRefundLog> implements BuyOrderRefundLogService {
@Override
public void insertRefundLog(int refundId, int type, int status){
BuyOrderRefundLog log = new BuyOrderRefundLog();
log.setRefundId(refundId);
log.setType(type);
log.setStatus(status);
this.save(log);
}
@Override
public void insertRefundLog(int refundId, int type, int status, String reason){
BuyOrderRefundLog log = new BuyOrderRefundLog();
log.setRefundId(refundId);
log.setType(type);
log.setStatus(status);
this.save(log);
}
}

View File

@@ -1,13 +1,48 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.modules.common.dao.BuyOrderRefundDao;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderRefund;
import com.peanut.modules.common.service.BuyOrderRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Random;
@Slf4j
@Service("commonBuyOrderRefundService")
public class BuyOrderRefundServiceImpl extends ServiceImpl<BuyOrderRefundDao, BuyOrderRefund> implements BuyOrderRefundService {
@Override
public int insertBuyOrderRefund(BuyOrder buyOrder, BigDecimal refundFee, int deductShipping,String remark){
BuyOrderRefund buyOrderRefund = new BuyOrderRefund();
buyOrderRefund.setOrderId(buyOrder.getOrderId());
buyOrderRefund.setType("线上"); //id
buyOrderRefund.setUserId(buyOrder.getUserId());
buyOrderRefund.setOrderSn(buyOrder.getOrderSn());
buyOrderRefund.setPayType(buyOrder.getPaymentMethod());
buyOrderRefund.setFee(refundFee);
buyOrderRefund.setJfDeduction(buyOrder.getJfDeduction());
buyOrderRefund.setShippingMoney(deductShipping==1?buyOrder.getShippingMoney():BigDecimal.ZERO);
buyOrderRefund.setDeductShipping(deductShipping);
buyOrderRefund.setRemark(remark);
this.save(buyOrderRefund);
return buyOrderRefund.getId();
}
@Override
public String genRefundNo() {
long time = System.currentTimeMillis();
int random = new Random().nextInt(900) + 100; // 100~999
return "RF" + time + random;
}
@Override
public BuyOrderRefund getRefundInfoByOrderId(int orderId){
QueryWrapper<BuyOrderRefund> wrapperRefund = new QueryWrapper<>();
wrapperRefund.eq("order_id",orderId).last("LIMIT 1");
BuyOrderRefund refundInfo = this.getOne(wrapperRefund);
return refundInfo;
}
}

View File

@@ -7,8 +7,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.ExpressOrderUtil;
import com.peanut.common.utils.Query;
import com.peanut.config.Constants;
import com.peanut.modules.common.dao.*;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.BuyOrderRefundService;
import com.peanut.modules.common.service.BuyOrderService;
import com.peanut.modules.common.to.PrepareOrderDto;
import com.peanut.modules.common.vo.UserBaseVo;
@@ -16,10 +18,10 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@@ -42,6 +44,8 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
private AiBuyConfigDao aiBuyConfigDao;
@Autowired
private ShopProductCourseDao shopProductCourseDao;
@Autowired
private BuyOrderRefundService buyOrderRefundService;
@Override
public Map<String, Object> initPrepareOrder(PrepareOrderDto prepareOrderDto) {
@@ -73,7 +77,7 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
wrapper.eq(BuyOrder::getUserId,params.get("userId"));
wrapper.eq(BuyOrder::getCome,params.get("come"));
if(StringUtils.isEmpty(params.get("orderStatus").toString())){
Integer[] sts = {0,1,2,3};
Integer[] sts = {0,1,2,3,6,7};
wrapper.in(BuyOrder::getOrderStatus,sts);
}else{
wrapper.eq(BuyOrder::getOrderStatus,params.get("orderStatus").toString());
@@ -88,6 +92,7 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
}
//组装购买人
b.setUser(userDao.selectById(b.getUserId()));
boolean refundableStatus = false;
//组装充值配置详情
if (b.getProductId()!=null){
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigDao.selectById(b.getProductId());
@@ -97,7 +102,12 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
}
b.setBookBuyConfigEntity(bookBuyConfigEntity);
}
long timestamp = Instant.now().toEpochMilli();
long paymentDateTime = b.getPaymentDate()==null?0: b.getPaymentDate().getTime();
if (b.getVipBuyConfigId()!=0){
if(paymentDateTime > timestamp-7*24*60*60*1000){
refundableStatus = true;
}
b.setVipBuyConfigEntity(vipBuyConfigDao.selectById(b.getVipBuyConfigId()));
}
if (b.getAiBuyConfigId()!=0){
@@ -107,10 +117,27 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
List<BuyOrderProduct> buyOrderProducts = buyOrderProductDao.selectList(
new LambdaQueryWrapper<BuyOrderProduct>().eq(BuyOrderProduct::getOrderId, b.getOrderId()));
if (buyOrderProducts.size() > 0) {
for (BuyOrderProduct bb : buyOrderProducts){
boolean[] refundableStatusArr = new boolean[buyOrderProducts.size()];
for (int i=0;i<buyOrderProducts.size();i++){
BuyOrderProduct bb = buyOrderProducts.get(i);
MPJLambdaWrapper<ShopProduct> w = new MPJLambdaWrapper<>();
w.disableLogicDel().eq(ShopProduct::getProductId,bb.getProductId());
bb.setProduct(shopProductDao.selectOne(w));
boolean refundableStatusProduct = false;
if(bb.getProduct()!=null && bb.getProduct().getGoodsType().equals("05") && (paymentDateTime > timestamp-7*24*60*60*1000)){
refundableStatusProduct = true;
}else if(bb.getProduct()!=null && !bb.getProduct().getGoodsType().equals("05") && b.getOrderStatus().equals("1") && bb.getExpressOrderId()==0){
refundableStatusProduct = true;
}
refundableStatusArr[i] = refundableStatusProduct;
}
for (boolean rs : refundableStatusArr){
if(!rs){
refundableStatus = false;
break;
}else{
refundableStatus = true;
}
}
b.setProductList(buyOrderProducts);
b.setTimestamp(b.getCreateTime().getTime()/1000);
@@ -121,7 +148,10 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
List<ExpressOrder> expressOrders = expressOrderDao.selectList(new LambdaQueryWrapper<ExpressOrder>().in(ExpressOrder::getId, collect));
b.setExpressList(expressOrders);
}
}else if("relearn".equals(b.getOrderType()) && paymentDateTime > timestamp-7*24*60*60*1000){
refundableStatus = true;
}
b.setRefundableStatus(b.getOrderStatus().equals("6") || b.getOrderStatus().equals("7")?false:refundableStatus);
}
}
return page;
@@ -225,12 +255,82 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
@Override
public List<Map<String, Object>> getPhysicalBuyOrderTotal(String date,String orderType) {
return this.baseMapper.getPhysicalBuyOrderTotal(date, orderType);
List<Map<String, Object>> incomeList = this.baseMapper.getPhysicalBuyOrderTotal(date, orderType);
List<Map<String, Object>> refundList = this.baseMapper.getRefund(date, orderType);
Map<String, Map<String, Object>> merged = new LinkedHashMap<>();
for (Map<String, Object> income : incomeList) {
String payType = income.get("payType").toString();
Map<String, Object> 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<String, Object> refund : refundList) {
String payType = refund.get("payType").toString();
Map<String, Object> row = merged.computeIfAbsent(payType, k -> {
Map<String, Object> 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<String, Object> 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<Map<String, Object>> getRefund(String date, String orderType) {
return this.baseMapper.getRefund(date, orderType);
}
@Override
public List<Map<String, Object>> exportPhysicalBuyOrderInfo(String date,String orderType) {
return this.baseMapper.exportPhysicalBuyOrderInfo(date, orderType);
List<Map<String, Object>> purchaseList = this.baseMapper.exportPhysicalBuyOrderInfo(date, orderType);
List<Map<String, Object>> refundList = this.baseMapper.exportPhysicalBuyOrderRefundInfo(date, orderType);
List<Map<String, Object>> result = new ArrayList<>();
for (Map<String, Object> map : purchaseList) {
//本月下单即为本月收入,已退款订单的购买行也展示(退款行按退款月份在对应报表中体现)
if ("已退款".equals(map.get("orderStatus").toString())) {
Map<String, Object> purchaseRow = new HashMap<>(map);
purchaseRow.put("orderStatus", "已付款");
result.add(purchaseRow);
} else {
result.add(map);
}
}
for (Map<String, Object> refund : refundList) {
Map<String, Object> 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

View File

@@ -1396,7 +1396,7 @@ public class ClassEntityServiceImpl extends ServiceImpl<ClassEntityDao, ClassEnt
.eq(ClassTaskAndQuesReply::getUserId,params.get("userId").toString()));
for (ClassTaskAndQuesReply reply:classTaskAndQuesReplys){
ClassEntity classEntity = this.getById(reply.getClassId());
if (!"2".equals(classEntity.getState())){
if (classEntity!=null && !"2".equals(classEntity.getState())){
res = reply;
}
}
@@ -1692,7 +1692,37 @@ public class ClassEntityServiceImpl extends ServiceImpl<ClassEntityDao, ClassEnt
}
return resultList;
}
@Override
public Map<String,Object> getClassCourseInfoByClassId(int classId, int courseId) {
ClassEntity classEntity = this.baseMapper.selectById(classId);
MPJLambdaWrapper<CourseEntity> wrapper = new MPJLambdaWrapper<>();
wrapper.selectAll(CourseEntity.class);
wrapper.leftJoin(ClassCourse.class, ClassCourse::getCourseId, CourseEntity::getId);
wrapper.leftJoin(ClassModel.class, ClassModel::getId, ClassCourse::getModelId);
wrapper.eq(ClassModel::getId, classEntity.getModelId());
if (courseId!=0){
wrapper.eq(CourseEntity::getId,courseId);
}
CourseEntity course = courseDao.selectOne(wrapper);
Map<String,Object> candk = new HashMap<>();
MPJLambdaWrapper<CourseCatalogueChapterEntity> w = new MPJLambdaWrapper<>();
w.leftJoin(CourseCatalogueChapterVideoEntity.class,CourseCatalogueChapterVideoEntity::getChapterId,CourseCatalogueChapterEntity::getId);
w.eq(CourseCatalogueChapterEntity::getCourseId,course.getId());
w.selectSum(CourseCatalogueChapterVideoEntity::getDuration);
Map<String,Object> map = courseCatalogueChapterDao.selectJoinMap(w);
double duration = Double.parseDouble(map.get("duration").toString());
double minute = duration/60;
double keshi = Math.ceil(minute/45);
candk.put("courseId",course.getId());
candk.put("courseTitle",course.getTitle());
candk.put("courseETitle",course.getEtitle());
candk.put("titleAbbr",course.getTitleAbbr());
candk.put("keshi",keshi);
return candk;
}
@Override
public List<Map<String,Object>> classCourseInfoClassId(int classId,int courseId) {
List<Map<String,Object>> res = new ArrayList<>();

View File

@@ -74,7 +74,7 @@ public class ClassExamServiceImpl extends ServiceImpl<ClassExamDao, ClassExam> i
public void updateClassExamSubject(ClassExamSubject classExamSubject) {
classExamSubjectDao.updateById(classExamSubject);
if (classExamSubject.getOptions()!=null&&classExamSubject.getOptions().size() > 0){
classExamOptionDao.delete(new LambdaQueryWrapper<ClassExamOption>().eq(ClassExamOption::getSubjectId,classExamSubject.getId()));
classExamOptionDao.realDeleteClassExamOption(classExamSubject.getId());
for (ClassExamOption option:classExamSubject.getOptions()){
option.setSubjectId(classExamSubject.getId());
classExamOptionDao.insert(option);

View File

@@ -1,6 +1,7 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.DateUtils;
@@ -8,7 +9,9 @@ import com.peanut.common.utils.R;
import com.peanut.common.utils.ShiroUtils;
import com.peanut.modules.common.dao.*;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.CouponHistoryService;
import com.peanut.modules.common.service.CouponService;
import com.peanut.modules.common.service.JfTransactionDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,6 +44,10 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
private ShopProductDao shopProductDao;
@Autowired
private JfTransactionDetailsDao jfTransactionDetailsDao;
@Autowired
private JfTransactionDetailsService jfTransactionDetailsService;
@Autowired
private CouponHistoryService couponHistoryService;
@Override
public CouponEntity getByIdSetRange(int id) {
@@ -116,7 +123,50 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
return R.error("优惠券暂未开始发放");
}
}
@Override
public R insertCouponHistory(BuyOrder buyOrder, int couponId, int userId, int getType, int status, String remark) {
CouponEntity couponEntity = couponDao.selectById(couponId);
if (couponEntity.getCurrentState()==0){
int historyCount = couponHistoryDao.selectCount(new LambdaQueryWrapper<CouponHistory>()
.eq(CouponHistory::getCouponId,couponId)).intValue();
//是否超出总发行量
if (historyCount<couponEntity.getTotalCirculation()){
List<CouponHistory> historyList = couponHistoryDao.selectList(new LambdaQueryWrapper<CouponHistory>()
.eq(CouponHistory::getUserId,userId)
.eq(CouponHistory::getCouponId,couponId));
//是否超出可持有张数
if (historyList.size()<couponEntity.getLimitedCollar()){
CouponHistory couponHistory = new CouponHistory();
couponHistory.setCouponId(couponId);
couponHistory.setUserId(userId);
couponHistory.setGetType(getType);
couponHistory.setStatus(status);
couponHistory.setRemark(remark);
couponHistory.setEffectType(couponEntity.getEffectType());
Date date = new Date();
if (couponEntity.getEffectType()==1){
couponHistory.setStartTime(date);
couponHistory.setEndTime(DateUtils.addDateDays(date,couponEntity.getValidity()));
}else if (couponEntity.getEffectType()==2){
couponHistory.setStartTime(couponEntity.getEffectTime());
couponHistory.setEndTime(couponEntity.getExpireTime());
}
if (couponHistory.getStatus()==1){
couponHistory.setUseTime(date);
}
couponHistory.setOrderId(buyOrder.getOrderId());
couponHistoryDao.insert(couponHistory);
return R.ok();
}else {
return R.error("每人限领"+couponEntity.getLimitedCollar()+"");
}
}else {
return R.error("优惠券已放完");
}
}else {
return R.error("优惠券暂未开始发放");
}
}
@Override
public List<CouponHistory> getCouponListPayment(Map<String, Object> params) {
List<CouponHistory> res = new ArrayList<>();
@@ -252,6 +302,71 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
}
}
@Override
public void refundZSCouponHistoryByOrder(BuyOrder order){
MyUserEntity userEntity = userDao.selectById(order.getUserId());
BigDecimal refundAllJF = BigDecimal.ZERO;
List<JfTransactionDetails> grantJfList = jfTransactionDetailsDao.selectList(new LambdaQueryWrapper<JfTransactionDetails>()
.eq(JfTransactionDetails::getRelationId, order.getOrderId())
.eq(JfTransactionDetails::getUserId, order.getUserId())
.eq(JfTransactionDetails::getActType, 0)
.gt(JfTransactionDetails::getChangeAmount, BigDecimal.ZERO)
.like(JfTransactionDetails::getRemark, "优惠券换积分"));
for (JfTransactionDetails grantJf : grantJfList) {
refundAllJF = refundAllJF.add(grantJf.getChangeAmount());
}
boolean orderGrantedJf = refundAllJF.compareTo(BigDecimal.ZERO) > 0;
MPJLambdaWrapper<CouponToProduct> wrapper = new MPJLambdaWrapper();
wrapper.leftJoin(BuyOrderProduct.class,BuyOrderProduct::getProductId,CouponToProduct::getProductId);
wrapper.leftJoin(CouponEntity.class,CouponEntity::getId,CouponToProduct::getCouponId);
wrapper.eq(CouponEntity::getCurrentState,0);
wrapper.eq(BuyOrderProduct::getOrderId,order.getOrderId());
wrapper.select(CouponToProduct::getCouponId);
wrapper.select(BuyOrderProduct::getProductId);
wrapper.select(BuyOrderProduct::getQuantity);
List<Map<String,Object>> buyOrderProducts = couponToProductDao.selectJoinMaps(wrapper);
Boolean isRefundCoupon = false;
for (Map<String,Object> map : buyOrderProducts) {
ShopProduct shopProduct = shopProductDao.selectById(map.get("product_id").toString());
if ("03".equals(shopProduct.getGoodsType())) {
if (!orderGrantedJf) {
isRefundCoupon = true;
}
} else {
isRefundCoupon = true;
}
}
if (orderGrantedJf) {
BigDecimal userJf = userEntity.getJf() == null ? BigDecimal.ZERO : userEntity.getJf();
BigDecimal actualDeduct;
if (userJf.compareTo(refundAllJF) >= 0) {
actualDeduct = refundAllJF;
} else if (userJf.compareTo(BigDecimal.ZERO) > 0) {
actualDeduct = userJf;
} else {
actualDeduct = BigDecimal.ZERO;
}
if (actualDeduct.compareTo(BigDecimal.ZERO) > 0) {
userEntity.setJf(userJf.subtract(actualDeduct));
userDao.updateById(userEntity);
jfTransactionDetailsService.recordZsJfTransaction(order, userEntity, actualDeduct);
QueryWrapper<CouponHistory> couponHistoryRemoveWrapper = new QueryWrapper<>();
couponHistoryRemoveWrapper.eq("order_id", order.getOrderId());
couponHistoryRemoveWrapper.eq("status", 1);
couponHistoryService.remove(couponHistoryRemoveWrapper);
}
}
if (isRefundCoupon) {
QueryWrapper<CouponHistory> couponHistoryRemoveWrapper = new QueryWrapper<>();
couponHistoryRemoveWrapper.eq("order_id", order.getOrderId());
couponHistoryRemoveWrapper.eq("status", 0);
couponHistoryService.remove(couponHistoryRemoveWrapper);
}
}
@Override
public void insertCouponHistoryByProductId(BuyOrder order) {
MPJLambdaWrapper<CouponToProduct> wrapper = new MPJLambdaWrapper();
@@ -265,20 +380,21 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
List<Map<String,Object>> buyOrderProducts = couponToProductDao.selectJoinMaps(wrapper);
for (Map<String,Object> map : buyOrderProducts) {
ShopProduct shopProduct = shopProductDao.selectById(map.get("product_id").toString());
//vip身份用户买送优惠券的预售书时候不送优惠券改自动送积分
//预售书+赠送现金券VIP用户将券额转为积分仅产品id=2023时需为妇幼生殖vip(type=10)
if ("03".equals(shopProduct.getGoodsType())){
MyUserEntity userEntity = userDao.selectById(order.getUserId());
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId, userEntity.getId())
.eq(UserVip::getState,0));
if (userVipList.size() > 0) {
int couponId = Integer.parseInt(map.get("coupon_id").toString());
CouponEntity couponEntity = couponDao.selectById(couponId);
//现金券
if (couponEntity.getCouponType()==0){
int productId = Integer.parseInt(map.get("product_id").toString());
int couponId = Integer.parseInt(map.get("coupon_id").toString());
CouponEntity couponEntity = couponDao.selectById(couponId);
boolean isFyszVip = userVipList.stream().anyMatch(userVip -> Integer.valueOf(10).equals(userVip.getType()));
boolean couponToJf = couponEntity.getCouponType() == 0 && (productId == 2023 ? isFyszVip : userVipList.size() > 0);
if (couponToJf){
BigDecimal jf = BigDecimal.ZERO;
for (int i=0;i<Integer.parseInt(map.get("quantity").toString());i++){
R res = insertCouponHistory(couponId,order.getUserId(), 1,1,
R res = insertCouponHistory(order,couponId,order.getUserId(), 1,1,
"购买商品"+shopProduct.getProductName()+"赠送;vip用户购买预售书优惠券换积分。");
if (Integer.parseInt(res.get("code").toString())==0&&couponEntity.getCouponAmount() != null && couponEntity.getCouponAmount().compareTo(BigDecimal.ZERO)>0) {
jf = jf.add(couponEntity.getCouponAmount());
@@ -296,12 +412,6 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
jfTransactionDetails.setRemark("vip用户买预售书送的优惠券换积分,订单号:"+order.getOrderSn());
jfTransactionDetailsDao.insert(jfTransactionDetails);
}
}else {
for (int i=0;i<Integer.parseInt(map.get("quantity").toString());i++){
insertCouponHistory(Integer.parseInt(map.get("coupon_id").toString()),
order.getUserId(), 1,0,"购买商品"+shopProduct.getProductName()+"赠送");
}
}
}else {
for (int i=0;i<Integer.parseInt(map.get("quantity").toString());i++){
insertCouponHistory(Integer.parseInt(map.get("coupon_id").toString()),

View File

@@ -0,0 +1,16 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.modules.common.dao.CourseMedicineDao;
import com.peanut.modules.common.dao.CourseToMedicineDao;
import com.peanut.modules.common.entity.CourseMedicine;
import com.peanut.modules.common.entity.CourseToMedicine;
import com.peanut.modules.common.service.CourseMedicineService;
import com.peanut.modules.common.service.CourseToMedicineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service("commonCourseMedicineService")
public class CourseMedicineServiceImpl extends ServiceImpl<CourseMedicineDao, CourseMedicine> implements CourseMedicineService {
}

View File

@@ -22,4 +22,26 @@ public class JfTransactionDetailsServiceImpl extends ServiceImpl<JfTransactionDe
jfTransactionDetails.setRemark("消费积分抵扣:"+jf.toString()+",订单号:"+buyOrder.getOrderSn());
getBaseMapper().insert(jfTransactionDetails);
}
@Override
public void refundJfTransaction(BuyOrder buyOrder, MyUserEntity user) {
JfTransactionDetails jfTransactionDetails = new JfTransactionDetails();
jfTransactionDetails.setUserId(user.getId());
jfTransactionDetails.setChangeAmount(buyOrder.getJfDeduction());
jfTransactionDetails.setActType(0);
jfTransactionDetails.setUserBalance(user.getJf().add(buyOrder.getJfDeduction()));
jfTransactionDetails.setRelationId(buyOrder.getOrderId());
jfTransactionDetails.setRemark("订单退款:"+buyOrder.getJfDeduction().toString()+",订单号:"+buyOrder.getOrderSn());
getBaseMapper().insert(jfTransactionDetails);
}
@Override
public void recordZsJfTransaction(BuyOrder buyOrder, MyUserEntity user, BigDecimal refundJF) {
JfTransactionDetails jfTransactionDetails = new JfTransactionDetails();
jfTransactionDetails.setUserId(buyOrder.getUserId());
jfTransactionDetails.setChangeAmount(refundJF.abs().negate());
jfTransactionDetails.setActType(1);
jfTransactionDetails.setUserBalance(user.getJf());
jfTransactionDetails.setRelationId(buyOrder.getOrderId());
jfTransactionDetails.setRemark("订单退款,赠送积分退回:"+refundJF.toString()+",订单号:"+buyOrder.getOrderSn());
getBaseMapper().insert(jfTransactionDetails);
}
}

View File

@@ -55,6 +55,8 @@ public class TrainingClassServiceImpl extends ServiceImpl<TrainingClassDao, Trai
identity = "心理学vip";
}else if ("9".equals(vipType)) {
identity = "中西汇通vip";
}else if ("10".equals(vipType)) {
identity = "妇幼生殖vip";
}
break;
}

View File

@@ -24,6 +24,11 @@ public class TransactionDetailsServiceImpl extends ServiceImpl<TransactionDetail
return this.baseMapper.getTransactionDetailsTotal(date);
}
@Override
public List<Map<String, Object>> getRefundTransactionDetails(String date) {
return this.baseMapper.getRefundTransactionDetails(date);
}
@Override
public List<Map<String, Object>> getTransactionDetailsInfo(String date) {
return this.baseMapper.getTransactionDetailsInfo(date);

View File

@@ -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,14 +94,177 @@ public class UserVipLogServiceImpl extends ServiceImpl<UserVipLogDao, UserVipLog
return userVipLog.getFee().divide(days, 2, BigDecimal.ROUND_HALF_UP);
}
}
@Override
public BigDecimal getLastMonthRefundFee(String date){
return this.baseMapper.getLastMonthRefundFee(date);
}
@Override
public List<Map<String, Object>> getLastMonthRefund(String date){
return this.baseMapper.getLastMonthRefund(date);
}
@Override
public List<Map<String, Object>> getCurrMonthOtherRefund(String date){
return this.baseMapper.getCurrMonthOtherRefund(date);
}
@Override
public List<Map<String, Object>> getNextNMonthRefund(String date){
return this.baseMapper.getNextNMonthRefund(date);
}
@Override
public List<Map<String, Object>> getMonthRefund(String date){
return this.baseMapper.getMonthRefund(date);
}
@Override
public List<Map<String, Object>> getUserVipLogInfo(String date) {
return this.baseMapper.getUserVipLogInfo(date);
List<Map<String, Object>> list = this.baseMapper.getUserVipLogInfo(date);
Map<String, Map<String, Object>> refundMap = new HashMap<>();
for (Map<String, Object> refund : this.baseMapper.getMonthRefund(date)) {
Object uvlId = refund.get("uvlId");
if (uvlId != null) {
refundMap.put(uvlId.toString(), refund);
}
}
List<Map<String, Object>> result = new ArrayList<>();
Set<String> matchedUvlIds = new HashSet<>();
for (Map<String, Object> row : list) {
row.put("orderStatus", "已付款");
Object uvlId = row.get("uvlId");
Map<String, Object> 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<String, Object> 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<String, Object> buildRefundRow(Map<String, Object> row, Map<String, Object> refund, String date) {
Map<String, Object> 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);
refundRow.put("startTime", refund.get("refundTime"));
} 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<String, Object> 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<String, Object> 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
public List<Map<String, Object>> getUserVipRefundInfo(String last_l_date, String last_date) {
return this.baseMapper.getUserVipRefundInfo(last_l_date,last_date);
}
@Override
public Map<String, Object> 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);
}
}

View File

@@ -1,8 +1,11 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.ShiroUtils;
import com.peanut.modules.book.vo.UserVipYearVo;
import com.peanut.modules.common.dao.*;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.UserVipLogService;
@@ -12,7 +15,6 @@ import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
@Slf4j
@@ -33,6 +35,8 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
private VipBuyConfigDao vipBuyConfigDao;
@Autowired
private UserVipLogService userVipLogService;
@Autowired
private UserVipLogDao userVipLogDao;
@Override
public boolean isVip() {
@@ -104,7 +108,7 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
@Override
public boolean is4569SVip(int uid) {
if (isVipByType(4,uid)&&isVipByType(9,uid)&&isVipByType(5,uid)&&isVipByType(6,uid)){
if (isVipByType(4,uid)&&isVipByType(9,uid)&&isVipByType(5,uid)&&isVipByType(6,uid)&&isVipByType(10,uid)){
return true;
}
return false;
@@ -135,8 +139,9 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId, u==null?ShiroUtils.getUId():u.getId())
.eq(UserVip::getState,0));
for (UserVip userVip : userVipList) {
if (userVip.getType()==4||userVip.getType()==9||userVip.getType()==5||userVip.getType()==6) {
if (userVip.getType()==4||userVip.getType()==9||userVip.getType()==5||userVip.getType()==6||userVip.getType()==10) {
List<CourseToMedicine> list = courseToMedicalDao.selectList(new LambdaQueryWrapper<CourseToMedicine>()
.eq(CourseToMedicine::getCourseId,courseId));
for (CourseToMedicine ctm:list) {
@@ -145,7 +150,9 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
if ((cm.getId()==1&&userVip.getType()==4)||//中医学
(cm.getId()==74&&userVip.getType()==9)||//中西汇通
(cm.getId()==2&&userVip.getType()==5)||//针灸学
(cm.getId()==109&&userVip.getType()==10)||//妇幼生殖
(cm.getId()==5&&userVip.getType()==6)){//肿瘤学
return userVip;
}
}
@@ -201,6 +208,8 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
set.add(6);
}else if (cm.getId() == 4) {//心身医学
set.add(8);
}else if (cm.getId() == 109){//妇幼生殖
set.add(10);
}
}
}
@@ -217,7 +226,8 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
return set;
}
public CourseMedicine topLabel(int labelId) {
public CourseMedicine
topLabel(int labelId) {
CourseMedicine cm = courseMedicineDao.selectById(labelId);
if (cm != null) {
CourseMedicine pcm = courseMedicineDao.selectById(cm.getPid());
@@ -254,8 +264,9 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
List<UserVip> resList = new ArrayList();
if(vipBuyConfigEntity.getType()==1){//医学超级
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getState,0).in(UserVip::getType,4,9,5,6));
for (int i=4;i<=7;i++){
.eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getState,0).in(UserVip::getType,4,9,5,6,10));
for (int i=4;i<=10;i++){
log.info("openVipForUser====i:"+i);
if (i==7){
i=9;
}
@@ -285,14 +296,14 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
}
}
}else if(vipBuyConfigEntity.getType()==11){//延期医学超级
for (int i=4;i<=7;i++){
for (int i=4;i<=10;i++){
if (i==7){
i=9;
}
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.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);
@@ -343,8 +354,8 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
for (int i=7;i<9;i++){
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.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);
@@ -363,7 +374,7 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
}
}
}else if (vipBuyConfigEntity.getType()==4||vipBuyConfigEntity.getType()==9||vipBuyConfigEntity.getType()==5||vipBuyConfigEntity.getType()==6||
vipBuyConfigEntity.getType()==7||vipBuyConfigEntity.getType()==8){
vipBuyConfigEntity.getType()==7||vipBuyConfigEntity.getType()==8 || vipBuyConfigEntity.getType()==10){
UserVip userVip = new UserVip();
userVip.setUserId(buyOrder.getUserId());
userVip.setType(vipBuyConfigEntity.getType());
@@ -372,13 +383,13 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
userVipDao.insert(userVip);
resList.add(userVip);
}else if (vipBuyConfigEntity.getType()==41||vipBuyConfigEntity.getType()==91||vipBuyConfigEntity.getType()==51||vipBuyConfigEntity.getType()==61||
vipBuyConfigEntity.getType()==71||vipBuyConfigEntity.getType()==81){
vipBuyConfigEntity.getType()==71||vipBuyConfigEntity.getType()==81 ||vipBuyConfigEntity.getType()==101){
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId,buyOrder.getUserId())
.eq(UserVip::getType,vipBuyConfigEntity.getType().toString().substring(0,1))
.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);
@@ -401,5 +412,26 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
}
}
@Override
public void refundVip(BuyOrder buyOrder){
MPJLambdaWrapper<UserVipLog> UserVipLogMPJLambdaWrapper = new MPJLambdaWrapper<>();
UserVipLogMPJLambdaWrapper.leftJoin(UserVip.class,UserVip::getId,UserVipLog::getUserVipId);
UserVipLogMPJLambdaWrapper.leftJoin(BuyOrder.class,BuyOrder::getOrderSn,UserVipLog::getOrderSn);
UserVipLogMPJLambdaWrapper.leftJoin(VipBuyConfigEntity.class,VipBuyConfigEntity::getId,BuyOrder::getVipBuyConfigId);
UserVipLogMPJLambdaWrapper.selectAll(UserVip.class);
UserVipLogMPJLambdaWrapper.select(VipBuyConfigEntity::getYear);
UserVipLogMPJLambdaWrapper.eq(UserVipLog::getOrderSn,buyOrder.getOrderSn()).eq(UserVip::getState,0);
List<UserVipYearVo> userVipYearList = userVipLogDao.selectJoinList(UserVipYearVo.class, UserVipLogMPJLambdaWrapper);
for (UserVipYearVo userVipYearVo:userVipYearList){
UserVip userVip = userVipDao.selectById(userVipYearVo.getId());
userVip.setEndTime(DateUtils.addYears(userVip.getEndTime(),-userVipYearVo.getYear()));
if(userVip.getStartTime().compareTo(userVip.getEndTime())==0){
this.removeById(userVip);
}else{
this.updateById(userVip);
}
}
userVipLogService.remove(new QueryWrapper<UserVipLog>().eq("order_sn",buyOrder.getOrderSn()).eq("user_id",buyOrder.getUserId()));
}
}

View File

@@ -63,7 +63,7 @@ public class StatisticsBusinessVipController {
.stream().map(UserVip::getType).collect(Collectors.toList());
// 定义复购规则
Map<String, List<Integer>> reBuyRules = new HashMap<>();
reBuyRules.put("医学超级", Arrays.asList(4, 5, 6, 9));
reBuyRules.put("医学超级", Arrays.asList(4, 5, 6, 9, 10));
reBuyRules.put("国学心理学超级", Arrays.asList(7, 8));
reBuyRules.put("中医学", Arrays.asList(4));
reBuyRules.put("针灸学", Arrays.asList(5));
@@ -71,6 +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));
// 判断是否复购
List<Integer> required = reBuyRules.get(vipType);
if (required != null && state1UserVips.containsAll(required)) {
@@ -141,14 +142,17 @@ 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());
row7.createCell(0).setCellValue("");row7.createCell(1).setCellValue(state1Counts.getOrDefault("",0).toString());
row7.createCell(2).setCellValue("");row7.createCell(3).setCellValue(state0Counts.getOrDefault("", 0).toString());
Row row8 = sheet.createRow(rowNum++);
row8.createCell(0).setCellValue("中西汇通");row8.createCell(1).setCellValue(state1Counts.getOrDefault("中西汇通", 0).toString());
row8.createCell(2).setCellValue("中西汇通");row8.createCell(3).setCellValue(state0Counts.getOrDefault("中西汇通", 0).toString());
row8.createCell(0).setCellValue("心理");row8.createCell(1).setCellValue(state1Counts.getOrDefault("心理", 0).toString());
row8.createCell(2).setCellValue("心理");row8.createCell(3).setCellValue(state0Counts.getOrDefault("心理", 0).toString());
Row row9 = sheet.createRow(rowNum++);
row9.createCell(0).setCellValue("中西汇通学");row9.createCell(1).setCellValue(state1Counts.getOrDefault("中西汇通学", 0).toString());
row9.createCell(2).setCellValue("中西汇通学");row9.createCell(3).setCellValue(state0Counts.getOrDefault("中西汇通学", 0).toString());
sheet.createRow(rowNum++);
String[] header = {"时间","姓名","电话","VIP类型","是否延期", "本次年限","本次金额","本次开始时间","本次结束时间","到期时间","是否复购"};
@@ -292,8 +296,8 @@ public class StatisticsBusinessVipController {
Row row1 = sheet.createRow(rowNum++);
Map<String,Integer> state1Counts = (Map<String,Integer>) r.get("banTypeTotalCounts");
Map<String,Integer> state0Counts = (Map<String,Integer>) 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));
@@ -316,14 +320,17 @@ 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());
row7.createCell(0).setCellValue("");row7.createCell(1).setCellValue(state1Counts.getOrDefault("",0).toString());
row7.createCell(2).setCellValue("");row7.createCell(3).setCellValue(state0Counts.getOrDefault("", 0).toString());
Row row8 = sheet.createRow(rowNum++);
row8.createCell(0).setCellValue("中西汇通");row8.createCell(1).setCellValue(state1Counts.getOrDefault("中西汇通", 0).toString());
row8.createCell(2).setCellValue("中西汇通");row8.createCell(3).setCellValue(state0Counts.getOrDefault("中西汇通", 0).toString());
row8.createCell(0).setCellValue("心理");row8.createCell(1).setCellValue(state1Counts.getOrDefault("心理", 0).toString());
row8.createCell(2).setCellValue("心理");row8.createCell(3).setCellValue(state0Counts.getOrDefault("心理", 0).toString());
Row row9 = sheet.createRow(rowNum++);
row9.createCell(0).setCellValue("中西汇通学");row9.createCell(1).setCellValue(state1Counts.getOrDefault("中西汇通学", 0).toString());
row9.createCell(2).setCellValue("中西汇通学");row9.createCell(3).setCellValue(state0Counts.getOrDefault("中西汇通学", 0).toString());
sheet.createRow(rowNum++);
String[] header2 = {"","首次办理三年","首次办理四年","其他","延期一年", "延期三年","延期四年","其他"};
@@ -339,6 +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);
@@ -352,6 +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());
@@ -434,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<Map<String, Object>>) r.get("resultList"));
}
@@ -480,7 +492,8 @@ public class StatisticsBusinessVipController {
"6","肿瘤学",
"7","国学",
"8","心理学",
"9","中西汇通学"
"9","中西汇通学",
"10","妇幼生殖学"
);
// 封装统计结果
@@ -501,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<String,Object> map : userVips) {
String[] types = map.get("type").toString().split(",");
@@ -508,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<String,Object> copy = new HashMap<>(map);
copy.put("vipType","医学超级");
@@ -536,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());

View File

@@ -367,9 +367,13 @@ public class StatisticsController {
@RequestMapping("/getUserCourseBuyInfoTotal")
public R getUserCourseBuyInfoTotal(@RequestBody Map<String, Object> params) {
List<Map<String,Object>> tanxiaoTotal = userCourseBuyService.getUserCourseBuyInfoTotal(params.get("date").toString());
List<Map<String,Object>> income = userCourseBuyService.getIncome(params.get("date").toString());
return R.ok().put("tanxiaoTotal", tanxiaoTotal).put("income", income);
String date = params.get("date").toString();
List<Map<String,Object>> tanxiaoTotal = userCourseBuyService.getUserCourseBuyInfoTotal(date);
List<Map<String,Object>> monthRefund = userCourseBuyService.getSameMonthRefund(date);
List<Map<String,Object>> income = mergeIncomeWithMonthRefund(
userCourseBuyService.getIncome(date), monthRefund);
List<Map<String,Object>> 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<String,Object> 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<String, Object> params) {
Map<String,Object> map = transactionDetailsService.getUserSurplusPeanutCoin(params.get("date").toString()+" 23:59:59");
List<Map<String,Object>> list = transactionDetailsService.getTransactionDetailsTotal(params.get("date").toString()+" 23:59:59");
return R.ok().put("total", list).put("surplus", map);
List<Map<String,Object>> 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<String, Object> params) {
List<Map<String,Object>> list = buyOrderService.getPhysicalBuyOrderTotal(params.get("date").toString(),params.get("orderType").toString());
List<Map<String,Object>> 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<String, Object> params) {
Map<String,Object> map = userVipLogService.getUserVipLogInfoTotal(params.get("date").toString());
String date = params.get("date").toString();
//有效订单
Map<String,Object> map = userVipLogService.getUserVipLogInfoTotal(date);
//本月退款金额
BigDecimal refundFee = userVipLogService.getUserVipRefundFeeTotal(date);
//本月退款的订单
List<Map<String,Object>> 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<String,Object> 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<Map<String,Object>> monthNextNRefundMap = userVipLogService.getNextNMonthRefund(date);
for (Map<String,Object> 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<Map<String, Object>> mergeIncomeWithMonthRefund(List<Map<String, Object>> income,
List<Map<String, Object>> monthRefund) {
Map<String, BigDecimal> feeMap = new LinkedHashMap<>();
for (Map<String, Object> row : income) {
String payType = normalizeCoursePayType(row.get("pay_type"));
feeMap.merge(payType, toAmount(row.get("fee")), BigDecimal::add);
}
for (Map<String, Object> row : monthRefund) {
String payType = normalizeCoursePayType(row.get("pay_type"));
feeMap.merge(payType, toAmount(row.get("fee")), BigDecimal::add);
}
List<Map<String, Object>> result = new ArrayList<>();
for (Map.Entry<String, BigDecimal> entry : feeMap.entrySet()) {
Map<String, Object> 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();
}
}

View File

@@ -1,5 +1,6 @@
package com.peanut.modules.master.controller;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@@ -38,6 +39,10 @@ public class UserCertificateController {
private CourseMedicalService courseMedicalService;
@Autowired
private CourseToMedicalService courseToMedicalService;
@Autowired
private MyUserService userService;
@Autowired
private ClassEntityService classEntityService;
//小班自考证书列表
@RequestMapping("/userClassAndZKCertificateList")
@@ -278,6 +283,60 @@ public class UserCertificateController {
}
@RequestMapping("/createCertificateNo")
public R createCertificateNo(@RequestBody Map<String,Object> params){
ClassEntity classEntity = classEntityService.getById(params.get("classId").toString());
String type = params.get("type").toString();
List<String> certificateNoList = new ArrayList<>();
int courseId = 0;
if(params.containsKey("courseId")){
courseId = Integer.parseInt(params.get("courseId").toString());
}
Map<String,Object> classCourseInfo = classEntityService.getClassCourseInfoByClassId(classEntity.getId(),courseId);
String pinyin = classCourseInfo.get("titleAbbr").toString();
String tels = params.get("tels").toString();
List<String> telList = Arrays.asList(tels.split(","));
List<MyUserEntity> userList = userService.list(new LambdaQueryWrapper<MyUserEntity>()
.in(MyUserEntity::getTel, telList));
for (int i=0;i<userList.size();i++){
MyUserEntity user = userList.get(i);
UserCertificate userCertificate = new UserCertificate();
userCertificate.setTitle(classEntity.getTitle());
userCertificate.setType(type);
userCertificate.setLabelId(5);
userCertificate.setUserId(user.getId());
userCertificate.setClassId(classEntity.getId());
String certificateNo = classEntityService.getNextCertificateNo(type,pinyin);
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);
// }
userCertificateService.save(userCertificate);
certificateNoList.add(user.getTel());
}
return R.ok().put("certificateNoList",certificateNoList);
}
}

View File

@@ -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<Integer> 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())) {//国心超级

View File

@@ -24,6 +24,12 @@ public interface UserCourseBuyService extends IService<UserCourseBuyEntity> {
List<Map<String,Object>> getIncome(String date);
List<Map<String,Object>> getRefund(String date);
List<Map<String,Object>> getSameMonthRefund(String date);
List<Map<String,Object>> getRefundInfo(String date);
List<Map<String,Object>> getUserCourseBuyInfoTotal(String date);
List<Map<String,Object>> getUserCourseBuyInfo(String date);

View File

@@ -19,8 +19,12 @@ import org.springframework.transaction.annotation.Transactional;
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
@@ -185,6 +189,21 @@ public class UserCourseBuyServiceImpl extends ServiceImpl<UserCourseBuyDao, User
return this.baseMapper.getIncome(date);
}
@Override
public List<Map<String, Object>> getRefund(String date) {
return this.baseMapper.getRefund(date);
}
@Override
public List<Map<String, Object>> getSameMonthRefund(String date) {
return this.baseMapper.getSameMonthRefund(date);
}
@Override
public List<Map<String, Object>> getRefundInfo(String date) {
return this.baseMapper.getRefundInfo(date);
}
@Override
public List<Map<String, Object>> getUserCourseBuyInfoTotal(String date) {
return this.baseMapper.getUserCourseBuyInfoTotal(date);
@@ -192,7 +211,165 @@ public class UserCourseBuyServiceImpl extends ServiceImpl<UserCourseBuyDao, User
@Override
public List<Map<String, Object>> getUserCourseBuyInfo(String date) {
return this.baseMapper.getUserCourseBuyInfo(date);
List<Map<String, Object>> list = this.baseMapper.getUserCourseBuyInfo(date);
Map<String, Map<String, Object>> refundMap = new HashMap<>();
for (Map<String, Object> refund : this.baseMapper.getRefundInfo(date)) {
refundMap.put(refundKey(refund), refund);
}
List<Map<String, Object>> result = new ArrayList<>();
Set<String> matchedKeys = new HashSet<>();
String exportMonth = date.length() >= 7 ? date.substring(0, 7) : date;
for (Map<String, Object> row : list) {
row.put("orderStatus", "已付款");
Map<String, Object> 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<String, Object> refund : refundMap.values()) {
String key = refundKey(refund);
if (matchedKeys.contains(key)) {
continue;
}
String payMonth = getPayMonth(refund);
if (exportMonth.equals(payMonth)) {
Map<String, Object> 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<String, Object> row) {
return String.valueOf(row.get("orderSn")) + "|" + String.valueOf(row.get("ctitle")) + "|" + String.valueOf(row.get("cctitle"));
}
private Map<String, Object> buildPaidRowFromRefund(Map<String, Object> refund) {
Map<String, Object> 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<String, Object> buildBaseRowFromRefund(Map<String, Object> refund) {
Map<String, Object> row = new HashMap<>(refund);
row.remove("refundTime");
row.remove("orderStatus");
fillAmortizationFields(row);
return row;
}
private void fillAmortizationFields(Map<String, Object> 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<String, Object> buildRefundRow(Map<String, Object> row, Map<String, Object> refund, String date) {
Map<String, Object> 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<String, Object> 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<String, Object> 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
@@ -221,18 +398,21 @@ public class UserCourseBuyServiceImpl extends ServiceImpl<UserCourseBuyDao, User
continue;
}
CellType cellTypeEnum = cell.getCellTypeEnum();
// if(cellTypeEnum==CellType.NUMERIC){
String phone = cell.toString();
MyUserEntity myUserEntity = userDao.selectOne(new LambdaQueryWrapper<MyUserEntity>().select(MyUserEntity::getId,MyUserEntity::getName,MyUserEntity::getTel).eq(MyUserEntity::getTel, phone));
if(myUserEntity!=null){
has.add(myUserEntity);
}else{
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("name",row.getCell(0)==null?"":row.getCell(0).toString());
stringStringHashMap.put("phone",phone);
nohas.add(stringStringHashMap);
}
// }
String phone = cell.toString().trim();
if(cellTypeEnum==CellType.NUMERIC){
BigInteger bigInteger = BigInteger.valueOf((long) cell.getNumericCellValue());
phone = bigInteger.toString();
}
MyUserEntity myUserEntity = userDao.selectOne(new LambdaQueryWrapper<MyUserEntity>().select(MyUserEntity::getId,MyUserEntity::getName,MyUserEntity::getTel).eq(MyUserEntity::getTel, phone));
if(myUserEntity!=null){
has.add(myUserEntity);
}else{
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("name",row.getCell(0)==null?"":row.getCell(0).toString());
stringStringHashMap.put("phone",phone);
nohas.add(stringStringHashMap);
}
}
stringArrayListMap.put("has",has);
stringArrayListMap.put("no",nohas);

View File

@@ -50,6 +50,7 @@ public class AliPayController {
*/
@RequestMapping("/refund")
public R refund(@RequestBody Map<String,Object> params) {
log.info("in=====refund=========");
String refund = aliPayService.refund(params);
return R.ok().put("msg",refund);
}

View File

@@ -2,8 +2,13 @@ package com.peanut.modules.pay.alipay.service;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.BuyOrderRefund;
import com.peanut.modules.common.entity.MyUserEntity;
import com.peanut.modules.pay.alipay.dto.AlipayDTO;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
@@ -30,4 +35,5 @@ public interface AliPayService {
String refund(Map<String,Object> params);
String refund(BuyOrder buyOrder, MyUserEntity user, BuyOrderRefund buyOrderRefund);
}

View File

@@ -7,8 +7,9 @@ import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.gson.JsonObject;
import com.peanut.common.utils.CopyUtils;
import com.peanut.common.utils.OrderUtils;
import com.peanut.config.Constants;
import com.peanut.modules.book.service.BookBuyConfigService;
import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.book.service.MyUserService;
@@ -25,6 +26,7 @@ import com.peanut.modules.pay.alipay.dto.ReFundDTO;
import com.peanut.modules.pay.alipay.service.AliPayService;
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
import com.qiniu.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -33,6 +35,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import jakarta.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -81,6 +84,10 @@ public class AliPayServiceImpl implements AliPayService {
private TrainingClassService trainingClassService;
@Autowired
private AiVipLogService aiVipLogService;
@Autowired
private BuyOrderRefundService buyOrderRefundService;
@Autowired
private BuyOrderRefundLogService buyOrderRefundLogService;
@Override
public String pay(AlipayDTO payDto) {
@@ -143,6 +150,7 @@ public class AliPayServiceImpl implements AliPayService {
}
log.info(">>>>>>>>>>支付宝回调 sign = {}, trade_status = {}, out_trade_no = {}, 参数 = {}", params.get("sign"),
params.get("trade_status"), params.get("out_trade_no"), params.toString());
log.info(params.get("out_trade_no"), params.toString());
//调用SDK验证签名验证是阿里回调而不是其他恶意回调
BuyOrder buyOrder = buyOrderService.getOne(new LambdaQueryWrapper<BuyOrder>()
.eq(BuyOrder::getOrderSn,params.get("out_trade_no")));
@@ -156,6 +164,31 @@ public class AliPayServiceImpl implements AliPayService {
log.info(">>>>>>>>>>验签通过");
//验签通过 获取交易状态
String tradeStatus = params.get("trade_status");
if(params.containsKey("out_biz_no") && params.containsKey("gmt_refund") && params.containsKey("refund_fee")){
PayRefundOrder refund = new PayRefundOrder();
refund.setPayType("2");
refund.setRefundId(params.get("out_biz_no").toString());
refund.setTradeNo(params.get("trade_no").toString());
refund.setOrderSn(params.get("out_trade_no").toString());
refund.setRefundFee(params.get("refund_fee").toString());
refundOrderService.save(refund);
String toJSON = JSONObject.toJSONString(params);
PayZfbOrderEntity aliNotifyDto = JSONObject.toJavaObject(JSON.parseObject(toJSON), PayZfbOrderEntity.class);
PayZfbOrderEntity payZfbOrderEntity = payZfbOrderService.getOne(new QueryWrapper<PayZfbOrderEntity>().eq("trade_no", aliNotifyDto.getTradeNo()));
payZfbOrderEntity.setOutBizNo(refund.getRefundId());
payZfbOrderEntity.setTradeStatus(tradeStatus);
payZfbOrderEntity.setRefundFee(refund.getRefundFee());
String PATTERN = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
payZfbOrderEntity.setGmtCreate(sdf.parse(params.get("gmt_create").toString()));
payZfbOrderEntity.setGmtRefund(sdf.parse(params.get("gmt_refund").toString()));
payZfbOrderEntity.setGmtClose(sdf.parse(params.get("gmt_close").toString()));
payZfbOrderService.updateById(payZfbOrderEntity);
return "success";
}
//只处理支付成功的订单: 修改交易表状态,支付成功
//只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时支付宝才会认定为买家付款成功。
if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {
@@ -323,7 +356,6 @@ public class AliPayServiceImpl implements AliPayService {
return "fail";
}
}
@Override
@Transactional
public String refund(Map<String,Object> params) {
@@ -331,6 +363,7 @@ public class AliPayServiceImpl implements AliPayService {
LambdaQueryWrapper<PayZfbOrderEntity> wrapper = new LambdaQueryWrapper();
wrapper.eq(PayZfbOrderEntity::getRelevanceoid,params.get("orderSn").toString());
PayZfbOrderEntity payZfbOrder = payZfbOrderService.getOne(wrapper);
ReFundDTO reFundDTO = new ReFundDTO();
reFundDTO.setOutTrandeNo(payZfbOrder.getOutTradeNo());
reFundDTO.setTradeNo(payZfbOrder.getTradeNo());
@@ -339,6 +372,7 @@ public class AliPayServiceImpl implements AliPayService {
reFundDTO.setRefundAmount(new BigDecimal(params.get("refundFee").toString()));
// reFundDTO.setOutRequestNo(params.get("outRequestNo").toString());
reFundDTO.setOutRequestNo(UUID.randomUUID().toString());
BuyOrder buyOrder = buyOrderService.getOne(new LambdaQueryWrapper<BuyOrder>()
.eq(BuyOrder::getOrderSn,params.get("orderSn")));
String mchName = "";
@@ -359,6 +393,7 @@ public class AliPayServiceImpl implements AliPayService {
MPJLambdaWrapper<BuyOrder> w = new MPJLambdaWrapper();
w.leftJoin(PayZfbOrderEntity.class,PayZfbOrderEntity::getRelevanceoid, BuyOrder::getOrderSn);
w.eq("trade_no",((Map)res.get("alipay_trade_refund_response")).get("trade_no"));
BuyOrder order = buyOrderService.getOne(w);
PayRefundOrder refund = new PayRefundOrder();
refund.setPayType("2");
@@ -367,11 +402,81 @@ public class AliPayServiceImpl implements AliPayService {
refund.setOutTradeNo(((Map)res.get("alipay_trade_refund_response")).get("out_trade_no").toString());
refund.setRefundFee(((Map)res.get("alipay_trade_refund_response")).get("refund_fee").toString());
refundOrderService.save(refund);
refundOrderService.businessOpt(order);
if (Constants.ORDER_STATUS_REFUND.equals(order.getOrderStatus())) {
BuyOrderRefund buyOrderRefund = buyOrderRefundService.getOne(new LambdaQueryWrapper<BuyOrderRefund>()
.eq(BuyOrderRefund::getOrderId, order.getOrderId())
.orderByDesc(BuyOrderRefund::getId)
.last("limit 1"));
if (buyOrderRefund != null) {
buyOrderRefundLogService.insertRefundLog(buyOrderRefund.getId(),3,1);
}
} else {
refundOrderService.businessOpt(order);
}
}
return resJson;
}
@Override
@Transactional
public String refund(BuyOrder buyOrder, MyUserEntity user, BuyOrderRefund buyOrderRefund){
LambdaQueryWrapper<PayZfbOrderEntity> wrapper = new LambdaQueryWrapper();
wrapper.eq(PayZfbOrderEntity::getRelevanceoid,buyOrder.getOrderSn());
PayZfbOrderEntity payZfbOrder = payZfbOrderService.getOne(wrapper);
//组装退款参数
ReFundDTO reFundDTO = new ReFundDTO();
reFundDTO.setOutTrandeNo(buyOrder.getOrderSn());
reFundDTO.setTradeNo(payZfbOrder.getTradeNo());
reFundDTO.setCustomerId(user.getId().toString());
reFundDTO.setRefundReason("用户申请退款");
reFundDTO.setRefundAmount(buyOrderRefund.getFee());
reFundDTO.setOutRequestNo(buyOrderRefund.getRefundNo());
String mchName = "";
if (("trainingClass".equals(buyOrder.getOrderType())||"lsorder".equals(buyOrder.getOrderType()))) {
mchName = "LS";
}
reFundDTO.setMchName(mchName);
log.info("========refundDto", JSON.toJSONString(reFundDTO));
//请求支付宝退款
Map<String, Object> map = aliPayUtil.aliPayRefund(reFundDTO);
buyOrderRefundLogService.insertRefundLog(buyOrderRefund.getId(),2,2);
Object obj = map.get("msg");
String resJson = obj.toString();
log.info(">>>>>>>>>>>支付宝返回的信息是 resJson = {}", resJson);
Map<String,Object> res = JSONObject.parseObject(resJson);
//10000表示接口请求成功Y表示资金变动成功
if ("10000".equals(((Map)res.get("alipay_trade_refund_response")).get("code"))&&
"Y".equals(((Map)res.get("alipay_trade_refund_response")).get("fund_change"))) {
log.info(">>>>>>>>>>>支付宝退款成功!<<<<<<<<<<<<<");
/* PayRefundOrder refund = new PayRefundOrder();
refund.setPayType("2");
// refund.setRefundId(((Map)res.get("alipay_trade_refund_response")).get("out_request_no").toString());
refund.setTradeNo(((Map)res.get("alipay_trade_refund_response")).get("trade_no").toString());
refund.setOrderSn(((Map)res.get("alipay_trade_refund_response")).get("out_trade_no").toString());
refund.setRefundFee(((Map)res.get("alipay_trade_refund_response")).get("refund_fee").toString());
refundOrderService.save(refund);*/
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("order_id",buyOrder.getOrderId()));
refundInfo.setStatus(1);
refundInfo.setWxRefundNo(refundInfo.getRefundNo());
buyOrderRefundService.updateById(refundInfo);
buyOrderService.refundOrder(buyOrder,user,refundInfo.getId());
buyOrderRefundLogService.insertRefundLog(refundInfo.getId(),2,1);
buyOrderService.updateOrderStatus(buyOrder.getUserId(),buyOrder.getOrderSn(),"6");
}
return resJson;
}
private void userCoinJf(BuyOrder order){
MyUserEntity userEntity = userService.getById(order.getUserId());
userEntity.setJf(userEntity.getJf().subtract(order.getJfDeduction()));

View File

@@ -19,7 +19,9 @@ public class PayRefundOrder implements Serializable {
@TableId
private Integer refundId;
private Integer id;
private String refundId;
/**
* 支付方式 1微信2支付宝3虚拟币
@@ -29,8 +31,9 @@ public class PayRefundOrder implements Serializable {
/**
* BuyOrder
*/
private Integer orderId;
private String orderSn;
private Integer orderId;
/**
* 微信支付宝订单号
*/

View File

@@ -126,6 +126,7 @@ public class WeChatPayController {
*/
@RequestMapping("/refund" )
public R refund(@RequestBody Map<String,Object> map){
return R.ok(wxpayService.refund(map));
}
@@ -135,10 +136,13 @@ public class WeChatPayController {
*/
@PostMapping("/refundNotify")
public void refundNotify(HttpServletRequest request){
wxpayService.refundNotify(request);
}
@PostMapping("/lsRefundNotify")
public void lsRefundNotify(HttpServletRequest request){
wxpayService.lsRefundNotify(request);
}

View File

@@ -0,0 +1,21 @@
package com.peanut.modules.pay.weChatPay.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class WeChatRefundInfo implements Serializable {
private String orderSn;
private Integer orderId;
private String orderType;
private String refundNo;
private BigDecimal totalAmount;
private BigDecimal refundAmount;
private String remark;
private String appName;
private String currency;
private String notify_url;
private int refundId;
}

View File

@@ -2,6 +2,7 @@ package com.peanut.modules.pay.weChatPay.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.modules.common.entity.PayWechatOrderEntity;
import com.peanut.modules.pay.weChatPay.dto.WeChatRefundInfo;
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
import org.springframework.stereotype.Service;
@@ -19,6 +20,8 @@ public interface WxpayService extends IService<PayWechatOrderEntity> {
String refund(Map<String,Object> map);
void refund(WeChatRefundInfo refundInfo);
void refundNotify(HttpServletRequest request);
void lsRefundNotify(HttpServletRequest request);

View File

@@ -20,11 +20,13 @@ import com.peanut.modules.master.service.UserCourseBuyService;
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
import com.peanut.modules.pay.weChatPay.dto.WeChatRefundInfo;
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
import com.peanut.modules.pay.weChatPay.service.WxpayService;
import com.peanut.modules.pay.weChatPay.util.HttpUtils;
import com.peanut.modules.pay.weChatPay.util.WechatPayValidator;
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
import com.qiniu.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -89,6 +91,12 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
private AiVipLogService aiVipLogService;
@Autowired
private UserCourseBuyLogDao userCourseBuyLogDao;
@Autowired
private BuyOrderRefundLogService buyOrderRefundLogService;
@Autowired
private MyUserService myUserService;
@Autowired
private BuyOrderRefundService buyOrderRefundService;
@Override
public void prepay(WechatPaymentInfo paymentInfo){
@@ -136,6 +144,7 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
}else {
responseJson = wxPayUtil.doPostWexinV3(wechatPayConfig.getPayUrl(), json.toJSONString(),"");
}
System.out.println(responseJson);
String prepayId = responseJson.getString("prepay_id");
if (paymentInfo.getBuyOrderId() == null) {
payWechatOrderService.add(paymentInfo.getOrderSn(), prepayId);
@@ -350,6 +359,68 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
return responseJson.toJSONString();
}
@Override
public void refund(WeChatRefundInfo refundInfo) {
Map<String, Object> paramMap = new HashMap<>();
BigDecimal refund = new BigDecimal(refundInfo.getRefundAmount().toString());
//原订单总金额
BigDecimal total = refundInfo.getTotalAmount();
// 这里 * 100微信支付单位为 ‘分’
BigDecimal hand = new BigDecimal("100");
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("refund", refund.multiply(hand).intValue());
amountMap.put("total", total.multiply(hand).intValue());
amountMap.put("currency", "CNY");
paramMap.put("amount", amountMap);
paramMap.put("out_refund_no", refundInfo.getRefundNo());
//微信支付订单号
paramMap.put("out_trade_no", refundInfo.getOrderSn());
//退款原因
paramMap.put("reason", refundInfo.getRemark());
String appid = "";
if (refundInfo.getAppName()==null||"".equals(refundInfo.getAppName())){
appid = wechatPayConfig.getAppId();
}else if ("zmzm".equals(refundInfo.getAppName())){
appid = wechatPayConfig.getZmzmappId();
} else if ("wumen".equals(refundInfo.getAppName())) {
appid = wechatPayConfig.getWumenappId();
} else if ("xlkj".equals(refundInfo.getAppName())) {
appid = wechatPayConfig.getXlkjappId();
} else if ("thyy".equals(refundInfo.getAppName())) {
appid = wechatPayConfig.getThyyappId();
}
// app id
// paramMap.put("appid", appid);
String notify_url = wechatPayConfig.getRefundNotifyUrl();
String mchName = "";
String mchid = wechatPayConfig.getMchId();
if ("trainingClass".equals(refundInfo.getOrderType())||"lsorder".equals(refundInfo.getOrderType())) {
mchName = "LS";
mchid = wechatPayConfig.getLsMchId();
notify_url = wechatPayConfig.getLsRefundNotifyUrl();
}
// paramMap.put("mchid", mchid);
paramMap.put("notify_url", notify_url);
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
log.info("=======微信退款申请请求参数:{}", json.toJSONString());
log.info(">>>>>>>>>>App请求微信退款申请接口");
JSONObject responseJson = wxPayUtil.doPostWexinV3(wechatPayConfig.getRefundUrl(), json.toJSONString(),mchName);
System.out.println(responseJson);
log.info(">>>>>>>>>>>微信退款返回的信息是 resJson = {}", responseJson.toJSONString());
buyOrderRefundLogService.insertRefundLog(refundInfo.getRefundId(),1,2);
if ("PROCESSING".equals(responseJson.get("status"))){
BuyOrderRefund buyOrderRefund = buyOrderRefundService.getById(refundInfo.getRefundId());
buyOrderRefund.setWxRefundNo(responseJson.getString("refund_id"));
buyOrderRefundService.updateById(buyOrderRefund);
}
}
private void userCoinJf(BuyOrder order){
MyUserEntity userEntity = userService.getById(order.getUserId());
userEntity.setJf(userEntity.getJf().subtract(order.getJfDeduction()));
@@ -373,6 +444,18 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
// 解密resource中的通知数据
String resource = bodyMap.get("resource").toString();
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(), 2);
/*BuyOrder orderFalse = buyOrderService.getOne(new QueryWrapper<BuyOrder>().eq("user_id",149299).orderByDesc("order_id"));
BuyOrderRefund refundFalse = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("user_id",149299).orderByDesc("id"));
Map<String, Object> resourceMap = new HashMap<>();
resourceMap.put("refund_status","SUCCESS");
resourceMap.put("out_trade_no",orderFalse.getOrderSn());
resourceMap.put("refund_id",System.currentTimeMillis());
resourceMap.put("out_refund_no",refundFalse.getRefundNo());
Map<String,BigDecimal> amount = new HashMap<>();
amount.put("refund",orderFalse.getRealMoney());
resourceMap.put("amount",amount);*/
log.info("微信退款回调结果 msg={}",resourceMap);
if ("SUCCESS".equals(resourceMap.get("refund_status").toString())){
log.info(">>>>>>>>>>>微信退款成功!<<<<<<<<<<<<<");
@@ -381,14 +464,41 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
w.leftJoin(PayWechatOrderEntity.class,PayWechatOrderEntity::getOrderSn, BuyOrder::getOrderSn);
w.eq("t1.order_id",resourceMap.get("transaction_id").toString());
BuyOrder order = buyOrderService.getOne(w);
PayRefundOrder refund = new PayRefundOrder();
refund.setPayType("1");
refund.setOrderId(order.getOrderId());
refund.setRefundId(resourceMap.get("refund_id").toString());
refund.setTradeNo(resourceMap.get("transaction_id").toString());
refund.setOutTradeNo(resourceMap.get("out_trade_no").toString());
refund.setOrderSn(resourceMap.get("out_trade_no").toString());
String refundFeeStr = ((Map)resourceMap.get("amount")).get("refund").toString();
BigDecimal refundFee = new BigDecimal(refundFeeStr).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
refund.setRefundFee(((Map)resourceMap.get("amount")).get("refund").toString());
refundOrderService.save(refund);
refundOrderService.businessOpt(order);
MyUserEntity user = myUserService.getById(order.getUserId());
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("order_id",order.getOrderId()));
refundInfo.setStatus(1);
refundInfo.setWxRefundNo( resourceMap.get("refund_id").toString());
buyOrderRefundService.updateById(refundInfo);
buyOrderService.refundOrder(order,user,refundInfo.getId());
buyOrderRefundLogService.insertRefundLog(refundInfo.getId(),1,1);
buyOrderService.updateOrderStatus(order.getUserId(),order.getOrderSn(),"6");
// refundOrderService.businessOpt(order);
}else{
if(resourceMap.containsKey("out_refund_no")){
String refundNo = resourceMap.get("out_refund_no").toString();
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("refund_no",refundNo));
refundInfo.setStatus(2);
refundInfo.setWxRefundNo( resourceMap.get("refund_id").toString());
buyOrderRefundService.updateById(refundInfo);
// buyOrderRefundLogService.insertRefundLog(refundInfo.getId(),1,3,resourceMap.get("reason").toString());
}
}
}
@Override
@@ -408,14 +518,40 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
w.leftJoin(PayWechatOrderEntity.class,PayWechatOrderEntity::getOrderSn, BuyOrder::getOrderSn);
w.eq("t1.order_id",resourceMap.get("transaction_id").toString());
BuyOrder order = buyOrderService.getOne(w);
PayRefundOrder refund = new PayRefundOrder();
refund.setPayType("1");
refund.setOrderId(order.getOrderId());
refund.setRefundId(resourceMap.get("refund_id").toString());
refund.setTradeNo(resourceMap.get("transaction_id").toString());
refund.setOutTradeNo(resourceMap.get("out_trade_no").toString());
refund.setOrderSn(resourceMap.get("out_trade_no").toString());
refund.setRefundFee(((Map)resourceMap.get("amount")).get("refund").toString());
refundOrderService.save(refund);
refundOrderService.businessOpt(order);
//refundOrderService.businessOpt(order);
MyUserEntity user = myUserService.getById(order.getUserId());
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("order_id",order.getOrderId()));
refundInfo.setStatus(1);
refundInfo.setWxRefundNo( resourceMap.get("refund_id").toString());
buyOrderRefundService.updateById(refundInfo);
buyOrderService.refundOrder(order,user,refundInfo.getId());
buyOrderRefundLogService.insertRefundLog(refundInfo.getId(),1,1);
buyOrderService.updateOrderStatus(order.getUserId(),order.getOrderSn(),"6");
}else{
if(resourceMap.containsKey("out_refund_no")){
String refundNo = resourceMap.get("out_refund_no").toString();
BuyOrderRefund refundInfo = buyOrderRefundService.getOne(new QueryWrapper<BuyOrderRefund>().eq("refund_no",refundNo));
refundInfo.setStatus(2);
refundInfo.setWxRefundNo( resourceMap.get("refund_id").toString());
buyOrderRefundService.updateById(refundInfo);
// buyOrderRefundLogService.insertRefundLog(refundInfo.getId(),1,3,resourceMap.get("reason").toString());
}
}
}

View File

@@ -1,6 +1,7 @@
package com.peanut.modules.sociology.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@@ -10,9 +11,12 @@ import com.peanut.common.utils.ShiroUtils;
import com.peanut.modules.book.service.ShopProductService;
import com.peanut.modules.common.dao.*;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.CourseMedicineService;
import com.peanut.modules.common.service.CourseToMedicineService;
import com.peanut.modules.common.service.MyUserService;
import com.peanut.modules.common.service.UserVipService;
import com.peanut.modules.common.to.ParamTo;
import com.peanut.modules.master.service.CourseMedicalService;
import com.peanut.modules.sociology.service.CourseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@@ -52,6 +56,10 @@ public class CourseServiceImpl extends ServiceImpl<CourseDao, CourseEntity> impl
private UserVipDao userVipDao;
@Autowired
private UserCourseBuyLogDao userCourseBuyLogDao;
@Autowired
private CourseToMedicineService courseToMedicineService;
@Autowired
private CourseMedicineService courseMedicineService;
//根据标签获取课程列表
@@ -117,7 +125,14 @@ public class CourseServiceImpl extends ServiceImpl<CourseDao, CourseEntity> impl
Page<CourseEntity> courseEntityPage = this.getBaseMapper().selectJoinPage(new Page<>(param.getPage(), param.getLimit()), CourseEntity.class, wrapper);
return courseEntityPage;
}
public CourseMedicine getCourseMedicinePid(int medicineId){
CourseMedicine courseMedicine = courseMedicineService.getById(medicineId);
if(courseMedicine.getPid()==0){
return courseMedicine;
}else{
return getCourseMedicinePid(courseMedicine.getPid());
}
}
@Override
public Map<String, Object> getCourseDetail(Integer id) {
Map<String, Object> flag = new HashMap<>();
@@ -163,6 +178,26 @@ public class CourseServiceImpl extends ServiceImpl<CourseDao, CourseEntity> impl
}
}
}
QueryWrapper<CourseToMedicine> courseToMedicineWrapper = new QueryWrapper<CourseToMedicine>();
courseToMedicineWrapper.eq("course_id",course.getId());
List<CourseToMedicine> courseToMedicineList = courseToMedicineService.list(courseToMedicineWrapper);
String content = course.getContent();
List<Integer> medicinePids = new ArrayList<>();
for (CourseToMedicine courseToMedicine:courseToMedicineList){
CourseMedicine courseMedicine = getCourseMedicinePid(courseToMedicine.getMedicalId());
if(medicinePids.contains(courseMedicine.getId())){
continue;
}
if(courseMedicine!=null && courseMedicine.getId()==1){
content = content+"<img src=\"https://ehh-public-01.oss-cn-beijing.aliyuncs.com/image/zhong-yi-xue-ke-cheng-biao.jpg\"/>";
}else if(courseMedicine!=null && courseMedicine.getId()==74){
content = content+"<img src=\"https://ehh-public-01.oss-cn-beijing.aliyuncs.com/image/hui-tong-ke-cheng-biao.jpg\"/>";
}
if(courseMedicine!=null){
medicinePids.add(courseMedicine.getId());
}
}
course.setContent(content);
flag.put("course",course);
//课程关联商品
if (StringUtils.isNotEmpty(course.getRelationProductIds())){

View File

@@ -98,7 +98,7 @@ wxpay:
mchId: 1612860909
serialNo: 679AECB2F7AC4183033F713828892BA640E4EEE3
apiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
wechatPayCertificateUrl: F:\hs\nuttyreading-java\src\main\resources\cent\wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem
wechatPayCertificateUrl: F:\hs\nuttyreading-server\src\main\resources\cent\wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem
privateKeyUrl: F:\hs\nuttyreading-java\src\main\resources\cent\apiclient_key.pem
keyPemPath: F:\hs\nuttyreading-java\src\main\resources\cent\apiclient_key.pem
notifyUrl: http://z6f8f828.natappfree.cc/pb/pay/payNotify
@@ -107,9 +107,9 @@ wxpay:
lsMchId: 1700371158
lsSerialNo: 3132D23C3130B74B87890DC6E7C80256C75113B9
lsApiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
lsWechatPayCertificateUrl: F:\hs\nuttyreading-java\src\main\resources\cent\lscent\wechatpay_30CFE19A12EDB4D9E0C7DF01DBF457C657566D04.pem
lsPrivateKeyUrl: F:\hs\nuttyreading-java\src\main\resources\cent\lscent\apiclient_key.pem
lsKeyPemPath: F:\hs\nuttyreading-java\src\main\resources\cent\lscent\apiclient_key.pem
lsWechatPayCertificateUrl: F:\hs\nuttyreading-server\src\main\resources\cent\lscent\wechatpay_30CFE19A12EDB4D9E0C7DF01DBF457C657566D04.pem
lsPrivateKeyUrl: F:\hs\nuttyreading-server\src\main\resources\cent\lscent\apiclient_key.pem
lsKeyPemPath: F:\hs\nuttyreading-server\src\main\resources\cent\lscent\apiclient_key.pem
lsNotifyUrl: http://z6f8f828.natappfree.cc/pb/pay/lsPayNotify
lsRefundNotifyUrl: https://testapi.nuttyreading.com/pay/refundNotify

View File

@@ -210,8 +210,9 @@
<!-- &lt;!&ndash; 4.2 生产环境:输出到文档&ndash;&gt;-->
<springProfile name="test,prod">
<logger name="com.peanut" level="ERROR" additivity="false">
<logger name="com.peanut" level="INFO" additivity="false">
<!-- <appender-ref ref="DEBUG_FILE"/>-->
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</logger>
<root level="info">

View File

@@ -65,8 +65,9 @@
left join user u on u.id = bo.user_id
left join buy_order_product bop on bop.order_id = bo.order_id
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)
and bo.order_status in (1,2,3,4) and sp.goods_type != '05' and bo.real_money > 0
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,6) and sp.goods_type != '05' and bo.real_money > 0
<if test="orderType != null and orderType!= ''">
<if test="orderType == 'lsorder' ">
and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >= 37867))
@@ -89,7 +90,47 @@
) s
group by payType
</select>
<select id="getRefund" resultType="map">
select payType,count(1) count,SUM(price) totalPrice from (
select q.*,pzo.trade_no zfbOrder
from (
select t.createTime,t.name,t.tel,t.orderSn,t.orderStatus,t.payType,t.refundFee,
t.refundFee-(select IF(SUM(if(sp2.activity_price&lt;sp2.price,sp2.activity_price,sp2.price)) is NULL,0,SUM(if(sp2.activity_price&lt;sp2.price,sp2.activity_price,sp2.price))) from shop_product sp2 where sp2.goods_type = '05' and sp2.product_id in (GROUP_CONCAT(sp.product_id SEPARATOR ','))) price,
GROUP_CONCAT(sp.product_name SEPARATOR ', ') productName,t.remark
from (
select bo.order_id,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') createTime,u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,bo.order_sn orderSn,
IF(bo.payment_method=1,'微信',IF(bo.payment_method=2,'支付宝',IF(bo.payment_method=4,'天医币','0'))) payType,
'已退款' orderStatus,bor.fee refundFee,if(bo.remark like '%退%',bo.remark,'') remark
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
left join user u on u.id = bo.user_id
left join buy_order_product bop on bop.order_id = bo.order_id
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 = '6' and sp.goods_type != '05' and bo.real_money > 0
<if test="orderType != null and orderType!= ''">
<if test="orderType == 'lsorder' ">
and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >= 37867))
and bo.order_type = 'lsorder'
</if>
<if test="orderType == 'order' ">
and (bo.order_type = 'order'
or (bo.order_type = 'lsorder' and bo.payment_method = '4')
or (bo.order_type = 'lsorder' and bo.payment_method = '2' and bo.order_id &lt; 37867))
</if>
</if>
and DATE_FORMAT(bor.create_time,'%Y-%m') = SUBSTR(#{date},1,7)
group by bo.order_sn
) t
left join buy_order_product bop on bop.order_id = t.order_id
left join shop_product sp on sp.product_id = bop.product_id
group by t.orderSn
) q
left join pay_zfb_order pzo on pzo.relevanceOid = q.orderSn and pzo.trade_no is not null
) s
group by payType
</select>
<select id="exportPhysicalBuyOrderInfo" resultType="map">
select q.*,pzo.trade_no zfbOrder
from (
@@ -99,16 +140,17 @@
from (
select bo.order_id,DATE_FORMAT(bo.create_time,'%Y-%m-%d %H:%i:%s') createTime,u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,bo.order_sn orderSn,
IF(bo.payment_method=1,'微信',IF(bo.payment_method=2,'支付宝',IF(bo.payment_method=4,'天医币','0'))) payType,
IF(bo.order_status = 4,'已删除',IF(bo.order_status = 3,'已完成',IF(bo.order_status = 2,'已发货','已付款'))) orderStatus,bo.real_money orderPrice,if(bo.remark like '%退%',bo.remark,'') remark
IF(bo.order_status = 4,'已删除',IF(bo.order_status = 3,'已完成',IF(bo.order_status = 2,'已发货',IF(bo.order_status = 6,'已退款','已付款')))) orderStatus,bo.real_money orderPrice,if(bo.remark like '%退%',bo.remark,'') remark
from buy_order bo
left join user u on u.id = bo.user_id
left join buy_order_product bop on bop.order_id = bo.order_id
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)
and bo.order_status in (1,2,3,4) and sp.goods_type != '05' and bo.real_money > 0
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,6) and sp.goods_type != '05' and bo.real_money > 0
<if test="orderType != null and orderType!= ''">
<if test="orderType == 'lsorder' ">
and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >37867))
and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >= 37867))
and bo.order_type = 'lsorder'
</if>
<if test="orderType == 'order' ">
@@ -126,6 +168,44 @@
) q
left join pay_zfb_order pzo on pzo.relevanceOid = q.orderSn and pzo.trade_no is not null
</select>
<select id="exportPhysicalBuyOrderRefundInfo" resultType="map">
select q.*,pzo.trade_no zfbOrder
from (
select t.createTime,t.name,t.tel,t.orderSn,t.orderStatus,t.payType,t.orderPrice,
t.orderPrice-(select IF(SUM(if(sp2.activity_price&lt;sp2.price,sp2.activity_price,sp2.price)) is NULL,0,SUM(if(sp2.activity_price&lt;sp2.price,sp2.activity_price,sp2.price))) from shop_product sp2 where sp2.goods_type = '05' and sp2.product_id in (GROUP_CONCAT(sp.product_id SEPARATOR ','))) price,
GROUP_CONCAT(sp.product_name SEPARATOR ', ') productName,IF(count(1)=1,bop.quantity,'') quantity,t.remark,t.refund_no
from (
select bo.order_id,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') createTime,u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,bo.order_sn orderSn,
IF(bo.payment_method=1,'微信',IF(bo.payment_method=2,'支付宝',IF(bo.payment_method=4,'天医币','0'))) payType,
'已退款' orderStatus,bor.fee orderPrice,if(bo.remark like '%退%',bo.remark,'') remark,IFNULL(bor.wx_refund_no,bor.refund_no) as refund_no
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
left join user u on u.id = bo.user_id
left join buy_order_product bop on bop.order_id = bo.order_id
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 = '6' and sp.goods_type != '05' and bo.real_money > 0
<if test="orderType != null and orderType!= ''">
<if test="orderType == 'lsorder' ">
and (bo.payment_method = '1' or (bo.payment_method = '2' and bo.order_id >= 37867))
and bo.order_type = 'lsorder'
</if>
<if test="orderType == 'order' ">
and (bo.order_type = 'order'
or (bo.order_type = 'lsorder' and bo.payment_method = '4')
or (bo.order_type = 'lsorder' and bo.payment_method = '2' and bo.order_id &lt; 37867))
</if>
</if>
and DATE_FORMAT(bor.create_time,'%Y-%m') = SUBSTR(#{date},1,7)
group by bo.order_sn
) t
left join buy_order_product bop on bop.order_id = t.order_id
left join shop_product sp on sp.product_id = bop.product_id
group by t.orderSn
) q
left join pay_zfb_order pzo on pzo.relevanceOid = q.orderSn and pzo.trade_no is not null
</select>
<select id="queryListByOrderIds" resultType="com.peanut.modules.common.entity.BuyOrder">

View File

@@ -39,7 +39,43 @@
from transaction_details td
left join user u on u.id = td.user_id
where DATE_FORMAT(td.create_time,'%Y-%m') = SUBSTR(#{date},1,7)
and td.user_id not in (select id from user where tester_flag = 1)
and td.user_id not in (select id from user where tester_flag = 1) and u.del_flag=0
) t
left join buy_order bo on bo.order_sn = t.payNo
left join buy_order_product bop on bop.order_id = bo.order_id
left join shop_product sp on sp.product_id = bop.product_id
left join vip_buy_config vbc on vbc.id = bo.vip_buy_config_id
group by t.id
order by t.createTime
) q
left join pay_zfb_order pzo on pzo.relevanceOid = q.payNo and pzo.trade_no is not null
) s
group by type,payMethod,goodsType
</select>
<select id="getRefundTransactionDetails" resultType="map">
select type,payMethod,goodsType,SUM(changeAmount) amount
from (
select q.*,pzo.trade_no zfbOrder
from (
select t.*,
IF(bo.order_type='relearn','课程',
IF(bo.order_type='trainingClass','培训班',
IF(bo.order_type='vip','VIP',
IF((GROUP_CONCAT(sp.goods_type SEPARATOR ',') like '%,05%') or (GROUP_CONCAT(sp.goods_type SEPARATOR ',') like '05,%') or (GROUP_CONCAT(sp.goods_type SEPARATOR ',')='05'),
IF((GROUP_CONCAT(sp.goods_type SEPARATOR ',') like '%,05%') or (GROUP_CONCAT(sp.goods_type SEPARATOR ',') like '05,%'),'实物、课程','课程'),
'实物')))) goodsType,
IF(IF(GROUP_CONCAT(sp.product_name SEPARATOR ',') is NULL,IF(bo.order_type='vip',vbc.title,bo.remark),GROUP_CONCAT(sp.product_name SEPARATOR ',')) is NULL,'',IF(GROUP_CONCAT(sp.product_name SEPARATOR ',') is NULL,IF(bo.order_type='vip',vbc.title,bo.remark),GROUP_CONCAT(sp.product_name SEPARATOR ','))) productName
from (
select bor.id,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') createTime,u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel
,'订单退款' type,'天医币' payMethod,bo.order_sn payNo
,bor.fee changeAmount,IF(bor.remark is NULL,'',bor.remark) note
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
left join user u on u.id = bor.user_id
where DATE_FORMAT(bor.create_time,'%Y-%m') = SUBSTR(#{date},1,7)
and bo.order_status = '6'
and bo.payment_method = '4'
and bor.user_id not in (select id from user where tester_flag = 1)
) t
left join buy_order bo on bo.order_sn = t.payNo
left join buy_order_product bop on bop.order_id = bo.order_id

View File

@@ -35,19 +35,88 @@
left join course_catalogue cc on cc.id = ucb.catalogue_id
left join pay_zfb_order pzo on pzo.relevanceOid = ucbl.order_sn and pzo.trade_no is not null
where ucbl.del_flag = 0 and ucbl.fee > 0 and DATE_FORMAT(ucbl.pay_time,'%Y-%m-%d') &lt;= #{date}
and u.id not in (select id from user where tester_flag = 1)
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 ( ucbl.pay_type in ('微信','支付宝') and ucbl.create_time>='2026-05-06 00:00:00'))))
order by ucb.id
) t) s) q) w) e) r
</select>
<select id="getIncome" resultType="map">
select ucbl.pay_type,SUM(ucbl.fee) fee
from user_course_buy_log ucbl
left join buy_order bo on bo.order_sn = ucbl.order_sn
where DATE_FORMAT(ucbl.pay_time,'%Y-%m') = SUBSTR(#{date},1,7) and ucbl.del_flag = 0
and (ucbl.user_id not in (select id from user where tester_flag = 1) or ( ucbl.user_id in (select id from user where tester_flag = 1) and ucbl.pay_type in ('微信','支付宝') and ucbl.create_time>='2026-05-06 00:00:00'))
GROUP BY ucbl.pay_type
</select>
<select id="getRefund" resultType="map">
select pay_type,SUM(fee) fee
from user_course_buy_log
where DATE_FORMAT(pay_time,'%Y-%m') = SUBSTR(#{date},1,7) and del_flag = 0
and user_id not in (select id from user where tester_flag = 1)
from (
select IF(bo.payment_method='1','App微信',IF(bo.payment_method='2','App支付宝',IF(bo.payment_method='4','App天医币','其他'))) pay_type,
bor.fee
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
where bo.order_status = '6'
and DATE_FORMAT(bor.create_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 (
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
</select>
<select id="getSameMonthRefund" resultType="map">
select pay_type,SUM(fee) fee
from (
select IF(bo.payment_method='1','微信',IF(bo.payment_method='2','支付宝',IF(bo.payment_method='4','天医币','其他'))) pay_type,
bor.fee
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
where bo.order_status = '6'
and DATE_FORMAT(bor.create_time,'%Y-%m') = SUBSTR(#{date},1,7)
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 (
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
</select>
<select id="getRefundInfo" resultType="map">
select IFNULL(bor.wx_refund_no,bor.refund_no) as refund_no,u.name,if(u.tel is null,if(u.email is null,'',u.email),u.tel) tel,
IFNULL(c.title,IFNULL(sp.product_name,'')) ctitle,IFNULL(cc.title,'') cctitle,
IFNULL(spc.days,0) totalDays,'' startTime,'' endTime,
IF(bo.order_type='relearn','复读','order') type,
IF(bo.payment_method='1','微信',IF(bo.payment_method='2','支付宝',IF(bo.payment_method='4','天医币','其他'))) payType,
DATE_FORMAT(IF(bo.success_time is null,bo.create_time,bo.success_time),'%Y-%m-%d %H:%i:%s') payTime,
bo.order_sn orderSn,pzo.trade_no zfbOrder,
0 beginDay,IFNULL(spc.days,0) days,
ROUND(bor.fee/(select count(1) from buy_order_product bop2
inner join shop_product sp2 on sp2.product_id = bop2.product_id
where bop2.order_id = bo.order_id and sp2.goods_type = '05'),2) fee,
if(bo.remark like '%退%',bo.remark,if(bor.remark is null,'',bor.remark)) remark,
DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
'已退款' orderStatus
from buy_order_refund bor
inner join buy_order bo on bo.order_id = bor.order_id and bo.del_flag = 0
inner join buy_order_product bop on bop.order_id = bo.order_id
inner join shop_product sp on sp.product_id = bop.product_id and sp.goods_type = '05'
left join shop_product_course spc on spc.product_id = sp.product_id and spc.del_flag = 0
left join course c on c.id = spc.course_id
left join course_catalogue cc on cc.id = spc.catalogue_id
left join user u on u.id = bo.user_id
left join pay_zfb_order pzo on pzo.relevanceOid = bo.order_sn and pzo.trade_no is not null
where bo.order_status = '6'
and DATE_FORMAT(bor.create_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'))
order by bor.create_time asc
</select>
<select id="getUserCourseBuyInfoTotal" resultType="map">
select if(ROUND(SUM(fee),2) is null,0,ROUND(SUM(fee),2)) fee,
if(ROUND(SUM(alreadyTanxiao),2) is null,0,ROUND(SUM(alreadyTanxiao),2)) alreadyTanxiao,

View File

@@ -9,18 +9,239 @@
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 uvl.id uvlId,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') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from user_vip_log uvl
from user_vip_log uvl LEFT JOIN buy_order a ON a.order_sn=uvl.order_sn
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
where u.del_flag = 0 and (uvl.del_flag = 0 or (uvl.del_flag = -1 and a.order_status=6))
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') &lt;= SUBSTR(#{date},1,7)
and u.id not in (select id from user where tester_flag = 1)
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
</select>
<select id="getLastMonthRefundFee" resultType="java.math.BigDecimal">
select IFNULL(SUM(t.refundFee),0) fee
from (
select a.order_id,MAX(bor.fee) refundFee
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
left join user_vip uv on uv.id = uvl.user_vip_id
left join user u on u.id = uvl.user_id
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.del_flag = 0
and DATE_FORMAT(bor.create_time, '%Y-%m') = SUBSTR(#{date},1,7)
and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') &lt; 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')))
group by a.order_id
) t
</select>
<select id="getNextNMonthRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.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 DATE_FORMAT(bor.create_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
</select>
<select id="getCurrMonthOtherRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.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 DATE_FORMAT(bor.create_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
</select>
<select id="getLastMonthRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.del_flag = 0
and DATE_FORMAT(bor.create_time, '%Y-%m') = SUBSTR(#{date},1,7)
and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') =
DATE_FORMAT(DATE_SUB(CONCAT(SUBSTR(#{date},1,7),'-01'), INTERVAL 1 MONTH), '%Y-%m')
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
</select>
<select id="getCurrMonthOtherRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.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 DATE_FORMAT(bor.create_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
</select>
<select id="getLastLMonthRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.del_flag = 0
and DATE_FORMAT(bor.create_time, '%Y-%m') = SUBSTR(#{date},1,7)
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
</select>
<select id="getMonthRefund" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select IFNULL(bor.wx_refund_no ,bor.refund_no) as refund_no,uvl.id uvlId,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,a.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,
bor.fee refundFee,DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
IF(DATE_FORMAT(uvl.end_time, '%Y-%m') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
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 = a.order_sn and pzo.trade_no is not null
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and u.del_flag = 0
and DATE_FORMAT(bor.create_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
</select>
<select id="getAllUserVipLogInfo" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (
select uvl.id uvlId,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,a.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') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a
inner join user_vip_log uvl on a.order_sn = uvl.order_sn and (uvl.del_flag = 0 or a.order_status = '6')
left join user_vip uv on uv.id = uvl.user_vip_id and (uv.del_flag = 0 or a.order_status = '6')
left join user u on u.id = uvl.user_id and u.del_flag = 0
left join pay_zfb_order pzo on pzo.relevanceOid = a.order_sn and pzo.trade_no is not null
where a.order_type = 'vip' and a.order_status in (1,2,3,4,6)
and a.del_flag = 0
and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') &lt;= 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
</select>
@@ -34,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') &lt; 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') &lt; 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') &lt; 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,
@@ -49,5 +270,69 @@
) s
</select>
<select id="getUserVipRefundLogInfo" resultType="map">
select uvl.id uvlId, a.order_sn orderSn, bor.fee refundFee, DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime
from buy_order a
inner join buy_order_refund bor on bor.order_id = a.order_id
inner join user_vip_log uvl on a.order_sn = uvl.order_sn
left join user_vip uv on uv.id = uvl.user_vip_id
left join user u on u.id = uvl.user_id
where a.order_status = '6'
and a.order_type = 'vip'
and a.del_flag = 0
and DATE_FORMAT(bor.create_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')))
</select>
<select id="getUserVipSameMonthRefundFeeTotal" resultType="java.math.BigDecimal">
select IFNULL(SUM(uvl.fee),0)
from user_vip_log uvl
left join user_vip uv on uv.id = uvl.user_vip_id
left join user u on u.id = uvl.user_id
left join buy_order a on a.order_sn = uvl.order_sn
left join buy_order_refund c on c.order_id = a.order_id
where u.del_flag = 0
and a.del_flag = 0
and a.order_status = '6'
and a.order_type = 'vip'
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')))
</select>
<select id="getUserVipRefundFeeTotal" resultType="java.math.BigDecimal">
select IFNULL(SUM(c.fee),0)
from user_vip_log uvl
left join user_vip uv on uv.id = uvl.user_vip_id
left join user u on u.id = uvl.user_id
left join buy_order a on a.order_sn = uvl.order_sn
left join buy_order_refund c on c.order_id = a.order_id
where u.del_flag = 0
and a.del_flag = 0
and a.order_status = '6'
and a.order_type = 'vip'
and DATE_FORMAT(IF(uvl.pay_time is NULL,uvl.start_time,uvl.pay_time), '%Y-%m') &lt;= SUBSTR(#{date},1,7)
and DATE_FORMAT(c.create_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')))
</select>
<select id="getUserVipRefundInfo" resultType="map">
select t.*,
IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays) alreadyTanxiao,
dayAmount*currentDays currentTanxiao,
fee-IF(totalDays=alreadyDays,fee,dayAmount*alreadyDays)-(dayAmount*currentDays) notyetTanxiao
from (select uvl.*,c.create_time refund_time,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') &lt; 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') &lt; 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') &lt; 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') &lt;= SUBSTR(#{date},1,7),0,DATEDIFF(uvl.end_time,#{date})))) notyetDays
from buy_order a left join user_vip_log uvl on a.order_sn = uvl.order_sn
left join user_vip vp on uvl.user_vip_id = vp.id
left join buy_order_refund c on c.order_id=a.order_id left join user u on a.user_id=u.id
left join pay_zfb_order pzo on pzo.relevanceOid = a.order_sn and pzo.trade_no is not null
where a.order_status='6' and
DATE_FORMAT(a.create_time, '%Y-%m') = SUBSTR(#{last_l_date},1,7) and DATE_FORMAT(c.create_time, '%Y-%m') = SUBSTR(#{last_date},1,7) and a.order_type='vip' and a.del_flag=0 and uvl.del_flag=0 and c.del_flag=0
) t order by currentDays desc
) s
</select>
</mapper>