Pārlūkot izejas kodu

商品搜索接口

wxd 3 nedēļas atpakaļ
vecāks
revīzija
2875d06fa4

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/second/SecondGoods.java

@@ -32,6 +32,10 @@ public class SecondGoods implements Serializable {
     @ApiModelProperty(value = "商品标题")
     private String title;
 
+    @TableField("home_image")
+    @ApiModelProperty(value = "商品封面图片")
+    private String homeImage;
+
     @TableField("describe")
     @ApiModelProperty(value = "商品描述")
     private String describe;

+ 55 - 9
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsVo.java

@@ -1,15 +1,19 @@
 package shop.alien.entity.second.vo;
 
+import com.alibaba.fastjson2.util.DateUtils;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import shop.alien.entity.second.SecondGoods;
 
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @Data
 @JsonInclude
@@ -42,15 +46,13 @@ public class SecondGoodsVo extends SecondGoods {
     @ApiModelProperty(value = "用户头像")
     private String userImage;
 
-    // 收藏状态
     @TableField(exist = false)
-    @ApiModelProperty(value = "收藏状态")
-    private Integer collectStatus;
+    @ApiModelProperty(value = "收藏状态 默认为 0")
+    private Integer collectStatus = 0;
 
-    // 点赞状态
     @TableField(exist = false)
-    @ApiModelProperty(value = "点赞状态")
-    private Integer likeStatus;
+    @ApiModelProperty(value = "点赞状态 默认为 0")
+    private Integer likeStatus = 0;
 
     @ApiModelProperty("一级分类名称")
     @TableField(exist = false)
@@ -65,10 +67,10 @@ public class SecondGoodsVo extends SecondGoods {
 
     @TableField(exist = false)
     @ApiModelProperty(value = "当前页码")
-    private Integer pageNum;
+    private Integer pageNum = 1;
 
     @ApiModelProperty(value = "每页数量")
-    private Integer pageSize;
+    private Integer pageSize = 10;
 
     @ApiModelProperty(value = "当前经度")
     private Double currentLatitude;
@@ -91,5 +93,49 @@ public class SecondGoodsVo extends SecondGoods {
     @ApiModelProperty(value = "拉黑用户IDList")
     private List<Integer> userIdList;
 
-
+    @JsonProperty("timeAgo")
+    public String getFormattedTimeAgo() {
+        return getTimeAgo(getReleaseTime());
+    }
+
+
+    /**
+     * 返回时间描述,根据发布时间计算距离现在多久。
+     * 24小时内 返回几小时前,24小时外 1-31返回几天前,31天外返回几月前,365天外返回几年前
+     *
+     * @param releaseTime 发布时间
+     * @return 时间描述字符串
+     */
+
+    public String getTimeAgo(Date releaseTime) {
+        if (releaseTime == null) {
+            return "未知时间";
+        }
+
+        long now = System.currentTimeMillis();
+        long diff = now - releaseTime.getTime();
+
+        // 新增分钟级判断
+        long minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
+        if (minutes < 1) {
+            return "刚刚";
+        } else if (minutes < 60) {
+            return minutes + "分钟前";
+        }
+
+        long hours = TimeUnit.MILLISECONDS.toHours(diff);
+        long days = TimeUnit.MILLISECONDS.toDays(diff);
+        long months = days / 31;
+        long years = days / 365;
+
+        if (hours < 24) {
+            return hours + "小时前";
+        } else if (days <= 31) {
+            return days + "天前";
+        } else if (years >= 1) {
+            return years + "年前";
+        } else {
+            return months + "个月前";
+        }
+    }
 }

+ 2 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeCollect.java

@@ -23,6 +23,8 @@ public class LifeCollect {
 
     private String userId;
 
+    private String goodsId;
+
     @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
     @TableField("delete_flag")
     @TableLogic

+ 1 - 1
alien-entity/src/main/java/shop/alien/entity/store/StoreImg.java

@@ -29,7 +29,7 @@ public class StoreImg {
     @TableField("store_id")
     private Integer storeId;
 
-    @ApiModelProperty(value = "图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉,10:商家头像,11:店铺轮播图,12:联名卡图片,13:动态折扣, 14:套餐图片")
+    @ApiModelProperty(value = "图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉,10:商家头像,11:店铺轮播图,12:联名卡图片,13:动态折扣, 14:套餐图片,15:合同照片,17:打卡广场小人图片 18: 商品发布图片")
     @TableField("img_type")
     private Integer imgType;
 

+ 32 - 13
alien-entity/src/main/java/shop/alien/mapper/second/SecondGoodsMapper.java

@@ -33,15 +33,6 @@ public interface SecondGoodsMapper extends BaseMapper<SecondGoods> {
     List<SecondGoods> getSecondGoodsByPageAndDistance(IPage<SecondGoods> page, @Param("currentLatitude") Double currentLatitude, @Param("currentLongitude") Double currentLongitude);
 
     /**
-     * 自定义查询方法,返回包含图片信息的二手商品列表
-     * @param page 分页信息
-     * @param categoryId 分类ID
-     * @param status 商品状态
-     * @return 包含图片信息的二手商品列表
-     */
-    IPage<SecondGoods> selectGoodsWithImages(IPage<SecondGoods> page, @Param("categoryId") Integer categoryId, @Param("status") Integer status);
-
-    /**
      * 查询用户屏蔽的商品列表
      * @param page 分页参数
      * @param userId 用户ID
@@ -50,11 +41,17 @@ public interface SecondGoodsMapper extends BaseMapper<SecondGoods> {
     IPage<SecondGoods> getShieldedGoodsListByType(IPage<SecondGoods> page, @Param("userId") Integer userId, @Param("shieldType") Integer shieldType);
 
     /**
-     * 查询用户屏蔽的商品列表
-     * @param userId 用户ID
+     * 获取用户屏蔽的商品列表(分页)
+     * @param page 分页参数
+     * @param queryWrapper 查询条件
      * @return 屏蔽的商品列表
      */
-    List<SecondGoods> getShieldedGoodsList(@Param("userId") Integer userId);
+    @Select("SELECT sg.* " +
+            "FROM second_goods sg " +
+            "INNER JOIN second_shield ss ON " +
+            "(sg.id = ss.shield_id AND ss.shield_type = 1) "+
+            "${ew.customSqlSegment}")
+    IPage<SecondGoodsVo>  getShieldedGoodsPage(IPage<SecondGoodsVo> page, @Param(Constants.WRAPPER) QueryWrapper<SecondGoodsVo> queryWrapper);
 
     /**
      * 查询商品热卖排行榜
@@ -84,7 +81,7 @@ public interface SecondGoodsMapper extends BaseMapper<SecondGoods> {
             "sg.*, " +
             "sgc1.category_name as categoryOneName, " +
             "sgc2.category_name as categoryTwoName, "+
-            "(6371 * acos(cos(radians(#{currentLatitude})) * cos(radians(SUBSTRING_INDEX(sg.position, ',', 1))) * cos(radians(SUBSTRING_INDEX(sg.position, ',', -1)) - radians(#{currentLongitude})) + sin(radians(#{currentLatitude})) * sin(radians(SUBSTRING_INDEX(sg.position, ',', 1))))) AS distance " +
+            "ROUND(ST_Distance_Sphere(ST_GeomFromText(CONCAT('POINT(',#{currentLongitude},' ',#{currentLatitude} , ')' )), ST_GeomFromText(CONCAT('POINT(', REPLACE(sg.position, ',', ' '), ')' ))) / 1000, 2) AS distance "+
             " FROM second_goods sg " +
             "left JOIN second_goods_category sgc1 " +
             "on sg.category_one_id = sgc1.id " +
@@ -92,4 +89,26 @@ public interface SecondGoodsMapper extends BaseMapper<SecondGoods> {
             "on sg.category_two_id = sgc2.id "+
             "${ew.customSqlSegment}")
     IPage<SecondGoodsVo> searchGoodsList(IPage<SecondGoodsVo> page,@Param("currentLatitude") Double currentLatitude , @Param("currentLongitude") Double currentLongitude, @Param(Constants.WRAPPER) QueryWrapper<SecondGoodsVo> queryWrapper);
+
+    /**
+     * 获取商品详情
+     * @param queryWrapper 查询条件
+     * @return 商品详情
+     */
+    @Select("SELECT " + "sg.*, " + "sgc1.category_name as categoryOneName, "
+            + "sgc2.category_name as categoryTwoName "
+            + "FROM second_goods sg "
+            + "left JOIN second_goods_category sgc1 "
+            + "on sg.category_one_id = sgc1.id "
+            + "left JOIN second_goods_category sgc2 "
+            + "on sg.category_two_id = sg.id " +
+            "${ew.customSqlSegment}")
+    SecondGoodsVo getGoodsDetails(@Param(Constants.WRAPPER) QueryWrapper<SecondGoodsVo> queryWrapper);
+
+    /**
+     * 获取用户屏蔽的商品列表
+     * @param userId 用户ID
+     * @return 屏蔽的商品列表
+     */
+    List<SecondGoods> getShieldedGoodsList( @Param("userId") Integer userId);
 }

+ 1 - 15
alien-entity/src/main/resources/mapper/second/SecondGoodsMapper.xml

@@ -72,25 +72,11 @@
             LIMIT 10
     </select>
 
-    <!-- 带图片信息的商品查询 支持分类和状态筛选 -->
-    <select id="selectGoodsWithImages" resultType="shop.alien.entity.second.SecondGoods">
-        SELECT *
-        FROM second_goods
-        <where>
-            <if test="categoryId != null">
-                AND category_one_id = #{categoryId}
-            </if>
-            <if test="status != null">
-                AND goods_status = #{status}
-            </if>
-        </where>
-    </select>
-
     <!-- 查询用户屏蔽的商品列表 -->
     <select id="getShieldedGoodsList" resultType="shop.alien.entity.second.SecondGoods">
         SELECT sg.*
         FROM second_goods sg
-        INNER JOIN second_shield ss ON 
+        INNER JOIN second_shield ss ON
             (sg.id = ss.shield_id AND ss.shield_type = 1)
         WHERE ss.user_id = #{userId} AND ss.delete_flag = 0 AND sg.delete_flag = 0
     </select>

+ 32 - 53
alien-second/src/main/java/shop/alien/second/controller/SecondGoodsController.java

@@ -34,63 +34,29 @@ public class SecondGoodsController {
     private final SecondGoodsService secondGoodsService;
 
     /**
-     * 获取所有二手商品
-     */
-    @GetMapping
-    @ApiOperation("获取所有二手商品")
-    public R<List<SecondGoods>> getAllSecondGoods() {
-        return R.data(secondGoodsService.list(), "获取成功");
-    }
-
-    /**
-     * 分页查询二手商品列表
-     */
-    @GetMapping("/list")
-    @ApiOperation("分页查询二手商品列表")
-    public R<IPage<SecondGoods>> getSecondGoodsList(
-            @ApiParam("当前页码") @RequestParam Integer pageNum,
-            @ApiParam("每页数量") @RequestParam Integer pageSize) {
-        IPage<SecondGoods> page = new Page<>(pageNum, pageSize);
-        IPage<SecondGoods> result = secondGoodsService.page(page);
-        return R.data(result, "查询成功");
-    }
-
-    /**
-     * 分页查询二手商品列表(包含图片信息)并支持筛选条件
-     */
-    @GetMapping("/list-with-images")
-    @ApiOperation("分页查询二手商品列表并包含图片信息,支持筛选")
-    public R<IPage<SecondGoods>> getSecondGoodsListWithImages(
-            @ApiParam("当前页码") @RequestParam Integer pageNum,
-            @ApiParam("每页数量") @RequestParam Integer pageSize,
-            @ApiParam("一级分类ID") @RequestParam(required = false) Integer categoryId,
-            @ApiParam("商品状态") @RequestParam(required = false) Integer status) {
-        IPage<SecondGoods> page = new Page<>(pageNum, pageSize);
-        IPage<SecondGoods> result = secondGoodsService.getGoodsWithImages(page, categoryId, status);
-        return R.data(result, "查询成功");
-    }
-
-    /**
      * 根据ID获取二手商品
      */
-    @GetMapping("/{id}")
-    @ApiOperation("根据ID获取二手商品")
-    public R<SecondGoods> getSecondGoodsById(@ApiParam("商品ID") @PathVariable Integer id) {
-        return R.data(secondGoodsService.getById(id), "获取成功");
+    @GetMapping("/getSecondGoodsById")
+    @ApiOperation("根据ID获取二手商品 - 商品编辑回显")
+    public R<SecondGoodsVo> getSecondGoodsById(@ApiParam("根据ID获取二手商品 - 商品编辑回显") @RequestParam Integer id) {
+        return R.data(secondGoodsService.getSecondGoodsById(id), "获取成功");
     }
 
     /**
      * 获取用户屏蔽的商品列表(分页)
      */
-    @GetMapping("/shieldedList")
+    @GetMapping("/getShieldedGoodsPage")
     @ApiOperation("获取用户屏蔽的商品列表(分页)")
-    public R<IPage<SecondGoods>> getShieldedGoodsList(
-            @ApiParam("当前页码") @RequestParam Integer pageNum,
-            @ApiParam("每页数量") @RequestParam Integer pageSize,
-            @ApiParam("用户ID") @RequestParam Integer userId,
-            @ApiParam("屏蔽类型 1:商品 2:卖家") @RequestParam Integer shieldType) {
-        IPage<SecondGoods> page = new Page<>(pageNum, pageSize);
-        return R.data(secondGoodsService.getShieldedGoodsListByType(page, userId, shieldType), "获取成功");
+    public R<IPage<SecondGoodsVo>> getShieldedGoodsPage(
+            @ApiParam("分页参数") @RequestBody SecondGoodsVo secondGoodsVo) {
+        R<IPage<SecondGoodsVo>> result = new R<>();
+        IPage<SecondGoodsVo> page = new Page<>(secondGoodsVo.getPageNum(), secondGoodsVo.getPageSize());
+        JSONObject data = JwtUtil.getCurrentUserInfo();
+        if (null != data) {
+            int userId = data.getInteger("userId");
+            result = R.data(secondGoodsService.getShieldedGoodsPage(page,userId));
+        }
+        return result;
     }
 
     /**
@@ -142,20 +108,33 @@ public class SecondGoodsController {
         return R.success("添加二手商品成功");
     }
 
+
+    /**
+     * 上架二手商品
+     */
+    @PostMapping("/shelve")
+    @ApiOperation("上架二手商品")
+    public R<Void> shelveSecondGoods(@ApiParam("上架二手商品") @RequestBody SecondGoodsVo secondGoods) {
+        // 修改商品状态为3 - 已上架
+        secondGoods.setGoodsStatus(3);
+        secondGoodsService.updateById(secondGoods);
+        return R.success("上架成功");
+    }
+
     /**
      * 删除二手商品
      */
-    @DeleteMapping("/{id}")
+    @PostMapping("/delete")
     @ApiOperation("删除二手商品")
-    public R<Void> deleteSecondGoods(@ApiParam("商品ID") @PathVariable Integer id) {
-        secondGoodsService.removeById(id);
+    public R<Void> deleteSecondGoods(@ApiParam("删除二手商品") @RequestBody SecondGoodsVo secondGoods) {
+        secondGoodsService.removeById(secondGoods.getId());
         return R.success("删除成功");
     }
 
     /**
      * 搜索商品列表(包含商品信息、图片、用户信息),按距离和创建时间倒序
      */
-    @GetMapping("/search")
+    @PostMapping("/search")
     @ApiOperation("搜索结果-商品列表")
     public R<IPage<SecondGoodsVo>> searchGoodsList(
             @ApiParam("二手商品搜索条件") @RequestBody SecondGoodsVo secondGoodsVo) {

+ 15 - 18
alien-second/src/main/java/shop/alien/second/service/SecondGoodsService.java

@@ -27,24 +27,6 @@ public interface SecondGoodsService extends IService<SecondGoods> {
     boolean saveAsDraft(SecondGoodsVo goods);
 
     /**
-     * 获取所有二手商品
-     * @param page 分页参数
-     *             pageNum 当前页码
-     *             pageSize 每页数量
-     *             categoryId 分类ID
-     *             status 商品状态 0:草稿 1:审核中 2:审核失败 3:已上架 4:已下架 5:已售出
-     * @return 二手商品列表
-     */
-    IPage<SecondGoods> getGoodsWithImages(IPage<SecondGoods> page, Integer categoryId, Integer status);
-
-    /**
-     * 获取用户屏蔽的商品列表
-     * @param userId 用户ID
-     * @return 屏蔽的商品列表
-     */
-    List<SecondGoods> getShieldedGoodsList(Integer userId);
-
-    /**
      * 获取用户屏蔽的商品列表(分页)
      * @param page 分页参数
      * @param userId 用户ID
@@ -78,4 +60,19 @@ public interface SecondGoodsService extends IService<SecondGoods> {
      * @return 搜索结果列表
      */
     IPage<SecondGoodsVo> searchGoodsList(IPage<SecondGoodsVo> page,Integer userId, SecondGoodsVo secondGoodsVo);
+
+    /**
+     * 获取商品详情
+     * @param id 商品ID
+     * @return 商品详情
+     */
+    SecondGoodsVo getSecondGoodsById(Integer id);
+
+    /**
+     * 获取用户屏蔽的商品列表(分页)
+     * @param page 搜索条件
+     * @param userId 用户ID
+     * @return 分页后的屏蔽商品列表
+     */
+    IPage<SecondGoodsVo>  getShieldedGoodsPage(IPage<SecondGoodsVo> page, Integer userId);
 }

+ 164 - 70
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java

@@ -2,8 +2,8 @@ package shop.alien.second.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
@@ -11,15 +11,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 import shop.alien.entity.second.SecondGoods;
 import shop.alien.entity.second.vo.SecondGoodsVo;
-import shop.alien.entity.store.LifeAppealManage;
-import shop.alien.entity.store.StoreImg;
-import shop.alien.entity.store.vo.LifeAppealManageVo;
+import shop.alien.entity.store.*;
 import shop.alien.entity.store.vo.LifeUserVo;
-import shop.alien.mapper.LifeBlacklistMapper;
-import shop.alien.mapper.LifeUserMapper;
-import shop.alien.mapper.StoreImgMapper;
+import shop.alien.mapper.*;
 import shop.alien.mapper.second.SecondGoodsMapper;
 import shop.alien.second.service.SecondGoodsService;
+import shop.alien.util.common.VideoUtils;
 import shop.alien.util.common.netease.ImageCheckUtil;
 import shop.alien.util.common.netease.TextCheckUtil;
 
@@ -36,6 +33,8 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, SecondGoods> implements SecondGoodsService {
 
+    private final VideoUtils videoUtils;
+
     /**
      * 二手商品Mapper
      */
@@ -47,6 +46,11 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     private final LifeUserMapper lifeUserMapper;
 
     /**
+     * 公告Mapper
+     */
+    private final LifeNoticeMapper lifeNoticeMapper;
+
+    /**
      * 店铺信息Mapper
      */
     private final StoreImgMapper storeImgMapper;
@@ -57,6 +61,15 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     private final LifeBlacklistMapper lifeBlacklistMapper;
 
     /**
+     * 点赞记录Mapper
+     */
+    private final LifeLikeRecordMapper lifeLikeRecordMapper;
+
+    /**
+     * 收藏Mapper
+     */
+    private final LifeCollectMapper lifeCollectMapper;
+    /**
      * 保存商品为草稿状态
      * @param goods 商品实体
      * @return 是否成功保存
@@ -167,25 +180,32 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         if (CollectionUtil.isEmpty(imgUrl)) {
             return true; // 如果没有图片,则返回成功
         }
+        // 处理 第一个值为视频地址,获取视频第一帧作为商品封面图
+        String coverImage = getCoverImageFromVideoOrImage(imgUrl);
+        if (coverImage != null) {
+            // 更新商品表封面图字段
+            SecondGoods goods = new SecondGoods();
+            goods.setId(savedGoodsId);
+            goods.setHomeImage(coverImage);
+            updateById(goods);
+        }
+        // 保存前先把原有的删除
+        storeImgMapper.delete(new LambdaUpdateWrapper<StoreImg>().eq(StoreImg::getStoreId, savedGoodsId));
+        // 批量保存图片信息
         for(int i = 0; i < imgUrl.size(); i++){
-            // 判断如果第一个值为视频地址,获取视频第一帧作为商品封面图
-            if (i == 0 && imgUrl.get(i).endsWith(".mp4")) {
-//                imgUrl.set(i, ImageCheckUtil.getFirstFrame(imgUrl.get(i)));
-                continue;
-            }
             StoreImg storeImg = new StoreImg();
             storeImg.setStoreId(savedGoodsId);
-            storeImg.setImgType(15);
+            storeImg.setImgType(18);
             storeImg.setImgSort(i);
-            storeImg.setImgDescription("商品图片");
+            storeImg.setImgDescription("发布二手商品图片");
             storeImg.setDeleteFlag(0);
             storeImg.setCreatedTime(new Date());
             storeImg.setUpdatedTime(new Date());
             storeImg.setCreatedUserId(1);
             storeImg.setUpdatedUserId(1);
             storeImg.setImgUrl(imgUrl.get(i));
-            //  调取feign接口 保存图片 插入store_img数据库
-//            storeImgMapper.insert(storeImg);
+            // 保存图片 插入store_img数据库
+            storeImgMapper.insert(storeImg);
         }
         return true;
     }
@@ -195,35 +215,19 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
      * @param goods 商品信息
      */
     private void sendMessage(SecondGoods goods) {
+        // 根据 goods.getUserId() 获取用户信息
+        LifeUser lifeUser = lifeUserMapper.selectById(goods.getUserId());
+        String phone = lifeUser.getUserPhone();
         // 调取feign接口 发送消息 life_notice表
-//        MessageService messageService = FeignClient.create(MessageService.class);
-//        messageService.sendMessage(message);
-//        message.setType(1);
-//        message.setCreatedTime(new Date());
-//        message.setUpdatedTime(new Date());
-//        messageMapper.insert(message);
-    }
-
-    @Override
-    public IPage<SecondGoods> getGoodsWithImages(IPage<SecondGoods> page, Integer categoryId, Integer status) {
-        // 调用 Mapper 层分页查询方法
-        IPage<SecondGoods> goodsPage = secondGoodsMapper.selectGoodsWithImages(page, categoryId, status);
-
-        if (CollectionUtil.isNotEmpty(goodsPage.getRecords())) {
-            List<Integer> goodsIds = goodsPage.getRecords().stream()
-                    .map(SecondGoods::getId)
-                    .collect(Collectors.toList());
-
-//            // 批量获取图片信息
-//            Map<Integer, List<String>> imagesMap = storeImgService.getImgsByGoodsIds(goodsIds);
-//
-//            // 设置图片信息
-//            for (SecondGoods goods : goodsPage.getRecords()) {
-//                goods.setImgUrl(imagesMap.getOrDefault(goods.getId(), Collections.emptyList()));
-//            }
-        }
-
-        return goodsPage;
+        LifeNotice lifeNotice = new LifeNotice();
+        lifeNotice.setSenderId("system");
+        lifeNotice.setReceiverId("user_"+ phone);
+        lifeNotice.setBusinessId(goods.getId());
+        lifeNotice.setTitle("商品发布通知");
+        lifeNotice.setContext("您有一笔新的二手商品发布成功,请及时查看");
+        lifeNotice.setNoticeType(1); // 系统通知
+        lifeNotice.setIsRead(0);
+        lifeNoticeMapper.insert(lifeNotice);
     }
 
     /**
@@ -268,9 +272,8 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
      * @return 封面图URL或Base64编码字符串
      */
     private String extractFirstFrameAsCover(String videoUrl) {
-        // TODO: 实现视频首帧提取逻辑,可基于FFmpeg、JavaCV等
         // 示例返回占位符
-        return "http://example.com/covers/" + System.currentTimeMillis() + ".jpg";
+        return videoUtils.getImg(videoUrl);
     }
 
     /**
@@ -296,16 +299,6 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         return secondGoodsMapper.getHotSellingRanking(page);
     }
 
-    /**
-     * 获取用户屏蔽的商品列表
-     * @param userId 用户ID
-     * @return 屏蔽的商品列表
-     */
-    @Override
-    public List<SecondGoods> getShieldedGoodsList(Integer userId) {
-        return secondGoodsMapper.getShieldedGoodsList(userId);
-    }
-
     @Override
     public IPage<SecondGoods> getShieldedGoodsListByType(IPage<SecondGoods> page, Integer userId, Integer shieldType) {
         return secondGoodsMapper.getShieldedGoodsListByType(page, userId, shieldType);
@@ -341,15 +334,109 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         // 获取搜索结果分页列表
         IPage<SecondGoodsVo> searchGoodsList = getSecondGoodsVoIPage(page, secondGoodsVo, shieldedGoodsIds, userIdList);
 
-        // 批量设置商品图片信息
-        batchSetGoodsImages(searchGoodsList);
-        // 批量设置用户信息
-
-        batchSetUserInfo(searchGoodsList);
+        // 判空
+        if (CollectionUtil.isNotEmpty(searchGoodsList.getRecords())) {
+            // 批量设置商品图片信息
+            batchSetGoodsImages(searchGoodsList);
+            // 批量设置用户信息
+            batchSetUserInfo(searchGoodsList);
+            // 批量设置收藏状态
+            batchSetCollectStatus(searchGoodsList, userId);
+            // 批量设置点赞状态
+            batchSetLikeStatus(searchGoodsList, userId);
+        }
         return searchGoodsList;
     }
 
     /**
+     * 批量设置收藏状态
+     * @param searchGoodsList 搜索结果列表
+     * @param userId 用户ID(登录用户)
+     */
+    private void batchSetLikeStatus(IPage<SecondGoodsVo> searchGoodsList, Integer userId) {
+        // 获取用户信息
+        LifeUser lifeUser = lifeUserMapper.selectById(userId);
+        String phone = lifeUser.getUserPhone();
+        // 批量设置点赞状态
+        searchGoodsList.getRecords().forEach(goods -> {
+            if (userId != null) {
+                // 设置点赞状态
+                LambdaUpdateWrapper<LifeLikeRecord> updateWrapper = new LambdaUpdateWrapper<>();
+                updateWrapper.eq(LifeLikeRecord::getHuifuId, goods.getId())
+                        .eq(LifeLikeRecord::getDianzanId, "user_"+phone).
+                        eq(LifeLikeRecord::getType, 6); // 6-二手商品
+                if (lifeLikeRecordMapper.selectCount(updateWrapper) > 0) {
+                    goods.setLikeStatus(1);
+                }
+            }
+        });
+    }
+
+    /**
+     * 批量设置收藏状态
+     * @param searchGoodsList 搜索结果列表
+     * @param userId 用户ID(登录用户)
+     */
+    private void batchSetCollectStatus(IPage<SecondGoodsVo> searchGoodsList, Integer userId) {
+        searchGoodsList.getRecords().forEach(goods -> {
+            if (userId != null) {
+                LambdaUpdateWrapper<LifeCollect> updateWrapper = new LambdaUpdateWrapper<>();
+                updateWrapper.eq(LifeCollect::getUserId, userId)
+                        .eq(LifeCollect::getGoodsId, goods.getId());
+                        if (lifeCollectMapper.selectCount(updateWrapper) > 0) {
+                            goods.setCollectStatus(1);
+                        }
+            }
+        });
+    }
+
+    /**
+     * 获取商品屏蔽列表
+     * @param userId 用户ID
+     * @return 商品屏蔽列表
+     */
+    private List<SecondGoods> getShieldedGoodsList(Integer userId) {
+        // 调用mapper方法
+        return secondGoodsMapper.getShieldedGoodsList(userId);
+    }
+
+    /**
+     * 获取商品详情
+     * @param id 商品ID
+     * @return 商品详情
+     */
+    @Override
+    public SecondGoodsVo getSecondGoodsById(Integer id) {
+        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("sg.id", id)
+                .eq("sg.delete_flag", 0);
+        SecondGoodsVo secondGoods = secondGoodsMapper.getGoodsDetails(queryWrapper);
+        // 设置图片信息
+        QueryWrapper<StoreImg> query = new QueryWrapper<>();
+        query.lambda()
+                .eq(StoreImg::getImgType, 18) // 商品 图片
+                .eq(StoreImg::getDeleteFlag, 0)
+                .in(StoreImg::getStoreId, id);
+        List<StoreImg> storeImgs = storeImgMapper.selectList(query);
+        // 设置图片信息
+        if (CollectionUtil.isNotEmpty(storeImgs)) {
+            secondGoods.setImgUrl(storeImgs.stream().map(StoreImg::getImgUrl).collect(Collectors.toList()));
+        }
+        return secondGoods;
+    }
+
+    @Override
+    public IPage<SecondGoodsVo> getShieldedGoodsPage(IPage<SecondGoodsVo> page, Integer userId) {
+        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("sg.delete_flag", 0)
+                .eq("ss.delete_flag", 0)
+                .eq("ss.user_id", userId)
+                .eq("ss.shield_type", 1);
+        return secondGoodsMapper.getShieldedGoodsPage(page, queryWrapper);
+
+    }
+
+    /**
      * 查询搜索结果
      * @param page 分页参数
      * @param secondGoodsVo 查询参数
@@ -361,8 +448,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
         queryWrapper.notIn(CollectionUtil.isNotEmpty(shieldedGoodsIds), "sg.id", shieldedGoodsIds)
                 .notIn(CollectionUtil.isNotEmpty(userIdList), "sg.user_id", userIdList)
-                .eq("sg.delete_flag", 0)
-                .orderByAsc("distance");
+                .eq("sg.delete_flag", 0);
         // 添加对 searchData 的模糊查询
         if (!StringUtils.isEmpty(secondGoodsVo.getSearchData())) {
             String searchData = "%" + secondGoodsVo.getSearchData() + "%";
@@ -380,14 +466,22 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
                 .like("sg.topic", searchData)
             );
         }
-        // 正序
-        if (secondGoodsVo.getOrderType() == 1){
-            queryWrapper.orderByAsc(secondGoodsVo.getOrderData());
-        }
-        // 倒序
-        if (secondGoodsVo.getOrderType() == 2){
-            queryWrapper.orderByDesc(secondGoodsVo.getOrderData());
+        // 添加对 orderData 的排序 若不为空
+        if (!StringUtils.isEmpty(secondGoodsVo.getOrderData()) && !StringUtils.isEmpty(secondGoodsVo.getOrderType())) {
+            // 正序
+            if (secondGoodsVo.getOrderType() == 1){
+                queryWrapper.orderByAsc(secondGoodsVo.getOrderData())
+                        .orderByAsc("distance");
+            }
+            // 倒序
+            if (secondGoodsVo.getOrderType() == 2){
+                queryWrapper.orderByDesc(secondGoodsVo.getOrderData())
+                        .orderByAsc("distance");
+            }
+        }else {
+            queryWrapper.orderByAsc("distance");
         }
+
         // 返回分页结果
         IPage<SecondGoodsVo> searchGoodsList = secondGoodsMapper.searchGoodsList(page, secondGoodsVo.getCurrentLatitude(), secondGoodsVo.getCurrentLongitude() ,queryWrapper);
         searchGoodsList.getRecords().forEach(secondGoods -> {

+ 14 - 0
alien-store/src/main/java/shop/alien/store/service/LifeCommentService.java

@@ -10,9 +10,11 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
+import shop.alien.entity.second.SecondGoods;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.vo.LifePinglunVo;
 import shop.alien.mapper.*;
+import shop.alien.mapper.second.SecondGoodsMapper;
 
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -45,6 +47,8 @@ public class LifeCommentService {
 
     private final LifeNoticeMapper lifeNoticeMapper;
 
+    private final SecondGoodsMapper secondGoodsMapper;
+
     public int like(String userId, String huifuId, String type) {
         LambdaUpdateWrapper<LifeLikeRecord> updateWrapper = new LambdaUpdateWrapper<>();
         updateWrapper.eq(LifeLikeRecord::getType, type);
@@ -86,6 +90,11 @@ public class LifeCommentService {
             lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId);
             lambdaUpdateWrapper.setSql("like_count = like_count + 1");
             return storeClockInMapper.update(null, lambdaUpdateWrapper);
+        } else if ("6".equals(type)) {
+            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+            lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId);
+            lambdaUpdateWrapper.setSql("like_count = like_count + 1");
+            return secondGoodsMapper.update(null, lambdaUpdateWrapper);
         }
         return 0;
     }
@@ -144,6 +153,11 @@ public class LifeCommentService {
             lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId).gt(StoreClockIn::getLikeCount, 0);
             lambdaUpdateWrapper.setSql("like_count = like_count - 1");
             return storeClockInMapper.update(null, lambdaUpdateWrapper);
+        }else if ("6".equals(type)) {
+            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+            lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId).gt(SecondGoods::getLikeCount, 0);
+            lambdaUpdateWrapper.setSql("like_count = like_count - 1");
+            return secondGoodsMapper.update(null, lambdaUpdateWrapper);
         }
         return 0;
     }