Compare commits

...

5 Commits

Author SHA1 Message Date
wyn
a8507deb2e 批量发货、课程报表、秒杀排序 2026-07-02 15:48:35 +08:00
wyn
76f96ae804 批量发货、课程报表、秒杀排序 2026-07-02 15:46:41 +08:00
wyn
dbcf3151bd 批量发货 2026-07-01 09:52:54 +08:00
wyn
7bddd3d012 只有指定vip才现金优惠券转积分 2026-06-23 17:06:07 +08:00
wyn
eef9e7ff69 送优惠券时,只有指定vip才可以送 2026-06-23 15:41:07 +08:00
13 changed files with 435 additions and 40 deletions

View File

@@ -1222,6 +1222,26 @@ public class BuyOrderController {
return buyOrderService.delivery(expressCompanyCode, buyOrderProductId); return buyOrderService.delivery(expressCompanyCode, buyOrderProductId);
} }
/**
* 批量订单发货仅支持单商品且数量为1的订单快递公司固定顺丰 SF
* 异步执行,立即返回 taskId通过 getBatchDeliveryProgress 查询进度
*
* @param orderIds 订单 ID 列表
* @return R包含 taskId存在不符合条件的订单时 msg 为逗号拼接的订单号
*/
@RequestMapping(value = "/batchDelivery", method = RequestMethod.POST)
public R batchDelivery(@RequestBody List<Integer> orderIds) throws Exception {
return buyOrderService.batchDelivery("SF", orderIds);
}
/**
* 查询批量发货任务进度
*/
@RequestMapping(value = "/getBatchDeliveryProgress", method = RequestMethod.GET)
public R getBatchDeliveryProgress(@RequestParam("taskId") Integer taskId) {
return buyOrderService.getBatchDeliveryProgress(taskId);
}
@RequestMapping("/mytest") @RequestMapping("/mytest")
public R mytest() throws IOException { public R mytest() throws IOException {
String mytest = buyOrderService.mytest(); String mytest = buyOrderService.mytest();

View File

@@ -55,6 +55,19 @@ public interface BuyOrderService extends IService<BuyOrder> {
*/ */
R delivery(String expressCompanyCode, List<Integer> buyOrderDetailId); R delivery(String expressCompanyCode, List<Integer> buyOrderDetailId);
/**
* 批量订单发货仅支持单商品且数量为1的订单
*
* @param expressCompanyCode 快递公司代码
* @param orderIds 订单 ID 列表
*/
R batchDelivery(String expressCompanyCode, List<Integer> orderIds);
/**
* 查询批量发货任务进度
*/
R getBatchDeliveryProgress(Integer taskId);
Page<BuyOrder> orderList(BuyOrderListRequestVo requestVo, Boolean isHT); Page<BuyOrder> orderList(BuyOrderListRequestVo requestVo, Boolean isHT);
Page<BuyOrder> getUserOrderList(UserOrderDto userOrderDto); Page<BuyOrder> getUserOrderList(UserOrderDto userOrderDto);

View File

@@ -0,0 +1,118 @@
package com.peanut.modules.book.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.peanut.common.utils.R;
import com.peanut.modules.book.service.BuyOrderBatchDeliveryAsyncService;
import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.common.dao.BuyOrderBatchDeliveryItemDao;
import com.peanut.modules.common.dao.BuyOrderBatchDeliveryTaskDao;
import com.peanut.modules.common.entity.BuyOrderBatchDeliveryItem;
import com.peanut.modules.common.entity.BuyOrderBatchDeliveryTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class BuyOrderBatchDeliveryAsyncServiceImpl implements BuyOrderBatchDeliveryAsyncService {
@Autowired
private BuyOrderBatchDeliveryTaskDao batchDeliveryTaskDao;
@Autowired
private BuyOrderBatchDeliveryItemDao batchDeliveryItemDao;
@Lazy
@Autowired
private BuyOrderService buyOrderService;
@Async
@Override
public void executeBatchDelivery(Integer taskId) {
BuyOrderBatchDeliveryTask task = batchDeliveryTaskDao.selectById(taskId);
if (task == null) {
return;
}
Date now = new Date();
task.setStatus(BuyOrderBatchDeliveryTask.STATUS_RUNNING);
task.setUpdateTime(now);
batchDeliveryTaskDao.updateById(task);
List<BuyOrderBatchDeliveryItem> items = batchDeliveryItemDao.selectList(
new LambdaQueryWrapper<BuyOrderBatchDeliveryItem>()
.eq(BuyOrderBatchDeliveryItem::getTaskId, taskId)
.orderByAsc(BuyOrderBatchDeliveryItem::getId));
int successCount = 0;
int failCount = 0;
try {
for (BuyOrderBatchDeliveryItem item : items) {
if (item.getStatus() != BuyOrderBatchDeliveryItem.STATUS_PENDING) {
continue;
}
try {
R result = buyOrderService.delivery(
task.getExpressCompanyCode(),
Collections.singletonList(item.getBuyOrderProductId()));
Date itemTime = new Date();
if (Integer.valueOf(0).equals(result.get("code"))) {
item.setStatus(BuyOrderBatchDeliveryItem.STATUS_SUCCESS);
successCount++;
} else {
item.setStatus(BuyOrderBatchDeliveryItem.STATUS_FAILED);
item.setFailMessage(String.valueOf(result.get("msg")));
failCount++;
}
item.setUpdateTime(itemTime);
batchDeliveryItemDao.updateById(item);
} catch (Exception e) {
log.error("批量发货单条失败 taskId={} orderId={}", taskId, item.getOrderId(), e);
item.setStatus(BuyOrderBatchDeliveryItem.STATUS_FAILED);
item.setFailMessage(e.getMessage());
item.setUpdateTime(new Date());
batchDeliveryItemDao.updateById(item);
failCount++;
}
updateTaskProgress(taskId, successCount, failCount);
}
finishTask(taskId, successCount, failCount, null);
} catch (Exception e) {
log.error("批量发货任务异常 taskId={}", taskId, e);
finishTask(taskId, successCount, failCount, e.getMessage());
}
}
private void updateTaskProgress(Integer taskId, int successCount, int failCount) {
BuyOrderBatchDeliveryTask task = batchDeliveryTaskDao.selectById(taskId);
if (task == null) {
return;
}
task.setSuccessCount(successCount);
task.setFailCount(failCount);
task.setUpdateTime(new Date());
batchDeliveryTaskDao.updateById(task);
}
private void finishTask(Integer taskId, int successCount, int failCount, String failMessage) {
BuyOrderBatchDeliveryTask task = batchDeliveryTaskDao.selectById(taskId);
if (task == null) {
return;
}
Date now = new Date();
task.setSuccessCount(successCount);
task.setFailCount(failCount);
task.setUpdateTime(now);
task.setFinishTime(now);
if (failMessage != null) {
task.setStatus(BuyOrderBatchDeliveryTask.STATUS_FAILED);
task.setFailMessage(failMessage);
} else {
task.setStatus(BuyOrderBatchDeliveryTask.STATUS_COMPLETED);
}
batchDeliveryTaskDao.updateById(task);
}
}

View File

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.*; import com.peanut.common.utils.*;
import com.peanut.config.Constants; import com.peanut.config.Constants;
import com.peanut.modules.book.service.BuyOrderBatchDeliveryAsyncService;
import com.peanut.modules.book.service.BuyOrderService; import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.book.service.CityService; import com.peanut.modules.book.service.CityService;
import com.peanut.modules.book.service.CountyService; import com.peanut.modules.book.service.CountyService;
@@ -118,8 +119,14 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
private UserVipDao userVipDao; private UserVipDao userVipDao;
@Autowired @Autowired
private VipBuyConfigDao vipBuyConfigDao; private VipBuyConfigDao vipBuyConfigDao;
@Autowired
private BuyOrderBatchDeliveryTaskDao batchDeliveryTaskDao;
@Autowired
private BuyOrderBatchDeliveryItemDao batchDeliveryItemDao;
@Autowired
private BuyOrderBatchDeliveryAsyncService batchDeliveryAsyncService;
// TODO 新版本上线后删除 //private static final int BATCH_DELIVERY_MAX_SIZE = 100;
@Override @Override
public PageUtils list(Map<String, Object> params) throws Exception { public PageUtils list(Map<String, Object> params) throws Exception {
@@ -437,6 +444,22 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
List<Integer> collect = buyOrderProductDao.selectJoinList(BuyOrderProduct.class, buyOrderProductMPJLambdaWrapper).stream().map(BuyOrderProduct::getOrderId).collect(Collectors.toList()); List<Integer> collect = buyOrderProductDao.selectJoinList(BuyOrderProduct.class, buyOrderProductMPJLambdaWrapper).stream().map(BuyOrderProduct::getOrderId).collect(Collectors.toList());
wrapper.in(BuyOrder::getOrderId,collect); wrapper.in(BuyOrder::getOrderId,collect);
} }
if(requestVo.getShowOne()!=null && requestVo.getShowOne()==1){
List<Map<String, Object>> list = buyOrderProductService.listMaps(
new QueryWrapper<BuyOrderProduct>()
.select("order_id orderId")
.groupBy("order_id")
.having("COUNT(*) = 1 AND SUM(quantity) = 1")
);
List<Integer> collect = list.stream()
.map(map -> ((Number) map.get("orderId")).intValue())
.collect(Collectors.toList());
if (collect.size() > 0) {
wrapper.in(BuyOrder::getOrderId, collect);
} else {
wrapper.eq(BuyOrder::getOrderId, -1);
}
}
Page<BuyOrder> buyOrderPage = getBaseMapper().selectPage(new Page<BuyOrder>(requestVo.getPageIndex(), requestVo.getPageSize()), wrapper); Page<BuyOrder> buyOrderPage = getBaseMapper().selectPage(new Page<BuyOrder>(requestVo.getPageIndex(), requestVo.getPageSize()), wrapper);
//丰富订单内容 //丰富订单内容
for (BuyOrder b : buyOrderPage.getRecords()){ for (BuyOrder b : buyOrderPage.getRecords()){
@@ -720,6 +743,107 @@ public class BuyOrderServiceImpl extends ServiceImpl<BuyOrderDao, BuyOrder> impl
} }
} }
@Override
public R batchDelivery(String expressCompanyCode, List<Integer> orderIds) {
if (orderIds == null || orderIds.isEmpty()) {
return R.error("订单列表不能为空");
}
// if (orderIds.size() > BATCH_DELIVERY_MAX_SIZE) {
// return R.error("单次批量发货最多" + BATCH_DELIVERY_MAX_SIZE + "单");
// }
List<Integer> distinctOrderIds = orderIds.stream().distinct().collect(Collectors.toList());
List<BatchDeliveryOrderItem> validOrders = new ArrayList<>();
List<String> invalidOrderSns = new ArrayList<>();
for (Integer orderId : distinctOrderIds) {
BuyOrder buyOrder = getById(orderId);
if (buyOrder == null) {
invalidOrderSns.add(String.valueOf(orderId));
continue;
}
List<BuyOrderProduct> products = buyOrderProductService.list(
new LambdaQueryWrapper<BuyOrderProduct>().eq(BuyOrderProduct::getOrderId, orderId));
if (products.size() != 1 || products.get(0).getQuantity() != 1) {
invalidOrderSns.add(buyOrder.getOrderSn());
} else {
BatchDeliveryOrderItem item = new BatchDeliveryOrderItem();
item.orderId = orderId;
item.orderSn = buyOrder.getOrderSn();
item.buyOrderProductId = products.get(0).getId();
validOrders.add(item);
}
}
if (!invalidOrderSns.isEmpty()) {
return R.error(String.join(",", invalidOrderSns));
}
List<Integer> busyOrderIds = batchDeliveryTaskDao.findBusyOrderIds(distinctOrderIds);
if (!busyOrderIds.isEmpty()) {
return R.error("以下订单正在批量发货处理中,请勿重复提交:" + busyOrderIds.stream()
.map(String::valueOf).collect(Collectors.joining(",")));
}
Date now = new Date();
BuyOrderBatchDeliveryTask task = new BuyOrderBatchDeliveryTask();
task.setExpressCompanyCode(expressCompanyCode);
task.setTotalCount(validOrders.size());
task.setSuccessCount(0);
task.setFailCount(0);
task.setStatus(BuyOrderBatchDeliveryTask.STATUS_PENDING);
task.setCreateTime(now);
task.setUpdateTime(now);
batchDeliveryTaskDao.insert(task);
for (BatchDeliveryOrderItem orderItem : validOrders) {
BuyOrderBatchDeliveryItem item = new BuyOrderBatchDeliveryItem();
item.setTaskId(task.getId());
item.setOrderId(orderItem.orderId);
item.setOrderSn(orderItem.orderSn);
item.setBuyOrderProductId(orderItem.buyOrderProductId);
item.setStatus(BuyOrderBatchDeliveryItem.STATUS_PENDING);
item.setCreateTime(now);
item.setUpdateTime(now);
batchDeliveryItemDao.insert(item);
}
batchDeliveryAsyncService.executeBatchDelivery(task.getId());
return R.ok()
.put("taskId", task.getId())
.put("totalCount", task.getTotalCount())
.put("message", "批量发货任务已提交,请轮询进度");
}
@Override
public R getBatchDeliveryProgress(Integer taskId) {
if (taskId == null) {
return R.error("任务ID不能为空");
}
BuyOrderBatchDeliveryTask task = batchDeliveryTaskDao.selectById(taskId);
if (task == null) {
return R.error("任务不存在");
}
List<BuyOrderBatchDeliveryItem> failedItems = batchDeliveryItemDao.selectList(
new LambdaQueryWrapper<BuyOrderBatchDeliveryItem>()
.eq(BuyOrderBatchDeliveryItem::getTaskId, taskId)
.eq(BuyOrderBatchDeliveryItem::getStatus, BuyOrderBatchDeliveryItem.STATUS_FAILED));
int processedCount = task.getSuccessCount() + task.getFailCount();
boolean finished = task.getStatus() >= BuyOrderBatchDeliveryTask.STATUS_COMPLETED;
return R.ok()
.put("taskId", task.getId())
.put("status", task.getStatus())
.put("totalCount", task.getTotalCount())
.put("successCount", task.getSuccessCount())
.put("failCount", task.getFailCount())
.put("processedCount", processedCount)
.put("finished", finished)
.put("failMessage", task.getFailMessage())
.put("failedItems", failedItems);
}
private static class BatchDeliveryOrderItem {
private Integer orderId;
private String orderSn;
private Integer buyOrderProductId;
}
public String mytest() throws IOException { public String mytest() throws IOException {
String html = ""; String html = "";
File file = new File("D:/1.html"); File file = new File("D:/1.html");

View File

@@ -55,4 +55,9 @@ public class BuyOrderListRequestVo {
* 数据起始位置 * 数据起始位置
*/ */
private Integer index; private Integer index;
/**
* 过滤预售
*/
private Integer showOne;
} }

View File

@@ -62,6 +62,9 @@ public class CouponEntity {
//使用门槛 //使用门槛
private Integer useLevel; private Integer useLevel;
//限定VIP类型逗号分隔如1,11,5,51用户开通其中任意VIP可现金券直接换积分
private String userVipIds;
private Date createTime; private Date createTime;
@TableLogic @TableLogic

View File

@@ -271,6 +271,15 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
return set; return set;
} }
private boolean matchUserVipIds(String userVipIds, List<UserVip> userVipList) {
Set<Integer> allowedVipTypes = Arrays.stream(userVipIds.split(","))
.map(String::trim)
.filter(StringUtils::isNotEmpty)
.map(Integer::parseInt)
.collect(Collectors.toSet());
return userVipList.stream().anyMatch(userVip -> allowedVipTypes.contains(userVip.getType()));
}
public void getCourseMedicalIds(int courseMedicalId,List<Integer> list){ public void getCourseMedicalIds(int courseMedicalId,List<Integer> list){
CourseMedicine courseMedicine = courseMedicineDao.selectById(courseMedicalId); CourseMedicine courseMedicine = courseMedicineDao.selectById(courseMedicalId);
if (courseMedicine.getIsLast()==1){ if (courseMedicine.getIsLast()==1){
@@ -380,7 +389,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
List<Map<String,Object>> buyOrderProducts = couponToProductDao.selectJoinMaps(wrapper); List<Map<String,Object>> buyOrderProducts = couponToProductDao.selectJoinMaps(wrapper);
for (Map<String,Object> map : buyOrderProducts) { for (Map<String,Object> map : buyOrderProducts) {
ShopProduct shopProduct = shopProductDao.selectById(map.get("product_id").toString()); ShopProduct shopProduct = shopProductDao.selectById(map.get("product_id").toString());
//预售书+赠送现金券VIP用户将券额转为积分仅产品id=2023时需为妇幼生殖vip(type=10) //预售书+赠送现金券VIP用户将券额转为积分配置user_vip_ids时匹配VIP且现金券换积分不匹配只送券
if ("03".equals(shopProduct.getGoodsType())){ if ("03".equals(shopProduct.getGoodsType())){
MyUserEntity userEntity = userDao.selectById(order.getUserId()); MyUserEntity userEntity = userDao.selectById(order.getUserId());
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>() List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
@@ -389,8 +398,15 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, CouponEntity> impl
int productId = Integer.parseInt(map.get("product_id").toString()); int productId = Integer.parseInt(map.get("product_id").toString());
int couponId = Integer.parseInt(map.get("coupon_id").toString()); int couponId = Integer.parseInt(map.get("coupon_id").toString());
CouponEntity couponEntity = couponDao.selectById(couponId); CouponEntity couponEntity = couponDao.selectById(couponId);
boolean isFyszVip = userVipList.stream().anyMatch(userVip -> Integer.valueOf(10).equals(userVip.getType())); boolean couponToJf = false;
boolean couponToJf = couponEntity.getCouponType() == 0 && (productId == 2023 ? isFyszVip : userVipList.size() > 0); if (StringUtils.isNotEmpty(couponEntity.getUserVipIds())) {
if (matchUserVipIds(couponEntity.getUserVipIds(), userVipList)) {
couponToJf = couponEntity.getCouponType() == 0;
}
} else {
boolean isFyszVip = userVipList.stream().anyMatch(userVip -> Integer.valueOf(10).equals(userVip.getType()));
couponToJf = couponEntity.getCouponType() == 0 && (productId == 2023 ? isFyszVip : userVipList.size() > 0);
}
if (couponToJf){ if (couponToJf){
BigDecimal jf = BigDecimal.ZERO; BigDecimal jf = BigDecimal.ZERO;
for (int i=0;i<Integer.parseInt(map.get("quantity").toString());i++){ for (int i=0;i<Integer.parseInt(map.get("quantity").toString());i++){

View File

@@ -266,7 +266,6 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>() List<UserVip> userVipList = userVipDao.selectList(new LambdaQueryWrapper<UserVip>()
.eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getState,0).in(UserVip::getType,4,9,5,6,10)); .eq(UserVip::getUserId,buyOrder.getUserId()).eq(UserVip::getState,0).in(UserVip::getType,4,9,5,6,10));
for (int i=4;i<=10;i++){ for (int i=4;i<=10;i++){
log.info("openVipForUser====i:"+i);
if (i==7){ if (i==7){
i=9; i=9;
} }

View File

@@ -35,13 +35,16 @@ public class StatisticsBusinessVipController {
@RequestMapping("/getUserVipByMonth") @RequestMapping("/getUserVipByMonth")
public R getUserVipByMonth(@RequestBody Map<String,Object> params) { public R getUserVipByMonth(@RequestBody Map<String,Object> params) {
CountResult result = countInfo(userVipService.getUserVipByMonth(params.get("date").toString())); CountResult result = countInfo(userVipService.getUserVipByMonth(params.get("date").toString()), params.get("date").toString());
List<Map<String,Object>> allResultList = result.resultList; List<Map<String,Object>> allResultList = result.resultList;
Map<String, Integer> banCounts = new HashMap<>(); Map<String, Integer> banCounts = new HashMap<>();
Map<String, Integer> yanCounts = new HashMap<>(); Map<String, Integer> yanCounts = new HashMap<>();
BigDecimal banTotalPrice = BigDecimal.ZERO; BigDecimal banTotalPrice = BigDecimal.ZERO;
BigDecimal yanTotalPrice = BigDecimal.ZERO; BigDecimal yanTotalPrice = BigDecimal.ZERO;
String date = params.get("date").toString();
Map<String, List<Integer>> reBuyRules = buildReBuyRules(date);
for (Map<String,Object> map : allResultList) { for (Map<String,Object> map : allResultList) {
String vipType = map.get("vipType").toString(); String vipType = map.get("vipType").toString();
boolean isBan = map.get("startTime").equals(map.get("uvlStartTime")); boolean isBan = map.get("startTime").equals(map.get("uvlStartTime"));
@@ -61,17 +64,6 @@ public class StatisticsBusinessVipController {
.eq(UserVip::getUserId, map.get("userId").toString()) .eq(UserVip::getUserId, map.get("userId").toString())
.eq(UserVip::getState,1).lt(UserVip::getStartTime,map.get("startTime").toString())) .eq(UserVip::getState,1).lt(UserVip::getStartTime,map.get("startTime").toString()))
.stream().map(UserVip::getType).collect(Collectors.toList()); .stream().map(UserVip::getType).collect(Collectors.toList());
// 定义复购规则
Map<String, List<Integer>> reBuyRules = new HashMap<>();
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));
reBuyRules.put("肿瘤学", Arrays.asList(6));
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); List<Integer> required = reBuyRules.get(vipType);
if (required != null && state1UserVips.containsAll(required)) { if (required != null && state1UserVips.containsAll(required)) {
@@ -112,7 +104,7 @@ public class StatisticsBusinessVipController {
row0.createCell(0).setCellValue("办理总人数");row0.createCell(1).setCellValue(r.get("banTotalCount").toString()); row0.createCell(0).setCellValue("办理总人数");row0.createCell(1).setCellValue(r.get("banTotalCount").toString());
row0.createCell(2).setCellValue("延期总人数");row0.createCell(3).setCellValue(r.get("yanTotalCount").toString()); row0.createCell(2).setCellValue("延期总人数");row0.createCell(3).setCellValue(r.get("yanTotalCount").toString());
row0.createCell(4).setCellValue("总办理金额");row0.createCell(5).setCellValue(r.get("banTotalPrice").toString()); row0.createCell(4).setCellValue("总办理金额");row0.createCell(5).setCellValue(r.get("banTotalPrice").toString());
BigDecimal a = new BigDecimal(r.get("banTotalCount").toString()).subtract(new BigDecimal(r2.get("banTotalCount").toString())).divide(new BigDecimal(r.get("banTotalCount").toString()), 4, RoundingMode.HALF_UP); BigDecimal a = calcGrowthRate(r.get("banTotalCount"), r2.get("banTotalCount"));
DecimalFormat df = new DecimalFormat("0.00%"); DecimalFormat df = new DecimalFormat("0.00%");
row0.createCell(6).setCellValue("办理总人数环比增长率:");row0.createCell(7).setCellValue(df.format(a)); row0.createCell(6).setCellValue("办理总人数环比增长率:");row0.createCell(7).setCellValue(df.format(a));
Row row1 = sheet.createRow(rowNum++); Row row1 = sheet.createRow(rowNum++);
@@ -121,19 +113,19 @@ public class StatisticsBusinessVipController {
row1.createCell(0).setCellValue("医学超级");row1.createCell(1).setCellValue(state1Counts.getOrDefault("医学超级",0).toString()); row1.createCell(0).setCellValue("医学超级");row1.createCell(1).setCellValue(state1Counts.getOrDefault("医学超级",0).toString());
row1.createCell(2).setCellValue("医学超级");row1.createCell(3).setCellValue(state0Counts.getOrDefault("医学超级",0).toString()); row1.createCell(2).setCellValue("医学超级");row1.createCell(3).setCellValue(state0Counts.getOrDefault("医学超级",0).toString());
row1.createCell(4).setCellValue("总延期金额");row1.createCell(5).setCellValue(r.get("yanTotalPrice").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); BigDecimal b = calcGrowthRate(r.get("yanTotalCount"), r2.get("yanTotalCount"));
row1.createCell(6).setCellValue("延期总人数环比增长率:");row1.createCell(7).setCellValue(df.format(b)); row1.createCell(6).setCellValue("延期总人数环比增长率:");row1.createCell(7).setCellValue(df.format(b));
Row row2 = sheet.createRow(rowNum++); Row row2 = sheet.createRow(rowNum++);
row2.createCell(0).setCellValue("国学心理学超级");row2.createCell(1).setCellValue(state1Counts.getOrDefault("国学心理学超级",0).toString()); row2.createCell(0).setCellValue("国学心理学超级");row2.createCell(1).setCellValue(state1Counts.getOrDefault("国学心理学超级",0).toString());
row2.createCell(2).setCellValue("国学心理学超级");row2.createCell(3).setCellValue(state0Counts.getOrDefault("国学心理学超级",0).toString()); row2.createCell(2).setCellValue("国学心理学超级");row2.createCell(3).setCellValue(state0Counts.getOrDefault("国学心理学超级",0).toString());
row2.createCell(4).setCellValue("总金额");row2.createCell(5).setCellValue( row2.createCell(4).setCellValue("总金额");row2.createCell(5).setCellValue(
new BigDecimal(r.get("banTotalPrice").toString()).add(new BigDecimal(r.get("yanTotalPrice").toString())).toString()); new BigDecimal(r.get("banTotalPrice").toString()).add(new BigDecimal(r.get("yanTotalPrice").toString())).toString());
BigDecimal c = new BigDecimal(r.get("banTotalPrice").toString()).subtract(new BigDecimal(r2.get("banTotalPrice").toString())).divide(new BigDecimal(r.get("banTotalPrice").toString()), 4, RoundingMode.HALF_UP); BigDecimal c = calcGrowthRate(r.get("banTotalPrice"), r2.get("banTotalPrice"));
row2.createCell(6).setCellValue("办理金额环比增长率:");row2.createCell(7).setCellValue(df.format(c)); row2.createCell(6).setCellValue("办理金额环比增长率:");row2.createCell(7).setCellValue(df.format(c));
Row row3 = sheet.createRow(rowNum++); Row row3 = sheet.createRow(rowNum++);
row3.createCell(0).setCellValue("中医学");row3.createCell(1).setCellValue(state1Counts.getOrDefault("中医学", 0).toString()); row3.createCell(0).setCellValue("中医学");row3.createCell(1).setCellValue(state1Counts.getOrDefault("中医学", 0).toString());
row3.createCell(2).setCellValue("中医学");row3.createCell(3).setCellValue(state0Counts.getOrDefault("中医学", 0).toString()); row3.createCell(2).setCellValue("中医学");row3.createCell(3).setCellValue(state0Counts.getOrDefault("中医学", 0).toString());
BigDecimal d = new BigDecimal(r.get("yanTotalPrice").toString()).subtract(new BigDecimal(r2.get("yanTotalPrice").toString())).divide(new BigDecimal(r.get("yanTotalPrice").toString()), 4, RoundingMode.HALF_UP); BigDecimal d = calcGrowthRate(r.get("yanTotalPrice"), r2.get("yanTotalPrice"));
row3.createCell(6).setCellValue("延期金额环比增长率:");row3.createCell(7).setCellValue(df.format(d)); row3.createCell(6).setCellValue("延期金额环比增长率:");row3.createCell(7).setCellValue(df.format(d));
Row row4 = sheet.createRow(rowNum++); Row row4 = sheet.createRow(rowNum++);
row4.createCell(0).setCellValue("针灸学");row4.createCell(1).setCellValue(state1Counts.getOrDefault("针灸学", 0).toString()); row4.createCell(0).setCellValue("针灸学");row4.createCell(1).setCellValue(state1Counts.getOrDefault("针灸学", 0).toString());
@@ -290,7 +282,7 @@ public class StatisticsBusinessVipController {
row0.createCell(0).setCellValue("办理总人数");row0.createCell(1).setCellValue(r.get("banTotalCount").toString()); row0.createCell(0).setCellValue("办理总人数");row0.createCell(1).setCellValue(r.get("banTotalCount").toString());
row0.createCell(2).setCellValue("延期总人数");row0.createCell(3).setCellValue(r.get("yanTotalCount").toString()); row0.createCell(2).setCellValue("延期总人数");row0.createCell(3).setCellValue(r.get("yanTotalCount").toString());
row0.createCell(4).setCellValue("总办理金额");row0.createCell(5).setCellValue(r.get("banTotalPrice").toString()); row0.createCell(4).setCellValue("总办理金额");row0.createCell(5).setCellValue(r.get("banTotalPrice").toString());
BigDecimal a = new BigDecimal(r.get("banTotalCount").toString()).subtract(new BigDecimal(r2.get("banTotalCount").toString())).divide(new BigDecimal(r.get("banTotalCount").toString()), 4, RoundingMode.HALF_UP); BigDecimal a = calcGrowthRate(r.get("banTotalCount"), r2.get("banTotalCount"));
DecimalFormat df = new DecimalFormat("0.00%"); DecimalFormat df = new DecimalFormat("0.00%");
row0.createCell(6).setCellValue("办理总人数同比增长率:");row0.createCell(7).setCellValue(df.format(a)); row0.createCell(6).setCellValue("办理总人数同比增长率:");row0.createCell(7).setCellValue(df.format(a));
Row row1 = sheet.createRow(rowNum++); Row row1 = sheet.createRow(rowNum++);
@@ -299,19 +291,19 @@ public class StatisticsBusinessVipController {
row1.createCell(0).setCellValue("医学超级");row1.createCell(1).setCellValue(state1Counts.containsKey("医学超级")?state1Counts.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(2).setCellValue("医学超级");row1.createCell(3).setCellValue(state0Counts.containsKey("医学超级")?state0Counts.get("医学超级").toString():"");
row1.createCell(4).setCellValue("总延期金额");row1.createCell(5).setCellValue(r.get("yanTotalPrice").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); BigDecimal b = calcGrowthRate(r.get("yanTotalCount"), r2.get("yanTotalCount"));
row1.createCell(6).setCellValue("延期总人数同比增长率:");row1.createCell(7).setCellValue(df.format(b)); row1.createCell(6).setCellValue("延期总人数同比增长率:");row1.createCell(7).setCellValue(df.format(b));
Row row2 = sheet.createRow(rowNum++); Row row2 = sheet.createRow(rowNum++);
row2.createCell(0).setCellValue("国学心理学超级");row2.createCell(1).setCellValue(state1Counts.get("国学心理学超级").toString()); row2.createCell(0).setCellValue("国学心理学超级");row2.createCell(1).setCellValue(state1Counts.get("国学心理学超级").toString());
row2.createCell(2).setCellValue("国学心理学超级");row2.createCell(3).setCellValue(state0Counts.get("国学心理学超级").toString()); row2.createCell(2).setCellValue("国学心理学超级");row2.createCell(3).setCellValue(state0Counts.get("国学心理学超级").toString());
row2.createCell(4).setCellValue("总金额");row2.createCell(5).setCellValue( row2.createCell(4).setCellValue("总金额");row2.createCell(5).setCellValue(
new BigDecimal(r.get("banTotalPrice").toString()).add(new BigDecimal(r.get("yanTotalPrice").toString())).toString()); new BigDecimal(r.get("banTotalPrice").toString()).add(new BigDecimal(r.get("yanTotalPrice").toString())).toString());
BigDecimal c = new BigDecimal(r.get("banTotalPrice").toString()).subtract(new BigDecimal(r2.get("banTotalPrice").toString())).divide(new BigDecimal(r.get("banTotalPrice").toString()), 4, RoundingMode.HALF_UP); BigDecimal c = calcGrowthRate(r.get("banTotalPrice"), r2.get("banTotalPrice"));
row2.createCell(6).setCellValue("办理金额同比增长率:");row2.createCell(7).setCellValue(df.format(c)); row2.createCell(6).setCellValue("办理金额同比增长率:");row2.createCell(7).setCellValue(df.format(c));
Row row3 = sheet.createRow(rowNum++); Row row3 = sheet.createRow(rowNum++);
row3.createCell(0).setCellValue("中医学");row3.createCell(1).setCellValue(state1Counts.getOrDefault("中医学", 0).toString()); row3.createCell(0).setCellValue("中医学");row3.createCell(1).setCellValue(state1Counts.getOrDefault("中医学", 0).toString());
row3.createCell(2).setCellValue("中医学");row3.createCell(3).setCellValue(state0Counts.getOrDefault("中医学", 0).toString()); row3.createCell(2).setCellValue("中医学");row3.createCell(3).setCellValue(state0Counts.getOrDefault("中医学", 0).toString());
BigDecimal d = new BigDecimal(r.get("yanTotalPrice").toString()).subtract(new BigDecimal(r2.get("yanTotalPrice").toString())).divide(new BigDecimal(r.get("yanTotalPrice").toString()), 4, RoundingMode.HALF_UP); BigDecimal d = calcGrowthRate(r.get("yanTotalPrice"), r2.get("yanTotalPrice"));
row3.createCell(6).setCellValue("延期金额同比增长率:");row3.createCell(7).setCellValue(df.format(d)); row3.createCell(6).setCellValue("延期金额同比增长率:");row3.createCell(7).setCellValue(df.format(d));
Row row4 = sheet.createRow(rowNum++); Row row4 = sheet.createRow(rowNum++);
row4.createCell(0).setCellValue("针灸学");row4.createCell(1).setCellValue(state1Counts.getOrDefault("针灸学", 0).toString()); row4.createCell(0).setCellValue("针灸学");row4.createCell(1).setCellValue(state1Counts.getOrDefault("针灸学", 0).toString());
@@ -503,7 +495,13 @@ public class StatisticsBusinessVipController {
Map<String,Integer> counts = new HashMap<>(); Map<String,Integer> counts = new HashMap<>();
} }
private static final String MEDICAL_SUPER_CUTOFF = "2026-05";
private CountResult countInfo(List<Map<String,Object>> userVips) { private CountResult countInfo(List<Map<String,Object>> userVips) {
return countInfo(userVips, null);
}
private CountResult countInfo(List<Map<String,Object>> userVips, String date) {
CountResult result = new CountResult(); CountResult result = new CountResult();
// 初始化计数器 // 初始化计数器
result.counts.put("yxSuperCount",0); result.counts.put("yxSuperCount",0);
@@ -517,16 +515,18 @@ public class StatisticsBusinessVipController {
result.counts.put("fyszCount",0); result.counts.put("fyszCount",0);
for (Map<String,Object> map : userVips) { for (Map<String,Object> map : userVips) {
String recordMonth = resolveRecordMonth(map, date);
List<String> medicalSuperTypes = getMedicalSuperTypes(recordMonth);
String[] types = map.get("type").toString().split(","); String[] types = map.get("type").toString().split(",");
Set<String> typeSet = new HashSet<>(Arrays.asList(types)); Set<String> typeSet = new HashSet<>(Arrays.asList(types));
int yxFlag = 0; int yxFlag = 0;
int gxFlag = 0; int gxFlag = 0;
// 超级类型 // 超级类型
if (typeSet.containsAll(Arrays.asList("4","5","6","9","10"))) { if (typeSet.containsAll(medicalSuperTypes)) {
yxFlag = 1; yxFlag = 1;
Map<String,Object> copy = new HashMap<>(map); Map<String,Object> copy = new HashMap<>(map);
copy.put("vipType","医学超级"); copy.put("vipType","医学超级");
copy.put("price",Math.round(Double.parseDouble(map.get("price").toString())*4)); copy.put("price",Math.round(Double.parseDouble(map.get("price").toString())*medicalSuperTypes.size()));
result.resultList.add(copy); result.resultList.add(copy);
result.counts.computeIfPresent("yxSuperCount",(k,v)->v+1); result.counts.computeIfPresent("yxSuperCount",(k,v)->v+1);
result.total.add(map.get("tel").toString()); result.total.add(map.get("tel").toString());
@@ -550,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 ("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 ("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 ("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); } else if ("10".equals(type) && yxFlag==0 && isFyszEnabled(recordMonth)) { copy.put("vipType","妇幼生殖学"); result.counts.computeIfPresent("fyszCount",(k,v)->v+1); }
if (copy.get("vipType") != null) { if (copy.get("vipType") != null) {
result.resultList.add(copy); result.resultList.add(copy);
result.total.add(map.get("tel").toString()); result.total.add(map.get("tel").toString());
@@ -560,6 +560,56 @@ public class StatisticsBusinessVipController {
return result; return result;
} }
private String resolveRecordMonth(Map<String, Object> map, String date) {
if (date != null) {
return date;
}
Object payTime = map.get("payTime");
if (payTime != null) {
String payTimeStr = payTime.toString();
return payTimeStr.length() >= 7 ? payTimeStr.substring(0, 7) : payTimeStr;
}
return MEDICAL_SUPER_CUTOFF;
}
private List<String> getMedicalSuperTypes(String recordMonth) {
if (recordMonth.compareTo(MEDICAL_SUPER_CUTOFF) < 0) {
return Arrays.asList("4", "5", "6", "9");
}
return Arrays.asList("4", "5", "6", "9", "10");
}
private boolean isFyszEnabled(String recordMonth) {
return recordMonth.compareTo(MEDICAL_SUPER_CUTOFF) >= 0;
}
private Map<String, List<Integer>> buildReBuyRules(String date) {
Map<String, List<Integer>> reBuyRules = new HashMap<>();
if (date.compareTo(MEDICAL_SUPER_CUTOFF) < 0) {
reBuyRules.put("医学超级", Arrays.asList(4, 5, 6, 9));
} else {
reBuyRules.put("医学超级", Arrays.asList(4, 5, 6, 9, 10));
reBuyRules.put("妇幼生殖学", Arrays.asList(10));
}
reBuyRules.put("国学心理学超级", Arrays.asList(7, 8));
reBuyRules.put("中医学", Arrays.asList(4));
reBuyRules.put("针灸学", Arrays.asList(5));
reBuyRules.put("肿瘤学", Arrays.asList(6));
reBuyRules.put("国学", Arrays.asList(7));
reBuyRules.put("心理学", Arrays.asList(8));
reBuyRules.put("中西汇通学", Arrays.asList(9));
return reBuyRules;
}
private BigDecimal calcGrowthRate(Object current, Object previous) {
BigDecimal currentVal = new BigDecimal(current.toString());
if (currentVal.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
BigDecimal previousVal = new BigDecimal(previous.toString());
return currentVal.subtract(previousVal).divide(currentVal, 4, RoundingMode.HALF_UP);
}
private void export(XSSFWorkbook wb,Sheet sheet,String fileName,int rowNum,HttpServletResponse response, String[] headers, String[] cellValues, List<Map<String,Object>> list){ private void export(XSSFWorkbook wb,Sheet sheet,String fileName,int rowNum,HttpServletResponse response, String[] headers, String[] cellValues, List<Map<String,Object>> list){
if (sheet!=null){ if (sheet!=null){
// 表头 // 表头

View File

@@ -114,7 +114,8 @@ public class UserVipController {
"5".equals(params.get("type").toString())?"开通针灸学VIP": "5".equals(params.get("type").toString())?"开通针灸学VIP":
"6".equals(params.get("type").toString())?"开通肿瘤学VIP": "6".equals(params.get("type").toString())?"开通肿瘤学VIP":
"7".equals(params.get("type").toString())?"开通国学VIP": "7".equals(params.get("type").toString())?"开通国学VIP":
"8".equals(params.get("type").toString())?"开通心理学VIP":"开通中西汇通VIP"; "10".equals(params.get("type").toString())?"妇幼生殖学VIP":
"8".equals(params.get("type").toString())?"开通心理学VIP":"开通中西汇通VIP";
if(fee.compareTo(BigDecimal.ZERO)>0){ if(fee.compareTo(BigDecimal.ZERO)>0){
user.setPeanutCoin(user.getPeanutCoin().subtract(fee)); user.setPeanutCoin(user.getPeanutCoin().subtract(fee));
TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity(); TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity();
@@ -155,8 +156,8 @@ public class UserVipController {
typeList.add(i); typeList.add(i);
} }
}else if ("1".equals(params.get("type").toString())) {//医学超级 }else if ("1".equals(params.get("type").toString())) {//医学超级
count = 4; count = 5;
for (int i=4;i<8;i++){ for (int i=4;i<=10;i++){
if (i==7){ if (i==7){
i = 9; i = 9;
} }

View File

@@ -235,18 +235,31 @@ public class UserCourseBuyServiceImpl extends ServiceImpl<UserCourseBuyDao, User
result.add(row); result.add(row);
} }
} }
Map<String, Integer> refundChapterCountMap = new HashMap<>();
for (Map<String, Object> refund : refundMap.values()) {
String orderCourseKey = String.valueOf(refund.get("orderSn")) + "|" + String.valueOf(refund.get("ctitle"));
refundChapterCountMap.merge(orderCourseKey, 1, Integer::sum);
}
for (Map<String, Object> refund : refundMap.values()) { for (Map<String, Object> refund : refundMap.values()) {
String key = refundKey(refund); String key = refundKey(refund);
if (matchedKeys.contains(key)) { if (matchedKeys.contains(key)) {
continue; continue;
} }
Map<String, Object> adjustedRefund = new HashMap<>(refund);
String orderCourseKey = String.valueOf(refund.get("orderSn")) + "|" + String.valueOf(refund.get("ctitle"));
int chapterCount = refundChapterCountMap.getOrDefault(orderCourseKey, 1);
if (chapterCount > 1) {
BigDecimal dividedFee = toBigDecimal(refund.get("fee"))
.divide(BigDecimal.valueOf(chapterCount), 2, RoundingMode.HALF_UP);
adjustedRefund.put("fee", dividedFee);
}
String payMonth = getPayMonth(refund); String payMonth = getPayMonth(refund);
if (exportMonth.equals(payMonth)) { if (exportMonth.equals(payMonth)) {
Map<String, Object> paidRow = buildPaidRowFromRefund(refund); Map<String, Object> paidRow = buildPaidRowFromRefund(adjustedRefund);
result.add(paidRow); result.add(paidRow);
result.add(buildRefundRow(paidRow, refund, date)); result.add(buildRefundRow(paidRow, adjustedRefund, date));
} else if (!payMonth.isEmpty() && payMonth.compareTo(exportMonth) < 0) { } else if (!payMonth.isEmpty() && payMonth.compareTo(exportMonth) < 0) {
result.add(buildRefundRow(buildBaseRowFromRefund(refund), refund, date)); result.add(buildRefundRow(buildBaseRowFromRefund(adjustedRefund), adjustedRefund, date));
} }
} }
return result; return result;

View File

@@ -66,7 +66,7 @@ public class MedicalLabelAndMarketController {
if (params.containsKey("medicineMarketId")&&!"".equals(params.get("medicineMarketId").toString())){ if (params.containsKey("medicineMarketId")&&!"".equals(params.get("medicineMarketId").toString())){
wrapper.eq(ShopProductToMedicineMarket::getMedicineMarketId,params.get("medicineMarketId").toString()); wrapper.eq(ShopProductToMedicineMarket::getMedicineMarketId,params.get("medicineMarketId").toString());
} }
wrapper.orderByAsc(ShopProductToMedicineMarket::getSort); wrapper.orderByDesc(ShopProductToMedicineMarket::getSort);
Page<ShopProduct> page = productService.page(new Page<>( Page<ShopProduct> page = productService.page(new Page<>(
Long.parseLong(params.get("current").toString()), Long.parseLong(params.get("limit").toString())),wrapper); Long.parseLong(params.get("current").toString()), Long.parseLong(params.get("limit").toString())),wrapper);
for (ShopProduct shopProduct:page.getRecords()){ for (ShopProduct shopProduct:page.getRecords()){

View File

@@ -96,16 +96,49 @@
DATE_FORMAT(IF(bo.success_time is null,bo.create_time,bo.success_time),'%Y-%m-%d %H:%i:%s') payTime, 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, bo.order_sn orderSn,pzo.trade_no zfbOrder,
0 beginDay,IFNULL(spc.days,0) days, 0 beginDay,IFNULL(spc.days,0) days,
ROUND(bor.fee/(select count(1) from buy_order_product bop2 ROUND(
inner join shop_product sp2 on sp2.product_id = bop2.product_id bor.fee / (
where bop2.order_id = bo.order_id and sp2.goods_type = '05'),2) fee, case
when bo.order_type='relearn' then
IFNULL((
select count(1)
from shop_product_course spc2
where spc2.product_id = (
case
when bo.remark is null or bo.remark = '' then null
else cast(SUBSTRING_INDEX(bo.remark, ',', 1) as unsigned)
end
)
and spc2.del_flag = 0
),1)
else
IFNULL((
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'
),1)
end
),2
) fee,
if(bo.remark like '%退%',bo.remark,if(bor.remark is null,'',bor.remark)) remark, 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, DATE_FORMAT(bor.create_time,'%Y-%m-%d %H:%i:%s') refundTime,
'已退款' orderStatus '已退款' orderStatus
from buy_order_refund bor 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 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 left join buy_order_product bop on bop.order_id = bo.order_id and bo.order_type &lt;&gt; 'relearn'
inner join shop_product sp on sp.product_id = bop.product_id and sp.goods_type = '05' left join shop_product sp
on sp.product_id = (
case
when bo.order_type='relearn' then
case
when bo.remark is null or bo.remark = '' then null
else cast(SUBSTRING_INDEX(bo.remark, ',', 1) as unsigned)
end
else bop.product_id
end
)
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 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 c on c.id = spc.course_id
left join course_catalogue cc on cc.id = spc.catalogue_id left join course_catalogue cc on cc.id = spc.catalogue_id