add product/order chart

This commit is contained in:
Timi
2026-09-06 17:56:47 +08:00
parent db2fca5715
commit 01d33a1122
32 changed files with 1783 additions and 0 deletions
@@ -0,0 +1,126 @@
package com.imyeyu.api.modules.gao.controller;
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
import com.imyeyu.api.modules.gao.service.GaoProductChartService;
import com.imyeyu.api.modules.gao.service.GaoStoreScopeService;
import com.imyeyu.api.modules.gao.vo.GaoProductCategoryStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductChartReq;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockHealthView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockMovementDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductTypeStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductUnitSalesRankView;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.annotation.AOPLog;
import com.imyeyu.spring.annotation.RequestRateLimit;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/// GAO 产品图表接口
///
/// @author Codex
/// @since 2026-09-06
@RestController
@RequiredArgsConstructor
@RequestMapping("/gao/product/chart")
public class GaoProductChartController {
private final GaoProductChartService service;
private final GaoStoreScopeService storeScopeService;
/// 查询产品每日销售统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/sales/daily")
public List<GaoProductSalesDailyStatView> salesDaily(@RequestBody GaoProductChartReq req) {
return service.salesDaily(normalize(req));
}
/// 查询产品销售排行
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/sales/rank")
public List<GaoProductSalesRankView> salesRank(@RequestBody GaoProductChartReq req) {
return service.salesRank(normalize(req));
}
/// 查询产品每日履约统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/fulfillment/daily")
public List<GaoProductFulfillmentDailyStatView> fulfillmentDaily(@RequestBody GaoProductChartReq req) {
return service.fulfillmentDaily(normalize(req));
}
/// 查询产品履约进度排行
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/fulfillment/rank")
public List<GaoProductFulfillmentRankView> fulfillmentRank(@RequestBody GaoProductChartReq req) {
return service.fulfillmentRank(normalize(req));
}
/// 查询产品每日库存变动统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/stock/movement/daily")
public List<GaoProductStockMovementDailyStatView> stockMovementDaily(@RequestBody GaoProductChartReq req) {
return service.stockMovementDaily(normalize(req));
}
/// 查询产品库存健康度
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/stock/health")
public List<GaoProductStockHealthView> stockHealth(@RequestBody GaoProductChartReq req) {
return service.stockHealth(normalize(req));
}
/// 查询产品类型统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/structure/type")
public List<GaoProductTypeStatView> type(@RequestBody GaoProductChartReq req) {
return service.type(normalize(req));
}
/// 查询产品分类统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/structure/category")
public List<GaoProductCategoryStatView> category(@RequestBody GaoProductChartReq req) {
return service.category(normalize(req));
}
/// 查询产品销售单位排行
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/sales/unit/rank")
public List<GaoProductUnitSalesRankView> unitSalesRank(@RequestBody GaoProductChartReq req) {
return service.unitSalesRank(normalize(req));
}
private GaoProductChartReq normalize(GaoProductChartReq req) {
TimiException.required(req, "not found product chart req");
req.setStoreId(storeScopeService.resolveStoreId(req.getStoreId()));
return req;
}
}
@@ -0,0 +1,146 @@
package com.imyeyu.api.modules.gao.controller;
import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission;
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
import com.imyeyu.api.modules.gao.service.GaoSalesOrderChartService;
import com.imyeyu.api.modules.gao.service.GaoStoreScopeService;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderProductRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatIntervalStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderChartReq;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderCalendarStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderConsumptionDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderPaymentStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderReceivableStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderStatusStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderTypeStatView;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.annotation.AOPLog;
import com.imyeyu.spring.annotation.RequestRateLimit;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/// GAO 销售订单图表接口
///
/// @author Codex
/// @since 2026-09-06
@RestController
@RequiredArgsConstructor
@RequestMapping("/gao/sales/order/chart")
public class GaoSalesOrderChartController {
private final GaoSalesOrderChartService service;
private final GaoStoreScopeService storeScopeService;
/// 查询销售订单每日统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/daily")
public List<GaoSalesOrderDailyStatView> daily(@RequestBody GaoSalesOrderChartReq req) {
return service.daily(normalize(req));
}
/// 查询销售订单类型统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/type")
public List<GaoSalesOrderTypeStatView> type(@RequestBody GaoSalesOrderChartReq req) {
return service.type(normalize(req));
}
/// 查询销售订单付款状态统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/payment")
public List<GaoSalesOrderPaymentStatView> payment(@RequestBody GaoSalesOrderChartReq req) {
return service.payment(normalize(req));
}
/// 查询客户订单排行
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/rank")
public List<GaoCustomerOrderRankView> customerRank(@RequestBody GaoSalesOrderChartReq req) {
return service.customerRank(normalize(req));
}
/// 查询指定客户订单产品排行
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/product/rank")
public List<GaoCustomerOrderProductRankView> customerProductRank(@RequestBody GaoSalesOrderChartReq req) {
return service.customerProductRank(normalize(req));
}
/// 查询销售订单状态统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/status")
public List<GaoSalesOrderStatusStatView> status(@RequestBody GaoSalesOrderChartReq req) {
return service.status(normalize(req));
}
/// 查询销售订单应收统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/receivable")
public GaoSalesOrderReceivableStatView receivable(@RequestBody GaoSalesOrderChartReq req) {
return service.receivable(normalize(req));
}
/// 查询客户每日有效消费统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/consumption/daily")
public List<GaoSalesOrderConsumptionDailyStatView> consumptionDaily(@RequestBody GaoSalesOrderChartReq req) {
return service.consumptionDaily(normalize(req));
}
/// 查询客户订单日历统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/calendar")
public List<GaoSalesOrderCalendarStatView> calendar(@RequestBody GaoSalesOrderChartReq req) {
return service.calendar(normalize(req));
}
/// 查询客户每日复购统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/repeat/daily")
public List<GaoCustomerRepeatDailyStatView> repeatDaily(@RequestBody GaoSalesOrderChartReq req) {
return service.repeatDaily(normalize(req));
}
/// 查询客户复购间隔统计
@AOPLog
@RequestRateLimit
@RequireGaoPermission(GaoPermissionCode.STAT_READ)
@PostMapping("/customer/repeat/interval")
public List<GaoCustomerRepeatIntervalStatView> repeatInterval(@RequestBody GaoSalesOrderChartReq req) {
return service.repeatInterval(normalize(req));
}
private GaoSalesOrderChartReq normalize(GaoSalesOrderChartReq req) {
TimiException.required(req, "not found sales order chart req");
req.setStoreId(storeScopeService.resolveStoreId(req.getStoreId()));
return req;
}
}
@@ -0,0 +1,48 @@
package com.imyeyu.api.modules.gao.mapper;
import com.imyeyu.api.modules.gao.vo.GaoProductChartReq;
import com.imyeyu.api.modules.gao.vo.GaoProductCategoryStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockHealthView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockMovementDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductTypeStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductUnitSalesRankView;
import java.util.List;
/// GAO 产品图表 Mapper
///
/// @author Codex
/// @since 2026-09-06
public interface GaoProductChartMapper {
/// 查询产品每日销售统计
List<GaoProductSalesDailyStatView> selectSalesDaily(GaoProductChartReq req);
/// 查询产品销售排行
List<GaoProductSalesRankView> selectSalesRank(GaoProductChartReq req);
/// 查询产品每日履约统计
List<GaoProductFulfillmentDailyStatView> selectFulfillmentDaily(GaoProductChartReq req);
/// 查询产品履约进度排行
List<GaoProductFulfillmentRankView> selectFulfillmentRank(GaoProductChartReq req);
/// 查询产品每日库存变动统计
List<GaoProductStockMovementDailyStatView> selectStockMovementDaily(GaoProductChartReq req);
/// 查询产品库存健康度
List<GaoProductStockHealthView> selectStockHealth(GaoProductChartReq req);
/// 查询产品类型统计
List<GaoProductTypeStatView> selectType(GaoProductChartReq req);
/// 查询产品分类统计
List<GaoProductCategoryStatView> selectCategory(GaoProductChartReq req);
/// 查询产品销售单位排行
List<GaoProductUnitSalesRankView> selectUnitSalesRank(GaoProductChartReq req);
}
@@ -0,0 +1,56 @@
package com.imyeyu.api.modules.gao.mapper;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderProductRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatIntervalStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderChartReq;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderCalendarStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderConsumptionDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderPaymentStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderReceivableStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderStatusStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderTypeStatView;
import java.util.List;
/// GAO 销售订单图表 Mapper
///
/// @author Codex
/// @since 2026-09-06
public interface GaoSalesOrderChartMapper {
/// 查询销售订单每日统计
List<GaoSalesOrderDailyStatView> selectDaily(GaoSalesOrderChartReq req);
/// 查询销售订单类型统计
List<GaoSalesOrderTypeStatView> selectType(GaoSalesOrderChartReq req);
/// 查询销售订单付款状态统计
List<GaoSalesOrderPaymentStatView> selectPayment(GaoSalesOrderChartReq req);
/// 查询客户订单排行
List<GaoCustomerOrderRankView> selectCustomerRank(GaoSalesOrderChartReq req);
/// 查询客户订单产品排行
List<GaoCustomerOrderProductRankView> selectCustomerProductRank(GaoSalesOrderChartReq req);
/// 查询销售订单状态统计
List<GaoSalesOrderStatusStatView> selectStatus(GaoSalesOrderChartReq req);
/// 查询销售订单应收统计
GaoSalesOrderReceivableStatView selectReceivable(GaoSalesOrderChartReq req);
/// 查询客户每日有效消费统计
List<GaoSalesOrderConsumptionDailyStatView> selectConsumptionDaily(GaoSalesOrderChartReq req);
/// 查询客户订单日历统计
List<GaoSalesOrderCalendarStatView> selectCalendar(GaoSalesOrderChartReq req);
/// 查询客户每日复购统计
List<GaoCustomerRepeatDailyStatView> selectRepeatDaily(GaoSalesOrderChartReq req);
/// 查询客户复购间隔统计
List<GaoCustomerRepeatIntervalStatView> selectRepeatInterval(GaoSalesOrderChartReq req);
}
@@ -0,0 +1,48 @@
package com.imyeyu.api.modules.gao.service;
import com.imyeyu.api.modules.gao.vo.GaoProductChartReq;
import com.imyeyu.api.modules.gao.vo.GaoProductCategoryStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockHealthView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockMovementDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductTypeStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductUnitSalesRankView;
import java.util.List;
/// GAO 产品图表服务
///
/// @author Codex
/// @since 2026-09-06
public interface GaoProductChartService {
/// 查询产品每日销售统计
List<GaoProductSalesDailyStatView> salesDaily(GaoProductChartReq req);
/// 查询产品销售排行
List<GaoProductSalesRankView> salesRank(GaoProductChartReq req);
/// 查询产品每日履约统计
List<GaoProductFulfillmentDailyStatView> fulfillmentDaily(GaoProductChartReq req);
/// 查询产品履约进度排行
List<GaoProductFulfillmentRankView> fulfillmentRank(GaoProductChartReq req);
/// 查询产品每日库存变动统计
List<GaoProductStockMovementDailyStatView> stockMovementDaily(GaoProductChartReq req);
/// 查询产品库存健康度
List<GaoProductStockHealthView> stockHealth(GaoProductChartReq req);
/// 查询产品类型统计
List<GaoProductTypeStatView> type(GaoProductChartReq req);
/// 查询产品分类统计
List<GaoProductCategoryStatView> category(GaoProductChartReq req);
/// 查询产品销售单位排行
List<GaoProductUnitSalesRankView> unitSalesRank(GaoProductChartReq req);
}
@@ -0,0 +1,56 @@
package com.imyeyu.api.modules.gao.service;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderProductRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatIntervalStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderChartReq;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderCalendarStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderConsumptionDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderPaymentStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderReceivableStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderStatusStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderTypeStatView;
import java.util.List;
/// GAO 销售订单图表服务
///
/// @author Codex
/// @since 2026-09-06
public interface GaoSalesOrderChartService {
/// 查询销售订单每日统计
List<GaoSalesOrderDailyStatView> daily(GaoSalesOrderChartReq req);
/// 查询销售订单类型统计
List<GaoSalesOrderTypeStatView> type(GaoSalesOrderChartReq req);
/// 查询销售订单付款状态统计
List<GaoSalesOrderPaymentStatView> payment(GaoSalesOrderChartReq req);
/// 查询客户订单排行
List<GaoCustomerOrderRankView> customerRank(GaoSalesOrderChartReq req);
/// 查询客户订单产品排行
List<GaoCustomerOrderProductRankView> customerProductRank(GaoSalesOrderChartReq req);
/// 查询销售订单状态统计
List<GaoSalesOrderStatusStatView> status(GaoSalesOrderChartReq req);
/// 查询销售订单应收统计
GaoSalesOrderReceivableStatView receivable(GaoSalesOrderChartReq req);
/// 查询客户每日有效消费统计
List<GaoSalesOrderConsumptionDailyStatView> consumptionDaily(GaoSalesOrderChartReq req);
/// 查询客户订单日历统计
List<GaoSalesOrderCalendarStatView> calendar(GaoSalesOrderChartReq req);
/// 查询客户每日复购统计
List<GaoCustomerRepeatDailyStatView> repeatDaily(GaoSalesOrderChartReq req);
/// 查询客户复购间隔统计
List<GaoCustomerRepeatIntervalStatView> repeatInterval(GaoSalesOrderChartReq req);
}
@@ -0,0 +1,109 @@
package com.imyeyu.api.modules.gao.service.implement;
import com.imyeyu.api.modules.gao.mapper.GaoProductChartMapper;
import com.imyeyu.api.modules.gao.service.GaoProductChartService;
import com.imyeyu.api.modules.gao.vo.GaoProductCategoryStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductChartReq;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductFulfillmentRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductSalesRankView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockHealthView;
import com.imyeyu.api.modules.gao.vo.GaoProductStockMovementDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductTypeStatView;
import com.imyeyu.api.modules.gao.vo.GaoProductUnitSalesRankView;
import com.imyeyu.java.bean.timi.TimiException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/// GAO 产品图表服务实现
///
/// @author Codex
/// @since 2026-09-06
@Service
@RequiredArgsConstructor
public class GaoProductChartServiceImplement implements GaoProductChartService {
private static final int DEFAULT_TOP_N = 20;
private static final int MAX_TOP_N = 100;
private final GaoProductChartMapper mapper;
@Override
public List<GaoProductSalesDailyStatView> salesDaily(GaoProductChartReq req) {
checkRangeReq(req);
return mapper.selectSalesDaily(req);
}
@Override
public List<GaoProductSalesRankView> salesRank(GaoProductChartReq req) {
checkRangeReq(req);
normalizeTopN(req);
return mapper.selectSalesRank(req);
}
@Override
public List<GaoProductFulfillmentDailyStatView> fulfillmentDaily(GaoProductChartReq req) {
checkRangeReq(req);
return mapper.selectFulfillmentDaily(req);
}
@Override
public List<GaoProductFulfillmentRankView> fulfillmentRank(GaoProductChartReq req) {
checkRangeReq(req);
normalizeTopN(req);
return mapper.selectFulfillmentRank(req);
}
@Override
public List<GaoProductStockMovementDailyStatView> stockMovementDaily(GaoProductChartReq req) {
checkRangeReq(req);
return mapper.selectStockMovementDaily(req);
}
@Override
public List<GaoProductStockHealthView> stockHealth(GaoProductChartReq req) {
checkStoreReq(req);
normalizeTopN(req);
return mapper.selectStockHealth(req);
}
@Override
public List<GaoProductTypeStatView> type(GaoProductChartReq req) {
checkStoreReq(req);
return mapper.selectType(req);
}
@Override
public List<GaoProductCategoryStatView> category(GaoProductChartReq req) {
checkStoreReq(req);
return mapper.selectCategory(req);
}
@Override
public List<GaoProductUnitSalesRankView> unitSalesRank(GaoProductChartReq req) {
checkRangeReq(req);
normalizeTopN(req);
return mapper.selectUnitSalesRank(req);
}
private void checkRangeReq(GaoProductChartReq req) {
checkStoreReq(req);
TimiException.required(req.getBeginAt(), "产品图表开始时间不能为空");
TimiException.required(req.getEndAt(), "产品图表结束时间不能为空");
TimiException.requiredTrue(req.getBeginAt() <= req.getEndAt(), "产品图表结束时间早于开始时间");
}
private void checkStoreReq(GaoProductChartReq req) {
TimiException.required(req, "产品图表请求不能为空");
TimiException.required(req.getStoreId(), "产品图表门店不能为空");
}
private void normalizeTopN(GaoProductChartReq req) {
int topN = req.getTopN() == null ? DEFAULT_TOP_N : req.getTopN();
TimiException.requiredTrue(0 < topN && topN < MAX_TOP_N + 1, "产品图表排行数量无效");
req.setTopN(topN);
}
}
@@ -0,0 +1,118 @@
package com.imyeyu.api.modules.gao.service.implement;
import com.imyeyu.api.modules.gao.mapper.GaoSalesOrderChartMapper;
import com.imyeyu.api.modules.gao.service.GaoSalesOrderChartService;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderProductRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerOrderRankView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoCustomerRepeatIntervalStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderChartReq;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderCalendarStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderConsumptionDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderDailyStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderPaymentStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderReceivableStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderStatusStatView;
import com.imyeyu.api.modules.gao.vo.GaoSalesOrderTypeStatView;
import com.imyeyu.java.bean.timi.TimiException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/// GAO 销售订单图表服务实现
///
/// @author Codex
/// @since 2026-09-06
@Service
@RequiredArgsConstructor
public class GaoSalesOrderChartServiceImplement implements GaoSalesOrderChartService {
private static final int DEFAULT_TOP_N = 20;
private static final int MAX_TOP_N = 100;
private final GaoSalesOrderChartMapper mapper;
@Override
public List<GaoSalesOrderDailyStatView> daily(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectDaily(req);
}
@Override
public List<GaoSalesOrderTypeStatView> type(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectType(req);
}
@Override
public List<GaoSalesOrderPaymentStatView> payment(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectPayment(req);
}
@Override
public List<GaoCustomerOrderRankView> customerRank(GaoSalesOrderChartReq req) {
checkRangeReq(req);
normalizeTopN(req);
return mapper.selectCustomerRank(req);
}
@Override
public List<GaoCustomerOrderProductRankView> customerProductRank(GaoSalesOrderChartReq req) {
checkRangeReq(req);
TimiException.required(req.getCustomerId(), "客户订单产品排行必须指定客户");
normalizeTopN(req);
return mapper.selectCustomerProductRank(req);
}
@Override
public List<GaoSalesOrderStatusStatView> status(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectStatus(req);
}
@Override
public GaoSalesOrderReceivableStatView receivable(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectReceivable(req);
}
@Override
public List<GaoSalesOrderConsumptionDailyStatView> consumptionDaily(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectConsumptionDaily(req);
}
@Override
public List<GaoSalesOrderCalendarStatView> calendar(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectCalendar(req);
}
@Override
public List<GaoCustomerRepeatDailyStatView> repeatDaily(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectRepeatDaily(req);
}
@Override
public List<GaoCustomerRepeatIntervalStatView> repeatInterval(GaoSalesOrderChartReq req) {
checkRangeReq(req);
return mapper.selectRepeatInterval(req);
}
private void checkRangeReq(GaoSalesOrderChartReq req) {
TimiException.required(req, "订单图表请求不能为空");
TimiException.required(req.getStoreId(), "订单图表门店不能为空");
TimiException.required(req.getBeginAt(), "订单图表开始时间不能为空");
TimiException.required(req.getEndAt(), "订单图表结束时间不能为空");
TimiException.requiredTrue(req.getBeginAt() <= req.getEndAt(), "订单图表结束时间早于开始时间");
}
private void normalizeTopN(GaoSalesOrderChartReq req) {
int topN = req.getTopN() == null ? DEFAULT_TOP_N : req.getTopN();
TimiException.requiredTrue(0 < topN && topN < MAX_TOP_N + 1, "订单图表排行数量无效");
req.setTopN(topN);
}
}
@@ -0,0 +1,40 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 客户订单产品排行视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoCustomerOrderProductRankView {
/// 产品 ID
private String productId;
/// 产品名称
private String productName;
/// 订单数
private Long orderCount;
/// 直接产品购买数量
private BigDecimal directQuantity;
/// 套餐权益数量
private BigDecimal packageQuantity;
/// 已预占数量
private BigDecimal reservedQuantity;
/// 已履约数量
private BigDecimal fulfilledQuantity;
/// 当前可履约数量
private BigDecimal availableQuantity;
/// 直接产品销售金额,单位分
private Long directSaleAmount;
}
@@ -0,0 +1,35 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 客户订单排行视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoCustomerOrderRankView {
/// 客户 ID
private String customerId;
/// 客户编码
private String customerCode;
/// 客户名称
private String customerName;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 有效退款,单位分
private Long refundedAmount;
/// 净收款,单位分
private Long netPaidAmount;
}
@@ -0,0 +1,23 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 客户复购每日统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoCustomerRepeatDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 当日购买客户数
private Long customerCount;
/// 当日复购客户数
private Long repeatCustomerCount;
/// 当日复购订单数
private Long repeatOrderCount;
}
@@ -0,0 +1,20 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 客户复购间隔统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoCustomerRepeatIntervalStatView {
/// 复购间隔天数
private Long intervalDays;
/// 发生复购的客户数
private Long customerCount;
/// 复购订单数
private Long orderCount;
}
@@ -0,0 +1,20 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 产品分类统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductCategoryStatView {
/// 分类 ID
private String categoryId;
/// 分类名称
private String categoryName;
/// 产品数量
private Long productCount;
}
@@ -0,0 +1,33 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoProduct;
import lombok.Data;
/// GAO 产品图表查询请求
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductChartReq {
/// 门店 ID
private String storeId;
/// 产品 ID
private String productId;
/// 分类 ID
private String categoryId;
/// 产品类型
private GaoProduct.ProductType productType;
/// 开始时间,包含
private Long beginAt;
/// 结束时间,包含
private Long endAt;
/// 返回排行数量
private Integer topN;
}
@@ -0,0 +1,25 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品每日履约统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductFulfillmentDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 直接产品履约数量
private BigDecimal directQuantity;
/// 套餐权益履约数量
private BigDecimal packageQuantity;
/// 履约基础单位数量
private BigDecimal baseQuantity;
}
@@ -0,0 +1,37 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品履约进度排行视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductFulfillmentRankView {
/// 产品 ID
private String productId;
/// 产品名称
private String productName;
/// 订单数
private Long orderCount;
/// 直接产品购买数量
private BigDecimal directQuantity;
/// 套餐权益数量
private BigDecimal packageQuantity;
/// 待履约数量
private BigDecimal reservedQuantity;
/// 已履约数量
private BigDecimal fulfilledQuantity;
/// 当前可履约数量
private BigDecimal availableQuantity;
}
@@ -0,0 +1,28 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品每日销售统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductSalesDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 包含该产品的订单数
private Long orderCount;
/// 直接产品销售数量
private BigDecimal directQuantity;
/// 套餐权益数量
private BigDecimal packageQuantity;
/// 直接产品销售金额,单位分
private Long directSaleAmount;
}
@@ -0,0 +1,31 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品销售排行视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductSalesRankView {
/// 产品 ID
private String productId;
/// 产品名称
private String productName;
/// 包含该产品的订单数
private Long orderCount;
/// 直接产品销售数量
private BigDecimal directQuantity;
/// 套餐权益数量
private BigDecimal packageQuantity;
/// 直接产品销售金额,单位分
private Long directSaleAmount;
}
@@ -0,0 +1,44 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoProduct;
import lombok.Data;
import java.math.BigDecimal;
/// 产品库存健康度视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductStockHealthView {
/// 产品 ID
private String productId;
/// 产品名称
private String productName;
/// 分类 ID
private String categoryId;
/// 分类名称
private String categoryName;
/// 产品类型
private GaoProduct.ProductType productType;
/// 实际库存,基础单位
private BigDecimal onHandQuantity;
/// 预占库存,基础单位
private BigDecimal reservedQuantity;
/// 可用库存,基础单位
private BigDecimal availableQuantity;
/// 最低库存,基础单位
private BigDecimal minStockQuantity;
/// 1 为低于最低库存,0 为正常
private Integer lowStock;
}
@@ -0,0 +1,31 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品每日库存变动统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductStockMovementDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 实际入库数量,基础单位
private BigDecimal inQuantity;
/// 实际出库数量,基础单位
private BigDecimal outQuantity;
/// 实际库存净变化,基础单位
private BigDecimal netOnHandQuantity;
/// 新增预占数量,基础单位
private BigDecimal reserveQuantity;
/// 释放预占数量,基础单位
private BigDecimal releaseQuantity;
}
@@ -0,0 +1,18 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoProduct;
import lombok.Data;
/// 产品类型统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductTypeStatView {
/// 产品类型
private GaoProduct.ProductType productType;
/// 产品数量
private Long productCount;
}
@@ -0,0 +1,34 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
import java.math.BigDecimal;
/// 产品销售单位排行视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoProductUnitSalesRankView {
/// 产品 ID
private String productId;
/// 产品名称
private String productName;
/// 产品单位 ID
private String productUnitId;
/// 单位名称
private String unitName;
/// 订单数
private Long orderCount;
/// 销售数量
private BigDecimal quantity;
/// 销售金额,单位分
private Long saleAmount;
}
@@ -0,0 +1,23 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 客户订单日历统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderCalendarStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 净收款,单位分
private Long netPaidAmount;
}
@@ -0,0 +1,36 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoSalesOrder;
import lombok.Data;
/// GAO 销售订单图表查询请求
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderChartReq {
/// 门店 ID
private String storeId;
/// 客户 ID
private String customerId;
/// 订单类型
private GaoSalesOrder.OrderType orderType;
/// 订单状态
private GaoSalesOrder.Status status;
/// 付款状态
private GaoSalesOrder.PaymentStatus paymentStatus;
/// 开始时间,包含
private Long beginAt;
/// 结束时间,包含
private Long endAt;
/// 返回排行数量
private Integer topN;
}
@@ -0,0 +1,23 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 客户每日有效消费统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderConsumptionDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 有效消费记录数
private Long recordCount;
/// 有效消费金额,单位分
private Long amount;
/// 截止当日累计有效消费金额,单位分
private Long cumulativeAmount;
}
@@ -0,0 +1,32 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 销售订单每日统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderDailyStatView {
/// 日期值,格式为 yyyyMMdd
private Integer dateValue;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 待核销收款,单位分
private Long pendingPaidAmount;
/// 有效退款,单位分
private Long refundedAmount;
/// 净收款,单位分
private Long netPaidAmount;
}
@@ -0,0 +1,33 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoSalesOrder;
import lombok.Data;
/// 销售订单付款状态统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderPaymentStatView {
/// 付款状态
private GaoSalesOrder.PaymentStatus paymentStatus;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 待核销收款,单位分
private Long pendingPaidAmount;
/// 未收金额,单位分
private Long unpaidAmount;
/// 有效退款,单位分
private Long refundedAmount;
}
@@ -0,0 +1,32 @@
package com.imyeyu.api.modules.gao.vo;
import lombok.Data;
/// 销售订单应收统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderReceivableStatView {
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 待核销收款,单位分
private Long pendingPaidAmount;
/// 未收金额,单位分
private Long unpaidAmount;
/// 有效退款,单位分
private Long refundedAmount;
/// 净收款,单位分
private Long netPaidAmount;
}
@@ -0,0 +1,27 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoSalesOrder;
import lombok.Data;
/// 销售订单状态统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderStatusStatView {
/// 订单状态
private GaoSalesOrder.Status status;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 有效退款,单位分
private Long refundedAmount;
}
@@ -0,0 +1,30 @@
package com.imyeyu.api.modules.gao.vo;
import com.imyeyu.api.modules.gao.entity.GaoSalesOrder;
import lombok.Data;
/// 销售订单类型统计视图
///
/// @author Codex
/// @since 2026-09-06
@Data
public class GaoSalesOrderTypeStatView {
/// 订单类型
private GaoSalesOrder.OrderType orderType;
/// 订单数
private Long orderCount;
/// 成交金额,单位分
private Long saleAmount;
/// 有效收款,单位分
private Long paidAmount;
/// 有效退款,单位分
private Long refundedAmount;
/// 净收款,单位分
private Long netPaidAmount;
}