feat(admin): 分组能力按类型收口(应用可分组,海报/图文平铺)

- 只有应用类分区显示分组管理与卡片预览分组;海报/图文保持平铺
- 后端 create_group 拒绝非应用分区;海报/图文读取时把历史分组条目一并平铺
- 侧栏不再显示非应用分组与空分组
- 类型 应用 ↔ 海报 切换时分组入口和侧栏子项随之出现/消失
- 测试 59 passed
This commit is contained in:
2026-10-30 19:55:45 +08:00
parent 1a4a6a3655
commit 261d202ce0
4 changed files with 111 additions and 39 deletions
+21 -13
View File
@@ -361,17 +361,22 @@ pub fn create_group(conn: &mut Connection, section_id: &str, new: NewGroup) -> R
return Err(StashError::InvalidDirectory("分组标题需为 1–40 个字".into()));
}
let section_exists: Option<String> = conn
let view_mode: Option<String> = conn
.query_row(
"SELECT key FROM node WHERE key = ?1 AND kind = 'section'",
"SELECT view_mode FROM node WHERE key = ?1 AND kind = 'section'",
[section_id],
|row| row.get(0),
)
.optional()
.map_err(map_error)?;
if section_exists.is_none() {
let Some(view_mode) = view_mode else {
return Err(StashError::NotFound(format!("分区不存在: {section_id}")));
};
if view_mode != "apps" {
return Err(StashError::InvalidDirectory(
"只有应用类分区可以添加分组".into(),
));
}
let exists: i64 = conn
@@ -707,18 +712,21 @@ mod tests {
}
#[test]
fn groups_under_any_kind_of_section() {
fn groups_only_under_apps_sections() {
let mut conn = db();
create(&mut conn, section("films", "电影", "posters")).expect("应能创建");
create_group(
&mut conn,
"films",
NewGroup {
id: "g1".into(),
title: "片单".into(),
},
)
.expect("海报分区也应能建分组");
assert!(
create_group(
&mut conn,
"films",
NewGroup {
id: "g1".into(),
title: "片单".into()
}
)
.is_err(),
"海报 / 图文分区不提供分组"
);
}
#[test]