Merge branch 'refs/heads/gyj' into dev
This commit is contained in:
@@ -248,7 +248,18 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||||||
Row row = sheet.createRow(i + 1);
|
Row row = sheet.createRow(i + 1);
|
||||||
for (int j = 0; j < keyList.size(); j++) {
|
for (int j = 0; j < keyList.size(); j++) {
|
||||||
Cell cell = row.createCell(j);
|
Cell cell = row.createCell(j);
|
||||||
cell.setCellValue(map.get(keyList.get(j)) == null ? "" : map.get(keyList.get(j)).toString());
|
String value = map.get(keyList.get(j)) == null ? "" : map.get(keyList.get(j)).toString();
|
||||||
|
cell.setCellValue(value);
|
||||||
|
|
||||||
|
if (j == 11 && !"0".equals(value)) {
|
||||||
|
cell.setCellValue("-" + value);
|
||||||
|
setCellBackground(cell, IndexedColors.YELLOW, workbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == 12 && !"0.00".equals(value)) {
|
||||||
|
cell.setCellValue("-" + value);
|
||||||
|
setCellBackground(cell, IndexedColors.YELLOW, workbook);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +279,13 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setCellBackground(Cell cell, IndexedColors color, Workbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
style.setFillForegroundColor(color.getIndex());
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
cell.setCellStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入标题到excel
|
* 输入标题到excel
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package cn.ysk.cashier.controller.shop;
|
package cn.ysk.cashier.controller.shop;
|
||||||
|
|
||||||
import cn.ysk.cashier.annotation.rest.AnonymousGetMapping;
|
|
||||||
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
|
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
|
||||||
import cn.ysk.cashier.dto.BaseQueryDto;
|
import cn.ysk.cashier.dto.BaseQueryDto;
|
||||||
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;
|
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package cn.ysk.cashier.dto.shop;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yijiegong
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class ExportTableStsDataDto {
|
|
||||||
private String dateStr;
|
|
||||||
|
|
||||||
private List<Map<String, Object>> data;
|
|
||||||
|
|
||||||
private List<List<Integer>> mergeCells;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package cn.ysk.cashier.service.impl;
|
package cn.ysk.cashier.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.ysk.cashier.dto.ShopSummaryDto;
|
|
||||||
import cn.ysk.cashier.dto.BaseQueryDto;
|
import cn.ysk.cashier.dto.BaseQueryDto;
|
||||||
|
import cn.ysk.cashier.dto.ShopSummaryDto;
|
||||||
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;
|
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;
|
||||||
import cn.ysk.cashier.enums.PayTypeEnum;
|
import cn.ysk.cashier.enums.PayTypeEnum;
|
||||||
import cn.ysk.cashier.exception.BadRequestException;
|
import cn.ysk.cashier.exception.BadRequestException;
|
||||||
@@ -35,6 +36,7 @@ import java.time.Instant;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -179,7 +181,6 @@ public class SummaryServiceImpl implements SummaryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@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);
|
Pageable pageable = PageRequest.of(page, size);
|
||||||
@@ -438,56 +439,119 @@ public class SummaryServiceImpl implements SummaryService {
|
|||||||
@Override
|
@Override
|
||||||
public void downloadTableSaleInfo(ShopTableSaleInfoDto shopTableSaleInfoDto, HttpServletResponse response) throws IOException {
|
public void downloadTableSaleInfo(ShopTableSaleInfoDto shopTableSaleInfoDto, HttpServletResponse response) throws IOException {
|
||||||
if (shopTableSaleInfoDto.getStartTime() == null) {
|
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) {
|
if (shopTableSaleInfoDto.getEndTime() == null) {
|
||||||
shopTableSaleInfoDto.setEndTime(new Date());
|
shopTableSaleInfoDto.setEndTime(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ShopTableSaleInfoVo> infoVos = selectSummaryTable(shopTableSaleInfoDto.getShopId(), shopTableSaleInfoDto.getStartTime(), shopTableSaleInfoDto.getEndTime());
|
// 计算开始时间和结束时间相差天数
|
||||||
|
long diff = shopTableSaleInfoDto.getEndTime().getTime() - shopTableSaleInfoDto.getStartTime().getTime();
|
||||||
infoVos.add(new ShopTableSaleInfoVo(99999, shopTableSaleInfoDto.getShopId(), null, "", "收银台", null, null, null, null));
|
long day = diff / (1000 * 60 * 60 * 24) + 1;
|
||||||
|
if (day > 31) {
|
||||||
List<TbOrderSalesCountByTable> countByTables = tbOrderDetailRepository.queryTbOrderSalesCountByTable(shopTableSaleInfoDto.getShopId(), shopTableSaleInfoDto.getStartTime(), shopTableSaleInfoDto.getEndTime());
|
throw new BadRequestException("时间范围不能超过31天");
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
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<>();
|
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;
|
int rowIndex = 1;
|
||||||
for (ShopTableSaleInfoVo all : infoVos) {
|
// 用于记录每个日期首次出现的行索引
|
||||||
List<TbOrderSalesCountByTable> tables = countByTableMap.get(all.getTableCode());
|
Map<String, Integer> dateFirstRowIndex = new HashMap<>();
|
||||||
if (tables == null) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal total = BigDecimal.ZERO;
|
BigDecimal total = BigDecimal.ZERO;
|
||||||
for (TbOrderSalesCountByTable table : tables) {
|
for (TbOrderSalesCountByTable table : countByTables) {
|
||||||
total = total.add(table.getSalesAmount().abs());
|
total = total.add(table.getSalesAmount().abs());
|
||||||
}
|
}
|
||||||
|
|
||||||
String tableCode = all.getTableName().toString();
|
totalAmount = totalAmount.add(total);
|
||||||
if (!tableStartIndexMap.containsKey(tableCode)) {
|
|
||||||
tableStartIndexMap.put(tableCode, rowIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TbOrderSalesCountByTable table : tables) {
|
String dateRowKey = queryDate + tableCode;
|
||||||
|
|
||||||
|
for (TbOrderSalesCountByTable table : countByTables) {
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
map.put("台桌", infoVo.getTableName());
|
||||||
map.put("日期", queryDate);
|
map.put("日期", queryDate);
|
||||||
map.put("台桌", all.getTableName());
|
|
||||||
map.put("商品分类", table.getCateName());
|
map.put("商品分类", table.getCateName());
|
||||||
map.put("商品名称", table.getProductName());
|
map.put("商品名称", table.getProductName());
|
||||||
map.put("单位", table.getUnitName());
|
map.put("单位", table.getUnitName());
|
||||||
@@ -498,22 +562,47 @@ public class SummaryServiceImpl implements SummaryService {
|
|||||||
map.put("销售额", total);
|
map.put("销售额", total);
|
||||||
map.put("退单量", table.getRefNum());
|
map.put("退单量", table.getRefNum());
|
||||||
map.put("退单额", table.getRefAmount());
|
map.put("退单额", table.getRefAmount());
|
||||||
list.add(map);
|
maps.add(map);
|
||||||
rowIndex++;
|
totalList.add(map);
|
||||||
|
finalDataList.add(map);
|
||||||
|
|
||||||
|
// 记录每个日期首次出现的行索引
|
||||||
|
if (!dateFirstRowIndex.containsKey(dateRowKey)) {
|
||||||
|
dateFirstRowIndex.put(dateRowKey, finalDataList.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int start = tableStartIndexMap.get(tableCode);
|
// 确定日期列的合并区域范围
|
||||||
int end = rowIndex - 1;
|
if (dateFirstRowIndex.containsKey(dateRowKey)) {
|
||||||
if (end - start > 0) {
|
int startRow = dateFirstRowIndex.get(dateRowKey);
|
||||||
mergeList.add(Arrays.asList(start, end, 0, 0));
|
int endRow = finalDataList.size();
|
||||||
mergeList.add(Arrays.asList(start, end, 1, 1));
|
if (endRow - startRow > 0) {
|
||||||
mergeList.add(Arrays.asList(start, end, 9, 9));
|
mergeList.add(Arrays.asList(startRow, endRow, 1, 1));
|
||||||
|
mergeList.add(Arrays.asList(startRow, endRow, 9, 9));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList.put(tableCode, dayMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<String> keyList = new ArrayList<>();
|
List<String> keyList = new ArrayList<>();
|
||||||
keyList.add("日期");
|
|
||||||
keyList.add("台桌");
|
keyList.add("台桌");
|
||||||
|
keyList.add("日期");
|
||||||
keyList.add("商品分类");
|
keyList.add("商品分类");
|
||||||
keyList.add("商品名称");
|
keyList.add("商品名称");
|
||||||
keyList.add("单位");
|
keyList.add("单位");
|
||||||
@@ -522,9 +611,10 @@ public class SummaryServiceImpl implements SummaryService {
|
|||||||
keyList.add("单价");
|
keyList.add("单价");
|
||||||
keyList.add("金额");
|
keyList.add("金额");
|
||||||
keyList.add("销售额");
|
keyList.add("销售额");
|
||||||
|
keyList.add("总销售额");
|
||||||
keyList.add("退单量");
|
keyList.add("退单量");
|
||||||
keyList.add("退单额");
|
keyList.add("退单额");
|
||||||
|
|
||||||
FileUtil.downloadAndMergeExcel(list, mergeList, keyList, response);
|
FileUtil.downloadAndMergeExcel(finalDataList, mergeList, keyList, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
package cn.ysk.cashier.utils;
|
|
||||||
|
|
||||||
import cn.ysk.cashier.dto.shop.ExportTableStsDataDto;
|
|
||||||
import org.apache.poi.ss.usermodel.*;
|
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yijiegong
|
|
||||||
*/
|
|
||||||
public class FileUtils {
|
|
||||||
/**
|
|
||||||
* 该方法用于导出台桌数据统计,不通用
|
|
||||||
*/
|
|
||||||
public static void downloadTableDataStsToExcel(List<ExportTableStsDataDto> dataList, List<String> keyList, HttpServletResponse response) throws IOException {
|
|
||||||
// String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
|
|
||||||
// 创建工作簿
|
|
||||||
Workbook workbook = new XSSFWorkbook();
|
|
||||||
|
|
||||||
for (ExportTableStsDataDto exportTableStsDataDto : dataList) {
|
|
||||||
|
|
||||||
Sheet sheet = workbook.createSheet(exportTableStsDataDto.getDateStr());
|
|
||||||
|
|
||||||
for (List<Integer> mergeDatum : exportTableStsDataDto.getMergeCells()) {
|
|
||||||
sheet.addMergedRegion(new CellRangeAddress(mergeDatum.get(0), mergeDatum.get(1), mergeDatum.get(2), mergeDatum.get(3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Row row0 = sheet.createRow(0);
|
|
||||||
for (int i = 0; i < keyList.size(); i++) {
|
|
||||||
Cell cell = row0.createCell(i);
|
|
||||||
cell.setCellValue(keyList.get(i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < exportTableStsDataDto.getData().size(); i++) {
|
|
||||||
Map<String, Object> map = exportTableStsDataDto.getData().get(i);
|
|
||||||
Row row = sheet.createRow(i + 1);
|
|
||||||
for (int j = 0; j < keyList.size(); j++) {
|
|
||||||
Cell cell = row.createCell(j);
|
|
||||||
String value = map.get(keyList.get(j)) == null ? "" : map.get(keyList.get(j)).toString();
|
|
||||||
cell.setCellValue(value);
|
|
||||||
|
|
||||||
if (j == 10 && !"0".equals(value)) {
|
|
||||||
cell.setCellValue("-" + value);
|
|
||||||
setCellBackground(cell, IndexedColors.YELLOW, workbook);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == 11 && !"0.00".equals(value)) {
|
|
||||||
cell.setCellValue("-" + value);
|
|
||||||
setCellBackground(cell, IndexedColors.YELLOW, workbook);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// response为HttpServletResponse对象
|
|
||||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
|
|
||||||
response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
|
|
||||||
|
|
||||||
try (ServletOutputStream out = response.getOutputStream()) {
|
|
||||||
workbook.write(out);
|
|
||||||
out.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setCellBackground(Cell cell, IndexedColors color, Workbook workbook) {
|
|
||||||
CellStyle style = workbook.createCellStyle();
|
|
||||||
style.setFillForegroundColor(color.getIndex());
|
|
||||||
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
||||||
cell.setCellStyle(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user