Files
mindfulness/client/src/services/recoApi.ts
2026-02-03 02:36:42 +08:00

75 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import i18n from 'i18next';
import { API_BASE_URL } from '@/src/constants/env';
import type { UserProfileV1_2 } from '@/src/features/userProfileScoring';
export type RecommendedItem = {
content_id: number;
text: string;
final_score: number;
fallback_level_final: number;
explanations?: Record<string, unknown> | null;
};
export type RecoMeta = Record<string, unknown>;
export type RecoEngineResult = {
items: RecommendedItem[];
meta: RecoMeta;
};
export type RecoRequest = {
k?: number;
user_profile: UserProfileV1_2;
already_recommended_ids?: Array<string | number>;
touched_or_viewed_ids?: Array<string | number>;
now?: string; // ISO8601可选
};
function withTimeout(ms: number): AbortController {
const controller = new AbortController();
setTimeout(() => controller.abort(), ms);
return controller;
}
export async function fetchRecoFeed(req: RecoRequest): Promise<RecoEngineResult> {
const controller = withTimeout(12_000);
const url = `${API_BASE_URL}/v1/reco/feed`;
const acceptLanguage = i18n.language?.toLowerCase().startsWith('zh') ? 'tc' : 'en';
const headers: Record<string, string> = {
'Content-Type': 'application/json',
// 让后端做 locale 选择(目前后端只区分 en/tc
'Accept-Language': acceptLanguage,
};
const bodyObj = {
k: req.k,
user_profile: req.user_profile,
already_recommended_ids: req.already_recommended_ids ?? [],
touched_or_viewed_ids: req.touched_or_viewed_ids ?? [],
now: req.now,
};
// 仅在开发环境打印,避免生产环境日志泄露敏感信息
if (__DEV__) {
console.log('[Feed API] 请求地址:', url);
console.log('[Feed API] Feed的API请求头:', headers);
console.log('[Feed API] Feed的API请求体:', bodyObj);
}
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(bodyObj),
signal: controller.signal,
});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`推荐接口请求失败:${res.status} ${res.statusText} ${text}`.trim());
}
return (await res.json()) as RecoEngineResult;
}