From 389139043b0679929d7da0e523e113e14eb9dd21 Mon Sep 17 00:00:00 2001 From: wuchunlei Date: Thu, 22 Jan 2026 15:45:33 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/controller/OrdersController.java | 3 +- .../controller/StatisticsController.java | 877 ++++++++++++++---- 2 files changed, 710 insertions(+), 170 deletions(-) diff --git a/src/main/java/com/zmzm/finance/common/controller/OrdersController.java b/src/main/java/com/zmzm/finance/common/controller/OrdersController.java index fb96d5e..92669a1 100644 --- a/src/main/java/com/zmzm/finance/common/controller/OrdersController.java +++ b/src/main/java/com/zmzm/finance/common/controller/OrdersController.java @@ -65,6 +65,7 @@ public class OrdersController { BigDecimal differencePoint = user.getPoint().subtract(wumenUser.getPeanutCoin()); List orders = ordersService.list(new LambdaQueryWrapper() .eq(Orders::getPayType, 1).eq(Orders::getUseFlag, 0) + .gt(Orders::getOrderTime,"2022-12-31 23:59:59") .eq(Orders::getTel, user.getTel()).orderByDesc(Orders::getOrderTime)); for (Orders order : orders) { if (differencePoint.compareTo(order.getFee()) >= 0) { @@ -78,7 +79,7 @@ public class OrdersController { } } ordersService.updateBatchById(ordersRes); - userService.updateBatchById(userList); + userService.updateBatchById(userRes); return R.ok(); } diff --git a/src/main/java/com/zmzm/finance/common/controller/StatisticsController.java b/src/main/java/com/zmzm/finance/common/controller/StatisticsController.java index 50894a8..448576b 100644 --- a/src/main/java/com/zmzm/finance/common/controller/StatisticsController.java +++ b/src/main/java/com/zmzm/finance/common/controller/StatisticsController.java @@ -4,14 +4,21 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.zmzm.finance.common.entity.*; import com.zmzm.finance.common.service.*; import com.zmzm.finance.util.R; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateUtils; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; +import java.io.OutputStream; import java.math.BigDecimal; +import java.net.URLEncoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.YearMonth; @@ -23,8 +30,6 @@ import java.util.stream.Collectors; @RequestMapping("common/statistics") public class StatisticsController { - @Autowired - private IUserService userService; @Autowired private IOrdersService ordersService; @Autowired @@ -76,9 +81,11 @@ public class StatisticsController { total = total.add(o.getFee()); } } - List applyBuyTotals = customerApplyBuyService.listByIds(yljkTotalOids); - for (TCustomerApplyBuy buy:applyBuyTotals){ - total = total.add(BigDecimal.valueOf(buy.getConvertpoint())); + if (yljkTotalOids.size()>0){ + List applyBuyTotals = customerApplyBuyService.listByIds(yljkTotalOids); + for (TCustomerApplyBuy buy:applyBuyTotals){ + total = total.add(BigDecimal.valueOf(buy.getConvertpoint())); + } } //指定月份以后的冲销差额 BigDecimal in = BigDecimal.ZERO; @@ -93,9 +100,11 @@ public class StatisticsController { in = in.add(o.getFee()); } } - List applyBuys = customerApplyBuyService.listByIds(yljkOids); - for (TCustomerApplyBuy buy:applyBuys){ - in = in.add(BigDecimal.valueOf(buy.getConvertpoint())); + if (yljkOids.size()>0){ + List applyBuys = customerApplyBuyService.listByIds(yljkOids); + for (TCustomerApplyBuy buy:applyBuys){ + in = in.add(BigDecimal.valueOf(buy.getConvertpoint())); + } } Map out = ordersService.getMap(new MPJLambdaWrapper() .eq(Orders::getUseFlag,1).eq(Orders::getPayType,1) @@ -107,10 +116,191 @@ public class StatisticsController { } //天医币明细导出 @RequestMapping("/pointInfoExport") - public R pointInfoExport(@RequestBody Map params){ + public R pointInfoExport(HttpServletResponse response,@RequestBody Map params){ + List> coinInfoList = ordersService.listMaps(new MPJLambdaWrapper() + .eq(Orders::getUseFlag,1).and(t->t.eq(Orders::getType,0).or().eq(Orders::getPayType,1)) + .apply("DATE_FORMAT(t.order_time, '%Y-%m') = '"+params.get("year")+"-"+params.get("month")+"'") + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source," + + "if(type=0,'充值',IF(type=1,'vip',IF(type=2,'课程',IF(type=3,'实物','培训班')))) type,tel,order_sn,fee") + .orderByAsc(Orders::getOrderTime)); + String fileName = params.get("year")+""+params.get("month")+"天医币明细"; + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(fileName); + Row titleRow = sheet.createRow(0); + titleRow.createCell(0).setCellValue("时间"); + titleRow.createCell(1).setCellValue("来源"); + titleRow.createCell(2).setCellValue("类型"); + titleRow.createCell(3).setCellValue("电话"); + titleRow.createCell(4).setCellValue("订单号"); + titleRow.createCell(5).setCellValue("金额"); + int cell = 1; + for (Map map : coinInfoList) { + Row row = sheet.createRow(cell); + row.createCell(0).setCellValue(map.get("orderTime").toString()); + row.createCell(1).setCellValue(map.get("source").toString()); + row.createCell(2).setCellValue(map.get("type").toString()); + row.createCell(3).setCellValue(map.get("tel").toString()); + row.createCell(4).setCellValue(map.get("order_sn").toString()); + row.createCell(5).setCellValue(map.get("fee").toString()); + //序号自增 + cell++; + } + exportTem(response,wb,fileName+".xlsx"); return R.ok(); } + //vip明细导出 + @RequestMapping("/vipInfoExport") + public R vipInfoExport(HttpServletResponse response, @RequestBody Map params) throws ParseException { + String date = params.get("year")+"-"+params.get("month"); + List> vipOrders = ordersService.listMaps(new MPJLambdaWrapper() + .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) + .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + .disableSubLogicDel() + .eq(Orders::getUseFlag,1).eq(Orders::getType,1) + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source,order_old_id orderOldId," + + "IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,tel,order_sn,t.fee realMoney") + .orderByAsc(Orders::getOrderTime)); + //吴门医述订单 + List wumenOrderIds = vipOrders.stream().filter(o -> o.get("source").equals("吴门医述")) + .map(map->map.get("orderOldId").toString()).collect(Collectors.toList()); + List> buyOrders = buyOrderService.listMaps(new MPJLambdaWrapper() + .leftJoin(UserVipLog.class,UserVipLog::getOrderSn,BuyOrder::getOrderSn) + .leftJoin(UserVip.class,UserVip::getId,UserVipLog::getUserVipId) + .disableSubLogicDel() + .in(BuyOrder::getOrderId,wumenOrderIds) + .select("t.order_id oid,if(t2.type=4,'中医学vip',if(t2.type=5,'针灸学vip',if(t2.type=6,'肿瘤学vip',if(t2.type=7,'国学vip',if(t2.type=8,'心理学vip',if(t2.type=9,'中西汇通vip','其他')))))) vipType," + + "t1.fee,DATE_FORMAT(t1.start_time, '%Y-%m-%d') startTime,DATE_FORMAT(t1.end_time, '%Y-%m-%d') endTime")); + Map buyOrdersMap = new HashMap<>(); + for (Map m : buyOrders) { + List> l = new ArrayList<>(); + if(buyOrdersMap.get(m.get("oid").toString())!=null){ + l = (List>) buyOrdersMap.get(m.get("oid").toString()); + } + l.add(m); + buyOrdersMap.put(m.get("oid").toString(),l); + } + YearMonth yearMonth = YearMonth.parse(date); + SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdfmonth = new SimpleDateFormat("yyyy-MM"); + String day = date+"-"+yearMonth.lengthOfMonth(); + String month = date; + List> result = new ArrayList<>(); + for(Map vipOrder:vipOrders){ + if (vipOrder.get("source").equals("吴门医述")){ + List> l = (List>) buyOrdersMap.get(vipOrder.get("orderOldId")); + for (Map m : l) { + Map res = new HashMap<>(); + if (m.get("fee")!=null){ + res.put("fee",m.get("fee")); + res.put("startTime",m.get("startTime")); + res.put("endTime",m.get("endTime")); + }else { + res.put("fee",vipOrder.get("realMoney")); + res.put("startTime",vipOrder.get("orderTime")); + res.put("endTime",vipOrder.get("orderTime")); + } + res.put("vipType",m.get("vipType")); + res.putAll(vipOrder); + result.add(res); + } + }else { + FinanceOrder financeOrder = financeOrderService.getById(vipOrder.get("orderOldId").toString()); + vipOrder.put("fee",financeOrder.getRealMoney()); + vipOrder.put("startTime",sdfday.format(financeOrder.getStartTime())); + vipOrder.put("endTime",sdfday.format(financeOrder.getEndTime())); + vipOrder.put("vipType",financeOrder.getProductName()); + result.add(vipOrder); + } + } + for (Map map:result){ + map.put("now",BigDecimal.ZERO); + map.put("already",BigDecimal.ZERO); + map.put("notyet",BigDecimal.ZERO); + BigDecimal fee = (BigDecimal) map.get("fee"); + String startTime = (String) map.get("startTime"); + String endTime = (String) map.get("endTime"); + if (startTime.equals(endTime)){ + if (map.get("orderTime").toString().contains(month)){ + map.put("now",fee); + } + //摊销完成 + }else if (sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ + map.put("already",fee); + //未开始摊销 + }else if (sdfday.parse(day).getTime()0){ + map.put("already",dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + alreadyDays = 0; + } + //当前月天数 + int nowDays = Integer.parseInt(day.substring(8, 10)); + BigDecimal now = BigDecimal.ZERO; + //如果开始时间是当前月,月天数-开始日=当月摊销天数 + if (startTime.contains(month)){ + nowDays = Integer.parseInt(day.substring(8, 10))-Integer.parseInt(startTime.substring(8, 10))+1; + now = dayAmount.multiply(new BigDecimal(nowDays)); + } else if (endTime.contains(month)) { + now = fee.subtract(dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + now = dayAmount.multiply(new BigDecimal(nowDays)); + } + map.put("now",now); + //剩余未摊销 + map.put("notyet",fee.subtract(now).subtract(dayAmount.multiply(new BigDecimal(alreadyDays)))); + } + } + String fileName = params.get("year")+""+params.get("month")+"vip明细"; + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(fileName); + Row titleRow = sheet.createRow(0); + titleRow.createCell(0).setCellValue("时间"); + titleRow.createCell(1).setCellValue("来源"); + titleRow.createCell(2).setCellValue("类型"); + titleRow.createCell(3).setCellValue("电话"); + titleRow.createCell(4).setCellValue("订单号"); + titleRow.createCell(5).setCellValue("缴费金额"); + titleRow.createCell(6).setCellValue("金额"); + titleRow.createCell(7).setCellValue("VIP类型"); + titleRow.createCell(8).setCellValue("开始时间"); + titleRow.createCell(9).setCellValue("结束时间"); + titleRow.createCell(10).setCellValue("已摊销"); + titleRow.createCell(11).setCellValue("当前摊销"); + titleRow.createCell(12).setCellValue("剩余摊销"); + int cell = 1; + for (Map map : result) { + Row row = sheet.createRow(cell); + row.createCell(0).setCellValue(map.get("orderTime").toString()); + row.createCell(1).setCellValue(map.get("source").toString()); + row.createCell(2).setCellValue(map.get("type").toString()); + row.createCell(3).setCellValue(map.get("tel").toString()); + row.createCell(4).setCellValue(map.get("order_sn").toString()); + row.createCell(5).setCellValue(map.get("realMoney").toString()); + row.createCell(6).setCellValue(map.get("fee").toString()); + row.createCell(7).setCellValue(map.get("vipType").toString()); + row.createCell(8).setCellValue(map.get("startTime").toString()); + row.createCell(9).setCellValue(map.get("endTime").toString()); + row.createCell(10).setCellValue(map.get("already").toString()); + row.createCell(11).setCellValue(map.get("now").toString()); + row.createCell(12).setCellValue(map.get("notyet").toString()); + //序号自增 + cell++; + } + exportTem(response,wb,fileName+".xlsx"); + return R.ok(); + } //vip @RequestMapping("/vipStatistics") public R vipStatistics(@RequestBody Map params) throws ParseException { @@ -135,116 +325,15 @@ public class StatisticsController { BigDecimal already = BigDecimal.ZERO; BigDecimal nowTotal = BigDecimal.ZERO; BigDecimal notyet = BigDecimal.ZERO; - for(Orders orders:vipOrders){ - List> list = new ArrayList<>(); - if (orders.getSource()==1){ - List userVipLogs = userVipLogService.list(new MPJLambdaWrapper() - .leftJoin("buy_order t2 on t2.order_sn = t.order_sn ") - .apply("t2.order_id = "+orders.getOrderOldId()) - .select("fee,start_time,end_time")); - for (UserVipLog userVipLog : userVipLogs) { - Map map = new HashMap<>(); - map.put("fee",userVipLog.getFee()); - map.put("startTime",sdfday.format(userVipLog.getStartTime())); - map.put("endTime",sdfday.format(userVipLog.getEndTime())); - list.add(map); - } - }else { - FinanceOrder financeOrder = financeOrderService.getById(orders.getOrderOldId()); - Map map = new HashMap<>(); - map.put("fee",financeOrder.getRealMoney()); - map.put("startTime",sdfday.format(financeOrder.getStartTime())); - map.put("endTime",sdfday.format(financeOrder.getEndTime())); - list.add(map); - } - for (Map map:list){ - BigDecimal fee = (BigDecimal) map.get("fee"); - String startTime = (String) map.get("startTime"); - String endTime = (String) map.get("endTime"); - //总天数 - int totalDays = Math.toIntExact((sdfday.parse(endTime).getTime() - sdfday.parse(startTime).getTime()) / 1000 / 60 / 60 / 24)+1; - //日摊销 - BigDecimal dayAmount = fee.divide(new BigDecimal(totalDays),2, BigDecimal.ROUND_HALF_UP); - //摊销完成 - if (sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ - already = already.add(fee); - //未开始摊销 - }else if (sdfday.parse(day).getTime()0){ - already = already.add(dayAmount.multiply(new BigDecimal(alreadyDays))); - }else { - alreadyDays = 0; - } - //当前月天数 - int nowDays = Integer.parseInt(day.substring(8, 10)); - BigDecimal now = BigDecimal.ZERO; - //如果开始时间是当前月,月天数-开始日=当月摊销天数 - if (startTime.contains(month)){ - nowDays = Integer.parseInt(day.substring(8, 10))-Integer.parseInt(startTime.substring(8, 10))+1; - now = dayAmount.multiply(new BigDecimal(nowDays)); - } else if (endTime.contains(month)) { - now = fee.subtract(dayAmount.multiply(new BigDecimal(alreadyDays))); - }else { - now = dayAmount.multiply(new BigDecimal(nowDays)); - } - nowTotal = nowTotal.add(now); - //剩余未摊销 - notyet = notyet.add(fee.subtract(now).subtract(dayAmount.multiply(new BigDecimal(alreadyDays)))); - } - } - } - return R.ok().putData("incomes",incomes).putData("already",already).putData("now",nowTotal).putData("notyet",notyet); - } - - //课程 - @RequestMapping("/courseStatistics") - public R courseStatistics(@RequestBody Map params) throws ParseException { - String date = params.get("year")+"-"+params.get("month"); - //收入 - List> incomes = ordersService.listMaps(new MPJLambdaWrapper() - .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) - .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + //吴门医述订单课程 + List wumenOrderIds = vipOrders.stream().filter(o -> o.getSource() == 1).map(Orders::getOrderOldId).collect(Collectors.toList()); + List> buyOrders = buyOrderService.listMaps(new MPJLambdaWrapper() + .leftJoin(UserVipLog.class,UserVipLog::getOrderSn,BuyOrder::getOrderSn) .disableSubLogicDel() - .eq(Orders::getUseFlag,1).eq(Orders::getType,2) - .apply("DATE_FORMAT(t.order_time, '%Y-%m') = '"+date+"'") - .select("IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,SUM(t.fee) fee") - .groupBy(Payment::getType)); - //所有课程订单 - List courseOrders = ordersService.list(new MPJLambdaWrapper() - .eq(Orders::getUseFlag,1).eq(Orders::getType,2)); - SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat sdfmonth = new SimpleDateFormat("yyyy-MM"); - YearMonth yearMonth = YearMonth.parse(date); - String day = date+"-"+yearMonth.lengthOfMonth(); - String month = date; - BigDecimal already = BigDecimal.ZERO; - BigDecimal nowTotal = BigDecimal.ZERO; - BigDecimal notyet = BigDecimal.ZERO; - - List taihuOrderIds = courseOrders.stream().filter(o -> o.getSource() == 0).map(Orders::getOrderOldId).collect(Collectors.toList()); - Map> taihuClassMap = customerApplyCurriculumService.listMaps(new MPJLambdaWrapper() - .in("t.oid", taihuOrderIds) - .apply("t.valid=1 and t.status = '50'") - .select("t.oid,if(t.point>0,t.point,t.money) fee,curriculumID")) - .stream().collect(Collectors.toMap(m -> m.get("oid").toString(), m -> m)); - - List wumenOrderIds = courseOrders.stream().filter(o -> o.getSource() == 1).map(Orders::getOrderOldId).collect(Collectors.toList()); - List> buyOrdersList = buyOrderService.listMaps(new MPJLambdaWrapper() - .leftJoin("user_course_buy_log t1 on (t1.order_sn = t.order_sn )") - .leftJoin("user_course_buy t2 on t2.id = t1.user_course_buy_id") - .in("t.order_id",wumenOrderIds) - .gt(BuyOrder::getRealMoney,0) - .select("t.order_id oid,t1.id ucblid,if(t1.fee is null,t.real_money,t1.fee) fee,t1.days,t1.begin_day," + - "DATE_FORMAT(t2.start_time, '%Y-%m-%d %H:%i:%s') start_time,DATE_FORMAT(t2.end_time, '%Y-%m-%d %H:%i:%s') end_time")); + .in(BuyOrder::getOrderId,wumenOrderIds) + .select("t.order_id oid,fee,DATE_FORMAT(start_time, '%Y-%m-%d %H:%i:%s') startTime,DATE_FORMAT(end_time, '%Y-%m-%d %H:%i:%s') endTime")); Map buyOrdersMap = new HashMap<>(); - for (Map m : buyOrdersList) { + for (Map m : buyOrders) { List> l = new ArrayList<>(); if(buyOrdersMap.get(m.get("oid").toString())!=null){ l = (List>) buyOrdersMap.get(m.get("oid").toString()); @@ -252,57 +341,22 @@ public class StatisticsController { l.add(m); buyOrdersMap.put(m.get("oid").toString(),l); } - - for(Orders orders:courseOrders){ + for(Orders orders:vipOrders){ List> list = new ArrayList<>(); - if(orders.getSource()==0){ - Map map = new HashMap<>(); - Map taihuClass = taihuClassMap.get(orders.getOrderOldId()); - Map c = customerTaihuClassService.getMap(new MPJLambdaWrapper() - .like(TCustomerTaihuClass::getDescription,taihuClass.get("curriculumID")) - .select("DATE_FORMAT(startDate, '%Y-%m-%d %H:%i:%s') startDate,studyDays")); - if (c != null) { - taihuClass.put("startDate",c.get("startDate")); - taihuClass.put("studyDays",c.get("studyDays")); - }else { - taihuClass.put("startDate",null); - } - map.put("fee",new BigDecimal(taihuClass.get("fee").toString())); - if (taihuClass.get("startDate")==null){ - map.put("startTime",null); - map.put("endTime",null); - }else { - map.put("startTime",taihuClass.get("startDate")); - map.put("endTime",sdfday.format(DateUtils.addDays(DateUtils.parseDate(taihuClass.get("startDate").toString(),new String[]{"yyyy-MM-dd HH:mm:ss"}), - Integer.parseInt(taihuClass.get("studyDays")==null?"0":taihuClass.get("studyDays").toString())))); - } - list.add(map); - }else if (orders.getSource()==1){ + if (orders.getSource()==1){ List> l = (List>) buyOrdersMap.get(orders.getOrderOldId()); - if (l!=null){ - for (Map userCourseBuyLog : l) { + for (Map m : l) { + if (m.get("fee")!=null){ Map map = new HashMap<>(); - map.put("fee",new BigDecimal(userCourseBuyLog.get("fee").toString())); - if (userCourseBuyLog.get("ucblid")==null){ - map.put("startTime","2022-12-30"); - map.put("endTime","2022-12-30"); - }else { - if (userCourseBuyLog.get("start_time")==null){ - map.put("startTime",null); - map.put("endTime",null); - }else { - if (Integer.parseInt(userCourseBuyLog.get("begin_day").toString())==0){ - map.put("startTime",userCourseBuyLog.get("start_time").toString()); - map.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(userCourseBuyLog.get("start_time").toString()), - Integer.parseInt(userCourseBuyLog.get("days").toString())-1))); - }else { - map.put("startTime",sdfday.format(DateUtils.addDays(sdfday.parse(userCourseBuyLog.get("start_time").toString()), - Integer.parseInt(userCourseBuyLog.get("days").toString())))); - map.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(userCourseBuyLog.get("start_time").toString()), - Integer.parseInt(userCourseBuyLog.get("days").toString())-1))); - } - } - } + map.put("fee",m.get("fee")); + map.put("startTime",m.get("startTime")); + map.put("endTime",m.get("endTime")); + list.add(map); + }else { + Map map = new HashMap<>(); + map.put("fee",orders.getFee()); + map.put("startTime",null); + map.put("endTime",null); list.add(map); } } @@ -318,10 +372,12 @@ public class StatisticsController { BigDecimal fee = (BigDecimal) map.get("fee"); String startTime = (String) map.get("startTime")==null?"":map.get("startTime").toString(); String endTime = (String) map.get("endTime")==null?"":map.get("endTime").toString(); - //摊销完成 if (StringUtils.isEmpty(startTime)){ - notyet = notyet.add(fee); - }else if (StringUtils.isNotEmpty(endTime)&&sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ + if (sdfmonth.format(orders.getOrderTime()).equals(month)){ + nowTotal = nowTotal.add(fee); + } + //摊销完成 + }else if (sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ already = already.add(fee); //未开始摊销 }else if (sdfday.parse(day).getTime() params) throws ParseException { + String date = params.get("year")+"-"+params.get("month"); + //所有课程订单 + List> courseOrders = ordersService.listMaps(new MPJLambdaWrapper() + .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) + .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + .disableSubLogicDel() + .eq(Orders::getUseFlag,1).eq(Orders::getType,2) + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source,order_old_id orderOldId," + + "IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,tel,order_sn,t.fee realMoney") + .orderByAsc(Orders::getOrderTime)); + //一路健康订单课程 + List taihuOrderIds = courseOrders.stream().filter(o -> o.get("source").equals("一路健康")) + .map(map->map.get("orderOldId").toString()).collect(Collectors.toList()); + Map> taihuClassMap = customerApplyCurriculumService.listMaps(new MPJLambdaWrapper() + .in("t.oid", taihuOrderIds) + .apply("t.valid=1 and t.status = '50'") + .select("t.oid,if(t.point>0,t.point,t.money) fee,curriculumID")) + .stream().collect(Collectors.toMap(m -> m.get("oid").toString(), m -> m)); + //订单开课记录 + Map> ctc = customerTaihuClassService.listMaps(new MPJLambdaWrapper() + .like(TCustomerTaihuClass::getDescription,"KC20") + .in(TCustomerTaihuClass::getStatus,10) + .gt(TCustomerTaihuClass::getStudydays,0) + .select("SUBSTRING(description, LOCATE('KC', description), 16) description,oid,DATE_FORMAT(startDate, '%Y-%m-%d') startDate,studyDays")) + .stream().collect(Collectors.toMap(m -> m.get("description").toString()+"-"+m.get("oid").toString(), m -> m)); + //吴门医述订单课程 + List wumenOrderIds = courseOrders.stream().filter(o -> o.get("source").equals("一路健康")) + .map(map->map.get("orderOldId").toString()).collect(Collectors.toList()); + List> buyOrdersList = buyOrderService.listMaps(new MPJLambdaWrapper() + .leftJoin("user_course_buy_log t1 on (t1.order_sn = t.order_sn )") + .leftJoin("user_course_buy t2 on t2.id = t1.user_course_buy_id") + .in("t.order_id",wumenOrderIds) + .gt(BuyOrder::getRealMoney,0) + .select("t.order_id oid,t1.id ucblid,if(t1.fee is null,t.real_money,t1.fee) fee,t1.days,t1.begin_day," + + "DATE_FORMAT(t2.start_time, '%Y-%m-%d %H:%i:%s') startTime")); + Map buyOrdersMap = new HashMap<>(); + for (Map m : buyOrdersList) { + List> l = new ArrayList<>(); + if(buyOrdersMap.get(m.get("oid").toString())!=null){ + l = (List>) buyOrdersMap.get(m.get("oid").toString()); + } + l.add(m); + buyOrdersMap.put(m.get("oid").toString(),l); + } + YearMonth yearMonth = YearMonth.parse(date); + SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdfmonth = new SimpleDateFormat("yyyy-MM"); + String day = date+"-"+yearMonth.lengthOfMonth(); + String month = date; + List> result = new ArrayList<>(); + for(Map courseOrder:courseOrders){ + String orderTime = courseOrder.get("orderTime").toString().substring(0,10); + if (courseOrder.get("source").equals("一路健康")){ + Map res = new HashMap<>(); + Map taihuClass = taihuClassMap.get(courseOrder.get("orderOldId").toString()); + Map tc = ctc.entrySet().stream().filter(e -> e.getKey() + .contains(taihuClass.get("curriculumID").toString())).map(Map.Entry::getValue).findFirst().orElse(null); + res.put("fee",courseOrder.get("realMoney")); + if (tc != null&&tc.get("startDate")!=null) { + res.put("startTime",tc.get("startDate")); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(tc.get("startDate").toString()), (Integer) tc.get("studyDays")))); + }else { + res.put("startTime",orderTime); + res.put("endTime",orderTime); + } + res.putAll(courseOrder); + result.add(res); + }else if(courseOrder.get("source").equals("吴门医述")){ + List> l = (List>) buyOrdersMap.get(courseOrder.get("orderOldId")); + Map res = new HashMap<>(); + if (l!=null){ + for (Map m : l) { + if (m.get("ucblid")!=null){ + res.put("fee",m.get("fee")); + if (m.get("startTime")==null){ + res.put("startTime",null); + res.put("endTime",null); + }else { + if (Integer.parseInt(m.get("begin_day").toString())==0){ + res.put("startTime",m.get("startTime").toString()); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(m.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())-1))); + }else { + res.put("startTime",sdfday.format(DateUtils.addDays(sdfday.parse(m.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())))); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(res.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())-1))); + } + } + }else { + res.put("fee",courseOrder.get("realMoney")); + res.put("startTime",orderTime); + res.put("endTime",orderTime); + } + res.putAll(courseOrder); + result.add(res); + } + }else { + res.put("fee",courseOrder.get("realMoney")); + res.put("startTime",orderTime); + res.put("endTime",orderTime); + res.putAll(courseOrder); + result.add(res); + } + }else { + FinanceOrder financeOrder = financeOrderService.getById(courseOrder.get("orderOldId").toString()); + courseOrder.put("fee",financeOrder.getRealMoney()); + courseOrder.put("startTime",sdfday.format(financeOrder.getStartTime())); + courseOrder.put("endTime",sdfday.format(financeOrder.getEndTime())); + result.add(courseOrder); + } + } + for (Map map:result) { + map.put("vipType", "1"); + map.put("now", BigDecimal.ZERO); + map.put("already", BigDecimal.ZERO); + map.put("notyet", BigDecimal.ZERO); + BigDecimal fee = (BigDecimal) map.get("fee"); + String startTime = (String) map.get("startTime"); + String endTime = (String) map.get("endTime"); + if (startTime==null){ + map.put("notyet",fee); + }else if (sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ + map.put("already",fee); + //未开始摊销 + }else if (sdfday.parse(day).getTime()0){ + map.put("already",dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + alreadyDays = 0; + } + //当前月天数 + int nowDays = Integer.parseInt(day.substring(8, 10)); + BigDecimal now = BigDecimal.ZERO; + //如果开始时间是当前月,月天数-开始日=当月摊销天数 + if (startTime.contains(month)){ + nowDays = Integer.parseInt(day.substring(8, 10))-Integer.parseInt(startTime.substring(8, 10))+1; + now = dayAmount.multiply(new BigDecimal(nowDays)); + } else if (endTime.contains(month)) { + now = fee.subtract(dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + now = dayAmount.multiply(new BigDecimal(nowDays)); + } + map.put("now",now); + //剩余未摊销 + map.put("notyet",fee.subtract(now).subtract(dayAmount.multiply(new BigDecimal(alreadyDays)))); + } + } + String fileName = params.get("year")+""+params.get("month")+"课程明细"; + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(fileName); + Row titleRow = sheet.createRow(0); + titleRow.createCell(0).setCellValue("时间"); + titleRow.createCell(1).setCellValue("来源"); + titleRow.createCell(2).setCellValue("类型"); + titleRow.createCell(3).setCellValue("电话"); + titleRow.createCell(4).setCellValue("订单号"); + titleRow.createCell(5).setCellValue("缴费金额"); + titleRow.createCell(6).setCellValue("金额"); + titleRow.createCell(7).setCellValue("VIP类型"); + titleRow.createCell(8).setCellValue("开始时间"); + titleRow.createCell(9).setCellValue("结束时间"); + titleRow.createCell(10).setCellValue("已摊销"); + titleRow.createCell(11).setCellValue("当前摊销"); + titleRow.createCell(12).setCellValue("剩余摊销"); + int cell = 1; + for (Map map : result) { + Row row = sheet.createRow(cell); + row.createCell(0).setCellValue(map.get("orderTime").toString()); + row.createCell(1).setCellValue(map.get("source").toString()); + row.createCell(2).setCellValue(map.get("type").toString()); + row.createCell(3).setCellValue(map.get("tel").toString()); + row.createCell(4).setCellValue(map.get("order_sn").toString()); + row.createCell(5).setCellValue(map.get("realMoney").toString()); + row.createCell(6).setCellValue(map.get("fee").toString()); + row.createCell(7).setCellValue(map.get("vipType").toString()); + row.createCell(8).setCellValue(map.get("startTime")==null?"":map.get("startTime").toString()); + row.createCell(9).setCellValue(map.get("endTime")==null?"":map.get("endTime").toString()); + row.createCell(10).setCellValue(map.get("already").toString()); + row.createCell(11).setCellValue(map.get("now").toString()); + row.createCell(12).setCellValue(map.get("notyet").toString()); + //序号自增 + cell++; + } + exportTem(response,wb,fileName+".xlsx"); + return R.ok(); + } + + //课程 + @RequestMapping("/courseStatistics") + public R courseStatistics(@RequestBody Map params) throws ParseException { + String date = params.get("year")+"-"+params.get("month"); + //收入 + List> incomes = ordersService.listMaps(new MPJLambdaWrapper() + .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) + .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + .disableSubLogicDel() + .eq(Orders::getUseFlag,1).eq(Orders::getType,2) + .apply("DATE_FORMAT(t.order_time, '%Y-%m') = '"+date+"'") + .select("IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,SUM(t.fee) fee") + .groupBy(Payment::getType)); + //所有课程订单 + List> courseOrders = ordersService.listMaps(new MPJLambdaWrapper() + .eq(Orders::getUseFlag,1).eq(Orders::getType,2) + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source,order_old_id orderOldId," + + "tel,order_sn,t.tel,t.fee realMoney") + .orderByAsc(Orders::getOrderTime)); + //一路健康订单课程 + List taihuOrderIds = courseOrders.stream().filter(o -> o.get("source").equals("一路健康")) + .map(map->map.get("orderOldId").toString()).collect(Collectors.toList()); + Map> taihuClassMap = customerApplyCurriculumService.listMaps(new MPJLambdaWrapper() + .in("t.oid", taihuOrderIds) + .apply("t.valid=1 and t.status = '50'") + .select("t.oid,if(t.point>0,t.point,t.money) fee,curriculumID")) + .stream().collect(Collectors.toMap(m -> m.get("oid").toString(), m -> m)); + //订单开课记录 + Map> ctc = customerTaihuClassService.listMaps(new MPJLambdaWrapper() + .like(TCustomerTaihuClass::getDescription,"KC20") + .in(TCustomerTaihuClass::getStatus,10) + .gt(TCustomerTaihuClass::getStudydays,0) + .select("SUBSTRING(description, LOCATE('KC', description), 16) description,oid,DATE_FORMAT(startDate, '%Y-%m-%d') startDate,studyDays")) + .stream().collect(Collectors.toMap(m -> m.get("description").toString()+"-"+m.get("oid").toString(), m -> m)); + //吴门医述订单课程 + List wumenOrderIds = courseOrders.stream().filter(o -> o.get("source").equals("一路健康")) + .map(map->map.get("orderOldId").toString()).collect(Collectors.toList()); + List> buyOrdersList = buyOrderService.listMaps(new MPJLambdaWrapper() + .leftJoin("user_course_buy_log t1 on (t1.order_sn = t.order_sn )") + .leftJoin("user_course_buy t2 on t2.id = t1.user_course_buy_id") + .in("t.order_id",wumenOrderIds) + .gt(BuyOrder::getRealMoney,0) + .select("t.order_id oid,t1.id ucblid,if(t1.fee is null,t.real_money,t1.fee) fee,t1.days,t1.begin_day," + + "DATE_FORMAT(t2.start_time, '%Y-%m-%d %H:%i:%s') startTime")); + Map buyOrdersMap = new HashMap<>(); + for (Map m : buyOrdersList) { + List> l = new ArrayList<>(); + if(buyOrdersMap.get(m.get("oid").toString())!=null){ + l = (List>) buyOrdersMap.get(m.get("oid").toString()); + } + l.add(m); + buyOrdersMap.put(m.get("oid").toString(),l); + } + SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdfmonth = new SimpleDateFormat("yyyy-MM"); + YearMonth yearMonth = YearMonth.parse(date); + String day = date+"-"+yearMonth.lengthOfMonth(); + String month = date; + BigDecimal already = BigDecimal.ZERO; + BigDecimal nowTotal = BigDecimal.ZERO; + BigDecimal notyet = BigDecimal.ZERO; + List> result = new ArrayList<>(); + for(Map courseOrder:courseOrders){ + String orderTime = courseOrder.get("orderTime").toString().substring(0,10); + if (courseOrder.get("source").equals("一路健康")){ + Map res = new HashMap<>(); + Map taihuClass = taihuClassMap.get(courseOrder.get("orderOldId").toString()); + Map tc = ctc.entrySet().stream().filter(e -> e.getKey() + .contains(taihuClass.get("curriculumID").toString())).map(Map.Entry::getValue).findFirst().orElse(null); + res.put("fee",courseOrder.get("realMoney")); + if (tc != null&&tc.get("startDate")!=null) { + res.put("startTime",tc.get("startDate")); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(tc.get("startDate").toString()), (Integer) tc.get("studyDays")))); + }else { + res.put("startTime",orderTime); + res.put("endTime",orderTime); + } + res.putAll(courseOrder); + result.add(res); + }else if(courseOrder.get("source").equals("吴门医述")){ + List> l = (List>) buyOrdersMap.get(courseOrder.get("orderOldId")); + Map res = new HashMap<>(); + if (l!=null){ + for (Map m : l) { + if (m.get("ucblid")!=null){ + res.put("fee",m.get("fee")); + if (m.get("startTime")==null){ + res.put("startTime",null); + res.put("endTime",null); + }else { + if (Integer.parseInt(m.get("begin_day").toString())==0){ + res.put("startTime",m.get("startTime").toString()); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(m.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())-1))); + }else { + res.put("startTime",sdfday.format(DateUtils.addDays(sdfday.parse(m.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())))); + res.put("endTime",sdfday.format(DateUtils.addDays(sdfday.parse(res.get("startTime").toString()), + Integer.parseInt(m.get("days").toString())-1))); + } + } + }else { + res.put("fee",courseOrder.get("realMoney")); + res.put("startTime",orderTime); + res.put("endTime",orderTime); + } + res.putAll(courseOrder); + result.add(res); + } + }else { + res.put("fee",courseOrder.get("realMoney")); + res.put("startTime",orderTime); + res.put("endTime",orderTime); + res.putAll(courseOrder); + result.add(res); + } + }else { + FinanceOrder financeOrder = financeOrderService.getById(courseOrder.get("orderOldId").toString()); + courseOrder.put("fee",financeOrder.getRealMoney()); + courseOrder.put("startTime",sdfday.format(financeOrder.getStartTime())); + courseOrder.put("endTime",sdfday.format(financeOrder.getEndTime())); + result.add(courseOrder); + } + } + for (Map map:result) { + BigDecimal fee = (BigDecimal) map.get("fee"); + String startTime = (String) map.get("startTime"); + String endTime = (String) map.get("endTime"); + if (startTime==null){ + notyet = notyet.add(fee); + }else if (sdfmonth.parse(day).getTime()>sdfmonth.parse(endTime).getTime()){ + already = already.add(fee); + //未开始摊销 + }else if (sdfday.parse(day).getTime()0){ + already = already.add(dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + alreadyDays = 0; + } + //当前月天数 + int nowDays = Integer.parseInt(day.substring(8, 10)); + BigDecimal now = BigDecimal.ZERO; + //如果开始时间是当前月,月天数-开始日=当月摊销天数 + if (startTime.contains(month)){ + nowDays = Integer.parseInt(day.substring(8, 10))-Integer.parseInt(startTime.substring(8, 10))+1; + now = dayAmount.multiply(new BigDecimal(nowDays)); + } else if (endTime.contains(month)) { + now = fee.subtract(dayAmount.multiply(new BigDecimal(alreadyDays))); + }else { + now = dayAmount.multiply(new BigDecimal(nowDays)); + } + nowTotal = nowTotal.add(now); + //剩余未摊销 + notyet = notyet.add(fee.subtract(now).subtract(dayAmount.multiply(new BigDecimal(alreadyDays)))); + } + } + return R.ok().putData("incomes",incomes).putData("already",already).putData("now",nowTotal).putData("notyet",notyet); + } + //实物统计 @RequestMapping("/physicalStatistics") public R physicalStatistics(@RequestBody Map params){ @@ -375,6 +819,43 @@ public class StatisticsController { .groupBy(Payment::getType)); return R.ok().putData("map",physical); } + //实物明细导出 + @RequestMapping("/physicalInfoExport") + public R physicalInfoExport(HttpServletResponse response,@RequestBody Map params){ + List> coinInfoList = ordersService.listMaps(new MPJLambdaWrapper() + .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) + .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + .disableSubLogicDel() + .eq(Orders::getUseFlag,1).eq(Orders::getType,3) + .apply("DATE_FORMAT(t.order_time, '%Y-%m') = '"+params.get("year")+"-"+params.get("month")+"'") + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source," + + "IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,tel,order_sn,t.fee") + .orderByAsc(Orders::getOrderTime)); + String fileName = params.get("year")+""+params.get("month")+"实物明细"; + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(fileName); + Row titleRow = sheet.createRow(0); + titleRow.createCell(0).setCellValue("时间"); + titleRow.createCell(1).setCellValue("来源"); + titleRow.createCell(2).setCellValue("类型"); + titleRow.createCell(3).setCellValue("电话"); + titleRow.createCell(4).setCellValue("订单号"); + titleRow.createCell(5).setCellValue("金额"); + int cell = 1; + for (Map map : coinInfoList) { + Row row = sheet.createRow(cell); + row.createCell(0).setCellValue(map.get("orderTime").toString()); + row.createCell(1).setCellValue(map.get("source").toString()); + row.createCell(2).setCellValue(map.get("type").toString()); + row.createCell(3).setCellValue(map.get("tel").toString()); + row.createCell(4).setCellValue(map.get("order_sn").toString()); + row.createCell(5).setCellValue(map.get("fee").toString()); + //序号自增 + cell++; + } + exportTem(response,wb,fileName+".xlsx"); + return R.ok().put("infoList",coinInfoList); + } //培训班 @RequestMapping("/trainingClassStatistics") @@ -389,6 +870,64 @@ public class StatisticsController { .groupBy(Payment::getType)); return R.ok().putData("map",trainingClass); } + //培训班明细导出 + @RequestMapping("/trainingClassInfoExport") + public R trainingClassInfoExport(HttpServletResponse response,@RequestBody Map params){ + List> coinInfoList = ordersService.listMaps(new MPJLambdaWrapper() + .leftJoin(PaymentToOrder.class,PaymentToOrder::getOrderId,Orders::getId) + .leftJoin(Payment.class,Payment::getId,PaymentToOrder::getPaymentId) + .disableSubLogicDel() + .eq(Orders::getUseFlag,1).eq(Orders::getType,4) + .apply("DATE_FORMAT(t.order_time, '%Y-%m') = '"+params.get("year")+"-"+params.get("month")+"'") + .select("DATE_FORMAT(order_time, '%Y-%m-%d %H:%i:%s') orderTime,if(source=0,'一路健康',if(source=1,'吴门医述','管理员')) source," + + "IF(t.pay_type=1,'天医币',IF(t2.type=0,'微信',IF(t2.type=1,'支付宝','银行'))) type,tel,order_sn,t.fee") + .orderByAsc(Orders::getOrderTime)); + String fileName = params.get("year")+""+params.get("month")+"培训班明细"; + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(fileName); + Row titleRow = sheet.createRow(0); + titleRow.createCell(0).setCellValue("时间"); + titleRow.createCell(1).setCellValue("来源"); + titleRow.createCell(2).setCellValue("支付类型"); + titleRow.createCell(3).setCellValue("电话"); + titleRow.createCell(4).setCellValue("订单号"); + titleRow.createCell(5).setCellValue("金额"); + int cell = 1; + for (Map map : coinInfoList) { + Row row = sheet.createRow(cell); + row.createCell(0).setCellValue(map.get("orderTime").toString()); + row.createCell(1).setCellValue(map.get("source").toString()); + row.createCell(2).setCellValue(map.get("type").toString()); + row.createCell(3).setCellValue(map.get("tel").toString()); + row.createCell(4).setCellValue(map.get("order_sn").toString()); + row.createCell(5).setCellValue(map.get("fee").toString()); + //序号自增 + cell++; + } + exportTem(response,wb,fileName+".xlsx"); + return R.ok().put("infoList",coinInfoList); + } - + public void exportTem(HttpServletResponse response, XSSFWorkbook wb, String fileName){ + OutputStream outputStream =null; + try { + //文件名编码格式 + fileName = URLEncoder.encode(fileName,"UTF-8"); + //设置ContentType请求信息格式 + response.setContentType("application/vnd.ms-excel"); + //设置标头 + response.setHeader("Content-disposition", "attachment;filename=" + fileName); + outputStream = response.getOutputStream(); + wb.write(outputStream); + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + outputStream.flush(); + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } }