xiangpei
2025-05-22 e868be6c913a6a99e1491c088d052a5f58e252f9
xxl-job调整、视频收藏
15个文件已修改
13个文件已添加
1 文件已重命名
835 ■■■■■ 已修改文件
buyer-api/src/main/java/cn/lili/controller/lmk/MyCollectController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
common-api/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/application.yml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
consumer/pom.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
consumer/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/pom.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/config/XxlJobConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/entity/MyCollect.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/form/MyCollectForm.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/query/MyCollectQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/MyCollectVO.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyCollectVO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/mapper/MyCollectMapper.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/MyCollectService.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/MyCollectServiceImpl.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/MyCollectMapper.xml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/VideoMapper.xml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
im-api/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/java/cn/lili/controller/job/TestJob.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager-api/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller-api/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/java/cn/lili/controller/lmk/MyCollectController.java
New file
@@ -0,0 +1,56 @@
package cn.lili.controller.lmk;
import cn.lili.base.Result;
import cn.lili.group.Add;
import cn.lili.modules.lmk.domain.form.MyCollectForm;
import cn.lili.modules.lmk.domain.query.MyCollectQuery;
import cn.lili.modules.lmk.service.MyCollectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
 * 我的收藏 前端控制器
 *
 * @author xp
 * @since 2025-05-22
 */
@Validated
@RequiredArgsConstructor
@Api(value = "我的收藏", tags = "我的收藏管理")
@RestController
@RequestMapping("/buyer/lmk/my-collect")
public class MyCollectController {
    private final MyCollectService myCollectService;
    @PostMapping("/change")
    @ApiOperation(value = "收藏/取消收藏", notes = "收藏/取消收藏")
    public Result change(@RequestBody @Validated(Add.class) MyCollectForm form) {
        return myCollectService.change(form);
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "ID删除", notes = "ID删除")
    public Result removeById(@PathVariable("id") String id) {
        return myCollectService.removeById(id);
    }
    @DeleteMapping("/batch")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    public Result remove(@RequestBody @NotEmpty(message = "请选择数据") List<String> ids) {
        return myCollectService.remove(ids);
    }
    @GetMapping("/page")
    @ApiOperation(value = "分页", notes = "分页")
    public Result page(MyCollectQuery query) {
        return myCollectService.page(query);
    }
}
buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
@@ -1,5 +1,6 @@
package cn.lili.controller.lmk;
import cn.lili.base.AbsQuery;
import cn.lili.group.Update;
import cn.lili.group.Add;
import org.springframework.validation.annotation.Validated;
@@ -57,21 +58,16 @@
        return videoService.remove(ids);
    }
    @GetMapping("/page")
    @ApiOperation(value = "分页", notes = "分页")
    public Result page(VideoQuery query) {
        return videoService.page(query);
    }
    @GetMapping("/{id}")
    @ApiOperation(value = "详情", notes = "详情")
    public Result detail(@PathVariable("id") Integer id) {
    public Result detail(@PathVariable("id") String id) {
        return videoService.detail(id);
    }
    @GetMapping("/list")
    @ApiOperation(value = "列表", notes = "列表")
    public Result list() {
        return videoService.all();
    @GetMapping("/recommend")
    @ApiOperation(value = "视频推荐", notes = "视频推荐")
    public Result recommendVideo(AbsQuery query) {
        return videoService.recommendVideo(query);
    }
}
buyer-api/src/main/resources/application.yml
@@ -277,6 +277,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
common-api/src/main/resources/application.yml
@@ -273,6 +273,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
config/application.yml
@@ -62,8 +62,10 @@
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://42.193.1.25:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
#        url: jdbc:mysql://127.0.0.1:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
        username: root
        password: 321$YcYl@1970!
#        password: 123456
        maxActive: 50
        initialSize: 20
        maxWait: 60000
@@ -306,12 +308,12 @@
xxl:
  job:
    admin:
      addresses: http://127.0.0.1:30001/xxl-job-admin
      addresses: http://127.0.0.1:9001/xxl-job-admin
    executor:
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
consumer/pom.xml
@@ -18,12 +18,6 @@
            <artifactId>framework</artifactId>
            <version>${revision}</version>
        </dependency>
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>${xxl-job}</version>
        </dependency>
    </dependencies>
    <repositories>
@@ -40,4 +34,4 @@
            </plugin>
        </plugins>
    </build>
</project>
</project>
consumer/src/main/resources/application.yml
@@ -284,6 +284,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
framework/pom.xml
@@ -22,7 +22,11 @@
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>${xxl-job}</version>
        </dependency>
        <dependency>
            <groupId>com.qiniu</groupId>
framework/src/main/java/cn/lili/config/XxlJobConfig.java
File was renamed from consumer/src/main/java/cn/lili/timetask/config/XxlJobConfig.java
@@ -1,4 +1,4 @@
package cn.lili.timetask.config;
package cn.lili.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
@@ -75,4 +75,4 @@
     */
}
}
framework/src/main/java/cn/lili/modules/lmk/domain/entity/MyCollect.java
New file
@@ -0,0 +1,33 @@
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 lombok.Data;
/**
 * 我的收藏
 *
 * @author xp
 * @since 2025-05-22
 */
@Data
@TableName("lmk_my_collect")
public class MyCollect extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableField("user_id")
    /** 用户id */
    private String userId;
    @TableField("collect_type")
    /** 收藏类型 */
    private String collectType;
    @TableField("ref_id")
    /** 收藏对应的id,视频id、商品id,根据收藏类型定 */
    private String refId;
}
framework/src/main/java/cn/lili/modules/lmk/domain/form/MyCollectForm.java
New file
@@ -0,0 +1,42 @@
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.MyCollect;
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 xp
 * @since 2025-05-22
 */
@Data
@ApiModel(value = "MyCollect表单", description = "我的收藏表单")
public class MyCollectForm extends AbsForm {
    @NotBlank(message = "收藏类型不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("收藏类型")
    private String collectType;
    @NotBlank(message = "收藏id不能为空", groups = {Add.class, Update.class})
    @ApiModelProperty("收藏对应的id,视频id、商品id,根据收藏类型定")
    private String refId;
    public static MyCollect getEntityByForm(@NonNull MyCollectForm form, MyCollect entity) {
        if(entity == null) {
          entity = new MyCollect();
        }
        BeanUtils.copyProperties(form, entity);
        return entity;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/query/MyCollectQuery.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 xp
 * @since 2025-05-22
 */
@Data
@ApiModel(value = "MyCollect查询参数", description = "我的收藏查询参数")
public class MyCollectQuery extends AbsQuery {
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/MyCollectVO.java
New file
@@ -0,0 +1,43 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.MyCollect;
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 xp
 * @since 2025-05-22
 */
@Data
@ApiModel(value = "我的收藏响应数据", description = "我的收藏响应数据")
public class MyCollectVO extends AbsVo {
    /** 用户id */
    @ApiModelProperty("用户id")
    private String userId;
    /** 收藏类型 */
    @ApiModelProperty("收藏类型")
    private String collectType;
    /** 收藏对应的id,视频id、商品id,根据收藏类型定 */
    @ApiModelProperty("收藏对应的id,视频id、商品id,根据收藏类型定")
    private String refId;
    public static MyCollectVO getVoByEntity(@NonNull MyCollect entity, MyCollectVO vo) {
        if(vo == null) {
            vo = new MyCollectVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyCollectVO.java
New file
@@ -0,0 +1,35 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.MyCollect;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.lang.NonNull;
/**
 * 我的收藏展示
 *
 * @author xp
 * @since 2025-05-22
 */
@Data
@ApiModel(value = "我的收藏响应数据", description = "我的收藏响应数据")
public class SimpleMyCollectVO {
    private String id;
    /** 收藏对应的id,视频id、商品id,根据收藏类型定 */
    @ApiModelProperty("收藏对应的id,视频id、商品id,根据收藏类型定")
    private String refId;
    public static SimpleMyCollectVO getVoByEntity(@NonNull MyCollect entity, SimpleMyCollectVO vo) {
        if(vo == null) {
            vo = new SimpleMyCollectVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsVO.java
New file
@@ -0,0 +1,32 @@
package cn.lili.modules.lmk.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * 视频悬挂商品信息
 *
 * @author:xp
 * @date:2025/5/22 14:17
 */
@Data
public class VideoGoodsVO {
    private String id;
    @ApiModelProperty("图片地址")
    private String imageUrl = "https://picsum.photos/200/200?random=2";
    @ApiModelProperty("商品名称")
    private String name = "推流";
    @ApiModelProperty("价格")
    private String price = "10";
    @ApiModelProperty("原价")
    private String originalPrice = "48.9";
    @ApiModelProperty("已售数量")
    private Long saleNum = 125L;
}
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java
New file
@@ -0,0 +1,74 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.Video;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.lang.NonNull;
import java.util.Date;
import java.util.List;
/**
 * 视频内容展示
 *
 * @author xp
 * @since 2025-05-16
 */
@Data
@ApiModel(value = "视频内容响应数据", description = "视频内容响应数据")
public class WxVideoVO extends AbsVo {
    /** 作者id */
    @ApiModelProperty("作者id")
    private String authorId;
    private String authorName;
    private String authorAvatar;
    /** 图片封面 */
    @ApiModelProperty("图片封面")
    private String coverUrl;
    /** 视频地址 */
    @ApiModelProperty("视频地址")
    private String videoFileKey;
    private String videoUrl;
    @ApiModelProperty("视频标签")
    private List<SimpleVideoTagVO> tagList;
    /** 视频填充模式 */
    @ApiModelProperty("视频填充模式")
    private String videoFit;
    /** 视频标题 */
    @ApiModelProperty("视频标题")
    private String title;
    /** 商品信息 */
    @ApiModelProperty("商品信息")
    private VideoGoodsVO goods;
    @ApiModelProperty("当前用户是否收藏了该视频")
    private Boolean collected = Boolean.FALSE;
    /** 收藏数 */
    @ApiModelProperty("收藏数")
    private Long collectNum;
    /** 评论数 */
    @ApiModelProperty("评论数")
    private Long commentNum;
    public static WxVideoVO getVoByEntity(@NonNull Video entity, WxVideoVO vo) {
        if(vo == null) {
            vo = new WxVideoVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/mapper/MyCollectMapper.java
New file
@@ -0,0 +1,43 @@
package cn.lili.modules.lmk.mapper;
import cn.lili.modules.lmk.domain.entity.MyCollect;
import cn.lili.modules.lmk.domain.vo.SimpleMyCollectVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.lili.modules.lmk.domain.vo.MyCollectVO;
import cn.lili.modules.lmk.domain.form.MyCollectForm;
import cn.lili.modules.lmk.domain.query.MyCollectQuery;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * 我的收藏 Mapper 接口
 *
 * @author xp
 * @since 2025-05-22
 */
@Mapper
public interface MyCollectMapper extends BaseMapper<MyCollect> {
    /**
     * id查找我的收藏
     * @param id
     * @return
     */
    MyCollectVO getById(String id);
    /**
    *  分页
    */
    IPage getPage(IPage page, @Param("query") MyCollectQuery query);
    /**
     * 查询某人收藏对应视频没
     *
     * @param videoIds
     * @param currentUserId
     * @return
     */
    List<SimpleMyCollectVO> getCollectsByVideoIds(@Param("videoIds") List<String> videoIds, @Param("userId") String currentUserId);
}
framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java
@@ -39,4 +39,11 @@
     * @param query
     */
    IPage managerPage(IPage page, @Param("query") ManagerVideoQuery query);
    /**
     * 查出5个推荐视频
     *
     * @return
     */
    IPage recommendVideo(IPage page);
}
framework/src/main/java/cn/lili/modules/lmk/service/MyCollectService.java
New file
@@ -0,0 +1,76 @@
package cn.lili.modules.lmk.service;
import cn.lili.modules.lmk.domain.entity.MyCollect;
import cn.lili.modules.lmk.domain.vo.SimpleMyCollectVO;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.lili.base.Result;
import cn.lili.modules.lmk.domain.form.MyCollectForm;
import cn.lili.modules.lmk.domain.query.MyCollectQuery;
import org.springframework.beans.PropertyValues;
import java.util.List;
/**
 * 我的收藏 服务类
 *
 * @author xp
 * @since 2025-05-22
 */
public interface MyCollectService extends IService<MyCollect> {
    /**
     * 添加
     * @param form
     * @return
     */
    Result change(MyCollectForm form);
    /**
     * 修改
     * @param form
     * @return
     */
    Result update(MyCollectForm form);
    /**
     * 批量删除
     * @param ids
     * @return
     */
    Result remove(List<String> ids);
    /**
     * id删除
     * @param id
     * @return
     */
    Result removeById(String id);
    /**
     * 分页查询
     * @param query
     * @return
     */
    Result page(MyCollectQuery query);
    /**
     * 根据id查找
     * @param id
     * @return
     */
    Result detail(String id);
    /**
     * 列表
     * @return
     */
    Result all();
    /**
     * 查询某人对应视频的收藏
     *
     * @param videoIds
     * @return
     */
    List<SimpleMyCollectVO> getCollectsByVideoIds(List<String> videoIds);
}
framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
@@ -1,5 +1,6 @@
package cn.lili.modules.lmk.service;
import cn.lili.base.AbsQuery;
import cn.lili.modules.lmk.domain.entity.Video;
import cn.lili.modules.lmk.domain.form.VideoAuditingForm;
import cn.lili.modules.lmk.domain.form.VideoDownForm;
@@ -114,4 +115,11 @@
     * @return
     */
    Result down(VideoDownForm form);
    /**
     * 小程序端的视频推荐接口
     *
     * @return
     */
    Result recommendVideo(AbsQuery query);
}
framework/src/main/java/cn/lili/modules/lmk/service/impl/MyCollectServiceImpl.java
New file
@@ -0,0 +1,140 @@
package cn.lili.modules.lmk.service.impl;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.lmk.domain.vo.SimpleMyCollectVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.lili.modules.lmk.domain.entity.MyCollect;
import cn.lili.modules.lmk.mapper.MyCollectMapper;
import cn.lili.modules.lmk.service.MyCollectService;
import cn.lili.base.Result;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.lili.modules.lmk.domain.form.MyCollectForm;
import cn.lili.modules.lmk.domain.vo.MyCollectVO;
import cn.lili.modules.lmk.domain.query.MyCollectQuery;
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.Objects;
import java.util.stream.Collectors;
/**
 * 我的收藏 服务实现类
 *
 * @author xp
 * @since 2025-05-22
 */
@Service
@RequiredArgsConstructor
public class MyCollectServiceImpl extends ServiceImpl<MyCollectMapper, MyCollect> implements MyCollectService {
    private final MyCollectMapper myCollectMapper;
    /**
     * 添加
     * @param form
     * @return
     */
    @Override
    public Result change(MyCollectForm form) {
        MyCollect myCollect = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(MyCollect::getCollectType, form.getCollectType())
                .eq(MyCollect::getRefId, form.getRefId())
                .eq(MyCollect::getUserId, UserContext.getCurrentUserId())
                .one();
        if (Objects.nonNull(myCollect)) {
            baseMapper.deleteById(myCollect.getId());
        } else {
            myCollect = new MyCollect();
            myCollect.setRefId(form.getRefId());
            myCollect.setCollectType(form.getCollectType());
            myCollect.setUserId(UserContext.getCurrentUserId());
            baseMapper.insert(myCollect);
        }
        return Result.ok("操作成功");
    }
    /**
     * 修改
     * @param form
     * @return
     */
    @Override
    public Result update(MyCollectForm form) {
        MyCollect 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(MyCollectQuery query) {
        IPage<MyCollectVO> page = PageUtil.getPage(query, MyCollectVO.class);
        baseMapper.getPage(page, query);
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 根据id查找
     * @param id
     * @return
     */
    @Override
    public Result detail(String id) {
        MyCollectVO vo = baseMapper.getById(id);
        Assert.notNull(vo, "记录不存在");
        return Result.ok().data(vo);
    }
    /**
     * 列表
     * @return
     */
    @Override
    public Result all() {
        List<MyCollect> entities = baseMapper.selectList(null);
        List<MyCollectVO> vos = entities.stream()
                .map(entity -> MyCollectVO.getVoByEntity(entity, null))
                .collect(Collectors.toList());
        return Result.ok().data(vos);
    }
    @Override
    public List<SimpleMyCollectVO> getCollectsByVideoIds(List<String> videoIds) {
        return baseMapper.getCollectsByVideoIds(videoIds, UserContext.getCurrentUserId());
    }
}
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
@@ -1,5 +1,6 @@
package cn.lili.modules.lmk.service.impl;
import cn.lili.base.AbsQuery;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.lmk.domain.entity.VideoAuditRecord;
import cn.lili.modules.lmk.domain.entity.VideoTag;
@@ -8,7 +9,7 @@
import cn.lili.modules.lmk.domain.form.VideoDownForm;
import cn.lili.modules.lmk.domain.form.VideoRecommendForm;
import cn.lili.modules.lmk.domain.query.ManagerVideoQuery;
import cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO;
import cn.lili.modules.lmk.domain.vo.*;
import cn.lili.modules.lmk.enums.general.TagCreateTypeEnum;
import cn.lili.modules.lmk.enums.general.VideoStatusEnum;
import cn.lili.modules.lmk.service.*;
@@ -21,8 +22,8 @@
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.lili.modules.lmk.domain.form.VideoForm;
import cn.lili.modules.lmk.domain.vo.VideoVO;
import cn.lili.modules.lmk.domain.query.VideoQuery;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@@ -49,6 +50,7 @@
    private final VideoTagRefService videoTagRefService;
    private final LmkFileService lmkFileService;
    private final VideoAuditRecordService videoAuditRecordService;
    private final MyCollectService myCollectService;
    private final COSUtil cosUtil;
    /**
@@ -252,4 +254,28 @@
        // TODO 将下架原因以通知的方式告知用户
        return Result.ok("下架成功");
    }
    @Override
    public Result recommendVideo(AbsQuery query) {
        // 推荐算法: 1. 根据用户的收藏视频的标签  2. 根据用户关注的作者的其它视频  3. 根据用户的观看记录(观看时长较长的、重复观看次数较多的) 4. 基于相似用户的观看行为来给该用户推荐
        IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
        baseMapper.recommendVideo(page);
        if (page.getTotal() > 0) {
            List<String> videoIds = page.getRecords().stream().map(WxVideoVO::getId).collect(Collectors.toList());
            Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds)
                    .stream()
                    .collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId));
            Map<String, List<SimpleMyCollectVO>> collectMap =myCollectService.getCollectsByVideoIds(videoIds)
                    .stream()
                    .collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId));
            // 3. 获取视频临时访问地址、设置视频标签、我是否收藏
            page.getRecords().forEach(v -> {
                v.setGoods(new VideoGoodsVO());
                v.setTagList(tagMap.get(v.getId()));
                v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId())));
                v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
            });
        }
        return Result.ok().data(page.getRecords());
    }
}
framework/src/main/resources/mapper/lmk/MyCollectMapper.xml
New file
@@ -0,0 +1,57 @@
<?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.MyCollectMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="cn.lili.modules.lmk.domain.vo.MyCollectVO">
        <id column="id" property="id"/>
        <result column="user_id" property="userId" />
        <result column="collect_type" property="collectType" />
        <result column="ref_id" property="refId" />
    </resultMap>
    <select id="getById" resultMap="BaseResultMap">
        SELECT
            LMC.user_id,
            LMC.collect_type,
            LMC.ref_id,
            LMC.id
        FROM
            lmk_my_collect LMC
        WHERE
            LMC.id = #{id} AND LMC.delete_flag = 0
    </select>
    <select id="getPage" resultMap="BaseResultMap">
        SELECT
            LMC.user_id,
            LMC.collect_type,
            LMC.ref_id,
            LMC.id
        FROM
            lmk_my_collect LMC
        WHERE
            LMC.delete_flag = 0
    </select>
    <select id="getCollectsByVideoIds" resultType="cn.lili.modules.lmk.domain.vo.SimpleMyCollectVO">
        SELECT
               id,
               ref_id as refId
        FROM
             lmk_my_collect
        WHERE
              user_id = #{userId}
          AND delete_flag = 0
          AND collect_type = 'video'
          AND ref_id IN <foreach collection="videoIds" open="(" item="videoId" close=")" separator=",">#{videoId}</foreach>
    </select>
</mapper>
framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -24,6 +24,20 @@
        <result column="update_time" property="updateTime" />
    </resultMap>
    <!-- 微信推荐视频 -->
    <resultMap id="WxResultMap" type="cn.lili.modules.lmk.domain.vo.WxVideoVO">
        <id column="id" property="id"/>
        <result column="author_id" property="authorId" />
        <result column="authorName" property="authorName" />
        <result column="authorAvatar" property="authorAvatar" />
        <result column="cover_url" property="coverUrl" />
        <result column="video_file_key" property="videoFileKey" />
        <result column="video_fit" property="videoFit" />
        <result column="title" property="title" />
        <result column="collect_num" property="collectNum" />
        <result column="comment_num" property="commentNum" />
    </resultMap>
    <select id="getById" resultMap="BaseResultMap">
        SELECT
@@ -66,13 +80,13 @@
            LV.recommend,
            LV.status,
            LV.play_num,
            LV.collect_num,
            LV.comment_num,
            LV.weight,
            LV.audit_pass_time,
            LV.update_time,
            LV.id,
            LM.nick_name as authorName
            LM.nick_name as authorName,
            (SELECT COUNT(*) FROM lmk_my_collect WHERE ref_id = LV.id AND collect_type = 'video' AND delete_flag = 0) as collect_num
        FROM
            lmk_video LV
                LEFT JOIN li_member LM ON LV.author_id = LM.id
@@ -94,13 +108,13 @@
            LV.recommend,
            LV.status,
            LV.play_num,
            LV.collect_num,
            LV.comment_num,
            LV.weight,
            LV.audit_pass_time,
            LV.update_time,
            LV.id,
            LM.nick_name as authorName
            LM.nick_name as authorName,
            (SELECT COUNT(*) FROM lmk_my_collect WHERE ref_id = LV.id AND collect_type = 'video' AND delete_flag = 0) as collect_num
        FROM
            lmk_video LV
                LEFT JOIN li_member LM ON LV.author_id = LM.id
@@ -119,4 +133,33 @@
            <if test="query.status != null and query.status != ''">AND LV.status = #{query.status}</if>
    </select>
    <select id="recommendVideo" resultMap="WxResultMap">
        SELECT
            LV.author_id,
            LV.cover_url,
            LV.video_fit,
            LV.video_file_key,
            LV.title,
            LV.goods_id,
            LV.goods_view_num,
            LV.goods_order_num,
            LV.recommend,
            LV.status,
            LV.play_num,
            LV.comment_num,
            LV.weight,
            LV.audit_pass_time,
            LV.update_time,
            LV.id,
            LM.nick_name as authorName,
            LM.face as authorAvatar,
            (SELECT COUNT(*) FROM lmk_my_collect WHERE ref_id = LV.id AND collect_type = 'video' AND delete_flag = 0) as collect_num
        FROM
            lmk_video LV
            LEFT JOIN li_member LM ON LV.author_id = LM.id
        WHERE
            LV.delete_flag = 0 AND LV.status = '1'
    </select>
</mapper>
im-api/src/main/resources/application.yml
@@ -272,6 +272,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
manager-api/pom.xml
@@ -29,4 +29,4 @@
        </plugins>
    </build>
</project>
</project>
manager-api/src/main/java/cn/lili/controller/job/TestJob.java
New file
@@ -0,0 +1,30 @@
package cn.lili.controller.job;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
 * @author:xp
 * @date:2025/5/22 16:49
 */
@Component
public class TestJob {
    // 简单任务示例
    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");
        // 执行你的业务逻辑
        for (int i = 0; i < 5; i++) {
            XxlJobHelper.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        // 默认返回成功结果
    }
}
manager-api/src/main/resources/application.yml
@@ -272,6 +272,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7
seller-api/src/main/resources/application.yml
@@ -265,6 +265,6 @@
      appname: xxl-job-executor-lilishop
      address:
      ip:
      port: 8891
      port: 8848
      logpath: ./xxl-job/executor
      logretentiondays: 7