点赞和改造开关加入后台配置

This commit is contained in:
2026-06-10 14:36:56 +08:00
parent 9db467d23f
commit e29992cf01
33 changed files with 1644 additions and 380 deletions

View File

@@ -1193,6 +1193,9 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
object
.entry("event_banners_json".to_string())
.or_insert(serde_json::Value::Null);
object
.entry("public_work_interactions_json".to_string())
.or_insert(serde_json::Value::Null);
}
}
if table_name == "creation_entry_type_config" {

View File

@@ -26,6 +26,9 @@ pub struct CreationEntryConfig {
/// 底部加号创作入口页的多 banner JSON 配置,旧单条字段仅用于兼容。
#[default(None::<String>)]
pub(crate) event_banners_json: Option<String>,
/// 公开作品点赞 / 改造能力配置,旧库为空时由读取层按默认矩阵兜底。
#[default(None::<String>)]
pub(crate) public_work_interactions_json: Option<String>,
}
#[spacetimedb::table(
@@ -109,6 +112,26 @@ pub fn upsert_creation_entry_event_banners_config(
}
}
#[spacetimedb::procedure]
/// 后台保存公开作品点赞 / 改造能力配置的过程入口。
pub fn upsert_public_work_interaction_config(
ctx: &mut ProcedureContext,
input: PublicWorkInteractionConfigAdminUpsertInput,
) -> CreationEntryConfigProcedureResult {
match ctx.try_with_tx(|tx| upsert_public_work_interaction_config_in_tx(tx, input.clone())) {
Ok(record) => CreationEntryConfigProcedureResult {
ok: true,
record: Some(record),
error_message: None,
},
Err(message) => CreationEntryConfigProcedureResult {
ok: false,
record: None,
error_message: Some(message),
},
}
}
fn upsert_creation_entry_type_config_in_tx(
ctx: &ReducerContext,
input: CreationEntryTypeAdminUpsertInput,
@@ -171,6 +194,33 @@ fn upsert_creation_entry_event_banners_config_in_tx(
get_or_seed_creation_entry_config_snapshot(ctx)
}
/// 在事务内归一化公开作品互动配置 JSON 并更新全局入口配置表头。
fn upsert_public_work_interaction_config_in_tx(
ctx: &ReducerContext,
input: PublicWorkInteractionConfigAdminUpsertInput,
) -> Result<CreationEntryConfigSnapshot, String> {
seed_creation_entry_config_if_missing(ctx);
let now = ctx.timestamp;
let config_id = CREATION_ENTRY_CONFIG_GLOBAL_ID.to_string();
let Some(header) = ctx.db.creation_entry_config().config_id().find(&config_id) else {
return Err("创作入口配置初始化失败".to_string());
};
let public_work_interactions_json =
module_runtime::normalize_public_work_interaction_config_json(
&input.public_work_interactions_json,
)?;
ctx.db
.creation_entry_config()
.config_id()
.update(CreationEntryConfig {
updated_at: now,
public_work_interactions_json: Some(public_work_interactions_json),
..header
});
get_or_seed_creation_entry_config_snapshot(ctx)
}
fn get_or_seed_creation_entry_config_snapshot(
ctx: &ReducerContext,
) -> Result<CreationEntryConfigSnapshot, String> {
@@ -247,6 +297,7 @@ fn get_or_seed_creation_entry_config_snapshot(
event_banners_json: header.event_banners_json,
creation_types,
updated_at_micros: header.updated_at.to_micros_since_unix_epoch(),
public_work_interactions_json: header.public_work_interactions_json,
})
}
@@ -276,6 +327,9 @@ fn seed_creation_entry_config_if_missing(ctx: &ReducerContext) {
event_starts_at_text: Some(DEFAULT_CREATION_ENTRY_EVENT_STARTS_AT_TEXT.to_string()),
event_ends_at_text: Some(DEFAULT_CREATION_ENTRY_EVENT_ENDS_AT_TEXT.to_string()),
event_banners_json: Some(module_runtime::default_creation_entry_event_banners_json()),
public_work_interactions_json: Some(
module_runtime::default_public_work_interaction_config_json(),
),
});
}