完善项目
This commit is contained in:
4
.idea/mybatisx/templates.xml
generated
4
.idea/mybatisx/templates.xml
generated
@@ -48,8 +48,8 @@
|
|||||||
<option name="tableUIInfoList">
|
<option name="tableUIInfoList">
|
||||||
<list>
|
<list>
|
||||||
<TableUIInfo>
|
<TableUIInfo>
|
||||||
<option name="className" value="Urls" />
|
<option name="className" value="Games" />
|
||||||
<option name="tableName" value="urls" />
|
<option name="tableName" value="games" />
|
||||||
</TableUIInfo>
|
</TableUIInfo>
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
|
|||||||
9
pom.xml
9
pom.xml
@@ -53,6 +53,15 @@
|
|||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>com.google.code.gson</groupId>-->
|
||||||
|
<!-- <artifactId>gson</artifactId>-->
|
||||||
|
<!-- <version>2.10.1</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|||||||
@@ -2,14 +2,27 @@ package com.ping.study.config;
|
|||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebMvc implements WebMvcConfigurer {
|
public class WebMvc implements WebMvcConfigurer {
|
||||||
|
|
||||||
@Bean
|
// 原有的 NBA WebClient
|
||||||
public WebClient webClient() {
|
@Bean("nbaWebClient")
|
||||||
|
public WebClient nbaWebClient() {
|
||||||
return WebClient.create("https://api.nba.cn/sib/v2");
|
return WebClient.create("https://api.nba.cn/sib/v2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增的腾讯视频 WebClient
|
||||||
|
@Bean("tencentWebClient")
|
||||||
|
public WebClient tencentWebClient() {
|
||||||
|
return WebClient.create("https://infozb6.video.qq.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ public class NbaController {
|
|||||||
log.info("执行定时方法添加当天赛程");
|
log.info("执行定时方法添加当天赛程");
|
||||||
return nbaApi.addGames();
|
return nbaApi.addGames();
|
||||||
}
|
}
|
||||||
|
@Scheduled(cron = "0 0 0 * * ?")
|
||||||
|
@RequestMapping("/updateLive")
|
||||||
|
public void updateLive() {
|
||||||
|
log.info("执行定时方法更新当天赛程直播链接");
|
||||||
|
|
||||||
|
}
|
||||||
@RequestMapping("/games")
|
@RequestMapping("/games")
|
||||||
public List<Games> getGames() {
|
public List<Games> getGames() {
|
||||||
log.info("获取所有赛程");
|
log.info("获取所有赛程");
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ping.study.controller.tx;
|
||||||
|
|
||||||
|
import com.ping.study.service.tx.LiveInfoService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/tx/nba")
|
||||||
|
public class LiveInfoController {
|
||||||
|
|
||||||
|
private final LiveInfoService liveInfoService;
|
||||||
|
|
||||||
|
public LiveInfoController(LiveInfoService liveInfoService) {
|
||||||
|
this.liveInfoService = liveInfoService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/live/{cnlid}")
|
||||||
|
public String getLiveInfo(@PathVariable String cnlid) {
|
||||||
|
return liveInfoService.getLiveInfo(cnlid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.ping.study.controller.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.tx.MatchListRequest;
|
||||||
|
import com.ping.study.service.tx.MatchService;
|
||||||
|
import com.ping.study.service.tx.SportsQqService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/tx/nba")
|
||||||
|
public class MatchController {
|
||||||
|
private final SportsQqService sportsQqService;
|
||||||
|
private final MatchService matchService;
|
||||||
|
|
||||||
|
public MatchController(MatchService matchService,SportsQqService sportsQqService) {
|
||||||
|
this.sportsQqService = sportsQqService;
|
||||||
|
this.matchService = matchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/matches")
|
||||||
|
public Mono<String> getMatches(
|
||||||
|
@RequestParam(required = false, defaultValue = "100000") Integer columnId,
|
||||||
|
@RequestParam String startTime,
|
||||||
|
@RequestParam String endTime) {
|
||||||
|
|
||||||
|
MatchListRequest request = new MatchListRequest();
|
||||||
|
request.setColumnId(columnId);
|
||||||
|
request.setStartTime(LocalDate.parse(startTime));
|
||||||
|
request.setEndTime(LocalDate.parse(endTime));
|
||||||
|
|
||||||
|
return sportsQqService.getMatchList(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/lives")
|
||||||
|
public List<String> getPlayoffLiveIds(
|
||||||
|
@RequestParam String startTime,
|
||||||
|
@RequestParam String endTime) {
|
||||||
|
|
||||||
|
LocalDate startDate = LocalDate.parse(startTime);
|
||||||
|
LocalDate endDate = LocalDate.parse(endTime);
|
||||||
|
|
||||||
|
return matchService.getPlayoffLiveIdsBlocking(startDate, endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ping.study.controller.tx;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ping.study.service.tx.TxSportTokenRefreshService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/tx")
|
||||||
|
public class TokenRefreshController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TxSportTokenRefreshService txSportTokenRefreshService;
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/refresh")
|
||||||
|
public Boolean refreshToken()
|
||||||
|
{
|
||||||
|
return txSportTokenRefreshService.refreshCookies();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ import com.ping.study.pojo.Games;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Administrator
|
* @author Ping01
|
||||||
* @description 针对表【games】的数据库操作Mapper
|
* @description 针对表【games】的数据库操作Mapper
|
||||||
* @createDate 2025-04-17 21:23:08
|
* @createDate 2025-04-20 20:13:51
|
||||||
* @Entity com.ping.study.pojo.Games
|
* @Entity com.ping.study.pojo.Games
|
||||||
*/
|
*/
|
||||||
public interface GamesMapper {
|
public interface GamesMapper {
|
||||||
@@ -30,4 +30,5 @@ public interface GamesMapper {
|
|||||||
|
|
||||||
//删除所有赛程
|
//删除所有赛程
|
||||||
void deleteAllGames();
|
void deleteAllGames();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.ping.study.model.dto.tx;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LiveInfoRequest {
|
||||||
|
|
||||||
|
private String ckey;
|
||||||
|
private String encryptVer;
|
||||||
|
private String platform;
|
||||||
|
private String tm;
|
||||||
|
private String cnlid;
|
||||||
|
//private String cookie =
|
||||||
|
|
||||||
|
public static final String getCookie() {
|
||||||
|
return "pgv_pvid=67939534; fqm_pvqid=5e0a1a80-2ffb-42c9-8878-99ef08c0bd21; RK=dudkRjOGUW; ptcz=d9e319494b15cb621d9f54a8e03a1b55fb6c6c3564ff6c4985d1ff7b4797ce4e; video_platform=2; qq_domain_video_guid_verify=119f9c981e9ffd34; _qimei_uuid42=184170b170810037e9eacb93c4fe35a57c7df28f38; _qimei_q36=; _qimei_h38=215914e0566ee066f810eb4b0200000e81840b; video_guid=119f9c981e9ffd34; tvfe_boss_uuid=d41b10b066856291; eas_sid=E1i7L1k4j4D7q1D0Q5J894p636; livelink_pvid=7900946432; check_16=584445b5d815fd331bb7206205f8c603; _qimei_fingerprint=3c06d28104a1e802703470a164d81dca; vqq_refresh_token=; vqq_next_refresh_time=6196; vqq_login_time_init=1745153828; v_qq_com_session_lapse_time=1745160024778; vqq_appid=101481799; vqq_openid=2E6A77E3002C87A9CA68908FB058D4E5; vqq_access_token=308C7CAFBC867AF65212034AC90E71D9; vqq_vuserid=3468482246; vqq_vusession=Kcz0B9FBUDZuIvwHKErD3g.N";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 密钥映射表
|
||||||
|
private static final Map<DayOfWeek, String> WEEKDAY_KEYS = Map.of(
|
||||||
|
DayOfWeek.MONDAY, "06fc1464",
|
||||||
|
DayOfWeek.TUESDAY, "4244ce1b",
|
||||||
|
DayOfWeek.WEDNESDAY, "77de31c5",
|
||||||
|
DayOfWeek.THURSDAY, "e0149fa2",
|
||||||
|
DayOfWeek.FRIDAY, "60394ced",
|
||||||
|
DayOfWeek.SATURDAY, "2da639f0",
|
||||||
|
DayOfWeek.SUNDAY, "c2f0cf9f"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 生成加密版本号
|
||||||
|
public static String generateEncryptVer(DayOfWeek dayOfWeek) {
|
||||||
|
int dayValue = dayOfWeek == DayOfWeek.SUNDAY ? 7 : dayOfWeek.getValue();
|
||||||
|
return "7." + dayValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当天密钥
|
||||||
|
public static String getTodaySecretKey() {
|
||||||
|
return WEEKDAY_KEYS.get(DayOfWeek.from(java.time.LocalDate.now()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ping.study.model.dto.tx;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MatchListRequest {
|
||||||
|
private Integer columnId = 100000; // 默认值
|
||||||
|
private LocalDate startTime;
|
||||||
|
private LocalDate endTime;
|
||||||
|
|
||||||
|
// 自定义参数校验逻辑(可选)
|
||||||
|
public void validate() {
|
||||||
|
if (startTime.isAfter(endTime)) {
|
||||||
|
throw new IllegalArgumentException("开始时间不能晚于结束时间");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/main/java/com/ping/study/model/vo/tx/MatchInfo.java
Normal file
11
src/main/java/com/ping/study/model/vo/tx/MatchInfo.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ping.study.model.vo.tx;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MatchInfo {
|
||||||
|
|
||||||
|
private String liveId;
|
||||||
|
private String matchType;
|
||||||
|
// 其他需要的字段...
|
||||||
|
}
|
||||||
14
src/main/java/com/ping/study/model/vo/tx/MatchResponse.java
Normal file
14
src/main/java/com/ping/study/model/vo/tx/MatchResponse.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ping.study.model.vo.tx;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MatchResponse {
|
||||||
|
private Integer code;
|
||||||
|
private String msg;
|
||||||
|
private Map<String, List<MatchInfo>> data;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ping.study.pojo;
|
package com.ping.study.pojo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -8,7 +9,7 @@ import lombok.Data;
|
|||||||
* @TableName games
|
* @TableName games
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class Games {
|
public class Games implements Serializable {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -24,6 +25,11 @@ public class Games {
|
|||||||
*/
|
*/
|
||||||
private String gameId;
|
private String gameId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private String playId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -48,4 +54,6 @@ public class Games {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private String awayTeamLogoDark;
|
private String awayTeamLogoDark;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
77
src/main/java/com/ping/study/service/tx/LiveInfoService.java
Normal file
77
src/main/java/com/ping/study/service/tx/LiveInfoService.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.tx.LiveInfoRequest;
|
||||||
|
import com.ping.study.utils.tx.CKeyGenerator;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class LiveInfoService {
|
||||||
|
|
||||||
|
private final WebClient webClient;
|
||||||
|
private final CKeyGenerator cKeyGenerator;
|
||||||
|
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
public LiveInfoService(@Qualifier("tencentWebClient")WebClient webClient, CKeyGenerator cKeyGenerator, StringRedisTemplate stringRedisTemplate) {
|
||||||
|
this.webClient = webClient;
|
||||||
|
this.cKeyGenerator = cKeyGenerator;
|
||||||
|
this.stringRedisTemplate = stringRedisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 远程调用时拼接 Cookie
|
||||||
|
public String getCookieForRequest() {
|
||||||
|
// 读取
|
||||||
|
String cookie = stringRedisTemplate.opsForValue().get("tx_sports_cookie");
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLiveInfo(String cnlid) {
|
||||||
|
String platform = "40201";
|
||||||
|
String ckey = cKeyGenerator.generateCKey(cnlid, platform);
|
||||||
|
|
||||||
|
// 1. 打印请求参数
|
||||||
|
String queryParams = String.format(
|
||||||
|
"ckey=%s&encrypt_ver=%s&platform=%s&tm=%d&cnlid=%s",
|
||||||
|
ckey,
|
||||||
|
LiveInfoRequest.generateEncryptVer(DayOfWeek.from(LocalDate.now())),
|
||||||
|
platform,
|
||||||
|
Instant.now().getEpochSecond(),
|
||||||
|
cnlid
|
||||||
|
);
|
||||||
|
log.info("请求参数: {}", queryParams);
|
||||||
|
|
||||||
|
// 2. 打印请求头(Cookie)
|
||||||
|
String cookie = getCookieForRequest();
|
||||||
|
log.info("请求头 Cookie: {}", cookie);
|
||||||
|
|
||||||
|
// 3. 发起请求
|
||||||
|
return webClient.get()
|
||||||
|
.uri(uriBuilder -> uriBuilder
|
||||||
|
.path("/cgi-bin/getliveinfo")
|
||||||
|
.queryParam("ckey", ckey)
|
||||||
|
.queryParam("encrypt_ver", LiveInfoRequest.generateEncryptVer(
|
||||||
|
DayOfWeek.from(LocalDate.now())))
|
||||||
|
.queryParam("platform", platform)
|
||||||
|
.queryParam("tm", Instant.now().getEpochSecond())
|
||||||
|
.queryParam("cnlid", cnlid)
|
||||||
|
.build())
|
||||||
|
.header("Cookie", "pgv_pvid=67939534; fqm_pvqid=5e0a1a80-2ffb-42c9-8878-99ef08c0bd21; RK=dudkRjOGUW; ptcz=d9e319494b15cb621d9f54a8e03a1b55fb6c6c3564ff6c4985d1ff7b4797ce4e; video_platform=2; qq_domain_video_guid_verify=119f9c981e9ffd34; _qimei_uuid42=184170b170810037e9eacb93c4fe35a57c7df28f38; _qimei_q36=; _qimei_h38=215914e0566ee066f810eb4b0200000e81840b; video_guid=119f9c981e9ffd34; tvfe_boss_uuid=d41b10b066856291; eas_sid=E1i7L1k4j4D7q1D0Q5J894p636; livelink_pvid=7900946432; check_16=584445b5d815fd331bb7206205f8c603; o2_uin=941039061; uin_cookie=o0941039061; ied_qq=o0941039061; o_cookie=941039061; pac_uid=0_ePEHB57t75p7c; LW_sid=31h7T2M8f3O5O280q0K0L365H2; LW_uid=P1J7P2i8S3R5a2r0j020t3n543; ptui_loginuin=1131302745; qq_nick=A; qq_head=https://tvpic.gtimg.cn/head/dbb128053992612c0c1327e8e32e95f8da39a3ee5e6b4b0d3255bfef95601890afd80709/346; vqq_refresh_token=; vqq_next_refresh_time=6505; vqq_login_time_init=1745154214; _qimei_fingerprint=829539b60aaa7ed28f0e5f604c391a63; main_login=qq; vqq_appid=101481799; vqq_openid=2E6A77E3002C87A9CA68908FB058D4E5; vqq_access_token=308C7CAFBC867AF65212034AC90E71D9; vqq_vuserid=3468482246; vqq_vusession=H1-ZxeRN0vDUVk4_wKLkyA.N")
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.block();
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/main/java/com/ping/study/service/tx/MatchService.java
Normal file
60
src/main/java/com/ping/study/service/tx/MatchService.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.vo.tx.MatchInfo;
|
||||||
|
import com.ping.study.model.vo.tx.MatchResponse;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MatchService {
|
||||||
|
|
||||||
|
private final WebClient webClient;
|
||||||
|
private static final DateTimeFormatter DATE_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
|
public MatchService(WebClient.Builder webClientBuilder) {
|
||||||
|
this.webClient = webClientBuilder
|
||||||
|
.baseUrl("https://matchweb.sports.qq.com")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期范围内所有NBA季后赛(matchType=2)的直播ID
|
||||||
|
*/
|
||||||
|
public List<String> getPlayoffLiveIdsBlocking(LocalDate startDate, LocalDate endDate) {
|
||||||
|
return webClient.get()
|
||||||
|
.uri(uriBuilder -> uriBuilder
|
||||||
|
.path("/matchUnion/list")
|
||||||
|
.queryParam("columnId", 100000)
|
||||||
|
.queryParam("startTime", startDate.format(DATE_FORMATTER))
|
||||||
|
.queryParam("endTime", endDate.format(DATE_FORMATTER))
|
||||||
|
.build())
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(MatchResponse.class)
|
||||||
|
.flatMapMany(response -> {
|
||||||
|
if (response.getCode() != 0 || response.getData() == null) {
|
||||||
|
return Flux.error(new RuntimeException("API返回异常: " + response.getMsg()));
|
||||||
|
}
|
||||||
|
// 提取所有matchType=2的比赛
|
||||||
|
List<String> liveIds = response.getData().values().stream()
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.filter(match -> "2".equals(match.getMatchType()))
|
||||||
|
.map(MatchInfo::getLiveId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return Flux.fromIterable(liveIds);
|
||||||
|
})
|
||||||
|
.collectList()
|
||||||
|
.block(); // 阻塞等待结果
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取完整比赛信息(过滤matchType=2)
|
||||||
|
*/
|
||||||
|
}
|
||||||
36
src/main/java/com/ping/study/service/tx/QQCookieService.java
Normal file
36
src/main/java/com/ping/study/service/tx/QQCookieService.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class QQCookieService {
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
private static final String REDIS_KEY = "user:nba"; // 固定 Key
|
||||||
|
|
||||||
|
// 存储 Cookie(无需 uin 参数)
|
||||||
|
public void saveCookie(Map<String, String> cookies) {
|
||||||
|
stringRedisTemplate.opsForHash().putAll(REDIS_KEY, cookies);
|
||||||
|
stringRedisTemplate.expire(REDIS_KEY, 30, TimeUnit.DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 Cookie(无需 uin 参数)
|
||||||
|
public Map<String, String> getCookie() {
|
||||||
|
Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(REDIS_KEY);
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
|
||||||
|
entries.forEach((key, value) ->
|
||||||
|
result.put(key.toString(), value.toString())
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class QQRequestService {
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate; // 现在可以正常注入
|
||||||
|
@Autowired
|
||||||
|
private QQCookieService qqCookieService;
|
||||||
|
@Autowired
|
||||||
|
private QQTokenRefreshService tokenRefreshService;
|
||||||
|
|
||||||
|
// 发起请求(自动处理 Cookie 和 Token 刷新)
|
||||||
|
public String fetchData(String uin, String apiUrl) throws IOException {
|
||||||
|
Map<String, String> cookies = qqCookieService.getCookie();
|
||||||
|
|
||||||
|
// 检查 Token 是否即将过期
|
||||||
|
long expiresIn = Long.parseLong(cookies.getOrDefault("vqq_next_refresh_time", "0"));
|
||||||
|
if (expiresIn < 300) { // 剩余 <5 分钟时刷新
|
||||||
|
tokenRefreshService.refreshToken();
|
||||||
|
cookies = qqCookieService.getCookie(); // 重新加载
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求头(模拟浏览器)
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
|
cookies.forEach((name, value) -> headers.add("Cookie", name + "=" + value));
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
|
apiUrl,
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(headers),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class QQTokenRefreshService {
|
||||||
|
@Autowired
|
||||||
|
private QQCookieService qqCookieService;
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
// 刷新 Token
|
||||||
|
public boolean refreshToken() throws IOException {
|
||||||
|
Map<String, String> cookies = qqCookieService.getCookie();
|
||||||
|
String refreshToken = cookies.get("vqq_refresh_token");
|
||||||
|
if (refreshToken == null || refreshToken.isEmpty()) {
|
||||||
|
throw new IllegalStateException("No refresh_token available, need re-login");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用 QQ 的 Token 刷新接口(示例,需替换真实 API)
|
||||||
|
String url = "https://xui.ptlogin2.qq.com/refresh?refresh_token=" + refreshToken;
|
||||||
|
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
|
||||||
|
|
||||||
|
if (response.getStatusCode().is2xxSuccessful()) {
|
||||||
|
// 解析新 Token 并更新 Cookie
|
||||||
|
String newAccessToken = parseNewToken(response.getBody());
|
||||||
|
cookies.put("vqq_access_token", newAccessToken);
|
||||||
|
cookies.put("vqq_next_refresh_time", "7200"); // 假设新有效期 2 小时
|
||||||
|
qqCookieService.saveCookie(cookies);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false; // 刷新失败,需重新登录
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseNewToken(String responseBody) throws IOException {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JsonNode root = mapper.readTree(responseBody);
|
||||||
|
return root.get("access_token").asText();
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/main/java/com/ping/study/service/tx/SportsQqService.java
Normal file
36
src/main/java/com/ping/study/service/tx/SportsQqService.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.tx.MatchListRequest;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SportsQqService {
|
||||||
|
|
||||||
|
private final WebClient webClient;
|
||||||
|
private static final DateTimeFormatter DATE_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
|
public SportsQqService(WebClient.Builder webClientBuilder) {
|
||||||
|
this.webClient = webClientBuilder
|
||||||
|
.baseUrl("https://matchweb.sports.qq.com")
|
||||||
|
.defaultHeader("User-Agent", "YourApp/1.0")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<String> getMatchList(MatchListRequest request) {
|
||||||
|
request.validate(); // 参数校验
|
||||||
|
|
||||||
|
return webClient.get()
|
||||||
|
.uri(uriBuilder -> uriBuilder
|
||||||
|
.path("/matchUnion/list")
|
||||||
|
.queryParam("columnId", request.getColumnId())
|
||||||
|
.queryParam("startTime", request.getStartTime().format(DATE_FORMATTER))
|
||||||
|
.queryParam("endTime", request.getEndTime().format(DATE_FORMATTER))
|
||||||
|
.build())
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class TxSportTokenRefreshService {
|
||||||
|
|
||||||
|
private final WebClient webClient;
|
||||||
|
private final StringRedisTemplate redisTemplate;
|
||||||
|
private static final String REDIS_COOKIE_KEY = "tx_sports_cookie";
|
||||||
|
|
||||||
|
public TxSportTokenRefreshService(WebClient.Builder builder,
|
||||||
|
StringRedisTemplate redisTemplate) {
|
||||||
|
this.webClient = builder.baseUrl("https://app.sports.qq.com").build();
|
||||||
|
this.redisTemplate = redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新Cookie并存储到Redis
|
||||||
|
*/
|
||||||
|
// 在首次成功时,分离并存储基础登录态Cookie
|
||||||
|
public boolean refreshCookies() {
|
||||||
|
try {
|
||||||
|
// 1. 从Redis获取基础登录态Cookie(首次需手动初始化)
|
||||||
|
String baseCookie = redisTemplate.opsForValue().get("tx_base_cookies");
|
||||||
|
if (baseCookie == null) {
|
||||||
|
baseCookie = "pgv_pvid=67939534; ptui_loginuin=1131302745; ..."; // 你的浏览器完整Cookie
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 携带基础Cookie发起请求
|
||||||
|
String response = webClient.get()
|
||||||
|
.uri("/init/refresh?os=web")
|
||||||
|
.header("Cookie", baseCookie) // 关键点:始终携带基础登录态
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
// 3. 合并新旧Cookie(保留基础登录态)
|
||||||
|
JsonNode data = new ObjectMapper().readTree(response).path("data");
|
||||||
|
String newCookie = extractNewCookies(data); // 提取spt_token等
|
||||||
|
String finalCookie = mergeCookies(baseCookie, newCookie);
|
||||||
|
|
||||||
|
// 4. 存储到Redis
|
||||||
|
redisTemplate.opsForValue().set(
|
||||||
|
"tx_sports_cookies",
|
||||||
|
finalCookie,
|
||||||
|
Long.parseLong(data.path("tokenTTL").asText()),
|
||||||
|
TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("刷新失败", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 合并Cookie的工具方法
|
||||||
|
private String mergeCookies(String base, String news) {
|
||||||
|
Map<String, String> map = new LinkedHashMap<>();
|
||||||
|
// 先解析基础Cookie
|
||||||
|
Arrays.stream(base.split("; "))
|
||||||
|
.forEach(c -> {
|
||||||
|
String[] kv = c.split("=", 2);
|
||||||
|
if (kv.length == 2) map.put(kv[0], kv[1]);
|
||||||
|
});
|
||||||
|
// 用新Cookie覆盖
|
||||||
|
Arrays.stream(news.split("; "))
|
||||||
|
.forEach(c -> {
|
||||||
|
String[] kv = c.split("=", 2);
|
||||||
|
if (kv.length == 2) map.put(kv[0], kv[1]);
|
||||||
|
});
|
||||||
|
// 重新拼接
|
||||||
|
return map.entrySet().stream()
|
||||||
|
.map(e -> e.getKey() + "=" + e.getValue())
|
||||||
|
.collect(Collectors.joining("; "));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时刷新任务(每1小时执行一次)
|
||||||
|
*/
|
||||||
|
// @Scheduled(fixedRate = 3600000) // 单位:毫秒
|
||||||
|
// public void scheduledRefresh() {
|
||||||
|
// if (!refreshCookies()) {
|
||||||
|
// log.warn("定时刷新Cookie失败,将重试...");
|
||||||
|
// // 失败后延迟5分钟重试
|
||||||
|
// try {
|
||||||
|
// Thread.sleep(300000);
|
||||||
|
// refreshCookies();
|
||||||
|
// } catch (InterruptedException ignored) {}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -6,14 +6,17 @@ import com.ping.study.model.vo.Game;
|
|||||||
import com.ping.study.model.vo.Group;
|
import com.ping.study.model.vo.Group;
|
||||||
import com.ping.study.pojo.Games;
|
import com.ping.study.pojo.Games;
|
||||||
import com.ping.study.service.GamesService;
|
import com.ping.study.service.GamesService;
|
||||||
|
import com.ping.study.service.tx.MatchService;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,7 +31,10 @@ public class NbaApi {
|
|||||||
|
|
||||||
private WebClient webClient;
|
private WebClient webClient;
|
||||||
|
|
||||||
public NbaApi(WebClient webClient) {
|
@Autowired
|
||||||
|
private MatchService matchService;
|
||||||
|
|
||||||
|
public NbaApi(@Qualifier("nbaWebClient")WebClient webClient) {
|
||||||
this.webClient = webClient;
|
this.webClient = webClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +43,8 @@ public class NbaApi {
|
|||||||
NbaStatsRequestDto requestParams = new NbaStatsRequestDto();
|
NbaStatsRequestDto requestParams = new NbaStatsRequestDto();
|
||||||
log.info("{}", requestParams);
|
log.info("{}", requestParams);
|
||||||
log.info("进入{},执行{}", this.getClass().getName(), "getGames");
|
log.info("进入{},执行{}", this.getClass().getName(), "getGames");
|
||||||
|
//获取所有当天直播id
|
||||||
|
List<String> lives = matchService.getPlayoffLiveIdsBlocking(LocalDate.now(), LocalDate.now());
|
||||||
List<Games> gameEntities = webClient.get()
|
List<Games> gameEntities = webClient.get()
|
||||||
.uri("/game/schedule", uriBuilder -> uriBuilder
|
.uri("/game/schedule", uriBuilder -> uriBuilder
|
||||||
.queryParam("app_key", requestParams.getAppKey())
|
.queryParam("app_key", requestParams.getAppKey())
|
||||||
@@ -60,17 +68,17 @@ public class NbaApi {
|
|||||||
List<Games> entities = new ArrayList<>();
|
List<Games> entities = new ArrayList<>();
|
||||||
// 遍历groups中的games
|
// 遍历groups中的games
|
||||||
for (Group group : response.getData().getGroups()) {
|
for (Group group : response.getData().getGroups()) {
|
||||||
for (Game game : group.getGames()) {
|
for (int i = 0; i < group.getGames().size(); i++){
|
||||||
Games entity = new Games();
|
Games entity = new Games();
|
||||||
entity.setDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
entity.setDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||||
entity.setGameId(game.getGameId());
|
entity.setGameId(group.getGames().get(i).getGameId());
|
||||||
entity.setHomeTeamName(game.getHomeTeamName());
|
entity.setHomeTeamName(group.getGames().get(i).getHomeTeamName());
|
||||||
entity.setAwayTeamName(game.getAwayTeamName());
|
entity.setAwayTeamName(group.getGames().get(i).getAwayTeamName());
|
||||||
entity.setHomeTeamLogoDark(game.getHomeTeamLogoDark());
|
entity.setHomeTeamLogoDark(group.getGames().get(i).getHomeTeamLogoDark());
|
||||||
entity.setAwayTeamLogoDark(game.getAwayTeamLogoDark());
|
entity.setAwayTeamLogoDark(group.getGames().get(i).getAwayTeamLogoDark());
|
||||||
|
entity.setPlayId(lives.get(i));
|
||||||
// 合并日期和时间
|
// 合并日期和时间
|
||||||
String dateTimeStr = game.getStartDate() + " " + game.getStartTime();
|
String dateTimeStr = group.getGames().get(i).getStartDate() + " " + group.getGames().get(i).getStartTime();
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
try {
|
try {
|
||||||
entity.setStartTime(format.parse(dateTimeStr));
|
entity.setStartTime(format.parse(dateTimeStr));
|
||||||
@@ -78,9 +86,31 @@ public class NbaApi {
|
|||||||
// 处理异常或设置默认值
|
// 处理异常或设置默认值
|
||||||
entity.setStartTime(null);
|
entity.setStartTime(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
gamesService.insertGames(entity);
|
gamesService.insertGames(entity);
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
}
|
}
|
||||||
|
// for (Game game : group.getGames()) {
|
||||||
|
// Games entity = new Games();
|
||||||
|
// entity.setDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||||
|
// entity.setGameId(game.getGameId());
|
||||||
|
// entity.setHomeTeamName(game.getHomeTeamName());
|
||||||
|
// entity.setAwayTeamName(game.getAwayTeamName());
|
||||||
|
// entity.setHomeTeamLogoDark(game.getHomeTeamLogoDark());
|
||||||
|
// entity.setAwayTeamLogoDark(game.getAwayTeamLogoDark());
|
||||||
|
//
|
||||||
|
// // 合并日期和时间
|
||||||
|
// String dateTimeStr = game.getStartDate() + " " + game.getStartTime();
|
||||||
|
// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
// try {
|
||||||
|
// entity.setStartTime(format.parse(dateTimeStr));
|
||||||
|
// } catch (ParseException e) {
|
||||||
|
// // 处理异常或设置默认值
|
||||||
|
// entity.setStartTime(null);
|
||||||
|
// }
|
||||||
|
// gamesService.insertGames(entity);
|
||||||
|
// entities.add(entity);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
return entities;
|
return entities;
|
||||||
})
|
})
|
||||||
|
|||||||
46
src/main/java/com/ping/study/utils/tx/CKeyGenerator.java
Normal file
46
src/main/java/com/ping/study/utils/tx/CKeyGenerator.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ping.study.utils.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.tx.LiveInfoRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CKeyGenerator {
|
||||||
|
|
||||||
|
public String generateCKey(String cnlid, String platform) {
|
||||||
|
// 获取当前时间戳(秒级)
|
||||||
|
String tm = String.valueOf(Instant.now().getEpochSecond());
|
||||||
|
|
||||||
|
// 获取当天星期几和密钥
|
||||||
|
DayOfWeek today = DayOfWeek.from(java.time.LocalDate.now());
|
||||||
|
String secretKey = LiveInfoRequest.getTodaySecretKey();
|
||||||
|
String encryptVer = LiveInfoRequest.generateEncryptVer(today);
|
||||||
|
|
||||||
|
// 构建输入字符串
|
||||||
|
String input = secretKey + cnlid + tm + "*#06#" + platform;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 计算MD5
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
// 转换为16进制字符串
|
||||||
|
StringBuilder hexString = new StringBuilder();
|
||||||
|
for (byte b : hash) {
|
||||||
|
String hex = Integer.toHexString(0xff & b);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
hexString.append('0');
|
||||||
|
}
|
||||||
|
hexString.append(hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexString.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("生成ckey失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
server:
|
server:
|
||||||
port: 9005
|
port: 9005
|
||||||
spring:
|
spring:
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 110.42.255.182
|
||||||
|
port: 6739
|
||||||
application:
|
application:
|
||||||
name: NBA
|
name: NBA
|
||||||
datasource:
|
datasource:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||||
<result property="date" column="date" jdbcType="VARCHAR"/>
|
<result property="date" column="date" jdbcType="VARCHAR"/>
|
||||||
<result property="gameId" column="game_id" jdbcType="VARCHAR"/>
|
<result property="gameId" column="game_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="playId" column="play_id" jdbcType="VARCHAR"/>
|
||||||
<result property="startTime" column="start_time" jdbcType="TIMESTAMP"/>
|
<result property="startTime" column="start_time" jdbcType="TIMESTAMP"/>
|
||||||
<result property="homeTeamName" column="home_team_name" jdbcType="VARCHAR"/>
|
<result property="homeTeamName" column="home_team_name" jdbcType="VARCHAR"/>
|
||||||
<result property="awayTeamName" column="away_team_name" jdbcType="VARCHAR"/>
|
<result property="awayTeamName" column="away_team_name" jdbcType="VARCHAR"/>
|
||||||
@@ -17,8 +18,8 @@
|
|||||||
|
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id,date,game_id,
|
id,date,game_id,
|
||||||
start_time,home_team_name,away_team_name,
|
play_id,start_time,home_team_name,
|
||||||
home_team_logo_dark,away_team_logo_dark
|
away_team_name,home_team_logo_dark,away_team_logo_dark
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
|
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
|
||||||
@@ -35,11 +36,13 @@
|
|||||||
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.Games" useGeneratedKeys="true">
|
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.Games" useGeneratedKeys="true">
|
||||||
insert into games
|
insert into games
|
||||||
( id,date,game_id
|
( id,date,game_id
|
||||||
,start_time,home_team_name,away_team_name
|
,play_id,start_time,home_team_name
|
||||||
,home_team_logo_dark,away_team_logo_dark)
|
,away_team_name,home_team_logo_dark,away_team_logo_dark
|
||||||
|
)
|
||||||
values (#{id,jdbcType=INTEGER},#{date,jdbcType=VARCHAR},#{gameId,jdbcType=VARCHAR}
|
values (#{id,jdbcType=INTEGER},#{date,jdbcType=VARCHAR},#{gameId,jdbcType=VARCHAR}
|
||||||
,#{startTime,jdbcType=TIMESTAMP},#{homeTeamName,jdbcType=VARCHAR},#{awayTeamName,jdbcType=VARCHAR}
|
,#{playId,jdbcType=VARCHAR},#{startTime,jdbcType=TIMESTAMP},#{homeTeamName,jdbcType=VARCHAR}
|
||||||
,#{homeTeamLogoDark,jdbcType=VARCHAR},#{awayTeamLogoDark,jdbcType=VARCHAR})
|
,#{awayTeamName,jdbcType=VARCHAR},#{homeTeamLogoDark,jdbcType=VARCHAR},#{awayTeamLogoDark,jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.Games" useGeneratedKeys="true">
|
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.Games" useGeneratedKeys="true">
|
||||||
insert into games
|
insert into games
|
||||||
@@ -47,6 +50,7 @@
|
|||||||
<if test="id != null">id,</if>
|
<if test="id != null">id,</if>
|
||||||
<if test="date != null">date,</if>
|
<if test="date != null">date,</if>
|
||||||
<if test="gameId != null">game_id,</if>
|
<if test="gameId != null">game_id,</if>
|
||||||
|
<if test="playId != null">play_id,</if>
|
||||||
<if test="startTime != null">start_time,</if>
|
<if test="startTime != null">start_time,</if>
|
||||||
<if test="homeTeamName != null">home_team_name,</if>
|
<if test="homeTeamName != null">home_team_name,</if>
|
||||||
<if test="awayTeamName != null">away_team_name,</if>
|
<if test="awayTeamName != null">away_team_name,</if>
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
<if test="id != null">#{id,jdbcType=INTEGER},</if>
|
<if test="id != null">#{id,jdbcType=INTEGER},</if>
|
||||||
<if test="date != null">#{date,jdbcType=VARCHAR},</if>
|
<if test="date != null">#{date,jdbcType=VARCHAR},</if>
|
||||||
<if test="gameId != null">#{gameId,jdbcType=VARCHAR},</if>
|
<if test="gameId != null">#{gameId,jdbcType=VARCHAR},</if>
|
||||||
|
<if test="playId != null">#{playId,jdbcType=VARCHAR},</if>
|
||||||
<if test="startTime != null">#{startTime,jdbcType=TIMESTAMP},</if>
|
<if test="startTime != null">#{startTime,jdbcType=TIMESTAMP},</if>
|
||||||
<if test="homeTeamName != null">#{homeTeamName,jdbcType=VARCHAR},</if>
|
<if test="homeTeamName != null">#{homeTeamName,jdbcType=VARCHAR},</if>
|
||||||
<if test="awayTeamName != null">#{awayTeamName,jdbcType=VARCHAR},</if>
|
<if test="awayTeamName != null">#{awayTeamName,jdbcType=VARCHAR},</if>
|
||||||
@@ -73,6 +78,9 @@
|
|||||||
<if test="gameId != null">
|
<if test="gameId != null">
|
||||||
game_id = #{gameId,jdbcType=VARCHAR},
|
game_id = #{gameId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="playId != null">
|
||||||
|
play_id = #{playId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="startTime != null">
|
<if test="startTime != null">
|
||||||
start_time = #{startTime,jdbcType=TIMESTAMP},
|
start_time = #{startTime,jdbcType=TIMESTAMP},
|
||||||
</if>
|
</if>
|
||||||
@@ -96,6 +104,7 @@
|
|||||||
set
|
set
|
||||||
date = #{date,jdbcType=VARCHAR},
|
date = #{date,jdbcType=VARCHAR},
|
||||||
game_id = #{gameId,jdbcType=VARCHAR},
|
game_id = #{gameId,jdbcType=VARCHAR},
|
||||||
|
play_id = #{playId,jdbcType=VARCHAR},
|
||||||
start_time = #{startTime,jdbcType=TIMESTAMP},
|
start_time = #{startTime,jdbcType=TIMESTAMP},
|
||||||
home_team_name = #{homeTeamName,jdbcType=VARCHAR},
|
home_team_name = #{homeTeamName,jdbcType=VARCHAR},
|
||||||
away_team_name = #{awayTeamName,jdbcType=VARCHAR},
|
away_team_name = #{awayTeamName,jdbcType=VARCHAR},
|
||||||
@@ -104,7 +113,6 @@
|
|||||||
where id = #{id,jdbcType=INTEGER}
|
where id = #{id,jdbcType=INTEGER}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
|
||||||
<select id="selectByGameId" resultMap="BaseResultMap">
|
<select id="selectByGameId" resultMap="BaseResultMap">
|
||||||
select
|
select
|
||||||
<include refid="Base_Column_List" />
|
<include refid="Base_Column_List" />
|
||||||
|
|||||||
Reference in New Issue
Block a user