下载商品按照快照状态下载
This commit is contained in:
@@ -50,11 +50,12 @@ public class ListingMallController {
|
|||||||
return Response.success(result);
|
return Response.success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取商品 listing 图片 URL 列表", description = "返回指定商品ID的 listing 分类图片 URL 列表")
|
@Operation(summary = "获取商品 listing 图片 URL 列表", description = "返回指定商品ID的 listing 分类图片 URL 列表(仅返回已购买该商品的用户)")
|
||||||
@GetMapping("/mall/main-product/urls")
|
@GetMapping("/mall/main-product/urls")
|
||||||
public Response<List<String>> getListingUrls(
|
public Response<List<String>> getListingUrls(
|
||||||
@Parameter(description = "商品ID") @RequestParam Long id) {
|
@Parameter(description = "商品ID") @RequestParam Long id,
|
||||||
List<String> urls = listingMallService.getListingUrls(id);
|
@Parameter(description = "买家ID") @RequestParam Long buyerId) {
|
||||||
|
List<String> urls = listingMallService.getListingUrls(id, buyerId);
|
||||||
return Response.success(urls);
|
return Response.success(urls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ public interface ListingMallService {
|
|||||||
* 获取商品的 listing 图片 URL 列表
|
* 获取商品的 listing 图片 URL 列表
|
||||||
*
|
*
|
||||||
* @param id 商品ID
|
* @param id 商品ID
|
||||||
|
* @param buyerId 买家ID
|
||||||
* @return listing 图片 URL 列表
|
* @return listing 图片 URL 列表
|
||||||
*/
|
*/
|
||||||
List<String> getListingUrls(Long id);
|
List<String> getListingUrls(Long id, Long buyerId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ import com.aida.seller.module.listing.dto.ListingMallQueryDTO;
|
|||||||
import com.aida.seller.module.listing.entity.ListingEntity;
|
import com.aida.seller.module.listing.entity.ListingEntity;
|
||||||
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
||||||
import com.aida.seller.module.listing.enums.DesignForEnum;
|
import com.aida.seller.module.listing.enums.DesignForEnum;
|
||||||
|
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
||||||
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
||||||
import com.aida.seller.module.listing.mapper.ListingMallMapper;
|
import com.aida.seller.module.listing.mapper.ListingMallMapper;
|
||||||
import com.aida.seller.module.listing.vo.ListingDetailVO;
|
import com.aida.seller.module.listing.vo.ListingDetailVO;
|
||||||
import com.aida.seller.module.listing.vo.ListingMallVO;
|
import com.aida.seller.module.listing.vo.ListingMallVO;
|
||||||
|
import com.aida.seller.module.order.entity.OrderItemImageEntity;
|
||||||
|
import com.aida.seller.module.order.mapper.OrderItemImageMapper;
|
||||||
import com.aida.seller.util.MinioUtil;
|
import com.aida.seller.util.MinioUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@@ -37,11 +40,14 @@ public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, Listi
|
|||||||
private final MinioUtil minioUtil;
|
private final MinioUtil minioUtil;
|
||||||
private final ListingImageMapper listingImageMapper;
|
private final ListingImageMapper listingImageMapper;
|
||||||
private final DesignerMapper designerMapper;
|
private final DesignerMapper designerMapper;
|
||||||
|
private final OrderItemImageMapper orderItemImageMapper;
|
||||||
|
|
||||||
public ListingMallServiceImpl(MinioUtil minioUtil, ListingImageMapper listingImageMapper, DesignerMapper designerMapper) {
|
public ListingMallServiceImpl(MinioUtil minioUtil, ListingImageMapper listingImageMapper, DesignerMapper designerMapper,
|
||||||
|
OrderItemImageMapper orderItemImageMapper) {
|
||||||
this.minioUtil = minioUtil;
|
this.minioUtil = minioUtil;
|
||||||
this.listingImageMapper = listingImageMapper;
|
this.listingImageMapper = listingImageMapper;
|
||||||
this.designerMapper = designerMapper;
|
this.designerMapper = designerMapper;
|
||||||
|
this.orderItemImageMapper = orderItemImageMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,6 +172,11 @@ public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, Listi
|
|||||||
|
|
||||||
Map<String, List<String>> imageMap = images.stream()
|
Map<String, List<String>> imageMap = images.stream()
|
||||||
.filter(img -> StringUtils.hasText(img.getCategory()))
|
.filter(img -> StringUtils.hasText(img.getCategory()))
|
||||||
|
// hasSelection == true 的类别只保留 isSelected == 1 的图片
|
||||||
|
.filter(img -> {
|
||||||
|
ImageCategoryEnum categoryEnum = ImageCategoryEnum.of(img.getCategory());
|
||||||
|
return categoryEnum == null || !categoryEnum.isHasSelection() || Integer.valueOf(1).equals(img.getIsSelected());
|
||||||
|
})
|
||||||
// 先按 category 分组,再按 sortOrder 组内排序,确保同组图片按 sortOrder 升序排列
|
// 先按 category 分组,再按 sortOrder 组内排序,确保同组图片按 sortOrder 升序排列
|
||||||
.sorted(Comparator.comparing(ListingImageEntity::getCategory)
|
.sorted(Comparator.comparing(ListingImageEntity::getCategory)
|
||||||
.thenComparing(ListingImageEntity::getSortOrder, Comparator.nullsLast(Comparator.naturalOrder())))
|
.thenComparing(ListingImageEntity::getSortOrder, Comparator.nullsLast(Comparator.naturalOrder())))
|
||||||
@@ -208,26 +219,21 @@ public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, Listi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getListingUrls(Long id) {
|
public List<String> getListingUrls(Long id, Long buyerId) {
|
||||||
List<ListingImageEntity> images = listingImageMapper.selectList(
|
List<OrderItemImageEntity> snapshots = orderItemImageMapper
|
||||||
new LambdaQueryWrapper<ListingImageEntity>()
|
.selectByListingIdAndBuyerIdWithOrderStatus(id, buyerId);
|
||||||
.eq(ListingImageEntity::getListingId, id)
|
|
||||||
.orderByAsc(ListingImageEntity::getSortOrder));
|
|
||||||
|
|
||||||
Map<String, List<String>> imageMap = images.stream()
|
if (snapshots.isEmpty()) {
|
||||||
.filter(img -> StringUtils.hasText(img.getCategory()))
|
throw new BusinessException("该商品尚未被购买,无法查看");
|
||||||
.sorted(Comparator.comparing(ListingImageEntity::getCategory)
|
}
|
||||||
.thenComparing(ListingImageEntity::getSortOrder, Comparator.nullsLast(Comparator.naturalOrder())))
|
|
||||||
.collect(Collectors.groupingBy(
|
|
||||||
ListingImageEntity::getCategory,
|
|
||||||
Collectors.mapping(ListingImageEntity::getImageUrl, Collectors.toList())
|
|
||||||
));
|
|
||||||
|
|
||||||
return imageMap.entrySet().stream()
|
return snapshots.stream()
|
||||||
.filter(entry -> !entry.getKey().equals("firstFrame") && !entry.getKey().equals("gif"))
|
.filter(img -> !ImageCategoryEnum.GIF.getCode().equals(img.getCategory())
|
||||||
.flatMap(entry -> entry.getValue().stream())
|
&& !ImageCategoryEnum.FIRST_FRAME.getCode().equals(img.getCategory())
|
||||||
.distinct()
|
&& !ImageCategoryEnum.VIDEO.getCode().equals(img.getCategory()))
|
||||||
.toList();
|
.sorted(Comparator.comparing(OrderItemImageEntity::getSortOrder, Comparator.nullsLast(Comparator.naturalOrder())))
|
||||||
|
.map(OrderItemImageEntity::getImageUrl)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.aida.seller.module.order.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单商品图片快照表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("seller_order_item_image")
|
||||||
|
public class OrderItemImageEntity implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 订单商品ID(关联 seller_order_item.id) */
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long orderItemId;
|
||||||
|
|
||||||
|
/** 订单ID */
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/** 原商品ID(留作参考) */
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long listingId;
|
||||||
|
|
||||||
|
/** 买家ID */
|
||||||
|
private Long buyerId;
|
||||||
|
|
||||||
|
/** 图片类别:cover / main_product / product / sketch / apparel / firstFrame / gif / video */
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/** 图片URL */
|
||||||
|
private String imageUrl;
|
||||||
|
|
||||||
|
/** 排序 */
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/** 是否删除:0-否,1-是 */
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.aida.seller.module.order.mapper;
|
||||||
|
|
||||||
|
import com.aida.seller.module.order.entity.OrderItemImageEntity;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单商品图片快照 Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderItemImageMapper extends BaseMapper<OrderItemImageEntity> {
|
||||||
|
|
||||||
|
List<OrderItemImageEntity> selectByListingIdAndBuyerIdWithOrderStatus(
|
||||||
|
@Param("listingId") Long listingId,
|
||||||
|
@Param("buyerId") Long buyerId);
|
||||||
|
}
|
||||||
@@ -6,6 +6,9 @@ import com.aida.seller.common.exception.BusinessException;
|
|||||||
import com.aida.seller.module.designer.entity.DesignerEntity;
|
import com.aida.seller.module.designer.entity.DesignerEntity;
|
||||||
import com.aida.seller.module.designer.mapper.DesignerMapper;
|
import com.aida.seller.module.designer.mapper.DesignerMapper;
|
||||||
import com.aida.seller.module.listing.entity.ListingEntity;
|
import com.aida.seller.module.listing.entity.ListingEntity;
|
||||||
|
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
||||||
|
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
||||||
|
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
||||||
import com.aida.seller.module.listing.mapper.ListingMapper;
|
import com.aida.seller.module.listing.mapper.ListingMapper;
|
||||||
import com.aida.seller.module.order.dto.AssetsDTO;
|
import com.aida.seller.module.order.dto.AssetsDTO;
|
||||||
import com.aida.seller.module.order.dto.CreateOrderDTO;
|
import com.aida.seller.module.order.dto.CreateOrderDTO;
|
||||||
@@ -14,7 +17,9 @@ import com.aida.seller.module.order.dto.UpdateOrderStatusDTO;
|
|||||||
import com.aida.seller.module.order.dto.BuyerOrdersDTO;
|
import com.aida.seller.module.order.dto.BuyerOrdersDTO;
|
||||||
import com.aida.seller.module.order.entity.OrderInfoEntity;
|
import com.aida.seller.module.order.entity.OrderInfoEntity;
|
||||||
import com.aida.seller.module.order.entity.OrderItemEntity;
|
import com.aida.seller.module.order.entity.OrderItemEntity;
|
||||||
|
import com.aida.seller.module.order.entity.OrderItemImageEntity;
|
||||||
import com.aida.seller.module.order.mapper.OrderInfoMapper;
|
import com.aida.seller.module.order.mapper.OrderInfoMapper;
|
||||||
|
import com.aida.seller.module.order.mapper.OrderItemImageMapper;
|
||||||
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
||||||
import com.aida.seller.module.order.vo.AssetsItemVO;
|
import com.aida.seller.module.order.vo.AssetsItemVO;
|
||||||
import com.aida.seller.module.order.vo.BuyerOrderItemVO;
|
import com.aida.seller.module.order.vo.BuyerOrderItemVO;
|
||||||
@@ -51,6 +56,8 @@ import java.util.stream.Collectors;
|
|||||||
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfoEntity> implements OrderService {
|
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfoEntity> implements OrderService {
|
||||||
|
|
||||||
private final OrderItemMapper orderItemMapper;
|
private final OrderItemMapper orderItemMapper;
|
||||||
|
private final OrderItemImageMapper orderItemImageMapper;
|
||||||
|
private final ListingImageMapper listingImageMapper;
|
||||||
private final MinioUtil minioUtil;
|
private final MinioUtil minioUtil;
|
||||||
private final ListingMapper listingMapper;
|
private final ListingMapper listingMapper;
|
||||||
private final DesignerMapper designerMapper;
|
private final DesignerMapper designerMapper;
|
||||||
@@ -283,6 +290,30 @@ public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||||||
item.setPrice(listing.getPrice());
|
item.setPrice(listing.getPrice());
|
||||||
item.setProductCategory(listing.getProductCategory());
|
item.setProductCategory(listing.getProductCategory());
|
||||||
orderItemMapper.insert(item);
|
orderItemMapper.insert(item);
|
||||||
|
|
||||||
|
List<ListingImageEntity> images = listingImageMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<ListingImageEntity>()
|
||||||
|
.eq(ListingImageEntity::getListingId, listing.getId()));
|
||||||
|
List<OrderItemImageEntity> snapshots = images.stream()
|
||||||
|
.filter(img -> {
|
||||||
|
ImageCategoryEnum categoryEnum = ImageCategoryEnum.of(img.getCategory());
|
||||||
|
return categoryEnum == null || !categoryEnum.isHasSelection() || Integer.valueOf(1).equals(img.getIsSelected());
|
||||||
|
})
|
||||||
|
.map(img -> {
|
||||||
|
OrderItemImageEntity snap = new OrderItemImageEntity();
|
||||||
|
snap.setOrderItemId(item.getId());
|
||||||
|
snap.setOrderId(order.getId());
|
||||||
|
snap.setListingId(listing.getId());
|
||||||
|
snap.setBuyerId(dto.getBuyerId());
|
||||||
|
snap.setCategory(img.getCategory());
|
||||||
|
snap.setImageUrl(img.getImageUrl());
|
||||||
|
snap.setSortOrder(img.getSortOrder());
|
||||||
|
return snap;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!snapshots.isEmpty()) {
|
||||||
|
orderItemImageMapper.insert(snapshots);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
orderIds.add(order.getId());
|
orderIds.add(order.getId());
|
||||||
|
|||||||
@@ -97,3 +97,18 @@ CREATE TABLE seller_order_item (
|
|||||||
INDEX idx_listing_id (listing_id),
|
INDEX idx_listing_id (listing_id),
|
||||||
INDEX idx_deleted (deleted)
|
INDEX idx_deleted (deleted)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品明细表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品明细表';
|
||||||
|
|
||||||
|
-- 订单商品图片快照表
|
||||||
|
CREATE TABLE seller_order_item_image (
|
||||||
|
id BIGINT PRIMARY KEY COMMENT '主键ID',
|
||||||
|
order_item_id BIGINT NOT NULL COMMENT '订单商品ID',
|
||||||
|
order_id BIGINT COMMENT '订单ID',
|
||||||
|
listing_id BIGINT COMMENT '原商品ID',
|
||||||
|
buyer_id BIGINT COMMENT '买家ID',
|
||||||
|
category VARCHAR(32) COMMENT '图片类别',
|
||||||
|
image_url VARCHAR(512) COMMENT '图片URL',
|
||||||
|
sort_order INT DEFAULT 0 COMMENT '排序',
|
||||||
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
deleted INT(1) DEFAULT 0 COMMENT '是否删除:0-否,1-是',
|
||||||
|
INDEX idx_listing_buyer (listing_id, buyer_id)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品图片快照表';
|
||||||
|
|||||||
Reference in New Issue
Block a user