framework/src/main/java/cn/lili/modules/lmk/domain/vo/PvUvVO.java
New file @@ -0,0 +1,31 @@ package cn.lili.modules.lmk.domain.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; /** * lmk-shop-java * * @author : zxl * @date : 2025-09-19 15:26 **/ @Data @AllArgsConstructor @NoArgsConstructor public class PvUvVO { /** * pv折线图数据 */ private List<Long> pvData; /** * uv折线图数据 */ private List<Long> uvData; } framework/src/main/java/cn/lili/modules/lmk/domain/vo/SelectVO.java
New file @@ -0,0 +1,26 @@ package cn.lili.modules.lmk.domain.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * lmk-shop-java * * @author : zxl * @date : 2025-09-22 10:09 **/ @Data @AllArgsConstructor @NoArgsConstructor public class SelectVO { /** * 下拉框id */ private String id; /** * 下拉框label */ private String label; } framework/src/main/java/cn/lili/modules/lmk/enums/general/StatisticsSearchTypeEnum.java
New file @@ -0,0 +1,21 @@ package cn.lili.modules.lmk.enums.general; import lombok.AllArgsConstructor; import lombok.Getter; /** * 统计搜索类型枚举 */ @Getter @AllArgsConstructor public enum StatisticsSearchTypeEnum { TODAY("今天"), YESTERDAY("昨天"), LAST_SEVEN("过去七天"), LAST_THIRTY("过去一个月"); private final String desc; } framework/src/main/java/cn/lili/modules/order/aftersale/serviceimpl/AfterSaleServiceImpl.java
@@ -14,6 +14,7 @@ import cn.lili.common.utils.BeanUtil; import cn.lili.common.utils.CurrencyUtil; import cn.lili.common.utils.SnowFlake; import cn.lili.common.utils.StringUtils; import cn.lili.modules.order.aftersale.aop.AfterSaleLogPoint; import cn.lili.modules.order.aftersale.entity.dos.AfterSale; import cn.lili.modules.order.aftersale.entity.dto.AfterSaleDTO; @@ -155,9 +156,15 @@ afterSaleApplyVO.setReturnGoods(false); } else { afterSaleApplyVO.setReturnMoney(true); if(StringUtils.isNotBlank(order.getOrderStatus()) && DeliverStatusEnum.UNDELIVERED.name().equals(order.getOrderStatus())){ afterSaleApplyVO.setReturnGoods(false); }else { afterSaleApplyVO.setReturnGoods(true); } } afterSaleApplyVO.setAccountType(order.getPaymentMethod()); afterSaleApplyVO.setApplyRefundPrice(CurrencyUtil.div(orderItem.getFlowPrice(), orderItem.getNum())); //如果已经退货或者退款过,则返回最大售后数量重新设置 framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java
@@ -119,6 +119,7 @@ private String couponFlag; private String storeSelectId; public <T> QueryWrapper<T> queryWrapper() { AuthUser currentUser = UserContext.getCurrentUser(); @@ -128,6 +129,7 @@ if (CharSequenceUtil.isNotEmpty(keywords)) { wrapper.and(keyWrapper -> keyWrapper.like("o.sn", keywords).or().like("oi.goods_name", keywords)); } //更具角色查询的 if (currentUser != null) { //按卖家查询 wrapper.eq(CharSequenceUtil.equals(currentUser.getRole().name(), UserEnums.STORE.name()), "o.store_id", currentUser.getStoreId()); @@ -140,6 +142,9 @@ wrapper.eq(CharSequenceUtil.equals(currentUser.getRole().name(), UserEnums.MEMBER.name()) && memberId == null, "o.member_id", currentUser.getId()); } //按下拉框选择查询 wrapper.eq(CharSequenceUtil.isNotEmpty(storeSelectId), "o.store_id", storeSelectId); //按照买家查询 wrapper.like(CharSequenceUtil.isNotEmpty(memberId), "o.member_id", memberId); framework/src/main/java/cn/lili/modules/order/order/service/OrderService.java
@@ -1,5 +1,6 @@ package cn.lili.modules.order.order.service; import cn.lili.base.Result; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.lmk.domain.vo.OrderCountVO; import cn.lili.modules.member.entity.dto.MemberAddressDTO; @@ -10,6 +11,7 @@ import cn.lili.modules.order.order.entity.vo.OrderSimpleVO; import cn.lili.modules.order.order.entity.vo.OrderSimpleXcxVO; import cn.lili.modules.order.order.entity.vo.PaymentLog; import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam; import cn.lili.modules.system.entity.vo.Traces; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -352,4 +354,10 @@ Order updateSellerRemark(String orderSn, String sellerRemark); /** * 获得每日订单统计数据 订单统计折线图用 * @param queryParam * @return */ Result getOrderCount(StatisticsQueryParam queryParam); } framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java
@@ -10,6 +10,7 @@ import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import cn.lili.base.Result; import cn.lili.common.enums.ClientTypeEnum; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.enums.ResultCode; @@ -56,6 +57,7 @@ import cn.lili.modules.promotion.entity.dos.Pintuan; import cn.lili.modules.promotion.service.CouponService; import cn.lili.modules.promotion.service.PintuanService; import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam; import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO; import cn.lili.modules.store.service.StoreDetailService; import cn.lili.modules.system.aspect.annotation.SystemLogPoint; @@ -86,6 +88,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Cell; @@ -109,6 +112,9 @@ import java.io.InputStream; import java.math.BigDecimal; import java.net.URLEncoder; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -1267,6 +1273,65 @@ return order; } @Override public Result getOrderCount(StatisticsQueryParam queryParam) { LocalDateTime startTime = null; LocalDateTime endTime = LocalDateTime.now(); // 结束时间默认是当前时间 int days = 0; switch (queryParam.getSearchType()) { case "TODAY": // 今天:从今天0点到现在 startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); days = 1; break; case "YESTERDAY": // 昨天:从昨天0点到昨天23:59:59 LocalDate yesterday = LocalDate.now().minusDays(1); startTime = LocalDateTime.of(yesterday, LocalTime.MIN); endTime = LocalDateTime.of(yesterday, LocalTime.MAX); days = 1; break; case "LAST_SEVEN": // 过去七天:从7天前0点到现在 startTime = LocalDateTime.of(LocalDate.now().minusDays(6), LocalTime.MIN); days = 7; break; case "LAST_THIRTY": // 过去30天:从30天前0点到现在 startTime = LocalDateTime.of(LocalDate.now().minusDays(29), LocalTime.MIN); days = 30; break; default: return Result.error("不支持的时间范围类型"); } // 2. 查询该时间范围内的每日订单数量(按日期分组) // LambdaQueryWrapper<Order> queryWrapper = Wrappers.lambdaQuery(); // queryWrapper.between(Order::getCreateTime, startTime, endTime); // // 按日期分组(提取日期部分) // // // 执行查询,返回日期和数量的映射(day -> count) // List<Map<String, Object>> maps = baseMapper.selectMaps(queryWrapper); // Map<String, Long> dayCountMap = maps.stream() // .collect(Collectors.toMap( // map -> map.get("day").toString(), // 日期字符串(如2023-09-19) // map -> Long.valueOf(map.get("count").toString()) // 订单数量 // )); // // // 3. 生成完整的日期列表(确保即使某天没有订单也会返回0) // List<Long> orderCounts = new ArrayList<>(days); // for (int i = 0; i < days; i++) { // // 计算当前循环对应的日期(从startTime开始的第i天) // LocalDate currentDate = startTime.toLocalDate().plusDays(i); // String dateStr = currentDate.toString(); // 转为yyyy-MM-dd格式 // // 从映射中获取数量,没有则为0 // orderCounts.add(dayCountMap.getOrDefault(dateStr, 0L)); // } return null; } /** * 虚拟成团 * framework/src/main/java/cn/lili/modules/statistics/entity/dto/StatisticsQueryParam.java
@@ -3,6 +3,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import cn.lili.modules.lmk.enums.general.StatisticsSearchTypeEnum; /** * 统计查询参数 * @@ -13,6 +14,9 @@ public class StatisticsQueryParam { @ApiModelProperty(value = "快捷搜索", allowableValues = "TODAY, YESTERDAY, LAST_SEVEN, LAST_THIRTY") /** * @see StatisticsSearchTypeEnum */ private String searchType; @ApiModelProperty(value = "类型:年(YEAR)、月(MONTH)") framework/src/main/java/cn/lili/modules/statistics/serviceimpl/PlatformViewServiceImpl.java
@@ -226,7 +226,6 @@ //获取当前时间 Calendar calendar = Calendar.getInstance(); calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); //如果是今天的统计,则从redis 中拿,否则从数据库中拿 manager-api/src/main/java/cn/lili/controller/lmk/StatisticsController.java
New file @@ -0,0 +1,84 @@ package cn.lili.controller.lmk; import cn.lili.base.Result; import cn.lili.common.enums.ResultUtil; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.lmk.domain.vo.PvUvVO; import cn.lili.modules.lmk.enums.general.StatisticsSearchTypeEnum; import cn.lili.modules.order.order.service.OrderService; import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam; import cn.lili.modules.statistics.entity.vo.PlatformViewVO; import cn.lili.modules.statistics.service.PlatformViewService; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; /** * lmk-shop-java * 统计数据控制层 * * @author : zxl * @date : 2025-09-16 16:36 **/ @RestController @AllArgsConstructor @RequestMapping("/manager/lmk/statistics") public class StatisticsController { private final OrderService orderService; @ApiOperation(value = "获取pv、uv流量数据 表单获取") @GetMapping("/pvUv") public Result getPVUVData(StatisticsQueryParam queryParam) { //TODO 获得 pv/uv数据 PvUvVO pvUvVO = new PvUvVO(); List<Long> pvData = new ArrayList<>(); List<Long> uvData = new ArrayList<>(); switch (queryParam.getSearchType()) { case "TODAY": // 今天的数据:添加1 pvData.add(1L); uvData.add(9L); break; case "YESTERDAY": // 明天的数据:添加1 pvData.add(1L); uvData.add(10L); break; case "LAST_SEVEN": // 过去七天的数据:添加1, 2, 3 for(int i =1;i<=7;i++){ pvData.add((long) i); uvData.add((long) i+7); } break; case "LAST_THIRTY": // 过去一个月的数据:可以根据需要自定义,这里示例添加1到5 for(int i =1;i<=30;i++){ pvData.add((long) i); uvData.add((long) i+7); } break; } pvUvVO.setPvData(pvData); pvUvVO.setUvData(uvData); return Result.ok().data(pvUvVO); } @GetMapping("/orderCount") public Result getOrderCount(StatisticsQueryParam queryParam) { return orderService.getOrderCount(queryParam); } } manager-api/src/main/java/cn/lili/controller/order/OrderManagerController.java
@@ -2,6 +2,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.NumberUtil; import cn.lili.base.Result; import cn.lili.common.aop.annotation.PreventDuplicateSubmissions; import cn.lili.common.context.ThreadContextHolder; import cn.lili.common.enums.ResultCode; @@ -9,6 +10,7 @@ import cn.lili.common.utils.StringUtils; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.lmk.domain.vo.OrderCountVO; import cn.lili.modules.lmk.domain.vo.SelectVO; import cn.lili.modules.member.entity.dto.MemberAddressDTO; import cn.lili.modules.order.order.entity.dos.Order; import cn.lili.modules.order.order.entity.dto.OrderExportDTO; @@ -18,8 +20,11 @@ import cn.lili.modules.order.order.service.OrderPackageService; import cn.lili.modules.order.order.service.OrderPriceService; import cn.lili.modules.order.order.service.OrderService; import cn.lili.modules.store.entity.dos.Store; import cn.lili.modules.store.mapper.StoreMapper; import cn.lili.utils.COSUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -29,6 +34,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; /** @@ -41,6 +47,8 @@ @RequestMapping("/manager/order/order") @Api(tags = "管理端,订单API") public class OrderManagerController { @Autowired private StoreMapper storeMapper; /** * 订单 @@ -59,6 +67,24 @@ @Autowired private COSUtil cosUtil; @ApiModelProperty(value = "店铺下拉") @GetMapping("/storeSelect") public ResultMessage<List<SelectVO>> getStoreSelect(){ List<Store> storeList = new LambdaQueryChainWrapper<>(storeMapper) .eq(Store::getDeleteFlag,Boolean.FALSE) .list(); List<SelectVO> selectVOS = new ArrayList<>(); for (Store store : storeList){ SelectVO vo = new SelectVO(); vo.setId(store.getId()); vo.setLabel(store.getStoreName()); selectVOS.add(vo); } return ResultUtil.data(selectVOS); } @ApiOperation(value = "查询订单列表分页") @GetMapping public ResultMessage<IPage<OrderSimpleVO>> queryMineOrder(OrderSearchParams orderSearchParams) {