You've already forked FrameTour-BE
feat(videoreview): 添加视频购买状态检查功能
- 在VideoReviewController中新增/check-purchase接口用于检查视频是否被购买 - 扩展OrderMapper接口,增加根据视频ID和模板ID查询订单ID的方法 - 在VideoReviewServiceImpl中实现checkVideoPurchase方法,支持两种购买方式判断 - 完善相关DTO类引入及Mapper XML配置文件的SQL查询逻辑 - 实现直接购买视频和通过模板购买的双重购买状态检测机制 - 添加详细的日志记录便于后续追踪与调试
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package com.ycwl.basic.controller;
|
package com.ycwl.basic.controller;
|
||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
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.VideoReviewAddReqDTO;
|
||||||
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
|
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
|
||||||
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
|
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
|
||||||
@@ -91,4 +93,20 @@ public class VideoReviewController {
|
|||||||
throw new RuntimeException("导出失败: " + e.getMessage());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.OrderAppRespVO;
|
||||||
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
|
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -61,4 +62,19 @@ public interface OrderMapper {
|
|||||||
List<OrderItemEntity> getOrderItems(Long orderId);
|
List<OrderItemEntity> getOrderItems(Long orderId);
|
||||||
|
|
||||||
OrderEntity getUserBuyFaceItem(Long memberId, Long faceId, int goodsType, Long goodsId);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.ycwl.basic.model.pc.videoreview.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频购买检查请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VideoPurchaseCheckReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频ID
|
||||||
|
*/
|
||||||
|
private Long videoId;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.ycwl.basic.service;
|
package com.ycwl.basic.service;
|
||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
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.VideoReviewAddReqDTO;
|
||||||
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
|
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewListReqDTO;
|
||||||
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
|
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewRespDTO;
|
||||||
@@ -45,4 +47,15 @@ public interface VideoReviewService {
|
|||||||
* @throws IOException IO异常
|
* @throws IOException IO异常
|
||||||
*/
|
*/
|
||||||
void exportReviews(VideoReviewListReqDTO reqDTO, OutputStream outputStream) throws IOException;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ import com.github.pagehelper.PageInfo;
|
|||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
import com.ycwl.basic.exception.BaseException;
|
import com.ycwl.basic.exception.BaseException;
|
||||||
import com.ycwl.basic.exception.BizException;
|
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.VideoMapper;
|
||||||
import com.ycwl.basic.mapper.VideoReviewMapper;
|
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.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.repository.DeviceRepository;
|
||||||
import com.ycwl.basic.model.pc.videoreview.dto.VideoReviewAddReqDTO;
|
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.VideoReviewListReqDTO;
|
||||||
@@ -48,6 +54,12 @@ public class VideoReviewServiceImpl implements VideoReviewService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DeviceRepository deviceRepository;
|
private DeviceRepository deviceRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrderMapper orderMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TaskMapper taskMapper;
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -274,6 +286,60 @@ public class VideoReviewServiceImpl implements VideoReviewService {
|
|||||||
log.info("导出视频评价数据成功,共{}条,机位数:{}", list.size(), sortedDeviceIds.size());
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算各机位的平均评分
|
* 计算各机位的平均评分
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -554,4 +554,23 @@
|
|||||||
set member_id = #{memberId}
|
set member_id = #{memberId}
|
||||||
where face_id = #{faceId}
|
where face_id = #{faceId}
|
||||||
</update>
|
</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>
|
</mapper>
|
||||||
Reference in New Issue
Block a user