tvbox支持根据用户细分
This commit is contained in:
@@ -1346,6 +1346,51 @@ export class D1Storage implements IStorage {
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== TVBox订阅token ====================
|
||||
|
||||
async getTvboxSubscribeToken?(userName: string): Promise<string | null> {
|
||||
try {
|
||||
const result = await this.db
|
||||
.prepare('SELECT tvbox_subscribe_token FROM users WHERE username = ?')
|
||||
.bind(userName)
|
||||
.first();
|
||||
|
||||
return result?.tvbox_subscribe_token || null;
|
||||
} catch (err) {
|
||||
console.error('D1Storage.getTvboxSubscribeToken error:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async setTvboxSubscribeToken?(userName: string, token: string): Promise<void> {
|
||||
try {
|
||||
await this.db
|
||||
.prepare('UPDATE users SET tvbox_subscribe_token = ? WHERE username = ?')
|
||||
.bind(token, userName)
|
||||
.run();
|
||||
|
||||
// 清除缓存
|
||||
userInfoCache?.delete(userName);
|
||||
} catch (err) {
|
||||
console.error('D1Storage.setTvboxSubscribeToken error:', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async getUsernameByTvboxToken?(token: string): Promise<string | null> {
|
||||
try {
|
||||
const result = await this.db
|
||||
.prepare('SELECT username FROM users WHERE tvbox_subscribe_token = ?')
|
||||
.bind(token)
|
||||
.first();
|
||||
|
||||
return result?.username || null;
|
||||
} catch (err) {
|
||||
console.error('D1Storage.getUsernameByTvboxToken error:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 搜索历史 ====================
|
||||
|
||||
async getSearchHistory(userName: string): Promise<string[]> {
|
||||
|
||||
@@ -482,6 +482,27 @@ export class DbManager {
|
||||
return [];
|
||||
}
|
||||
|
||||
// ---------- TVBox订阅token ----------
|
||||
async getTvboxSubscribeToken(userName: string): Promise<string | null> {
|
||||
if (typeof (this.storage as any).getTvboxSubscribeToken === 'function') {
|
||||
return (this.storage as any).getTvboxSubscribeToken(userName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async setTvboxSubscribeToken(userName: string, token: string): Promise<void> {
|
||||
if (typeof (this.storage as any).setTvboxSubscribeToken === 'function') {
|
||||
await (this.storage as any).setTvboxSubscribeToken(userName, token);
|
||||
}
|
||||
}
|
||||
|
||||
async getUsernameByTvboxToken(token: string): Promise<string | null> {
|
||||
if (typeof (this.storage as any).getUsernameByTvboxToken === 'function') {
|
||||
return (this.storage as any).getUsernameByTvboxToken(token);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ---------- 播放记录迁移 ----------
|
||||
async migratePlayRecords(userName: string): Promise<void> {
|
||||
if (typeof (this.storage as any).migratePlayRecords === 'function') {
|
||||
|
||||
@@ -911,6 +911,52 @@ export class PostgresStorage implements IStorage {
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== TVBox订阅token ====================
|
||||
|
||||
async getTvboxSubscribeToken(userName: string): Promise<string | null> {
|
||||
try {
|
||||
const result = await this.db
|
||||
.prepare('SELECT tvbox_subscribe_token FROM users_v2 WHERE username = $1')
|
||||
.bind(userName)
|
||||
.first();
|
||||
|
||||
return result?.tvbox_subscribe_token || null;
|
||||
} catch (err) {
|
||||
console.error('PostgresStorage.getTvboxSubscribeToken error:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async setTvboxSubscribeToken(userName: string, token: string): Promise<void> {
|
||||
try {
|
||||
await this.db
|
||||
.prepare('UPDATE users_v2 SET tvbox_subscribe_token = $1 WHERE username = $2')
|
||||
.bind(token, userName)
|
||||
.run();
|
||||
|
||||
// 清除用户信息缓存
|
||||
const { userInfoCache } = await import('./user-cache');
|
||||
userInfoCache.delete(userName);
|
||||
} catch (err) {
|
||||
console.error('PostgresStorage.setTvboxSubscribeToken error:', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async getUsernameByTvboxToken(token: string): Promise<string | null> {
|
||||
try {
|
||||
const result = await this.db
|
||||
.prepare('SELECT username FROM users_v2 WHERE tvbox_subscribe_token = $1')
|
||||
.bind(token)
|
||||
.first();
|
||||
|
||||
return result?.username || null;
|
||||
} catch (err) {
|
||||
console.error('PostgresStorage.getUsernameByTvboxToken error:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 音乐播放记录 ====================
|
||||
|
||||
async getMusicPlayRecord(userName: string, key: string): Promise<any | null> {
|
||||
|
||||
@@ -1723,4 +1723,35 @@ export abstract class BaseRedisStorage implements IStorage {
|
||||
// 清除缓存
|
||||
userInfoCache?.delete(userName);
|
||||
}
|
||||
|
||||
// ---------- TVBox订阅token相关 ----------
|
||||
async getTvboxSubscribeToken(userName: string): Promise<string | null> {
|
||||
// 直接从数据库读取,不使用缓存
|
||||
const token = await this.withRetry(() =>
|
||||
this.adapter.hGet(this.userInfoKey(userName), 'tvboxSubscribeToken')
|
||||
);
|
||||
return token || null;
|
||||
}
|
||||
|
||||
async setTvboxSubscribeToken(userName: string, token: string): Promise<void> {
|
||||
// 保存token到用户信息
|
||||
await this.withRetry(() =>
|
||||
this.adapter.hSet(this.userInfoKey(userName), 'tvboxSubscribeToken', token)
|
||||
);
|
||||
|
||||
// 创建token到用户名的反向索引
|
||||
await this.withRetry(() =>
|
||||
this.adapter.set(`tvbox:token:${token}`, userName)
|
||||
);
|
||||
|
||||
// 清除缓存
|
||||
userInfoCache?.delete(userName);
|
||||
}
|
||||
|
||||
async getUsernameByTvboxToken(token: string): Promise<string | null> {
|
||||
const userName = await this.withRetry(() =>
|
||||
this.adapter.get(`tvbox:token:${token}`)
|
||||
);
|
||||
return userName || null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
/**
|
||||
* 生成TVBox订阅token
|
||||
* 使用crypto生成32位随机hex字符串
|
||||
*/
|
||||
export function generateTvboxToken(): string {
|
||||
return randomBytes(16).toString('hex');
|
||||
}
|
||||
@@ -161,6 +161,11 @@ export interface IStorage {
|
||||
setUserEmail?(userName: string, email: string): Promise<void>;
|
||||
getEmailNotificationPreference?(userName: string): Promise<boolean>;
|
||||
setEmailNotificationPreference?(userName: string, enabled: boolean): Promise<void>;
|
||||
|
||||
// TVBox订阅token相关
|
||||
getTvboxSubscribeToken?(userName: string): Promise<string | null>;
|
||||
setTvboxSubscribeToken?(userName: string, token: string): Promise<void>;
|
||||
getUsernameByTvboxToken?(token: string): Promise<string | null>;
|
||||
}
|
||||
|
||||
// 搜索结果数据结构
|
||||
|
||||
Reference in New Issue
Block a user