补齐拼消消作品可见性管理

接入后台作品可见性列表中的拼消消源类型

支持后台切换拼消消已发布作品 visible 状态

补充后台前端玩法标签与公开 ReadModel 文档说明
This commit is contained in:
2026-06-07 15:08:32 +08:00
parent 8131894bb5
commit 63444d047f
3 changed files with 64 additions and 1 deletions

View File

@@ -4,6 +4,7 @@ use module_custom_world::CustomWorldPublicationStatus;
use module_puzzle::PuzzlePublicationStatus;
const SOURCE_TYPE_PUZZLE: &str = "puzzle";
const SOURCE_TYPE_PUZZLE_CLEAR: &str = "puzzle-clear";
const SOURCE_TYPE_CUSTOM_WORLD: &str = "custom-world";
const SOURCE_TYPE_JUMP_HOP: &str = "jump-hop";
const SOURCE_TYPE_WOODEN_FISH: &str = "wooden-fish";
@@ -63,6 +64,7 @@ fn list_work_visibility_tx(
let mut entries = Vec::new();
entries.extend(list_puzzle_work_visibility(ctx));
entries.extend(list_puzzle_clear_work_visibility(ctx));
entries.extend(list_custom_world_work_visibility(ctx));
entries.extend(list_jump_hop_work_visibility(ctx));
entries.extend(list_wooden_fish_work_visibility(ctx));
@@ -85,6 +87,9 @@ fn update_work_visibility_tx(
match source_type.as_str() {
SOURCE_TYPE_PUZZLE => update_puzzle_work_visibility(ctx, &profile_id, input.visible),
SOURCE_TYPE_PUZZLE_CLEAR => {
update_puzzle_clear_work_visibility(ctx, &profile_id, input.visible)
}
SOURCE_TYPE_CUSTOM_WORLD => {
update_custom_world_work_visibility(ctx, &profile_id, input.visible)
}
@@ -167,6 +172,63 @@ fn puzzle_work_visibility_snapshot(row: &PuzzleWorkProfileRow) -> AdminWorkVisib
}
}
fn list_puzzle_clear_work_visibility(ctx: &ReducerContext) -> Vec<AdminWorkVisibilitySnapshot> {
ctx.db
.puzzle_clear_work_profile()
.by_puzzle_clear_work_publication_status()
.filter(PUZZLE_CLEAR_PUBLICATION_PUBLISHED)
.map(|row| puzzle_clear_work_visibility_snapshot(&row))
.collect()
}
fn update_puzzle_clear_work_visibility(
ctx: &ReducerContext,
profile_id: &str,
visible: bool,
) -> Result<AdminWorkVisibilitySnapshot, String> {
let row = ctx
.db
.puzzle_clear_work_profile()
.profile_id()
.find(&profile_id.to_string())
.ok_or_else(|| "拼消消作品不存在".to_string())?;
if row.publication_status != PUZZLE_CLEAR_PUBLICATION_PUBLISHED {
return Err("只能修改已发布拼消消作品可见性".to_string());
}
let next = PuzzleClearWorkProfileRow { visible, ..row };
let snapshot = puzzle_clear_work_visibility_snapshot(&next);
let profile_id = next.profile_id.clone();
ctx.db
.puzzle_clear_work_profile()
.profile_id()
.delete(&profile_id);
ctx.db.puzzle_clear_work_profile().insert(next);
Ok(snapshot)
}
fn puzzle_clear_work_visibility_snapshot(
row: &PuzzleClearWorkProfileRow,
) -> AdminWorkVisibilitySnapshot {
let sort_time = timestamp_sort_micros(row.published_at, row.updated_at);
AdminWorkVisibilitySnapshot {
source_type: SOURCE_TYPE_PUZZLE_CLEAR.to_string(),
work_id: row.work_id.clone(),
profile_id: row.profile_id.clone(),
source_session_id: Some(row.source_session_id.clone()).filter(|value| !value.is_empty()),
public_work_code: build_prefixed_public_work_code("PC", &row.profile_id),
owner_user_id: row.owner_user_id.clone(),
author_display_name: row.author_display_name.clone(),
title: choose_non_empty(&[row.work_title.as_str(), row.theme_prompt.as_str(), "拼消消"]),
subtitle: "拼消消".to_string(),
cover_image_src: Some(row.cover_image_src.clone()).filter(|value| !value.is_empty()),
visible: row.visible,
published_at_micros: row
.published_at
.map(|value| value.to_micros_since_unix_epoch()),
updated_at_micros: sort_time,
}
}
fn list_custom_world_work_visibility(ctx: &ReducerContext) -> Vec<AdminWorkVisibilitySnapshot> {
ctx.db
.custom_world_profile()