|
@@ -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 -> {
|