52 lines
5.5 KiB
Python
52 lines
5.5 KiB
Python
from pathlib import Path
|
||
root=Path('C:/kefu')
|
||
p=root/'wechat_rpa/knowledge_review.py';s=p.read_text(encoding='utf-8').replace(" db.execute('INSERT INTO knowledge_review_job", " db.execute(\"UPDATE knowledge_review_job SET status='expired' WHERE created_by=? AND status='preview'\", (actor,))\n db.execute('INSERT INTO knowledge_review_job")
|
||
s=s.replace("COALESCE(k.title,'知识已删除') title FROM knowledge_review_target", """COALESCE(k.title,'知识已删除') title,
|
||
COALESCE((SELECT id FROM desktop_accounts WHERE tenant_id=t.tenant_id LIMIT 1),0) account_id,
|
||
COALESCE((SELECT CASE WHEN nickname='' THEN zyt_sn ELSE nickname||'('||zyt_sn||')' END
|
||
FROM desktop_accounts WHERE tenant_id=t.tenant_id LIMIT 1),'旧版未归属数据') account_name FROM knowledge_review_target""")
|
||
p.write_text(s,encoding='utf-8',newline='\n')
|
||
p=root/'admin-web/apps/web-antd/src/api/knowledge.ts';s=p.read_text(encoding='utf-8');s+='''
|
||
|
||
export interface KnowledgeReviewJob {
|
||
id: string; account_id: number; scope_label: string; status: string; total: number; processed: number;
|
||
approved: number; skipped: number; error: string; created_at: string; progress_percent: number;
|
||
preview: { total: number; eligible: number; blocked: number; snapshot_at: string;
|
||
reasons: { code: string; reason: string; count: number }[];
|
||
accounts: { tenant_id: string; name: string; total: number; eligible: number }[] };
|
||
}
|
||
export interface KnowledgeReviewResult {
|
||
item_id: string; tenant_id: string; revision: number; result: string; reason: string; reason_text: string;
|
||
title: string; account_id: number; account_name: string;
|
||
}
|
||
export const previewKnowledgeReview = (accountId: number) =>
|
||
requestClient.post<KnowledgeReviewJob>(path('review-tasks/preview', accountId), {}, { timeout: 120000 });
|
||
export const fetchKnowledgeReviewJobs = (signal?: AbortSignal) =>
|
||
requestClient.get<{ items: KnowledgeReviewJob[] }>('/knowledge/review-tasks', { signal });
|
||
export const knowledgeReviewAction = (jobId: string, action: string, confirmed = false) =>
|
||
requestClient.post<KnowledgeReviewJob>(`/knowledge/review-tasks/${jobId}/${action}`, { confirmed });
|
||
export const fetchKnowledgeReviewResults = (jobId: string, result: string, page: number) =>
|
||
requestClient.get<{ items: KnowledgeReviewResult[]; total: number }>(`/knowledge/review-tasks/${jobId}/results`, { params: { result, page } });
|
||
''';p.write_text(s,encoding='utf-8',newline='\n')
|
||
p=root/'admin-web/apps/web-antd/src/views/knowledge/center.vue';s=p.read_text(encoding='utf-8')
|
||
s=s.replace('KnowledgeItem, KnowledgeJob,', 'KnowledgeItem, KnowledgeJob, KnowledgeReviewJob,')
|
||
s=s.replace('exportKnowledge, fetchKnowledgeItem,', 'exportKnowledge, fetchKnowledgeReviewJobs, fetchKnowledgeItem,')
|
||
s=s.replace("import KnowledgeBatchDialog from './batch-dialog.vue';", "import KnowledgeBatchDialog from './batch-dialog.vue';\nimport KnowledgeReviewAll from './review-all.vue';")
|
||
s=s.replace('const jobs = ref<KnowledgeJob[]>([]);', "const jobs = ref<KnowledgeJob[]>([]);\nconst reviewJobs = ref<KnowledgeReviewJob[]>([]);\nconst reviewOpen = ref(false);\nconst reviewTab = ref('new');\nfunction openFullReview(view: string) { reviewTab.value = view; reviewOpen.value = true; }\nasync function inspectReviewed(itemId: string, targetAccount: number) {\n reviewOpen.value = false; accountId.value = targetAccount;\n await accountChanged();\n if (accountId.value === targetAccount) await inspect(itemId);\n}")
|
||
s=s.replace('const [summary, entries, tasks, logs] = await Promise.all([', 'const [summary, entries, tasks, logs, reviews] = await Promise.all([')
|
||
s=s.replace("canTrace.value ? fetchKnowledgeTraces(id, signal) : Promise.resolve({ items: [] }),", "canTrace.value ? fetchKnowledgeTraces(id, signal) : Promise.resolve({ items: [] }),\n canReview.value ? fetchKnowledgeReviewJobs(signal) : Promise.resolve({ items: [] }),")
|
||
s=s.replace('return { summary, entries, tasks, logs };', 'return { summary, entries, tasks, logs, reviews };')
|
||
s=s.replace('jobs.value = data.tasks.items; traces.value', 'jobs.value = data.tasks.items; reviewJobs.value = data.reviews.items; traces.value')
|
||
s=s.replace("!jobs.value.some((j) => ['queued', 'running'].includes(j.status))", "![...jobs.value, ...reviewJobs.value].some((j) => ['queued', 'running'].includes(j.status))")
|
||
s=s.replace('busy || createOpen || batchOpen || configOpen', 'busy || createOpen || batchOpen || configOpen || reviewOpen')
|
||
s=s.replace("message=\"当前汇总全部授权账号。整理、审核、发布和测试前,请选择具体账号。\"", "message=\"当前汇总全部授权账号,可一键审核全部授权账号的草稿。整理聊天、单条编辑、发布和检索测试需选择具体账号。\"")
|
||
needle=' <Space v-if="single && (canReview || canPublish || canWrite)"'
|
||
assert needle in s;s=s.replace(needle, ''' <Space v-if="canReview" class="mb-4 flex" wrap>
|
||
<Button type="primary" :disabled="busy" @click="openFullReview('new')">{{ single ? '一键审核此账号全部草稿' : '一键审核全部授权账号' }}</Button>
|
||
<Button @click="openFullReview('jobs')">审核任务与结果</Button>
|
||
<Tag v-if="reviewJobs.some((job) => ['queued', 'running'].includes(job.status))" color="blue">后台审核进行中</Tag>
|
||
</Space>
|
||
'''+needle)
|
||
s=s.replace(' <KnowledgeBatchDialog ', ' <KnowledgeReviewAll v-model:open="reviewOpen" :account-id="accountId" :initial-tab="reviewTab" @changed="load" @inspect="inspectReviewed" />\n <KnowledgeBatchDialog ')
|
||
p.write_text(s,encoding='utf-8',newline='\n')
|