Browse Source

feat(second): 添加二手商品管理后台相关功能

- 新增管理后台商品列表查询接口和相关实体类
- 实现管理后台商品详情和操作记录详情查询功能
- 优化商品查询条件和结果展示
- 增加举报信息处理相关功能
wxd 3 months ago
parent
commit
ff15b294b2

+ 33 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsAdminQueryDTO.java

@@ -0,0 +1,33 @@
+package shop.alien.entity.second.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 二手商品管理后台查询DTO
+ */
+@Data
+@ApiModel(value = "SecondGoodsAdminQueryDTO", description = "二手商品管理后台查询参数")
+public class SecondGoodsAdminQueryDTO {
+
+    @ApiModelProperty(value = "当前页码")
+    private Integer pageNum = 1;
+
+    @ApiModelProperty(value = "每页数量")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty(value = "商品名称")
+    private String title;
+
+    @ApiModelProperty(value = "商品状态 0:草稿 1:审核中 2:审核失败 3:已上架 4:已下架 5:已售出,6:已删除")
+    private Integer goodsStatus;
+
+    @ApiModelProperty(value = "发布时间开始时间")
+    private Date releaseStartTime;
+
+    @ApiModelProperty(value = "发布时间结束时间")
+    private Date releaseEndTime;
+}

+ 34 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsDetailVo.java

@@ -0,0 +1,34 @@
+package shop.alien.entity.second.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.second.SecondGoods;
+import shop.alien.entity.second.SecondGoodsRecord;
+import shop.alien.entity.second.SecondTradeRecord;
+import shop.alien.entity.store.StoreImg;
+import shop.alien.entity.second.vo.SecondReportingVo;
+
+import java.util.List;
+
+@Data
+@JsonInclude
+@ApiModel(value = "SecondGoodsDetailVo", description = "二手商品详情VO")
+public class SecondGoodsDetailVo {
+
+    @ApiModelProperty(value = "商品基本信息")
+    private SecondGoods goodsInfo;
+
+    @ApiModelProperty(value = "商品图片列表")
+    private List<StoreImg> imageList;
+
+    @ApiModelProperty(value = "商品操作记录集合")
+    private List<SecondGoodsRecord> operationRecords;
+
+    @ApiModelProperty(value = "商品交易记录集合")
+    private List<SecondTradeRecord> tradeRecords;
+
+    @ApiModelProperty(value = "商品举报集合")
+    private List<SecondReportingVo> reports;
+}

+ 127 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsRecordDetailVo.java

@@ -0,0 +1,127 @@
+package shop.alien.entity.second.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.second.SecondGoodsRecord;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@ApiModel("商品操作记录详情VO")
+public class SecondGoodsRecordDetailVo {
+
+    @ApiModelProperty(value = "主键ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "商品ID")
+    private Integer goodsId;
+
+    @ApiModelProperty(value = "商品标题")
+    private String title;
+
+    @ApiModelProperty(value = "商品描述")
+    private String description;
+
+    @ApiModelProperty(value = "商品价格(元,保留小数后两位)")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "商品位置")
+    private String position;
+
+    @ApiModelProperty(value = "点赞数量")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "收藏数量")
+    private Integer collectCount;
+
+    @ApiModelProperty(value = "一级类别ID")
+    private Integer categoryOneId;
+
+    @ApiModelProperty(value = "二级类别ID")
+    private Integer categoryTwoId;
+
+    @ApiModelProperty(value = "标签")
+    private String label;
+
+    @ApiModelProperty(value = "话题(以逗号分隔)")
+    private String topic;
+
+    @ApiModelProperty(value = "交易ID")
+    private Integer tradeId;
+
+    @ApiModelProperty(value = "发布时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date releaseTime;
+
+    @ApiModelProperty(value = "商品状态 0:草稿 1:审核中 2:审核失败 3:已上架 4:已下架 5:已售出")
+    private Integer goodsStatus;
+
+    @ApiModelProperty(value = "审核失败原因")
+    private String failedReason;
+
+    @ApiModelProperty(value = "首页图")
+    private String homeImage;
+
+    @ApiModelProperty(value = "视频审核任务id")
+    private String videoTaskId;
+
+    @ApiModelProperty(value = "视频第一帧图片")
+    private String videoFirstFrame;
+
+    @ApiModelProperty(value = "删除标记 0:未删除 1:已删除")
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "地址文本")
+    private String addressText;
+
+    @ApiModelProperty(value = "商品图片列表")
+    private List<String> imageUrls;
+
+    public static SecondGoodsRecordDetailVo fromRecord(SecondGoodsRecord record) {
+        SecondGoodsRecordDetailVo vo = new SecondGoodsRecordDetailVo();
+        vo.setId(record.getId());
+        vo.setGoodsId(record.getGoodsId());
+        vo.setTitle(record.getTitle());
+        vo.setDescription(record.getDescription());
+        vo.setPrice(record.getPrice());
+        vo.setPosition(record.getPosition());
+        vo.setLikeCount(record.getLikeCount());
+        vo.setCollectCount(record.getCollectCount());
+        vo.setCategoryOneId(record.getCategoryOneId());
+        vo.setCategoryTwoId(record.getCategoryTwoId());
+        vo.setLabel(record.getLabel());
+        vo.setTopic(record.getTopic());
+        vo.setTradeId(record.getTradeId());
+        vo.setReleaseTime(record.getReleaseTime());
+        vo.setGoodsStatus(record.getGoodsStatus());
+        vo.setFailedReason(record.getFailedReason());
+        vo.setHomeImage(record.getHomeImage());
+        vo.setVideoTaskId(record.getVideoTaskId());
+        vo.setVideoFirstFrame(record.getVideoFirstFrame());
+        vo.setDeleteFlag(record.getDeleteFlag());
+        vo.setCreatedTime(record.getCreatedTime());
+        vo.setCreatedUserId(record.getCreatedUserId());
+        vo.setUpdatedTime(record.getUpdatedTime());
+        vo.setUpdatedUserId(record.getUpdatedUserId());
+        vo.setAddressText(record.getAddressText());
+        return vo;
+    }
+}

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

@@ -55,6 +55,10 @@ public class SecondGoodsVo extends SecondGoods {
     @TableField(exist = false)
     @ApiModelProperty(value = "点赞状态 默认为 0")
     private Integer likeStatus = 0;
+    
+    @TableField(exist = false)
+    @ApiModelProperty(value = "商品状态名称")
+    private String goodsStatusName;
 
     @ApiModelProperty("一级分类名称")
     @TableField(exist = false)

+ 7 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondReportingVo.java

@@ -49,4 +49,11 @@ public class SecondReportingVo{
 
     @ApiModelProperty(value = "图片集合")
     private List<Map<String, Object>> imgList;
+
+    @ApiModelProperty(value = "举报人名称")
+    private String reportingUserName;
+
+    @ApiModelProperty(value = "联系方式")
+    private String reportingUserPhone;
+
 }

+ 19 - 0
alien-entity/src/main/java/shop/alien/mapper/second/SecondGoodsMapper.java

@@ -289,4 +289,23 @@ public interface SecondGoodsMapper extends BaseMapper<SecondGoods> {
             "LEFT JOIN second_goods sg ON str.goods_id = sg.id "+
             "${ew.customSqlSegment}")
     IPage<SellGoodsVo> getTransactionList(IPage<SellGoodsVo> page, @Param("userId") Integer userId, @Param(Constants.WRAPPER) QueryWrapper<SellGoodsVo> queryWrapper);
+
+    /**
+     * 管理后台商品列表查询
+     * @param page 分页参数
+     * @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 = sgc2.id " +
+            "${ew.customSqlSegment}")
+    IPage<SecondGoodsVo> getAdminGoodsList(IPage<SecondGoodsVo> page, @Param(Constants.WRAPPER) QueryWrapper<SecondGoodsVo> queryWrapper);
+
 }

+ 69 - 0
alien-second/src/main/java/shop/alien/second/controller/AdminSecondGoodsController.java

@@ -0,0 +1,69 @@
+package shop.alien.second.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.second.vo.SecondGoodsAdminQueryDTO;
+import shop.alien.entity.second.vo.SecondGoodsDetailVo;
+import shop.alien.entity.second.vo.SecondGoodsRecordDetailVo;
+import shop.alien.entity.second.vo.SecondGoodsVo;
+import shop.alien.second.service.SecondGoodsService;
+
+/**
+ * 二手商品管理后台控制器
+ */
+@Slf4j
+@Api(tags = {"二手平台-商品管理(管理后台)"})
+@ApiSort(2)
+@CrossOrigin
+@RestController
+@RequestMapping("/admin/secondGoods")
+@RequiredArgsConstructor
+public class AdminSecondGoodsController {
+
+    /**
+     * 二手商品服务
+     */
+    private final SecondGoodsService secondGoodsService;
+
+    /**
+     * 管理后台商品列表接口
+     */
+    @PostMapping("/list")
+    @ApiOperation("管理后台商品列表")
+    public R<IPage<SecondGoodsVo>> getAdminGoodsList(@ApiParam("查询参数") @RequestBody SecondGoodsAdminQueryDTO queryDTO) {
+        log.info("AdminSecondGoodsController.getAdminGoodsList?queryDTO={}", queryDTO);
+
+        // 构建分页对象
+        IPage<SecondGoodsVo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+
+        // 执行分页查询
+        IPage<SecondGoodsVo> result = secondGoodsService.getAdminGoodsList(page, queryDTO);
+        
+        return R.data(result, "查询成功");
+    }
+    
+    @GetMapping("/detail")
+    @ApiOperation("管理后台商品详情")
+    public R<SecondGoodsDetailVo> getAdminGoodsDetail(@ApiParam("商品ID") @RequestParam Integer goodsId) {
+        log.info("AdminSecondGoodsController.getAdminGoodsDetail?goodsId={}", goodsId);
+        
+        SecondGoodsDetailVo result = secondGoodsService.getAdminGoodsDetail(goodsId);
+        
+        return R.data(result, "查询成功");
+    }
+
+    @GetMapping("/record/detail")
+    @ApiOperation("管理后台商品操作记录详情")
+    public R<SecondGoodsRecordDetailVo> getAdminGoodsRecordDetail(@ApiParam("操作记录ID") @RequestParam Integer recordId) {
+        log.info("AdminSecondGoodsController.getAdminGoodsRecordDetail?recordId={}", recordId);
+
+        SecondGoodsRecordDetailVo result = secondGoodsService.getAdminGoodsRecordDetail(recordId);
+
+        return R.data(result, "查询成功");
+    }
+}

+ 37 - 11
alien-second/src/main/java/shop/alien/second/service/SecondGoodsService.java

@@ -7,6 +7,9 @@ import shop.alien.entity.SecondVideoTask;
 import shop.alien.entity.second.SecondGoods;
 import shop.alien.entity.second.SecondGoodsRecord;
 import shop.alien.entity.second.vo.SecondGoodsVo;
+import shop.alien.entity.second.vo.SecondGoodsAdminQueryDTO;
+import shop.alien.entity.second.vo.SecondGoodsDetailVo;
+import shop.alien.entity.second.vo.SecondGoodsRecordDetailVo;
 import shop.alien.entity.second.vo.SellGoodsVo;
 
 import java.util.List;
@@ -101,43 +104,44 @@ public interface SecondGoodsService extends IService<SecondGoods> {
     /**
      * 获取我卖出的商品列表(分页)
      * @param page 搜索条件
+     * @param secondGoodsVo 查询参数
      * @param userId 用户ID
      * @return 分页后的卖出商品列表
      */
-    IPage<SecondGoodsVo> getSellGoodsPage(IPage<SecondGoodsVo> page,SecondGoodsVo secondGoodsVo,int userId);
+    IPage<SecondGoodsVo> getSellGoodsPage(IPage<SecondGoodsVo> page, SecondGoodsVo secondGoodsVo,int userId);
 
     /**
-     * 获取个人主页用户发布的商品列表(分页)
+     * 获取用户发布的商品列表(分页)
      * @param page 搜索条件
-     * @param currentLatitude 当前位置纬度
-     * @param currentLongitude 当前位置经度
+     * @param currentLatitude 当前纬度
+     * @param currentLongitude 当前经度
      * @param userId 用户ID
      * @return 分页后的用户商品列表
      */
     IPage<SecondGoodsVo> getUserGoodsPage(IPage<SecondGoodsVo> page, Double currentLatitude , Double currentLongitude, Integer userId);
 
     /**
-     * 获取个人主页用户发布的商品列表(分页)
+     * 获取的商品列表(分页)
      * @param page 搜索条件
      * @param userId 用户ID
-     * @return 分页后的用户商品列表
+     * @return 分页后的我的商品列表
      */
     IPage<SecondGoodsVo> getMyGoodsPage(IPage<SecondGoodsVo> page, int userId);
 
     /**
-     * 获取商品草稿列表(分页)
+     * 获取草稿列表(分页)
      * @param page 搜索条件
      * @param userId 用户ID
-     * @return 分页后的商品草稿列表
+     * @return 分页后的草稿列表
      */
     IPage<SecondGoodsVo> getDraftList(IPage<SecondGoodsVo> page, int userId);
 
     /**
-     * 获取商品点赞商品列表(分页)
+     * 获取点赞商品列表(分页)
      * @param page 搜索条件
      * @param userId 用户ID
-     * @param phone 手机号
-     * @return 分页后的商品点赞商品列表
+     * @param phone 用户手机号
+     * @return 分页后的点赞商品列表
      */
     IPage<SecondGoodsVo> getLikeGoodsPage(IPage<SecondGoodsVo> page, int userId, String phone);
 
@@ -162,4 +166,26 @@ public interface SecondGoodsService extends IService<SecondGoods> {
      * @param goods 商品信息
      */
     void recordGoodsOperation(SecondGoods goods);
+
+    /**
+     * 管理后台商品列表查询
+     * @param page 分页参数
+     * @param queryDTO 查询参数
+     * @return 商品列表
+     */
+    IPage<SecondGoodsVo> getAdminGoodsList(IPage<SecondGoodsVo> page, SecondGoodsAdminQueryDTO queryDTO);
+    
+    /**
+     * 获取商品详情(管理后台使用)
+     * @param goodsId 商品ID
+     * @return 商品详情信息
+     */
+    SecondGoodsDetailVo getAdminGoodsDetail(Integer goodsId);
+
+    /**
+     * 获取管理后台商品操作记录详情
+     * @param recordId 操作记录ID
+     * @return 操作记录详情
+     */
+    SecondGoodsRecordDetailVo getAdminGoodsRecordDetail(Integer recordId);
 }

+ 298 - 7
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java

@@ -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;
+    }
 }