framework/src/main/java/cn/lili/modules/goods/entity/dto/GoodsSkuDTO.java
@@ -26,6 +26,9 @@ @ApiModelProperty(value = "商品参数json") private String params; @ApiModelProperty(value = "商品排序") private Integer goodsSort; @ApiModelProperty(value = "预售结束时间") @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") framework/src/main/java/cn/lili/modules/goods/mapper/GoodsSkuMapper.java
@@ -114,7 +114,7 @@ * @param queryWrapper 查询条件 * @return 售后VO分页 */ @Select("SELECT *,g.params as params,g.pre_sale_end_date,g.pre_sale_begin_date FROM li_goods_sku gs inner join li_goods g on gs.goods_id = g.id ${ew.customSqlSegment}") @Select("SELECT *,g.params as params,g.goods_sort as goodsSort,g.pre_sale_end_date,g.pre_sale_begin_date FROM li_goods_sku gs inner join li_goods g on gs.goods_id = g.id ${ew.customSqlSegment}") IPage<GoodsSkuDTO> queryByParams(IPage<GoodsSkuDTO> page, @Param(Constants.WRAPPER) Wrapper<GoodsSkuDTO> queryWrapper); @Select("SELECT id as sku_id, quantity, goods_id,simple_specs,sn,goods_name FROM li_goods_sku ${ew.customSqlSegment}") 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,7 +156,13 @@ afterSaleApplyVO.setReturnGoods(false); } else { afterSaleApplyVO.setReturnMoney(true); afterSaleApplyVO.setReturnGoods(true); if(StringUtils.isNotBlank(order.getOrderStatus()) && DeliverStatusEnum.UNDELIVERED.name().equals(order.getOrderStatus())){ afterSaleApplyVO.setReturnGoods(false); }else { afterSaleApplyVO.setReturnGoods(true); } } afterSaleApplyVO.setAccountType(order.getPaymentMethod()); framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderExportDTO.java
@@ -89,4 +89,6 @@ private String storeName; private String nickName; private String memberId; } framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderExportDetailDTO.java
@@ -92,4 +92,6 @@ private String storeName; private String nickName; private String memberId; } 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/mapper/OrderMapper.java
@@ -61,7 +61,8 @@ "o.logistics_time AS logistics_time," + "o.complete_time AS complete_time," + "o.store_name AS store_name, " + "m.nick_name AS nickName" + "m.nick_name AS nickName," + "o.member_id AS memberId" + " FROM li_order o LEFT JOIN li_order_item oi ON oi.order_sn = o.sn " + "LEFT JOIN li_member m on m.id = o.member_id " + "${ew.customSqlSegment}") 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; @@ -1246,12 +1252,31 @@ orderLogService.saveBatch(orderLogList); //判断订单货物是否全部发货完毕 Boolean delivery = true; log.info("打印订单货物:{}",orderItemList); //需要再此处判断订单是否有申请售后状态 for (OrderItem orderItem : orderItemList) { if (orderItem.getDeliverNumber() < orderItem.getNum()) { delivery = false; break; // 先判断是否是未申请售后的订单 if (OrderItemAfterSaleStatusEnum.NOT_APPLIED.name().equals(orderItem.getAfterSaleStatus())){ // 发货数量小于订单数量则全发 log.info("打印发货数量:{},该商品订单数量货物对应的:{}",orderItem.getDeliverNumber(),orderItem.getNum()); if (orderItem.getDeliverNumber() < orderItem.getNum()) { delivery = false; break; } }else{ //全部退回情况 if(Objects.equals(orderItem.getReturnGoodsNumber(), orderItem.getNum())){ break; } //存在情况 退回数量不是全部退回而是部分退回 if (orderItem.getReturnGoodsNumber() + orderItem.getDeliverNumber() < orderItem.getNum()) { delivery = false; break; } } } log.info("delivery状态:{}",delivery); //是否全部发货 if (delivery) { return delivery(orderSn, invoiceNumber, logisticsId); @@ -1265,6 +1290,65 @@ order.setSellerRemark(sellerRemark); this.updateById(order); 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; } /** @@ -1283,6 +1367,7 @@ for (Order unpaidOrder : unpaidOrders) { this.systemCancel(unpaidOrder.getSn(), "拼团活动结束订单未付款,系统自动取消订单", false); } } List<Order> paidOrders = listMap.get(PayStatusEnum.PAID.name()); //如待参团人数大于0,并已开启虚拟成团 @@ -1616,7 +1701,7 @@ // 创建表头 Row header = sheet.createRow(0); String[] headers = {"主订单编号", "子订单编号", "选购商品", "商品数量", "商品ID", "商品单价", "订单应付金额", "运费", "优惠总金额", "平台优惠", "商家优惠", "商家改价", "支付方式","买家名称", "收件人", "收件人手机号", "运费", "优惠总金额", "平台优惠", "商家优惠", "商家改价", "支付方式","会员ID","买家名称", "收件人", "收件人手机号", "省", "市", "区", "街道", "详细地址", "买家留言", "订单提交时间", "支付完成时间", "来源", "订单状态", "订单类型", "售后状态", "取消原因", "发货时间", "完成时间", "店铺"}; @@ -1641,27 +1726,27 @@ row.createCell(10).setCellValue(dto.getStoreMarketingCost()!=null?dto.getStoreMarketingCost():0); row.createCell(11).setCellValue(dto.getUpdatePrice()!=null?dto.getUpdatePrice():0); row.createCell(12).setCellValue(dto.getPaymentMethod()); row.createCell(13).setCellValue(dto.getMemberId()); row.createCell(14).setCellValue(dto.getNickName()); row.createCell(13).setCellValue(dto.getNickName()); row.createCell(14).setCellValue(dto.getConsigneeName()); row.createCell(15).setCellValue(dto.getConsigneeMobile()); row.createCell(16).setCellValue(dto.getProvince()); row.createCell(17).setCellValue(dto.getCity()); row.createCell(18).setCellValue(dto.getDistrict()); row.createCell(19).setCellValue(dto.getStreet()); row.createCell(20).setCellValue(dto.getConsigneeDetail()); row.createCell(21).setCellValue(dto.getRemark()); row.createCell(22).setCellValue(dto.getCreateTime()); row.createCell(23).setCellValue(dto.getPaymentTime()); row.createCell(24).setCellValue(dto.getClientType()); row.createCell(25).setCellValue(dto.getOrderStatus()); row.createCell(26).setCellValue(dto.getOrderType()); row.createCell(27).setCellValue(dto.getAfterSaleStatus()); row.createCell(28).setCellValue(dto.getCancelReason()); row.createCell(29).setCellValue(dto.getLogisticsTime()); row.createCell(30).setCellValue(dto.getCompleteTime()); row.createCell(31).setCellValue(dto.getStoreName()); row.createCell(15).setCellValue(dto.getConsigneeName()); row.createCell(16).setCellValue(dto.getConsigneeMobile()); row.createCell(17).setCellValue(dto.getProvince()); row.createCell(18).setCellValue(dto.getCity()); row.createCell(19).setCellValue(dto.getDistrict()); row.createCell(20).setCellValue(dto.getStreet()); row.createCell(21).setCellValue(dto.getConsigneeDetail()); row.createCell(22).setCellValue(dto.getRemark()); row.createCell(23).setCellValue(dto.getCreateTime()); row.createCell(24).setCellValue(dto.getPaymentTime()); row.createCell(25).setCellValue(dto.getClientType()); row.createCell(26).setCellValue(dto.getOrderStatus()); row.createCell(27).setCellValue(dto.getOrderType()); row.createCell(28).setCellValue(dto.getAfterSaleStatus()); row.createCell(29).setCellValue(dto.getCancelReason()); row.createCell(30).setCellValue(dto.getLogisticsTime()); row.createCell(31).setCellValue(dto.getCompleteTime()); row.createCell(32).setCellValue(dto.getStoreName()); } //修改列宽 framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java
@@ -45,6 +45,7 @@ import cn.lili.modules.search.service.EsGoodsSearchService; import cn.lili.rocketmq.RocketmqSendCallbackBuilder; import cn.lili.rocketmq.tags.GoodsTagsEnum; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -256,7 +257,8 @@ if (CollUtil.isNotEmpty(promotionGoods)) { esGoodsIndex.setPromotionMapJson(JSONUtil.toJsonStr(promotionService.wrapperPromotionMapList(promotionGoods))); } log.info("构建出es的索引信息为{}", JSON.toJSONString(esGoodsIndex)); esGoodsIndex.setGoodsSort(goodsSku.getGoodsSort()); esGoodsIndices.add(esGoodsIndex); //库存锁是在redis做的,所以生成索引,同时更新一下redis中的库存数量 cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity()); 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,12 @@ 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.entity.enums.StoreStatusEnum; 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 +35,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 +48,8 @@ @RequestMapping("/manager/order/order") @Api(tags = "管理端,订单API") public class OrderManagerController { @Autowired private StoreMapper storeMapper; /** * 订单 @@ -59,6 +68,25 @@ @Autowired private COSUtil cosUtil; @ApiModelProperty(value = "店铺下拉") @GetMapping("/storeSelect") public ResultMessage<List<SelectVO>> getStoreSelect(){ List<Store> storeList = new LambdaQueryChainWrapper<>(storeMapper) .eq(Store::getDeleteFlag,Boolean.FALSE) .eq(Store::getStoreDisable, StoreStatusEnum.OPEN.name()) .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) {