diff --git a/VERSION.txt b/VERSION.txt index 772c3e7..43c5cbf 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -20250728105125 \ No newline at end of file +20250728125318 \ No newline at end of file diff --git a/src/lib/redis.db.ts b/src/lib/redis.db.ts index e288bc1..1b9d024 100644 --- a/src/lib/redis.db.ts +++ b/src/lib/redis.db.ts @@ -8,6 +8,15 @@ import { Favorite, IStorage, PlayRecord } from './types'; // 搜索历史最大条数 const SEARCH_HISTORY_LIMIT = 20; +// 数据类型转换辅助函数 +function ensureString(value: any): string { + return String(value); +} + +function ensureStringArray(value: any[]): string[] { + return value.map((item) => String(item)); +} + // 添加Redis操作重试包装器 async function withRetry( operation: () => Promise, @@ -99,7 +108,7 @@ export class RedisStorage implements IStorage { if (raw) { const rec = JSON.parse(raw) as PlayRecord; // 截取 source+id 部分 - const keyPart = fullKey.replace(`u:${userName}:pr:`, ''); + const keyPart = ensureString(fullKey.replace(`u:${userName}:pr:`, '')); result[keyPart] = rec; } }); @@ -142,7 +151,7 @@ export class RedisStorage implements IStorage { const raw = values[idx]; if (raw) { const fav = JSON.parse(raw) as Favorite; - const keyPart = fullKey.replace(`u:${userName}:fav:`, ''); + const keyPart = ensureString(fullKey.replace(`u:${userName}:fav:`, '')); result[keyPart] = fav; } }); @@ -168,7 +177,8 @@ export class RedisStorage implements IStorage { this.client.get(this.userPwdKey(userName)) ); if (stored === null) return false; - return stored === password; + // 确保比较时都是字符串类型 + return ensureString(stored) === password; } // 检查用户是否存在 @@ -221,17 +231,19 @@ export class RedisStorage implements IStorage { } async getSearchHistory(userName: string): Promise { - return withRetry( - () => this.client.lRange(this.shKey(userName), 0, -1) as Promise + const result = await withRetry(() => + this.client.lRange(this.shKey(userName), 0, -1) ); + // 确保返回的都是字符串类型 + return ensureStringArray(result as any[]); } async addSearchHistory(userName: string, keyword: string): Promise { const key = this.shKey(userName); // 先去重 - await withRetry(() => this.client.lRem(key, 0, keyword)); + await withRetry(() => this.client.lRem(key, 0, ensureString(keyword))); // 插入到最前 - await withRetry(() => this.client.lPush(key, keyword)); + await withRetry(() => this.client.lPush(key, ensureString(keyword))); // 限制最大长度 await withRetry(() => this.client.lTrim(key, 0, SEARCH_HISTORY_LIMIT - 1)); } @@ -239,7 +251,7 @@ export class RedisStorage implements IStorage { async deleteSearchHistory(userName: string, keyword?: string): Promise { const key = this.shKey(userName); if (keyword) { - await withRetry(() => this.client.lRem(key, 0, keyword)); + await withRetry(() => this.client.lRem(key, 0, ensureString(keyword))); } else { await withRetry(() => this.client.del(key)); } @@ -251,7 +263,7 @@ export class RedisStorage implements IStorage { return keys .map((k) => { const match = k.match(/^u:(.+?):pwd$/); - return match ? match[1] : undefined; + return match ? ensureString(match[1]) : undefined; }) .filter((u): u is string => typeof u === 'string'); } diff --git a/src/lib/upstash.db.ts b/src/lib/upstash.db.ts index f0c0361..3832bd3 100644 --- a/src/lib/upstash.db.ts +++ b/src/lib/upstash.db.ts @@ -8,6 +8,15 @@ import { Favorite, IStorage, PlayRecord } from './types'; // 搜索历史最大条数 const SEARCH_HISTORY_LIMIT = 20; +// 数据类型转换辅助函数 +function ensureString(value: any): string { + return String(value); +} + +function ensureStringArray(value: any[]): string[] { + return value.map((item) => String(item)); +} + // 添加Upstash Redis操作重试包装器 async function withRetry( operation: () => Promise, @@ -86,7 +95,7 @@ export class UpstashRedisStorage implements IStorage { const value = await withRetry(() => this.client.get(fullKey)); if (value) { // 截取 source+id 部分 - const keyPart = fullKey.replace(`u:${userName}:pr:`, ''); + const keyPart = ensureString(fullKey.replace(`u:${userName}:pr:`, '')); result[keyPart] = value as PlayRecord; } } @@ -128,7 +137,7 @@ export class UpstashRedisStorage implements IStorage { for (const fullKey of keys) { const value = await withRetry(() => this.client.get(fullKey)); if (value) { - const keyPart = fullKey.replace(`u:${userName}:fav:`, ''); + const keyPart = ensureString(fullKey.replace(`u:${userName}:fav:`, '')); result[keyPart] = value as Favorite; } } @@ -154,7 +163,8 @@ export class UpstashRedisStorage implements IStorage { this.client.get(this.userPwdKey(userName)) ); if (stored === null) return false; - return stored === password; + // 确保比较时都是字符串类型 + return ensureString(stored) === password; } // 检查用户是否存在 @@ -210,15 +220,16 @@ export class UpstashRedisStorage implements IStorage { const result = await withRetry(() => this.client.lrange(this.shKey(userName), 0, -1) ); - return result as string[]; + // 确保返回的都是字符串类型 + return ensureStringArray(result as any[]); } async addSearchHistory(userName: string, keyword: string): Promise { const key = this.shKey(userName); // 先去重 - await withRetry(() => this.client.lrem(key, 0, keyword)); + await withRetry(() => this.client.lrem(key, 0, ensureString(keyword))); // 插入到最前 - await withRetry(() => this.client.lpush(key, keyword)); + await withRetry(() => this.client.lpush(key, ensureString(keyword))); // 限制最大长度 await withRetry(() => this.client.ltrim(key, 0, SEARCH_HISTORY_LIMIT - 1)); } @@ -226,7 +237,7 @@ export class UpstashRedisStorage implements IStorage { async deleteSearchHistory(userName: string, keyword?: string): Promise { const key = this.shKey(userName); if (keyword) { - await withRetry(() => this.client.lrem(key, 0, keyword)); + await withRetry(() => this.client.lrem(key, 0, ensureString(keyword))); } else { await withRetry(() => this.client.del(key)); } @@ -238,7 +249,7 @@ export class UpstashRedisStorage implements IStorage { return keys .map((k) => { const match = k.match(/^u:(.+?):pwd$/); - return match ? match[1] : undefined; + return match ? ensureString(match[1]) : undefined; }) .filter((u): u is string => typeof u === 'string'); } @@ -269,7 +280,7 @@ function getUpstashRedisClient(): Redis { if (!upstashUrl || !upstashToken) { throw new Error( - 'UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN env variables must be set' + 'UPSTASH_URL and UPSTASH_TOKEN env variables must be set' ); } diff --git a/src/lib/version.ts b/src/lib/version.ts index 2606cd3..ac60bbf 100644 --- a/src/lib/version.ts +++ b/src/lib/version.ts @@ -2,7 +2,7 @@ 'use client'; -const CURRENT_VERSION = '20250728105125'; +const CURRENT_VERSION = '20250728125318'; // 版本检查结果枚举 export enum UpdateStatus {