diff --git a/server-rs/crates/api-server/src/tripo3d/pricing.rs b/server-rs/crates/api-server/src/tripo3d/pricing.rs index 547e75708..aa37995a3 100644 --- a/server-rs/crates/api-server/src/tripo3d/pricing.rs +++ b/server-rs/crates/api-server/src/tripo3d/pricing.rs @@ -146,6 +146,8 @@ pub(crate) enum Model3dPricingError { model_version: Model3dModelVersion, }, MissingAddOnPrice(Model3dAddOn), + /// `texture=false` 却带上贴图类加价项:组合自相矛盾,直接报错而不是照价收费。 + InconsistentTextureAddOn(Model3dAddOn), } impl std::fmt::Display for Model3dPricingError { @@ -164,6 +166,10 @@ impl std::fmt::Display for Model3dPricingError { Self::MissingAddOnPrice(add_on) => { write!(f, "Tripo 3D 定价缺少 add-on:{add_on:?}") } + Self::InconsistentTextureAddOn(add_on) => write!( + f, + "Tripo 3D 定价组合不合法:texture=false 与贴图类 add-on {add_on:?} 冲突" + ), } } } @@ -224,7 +230,18 @@ impl Model3dPricingConfig { } /// 查价:底价 + 命中的全部 add-on。缺键直接报错,不回退默认值。 + /// + /// `texture=false` 与贴图类 add-on 同时出现属于自相矛盾的组合,这里失败关闭: + /// 生产构造点([`model3d_add_ons`])已把贴图类加价项挂在 `texture` 上,构造不出该状态。 pub(crate) fn price(&self, query: &Model3dPricingQuery) -> Result { + if !query.texture + && let Some(add_on) = query.add_ons.iter().find(|add_on| { + matches!(add_on, Model3dAddOn::HdTexture | Model3dAddOn::UltraTexture) + }) + { + return Err(Model3dPricingError::InconsistentTextureAddOn(add_on)); + } + let base = self .base_prices .get(&query.endpoint) @@ -345,6 +362,30 @@ mod tests { ); } + #[test] + fn texture_add_ons_without_texture_are_rejected() { + let config = sample_config(); + let inconsistent = Model3dAddOnSet { + hd_texture: true, + ..Model3dAddOnSet::default() + }; + + assert_eq!( + config.price(&text_query(false, inconsistent)), + Err(Model3dPricingError::InconsistentTextureAddOn( + Model3dAddOn::HdTexture + )) + ); + + // texture=true 时同一个 add-on 集合是合法组合,价格按底价 + 加价项计算。 + assert_eq!( + config + .price(&text_query(true, inconsistent)) + .expect("带贴图时贴图加价项合法"), + 20 + 5 + ); + } + #[test] fn texture_quality_only_charges_detailed_and_extreme() { for (quality, expected) in [