|
|
@@ -15,17 +15,16 @@ import com.google.common.collect.Lists;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
import shop.alien.entity.SecondVideoTask;
|
|
|
-import shop.alien.entity.second.SecondGoods;
|
|
|
-import shop.alien.entity.second.SecondGoodsAudit;
|
|
|
-import shop.alien.entity.second.SecondGoodsRecord;
|
|
|
-import shop.alien.entity.second.enums.SecondGoodsStatusEnum;
|
|
|
-import shop.alien.entity.second.vo.SecondGoodsVo;
|
|
|
-import shop.alien.entity.second.vo.SellGoodsVo;
|
|
|
+import shop.alien.entity.second.*;
|
|
|
+import shop.alien.entity.second.SecondTradeRecord;
|
|
|
+import shop.alien.entity.second.vo.*;
|
|
|
+import shop.alien.entity.second.vo.SecondGoodsDetailVo;
|
|
|
import shop.alien.entity.store.*;
|
|
|
import shop.alien.entity.store.vo.LifeUserVo;
|
|
|
import shop.alien.entity.store.vo.WebSocketVo;
|
|
|
@@ -33,17 +32,22 @@ import shop.alien.mapper.*;
|
|
|
import shop.alien.mapper.second.SecondGoodsAuditMapper;
|
|
|
import shop.alien.mapper.second.SecondGoodsMapper;
|
|
|
import shop.alien.mapper.second.SecondGoodsRecordMapper;
|
|
|
+import shop.alien.mapper.second.SecondTradeRecordMapper;
|
|
|
import shop.alien.second.feign.AlienStoreFeign;
|
|
|
import shop.alien.second.service.SecondGoodsService;
|
|
|
import shop.alien.second.service.VideoModerationService;
|
|
|
import shop.alien.util.common.Constants;
|
|
|
+import shop.alien.entity.second.enums.SecondGoodsStatusEnum;
|
|
|
import shop.alien.util.common.VideoUtils;
|
|
|
import shop.alien.util.common.safe.*;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
@@ -129,6 +133,101 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
*/
|
|
|
private final SecondGoodsRecordMapper secondGoodsRecordMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private SecondTradeRecordMapper secondTradeRecordMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 举报信息Mapper
|
|
|
+ */
|
|
|
+ private final LifeUserViolationMapper lifeUserViolationMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 字典Mapper
|
|
|
+ */
|
|
|
+ private final StoreDictionaryMapper storeDictionaryMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SecondGoodsRecordDetailVo getAdminGoodsRecordDetail(Integer recordId) {
|
|
|
+ // 1. 获取商品操作记录基本信息
|
|
|
+ SecondGoodsRecord record = secondGoodsRecordMapper.selectById(recordId);
|
|
|
+ if (record == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 转换为VO对象
|
|
|
+ SecondGoodsRecordDetailVo detailVo = SecondGoodsRecordDetailVo.fromRecord(record);
|
|
|
+
|
|
|
+ // 3. 获取商品图片列表
|
|
|
+ QueryWrapper<StoreImg> imageQueryWrapper = new QueryWrapper<>();
|
|
|
+ imageQueryWrapper.lambda()
|
|
|
+ .eq(StoreImg::getStoreId, record.getGoodsId())
|
|
|
+ .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS)
|
|
|
+ .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
|
|
|
+ .orderByAsc(StoreImg::getImgSort);
|
|
|
+ List<StoreImg> imageList = storeImgMapper.selectList(imageQueryWrapper);
|
|
|
+
|
|
|
+ // 4. 提取图片URL列表
|
|
|
+ if (CollectionUtil.isNotEmpty(imageList)) {
|
|
|
+ List<String> imageUrls = imageList.stream()
|
|
|
+ .map(StoreImg::getImgUrl)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ detailVo.setImageUrls(imageUrls);
|
|
|
+ }
|
|
|
+
|
|
|
+ return detailVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SecondGoodsDetailVo getAdminGoodsDetail(Integer goodsId) {
|
|
|
+ SecondGoodsDetailVo detailVo = new SecondGoodsDetailVo();
|
|
|
+
|
|
|
+ // 1. 获取商品基本信息
|
|
|
+ SecondGoods goodsInfo = getById(goodsId);
|
|
|
+ detailVo.setGoodsInfo(goodsInfo);
|
|
|
+
|
|
|
+ // 2. 获取商品图片列表
|
|
|
+ QueryWrapper<StoreImg> imageQueryWrapper = new QueryWrapper<>();
|
|
|
+ imageQueryWrapper.lambda()
|
|
|
+ .eq(StoreImg::getStoreId, goodsId)
|
|
|
+ .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS)
|
|
|
+ .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
|
|
|
+ .orderByAsc(StoreImg::getImgSort);
|
|
|
+ List<StoreImg> imageList = storeImgMapper.selectList(imageQueryWrapper);
|
|
|
+ detailVo.setImageList(imageList);
|
|
|
+
|
|
|
+ // 3. 获取商品操作记录集合
|
|
|
+ QueryWrapper<SecondGoodsRecord> recordQueryWrapper = new QueryWrapper<>();
|
|
|
+ recordQueryWrapper.lambda()
|
|
|
+ .eq(SecondGoodsRecord::getGoodsId, goodsId)
|
|
|
+ .orderByDesc(SecondGoodsRecord::getCreatedTime);
|
|
|
+ List<SecondGoodsRecord> operationRecords = secondGoodsRecordMapper.selectList(recordQueryWrapper);
|
|
|
+ detailVo.setOperationRecords(operationRecords);
|
|
|
+
|
|
|
+ // 4. 获取商品交易记录集合
|
|
|
+ QueryWrapper<SecondTradeRecord> tradeQueryWrapper = new QueryWrapper<>();
|
|
|
+ tradeQueryWrapper.eq("goods_id", goodsId)
|
|
|
+ .orderByDesc("transaction_time");
|
|
|
+ List<SecondTradeRecord> tradeRecords = secondTradeRecordMapper.selectList(tradeQueryWrapper);
|
|
|
+
|
|
|
+ // TODO 处理交易步骤
|
|
|
+
|
|
|
+ detailVo.setTradeRecords(tradeRecords);
|
|
|
+
|
|
|
+ // 5. 获取商品举报集合
|
|
|
+ QueryWrapper<LifeUserViolation> reportQueryWrapper = new QueryWrapper<>();
|
|
|
+ reportQueryWrapper.lambda()
|
|
|
+ .eq(LifeUserViolation::getBusinessId, goodsId)
|
|
|
+ .eq(LifeUserViolation::getReportContextType, "4") // 4:二手商品
|
|
|
+ .orderByDesc(LifeUserViolation::getCreatedTime);
|
|
|
+ List<LifeUserViolation> reports = lifeUserViolationMapper.selectList(reportQueryWrapper);
|
|
|
+
|
|
|
+ // 转换举报信息为SecondReportingVo
|
|
|
+ List<SecondReportingVo> reportingVos = convertReportsToVos(reports);
|
|
|
+ detailVo.setReports(reportingVos);
|
|
|
+
|
|
|
+ return detailVo;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 记录商品操作历史
|
|
|
* @param goods 商品信息
|
|
|
@@ -178,6 +277,125 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 批量转换举报信息为SecondReportingVo对象
|
|
|
+ * @param reports 举报信息列表
|
|
|
+ * @return SecondReportingVo列表
|
|
|
+ */
|
|
|
+ private List<SecondReportingVo> convertReportsToVos(List<LifeUserViolation> reports) {
|
|
|
+ List<SecondReportingVo> reportingVos = new ArrayList<>();
|
|
|
+
|
|
|
+ // 获取所有相关的举报类型字典信息
|
|
|
+ List<String> dictTypes = reports.stream()
|
|
|
+ .map(LifeUserViolation::getDictType)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<Integer> dictIds = reports.stream()
|
|
|
+ .map(LifeUserViolation::getDictId)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Map<String, StoreDictionary> dictMap = new HashMap<>();
|
|
|
+ if (!dictTypes.isEmpty() && !dictIds.isEmpty()) {
|
|
|
+ QueryWrapper<StoreDictionary> dictQueryWrapper = new QueryWrapper<>();
|
|
|
+ dictQueryWrapper.lambda()
|
|
|
+ .in(StoreDictionary::getTypeName, dictTypes)
|
|
|
+ .in(StoreDictionary::getDictId, dictIds);
|
|
|
+ List<StoreDictionary> dicts = storeDictionaryMapper.selectList(dictQueryWrapper);
|
|
|
+ dictMap = dicts.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ d -> d.getTypeName() + "_" + d.getDictId(),
|
|
|
+ d -> d));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转换每个举报信息
|
|
|
+ for (LifeUserViolation report : reports) {
|
|
|
+ SecondReportingVo reportingVo = new SecondReportingVo();
|
|
|
+
|
|
|
+ // 查询用户表 根据举报用户类型和举报用户ID 查询 life_user 表 user_phone
|
|
|
+ LifeUser reporter = lifeUserMapper.selectById(report.getReportedUserId());
|
|
|
+ if (reporter != null) {
|
|
|
+ // 处理举报用户名称 life_user 表 user_name
|
|
|
+ reportingVo.setReportingUserName(reporter.getUserName());
|
|
|
+ // 处理联系方式 life_user 表 user_phone
|
|
|
+ reportingVo.setReportingUserPhone(reporter.getUserPhone());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 基本信息
|
|
|
+ reportingVo.setId(report.getId());
|
|
|
+ // 举报时间
|
|
|
+ reportingVo.setReportingTime(report.getCreatedTime());
|
|
|
+ // 举报内容补充
|
|
|
+ reportingVo.setReportingContext(report.getOtherReasonContent());
|
|
|
+// reportingVo.setFeedbackTime(report.getCreatedTime());
|
|
|
+// reportingVo.setFeedbackContext("平台已受理,感谢您的反馈!");
|
|
|
+
|
|
|
+ // 获取举报类型信息
|
|
|
+ StoreDictionary storeDictionary = dictMap.get(report.getDictType() + "_" + report.getDictId());
|
|
|
+ // 举报类型
|
|
|
+ reportingVo.setReportContextType(storeDictionary.getTypeDetail());
|
|
|
+ // 二手商品举报
|
|
|
+ SecondGoods secondGoods = secondGoodsMapper.selectById(report.getBusinessId());
|
|
|
+ if (secondGoods != null) {
|
|
|
+ reportingVo.setPrice(secondGoods.getPrice() != null ?
|
|
|
+ secondGoods.getPrice().toString() : null);
|
|
|
+ reportingVo.setHomeImage(secondGoods.getHomeImage());
|
|
|
+ reportingVo.setTitle(secondGoods.getTitle());
|
|
|
+ reportingVo.setDescription(secondGoods.getDescription());
|
|
|
+ }
|
|
|
+ // 处理举报凭证图片
|
|
|
+ if (StringUtils.hasText(report.getReportEvidenceImg())) {
|
|
|
+ List<Map<String, Object>> imgList = processReportImages(report.getReportEvidenceImg());
|
|
|
+ reportingVo.setImgList(imgList);
|
|
|
+ }
|
|
|
+
|
|
|
+ reportingVos.add(reportingVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return reportingVos;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理举报凭证图片
|
|
|
+ * @param reportEvidenceImg 图片URL字符串
|
|
|
+ * @return 图片列表
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> processReportImages(String reportEvidenceImg) {
|
|
|
+ List<Map<String, Object>> list = new ArrayList<>();
|
|
|
+ List<String> urlList = Arrays.asList(reportEvidenceImg.split(","));
|
|
|
+ List<String> videoList = new ArrayList<>();
|
|
|
+ List<String> videoFileType = Arrays.asList("mp4", "avi", "flv", "mkv", "rmvb", "wmv", "3gp", "mov");
|
|
|
+
|
|
|
+ for (int i = 0; i < urlList.size(); i++) {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+
|
|
|
+ // 查找最后一个点的位置
|
|
|
+ int lastDotIndex = urlList.get(i).lastIndexOf('.');
|
|
|
+
|
|
|
+ String fileType = urlList.get(i).substring(urlList.get(i).lastIndexOf(".") + 1);
|
|
|
+ String contains = null;
|
|
|
+ if (lastDotIndex != -1) { // 确保存在
|
|
|
+ contains = urlList.get(i).substring(0, lastDotIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!videoList.contains(contains)) {
|
|
|
+ videoList.add(contains);
|
|
|
+ if (videoFileType.contains(fileType.toLowerCase())) {
|
|
|
+ map.put("type", "video");
|
|
|
+ map.put("imgUrl", urlList.get(i + 1));
|
|
|
+ map.put("videoUrl", urlList.get(i));
|
|
|
+ } else {
|
|
|
+ map.put("type", "image");
|
|
|
+ map.put("imgUrl", urlList.get(i));
|
|
|
+ }
|
|
|
+ list.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 保存商品为草稿状态
|
|
|
* @param goods 商品实体
|
|
|
* @return 是否成功保存
|
|
|
@@ -1261,6 +1479,38 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
List<Integer> goodsIds = searchGoodsList.getRecords().stream()
|
|
|
.map(SecondGoodsVo::getId)
|
|
|
.collect(Collectors.toList());
|
|
|
+ // 批量获取图片信息
|
|
|
+ QueryWrapper<StoreImg> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda()
|
|
|
+ .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS) // 商品 图片
|
|
|
+ .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
|
|
|
+ .in(StoreImg::getStoreId, goodsIds);
|
|
|
+ List<StoreImg> imagesList= storeImgMapper.getImgsByGoodsIds(queryWrapper);
|
|
|
+ // 集合根據商品id进行分组返回map
|
|
|
+ Map<Integer, List<StoreImg>> imagesMap = imagesList.stream().collect(Collectors.groupingBy(StoreImg::getStoreId));
|
|
|
+ // 遍历
|
|
|
+ for (SecondGoodsVo goods : searchGoodsList.getRecords()) {
|
|
|
+ // 提取图片url
|
|
|
+ List<StoreImg> images = imagesMap.get(goods.getId());
|
|
|
+ if (images != null) {
|
|
|
+ goods.setImgUrl(images.stream()
|
|
|
+ .map(StoreImg::getImgUrl)
|
|
|
+ .collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量设置商品图片信息(用于管理后台)
|
|
|
+ * @param goodsList 商品列表
|
|
|
+ */
|
|
|
+ private void batchSetGoodsImagesForAdmin(IPage<SecondGoodsVo> goodsList) {
|
|
|
+ // 批量获取图片信息
|
|
|
+ if (CollectionUtil.isNotEmpty(goodsList.getRecords())) {
|
|
|
+ List<Integer> goodsIds = goodsList.getRecords().stream()
|
|
|
+ .map(SecondGoodsVo::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
// 批量获取图片信息
|
|
|
QueryWrapper<StoreImg> queryWrapper = new QueryWrapper<>();
|
|
|
queryWrapper.lambda()
|
|
|
@@ -1271,7 +1521,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
// 集合根據商品id进行分组返回map
|
|
|
Map<Integer, List<StoreImg>> imagesMap = imagesList.stream().collect(Collectors.groupingBy(StoreImg::getStoreId));
|
|
|
// 遍历
|
|
|
- for (SecondGoodsVo goods : searchGoodsList.getRecords()) {
|
|
|
+ for (SecondGoodsVo goods : goodsList.getRecords()) {
|
|
|
// 提取图片url
|
|
|
List<StoreImg> images = imagesMap.get(goods.getId());
|
|
|
if (images != null) {
|
|
|
@@ -1280,6 +1530,16 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
.collect(Collectors.toList()));
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+ // 设置状态名称
|
|
|
+ if (goods.getDeleteFlag() != null && goods.getDeleteFlag().equals(Constants.DeleteFlag.DELETED)) {
|
|
|
+ goods.setGoodsStatusName("已删除");
|
|
|
+ } else if (goods.getGoodsStatus() != null) {
|
|
|
+ SecondGoodsStatusEnum statusEnum = SecondGoodsStatusEnum.fromCode(goods.getGoodsStatus());
|
|
|
+ if (statusEnum != null) {
|
|
|
+ goods.setGoodsStatusName(statusEnum.getDescription());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1317,4 +1577,35 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public IPage<SecondGoodsVo> getAdminGoodsList(IPage<SecondGoodsVo> page, SecondGoodsAdminQueryDTO queryDTO) {
|
|
|
+ // 构建查询条件
|
|
|
+ QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
|
|
|
+
|
|
|
+ // 商品名称模糊查询
|
|
|
+ queryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(queryDTO.getTitle()), "sg.title", queryDTO.getTitle());
|
|
|
+
|
|
|
+ // 状态查询分为两种情况处理
|
|
|
+ if (queryDTO.getGoodsStatus() != null) {
|
|
|
+ if (queryDTO.getGoodsStatus() == 6) {
|
|
|
+ // 当状态为6时,查询删除标记为1的数据
|
|
|
+ queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.DELETED);
|
|
|
+ } else {
|
|
|
+ // 其他状态按照商品状态进行查询,并且删除标记为0
|
|
|
+ queryWrapper.eq("sg.goods_status", queryDTO.getGoodsStatus());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 发布时间范围查询
|
|
|
+ queryWrapper.ge(queryDTO.getReleaseStartTime() != null, "sg.release_time", queryDTO.getReleaseStartTime())
|
|
|
+ .le(queryDTO.getReleaseEndTime() != null, "sg.release_time", queryDTO.getReleaseEndTime());
|
|
|
+
|
|
|
+ // 查询数据
|
|
|
+ IPage<SecondGoodsVo> result = secondGoodsMapper.getAdminGoodsList(page, queryWrapper);
|
|
|
+
|
|
|
+ // 批量设置商品图片信息
|
|
|
+ batchSetGoodsImagesForAdmin(result);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|