Merge remote-tracking branch 'origin/test' into test

This commit is contained in:
Tankaikai 2024-10-31 14:47:48 +08:00
commit 7691a967b4
15 changed files with 346 additions and 265 deletions

View File

@ -248,7 +248,18 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
Row row = sheet.createRow(i + 1);
for (int j = 0; j < keyList.size(); 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
*

View File

@ -1,6 +1,5 @@
package cn.ysk.cashier.controller.shop;
import cn.ysk.cashier.annotation.rest.AnonymousGetMapping;
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
import cn.ysk.cashier.dto.BaseQueryDto;
import cn.ysk.cashier.dto.shop.ShopTableSaleInfoDto;

View File

@ -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;
}

View File

@ -4,6 +4,8 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@Data
public class CreateOrderDTO {
@ -18,4 +20,8 @@ public class CreateOrderDTO {
@NotEmpty
private String useType;
private String vipUserId;
// 使用的优惠券
private List<Integer> userCouponIds = new ArrayList<>();
// 使用的积分抵扣数量
private Integer pointsNum ;
}

View File

@ -1,6 +1,7 @@
package cn.ysk.cashier.mybatis.service;
import cn.ysk.cashier.cons.TableConstant;
import cn.ysk.cashier.dto.shoptable.ShopEatTypeInfoDTO;
import cn.ysk.cashier.enums.OrderStatusEnums;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import com.baomidou.mybatisplus.extension.service.IService;
@ -55,5 +56,13 @@ public interface MpCashierCartService extends IService<TbCashierCart> {
* @param orderId 订单id
*/
boolean updateStateByOrderId(TableConstant.OrderInfo.Status status, Integer orderId);
/**
* 根据店就餐模式查询购物车
* @param shopEatTypeInfoDTO 就餐模式
* @return 购物车信息
*/
List<TbCashierCart> selectByShopEatType(ShopEatTypeInfoDTO shopEatTypeInfoDTO, String masterId);
}

View File

@ -42,5 +42,13 @@ public interface MpOrderDetailService extends IService<TbOrderDetail> {
*/
List<TbOrderDetail> selectByOrderId(Integer orderId);
/**
* 根据购物车id和订单id查询订单详情
* @param shopId 店铺id
* @param cartIdList 购物车id
* @param orderId 订单id
* @return 详情信息
*/
List<TbOrderDetail> selectByCartIdOrOrderId(Integer shopId, ArrayList<Integer> cartIdList, Integer orderId);
}

View File

@ -3,16 +3,16 @@ package cn.ysk.cashier.mybatis.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.cons.TableConstant;
import cn.ysk.cashier.enums.OrderStatusEnums;
import cn.ysk.cashier.enums.OrderUseTypeEnum;
import cn.ysk.cashier.enums.ShopInfoEatModelEnum;
import cn.ysk.cashier.enums.ShopInfoRegisterlEnum;
import cn.ysk.cashier.dto.shoptable.ShopEatTypeInfoDTO;
import cn.ysk.cashier.enums.*;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.mapper.MpShopInfoMapper;
import cn.ysk.cashier.mybatis.mapper.MpShopTableMapper;
import cn.ysk.cashier.mybatis.mapper.TbCashierCartMapper;
import cn.ysk.cashier.mybatis.service.MpCashierCartService;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -32,8 +32,11 @@ import java.util.List;
public class MpCashierCartServiceImpl extends ServiceImpl<TbCashierCartMapper, TbCashierCart> implements MpCashierCartService {
private final MpShopInfoMapper mpShopInfoMapper;
public MpCashierCartServiceImpl(MpShopInfoMapper mpShopInfoMapper) {
private final MpShopTableMapper shopTableMapper;
public MpCashierCartServiceImpl(MpShopInfoMapper mpShopInfoMapper, MpShopTableMapper shopTableMapper) {
this.mpShopInfoMapper = mpShopInfoMapper;
this.shopTableMapper = shopTableMapper;
}
@Override
@ -93,5 +96,31 @@ public class MpCashierCartServiceImpl extends ServiceImpl<TbCashierCartMapper, T
.eq(TbCashierCart::getOrderId, orderId)
.set(TbCashierCart::getStatus, status.getValue()));
}
@Override
public List<TbCashierCart> selectByShopEatType(ShopEatTypeInfoDTO shopEatTypeInfoDTO, String masterId) {
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getShopId, shopEatTypeInfoDTO.getShopId())
.eq(TbCashierCart::getUseType, shopEatTypeInfoDTO.getUseType())
.in(TbCashierCart::getStatus, "create", "return")
.gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
.and(q -> q.eq(TbCashierCart::getMasterId, masterId).or().isNull(TbCashierCart::getMasterId));
// 非堂食校验台桌状态
TbShopTable tbShopTable;
if (shopEatTypeInfoDTO.isTakeout()) {
queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""))
.in(TbCashierCart::getPlatformType, OrderPlatformTypeEnum.PC.getValue(), OrderPlatformTypeEnum.CASH.getValue());
} else {
if (StrUtil.isNotBlank(shopEatTypeInfoDTO.getTableId())) {
queryWrapper.eq(TbCashierCart::getTableId, shopEatTypeInfoDTO.getTableId());
} else {
queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""));
}
}
return list(queryWrapper);
}
}

View File

@ -46,5 +46,12 @@ public class MpOrderDetailServiceImpl extends ServiceImpl<TbOrderDetailMapper, T
return list(new LambdaQueryWrapper<TbOrderDetail>()
.eq(TbOrderDetail::getOrderId, orderId));
}
@Override
public List<TbOrderDetail> selectByCartIdOrOrderId(Integer shopId, ArrayList<Integer> cartIdList, Integer orderId) {
return list(new LambdaQueryWrapper<TbOrderDetail>()
.and(q -> q.in(TbOrderDetail::getCartId, cartIdList).or().eq(TbOrderDetail::getOrderId, orderId))
.eq(TbOrderDetail::getShopId, shopId));
}
}

View File

@ -240,6 +240,16 @@ public class TbOrderInfo implements Serializable {
@Column(name = "`refund_remark`")
private String refundRemark;
// 积分折扣金额
private BigDecimal pointsDiscountAmount;
// 使用的积分数量
private Integer pointsNum;
// 用户优惠券id
private String activateInInfoList;
// 优惠券折扣金额
private BigDecimal activateInDiscountAmount;
public void copy(TbOrderInfo source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}

View File

@ -207,7 +207,7 @@ public interface TbOrderDetailRepository extends JpaRepository<TbOrderDetail, In
"LEFT JOIN TbShopCategory cate ON cate.id = pro.categoryId " +
"WHERE info.shopId = :shopId " +
"AND info.createTime > :startTime AND info.createTime < :endTime " +
"AND (info.status = 'closed' OR info.status = 'refund') " +
"AND (orders.status = 'closed' OR orders.orderType = 'return') " +
"GROUP BY info.productId, info.productSkuId, orders.tableId " +
"ORDER BY salesNum DESC")
List<TbOrderSalesCountByTable> queryTbOrderSalesCountByTable(@Param("shopId") Integer shopId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);

View File

@ -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);
}
}

View File

@ -329,14 +329,8 @@ public class TbOrderInfoServiceImpl implements TbOrderInfoService {
.eq(TbOrderDetail::getOrderId, id)
.eq(TbOrderDetail::getProductId, TableConstant.CART_SEAT_ID)
.orderByDesc(TbOrderDetail::getId));
TbOrderDetail cashierCart = tbCashierCarts.isEmpty() ? null : tbCashierCarts.get(0);
Map<String, Object> map = BeanUtil.beanToMap(cashierCart, false, false);
if (cashierCart != null) {
map.put("cartId", cashierCart.getCartId());
TbOrderDetail orderDetail = details.stream().filter(item -> item.getCartId().equals(cashierCart.getId())).findFirst().orElse(null);
map.put("id", orderDetail != null ? orderDetail.getId() : null);
}
dto.setSeatInfo(map);
TbOrderDetail cashierDetail = tbCashierCarts.isEmpty() ? null : tbCashierCarts.get(0);
dto.setSeatInfo(cashierDetail);
Map<String, Object> data = BeanUtil.beanToMap(tbOrderInfo, false, false);
data.putAll(BeanUtil.beanToMap(dto, false, false));
data.put("refundAmount", tbOrderInfo.getRefundAmount());

View File

@ -11,6 +11,7 @@ import cn.ysk.cashier.config.security.security.TokenProvider;
import cn.ysk.cashier.cons.RedisConstant;
import cn.ysk.cashier.cons.TableConstant;
import cn.ysk.cashier.cons.rabbit.RabbitConstants;
import cn.ysk.cashier.dto.points.OrderDeductionPointsDTO;
import cn.ysk.cashier.dto.shop.TbShopTableDto;
import cn.ysk.cashier.dto.shop.TbShopTableQueryCriteria;
import cn.ysk.cashier.dto.shoptable.*;
@ -18,10 +19,7 @@ import cn.ysk.cashier.enums.*;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.shop.TbShopTableMapper;
import cn.ysk.cashier.mybatis.mapper.*;
import cn.ysk.cashier.mybatis.service.MpCashierCartService;
import cn.ysk.cashier.mybatis.service.MpOrderDetailService;
import cn.ysk.cashier.mybatis.service.MpOrderInfoService;
import cn.ysk.cashier.mybatis.service.MpShopTableService;
import cn.ysk.cashier.mybatis.service.*;
import cn.ysk.cashier.pojo.TbShopPayType;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
@ -98,6 +96,8 @@ public class TbShopTableServiceImpl implements TbShopTableService {
private final MpShopTableService mpShopTableService;
private final MpShopUnitMapper mpShopUnitMapper;
private final MpProductStockDetailMapper mpProductStockDetailMapper;
private final TbMemberPointsService memberPointsService;
private final TbShopCouponService shopCouponService;
/**
@ -1107,53 +1107,35 @@ public class TbShopTableServiceImpl implements TbShopTableService {
TbShopInfo shopInfo = shopInfoRepository.findById(createOrderDTO.getShopId()).orElse(null);
if (shopInfo == null) throw new BadRequestException("店铺信息不存在");
// 非堂食校验台桌状态
TbShopTable tbShopTable = null;
if (StrUtil.isNotBlank(createOrderDTO.getTableId())) {
tbShopTable = mpShopTableMapper.selectOne(new LambdaQueryWrapper<TbShopTable>()
.eq(TbShopTable::getQrcode, createOrderDTO.getTableId())
.in(TbShopTable::getStatus, "idle", "using"));
if (tbShopTable == null) {
throw new BadRequestException("台桌未开台或不存在");
}
}
// 就餐模式信息
ShopEatTypeInfoDTO shopEatTypeInfoDTO = checkEatModel(createOrderDTO.getShopId(), createOrderDTO.getTableId(), createOrderDTO.getUseType());
// 传递orderId直接取否则取当前缓存id
Integer orderId = shopEatTypeInfoDTO.isDineInAfter() ?
getCurrentOrderId(shopEatTypeInfoDTO) : null;
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getShopId, createOrderDTO.getShopId())
.eq(TbCashierCart::getUseType, shopEatTypeInfoDTO.getUseType())
.in(TbCashierCart::getStatus, "create", "return")
.gt(TbCashierCart::getCreatedAt, DateUtil.offsetDay(DateUtil.date(), -1).getTime())
.and(q -> q.eq(TbCashierCart::getMasterId, createOrderDTO.getMasterId()).or().isNull(TbCashierCart::getMasterId));
// 非堂食校验台桌状态
TbShopTable tbShopTable = null;
if (shopEatTypeInfoDTO.isTakeout()) {
queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""))
.in(TbCashierCart::getPlatformType, OrderPlatformTypeEnum.PC.getValue(), OrderPlatformTypeEnum.CASH.getValue());
} else {
if (StrUtil.isNotBlank(createOrderDTO.getTableId())) {
tbShopTable = mpShopTableMapper.selectOne(new LambdaQueryWrapper<TbShopTable>()
.eq(TbShopTable::getQrcode, createOrderDTO.getTableId())
.in(TbShopTable::getStatus, "idle", "using"));
if (tbShopTable == null) {
throw new BadRequestException("台桌未开台或不存在");
}
queryWrapper.eq(TbCashierCart::getTableId, createOrderDTO.getTableId());
} else {
queryWrapper.and(q -> q.isNull(TbCashierCart::getTableId).or().eq(TbCashierCart::getTableId, ""));
}
}
List<TbCashierCart> allCashierCarts = cashierCartMapper
.selectList(queryWrapper);
List<TbCashierCart> allCashierCarts = mpCashierCartService.selectByShopEatType(shopEatTypeInfoDTO, createOrderDTO.getMasterId());
List<TbCashierCart> cashierCarts = new ArrayList<>();
TbCashierCart seatCart = null;
for (TbCashierCart allCashierCart : allCashierCarts) {
if (TableConstant.CART_SEAT_ID.equals(allCashierCart.getProductId())) {
seatCart = allCashierCart;
}
if (OrderStatusEnums.CREATE.getValue().equals(allCashierCart.getStatus())) {
cashierCarts.add(allCashierCart);
}
// if (OrderStatusEnums.CREATE.getValue().equals(allCashierCart.getStatus())) {
// cashierCarts.add(allCashierCart);
// }
cashierCarts.add(allCashierCart);
}
if (StrUtil.isNotBlank(createOrderDTO.getTableId())
@ -1175,12 +1157,8 @@ public class TbShopTableServiceImpl implements TbShopTableService {
cartIdList.add(tbCashierCart.getId());
}
// 查询历史orderDetail
Integer finalOrderId = orderId;
LambdaQueryWrapper<TbOrderDetail> query = new LambdaQueryWrapper<TbOrderDetail>()
.and(q -> q.in(TbOrderDetail::getCartId, cartIdList).or().eq(TbOrderDetail::getOrderId, finalOrderId))
.eq(TbOrderDetail::getShopId, createOrderDTO.getShopId());
List<TbOrderDetail> oldOrderDetailList = mpOrderDetailService.selectByCartIdOrOrderId(createOrderDTO.getShopId(), cartIdList, orderId);
List<TbOrderDetail> oldOrderDetailList = orderDetailMapper.selectList(query);
ArrayList<Integer> removeOrderDetailIds = new ArrayList<>();
ArrayList<TbOrderDetail> removeOrderDetailList = new ArrayList<>();
HashMap<String, TbOrderDetail> oldOrderDetailMap = new HashMap<>();
@ -1202,7 +1180,6 @@ public class TbShopTableServiceImpl implements TbShopTableService {
List<TbOrderDetail> orderDetails = new ArrayList<>();
List<TbOrderDetail> addOrderDetails = new ArrayList<>();
boolean hasNewInfo = false;
for (TbCashierCart cashierCart : cashierCarts) {
if (!"return".equals(cashierCart.getStatus())) {
@ -1238,7 +1215,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
orderDetail.setProductName(cashierCart.getName());
orderDetail.setShopId(Integer.valueOf(cashierCart.getShopId()));
orderDetail.setPackAmount(cashierCart.getPackFee());
orderDetail.setStatus("unpaid");
orderDetail.setStatus(TableConstant.CashierCart.Status.RETURN.equalsVals(cashierCart.getStatus()) ? cashierCart.getStatus() : "unpaid");
orderDetail.setUseType(shopEatTypeInfoDTO.getUseType());
orderDetail.setProductImg(cashierCart.getCoverImg());
orderDetail.setCartId(cashierCart.getId());
@ -1249,7 +1226,6 @@ public class TbShopTableServiceImpl implements TbShopTableService {
orderDetails.add(orderDetail);
}
// 查询订单
TbOrderInfo orderInfo = null;
if (orderId != null) {
@ -1274,7 +1250,6 @@ public class TbShopTableServiceImpl implements TbShopTableService {
orderInfo.setSettlementAmount(totalAmount);
orderInfo.setAmount(totalAmount);
orderInfo.setOriginAmount(totalAmount);
// orderInfo.setStatus("unpaid");
orderInfo.setOrderAmount(totalAmount);
orderInfo.setRemark(createOrderDTO.getNote());
orderInfo.setFreightAmount(feeAmount);
@ -1448,6 +1423,30 @@ public class TbShopTableServiceImpl implements TbShopTableService {
}
private void calculateOrderCouponAndPoints(TbOrderInfo orderInfo, List<Integer> userCouponList, Integer pointsNum) {
BigDecimal shouldPayAmount = BigDecimal.ZERO;
if (pointsNum != null) {
Long memberId = Long.valueOf(orderInfo.getMemberId());
OrderDeductionPointsDTO memberUsablePoints = memberPointsService.getMemberUsablePoints(memberId, orderInfo.getOrderAmount());
if (!memberUsablePoints.getUsable()) {
throw new BadRequestException(memberUsablePoints.getUnusableReason());
}
if (pointsNum < memberUsablePoints.getMinDeductionPoints() || pointsNum > memberUsablePoints.getMaxUsablePoints()) {
throw new BadRequestException("可抵扣积分区间为: [" + memberUsablePoints.getMinDeductionPoints() + "-" + memberUsablePoints.getMaxUsablePoints() + "]");
}
BigDecimal discountAmount = memberPointsService.calcDeductionAmount(memberId, orderInfo.getOrderAmount(), pointsNum);
orderInfo.setPointsNum(pointsNum);
orderInfo.setPointsDiscountAmount(discountAmount);
shouldPayAmount = shouldPayAmount.subtract(discountAmount);
memberPointsService.deductPoints(memberId, pointsNum, "霸王餐充值抵扣", Long.valueOf(orderInfo.getId()));
}
if (!userCouponList.isEmpty()) {
}
}
@Override
public Object pending(PendingDTO pendingDTO) {
@ -1769,15 +1768,14 @@ public class TbShopTableServiceImpl implements TbShopTableService {
.in(TbCashierCart::getPlatformType, OrderPlatformTypeEnum.PC.getValue(), OrderPlatformTypeEnum.CASH.getValue());
}
TbShopUser shopUser = tbShopUserMapper.selectById(updateVipDTO.getVipUserId());
if (shopUser == null) {
throw new BadRequestException("用户信息不存在");
}
List<TbCashierCart> tbCashierCarts = cashierCartMapper.selectList(queryWrapper.isNotNull(TbCashierCart::getOrderId));
if (!tbCashierCarts.isEmpty()) {
Integer orderId = tbCashierCarts.get(0).getOrderId();
if (updateVipDTO.getType() == 0) {
TbShopUser shopUser = tbShopUserMapper.selectById(updateVipDTO.getVipUserId());
if (shopUser == null) {
throw new BadRequestException("用户信息不存在");
}
return orderInfoMapper.update(null, new LambdaUpdateWrapper<TbOrderInfo>()
.eq(TbOrderInfo::getId, orderId)
.set(TbOrderInfo::getUserId, shopUser.getUserId())
@ -1786,7 +1784,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
return orderInfoMapper.update(null, new LambdaUpdateWrapper<TbOrderInfo>()
.eq(TbOrderInfo::getId, orderId)
.set(TbOrderInfo::getUserId, null)
.set(TbOrderInfo::getUserId, null));
.set(TbOrderInfo::getMemberId, null));
}
}
return true;
@ -1904,6 +1902,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
tbCashierCart.setUseType(choseCountDTO.getUseType());
tbCashierCartMapper.insert(tbCashierCart);
} else {
tbCashierCart.setStatus(TableConstant.CashierCart.Status.CREATE.getValue());
tbCashierCart.setTotalAmount(new BigDecimal(choseCountDTO.getNum()).multiply(shopInfo.getTableFee()));
tbCashierCart.setNumber(choseCountDTO.getNum());
tbCashierCart.setTotalNumber(choseCountDTO.getNum());

View File

@ -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);
}
}

View File

@ -61,4 +61,11 @@ public class TbOrderSalesCountByTable {
salesNum=salesNum-refNum;
salesAmount=salesAmount.subtract(refAmount);
}
public String getTableId() {
if (tableId == null) {
return "";
}
return tableId;
}
}