点赞和改造开关加入后台配置
This commit is contained in:
@@ -17,6 +17,21 @@ use crate::{
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum PublicWorkInteractionAction {
|
||||
Like,
|
||||
Remix,
|
||||
}
|
||||
|
||||
impl PublicWorkInteractionAction {
|
||||
fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::Like => "like",
|
||||
Self::Remix => "remix",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 中文注释:入口配置由 SpacetimeDB 表提供;api-server 只负责读取同一份配置并熔断运行态路由。
|
||||
pub async fn get_creation_entry_config_handler(
|
||||
State(state): State<AppState>,
|
||||
@@ -71,6 +86,68 @@ pub async fn require_creation_entry_route_enabled(
|
||||
next.run(request).await
|
||||
}
|
||||
|
||||
/// 中文注释:公开作品互动配置只拦点赞 / 改造动作,不影响作品详情读取和正式游玩。
|
||||
pub async fn require_public_work_interaction_enabled(
|
||||
State(state): State<AppState>,
|
||||
request: Request<Body>,
|
||||
next: Next,
|
||||
) -> Response {
|
||||
let path = request.uri().path();
|
||||
if let Some((source_type, action)) = resolve_public_work_interaction_route(path) {
|
||||
match state
|
||||
.is_public_work_interaction_enabled(source_type, action)
|
||||
.await
|
||||
{
|
||||
Ok(true) => {}
|
||||
Ok(false) => {
|
||||
return AppError::from_status(StatusCode::SERVICE_UNAVAILABLE)
|
||||
.with_message("该作品互动暂不可用")
|
||||
.with_details(json!({
|
||||
"reason": "public_work_interaction_disabled",
|
||||
"sourceType": source_type,
|
||||
"action": action.as_str(),
|
||||
}))
|
||||
.into();
|
||||
}
|
||||
Err(error) => {
|
||||
return AppError::from_status(StatusCode::BAD_GATEWAY)
|
||||
.with_message("读取作品互动配置失败")
|
||||
.with_details(json!({
|
||||
"provider": "spacetimedb",
|
||||
"message": error.to_string(),
|
||||
}))
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next.run(request).await
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_public_work_interaction_route(
|
||||
path: &str,
|
||||
) -> Option<(&'static str, PublicWorkInteractionAction)> {
|
||||
let action = if path.ends_with("/like") {
|
||||
PublicWorkInteractionAction::Like
|
||||
} else if path.ends_with("/remix") {
|
||||
PublicWorkInteractionAction::Remix
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if path.starts_with("/api/runtime/custom-world-gallery/") {
|
||||
return Some(("custom-world", action));
|
||||
}
|
||||
if path.starts_with("/api/runtime/big-fish/gallery/") {
|
||||
return Some(("big-fish", action));
|
||||
}
|
||||
if path.starts_with("/api/runtime/puzzle/gallery/") {
|
||||
return Some(("puzzle", action));
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_creation_entry_mud_point_cost_from_config(
|
||||
config: &CreationEntryConfigResponse,
|
||||
creation_type_id: &str,
|
||||
@@ -142,6 +219,9 @@ pub(crate) fn default_creation_entry_config_response() -> CreationEntryConfigRes
|
||||
event_banners_json: Some(module_runtime::default_creation_entry_event_banners_json()),
|
||||
creation_types: module_runtime::default_creation_entry_type_snapshots(0),
|
||||
updated_at_micros: 0,
|
||||
public_work_interactions_json: Some(
|
||||
module_runtime::default_public_work_interaction_config_json(),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -242,6 +322,28 @@ mod tests {
|
||||
assert_eq!(resolve_creation_entry_route_id("/healthz"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_public_work_interaction_routes() {
|
||||
assert_eq!(
|
||||
resolve_public_work_interaction_route("/api/runtime/puzzle/gallery/profile-1/like"),
|
||||
Some(("puzzle", PublicWorkInteractionAction::Like)),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_public_work_interaction_route(
|
||||
"/api/runtime/custom-world-gallery/user-1/profile-1/remix"
|
||||
),
|
||||
Some(("custom-world", PublicWorkInteractionAction::Remix)),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_public_work_interaction_route("/api/runtime/puzzle/gallery/profile-1"),
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_public_work_interaction_route("/api/runtime/wooden-fish/runs/run-1"),
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_mud_point_cost_from_unified_creation_spec() {
|
||||
let mut config = test_creation_entry_config_response();
|
||||
|
||||
Reference in New Issue
Block a user