tv完善弹幕以及各种焦点
This commit is contained in:
+18
-13
@@ -18,6 +18,13 @@ export function createEmptyFeatureAccessMap(): FeatureAccessMap {
|
||||
}, {} as FeatureAccessMap);
|
||||
}
|
||||
|
||||
function createFullFeatureAccessMap(): FeatureAccessMap {
|
||||
return ALL_FEATURE_PERMISSION_KEYS.reduce((acc, key) => {
|
||||
acc[key] = true;
|
||||
return acc;
|
||||
}, {} as FeatureAccessMap);
|
||||
}
|
||||
|
||||
function isPrivilegedRole(role?: string) {
|
||||
return role === 'owner' || role === 'admin';
|
||||
}
|
||||
@@ -25,10 +32,7 @@ function isPrivilegedRole(role?: string) {
|
||||
async function getUserFeatureAccessMap(username: string): Promise<FeatureAccessMap> {
|
||||
const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage';
|
||||
if (storageType === 'localstorage') {
|
||||
return ALL_FEATURE_PERMISSION_KEYS.reduce((acc, key) => {
|
||||
acc[key] = true;
|
||||
return acc;
|
||||
}, {} as FeatureAccessMap);
|
||||
return createFullFeatureAccessMap();
|
||||
}
|
||||
|
||||
const userInfo = await db.getUserInfoV2(username);
|
||||
@@ -37,10 +41,7 @@ async function getUserFeatureAccessMap(username: string): Promise<FeatureAccessM
|
||||
}
|
||||
|
||||
if (username === process.env.USERNAME || isPrivilegedRole(userInfo.role)) {
|
||||
return ALL_FEATURE_PERMISSION_KEYS.reduce((acc, key) => {
|
||||
acc[key] = true;
|
||||
return acc;
|
||||
}, {} as FeatureAccessMap);
|
||||
return createFullFeatureAccessMap();
|
||||
}
|
||||
|
||||
const config = await getConfig();
|
||||
@@ -48,10 +49,7 @@ async function getUserFeatureAccessMap(username: string): Promise<FeatureAccessM
|
||||
|
||||
// 兼容旧用户:未分配用户组时,默认拥有全部功能权限
|
||||
if (tags.length === 0) {
|
||||
return ALL_FEATURE_PERMISSION_KEYS.reduce((acc, key) => {
|
||||
acc[key] = true;
|
||||
return acc;
|
||||
}, {} as FeatureAccessMap);
|
||||
return createFullFeatureAccessMap();
|
||||
}
|
||||
|
||||
const allowedPermissions = new Set<FeaturePermissionKey>();
|
||||
@@ -71,7 +69,14 @@ async function getUserFeatureAccessMap(username: string): Promise<FeatureAccessM
|
||||
|
||||
export async function getUserFeatureAccess(username?: string | null): Promise<FeatureAccessMap> {
|
||||
if (!username) return createEmptyFeatureAccessMap();
|
||||
return getUserFeatureAccessMap(username);
|
||||
try {
|
||||
return await getUserFeatureAccessMap(username);
|
||||
} catch (error) {
|
||||
console.error('[Permissions] Failed to load feature access:', error);
|
||||
return username === process.env.USERNAME
|
||||
? createFullFeatureAccessMap()
|
||||
: createEmptyFeatureAccessMap();
|
||||
}
|
||||
}
|
||||
|
||||
export async function hasFeaturePermission(
|
||||
|
||||
+25
-3
@@ -5,10 +5,27 @@ import { Redis } from '@upstash/redis';
|
||||
import { UpstashRedisAdapter } from './redis-adapter';
|
||||
import { BaseRedisStorage } from './redis-base.db';
|
||||
|
||||
const DEFAULT_UPSTASH_TIMEOUT_MS =
|
||||
process.env.NODE_ENV === 'development' ? 2500 : 8000;
|
||||
const UPSTASH_TIMEOUT_MS = Math.max(
|
||||
1000,
|
||||
Number(process.env.UPSTASH_TIMEOUT_MS || DEFAULT_UPSTASH_TIMEOUT_MS)
|
||||
);
|
||||
const DEFAULT_UPSTASH_RETRIES =
|
||||
process.env.NODE_ENV === 'development' ? 1 : 3;
|
||||
const UPSTASH_MAX_RETRIES = Math.max(
|
||||
1,
|
||||
Number(process.env.UPSTASH_MAX_RETRIES || DEFAULT_UPSTASH_RETRIES)
|
||||
);
|
||||
|
||||
function createUpstashAbortSignal() {
|
||||
return AbortSignal.timeout(UPSTASH_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
// 添加Upstash Redis操作重试包装器
|
||||
async function withRetry<T>(
|
||||
operation: () => Promise<T>,
|
||||
maxRetries = 3
|
||||
maxRetries = UPSTASH_MAX_RETRIES
|
||||
): Promise<T> {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
@@ -19,6 +36,10 @@ async function withRetry<T>(
|
||||
err.message?.includes('Connection') ||
|
||||
err.message?.includes('ECONNREFUSED') ||
|
||||
err.message?.includes('ENOTFOUND') ||
|
||||
err.name === 'AbortError' ||
|
||||
err.name === 'TimeoutError' ||
|
||||
err.message?.includes('Aborted') ||
|
||||
err.message?.includes('Timeout') ||
|
||||
err.code === 'ECONNRESET' ||
|
||||
err.code === 'EPIPE' ||
|
||||
err.name === 'UpstashError';
|
||||
@@ -68,11 +89,12 @@ function getUpstashRedisClient(): Redis {
|
||||
client = new Redis({
|
||||
url: upstashUrl,
|
||||
token: upstashToken,
|
||||
signal: createUpstashAbortSignal,
|
||||
// 可选配置
|
||||
retry: {
|
||||
retries: 3,
|
||||
retries: UPSTASH_MAX_RETRIES,
|
||||
backoff: (retryCount: number) =>
|
||||
Math.min(1000 * Math.pow(2, retryCount), 30000),
|
||||
Math.min(500 * Math.pow(2, retryCount), 5000),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user