feat(videoreview): 添加视频购买状态检查功能

- 在VideoReviewController中新增/check-purchase接口用于检查视频是否被购买
- 扩展OrderMapper接口,增加根据视频ID和模板ID查询订单ID的方法
- 在VideoReviewServiceImpl中实现checkVideoPurchase方法,支持两种购买方式判断
- 完善相关DTO类引入及Mapper XML配置文件的SQL查询逻辑
- 实现直接购买视频和通过模板购买的双重购买状态检测机制
- 添加详细的日志记录便于后续追踪与调试
This commit is contained in:
2025-12-15 14:55:30 +08:00
parent adabe88648
commit 0665eef37d
7 changed files with 174 additions and 0 deletions

View File

@@ -1,6 +1,8 @@
package com.ycwl.basic.controller;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckRespDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewAddReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
@@ -91,4 +93,20 @@ public class VideoReviewController {
throw new RuntimeException("导出失败: " + e.getMessage());
}
}
/**
* 检查视频是否已被购买
* 购买条件:
* 1. 直接购买视频(order_item中goods_type=0且goods_id=视频id)
* 2. 购买整个模板(order的face_id与video关联的task的face_id相同,goods_type=-1,goods_id为video的templateId)
*
* @param reqDTO 查询条件
* @return 购买状态及订单ID列表
*/
@PostMapping("/check-purchase")
public ApiResponse<VideoPurchaseCheckRespDTO> checkVideoPurchase(@RequestBody VideoPurchaseCheckReqDTO reqDTO) {
log.info("检查视频购买状态,videoId: {}", reqDTO.getVideoId());
VideoPurchaseCheckRespDTO respDTO = videoReviewService.checkVideoPurchase(reqDTO);
return ApiResponse.success(respDTO);
}
}

View File

@@ -9,6 +9,7 @@ import com.ycwl.basic.model.pc.order.req.OrderReqQuery;
import com.ycwl.basic.model.pc.order.resp.OrderAppRespVO;
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -61,4 +62,19 @@ public interface OrderMapper {
List<OrderItemEntity> getOrderItems(Long orderId);
OrderEntity getUserBuyFaceItem(Long memberId, Long faceId, int goodsType, Long goodsId);
/**
* 查询购买了指定视频的所有订单ID(直接购买)
* @param videoId 视频ID
* @return 订单ID列表
*/
List<Long> getOrderIdsByVideoId(Long videoId);
/**
* 查询购买了指定模板和faceId的所有订单ID
* @param faceId 人脸ID
* @param templateId 模板ID
* @return 订单ID列表
*/
List<Long> getOrderIdsByFaceIdAndTemplateId(@Param("faceId") Long faceId, @Param("templateId") Long templateId);
}

View File

@@ -0,0 +1,15 @@
package com.ycwl.basic.model.pc.videoreview.dto;
import lombok.Data;
/**
* 视频购买检查请求DTO
*/
@Data
public class VideoPurchaseCheckReqDTO {
/**
* 视频ID
*/
private Long videoId;
}

View File

@@ -0,0 +1,27 @@
package com.ycwl.basic.model.pc.videoreview.dto;
import lombok.Data;
import java.util.List;
/**
* 视频购买检查响应DTO
*/
@Data
public class VideoPurchaseCheckRespDTO {
/**
* 视频ID
*/
private Long videoId;
/**
* 是否已被购买
*/
private Boolean isPurchased;
/**
* 购买该视频的订单ID列表(包括直接购买和通过模板购买)
*/
private List<Long> orderIds;
}

View File

@@ -1,6 +1,8 @@
package com.ycwl.basic.service;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckRespDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewAddReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
@@ -45,4 +47,15 @@ public interface VideoReviewService {
* @throws IOException IO异常
*/
void exportReviews(VideoReviewListReqDTO reqDTO, OutputStream outputStream) throws IOException;
/**
* 检查视频是否已被购买
* 购买条件:
* 1. 直接购买视频(order_item中goods_type=0且goods_id=视频id)
* 2. 购买整个模板(order的face_id与video关联的task的face_id相同,goods_type=-1,goods_id为video的templateId)
*
* @param reqDTO 查询条件
* @return 购买状态及订单ID列表
*/
VideoPurchaseCheckRespDTO checkVideoPurchase(VideoPurchaseCheckReqDTO reqDTO);
}

View File

@@ -7,9 +7,15 @@ import com.github.pagehelper.PageInfo;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.exception.BaseException;
import com.ycwl.basic.exception.BizException;
import com.ycwl.basic.mapper.OrderMapper;
import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.mapper.VideoReviewMapper;
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoPurchaseCheckRespDTO;
import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewAddReqDTO;
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
@@ -48,6 +54,12 @@ public class VideoReviewServiceImpl implements VideoReviewService {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private OrderMapper orderMapper;
@Autowired
private TaskMapper taskMapper;
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
@@ -274,6 +286,60 @@ public class VideoReviewServiceImpl implements VideoReviewService {
log.info("导出视频评价数据成功,共{}条,机位数:{}", list.size(), sortedDeviceIds.size());
}
@Override
public VideoPurchaseCheckRespDTO checkVideoPurchase(VideoPurchaseCheckReqDTO reqDTO) {
// 参数校验
if (reqDTO.getVideoId() == null) {
throw new BaseException("视频ID不能为空");
}
Long videoId = reqDTO.getVideoId();
// 查询视频信息
VideoEntity video = videoMapper.getEntity(videoId);
if (video == null) {
throw new BaseException("视频不存在");
}
VideoPurchaseCheckRespDTO respDTO = new VideoPurchaseCheckRespDTO();
respDTO.setVideoId(videoId);
List<Long> allOrderIds = new ArrayList<>();
// 情况1:直接购买视频的订单(goods_type=0, goods_id=视频id)
List<Long> directOrderIds = orderMapper.getOrderIdsByVideoId(videoId);
if (directOrderIds != null && !directOrderIds.isEmpty()) {
allOrderIds.addAll(directOrderIds);
log.info("视频[{}]直接购买订单数: {}", videoId, directOrderIds.size());
}
// 情况2:通过购买模板间接拥有(goods_type=-1, goods_id=templateId)
// 需要通过video的taskId找到task,再通过task的faceId查询购买模板的订单
if (video.getTaskId() != null && video.getTemplateId() != null) {
TaskEntity task = taskMapper.get(video.getTaskId());
if (task != null && task.getFaceId() != null) {
List<Long> templateOrderIds = orderMapper.getOrderIdsByFaceIdAndTemplateId(
task.getFaceId(),
video.getTemplateId()
);
if (templateOrderIds != null && !templateOrderIds.isEmpty()) {
allOrderIds.addAll(templateOrderIds);
log.info("视频[{}]通过模板[{}]购买订单数: {}, faceId: {}",
videoId, video.getTemplateId(), templateOrderIds.size(), task.getFaceId());
}
}
}
respDTO.setOrderIds(allOrderIds);
respDTO.setIsPurchased(!allOrderIds.isEmpty());
log.info("视频[{}]购买检查完成,是否被购买: {}, 总订单数: {}",
videoId, respDTO.getIsPurchased(), allOrderIds.size());
return respDTO;
}
/**
* 计算各机位的平均评分
*/

View File

@@ -554,4 +554,23 @@
set member_id = #{memberId}
where face_id = #{faceId}
</update>
<select id="getOrderIdsByVideoId" resultType="java.lang.Long">
select distinct o.id
from order_item oi
left join `order` o on o.id = oi.order_id
where oi.goods_id = #{videoId}
and oi.goods_type = 0
and o.status = 1
and o.refund_status = 0
</select>
<select id="getOrderIdsByFaceIdAndTemplateId" resultType="java.lang.Long">
select distinct o.id
from order_item oi
left join `order` o on o.id = oi.order_id
where o.face_id = #{faceId}
and oi.goods_id = #{templateId}
and oi.goods_type = -1
and o.status = 1
and o.refund_status = 0
</select>
</mapper>