This commit is contained in:
fengxiangdebaozi committed 2026-06-24 19:48:15 +08:00
commit 3ea8e73389
61 files changed
+734 -429

No files matched your search

@@ -405,8 +405,15 @@ const DocumentUploadPopupContent: FC<{
if (response.ok) {
const data = await response.json() as { imported_count?: number };
toast.success(`成功导入 ${data.imported_count || dataList.length} 个来源`);
setListData([]);
handleBatchDelete();
onUploadComplete?.(
selectedSearchSources.map((s) => ({
id: undefined,
title: s.title,
task_id: undefined,
status: "success" as const,
}))
);
onOpenChange(false);
} else {
const errorData = await response.json() as { detail?: string };
toast.error(errorData.detail || "导入失败,请重试");
@@ -45,7 +45,7 @@ export function AccountSettingsPage() {
// 操作日志(Y-Log):在清除 token1 之前上报登出(此时 token1 还在),keepalive 保证发出。
writeYLog({
optType: OptType.logout,
optDetail: "B1-CM助手-登出",
optDetail: "CM助手-全量-登出",
url: "/api/v1/auth/logout",
keepalive: true,
});
+16 -16
View File
@@ -177,7 +177,7 @@ export async function listUserThreads(userId: string): Promise<AdminThread[]> {
const result = await parse<AdminThread[]>(await apiFetch(url), "Failed to load threads");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-管理后台-查询用户会话列表",
optDetail: "CM助手-全量-管理后台-查询用户会话列表",
url,
reqParam: { userId },
returnParam: { count: result.length },
@@ -193,7 +193,7 @@ export async function listUserThreadMessages(
const result = await parse<AdminMessage[]>(await apiFetch(url), "Failed to load messages");
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-管理后台-查看会话消息",
optDetail: "CM助手-全量-管理后台-查看会话消息",
url,
reqParam: { userId, threadId },
returnParam: { count: result.length },
@@ -215,7 +215,7 @@ export async function listUserQa(
const result = await parse<AdminUserQaPageResponse>(await apiFetch(url), "Failed to load user Q&A");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-管理后台-查询用户问答",
optDetail: "CM助手-全量-管理后台-查询用户问答",
url,
reqParam: { userId, ...params },
returnParam: { total: result.total, count: result.items.length },
@@ -230,7 +230,7 @@ export async function getUserMemory(
const result = await parse<AdminMemoryResponse>(await apiFetch(url), "Failed to load memory");
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-管理后台-查看用户记忆",
optDetail: "CM助手-全量-管理后台-查看用户记忆",
url,
reqParam: { userId },
});
@@ -255,7 +255,7 @@ export async function getUserLeaderboard(
const result = await parse<AdminLeaderboardResponse>(await apiFetch(url), "Failed to load leaderboard");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-管理后台-查询用户排行榜",
optDetail: "CM助手-全量-管理后台-查询用户排行榜",
url,
reqParam: { ...range, limit },
});
@@ -287,7 +287,7 @@ export async function refreshTodayLeaderboard(
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-管理后台-刷新今日排行榜",
optDetail: "CM助手-全量-管理后台-刷新今日排行榜",
url,
reqParam: { ...range, limit },
});
@@ -309,7 +309,7 @@ export async function getUserAnalytics(
const result = await parse<AdminUserAnalyticsResponse>(await apiFetch(url), "Failed to load user analytics");
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-管理后台-查看用户分析",
optDetail: "CM助手-全量-管理后台-查看用户分析",
url,
reqParam: { userId, ...range, limit },
});
@@ -335,7 +335,7 @@ export async function generateUserLeaderboardReport(
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-管理后台-生成排行榜报告",
optDetail: "CM助手-全量-管理后台-生成排行榜报告",
url,
reqParam: { ...range, limit, modelName },
returnParam: { generated_at: result.generated_at, model_name: result.model_name },
@@ -414,7 +414,7 @@ export async function streamUserLeaderboardReport({
}
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-管理后台-流式生成排行榜报告",
optDetail: "CM助手-全量-管理后台-流式生成排行榜报告",
url,
reqParam: { ...range, limit, modelName },
});
@@ -436,7 +436,7 @@ export async function addAdminMemoryEntry(
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-管理后台-新增记忆条目",
optDetail: "CM助手-全量-管理后台-新增记忆条目",
url,
reqParam: { userId, content, agent },
});
@@ -460,7 +460,7 @@ export async function replaceAdminMemoryEntry(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-管理后台-编辑记忆条目",
optDetail: "CM助手-全量-管理后台-编辑记忆条目",
url,
reqParam: { userId, old_text: oldText, content, agent },
});
@@ -481,7 +481,7 @@ export async function deleteAdminMemoryEntry(
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-管理后台-删除记忆条目",
optDetail: "CM助手-全量-管理后台-删除记忆条目",
url,
reqParam: { userId, old_text: oldText, agent },
});
@@ -508,7 +508,7 @@ export async function updateAdminV1Section(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-管理后台-编辑记忆段落",
optDetail: "CM助手-全量-管理后台-编辑记忆段落",
url,
reqParam: { userId, section_type: sectionType, field, summary, agent },
});
@@ -533,7 +533,7 @@ export async function addAdminV1Fact(
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-管理后台-新增记忆事实",
optDetail: "CM助手-全量-管理后台-新增记忆事实",
url,
reqParam: { userId, content, category, confidence, agent },
});
@@ -557,7 +557,7 @@ export async function updateAdminV1Fact(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-管理后台-编辑记忆事实",
optDetail: "CM助手-全量-管理后台-编辑记忆事实",
url,
reqParam: { userId, factId, ...updates, agent },
});
@@ -579,7 +579,7 @@ export async function deleteAdminV1Fact(
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-管理后台-删除记忆事实",
optDetail: "CM助手-全量-管理后台-删除记忆事实",
url,
reqParam: { userId, factId, agent },
});
+19 -19
View File
@@ -61,7 +61,7 @@ export async function listAgents(params: ListAgentsParams = {}): Promise<Agent[]
const data = (await res.json()) as { agents: Agent[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-智能体列表",
optDetail: "CM助手-全量-智能体列表",
url: `/api/agents${query ? `?${query}` : ""}`,
reqParam: params,
returnParam: data.agents,
@@ -92,7 +92,7 @@ export async function listAgentsPaginated(
};
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-智能体列表",
optDetail: "CM助手-全量-智能体列表",
url: `/api/agents${query ? `?${query}` : ""}`,
reqParam: params,
returnParam: result,
@@ -109,7 +109,7 @@ export async function listAllAgentsAdmin(): Promise<Agent[]> {
const data = (await res.json()) as { agents: Agent[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-智能体列表",
optDetail: "CM助手-全量-智能体列表",
url: `/api/agents?admin=true`,
returnParam: data.agents,
});
@@ -122,7 +122,7 @@ export async function getAgent(id: string): Promise<Agent> {
const agent = (await res.json()) as Agent;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-智能体-查看",
optDetail: "CM助手-全量-智能体-查看",
url: `/api/agents/${id}`,
reqParam: { id },
returnParam: agent,
@@ -143,7 +143,7 @@ export async function createAgent(request: CreateAgentRequest): Promise<Agent> {
const created = (await res.json()) as Agent;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-智能体-新建",
optDetail: "CM助手-全量-智能体-新建",
url: `/api/agents`,
reqParam: request,
returnParam: created,
@@ -167,7 +167,7 @@ export async function updateAgent(
const updated = (await res.json()) as Agent;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-修改",
optDetail: "CM助手-全量-智能体-修改",
url: `/api/agents/${id}`,
reqParam: { id, ...request },
returnParam: updated,
@@ -182,7 +182,7 @@ export async function deleteAgent(id: string): Promise<void> {
if (!res.ok) throw new Error(`Failed to delete agent: ${res.statusText}`);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-智能体-删除",
optDetail: "CM助手-全量-智能体-删除",
url: `/api/agents/${id}`,
reqParam: { id },
});
@@ -194,7 +194,7 @@ export async function getAgentSelector(): Promise<AgentSelectorResponse> {
const selector = (await res.json()) as AgentSelectorResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-智能体-选择器",
optDetail: "CM助手-全量-智能体-选择器",
url: `/api/agents/selector`,
returnParam: selector,
});
@@ -211,7 +211,7 @@ export async function favoriteAgent(id: string): Promise<void> {
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-收藏",
optDetail: "CM助手-全量-智能体-收藏",
url: `/api/agents/${id}/favorite`,
reqParam: { id },
});
@@ -227,7 +227,7 @@ export async function unfavoriteAgent(id: string): Promise<void> {
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-取消收藏",
optDetail: "CM助手-全量-智能体-取消收藏",
url: `/api/agents/${id}/favorite`,
reqParam: { id },
});
@@ -243,7 +243,7 @@ export async function pinAgent(id: string): Promise<void> {
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-置顶",
optDetail: "CM助手-全量-智能体-置顶",
url: `/api/agents/${id}/pin`,
reqParam: { id },
});
@@ -259,7 +259,7 @@ export async function unpinAgent(id: string): Promise<void> {
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-取消置顶",
optDetail: "CM助手-全量-智能体-取消置顶",
url: `/api/agents/${id}/pin`,
reqParam: { id },
});
@@ -282,7 +282,7 @@ export async function reorderFeaturedAgents(agentIds: string[]): Promise<void> {
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-精选排序",
optDetail: "CM助手-全量-智能体-精选排序",
url: `/api/agents/featured/order`,
reqParam: { agent_ids: agentIds },
});
@@ -306,7 +306,7 @@ export async function listPrivateAgents(password: string): Promise<Agent[]> {
const data = (await res.json()) as { agents: Agent[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-私有广场智能体列表",
optDetail: "CM助手-全量-私有广场智能体列表",
url: `/api/agents/private-square/list`,
returnParam: data.agents,
});
@@ -364,7 +364,7 @@ export async function listPrivateAgentsPaginated(
};
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-私有广场智能体列表",
optDetail: "CM助手-全量-私有广场智能体列表",
url: `/api/agents/private-square/list`,
reqParam: { ...params, password: undefined },
returnParam: result,
@@ -393,7 +393,7 @@ export async function setAgentPrivate(
const updated = (await res.json()) as Agent;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-设置私有",
optDetail: "CM助手-全量-智能体-设置私有",
url: `/api/agents/${id}/private`,
reqParam: { id, is_private: isPrivate },
returnParam: updated,
@@ -422,7 +422,7 @@ export async function setAgentFeatured(
const updated = (await res.json()) as Agent;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-设置精选",
optDetail: "CM助手-全量-智能体-设置精选",
url: `/api/agents/${id}/featured`,
reqParam: { id, order },
returnParam: updated,
@@ -455,7 +455,7 @@ export async function adminSyncAgentSkills(): Promise<AgentSkillsSyncResult> {
const result = (await res.json()) as AgentSkillsSyncResult;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-智能体-同步技能",
optDetail: "CM助手-全量-智能体-同步技能",
url: `/api/agents/admin/sync-skills`,
returnParam: result,
});
@@ -500,7 +500,7 @@ export async function publishArtifactToKnowledge(request: {
const result = (await res.json()) as KnowledgeIngestPublishResult;
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-智能体-产物发布入库",
optDetail: "CM助手-全量-智能体-产物发布入库",
url: `/api/knowledge-ingest/publish`,
reqParam: request,
returnParam: result,
@@ -82,7 +82,7 @@ export async function downloadMarkdownDocxFromBackend(options: {
await downloadMarkdownAsDocx(markdown, options.title?.trim() || "document", options.title);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-导出-Word",
optDetail: "CM助手-全量-导出-Word",
url: `${getBackendBaseURL()}/api/writing/export/docx`,
reqParam: { title: options.title?.trim() || undefined },
});
@@ -92,7 +92,7 @@ export async function downloadMarkdownDocxFromBackend(options: {
await downloadBlobResponse(response, fallbackFilename);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-导出-Word",
optDetail: "CM助手-全量-导出-Word",
url: `${getBackendBaseURL()}/api/writing/export/docx`,
reqParam: { title: options.title?.trim() || undefined },
});
@@ -101,7 +101,7 @@ export async function downloadMarkdownDocxFromBackend(options: {
await downloadMarkdownAsDocx(markdown, options.title?.trim() || "document", options.title);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-导出-Word",
optDetail: "CM助手-全量-导出-Word",
url: `${getBackendBaseURL()}/api/writing/export/docx`,
reqParam: { title: options.title?.trim() || undefined },
});
+1 -1
View File
@@ -40,7 +40,7 @@ export async function updateArtifactContent({
}
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-产物-编辑产物内容",
optDetail: "CM助手-全量-产物-编辑产物内容",
url,
reqParam: { filepath, threadId },
});
+3 -3
View File
@@ -37,7 +37,7 @@ export async function updateCuratorConfig(
const result = (await response.json()) as CuratorConfig;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-策展-更新配置",
optDetail: "CM助手-全量-策展-更新配置",
url,
reqParam: payload,
returnParam: result,
@@ -57,7 +57,7 @@ export async function runCurator(): Promise<RunCuratorResult> {
const result = (await response.json()) as RunCuratorResult;
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-策展-手动触发策展",
optDetail: "CM助手-全量-策展-手动触发策展",
url,
returnParam: result,
});
@@ -70,7 +70,7 @@ export async function getCuratorLogs(): Promise<CuratorLogs> {
const result = (await response.json()) as CuratorLogs;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-策展-查看运行日志",
optDetail: "CM助手-全量-策展-查看运行日志",
url,
});
return result;
@@ -30,7 +30,7 @@ async function listUserPrompts(): Promise<CustomPrompt[]> {
const data = (await res.json()) as { prompts: CustomPrompt[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-自定义提示词-查询",
optDetail: "CM助手-全量-自定义提示词-查询",
url: "/api/user-prompts",
returnParam: data.prompts,
});
@@ -54,7 +54,7 @@ async function createUserPrompt(input: {
const created = (await res.json()) as CustomPrompt;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-自定义提示词-新增",
optDetail: "CM助手-全量-自定义提示词-新增",
url: "/api/user-prompts",
reqParam: input,
returnParam: created,
@@ -78,7 +78,7 @@ async function updateUserPrompt(
const updated = (await res.json()) as CustomPrompt;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-自定义提示词-编辑",
optDetail: "CM助手-全量-自定义提示词-编辑",
url: `/api/user-prompts/${id}`,
reqParam: input,
returnParam: updated,
@@ -96,7 +96,7 @@ async function deleteUserPrompt(id: string): Promise<void> {
}
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-自定义提示词-删除",
optDetail: "CM助手-全量-自定义提示词-删除",
url: `/api/user-prompts/${id}`,
reqParam: { id },
});
+27 -27
View File
@@ -47,7 +47,7 @@ export async function listKnowledgeNotes(params: KnowledgeListParams = {}) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-检索",
optDetail: "CM助手-全量-知识库-检索",
url: `${baseUrl()}/notes?${qs.toString()}`,
reqParam: params,
returnParam: result,
@@ -61,7 +61,7 @@ export async function getKnowledgeNote(noteId: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-知识库-查看",
optDetail: "CM助手-全量-知识库-查看",
url: `${baseUrl()}/notes/${encodeURIComponent(noteId)}`,
reqParam: { noteId },
returnParam: result,
@@ -86,7 +86,7 @@ export async function createKnowledgeNote(data: {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-知识库-新建",
optDetail: "CM助手-全量-知识库-新建",
url: `${baseUrl()}/notes`,
reqParam: data,
returnParam: res.note,
@@ -114,7 +114,7 @@ export async function updateKnowledgeNote(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-知识库-修改",
optDetail: "CM助手-全量-知识库-修改",
url: `${baseUrl()}/notes/${encodeURIComponent(noteId)}`,
reqParam: { noteId, data },
returnParam: result,
@@ -131,7 +131,7 @@ export async function deleteKnowledgeNote(noteId: string, hard = false) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-知识库-删除",
optDetail: "CM助手-全量-知识库-删除",
url: `${baseUrl()}/notes/${encodeURIComponent(noteId)}${hard ? "?hard=true" : ""}`,
reqParam: { noteId, hard },
returnParam: result,
@@ -149,7 +149,7 @@ export async function searchKnowledge(query: string, limit = 8) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-检索",
optDetail: "CM助手-全量-知识库-检索",
url: `${baseUrl()}/search`,
reqParam: { query, mode: "keyword", limit },
returnParam: res.items,
@@ -171,7 +171,7 @@ export async function ingestThread(threadId: string, payload: IngestThreadPayloa
);
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-知识库-导入",
optDetail: "CM助手-全量-知识库-导入",
url: `${baseUrl()}/ingest/thread/${encodeURIComponent(threadId)}`,
reqParam: { threadId, payload },
returnParam: result,
@@ -189,7 +189,7 @@ export async function ingestThreadsBatch(payload: BatchIngestPayload = {}) {
);
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-知识库-导入",
optDetail: "CM助手-全量-知识库-导入",
url: `${baseUrl()}/ingest/threads/batch`,
reqParam: payload,
returnParam: result,
@@ -230,7 +230,7 @@ export async function ingestKnowledgeFile(
);
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-知识库-导入",
optDetail: "CM助手-全量-知识库-导入",
url: `${baseUrl()}/ingest/file`,
reqParam: { fileName: file.name, ...opts },
returnParam: result,
@@ -267,7 +267,7 @@ export async function fetchVaultPage(path: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-知识库-Vault页面查看",
optDetail: "CM助手-全量-知识库-Vault页面查看",
url: `${baseUrl()}/vault-page?path=${encodeURIComponent(path)}`,
reqParam: { path },
returnParam: result,
@@ -281,7 +281,7 @@ export async function exportKnowledgeGraph() {
);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-知识库-导出",
optDetail: "CM助手-全量-知识库-导出",
url: `${baseUrl()}/export/graph`,
returnParam: result,
});
@@ -313,7 +313,7 @@ export async function listNoteVersions(noteId: string) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-历史版本列表",
optDetail: "CM助手-全量-知识库-历史版本列表",
url: `${baseUrl()}/notes/${encodeURIComponent(noteId)}/versions`,
reqParam: { noteId },
returnParam: res.items,
@@ -332,7 +332,7 @@ export async function listDuplicates() {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-重复项列表",
optDetail: "CM助手-全量-知识库-重复项列表",
url: `${baseUrl()}/duplicates`,
returnParam: res.groups,
});
@@ -349,7 +349,7 @@ export async function mergeKnowledgeNotes(primaryId: string, duplicateIds: strin
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-知识库-合并",
optDetail: "CM助手-全量-知识库-合并",
url: `${baseUrl()}/merge`,
reqParam: { primary_id: primaryId, duplicate_ids: duplicateIds },
returnParam: result,
@@ -363,7 +363,7 @@ export async function reindexKnowledge() {
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-知识库-重建索引",
optDetail: "CM助手-全量-知识库-重建索引",
url: `${baseUrl()}/reindex`,
returnParam: result,
});
@@ -379,7 +379,7 @@ export async function getKnowledgeGraph() {
const result = await parseResponse<KnowledgeGraph>(await apiFetch(`${baseUrl()}/graph`));
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-图谱查看",
optDetail: "CM助手-全量-知识库-图谱查看",
url: `${baseUrl()}/graph`,
returnParam: result,
});
@@ -401,7 +401,7 @@ export async function getGraphBlacklist() {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-图谱黑名单列表",
optDetail: "CM助手-全量-知识库-图谱黑名单列表",
url: `${baseUrl()}/graph/blacklist`,
returnParam: res.items,
});
@@ -419,7 +419,7 @@ export async function addGraphBlacklist(labels: string[]) {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-知识库-图谱黑名单新增",
optDetail: "CM助手-全量-知识库-图谱黑名单新增",
url: `${baseUrl()}/graph/blacklist`,
reqParam: { labels },
returnParam: result,
@@ -435,7 +435,7 @@ export async function removeGraphBlacklist(entryId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-知识库-图谱黑名单删除",
optDetail: "CM助手-全量-知识库-图谱黑名单删除",
url: `${baseUrl()}/graph/blacklist/${encodeURIComponent(entryId)}`,
reqParam: { entryId },
returnParam: result,
@@ -451,7 +451,7 @@ export async function listKnowledgeFolders() {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-目录列表",
optDetail: "CM助手-全量-知识库-目录列表",
url: `${baseUrl()}/folders`,
returnParam: res.items,
});
@@ -468,7 +468,7 @@ export async function createKnowledgeFolder(path: string) {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-知识库-目录新建",
optDetail: "CM助手-全量-知识库-目录新建",
url: `${baseUrl()}/folders`,
reqParam: { path },
returnParam: res.folder,
@@ -486,7 +486,7 @@ export async function renameKnowledgeFolder(folderId: string, path: string) {
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-知识库-目录重命名",
optDetail: "CM助手-全量-知识库-目录重命名",
url: `${baseUrl()}/folders/${encodeURIComponent(folderId)}`,
reqParam: { folderId, path },
returnParam: res.folder,
@@ -503,7 +503,7 @@ export async function deleteKnowledgeFolder(folderId: string, reassignTo?: strin
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-知识库-目录删除",
optDetail: "CM助手-全量-知识库-目录删除",
url: `${baseUrl()}/folders/${encodeURIComponent(folderId)}${qs}`,
reqParam: { folderId, reassignTo },
returnParam: result,
@@ -523,7 +523,7 @@ export async function listExtractTemplates(scope?: ExtractTemplateScope, enabled
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-知识库-抽取模板列表",
optDetail: "CM助手-全量-知识库-抽取模板列表",
url: `${baseUrl()}/extract-templates${q ? `?${q}` : ""}`,
reqParam: { scope, enabledOnly },
returnParam: res.items,
@@ -550,7 +550,7 @@ export async function createExtractTemplate(data: ExtractTemplateInput) {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-知识库-抽取模板新建",
optDetail: "CM助手-全量-知识库-抽取模板新建",
url: `${baseUrl()}/extract-templates`,
reqParam: data,
returnParam: res.template,
@@ -571,7 +571,7 @@ export async function updateExtractTemplate(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-知识库-抽取模板修改",
optDetail: "CM助手-全量-知识库-抽取模板修改",
url: `${baseUrl()}/extract-templates/${encodeURIComponent(templateId)}`,
reqParam: { templateId, data },
returnParam: res.template,
@@ -587,7 +587,7 @@ export async function deleteExtractTemplate(templateId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-知识库-抽取模板删除",
optDetail: "CM助手-全量-知识库-抽取模板删除",
url: `${baseUrl()}/extract-templates/${encodeURIComponent(templateId)}`,
reqParam: { templateId },
returnParam: result,
+2 -2
View File
@@ -64,7 +64,7 @@ export async function loadLlmMetrics(
const result = (await response.json()) as LlmMetricsListResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-模型指标-查询调用列表",
optDetail: "CM助手-全量-模型指标-查询调用列表",
url,
reqParam: query,
returnParam: { total: result.total, count: result.items.length },
@@ -87,7 +87,7 @@ export async function downloadLlmMetricsExcel(
}
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-模型指标-导出Excel",
optDetail: "CM助手-全量-模型指标-导出Excel",
url: requestUrl,
reqParam: filters,
});
+1 -1
View File
@@ -35,7 +35,7 @@ export enum OptType {
export interface WriteYLogParams {
/** 操作类型枚举。 */
optType: OptType;
/** 操作详情(简短描述),统一「B1-CM助手-xxx」。 */
/** 操作详情(简短描述),统一「CM助手-全量-xxx」。 */
optDetail: string;
/** 操作命中的接口地址(完整或相对,内部自动转相对,去 ip/host)。 */
url: string;
+36 -36
View File
@@ -1,36 +1,36 @@
import { getBackendBaseURL } from "@/core/config";
import { apiFetch } from "@/core/api";
import { OptType, writeYLog } from "@/core/log/y-log";
import type { MCPConfig } from "./types";
export async function loadMCPConfig() {
const response = await apiFetch(`${getBackendBaseURL()}/api/mcp/config`);
const data = (await response.json()) as MCPConfig;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-MCP服务-配置查看",
url: "/api/mcp/config",
returnParam: data,
});
return data;
}
export async function updateMCPConfig(config: MCPConfig) {
const response = await apiFetch(`${getBackendBaseURL()}/api/mcp/config`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(config),
});
const data = await response.json();
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-MCP服务-配置编辑",
url: "/api/mcp/config",
reqParam: config,
returnParam: data,
});
return data;
}
import { getBackendBaseURL } from "@/core/config";
import { apiFetch } from "@/core/api";
import { OptType, writeYLog } from "@/core/log/y-log";
import type { MCPConfig } from "./types";
export async function loadMCPConfig() {
const response = await apiFetch(`${getBackendBaseURL()}/api/mcp/config`);
const data = (await response.json()) as MCPConfig;
writeYLog({
optType: OptType.view,
optDetail: "CM助手-全量-MCP服务-配置查看",
url: "/api/mcp/config",
returnParam: data,
});
return data;
}
export async function updateMCPConfig(config: MCPConfig) {
const response = await apiFetch(`${getBackendBaseURL()}/api/mcp/config`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(config),
});
const data = await response.json();
writeYLog({
optType: OptType.edit,
optDetail: "CM助手-全量-MCP服务-配置编辑",
url: "/api/mcp/config",
reqParam: config,
returnParam: data,
});
return data;
}
+7 -7
View File
@@ -58,7 +58,7 @@ export async function loadMemoryV2(agent?: string): Promise<MemoryV2Data> {
const data = await readJson<MemoryV2Data>(response, "Failed to fetch memory");
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-记忆-查看",
optDetail: "CM助手-全量-记忆-查看",
url: `/api/memory/v2${agentQuery(agent)}`,
reqParam: { agent },
returnParam: data,
@@ -82,7 +82,7 @@ export async function addMemoryEntry(
const data = await readJson<MemoryV2Data>(response, "Failed to add memory entry");
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-记忆-新增",
optDetail: "CM助手-全量-记忆-新增",
url: `/api/memory/v2/entries${agentQuery(agent)}`,
reqParam: { target, content, agent },
returnParam: data,
@@ -107,7 +107,7 @@ export async function replaceMemoryEntry(
const data = await readJson<MemoryV2Data>(response, "Failed to replace memory entry");
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-记忆-编辑",
optDetail: "CM助手-全量-记忆-编辑",
url: `/api/memory/v2/entries${agentQuery(agent)}`,
reqParam: { target, old_text: oldText, content, agent },
returnParam: data,
@@ -131,7 +131,7 @@ export async function deleteMemoryEntry(
const data = await readJson<MemoryV2Data>(response, "Failed to delete memory entry");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-记忆-删除",
optDetail: "CM助手-全量-记忆-删除",
url: `/api/memory/v2/entries?${params.toString()}`,
reqParam: { target, old_text: oldText, agent },
returnParam: data,
@@ -146,7 +146,7 @@ export async function loadMemoryConfig(): Promise<MemoryV2ConfigResponse> {
const data = await readJson<MemoryV2ConfigResponse>(response, "Failed to fetch memory config");
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-记忆-配置查看",
optDetail: "CM助手-全量-记忆-配置查看",
url: "/api/memory/v2/config",
returnParam: data,
});
@@ -164,7 +164,7 @@ export async function patchMemoryConfig(
const data = await readJson<MemoryV2ConfigResponse>(response, "Failed to update memory config");
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-记忆-配置编辑",
optDetail: "CM助手-全量-记忆-配置编辑",
url: "/api/memory/v2/config",
reqParam: { overrides },
returnParam: data,
@@ -190,7 +190,7 @@ export async function searchMemory(
const data = await readJson<MemorySearchResult>(response, "Failed to search memory");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-记忆-检索",
optDetail: "CM助手-全量-记忆-检索",
url: `/api/memory/v2/search${agentQuery(agent)}`,
reqParam: { query, mode, agent },
returnParam: data,
+21 -21
View File
@@ -1,21 +1,21 @@
import { getBackendBaseURL } from "../config";
import { apiFetch } from "../api";
import { OptType, writeYLog } from "../log/y-log";
import type { ModelsResponse } from "./types";
export async function loadModels(): Promise<ModelsResponse> {
const res = await apiFetch(`${getBackendBaseURL()}/api/models`);
const data = (await res.json()) as Partial<ModelsResponse>;
const result: ModelsResponse = {
models: data.models ?? [],
token_usage: data.token_usage ?? { enabled: false },
};
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-模型-查询",
url: "/api/models",
returnParam: result,
});
return result;
}
import { getBackendBaseURL } from "../config";
import { apiFetch } from "../api";
import { OptType, writeYLog } from "../log/y-log";
import type { ModelsResponse } from "./types";
export async function loadModels(): Promise<ModelsResponse> {
const res = await apiFetch(`${getBackendBaseURL()}/api/models`);
const data = (await res.json()) as Partial<ModelsResponse>;
const result: ModelsResponse = {
models: data.models ?? [],
token_usage: data.token_usage ?? { enabled: false },
};
writeYLog({
optType: OptType.search,
optDetail: "CM助手-全量-模型-查询",
url: "/api/models",
returnParam: result,
});
return result;
}
+2 -2
View File
@@ -80,7 +80,7 @@ export async function createSearchSpace(
const result = (await response.json()) as SearchSpace;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-笔记-新建笔记空间",
optDetail: "CM助手-全量-笔记-新建笔记空间",
url: "/api/v1/searchspaces",
reqParam: { name: input.name, description: input.description ?? "" },
returnParam: { id: result.id, name: result.name },
@@ -110,7 +110,7 @@ export async function listSearchSpaces(
const list = Array.isArray(data) ? (data as SearchSpace[]) : [];
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-笔记-查询笔记空间列表",
optDetail: "CM助手-全量-笔记-查询笔记空间列表",
url: path,
reqParam: query,
returnParam: { count: list.length },
+4 -4
View File
@@ -27,7 +27,7 @@ export async function listNotifications(
const data = (await res.json()) as NotificationListResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-通知-查询通知列表",
optDetail: "CM助手-全量-通知-查询通知列表",
url,
reqParam: options,
returnParam: { count: data.items.length },
@@ -48,7 +48,7 @@ export async function markNotificationRead(id: string): Promise<void> {
if (!res.ok) throw await parseDetail(res, "Failed to mark notification read");
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-通知-标记已读",
optDetail: "CM助手-全量-通知-标记已读",
url,
reqParam: { id },
});
@@ -61,7 +61,7 @@ export async function markAllNotificationsRead(): Promise<number> {
const data = (await res.json()) as { updated: number };
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-通知-全部标记已读",
optDetail: "CM助手-全量-通知-全部标记已读",
url,
returnParam: data,
});
@@ -74,7 +74,7 @@ export async function deleteNotification(id: string): Promise<void> {
if (!res.ok) throw await parseDetail(res, "Failed to delete notification");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-通知-删除通知",
optDetail: "CM助手-全量-通知-删除通知",
url,
reqParam: { id },
});
+12 -12
View File
@@ -27,7 +27,7 @@ export async function listPositions(): Promise<Position[]> {
const data = (await res.json()) as PositionListResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-岗位-查询",
optDetail: "CM助手-全量-岗位-查询",
url: "/api/positions",
returnParam: data.positions,
});
@@ -44,7 +44,7 @@ export async function createPosition(input: PositionCreateInput): Promise<Positi
const created = (await res.json()) as Position;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-岗位-新增",
optDetail: "CM助手-全量-岗位-新增",
url: "/api/positions",
reqParam: input,
returnParam: created,
@@ -62,7 +62,7 @@ export async function updatePosition(id: string, input: PositionUpdateInput): Pr
const updated = (await res.json()) as Position;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-岗位-编辑",
optDetail: "CM助手-全量-岗位-编辑",
url: `/api/positions/${id}`,
reqParam: input,
returnParam: updated,
@@ -75,7 +75,7 @@ export async function deletePosition(id: string): Promise<void> {
if (!res.ok) throw await parseDetail(res, "Failed to delete position");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-岗位-删除",
optDetail: "CM助手-全量-岗位-删除",
url: `/api/positions/${id}`,
reqParam: { id },
});
@@ -87,7 +87,7 @@ export async function getTagBindings(positionId: string): Promise<TagBindings> {
const data = (await res.json()) as TagBindingsResponse;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-岗位-标签绑定查看",
optDetail: "CM助手-全量-岗位-标签绑定查看",
url: `/api/positions/${positionId}/tag-bindings`,
reqParam: { positionId },
returnParam: data.bindings,
@@ -105,7 +105,7 @@ export async function setTagBindings(positionId: string, bindings: TagBindings):
const data = (await res.json()) as TagBindingsResponse;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-岗位-标签绑定保存",
optDetail: "CM助手-全量-岗位-标签绑定保存",
url: `/api/positions/${positionId}/tag-bindings`,
reqParam: { positionId, bindings },
returnParam: data.bindings,
@@ -119,7 +119,7 @@ export async function listMembers(positionId: string): Promise<PositionMember[]>
const data = (await res.json()) as { members: PositionMember[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-岗位-成员查询",
optDetail: "CM助手-全量-岗位-成员查询",
url: `/api/positions/${positionId}/members`,
reqParam: { positionId },
returnParam: data.members,
@@ -137,7 +137,7 @@ export async function addMembers(positionId: string, userIds: string[]): Promise
const data = (await res.json()) as { members: PositionMember[] };
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-岗位-添加成员",
optDetail: "CM助手-全量-岗位-添加成员",
url: `/api/positions/${positionId}/members`,
reqParam: { positionId, userIds },
returnParam: data.members,
@@ -155,7 +155,7 @@ export async function removeMembers(positionId: string, userIds: string[]): Prom
const data = (await res.json()) as { members: PositionMember[] };
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-岗位-移除成员",
optDetail: "CM助手-全量-岗位-移除成员",
url: `/api/positions/${positionId}/members`,
reqParam: { positionId, userIds },
returnParam: data.members,
@@ -169,7 +169,7 @@ export async function resyncPosition(positionId: string): Promise<number> {
const data = (await res.json()) as { synced: number };
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-岗位-同步",
optDetail: "CM助手-全量-岗位-同步",
url: `/api/positions/${positionId}/resync`,
reqParam: { positionId },
returnParam: data,
@@ -190,7 +190,7 @@ export async function listPositionUsers(): Promise<PositionUser[]> {
const data = (await res.json()) as { users: PositionUser[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-岗位-用户查询",
optDetail: "CM助手-全量-岗位-用户查询",
url: "/api/positions/users",
returnParam: data.users,
});
@@ -206,7 +206,7 @@ export async function setUserPosition(userId: string, positionId: string | null)
if (!res.ok) throw await parseDetail(res, "Failed to set user position");
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-岗位-设置用户岗位",
optDetail: "CM助手-全量-岗位-设置用户岗位",
url: `/api/positions/users/${userId}`,
reqParam: { userId, positionId },
});
@@ -19,7 +19,7 @@ export async function listRecommendedQuestions(all = false): Promise<Recommended
const data = (await res.json()) as { questions: RecommendedQuestion[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-推荐问题-查询列表",
optDetail: "CM助手-全量-推荐问题-查询列表",
url,
reqParam: { all },
returnParam: { count: data.questions.length },
@@ -43,7 +43,7 @@ export async function createRecommendedQuestion(
const result = (await res.json()) as RecommendedQuestion;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-推荐问题-新增问题",
optDetail: "CM助手-全量-推荐问题-新增问题",
url,
reqParam: body,
returnParam: result,
@@ -68,7 +68,7 @@ export async function updateRecommendedQuestion(
const result = (await res.json()) as RecommendedQuestion;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-推荐问题-编辑问题",
optDetail: "CM助手-全量-推荐问题-编辑问题",
url,
reqParam: { id, ...body },
returnParam: result,
@@ -82,7 +82,7 @@ export async function deleteRecommendedQuestion(id: string): Promise<void> {
if (!res.ok) throw new Error(`Failed to delete question: ${res.statusText}`);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-推荐问题-删除问题",
optDetail: "CM助手-全量-推荐问题-删除问题",
url,
reqParam: { id },
});
@@ -101,7 +101,7 @@ export async function reorderRecommendedQuestions(
const data = (await res.json()) as { questions: RecommendedQuestion[] };
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-推荐问题-调整排序",
optDetail: "CM助手-全量-推荐问题-调整排序",
url,
reqParam: { ids },
});
@@ -90,7 +90,7 @@ export async function createDraftShare(
const result = (await response.json()) as DraftShare;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-会商草稿分享-创建分享",
optDetail: "CM助手-全量-会商草稿分享-创建分享",
url: baseUrl(),
reqParam: { draft_id: draftId, mode },
returnParam: { share_code: result.share_code, mode: result.mode },
@@ -105,7 +105,7 @@ export async function listDraftShares(): Promise<DraftShare[]> {
const json = (await response.json()) as { shares: DraftShare[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-会商草稿分享-查询分享列表",
optDetail: "CM助手-全量-会商草稿分享-查询分享列表",
url: baseUrl(),
returnParam: { count: json.shares.length },
});
@@ -119,7 +119,7 @@ export async function revokeDraftShare(shareCode: string): Promise<void> {
if (!response.ok) throw await parseError(response, "撤销分享失败");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-会商草稿分享-撤销分享",
optDetail: "CM助手-全量-会商草稿分享-撤销分享",
url,
reqParam: { shareCode },
});
@@ -133,7 +133,7 @@ export async function previewDraftShare(shareCode: string): Promise<DraftSharePr
const result = (await response.json()) as DraftSharePreview;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-会商草稿分享-预览分享",
optDetail: "CM助手-全量-会商草稿分享-预览分享",
url,
reqParam: { shareCode },
});
@@ -148,7 +148,7 @@ export async function importDraftShare(shareCode: string): Promise<DraftImportRe
const result = (await response.json()) as DraftImportResult;
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-会商草稿分享-导入分享",
optDetail: "CM助手-全量-会商草稿分享-导入分享",
url,
reqParam: { shareCode },
returnParam: result,
+33 -33
View File
@@ -77,7 +77,7 @@ export async function listScheduledTasks(params: ListScheduledTasksParams = {})
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-定时任务-列表",
optDetail: "CM助手-全量-定时任务-列表",
url: `${baseUrl()}${query ? `?${query}` : ""}`,
reqParam: params,
returnParam: result,
@@ -104,7 +104,7 @@ export async function createScheduledTask(data: {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-定时任务-新建",
optDetail: "CM助手-全量-定时任务-新建",
url: baseUrl(),
reqParam: data,
returnParam: result,
@@ -118,7 +118,7 @@ export async function listScheduledTaskRuns(taskId: string) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-定时任务-运行记录列表",
optDetail: "CM助手-全量-定时任务-运行记录列表",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/runs`,
reqParam: { taskId },
returnParam: result,
@@ -132,7 +132,7 @@ export async function getScheduledTaskRun(runId: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-定时任务-运行详情",
optDetail: "CM助手-全量-定时任务-运行详情",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}`,
reqParam: { runId },
returnParam: result,
@@ -148,7 +148,7 @@ export async function deleteScheduledTaskRun(runId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-定时任务-删除运行记录",
optDetail: "CM助手-全量-定时任务-删除运行记录",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}`,
reqParam: { runId },
returnParam: result,
@@ -163,7 +163,7 @@ export async function getScheduledTaskRunMessages(runId: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-定时任务-运行消息",
optDetail: "CM助手-全量-定时任务-运行消息",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}/messages`,
reqParam: { runId },
returnParam: result,
@@ -185,7 +185,7 @@ export async function getScheduledTaskRunFileContent(runId: string, fileIndex: n
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-定时任务-运行文件查看",
optDetail: "CM助手-全量-定时任务-运行文件查看",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}/files/${fileIndex}`,
reqParam: { runId, fileIndex },
returnParam: result,
@@ -207,7 +207,7 @@ export async function updateScheduledTaskRunFile(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-定时任务-运行文件编辑",
optDetail: "CM助手-全量-定时任务-运行文件编辑",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}/files/${fileIndex}`,
reqParam: { runId, fileIndex },
returnParam: result,
@@ -274,7 +274,7 @@ export async function downloadScheduledTaskRun(runId: string) {
);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-定时任务-下载运行结果",
optDetail: "CM助手-全量-定时任务-下载运行结果",
url: scheduledTaskRunDownloadUrl(runId),
reqParam: { runId },
});
@@ -287,7 +287,7 @@ export async function downloadScheduledTaskRunFile(runId: string, fileIndex: num
);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-定时任务-下载运行文件",
optDetail: "CM助手-全量-定时任务-下载运行文件",
url: scheduledTaskRunFileDownloadUrl(runId, fileIndex),
reqParam: { runId, fileIndex },
});
@@ -299,7 +299,7 @@ export async function getScheduledTaskDeliveryProfile() {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-定时任务-投递配置查看",
optDetail: "CM助手-全量-定时任务-投递配置查看",
url: `${baseUrl()}/delivery-profile`,
returnParam: result,
});
@@ -318,7 +318,7 @@ export async function updateScheduledTaskDeliveryProfile(data: {
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-定时任务-投递配置修改",
optDetail: "CM助手-全量-定时任务-投递配置修改",
url: `${baseUrl()}/delivery-profile`,
reqParam: data,
returnParam: result,
@@ -349,7 +349,7 @@ export async function updateScheduledTask(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-定时任务-修改",
optDetail: "CM助手-全量-定时任务-修改",
url: `${baseUrl()}/${encodeURIComponent(taskId)}`,
reqParam: { taskId, data },
returnParam: result,
@@ -365,7 +365,7 @@ export async function deleteScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-定时任务-删除",
optDetail: "CM助手-全量-定时任务-删除",
url: `${baseUrl()}/${encodeURIComponent(taskId)}`,
reqParam: { taskId },
returnParam: result,
@@ -381,7 +381,7 @@ export async function pauseScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.disabled,
optDetail: "B1-CM助手-定时任务-暂停",
optDetail: "CM助手-全量-定时任务-暂停",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/pause`,
reqParam: { taskId },
returnParam: result,
@@ -397,7 +397,7 @@ export async function resumeScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.enabled,
optDetail: "B1-CM助手-定时任务-恢复",
optDetail: "CM助手-全量-定时任务-恢复",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/resume`,
reqParam: { taskId },
returnParam: result,
@@ -413,7 +413,7 @@ export async function triggerScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-定时任务-手动运行",
optDetail: "CM助手-全量-定时任务-手动运行",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/trigger`,
reqParam: { taskId },
returnParam: result,
@@ -431,7 +431,7 @@ export async function listPublishedScheduledTasks(params: { limit?: number; offs
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-定时任务-已发布列表",
optDetail: "CM助手-全量-定时任务-已发布列表",
url: `${baseUrl()}/published${suffix ? `?${suffix}` : ""}`,
reqParam: params,
returnParam: result,
@@ -447,7 +447,7 @@ export async function publishScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-定时任务-发布",
optDetail: "CM助手-全量-定时任务-发布",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/publish`,
reqParam: { taskId },
returnParam: result,
@@ -463,7 +463,7 @@ export async function unpublishScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-定时任务-取消发布",
optDetail: "CM助手-全量-定时任务-取消发布",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/unpublish`,
reqParam: { taskId },
returnParam: result,
@@ -481,7 +481,7 @@ export async function subscribeScheduledTask(taskId: string, notifyElement: bool
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-定时任务-订阅",
optDetail: "CM助手-全量-定时任务-订阅",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/subscribe`,
reqParam: { taskId, notify_element: notifyElement },
returnParam: result,
@@ -499,7 +499,7 @@ export async function updateScheduledTaskSubscription(taskId: string, notifyElem
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-定时任务-订阅修改",
optDetail: "CM助手-全量-定时任务-订阅修改",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/subscribe`,
reqParam: { taskId, notify_element: notifyElement },
returnParam: result,
@@ -515,7 +515,7 @@ export async function unsubscribeScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-定时任务-取消订阅",
optDetail: "CM助手-全量-定时任务-取消订阅",
url: `${baseUrl()}/${encodeURIComponent(taskId)}/subscribe`,
reqParam: { taskId },
returnParam: result,
@@ -535,7 +535,7 @@ export async function listAllScheduledTasks(search?: string) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-定时任务-全部任务列表",
optDetail: "CM助手-全量-定时任务-全部任务列表",
url: `${baseUrl()}/admin/all${query ? `?${query}` : ""}`,
reqParam: { search },
returnParam: result,
@@ -550,7 +550,7 @@ export async function adminListScheduledTaskRuns(taskId: string) {
);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-定时任务-运行记录列表",
optDetail: "CM助手-全量-定时任务-运行记录列表",
url: `${baseUrl()}/admin/${encodeURIComponent(taskId)}/runs`,
reqParam: { taskId },
returnParam: result,
@@ -581,7 +581,7 @@ export async function adminUpdateScheduledTask(
);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-定时任务-修改",
optDetail: "CM助手-全量-定时任务-修改",
url: `${baseUrl()}/admin/${encodeURIComponent(taskId)}`,
reqParam: { taskId, data },
returnParam: result,
@@ -598,7 +598,7 @@ export async function adminDeleteScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-定时任务-删除",
optDetail: "CM助手-全量-定时任务-删除",
url: `${baseUrl()}/admin/${encodeURIComponent(taskId)}`,
reqParam: { taskId },
returnParam: result,
@@ -615,7 +615,7 @@ export async function adminTriggerScheduledTask(taskId: string) {
);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-定时任务-手动运行",
optDetail: "CM助手-全量-定时任务-手动运行",
url: `${baseUrl()}/admin/${encodeURIComponent(taskId)}/trigger`,
reqParam: { taskId },
returnParam: result,
@@ -632,7 +632,7 @@ export async function getScheduledTaskRunHtml(runId: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-定时任务-运行HTML查看",
optDetail: "CM助手-全量-定时任务-运行HTML查看",
url: `${baseUrl()}/runs/${encodeURIComponent(runId)}/html`,
reqParam: { runId },
returnParam: result,
@@ -646,7 +646,7 @@ export async function listHtmlPageFavorites() {
const result = await parseResponse<HtmlPageFavorite[]>(await apiFetch(favoritesUrl()));
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-HTML收藏-列表",
optDetail: "CM助手-全量-HTML收藏-列表",
url: `/api/html-page-favorites`,
returnParam: result,
});
@@ -659,7 +659,7 @@ export async function getHtmlPageFavorite(favoriteId: string) {
);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-HTML收藏-查看",
optDetail: "CM助手-全量-HTML收藏-查看",
url: `/api/html-page-favorites/${encodeURIComponent(favoriteId)}`,
reqParam: { favoriteId },
returnParam: result,
@@ -682,7 +682,7 @@ export async function createHtmlPageFavorite(data: {
);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-HTML收藏-新建",
optDetail: "CM助手-全量-HTML收藏-新建",
url: `/api/html-page-favorites`,
reqParam: data,
returnParam: result,
@@ -698,7 +698,7 @@ export async function deleteHtmlPageFavorite(favoriteId: string) {
);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-HTML收藏-删除",
optDetail: "CM助手-全量-HTML收藏-删除",
url: `/api/html-page-favorites/${encodeURIComponent(favoriteId)}`,
reqParam: { favoriteId },
returnParam: result,
@@ -488,7 +488,7 @@ export async function downloadMarkdownAsDocx(
const blob = await markdownToDocxBlob(markdown, title);
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-定时任务-导出",
optDetail: "CM助手-全量-定时任务-导出",
url: "/scheduled-tasks/export/docx",
reqParam: { fileName, title },
});
@@ -0,0 +1,73 @@
import assert from "node:assert/strict";
import test from "node:test";
import { applyInlineCitations, type RuntimeDisplaySource } from "./runtime";
function makeSources(count: number): RuntimeDisplaySource[] {
return Array.from({ length: count }, (_unused, position) => ({
index: position + 1,
skillName: "knowledge-base-search",
mode: "citation",
title: `参考文献 ${position + 1}`,
type: "result",
snippet: "",
raw: {},
}));
}
function citation(index: number): string {
return `[citation:${index}](#reference-${index})`;
}
test("全角单编号 【1】【2】 解析为引用徽章", () => {
const out = applyInlineCitations("结论见【1】【2】。", makeSources(2));
assert.equal(out.includes(citation(1)), true);
assert.equal(out.includes(citation(2)), true);
assert.equal(out.includes("【1】"), false);
assert.equal(out.includes("【2】"), false);
});
test("全角数字 【1】 也能识别", () => {
const out = applyInlineCitations("参考【1】和【2】。", makeSources(2));
assert.equal(out.includes(citation(1)), true);
assert.equal(out.includes(citation(2)), true);
});
test("全角括号合并编号 【1,2】/【1,2】/【1、2】 拆成多个引用", () => {
for (const marker of ["【1,2】", "【1,2】", "【1、2】"]) {
const out = applyInlineCitations(`见${marker}。`, makeSources(2));
assert.equal(out.includes(citation(1)), true, marker);
assert.equal(out.includes(citation(2)), true, marker);
}
});
test("全角区间编号 【1-3】/【2~5】 展开为连续引用", () => {
const dash = applyInlineCitations("见【1-3】。", makeSources(3));
assert.equal(dash.includes(citation(1)), true);
assert.equal(dash.includes(citation(2)), true);
assert.equal(dash.includes(citation(3)), true);
const tilde = applyInlineCitations("见【2~4】。", makeSources(4));
assert.equal(tilde.includes(citation(2)), true);
assert.equal(tilde.includes(citation(3)), true);
assert.equal(tilde.includes(citation(4)), true);
});
test("超出来源范围的全角编号保持原样,不误判正文", () => {
// 只有 1 条来源,【3】 没有对应来源 → 不应转换
const out = applyInlineCitations("正文【3】不是引用。", makeSources(1));
assert.equal(out.includes("【3】"), true);
assert.equal(out.includes("#reference-3"), false);
});
test("非数字的全角括号不被改写", () => {
const out = applyInlineCitations("见【附录】小节。", makeSources(2));
assert.equal(out.includes("【附录】"), true);
});
test("半角写法仍然正常工作", () => {
const out = applyInlineCitations("见[1][2]和[1,3]。", makeSources(3));
assert.equal(out.includes(citation(1)), true);
assert.equal(out.includes(citation(2)), true);
assert.equal(out.includes(citation(3)), true);
});
+56 -3
View File
@@ -623,9 +623,62 @@ function normalizeLooseCitationTokens(
return indexes.map((index) => `[${index}]`).join("");
};
// 全角括号写法:【1】→ [1]
let next = content.replace(/【\s*(\d{1,3})\s*】/g, (match, rawIndex: string) =>
isValidIndex(Number(rawIndex)) ? `[${rawIndex}]` : match,
// 全角数字转半角:123 → 123(仅用于括号内的编号识别)
const toAsciiDigits = (value: string) =>
value.replace(/[0-9]/g, (digit) =>
String.fromCharCode(digit.charCodeAt(0) - 0xfee0),
);
// 全角括号写法(含全角数字):
// 【1】/【1】 → [1]
// 【1,2】/【1,2】/【1、2】 → [1][2]
// 【1-3】/【2~5】 → [1][2][3]
// 三种形态互斥(单编号内不含分隔符),且都要求编号能对应到参考来源,
// 避免把正文里的【…】误判成引用。转成半角后交给下面的半角逻辑统一处理。
// 全角单编号:【1】/【1】
let next = content.replace(
/【\s*([0-90-9]{1,3})\s*】/g,
(match, rawIndex: string) => {
const index = Number(toAsciiDigits(rawIndex));
return isValidIndex(index) ? `[${index}]` : match;
},
);
// 全角合并编号:【1,2】/【1,2】/【1、2】
next = next.replace(
/【\s*([0-90-9]{1,3}(?:\s*[,,、]\s*[0-90-9]{1,3})+)\s*】/g,
(match, rawList: string) => {
const indexes = rawList
.split(/[,,、]/)
.map((part) => Number(toAsciiDigits(part.trim())));
if (indexes.some((index) => !isValidIndex(index))) {
return match;
}
return indexes.map((index) => `[${index}]`).join("");
},
);
// 全角区间编号:【1-3】/【2~5】
next = next.replace(
/【\s*([0-90-9]{1,3})\s*[-–~~]\s*([0-90-9]{1,3})\s*】/g,
(match, rawStart: string, rawEnd: string) => {
const start = Number(toAsciiDigits(rawStart));
const end = Number(toAsciiDigits(rawEnd));
if (
end <= start ||
end - start > 20 ||
!isValidIndex(start) ||
!isValidIndex(end)
) {
return match;
}
const tokens: string[] = [];
for (let index = start; index <= end; index++) {
tokens.push(`[${index}]`);
}
return tokens.join("");
},
);
// 合并写法:[1,2,3] / [1,2] / [1、2] → [1][2][3]
+8 -8
View File
@@ -34,7 +34,7 @@ export async function fetchStudioNotebooks(
const notebooks = (await res.json()) as StudioNotebook[];
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-工作室-空间查询",
optDetail: "CM助手-全量-工作室-空间查询",
url: "/api/v1/searchspaces",
returnParam: notebooks,
});
@@ -62,7 +62,7 @@ export async function createSearchSpace(
}
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-工作室-新建空间",
optDetail: "CM助手-全量-工作室-新建空间",
url: "/api/v1/searchspaces",
reqParam: { name },
});
@@ -91,7 +91,7 @@ export async function uploadSourceText(
if (!res.ok) throw new Error(`上传失败:${res.status}`);
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-工作室-上传文字来源",
optDetail: "CM助手-全量-工作室-上传文字来源",
url: "/api/v1/documents/textupload",
reqParam: { search_space_id: notebookId, title: title || "粘贴的文字" },
});
@@ -110,7 +110,7 @@ export async function deleteSearchSpace(
if (!res.ok) throw new Error(`删除失败:${res.status}`);
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-工作室-删除空间",
optDetail: "CM助手-全量-工作室-删除空间",
url: `/api/v1/searchspaces/${id}`,
reqParam: { id },
});
@@ -134,7 +134,7 @@ export async function renameSearchSpace(
if (!res.ok) throw new Error(`重命名失败:${res.status}`);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-工作室-重命名空间",
optDetail: "CM助手-全量-工作室-重命名空间",
url: `/api/v1/searchspaces/${id}`,
reqParam: { id, name },
});
@@ -169,7 +169,7 @@ export async function fetchDocumentByChunk(
const doc = (await res.json()) as DocumentWithChunks;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-工作室-查看文档",
optDetail: "CM助手-全量-工作室-查看文档",
url: `/api/v1/documents/by-chunk/${chunkId}`,
reqParam: { chunkId },
returnParam: { id: doc.id, title: doc.title, file_type: doc.file_type },
@@ -199,7 +199,7 @@ export async function uploadSourceFiles(
if (!res.ok) throw new Error(`上传失败:${res.status}`);
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-工作室-上传文件来源",
optDetail: "CM助手-全量-工作室-上传文件来源",
url: "/api/v1/documents/fileupload",
reqParam: {
search_space_id: notebookId,
@@ -223,7 +223,7 @@ export async function fetchNotebookSources(
const sources = (await res.json()) as SourceItem[];
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-工作室-来源查询",
optDetail: "CM助手-全量-工作室-来源查询",
url: `/api/v1/source/search-space/${notebookId}?limit=100`,
reqParam: { notebookId },
returnParam: sources,
+17 -17
View File
@@ -24,7 +24,7 @@ export async function loadPromptPrefixSettings(): Promise<PromptPrefixSettings>
const data = (await response.json()) as PromptPrefixSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-提示词前缀查看",
optDetail: "CM助手-全量-系统设置-提示词前缀查看",
url: "/api/system-settings/prompt-prefix",
returnParam: data,
});
@@ -51,7 +51,7 @@ export async function updatePromptPrefixSettings(
const data = (await response.json()) as PromptPrefixSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-提示词前缀编辑",
optDetail: "CM助手-全量-系统设置-提示词前缀编辑",
url: "/api/system-settings/prompt-prefix",
reqParam: body,
returnParam: data,
@@ -105,7 +105,7 @@ export async function loadPrivateSquareStatus(): Promise<PrivateSquareStatus> {
const data = (await response.json()) as PrivateSquareStatus;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-私密广场查看",
optDetail: "CM助手-全量-系统设置-私密广场查看",
url: "/api/system-settings/private-square",
returnParam: data,
});
@@ -138,7 +138,7 @@ export async function loadPublishSquares(): Promise<PublishSquaresSettings> {
const data = (await response.json()) as PublishSquaresSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-发布广场查看",
optDetail: "CM助手-全量-系统设置-发布广场查看",
url: "/api/system-settings/publish-squares",
returnParam: data,
});
@@ -165,7 +165,7 @@ export async function updatePublishSquares(
const data = (await response.json()) as PublishSquaresSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-发布广场编辑",
optDetail: "CM助手-全量-系统设置-发布广场编辑",
url: "/api/system-settings/publish-squares",
reqParam: body,
returnParam: data,
@@ -203,7 +203,7 @@ export async function loadAppearanceSettings(): Promise<AppearanceSettings> {
const data = (await response.json()) as AppearanceSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-外观查看",
optDetail: "CM助手-全量-系统设置-外观查看",
url: "/api/system-settings/appearance",
returnParam: data,
});
@@ -230,7 +230,7 @@ export async function updateAppearanceSettings(
const data = (await response.json()) as AppearanceSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-外观编辑",
optDetail: "CM助手-全量-系统设置-外观编辑",
url: "/api/system-settings/appearance",
reqParam: body,
returnParam: data,
@@ -250,7 +250,7 @@ export async function loadCitationDisplaySettings(): Promise<CitationDisplaySett
const data = (await response.json()) as CitationDisplaySettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-引用展示查看",
optDetail: "CM助手-全量-系统设置-引用展示查看",
url: "/api/system-settings/citation-display",
returnParam: data,
});
@@ -267,7 +267,7 @@ export async function loadLeaderboardSettings(): Promise<LeaderboardSettings> {
const data = (await response.json()) as LeaderboardSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-排行榜查看",
optDetail: "CM助手-全量-系统设置-排行榜查看",
url: "/api/system-settings/leaderboard",
returnParam: data,
});
@@ -294,7 +294,7 @@ export async function updateLeaderboardSettings(
const data = (await response.json()) as LeaderboardSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-排行榜编辑",
optDetail: "CM助手-全量-系统设置-排行榜编辑",
url: "/api/system-settings/leaderboard",
reqParam: body,
returnParam: data,
@@ -322,7 +322,7 @@ export async function updateCitationDisplaySettings(
const data = (await response.json()) as CitationDisplaySettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-引用展示编辑",
optDetail: "CM助手-全量-系统设置-引用展示编辑",
url: "/api/system-settings/citation-display",
reqParam: body,
returnParam: data,
@@ -354,7 +354,7 @@ export async function loadSkillCompressionSettings(): Promise<SkillCompressionSe
const data = (await response.json()) as SkillCompressionSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-技能压缩查看",
optDetail: "CM助手-全量-系统设置-技能压缩查看",
url: "/api/system-settings/skill-compression",
returnParam: data,
});
@@ -381,7 +381,7 @@ export async function updateSkillCompressionSettings(
const data = (await response.json()) as SkillCompressionSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-技能压缩编辑",
optDetail: "CM助手-全量-系统设置-技能压缩编辑",
url: "/api/system-settings/skill-compression",
reqParam: body,
returnParam: data,
@@ -407,7 +407,7 @@ export async function loadAgentModuleConfig(
const data = (await response.json()) as AgentModuleConfig;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-智能体模块查看",
optDetail: "CM助手-全量-系统设置-智能体模块查看",
url: `/api/system-settings/agent-modules/${key}`,
reqParam: { key },
returnParam: data,
@@ -436,7 +436,7 @@ export async function updateAgentModuleConfig(
const data = (await response.json()) as AgentModuleConfig;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-智能体模块编辑",
optDetail: "CM助手-全量-系统设置-智能体模块编辑",
url: `/api/system-settings/agent-modules/${key}`,
reqParam: { key, tag_ids: tagIds },
returnParam: data,
@@ -460,7 +460,7 @@ export async function loadLogSystemSettings(): Promise<LogSystemSettings> {
const data = (await response.json()) as LogSystemSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-日志系统查看",
optDetail: "CM助手-全量-系统设置-日志系统查看",
url: "/api/system-settings/log-system",
returnParam: data,
});
@@ -487,7 +487,7 @@ export async function updatePrivateSquareSettings(
const data = (await response.json()) as PrivateSquareStatus;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-私密广场编辑",
optDetail: "CM助手-全量-系统设置-私密广场编辑",
url: "/api/system-settings/private-square",
// omit `password` (secret) from the logged request params
reqParam: { enabled: body.enabled, password_set: body.password != null },
+6 -6
View File
@@ -25,7 +25,7 @@ export async function listTags(tagType?: TagType): Promise<Tag[]> {
const data = (await res.json()) as TagListResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-标签-查询",
optDetail: "CM助手-全量-标签-查询",
url: `/api/tags${query}`,
reqParam: { tagType },
returnParam: data.tags,
@@ -43,7 +43,7 @@ export async function createTag(input: TagCreateInput): Promise<Tag> {
const created = (await res.json()) as Tag;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-标签-新增",
optDetail: "CM助手-全量-标签-新增",
url: "/api/tags",
reqParam: input,
returnParam: created,
@@ -61,7 +61,7 @@ export async function updateTag(id: string, input: TagUpdateInput): Promise<Tag>
const updated = (await res.json()) as Tag;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-标签-编辑",
optDetail: "CM助手-全量-标签-编辑",
url: `/api/tags/${id}`,
reqParam: input,
returnParam: updated,
@@ -76,7 +76,7 @@ export async function deleteTag(id: string): Promise<void> {
if (!res.ok) throw await parseDetail(res, "Failed to delete tag");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-标签-删除",
optDetail: "CM助手-全量-标签-删除",
url: `/api/tags/${id}`,
reqParam: { id },
});
@@ -93,7 +93,7 @@ export async function getResourceTags(
const data = (await res.json()) as TagListResponse;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-标签-资源标签查看",
optDetail: "CM助手-全量-标签-资源标签查看",
url: `/api/tags/assignments/${targetType}/${targetId}`,
reqParam: { targetType, targetId },
returnParam: data.tags,
@@ -118,7 +118,7 @@ export async function setResourceTags(
const data = (await res.json()) as TagListResponse;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-标签-资源标签设置",
optDetail: "CM助手-全量-标签-资源标签设置",
url: `/api/tags/assignments/${targetType}/${targetId}`,
reqParam: { targetType, targetId, tagIds },
returnParam: data.tags,
+5 -5
View File
@@ -69,7 +69,7 @@ export async function createShare(
const result = (await response.json()) as ThreadShare;
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-会话分享-创建分享",
optDetail: "CM助手-全量-会话分享-创建分享",
url: baseUrl(),
reqParam: { thread_id: threadId, mode },
returnParam: { share_code: result.share_code, mode: result.mode },
@@ -84,7 +84,7 @@ export async function listShares(): Promise<ThreadShare[]> {
const json = (await response.json()) as { shares: ThreadShare[] };
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-会话分享-查询分享列表",
optDetail: "CM助手-全量-会话分享-查询分享列表",
url: baseUrl(),
returnParam: { count: json.shares.length },
});
@@ -98,7 +98,7 @@ export async function revokeShare(shareCode: string): Promise<void> {
if (!response.ok) throw await parseError(response, "撤销分享失败");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-会话分享-撤销分享",
optDetail: "CM助手-全量-会话分享-撤销分享",
url,
reqParam: { shareCode },
});
@@ -112,7 +112,7 @@ export async function previewShare(shareCode: string): Promise<SharePreview> {
const result = (await response.json()) as SharePreview;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-会话分享-预览分享",
optDetail: "CM助手-全量-会话分享-预览分享",
url,
reqParam: { shareCode },
});
@@ -127,7 +127,7 @@ export async function importShare(shareCode: string): Promise<ImportResult> {
const result = (await response.json()) as ImportResult;
writeYLog({
optType: OptType.import,
optDetail: "B1-CM助手-会话分享-导入分享",
optDetail: "CM助手-全量-会话分享-导入分享",
url,
reqParam: { shareCode },
returnParam: result,
+1 -1
View File
@@ -425,7 +425,7 @@ export function useThreadStream({
const question = lastHumanFromChatModelInput(data.input);
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-智能问答",
optDetail: "CM助手-全量-智能问答",
url: `/api/threads/${threadIdRef.current ?? ""}/runs/stream`,
reqParam: { model: event.name ?? "", question },
returnParam: { data: answer },
+3 -3
View File
@@ -108,7 +108,7 @@ export async function loadToolMetrics(
const result = (await response.json()) as ToolMetricsListResponse;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-工具指标-查询调用列表",
optDetail: "CM助手-全量-工具指标-查询调用列表",
url,
reqParam: query,
returnParam: { total: result.total, count: result.items.length },
@@ -128,7 +128,7 @@ export async function loadToolMetricsSummary(
const result = (await response.json()) as ToolMetricsSummary;
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-工具指标-查询汇总统计",
optDetail: "CM助手-全量-工具指标-查询汇总统计",
url,
reqParam: filters,
returnParam: { total: result.total, error_total: result.error_total },
@@ -147,7 +147,7 @@ export async function downloadToolMetricsExcel(
}
writeYLog({
optType: OptType.export,
optDetail: "B1-CM助手-工具指标-导出Excel",
optDetail: "CM助手-全量-工具指标-导出Excel",
url: requestUrl,
reqParam: filters,
});
@@ -40,7 +40,7 @@ async function updateUserPreferences(
const result = { hide_admin_prompt_prefix: !!data.hide_admin_prompt_prefix };
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-用户偏好-编辑",
optDetail: "CM助手-全量-用户偏好-编辑",
url: "/api/user-preferences",
reqParam: input,
returnParam: result,
+1 -1
View File
@@ -45,7 +45,7 @@ export async function listMyQa(
const result = await parse<UserQaPageResponse>(await apiFetch(url), "Failed to load my Q&A");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-用户问答-查询我的问答",
optDetail: "CM助手-全量-用户问答-查询我的问答",
url,
reqParam: params,
returnParam: { total: result.total, count: result.items.length },
+1 -1
View File
@@ -186,7 +186,7 @@ export default function AgentChatPage({
const lastHuman = [...msgs].reverse().find((m) => (m as { type?: string }).type === "human");
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-专家代理问答",
optDetail: "CM助手-全量-专家代理问答",
url: `/api/threads/${threadId ?? ""}/runs/stream`,
reqParam: { agent_id, question: lastHuman ? textOfMessage(lastHuman) : "" },
returnParam: { data: lastAi ? textOfMessage(lastAi) : "" },
+1 -1
View File
@@ -195,7 +195,7 @@ export default function ChatPage() {
const lastHuman = [...msgs].reverse().find((m) => (m as { type?: string }).type === "human");
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-专家代理问答",
optDetail: "CM助手-全量-专家代理问答",
url: `/api/threads/${threadId ?? ""}/runs/stream`,
reqParam: { agent_id: selectedAgentId, question: lastHuman ? textOfMessage(lastHuman) : "" },
returnParam: { data: lastAi ? textOfMessage(lastAi) : "" },
+1 -1
View File
@@ -200,7 +200,7 @@ export default function LoginPage() {
void fetchYLogConfig();
writeYLog({
optType: OptType.login,
optDetail: 'B1-CM助手-登录',
optDetail: 'CM助手-全量-登录',
url: '/api/v1/auth/login/token',
reqParam: { username: loginUserName || auth.user_id },
returnParam: { user_id: auth.user_id },
@@ -154,6 +154,7 @@ function SourcesDialog({
isLoadingSources,
selectedSourceIds,
pendingSources,
pendingImportTitles,
onToggle,
onDelete,
}: {
@@ -164,6 +165,7 @@ function SourcesDialog({
isLoadingSources: boolean;
selectedSourceIds: number[];
pendingSources: Map<string, { id?: number; title: string }>;
pendingImportTitles: string[];
onToggle: (id: number) => void;
onDelete: (id: number) => void;
}) {
@@ -216,6 +218,14 @@ function SourcesDialog({
.map(([taskId, s]) => (
<PendingSourceCard key={taskId} title={s.title} />
))}
{pendingImportTitles
.filter((t) => !sources.some((src) => {
const srcTitle = src.title ?? (src.document as { title?: string } | undefined)?.title ?? "";
return srcTitle === t;
}))
.map((t) => (
<PendingSourceCard key={`import-${t}`} title={t} />
))}
{sources.map((src) => (
<SourceCard
key={src.id}
@@ -269,6 +279,8 @@ export default function StudioNotebookDetailPage({
// 轮询任务管理:task_id -> 来源信息
const [pendingSources, setPendingSources] = useState<Map<string, { id?: number; title: string }>>(new Map());
const pollingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
// 同步导入(搜索导入)的占位标题列表,sources 刷新后按标题匹配移除
const [pendingImportTitles, setPendingImportTitles] = useState<string[]>([]);
useEffect(() => {
if (!selectedModel && models.length > 0) {
@@ -287,20 +299,25 @@ export default function StudioNotebookDetailPage({
}
}, [sources, notebook?.id, initializedForNotebook]);
// sources 刷新后,将轮询成功的来源(按标题匹配)自动选中
// sources 刷新后,将轮询成功/同步导入的来源(按标题匹配)自动选中,并移除占位卡
useEffect(() => {
if (pendingSelectTitlesRef.current.size === 0) return;
const matched = sources.filter((s) => {
const title = s.title ?? (s.document as { title?: string } | undefined)?.title ?? "";
return pendingSelectTitlesRef.current.has(title);
});
if (matched.length > 0) {
setSelectedSourceIds((prev) => [...new Set([...prev, ...matched.map((s) => s.id)])]);
matched.forEach((s) => {
const title = s.title ?? (s.document as { title?: string } | undefined)?.title ?? "";
pendingSelectTitlesRef.current.delete(title);
});
const getTitle = (s: SourceItem) =>
s.title ?? (s.document as { title?: string } | undefined)?.title ?? "";
if (pendingSelectTitlesRef.current.size > 0) {
const matched = sources.filter((s) => pendingSelectTitlesRef.current.has(getTitle(s)));
if (matched.length > 0) {
setSelectedSourceIds((prev) => [...new Set([...prev, ...matched.map((s) => s.id)])]);
matched.forEach((s) => pendingSelectTitlesRef.current.delete(getTitle(s)));
}
}
setPendingImportTitles((prev) => {
if (prev.length === 0) return prev;
const sourceTitles = new Set(sources.map(getTitle));
const remaining = prev.filter((t) => !sourceTitles.has(t));
return remaining.length === prev.length ? prev : remaining;
});
}, [sources]);
const citationRehypePlugins = useMemo(() => {
const mapped = sources.map((s) => ({
@@ -392,6 +409,12 @@ export default function StudioNotebookDetailPage({
return newMap;
});
}
// 同步导入(status=success,无 task_id):立刻显示占位卡 + 等 sources 刷新后自动选中
const syncTitles = uploadedSources.filter(s => s.status === 'success' && s.title).map(s => s.title);
if (syncTitles.length > 0) {
syncTitles.forEach(t => pendingSelectTitlesRef.current.add(t));
setPendingImportTitles(prev => [...new Set([...prev, ...syncTitles])]);
}
// 刷新来源列表
void queryClient.invalidateQueries({ queryKey: ["studio", "sources", notebook.id] });
// 刷新 notebooks 数据以更新 source_count
@@ -854,6 +877,7 @@ export default function StudioNotebookDetailPage({
isLoadingSources={isLoadingSources}
selectedSourceIds={selectedSourceIds}
pendingSources={pendingSources}
pendingImportTitles={pendingImportTitles}
onToggle={handleToggleSource}
onDelete={handleDeleteSource}
/>
@@ -158,7 +158,7 @@ export async function listChains(scope: ChainScope = "mine"): Promise<BusinessCh
const chains = (data.chains ?? []).map(toChain);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-业务链条-查询",
optDetail: "CM助手-全量-业务链条-查询",
url,
reqParam: { scope },
returnParam: { count: chains.length },
@@ -179,7 +179,7 @@ export async function getChain(id: string): Promise<BusinessChain | null> {
const chain = toChain(data);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-业务链条-查看",
optDetail: "CM助手-全量-业务链条-查看",
url: `${BASE()}/${id}`,
reqParam: { id },
returnParam: { id: chain.id, title: chain.title },
@@ -197,7 +197,7 @@ export async function createChain(payload: ChainCreatePayload): Promise<Business
const chain = toChain(data);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-业务链条-新建",
optDetail: "CM助手-全量-业务链条-新建",
url: BASE(),
reqParam: { title: payload.title, seats: payload.seats?.length ?? 0 },
returnParam: { id: chain.id, title: chain.title },
@@ -218,10 +218,10 @@ export async function updateChain(id: string, patch: ChainUpdatePayload): Promis
optType: patch.isPublic === true ? OptType.enabled : patch.isPublic === false ? OptType.disabled : OptType.edit,
optDetail:
patch.isPublic === true
? "B1-CM助手-业务链条-发布"
? "CM助手-全量-业务链条-发布"
: patch.isPublic === false
? "B1-CM助手-业务链条-取消发布"
: "B1-CM助手-业务链条-编辑",
? "CM助手-全量-业务链条-取消发布"
: "CM助手-全量-业务链条-编辑",
url: `${BASE()}/${id}`,
reqParam: { id, ...patch },
returnParam: { id: chain.id, title: chain.title },
@@ -237,7 +237,7 @@ export async function deleteChain(id: string): Promise<void> {
}
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-业务链条-删除",
optDetail: "CM助手-全量-业务链条-删除",
url: `${BASE()}/${id}`,
reqParam: { id },
});
@@ -48,7 +48,7 @@ export async function getDashboardSessionByTask(taskId: string): Promise<Dashboa
const session = toClient((await res.json()) as ServerDashboardSession);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-大屏会话-查看",
optDetail: "CM助手-全量-大屏会话-查看",
url: `${BASE()}/by-task/${taskId}`,
reqParam: { taskId },
returnParam: { taskId: session.taskId, updatedAt: session.updatedAt },
@@ -76,7 +76,7 @@ export async function putDashboardSessionByTask(
const session = toClient((await res.json()) as ServerDashboardSession);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-大屏会话-保存",
optDetail: "CM助手-全量-大屏会话-保存",
url: `${BASE()}/by-task/${taskId}`,
reqParam: { taskId, hasTranscript: patch.transcript !== undefined, hasReportJson: patch.reportJson !== undefined },
returnParam: { taskId: session.taskId, updatedAt: session.updatedAt },
@@ -325,7 +325,7 @@ export async function listDrafts(): Promise<DraftMeta[]> {
const metas = (data.drafts ?? []).map(toMeta);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-会商-查询草稿",
optDetail: "CM助手-全量-会商-查询草稿",
url: BASE(),
returnParam: { count: metas.length },
});
@@ -340,7 +340,7 @@ export async function getDraft(id: string): Promise<DraftRecord | null> {
const record = toRecord(data);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-会商-查看草稿",
optDetail: "CM助手-全量-会商-查看草稿",
url: `${BASE()}/${id}`,
reqParam: { id },
returnParam: { id: record.id, title: record.title },
@@ -358,7 +358,7 @@ export async function createDraft(payload: DraftCreatePayload): Promise<DraftRec
const record = toRecord(data);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-会商-新建草稿",
optDetail: "CM助手-全量-会商-新建草稿",
url: BASE(),
reqParam: { title: payload.title, furthestStep: payload.furthestStep, taskId: payload.taskId ?? null },
returnParam: { id: record.id, title: record.title },
@@ -377,7 +377,7 @@ export async function updateDraft(id: string, patch: DraftUpdatePayload): Promis
const record = toRecord(data);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-会商-更新草稿",
optDetail: "CM助手-全量-会商-更新草稿",
url: `${BASE()}/${id}`,
reqParam: { id, ...patch },
returnParam: { id: record.id, title: record.title },
@@ -393,7 +393,7 @@ export async function deleteDraft(id: string): Promise<void> {
}
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-会商-删除草稿",
optDetail: "CM助手-全量-会商-删除草稿",
url: `${BASE()}/${id}`,
reqParam: { id },
});
@@ -934,7 +934,7 @@ export async function listSessionArtifacts(
};
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-会商产物-查询",
optDetail: "CM助手-全量-会商产物-查询",
url: `/api/threads/${threadId}/artifacts`,
reqParam: { threadId },
returnParam: { count: result.files.length },
@@ -272,7 +272,7 @@ export async function listRecommendHistory(draftId: string): Promise<RecommendHi
const items = (data.history ?? []).map(toHistoryItem);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-席位推荐-查询历史",
optDetail: "CM助手-全量-席位推荐-查询历史",
url: `/api/roundtable-drafts/${draftId}/recommendations`,
reqParam: { draftId },
returnParam: { count: items.length },
@@ -308,7 +308,7 @@ export async function saveRecommendHistory(
const item = toHistoryItem((await res.json()) as ServerHistoryItem);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-席位推荐-保存历史",
optDetail: "CM助手-全量-席位推荐-保存历史",
url: `/api/roundtable-drafts/${draftId}/recommendations`,
reqParam: { draftId, status: payload.status, picks: payload.picks?.length ?? 0 },
returnParam: { id: item.id },
@@ -133,7 +133,7 @@ export async function startJob(payload: StartJobPayload): Promise<RoundtableJob>
const job = mapJob(await readJson<Record<string, unknown>>(res, "start job"));
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-会商-运行",
optDetail: "CM助手-全量-会商-运行",
url: BASE(),
reqParam: { draftId: payload.draftId ?? null, taskId: payload.taskId ?? null, model: payload.model },
returnParam: { id: job.id, status: job.status },
@@ -192,7 +192,7 @@ export async function resumeJob(jobId: string, answer: string, taskId?: string |
const job = mapJob(await readJson<Record<string, unknown>>(res, "resume job"));
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-会商-回答澄清续跑",
optDetail: "CM助手-全量-会商-回答澄清续跑",
url: `${BASE()}/${jobId}/resume`,
reqParam: { jobId, taskId: taskId ?? null },
returnParam: { id: job.id, status: job.status },
@@ -206,7 +206,7 @@ export async function cancelJob(jobId: string, taskId?: string | null): Promise<
const job = mapJob(await readJson<Record<string, unknown>>(res, "cancel job"));
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-会商-取消",
optDetail: "CM助手-全量-会商-取消",
url: `${BASE()}/${jobId}/cancel`,
reqParam: { jobId, taskId: taskId ?? null },
returnParam: { id: job.id, status: job.status },
@@ -37,7 +37,7 @@ export async function listTaskDraftsByTask(taskId: string): Promise<DraftMeta[]>
const metas = (data.drafts ?? []).map(toMeta);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-会商任务-查询草稿",
optDetail: "CM助手-全量-会商任务-查询草稿",
url: `${BASE()}/by-task/${taskId}`,
reqParam: { taskId },
returnParam: { count: metas.length },
@@ -53,7 +53,7 @@ export async function getLatestTaskDraftByTask(taskId: string): Promise<DraftRec
const record = toRecord(data);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-会商任务-查看最新草稿",
optDetail: "CM助手-全量-会商任务-查看最新草稿",
url: `${BASE()}/by-task/${taskId}/latest`,
reqParam: { taskId },
returnParam: { id: record.id, title: record.title },
@@ -69,7 +69,7 @@ export async function getTaskDraft(id: string): Promise<DraftRecord | null> {
const record = toRecord(data);
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-会商任务-查看草稿",
optDetail: "CM助手-全量-会商任务-查看草稿",
url: `${BASE()}/${id}`,
reqParam: { id },
returnParam: { id: record.id, title: record.title },
@@ -88,7 +88,7 @@ export async function createTaskDraft(payload: DraftCreatePayload): Promise<Draf
const record = toRecord(data);
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-会商任务-新建草稿",
optDetail: "CM助手-全量-会商任务-新建草稿",
url: BASE(),
reqParam: { taskId: payload.taskId ?? null, title: payload.title, furthestStep: payload.furthestStep },
returnParam: { id: record.id, title: record.title },
@@ -107,7 +107,7 @@ export async function updateTaskDraft(id: string, patch: DraftUpdatePayload): Pr
const record = toRecord(data);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-会商任务-更新草稿",
optDetail: "CM助手-全量-会商任务-更新草稿",
url: `${BASE()}/${id}`,
reqParam: { id, ...patch },
returnParam: { id: record.id, title: record.title },
@@ -123,7 +123,7 @@ export async function deleteTaskDraft(id: string): Promise<void> {
}
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-会商任务-删除草稿",
optDetail: "CM助手-全量-会商任务-删除草稿",
url: `${BASE()}/${id}`,
reqParam: { id },
});
@@ -67,7 +67,7 @@ export async function listBusinessMappings(): Promise<BusinessMapping[]> {
const mappings = (data.mappings ?? []).map(toMapping);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-业务映射-列表",
optDetail: "CM助手-全量-业务映射-列表",
url: "/api/business-mapping",
returnParam: mappings,
});
@@ -94,7 +94,7 @@ export async function updateBusinessMapping(
const mapping = toMapping(data);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-业务映射-修改",
optDetail: "CM助手-全量-业务映射-修改",
url: `${BASE()}/${encodeURIComponent(businessCode)}`,
reqParam: { businessCode, patch },
returnParam: mapping,
@@ -160,7 +160,7 @@ export async function listLightApps(params: ListLightAppsParams = {}): Promise<L
const apps = (data.apps ?? []).map(toApp);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-轻应用-列表",
optDetail: "CM助手-全量-轻应用-列表",
url: `${BASE()}${query ? `?${query}` : ""}`,
reqParam: params,
returnParam: apps,
@@ -173,7 +173,7 @@ export async function getLightApp(appId: string): Promise<LightApp> {
const app = toApp(await readJson<ServerApp>(res, "get light app"));
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-轻应用-查看",
optDetail: "CM助手-全量-轻应用-查看",
url: `${BASE()}/${encodeURIComponent(appId)}`,
reqParam: { appId },
returnParam: app,
@@ -190,7 +190,7 @@ export async function createLightApp(input: LightAppInput): Promise<LightApp> {
const app = toApp(await readJson<ServerApp>(res, "create light app"));
writeYLog({
optType: OptType.create,
optDetail: "B1-CM助手-轻应用-注册",
optDetail: "CM助手-全量-轻应用-注册",
url: BASE(),
reqParam: input,
returnParam: app,
@@ -210,7 +210,7 @@ export async function updateLightApp(
const app = toApp(await readJson<ServerApp>(res, "update light app"));
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-轻应用-修改",
optDetail: "CM助手-全量-轻应用-修改",
url: `${BASE()}/${encodeURIComponent(appId)}`,
reqParam: { appId, patch },
returnParam: app,
@@ -223,7 +223,7 @@ export async function deleteLightApp(appId: string): Promise<void> {
await readJson<{ success: boolean }>(res, "delete light app");
writeYLog({
optType: OptType.delete,
optDetail: "B1-CM助手-轻应用-删除",
optDetail: "CM助手-全量-轻应用-删除",
url: `${BASE()}/${encodeURIComponent(appId)}`,
reqParam: { appId },
});
@@ -71,7 +71,7 @@ export async function replaceMenuOverrides(overrides: MenuOverride[]): Promise<M
const saved = (data.overrides ?? []).map(toOverride);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-菜单管理-保存",
optDetail: "CM助手-全量-菜单管理-保存",
url: "/api/menu-overrides",
reqParam: { overrides },
returnParam: saved,
@@ -75,7 +75,7 @@ export async function listSensitiveWords(): Promise<SensitiveWord[]> {
const words = (data.words ?? []).map(toWord);
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-敏感词管理-列表",
optDetail: "CM助手-全量-敏感词管理-列表",
url: "/api/sensitive-words",
returnParam: words,
});
@@ -92,7 +92,7 @@ export async function replaceSensitiveWords(words: SensitiveWord[]): Promise<Sen
const saved = (data.words ?? []).map(toWord);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-敏感词管理-保存",
optDetail: "CM助手-全量-敏感词管理-保存",
url: "/api/sensitive-words",
reqParam: { words },
returnParam: saved,
@@ -201,7 +201,7 @@ export async function scanAddresses(kinds?: AddressKind[], skill?: string): Prom
const result = toScanResult(await readJson<any>(res, "扫描"));
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-技能地址管理-扫描",
optDetail: "CM助手-全量-技能地址管理-扫描",
url: `${BASE()}/scan${qs ? `?${qs}` : ""}`,
reqParam: { kinds, skill },
returnParam: result,
@@ -227,7 +227,7 @@ export async function scanAddressesStream(
if (!result) throw new Error("扫描未返回结果");
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-技能地址管理-扫描",
optDetail: "CM助手-全量-技能地址管理-扫描",
url: `${BASE()}/scan/stream${qs ? `?${qs}` : ""}`,
reqParam: { kinds: opts.kinds, skill: opts.skill },
returnParam: result,
@@ -245,7 +245,7 @@ export async function previewReplacements(replacements: Replacement[]): Promise<
const result = toPreviewResult(await readJson<any>(res, "预览"));
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-技能地址管理-预览",
optDetail: "CM助手-全量-技能地址管理-预览",
url: `${BASE()}/preview`,
reqParam: { replacements },
returnParam: result,
@@ -277,7 +277,7 @@ export async function applyReplacementsStream(
if (!result) throw new Error("应用未返回结果");
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-技能地址管理-应用替换",
optDetail: "CM助手-全量-技能地址管理-应用替换",
url: `${BASE()}/apply/stream`,
reqParam: body,
returnParam: result,
@@ -297,7 +297,7 @@ export async function listBackups(): Promise<BackupEntry[]> {
}));
writeYLog({
optType: OptType.search,
optDetail: "B1-CM助手-技能地址管理-修改记录",
optDetail: "CM助手-全量-技能地址管理-修改记录",
url: `${BASE()}/backups`,
returnParam: backups,
});
@@ -310,7 +310,7 @@ export async function rollbackBackup(backupId: string): Promise<{ restored: numb
const result = { restored: (data.restored_files ?? []).length };
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-技能地址管理-回退",
optDetail: "CM助手-全量-技能地址管理-回退",
url: `${BASE()}/rollback/${encodeURIComponent(backupId)}`,
reqParam: { backupId },
returnParam: result,
@@ -95,7 +95,7 @@ export async function replaceTaskButtons(buttons: TaskButton[]): Promise<TaskBut
const saved = (data.buttons ?? []).map(toButton);
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-按钮管理-保存",
optDetail: "CM助手-全量-按钮管理-保存",
url: "/api/task-buttons",
reqParam: { buttons },
returnParam: saved,