16个文件已修改
17个文件已添加
1278 ■■■■■ 已修改文件
buyer-api/src/main/java/cn/lili/controller/lmk/ActionRecordBuyerController.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/goods/entity/dto/GoodsSkuDTO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/goods/mapper/GoodsSkuMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/entity/ShareAction.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/form/ShareActionForm.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/query/ShareActionQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/PvUvVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/SelectVO.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/ShareActionVO.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoViewCompletionRateVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/StatisticsSearchTypeEnum.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionInPageStatusEnum.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionJoinPageTypeEnum.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageEnums.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageTypeEnum.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionTypeEnum.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/mapper/ShareActionMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/ShareActionService.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/ShareActionServiceImpl.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/member/mapper/FootprintMapper.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/member/service/FootprintService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/member/serviceimpl/FootprintServiceImpl.java 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/order/aftersale/serviceimpl/AfterSaleServiceImpl.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/order/order/entity/dto/OrderSearchParams.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/order/order/mapper/OrderMapper.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/order/order/service/OrderService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsIndexServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/statistics/entity/dto/StatisticsQueryParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/statistics/serviceimpl/PlatformViewServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/ShareActionMapper.xml 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/java/cn/lili/controller/lmk/StatisticsController.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/java/cn/lili/controller/order/OrderManagerController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/java/cn/lili/controller/lmk/ActionRecordBuyerController.java
@@ -1,20 +1,15 @@
package cn.lili.controller.lmk;
import cn.lili.group.Update;
import cn.lili.base.Result;
import cn.lili.group.Add;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.form.ShareActionForm;
import cn.lili.modules.lmk.service.ActionRecordService;
import cn.lili.modules.lmk.service.ShareActionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import cn.lili.modules.lmk.service.ActionRecordService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.ActionRecordForm;
import cn.lili.modules.lmk.domain.query.ActionRecordQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
@@ -31,12 +26,18 @@
public class ActionRecordBuyerController {
    private final ActionRecordService actionRecordService;
    private final ShareActionService shareActionService;
    @PostMapping
    @ApiOperation(value = "添加", notes = "添加")
    public Result add(@RequestBody @Validated(Add.class) ActionRecordForm form) {
        return actionRecordService.add(form);
    }
    @PostMapping("/share")
    @ApiOperation(value = "添加分享", notes = "添加分享")
    public Result shareAdd(@RequestBody @Validated(Add.class) ShareActionForm form) {
        return shareActionService.add(form);
    }
    @GetMapping("/sessionId")
    @ApiOperation(value = "获取会话id", notes = "获取会话id")
    public Result grantSessionId() {
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/entity/ShareAction.java
New file
@@ -0,0 +1,42 @@
package cn.lili.modules.lmk.domain.entity;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
 * 用户行为分享
 *
 * @author peng
 * @since 2025-09-25
 */
@Data
@TableName("lmk_share_action")
public class ShareAction extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableField("user_id")
    /** 用户id */
    private String userId;
    @TableField("share_option")
    /** 分享参数 */
    private String shareOption;
    @TableField("page_code")
    /** 页面编码 */
    private String pageCode;
    @TableField("page_type")
    /** 页面类型 */
    private String pageType;
    @TableField("pid")
    /** pid */
    private Long pid;
}
framework/src/main/java/cn/lili/modules/lmk/domain/form/ShareActionForm.java
New file
@@ -0,0 +1,52 @@
package cn.lili.modules.lmk.domain.form;
import cn.lili.group.Update;
import cn.lili.group.Add;
import cn.lili.base.AbsForm;
import cn.lili.modules.lmk.domain.entity.ShareAction;
import org.springframework.beans.BeanUtils;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.springframework.lang.NonNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * 用户行为分享表单
 *
 * @author peng
 * @since 2025-09-25
 */
@Data
@ApiModel(value = "ShareAction表单", description = "用户行为分享表单")
public class ShareActionForm extends AbsForm {
    @ApiModelProperty("用户id")
    private Long userId;
    @NotBlank(message = "分享参数不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("分享参数")
    private String shareOption;
    @NotBlank(message = "页面编码不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面编码")
    private String pageCode;
    @NotBlank(message = "页面类型不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("页面类型")
    private String pageType;
    @ApiModelProperty("pid")
    private Long pid;
    public static ShareAction getEntityByForm(@NonNull ShareActionForm form, ShareAction entity) {
        if(entity == null) {
          entity = new ShareAction();
        }
        BeanUtils.copyProperties(form, entity);
        return entity;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/query/ShareActionQuery.java
New file
@@ -0,0 +1,22 @@
package cn.lili.modules.lmk.domain.query;
import cn.lili.base.AbsQuery;
import java.util.List;
import org.springframework.lang.NonNull;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * 用户行为分享查询
 *
 * @author peng
 * @since 2025-09-25
 */
@Data
@ApiModel(value = "ShareAction查询参数", description = "用户行为分享查询参数")
public class ShareActionQuery extends AbsQuery {
}
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/domain/vo/ShareActionVO.java
New file
@@ -0,0 +1,51 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.ShareAction;
import java.util.List;
import org.springframework.lang.NonNull;
import org.springframework.beans.BeanUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * 用户行为分享展示
 *
 * @author peng
 * @since 2025-09-25
 */
@Data
@ApiModel(value = "用户行为分享响应数据", description = "用户行为分享响应数据")
public class ShareActionVO extends AbsVo {
    /** 用户id */
    @ApiModelProperty("用户id")
    private Long userId;
    /** 分享参数 */
    @ApiModelProperty("分享参数")
    private String shareOption;
    /** 页面编码 */
    @ApiModelProperty("页面编码")
    private String pageCode;
    /** 页面类型 */
    @ApiModelProperty("页面类型")
    private String pageType;
    /** pid */
    @ApiModelProperty("pid")
    private Long pid;
    public static ShareActionVO getVoByEntity(@NonNull ShareAction entity, ShareActionVO vo) {
        if(vo == null) {
            vo = new ShareActionVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoViewCompletionRateVO.java
New file
@@ -0,0 +1,22 @@
package cn.lili.modules.lmk.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * lmk-shop-java
 *
 * @author : zxl
 * @date : 2025-09-25 15:36
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VideoViewCompletionRateVO {
    private String complete_rate;
    private Long total_views;
}
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/lmk/enums/general/UserActionInPageStatusEnum.java
New file
@@ -0,0 +1,19 @@
package cn.lili.modules.lmk.enums.general;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum UserActionInPageStatusEnum {
    JOIN("进入"),
    LEAVE("离开");
    private final String des;
    public UserActionInPageStatusEnum select(String name){
        for (UserActionInPageStatusEnum value : UserActionInPageStatusEnum.values()) {
            if (value.name().equals(name)) {
                return value;
            }
        }
        return null;
    }
}
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionJoinPageTypeEnum.java
New file
@@ -0,0 +1,20 @@
package cn.lili.modules.lmk.enums.general;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum UserActionJoinPageTypeEnum {
    SCAN("扫码"),
    SELF("自己"),
    SHARE("分享");
    private final String des;
    public UserActionJoinPageTypeEnum select(String name){
        for (UserActionJoinPageTypeEnum value : UserActionJoinPageTypeEnum.values()) {
            if (value.name().equals(name)) {
                return value;
            }
        }
        return null;
    }
}
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageEnums.java
@@ -16,7 +16,19 @@
    ORDER_LIST("订单列表"),
    ORDER_DETAIL("订单详情"),
    ACTIVITY("活动"),
    PRIZE_DETAIL("抽奖活动"),
    CART_LIST("购物车"),
    TBA_BAR_MY("我的页面"),
    SHOPPING_SQUARE("商品广场"),
    ACTIVITY_LIST("活动列表"),
    ACTIVITY_DETAIL("活动详情"),
    PUBLISH_VIDEO("视频发布"),
    SWIPER_GOODS("滑动商品"),
    COUPON_CENTER("领卷中心"),
    MY_COUPON("我的优惠卷"),
    AFTER_SALE("售后列表"),
    APPLY_SALE("申请售后"),
    REFUND_ORDER("退款/退货"),
    GOODS_DETAILS("商品详情页面");
    private final String des;
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionPageTypeEnum.java
New file
@@ -0,0 +1,19 @@
package cn.lili.modules.lmk.enums.general;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum UserActionPageTypeEnum {
    LIST("列表页"),
    DETAIL("详情页");
    private final String des;
    public UserActionPageTypeEnum select(String name){
        for (UserActionPageTypeEnum value : UserActionPageTypeEnum.values()) {
            if (value.name().equals(name)) {
                return value;
            }
        }
        return null;
    }
}
framework/src/main/java/cn/lili/modules/lmk/enums/general/UserActionTypeEnum.java
New file
@@ -0,0 +1,19 @@
package cn.lili.modules.lmk.enums.general;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum UserActionTypeEnum {
    PAGE("页面"),
    BTN("功能");
    private final String des;
    public UserActionTypeEnum select(String name){
        for (UserActionTypeEnum value : UserActionTypeEnum.values()) {
            if (value.name().equals(name)) {
                return value;
            }
        }
        return null;
    }
}
framework/src/main/java/cn/lili/modules/lmk/mapper/ShareActionMapper.java
New file
@@ -0,0 +1,34 @@
package cn.lili.modules.lmk.mapper;
import cn.lili.modules.lmk.domain.entity.ShareAction;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.lili.modules.lmk.domain.vo.ShareActionVO;
import cn.lili.modules.lmk.domain.form.ShareActionForm;
import cn.lili.modules.lmk.domain.query.ShareActionQuery;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * 用户行为分享 Mapper 接口
 *
 * @author peng
 * @since 2025-09-25
 */
@Mapper
public interface ShareActionMapper extends BaseMapper<ShareAction> {
    /**
     * id查找用户行为分享
     * @param id
     * @return
     */
    ShareActionVO getById(String id);
    /**
    *  分页
    */
    IPage getPage(IPage page, @Param("query") ShareActionQuery query);
}
framework/src/main/java/cn/lili/modules/lmk/service/ShareActionService.java
New file
@@ -0,0 +1,65 @@
package cn.lili.modules.lmk.service;
import cn.lili.modules.lmk.domain.entity.ShareAction;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.ShareActionForm;
import cn.lili.modules.lmk.domain.query.ShareActionQuery;
import java.util.List;
/**
 * 用户行为分享 服务类
 *
 * @author peng
 * @since 2025-09-25
 */
public interface ShareActionService extends IService<ShareAction> {
    /**
     * 添加
     * @param form
     * @return
     */
    Result add(ShareActionForm form);
    /**
     * 修改
     * @param form
     * @return
     */
    Result update(ShareActionForm form);
    /**
     * 批量删除
     * @param ids
     * @return
     */
    Result remove(List<String> ids);
    /**
     * id删除
     * @param id
     * @return
     */
    Result removeById(String id);
    /**
     * 分页查询
     * @param query
     * @return
     */
    Result page(ShareActionQuery query);
    /**
     * 根据id查找
     * @param id
     * @return
     */
    Result detail(String id);
    /**
     * 列表
     * @return
     */
    Result all();
}
framework/src/main/java/cn/lili/modules/lmk/service/impl/ShareActionServiceImpl.java
New file
@@ -0,0 +1,127 @@
package cn.lili.modules.lmk.service.impl;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.lili.modules.lmk.domain.entity.ShareAction;
import cn.lili.modules.lmk.mapper.ShareActionMapper;
import cn.lili.modules.lmk.service.ShareActionService;
import cn.lili.base.Result;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.lili.modules.lmk.domain.form.ShareActionForm;
import cn.lili.modules.lmk.domain.vo.ShareActionVO;
import cn.lili.modules.lmk.domain.query.ShareActionQuery;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import cn.lili.utils.PageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 用户行为分享 服务实现类
 *
 * @author peng
 * @since 2025-09-25
 */
@Service
@RequiredArgsConstructor
public class ShareActionServiceImpl extends ServiceImpl<ShareActionMapper, ShareAction> implements ShareActionService {
    private final ShareActionMapper shareActionMapper;
    /**
     * 添加
     * @param form
     * @return
     */
    @Override
    public Result add(ShareActionForm form) {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            return Result.ok();
        }
        ShareAction entity = ShareActionForm.getEntityByForm(form, null);
        entity.setUserId(currentUser.getId());
        baseMapper.insert(entity);
        return Result.ok("添加成功").data(entity.getId());
    }
    /**
     * 修改
     * @param form
     * @return
     */
    @Override
    public Result update(ShareActionForm form) {
        ShareAction entity = baseMapper.selectById(form.getId());
        // 为空抛IllegalArgumentException,做全局异常处理
        Assert.notNull(entity, "记录不存在");
        BeanUtils.copyProperties(form, entity);
        baseMapper.updateById(entity);
        return Result.ok("修改成功");
    }
    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public Result remove(List<String> ids) {
        baseMapper.deleteBatchIds(ids);
        return Result.ok("删除成功");
    }
    /**
     * id删除
     * @param id
     * @return
     */
    @Override
    public Result removeById(String id) {
        baseMapper.deleteById(id);
        return Result.ok("删除成功");
    }
    /**
     * 分页查询
     * @param query
     * @return
     */
    @Override
    public Result page(ShareActionQuery query) {
        IPage<ShareActionVO> page = PageUtil.getPage(query, ShareActionVO.class);
        baseMapper.getPage(page, query);
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 根据id查找
     * @param id
     * @return
     */
    @Override
    public Result detail(String id) {
        ShareActionVO vo = baseMapper.getById(id);
        Assert.notNull(vo, "记录不存在");
        return Result.ok().data(vo);
    }
    /**
     * 列表
     * @return
     */
    @Override
    public Result all() {
        List<ShareAction> entities = baseMapper.selectList(null);
        List<ShareActionVO> vos = entities.stream()
                .map(entity -> ShareActionVO.getVoByEntity(entity, null))
                .collect(Collectors.toList());
        return Result.ok().data(vos);
    }
}
framework/src/main/java/cn/lili/modules/member/mapper/FootprintMapper.java
@@ -3,6 +3,12 @@
import cn.lili.modules.member.entity.dos.FootPrint;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 浏览历史数据处理层
@@ -32,4 +38,65 @@
            "WHERE li_foot_print.member_id = ${memberId} AND latest_footprints.id IS NULL; ")
    void deleteLastFootPrint(String memberId);
    @Select("SELECT " +
            "lfp.ref_id AS GoodsId, " +
            "lg.goods_name AS GoodsName, "+
            "COUNT(*) AS view_count " +
            "FROM li_foot_print lfp " +
            "LEFT JOIN li_goods lg ON lfp.ref_id = lg.id " +
            "WHERE lfp.delete_flag = 0 " +
            "AND lfp.create_time BETWEEN #{startTime} AND #{endTime} " +
            "AND lfp.view_type = 'goods' " +
            "AND lg.goods_name is not null " +
            "GROUP BY lfp.ref_id " +  // 按商品ID分组
            "ORDER BY view_count DESC " +
            "LIMIT #{currentLimit}"
            )
    List<Map<String,Object>> selectViewAndCompletionRateCountByDay(Date startTime,
                                                                   Date endTime,
                                                                   Integer currentLimit);
    /**
     * 按视频维度统计:每个视频的总浏览数和完播率
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 包含视频ID、名称、总浏览数、完播率的列表
     */
    @Select({
            "SELECT",
            "  lfp.ref_id AS video_id, " +
            "  lmk.title, " +
            "  COUNT(*) AS total_views, " +
            "  ROUND(" +
                    "    IF(COUNT(*) = 0, 0," +
                    "      (SUM(" +
                    "          CASE WHEN ( " +
                    "            CAST(lfp.play_at AS DECIMAL(10,3)) >= CAST(lmk.video_duration AS DECIMAL(10,3)) " +
                    "            OR " +
                    "            CAST(lfp.play_at AS DECIMAL(10,3)) / CAST(lmk.video_duration AS DECIMAL(10,3)) > 0.9 " +
                    "          ) THEN 1  " +
                    "          ELSE 0 " +
                    "        END " +
                    "      ) / COUNT(*)) * 100  " +
                    "    ), 2  " +
                    "  ) AS complete_rate " +
            "FROM li_foot_print lfp" +
            "  LEFT JOIN lmk_video lmk ON lfp.ref_id = lmk.id " +  // 按实际关联字段调整
            "WHERE " +
            "  lfp.delete_flag = 0",
            "  AND lfp.view_type = 'video' " +// 只统计视频类型
            "  AND lfp.create_time BETWEEN #{startTime} AND #{endTime} " +
            "  AND lmk.video_duration > 0 " +
            "  AND ref_id IS NOT NULL AND lmk.title IS NOT NULL "+
            "GROUP BY lfp.ref_id "+
            "ORDER BY total_views DESC " +
            "LIMIT #{currentLimit}"
    })
    List<Map<String, Object>> selectEachVideoStats(
             Date startTime,
            Date endTime,
            Integer currentLimit
    );
}
framework/src/main/java/cn/lili/modules/member/service/FootprintService.java
@@ -8,6 +8,7 @@
import cn.lili.modules.member.entity.dos.FootPrint;
import cn.lili.modules.member.entity.dto.FootPrintQueryParams;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -75,4 +76,5 @@
     */
    long getFootprintNum();
    Result getViewAndCompletionRateCount(StatisticsQueryParam queryParam);
}
framework/src/main/java/cn/lili/modules/member/serviceimpl/FootprintServiceImpl.java
@@ -2,19 +2,18 @@
import cn.lili.base.Result;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.lmk.domain.query.FootPrintQuery;
import cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO;
import cn.lili.modules.lmk.domain.vo.VideoFootInfoVo;
import cn.lili.modules.lmk.domain.vo.VideoFootVO;
import cn.lili.modules.lmk.domain.vo.VideoVO;
import cn.lili.modules.lmk.domain.vo.*;
import cn.lili.modules.lmk.mapper.VideoMapper;
import cn.lili.modules.member.entity.dos.FootPrint;
import cn.lili.modules.member.entity.dto.FootPrintQueryParams;
import cn.lili.modules.member.mapper.FootprintMapper;
import cn.lili.modules.member.service.FootprintService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.utils.COSUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -28,6 +27,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -168,7 +168,151 @@
        return this.count(lambdaQueryWrapper);
    }
    @Override
    public Result getViewAndCompletionRateCount(StatisticsQueryParam queryParam) {
        Date startTime = null;
        Date endTime = new Date(); // 结束时间默认是当前时间
        List<String> dateList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance(); // 用于日期计算的日历实例
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int days = 0;
        switch (queryParam.getSearchType()) {
            case "TODAY":
                // 今天:从今天0点到现在
                calendar.setTime(new Date()); // 重置为当前时间
                calendar.set(Calendar.HOUR_OF_DAY, 0); // 小时设为0(24小时制)
                calendar.set(Calendar.MINUTE, 0);      // 分钟设为0
                calendar.set(Calendar.SECOND, 0);      // 秒设为0
                calendar.set(Calendar.MILLISECOND, 0); // 毫秒设为0
                startTime = calendar.getTime();        // 得到今天0点的Date对象
                dateList.add(sdf.format(startTime));
                break;
            case "YESTERDAY":
                // 昨天:从昨天0点到昨天23:59:59.999
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1); // 日期减1天(变为昨天)
                // 设置昨天0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                // 设置昨天23:59:59.999
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                endTime = calendar.getTime();
                dateList.add(sdf.format(startTime));
                break;
            case "LAST_SEVEN":
                // 过去七天:从7天前0点到现在(含今天共7天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -6); // 日期减6天(7天前的今天)
                // 设置7天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                days = 7;
                // 循环生成7天的日期字符串
                Calendar tempCalendar = Calendar.getInstance();
                tempCalendar.setTime(startTime);
                for (int i = 0; i < days; i++) {
                    dateList.add(sdf.format(tempCalendar.getTime()));
                    tempCalendar.add(Calendar.DATE, 1); // 每天累加1天
                }
                break;
            case "LAST_THIRTY":
                // 过去30天:从30天前0点到现在(含今天共30天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -29); // 日期减29天(30天前的今天)
                // 设置30天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                days = 30;
                // 循环生成30天的日期字符串
                Calendar tempCalendar30 = Calendar.getInstance();
                tempCalendar30.setTime(startTime);
                for (int i = 0; i < days; i++) {
                    dateList.add(sdf.format(tempCalendar30.getTime()));
                    tempCalendar30.add(Calendar.DATE, 1); // 每天累加1天
                }
                break;
            default:
                return Result.error("不支持的时间范围类型");
        }
        if ("goods".equals(queryParam.getCurrentType())){
            List<Map<String, Object>> maps = baseMapper.selectViewAndCompletionRateCountByDay(startTime, endTime,queryParam.getCurrentLimit());
            Map<String,Long> viewPrintMap = maps.stream()
                    .collect(Collectors.toMap(
                            map -> {
                                String goodsId = Objects.toString(map.get("GoodsId"), ""); // 空值处理
                                String goodsName = Objects.toString(map.get("GoodsName"), ""); // 空值处理
                                return goodsName + " | " + goodsId; // 用|分隔,方便后续拆分
                            },
                            map-> Long.valueOf(map.get("view_count").toString()),
                            (existing, replacement) -> existing,
                            LinkedHashMap::new  // 指定使用 LinkedHashMap,保留插入顺序
                    ));
            List<String> yData = new ArrayList<>();
            List<Long> xData = new ArrayList<>();
            for (Map.Entry<String, Long> entry : viewPrintMap.entrySet()){
                yData.add(entry.getKey());
                xData.add(entry.getValue());
            }
            Map<String,Object> data = new HashMap<>();
            data.put("yData", yData);
            data.put("xData", xData);
            return Result.ok().data(data);
        }else{
            List<Map<String, Object>> maps = baseMapper.selectEachVideoStats(startTime, endTime,queryParam.getCurrentLimit());
            Map<String, VideoViewCompletionRateVO> viewPrintMap = maps.stream()
                    .collect(Collectors.toMap(
                            map -> {
                                String videoId = Objects.toString(map.get("video_id"), ""); // 空值处理
                                String videoName = Objects.toString(map.get("title"), ""); // 空值处理
                                return videoName + " | " + videoId; // 用|分隔,方便后续拆分
                            },
                            map-> {
                                VideoViewCompletionRateVO vo = new VideoViewCompletionRateVO();
                                vo.setTotal_views(Long.valueOf(map.get("total_views").toString()));
                                vo.setComplete_rate(map.get("complete_rate").toString());
                                return vo;
                            },
                            (existing, replacement) -> existing,
                            LinkedHashMap::new  // 指定使用 LinkedHashMap,保留插入顺序
                    ));
            List<String> yData = new ArrayList<>();
            List<Long> xData = new ArrayList<>();
            List<String> rateData = new ArrayList<>();
            for (Map.Entry<String, VideoViewCompletionRateVO> entry : viewPrintMap.entrySet()){
                yData.add(entry.getKey());
                xData.add(entry.getValue().getTotal_views());
                rateData.add(entry.getValue().getComplete_rate());
            }
            Map<String,Object> data = new HashMap<>();
            data.put("yData", yData);
            data.put("xData", xData);
            data.put("rateData", rateData);
            return Result.ok().data(data);
        }
    }
}
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/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
@@ -13,7 +13,9 @@
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 订单数据处理层
@@ -192,4 +194,30 @@
    List<Order> queryListByParams(@Param(Constants.WRAPPER) Wrapper<Order> queryWrapper);
    @Select("SELECT " +
            "  DATE(create_time) AS day, " +
            "  COUNT(*) AS count " +
            "  FROM" +
            "  li_order o" +
            "  WHERE " +
            "  o.create_time BETWEEN #{startTime} AND #{endTime} " +
            "  GROUP BY" +
            "  day " +
            "  ORDER BY " +
            "  day ASC")
    List<Map<String, Object>>  selectOrderCountByDay(Date startTime, Date endTime);
    @Select("SELECT " +
            "  DATE(create_time) AS day, " +
            "  HOUR(create_time) AS hour," +
            "  COUNT(*) AS count " +
            "  FROM" +
            "  li_order o" +
            "  WHERE " +
            "  o.create_time BETWEEN #{startTime} AND #{endTime} " +
            "  GROUP BY" +
            "  day " +
            "  ORDER BY " +
            "  day , hour ASC")
    List<Map<String, Object>>  selectOrderTimePeriod(Date startTime, Date endTime);
}
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,12 @@
    Order updateSellerRemark(String orderSn, String sellerRemark);
    /**
     * 获得每日订单统计数据 订单统计折线图用
     * @param queryParam
     * @return
     */
    Result getOrderCount(StatisticsQueryParam queryParam);
    Result getOrderTimePeriod(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,7 +88,9 @@
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 io.reactivex.rxjava3.core.Maybe;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@@ -109,6 +113,10 @@
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
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 +1275,197 @@
        return order;
    }
    @Override
    public Result getOrderCount(StatisticsQueryParam queryParam) {
        Date startTime = null;
        Date endTime = new Date(); // 结束时间默认是当前时间
        List<String> dateList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance(); // 用于日期计算的日历实例
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int days = 0;
        switch (queryParam.getSearchType()) {
            case "TODAY":
                // 今天:从今天0点到现在
                calendar.setTime(new Date()); // 重置为当前时间
                calendar.set(Calendar.HOUR_OF_DAY, 0); // 小时设为0(24小时制)
                calendar.set(Calendar.MINUTE, 0);      // 分钟设为0
                calendar.set(Calendar.SECOND, 0);      // 秒设为0
                calendar.set(Calendar.MILLISECOND, 0); // 毫秒设为0
                startTime = calendar.getTime();        // 得到今天0点的Date对象
                dateList.add(sdf.format(startTime));
                break;
            case "YESTERDAY":
                // 昨天:从昨天0点到昨天23:59:59.999
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1); // 日期减1天(变为昨天)
                // 设置昨天0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                // 设置昨天23:59:59.999
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                endTime = calendar.getTime();
                dateList.add(sdf.format(startTime));
                break;
            case "LAST_SEVEN":
                // 过去七天:从7天前0点到现在(含今天共7天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -6); // 日期减6天(7天前的今天)
                // 设置7天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                days = 7;
                // 循环生成7天的日期字符串
                Calendar tempCalendar = Calendar.getInstance();
                tempCalendar.setTime(startTime);
                for (int i = 0; i < days; i++) {
                    dateList.add(sdf.format(tempCalendar.getTime()));
                    tempCalendar.add(Calendar.DATE, 1); // 每天累加1天
                }
                break;
            case "LAST_THIRTY":
                // 过去30天:从30天前0点到现在(含今天共30天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -29); // 日期减29天(30天前的今天)
                // 设置30天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                days = 30;
                // 循环生成30天的日期字符串
                Calendar tempCalendar30 = Calendar.getInstance();
                tempCalendar30.setTime(startTime);
                for (int i = 0; i < days; i++) {
                    dateList.add(sdf.format(tempCalendar30.getTime()));
                    tempCalendar30.add(Calendar.DATE, 1); // 每天累加1天
                }
                break;
            default:
                return Result.error("不支持的时间范围类型");
        }
        List<Map<String, Object>> maps = baseMapper.selectOrderCountByDay(startTime,endTime);
        Map<String, Long> dayCountMap = maps.stream()
                .collect(Collectors.toMap(
                        map -> map.get("day").toString(),  // 日期字符串(如2023-09-19)
                        map -> Long.valueOf(map.get("count").toString())  // 订单数量
                ));
        List<Long> orderCounts = new ArrayList<>();
        for (String date : dateList) {
            // 核心:存在则取查询结果,不存在则补0
            orderCounts.add(dayCountMap.getOrDefault(date, 0L));
        }
        return Result.ok().data(orderCounts);
    }
    @Override
    public Result getOrderTimePeriod(StatisticsQueryParam queryParam) {
        Date startTime = null;
        Date endTime = new Date(); // 结束时间默认是当前时间
        List<String> dateList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance(); // 用于日期计算的日历实例
        for (int i =0;i<=24;i++){
            dateList.add(i + "点");
        }
        switch (queryParam.getSearchType()) {
            case "TODAY":
                // 今天:从今天0点到现在
                calendar.setTime(new Date()); // 重置为当前时间
                calendar.set(Calendar.HOUR_OF_DAY, 0); // 小时设为0(24小时制)
                calendar.set(Calendar.MINUTE, 0);      // 分钟设为0
                calendar.set(Calendar.SECOND, 0);      // 秒设为0
                calendar.set(Calendar.MILLISECOND, 0); // 毫秒设为0
                startTime = calendar.getTime();        // 得到今天0点的Date对象
                break;
            case "YESTERDAY":
                // 昨天:从昨天0点到昨天23:59:59.999
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1); // 日期减1天(变为昨天)
                // 设置昨天0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                // 设置昨天23:59:59.999
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                endTime = calendar.getTime();
                break;
            case "LAST_SEVEN":
                // 过去七天:从7天前0点到现在(含今天共7天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -6); // 日期减6天(7天前的今天)
                // 设置7天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                break;
            case "LAST_THIRTY":
                // 过去30天:从30天前0点到现在(含今天共30天)
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -29); // 日期减29天(30天前的今天)
                // 设置30天前0点
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                startTime = calendar.getTime();
                break;
            default:
                return Result.error("不支持的时间范围类型");
        }
        List<Map<String, Object>> maps = baseMapper.selectOrderTimePeriod(startTime,endTime);
        Map<String, Long> dayCountMap = maps.stream()
                .collect(Collectors.toMap(
                        map -> map.get("day").toString(),  // 日期字符串(如2023-09-19)
                        map -> Long.valueOf(map.get("count").toString())  // 订单数量
                ));
        List<Long> orderCounts = new ArrayList<>();
        for (String date : dateList) {
            // 核心:存在则取查询结果,不存在则补0
            orderCounts.add(dayCountMap.getOrDefault(date, 0L));
        }
        return Result.ok().data(orderCounts);
    }
    /**
     * 虚拟成团
     *
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)")
@@ -27,4 +31,10 @@
    @ApiModelProperty(value = "店铺ID")
    private String storeId;
    @ApiModelProperty(value = "类型:商品goods 、视频video")
    private String currentType;
    @ApiModelProperty(value = "显示排名:10,20,30")
    private Integer currentLimit;
}
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 中拿,否则从数据库中拿
framework/src/main/resources/mapper/lmk/ShareActionMapper.xml
New file
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.lili.modules.lmk.mapper.ShareActionMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="cn.lili.modules.lmk.domain.vo.ShareActionVO">
        <id column="id" property="id"/>
        <result column="user_id" property="userId" />
        <result column="share_option" property="shareOption" />
        <result column="page_code" property="pageCode" />
        <result column="page_type" property="pageType" />
        <result column="pid" property="pid" />
    </resultMap>
    <select id="getById" resultMap="BaseResultMap">
        SELECT
            LSA.user_id,
            LSA.share_option,
            LSA.page_code,
            LSA.page_type,
            LSA.pid,
            LSA.id
        FROM
            lmk_share_action LSA
        WHERE
            LSA.id = #{id} AND LSA.delete_flag = 0
    </select>
    <select id="getPage" resultMap="BaseResultMap">
        SELECT
            LSA.user_id,
            LSA.share_option,
            LSA.page_code,
            LSA.page_type,
            LSA.pid,
            LSA.id
        FROM
            lmk_share_action LSA
        WHERE
            LSA.delete_flag = 0
    </select>
</mapper>
manager-api/src/main/java/cn/lili/controller/lmk/StatisticsController.java
New file
@@ -0,0 +1,103 @@
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.member.service.FootprintService;
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;
    private final FootprintService footprintService;
    @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);
    }
    /**
     * 视频/商品 完播率和浏览量统计
     * @param queryParam
     * @return
     */
    @GetMapping("/viewAndCompletionRateCount")
    public Result getViewAndCompletionRateCount(StatisticsQueryParam queryParam) {
        return footprintService.getViewAndCompletionRateCount(queryParam);
    }
    @GetMapping("/orderTimePeriod")
    public Result getOrderTimePeriod(StatisticsQueryParam queryParam) {
        return orderService.getOrderTimePeriod(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) {