数据统计

This commit is contained in:
Tankaikai
2025-03-19 09:58:05 +08:00
parent 36ddbba45e
commit ddf8a89cb0
9 changed files with 284 additions and 17 deletions

View File

@@ -86,6 +86,7 @@ public class DataSummaryController {
* @param day 天数
*/
@GetMapping("datePayType")
@OperationLog("支付占比饼图 左下")
@SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju")
//@SaAdminCheckPermission("dataSummary:datePayType")
public CzgResult<DataSummaryPayTypeVo> shopSummaryPayType(@RequestParam Integer day) {

View File

@@ -36,5 +36,15 @@ public class DataSummaryProductSaleParam implements Serializable {
*/
@JSONField(serialize = false)
private Long shopId;
/**
* 开始日期
*/
@JSONField(serialize = false)
private String beginDate;
/**
* 结束日期
*/
@JSONField(serialize = false)
private String endDate;
}

View File

@@ -3,6 +3,11 @@ package com.czg.service.order.mapper;
import com.czg.order.entity.ShopOrderStatistic;
import com.czg.order.param.DataSummaryTradeParam;
import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 映射层。
@@ -10,9 +15,17 @@ import com.mybatisflex.core.BaseMapper;
* @author zs
* @since 2025-03-07
*/
@Mapper
public interface ShopOrderStatisticMapper extends BaseMapper<ShopOrderStatistic> {
ShopOrderStatistic getTradeData(DataSummaryTradeParam param);
long getNewMemberCount(DataSummaryTradeParam param);
List<Map<String, Object>> getPayTypeAmountCount(DataSummaryTradeParam param);
List<Map<String, Object>> getVipRechargeAmountCount(DataSummaryTradeParam param);
BigDecimal getCustomerUnitPrice(DataSummaryTradeParam param);
BigDecimal getTableTurnoverRate(DataSummaryTradeParam param);
}

View File

@@ -20,8 +20,14 @@ public interface ShopProdStatisticMapper extends BaseMapper<ShopProdStatistic> {
List<DataSummaryProductSaleRankingVo> findProdRandingSummaryPage(DataSummaryProductSaleParam param);
List<DataSummaryProductSaleRankingVo> findProdRandingSummaryPage2(DataSummaryProductSaleParam param);
SaleSummaryCountVo getSaleSummaryCount(SaleSummaryCountParam param);
SaleSummaryCountVo getSaleSummaryCount2(SaleSummaryCountParam param);
List<SaleSummaryInfoVo> findSaleSummaryList(SaleSummaryCountParam param);
List<SaleSummaryInfoVo> findSaleSummaryList2(SaleSummaryCountParam param);
}

View File

@@ -1,7 +1,10 @@
package com.czg.service.order.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import com.czg.order.entity.OrderInfo;
import com.czg.order.entity.ShopOrderStatistic;
import com.czg.order.enums.PayEnums;
@@ -22,9 +25,13 @@ import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 数据统计Service实现类
@@ -44,15 +51,66 @@ public class DataSummaryServiceImpl implements DataSummaryService {
@Override
public ShopOrderStatistic getTradeData(DataSummaryTradeParam param) {
ShopOrderStatistic shopOrderStatistic = shopOrderStatisticMapper.getTradeData(param);
if (shopOrderStatistic == null) {
shopOrderStatistic = new ShopOrderStatistic();
List<String> funs = Arrays.asList("getPayTypeAmountCount", "getVipRechargeAmountCount", "getNewMemberCount", "getCustomerUnitPrice", "getTableTurnoverRate");
Map<String, Object> collect = funs.parallelStream().collect(Collectors.toMap(fun -> fun, fun ->
ReflectUtil.invoke(shopOrderStatisticMapper, fun, param)
));
/*Map<String, Object> collect = new ConcurrentHashMap<>();
for (String fun : funs) {
Object invoke = ReflectUtil.invoke(shopOrderStatisticMapper, fun, param);
collect.put(fun, ObjUtil.defaultIfNull(invoke,BigDecimal.ZERO));
}*/
ShopOrderStatistic data = new ShopOrderStatistic();
//List<Map<String, Object>> list = shopOrderStatisticMapper.getPayTypeAmountCount(param);
List<Map<String, Object>> list = (List<Map<String, Object>>) collect.get("getPayTypeAmountCount");
if (CollUtil.isEmpty(list)) {
return data;
}
Map<String, BigDecimal> sum = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toBigDecimal(item.get("amount"))));
Map<String, Long> count = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toLong(item.get("count"))));
data.setWechatPayAmount(sum.getOrDefault(PayEnums.WECHAT_MINI.getValue(), BigDecimal.ZERO));
data.setWechatPayCount(count.getOrDefault(PayEnums.WECHAT_MINI.getValue(), 0L));
data.setAliPayAmount(sum.getOrDefault(PayEnums.ALIPAY_MINI.getValue(), BigDecimal.ZERO));
data.setAliPayCount(count.getOrDefault(PayEnums.ALIPAY_MINI.getValue(), 0L));
data.setScanPayAmount(sum.getOrDefault(PayEnums.MAIN_SCAN.getValue(), BigDecimal.ZERO));
data.setScanPayCount(count.getOrDefault(PayEnums.MAIN_SCAN.getValue(), 0L));
data.setCashPayAmount(sum.getOrDefault(PayEnums.CASH_PAY.getValue(), BigDecimal.ZERO));
data.setCashPayCount(count.getOrDefault(PayEnums.CASH_PAY.getValue(), 0L));
data.setCreditPayAmount(sum.getOrDefault(PayEnums.CREDIT_PAY.getValue(), BigDecimal.ZERO));
data.setCreditPayCount(count.getOrDefault(PayEnums.CREDIT_PAY.getValue(), 0L));
//List<Map<String, Object>> list1 = shopOrderStatisticMapper.getVipRechargeAmountCount(param);
List<Map<String, Object>> list1 = (List<Map<String, Object>>) collect.get("getVipRechargeAmountCount");
Map<String, BigDecimal> sum1 = list1.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("bizCode")), item -> Convert.toBigDecimal(item.get("amount"))));
Map<String, Long> count1 = list1.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("bizCode")), item -> Convert.toLong(item.get("count"))));
data.setRechargeAmount(NumberUtil.add(sum1.getOrDefault("cashIn", BigDecimal.ZERO), sum1.getOrDefault("wechatIn", BigDecimal.ZERO), sum1.getOrDefault("alipayIn", BigDecimal.ZERO)));
data.setMemberPayAmount(sum1.getOrDefault("orderPay", BigDecimal.ZERO).abs());
data.setMemberPayCount(count1.getOrDefault("orderPay", 0L));
data.setSaleAmount(NumberUtil.add(data.getWechatPayAmount(), data.getAliPayAmount(), data.getScanPayAmount(), data.getCashPayAmount(), data.getCreditPayAmount()));
BigDecimal refundAmount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toBigDecimal(item.get("refund"), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add);
data.setRefundAmount(refundAmount);
long refundCount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toLong(item.get("refundCount"), 0L)).reduce(0L, Long::sum);
data.setRefundCount(refundCount);
//long newMemberCount = shopOrderStatisticMapper.getNewMemberCount(param);
long newMemberCount = (long) collect.get("getNewMemberCount");
data.setNewMemberCount(newMemberCount);
//BigDecimal customerUnitPrice = shopOrderStatisticMapper.getCustomerUnitPrice(param);
BigDecimal customerUnitPrice = (BigDecimal) collect.get("getCustomerUnitPrice");
data.setCustomerUnitPrice(NumberUtil.nullToZero(customerUnitPrice).setScale(2, java.math.RoundingMode.HALF_UP));
//BigDecimal tableTurnoverRate = shopOrderStatisticMapper.getTableTurnoverRate(param);
BigDecimal tableTurnoverRate = (BigDecimal) collect.get("getTableTurnoverRate");
data.setTableTurnoverRate(tableTurnoverRate);
BigDecimal discountAmount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toBigDecimal(item.get("discount"), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add);
long discountCount = list.stream().filter(item -> item.get("payType") != null).map(item -> Convert.toLong(item.get("discountCount"), 0L)).reduce(0L, Long::sum);
data.setDiscountAmount(discountAmount);
data.setDiscountCount(discountCount);
return data;
/*ShopOrderStatistic shopOrderStatistic = shopOrderStatisticMapper.getTradeData(param);
long newMemberCount = shopOrderStatisticMapper.getNewMemberCount(param);
data.setNewMemberCount(newMemberCount);
shopOrderStatistic.setCustomerUnitPrice(shopOrderStatistic.getCustomerUnitPrice().setScale(2, java.math.RoundingMode.HALF_UP));
shopOrderStatistic.setTableTurnoverRate(shopOrderStatistic.getTableTurnoverRate().setScale(2, java.math.RoundingMode.HALF_UP));
long newMemberCount = shopOrderStatisticMapper.getNewMemberCount(param);
shopOrderStatistic.setNewMemberCount(newMemberCount);
return shopOrderStatistic;
return shopOrderStatistic;*/
}
@Override
@@ -66,8 +124,10 @@ public class DataSummaryServiceImpl implements DataSummaryService {
days.add(thisDay);
}
param.setDays(days);
param.setBeginDate(days.getFirst() + " 00:00:00");
param.setEndDate(days.getLast() + " 23:59:59");
PageHelper.startPage(PageUtil.buildPageHelp());
PageInfo<DataSummaryProductSaleRankingVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findProdRandingSummaryPage(param));
PageInfo<DataSummaryProductSaleRankingVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findProdRandingSummaryPage2(param));
return PageUtil.convert(pageInfo);
}

View File

@@ -27,7 +27,7 @@ public class SaleSummaryServiceImpl implements SaleSummaryService {
@Override
public SaleSummaryCountVo summaryCount(SaleSummaryCountParam param) {
SaleSummaryCountVo saleSummaryCount = shopProdStatisticMapper.getSaleSummaryCount(param);
SaleSummaryCountVo saleSummaryCount = shopProdStatisticMapper.getSaleSummaryCount2(param);
if (saleSummaryCount == null) {
saleSummaryCount = new SaleSummaryCountVo();
}
@@ -37,12 +37,12 @@ public class SaleSummaryServiceImpl implements SaleSummaryService {
@Override
public Page<SaleSummaryInfoVo> summaryPage(SaleSummaryCountParam param) {
PageHelper.startPage(PageUtil.buildPageHelp());
PageInfo<SaleSummaryInfoVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList(param));
PageInfo<SaleSummaryInfoVo> pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList2(param));
return PageUtil.convert(pageInfo);
}
@Override
public List<SaleSummaryInfoVo> summaryList(SaleSummaryCountParam param) {
return shopProdStatisticMapper.findSaleSummaryList(param);
return shopProdStatisticMapper.findSaleSummaryList2(param);
}
}

View File

@@ -50,4 +50,74 @@
]]>
</if>
</select>
<select id="getPayTypeAmountCount" resultType="java.util.Map">
SELECT
t1.pay_type as payType,
sum(t1.pay_amount) as amount,
sum(t1.refund_amount) as refund,
count(case when t1.refund_amount>0 then 1 end) as refundCount,
sum(t1.discount_amount) as discount,
count(case when t1.discount_amount>0 then 1 end) as discountCount,
count(*) as count
FROM
tb_order_info t1
WHERE t1.shop_id = #{shopId}
and t1.paid_time is not null
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(concat(#{beginDate},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(concat(#{endDate},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
]]>
</if>
group by t1.pay_type
</select>
<select id="getVipRechargeAmountCount" resultType="java.util.Map">
select
t1.biz_code as bizCode,sum(t1.amount) as amount,count(*) as count
from tb_shop_user_flow t1
where t1.shop_id = #{shopId}
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(concat(#{beginDate},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(concat(#{endDate},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
]]>
</if>
group by t1.biz_code
</select>
<select id="getCustomerUnitPrice" resultType="java.math.BigDecimal">
SELECT
ifnull((sum(t1.pay_amount)-sum(t1.refund_amount))/count(ifnull(case t1.seat_num when 0 then 1 end,1)),0.00) as customerUnitPrice
FROM
tb_order_info t1
WHERE t1.shop_id = #{shopId}
and t1.paid_time is not null
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(concat(#{beginDate},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(concat(#{endDate},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
]]>
</if>
</select>
<select id="getTableTurnoverRate" resultType="java.math.BigDecimal">
SELECT
ifnull((count(*)-count(DISTINCT t1.table_code))/count(DISTINCT t1.table_code)*100,0.00)
FROM
tb_order_info t1
WHERE t1.shop_id = #{shopId}
and t1.paid_time is not null
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(concat(#{beginDate},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(concat(#{endDate},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
]]>
</if>
</select>
</mapper>

View File

@@ -74,4 +74,88 @@
group by t1.prod_id
ORDER BY sum( t1.sale_count ) DESC,max(t1.id) DESC
</select>
<select id="getSaleSummaryCount2" resultType="com.czg.order.vo.SaleSummaryCountVo">
SELECT
sum(t1.pay_amount) as totalAmount,
sum(t1.refund_amount) as refundAmount,
count(*) as saleCount,
count(case when t1.refund_amount > 0 then 1 end) as refundCount
FROM
tb_order_info t1
left join (
SELECT
x1.order_id,
concat( ',', GROUP_CONCAT( x2.category_id ), ',' ) AS category_id,
GROUP_CONCAT( x1.product_name ) AS product_name
FROM
tb_order_detail x1
LEFT JOIN tb_product x2 ON x1.product_id = x2.id
GROUP BY x1.order_id
) t2 on t1.id = t2.order_id
where t1.shop_id = #{shopId}
<if test="productName != null and productName != ''">
and t2.product_name like concat('%', #{productName}, '%')
</if>
<if test="prodCategoryId != null">
and t2.category_id like concat('%,', #{prodCategoryId}, ',%')
</if>
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d')
]]>
</if>
</select>
<select id="findSaleSummaryList2" resultType="com.czg.order.vo.SaleSummaryInfoVo">
SELECT
t1.product_id,
t1.product_name as productName,
t3.name as category_name,
sum( t1.num ) AS saleCount,
sum( t1.pay_amount ) AS saleAmount,
sum( t1.return_num ) AS refundCount,
sum( t1.return_amount ) AS refundAmount
FROM
tb_order_detail t1
left join tb_product t2 on t1.product_id = t2.id
left join tb_shop_prod_category t3 on t2.category_id = t3.id
where t1.shop_id = #{shopId}
<if test="productName != null and productName != ''">
and t1.product_name like concat('%', #{productName}, '%')
</if>
<if test="prodCategoryId != null">
and t2.category_id = #{prodCategoryId}
</if>
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d')
]]>
</if>
GROUP BY t1.product_id,t1.product_name
ORDER BY sum( t1.num ) DESC,max(t1.product_id) DESC
</select>
<select id="findProdRandingSummaryPage2" resultType="com.czg.order.vo.DataSummaryProductSaleRankingVo">
select
t1.product_id,
t1.product_name,
sum(t1.num) as number,
sum(t1.pay_amount) as amount
from tb_order_detail t1
where t1.shop_id = #{shopId}
<if test="beginDate != null and beginDate != ''">
and t1.create_time >= str_to_date(#{beginDate}, '%Y-%m-%d')
</if>
<if test="endDate != null and endDate != ''">
<![CDATA[
and t1.create_time <= str_to_date(#{endDate}, '%Y-%m-%d')
]]>
</if>
GROUP BY t1.product_id,t1.product_name
order by sum(t1.num) desc
</select>
</mapper>

View File

@@ -352,7 +352,11 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
}
prodSku.setIsGrounding(isSale);
prodSkuMapper.update(prodSku);
long normalCount = prodSkuMapper.selectCountByQuery(QueryWrapper.create().eq(ProdSku::getProductId, prodSku.getProductId()).eq(ProdSku::getIsDel, DeleteEnum.NORMAL.value()));
long normalCount = prodSkuMapper.selectCountByQuery(QueryWrapper.create()
.eq(ProdSku::getProductId, prodSku.getProductId())
.eq(ProdSku::getIsGrounding, YesNoEnum.NO.value())
.eq(ProdSku::getIsDel, DeleteEnum.NORMAL.value())
);
if (normalCount == 0) {
UpdateChain.of(Product.class)
.set(Product::getIsSale, isSale)
@@ -388,17 +392,36 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
String type = param.getType();
Long id = param.getId();
Integer isSoldOut = param.getIsSoldOut();
UpdateChain.of(ProdSku.class)
.set(ProdSku::getIsPauseSale, isSoldOut)
.eq(ProdSku::getId, id)
.eq(ProdSku::getShopId, shopId)
.update();
if (ProductIsSaleTypeEnum.PRODUCT.value().equals(type)) {
if (ProductIsSaleTypeEnum.SKU.value().equals(type)) {
ProdSku prodSku = prodSkuMapper.selectOneById(id);
if (prodSku == null) {
throw new CzgException("SKU不存在");
}
prodSku.setIsPauseSale(isSoldOut);
prodSkuMapper.update(prodSku);
long normalCount = prodSkuMapper.selectCountByQuery(QueryWrapper.create()
.eq(ProdSku::getProductId, prodSku.getProductId())
.eq(ProdSku::getIsPauseSale, YesNoEnum.NO.value())
.eq(ProdSku::getIsDel, DeleteEnum.NORMAL.value())
);
if (normalCount == 0) {
UpdateChain.of(Product.class)
.set(Product::getIsSoldStock, isSoldOut)
.eq(Product::getId, prodSku.getProductId())
.eq(Product::getShopId, shopId)
.update();
}
} else if (ProductIsSaleTypeEnum.PRODUCT.value().equals(type)) {
UpdateChain.of(Product.class)
.set(Product::getIsSoldStock, isSoldOut)
.eq(Product::getId, id)
.eq(Product::getShopId, shopId)
.update();
UpdateChain.of(ProdSku.class)
.set(ProdSku::getIsPauseSale, isSoldOut)
.eq(ProdSku::getProductId, id)
.eq(ProdSku::getShopId, shopId)
.update();
}
}