用户发来 https://mp.weixin.qq.com/s/ZEOsi4R4JcmZ_mhS6qpcww,存进库的正文只有 67 个字符 ("原文链接 + 一个句号")。复盘发现公众号换了渲染方式:新版页面把整篇塞进 window.cgiDataNew 这个 JS 对象由前端渲染,页面里根本没有 id="js_content"; 三种 UA 拿到的字节数完全一样,也不是 UA 的问题。 - 从 JS 字符串字面量里读正文(content_noencode / desc),按 \xNN、\uNNNN 反转义, 话题标签是双重转义过的 HTML,先 unescape 再走 DOM。 - 配图字段排在文字之后,所以前后各找 2500 字符合图;剩下没用过的 mmbiz 图按 12 张上限补在末尾(图文型文章靠就近配对会漏)。 - 解析顺序:旧 DOM → 新版 JS 数据 → 通用抽取,一层层退。 实测两篇:2373 字符 + 12 张图、2772 字符 + 13 张图,作者也都取到了。 同时补上用户提的两件: - 知识能删了:DELETE /knowledge/{id}?confirm=true,软删 + 真删检索切片, 只有作者或 owner/admin 能删;列表卡片(悬停出现)和阅读页动作行各一个入口。 删完详情也回 7001,否则收藏的链接还能打开一篇已删除的知识。 - 分类下面有标签清单了:GET /knowledge/tags 按标签数"有多少条知识用了它", 侧栏渲染成 #标签 + 条数,点一下筛选、再点取消。
This commit is contained in:
@@ -11,7 +11,7 @@ import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { AppShell } from "../components/AppShell";
|
||||
import { AttachmentPanel } from "../components/AttachmentPanel";
|
||||
import { Markdown } from "../components/Markdown";
|
||||
import { ChevronLeft, Link2, Pencil } from "../components/icons";
|
||||
import { ChevronLeft, Link2, Pencil, Trash } from "../components/icons";
|
||||
import { Button, InlineAlert, SkeletonRows, StatusPill } from "../components/ui";
|
||||
import { ApiError, api } from "../lib/client";
|
||||
import { ACTION_LABEL, DOC_TYPE_LABEL, STATUS_LABEL, categoryColor } from "../lib/knowledge";
|
||||
@@ -92,6 +92,22 @@ export function KnowledgeDocPage() {
|
||||
|
||||
const status = doc?.knowledge.status_hint;
|
||||
const canEdit = status === "draft" || status === "in_review" || status === "published";
|
||||
|
||||
/** 删除:确认后回列表页。后端是软删,但界面按"没了"处理最不容易让人误会。 */
|
||||
async function remove() {
|
||||
if (!doc) return;
|
||||
if (!window.confirm(`删除「${doc.title}」?删了不会回来,检索里也会一起消失。`)) return;
|
||||
setBusy(true);
|
||||
setError(null);
|
||||
try {
|
||||
await api.del(`/workspaces/${wsId}/knowledge/${itemId}?confirm=true`);
|
||||
navigate(`/w/${wsId}/knowledge`, { replace: true });
|
||||
} catch (err) {
|
||||
setError(err instanceof ApiError ? err.message : "删除失败");
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
const actions: { key: string; label: string; show: boolean }[] = [
|
||||
{ key: "submit_review", label: ACTION_LABEL.submit_review, show: status === "draft" },
|
||||
{ key: "withdraw", label: ACTION_LABEL.withdraw, show: status === "in_review" },
|
||||
@@ -210,6 +226,11 @@ export function KnowledgeDocPage() {
|
||||
{a.label}
|
||||
</Button>
|
||||
))}
|
||||
{/* 删除放最后、用弱色 + 垃圾桶:它是不可逆的,不该和"发布"抢注意力 */}
|
||||
<Button variant="ghost" disabled={busy} className="ml-auto text-ink-400 hover:text-red-600" onClick={() => void remove()}>
|
||||
<Trash size={13} />
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
|
||||
Reference in New Issue
Block a user