播放记录设计与开发
表设计
play_record
CREATE TABLE `play_record` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`video_id` int(11) DEFAULT NULL,
`current_num` int(11) DEFAULT NULL COMMENT '当前播放第几集',
`episode_id` int(11) DEFAULT NULL COMMENT '当前播放第几集视频id',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Model
package net.xdclass.online_xdclass.model.entity;
import java.util.Date;
/**
* 小滴课堂 播放记录
*
* `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
* `user_id` int(11) DEFAULT NULL,
* `video_id` int(11) DEFAULT NULL,
* `current_num` int(11) DEFAULT NULL COMMENT '当前播放第几集',
* `episode_id` int(11) DEFAULT NULL COMMENT '当前播放第几集视频id',
* `create_time` datetime DEFAULT NULL,
*/
public class PlayRecord {
private Integer id;
private Integer userId;
private Integer videoId;
private Integer currentNum;
private Integer episodeId;
private Date createTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getVideoId() {
return videoId;
}
public void setVideoId(Integer videoId) {
this.videoId = videoId;
}
public Integer getCurrentNum() {
return currentNum;
}
public void setCurrentNum(Integer currentNum) {
this.currentNum = currentNum;
}
public Integer getEpisodeId() {
return episodeId;
}
public void setEpisodeId(Integer episodeId) {
this.episodeId = episodeId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
Mapper
查找指定video的第一集
interface
package net.xdclass.online_xdclass.mapper;
import net.xdclass.online_xdclass.model.entity.Episode;
import org.apache.ibatis.annotations.Param;
public interface EpisodeMapper {
Episode findFirstEpisodeByVideoId(@Param("video_id") int videoId);
}
Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="net.xdclass.online_xdclass.mapper.EpisodeMapper">
<select id="findFirstEpisodeByVideoId" resultType="Episode">
select * from episode where video_id = #{video_id} and num = 1
</select>
</mapper>
interface
package net.xdclass.online_xdclass.mapper;
import net.xdclass.online_xdclass.model.entity.Episode;
import net.xdclass.online_xdclass.model.entity.PlayRecord;
import org.apache.ibatis.annotations.Param;
public interface PlayRecordMapper {
int saveRecord(PlayRecord playRecord);
}
Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="net.xdclass.online_xdclass.mapper.PlayRecordMapper">
<insert id="saveRecord" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO `play_record` ( `user_id`, `video_id`, `current_num`, `episode_id`, `create_time`)
VALUES (#{userId},#{videoId},#{currentNum},#{episodeId},#{createTime});
</insert>
</mapper>
整合用户下单接口
package net.xdclass.online_xdclass.service.impl;
import net.xdclass.online_xdclass.exception.XDException;
import net.xdclass.online_xdclass.mapper.*;
import net.xdclass.online_xdclass.model.entity.Episode;
import net.xdclass.online_xdclass.model.entity.PlayRecord;
import net.xdclass.online_xdclass.model.entity.Video;
import net.xdclass.online_xdclass.model.entity.VideoOrder;
import net.xdclass.online_xdclass.model.request.VideoOrderRequest;
import net.xdclass.online_xdclass.service.VideoOrderService;
import net.xdclass.online_xdclass.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.UUID;
@Service
public class VideoOrderServiceImpl implements VideoOrderService {
@Autowired
private VideoOrderMapper videoOrderMapper;
@Autowired
private VideoMapper videoMapper;
@Autowired
private EpisodeMapper episodeMapper;
@Autowired
private PlayRecordMapper playRecordMapper;
/**
* 下单操作
* 未来版本:优惠券抵扣,风控用户检查,生成订单基础信息,生成支付信息
* @param userId
* @param videoId
* @return
*/
@Override
public int save(int userId, int videoId) {
//判断是否已经购买
VideoOrder videoOrder = videoOrderMapper.findByUserIdAndVideoIdAndState(userId,videoId,1);
if(videoOrder!=null){return 0;}
Video video = videoMapper.findById(videoId);
VideoOrder newVideoOrder = new VideoOrder();
newVideoOrder.setCreateTime(new Date());
newVideoOrder.setOutTradeNo(UUID.randomUUID().toString());
newVideoOrder.setState(1);
newVideoOrder.setTotalFee(video.getPrice());
newVideoOrder.setUserId(userId);
newVideoOrder.setVideoId(videoId);
newVideoOrder.setVideoImg(video.getCoverImg());
newVideoOrder.setVideoTitle(video.getTitle());
int rows = videoOrderMapper.saveOrder(newVideoOrder);
//生成播放记录
if(rows == 1){
Episode episode = episodeMapper.findFirstEpisodeByVideoId(videoId);
if(episode == null){
throw new XDException(-1,"视频没有集信息,请运营人员检查");
}
PlayRecord playRecord = new PlayRecord();
playRecord.setCreateTime(new Date());
playRecord.setEpisodeId(episode.getId());
playRecord.setCurrentNum(episode.getNum());
playRecord.setUserId(userId);
playRecord.setVideoId(videoId);
playRecordMapper.saveRecord(playRecord);
}
return rows;
}
}
测试
http://localhost:8081/api/v1/pri/order/save
POST Body-raw-JSON
{
"video_id":40
}
Headers
token
xdclasseyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4ZGNsYXNzIiwiaGVhZF9pbWciOiJodHRwczovL3hkLXZpZGVvLXBjLWltZy5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20veGRjbGFzc19wcm8vZGVmYXVsdC9oZWFkX2ltZy8xNS5qcGVnIiwiaWQiOjgsIm5hbWUiOiJhbGljZSIsImlhdCI6MTYxMDUwMzM5NSwiZXhwIjoxNjExMTA4MTk1fQ.Hru8k9bwXd32t2iQX-6br_30M-HwiYKVerfChv_Recw
播放记录和下单整合,开启事务控制
启动类 @EnableTransactionManagement
@SpringBootApplication
@MapperScan("net.xdclass.online_xdclass.mapper")
@EnableTransactionManagement
public class OnlineXdclassApplication {
public static void main(String[] args) {
SpringApplication.run(OnlineXdclassApplication.class, args);
}
}
业务类,或者业务方法 @Transactional
package net.xdclass.online_xdclass.service.impl;
import net.xdclass.online_xdclass.exception.XDException;
import net.xdclass.online_xdclass.mapper.*;
import net.xdclass.online_xdclass.model.entity.Episode;
import net.xdclass.online_xdclass.model.entity.PlayRecord;
import net.xdclass.online_xdclass.model.entity.Video;
import net.xdclass.online_xdclass.model.entity.VideoOrder;
import net.xdclass.online_xdclass.model.request.VideoOrderRequest;
import net.xdclass.online_xdclass.service.VideoOrderService;
import net.xdclass.online_xdclass.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
@Service
public class VideoOrderServiceImpl implements VideoOrderService {
@Autowired
private VideoOrderMapper videoOrderMapper;
@Autowired
private VideoMapper videoMapper;
@Autowired
private EpisodeMapper episodeMapper;
@Autowired
private PlayRecordMapper playRecordMapper;
/**
* 下单操作
* 未来版本:优惠券抵扣,风控用户检查,生成订单基础信息,生成支付信息
* @param userId
* @param videoId
* @return
*/
@Override
@Transactional
public int save(int userId, int videoId) {
//判断是否已经购买
VideoOrder videoOrder = videoOrderMapper.findByUserIdAndVideoIdAndState(userId,videoId,1);
if(videoOrder!=null){return 0;}
Video video = videoMapper.findById(videoId);
VideoOrder newVideoOrder = new VideoOrder();
newVideoOrder.setCreateTime(new Date());
newVideoOrder.setOutTradeNo(UUID.randomUUID().toString());
newVideoOrder.setState(1);
newVideoOrder.setTotalFee(video.getPrice());
newVideoOrder.setUserId(userId);
newVideoOrder.setVideoId(videoId);
newVideoOrder.setVideoImg(video.getCoverImg());
newVideoOrder.setVideoTitle(video.getTitle());
int rows = videoOrderMapper.saveOrder(newVideoOrder);
//生成播放记录
if(rows == 1){
Episode episode = episodeMapper.findFirstEpisodeByVideoId(videoId);
if(episode == null){
throw new XDException(-1,"视频没有集信息,请运营人员检查");
}
PlayRecord playRecord = new PlayRecord();
playRecord.setCreateTime(new Date());
playRecord.setEpisodeId(episode.getId());
playRecord.setCurrentNum(episode.getNum());
playRecord.setUserId(userId);
playRecord.setVideoId(videoId);
playRecordMapper.saveRecord(playRecord);
}
return rows;
}
}
订单列表接口
/**
* 订单列表
* @param request
* @return
*/
@GetMapping("list")
public JsonData listOrder(HttpServletRequest request){
Integer userId = (Integer) request.getAttribute("user_id");
List<VideoOrder> videoOrderList = videoOrderService.listOrderByUserId(userId);
return JsonData.buildSuccess(videoOrderList);
}
<select id="listOrderByUserId" resultType="VideoOrder">
select * from video_order where user_id=#{user_id} order by create_time desc
</select>