创建仓库

This commit is contained in:
zw
2025-08-01 13:59:30 +08:00
parent 7f6dbe8feb
commit 4c0d5dbd75
85 changed files with 3219 additions and 0 deletions

View File

@@ -0,0 +1,326 @@
package vvpkassistant.pk;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import vvpkassistant.CoinRecords.CoinRecords;
import vvpkassistant.CoinRecords.CoinRecordsDao;
import vvpkassistant.Data.ResponseData;
import vvpkassistant.Data.ResponseInfo;
import vvpkassistant.FunctionConfig.FunctionConfigHolder;
import vvpkassistant.Tools.VVTools;
import vvpkassistant.User.UserDao;
import vvpkassistant.User.UserModel;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("pk")
public class PkController {
@Autowired
private PkInfoDao pkDao;
@Autowired
private PkRecordDao recordDao;
@Autowired
private PkRecordDetailDao detailDao;
@Autowired
private UserDao userDao;
@Autowired
private CoinRecordsDao coinRecordsDao;
// 创建pk数据
@PostMapping("addPkData")
public ResponseData<Object> addPkData(@RequestBody PkInfoModel pkModel) {
// 初始可邀请状态为0
pkModel.setInviteStatus(0);
pkModel.setPinExpireTime(0);
// 获取主播id
String anchorId = pkModel.getAnchorId();
// 查询当天是否存在该主播发布的pk信息。
Integer pkTime = pkModel.getPkTime();
// 根据设置的pk时间。查询出当天的开始时间和结束时间
Map<String, Long> dayStartAndEndTimestamp = VVTools.getDayStartAndEndTimestamp(pkTime);
Long start = dayStartAndEndTimestamp.get("start");
Long end = dayStartAndEndTimestamp.get("end");
// 查询主播在当天是否有发布过pk信息
List<PkInfoModel> pkInfoModels = pkDao.selectDataWithAnchorIdAndTime(anchorId, start, end);
// 判断该主播在当日是否已发布过pk信息
if (pkInfoModels.size() > 0) {
return ResponseData.error(ResponseInfo.ERROR,"该主播当日已有pk信息");
}
int insert = pkDao.insert(pkModel);
return insert == 1 ? ResponseData.success(pkModel) : ResponseData.error(ResponseInfo.ERROR,null);
}
// 更新pk信息
@PostMapping("updatePkStatus")
public ResponseData<Object> updatePkStatus(@RequestBody PkRecord recordModel) {
//如果是同意了pk邀请、则更新已发布的主播pk可邀请状态
if (recordModel.getPkStatus() == 1) {
// 查询出记录信息
PkRecord pkRecordById = recordDao.singleRecord(recordModel.getId());
// 更新可邀请状态
PkInfoModel pkInfoModelA = pkDao.selectById(pkRecordById.getPkIdA());
pkInfoModelA.setInviteStatus(1);
PkInfoModel pkInfoModelB = pkDao.selectById(pkRecordById.getPkIdB());
pkInfoModelB.setInviteStatus(1);
pkDao.updateById(pkInfoModelA);
pkDao.updateById(pkInfoModelB);
// 如果有置顶的状态。需要取消置顶
if (pkInfoModelA.getPinExpireTime() > VVTools.currentTimeStamp()) {
long hour = VVTools.calculateHoursFloor(pkInfoModelA.getPinExpireTime(),VVTools.currentTimeStamp());
int coin = Integer.parseInt(FunctionConfigHolder.getValue("置顶扣除积分"));
int totalCoin = (int) (coin * hour);
// 插入记录
CoinRecords coinRecords = new CoinRecords("成功预约pk自动取消置顶", pkInfoModelA.getSenderId(),totalCoin, (int) VVTools.currentTimeStamp(),1);
coinRecordsDao.insert(coinRecords);
// 更新积分
UserModel userModel = userDao.selectById(pkRecordById.getUserIdA());
Integer points = userModel.getPoints();
userModel.setPoints(points + totalCoin);
}
if (pkInfoModelB.getPinExpireTime() > VVTools.currentTimeStamp()) {
long hour = VVTools.calculateHoursFloor(pkInfoModelB.getPinExpireTime(),VVTools.currentTimeStamp());
int coin = Integer.parseInt(FunctionConfigHolder.getValue("置顶扣除积分"));
int totalCoin = (int) (coin * hour);
// 插入记录
CoinRecords coinRecords = new CoinRecords("成功预约pk自动取消置顶", pkInfoModelB.getSenderId(),totalCoin, (int) VVTools.currentTimeStamp(),1);
coinRecordsDao.insert(coinRecords);
// 更新积分
UserModel userModel = userDao.selectById(pkRecordById.getUserIdB());
Integer points = userModel.getPoints();
userModel.setPoints(points + totalCoin);
}
}
// 更新pk邀请记录
int update = recordDao.updateById(recordModel);
return update == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR,null);
}
// 创建PK记录
@PostMapping("createPkRecord")
public ResponseData<Object> createPkRecord(@RequestBody PkRecord record) {
// 如果这两个邀约直播之间存在未处理的邀请记录。那就不允许继续发送pk邀请
String anchorIdA = record.getAnchorIdA();
String anchorIdB = record.getAnchorIdB();
Integer dataCount = recordDao.getPendingInvitations(anchorIdA, anchorIdB);
if (dataCount > 0) {
return ResponseData.error(ResponseInfo.ERROR,"已存在一条未处理的pk申请不能重复发送");
}
record.setPkStatus(0);
int insert = recordDao.insert(record);
return insert == 1 ? ResponseData.success(record) : ResponseData.error(ResponseInfo.ERROR,null);
}
// pk列表
@PostMapping("pkList")
public ResponseData<Object> pkList(@RequestBody Map<String,Object> map) {
Integer page = (Integer) map.get("page");
Integer size = (Integer) map.get("size");
Map<String,Object> condition = (Map<String, Object>) map.get("condition");
Map<String, Long> todayTimeStampMap = VVTools.startAndEndTimeStampForToday();
Long start = VVTools.currentTimeStamp();
Long end = todayTimeStampMap.get("end");
List<PkInfoModel> pkModels = pkDao.selectPkInfoByCondition(page * size, size, condition, start, end);
long currentTimeStamp = VVTools.currentTimeStamp();
//如果传了用户id
if (map.containsKey("userId")) {
Long begin = VVTools.currentTimeStamp();
Integer userId = Integer.valueOf(map.get("userId").toString());
// 查询出当前用户大于等于今天的已接受邀请的pk数据
List<PkRecord> pkRecords = recordDao.fetchDataFromTodayWithUserId(userId, begin);
// 遍历查询出的数据。如果文章的id相同。就显示完整的主播名称
for (PkInfoModel pkModel : pkModels) {
pkModel.setDisPlayId(pkModel.getAnchorId());
// 设置是否为置顶
pkModel.setIsPin(pkModel.getPinExpireTime() > currentTimeStamp);
// 如果文章的发布者不是当前登录主播。
if (pkModel.getSenderId().intValue() != userId) {
boolean showId = false;
// 查找是否和当前登录的账号有pk关系。
for (PkRecord pkRecord : pkRecords) {
// 如果当前用户是邀请pk的并且对方已接受pk也可以看到主播id
if (pkRecord.getUserIdB().intValue() == userId &&
pkRecord.getPkIdA().intValue() == pkModel.getId().intValue() &&
pkRecord.getPkStatus() == 1) {
showId = true;
break;
}
}
// 条件不满足则隐藏主播id'
if (!showId) {
pkModel.setDisPlayId(VVTools.replaceChar(pkModel.getAnchorId(), '*'));
}
}
}
}else{
for (PkInfoModel pkModel : pkModels) {
// 设置是否为置顶
pkModel.setIsPin(pkModel.getPinExpireTime() > currentTimeStamp);
pkModel.setDisPlayId(VVTools.replaceChar(pkModel.getAnchorId(), '*'));
}
}
return ResponseData.success(pkModels);
}
// 查询用户发布的大于当前时间的pk数据
@PostMapping("queryMyCanUsePkData")
public ResponseData<Object> queryMyCanUsePkData(@RequestBody Map<String,Object> map) {
Long time = VVTools.currentTimeStamp();
Integer userId = (Integer) map.get("userId");
List<PkInfoModel> pkModels = pkDao.queryCanUseData(userId, time);
return ResponseData.success(pkModels);
}
//pk文章详情
@PostMapping("pkInfoDetail")
public ResponseData<Object> pkInfoDetail(@RequestBody Map<String, Integer> map) {
Integer id = map.get("id");
Integer userId = map.get("userId");
Integer from = map.get("from"); // 1 首页 2 聊天
PkInfoModel pkInfoModel = pkDao.selectById(id);
if (pkInfoModel == null) {
return ResponseData.error(ResponseInfo.ERROR,"该信息不存在");
}
if (from == 1) {
if (pkInfoModel.getPkTime() > VVTools.currentTimeStamp()) {
// 判断是否是自己发布的数据 如果不是就隐藏主播id
if (pkInfoModel.getSenderId().equals(userId)) {
pkInfoModel.setDisPlayId(pkInfoModel.getAnchorId());
} else {
// 查询是否存在未完成的pk记录
Integer isHave = pkDao.checkIfUnfinishedPKExistsWithAnchor(userId, pkInfoModel.getAnchorId());
if (isHave > 0) {
pkInfoModel.setDisPlayId(pkInfoModel.getAnchorId());
}else {
pkInfoModel.setDisPlayId(VVTools.replaceChar(pkInfoModel.getAnchorId(), '*'));
}
}
return ResponseData.success(pkInfoModel);
}else {
return ResponseData.error(ResponseInfo.ERROR,"当前信息已无效");
}
}else{
Integer isHave = pkDao.checkIfUnfinishedPKExistsWithAnchor(userId, pkInfoModel.getAnchorId());
if (isHave > 0) {
pkInfoModel.setDisPlayId(pkInfoModel.getAnchorId());
}else {
pkInfoModel.setDisPlayId(VVTools.replaceChar(pkInfoModel.getAnchorId(), '*'));
}
return ResponseData.success(pkInfoModel);
}
}
//删除自己的pk数据 (单个)
@PostMapping("deletePkDataWithId")
public ResponseData<Object> deletePkDataWithId(@RequestBody Map<String,Integer> map) {
Integer id = map.get("id");
PkInfoModel pkInfoModel = pkDao.selectById(id);
if (pkInfoModel.getPinExpireTime() > VVTools.currentTimeStamp()) {
return ResponseData.error(ResponseInfo.ERROR,"该信息在置顶中。如要删除清先取消置顶");
}
Integer result = pkDao.deletePkDataWithId(id);
return result == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR,"删除数据失败");
}
//修改pk信息内容
@PostMapping("updatePkInfoById")
public ResponseData<Object> updatePkInfoById(@RequestBody PkInfoModel infoModel) {
int result = pkDao.updateById(infoModel);
return result == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR,null);
}
// 根据id查询pk记录
@PostMapping("singleRecord")
public ResponseData<Object> singleRecord(@RequestBody PkRecord record) {
PkRecord data = recordDao.singleRecord(record.getId());
return ResponseData.success(data);
}
// 查询pk中每个场次的详细数据
@PostMapping("fetchDetailPkDataWithId")
public ResponseData<Object> fetchDetailPkDataWithId(@RequestBody Map<String,Integer> map) {
Integer id = map.get("id");
List<PkRecordDetail> pkRecordDetails = recordDao.fetchDetailPkDataWithId(id);
return ResponseData.success(pkRecordDetails);
}
// 根据用户id查询该用户已发布的未被邀请的主播列表
@PostMapping("listUninvitedPublishedAnchorsByUserId")
public ResponseData<Object> listUninvitedPublishedAnchorsByUserId(@RequestBody Map<String,Integer> map) {
Integer userId = map.get("userId");
List<PkInfoModel> pkInfoModels = pkDao.listUninvitedPublishedAnchorsByUserId(userId);
for (PkInfoModel pkInfoModel : pkInfoModels) {
pkInfoModel.setDisPlayId(VVTools.replaceChar(pkInfoModel.getAnchorId(),'*'));
}
return ResponseData.success(pkInfoModels);
}
/************************************************************************************************************************************/
/** Python 相关接口 */
/************************************************************************************************************************************/
// Python那边需要的pk数据
@PostMapping("pkListForPython")
public ResponseData<Object> pkDataListForPython() {
// 获取当日的开始时间和结束时间
Map<String, Long> timeMap = VVTools.startAndEndTimeStampForToday();
long start = timeMap.get("start");
long end = timeMap.get("end");
List<PkRecord> result = recordDao.pkListForToday(start, end);
return ResponseData.success(result);
}
// 更新pk结果信息
@PostMapping("updatePkRecordInfo")
public ResponseData<Object> updatePkRecordInfo(@RequestBody PkRecord record) {
int i = recordDao.updateById(record);
return i == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR,null);
}
// 插入pk明细表数据
@PostMapping("insertPkDetail")
public ResponseData<Object> insert(@RequestBody PkRecordDetail detail) {
detail.setCreateTime(VVTools.currentTimeStamp());
int insert = detailDao.insert(detail);
return insert == 1 ? ResponseData.success("") : ResponseData.error(ResponseInfo.ERROR,null);
}
}

View File

@@ -0,0 +1,77 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.*;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
@Mapper
public interface PkInfoDao extends BaseMapper<PkInfoModel> {
//根据条件筛选pk列表数据
@Select("<script>" +
"SELECT * FROM pk_info " +
"WHERE 1=1 " +
" <if test='condition.sex != null'> AND sex = #{condition.sex} </if>" + // 性别筛选
" <if test='condition.coin != null'> " + // 金币筛选
" AND coin BETWEEN #{condition.coin.start} AND #{condition.coin.end} " +
" </if>" +
" <if test='condition.country != null'> AND country = #{condition.country} </if>" +
" <if test='condition.pkTime != null'> " + // pk时间筛选
" AND pk_time BETWEEN #{condition.pkTime.start} AND #{condition.pkTime.end} " +
" </if>" +
" <if test='condition.type == 1'> " + // 当天时间
" AND pk_time BETWEEN #{todayStart} AND #{todayEnd}" +
" </if>" +
" <if test='condition.type == 2'> " + // 大于当天
" AND pk_time > #{todayEnd}" +
" </if>" +
" AND invite_status = 0 " +
"ORDER BY pin_expire_time > UNIX_TIMESTAMP() DESC, " +
"CASE WHEN pin_expire_time > UNIX_TIMESTAMP() THEN pin_create_time ELSE NULL END ASC, " +
"id DESC " +
"LIMIT #{page} , #{size}" +
"</script>")
List<PkInfoModel> selectPkInfoByCondition(
@Param("page") int page,
@Param("size") int size,
@Param("condition") Map<String, Object> condition,
@Param("todayStart") long todayStart, // 当天开始时间戳00:00:00
@Param("todayEnd") long todayEnd // 当天结束时间戳23:59:59
);
// 查询用户发布的大于当前时间的pk数据
@Select("select * from pk_info where #{userId} = sender_id and #{time} <= pk_time and invite_status = 0;")
List<PkInfoModel> queryCanUseData(@Param("userId") Integer userId , @Param("time") Long time);
// 查询用户发布的所有pk数据
@Select("select * from pk_info where sender_id = #{userId} order by id desc limit #{page}, #{size};")
List<PkInfoModel> queryAllPkData(@Param("userId") Integer userId, @Param("page") Integer page, @Param("size") Integer size);
// 根据id删除pk信息
@Delete("delete from pk_info where id = #{id}")
Integer deletePkDataWithId(@Param("id") Integer id);
//查询制定时间范围制定主播的pk信息
@Select("select * from pk_info where anchor_id = #{anchorId} and pk_time between #{startTime} and #{endTime}")
List<PkInfoModel> selectDataWithAnchorIdAndTime(@Param("anchorId") String anchorId, @Param("startTime") long startTime , @Param("endTime") long endTime);
// 置顶和取消置顶
@Update("update pk_info set pin_expire_time = #{time} where id = #{id}")
int setPinTime(@Param("id") Integer id, @Param("time") @Nullable Integer time);
// 根据用户id查询该用户已发布的未被邀请的主播列表
@Select("select * from pk_info where sender_id = #{userId} and invite_status = 0 and pk_time > UNIX_TIMESTAMP();")
List<PkInfoModel> listUninvitedPublishedAnchorsByUserId(@Param("userId") Integer userId);
// 查询当前用户与该主播是否存在未完成的pk记录
@Select("SELECT COUNT(*) FROM `pk_record`\n" +
"WHERE (user_id_a = #{userId} OR user_id_b = #{userId})\n" +
"AND (anchor_id_a = #{anchorId} OR anchor_id_b = #{anchorId})\n" +
"AND pk_status = 1\n" +
"AND pk_time > UNIX_TIMESTAMP()")
Integer checkIfUnfinishedPKExistsWithAnchor(@Param("userId") Integer userId, @Param("anchorId") String anchorId);
}

View File

@@ -0,0 +1,31 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("pk_info")
public class PkInfoModel {
@TableId(type = IdType.AUTO)
private Integer id; // 主键,自动递增
private String anchorId; // 主播ID
private Integer pkTime; // PK时间
private String sex; // 性别 1 男 2 女
private String country; // 国家
private Integer coin; // 金币
private String remark; // 描述
private Integer senderId; // 发布人id
private Integer pkNumber; // pk场次
private String anchorIcon; // 主播头像
private Integer inviteStatus; // 可邀请状态 0 未邀请 1 已邀请
private Integer pinExpireTime; // 文章置顶到期时间
private Integer pinCreateTime; // 置顶创建时间
@TableField(exist = false)
private String disPlayId; // 页面上显示的id
@TableField(exist = false)
private Boolean isPin; // 是否在置顶
}

View File

@@ -0,0 +1,27 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class PkRecord {
@TableId(type = IdType.AUTO)
private Integer id; // 数据库主键
private Integer pkIdA; // 发起方的pk表id
private Integer pkIdB; // 被邀请方的pk表id
private Integer userIdA; // 发起人的小程序id
private Integer userIdB; // 邀请人的小程序id
private String anchorIdA; // 主播A的id
private String anchorIdB; // 主播B的id
private String anchorIconA; // 主播A的头像
private String anchorIconB; // 主播B的头像
private Integer userACoins; // 用户A的金币数量
private String pkTime; // pk时间
private Integer userBCoins; // 用户B的金币数量
private Integer pkNumber; // pk场次
private Integer winnerId; // 获胜的userid
private String winnerAnchorId; // 获胜主播的Tik Tok id
private Integer pkStatus; // 状态 0 未处理 1 同意 2 拒绝
}

View File

@@ -0,0 +1,38 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface PkRecordDao extends BaseMapper<PkRecord> {
// 查询当天所有的pk数据 Python使用
@Select("SELECT * FROM pk_record WHERE pk_time BETWEEN #{startTime} AND #{endTime} and pk_status = 1;")
List<PkRecord> pkListForToday(@Param("startTime") long start, @Param("endTime") long end);
// 查询大于等于今天的PK记录数据
@Select("select * from pk_record where (user_id_a = #{userId} or user_id_b = #{userId}) and pk_time >= #{fromTime}")
List<PkRecord> fetchDataFromTodayWithUserId(@Param("userId") Integer userId, @Param("fromTime") Long fromTime);
// 查询是否存在未处理的邀请数据
@Select("select count(*) from pk_record where anchor_id_a = #{anchorA} and anchor_id_b = #{anchorB} and pk_status = 0")
Integer getPendingInvitations(@Param("anchorA") String anchorA , @Param("anchorB") String anchorB);
// 根据id查询记录详情
@Select("select * from pk_record where id = #{id}")
PkRecord singleRecord(@Param("id") Integer id);
// 查询每场pk的详细数据
@Select("select * from pk_record_detail where pk_record_id = #{id}")
List<PkRecordDetail> fetchDetailPkDataWithId(@Param("id") Integer id);
// 查询主播是否存在pk记录
@Select("select count(*) from pk_record where anchor_id_a = #{id} or anchor_id_b = #{id}")
int existsPkRecordByAnchor(@Param("id") String id);
}

View File

@@ -0,0 +1,21 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class PkRecordDetail {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer pkRecordId; // 记录表主id
private String winnerAnchorId; // 获胜主播ID
private Integer winnerId; // 胜利方用户id
private String anchorIdA; // 主播A
private Integer anchorCoinA; // 主播A的金币
private Integer anchorCoinB;
private String anchorIdB; // 主播B
// 主播B的金币
private Long createTime; // 数据创建时间
}

View File

@@ -0,0 +1,17 @@
package vvpkassistant.pk;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface PkRecordDetailDao extends BaseMapper<PkRecordDetail> {
// 根据id查询对应的明细数据
@Select("select * from pk_record_detail where pk_record_id = #{id}")
List<PkRecordDetail> queryDetail(@Param("id") Integer id);
}