|
|
|
|
@ -1,8 +1,9 @@
|
|
|
|
|
package cn.ysk.cashier.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
import cn.ysk.cashier.dto.ShopSummaryDto;
|
|
|
|
|
import cn.ysk.cashier.dto.BaseQueryDto;
|
|
|
|
|
import cn.ysk.cashier.dto.ShopSummaryDto;
|
|
|
|
|
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;
|
|
|
|
|
import cn.ysk.cashier.enums.PayTypeEnum;
|
|
|
|
|
import cn.ysk.cashier.exception.BadRequestException;
|
|
|
|
|
@ -36,6 +37,7 @@ import java.time.Instant;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.concurrent.CountDownLatch;
|
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@ -93,7 +95,7 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
sale.put("inAmount", flowMap.get("inAmount")); //会员 充值金额
|
|
|
|
|
sale.put("outAmount", flowMap.get("outAmount"));//会员 退款金额
|
|
|
|
|
|
|
|
|
|
sale.put("incomeAmountAll",incomeAmount);//总实收 销售实收
|
|
|
|
|
sale.put("incomeAmountAll", incomeAmount);//总实收 销售实收
|
|
|
|
|
List<TbOrderPayCountVo> payCountVos = initPaysCount();
|
|
|
|
|
List<TbOrderPayCountVo> payCounts = tbOrderInfoRepository.queryTbOrderPayCount(
|
|
|
|
|
param.getShopId().toString(), null, param.getStartTime().getTime(), param.getEndTime().getTime());
|
|
|
|
|
@ -111,79 +113,78 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
param.getShopId().longValue(), DateUtil.getStrTime(param.getStartTime()), DateUtil.getStrTime(param.getEndTime()));
|
|
|
|
|
for (TbOrderPayCountVo payCountVo : payCountVos) {
|
|
|
|
|
BigDecimal payAmount = new BigDecimal(payCountVo.getPayAmount().toString());
|
|
|
|
|
switch (payCountVo.getPayType()){
|
|
|
|
|
switch (payCountVo.getPayType()) {
|
|
|
|
|
case "微信小程序":
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("wx_lite")?payAmount.add(payCountMap.get("wx_lite")):payAmount);
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("wx_lite") ? payAmount.add(payCountMap.get("wx_lite")) : payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "支付宝小程序":
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("ali_lite")?payAmount.add(payCountMap.get("ali_lite")):payAmount);
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("ali_lite") ? payAmount.add(payCountMap.get("ali_lite")) : payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "主扫收款":
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("scanCode")?payAmount.add(payCountMap.get("scanCode")):payAmount);
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("scanCode") ? payAmount.add(payCountMap.get("scanCode")) : payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "收款码收款":
|
|
|
|
|
if(payCountMap.containsKey("ALIPAY")){
|
|
|
|
|
if (payCountMap.containsKey("ALIPAY")) {
|
|
|
|
|
payAmount = payAmount.add(payCountMap.get("ALIPAY"));
|
|
|
|
|
}
|
|
|
|
|
if(payCountMap.containsKey("WECHAT")){
|
|
|
|
|
if (payCountMap.containsKey("WECHAT")) {
|
|
|
|
|
payAmount = payAmount.add(payCountMap.get("WECHAT"));
|
|
|
|
|
}
|
|
|
|
|
payCountVo.setPayAmount(payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "现金":
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("cash")?payAmount.add(payCountMap.get("cash")):payAmount);
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("cash") ? payAmount.add(payCountMap.get("cash")) : payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "会员":
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("deposit")?payAmount.add(payCountMap.get("deposit")):payAmount);
|
|
|
|
|
payCountVo.setPayAmount(payCountMap.containsKey("deposit") ? payAmount.add(payCountMap.get("deposit")) : payAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "充值":
|
|
|
|
|
payCountVo.setPayAmount(payAmount.add(vipSaveAmount));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sale.put("payCount",payCountVos);
|
|
|
|
|
result.put("sale",sale);
|
|
|
|
|
sale.put("payCount", payCountVos);
|
|
|
|
|
result.put("sale", sale);
|
|
|
|
|
vip.put("useAmount", flowMap.get("useAmount"));//会员消费金额
|
|
|
|
|
vip.put("newFlow",newFlow);//新增会员数
|
|
|
|
|
vip.put("useNum",flowMap.get("useNum"));//会员消费笔数
|
|
|
|
|
result.put("vip",vip);
|
|
|
|
|
vip.put("newFlow", newFlow);//新增会员数
|
|
|
|
|
vip.put("useNum", flowMap.get("useNum"));//会员消费笔数
|
|
|
|
|
result.put("vip", vip);
|
|
|
|
|
BigDecimal saleAmount = new BigDecimal(orderMap.get("saleAmount").toString()).subtract(new BigDecimal(orderMap.get("saveAmount").toString()));
|
|
|
|
|
//客单价
|
|
|
|
|
if(saleAmount.compareTo(BigDecimal.ZERO) == 0){
|
|
|
|
|
count.put("unitPrice",BigDecimal.ZERO);
|
|
|
|
|
}else {
|
|
|
|
|
count.put("unitPrice",saleAmount.divide(new BigDecimal(orderMap.get("saleNum").toString()),2,RoundingMode.DOWN));
|
|
|
|
|
if (saleAmount.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
|
|
count.put("unitPrice", BigDecimal.ZERO);
|
|
|
|
|
} else {
|
|
|
|
|
count.put("unitPrice", saleAmount.divide(new BigDecimal(orderMap.get("saleNum").toString()), 2, RoundingMode.DOWN));
|
|
|
|
|
}
|
|
|
|
|
BigDecimal saleNum = new BigDecimal(orderMap.get("saleNum").toString());
|
|
|
|
|
if(saleNum.compareTo(BigDecimal.ZERO) == 0 || saleNum.compareTo(new BigDecimal(tables)) < 0){
|
|
|
|
|
count.put("turnoverRate","0%");//翻台率
|
|
|
|
|
}else {
|
|
|
|
|
if (saleNum.compareTo(BigDecimal.ZERO) == 0 || saleNum.compareTo(new BigDecimal(tables)) < 0) {
|
|
|
|
|
count.put("turnoverRate", "0%");//翻台率
|
|
|
|
|
} else {
|
|
|
|
|
BigDecimal turnoverRate = saleNum.divide(new BigDecimal(tables), 4, RoundingMode.DOWN).subtract(BigDecimal.ONE)
|
|
|
|
|
.multiply(new BigDecimal("100"));
|
|
|
|
|
count.put("turnoverRate", turnoverRate.setScale(2, RoundingMode.DOWN) + "%");
|
|
|
|
|
}
|
|
|
|
|
count.put("saveAmount",orderMap.get("saveAmount"));//优惠金额
|
|
|
|
|
count.put("saveNum",orderMap.get("saveNum"));//优惠单数
|
|
|
|
|
result.put("count",count);
|
|
|
|
|
count.put("saveAmount", orderMap.get("saveAmount"));//优惠金额
|
|
|
|
|
count.put("saveNum", orderMap.get("saveNum"));//优惠单数
|
|
|
|
|
result.put("count", count);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<TbOrderPayCountVo> initPaysCount(){
|
|
|
|
|
public List<TbOrderPayCountVo> initPaysCount() {
|
|
|
|
|
List<TbOrderPayCountVo> payCountVos = new ArrayList<>();
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/wx.png","微信小程序","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/ali.png","支付宝小程序","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/scan.png","主扫收款","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/bscan.png","收款码收款","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/cash.png","现金","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/vipIn.png","充值","1",BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/wx.png", "微信小程序", "1", BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/ali.png", "支付宝小程序", "1", BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/scan.png", "主扫收款", "1", BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/bscan.png", "收款码收款", "1", BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/cash.png", "现金", "1", BigDecimal.ZERO));
|
|
|
|
|
payCountVos.add(new TbOrderPayCountVo("https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/vipIn.png", "充值", "1", BigDecimal.ZERO));
|
|
|
|
|
// payCountVos.add(new TbOrderPayCountVo("","会员支付","1",BigDecimal.ZERO));
|
|
|
|
|
return payCountVos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, Object> productSaleDate(Integer shopId, Integer day,Integer page,Integer size) {
|
|
|
|
|
public Map<String, Object> productSaleDate(Integer shopId, Integer day, Integer page, Integer size) {
|
|
|
|
|
Pageable pageable = PageRequest.of(page, size);
|
|
|
|
|
Date startTime = new Date();
|
|
|
|
|
Date endTime = new Date();
|
|
|
|
|
@ -201,14 +202,14 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
endTime = DateUtil.getDayEnd();
|
|
|
|
|
}
|
|
|
|
|
HashMap<String, Object> map = new HashMap<>();
|
|
|
|
|
Page<TbOrderSalesCountByDayVo> tbOrderSalesCountByDayVos = detailRepository.queryTbOrderSalesCountByDay(shopId, null, null, startTime, endTime,pageable);
|
|
|
|
|
Page<TbOrderSalesCountByDayVo> tbOrderSalesCountByDayVos = detailRepository.queryTbOrderSalesCountByDay(shopId, null, null, startTime, endTime, pageable);
|
|
|
|
|
TbOrderSalesCountByDayVo tbOrderSalesCountByDayVo = detailRepository.queryTbOrderSalesCountByDaysummaryCount(shopId, null, null, startTime, endTime);
|
|
|
|
|
TbOrderPayCountVo zong =new TbOrderPayCountVo("el-icon-coin","总金额","1",tbOrderSalesCountByDayVo.getSalesAmount());
|
|
|
|
|
TbOrderPayCountVo xiaoliang =new TbOrderPayCountVo("el-icon-goods","销售量","0",tbOrderSalesCountByDayVo.getSalesNum());
|
|
|
|
|
TbOrderPayCountVo zong = new TbOrderPayCountVo("el-icon-coin", "总金额", "1", tbOrderSalesCountByDayVo.getSalesAmount());
|
|
|
|
|
TbOrderPayCountVo xiaoliang = new TbOrderPayCountVo("el-icon-goods", "销售量", "0", tbOrderSalesCountByDayVo.getSalesNum());
|
|
|
|
|
List<CountStockByDayVo> countStockByDayVos = tbOrderDetailRepository.countStockByDay(shopId, startTime, endTime);
|
|
|
|
|
map.put("productCount", xiaoliang);
|
|
|
|
|
map.put("productSum", zong);
|
|
|
|
|
map.put("countList", countStockByDayVos) ;
|
|
|
|
|
map.put("countList", countStockByDayVos);
|
|
|
|
|
map.put("productList", tbOrderSalesCountByDayVos);
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
@ -257,7 +258,7 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
sumDateVO = dataMap.get(tradeDayString);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不存在,则创建新的SumDateVO对象,amount设为0
|
|
|
|
|
sumDateVO = new SumDateVO(tradeDayString, BigDecimal.ZERO,BigDecimal.ZERO, BigDecimal.ZERO);
|
|
|
|
|
sumDateVO = new SumDateVO(tradeDayString, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
|
|
|
|
|
}
|
|
|
|
|
// 将SumDateVO对象添加到列表中
|
|
|
|
|
sumDateList.add(sumDateVO);
|
|
|
|
|
@ -397,7 +398,7 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (TbOrderSalesCountByDayV2Vo product : products) {
|
|
|
|
|
if("sku".equals(product.getTypeEnum())){
|
|
|
|
|
if ("sku".equals(product.getTypeEnum())) {
|
|
|
|
|
for (TbOrderSalesCountByDayV2Vo skus : product.getSkus()) {
|
|
|
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
|
|
|
map.put("商品分类", product.getCateName());
|
|
|
|
|
@ -409,7 +410,7 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
map.put("退 单 量", skus.getRefNum());
|
|
|
|
|
list.add(map);
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
|
|
|
map.put("商品分类", product.getCateName());
|
|
|
|
|
map.put("商品名称", product.getName());
|
|
|
|
|
@ -475,82 +476,171 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
@Override
|
|
|
|
|
public void downloadTableSaleInfo(ShopTableSaleInfoDto shopTableSaleInfoDto, HttpServletResponse response) throws IOException {
|
|
|
|
|
if (shopTableSaleInfoDto.getStartTime() == null) {
|
|
|
|
|
shopTableSaleInfoDto.setStartTime(DateUtil.toDate(DateUtil.fromTimeStamp(1704038400L)));
|
|
|
|
|
// 设置开始时间为30天前
|
|
|
|
|
shopTableSaleInfoDto.setStartTime(cn.hutool.core.date.DateUtil.offsetDay(new Date(), -30));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shopTableSaleInfoDto.getEndTime() == null) {
|
|
|
|
|
shopTableSaleInfoDto.setEndTime(new Date());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<ShopTableSaleInfoVo> infoVos = selectSummaryTable(shopTableSaleInfoDto.getShopId(), shopTableSaleInfoDto.getStartTime(), shopTableSaleInfoDto.getEndTime());
|
|
|
|
|
|
|
|
|
|
infoVos.add(new ShopTableSaleInfoVo(99999, shopTableSaleInfoDto.getShopId(), null, "", "收银台", null, null, null, null));
|
|
|
|
|
|
|
|
|
|
List<TbOrderSalesCountByTable> countByTables = tbOrderDetailRepository.queryTbOrderSalesCountByTable(shopTableSaleInfoDto.getShopId(), shopTableSaleInfoDto.getStartTime(), shopTableSaleInfoDto.getEndTime());
|
|
|
|
|
|
|
|
|
|
Map<String, List<TbOrderSalesCountByTable>> countByTableMap = countByTables.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(TbOrderSalesCountByTable::getTableId));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 比较 shopTableSaleInfoDto 的 startTime 和 endTime 是不是同一天
|
|
|
|
|
boolean sameDay = cn.hutool.core.date.DateUtil.isSameDay(shopTableSaleInfoDto.getStartTime(), shopTableSaleInfoDto.getEndTime());
|
|
|
|
|
|
|
|
|
|
String queryDate = cn.hutool.core.date.DateUtil.format(shopTableSaleInfoDto.getStartTime(), "yyyy-MM-dd");
|
|
|
|
|
if (!sameDay) {
|
|
|
|
|
queryDate += " 至 " + cn.hutool.core.date.DateUtil.format(shopTableSaleInfoDto.getEndTime(), "yyyy-MM-dd");
|
|
|
|
|
// 计算开始时间和结束时间相差天数
|
|
|
|
|
long diff = shopTableSaleInfoDto.getEndTime().getTime() - shopTableSaleInfoDto.getStartTime().getTime();
|
|
|
|
|
long day = diff / (1000 * 60 * 60 * 24) + 1;
|
|
|
|
|
if (day > 31) {
|
|
|
|
|
throw new BadRequestException("时间范围不能超过31天");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> list = new ArrayList<>();
|
|
|
|
|
ThreadGroup threadGroup = new ThreadGroup("MyThreadGroup");
|
|
|
|
|
CountDownLatch countDownLatch = new CountDownLatch((int) day);
|
|
|
|
|
|
|
|
|
|
Map<String, List<ShopTableSaleInfoVo>> infoVoMap = new HashMap<>();
|
|
|
|
|
Map<String, List<TbOrderSalesCountByTable>> countByTableMap = new HashMap<>();
|
|
|
|
|
Set<String> tableCodeSet = new HashSet<>();
|
|
|
|
|
for (int i = 0; i < day; i++) {
|
|
|
|
|
DateTime date = cn.hutool.core.date.DateUtil.offsetDay(shopTableSaleInfoDto.getStartTime(), i);
|
|
|
|
|
|
|
|
|
|
Thread thread = new Thread(threadGroup, () -> {
|
|
|
|
|
try {
|
|
|
|
|
String dateKey = cn.hutool.core.date.DateUtil.format(date, "yyyy-MM-dd");
|
|
|
|
|
DateTime start = cn.hutool.core.date.DateUtil.beginOfDay(date);
|
|
|
|
|
DateTime end = cn.hutool.core.date.DateUtil.endOfDay(date);
|
|
|
|
|
List<ShopTableSaleInfoVo> infoVos = selectSummaryTable(shopTableSaleInfoDto.getShopId(),
|
|
|
|
|
start, end);
|
|
|
|
|
infoVos.add(new ShopTableSaleInfoVo(99999, shopTableSaleInfoDto.getShopId(), null, "", "收银台", null, null, null, null));
|
|
|
|
|
infoVoMap.put(dateKey, infoVos);
|
|
|
|
|
|
|
|
|
|
List<TbOrderSalesCountByTable> countByTables = tbOrderDetailRepository.queryTbOrderSalesCountByTable(
|
|
|
|
|
shopTableSaleInfoDto.getShopId(),
|
|
|
|
|
start, end);
|
|
|
|
|
|
|
|
|
|
if (countByTables != null && !countByTables.isEmpty()) {
|
|
|
|
|
Map<String, List<TbOrderSalesCountByTable>> ctMap = countByTables.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(TbOrderSalesCountByTable::getTableId));
|
|
|
|
|
|
|
|
|
|
ctMap.forEach((k, v) -> {
|
|
|
|
|
countByTableMap.put(dateKey + "-" + k, v);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ShopTableSaleInfoVo infoVo : infoVos) {
|
|
|
|
|
tableCodeSet.add(infoVo.getTableCode());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
countDownLatch.countDown();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
thread.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 等待所有线程完成
|
|
|
|
|
try {
|
|
|
|
|
countDownLatch.await();
|
|
|
|
|
|
|
|
|
|
System.out.println("所有线程执行完成");
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> finalDataList = new ArrayList<>();
|
|
|
|
|
List<List<Integer>> mergeList = new ArrayList<>();
|
|
|
|
|
Map<String, Integer> tableStartIndexMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 桌子 --- list【天--- list【商品】】
|
|
|
|
|
Map<String, Map<String, List<Map<String, Object>>>> dataList = new HashMap<>();
|
|
|
|
|
int rowIndex = 1;
|
|
|
|
|
for (ShopTableSaleInfoVo all : infoVos) {
|
|
|
|
|
List<TbOrderSalesCountByTable> tables = countByTableMap.get(all.getTableCode());
|
|
|
|
|
if (tables == null) {
|
|
|
|
|
continue;
|
|
|
|
|
// 用于记录每个日期首次出现的行索引
|
|
|
|
|
Map<String, Integer> dateFirstRowIndex = new HashMap<>();
|
|
|
|
|
for (String tableCode : tableCodeSet) {
|
|
|
|
|
Map<String, List<Map<String, Object>>> dayMap = new HashMap<>();
|
|
|
|
|
BigDecimal totalAmount = BigDecimal.ZERO;
|
|
|
|
|
List<Map<String, Object>> totalList = new ArrayList<>();
|
|
|
|
|
for (int i = 0; i < day; i++) {
|
|
|
|
|
DateTime date = cn.hutool.core.date.DateUtil.offsetDay(shopTableSaleInfoDto.getStartTime(), i);
|
|
|
|
|
String queryDate = cn.hutool.core.date.DateUtil.format(date, "yyyy-MM-dd");
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> maps = dayMap.computeIfAbsent(queryDate, k -> new ArrayList<>());
|
|
|
|
|
|
|
|
|
|
List<ShopTableSaleInfoVo> infoVos = infoVoMap.get(queryDate);
|
|
|
|
|
if (infoVos == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (ShopTableSaleInfoVo infoVo : infoVos) {
|
|
|
|
|
String valueKey = queryDate + "-" + infoVo.getTableCode();
|
|
|
|
|
List<TbOrderSalesCountByTable> countByTables = countByTableMap.get(valueKey);
|
|
|
|
|
if (countByTables == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!tableCode.equals(infoVo.getTableCode())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BigDecimal total = BigDecimal.ZERO;
|
|
|
|
|
for (TbOrderSalesCountByTable table : countByTables) {
|
|
|
|
|
total = total.add(table.getSalesAmount().abs());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalAmount = totalAmount.add(total);
|
|
|
|
|
|
|
|
|
|
String dateRowKey = queryDate + tableCode;
|
|
|
|
|
|
|
|
|
|
for (TbOrderSalesCountByTable table : countByTables) {
|
|
|
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
|
|
|
map.put("台桌", infoVo.getTableName());
|
|
|
|
|
map.put("日期", queryDate);
|
|
|
|
|
map.put("商品分类", table.getCateName());
|
|
|
|
|
map.put("商品名称", table.getProductName());
|
|
|
|
|
map.put("单位", table.getUnitName());
|
|
|
|
|
map.put("商品规格", table.getProductSkuName());
|
|
|
|
|
map.put("销量", table.getSalesNum());
|
|
|
|
|
map.put("单价", table.getPrice());
|
|
|
|
|
map.put("金额", table.getSalesAmount());
|
|
|
|
|
map.put("销售额", total);
|
|
|
|
|
map.put("退单量", table.getRefNum());
|
|
|
|
|
map.put("退单额", table.getRefAmount());
|
|
|
|
|
maps.add(map);
|
|
|
|
|
totalList.add(map);
|
|
|
|
|
finalDataList.add(map);
|
|
|
|
|
|
|
|
|
|
// 记录每个日期首次出现的行索引
|
|
|
|
|
if (!dateFirstRowIndex.containsKey(dateRowKey)) {
|
|
|
|
|
dateFirstRowIndex.put(dateRowKey, finalDataList.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确定日期列的合并区域范围
|
|
|
|
|
if (dateFirstRowIndex.containsKey(dateRowKey)) {
|
|
|
|
|
int startRow = dateFirstRowIndex.get(dateRowKey);
|
|
|
|
|
int endRow = finalDataList.size();
|
|
|
|
|
if (endRow - startRow > 0) {
|
|
|
|
|
mergeList.add(Arrays.asList(startRow, endRow, 1, 1));
|
|
|
|
|
mergeList.add(Arrays.asList(startRow, endRow, 9, 9));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BigDecimal total = BigDecimal.ZERO;
|
|
|
|
|
for (TbOrderSalesCountByTable table : tables) {
|
|
|
|
|
total = total.add(table.getSalesAmount().abs());
|
|
|
|
|
if (finalDataList.size() - rowIndex > 0) {
|
|
|
|
|
mergeList.add(Arrays.asList(rowIndex, finalDataList.size(), 0, 0));
|
|
|
|
|
mergeList.add(Arrays.asList(rowIndex, finalDataList.size(), 10, 10));
|
|
|
|
|
}
|
|
|
|
|
rowIndex = finalDataList.size() + 1;
|
|
|
|
|
|
|
|
|
|
for (Map<String, Object> map : totalList) {
|
|
|
|
|
map.put("总销售额", totalAmount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String tableCode = all.getTableName().toString();
|
|
|
|
|
if (!tableStartIndexMap.containsKey(tableCode)) {
|
|
|
|
|
tableStartIndexMap.put(tableCode, rowIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (TbOrderSalesCountByTable table : tables) {
|
|
|
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
|
|
|
map.put("日期", queryDate);
|
|
|
|
|
map.put("台桌", all.getTableName());
|
|
|
|
|
map.put("商品分类", table.getCateName());
|
|
|
|
|
map.put("商品名称", table.getProductName());
|
|
|
|
|
map.put("单位", table.getUnitName());
|
|
|
|
|
map.put("商品规格", table.getProductSkuName());
|
|
|
|
|
map.put("销量", table.getSalesNum());
|
|
|
|
|
map.put("单价", table.getPrice());
|
|
|
|
|
map.put("金额", table.getSalesAmount());
|
|
|
|
|
map.put("销售额", total);
|
|
|
|
|
map.put("退单量", table.getRefNum());
|
|
|
|
|
map.put("退单额", table.getRefAmount());
|
|
|
|
|
list.add(map);
|
|
|
|
|
rowIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int start = tableStartIndexMap.get(tableCode);
|
|
|
|
|
int end = rowIndex - 1;
|
|
|
|
|
if (end - start > 0) {
|
|
|
|
|
mergeList.add(Arrays.asList(start, end, 0, 0));
|
|
|
|
|
mergeList.add(Arrays.asList(start, end, 1, 1));
|
|
|
|
|
mergeList.add(Arrays.asList(start, end, 9, 9));
|
|
|
|
|
}
|
|
|
|
|
dataList.put(tableCode, dayMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<String> keyList = new ArrayList<>();
|
|
|
|
|
keyList.add("日期");
|
|
|
|
|
keyList.add("台桌");
|
|
|
|
|
keyList.add("日期");
|
|
|
|
|
keyList.add("商品分类");
|
|
|
|
|
keyList.add("商品名称");
|
|
|
|
|
keyList.add("单位");
|
|
|
|
|
@ -559,9 +649,10 @@ public class SummaryServiceImpl implements SummaryService {
|
|
|
|
|
keyList.add("单价");
|
|
|
|
|
keyList.add("金额");
|
|
|
|
|
keyList.add("销售额");
|
|
|
|
|
keyList.add("总销售额");
|
|
|
|
|
keyList.add("退单量");
|
|
|
|
|
keyList.add("退单额");
|
|
|
|
|
|
|
|
|
|
FileUtil.downloadAndMergeExcel(list, mergeList, keyList, response);
|
|
|
|
|
FileUtil.downloadAndMergeExcel(finalDataList, mergeList, keyList, response);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|