Compare commits
10 Commits
48c1e03945
...
ddb78e29a3
| Author | SHA1 | Date | |
|---|---|---|---|
| ddb78e29a3 | |||
| 0adfe7d539 | |||
| 332b79c13e | |||
| 7231281302 | |||
| 6bb06266b0 | |||
| 251e8446d6 | |||
| 2d152da62a | |||
| ffb564db01 | |||
| 1c68932238 | |||
| 31dc7c9cde |
278
.idea/IntelliLang.xml
generated
Normal file
278
.idea/IntelliLang.xml
generated
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="LanguageInjectionConfiguration">
|
||||||
|
<injection language="http-header-reference" injector-id="java">
|
||||||
|
<display-name>Apache HttpClient 4 HTTP Header (org.apache.http)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.http.HttpMessage"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.http.message.AbstractHttpMessage"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="http-header-reference" injector-id="java">
|
||||||
|
<display-name>Apache HttpClient 5 HTTP Header (org.apache.hc.core5)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader").definedInClass("org.apache.hc.core5.http.message.BasicHttpRequest"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.hc.client5.http.async.methods.SimpleRequestBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.hc.core5.http.io.support.ClassicRequestBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.hc.core5.http.nio.support.AsyncRequestBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("setHeader", "addHeader", "getFirstHeader", "getLastHeader", "removeHeaders").definedInClass("org.apache.hc.core5.http.support.BasicRequestBuilder"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>AsyncQueryRunner (org.apache.commons.dbutils)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("batch").withParameterCount(2).definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("insertBatch").withParameterCount(3).definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "insert").withParameters("java.lang.String", "org.apache.commons.dbutils.ResultSetHandler").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "insert").withParameters("java.lang.String", "org.apache.commons.dbutils.ResultSetHandler", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").withParameters("java.lang.String").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").withParameters("java.lang.String", "java.lang.Object").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").withParameters("java.lang.String", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("batch").withParameterCount(3).definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("insertBatch").withParameterCount(4).definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("query", "insert").withParameters("java.sql.Connection", "java.lang.String", "org.apache.commons.dbutils.ResultSetHandler").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("query", "insert").withParameters("java.sql.Connection", "java.lang.String", "org.apache.commons.dbutils.ResultSetHandler", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update").withParameters("java.sql.Connection", "java.lang.String").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update").withParameters("java.sql.Connection", "java.lang.String", "java.lang.Object").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update").withParameters("java.sql.Connection", "java.lang.String", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.AsyncQueryRunner"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Jodd (jodd.db)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query").withParameterCount(1).definedInClass("jodd.db.DbQuery"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("DbQuery").withParameterCount(2).definedInClass("jodd.db.DbQuery"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("query").withParameterCount(2).definedInClass("jodd.db.DbQuery"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(2, psiMethod().withName("DbQuery").withParameterCount(3).definedInClass("jodd.db.DbQuery"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="http-header-reference" injector-id="java">
|
||||||
|
<display-name>MockServer Header (org.mockserver)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header").definedInClass("org.mockserver.model.Header"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("withHeader").definedInClass("org.mockserver.model.HttpRequest"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("withHeader", "getHeader", "getFirstHeader", "containsHeader", "removeHeader").definedInClass("org.mockserver.model.HttpResponse"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>QueryRunner (org.apache.commons.dbutils)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("batch").withParameterCount(2).definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("insertBatch").withParameterCount(3).definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "insert").withParameters("java.lang.String", "org.apache.commons.dbutils.ResultSetHandler").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "insert", "execute").withParameters("java.lang.String", "org.apache.commons.dbutils.ResultSetHandler", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").withParameters("java.lang.String").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").withParameters("java.lang.String", "java.lang.Object").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update", "execute").withParameters("java.lang.String", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("batch").withParameterCount(3).definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("insertBatch").withParameterCount(4).definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("query", "insert").withParameters("java.sql.Connection", "java.lang.String", "org.apache.commons.dbutils.ResultSetHandler", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("query", "insert", "execute").withParameters("java.sql.Connection", "java.lang.String", "org.apache.commons.dbutils.ResultSetHandler").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update").withParameters("java.sql.Connection", "java.lang.String").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update").withParameters("java.sql.Connection", "java.lang.String", "java.lang.Object").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(1, psiMethod().withName("update", "execute").withParameters("java.sql.Connection", "java.lang.String", "java.lang.Object...").definedInClass("org.apache.commons.dbutils.QueryRunner"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>R2DBC (io.r2dbc)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("add").definedInClass("io.r2dbc.spi.Batch"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createStatement").definedInClass("io.r2dbc.spi.Connection"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="PostgreSQL" injector-id="java">
|
||||||
|
<display-name>Reactiverse Postgres Client (io.reactiverse)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.reactiverse.pgclient.PgConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.reactiverse.pgclient.PgTransaction"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.reactiverse.reactivex.pgclient.PgClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.reactiverse.reactivex.pgclient.PgConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.reactiverse.reactivex.pgclient.PgPool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.reactiverse.reactivex.pgclient.PgTransaction"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.reactiverse.axle.pgclient.PgClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.reactiverse.pgclient.PgClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.reactiverse.pgclient.PgPool"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="http-header-reference" injector-id="java">
|
||||||
|
<display-name>RestAssured HTTP Header (io.restassured)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("addHeader").definedInClass("io.restassured.builder.RequestSpecBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header", "getHeader", "headers").definedInClass("io.restassured.response.ResponseOptions"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header", "getHeader", "headers").definedInClass("io.restassured.response.ValidatableResponseOptions"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header", "headers").definedInClass("io.restassured.specification.RequestSpecification"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>SmallRye Axle SqlClient (io.vertx.axle.sqlclient)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.vertx.axle.sqlclient.Pool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.vertx.axle.sqlclient.SqlClient"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>SmallRye Mutiny SqlClient (io.vertx.mutiny.sqlclient)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.vertx.mutiny.sqlclient.Pool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "preparedQuery", "preparedBatch").definedInClass("io.vertx.mutiny.sqlclient.SqlClient"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>SmallRye Mutiny SqlConnection (io.vertx.mutiny.sqlclient)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("prepare", "prepareAndAwait").definedInClass("io.vertx.mutiny.db2client.DB2Connection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("prepare", "prepareAndAwait").definedInClass("io.vertx.mutiny.mssqlclient.MSSQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("prepare", "prepareAndAwait").definedInClass("io.vertx.mutiny.mysqlclient.MySQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("prepare", "prepareAndAwait").definedInClass("io.vertx.mutiny.pgclient.PgConnection"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SpEL" injector-id="java">
|
||||||
|
<display-name>Spring @Cacheable and @CacheEvict</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiMethod().withName("condition").withParameters().definedInClass("org.springframework.cache.annotation.CacheEvict")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("condition").withParameters().definedInClass("org.springframework.cache.annotation.CachePut")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("condition").withParameters().definedInClass("org.springframework.cache.annotation.Cacheable")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("key").withParameters().definedInClass("org.springframework.cache.annotation.CacheEvict")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("key").withParameters().definedInClass("org.springframework.cache.annotation.CachePut")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("key").withParameters().definedInClass("org.springframework.cache.annotation.Cacheable")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("unless").withParameters().definedInClass("org.springframework.cache.annotation.CachePut")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("unless").withParameters().definedInClass("org.springframework.cache.annotation.Cacheable")]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="http-header-reference" injector-id="java">
|
||||||
|
<display-name>Spring HttpHeaders (org.springframework.http)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header").definedInClass("org.springframework.http.ResponseEntity.HeadersBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("header").definedInClass("org.springframework.web.servlet.function.ServerResponse.HeadersBuilder"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("set", "add", "addAll", "getFirst", "containsKey", "get", "put", "getFirstDate", "setDate", "setInstant", "setZonedDateTime").definedInClass("org.springframework.http.HttpHeaders"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SpEL" injector-id="java">
|
||||||
|
<display-name>Spring Integration/Messaging</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiMethod().withName("expression").withParameters().definedInClass("org.springframework.messaging.handler.annotation.Payload")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.integration.annotation.Payload")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.messaging.handler.annotation.Payload")]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Spring JDBC (org.springframework.jdbc.core.JdbcOperations)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("batchUpdate").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("execute").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForInt").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForList").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForLong").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForMap").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForObject").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForRowSet").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("queryForStream").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("sql").definedInClass("org.springframework.jdbc.core.simple.JdbcClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("update").definedInClass("org.springframework.jdbc.core.JdbcOperations"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Spring JDBC (org.springframework.jdbc.core.PreparedStatementCreatorFactory)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("PreparedStatementCreatorFactory").withParameters("java.lang.String").definedInClass("org.springframework.jdbc.core.PreparedStatementCreatorFactory"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("PreparedStatementCreatorFactory").withParameters("java.lang.String", "int[]").definedInClass("org.springframework.jdbc.core.PreparedStatementCreatorFactory"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("PreparedStatementCreatorFactory").withParameters("java.lang.String", "java.util.List").definedInClass("org.springframework.jdbc.core.PreparedStatementCreatorFactory"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Spring JDBC (org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("createCustomException").withParameters("java.lang.String", "java.lang.String", "java.sql.SQLException", "java.lang.Class").definedInClass("org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("customTranslate").withParameters("java.lang.String", "java.lang.String", "java.sql.SQLException").definedInClass("org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("doTranslate").withParameters("java.lang.String", "java.lang.String", "java.sql.SQLException").definedInClass("org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("logTranslation").withParameters("java.lang.String", "java.lang.String", "java.sql.SQLException", "boolean").definedInClass("org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SpEL" injector-id="java">
|
||||||
|
<display-name>Spring Security @PostAuthorize/@PostFilter/@PreAuthorize/@PreFilter/@AuthenticationPrincipal</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiMethod().withName("expression").withParameters().definedInClass("org.springframework.security.core.annotation.AuthenticationPrincipal")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("expression").withParameters().definedInClass("org.springframework.security.core.annotation.CurrentSecurityContext")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.security.access.prepost.PostAuthorize")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.security.access.prepost.PostFilter")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.security.access.prepost.PreAuthorize")]]></place>
|
||||||
|
<place><![CDATA[psiMethod().withName("value").withParameters().definedInClass("org.springframework.security.access.prepost.PreFilter")]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SpEL" injector-id="java">
|
||||||
|
<display-name>Spring State Machine</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("event").withParameters("java.lang.String").definedInClass("org.springframework.statemachine.config.configurers.SecurityConfigurer"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("guardExpression").withParameters("java.lang.String").definedInClass("org.springframework.statemachine.config.configurers.TransitionConfigurer"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("secured").withParameters("java.lang.String").definedInClass("org.springframework.statemachine.config.configurers.TransitionConfigurer"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("transition").withParameters("java.lang.String").definedInClass("org.springframework.statemachine.config.configurers.SecurityConfigurer"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Vert.x SQL Extensions (io.vertx.ext.sql)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams").definedInClass("io.vertx.ext.sql.SQLClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams").definedInClass("io.vertx.ext.sql.SQLOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams", "execute", "batchWithParams", "batchCallableWithParams").definedInClass("io.vertx.ext.sql.SQLConnection"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Vert.x SQL Reactive Extensions (io.vertx.reactivex.ext.sql)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams").definedInClass("io.vertx.reactivex.ext.sql.SQLOperations"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams", "execute", "batchWithParams", "batchCallableWithParams", "rxQuerySingle", "rxQuerySingleWithParams", "rxQuery", "rxQueryWithParams", "rxQueryStream", "rxQueryStreamWithParams", "rxUpdate", "rxUpdateWithParams", "rxCall", "rxCallWithParams", "rxExecute", "rxBatchWithParams", "rxBatchCallableWithParams").definedInClass("io.vertx.reactivex.ext.sql.SQLClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "queryWithParams", "queryStream", "queryStreamWithParams", "querySingle", "querySingleWithParams", "update", "updateWithParams", "call", "callWithParams", "execute", "batchWithParams", "batchCallableWithParams", "rxQuerySingle", "rxQuerySingleWithParams", "rxQuery", "rxQueryWithParams", "rxQueryStream", "rxQueryStreamWithParams", "rxUpdate", "rxUpdateWithParams", "rxCall", "rxCallWithParams", "rxExecute", "rxBatchWithParams", "rxBatchCallableWithParams").definedInClass("io.vertx.reactivex.ext.sql.SQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("querySingle", "rxQuerySingle", "querySingleWithParams", "rxQuerySingleWithParams").definedInClass("io.vertx.reactivex.ext.asyncsql.AsyncSQLClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("querySingle", "rxQuerySingle", "querySingleWithParams", "rxQuerySingleWithParams").definedInClass("io.vertx.reactivex.ext.asyncsql.MySQLClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("querySingle", "rxQuerySingle", "querySingleWithParams", "rxQuerySingleWithParams").definedInClass("io.vertx.reactivex.ext.asyncsql.PostgreSQLClient"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Vert.x SqlClient (io.vertx.sqlclient)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.mssqlclient.MSSQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.mysqlclient.MySQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.pgclient.PgConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.sqlclient.Pool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.sqlclient.SqlClient"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.sqlclient.SqlConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch").definedInClass("io.vertx.sqlclient.Transaction"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>Vert.x SqlClient RxJava2 (io.vertx.reactivex.sqlclient)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.mysqlclient.MySQLConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.pgclient.PgConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.sqlclient.SqlConnection"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPrepare", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.sqlclient.Transaction"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.mysqlclient.MySQLPool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.pgclient.PgPool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.sqlclient.Pool"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "prepare", "preparedQuery", "preparedBatch", "rxQuery", "rxPreparedQuery", "rxPreparedBatch").definedInClass("io.vertx.reactivex.sqlclient.SqlClient"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="JSON" injector-id="java">
|
||||||
|
<display-name>WireMock (com.github.tomakehurst.wiremock.client)</display-name>
|
||||||
|
<single-file value="false" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("equalToJson").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("equalToJson").withParameters("java.lang.String", "boolean", "boolean").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("jsonResponse").withParameters("java.lang.String", "int").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("okJson").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="XML" injector-id="java">
|
||||||
|
<display-name>WireMock (com.github.tomakehurst.wiremock.client)</display-name>
|
||||||
|
<single-file value="false" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("equalToXml").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("okTextXml").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("okXml").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="RegExp" injector-id="java">
|
||||||
|
<display-name>WireMock (com.github.tomakehurst.wiremock.client)</display-name>
|
||||||
|
<single-file value="false" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("matching").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("notMatching").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("urlMatching").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("urlPathMatching").withParameters("java.lang.String").definedInClass("com.github.tomakehurst.wiremock.client.WireMock"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>jOOQ (org.jooq.DSLContext)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("batch").withParameters("java.lang.String", "java.lang.Object[]...").definedInClass("org.jooq.DSLContext"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "fetch", "fetchLazy", "fetchAsync", "fetchStream", "fetchMany", "fetchOne", "fetchSingle", "fetchOptional", "fetchValue", "fetchOptionalValue", "fetchValues", "execute", "resultQuery").withParameters("java.lang.String", "java.lang.Object...").definedInClass("org.jooq.DSLContext"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("query", "fetch", "fetchLazy", "fetchAsync", "fetchStream", "fetchMany", "fetchOne", "fetchSingle", "fetchOptional", "fetchValue", "fetchOptionalValue", "fetchValues", "execute", "resultQuery", "batch").withParameters("java.lang.String").definedInClass("org.jooq.DSLContext"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(psiMethod().withName("batch").withParameters("java.lang.String...").definedInClass("org.jooq.DSLContext"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SQL" injector-id="java">
|
||||||
|
<display-name>rxjava2-jdbc (org.davidmoten.rx.jdbc)</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[psiMethod().withName("value").definedInClass("org.davidmoten.rx.jdbc.annotations.Query")]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("call", "select", "update").definedInClass("org.davidmoten.rx.jdbc.Database"))]]></place>
|
||||||
|
<place><![CDATA[psiParameter().ofMethod(0, psiMethod().withName("call", "select", "update").definedInClass("org.davidmoten.rx.jdbc.TransactedBuilder"))]]></place>
|
||||||
|
</injection>
|
||||||
|
<injection language="SpEL" injector-id="xml">
|
||||||
|
<display-name>SpEL for Spring Cache</display-name>
|
||||||
|
<single-file value="true" />
|
||||||
|
<place><![CDATA[xmlAttribute().withLocalName("condition").withParent(xmlTag().withNamespace(string().equalTo("http://www.springframework.org/schema/cache")))]]></place>
|
||||||
|
<place><![CDATA[xmlAttribute().withLocalName("key").withParent(xmlTag().withNamespace(string().equalTo("http://www.springframework.org/schema/cache")))]]></place>
|
||||||
|
<place><![CDATA[xmlAttribute().withLocalName("unless").withParent(xmlTag().withNamespace(string().equalTo("http://www.springframework.org/schema/cache")))]]></place>
|
||||||
|
</injection>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
28
.idea/dataSources.xml
generated
28
.idea/dataSources.xml
generated
@@ -1,11 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="NBA@110.42.255.182" uuid="989a1610-33a4-4371-ba47-77639ee274e4">
|
<data-source source="LOCAL" name="nba@154.36.154.211" uuid="989a1610-33a4-4371-ba47-77639ee274e4">
|
||||||
<driver-ref>mysql.8</driver-ref>
|
<driver-ref>mysql.8</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||||
<jdbc-url>jdbc:mysql://110.42.255.182:3306/NBA</jdbc-url>
|
<jdbc-url>jdbc:mysql://154.36.154.211:9002/nba</jdbc-url>
|
||||||
|
<jdbc-additional-properties>
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||||
|
</jdbc-additional-properties>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
</data-source>
|
||||||
|
<data-source source="LOCAL" name="@103.244.88.91" uuid="198b1b07-b5bc-4475-ad72-25ab848d510c">
|
||||||
|
<driver-ref>redis</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:redis://103.244.88.91:6739/</jdbc-url>
|
||||||
|
<jdbc-additional-properties>
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||||
|
</jdbc-additional-properties>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
</data-source>
|
||||||
|
<data-source source="LOCAL" name="0@154.36.154.211" uuid="310cedf0-fad7-43c7-84b6-88e011089af6">
|
||||||
|
<driver-ref>redis</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:redis://154.36.154.211:6379/0</jdbc-url>
|
||||||
<jdbc-additional-properties>
|
<jdbc-additional-properties>
|
||||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
|||||||
11
.idea/db-forest-config.xml
generated
Normal file
11
.idea/db-forest-config.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="db-forest-configuration">
|
||||||
|
<data version="2">.
|
||||||
|
----------------------------------------
|
||||||
|
1:0:989a1610-33a4-4371-ba47-77639ee274e4
|
||||||
|
2:0:198b1b07-b5bc-4475-ad72-25ab848d510c
|
||||||
|
3:0:310cedf0-fad7-43c7-84b6-88e011089af6
|
||||||
|
.</data>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
563
.idea/dbnavigator.xml
generated
Normal file
563
.idea/dbnavigator.xml
generated
Normal file
@@ -0,0 +1,563 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DBNavigator.Project.DDLFileAttachmentManager">
|
||||||
|
<mappings />
|
||||||
|
<preferences />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseAssistantManager">
|
||||||
|
<assistants />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||||
|
<autoscroll-to-editor value="false" />
|
||||||
|
<autoscroll-from-editor value="true" />
|
||||||
|
<show-object-properties value="true" />
|
||||||
|
<loaded-nodes />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseConsoleManager">
|
||||||
|
<connection id="2a966116-5af8-4991-8ec7-bb1cab412346">
|
||||||
|
<console name="Connection" type="STANDARD" schema="nba" session="Main" />
|
||||||
|
</connection>
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||||
|
<open-files />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatasetFilterManager">
|
||||||
|
<filter-actions connection-id="2a966116-5af8-4991-8ec7-bb1cab412346" dataset="nba.nba_user" active-filter-id="" />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.ObjectQuickFilterManager">
|
||||||
|
<last-used-operator value="EQUAL" />
|
||||||
|
<filters />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.Settings">
|
||||||
|
<connections>
|
||||||
|
<connection source-id="" id="2a966116-5af8-4991-8ec7-bb1cab412346" active="true" signed="true">
|
||||||
|
<database>
|
||||||
|
<name value="Connection" />
|
||||||
|
<description value="" />
|
||||||
|
<database-type value="MYSQL" />
|
||||||
|
<config-type value="BASIC" />
|
||||||
|
<database-version value="5.7" />
|
||||||
|
<driver-source value="BUNDLED" />
|
||||||
|
<driver-library value="" />
|
||||||
|
<driver value="" />
|
||||||
|
<url-type value="DATABASE" />
|
||||||
|
<host value="103.244.88.91" />
|
||||||
|
<port value="3306" />
|
||||||
|
<database value="nba" />
|
||||||
|
<tns-folder value="" />
|
||||||
|
<tns-profile value="" />
|
||||||
|
<server-type value="" />
|
||||||
|
<protocol value="" />
|
||||||
|
<url-parameters />
|
||||||
|
<type value="USER_PASSWORD" />
|
||||||
|
<user value="nba" />
|
||||||
|
<token-type value="" />
|
||||||
|
<token-config-file value="" />
|
||||||
|
<token-profile value="" />
|
||||||
|
<session-user value="nba@182.101.122.174" />
|
||||||
|
</database>
|
||||||
|
<properties>
|
||||||
|
<auto-commit value="false" />
|
||||||
|
</properties>
|
||||||
|
<ssh-settings>
|
||||||
|
<active value="false" />
|
||||||
|
<proxy-host value="" />
|
||||||
|
<proxy-port value="22" />
|
||||||
|
<proxy-user value="" />
|
||||||
|
<auth-type value="PASSWORD" />
|
||||||
|
<key-file value="" />
|
||||||
|
</ssh-settings>
|
||||||
|
<ssl-settings>
|
||||||
|
<active value="false" />
|
||||||
|
<certificate-authority-file value="" />
|
||||||
|
<client-certificate-file value="" />
|
||||||
|
<client-key-file value="" />
|
||||||
|
</ssl-settings>
|
||||||
|
<details>
|
||||||
|
<charset value="UTF-8" />
|
||||||
|
<session-management value="true" />
|
||||||
|
<ddl-file-binding value="true" />
|
||||||
|
<database-logging value="true" />
|
||||||
|
<connect-automatically value="true" />
|
||||||
|
<restore-workspace value="true" />
|
||||||
|
<restore-workspace-deep value="false" />
|
||||||
|
<environment-type value="default" />
|
||||||
|
<connectivity-timeout value="30" />
|
||||||
|
<idle-time-to-disconnect value="30" />
|
||||||
|
<idle-time-to-disconnect-pool value="5" />
|
||||||
|
<credential-expiry-time value="10" />
|
||||||
|
<max-connection-pool-size value="7" />
|
||||||
|
<alternative-statement-delimiter value="" />
|
||||||
|
</details>
|
||||||
|
<debugger>
|
||||||
|
<compile-dependencies value="true" />
|
||||||
|
<tcp-driver-tunneling value="false" />
|
||||||
|
<tcp-host-address value="" />
|
||||||
|
<tcp-port-from value="4000" />
|
||||||
|
<tcp-port-to value="4999" />
|
||||||
|
<debugger-type value="ASK" />
|
||||||
|
</debugger>
|
||||||
|
<object-filters hide-empty-schemas="false" hide-pseudo-columns="false" hide-audit-columns="false">
|
||||||
|
<object-filters />
|
||||||
|
<object-type-filter use-master-settings="true">
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="true" />
|
||||||
|
<object-type name="ROLE" enabled="true" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="true" />
|
||||||
|
<object-type name="CHARSET" enabled="true" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="JSON_VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||||
|
<object-type name="NESTED_TABLE" enabled="true" />
|
||||||
|
<object-type name="COLUMN" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="true" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||||
|
<object-type name="ARGUMENT" enabled="true" />
|
||||||
|
<object-type name="JAVA_CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA_FIELD" enabled="true" />
|
||||||
|
<object-type name="JAVA_METHOD" enabled="true" />
|
||||||
|
<object-type name="JAVA_RESOURCE" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="true" />
|
||||||
|
<object-type name="CLUSTER" enabled="true" />
|
||||||
|
<object-type name="DBLINK" enabled="true" />
|
||||||
|
<object-type name="CREDENTIAL" enabled="true" />
|
||||||
|
<object-type name="AI_PROFILE" enabled="true" />
|
||||||
|
</object-type-filter>
|
||||||
|
</object-filters>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<browser-settings>
|
||||||
|
<general>
|
||||||
|
<display-mode value="TABBED" />
|
||||||
|
<navigation-history-size value="100" />
|
||||||
|
<show-object-details value="false" />
|
||||||
|
<enable-sticky-paths value="true" />
|
||||||
|
<enable-quick-filters value="false" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<object-type-filter>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="true" />
|
||||||
|
<object-type name="ROLE" enabled="true" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="true" />
|
||||||
|
<object-type name="CHARSET" enabled="true" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="JSON_VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||||
|
<object-type name="NESTED_TABLE" enabled="true" />
|
||||||
|
<object-type name="COLUMN" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="true" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||||
|
<object-type name="ARGUMENT" enabled="true" />
|
||||||
|
<object-type name="JAVA_CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA_FIELD" enabled="true" />
|
||||||
|
<object-type name="JAVA_METHOD" enabled="true" />
|
||||||
|
<object-type name="JAVA_RESOURCE" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="true" />
|
||||||
|
<object-type name="CLUSTER" enabled="true" />
|
||||||
|
<object-type name="DBLINK" enabled="true" />
|
||||||
|
<object-type name="CREDENTIAL" enabled="true" />
|
||||||
|
<object-type name="AI_PROFILE" enabled="true" />
|
||||||
|
</object-type-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting>
|
||||||
|
<object-type name="COLUMN" sorting-type="NAME" />
|
||||||
|
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||||
|
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||||
|
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||||
|
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||||
|
</sorting>
|
||||||
|
<default-editors>
|
||||||
|
<object-type name="VIEW" editor-type="SELECTION" />
|
||||||
|
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||||
|
<object-type name="TYPE" editor-type="SELECTION" />
|
||||||
|
</default-editors>
|
||||||
|
</browser-settings>
|
||||||
|
<navigation-settings>
|
||||||
|
<lookup-filters>
|
||||||
|
<lookup-objects>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="false" />
|
||||||
|
<object-type name="ROLE" enabled="false" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="false" />
|
||||||
|
<object-type name="CHARSET" enabled="false" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="JSON VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="false" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="JAVA CLASS" enabled="true" />
|
||||||
|
<object-type name="INNER CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA FIELD" enabled="true" />
|
||||||
|
<object-type name="JAVA METHOD" enabled="true" />
|
||||||
|
<object-type name="JAVA PARAMETER" enabled="true" />
|
||||||
|
<object-type name="JAVA RESOURCE" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="false" />
|
||||||
|
<object-type name="CLUSTER" enabled="false" />
|
||||||
|
<object-type name="DBLINK" enabled="false" />
|
||||||
|
<object-type name="CREDENTIAL" enabled="false" />
|
||||||
|
</lookup-objects>
|
||||||
|
<force-database-load value="false" />
|
||||||
|
<prompt-connection-selection value="true" />
|
||||||
|
<prompt-schema-selection value="true" />
|
||||||
|
</lookup-filters>
|
||||||
|
</navigation-settings>
|
||||||
|
<dataset-grid-settings>
|
||||||
|
<general>
|
||||||
|
<enable-zooming value="true" />
|
||||||
|
<enable-column-tooltip value="true" />
|
||||||
|
</general>
|
||||||
|
<sorting>
|
||||||
|
<nulls-first value="true" />
|
||||||
|
<max-sorting-columns value="4" />
|
||||||
|
</sorting>
|
||||||
|
<audit-columns>
|
||||||
|
<column-names value="" />
|
||||||
|
<visible value="true" />
|
||||||
|
<editable value="false" />
|
||||||
|
</audit-columns>
|
||||||
|
</dataset-grid-settings>
|
||||||
|
<dataset-editor-settings>
|
||||||
|
<text-editor-popup>
|
||||||
|
<active value="false" />
|
||||||
|
<active-if-empty value="false" />
|
||||||
|
<data-length-threshold value="100" />
|
||||||
|
<popup-delay value="1000" />
|
||||||
|
</text-editor-popup>
|
||||||
|
<values-actions-popup>
|
||||||
|
<show-popup-button value="true" />
|
||||||
|
<element-count-threshold value="1000" />
|
||||||
|
<data-length-threshold value="250" />
|
||||||
|
</values-actions-popup>
|
||||||
|
<general>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<fetch-timeout value="30" />
|
||||||
|
<trim-whitespaces value="true" />
|
||||||
|
<convert-empty-strings-to-null value="true" />
|
||||||
|
<select-content-on-cell-edit value="true" />
|
||||||
|
<large-value-preview-active value="true" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<prompt-filter-dialog value="true" />
|
||||||
|
<default-filter-type value="BASIC" />
|
||||||
|
</filters>
|
||||||
|
<qualified-text-editor text-length-threshold="300">
|
||||||
|
<content-types>
|
||||||
|
<content-type name="Text" enabled="true" />
|
||||||
|
<content-type name="Properties" enabled="true" />
|
||||||
|
<content-type name="XML" enabled="true" />
|
||||||
|
<content-type name="DTD" enabled="true" />
|
||||||
|
<content-type name="HTML" enabled="true" />
|
||||||
|
<content-type name="XHTML" enabled="true" />
|
||||||
|
<content-type name="Java" enabled="true" />
|
||||||
|
<content-type name="SQL" enabled="true" />
|
||||||
|
<content-type name="PL/SQL" enabled="true" />
|
||||||
|
<content-type name="JSON" enabled="true" />
|
||||||
|
<content-type name="JSON5" enabled="true" />
|
||||||
|
<content-type name="Groovy" enabled="true" />
|
||||||
|
<content-type name="YAML" enabled="true" />
|
||||||
|
<content-type name="Manifest" enabled="true" />
|
||||||
|
</content-types>
|
||||||
|
</qualified-text-editor>
|
||||||
|
<record-navigation>
|
||||||
|
<navigation-target value="VIEWER" />
|
||||||
|
</record-navigation>
|
||||||
|
</dataset-editor-settings>
|
||||||
|
<code-editor-settings>
|
||||||
|
<general>
|
||||||
|
<show-object-navigation-gutter value="false" />
|
||||||
|
<show-spec-declaration-navigation-gutter value="true" />
|
||||||
|
<enable-spellchecking value="true" />
|
||||||
|
<enable-reference-spellchecking value="false" />
|
||||||
|
</general>
|
||||||
|
<confirmations>
|
||||||
|
<save-changes value="false" />
|
||||||
|
<revert-changes value="true" />
|
||||||
|
<exit-on-changes value="ASK" />
|
||||||
|
</confirmations>
|
||||||
|
</code-editor-settings>
|
||||||
|
<code-completion-settings>
|
||||||
|
<filters>
|
||||||
|
<basic-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</basic-filter>
|
||||||
|
<extended-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="json view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</extended-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting enabled="true">
|
||||||
|
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||||
|
<sorting-element type="OBJECT" id="column" />
|
||||||
|
<sorting-element type="OBJECT" id="table" />
|
||||||
|
<sorting-element type="OBJECT" id="view" />
|
||||||
|
<sorting-element type="OBJECT" id="json view" />
|
||||||
|
<sorting-element type="OBJECT" id="materialized view" />
|
||||||
|
<sorting-element type="OBJECT" id="index" />
|
||||||
|
<sorting-element type="OBJECT" id="constraint" />
|
||||||
|
<sorting-element type="OBJECT" id="trigger" />
|
||||||
|
<sorting-element type="OBJECT" id="synonym" />
|
||||||
|
<sorting-element type="OBJECT" id="sequence" />
|
||||||
|
<sorting-element type="OBJECT" id="procedure" />
|
||||||
|
<sorting-element type="OBJECT" id="function" />
|
||||||
|
<sorting-element type="OBJECT" id="package" />
|
||||||
|
<sorting-element type="OBJECT" id="type" />
|
||||||
|
<sorting-element type="OBJECT" id="dimension" />
|
||||||
|
<sorting-element type="OBJECT" id="cluster" />
|
||||||
|
<sorting-element type="OBJECT" id="dblink" />
|
||||||
|
<sorting-element type="OBJECT" id="schema" />
|
||||||
|
<sorting-element type="OBJECT" id="role" />
|
||||||
|
<sorting-element type="OBJECT" id="user" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="function" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||||
|
</sorting>
|
||||||
|
<format>
|
||||||
|
<enforce-code-style-case value="true" />
|
||||||
|
</format>
|
||||||
|
</code-completion-settings>
|
||||||
|
<execution-engine-settings>
|
||||||
|
<statement-execution>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<execution-timeout value="20" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<focus-result value="false" />
|
||||||
|
<prompt-execution value="false" />
|
||||||
|
</statement-execution>
|
||||||
|
<script-execution>
|
||||||
|
<command-line-interfaces />
|
||||||
|
<execution-timeout value="300" />
|
||||||
|
</script-execution>
|
||||||
|
<method-execution>
|
||||||
|
<execution-timeout value="30" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<parameter-history-size value="10" />
|
||||||
|
</method-execution>
|
||||||
|
</execution-engine-settings>
|
||||||
|
<operation-settings>
|
||||||
|
<transactions>
|
||||||
|
<uncommitted-changes>
|
||||||
|
<on-project-close value="ASK" />
|
||||||
|
<on-disconnect value="ASK" />
|
||||||
|
<on-autocommit-toggle value="ASK" />
|
||||||
|
</uncommitted-changes>
|
||||||
|
<multiple-uncommitted-changes>
|
||||||
|
<on-commit value="ASK" />
|
||||||
|
<on-rollback value="ASK" />
|
||||||
|
</multiple-uncommitted-changes>
|
||||||
|
</transactions>
|
||||||
|
<session-browser>
|
||||||
|
<disconnect-session value="ASK" />
|
||||||
|
<kill-session value="ASK" />
|
||||||
|
<reload-on-filter-change value="false" />
|
||||||
|
</session-browser>
|
||||||
|
<compiler>
|
||||||
|
<compile-type value="KEEP" />
|
||||||
|
<compile-dependencies value="ASK" />
|
||||||
|
<always-show-controls value="false" />
|
||||||
|
</compiler>
|
||||||
|
</operation-settings>
|
||||||
|
<ddl-file-settings>
|
||||||
|
<extensions>
|
||||||
|
<mapping file-type-id="VIEW" extensions="vw" />
|
||||||
|
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||||
|
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||||
|
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||||
|
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||||
|
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||||
|
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||||
|
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||||
|
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||||
|
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||||
|
<mapping file-type-id="JAVA_SOURCE" extensions="sql" />
|
||||||
|
</extensions>
|
||||||
|
<general>
|
||||||
|
<lookup-ddl-files value="true" />
|
||||||
|
<create-ddl-files value="false" />
|
||||||
|
<synchronize-ddl-files value="true" />
|
||||||
|
<use-qualified-names value="false" />
|
||||||
|
<make-scripts-rerunnable value="true" />
|
||||||
|
</general>
|
||||||
|
</ddl-file-settings>
|
||||||
|
<assistant-settings>
|
||||||
|
<credential-settings>
|
||||||
|
<credentials />
|
||||||
|
</credential-settings>
|
||||||
|
</assistant-settings>
|
||||||
|
<general-settings>
|
||||||
|
<regional-settings>
|
||||||
|
<date-format value="MEDIUM" />
|
||||||
|
<number-format value="UNGROUPED" />
|
||||||
|
<locale value="zh" />
|
||||||
|
<use-custom-formats value="false" />
|
||||||
|
</regional-settings>
|
||||||
|
<environment>
|
||||||
|
<environment-types>
|
||||||
|
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||||
|
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||||
|
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||||
|
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||||
|
</environment-types>
|
||||||
|
<visibility-settings>
|
||||||
|
<connection-tabs value="true" />
|
||||||
|
<dialog-headers value="true" />
|
||||||
|
<object-editor-tabs value="true" />
|
||||||
|
<script-editor-tabs value="false" />
|
||||||
|
<execution-result-tabs value="true" />
|
||||||
|
</visibility-settings>
|
||||||
|
</environment>
|
||||||
|
</general-settings>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -8,7 +8,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
7
.idea/mybatisx/templates.xml
generated
7
.idea/mybatisx/templates.xml
generated
@@ -37,19 +37,18 @@
|
|||||||
<option name="fileName" value="${domain.fileName}Mapper" />
|
<option name="fileName" value="${domain.fileName}Mapper" />
|
||||||
<option name="fileNameWithSuffix" value="${domain.fileName}Mapper.xml" />
|
<option name="fileNameWithSuffix" value="${domain.fileName}Mapper.xml" />
|
||||||
<option name="modulePath" value="$PROJECT_DIR$" />
|
<option name="modulePath" value="$PROJECT_DIR$" />
|
||||||
<option name="packageName" value="mapper" />
|
<option name="packageName" value="${domain.basePackage}.mapper" />
|
||||||
</ModuleInfoGo>
|
</ModuleInfoGo>
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
<option name="needsComment" value="true" />
|
|
||||||
<option name="needsModel" value="true" />
|
<option name="needsModel" value="true" />
|
||||||
<option name="relativePackage" value="pojo" />
|
<option name="relativePackage" value="pojo" />
|
||||||
<option name="superClass" value="" />
|
<option name="superClass" value="" />
|
||||||
<option name="tableUIInfoList">
|
<option name="tableUIInfoList">
|
||||||
<list>
|
<list>
|
||||||
<TableUIInfo>
|
<TableUIInfo>
|
||||||
<option name="className" value="Games" />
|
<option name="className" value="LoginLog" />
|
||||||
<option name="tableName" value="games" />
|
<option name="tableName" value="login_log" />
|
||||||
</TableUIInfo>
|
</TableUIInfo>
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
|
|||||||
43
README.md
Normal file
43
README.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# NBA赛事共享在线观看平台
|
||||||
|
|
||||||
|
## 项目简介
|
||||||
|
|
||||||
|
本项目是一个基于 NBA 赛事的共享在线观看平台,支持实时展示赛程、赛事直播播放等功能。用户可以便捷地浏览最新赛程信息,并使用内嵌播放器观看赛事直播。平台通过整合腾讯体育资源,自动化采集与维护直播数据,实现赛事数据的高效管理与分享。
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
### 后端技术
|
||||||
|
- **Spring Boot**:构建高性能的后端服务。
|
||||||
|
- **MyBatis**:简化数据库操作,灵活执行 SQL。
|
||||||
|
- **MySQL**:存储赛程、直播间等核心数据。
|
||||||
|
- **Redis**:缓存腾讯体育 Cookie 及直播数据,提升请求效率。
|
||||||
|
- **Scheduled Task**:定时任务机制,周期性同步直播信息。
|
||||||
|
|
||||||
|
### 前端技术
|
||||||
|
- **Vue 3**:构建响应式单页应用。
|
||||||
|
- **Pinia**:集中式状态管理,存储赛程相关数据。
|
||||||
|
- **Vue Router**:实现页面间路由导航。
|
||||||
|
- **Axios**:与后端进行 HTTP 通信。
|
||||||
|
- **DPlayer**:集成播放器,用于播放赛事直播流。
|
||||||
|
|
||||||
|
## 核心功能实现
|
||||||
|
|
||||||
|
- **Cookie自动更新与存储**:后端首次手动配置腾讯体育 Cookie 并保存至 Redis,通过定时任务定期刷新 Cookie,保证接口调用的稳定性。
|
||||||
|
- **直播数据采集**:根据数据库中的赛程 ID,携带 Cookie 向腾讯体育接口发起请求,抓取对应的直播间信息,并定期存储至直播间信息表。
|
||||||
|
- **前端展示与播放**:
|
||||||
|
- 使用 Axios 获取后端赛程数据,展示赛程信息。
|
||||||
|
- 用户点击感兴趣的赛程后,前端将相关 ID 保存到 Pinia 中,用于后续状态追踪与页面展示。
|
||||||
|
- 基于 DPlayer 实现直播流的嵌入播放体验。
|
||||||
|
|
||||||
|
## 项目亮点
|
||||||
|
|
||||||
|
- 实现与第三方平台(腾讯体育)无官方 API 接口的半自动数据采集与更新。
|
||||||
|
- 利用 Redis 缓存与定时刷新机制,提升系统稳定性与数据实时性。
|
||||||
|
- 前后端分离架构,增强了系统的可维护性和拓展性。
|
||||||
|
- 播放器集成体验良好,用户可便捷观看赛事直播。
|
||||||
|
|
||||||
|
## 后续优化方向
|
||||||
|
|
||||||
|
- 接入用户评论与弹幕系统,提升用户互动性。
|
||||||
|
- 增加赛事订阅与提醒功能,优化用户体验。
|
||||||
|
- 提升异常处理与容错机制,增强系统健壮性。
|
||||||
17
pom.xml
17
pom.xml
@@ -68,6 +68,23 @@
|
|||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.mail</groupId>
|
||||||
|
<artifactId>jakarta.mail</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.activation</groupId>
|
||||||
|
<artifactId>activation</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|||||||
public class GlobalException {
|
public class GlobalException {
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public Object handleException(Exception e) {
|
public Object handleException(Exception e) {
|
||||||
|
//e.printStackTrace();
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return e.getMessage();
|
return e.getMessage();
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/main/java/com/ping/study/config/RedisConf.java
Normal file
33
src/main/java/com/ping/study/config/RedisConf.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package com.ping.study.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RedisConf {
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||||
|
|
||||||
|
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||||
|
template.setConnectionFactory(factory);
|
||||||
|
|
||||||
|
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||||
|
GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
|
||||||
|
|
||||||
|
// key
|
||||||
|
template.setKeySerializer(stringRedisSerializer);
|
||||||
|
template.setHashKeySerializer(stringRedisSerializer);
|
||||||
|
|
||||||
|
// value
|
||||||
|
template.setValueSerializer(jsonSerializer);
|
||||||
|
template.setHashValueSerializer(jsonSerializer);
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,18 +2,37 @@ 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.bind.annotation.CrossOrigin;
|
||||||
import org.springframework.web.client.RestTemplate;
|
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.CorsRegistry;
|
||||||
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 {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCorsMappings(CorsRegistry registry) {
|
||||||
|
registry.addMapping("/**")
|
||||||
|
.allowedOrigins("http://jrs77.xyz","https://jrs77.xyz",
|
||||||
|
"http://localhost:5173", "https://nba.1024x.icu",
|
||||||
|
"http://nba.1024x.icu","http://167.253.156.235:9006",
|
||||||
|
"http://116.62.173.2:9001")
|
||||||
|
.allowedMethods("GET","POST","PUT","DELETE","OPTIONS")
|
||||||
|
.allowedHeaders("X-Timestamp","X-Sign","*")
|
||||||
|
.allowCredentials(true) // 若不用 Cookie 也可为 false
|
||||||
|
.maxAge(3600);
|
||||||
|
}
|
||||||
// 原有的 NBA WebClient
|
// 原有的 NBA WebClient
|
||||||
@Bean("nbaWebClient")
|
@Bean("nbaWebClient")
|
||||||
public WebClient nbaWebClient() {
|
public WebClient nbaWebClient() {
|
||||||
return WebClient.create("https://api.nba.cn/sib/v2");
|
return WebClient.create("https://api.nba.cn/sib/v2");
|
||||||
}
|
}
|
||||||
|
@Bean("matchWebClient")
|
||||||
|
public WebClient txWebClient() {
|
||||||
|
return WebClient.create("https://matchweb.sports.qq.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 新增的腾讯视频 WebClient
|
// 新增的腾讯视频 WebClient
|
||||||
@Bean("tencentWebClient")
|
@Bean("tencentWebClient")
|
||||||
|
|||||||
@@ -5,26 +5,37 @@ package com.ping.study.controller;
|
|||||||
import com.ping.study.model.dto.addUrls;
|
import com.ping.study.model.dto.addUrls;
|
||||||
import com.ping.study.model.vo.live.LiveUrl;
|
import com.ping.study.model.vo.live.LiveUrl;
|
||||||
import com.ping.study.pojo.Games;
|
import com.ping.study.pojo.Games;
|
||||||
|
import com.ping.study.pojo.NbaUser;
|
||||||
import com.ping.study.service.GamesService;
|
import com.ping.study.service.GamesService;
|
||||||
import com.ping.study.service.UrlsService;
|
import com.ping.study.service.UrlsService;
|
||||||
import com.ping.study.utils.NbaApi;
|
import com.ping.study.utils.NbaApi;
|
||||||
|
|
||||||
|
import com.ping.study.utils.UserUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
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.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@RequestMapping("/api")
|
@RequestMapping("/api")
|
||||||
@RestController
|
@RestController
|
||||||
@Data
|
@Data
|
||||||
@Slf4j
|
@Slf4j
|
||||||
//@CrossOrigin(origins = "http://nba.new9.me")
|
//@CrossOrigin(origins = {"http://nba.1024x.icu/","https://nba.1024x.icu/","http://localhost:5173/"})
|
||||||
@CrossOrigin
|
|
||||||
public class NbaController {
|
public class NbaController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -33,26 +44,59 @@ public class NbaController {
|
|||||||
private GamesService gamesService;
|
private GamesService gamesService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private UrlsService urlsService;
|
private UrlsService urlsService;
|
||||||
|
@Autowired
|
||||||
|
private UserUtil userUtil;
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> stringRedisTemplate;
|
||||||
|
|
||||||
//添加定时任务,每日凌晨0点执行一次
|
//添加定时任务,每日凌晨0点执行一次
|
||||||
// 每天 00:00:00 执行
|
// 每天 00:00:00 执行
|
||||||
@Scheduled(cron = "0 0 0 * * ?")
|
@Scheduled(cron = "0 0 0 * * ?")
|
||||||
@RequestMapping("/add")
|
@RequestMapping("/add")
|
||||||
public List<Games> addGames() {
|
public List<Games> addGames() throws InterruptedException {
|
||||||
//先删除数据库中所有赛程
|
//先删除数据库中所有赛程
|
||||||
log.info("执行定时方法删除数据库中所有赛程");
|
log.info("执行定时方法删除数据库中所有赛程");
|
||||||
gamesService.deleteAllGames();
|
gamesService.deleteAllGames();
|
||||||
|
Thread.sleep(100);
|
||||||
//再删除数据库中所有直播链接
|
//再删除数据库中所有直播链接
|
||||||
log.info("执行定时方法删除数据库中所有直播链接");
|
log.info("执行定时方法删除数据库中所有直播链接");
|
||||||
urlsService.deleteAllUrls();
|
urlsService.deleteAllUrls();
|
||||||
|
Thread.sleep(100);
|
||||||
log.info("执行定时方法添加当天赛程");
|
log.info("执行定时方法添加当天赛程");
|
||||||
return nbaApi.addGames();
|
List<Games> gamesList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
gamesList = nbaApi.addGames();
|
||||||
|
if (gamesList.isEmpty()){
|
||||||
|
stringRedisTemplate.opsForValue().set("games","0");
|
||||||
|
}
|
||||||
|
stringRedisTemplate.delete("live:urls:all");
|
||||||
|
log.info("添加赛程成功:{}",gamesList);
|
||||||
|
}catch (Exception e){
|
||||||
|
stringRedisTemplate.opsForValue().set("games","0");
|
||||||
|
log.info("添加赛程失败:{}",e.getMessage());
|
||||||
|
}
|
||||||
|
return gamesList;
|
||||||
}
|
}
|
||||||
@Scheduled(cron = "0 0 0 * * ?")
|
|
||||||
@RequestMapping("/updateLive")
|
|
||||||
public void updateLive() {
|
|
||||||
log.info("执行定时方法更新当天赛程直播链接");
|
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0/10 0-1 * * ?")
|
||||||
|
public void updateGames(){
|
||||||
|
String games_status = stringRedisTemplate.opsForValue().get("games");
|
||||||
|
List<Games> gamesList = new ArrayList<>();
|
||||||
|
if (Objects.equals(games_status, "0")){
|
||||||
|
try {
|
||||||
|
gamesList = nbaApi.addGames();
|
||||||
|
if (gamesList.isEmpty()){
|
||||||
|
stringRedisTemplate.opsForValue().set("games","0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stringRedisTemplate.opsForValue().set("games","1");
|
||||||
|
stringRedisTemplate.delete("live:urls:all");
|
||||||
|
}catch (Exception e){
|
||||||
|
stringRedisTemplate.opsForValue().set("games","0");
|
||||||
|
log.info("添加赛程失败:{}",e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("=======跳过更新数据库赛程========");
|
||||||
}
|
}
|
||||||
@RequestMapping("/games")
|
@RequestMapping("/games")
|
||||||
public List<Games> getGames() {
|
public List<Games> getGames() {
|
||||||
@@ -60,12 +104,85 @@ public class NbaController {
|
|||||||
return gamesService.getGames();
|
return gamesService.getGames();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/urls")
|
// @RequestMapping("/urls")
|
||||||
public List<HashMap<String, List<LiveUrl>>> getUrls() {
|
// public List<HashMap<String, List<LiveUrl>>> getUrls() {
|
||||||
log.info("获取所有赛程直播链接");
|
// log.info("获取所有赛程直播链接");
|
||||||
return urlsService.getUrls();
|
// return urlsService.getUrls();
|
||||||
|
// }
|
||||||
|
|
||||||
|
//根据比赛id和直播流类型获取流
|
||||||
|
@GetMapping("/live/url")
|
||||||
|
public ResponseEntity<?> getPlayUrl(
|
||||||
|
@RequestParam("gameId") String gameId,
|
||||||
|
@RequestParam("type") String playType,
|
||||||
|
@RequestHeader(value = "X-Timestamp", required = false) String timestamp,
|
||||||
|
@RequestHeader(value = "X-Sign", required = false) String sign,
|
||||||
|
HttpSession session,
|
||||||
|
HttpServletRequest request
|
||||||
|
) throws Exception {
|
||||||
|
|
||||||
|
String secretKey = "20251125";
|
||||||
|
if (timestamp == null || sign == null) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Missing headers");
|
||||||
|
}
|
||||||
|
// 超时校验(5分钟内有效)
|
||||||
|
long ts = Long.parseLong(timestamp);
|
||||||
|
if (Math.abs(System.currentTimeMillis() - ts) > 5 * 60 * 1000) {
|
||||||
|
// log.info("Request expired: " + timestamp);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Request expired");
|
||||||
|
}
|
||||||
|
// log.info("Request timestamp: "+timestamp +", sign: " + sign);
|
||||||
|
|
||||||
|
String expected = DigestUtils.md5DigestAsHex((timestamp + secretKey).getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
if (!expected.equalsIgnoreCase(sign)) {
|
||||||
|
// log.info("Invalid sign: " + sign + ", expected: " + expected);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Invalid sign");
|
||||||
|
}
|
||||||
|
NbaUser loginUser = (NbaUser) session.getAttribute("loginUser");
|
||||||
|
if (loginUser == null){
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("请先登录");
|
||||||
|
}
|
||||||
|
log.info("{}:获取直播链接开始",loginUser.getEmail());
|
||||||
|
String ip = userUtil.getClientIp(request);
|
||||||
|
String url = urlsService.findUrlByGameIdAndType(gameId, playType);
|
||||||
|
// log.info("来自ip:{} 用户:{}:获取直播链接成功:{}",ip,loginUser.getEmail(),url);
|
||||||
|
return ResponseEntity.ok(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/urls")
|
||||||
|
public ResponseEntity<?> getUrls(
|
||||||
|
@RequestHeader(value = "X-Timestamp", required = false) String timestamp,
|
||||||
|
@RequestHeader(value = "X-Sign", required = false) String sign,
|
||||||
|
@RequestParam(value = "includeM3u8", required = false, defaultValue = "0") String includeM3u8
|
||||||
|
) {
|
||||||
|
String secretKey = "20251125";
|
||||||
|
if (timestamp == null || sign == null) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Missing headers");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超时校验(5分钟内有效)
|
||||||
|
long ts = Long.parseLong(timestamp);
|
||||||
|
if (Math.abs(System.currentTimeMillis() - ts) > 5 * 60 * 1000) {
|
||||||
|
// log.info("Request expired: " + timestamp);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Request expired");
|
||||||
|
}
|
||||||
|
//log.info("Request timestamp: "+timestamp +", sign: " + sign);
|
||||||
|
|
||||||
|
String expected = DigestUtils.md5DigestAsHex((timestamp + secretKey).getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
if (!expected.equalsIgnoreCase(sign)) {
|
||||||
|
// log.info("Invalid sign: " + sign + ", expected: " + expected);
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Invalid sign");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("================"+String.valueOf(includeM3u8));
|
||||||
|
List<HashMap<String, List<LiveUrl>>> data = urlsService.getUrls(includeM3u8);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/go")
|
@RequestMapping("/go")
|
||||||
public Boolean go(@RequestParam("pwd") String pwd) {
|
public Boolean go(@RequestParam("pwd") String pwd) {
|
||||||
return pwd.equals("inspur123");
|
return pwd.equals("inspur123");
|
||||||
@@ -81,4 +198,13 @@ public class NbaController {
|
|||||||
public void deleteUrlById(@PathVariable("id") Integer id){
|
public void deleteUrlById(@PathVariable("id") Integer id){
|
||||||
urlsService.deleteUrlById(id);
|
urlsService.deleteUrlById(id);
|
||||||
}
|
}
|
||||||
|
//修改直播链接根据id
|
||||||
|
@RequestMapping("/update")
|
||||||
|
//使用hashmap接收参数
|
||||||
|
public void updateUrlById(@RequestBody HashMap<String, String> liveUrl){
|
||||||
|
urlsService.updateUrlById(liveUrl);
|
||||||
|
}
|
||||||
|
// public void updateUrlById(@RequestBody LiveUrl liveUrl){
|
||||||
|
// urlsService.updateUrlById(liveUrl);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package com.ping.study.controller.tx;
|
package com.ping.study.controller.tx;
|
||||||
|
|
||||||
|
import com.ping.study.service.UrlsService;
|
||||||
import com.ping.study.service.tx.LiveInfoService;
|
import com.ping.study.service.tx.LiveInfoService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
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
|
@RestController
|
||||||
@RequestMapping("/tx/nba")
|
@RequestMapping("/tx/nba")
|
||||||
|
@Slf4j
|
||||||
public class LiveInfoController {
|
public class LiveInfoController {
|
||||||
|
|
||||||
private final LiveInfoService liveInfoService;
|
private final LiveInfoService liveInfoService;
|
||||||
@@ -19,15 +20,17 @@ public class LiveInfoController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/live/{cnlid}")
|
@GetMapping("/live/{cnlid}")
|
||||||
public String getLiveInfo(@PathVariable String cnlid) {
|
public String getLiveInfo(@PathVariable String cnlid) throws Exception {
|
||||||
|
log.info("执行查询直播id: {}", cnlid);
|
||||||
return liveInfoService.getLiveInfo(cnlid);
|
return liveInfoService.getLiveInfo(cnlid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//定时执行更新直播链接
|
//定时执行更新直播链接
|
||||||
//定时任务 从北京时间凌晨到12点,每过半个小时执行一次
|
//定时任务 从北京时间凌晨到12:00点,每过5分钟执行一次
|
||||||
@Scheduled(cron = "0 0/30 0-11 * * ?")
|
@Scheduled(cron = "0 0/10 0-12 * * ?")
|
||||||
@RequestMapping("/live/refresh")
|
@RequestMapping("/live/refresh")
|
||||||
public String refreshLiveInfo() {
|
public String refreshLiveInfo() throws Exception {
|
||||||
|
log.info("=========开始执行更新直播链接=========");
|
||||||
return liveInfoService.refreshLiveInfo();
|
return liveInfoService.refreshLiveInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.ping.study.controller.tx;
|
package com.ping.study.controller.tx;
|
||||||
|
|
||||||
import com.ping.study.model.dto.tx.MatchListRequest;
|
import com.ping.study.model.dto.tx.MatchListRequest;
|
||||||
|
import com.ping.study.model.vo.live.LiveIds;
|
||||||
import com.ping.study.service.tx.MatchService;
|
import com.ping.study.service.tx.MatchService;
|
||||||
import com.ping.study.service.tx.SportsQqService;
|
import com.ping.study.service.tx.SportsQqService;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@@ -23,22 +25,25 @@ public class MatchController {
|
|||||||
this.matchService = matchService;
|
this.matchService = matchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/matches")
|
@GetMapping("/matches")
|
||||||
public Mono<String> getMatches(
|
public Mono<String> getMatches(
|
||||||
@RequestParam(required = false, defaultValue = "100000") Integer columnId,
|
@RequestParam(required = false, defaultValue = "100000") Integer columnId,
|
||||||
@RequestParam String startTime,
|
@RequestParam(required = false) String startTime,
|
||||||
@RequestParam String endTime) {
|
@RequestParam(required = false) String endTime) {
|
||||||
|
|
||||||
MatchListRequest request = new MatchListRequest();
|
MatchListRequest request = new MatchListRequest();
|
||||||
request.setColumnId(columnId);
|
request.setColumnId(columnId);
|
||||||
request.setStartTime(LocalDate.parse(startTime));
|
|
||||||
request.setEndTime(LocalDate.parse(endTime));
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
request.setStartTime(startTime != null ? LocalDate.parse(startTime) : currentDate);
|
||||||
|
request.setEndTime(endTime != null ? LocalDate.parse(endTime) : currentDate);
|
||||||
|
|
||||||
return sportsQqService.getMatchList(request);
|
return sportsQqService.getMatchList(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/lives")
|
@GetMapping("/lives")
|
||||||
public List<String> getPlayoffLiveIds(
|
public List<LiveIds> getPlayoffLiveIds(
|
||||||
@RequestParam String startTime,
|
@RequestParam String startTime,
|
||||||
@RequestParam String endTime) {
|
@RequestParam String endTime) {
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ public class TokenRefreshController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TxSportTokenRefreshService txSportTokenRefreshService;
|
private TxSportTokenRefreshService txSportTokenRefreshService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/cookie/refresh")
|
@RequestMapping("/cookie/refresh")
|
||||||
public Boolean refreshToken()
|
public Boolean refreshToken()
|
||||||
{
|
{
|
||||||
|
|||||||
168
src/main/java/com/ping/study/controller/user/UserController.java
Normal file
168
src/main/java/com/ping/study/controller/user/UserController.java
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package com.ping.study.controller.user;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.DtoUpdateUser;
|
||||||
|
import com.ping.study.model.dto.registerUserDto;
|
||||||
|
|
||||||
|
import com.ping.study.pojo.NbaUser;
|
||||||
|
import com.ping.study.service.NbaUserService;
|
||||||
|
import com.ping.study.utils.MailUtil;
|
||||||
|
import com.ping.study.utils.UserUtil;
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.ResponseCookie;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin(
|
||||||
|
origins = {"http://nba.1024x.icu", "https://nba.1024x.icu","http://jrs77.xyz","https://jrs77.xyz"},
|
||||||
|
allowCredentials = "true"
|
||||||
|
)
|
||||||
|
@RequestMapping("/user")
|
||||||
|
@Slf4j
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MailUtil mailUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NbaUserService nbaUserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserUtil userUtil;
|
||||||
|
|
||||||
|
//发送验证码
|
||||||
|
@RequestMapping("/send")
|
||||||
|
public String send(String email,Integer type) {
|
||||||
|
switch (type){
|
||||||
|
case 1://注册用户
|
||||||
|
if (nbaUserService.findByEmail(email) != null){
|
||||||
|
return "邮箱已存在";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2://修改密码
|
||||||
|
if (nbaUserService.findByEmail(email) == null){
|
||||||
|
return "邮箱不存在";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mailUtil.sendVerificationCode(email);
|
||||||
|
// return "发送成功";
|
||||||
|
}
|
||||||
|
|
||||||
|
//注册
|
||||||
|
@PostMapping("/register")
|
||||||
|
public String register(@RequestBody registerUserDto registerUserDto, HttpServletRequest request){
|
||||||
|
String ip = userUtil.getClientIp(request);
|
||||||
|
registerUserDto.setRegisterIp(ip);
|
||||||
|
return nbaUserService.register(registerUserDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录 + rememberToken 功能
|
||||||
|
@PostMapping("/login")
|
||||||
|
public String login(
|
||||||
|
@RequestParam String email,
|
||||||
|
@RequestParam String password,
|
||||||
|
HttpSession session,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response
|
||||||
|
) {
|
||||||
|
String ip = userUtil.getClientIp(request);
|
||||||
|
NbaUser user = nbaUserService.login(email, password,ip);
|
||||||
|
if (user != null){
|
||||||
|
// session 存 7 天
|
||||||
|
session.setMaxInactiveInterval(1 * 24 * 60 * 60);
|
||||||
|
session.setAttribute("loginUser", user);
|
||||||
|
|
||||||
|
// 生成 rememberToken
|
||||||
|
String token = UUID.randomUUID().toString();
|
||||||
|
nbaUserService.saveRememberToken(Long.valueOf(user.getId()), token);
|
||||||
|
|
||||||
|
|
||||||
|
ResponseCookie rememberCookie = ResponseCookie
|
||||||
|
.from("rememberToken", token)
|
||||||
|
.httpOnly(true)
|
||||||
|
.secure(true) // 生产 https 环境一定要 true
|
||||||
|
.path("/")
|
||||||
|
.sameSite("None")
|
||||||
|
.maxAge(1 * 24 * 60 * 60)
|
||||||
|
.build();
|
||||||
|
response.addHeader(HttpHeaders.SET_COOKIE, rememberCookie.toString());
|
||||||
|
// Cookie cookie = new Cookie("rememberToken", token);
|
||||||
|
// cookie.setPath("/");
|
||||||
|
// cookie.setMaxAge(7 * 24 * 60 * 60); // 7 天
|
||||||
|
// cookie.setHttpOnly(true); // JS 不能读
|
||||||
|
// // 如果你用 https,请启用:cookie.setSecure(true);
|
||||||
|
// response.addCookie(cookie);
|
||||||
|
|
||||||
|
log.info("用户 {} 登录成功(记住我 token={})", user.getEmail(), token);
|
||||||
|
|
||||||
|
return "登录成功";
|
||||||
|
}
|
||||||
|
return "登录失败";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
public String updateUser(@RequestBody DtoUpdateUser dtoUpdateUser){
|
||||||
|
return nbaUserService.updateUser(dtoUpdateUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回当前登录用户(支持自动登录)
|
||||||
|
@GetMapping("/me")
|
||||||
|
public Object me(
|
||||||
|
HttpSession session,
|
||||||
|
@CookieValue(value = "rememberToken", required = false) String rememberToken
|
||||||
|
) {
|
||||||
|
// 1. session 已登录
|
||||||
|
NbaUser loginUser = (NbaUser) session.getAttribute("loginUser");
|
||||||
|
if (loginUser != null) {
|
||||||
|
return loginUser.getEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 尝试自动登录(记住我)
|
||||||
|
if (rememberToken != null && !rememberToken.isEmpty()) {
|
||||||
|
NbaUser user = nbaUserService.findByRememberToken(rememberToken);
|
||||||
|
if (user != null) {
|
||||||
|
// 自动恢复 session
|
||||||
|
session.setMaxInactiveInterval(1 * 24 * 60 * 60);
|
||||||
|
session.setAttribute("loginUser", user);
|
||||||
|
|
||||||
|
log.info("自动登录成功 -> {}", user.getEmail());
|
||||||
|
return user.getEmail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "未登录";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退出登录(清 session + 清 token + 清 cookie)
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public String logout(
|
||||||
|
HttpSession session,
|
||||||
|
HttpServletResponse response,
|
||||||
|
@CookieValue(value = "rememberToken", required = false) String rememberToken
|
||||||
|
) {
|
||||||
|
session.invalidate();
|
||||||
|
|
||||||
|
// 清数据库 token
|
||||||
|
if (rememberToken != null) {
|
||||||
|
nbaUserService.deleteRememberToken(rememberToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清 cookie
|
||||||
|
Cookie cookie = new Cookie("rememberToken", "");
|
||||||
|
cookie.setPath("/");
|
||||||
|
cookie.setMaxAge(0);
|
||||||
|
response.addCookie(cookie);
|
||||||
|
|
||||||
|
return "退出成功";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
25
src/main/java/com/ping/study/mapper/LoginLogMapper.java
Normal file
25
src/main/java/com/ping/study/mapper/LoginLogMapper.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ping.study.mapper;
|
||||||
|
|
||||||
|
import com.ping.study.pojo.LoginLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Administrator
|
||||||
|
* @description 针对表【login_log】的数据库操作Mapper
|
||||||
|
* @createDate 2025-12-22 13:10:39
|
||||||
|
* @Entity com.ping.study.pojo.LoginLog
|
||||||
|
*/
|
||||||
|
public interface LoginLogMapper {
|
||||||
|
|
||||||
|
int deleteByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
int insert(LoginLog record);
|
||||||
|
|
||||||
|
int insertSelective(LoginLog record);
|
||||||
|
|
||||||
|
LoginLog selectByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(LoginLog record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(LoginLog record);
|
||||||
|
|
||||||
|
}
|
||||||
38
src/main/java/com/ping/study/mapper/NbaUserMapper.java
Normal file
38
src/main/java/com/ping/study/mapper/NbaUserMapper.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package com.ping.study.mapper;
|
||||||
|
|
||||||
|
import com.ping.study.pojo.NbaUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Administrator
|
||||||
|
* @description 针对表【nba_user】的数据库操作Mapper
|
||||||
|
* @createDate 2025-11-19 22:54:55
|
||||||
|
* @Entity com.ping.study.pojo.NbaUser
|
||||||
|
*/
|
||||||
|
public interface NbaUserMapper {
|
||||||
|
|
||||||
|
int deleteByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
int insert(NbaUser record);
|
||||||
|
|
||||||
|
int insertSelective(NbaUser record);
|
||||||
|
|
||||||
|
NbaUser selectByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(NbaUser record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(NbaUser record);
|
||||||
|
|
||||||
|
NbaUser login(String email, String password);
|
||||||
|
|
||||||
|
void updateRememberToken(Long userId, String token);
|
||||||
|
|
||||||
|
NbaUser selectByRememberToken(String token);
|
||||||
|
|
||||||
|
void clearRememberToken(String token);
|
||||||
|
|
||||||
|
NbaUser findByEmail(String email);
|
||||||
|
|
||||||
|
NbaUser selectByEmail(String email);
|
||||||
|
|
||||||
|
void updatePasswordByEmail(String email, String password);
|
||||||
|
}
|
||||||
@@ -26,9 +26,16 @@ public interface UrlsMapper {
|
|||||||
int updateByPrimaryKeySelective(Urls record);
|
int updateByPrimaryKeySelective(Urls record);
|
||||||
|
|
||||||
int updateByPrimaryKey(Urls record);
|
int updateByPrimaryKey(Urls record);
|
||||||
|
|
||||||
List<String> selectGameIds();
|
List<String> selectGameIds();
|
||||||
|
|
||||||
List<LiveUrl> selectUrlsListByGameId(String gameId);
|
List<LiveUrl> selectUrlsListByGameId(
|
||||||
|
@Param("gameId") String gameId
|
||||||
|
);
|
||||||
|
|
||||||
|
List<LiveUrl> selectUrlsListByAdmin(
|
||||||
|
@Param("gameId") String gameId
|
||||||
|
);
|
||||||
|
|
||||||
void insertUrlsWithGameId(@Param("gameId") String gameId, @Param("list") List<LiveUrl> urls);
|
void insertUrlsWithGameId(@Param("gameId") String gameId, @Param("list") List<LiveUrl> urls);
|
||||||
|
|
||||||
@@ -38,5 +45,12 @@ public interface UrlsMapper {
|
|||||||
void deleteAllUrls();
|
void deleteAllUrls();
|
||||||
|
|
||||||
//更新比赛直播链接
|
//更新比赛直播链接
|
||||||
void updateUrlsWithGameId(String gameId, String s);
|
void updateUrlsWithGameId(String gameId, String s,String type);
|
||||||
|
|
||||||
|
String selectUrlsListByGameIdAndType(String gameId, String type);
|
||||||
|
|
||||||
|
//更新比赛状态
|
||||||
|
void updateStatusWithGameId(String gameId, String status);
|
||||||
|
|
||||||
|
void updateUrlsById(String id, String url);
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/java/com/ping/study/model/dto/DtoUpdateUser.java
Normal file
11
src/main/java/com/ping/study/model/dto/DtoUpdateUser.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ping.study.model.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DtoUpdateUser {
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
private String code;
|
||||||
|
}
|
||||||
20
src/main/java/com/ping/study/model/dto/registerUserDto.java
Normal file
20
src/main/java/com/ping/study/model/dto/registerUserDto.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.ping.study.model.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class registerUserDto {
|
||||||
|
// private Integer id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String registerIp;
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.ping.study.model.dto.tx;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TxMatchRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前日期 yyyy-MM-dd(默认:当前日期)
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询开始日期 yyyy-MM-dd(默认:当前日期)
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String startTime = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询结束日期 yyyy-MM-dd(默认:当前日期)
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String endTime = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 栏目 ID
|
||||||
|
*/
|
||||||
|
private Integer columnId=100000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页码或索引
|
||||||
|
*/
|
||||||
|
private Integer index =1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否初始化
|
||||||
|
*/
|
||||||
|
private Boolean isInit= true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳(默认:当前系统时间毫秒)
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private Long timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调函数名
|
||||||
|
*/
|
||||||
|
private String callback = "fetchScheduleListCallback100000";
|
||||||
|
}
|
||||||
@@ -11,4 +11,5 @@ public class Game {
|
|||||||
private String awayTeamLogoDark;
|
private String awayTeamLogoDark;
|
||||||
private String startDate; // 格式:"2025-04-17"
|
private String startDate; // 格式:"2025-04-17"
|
||||||
private String startTime; // 格式:"07:30:00"
|
private String startTime; // 格式:"07:30:00"
|
||||||
|
private String status;//比赛状态
|
||||||
}
|
}
|
||||||
11
src/main/java/com/ping/study/model/vo/live/LiveIds.java
Normal file
11
src/main/java/com/ping/study/model/vo/live/LiveIds.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ping.study.model.vo.live;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LiveIds {
|
||||||
|
|
||||||
|
private String mId;
|
||||||
|
private String playId;
|
||||||
|
}
|
||||||
@@ -12,10 +12,9 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class LiveUrl {
|
public class LiveUrl {
|
||||||
|
|
||||||
// private Integer gameId;
|
// private Integer gameId;
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private String type;
|
private String type;
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class MatchInfo {
|
public class MatchInfo {
|
||||||
|
|
||||||
|
private String mId;
|
||||||
private String liveId;
|
private String liveId;
|
||||||
private String matchType;
|
private String matchType;
|
||||||
|
private String competitionId;
|
||||||
// 其他需要的字段...
|
// 其他需要的字段...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,4 +56,7 @@ public class Games implements Serializable {
|
|||||||
private String awayTeamLogoDark;
|
private String awayTeamLogoDark;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
//比赛状态
|
||||||
|
private String status;
|
||||||
}
|
}
|
||||||
18
src/main/java/com/ping/study/pojo/LoginLog.java
Normal file
18
src/main/java/com/ping/study/pojo/LoginLog.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ping.study.pojo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TableName login_log
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginLog {
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private Integer userId;
|
||||||
|
|
||||||
|
private Date loginTime;
|
||||||
|
|
||||||
|
private String loginIp;
|
||||||
|
}
|
||||||
28
src/main/java/com/ping/study/pojo/NbaUser.java
Normal file
28
src/main/java/com/ping/study/pojo/NbaUser.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ping.study.pojo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TableName nba_user
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class NbaUser {
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
private Date lastLoginTime;
|
||||||
|
|
||||||
|
private String lastLoginIp;
|
||||||
|
|
||||||
|
private String registerIp;
|
||||||
|
}
|
||||||
@@ -27,4 +27,6 @@ public class Urls {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
private Integer status;
|
||||||
}
|
}
|
||||||
27
src/main/java/com/ping/study/service/NbaUserService.java
Normal file
27
src/main/java/com/ping/study/service/NbaUserService.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package com.ping.study.service;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.DtoUpdateUser;
|
||||||
|
import com.ping.study.model.dto.registerUserDto;
|
||||||
|
import com.ping.study.pojo.NbaUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Administrator
|
||||||
|
* @description 针对表【nba_user】的数据库操作Service
|
||||||
|
* @createDate 2025-11-19 22:52:24
|
||||||
|
*/
|
||||||
|
public interface NbaUserService{
|
||||||
|
|
||||||
|
String register(registerUserDto registerUserDto);
|
||||||
|
|
||||||
|
NbaUser login(String email, String password,String ip);
|
||||||
|
|
||||||
|
void saveRememberToken(Long userId, String token);
|
||||||
|
|
||||||
|
NbaUser findByRememberToken(String token);
|
||||||
|
|
||||||
|
void deleteRememberToken(String token);
|
||||||
|
|
||||||
|
String updateUser(DtoUpdateUser dtoUpdateUser);
|
||||||
|
|
||||||
|
NbaUser findByEmail(String email);
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ public interface UrlsService {
|
|||||||
|
|
||||||
|
|
||||||
//查询当天的直播地址
|
//查询当天的直播地址
|
||||||
public List<HashMap<String, List<LiveUrl>>> getUrls();
|
public List<HashMap<String, List<LiveUrl>>> getUrls(String includeM3u8);
|
||||||
|
|
||||||
//添加直播地址到对应赛事
|
//添加直播地址到对应赛事
|
||||||
public void addUrls(addUrls addUrls);
|
public void addUrls(addUrls addUrls);
|
||||||
@@ -19,4 +19,8 @@ public interface UrlsService {
|
|||||||
public void deleteUrlById(Integer id);
|
public void deleteUrlById(Integer id);
|
||||||
|
|
||||||
void deleteAllUrls();
|
void deleteAllUrls();
|
||||||
|
|
||||||
|
String findUrlByGameIdAndType(String gameId, String type);
|
||||||
|
|
||||||
|
void updateUrlById(HashMap<String, String> liveUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package com.ping.study.service.impl;
|
||||||
|
|
||||||
|
import com.ping.study.mapper.LoginLogMapper;
|
||||||
|
import com.ping.study.mapper.NbaUserMapper;
|
||||||
|
import com.ping.study.model.dto.DtoUpdateUser;
|
||||||
|
import com.ping.study.model.dto.registerUserDto;
|
||||||
|
import com.ping.study.pojo.LoginLog;
|
||||||
|
import com.ping.study.pojo.NbaUser;
|
||||||
|
import com.ping.study.service.NbaUserService;
|
||||||
|
|
||||||
|
import com.ping.study.utils.UserUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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 org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class NbaUserServiceImpl implements NbaUserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> stringRedisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private NbaUserMapper nbaUserMapper;
|
||||||
|
@Autowired
|
||||||
|
private LoginLogMapper loginLogMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String register(registerUserDto registerUserDto) {
|
||||||
|
String s = stringRedisTemplate.opsForValue().get(registerUserDto.getEmail());
|
||||||
|
if (s != null && s.equals(registerUserDto.getCode())) {
|
||||||
|
if (nbaUserMapper.findByEmail(registerUserDto.getEmail()) != null){
|
||||||
|
return "邮箱已存在";
|
||||||
|
}
|
||||||
|
NbaUser nbaUser = new NbaUser();
|
||||||
|
nbaUser.setUsername(registerUserDto.getUsername());
|
||||||
|
nbaUser.setPassword(registerUserDto.getPassword());
|
||||||
|
nbaUser.setEmail(registerUserDto.getEmail());
|
||||||
|
nbaUser.setCreateTime(new Date());
|
||||||
|
nbaUser.setUpdateTime(new Date());
|
||||||
|
nbaUser.setLastLoginTime(new Date());
|
||||||
|
nbaUser.setLastLoginIp("");
|
||||||
|
nbaUser.setRegisterIp(registerUserDto.getRegisterIp());
|
||||||
|
stringRedisTemplate.delete(registerUserDto.getEmail());
|
||||||
|
nbaUserMapper.insert(nbaUser);
|
||||||
|
return "注册成功";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//throw new RuntimeException("验证码错误");
|
||||||
|
return "验证码错误";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public NbaUser login(String email, String password, String ip) {
|
||||||
|
NbaUser loginUser = nbaUserMapper.login(email, password);
|
||||||
|
if (loginUser!=null){
|
||||||
|
LoginLog loginLog = new LoginLog();
|
||||||
|
loginLog.setUserId(loginUser.getId());
|
||||||
|
loginLog.setLoginTime(new Date());
|
||||||
|
loginLog.setLoginIp(ip);
|
||||||
|
loginLogMapper.insert(loginLog);
|
||||||
|
loginUser.setLastLoginTime(new Date());
|
||||||
|
nbaUserMapper.updateByPrimaryKeySelective(loginUser);
|
||||||
|
return loginUser;
|
||||||
|
}
|
||||||
|
else return null;
|
||||||
|
//return loginUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveRememberToken(Long userId, String token) {
|
||||||
|
// update nba_user set remember_token = ? where id = ?
|
||||||
|
nbaUserMapper.updateRememberToken(userId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NbaUser findByRememberToken(String token) {
|
||||||
|
return nbaUserMapper.selectByRememberToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRememberToken(String token) {
|
||||||
|
nbaUserMapper.clearRememberToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String updateUser(DtoUpdateUser dtoUpdateUser) {
|
||||||
|
NbaUser nbaUser = nbaUserMapper.selectByEmail(dtoUpdateUser.getEmail());
|
||||||
|
if (nbaUser != null){
|
||||||
|
String s = stringRedisTemplate.opsForValue().get(dtoUpdateUser.getEmail());
|
||||||
|
if (s != null && s.equals(dtoUpdateUser.getCode())){
|
||||||
|
nbaUserMapper.updatePasswordByEmail(dtoUpdateUser.getEmail(), dtoUpdateUser.getPassword());
|
||||||
|
stringRedisTemplate.delete(dtoUpdateUser.getEmail());
|
||||||
|
return "更新成功";
|
||||||
|
}
|
||||||
|
return "验证码错误";
|
||||||
|
}
|
||||||
|
return "当前邮箱无账号";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NbaUser findByEmail(String email) {
|
||||||
|
return nbaUserMapper.findByEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,39 +5,85 @@ import com.ping.study.model.dto.addUrls;
|
|||||||
import com.ping.study.model.vo.live.LiveUrl;
|
import com.ping.study.model.vo.live.LiveUrl;
|
||||||
import com.ping.study.service.UrlsService;
|
import com.ping.study.service.UrlsService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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 org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UrlsServiceImpl implements UrlsService {
|
public class UrlsServiceImpl implements UrlsService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UrlsMapper urlsMapper;
|
private UrlsMapper urlsMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
@Override
|
@Override
|
||||||
public List<HashMap<String, List<LiveUrl>>> getUrls() {
|
public List<HashMap<String, List<LiveUrl>>> getUrls(String includeM3u8) {
|
||||||
|
|
||||||
|
String redisKey = "live:urls:all";
|
||||||
|
|
||||||
|
// ② 查数据库兜底
|
||||||
List<HashMap<String,List<LiveUrl>>> urlsList = new ArrayList<>();
|
List<HashMap<String,List<LiveUrl>>> urlsList = new ArrayList<>();
|
||||||
List<String> gameIds = urlsMapper.selectGameIds();
|
List<String> gameIds = urlsMapper.selectGameIds();
|
||||||
|
|
||||||
|
if (includeM3u8.equals("1")){
|
||||||
|
gameIds.forEach(gameId -> {
|
||||||
|
List<LiveUrl> maps = urlsMapper.selectUrlsListByAdmin(gameId);
|
||||||
|
HashMap<String, List<LiveUrl>> map = new HashMap<>();
|
||||||
|
map.put(gameId,maps);
|
||||||
|
urlsList.add(map);
|
||||||
|
});
|
||||||
|
return urlsList;
|
||||||
|
}
|
||||||
|
// ① 先读缓存,Redis 挂了会抛异常,进入 catch → 去 DB
|
||||||
|
try {
|
||||||
|
List<HashMap<String, List<LiveUrl>>> cache =
|
||||||
|
(List<HashMap<String, List<LiveUrl>>>) redisTemplate.opsForValue().get(redisKey);
|
||||||
|
|
||||||
|
if(cache != null){
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// Redis 错了不要打印到控制台,生产只记录日志
|
||||||
|
}
|
||||||
|
|
||||||
gameIds.forEach(gameId -> {
|
gameIds.forEach(gameId -> {
|
||||||
List<LiveUrl> maps = urlsMapper.selectUrlsListByGameId(gameId);
|
List<LiveUrl> maps = urlsMapper.selectUrlsListByGameId(gameId);
|
||||||
HashMap<String, List<LiveUrl>> map = new HashMap<>();
|
HashMap<String, List<LiveUrl>> map = new HashMap<>();
|
||||||
map.put(gameId,maps);
|
map.put(gameId,maps);
|
||||||
urlsList.add(map);
|
urlsList.add(map);
|
||||||
}); // 添加右括号和分号
|
});
|
||||||
|
|
||||||
|
// ③ DB 查询结果写回 Redis(可选)
|
||||||
|
try {
|
||||||
|
// redisTemplate.opsForValue().set(redisKey, urlsList, 1, TimeUnit.HOURS);
|
||||||
|
redisTemplate.opsForValue().set(redisKey, urlsList);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// redis 宕机不影响业务
|
||||||
|
}
|
||||||
|
|
||||||
return urlsList;
|
return urlsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addUrls(addUrls addUrls) {
|
public void addUrls(addUrls addUrls) {
|
||||||
urlsMapper.insertUrlsWithGameId(addUrls.getGameId(), addUrls.getUrls());
|
urlsMapper.insertUrlsWithGameId(addUrls.getGameId(), addUrls.getUrls());
|
||||||
|
//删除redis缓存
|
||||||
|
redisTemplate.delete("live:urls:all");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteUrlById(Integer id) {
|
public void deleteUrlById(Integer id) {
|
||||||
try {
|
try {
|
||||||
urlsMapper.deleteUrlById(id);
|
urlsMapper.deleteUrlById(id);
|
||||||
|
//删除redis缓存
|
||||||
|
redisTemplate.delete("live:urls:all");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -48,6 +94,40 @@ public class UrlsServiceImpl implements UrlsService {
|
|||||||
@Override
|
@Override
|
||||||
public void deleteAllUrls() {
|
public void deleteAllUrls() {
|
||||||
urlsMapper.deleteAllUrls();
|
urlsMapper.deleteAllUrls();
|
||||||
|
//删除redis缓存
|
||||||
|
redisTemplate.delete("live:urls:all");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findUrlByGameIdAndType(String gameId, String type) {
|
||||||
|
String redis_url = "url:" + gameId+":"+type;
|
||||||
|
String url;
|
||||||
|
try {
|
||||||
|
url = (String) redisTemplate.opsForValue().get(redis_url);
|
||||||
|
if (url != null){
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}catch (Exception ignored){
|
||||||
|
|
||||||
|
}
|
||||||
|
url = urlsMapper.selectUrlsListByGameIdAndType(gameId, type);
|
||||||
|
try {
|
||||||
|
if (!url.equals("null")){
|
||||||
|
redisTemplate.opsForValue().set(redis_url, url,1,TimeUnit.HOURS);
|
||||||
|
}
|
||||||
|
}catch (Exception ignored){
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改直播链接
|
||||||
|
@Override
|
||||||
|
public void updateUrlById(HashMap<String, String> liveUrl) {
|
||||||
|
//修改当前id直播链接
|
||||||
|
urlsMapper.updateUrlsById(liveUrl.get("id"),liveUrl.get("url"));
|
||||||
|
//删除redis缓存 url:0042500224:tx
|
||||||
|
redisTemplate.delete("url:"+liveUrl.get("gameId")+":"+liveUrl.get("type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.ping.study.service.tx;
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.ping.study.mapper.GamesMapper;
|
import com.ping.study.mapper.GamesMapper;
|
||||||
import com.ping.study.mapper.UrlsMapper;
|
import com.ping.study.mapper.UrlsMapper;
|
||||||
@@ -8,10 +10,12 @@ import com.ping.study.model.vo.live.LiveInfoResponse;
|
|||||||
import com.ping.study.pojo.Games;
|
import com.ping.study.pojo.Games;
|
||||||
import com.ping.study.utils.tx.CKeyGenerator;
|
import com.ping.study.utils.tx.CKeyGenerator;
|
||||||
|
|
||||||
|
import com.ping.study.utils.tx.TxVideoAuthRedisUtil;
|
||||||
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.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
@@ -35,84 +39,166 @@ public class LiveInfoService {
|
|||||||
private GamesMapper gamesMapper;
|
private GamesMapper gamesMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private UrlsMapper urlsMapper;
|
private UrlsMapper urlsMapper;
|
||||||
|
@Autowired
|
||||||
|
private TxSportTokenRefreshService txSportTokenRefreshService;;
|
||||||
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> stringRedisTemplate;
|
||||||
|
|
||||||
public LiveInfoService(@Qualifier("tencentWebClient")WebClient webClient, CKeyGenerator cKeyGenerator, StringRedisTemplate stringRedisTemplate) {
|
@Autowired
|
||||||
|
private TxVideoAuthRedisUtil txVideoAuthRedisUtil;
|
||||||
|
|
||||||
|
public LiveInfoService(@Qualifier("tencentWebClient")WebClient webClient, CKeyGenerator cKeyGenerator) {
|
||||||
this.webClient = webClient;
|
this.webClient = webClient;
|
||||||
this.cKeyGenerator = cKeyGenerator;
|
this.cKeyGenerator = cKeyGenerator;
|
||||||
this.stringRedisTemplate = stringRedisTemplate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 远程调用时拼接 Cookie
|
// 2. 远程调用时拼接 Cookie
|
||||||
public String getCookieForRequest() {
|
public String getCookieForRequest() throws JsonProcessingException {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
// 读取
|
// 读取
|
||||||
String cookie = stringRedisTemplate.opsForValue().get("tx_sports_cookie");
|
String cookieJson = stringRedisTemplate.opsForValue().get("tx_sports_cookie_map");
|
||||||
return cookie;
|
Map<String, String> cookieMap = objectMapper.readValue(cookieJson, new TypeReference<>() {});
|
||||||
|
return buildCookieHeader(cookieMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLiveInfo(String cnlid) {
|
public String getLiveInfo(String cnlid) throws Exception {
|
||||||
|
//先调用刷新cookie
|
||||||
|
txSportTokenRefreshService.refreshCookies();
|
||||||
|
Thread.sleep(3000);
|
||||||
String platform = "40201";
|
String platform = "40201";
|
||||||
String ckey = cKeyGenerator.generateCKey(cnlid, platform);
|
String ckey = cKeyGenerator.generateCKey(cnlid, platform);
|
||||||
|
|
||||||
// 1. 打印请求参数
|
// 1. 打印请求参数
|
||||||
String queryParams = String.format(
|
// String queryParams = String.format(
|
||||||
"ckey=%s&encrypt_ver=%s&platform=%s&tm=%d&cnlid=%s",
|
// "ckey=%s&encrypt_ver=%s&platform=%s&tm=%d&cnlid=%s",
|
||||||
ckey,
|
// ckey,
|
||||||
LiveInfoRequest.generateEncryptVer(DayOfWeek.from(LocalDate.now())),
|
// LiveInfoRequest.generateEncryptVer(DayOfWeek.from(LocalDate.now())),
|
||||||
platform,
|
// platform,
|
||||||
Instant.now().getEpochSecond(),
|
// Instant.now().getEpochSecond(),
|
||||||
cnlid
|
// cnlid
|
||||||
);
|
// );
|
||||||
log.info("请求参数: {}", queryParams);
|
// log.info("请求参数: {}", queryParams);
|
||||||
|
|
||||||
// 2. 打印请求头(Cookie)
|
// 2. 打印请求头(Cookie)
|
||||||
String cookie = getCookieForRequest();
|
String cookie = getCookieForRequest();
|
||||||
log.info("请求头 Cookie: {}", cookie);
|
// log.info("请求头 Cookie: {}", cookie);
|
||||||
|
// String s = txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("auth_ext_raw");
|
||||||
|
// String s1 = txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("logintoken_raw");
|
||||||
|
// log.info("请求头 auth_ext_encoded: {}", s);
|
||||||
|
// log.info("请求头 logintoken_encoded: {}", s1);
|
||||||
// 3. 发起请求
|
// 3. 发起请求
|
||||||
return webClient.get()
|
//defnswitch、auth_ext、logintoken为高帧率fhd_hfps请求参数
|
||||||
|
String res = webClient.get()
|
||||||
.uri(uriBuilder -> uriBuilder
|
.uri(uriBuilder -> uriBuilder
|
||||||
.path("/cgi-bin/getliveinfo")
|
.path("/cgi-bin/getliveinfo")
|
||||||
.queryParam("ckey", ckey)
|
.queryParam("ckey", ckey)
|
||||||
.queryParam("encrypt_ver", LiveInfoRequest.generateEncryptVer(
|
.queryParam("auth_ext", txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("auth_ext_encoded"))
|
||||||
DayOfWeek.from(LocalDate.now())))
|
.queryParam("logintoken", txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("logintoken_encoded"))
|
||||||
|
.queryParam("encrypt_ver", LiveInfoRequest.generateEncryptVer(DayOfWeek.from(LocalDate.now())))
|
||||||
.queryParam("platform", platform)
|
.queryParam("platform", platform)
|
||||||
|
.queryParam("auth_from", 4001)
|
||||||
|
.queryParam("sphttps", 1)
|
||||||
.queryParam("tm", Instant.now().getEpochSecond())
|
.queryParam("tm", Instant.now().getEpochSecond())
|
||||||
.queryParam("cnlid", cnlid)
|
.queryParam("cnlid", cnlid)
|
||||||
|
.queryParam("defn", "fhd")
|
||||||
|
.queryParam("ufps", "auto")
|
||||||
.build())
|
.build())
|
||||||
.header("Cookie", "_qimei_q32=b6ff8aedc45c2d93874747a3e7f5e3dd; ptui_loginuin=1131302745; vqq_access_token=308C7CAFBC867AF65212034AC90E71D9; lcad_appuser=CCC4A35B6047F544; tvfe_boss_uuid=d41b10b066856291; _qimei_uuid42=184170b170810037e9eacb93c4fe35a57c7df28f38; LW_sid=31h7T2M8f3O5O280q0K0L365H2; o_cookie=941039061; lcad_LDERturn=503; last_nick=%E8%85%BE%E8%AE%AF%E7%BD%91%E5%8F%8B; uin_cookie=o0941039061; lcad_LPDFturn=43; spt_uid=1829817828670177361; RK=dudkRjOGUW; ied_qq=o0941039061; lcad_LPVLturn=470; lcad_o_minduid=OCcytZR6an_BFYcypXv6ZzuBX65okAHc; pgv_pvid=67939534; lcad_LVINturn=636; pgv_info=ssid=s6516917000; last_main_login=qq; eas_sid=E1i7L1k4j4D7q1D0Q5J894p636; fqm_pvqid=5e0a1a80-2ffb-42c9-8878-99ef08c0bd21; last_avatar=https://mat1.gtimg.com/sports/sportapp/default_profile_big_after_v1_4.png; lcad_LPPBturn=28; lcad_LPSJturn=135; livelink_pvid=7900946432; LW_uid=P1J7P2i8S3R5a2r0j020t3n543; o2_uin=941039061; pac_uid=0_ePEHB57t75p7c; ptcz=d9e319494b15cb621d9f54a8e03a1b55fb6c6c3564ff6c4985d1ff7b4797ce4e; qq_domain_video_guid_verify=119f9c981e9ffd34; vqq_appid=101481799; vqq_openid=2E6A77E3002C87A9CA68908FB058D4E5; vqq_vuserid=3468482246; _qimei_fingerprint=aaf3a442da56251083fbe4352a04dc72; _qimei_q36=09d3b683102573c400e0b201300015518b19; _qimei_h38=fdedada2b12cacb7c731c46802000004418b19; vqq_vusession=jjtKD6NC-SPkVdItUGl3Sg.N; ts_last=sports.qq.com/kbsweb/mycenter.htm; ts_uid=9292458684; ukey=174520991101356433; boss_user=loginType=1&nbaVipType=0&qq=&wxOpenId=2E6A77E3002C87A9CA68908FB058D4E5&wxAppId=101481799&uKey=174520991101356433; ptag=film_video_qq_com|; main_login=qq; spt_session=CLuygiIQ7MONwAYY8ZWXwAYg1wE; spt_token=roxqAw5zstnrHn4H7DMOSbTeSkCVC0JjQGPz6Lp5Jx1-rxtW6mfo-wgg8jq41xEi; next_refresh_time=1745216492421; bossv2_isvip=-1")
|
// --- 在这里添加伪造 IP 的 Header ---
|
||||||
|
.header("X-Forwarded-For", "59.54.11.234")
|
||||||
|
.header("X-Real-IP", "59.54.11.234")
|
||||||
|
.header("Client-IP", "59.54.11.234")
|
||||||
|
// -------------------------------------
|
||||||
|
.header("Cookie", cookie)
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36") // 确保 UA 也像浏览器
|
||||||
|
.header("Referer", "https://sports.qq.com/") // 强烈建议加上 Referer,通常防盗链会查这个
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(String.class)
|
.bodyToMono(String.class)
|
||||||
.block();
|
.block();
|
||||||
|
// String res = webClient.get()
|
||||||
|
// .uri(uriBuilder -> uriBuilder
|
||||||
|
// .path("/cgi-bin/getliveinfo")
|
||||||
|
// .queryParam("ckey", ckey)
|
||||||
|
//// .queryParam("defnswitch",1)
|
||||||
|
// .queryParam("auth_ext", txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("auth_ext_encoded"))
|
||||||
|
// .queryParam("logintoken",txVideoAuthRedisUtil.buildAuthAndLoginToken("tx_sports_cookie_map").get("logintoken_encoded"))
|
||||||
|
// .queryParam("encrypt_ver", LiveInfoRequest.generateEncryptVer(
|
||||||
|
// DayOfWeek.from(LocalDate.now())))
|
||||||
|
// .queryParam("platform", platform)
|
||||||
|
//// .queryParam("hevclv",26)
|
||||||
|
//// .queryParam("host","sports.qq.com")
|
||||||
|
// .queryParam("auth_from",4001)
|
||||||
|
// .queryParam("sphttps",1)
|
||||||
|
// .queryParam("tm", Instant.now().getEpochSecond())
|
||||||
|
// .queryParam("cnlid", cnlid)
|
||||||
|
// .queryParam("defn","fhd")
|
||||||
|
// .queryParam("ufps","auto")
|
||||||
|
// .build())
|
||||||
|
// .header("Cookie", cookie)
|
||||||
|
// .retrieve()
|
||||||
|
// .bodyToMono(String.class)
|
||||||
|
// .block();
|
||||||
|
|
||||||
|
List<String> list = extractPlayUrls(res);
|
||||||
|
// log.info("提取到的播放URL: {}", list);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildCookieHeader(Map<String, String> cookieMap) {
|
||||||
|
return cookieMap.entrySet().stream()
|
||||||
|
.map(e -> e.getKey() + "=" + e.getValue())
|
||||||
|
.collect(Collectors.joining("; "));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> extractPlayUrls(String liveInfoJson) throws Exception {
|
public List<String> extractPlayUrls(String liveInfoJson) throws Exception {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
LiveInfoResponse response = mapper.readValue(liveInfoJson, LiveInfoResponse.class);
|
|
||||||
|
// 首先将JSON字符串解析为Map结构
|
||||||
|
Map<String, Object> responseMap = mapper.readValue(liveInfoJson, new TypeReference<Map<String, Object>>() {});
|
||||||
|
|
||||||
List<String> urls = new ArrayList<>();
|
List<String> urls = new ArrayList<>();
|
||||||
if (response.getPlay_list() != null) {
|
|
||||||
for (LiveInfoResponse.PlayItem item : response.getPlay_list()) {
|
// 检查play_list是否存在
|
||||||
if (item.getUrls() != null) {
|
if (responseMap.containsKey("play_list")) {
|
||||||
urls.addAll(item.getUrls());
|
List<Map<String, Object>> playList = (List<Map<String, Object>>) responseMap.get("play_list");
|
||||||
|
|
||||||
|
for (Map<String, Object> playItem : playList) {
|
||||||
|
// 检查urls是否存在
|
||||||
|
if (playItem.containsKey("urls")) {
|
||||||
|
List<String> itemUrls = (List<String>) playItem.get("urls");
|
||||||
|
urls.addAll(itemUrls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// log.info("提取到的播放URL数量: {}", urls.size());
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String refreshLiveInfo() {
|
public String refreshLiveInfo() throws Exception {
|
||||||
List<Games> gamesList = gamesMapper.selectAll();
|
List<Games> gamesList = gamesMapper.selectAll();
|
||||||
for (Games games : gamesList) {
|
for (Games games : gamesList) {
|
||||||
String playId = games.getPlayId();
|
String playId = games.getPlayId();
|
||||||
String liveInfo = getLiveInfo(playId);
|
String liveInfo = getLiveInfo(playId);
|
||||||
log.info("获取到的直播信息: {}", liveInfo);
|
// log.info("当前直播id: {}", playId);
|
||||||
|
// log.info("获取到的直播信息: {}", liveInfo);
|
||||||
try {
|
try {
|
||||||
|
// log.info("进入refreshLiveInfo解析liveInfo");
|
||||||
List<String> urls = extractPlayUrls(liveInfo);
|
List<String> urls = extractPlayUrls(liveInfo);
|
||||||
log.info("提取到的播放URL: {}", urls);
|
// log.info("提取到的播放URL: {}", urls);
|
||||||
urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(0));
|
if (urls.size()<2){
|
||||||
|
log.info("当前直播id: {}, 获取直播源失败", playId);
|
||||||
|
log.info("跳过当前直播,等待下一次获取");
|
||||||
|
continue;
|
||||||
|
// Thread.sleep(500);
|
||||||
|
// liveInfo = getLiveInfo(playId);
|
||||||
|
// urls = extractPlayUrls(liveInfo);
|
||||||
|
}
|
||||||
|
urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(0),"tx");
|
||||||
|
log.info("当前直播id: {}, 获取直播源成功", playId);
|
||||||
|
Thread.sleep(100);
|
||||||
|
// log.info("提取的直播链接:{}",urls.get(urls.size()-1));
|
||||||
|
// urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(1),"tx2");
|
||||||
|
// urlsMapper.updateUrlsWithGameId(games.getGameId(), urls.get(0),"zb");
|
||||||
// 这里可以保存urls到数据库或其他处理
|
// 这里可以保存urls到数据库或其他处理
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("解析直播信息失败");
|
log.error("解析直播信息失败");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ping.study.service.tx;
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.ping.study.model.vo.live.LiveIds;
|
||||||
import com.ping.study.model.vo.tx.MatchInfo;
|
import com.ping.study.model.vo.tx.MatchInfo;
|
||||||
import com.ping.study.model.vo.tx.MatchResponse;
|
import com.ping.study.model.vo.tx.MatchResponse;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -28,7 +29,7 @@ public class MatchService {
|
|||||||
/**
|
/**
|
||||||
* 获取指定日期范围内所有NBA季后赛(matchType=2)的直播ID
|
* 获取指定日期范围内所有NBA季后赛(matchType=2)的直播ID
|
||||||
*/
|
*/
|
||||||
public List<String> getPlayoffLiveIdsBlocking(LocalDate startDate, LocalDate endDate) {
|
public List<LiveIds> getPlayoffLiveIdsBlocking(LocalDate startDate, LocalDate endDate) {
|
||||||
return webClient.get()
|
return webClient.get()
|
||||||
.uri(uriBuilder -> uriBuilder
|
.uri(uriBuilder -> uriBuilder
|
||||||
.path("/matchUnion/list")
|
.path("/matchUnion/list")
|
||||||
@@ -42,18 +43,53 @@ public class MatchService {
|
|||||||
if (response.getCode() != 0 || response.getData() == null) {
|
if (response.getCode() != 0 || response.getData() == null) {
|
||||||
return Flux.error(new RuntimeException("API返回异常: " + response.getMsg()));
|
return Flux.error(new RuntimeException("API返回异常: " + response.getMsg()));
|
||||||
}
|
}
|
||||||
// 提取所有matchType=2的比赛
|
|
||||||
List<String> liveIds = response.getData().values().stream()
|
// 提取所有 matchType=2 & competitionId=100000 的比赛
|
||||||
|
List<LiveIds> liveIds = response.getData().values().stream()
|
||||||
.flatMap(List::stream)
|
.flatMap(List::stream)
|
||||||
.filter(match -> "2".equals(match.getMatchType()))
|
.filter(match -> "2".equals(match.getMatchType()))
|
||||||
.map(MatchInfo::getLiveId)
|
.filter(match -> "100000".equals(match.getCompetitionId()))
|
||||||
|
.map(match -> {
|
||||||
|
LiveIds ids = new LiveIds();
|
||||||
|
ids.setMId(match.getMId());
|
||||||
|
ids.setPlayId(match.getLiveId());
|
||||||
|
return ids;
|
||||||
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return Flux.fromIterable(liveIds);
|
return Flux.fromIterable(liveIds);
|
||||||
})
|
})
|
||||||
.collectList()
|
.collectList()
|
||||||
.block(); // 阻塞等待结果
|
.block(); // 阻塞等待结果
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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()))
|
||||||
|
// .filter(match -> "100000".equals(match.getCompetitionId()))
|
||||||
|
// .map(MatchInfo::getLiveId)
|
||||||
|
// .collect(Collectors.toList());
|
||||||
|
// return Flux.fromIterable(liveIds);
|
||||||
|
// })
|
||||||
|
// .collectList()
|
||||||
|
// .block(); // 阻塞等待结果
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取完整比赛信息(过滤matchType=2)
|
* 获取完整比赛信息(过滤matchType=2)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,35 @@
|
|||||||
package com.ping.study.service.tx;
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.ping.study.mapper.UrlsMapper;
|
||||||
import com.ping.study.model.dto.tx.MatchListRequest;
|
import com.ping.study.model.dto.tx.MatchListRequest;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class SportsQqService {
|
public class SportsQqService {
|
||||||
|
|
||||||
|
|
||||||
private final WebClient webClient;
|
private final WebClient webClient;
|
||||||
private static final DateTimeFormatter DATE_FORMATTER =
|
private static final DateTimeFormatter DATE_FORMATTER =
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UrlsMapper urlsMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper; // Spring Boot 自动注入 Jackson
|
||||||
|
|
||||||
public SportsQqService(WebClient.Builder webClientBuilder) {
|
public SportsQqService(WebClient.Builder webClientBuilder) {
|
||||||
this.webClient = webClientBuilder
|
this.webClient = webClientBuilder
|
||||||
.baseUrl("https://matchweb.sports.qq.com")
|
.baseUrl("https://matchweb.sports.qq.com")
|
||||||
@@ -20,8 +37,34 @@ public class SportsQqService {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- 修改点 1: 新增一个无参方法专门用于定时任务 ---
|
||||||
|
// 定时任务入口:不需要参数,也不需要返回值(或者返回Mono<Void>)
|
||||||
|
@Scheduled(cron = "0 0/5 3-16 * * ?")
|
||||||
|
public void scheduledSyncTask() {
|
||||||
|
log.info("开始执行定时同步直播源任务...");
|
||||||
|
|
||||||
|
// 1. 在这里手动构造请求参数
|
||||||
|
// 假设你需要查询当天的比赛
|
||||||
|
MatchListRequest request = new MatchListRequest();
|
||||||
|
//request.setColumnId("100000"); // 示例值,根据你的实际情况设置
|
||||||
|
request.setStartTime(LocalDate.now()); // 设置开始时间
|
||||||
|
request.setEndTime(LocalDate.now()); // 设置结束时间
|
||||||
|
|
||||||
|
// 2. 调用业务逻辑,并且必须订阅 (.subscribe) 才能触发执行
|
||||||
|
getMatchList(request)
|
||||||
|
.subscribe(
|
||||||
|
result -> log.info("定时任务执行完成"),
|
||||||
|
error -> log.error("定时任务执行出错", error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 修改点 2: 原来的方法去掉 @Scheduled,作为一个普通的服务方法 ---
|
||||||
public Mono<String> getMatchList(MatchListRequest request) {
|
public Mono<String> getMatchList(MatchListRequest request) {
|
||||||
request.validate(); // 参数校验
|
// 参数校验 (建议保留)
|
||||||
|
if (request == null) {
|
||||||
|
return Mono.error(new IllegalArgumentException("Request cannot be null"));
|
||||||
|
}
|
||||||
|
// request.validate(); // 如果你有 validate 方法
|
||||||
|
|
||||||
return webClient.get()
|
return webClient.get()
|
||||||
.uri(uriBuilder -> uriBuilder
|
.uri(uriBuilder -> uriBuilder
|
||||||
@@ -31,6 +74,128 @@ public class SportsQqService {
|
|||||||
.queryParam("endTime", request.getEndTime().format(DATE_FORMATTER))
|
.queryParam("endTime", request.getEndTime().format(DATE_FORMATTER))
|
||||||
.build())
|
.build())
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(String.class);
|
.bodyToMono(String.class)
|
||||||
|
.doOnNext(jsonString -> {
|
||||||
|
try {
|
||||||
|
JsonNode rootNode = objectMapper.readTree(jsonString);
|
||||||
|
JsonNode dataNode = rootNode.path("data");
|
||||||
|
|
||||||
|
dataNode.fields().forEachRemaining(entry -> {
|
||||||
|
JsonNode matchesArray = entry.getValue();
|
||||||
|
if (matchesArray.isArray()) {
|
||||||
|
for (JsonNode match : matchesArray) {
|
||||||
|
String mid = match.path("mid").asText("");
|
||||||
|
String matchPeriod = match.path("matchPeriod").asText("");
|
||||||
|
|
||||||
|
// 3. 处理 mid 获取后 10 位
|
||||||
|
String targetId = "";
|
||||||
|
if (mid.contains(":")) {
|
||||||
|
String[] parts = mid.split(":");
|
||||||
|
String suffix = parts[1]; // 这里拿到的是冒号后的完整部分,如 10022500079 (11位) 或 20257089 (8位)
|
||||||
|
|
||||||
|
// 如果长度大于10,截取最后10位;否则保持原样
|
||||||
|
if (suffix.length() > 10) {
|
||||||
|
targetId = suffix.substring(suffix.length() - 10);
|
||||||
|
} else {
|
||||||
|
targetId = suffix;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 防止没有冒号的情况,同样做截取保护
|
||||||
|
if (mid.length() > 10) {
|
||||||
|
targetId = mid.substring(mid.length() - 10);
|
||||||
|
} else {
|
||||||
|
targetId = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetId.isEmpty()) {
|
||||||
|
urlsMapper.updateStatusWithGameId(targetId, matchPeriod);
|
||||||
|
log.info("更新比赛:{} 直播状态成功,阶段: {}", targetId, matchPeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解析或更新数据库失败", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//更新直播源状态
|
||||||
|
//定时任务 每隔10分钟执行一次,从每天早上3点到下午5点之间执行
|
||||||
|
// @Scheduled(cron = "0 0/5 3-16 * * ?")
|
||||||
|
// public Mono<String> updateGameStatus() {
|
||||||
|
//// request.validate();
|
||||||
|
// MatchListRequest request = new MatchListRequest();
|
||||||
|
// 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)
|
||||||
|
// .doOnNext(jsonString -> {
|
||||||
|
// // --- 在这里进行解析和数据库保存操作 ---
|
||||||
|
// try {
|
||||||
|
// JsonNode rootNode = objectMapper.readTree(jsonString);
|
||||||
|
// JsonNode dataNode = rootNode.path("data");
|
||||||
|
//
|
||||||
|
// // 1. data 下面的 key 是动态日期 (例如 "2025-11-29"),所以我们要遍历字段
|
||||||
|
// dataNode.fields().forEachRemaining(entry -> {
|
||||||
|
// // String dateKey = entry.getKey(); // 如果需要日期,可以拿这个
|
||||||
|
// JsonNode matchesArray = entry.getValue();
|
||||||
|
//
|
||||||
|
// // 2. 遍历当天的比赛列表
|
||||||
|
// if (matchesArray.isArray()) {
|
||||||
|
// for (JsonNode match : matchesArray) {
|
||||||
|
// // 提取 mid
|
||||||
|
// String mid = match.path("mid").asText("");
|
||||||
|
// // 提取 matchPeriod
|
||||||
|
// String matchPeriod = match.path("matchPeriod").asText("");
|
||||||
|
//
|
||||||
|
// // 3. 处理 mid 获取后 10 位 (或冒号后的部分)
|
||||||
|
// String targetId = "";
|
||||||
|
// if (mid.contains(":")) {
|
||||||
|
// // 逻辑A:获取冒号后面的所有数字 (推荐,通常这是唯一ID)
|
||||||
|
// String[] parts = mid.split(":");
|
||||||
|
// targetId = parts[1];
|
||||||
|
//
|
||||||
|
// // 逻辑B:如果你严格需要“最后10位字符” (如果ID长度超过10,会截取)
|
||||||
|
// if (targetId.length() > 10) {
|
||||||
|
// targetId = targetId.substring(targetId.length() - 10);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// targetId = mid; // 防止没有冒号的情况
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 4. 保存到数据库
|
||||||
|
// if (!targetId.isEmpty()) {
|
||||||
|
// //saveMatchInfoToDb(mid, targetId, matchPeriod);
|
||||||
|
// urlsMapper.updateStatusWithGameId(targetId,matchPeriod);
|
||||||
|
// log.info("更新比赛:{}直播状态成功:",targetId);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// // 记录日志:解析失败
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package com.ping.study.service.tx;
|
package com.ping.study.service.tx;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.ping.study.model.vo.live.LiveInfoResponse;
|
import com.ping.study.utils.MailUtil;
|
||||||
import jakarta.annotation.PostConstruct;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -23,115 +21,97 @@ import java.util.stream.Collectors;
|
|||||||
public class TxSportTokenRefreshService {
|
public class TxSportTokenRefreshService {
|
||||||
|
|
||||||
private final WebClient webClient;
|
private final WebClient webClient;
|
||||||
private final StringRedisTemplate redisTemplate;
|
private final RedisTemplate<String, String> redisTemplate;
|
||||||
private static final String REDIS_COOKIE_KEY = "tx_sports_cookie";
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
private static final String REDIS_COOKIE_MAP_KEY = "tx_sports_cookie_map";
|
||||||
|
@Autowired
|
||||||
|
private MailUtil mailUtil;
|
||||||
|
|
||||||
public TxSportTokenRefreshService(WebClient.Builder builder,
|
public TxSportTokenRefreshService(WebClient.Builder builder,
|
||||||
StringRedisTemplate redisTemplate) {
|
RedisTemplate<String, String> redisTemplate) {
|
||||||
this.webClient = builder.baseUrl("https://app.sports.qq.com").build();
|
this.webClient = builder.baseUrl("https://app.sports.qq.com").build();
|
||||||
this.redisTemplate = redisTemplate;
|
this.redisTemplate = redisTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void initBaseCookies() {
|
|
||||||
String baseCookies = "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; ptui_loginuin=1131302745";
|
|
||||||
redisTemplate.opsForValue().set(REDIS_COOKIE_KEY, baseCookies, 30, TimeUnit.DAYS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新Cookie并存储到Redis
|
|
||||||
*/
|
|
||||||
// 在首次成功时,分离并存储基础登录态Cookie
|
|
||||||
public boolean refreshCookies() {
|
public boolean refreshCookies() {
|
||||||
try {
|
try {
|
||||||
// 1. 从Redis获取基础登录态Cookie(首次需手动初始化)
|
String cookieJson = redisTemplate.opsForValue().get(REDIS_COOKIE_MAP_KEY);
|
||||||
String baseCookie = redisTemplate.opsForValue().get(REDIS_COOKIE_KEY);
|
if (cookieJson == null) {
|
||||||
log.info("当前Cookie: {}", baseCookie);
|
log.error("Redis 中未找到 Cookie,无法刷新");
|
||||||
// 2. 携带基础Cookie发起请求
|
return false;
|
||||||
|
}
|
||||||
|
// log.info("旧的cookie:{}",cookieJson);
|
||||||
|
|
||||||
|
Map<String, String> baseCookies = objectMapper.readValue(cookieJson, new TypeReference<>() {});
|
||||||
|
String cookieHeader = buildCookieHeader(baseCookies);
|
||||||
|
|
||||||
|
log.info("新的cookie:{}",cookieHeader);
|
||||||
String response = webClient.get()
|
String response = webClient.get()
|
||||||
.uri("/init/refresh?os=web")
|
.uri("/init/refresh?os=web")
|
||||||
.header("Cookie", baseCookie) // 关键点:始终携带基础登录态
|
.header("Cookie", cookieHeader)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(String.class)
|
.bodyToMono(String.class)
|
||||||
.block();
|
.block();
|
||||||
// 3. 合并新旧Cookie(保留基础登录态)
|
|
||||||
JsonNode data = new ObjectMapper().readTree(response).path("data");
|
|
||||||
String newCookie = extractNewCookies(data); // 提取spt_token等
|
|
||||||
String finalCookie = mergeCookies(baseCookie, newCookie);
|
|
||||||
|
|
||||||
// 4. 存储到Redis
|
JsonNode data = objectMapper.readTree(response).path("data");
|
||||||
|
Map<String, String> newCookies = extractNewCookieMap(data);
|
||||||
|
|
||||||
|
baseCookies.putAll(newCookies);
|
||||||
|
|
||||||
redisTemplate.opsForValue().set(
|
redisTemplate.opsForValue().set(
|
||||||
REDIS_COOKIE_KEY,
|
REDIS_COOKIE_MAP_KEY,
|
||||||
finalCookie,
|
objectMapper.writeValueAsString(baseCookies),
|
||||||
Long.parseLong(data.path("tokenTTL").asText()),
|
Long.parseLong(data.path("tokenTTL").asText()),
|
||||||
TimeUnit.SECONDS
|
TimeUnit.SECONDS
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("刷新失败", e);
|
log.error("刷新 Cookie 失败,原因:{}", e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 从腾讯API响应中提取新的Cookie信息
|
private Map<String, String> extractNewCookieMap(JsonNode dataNode) {
|
||||||
*/
|
Map<String, String> result = new HashMap<>();
|
||||||
private String extractNewCookies(JsonNode dataNode) {
|
if (dataNode != null && dataNode.has("cookie")) {
|
||||||
if (dataNode == null || !dataNode.has("cookie")) {
|
for (JsonNode cookie : dataNode.get("cookie")) {
|
||||||
return "";
|
result.put(cookie.get("name").asText(), cookie.get("value").asText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
StringBuilder cookieStr = new StringBuilder();
|
|
||||||
Iterator<JsonNode> cookies = dataNode.path("cookie").elements();
|
|
||||||
|
|
||||||
while (cookies.hasNext()) {
|
|
||||||
JsonNode cookie = cookies.next();
|
|
||||||
cookieStr.append(cookie.path("name").asText())
|
|
||||||
.append("=")
|
|
||||||
.append(cookie.path("value").asText())
|
|
||||||
.append("; ");
|
|
||||||
}
|
|
||||||
|
|
||||||
return cookieStr.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String buildCookieHeader(Map<String, String> cookieMap) {
|
||||||
// 合并Cookie的工具方法
|
return cookieMap.entrySet().stream()
|
||||||
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())
|
.map(e -> e.getKey() + "=" + e.getValue())
|
||||||
.collect(Collectors.joining("; "));
|
.collect(Collectors.joining("; "));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 可选:定时自动刷新(你可以打开)
|
||||||
* 定时刷新任务(每1小时执行一次)
|
@Scheduled(fixedRate = 1800000)
|
||||||
*/
|
|
||||||
// @Scheduled(fixedRate = 3600000)
|
|
||||||
public void scheduledRefresh() {
|
public void scheduledRefresh() {
|
||||||
if (!refreshCookies()) {
|
log.info("定时刷新Cookie");
|
||||||
log.warn("首次刷新失败,尝试重新初始化基础Cookie...");
|
|
||||||
initBaseCookies();
|
boolean success = refreshCookies();
|
||||||
// try {
|
|
||||||
// Thread.sleep(30000); // 等待30秒后重试
|
if (success) {
|
||||||
// if (!refreshCookies()) {
|
redisTemplate.delete("errors");
|
||||||
// log.error("重试刷新仍然失败");
|
log.info("Cookie 刷新成功");
|
||||||
// }
|
return;
|
||||||
// } catch (InterruptedException e) {
|
}
|
||||||
// Thread.currentThread().interrupt();
|
|
||||||
// }
|
Long errorCount = redisTemplate.opsForValue().increment("errors");
|
||||||
|
|
||||||
|
log.warn("Cookie 刷新失败,当前连续失败次数:{}", errorCount);
|
||||||
|
|
||||||
|
if (errorCount != null && errorCount > 2) {
|
||||||
|
log.warn("Cookie 刷新失败超过 2 次,Redis 中可能缺失数据");
|
||||||
|
|
||||||
|
mailUtil.sendEmail2(
|
||||||
|
"1131302745@qq.com",
|
||||||
|
"NBA服务异常通知",
|
||||||
|
"腾讯体育超级会员 Cookie 刷新失败,请排查。当前连续失败次数:" + errorCount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
src/main/java/com/ping/study/test/TxMatch.java
Normal file
47
src/main/java/com/ping/study/test/TxMatch.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package com.ping.study.test;
|
||||||
|
|
||||||
|
import com.ping.study.model.dto.tx.TxMatchRequest;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/test")
|
||||||
|
public class TxMatch {
|
||||||
|
|
||||||
|
private final WebClient webClient;
|
||||||
|
|
||||||
|
public TxMatch(@Qualifier("matchWebClient") WebClient webClient) {
|
||||||
|
this.webClient = webClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/match")
|
||||||
|
public String getMatch() {
|
||||||
|
TxMatchRequest request = new TxMatchRequest();
|
||||||
|
System.out.println("TxMatchRequest = " + request);
|
||||||
|
|
||||||
|
// 正式发起请求
|
||||||
|
return webClient.get()
|
||||||
|
.uri(uriBuilder -> {
|
||||||
|
uriBuilder.path("/matchUnion/list")
|
||||||
|
.queryParam("today", request.getToday())
|
||||||
|
.queryParam("startTime", request.getStartTime())
|
||||||
|
.queryParam("endTime", request.getEndTime())
|
||||||
|
.queryParam("columnId", request.getColumnId())
|
||||||
|
.queryParam("index", request.getIndex())
|
||||||
|
.queryParam("isInit", request.getIsInit())
|
||||||
|
.queryParam("timestamp", request.getTimestamp())
|
||||||
|
.queryParam("callback", request.getCallback());
|
||||||
|
return uriBuilder.build();
|
||||||
|
})
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.block();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
201
src/main/java/com/ping/study/utils/MailUtil.java
Normal file
201
src/main/java/com/ping/study/utils/MailUtil.java
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package com.ping.study.utils;
|
||||||
|
|
||||||
|
import jakarta.mail.MessagingException;
|
||||||
|
import jakarta.mail.internet.MimeMessage;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mail.SimpleMailMessage;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮件发送工具类
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class MailUtil {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
private final JavaMailSender javaMailSender;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public MailUtil(JavaMailSender javaMailSender) {
|
||||||
|
this.javaMailSender = javaMailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 6 位数字验证码
|
||||||
|
*
|
||||||
|
* @return 6 位验证码
|
||||||
|
*/
|
||||||
|
private String generateVerificationCode() {
|
||||||
|
Random random = new Random();
|
||||||
|
int code = 100000 + random.nextInt(900000); // 生成 100000 - 999999 的随机数
|
||||||
|
return String.valueOf(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
*/
|
||||||
|
public String sendVerificationCode(String to) {
|
||||||
|
Assert.hasText(to, "邮箱不能为空");
|
||||||
|
|
||||||
|
// 生成验证码
|
||||||
|
String verificationCode = generateVerificationCode();
|
||||||
|
// 构造邮件
|
||||||
|
SimpleMailMessage message = new SimpleMailMessage();
|
||||||
|
message.setFrom("xdd9@vip.qq.com");
|
||||||
|
message.setTo(to);
|
||||||
|
message.setSubject("【NBA轻松看验证码】");
|
||||||
|
message.setText("您的验证码是:" + verificationCode + ",有效期 5 分钟"+"。请勿回复此邮件。"+"\n反馈邮箱:super@2026123.xyz"+"\n发布页:2026123.xyz");
|
||||||
|
// message.setText("发布页:2026123.xyz");
|
||||||
|
// 发送邮件
|
||||||
|
try {
|
||||||
|
// 返回验证码(存入 Redis 用于验证)
|
||||||
|
if (redisUtil.redisTemplateT(to,verificationCode)){
|
||||||
|
javaMailSender.send(message);
|
||||||
|
log.info("收件邮箱 -> {}", to);
|
||||||
|
log.info("验证码存入redis -> {}", verificationCode);
|
||||||
|
return "验证码发送成功,因邮件发送有延迟请不要重复发送";
|
||||||
|
}
|
||||||
|
// redisUtil.redisTemplateT(to,verificationCode);
|
||||||
|
return "验证码已发送到邮箱,请不要重复点击,如未收到邮件检查垃圾箱或邮箱是否正确";
|
||||||
|
// return verificationCode;
|
||||||
|
}catch (Exception e){
|
||||||
|
//System.out.println("发送邮件失败:" + e.getMessage());
|
||||||
|
return "发送邮件失败,请检查邮箱号是否正确";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param text 邮件内容
|
||||||
|
*/
|
||||||
|
public String sendEmail2(String to,String subject,String text) {
|
||||||
|
Assert.hasText(to, "邮箱不能为空");
|
||||||
|
|
||||||
|
// 构造邮件
|
||||||
|
SimpleMailMessage message = new SimpleMailMessage();
|
||||||
|
message.setFrom("xdd9@vip.qq.com");
|
||||||
|
message.setTo(to);
|
||||||
|
message.setSubject(subject);
|
||||||
|
message.setText(text);
|
||||||
|
// message.setText("发布页:2026123.xyz");
|
||||||
|
// 发送邮件
|
||||||
|
try {
|
||||||
|
javaMailSender.send(message);
|
||||||
|
return "发送成功";
|
||||||
|
// return verificationCode;
|
||||||
|
}catch (Exception e){
|
||||||
|
log.info("发送邮件失败:{}", e.getMessage());
|
||||||
|
return "发送邮件失败";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param map
|
||||||
|
*/
|
||||||
|
public void sendEmail(HashMap<String,String> map) {
|
||||||
|
Assert.hasText(map.get("mail"), "收件人不能为空");
|
||||||
|
|
||||||
|
// 构造邮件
|
||||||
|
SimpleMailMessage message = new SimpleMailMessage();
|
||||||
|
message.setFrom("xdd9@vip.qq.com");
|
||||||
|
message.setTo(map.get("mail"));
|
||||||
|
message.setSubject(map.get("subject"));
|
||||||
|
message.setText(map.get("text"));
|
||||||
|
// 发送邮件
|
||||||
|
javaMailSender.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送 HTML 邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param html HTML 内容
|
||||||
|
*/
|
||||||
|
public void sendHtmlEmail(String to, String subject, String html) throws MessagingException, jakarta.mail.MessagingException {
|
||||||
|
Assert.hasText(to, "邮箱不能为空");
|
||||||
|
Assert.hasText(subject, "邮件主题不能为空");
|
||||||
|
Assert.hasText(html, "HTML 内容不能为空");
|
||||||
|
|
||||||
|
jakarta.mail.internet.MimeMessage message = javaMailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||||
|
helper.setTo(to);
|
||||||
|
helper.setSubject(subject);
|
||||||
|
helper.setText(html, true); // true 表示支持 HTML
|
||||||
|
javaMailSender.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送带附件的邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param text 邮件内容
|
||||||
|
* @param attachments 附件文件列表
|
||||||
|
*/
|
||||||
|
public void sendEmailWithAttachments(String to, String subject, String text, List<File> attachments) throws MessagingException, jakarta.mail.MessagingException {
|
||||||
|
Assert.hasText(to, "收件人邮箱不能为空");
|
||||||
|
Assert.hasText(subject, "邮件主题不能为空");
|
||||||
|
Assert.hasText(text, "邮件内容不能为空");
|
||||||
|
Assert.notEmpty(attachments, "附件列表不能为空");
|
||||||
|
|
||||||
|
jakarta.mail.internet.MimeMessage message = javaMailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||||
|
helper.setTo(to);
|
||||||
|
helper.setSubject(subject);
|
||||||
|
helper.setText(text);
|
||||||
|
|
||||||
|
// 添加附件
|
||||||
|
for (File file : attachments) {
|
||||||
|
helper.addAttachment(file.getName(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
javaMailSender.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送带内联资源的 HTML 邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param html HTML 内容
|
||||||
|
* @param inlineFiles 内联资源文件列表
|
||||||
|
*/
|
||||||
|
public void sendHtmlEmailWithInline(String to, String subject, String html, List<File> inlineFiles) throws MessagingException, jakarta.mail.MessagingException {
|
||||||
|
Assert.hasText(to, "收件人邮箱不能为空");
|
||||||
|
Assert.hasText(subject, "邮件主题不能为空");
|
||||||
|
Assert.hasText(html, "HTML 内容不能为空");
|
||||||
|
Assert.notEmpty(inlineFiles, "内联资源文件列表不能为空");
|
||||||
|
|
||||||
|
MimeMessage message = javaMailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||||
|
helper.setTo(to);
|
||||||
|
helper.setSubject(subject);
|
||||||
|
helper.setText(html, true);
|
||||||
|
|
||||||
|
// 添加内联资源
|
||||||
|
for (File file : inlineFiles) {
|
||||||
|
helper.addInline(file.getName(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
javaMailSender.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.ping.study.utils;
|
package com.ping.study.utils;
|
||||||
|
|
||||||
|
import com.ping.study.mapper.UrlsMapper;
|
||||||
import com.ping.study.model.dto.NbaStatsRequestDto;
|
import com.ping.study.model.dto.NbaStatsRequestDto;
|
||||||
import com.ping.study.model.vo.ApiResponse;
|
import com.ping.study.model.vo.ApiResponse;
|
||||||
import com.ping.study.model.vo.Game;
|
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.model.vo.live.LiveIds;
|
||||||
import com.ping.study.pojo.Games;
|
import com.ping.study.pojo.Games;
|
||||||
|
import com.ping.study.pojo.Urls;
|
||||||
import com.ping.study.service.GamesService;
|
import com.ping.study.service.GamesService;
|
||||||
import com.ping.study.service.tx.MatchService;
|
import com.ping.study.service.tx.MatchService;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -34,17 +37,22 @@ public class NbaApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MatchService matchService;
|
private MatchService matchService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UrlsMapper urlsMapper;
|
||||||
|
|
||||||
public NbaApi(@Qualifier("nbaWebClient")WebClient webClient) {
|
public NbaApi(@Qualifier("nbaWebClient")WebClient webClient) {
|
||||||
this.webClient = webClient;
|
this.webClient = webClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Games> addGames() {
|
public List<Games> addGames() throws InterruptedException {
|
||||||
// 创建请求DTO(会自动设置当前时间戳和日期)
|
// 创建请求DTO(会自动设置当前时间戳和日期)
|
||||||
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
|
//获取所有当天直播id集合
|
||||||
List<String> lives = matchService.getPlayoffLiveIdsBlocking(LocalDate.now(), LocalDate.now());
|
List<LiveIds> lives = matchService.getPlayoffLiveIdsBlocking(LocalDate.now(), LocalDate.now());
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
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())
|
||||||
@@ -64,7 +72,7 @@ public class NbaApi {
|
|||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(ApiResponse.class)
|
.bodyToMono(ApiResponse.class)
|
||||||
.map(response -> {
|
.map(response -> {
|
||||||
log.info("{}", response);
|
|
||||||
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()) {
|
||||||
@@ -76,7 +84,14 @@ public class NbaApi {
|
|||||||
entity.setAwayTeamName(group.getGames().get(i).getAwayTeamName());
|
entity.setAwayTeamName(group.getGames().get(i).getAwayTeamName());
|
||||||
entity.setHomeTeamLogoDark(group.getGames().get(i).getHomeTeamLogoDark());
|
entity.setHomeTeamLogoDark(group.getGames().get(i).getHomeTeamLogoDark());
|
||||||
entity.setAwayTeamLogoDark(group.getGames().get(i).getAwayTeamLogoDark());
|
entity.setAwayTeamLogoDark(group.getGames().get(i).getAwayTeamLogoDark());
|
||||||
entity.setPlayId(lives.get(i));
|
entity.setStatus(group.getGames().get(i).getStatus());
|
||||||
|
for (int j = 0; j < lives.size(); j++){
|
||||||
|
if (lives.get(j).getMId().contains(group.getGames().get(i).getGameId())){
|
||||||
|
entity.setPlayId(lives.get(j).getPlayId());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// entity.setPlayId(lives.get(i));
|
||||||
// 合并日期和时间
|
// 合并日期和时间
|
||||||
String dateTimeStr = group.getGames().get(i).getStartDate() + " " + group.getGames().get(i).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");
|
||||||
@@ -86,31 +101,28 @@ public class NbaApi {
|
|||||||
// 处理异常或设置默认值
|
// 处理异常或设置默认值
|
||||||
entity.setStartTime(null);
|
entity.setStartTime(null);
|
||||||
}
|
}
|
||||||
|
for (int j = 0; j < 2; j++){
|
||||||
|
Urls urls = new Urls(); // 每次新建一个对象
|
||||||
|
urls.setGameId(entity.getGameId());
|
||||||
|
switch (j) {
|
||||||
|
case 0:
|
||||||
|
urls.setType("tx");
|
||||||
|
urls.setUrl("");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
urls.setType("zb");
|
||||||
|
urls.setUrl("");
|
||||||
|
break;
|
||||||
|
// case 2:
|
||||||
|
// urls.setType("zb");
|
||||||
|
// urls.setUrl("");
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
urlsMapper.insertSelective(urls);
|
||||||
|
}
|
||||||
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;
|
||||||
})
|
})
|
||||||
|
|||||||
24
src/main/java/com/ping/study/utils/RedisUtil.java
Normal file
24
src/main/java/com/ping/study/utils/RedisUtil.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ping.study.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class RedisUtil {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> stringRedisTemplate;
|
||||||
|
|
||||||
|
public boolean redisTemplateT(String email,String code) {
|
||||||
|
//log.info("验证码:{}",code);
|
||||||
|
return stringRedisTemplate.opsForValue().setIfAbsent(email, code, Duration.ofSeconds(60*5));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
src/main/java/com/ping/study/utils/UserUtil.java
Normal file
24
src/main/java/com/ping/study/utils/UserUtil.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ping.study.utils;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserUtil {
|
||||||
|
|
||||||
|
public String getClientIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
// 取第一段 IP
|
||||||
|
return ip.split(",")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = request.getHeader("X-Real-IP");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
return request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
194
src/main/java/com/ping/study/utils/tx/TxVideoAuthRedisUtil.java
Normal file
194
src/main/java/com/ping/study/utils/tx/TxVideoAuthRedisUtil.java
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
package com.ping.study.utils.tx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Redis 获取 cookie 并生成 auth_ext / logintoken(raw + urlencoded)
|
||||||
|
*
|
||||||
|
* 使用:
|
||||||
|
* @Autowired TxVideoAuthRedisUtil txUtil;
|
||||||
|
* Map<String,String> result = txUtil.buildAuthAndLoginToken("tx_sports_cookie_map");
|
||||||
|
* String authExtEncoded = result.get("auth_ext_encoded");
|
||||||
|
* String loginTokenEncoded = result.get("logintoken_encoded");
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TxVideoAuthRedisUtil {
|
||||||
|
|
||||||
|
private final RedisTemplate<String, String> stringRedisTemplate;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public TxVideoAuthRedisUtil(RedisTemplate<String, String> stringRedisTemplate) {
|
||||||
|
this.stringRedisTemplate = stringRedisTemplate;
|
||||||
|
this.objectMapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主方法:给定 redis key(存 cookie 的值),返回 map 包含:
|
||||||
|
* - auth_ext_raw
|
||||||
|
* - auth_ext_encoded
|
||||||
|
* - logintoken_raw
|
||||||
|
* - logintoken_encoded
|
||||||
|
* - cookie_map_json (string representation of parsed cookie map)
|
||||||
|
*/
|
||||||
|
public Map<String, String> buildAuthAndLoginToken(String redisKey) {
|
||||||
|
String redisValue = stringRedisTemplate.opsForValue().get(redisKey);
|
||||||
|
Map<String, String> cookieMap = parseRedisCookieValue(redisValue);
|
||||||
|
|
||||||
|
String authExtRaw = genAuthExt(cookieMap);
|
||||||
|
String logintokenRaw = genLoginToken(cookieMap);
|
||||||
|
|
||||||
|
String authExtEncoded = urlEncode(authExtRaw);
|
||||||
|
String logintokenEncoded = urlEncode(logintokenRaw);
|
||||||
|
|
||||||
|
Map<String, String> out = new HashMap<>();
|
||||||
|
out.put("auth_ext_raw", authExtRaw);
|
||||||
|
out.put("auth_ext_encoded", authExtEncoded);
|
||||||
|
out.put("logintoken_raw", logintokenRaw);
|
||||||
|
out.put("logintoken_encoded", logintokenEncoded);
|
||||||
|
try {
|
||||||
|
out.put("cookie_map_json", objectMapper.writeValueAsString(cookieMap));
|
||||||
|
} catch (Exception e) {
|
||||||
|
out.put("cookie_map_json", cookieMap.toString());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 Redis 中的值 —— 支持两种常见情况:
|
||||||
|
* 1) JSON 字符串(例如你直接把 Map->JSON 存进去);
|
||||||
|
* 2) Cookie 的原始字符串 "k=v; k2=v2; ..."
|
||||||
|
*/
|
||||||
|
private Map<String, String> parseRedisCookieValue(String redisValue) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
if (redisValue == null) return map;
|
||||||
|
|
||||||
|
String trimmed = redisValue.trim();
|
||||||
|
// 1) 如果像 JSON(以 { 开头 和 } 结尾),尝试解析为 Map
|
||||||
|
if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
|
||||||
|
(trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
||||||
|
try {
|
||||||
|
Map<String, Object> temp = objectMapper.readValue(trimmed, new TypeReference<Map<String,Object>>() {});
|
||||||
|
for (Map.Entry<String, Object> e : temp.entrySet()) {
|
||||||
|
map.put(e.getKey(), e.getValue() == null ? "" : String.valueOf(e.getValue()));
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// 解析失败 —— 退回到 cookie 规则解析
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) cookie 格式解析: "a=1; b=2; c=3"
|
||||||
|
String[] parts = redisValue.split(";");
|
||||||
|
for (String p : parts) {
|
||||||
|
if (p == null) continue;
|
||||||
|
String kv = p.trim();
|
||||||
|
if (kv.isEmpty()) continue;
|
||||||
|
int idx = kv.indexOf('=');
|
||||||
|
if (idx <= 0) continue;
|
||||||
|
String k = kv.substring(0, idx).trim();
|
||||||
|
String v = kv.substring(idx + 1).trim();
|
||||||
|
if (v.startsWith("\"") && v.endsWith("\"") && v.length() >= 2) {
|
||||||
|
v = v.substring(1, v.length() - 1);
|
||||||
|
}
|
||||||
|
map.put(k, v);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 auth_ext raw JSON 字符串(未 encode)
|
||||||
|
* 形如: {"main_login":"qq","vqq_openid":"...","vqq_appid":"...","vqq_access_token":"..."}
|
||||||
|
* 若 cookie 缺字段则使用空串
|
||||||
|
*/
|
||||||
|
private String genAuthExt(Map<String, String> cookie) {
|
||||||
|
Map<String, String> auth = new LinkedHashMap<>();
|
||||||
|
auth.put("main_login", cookie.getOrDefault("main_login", "qq"));
|
||||||
|
auth.put("vqq_openid", cookie.getOrDefault("vqq_openid", cookie.getOrDefault("openid", "")));
|
||||||
|
auth.put("vqq_appid", cookie.getOrDefault("vqq_appid", cookie.getOrDefault("appid", "")));
|
||||||
|
auth.put("vqq_access_token", cookie.getOrDefault("vqq_access_token", cookie.getOrDefault("access_token", "")));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(auth);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 手工构造(极小概率)
|
||||||
|
StringBuilder sb = new StringBuilder("{");
|
||||||
|
boolean first = true;
|
||||||
|
for (Map.Entry<String, String> en : auth.entrySet()) {
|
||||||
|
if (!first) sb.append(",");
|
||||||
|
sb.append("\"").append(escapeJson(en.getKey())).append("\":");
|
||||||
|
sb.append("\"").append(escapeJson(en.getValue())).append("\"");
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
sb.append("}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 logintoken raw JSON 字符串(未 encode)
|
||||||
|
* 常见字段来源于 cookie:vqq_access_token, vqq_appid, vqq_vusession/vqq_vsession, vqq_openid, vqq_vuserid, video_guid, main_login
|
||||||
|
*/
|
||||||
|
private String genLoginToken(Map<String, String> cookie) {
|
||||||
|
Map<String, String> t = new LinkedHashMap<>();
|
||||||
|
t.put("access_token", cookie.getOrDefault("vqq_access_token", cookie.getOrDefault("access_token", "")));
|
||||||
|
t.put("appid", cookie.getOrDefault("vqq_appid", cookie.getOrDefault("appid", "")));
|
||||||
|
// 多种可能命名,优先常见 vqq_vusession -> vqq_vusession -> vusession -> vusess
|
||||||
|
String vusession = cookie.getOrDefault("vqq_vusession",
|
||||||
|
cookie.getOrDefault("vqq_vsession",
|
||||||
|
cookie.getOrDefault("vusession", "")));
|
||||||
|
t.put("vusession", vusession);
|
||||||
|
t.put("openid", cookie.getOrDefault("vqq_openid", cookie.getOrDefault("openid", "")));
|
||||||
|
t.put("vuserid", cookie.getOrDefault("vqq_vuserid", cookie.getOrDefault("vuserid", "")));
|
||||||
|
t.put("video_guid", cookie.getOrDefault("video_guid", cookie.getOrDefault("qq_domain_video_guid_verify", "")));
|
||||||
|
t.put("main_login", cookie.getOrDefault("main_login", "qq"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(t);
|
||||||
|
} catch (Exception e) {
|
||||||
|
StringBuilder sb = new StringBuilder("{");
|
||||||
|
boolean first = true;
|
||||||
|
for (Map.Entry<String, String> en : t.entrySet()) {
|
||||||
|
if (!first) sb.append(",");
|
||||||
|
sb.append("\"").append(escapeJson(en.getKey())).append("\":");
|
||||||
|
sb.append("\"").append(escapeJson(en.getValue())).append("\"");
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
sb.append("}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String urlEncode(String s) {
|
||||||
|
if (s == null) return "";
|
||||||
|
return URLEncoder.encode(s, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简单 JSON 字符串转义(用于 fallback)
|
||||||
|
private String escapeJson(String s) {
|
||||||
|
if (s == null) return "";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (char ch : s.toCharArray()) {
|
||||||
|
switch (ch) {
|
||||||
|
case '"': sb.append("\\\""); break;
|
||||||
|
case '\\': sb.append("\\\\"); break;
|
||||||
|
case '\b': sb.append("\\b"); break;
|
||||||
|
case '\f': sb.append("\\f"); break;
|
||||||
|
case '\n': sb.append("\\n"); break;
|
||||||
|
case '\r': sb.append("\\r"); break;
|
||||||
|
case '\t': sb.append("\\t"); break;
|
||||||
|
default:
|
||||||
|
if (ch < 0x20) sb.append(String.format("\\u%04x", (int) ch));
|
||||||
|
else sb.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,63 @@
|
|||||||
server:
|
server:
|
||||||
|
servlet:
|
||||||
|
session:
|
||||||
|
cookie:
|
||||||
|
same-site: None
|
||||||
|
secure: true # 生产是 https 必须 true
|
||||||
port: 9005
|
port: 9005
|
||||||
|
#spring:
|
||||||
|
# data:
|
||||||
|
# redis:
|
||||||
|
# host: 167.253.156.235
|
||||||
|
# port: 6739
|
||||||
|
# password: redis_a7Gw6f
|
||||||
|
#spring:
|
||||||
|
# data:
|
||||||
|
# redis:
|
||||||
|
# host: 103.244.88.91
|
||||||
|
# port: 6379
|
||||||
|
# password: inspur123
|
||||||
|
# timeout: 5000ms
|
||||||
spring:
|
spring:
|
||||||
data:
|
data:
|
||||||
redis:
|
redis:
|
||||||
host: 110.42.255.182
|
host: 116.62.173.2
|
||||||
port: 6739
|
port: 6379
|
||||||
|
password: redis_cfF356
|
||||||
|
timeout: 5000ms
|
||||||
application:
|
application:
|
||||||
name: NBA
|
name: NBA
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
#mysql5.7.4配置
|
||||||
url: jdbc:mysql://110.42.255.182:3306/NBA?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/nba?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
||||||
|
# url: jdbc:mysql://116.62.173.2:3306/nba?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
||||||
|
# url: jdbc:mysql://154.36.154.211:9002/nba?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
||||||
username: root
|
username: root
|
||||||
password: inspur123
|
password: 123123321 #本地
|
||||||
|
# password: mysql_k2KzJj #阿里云杭州
|
||||||
|
# driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
# url: jdbc:mysql://103.244.88.91:3306/nba?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
||||||
|
# username: nba
|
||||||
|
# password: d2mzG6w8277NpxFW
|
||||||
|
mail:
|
||||||
|
host: smtp.qq.com
|
||||||
|
port: 465
|
||||||
|
username: xdd9@vip.qq.com
|
||||||
|
password: qhcladjicfydbejj
|
||||||
|
default-encoding: UTF-8
|
||||||
|
properties:
|
||||||
|
mail.smtp.connectiontimeout: 5000 # 连接超时 5 秒
|
||||||
|
mail.smtp.timeout: 5000 # 读超时 5 秒
|
||||||
|
mail.smtp.writetimeout: 5000 # 写超时 5 秒
|
||||||
|
mail:
|
||||||
|
smtp:
|
||||||
|
auth: true
|
||||||
|
ssl:
|
||||||
|
enable: true
|
||||||
|
starttls:
|
||||||
|
enable: true
|
||||||
|
required: true
|
||||||
mybatis:
|
mybatis:
|
||||||
configuration:
|
configuration:
|
||||||
map-underscore-to-camel-case: true
|
map-underscore-to-camel-case: true
|
||||||
|
|||||||
72
src/main/resources/com/ping/study/mapper/LoginLogMapper.xml
Normal file
72
src/main/resources/com/ping/study/mapper/LoginLogMapper.xml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?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="com.ping.study.mapper.LoginLogMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.ping.study.pojo.LoginLog">
|
||||||
|
<id property="id" column="id" />
|
||||||
|
<result property="userId" column="user_id" />
|
||||||
|
<result property="loginTime" column="login_time" />
|
||||||
|
<result property="loginIp" column="login_ip" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id,user_id,login_time,login_ip
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from login_log
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
|
||||||
|
delete from login_log
|
||||||
|
where id = #{id}
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.LoginLog" useGeneratedKeys="true">
|
||||||
|
insert into login_log
|
||||||
|
( id,user_id,login_time,login_ip)
|
||||||
|
values (#{id},#{userId},#{loginTime},#{loginIp})
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.LoginLog" useGeneratedKeys="true">
|
||||||
|
insert into login_log
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">id,</if>
|
||||||
|
<if test="userId != null">user_id,</if>
|
||||||
|
<if test="loginTime != null">login_time,</if>
|
||||||
|
<if test="loginIp != null">login_ip,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">#{id},</if>
|
||||||
|
<if test="userId != null">#{userId},</if>
|
||||||
|
<if test="loginTime != null">#{loginTime},</if>
|
||||||
|
<if test="loginIp != null">#{loginIp},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<update id="updateByPrimaryKeySelective" parameterType="com.ping.study.pojo.LoginLog">
|
||||||
|
update login_log
|
||||||
|
<set>
|
||||||
|
<if test="userId != null">
|
||||||
|
user_id = #{userId},
|
||||||
|
</if>
|
||||||
|
<if test="loginTime != null">
|
||||||
|
login_time = #{loginTime},
|
||||||
|
</if>
|
||||||
|
<if test="loginIp != null">
|
||||||
|
login_ip = #{loginIp},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="com.ping.study.pojo.LoginLog">
|
||||||
|
update login_log
|
||||||
|
set
|
||||||
|
user_id = #{userId},
|
||||||
|
login_time = #{loginTime},
|
||||||
|
login_ip = #{loginIp}
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
</mapper>
|
||||||
139
src/main/resources/com/ping/study/mapper/NbaUserMapper.xml
Normal file
139
src/main/resources/com/ping/study/mapper/NbaUserMapper.xml
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?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="com.ping.study.mapper.NbaUserMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.ping.study.pojo.NbaUser">
|
||||||
|
<id property="id" column="id" />
|
||||||
|
<result property="username" column="username" />
|
||||||
|
<result property="password" column="password" />
|
||||||
|
<result property="email" column="email" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="lastLoginTime" column="last_login_time" />
|
||||||
|
<result property="lastLoginIp" column="last_login_ip" />
|
||||||
|
<result property="registerIp" column="register_ip" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id,username,password,email,create_time,update_time,
|
||||||
|
last_login_time,last_login_ip,register_ip
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from nba_user
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
|
||||||
|
delete from nba_user
|
||||||
|
where id = #{id}
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.NbaUser" useGeneratedKeys="true">
|
||||||
|
insert into nba_user
|
||||||
|
( id,username,password,email,create_time,update_time,
|
||||||
|
last_login_time,last_login_ip,register_ip)
|
||||||
|
values (#{id},#{username},#{password},#{email},#{createTime},#{updateTime},
|
||||||
|
#{lastLoginTime},#{lastLoginIp},#{registerIp})
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.ping.study.pojo.NbaUser" useGeneratedKeys="true">
|
||||||
|
insert into nba_user
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">id,</if>
|
||||||
|
<if test="username != null">username,</if>
|
||||||
|
<if test="password != null">password,</if>
|
||||||
|
<if test="email != null">email,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
<if test="lastLoginTime != null">last_login_time,</if>
|
||||||
|
<if test="lastLoginIp != null">last_login_ip,</if>
|
||||||
|
<if test="registerIp != null">register_ip,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">#{id},</if>
|
||||||
|
<if test="username != null">#{username},</if>
|
||||||
|
<if test="password != null">#{password},</if>
|
||||||
|
<if test="email != null">#{email},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
<if test="lastLoginTime != null">#{lastLoginTime},</if>
|
||||||
|
<if test="lastLoginIp != null">#{lastLoginIp},</if>
|
||||||
|
<if test="registerIp != null">#{registerIp},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<update id="updateByPrimaryKeySelective" parameterType="com.ping.study.pojo.NbaUser">
|
||||||
|
update nba_user
|
||||||
|
<set>
|
||||||
|
<if test="username != null">
|
||||||
|
username = #{username},
|
||||||
|
</if>
|
||||||
|
<if test="password != null">
|
||||||
|
password = #{password},
|
||||||
|
</if>
|
||||||
|
<if test="email != null">
|
||||||
|
email = #{email},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time = #{createTime},
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
update_time = #{updateTime},
|
||||||
|
</if>
|
||||||
|
<if test="lastLoginTime != null">
|
||||||
|
last_login_time = #{lastLoginTime},
|
||||||
|
</if>
|
||||||
|
<if test="lastLoginIp != null">
|
||||||
|
last_login_ip = #{lastLoginIp},
|
||||||
|
</if>
|
||||||
|
<if test="registerIp != null">
|
||||||
|
register_ip = #{registerIp},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="com.ping.study.pojo.NbaUser">
|
||||||
|
update nba_user
|
||||||
|
set
|
||||||
|
username = #{username},
|
||||||
|
password = #{password},
|
||||||
|
email = #{email},
|
||||||
|
create_time = #{createTime},
|
||||||
|
update_time = #{updateTime},
|
||||||
|
last_login_time = #{lastLoginTime},
|
||||||
|
last_login_ip = #{lastLoginIp},
|
||||||
|
register_ip = #{registerIp}
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="login" resultType="com.ping.study.pojo.NbaUser">
|
||||||
|
select * from nba_user where email = #{email} and password = #{password}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateRememberToken">
|
||||||
|
update nba_user set remember_token = #{token} where id = #{userId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="selectByRememberToken" resultType="NbaUser">
|
||||||
|
select * from nba_user where remember_token = #{token} limit 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="clearRememberToken">
|
||||||
|
update nba_user set remember_token = null where remember_token = #{token}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="findByEmail" resultType="NbaUser">
|
||||||
|
select * from nba_user where email = #{email}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByEmail" resultType="NbaUser">
|
||||||
|
select * from nba_user where email = #{email}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updatePasswordByEmail">
|
||||||
|
update nba_user set password = #{password} where email = #{email}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -77,12 +77,16 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectUrlsListByGameId" resultType="map">
|
<select id="selectUrlsListByGameId" resultType="map">
|
||||||
select urls.id,urls.type,urls.url from urls where game_id = #{gameId}
|
select urls.id,urls.type from urls where game_id = #{gameId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectUrlsListByAdmin" resultType="map">
|
||||||
|
select urls.id,urls.type,urls.m3u8_url from urls where game_id = #{gameId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insertUrlsWithGameId">
|
<insert id="insertUrlsWithGameId">
|
||||||
insert into urls
|
insert into urls
|
||||||
(game_id, url, type)
|
(game_id, m3u8_url, type)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{gameId}, #{item.url}, #{item.type})
|
(#{gameId}, #{item.url}, #{item.type})
|
||||||
@@ -96,6 +100,22 @@
|
|||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<update id="updateUrlsWithGameId" parameterType="map">
|
<update id="updateUrlsWithGameId" parameterType="map">
|
||||||
update urls set url = #{s},type = 'tx' where game_id = #{gameId}
|
update urls set url = #{s} where game_id = #{gameId} and type = #{type}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- <select id="findUrlByGameIdAndType" resultType="string">-->
|
||||||
|
<!-- select url from urls where game_id = #{gameId} and type = #{type}-->
|
||||||
|
<!-- </select>-->
|
||||||
|
|
||||||
|
<select id="selectUrlsListByGameIdAndType" resultType="string">
|
||||||
|
select m3u8_url from urls where game_id = #{gameId} and type = #{type}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateStatusWithGameId">
|
||||||
|
update urls set status = #{status} where game_id = #{gameId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateUrlsById">
|
||||||
|
update urls set m3u8_url = #{url} where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user