Prune stale docs and update .hermes content
Delete a large set of outdated documentation (many files under docs/ and .hermes/plans/, including audits, design, prd, technical, planning, assets, and todos). Update and consolidate .hermes content: refresh shared-memory pages (decision-log, development-workflow, document-map, pitfalls, project-overview, team-conventions) and several skills/references under .hermes/skills. Also modify AGENTS.md, README.md, UI_CODING_STANDARD.md, docs/README.md and .encoding-check-ignore. Purpose: clean up stale planning/audit material and keep current hermes documentation and related top-level docs in sync.
This commit is contained in:
@@ -81,6 +81,9 @@ pub fn resolve_creation_entry_route_id(path: &str) -> Option<&'static str> {
|
||||
if normalized.starts_with("/api/runtime/bark-battle") {
|
||||
return Some("bark-battle");
|
||||
}
|
||||
if normalized.starts_with("/api/creation/bark-battle") {
|
||||
return Some("bark-battle");
|
||||
}
|
||||
if normalized.starts_with("/api/runtime/square-hole") {
|
||||
return Some("square-hole");
|
||||
}
|
||||
@@ -156,6 +159,10 @@ mod tests {
|
||||
resolve_creation_entry_route_id("/api/runtime/bark-battle/works/work-1/config"),
|
||||
Some("bark-battle"),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_creation_entry_route_id("/api/creation/bark-battle/drafts"),
|
||||
Some("bark-battle"),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_creation_entry_route_id("/api/creation/edutainment/baby-object-match/assets"),
|
||||
Some("baby-object-match"),
|
||||
@@ -168,7 +175,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_creation_entry_config_response_keeps_baby_object_match_visible() {
|
||||
fn test_creation_entry_config_response_keeps_baby_object_match_coming_soon() {
|
||||
let config = test_creation_entry_config_response();
|
||||
let baby_object_match = config
|
||||
.creation_types
|
||||
@@ -178,7 +185,8 @@ mod tests {
|
||||
|
||||
assert_eq!(baby_object_match.title, "宝贝识物");
|
||||
assert!(baby_object_match.visible);
|
||||
assert!(baby_object_match.open);
|
||||
assert!(!baby_object_match.open);
|
||||
assert_eq!(baby_object_match.badge, "敬请期待");
|
||||
assert_eq!(baby_object_match.sort_order, 90);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,9 @@ const MATCH3D_OSS_PUT_TIMEOUT_MS: u64 = 3 * 60_000;
|
||||
const MATCH3D_LEGACY_MODEL_MAX_BYTES: usize = 120 * 1024 * 1024;
|
||||
const MATCH3D_ITEM_IMAGE_MAX_BYTES: usize = 20 * 1024 * 1024;
|
||||
const MATCH3D_WORK_METADATA_LLM_MODEL: &str = "gpt-4o";
|
||||
const MATCH3D_ITEM_SIZE_LARGE: &str = "大";
|
||||
const MATCH3D_ITEM_SIZE_MEDIUM: &str = "中";
|
||||
const MATCH3D_ITEM_SIZE_SMALL: &str = "小";
|
||||
const MATCH3D_CONTAINER_REFERENCE_IMAGE_PATH: &str =
|
||||
"public/match3d-background-references/pot-fused-reference.png";
|
||||
const MATCH3D_QUESTION_THEME: &str = "你想创作什么题材";
|
||||
@@ -136,6 +139,7 @@ struct Match3DConfigJson {
|
||||
struct Match3DGeneratedItemAsset {
|
||||
item_id: String,
|
||||
item_name: String,
|
||||
item_size: Option<String>,
|
||||
image_src: Option<String>,
|
||||
image_object_key: Option<String>,
|
||||
image_views: Vec<Match3DGeneratedItemImageView>,
|
||||
@@ -195,6 +199,7 @@ struct Match3DGeneratedWorkMetadata {
|
||||
#[derive(Clone, Debug)]
|
||||
struct Match3DGeneratedItemPlan {
|
||||
name: String,
|
||||
item_size: String,
|
||||
sound_prompt: String,
|
||||
}
|
||||
|
||||
@@ -211,6 +216,8 @@ struct Match3DGeneratedItemAssetJson {
|
||||
item_id: String,
|
||||
item_name: String,
|
||||
#[serde(default)]
|
||||
item_size: Option<String>,
|
||||
#[serde(default)]
|
||||
image_src: Option<String>,
|
||||
#[serde(default)]
|
||||
image_object_key: Option<String>,
|
||||
@@ -920,6 +927,10 @@ pub async fn persist_match3d_generated_model(
|
||||
let next_asset = Match3DGeneratedItemAsset {
|
||||
item_id: payload.item_id,
|
||||
item_name,
|
||||
item_size: current_asset
|
||||
.as_ref()
|
||||
.and_then(|asset| asset.item_size.clone())
|
||||
.or_else(|| Some(MATCH3D_ITEM_SIZE_LARGE.to_string())),
|
||||
image_src: current_asset
|
||||
.as_ref()
|
||||
.and_then(|asset| asset.image_src.clone()),
|
||||
@@ -1343,7 +1354,7 @@ pub async fn generate_match3d_item_assets_for_work(
|
||||
item: map_match3d_work_profile_response(profile),
|
||||
generated_item_assets: sort_match3d_generated_assets(assets)
|
||||
.into_iter()
|
||||
.map(Match3DGeneratedItemAssetJson::from)
|
||||
.map(Match3DGeneratedItemAssetJson::from)
|
||||
.map(map_match3d_generated_item_asset_for_work)
|
||||
.collect(),
|
||||
},
|
||||
@@ -2456,6 +2467,7 @@ fn map_match3d_generated_item_asset_for_agent(
|
||||
Match3DAgentGeneratedItemAssetResponse {
|
||||
item_id: asset.item_id,
|
||||
item_name: asset.item_name,
|
||||
item_size: asset.item_size,
|
||||
image_src: asset.image_src,
|
||||
image_object_key: asset.image_object_key,
|
||||
image_views: asset
|
||||
@@ -2488,6 +2500,7 @@ fn map_match3d_generated_item_asset_for_work(
|
||||
shared_contracts::match3d_works::Match3DGeneratedItemAssetResponse {
|
||||
item_id: asset.item_id,
|
||||
item_name: asset.item_name,
|
||||
item_size: asset.item_size.or_else(|| Some(MATCH3D_ITEM_SIZE_LARGE.to_string())),
|
||||
image_src: asset.image_src,
|
||||
image_object_key: asset.image_object_key,
|
||||
image_views: asset
|
||||
@@ -3222,6 +3235,7 @@ impl From<Match3DGeneratedItemAsset> for Match3DGeneratedItemAssetJson {
|
||||
Self {
|
||||
item_id: asset.item_id,
|
||||
item_name: asset.item_name,
|
||||
item_size: asset.item_size,
|
||||
image_src: asset.image_src,
|
||||
image_object_key: asset.image_object_key,
|
||||
image_views: asset.image_views,
|
||||
@@ -3248,6 +3262,7 @@ impl From<Match3DGeneratedItemAssetJson> for Match3DGeneratedItemAsset {
|
||||
Self {
|
||||
item_id: asset.item_id,
|
||||
item_name: asset.item_name,
|
||||
item_size: asset.item_size.or_else(|| Some(MATCH3D_ITEM_SIZE_LARGE.to_string())),
|
||||
image_src: asset.image_src,
|
||||
image_object_key: asset.image_object_key,
|
||||
image_views: asset.image_views,
|
||||
@@ -3276,6 +3291,7 @@ impl From<shared_contracts::match3d_works::Match3DGeneratedItemAssetResponse>
|
||||
Self {
|
||||
item_id: asset.item_id,
|
||||
item_name: asset.item_name,
|
||||
item_size: asset.item_size,
|
||||
image_src: asset.image_src,
|
||||
image_object_key: asset.image_object_key,
|
||||
image_views: asset
|
||||
@@ -3401,6 +3417,7 @@ async fn ensure_match3d_item_image_assets(
|
||||
Some(Match3DItemImageGenerationSeed {
|
||||
item_id,
|
||||
item_name: item.name.clone(),
|
||||
item_size: item.item_size.clone(),
|
||||
sound_prompt: item.sound_prompt.clone(),
|
||||
persist_asset: true,
|
||||
background_music_title: None,
|
||||
@@ -3454,6 +3471,7 @@ async fn ensure_match3d_item_image_assets(
|
||||
struct Match3DItemImageGenerationSeed {
|
||||
item_id: String,
|
||||
item_name: String,
|
||||
item_size: String,
|
||||
sound_prompt: String,
|
||||
persist_asset: bool,
|
||||
background_music_title: Option<String>,
|
||||
@@ -3580,6 +3598,9 @@ async fn generate_match3d_item_image_assets_in_batches(
|
||||
asset: Match3DGeneratedItemAsset {
|
||||
item_id: seed.item_id,
|
||||
item_name: seed.item_name,
|
||||
item_size: Some(normalize_match3d_item_size(seed.item_size.as_str()))
|
||||
.filter(|value| !value.is_empty())
|
||||
.or_else(|| Some(MATCH3D_ITEM_SIZE_LARGE.to_string())),
|
||||
image_src: primary_view
|
||||
.as_ref()
|
||||
.and_then(|view| view.image_src.clone()),
|
||||
@@ -3685,6 +3706,7 @@ async fn append_match3d_new_item_assets(
|
||||
let item_id = allocate_match3d_generated_item_id(&assets, &mut next_item_index);
|
||||
Match3DItemImageGenerationSeed {
|
||||
item_id,
|
||||
item_size: infer_match3d_item_size(item_name.as_str()),
|
||||
sound_prompt: build_fallback_match3d_item_sound_prompt(config, item_name.as_str()),
|
||||
item_name,
|
||||
persist_asset: index < requested_item_count,
|
||||
@@ -3766,6 +3788,12 @@ async fn replace_match3d_item_assets(
|
||||
});
|
||||
Match3DItemImageGenerationSeed {
|
||||
item_id,
|
||||
item_size: matched_asset
|
||||
.as_ref()
|
||||
.and_then(|asset| asset.item_size.clone())
|
||||
.map(|value| normalize_match3d_item_size(value.as_str()))
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_else(|| infer_match3d_item_size(item_name.as_str())),
|
||||
sound_prompt: matched_asset
|
||||
.as_ref()
|
||||
.and_then(|asset| asset.sound_prompt.clone())
|
||||
@@ -3857,7 +3885,7 @@ async fn generate_match3d_draft_plan(
|
||||
let gameplay_item_count = resolve_match3d_gameplay_item_count(config);
|
||||
let generated_item_count = resolve_match3d_generated_item_count(config);
|
||||
let user_prompt = format!(
|
||||
"题材设定:{}\n请生成抓大鹅游戏草稿生成计划。要求:只返回 JSON 对象,字段为 gameName、summary、tags、backgroundPrompt、items。gameName 为 4 到 12 个中文字符,不要包含“作品”“游戏”;summary 为 18 到 48 个中文字符的作品描述,说明题材氛围和核心体验,不要写规则说明;tags 为 3 到 6 个中文短标签,每个 2 到 6 个汉字,后续会用同一作品信息再次生成作品标签;backgroundPrompt 是用于生成局内纯背景图的中文提示词,只描述竖屏移动端抓大鹅题材氛围、色彩和环境,不得描述锅、圆盘、托盘、拼图槽、物品槽、HUD、UI、文字、按钮、倒计时、分数或物品;当前玩法需要 {} 种物品,但素材图固定每 5 个物品一批,因此 items 必须向上补齐并正好返回 {} 项,每项包含 name 和 soundPrompt,name 为 2 到 6 个汉字,soundPrompt 只作为历史字段保留,可返回空字符串。",
|
||||
"题材设定:{}\n请生成抓大鹅游戏草稿生成计划。要求:只返回 JSON 对象,字段为 gameName、summary、tags、backgroundPrompt、items。gameName 为 4 到 12 个中文字符,不要包含“作品”“游戏”;summary 为 18 到 48 个中文字符的作品描述,说明题材氛围和核心体验,不要写规则说明;tags 为 3 到 6 个中文短标签,每个 2 到 6 个汉字,后续会用同一作品信息再次生成作品标签;backgroundPrompt 是用于生成局内纯背景图的中文提示词,只描述竖屏移动端抓大鹅题材氛围、色彩和环境,不得描述锅、圆盘、托盘、拼图槽、物品槽、HUD、UI、文字、按钮、倒计时、分数或物品;当前玩法需要 {} 种物品,但素材图固定每 5 个物品一批,因此 items 必须向上补齐并正好返回 {} 项,每项包含 name、itemSize 和 soundPrompt。name 为 2 到 6 个汉字;itemSize 只能是“大”“中”“小”之一,按物品真实相对尺寸判断,例如西瓜/大箱子偏大,苹果/杯子偏中,糖果/钥匙偏小;soundPrompt 只作为历史字段保留,可返回空字符串。",
|
||||
config.theme_text, gameplay_item_count, generated_item_count
|
||||
);
|
||||
let response = llm_client
|
||||
@@ -3931,6 +3959,14 @@ fn parse_match3d_draft_plan(
|
||||
if name.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let item_size = item
|
||||
.get("itemSize")
|
||||
.or_else(|| item.get("item_size"))
|
||||
.or_else(|| item.get("size"))
|
||||
.and_then(Value::as_str)
|
||||
.map(normalize_match3d_item_size)
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_else(|| infer_match3d_item_size(&name));
|
||||
let sound_prompt = item
|
||||
.get("soundPrompt")
|
||||
.or_else(|| item.get("sound_prompt"))
|
||||
@@ -3938,7 +3974,11 @@ fn parse_match3d_draft_plan(
|
||||
.map(normalize_match3d_audio_prompt)
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_else(|| build_fallback_match3d_item_sound_prompt(config, &name));
|
||||
Some(Match3DGeneratedItemPlan { name, sound_prompt })
|
||||
Some(Match3DGeneratedItemPlan {
|
||||
name,
|
||||
item_size,
|
||||
sound_prompt,
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
@@ -4020,6 +4060,7 @@ fn fallback_match3d_draft_plan(config: &Match3DConfigJson) -> Match3DGeneratedDr
|
||||
.into_iter()
|
||||
.take(resolve_match3d_generated_item_count(config))
|
||||
.map(|name| Match3DGeneratedItemPlan {
|
||||
item_size: infer_match3d_item_size(&name),
|
||||
sound_prompt: build_fallback_match3d_item_sound_prompt(config, &name),
|
||||
name,
|
||||
})
|
||||
@@ -4042,6 +4083,36 @@ fn normalize_match3d_item_name(raw: &str) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn normalize_match3d_item_size(raw: &str) -> String {
|
||||
let normalized = raw.trim().trim_matches(['"', '\'', '“', '”', '。', ',', ',', '、']);
|
||||
match normalized {
|
||||
"大" | "大型" | "偏大" | "large" | "Large" | "L" | "l" => MATCH3D_ITEM_SIZE_LARGE.to_string(),
|
||||
"中" | "中型" | "中等" | "medium" | "Medium" | "M" | "m" => MATCH3D_ITEM_SIZE_MEDIUM.to_string(),
|
||||
"小" | "小型" | "偏小" | "small" | "Small" | "S" | "s" => MATCH3D_ITEM_SIZE_SMALL.to_string(),
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_match3d_item_size(item_name: &str) -> String {
|
||||
let name = item_name.trim();
|
||||
let large_keywords = [
|
||||
"西瓜", "南瓜", "椰子", "箱", "盒", "桶", "盆", "锅", "坛", "瓶子", "大瓶", "包",
|
||||
"书包", "枕", "抱枕", "玩偶", "球", "圆球", "足球", "篮球", "鼓",
|
||||
];
|
||||
if large_keywords.iter().any(|keyword| name.contains(keyword)) {
|
||||
return MATCH3D_ITEM_SIZE_LARGE.to_string();
|
||||
}
|
||||
let small_keywords = [
|
||||
"草莓", "蓝莓", "葡萄", "樱桃", "莓", "糖", "糖果", "钥匙", "硬币", "纽扣", "徽章",
|
||||
"戒指", "耳环", "铃铛", "星星", "宝石", "叶片", "花瓣", "蘑菇", "贝壳", "印章",
|
||||
"彩蛋", "棋子", "骰子", "挂件",
|
||||
];
|
||||
if small_keywords.iter().any(|keyword| name.contains(keyword)) {
|
||||
return MATCH3D_ITEM_SIZE_SMALL.to_string();
|
||||
}
|
||||
MATCH3D_ITEM_SIZE_MEDIUM.to_string()
|
||||
}
|
||||
|
||||
fn fallback_match3d_item_names(theme_text: &str) -> Vec<String> {
|
||||
let theme = theme_text.trim();
|
||||
let normalized_theme = if theme.is_empty() { "主题" } else { theme };
|
||||
@@ -4094,7 +4165,13 @@ fn normalize_match3d_item_plan(
|
||||
continue;
|
||||
}
|
||||
let sound_prompt = normalize_match3d_audio_prompt(item.sound_prompt.as_str());
|
||||
let item_size = normalize_match3d_item_size(item.item_size.as_str());
|
||||
normalized.push(Match3DGeneratedItemPlan {
|
||||
item_size: if item_size.is_empty() {
|
||||
infer_match3d_item_size(&name)
|
||||
} else {
|
||||
item_size
|
||||
},
|
||||
sound_prompt: if sound_prompt.is_empty() {
|
||||
build_fallback_match3d_item_sound_prompt(config, &name)
|
||||
} else {
|
||||
@@ -4113,6 +4190,7 @@ fn normalize_match3d_item_plan(
|
||||
continue;
|
||||
}
|
||||
normalized.push(Match3DGeneratedItemPlan {
|
||||
item_size: infer_match3d_item_size(&name),
|
||||
sound_prompt: build_fallback_match3d_item_sound_prompt(config, &name),
|
||||
name,
|
||||
});
|
||||
@@ -4149,6 +4227,7 @@ fn fill_match3d_item_plan_to_count(
|
||||
.any(|candidate: &Match3DGeneratedItemPlan| candidate.name == name)
|
||||
{
|
||||
normalized.push(Match3DGeneratedItemPlan {
|
||||
item_size: infer_match3d_item_size(&name),
|
||||
sound_prompt: build_fallback_match3d_item_sound_prompt(config, &name),
|
||||
name,
|
||||
});
|
||||
@@ -4488,6 +4567,10 @@ fn merge_regenerated_match3d_item_asset(
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: current_asset.item_id,
|
||||
item_name: current_asset.item_name,
|
||||
item_size: current_asset
|
||||
.item_size
|
||||
.or(generated_asset.item_size)
|
||||
.or_else(|| Some(MATCH3D_ITEM_SIZE_LARGE.to_string())),
|
||||
image_src: generated_asset.image_src,
|
||||
image_object_key: generated_asset.image_object_key,
|
||||
image_views: generated_asset.image_views,
|
||||
@@ -7092,6 +7175,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: format!("match3d-item-{index}"),
|
||||
item_name: name.to_string(),
|
||||
item_size: Some(infer_match3d_item_size(name)),
|
||||
image_src: Some(format!(
|
||||
"/generated-match3d-assets/s/p/items/i{index}/views/view-01.png"
|
||||
)),
|
||||
@@ -7592,9 +7676,33 @@ mod tests {
|
||||
);
|
||||
assert!(plan.background_prompt.contains("纯背景"));
|
||||
assert_eq!(plan.items[0].name, "草莓");
|
||||
assert_eq!(plan.items[0].item_size, MATCH3D_ITEM_SIZE_SMALL);
|
||||
assert!(plan.items[0].sound_prompt.contains("草莓"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_draft_plan_parses_relative_item_sizes() {
|
||||
let plan = parse_match3d_draft_plan(
|
||||
r#"{"gameName":"果园大鹅宴","summary":"果园小物堆满浅盘,轻快明亮适合随手消除。","tags":["水果","抓大鹅"],"backgroundPrompt":"果园主题竖屏纯背景","items":[{"name":"西瓜","itemSize":"大","soundPrompt":""},{"name":"苹果","itemSize":"中","soundPrompt":""},{"name":"糖果","itemSize":"小","soundPrompt":""}]}"#,
|
||||
&config("水果", 3, 3),
|
||||
)
|
||||
.expect("draft plan should parse");
|
||||
|
||||
assert_eq!(plan.items[0].item_size, MATCH3D_ITEM_SIZE_LARGE);
|
||||
assert_eq!(plan.items[1].item_size, MATCH3D_ITEM_SIZE_MEDIUM);
|
||||
assert_eq!(plan.items[2].item_size, MATCH3D_ITEM_SIZE_SMALL);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_legacy_item_asset_without_size_defaults_to_large() {
|
||||
let assets = parse_match3d_generated_item_assets(Some(
|
||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","status":"image_ready"}]"#,
|
||||
));
|
||||
let asset = Match3DGeneratedItemAsset::from(assets[0].clone());
|
||||
|
||||
assert_eq!(asset.item_size.as_deref(), Some(MATCH3D_ITEM_SIZE_LARGE));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_draft_item_plan_rounds_up_to_full_five_item_sheets() {
|
||||
let plan = parse_match3d_draft_plan(
|
||||
@@ -7642,6 +7750,7 @@ mod tests {
|
||||
let existing_assets = vec![Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
item_name: "草莓".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_SMALL.to_string()),
|
||||
image_src: None,
|
||||
image_object_key: None,
|
||||
image_views: Vec::new(),
|
||||
@@ -7686,6 +7795,7 @@ mod tests {
|
||||
.map(|index| Match3DGeneratedItemAsset {
|
||||
item_id: format!("match3d-item-{index}"),
|
||||
item_name: format!("已有物品{index}"),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_LARGE.to_string()),
|
||||
image_src: None,
|
||||
image_object_key: None,
|
||||
image_views: Vec::new(),
|
||||
@@ -7977,6 +8087,7 @@ mod tests {
|
||||
let assets = vec![Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
item_name: "草莓".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_SMALL.to_string()),
|
||||
image_src: None,
|
||||
image_object_key: None,
|
||||
image_views: Vec::new(),
|
||||
@@ -8078,6 +8189,7 @@ mod tests {
|
||||
let assets = vec![Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
item_name: "草莓".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_SMALL.to_string()),
|
||||
image_src: None,
|
||||
image_object_key: None,
|
||||
image_views: Vec::new(),
|
||||
@@ -8223,6 +8335,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-2".to_string(),
|
||||
item_name: "苹果".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_MEDIUM.to_string()),
|
||||
image_src: Some("/generated-match3d-assets/s/p/items/i2/image.png".to_string()),
|
||||
image_object_key: Some(
|
||||
"generated-match3d-assets/s/p/items/i2/image.png".to_string(),
|
||||
@@ -8250,6 +8363,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
item_name: "草莓".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_SMALL.to_string()),
|
||||
image_src: Some("/generated-match3d-assets/s/p/items/i1/image.png".to_string()),
|
||||
image_object_key: Some(
|
||||
"generated-match3d-assets/s/p/items/i1/image.png".to_string(),
|
||||
@@ -8282,6 +8396,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
item_name: "草莓".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_SMALL.to_string()),
|
||||
image_src: Some("/generated-match3d-assets/s/p/items/i1/image.png".to_string()),
|
||||
image_object_key: Some(
|
||||
"generated-match3d-assets/s/p/items/i1/image.png".to_string(),
|
||||
@@ -8305,6 +8420,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-2".to_string(),
|
||||
item_name: "苹果".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_MEDIUM.to_string()),
|
||||
image_src: Some("/generated-match3d-assets/s/p/items/i2/image.png".to_string()),
|
||||
image_object_key: Some(
|
||||
"generated-match3d-assets/s/p/items/i2/image.png".to_string(),
|
||||
@@ -8328,6 +8444,7 @@ mod tests {
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-3".to_string(),
|
||||
item_name: "香蕉".to_string(),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_MEDIUM.to_string()),
|
||||
image_src: Some("/generated-match3d-assets/s/p/items/i3/image.png".to_string()),
|
||||
image_object_key: None,
|
||||
image_views: Vec::new(),
|
||||
@@ -8354,6 +8471,7 @@ mod tests {
|
||||
.map(|index| Match3DGeneratedItemAsset {
|
||||
item_id: format!("match3d-item-{index}"),
|
||||
item_name: format!("物品{index}"),
|
||||
item_size: Some(MATCH3D_ITEM_SIZE_LARGE.to_string()),
|
||||
image_src: Some(format!(
|
||||
"/generated-match3d-assets/s/p/items/i{index}/views/view-01.png"
|
||||
)),
|
||||
|
||||
Reference in New Issue
Block a user