两个都是"看着不对劲"的问题: 1. 侧栏把二级分类全堆在一级分类后面(按 depth 排序的副作用), 「技术」和它的上级「我的备忘」隔着十几行,看着像一棵假树。 后端改成按树的先序返回(父分类后紧跟它的子分类,兄弟仍按 sort_order、name), 前端照 depth 缩进就是个真树;二级以下再加一个「·」标记,小屏也分得清。 2. 点开已发布的知识只有「归档」,没有改的入口——因为后端原来硬性拒绝 修改已发布内容(7003)。但"发布"是给团队看的,写错了总要能改: 现在已发布的可以直接 PATCH,改完立刻重建检索切片(chunk_count 当场更新), 状态和版本号照常推进;归档的仍然要先「恢复成草稿」再改。 Web 与安卓同步:抽屉/详情里已发布也显示「编辑」,安卓分类标签区不再锁。 验证:pytest 95 passed(新增"分类按树返回"用例、发布后可改用例)、 ruff 全绿、tsc 0、vite build ✓;`knowledge-notebook.mjs` 17 项、 `knowledge.mjs` 9 项 e2e 全绿。安卓仍未编译(JDK 25 / Gradle 8.7 不兼容)。
This commit is contained in:
@@ -200,13 +200,18 @@ async def test_publish_requires_admin(client: AsyncClient) -> None:
|
||||
assert published["status"] == "published"
|
||||
assert published["knowledge"]["published_at"] is not None
|
||||
|
||||
# 已发布的内容不许直接改,先撤回
|
||||
blocked = await client.patch(
|
||||
f"{V1}/workspaces/{ws['id']}/knowledge/{doc['id']}",
|
||||
json={"title": "值班手册 v2", "version": published["version"]},
|
||||
headers=owner["headers"],
|
||||
# 已发布的能直接改正文:改完后端自动重建切片,状态仍是已发布
|
||||
edited = unwrap(
|
||||
await client.patch(
|
||||
f"{V1}/workspaces/{ws['id']}/knowledge/{doc['id']}",
|
||||
json={"title": "值班手册 v2", "version": published["version"]},
|
||||
headers=owner["headers"],
|
||||
)
|
||||
)
|
||||
assert blocked.json()["code"] == 7003
|
||||
assert edited["title"] == "值班手册 v2"
|
||||
assert edited["knowledge"]["status_hint"] == "published"
|
||||
assert edited["version"] == published["version"] + 1
|
||||
published = edited
|
||||
|
||||
archived = unwrap(
|
||||
await client.post(
|
||||
@@ -218,6 +223,14 @@ async def test_publish_requires_admin(client: AsyncClient) -> None:
|
||||
assert archived["status"] == "archived"
|
||||
assert archived["knowledge"]["archived_at"] is not None
|
||||
|
||||
# 归档是先收起来;要改先恢复成草稿,免得改完还挂着"现役"的样子
|
||||
blocked = await client.patch(
|
||||
f"{V1}/workspaces/{ws['id']}/knowledge/{doc['id']}",
|
||||
json={"title": "值班手册 v3", "version": archived["version"]},
|
||||
headers=owner["headers"],
|
||||
)
|
||||
assert blocked.json()["code"] == 7003
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_illegal_action_reports_allowed(client: AsyncClient) -> None:
|
||||
|
||||
@@ -303,3 +303,29 @@ async def test_patch_knowledge_accepts_doc_type_and_bumps_version(client: AsyncC
|
||||
assert patched["body_md"] == "改过的正文"
|
||||
assert patched["version"] == doc["version"] + 1
|
||||
assert {t["name"] for t in patched["tags"]} == {"写法"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_categories_come_back_as_a_tree(client: AsyncClient) -> None:
|
||||
"""列表按「父在前、子紧跟」排:前端照着 depth 缩进才像一棵树。
|
||||
|
||||
之前按 (depth, sort_order) 排,二级分类全堆在一级后面,
|
||||
侧栏看着像"所有一级在一起、所有二级在一起"。
|
||||
"""
|
||||
user, ws_id = await _ws(client)
|
||||
tech = await _category(client, user, ws_id, "技术开发")
|
||||
biz = await _category(client, user, ws_id, "餐饮业务")
|
||||
child = await _category(client, user, ws_id, "技术", tech["id"])
|
||||
await _category(client, user, ws_id, "部署", child["id"])
|
||||
assert biz["depth"] == 1
|
||||
|
||||
items = unwrap(
|
||||
await client.get(f"{V1}/workspaces/{ws_id}/knowledge/categories", headers=user["headers"])
|
||||
)["items"]
|
||||
assert [i["name"] for i in items] == ["技术开发", "技术", "部署", "餐饮业务"]
|
||||
assert [i["full_path"] for i in items] == [
|
||||
"技术开发",
|
||||
"技术开发 / 技术",
|
||||
"技术开发 / 技术 / 部署",
|
||||
"餐饮业务",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user