统计
This commit is contained in:
@@ -124,7 +124,7 @@ public class OrderDetailDTO implements Serializable {
|
||||
private String discountSaleNote;
|
||||
|
||||
/**
|
||||
* 状态: wait-pay 待支付;in-production 制作中;wait-out 待取餐;refunding 退款中; part-refund 部分退单; refund-退单; done 完成;
|
||||
* 状态: wait-pay 待支付;in-production 制作中;wait_out 待取餐;refunding 退款中; part_refund 部分退单; refund-退单; done 完成;
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package com.czg.account.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Date;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
@Data
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_prod_statistic")
|
||||
public class ShopProdStatistic implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品id
|
||||
*/
|
||||
private Long prodId;
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
*/
|
||||
private Long saleNum;
|
||||
|
||||
/**
|
||||
* 销售金额
|
||||
*/
|
||||
private BigDecimal saleAmount;
|
||||
|
||||
/**
|
||||
* 退单量
|
||||
*/
|
||||
private Long refundNum;
|
||||
|
||||
/**
|
||||
* 退单金额
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createDay;
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import java.util.List;
|
||||
*/
|
||||
public interface ShopInfoService extends IService<ShopInfo> {
|
||||
|
||||
@Override
|
||||
ShopInfo getById(Serializable id) throws CzgException;
|
||||
Page<ShopInfo> get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop);
|
||||
|
||||
@@ -40,4 +41,11 @@ public interface ShopInfoService extends IService<ShopInfo> {
|
||||
List<ShopInfo> getByMainIdOrList(Long mainShopId, List<Long> shopIdList, String shopName);
|
||||
|
||||
BigDecimal updateAmount(Long id, BigDecimal amount);
|
||||
|
||||
/**
|
||||
* 获取所有未删除的 过期时间>三天前 店铺id列表
|
||||
*
|
||||
* @return 店铺id列表
|
||||
*/
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.czg.account.service;
|
||||
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-06
|
||||
*/
|
||||
public interface ShopProdStatisticService extends IService<ShopProdStatistic> {
|
||||
|
||||
Page<?> pageInfo(Long shopId, String name, String classifyId, String startTime, String endTime);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
//package com.czg.account.service;
|
||||
//
|
||||
//import com.czg.account.dto.ShopShareDTO;
|
||||
//import com.czg.account.vo.ShopShareRecordVO;
|
||||
//import com.czg.account.vo.ShopShareVO;
|
||||
//import com.mybatisflex.core.paginate.Page;
|
||||
//import com.mybatisflex.core.service.IService;
|
||||
//import com.czg.account.entity.ShopShare;
|
||||
//
|
||||
///**
|
||||
// * 店铺分享 服务层。
|
||||
// *
|
||||
// * @author zs
|
||||
// * @since 2025-03-05
|
||||
// */
|
||||
//public interface ShopShareService extends IService<ShopShare> {
|
||||
//
|
||||
// ShopShareVO get(Long shopId);
|
||||
//
|
||||
// Boolean add(Long shopId, ShopShareDTO shopShareDTO);
|
||||
//
|
||||
// Page<ShopShareRecordVO> recordPage(Long shopId, String key, Integer status);
|
||||
//}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.czg.account.vo;
|
||||
|
||||
import com.czg.account.entity.ShopProdStatistic;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ShopProdStatisticVO extends ShopProdStatistic {
|
||||
private String name;
|
||||
}
|
||||
@@ -63,6 +63,10 @@ public class OrderInfoDTO implements Serializable {
|
||||
* 抹零金额 减免多少钱
|
||||
*/
|
||||
private BigDecimal roundAmount;
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAllAmount;
|
||||
|
||||
/**
|
||||
* 订单金额 (扣除各类折扣)
|
||||
@@ -104,10 +108,10 @@ public class OrderInfoDTO implements Serializable {
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
|
||||
/**
|
||||
* 折扣比例
|
||||
*/
|
||||
private BigDecimal discountRatio;
|
||||
// /**
|
||||
// * 折扣比例
|
||||
// */
|
||||
// private BigDecimal discountRatio;
|
||||
|
||||
/**
|
||||
* 打包费
|
||||
@@ -161,7 +165,7 @@ public class OrderInfoDTO implements Serializable {
|
||||
private String payType;
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class OrderInfoQueryDTO implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public class OrderDetail implements Serializable {
|
||||
private String discountSaleNote;
|
||||
|
||||
/**
|
||||
* 状态: in-production 制作中;wait-out 待取餐;refunding 退款中; part-refund 部分退单; refund-退单; done 完成;
|
||||
* 状态: in-production 制作中;wait_out 待取餐;refunding 退款中; part_refund 部分退单; refund-退单; done 完成;
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -73,6 +73,10 @@ public class OrderInfo implements Serializable {
|
||||
* 订单金额 (扣除各类折扣)
|
||||
*/
|
||||
private BigDecimal orderAmount;
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAllAmount;
|
||||
|
||||
/**
|
||||
* 实际支付金额
|
||||
@@ -122,10 +126,10 @@ public class OrderInfo implements Serializable {
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
|
||||
/**
|
||||
* 折扣比例
|
||||
*/
|
||||
private BigDecimal discountRatio;
|
||||
// /**
|
||||
// * 折扣比例
|
||||
// */
|
||||
// private BigDecimal discountRatio;
|
||||
|
||||
/**
|
||||
* 打包费
|
||||
@@ -186,7 +190,7 @@ public class OrderInfo implements Serializable {
|
||||
|
||||
/**
|
||||
* {@link com.czg.service.order.enums.OrderStatusEnums}
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
@@ -319,4 +323,21 @@ public class OrderInfo implements Serializable {
|
||||
public BigDecimal getPackFee() {
|
||||
return packFee == null ? BigDecimal.ZERO : packFee;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算并设置所有优惠金额的总和
|
||||
*/
|
||||
public void initDiscountAllAmount() {
|
||||
this.discountAllAmount = BigDecimal.ZERO
|
||||
.add(this.getProductCouponDiscountAmount() != null ? this.getProductCouponDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getOtherCouponDiscountAmount() != null ? this.getOtherCouponDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getPointsDiscountAmount() != null ? this.getPointsDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getNewCustomerDiscountAmount() != null ? this.getNewCustomerDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getDiscountAmount() != null ? this.getDiscountAmount() : BigDecimal.ZERO)
|
||||
.add(this.getDiscountActAmount() != null ? this.getDiscountActAmount() : BigDecimal.ZERO)
|
||||
.add(this.getVipDiscountAmount() != null ? this.getVipDiscountAmount() : BigDecimal.ZERO);
|
||||
// 如果需要加上抹零金额,可以取消下面这行注释
|
||||
// .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.czg.order.entity;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@@ -15,13 +16,13 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
* 店铺订单统计报表 实体类。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
@Data
|
||||
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_order_statistic")
|
||||
@@ -30,151 +31,469 @@ public class ShopOrderStatistic implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 检查订单统计数据是否有效
|
||||
*
|
||||
* @param stat 订单统计数据
|
||||
* @return 是否有效
|
||||
*/
|
||||
public boolean hasValidData(ShopOrderStatistic stat) {
|
||||
if (stat == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查BigDecimal类型字段 检查Long类型字段
|
||||
return checkBigDecimalFields(stat) && checkLongFields(stat);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 初始化空白数据 标识为 无效数据 valid = false
|
||||
*/
|
||||
public void init() {
|
||||
this.valid = false;
|
||||
this.originAmount = zero;
|
||||
this.payAmount = zero;
|
||||
this.refundAmount = zero;
|
||||
this.onlineRefundAmount = zero;
|
||||
this.cashRefundAmount = zero;
|
||||
this.memberRefundAmount = zero;
|
||||
this.memberPayAmount = zero;
|
||||
this.memberPayCount = 0L;
|
||||
this.rechargeAmount = zero;
|
||||
this.onlineRechargeAmount = zero;
|
||||
this.cashRechargeAmount = zero;
|
||||
this.giveAmount = zero;
|
||||
this.rechargeRefundAmount = zero;
|
||||
this.onlineRechargeRefundAmount = zero;
|
||||
this.cashRechargeRefundAmount = zero;
|
||||
this.newMemberCount = 0L;
|
||||
this.customerCount = 0L;
|
||||
this.orderCount = 0L;
|
||||
this.tableCount = 0L;
|
||||
this.avgPayAmount = zero;
|
||||
this.turnoverRate = zero;
|
||||
this.profitAmount = zero;
|
||||
this.productCostAmount = zero;
|
||||
this.profitRate = zero;
|
||||
this.netProfitAmount = zero;
|
||||
this.netProfitRate = zero;
|
||||
this.discountAmount = zero;
|
||||
this.discountCount = 0L;
|
||||
this.newCustomerDiscountAmount = zero;
|
||||
this.fullDiscountAmount = zero;
|
||||
this.couponDiscountAmount = zero;
|
||||
this.pointDiscountAmount = zero;
|
||||
this.backDiscountAmount = zero;
|
||||
this.memberDiscountAmount = zero;
|
||||
this.orderPriceDiscountAmount = zero;
|
||||
this.onlinePayAmount = zero;
|
||||
this.cashPayAmount = zero;
|
||||
this.wechatPayAmount = zero;
|
||||
this.alipayPayAmount = zero;
|
||||
this.backScanPayAmount = zero;
|
||||
this.mainScanPayAmount = zero;
|
||||
this.creditPayAmount = zero;
|
||||
this.cashPayCount = 0L;
|
||||
this.wechatPayCount = 0L;
|
||||
this.alipayPayCount = 0L;
|
||||
this.backScanPayCount = 0L;
|
||||
this.mainScanPayCount = 0L;
|
||||
this.creditPayCount = 0L;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 销售额
|
||||
* 店铺id
|
||||
*/
|
||||
private BigDecimal saleAmount = BigDecimal.ZERO;
|
||||
private Long shopId;
|
||||
/**
|
||||
* 统计日期 yyyy-MM-dd
|
||||
*/
|
||||
private LocalDate statisticDate;
|
||||
//*********************以下为订单金额********************************************************************************
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
* 订单金额 订单原金额
|
||||
*/
|
||||
private Long saleCount = 0L;
|
||||
private BigDecimal originAmount;
|
||||
/**
|
||||
* 实付金额 (线上付款 现金支付 会员支付 挂账)
|
||||
*/
|
||||
private BigDecimal payAmount;
|
||||
/**
|
||||
* 线上付款金额
|
||||
*/
|
||||
private BigDecimal onlinePayAmount;
|
||||
/**
|
||||
* 订单退款 退款金额(原路返回 现金退款)
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
/**
|
||||
* 订单退款 线上退款金额
|
||||
*/
|
||||
private BigDecimal onlineRefundAmount;
|
||||
/**
|
||||
* 订单退款 线下退款金额/现金退款金额
|
||||
*/
|
||||
private BigDecimal cashRefundAmount;
|
||||
/**
|
||||
* 订单退款 会员退款金额
|
||||
*/
|
||||
private BigDecimal memberRefundAmount;
|
||||
|
||||
/**
|
||||
* 优惠金额
|
||||
* 会员消费 会员订单支付金额
|
||||
*/
|
||||
private BigDecimal discountAmount = BigDecimal.ZERO;
|
||||
private BigDecimal memberPayAmount;
|
||||
/**
|
||||
* 会员消费笔数
|
||||
*/
|
||||
private Long memberPayCount;
|
||||
|
||||
|
||||
//*********************以下为充值金额********************************************************************************
|
||||
/**
|
||||
* 会员充值 充值金额(包含现金支付) 不包括赠送 多店 按 主店算
|
||||
*/
|
||||
private BigDecimal rechargeAmount;
|
||||
/**
|
||||
* 会员充值 线上充值金额
|
||||
*/
|
||||
private BigDecimal onlineRechargeAmount;
|
||||
/**
|
||||
* 会员充值 现金充值金额
|
||||
*/
|
||||
private BigDecimal cashRechargeAmount;
|
||||
/**
|
||||
* 会员充值 充值赠送金额
|
||||
*/
|
||||
private BigDecimal giveAmount;
|
||||
|
||||
/**
|
||||
* 优惠笔数
|
||||
* 会员充值退款 充值退款金额(线上退款+现金退款)
|
||||
*/
|
||||
private Long discountCount = 0L;
|
||||
|
||||
private BigDecimal rechargeRefundAmount;
|
||||
/**
|
||||
* 退款金额
|
||||
* 会员充值退款 线上退款
|
||||
*/
|
||||
private BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
|
||||
private BigDecimal onlineRechargeRefundAmount;
|
||||
/**
|
||||
* 退款笔数
|
||||
* 会员充值退款 现金退款金额
|
||||
*/
|
||||
private Long refundCount = 0L;
|
||||
|
||||
/**
|
||||
* 微信支付笔数
|
||||
*/
|
||||
private Long wechatPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 微信支付金额
|
||||
*/
|
||||
private BigDecimal wechatPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 支付宝支付笔数
|
||||
*/
|
||||
private Long aliPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 支付宝支付金额
|
||||
*/
|
||||
private BigDecimal aliPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 挂账支付笔数
|
||||
*/
|
||||
private Long creditPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 挂账支付金额
|
||||
*/
|
||||
private BigDecimal creditPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 会员支付笔数
|
||||
*/
|
||||
private Long memberPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 会员支付金额
|
||||
*/
|
||||
private BigDecimal memberPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 主扫支付笔数
|
||||
*/
|
||||
private Long scanPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 主扫支付金额
|
||||
*/
|
||||
private BigDecimal scanPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 被扫支付笔数
|
||||
*/
|
||||
private Long backScanPayCount = 0L;
|
||||
|
||||
/**
|
||||
* 被扫支付金额
|
||||
*/
|
||||
private BigDecimal backScanPayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 被扫支付笔数
|
||||
*/
|
||||
private Long h5PayCount = 0L;
|
||||
|
||||
/**
|
||||
* 被扫支付金额
|
||||
*/
|
||||
private BigDecimal h5PayAmount = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 现金支付笔数
|
||||
*/
|
||||
private Long cashPayCount = 0L;
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
private BigDecimal cashPayAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 充值金额
|
||||
*/
|
||||
private BigDecimal rechargeAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 充值退款金额
|
||||
*/
|
||||
private BigDecimal rechargeRefundAmount = BigDecimal.ZERO;
|
||||
/**
|
||||
* 客单价
|
||||
*/
|
||||
private BigDecimal customerUnitPrice = BigDecimal.ZERO;
|
||||
/**
|
||||
* 翻台率
|
||||
*/
|
||||
private BigDecimal tableTurnoverRate = BigDecimal.ZERO;
|
||||
private BigDecimal cashRechargeRefundAmount;
|
||||
/**
|
||||
* 新增会员数
|
||||
*/
|
||||
private Long newMemberCount = 0L;
|
||||
private Long newMemberCount;
|
||||
|
||||
|
||||
//*********************以下为客单价 翻台率 的计算********************************************************************************
|
||||
/**
|
||||
* 店铺id
|
||||
* 就餐人数
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private Long shopId;
|
||||
private Long customerCount;
|
||||
/**
|
||||
* 订单数
|
||||
*/
|
||||
private Long orderCount;
|
||||
/**
|
||||
* 桌台数
|
||||
*/
|
||||
private Long tableCount;
|
||||
/**
|
||||
* 客单价
|
||||
* 实付金额(包含现金支付 包含会员支付 包含挂账)/就餐人数
|
||||
* 没有具体人数时,默认一桌按照1人计算
|
||||
*/
|
||||
private BigDecimal avgPayAmount;
|
||||
/**
|
||||
* 翻台率
|
||||
* (订单数-桌台数)/桌台数*100%
|
||||
*/
|
||||
private BigDecimal turnoverRate;
|
||||
|
||||
/**
|
||||
* 毛利润(订单实付金额-商品成本)
|
||||
*/
|
||||
private BigDecimal profitAmount;
|
||||
/**
|
||||
* 商品成本
|
||||
*/
|
||||
private BigDecimal productCostAmount;
|
||||
/**
|
||||
* 毛利率(订单实付金额-商品成本)/订单实付金额*100%
|
||||
*/
|
||||
private BigDecimal profitRate;
|
||||
/**
|
||||
* 净利润
|
||||
*/
|
||||
private BigDecimal netProfitAmount;
|
||||
/**
|
||||
* 净利润率
|
||||
*/
|
||||
private BigDecimal netProfitRate;
|
||||
|
||||
|
||||
//*********************以下为优惠金额********************************************************************************
|
||||
/**
|
||||
* 优惠总金额
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
/**
|
||||
* 优惠笔数
|
||||
*/
|
||||
private Long discountCount;
|
||||
|
||||
/**
|
||||
* 新客立减金额
|
||||
*/
|
||||
private BigDecimal newCustomerDiscountAmount;
|
||||
/**
|
||||
* 满减活动金额
|
||||
*/
|
||||
private BigDecimal fullDiscountAmount;
|
||||
/**
|
||||
* 优惠券抵扣金额
|
||||
*/
|
||||
private BigDecimal couponDiscountAmount;
|
||||
/**
|
||||
* 积分抵扣金额
|
||||
*/
|
||||
private BigDecimal pointDiscountAmount;
|
||||
/**
|
||||
* 霸王餐金额
|
||||
*/
|
||||
private BigDecimal backDiscountAmount;
|
||||
/**
|
||||
* 会员整单折扣金额
|
||||
*/
|
||||
private BigDecimal memberDiscountAmount;
|
||||
/**
|
||||
* 订单改价金额
|
||||
*/
|
||||
private BigDecimal orderPriceDiscountAmount;
|
||||
|
||||
|
||||
//*********************以下为支付金额********************************************************************************
|
||||
/**
|
||||
* 现金支付金额
|
||||
*/
|
||||
private BigDecimal cashPayAmount;
|
||||
/**
|
||||
* 现金支付笔数
|
||||
*/
|
||||
private Long cashPayCount;
|
||||
/**
|
||||
* 微信小程序支付金额
|
||||
*/
|
||||
private BigDecimal wechatPayAmount;
|
||||
/**
|
||||
* 微信小程序支付笔数
|
||||
*/
|
||||
private Long wechatPayCount;
|
||||
/**
|
||||
* 支付宝小程序支付金额
|
||||
*/
|
||||
private BigDecimal alipayPayAmount;
|
||||
/**
|
||||
* 支付宝小程序支付笔数
|
||||
*/
|
||||
private Long alipayPayCount;
|
||||
/**
|
||||
* 被扫收款金额
|
||||
*/
|
||||
private BigDecimal backScanPayAmount;
|
||||
/**
|
||||
* 被扫收款笔数
|
||||
*/
|
||||
private Long backScanPayCount;
|
||||
/**
|
||||
* 主扫收款金额
|
||||
*/
|
||||
private BigDecimal mainScanPayAmount;
|
||||
/**
|
||||
* 主扫收款笔数
|
||||
*/
|
||||
private Long mainScanPayCount;
|
||||
/**
|
||||
* 挂账支付金额
|
||||
*/
|
||||
private BigDecimal creditPayAmount;
|
||||
/**
|
||||
* 挂账支付笔数
|
||||
*/
|
||||
private Long creditPayCount;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(serialize = false, format = "yyyy-MM-dd")
|
||||
private LocalDate createDay;
|
||||
@Column(onInsertValue = "now()")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 最近一次统计时间
|
||||
* 更新时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Column(ignore = true)
|
||||
BigDecimal zero = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 是否有效
|
||||
*/
|
||||
@Column(ignore = true)
|
||||
private Boolean valid = true;
|
||||
|
||||
|
||||
private static boolean checkBigDecimalFields(ShopOrderStatistic stat) {
|
||||
return
|
||||
isGreaterThanZero(stat.getOriginAmount()) ||
|
||||
isGreaterThanZero(stat.getPayAmount()) ||
|
||||
isGreaterThanZero(stat.getRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberPayAmount()) ||
|
||||
isGreaterThanZero(stat.getRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRechargeAmount()) ||
|
||||
isGreaterThanZero(stat.getGiveAmount()) ||
|
||||
isGreaterThanZero(stat.getRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlineRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getCashRechargeRefundAmount()) ||
|
||||
isGreaterThanZero(stat.getAvgPayAmount()) ||
|
||||
isGreaterThanZero(stat.getTurnoverRate()) ||
|
||||
isGreaterThanZero(stat.getProfitAmount()) ||
|
||||
isGreaterThanZero(stat.getProductCostAmount()) ||
|
||||
isGreaterThanZero(stat.getProfitRate()) ||
|
||||
isGreaterThanZero(stat.getNetProfitAmount()) ||
|
||||
isGreaterThanZero(stat.getNetProfitRate()) ||
|
||||
isGreaterThanZero(stat.getDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getNewCustomerDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getFullDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getCouponDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getPointDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getBackDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getMemberDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getOrderPriceDiscountAmount()) ||
|
||||
isGreaterThanZero(stat.getOnlinePayAmount()) ||
|
||||
isGreaterThanZero(stat.getCashPayAmount()) ||
|
||||
isGreaterThanZero(stat.getWechatPayAmount()) ||
|
||||
isGreaterThanZero(stat.getAlipayPayAmount()) ||
|
||||
isGreaterThanZero(stat.getBackScanPayAmount()) ||
|
||||
isGreaterThanZero(stat.getMainScanPayAmount()) ||
|
||||
isGreaterThanZero(stat.getCreditPayAmount());
|
||||
}
|
||||
|
||||
private static boolean checkLongFields(ShopOrderStatistic stat) {
|
||||
return (stat.getMemberPayCount() != null && stat.getMemberPayCount() > 0) ||
|
||||
(stat.getNewMemberCount() != null && stat.getNewMemberCount() > 0) ||
|
||||
(stat.getCustomerCount() != null && stat.getCustomerCount() > 0) ||
|
||||
(stat.getOrderCount() != null && stat.getOrderCount() > 0) ||
|
||||
(stat.getTableCount() != null && stat.getTableCount() > 0) ||
|
||||
(stat.getDiscountCount() != null && stat.getDiscountCount() > 0) ||
|
||||
(stat.getCashPayCount() != null && stat.getCashPayCount() > 0) ||
|
||||
(stat.getWechatPayCount() != null && stat.getWechatPayCount() > 0) ||
|
||||
(stat.getAlipayPayCount() != null && stat.getAlipayPayCount() > 0) ||
|
||||
(stat.getBackScanPayCount() != null && stat.getBackScanPayCount() > 0) ||
|
||||
(stat.getMainScanPayCount() != null && stat.getMainScanPayCount() > 0) ||
|
||||
(stat.getCreditPayCount() != null && stat.getCreditPayCount() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并两个统计对象
|
||||
*/
|
||||
public static ShopOrderStatistic mergeStatistics(ShopOrderStatistic stat1, ShopOrderStatistic stat2) {
|
||||
if (stat2 == null) return stat1;
|
||||
if (stat1 == null) return stat2;
|
||||
|
||||
if(!stat2.getValid()) return stat1;
|
||||
if(!stat1.getValid()) return stat2;
|
||||
|
||||
ShopOrderStatistic result = new ShopOrderStatistic();
|
||||
|
||||
// 合并BigDecimal字段
|
||||
result.setOriginAmount(safeAdd(stat1.getOriginAmount(), stat2.getOriginAmount()));
|
||||
result.setPayAmount(safeAdd(stat1.getPayAmount(), stat2.getPayAmount()));
|
||||
result.setRefundAmount(safeAdd(stat1.getRefundAmount(), stat2.getRefundAmount()));
|
||||
result.setOnlineRefundAmount(safeAdd(stat1.getOnlineRefundAmount(), stat2.getOnlineRefundAmount()));
|
||||
result.setCashRefundAmount(safeAdd(stat1.getCashRefundAmount(), stat2.getCashRefundAmount()));
|
||||
result.setMemberRefundAmount(safeAdd(stat1.getMemberRefundAmount(), stat2.getMemberRefundAmount()));
|
||||
result.setMemberPayAmount(safeAdd(stat1.getMemberPayAmount(), stat2.getMemberPayAmount()));
|
||||
result.setRechargeAmount(safeAdd(stat1.getRechargeAmount(), stat2.getRechargeAmount()));
|
||||
result.setOnlineRechargeAmount(safeAdd(stat1.getOnlineRechargeAmount(), stat2.getOnlineRechargeAmount()));
|
||||
result.setCashRechargeAmount(safeAdd(stat1.getCashRechargeAmount(), stat2.getCashRechargeAmount()));
|
||||
result.setGiveAmount(safeAdd(stat1.getGiveAmount(), stat2.getGiveAmount()));
|
||||
result.setRechargeRefundAmount(safeAdd(stat1.getRechargeRefundAmount(), stat2.getRechargeRefundAmount()));
|
||||
result.setOnlineRechargeRefundAmount(safeAdd(stat1.getOnlineRechargeRefundAmount(), stat2.getOnlineRechargeRefundAmount()));
|
||||
result.setCashRechargeRefundAmount(safeAdd(stat1.getCashRechargeRefundAmount(), stat2.getCashRechargeRefundAmount()));
|
||||
result.setAvgPayAmount(safeAdd(stat1.getAvgPayAmount(), stat2.getAvgPayAmount()));
|
||||
result.setTurnoverRate(safeAdd(stat1.getTurnoverRate(), stat2.getTurnoverRate()));
|
||||
result.setProfitAmount(safeAdd(stat1.getProfitAmount(), stat2.getProfitAmount()));
|
||||
result.setProductCostAmount(safeAdd(stat1.getProductCostAmount(), stat2.getProductCostAmount()));
|
||||
result.setProfitRate(safeAdd(stat1.getProfitRate(), stat2.getProfitRate()));
|
||||
result.setNetProfitAmount(safeAdd(stat1.getNetProfitAmount(), stat2.getNetProfitAmount()));
|
||||
result.setNetProfitRate(safeAdd(stat1.getNetProfitRate(), stat2.getNetProfitRate()));
|
||||
result.setDiscountAmount(safeAdd(stat1.getDiscountAmount(), stat2.getDiscountAmount()));
|
||||
result.setNewCustomerDiscountAmount(safeAdd(stat1.getNewCustomerDiscountAmount(), stat2.getNewCustomerDiscountAmount()));
|
||||
result.setFullDiscountAmount(safeAdd(stat1.getFullDiscountAmount(), stat2.getFullDiscountAmount()));
|
||||
result.setCouponDiscountAmount(safeAdd(stat1.getCouponDiscountAmount(), stat2.getCouponDiscountAmount()));
|
||||
result.setPointDiscountAmount(safeAdd(stat1.getPointDiscountAmount(), stat2.getPointDiscountAmount()));
|
||||
result.setBackDiscountAmount(safeAdd(stat1.getBackDiscountAmount(), stat2.getBackDiscountAmount()));
|
||||
result.setMemberDiscountAmount(safeAdd(stat1.getMemberDiscountAmount(), stat2.getMemberDiscountAmount()));
|
||||
result.setOrderPriceDiscountAmount(safeAdd(stat1.getOrderPriceDiscountAmount(), stat2.getOrderPriceDiscountAmount()));
|
||||
result.setOnlinePayAmount(safeAdd(stat1.getOnlinePayAmount(), stat2.getOnlinePayAmount()));
|
||||
result.setCashPayAmount(safeAdd(stat1.getCashPayAmount(), stat2.getCashPayAmount()));
|
||||
result.setWechatPayAmount(safeAdd(stat1.getWechatPayAmount(), stat2.getWechatPayAmount()));
|
||||
result.setAlipayPayAmount(safeAdd(stat1.getAlipayPayAmount(), stat2.getAlipayPayAmount()));
|
||||
result.setBackScanPayAmount(safeAdd(stat1.getBackScanPayAmount(), stat2.getBackScanPayAmount()));
|
||||
result.setMainScanPayAmount(safeAdd(stat1.getMainScanPayAmount(), stat2.getMainScanPayAmount()));
|
||||
result.setCreditPayAmount(safeAdd(stat1.getCreditPayAmount(), stat2.getCreditPayAmount()));
|
||||
|
||||
// 合并Long字段
|
||||
result.setMemberPayCount(safeAdd(stat1.getMemberPayCount(), stat2.getMemberPayCount()));
|
||||
result.setNewMemberCount(safeAdd(stat1.getNewMemberCount(), stat2.getNewMemberCount()));
|
||||
result.setCustomerCount(safeAdd(stat1.getCustomerCount(), stat2.getCustomerCount()));
|
||||
result.setOrderCount(safeAdd(stat1.getOrderCount(), stat2.getOrderCount()));
|
||||
result.setTableCount(safeAdd(stat1.getTableCount(), stat2.getTableCount()));
|
||||
result.setDiscountCount(safeAdd(stat1.getDiscountCount(), stat2.getDiscountCount()));
|
||||
result.setCashPayCount(safeAdd(stat1.getCashPayCount(), stat2.getCashPayCount()));
|
||||
result.setWechatPayCount(safeAdd(stat1.getWechatPayCount(), stat2.getWechatPayCount()));
|
||||
result.setAlipayPayCount(safeAdd(stat1.getAlipayPayCount(), stat2.getAlipayPayCount()));
|
||||
result.setBackScanPayCount(safeAdd(stat1.getBackScanPayCount(), stat2.getBackScanPayCount()));
|
||||
result.setMainScanPayCount(safeAdd(stat1.getMainScanPayCount(), stat2.getMainScanPayCount()));
|
||||
result.setCreditPayCount(safeAdd(stat1.getCreditPayCount(), stat2.getCreditPayCount()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的BigDecimal相加
|
||||
*/
|
||||
private static BigDecimal safeAdd(BigDecimal num1, BigDecimal num2) {
|
||||
if (num1 == null) return num2;
|
||||
if (num2 == null) return num1;
|
||||
return num1.add(num2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的Long相加
|
||||
*/
|
||||
private static Long safeAdd(Long num1, Long num2) {
|
||||
if (num1 == null) return num2;
|
||||
if (num2 == null) return num1;
|
||||
return num1 + num2;
|
||||
}
|
||||
|
||||
private static boolean isGreaterThanZero(BigDecimal value) {
|
||||
return value != null && value.compareTo(BigDecimal.ZERO) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.czg.order.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
@@ -35,6 +36,11 @@ public class ShopProdStatistic implements Serializable {
|
||||
* 商品id
|
||||
*/
|
||||
private Long prodId;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@Column(ignore = true)
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* 销售数量
|
||||
@@ -66,4 +72,25 @@ public class ShopProdStatistic implements Serializable {
|
||||
*/
|
||||
private Date createDay;
|
||||
|
||||
// 在 ShopProdStatistic.java 中添加以下方法
|
||||
/**
|
||||
* 判断当前统计数据是否有效(销售数量、金额,退单数量、金额均有值且大于0)
|
||||
* @return true=有效,false=无效
|
||||
*/
|
||||
public boolean isValid() {
|
||||
// 1. 校验所有字段是否为 null
|
||||
if (saleCount == null || saleAmount == null || refundCount == null || refundAmount == null) {
|
||||
return false;
|
||||
}
|
||||
// 2. 校验所有字段是否大于 0(BigDecimal 需用 compareTo 比较,不能直接用 >)
|
||||
if (saleCount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
saleAmount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
refundCount.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return false;
|
||||
}
|
||||
// 3. 所有条件满足,返回 true
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 实体类。
|
||||
@@ -18,6 +20,7 @@ import java.util.Date;
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_shop_table_order_statistic")
|
||||
@@ -74,92 +77,58 @@ public class ShopTableOrderStatistic implements Serializable {
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
/**
|
||||
* 判断是否有有效数据
|
||||
*/
|
||||
public boolean hasValidData() {
|
||||
return (orderCount != null && orderCount > 0) ||
|
||||
(orderAmount != null && orderAmount.compareTo(BigDecimal.ZERO) > 0) ||
|
||||
(refundCount != null && refundCount > 0) ||
|
||||
(refundAmount != null && refundAmount.compareTo(BigDecimal.ZERO) > 0);
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
|
||||
public static List<ShopTableOrderStatistic> mergeWithStream(
|
||||
List<ShopTableOrderStatistic> realTimeData,
|
||||
List<ShopTableOrderStatistic> historyData) {
|
||||
// 最简单的合并方式
|
||||
return Stream.concat(realTimeData.stream(), historyData.stream())
|
||||
.filter(item -> item != null && item.getTableId() != null)
|
||||
.collect(Collectors.toMap(
|
||||
ShopTableOrderStatistic::getTableId,
|
||||
item -> item,
|
||||
(item1, item2) -> {
|
||||
ShopTableOrderStatistic merged = new ShopTableOrderStatistic();
|
||||
merged.setTableId(item1.getTableId());
|
||||
merged.setTableCode(item1.getTableCode());
|
||||
merged.setTableName(item1.getTableName());
|
||||
merged.setAreaName(item1.getAreaName());
|
||||
|
||||
// 数值字段求和
|
||||
merged.setOrderCount(addLong(item1.getOrderCount(), item2.getOrderCount()));
|
||||
merged.setOrderAmount(addBigDecimal(item1.getOrderAmount(), item2.getOrderAmount()));
|
||||
merged.setRefundCount(addLong(item1.getRefundCount(), item2.getRefundCount()));
|
||||
merged.setRefundAmount(addBigDecimal(item1.getRefundAmount(), item2.getRefundAmount()));
|
||||
return merged;
|
||||
}
|
||||
))
|
||||
.values()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(
|
||||
(ShopTableOrderStatistic item) -> item.getOrderCount() != null ? item.getOrderCount() : 0L,
|
||||
// 降序排列
|
||||
Comparator.reverseOrder()
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Long getTableId() {
|
||||
return tableId;
|
||||
// 辅助方法
|
||||
private static Long addLong(Long a, Long b) {
|
||||
return (a != null ? a : 0L) + (b != null ? b : 0L);
|
||||
}
|
||||
|
||||
public void setTableId(Long tableId) {
|
||||
this.tableId = tableId;
|
||||
}
|
||||
|
||||
public String getTableCode() {
|
||||
return tableCode;
|
||||
}
|
||||
|
||||
public void setTableCode(String tableCode) {
|
||||
this.tableCode = tableCode;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getAreaName() {
|
||||
return areaName;
|
||||
}
|
||||
|
||||
public void setAreaName(String areaName) {
|
||||
this.areaName = areaName;
|
||||
}
|
||||
|
||||
public Long getOrderCount() {
|
||||
return orderCount;
|
||||
}
|
||||
|
||||
public void setOrderCount(Long orderCount) {
|
||||
this.orderCount = orderCount;
|
||||
}
|
||||
|
||||
public BigDecimal getOrderAmount() {
|
||||
return orderAmount;
|
||||
}
|
||||
|
||||
public void setOrderAmount(BigDecimal orderAmount) {
|
||||
this.orderAmount = orderAmount;
|
||||
}
|
||||
|
||||
public Long getShopId() {
|
||||
return shopId;
|
||||
}
|
||||
|
||||
public void setShopId(Long shopId) {
|
||||
this.shopId = shopId;
|
||||
}
|
||||
|
||||
public Date getCreateDay() {
|
||||
return createDay;
|
||||
}
|
||||
|
||||
public void setCreateDay(Date createDay) {
|
||||
this.createDay = createDay;
|
||||
}
|
||||
|
||||
public Long getRefundCount() {
|
||||
return refundCount;
|
||||
}
|
||||
|
||||
public void setRefundCount(Long refundCount) {
|
||||
this.refundCount = refundCount;
|
||||
}
|
||||
|
||||
public BigDecimal getRefundAmount() {
|
||||
return refundAmount;
|
||||
}
|
||||
|
||||
public void setRefundAmount(BigDecimal refundAmount) {
|
||||
this.refundAmount = refundAmount;
|
||||
private static BigDecimal addBigDecimal(BigDecimal a, BigDecimal b) {
|
||||
return (a != null ? a : BigDecimal.ZERO).add(b != null ? b : BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ public enum PayEnums {
|
||||
* 挂账支付
|
||||
*/
|
||||
CREDIT_PAY("credit_pay", "挂账支付"),
|
||||
/**
|
||||
* 霸王餐支付
|
||||
*/
|
||||
FREE_PAY("free_pay", "霸王餐支付"),
|
||||
/**
|
||||
* h5支付
|
||||
*/
|
||||
@@ -56,12 +60,4 @@ public enum PayEnums {
|
||||
return Arrays.stream(values()).map(PayEnums::getValue).toList();
|
||||
}
|
||||
|
||||
public static String getText(String value) {
|
||||
PayEnums item = Arrays.stream(values()).filter(obj -> value.equals(obj.getValue())).findFirst().orElse(null);
|
||||
if (item != null) {
|
||||
return item.getMsg();
|
||||
}
|
||||
return "未知支付方式";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.czg.order.param;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据统计-营业-产品销量
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:35
|
||||
*/
|
||||
@Data
|
||||
public class DataSummaryProductSaleParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 天数
|
||||
*/
|
||||
@NotNull(message = "天数不能为空", groups = DefaultGroup.class)
|
||||
private Integer day;
|
||||
/**
|
||||
* 天数列表
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private List<String> days;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 开始日期
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private String beginDate;
|
||||
/**
|
||||
* 结束日期
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private String endDate;
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 数据统计-营业-上半部分
|
||||
@@ -20,15 +21,26 @@ public class DataSummaryTradeParam implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开始时间 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 开始时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
@NotBlank(message = "开始日期不能为空", groups = DefaultGroup.class)
|
||||
private String beginDate;
|
||||
private LocalDate beginDate;
|
||||
/**
|
||||
* 结束时间 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 结束时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
@NotBlank(message = "结束日期不能为空", groups = DefaultGroup.class)
|
||||
private String endDate;
|
||||
private LocalDate endDate;
|
||||
/**
|
||||
* 时间范围类型
|
||||
* TODAY, 今天
|
||||
* YESTERDAY, 昨天
|
||||
* LAST_7_DAYS, 最近7天
|
||||
* LAST_30_DAYS,最近30天
|
||||
* THIS_WEEK, 本周
|
||||
* THIS_MONTH 本月
|
||||
* CUSTOM 自定义时间范围
|
||||
*/
|
||||
private String rangeType;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.czg.order.param;
|
||||
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 销售统计Count入参
|
||||
@@ -16,24 +19,34 @@ public class SaleSummaryCountParam implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* 商品分类id
|
||||
* 开始时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
private Long prodCategoryId;
|
||||
@NotBlank(message = "开始日期不能为空", groups = DefaultGroup.class)
|
||||
private LocalDate beginDate;
|
||||
/**
|
||||
* 开始日期 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 结束时间 格式:yyyy-MM-dd
|
||||
*/
|
||||
private String beginDate;
|
||||
@NotBlank(message = "结束日期不能为空", groups = DefaultGroup.class)
|
||||
private LocalDate endDate;
|
||||
/**
|
||||
* 结束日期 格式:yyyy-MM-dd HH:mm:ss
|
||||
* 时间范围类型
|
||||
* TODAY, 今天
|
||||
* YESTERDAY, 昨天
|
||||
* LAST_7_DAYS, 最近7天
|
||||
* LAST_30_DAYS,最近30天
|
||||
* THIS_WEEK, 本周
|
||||
* THIS_MONTH 本月
|
||||
* CUSTOM 自定义时间范围
|
||||
*/
|
||||
private String endDate;
|
||||
private String rangeType;
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.param.DataSummaryProductSaleParam;
|
||||
import com.czg.order.param.DataSummaryTradeParam;
|
||||
import com.czg.order.vo.DataSummaryDateAmountVo;
|
||||
import com.czg.order.vo.DataSummaryPayTypeVo;
|
||||
import com.czg.order.vo.DataSummaryProductSaleRankingVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据统计Service接口
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:31
|
||||
*/
|
||||
public interface DataSummaryService {
|
||||
|
||||
ShopOrderStatistic getArchiveTradeData(DataSummaryTradeParam param);
|
||||
|
||||
ShopOrderStatistic getRealTimeTradeData(DataSummaryTradeParam param);
|
||||
|
||||
Page<DataSummaryProductSaleRankingVo> getProductSaleRankingPage(DataSummaryProductSaleParam param);
|
||||
|
||||
DataSummaryDateAmountVo getSummaryAmountData(Long shopId,Integer day);
|
||||
|
||||
DataSummaryPayTypeVo getSummaryPayTypeData(Long shopId, Integer day);
|
||||
|
||||
List<Long> getShopIdList();
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import com.czg.order.param.SaleSummaryCountParam;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.czg.order.vo.SaleSummaryInfoVo;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 销量统计Service接口
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 15:31
|
||||
*/
|
||||
public interface SaleSummaryService {
|
||||
|
||||
SaleSummaryCountVo summaryCount(SaleSummaryCountParam param);
|
||||
Page<SaleSummaryInfoVo> summaryPage(SaleSummaryCountParam param);
|
||||
List<SaleSummaryInfoVo> summaryList(SaleSummaryCountParam param);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,17 +1,73 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
import com.czg.order.vo.CountPayTypeVo;
|
||||
import com.czg.order.vo.TotalVo;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import com.czg.order.entity.ShopOrderStatistic;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
* 店铺订单统计报表 服务层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
* @author ww
|
||||
* @since 2025-11-20
|
||||
*/
|
||||
public interface ShopOrderStatisticService extends IService<ShopOrderStatistic> {
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
/**
|
||||
* 数据统计 营业板块上半部分
|
||||
* @param shopId 店铺id
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
*/
|
||||
ShopOrderStatistic getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
/**
|
||||
* 获取多少天的数据 30/90天
|
||||
*/
|
||||
List<TotalVo> getDateAmount(Long shopId, Integer day);
|
||||
/**
|
||||
* 获取支付方式数据
|
||||
*/
|
||||
List<CountPayTypeVo> getSummaryPayTypeData(Long shopId, Integer day);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day 日期
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
ShopOrderStatistic getRealTimeDataByDay(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
ShopOrderStatistic getStatSingleDate(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
ShopOrderStatistic getStatDateRange(Long shopId, LocalDate start, LocalDate end);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,72 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopProdStatistic;
|
||||
import com.czg.order.vo.SaleSummaryCountVo;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
* 服务层。
|
||||
*
|
||||
* @author zs
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
public interface ShopProdStatisticService extends IService<ShopProdStatistic> {
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
/**
|
||||
* 统计一段时间内的商品交易数据
|
||||
*
|
||||
* @param param 入参
|
||||
* @return 商品数据
|
||||
*/
|
||||
SaleSummaryCountVo summaryCount(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
/**
|
||||
* 获取某一段时间的商品交易数据
|
||||
*
|
||||
* @param shopId 店铺id
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @return 商品数据
|
||||
*/
|
||||
List<ShopProdStatistic> getArchiveTradeData(Long shopId, String productName, String rangeType, LocalDate start, LocalDate end);
|
||||
List<ShopProdStatistic> getArchiveTradeDataBy20(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
List<ShopProdStatistic> getRealTimeDataByDay(Long shopId, LocalDate day, String productName);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
List<ShopProdStatistic> getProdStatSingleDate(Long shopId, LocalDate day, String productName);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
List<ShopProdStatistic> getProdStatDateRange(Long shopId, LocalDate start, LocalDate end, String productName);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.czg.order.entity.ShopTableOrderStatistic;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台桌订单统计表 服务层。
|
||||
@@ -14,17 +13,47 @@ import java.math.BigDecimal;
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
public interface ShopTableOrderStatisticService extends IService<ShopTableOrderStatistic> {
|
||||
Page<ShopTableOrderStatistic> summary(Long shopId, String startTime, String endTime);
|
||||
|
||||
/**
|
||||
* 增加每日统计信息
|
||||
* @param shopId 店铺id
|
||||
* @param tableId 台桌id
|
||||
* @param count 订单数量
|
||||
* @param amount 订单总金额
|
||||
* @return 是否成功
|
||||
* @param shopId 店铺id
|
||||
* @param rangeType 时间范围类型
|
||||
* TODAY, // 今天
|
||||
* YESTERDAY, // 昨天
|
||||
* LAST_7_DAYS, // 最近7天
|
||||
* LAST_30_DAYS,// 最近30天
|
||||
* THIS_WEEK, // 本周
|
||||
* THIS_MONTH // 本月
|
||||
* CUSTOM // 自定义时间范围
|
||||
* @param start 开始时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
* @param end 结束时间 格式yyyy-MM-dd 今天/昨天不用传
|
||||
*/
|
||||
boolean addInfo(long shopId, long tableId, long count, BigDecimal amount);
|
||||
List<ShopTableOrderStatistic> getArchiveTradeData(Long shopId, String rangeType, LocalDate start, LocalDate end);
|
||||
|
||||
void statistic(DateTime dateTime);
|
||||
//------------------------------------------------------------下列为 后台使用------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 统计某天数据并插入数据库
|
||||
*
|
||||
* @param day
|
||||
*/
|
||||
void statisticAndInsert(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 实时统计某天数据
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getRealTimeDataByDay(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 获取某一天的数据 历史数据
|
||||
* 从ShopOrderStatistic 表中查询
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getStatSingleDate(Long shopId, LocalDate day);
|
||||
|
||||
/**
|
||||
* 统计 某时间段数据 总和 不包括当日实时数据
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
*/
|
||||
List<ShopTableOrderStatistic> getStatDateRange(Long shopId, LocalDate start, LocalDate end);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.czg.order.service;
|
||||
|
||||
import com.czg.order.param.TableSummaryParam;
|
||||
import com.czg.order.vo.TableSummaryExportVo;
|
||||
import com.czg.order.vo.TableSummaryInfoVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,7 +13,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface TableSummaryService {
|
||||
|
||||
List<TableSummaryInfoVo> summaryList(TableSummaryParam param);
|
||||
|
||||
List<TableSummaryExportVo> summaryExportList(TableSummaryParam param);
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ww
|
||||
* @description
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CountPayTypeVo {
|
||||
/**
|
||||
* 笔数
|
||||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String payType;
|
||||
|
||||
private static final Map<String, String> PAY_TYPE_MAPPING = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
PAY_TYPE_MAPPING.put("memberPay", "会员支付");
|
||||
PAY_TYPE_MAPPING.put("cashPay", "现金支付");
|
||||
PAY_TYPE_MAPPING.put("wechatPay", "微信支付");
|
||||
PAY_TYPE_MAPPING.put("alipayPay", "支付宝支付");
|
||||
PAY_TYPE_MAPPING.put("mainScanPay", "主扫支付");
|
||||
PAY_TYPE_MAPPING.put("backScanPay", "被扫支付");
|
||||
PAY_TYPE_MAPPING.put("creditPay", "信用支付");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 合并实时数据和历史统计数据
|
||||
*/
|
||||
public static List<CountPayTypeVo> mergePayTypeData(Map<String, Integer> realTimeData,
|
||||
Map<String, Integer> historyData) {
|
||||
|
||||
List<CountPayTypeVo> result = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : PAY_TYPE_MAPPING.entrySet()) {
|
||||
String payCode = entry.getKey();
|
||||
String payName = entry.getValue();
|
||||
|
||||
Integer realTimeCount = getSafeValue(realTimeData, payCode);
|
||||
Integer historyCount = getSafeValue(historyData, payCode);
|
||||
|
||||
int totalCount = (realTimeCount != null ? realTimeCount : 0)
|
||||
+ (historyCount != null ? historyCount : 0);
|
||||
|
||||
result.add(new CountPayTypeVo(totalCount, payName));
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取Map中的值,处理null情况
|
||||
*/
|
||||
private static Integer getSafeValue(Map<String, Integer> data, String key) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data.get(key);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 销售趋势柱状图 左下
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class DataSummaryDateAmountVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* total
|
||||
*/
|
||||
private List<TotalVo> total = new ArrayList<>();
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付占比饼图 左下
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class DataSummaryPayTypeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* countPayType
|
||||
*/
|
||||
private List<CountPayTypeVo> countPayType = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* CountPayTypeVo
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class CountPayTypeVo {
|
||||
/**
|
||||
* 笔数
|
||||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String payType;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class OrderInfoVo implements Serializable {
|
||||
private String payType;
|
||||
|
||||
/**
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
|
||||
* 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -12,6 +14,8 @@ import java.math.BigDecimal;
|
||||
* @since 2025-03-07 16:22
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SaleSummaryCountVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.czg.order.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnore;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.idev.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 销量统计明细
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:22
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@ColumnWidth(30)
|
||||
public class SaleSummaryInfoVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 导入时候回显行号
|
||||
*/
|
||||
@ExcelLine
|
||||
@ExcelIgnore
|
||||
@JSONField(serialize = false)
|
||||
private Long lineNum;
|
||||
/**
|
||||
* 商品分类
|
||||
*/
|
||||
@ExcelProperty("商品分类")
|
||||
private String categoryName;
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@ExcelProperty("商品名称")
|
||||
private String productName;
|
||||
/**
|
||||
* 销量
|
||||
*/
|
||||
@ExcelProperty("销量")
|
||||
private BigDecimal saleCount;
|
||||
/**
|
||||
* 销售金额
|
||||
*/
|
||||
@ExcelProperty("销售金额")
|
||||
private BigDecimal saleAmount;
|
||||
/**
|
||||
* 退单量
|
||||
*/
|
||||
@ExcelProperty("退单量")
|
||||
private BigDecimal refundCount;
|
||||
/**
|
||||
* 退单金额
|
||||
*/
|
||||
@ExcelProperty("退单金额")
|
||||
private BigDecimal refundAmount;
|
||||
}
|
||||
@@ -6,15 +6,18 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 销售趋势柱状图 左下
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2025-03-07 16:08
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class TotalVo implements Serializable {
|
||||
public class TotalVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -34,5 +37,44 @@ public class TotalVo implements Serializable {
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
private String tradeDay;
|
||||
private LocalDate tradeDay;
|
||||
|
||||
|
||||
public TotalVo(LocalDate tradeDay) {
|
||||
this.tradeDay = tradeDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并实时数据和历史数据,并填充缺失的日期
|
||||
*/
|
||||
public static List<TotalVo> mergeAndFillData(TotalVo onlineData, List<TotalVo> historyData,
|
||||
LocalDate startDate, LocalDate endDate) {
|
||||
// 创建日期到数据的映射,方便查找
|
||||
Map<LocalDate, TotalVo> dataMap = new HashMap<>();
|
||||
|
||||
// 将历史数据放入映射
|
||||
for (TotalVo vo : historyData) {
|
||||
if (vo.getTradeDay() != null) {
|
||||
dataMap.put(vo.getTradeDay(), vo);
|
||||
}
|
||||
}
|
||||
dataMap.put(onlineData.getTradeDay(), onlineData);
|
||||
|
||||
List<TotalVo> result = new ArrayList<>();
|
||||
LocalDate currentDay = startDate;
|
||||
|
||||
while (!currentDay.isAfter(endDate)) {
|
||||
if (dataMap.containsKey(currentDay)) {
|
||||
result.add(dataMap.get(currentDay));
|
||||
} else {
|
||||
// 创建空的TotalVo填充缺失的日期
|
||||
TotalVo emptyVo = new TotalVo(currentDay);
|
||||
result.add(emptyVo);
|
||||
}
|
||||
currentDay = currentDay.plusDays(1);
|
||||
}
|
||||
// 按日期排序确保顺序正确
|
||||
result.sort(Comparator.comparing(TotalVo::getTradeDay));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.czg.utils;
|
||||
|
||||
import cn.hutool.core.lang.id.NanoId;
|
||||
|
||||
/**
|
||||
* @author ww
|
||||
* @description
|
||||
*/
|
||||
public class CzgRandomUtils {
|
||||
|
||||
private static final char[] DEFAULT_ALPHABET =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
|
||||
|
||||
/**
|
||||
* 默认长度
|
||||
*/
|
||||
public static final int DEFAULT_SIZE = 12;
|
||||
|
||||
|
||||
/**
|
||||
* 随机生成指定长度的字符串
|
||||
*
|
||||
* @return 随机字符串
|
||||
*/
|
||||
public static String randomString() {
|
||||
return NanoId.randomNanoId(null, DEFAULT_ALPHABET, DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成指定长度的字符串
|
||||
*
|
||||
* @param length 字符串长度
|
||||
* @return 随机字符串
|
||||
*/
|
||||
public static String randomString(int length) {
|
||||
return NanoId.randomNanoId(null, DEFAULT_ALPHABET, length);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user