fix(studio): hide sidebar group until token resolves; remove VITE_STUDIO_ENABLED
- workspace-nav-studio: return null while isLoading so the "工作室" group no longer briefly mounts and then unmounts when getTokenByEmail returns "用户不存在" (404). Skeleton branch became dead code, removed. - studio/hooks: switch all three token queries from retry: 1 to false — account-not-found is a permanent error; retry just doubled isError latency. - env: drop VITE_STUDIO_ENABLED everywhere (env.ts + 7 env files + workspace-nav-chat-list). Sidebar availability is now decided at runtime by token success instead of a build-time flag. - env: add VITE_AIPI_PRESENT_URL + VITE_AIPI_KNOWES_URL for the document upload popup's A-system jump + B-system knowledge iframe; reuse the existing VITE_AIPI_KNOWLEDGE_URL for the Y-system iframe. - document-upload-popup: replace 8 hardcoded URLs (6 present, 1 knowes, 1 knowlibrary) with the corresponding env vars. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
bd0eceda61
commit
4416348c51
13 files changed
+287
-80
No files matched your search
@@ -50,7 +50,7 @@ function getYUserId(): string {
|
||||
const obj = JSON.parse(raw) as { yUserId?: string };
|
||||
if (obj?.yUserId) return obj.yUserId;
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
return "1157761008018653184";
|
||||
}
|
||||
|
||||
@@ -72,6 +72,23 @@ interface DocumentUploadDialogContextType {
|
||||
mode?: "search",
|
||||
data?: { query: string; mode: string }
|
||||
) => Promise<void>;
|
||||
// 上传成功回调,返回上传的来源信息
|
||||
onUploadComplete?: (sources: Array<{ id?: number; title: string; task_id?: string; status: string }>) => void;
|
||||
}
|
||||
|
||||
// ── 任务轮询类型 ─────────────────────────────────────────────
|
||||
interface TaskSource {
|
||||
task_id: string;
|
||||
title: string;
|
||||
status: 'processing' | 'success' | 'error';
|
||||
source_type: string;
|
||||
}
|
||||
|
||||
interface UploadResponse {
|
||||
status: string;
|
||||
uploaded: number;
|
||||
skipped: number;
|
||||
sources: TaskSource[];
|
||||
}
|
||||
|
||||
interface listDataItem {
|
||||
@@ -83,6 +100,10 @@ interface listDataItem {
|
||||
title: string;
|
||||
content: string;
|
||||
url: string;
|
||||
// 上传文件轮询相关字段
|
||||
task_id?: string;
|
||||
processing_status?: 'processing' | 'success' | 'error';
|
||||
is_uploaded_file?: boolean;
|
||||
country?: string;
|
||||
dateOfBirth?: string;
|
||||
occupationData?: string;
|
||||
@@ -188,9 +209,10 @@ export const DocumentUploadDialogProvider: FC<{
|
||||
mode?: "search",
|
||||
data?: { query: string; mode: string }
|
||||
) => void | Promise<void>;
|
||||
searchSpace: { id: number | string; [key: string]: unknown };
|
||||
searchSpace: { id: number | string;[key: string]: unknown };
|
||||
onUploadSuccess?: () => void;
|
||||
}> = ({ children, onClose, searchSpace, onUploadSuccess }) => {
|
||||
onUploadComplete?: (sources: Array<{ id?: number; title: string; task_id?: string; status: string }>) => void;
|
||||
}> = ({ children, onClose, searchSpace, onUploadSuccess, onUploadComplete }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [initialSearchText, setInitialSearchText] = useState("");
|
||||
const isClosingRef = useRef(false);
|
||||
@@ -236,7 +258,7 @@ export const DocumentUploadDialogProvider: FC<{
|
||||
);
|
||||
|
||||
return (
|
||||
<DocumentUploadDialogContext.Provider value={{ openDialog, closeDialog }}>
|
||||
<DocumentUploadDialogContext.Provider value={{ openDialog, closeDialog, onUploadComplete }}>
|
||||
{children}
|
||||
<DocumentUploadPopupContent
|
||||
isOpen={isOpen}
|
||||
@@ -257,7 +279,7 @@ const UPLOAD_ACCEPT =
|
||||
const DocumentUploadPopupContent: FC<{
|
||||
isOpen: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
searchSpace: { id: number | string; [key: string]: unknown };
|
||||
searchSpace: { id: number | string;[key: string]: unknown };
|
||||
onUploadSuccess?: () => void;
|
||||
closeDialog: (
|
||||
mode?: "search",
|
||||
@@ -265,12 +287,15 @@ const DocumentUploadPopupContent: FC<{
|
||||
) => Promise<void>;
|
||||
initialSearchText?: string;
|
||||
}> = ({ isOpen, onOpenChange, searchSpace, onUploadSuccess, initialSearchText }) => {
|
||||
const { onUploadComplete } = useContext(DocumentUploadDialogContext) || {};
|
||||
const searchSpaceId = String(searchSpace?.id);
|
||||
const backendUrl =
|
||||
typeof window !== "undefined"
|
||||
? (import.meta.env.VITE_BACKEND_BASE_URL || "http://localhost:8001")
|
||||
: "http://localhost:8001";
|
||||
const consumerUrl = "http://ch1.b.uat.4.cn/consumer";
|
||||
|
||||
// 从环境变量获取配置
|
||||
const backendUrl = import.meta.env.VITE_AIPI_BACKENP_URL || "http://localhost:8001";
|
||||
const consumerUrl = import.meta.env.VITE_AIPI_CONSUMER_URL || "http://ch1.b.uat.4.cn/consumer";
|
||||
const presentUrl = import.meta.env.VITE_AIPI_PRESENT_URL || "http://present.a.uat.4.cn/present/domain";
|
||||
const knowesUrl = import.meta.env.VITE_AIPI_KNOWES_URL || "http://ch1.b.uat.4.cn/knowes";
|
||||
const knowledgeUrl = import.meta.env.VITE_AIPI_KNOWLEDGE_URL || "http://chlib.b.uat.4.cn/knowlibrary";
|
||||
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
@@ -321,8 +346,19 @@ const DocumentUploadPopupContent: FC<{
|
||||
body: formData,
|
||||
});
|
||||
if (res.ok) {
|
||||
toast.success("上传成功");
|
||||
handleSuccess();
|
||||
const data = await res.json() as UploadResponse;
|
||||
// 调用上传完成回调,传递来源信息
|
||||
if (data.sources && data.sources.length > 0) {
|
||||
onUploadComplete?.(data.sources.map(s => ({
|
||||
id: undefined, // 后端返回的数据中暂时没有 id
|
||||
title: s.title,
|
||||
task_id: s.task_id,
|
||||
status: s.status,
|
||||
})));
|
||||
}
|
||||
toast.success(`上传成功 ${data.uploaded || files.length} 个文件`);
|
||||
// 只关闭上传弹窗
|
||||
onOpenChange(false);
|
||||
} else {
|
||||
toast.error("上传失败,请重试");
|
||||
}
|
||||
@@ -414,7 +450,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
item.title = item.name || "";
|
||||
item.content = item.abstractz || "";
|
||||
const redirect = urlSafeBtoa(`/gene/#/human/basic?mid=${item.id}`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
setListData(result);
|
||||
}
|
||||
@@ -437,7 +473,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
item.title = item.name || "";
|
||||
item.content = item.abstractz || "";
|
||||
const redirect = urlSafeBtoa(`/gene/#/organization/basicAttr?mid=${item.mongoId}`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
setListData(result);
|
||||
}
|
||||
@@ -461,7 +497,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
item.title = item.community_name || "";
|
||||
item.content = item.community_description || "";
|
||||
const redirect = urlSafeBtoa(`/gene/#/commune/basicCommune?cid=${item.id}`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
setListData(result);
|
||||
}
|
||||
@@ -483,7 +519,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
item.title = item.issue_name || "";
|
||||
item.content = item.issue_type || "";
|
||||
const redirect = encodeURIComponent(`/gene/#/issue/zzyyIssue?mid=${item.id}&event_type=issue`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
setListData(result);
|
||||
}
|
||||
@@ -504,7 +540,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
result.forEach((item) => {
|
||||
item.checked = false;
|
||||
const redirect = urlSafeBtoa(`/gene/#/event/basicEvent?event_type=hot&mid=${item.id}`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
setListData(result);
|
||||
}
|
||||
@@ -526,7 +562,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
results.forEach((item) => {
|
||||
item.checked = false;
|
||||
const redirect = urlSafeBtoa(`/gene/#/event/basicEvent?event_type=hot&mid=${item.id}`);
|
||||
item.url = `http://present.a.uat.4.cn/present/domain?inredirect=${redirect}`;
|
||||
item.url = `${presentUrl}?inredirect=${redirect}`;
|
||||
});
|
||||
result = [...result, ...results];
|
||||
}
|
||||
@@ -614,9 +650,8 @@ const DocumentUploadPopupContent: FC<{
|
||||
<button
|
||||
key={key}
|
||||
onClick={() => void searchActiveChange(key)}
|
||||
className={`relative pb-3 px-6 pt-4 text-sm font-medium transition-colors ${
|
||||
activeTab === key ? "text-gray-900" : "text-gray-400 hover:text-gray-600"
|
||||
}`}
|
||||
className={`relative pb-3 px-6 pt-4 text-sm font-medium transition-colors ${activeTab === key ? "text-gray-900" : "text-gray-400 hover:text-gray-600"
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
{activeTab === key && (
|
||||
@@ -632,7 +667,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
{activeTab === "search" && !isSearching && (
|
||||
<iframe
|
||||
className="w-full h-[calc(100vh-200px)]"
|
||||
src={`http://ch1.b.uat.4.cn/knowes/fromB1?yUserId=${yUserId}&processType=searchMode&bookChatId=${searchSpaceId}&inputValue=${searchValue}`}
|
||||
src={`${knowesUrl}/fromB1?yUserId=${yUserId}&processType=searchMode&bookChatId=${searchSpaceId}&inputValue=${searchValue}`}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -640,7 +675,7 @@ const DocumentUploadPopupContent: FC<{
|
||||
{activeTab === "Y" && !isSearching && (
|
||||
<iframe
|
||||
className="w-full h-[calc(100vh-200px)]"
|
||||
src={`http://chlib.b.uat.4.cn/knowlibrary/#/sousou?chatType=new-chat&bookChatId=${searchSpaceId}&inputValue=${searchText}`}
|
||||
src={`${knowledgeUrl}/#/sousou?chatType=new-chat&bookChatId=${searchSpaceId}&inputValue=${searchText}`}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -686,6 +721,23 @@ const DocumentUploadPopupContent: FC<{
|
||||
<div className="bg-white p-[10px] grid grid-cols-5 gap-[10px]">
|
||||
{listData.map((item, index) => (
|
||||
<div key={index} className="relative flex items-center shadow-[0px_0px_2px_1px_#ededed] mb-[10px] p-[10px] rounded-[5px]">
|
||||
{/* 上传文件显示 loading 状态 */}
|
||||
{item.is_uploaded_file && item.processing_status === 'processing' && (
|
||||
<div className="absolute inset-0 bg-white/80 flex items-center justify-center z-10">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-primary" />
|
||||
</div>
|
||||
)}
|
||||
{/* 上传文件完成状态标记 */}
|
||||
{item.is_uploaded_file && item.processing_status === 'error' && (
|
||||
<div className="absolute top-1 left-1">
|
||||
<span className="text-xs text-red-500">处理失败</span>
|
||||
</div>
|
||||
)}
|
||||
{item.is_uploaded_file && item.processing_status === 'success' && (
|
||||
<div className="absolute top-1 left-1">
|
||||
<span className="text-xs text-green-500">✓ 已完成</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="w-[50px] mr-[10px]">
|
||||
<img src={item.imagePath || ""} className="w-[50px] h-[50px]" alt="" />
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user