|
@@ -138,6 +138,29 @@ def _parse_tier_key(key: str):
|
|
|
return None
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _normalize_price_label(label: str) -> str:
|
|
|
|
|
+ text = (label or "").strip().lower()
|
|
|
|
|
+ if not text:
|
|
|
|
|
+ return label
|
|
|
|
|
+
|
|
|
|
|
+ text = text.replace("(", "(").replace(")", ")")
|
|
|
|
|
+ if text in {"输入", "input"}:
|
|
|
|
|
+ return "input"
|
|
|
|
|
+ if text in {"输出", "output"}:
|
|
|
|
|
+ return "output"
|
|
|
|
|
+ if ("输入" in text or "input" in text) and "缓存命中" in text:
|
|
|
|
|
+ return "input_cache_hit"
|
|
|
|
|
+ if ("输入" in text or "input" in text) and "batch file" in text:
|
|
|
|
|
+ return "input_batch"
|
|
|
|
|
+ if ("输出" in text or "output" in text) and "batch file" in text:
|
|
|
|
|
+ return "output_batch"
|
|
|
|
|
+ if "显式缓存创建" in text:
|
|
|
|
|
+ return "explicit_cache_create"
|
|
|
|
|
+ if "显式缓存命中" in text:
|
|
|
|
|
+ return "explicit_cache_hit"
|
|
|
|
|
+ return label
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def _extract_video_spec(label: str) -> Optional[str]:
|
|
def _extract_video_spec(label: str) -> Optional[str]:
|
|
|
"""从 label 中提取视频规格,如 '视频生成(720P)' -> '720P'。"""
|
|
"""从 label 中提取视频规格,如 '视频生成(720P)' -> '720P'。"""
|
|
|
m = re.search(r"[((]([^))]+)[))]", label)
|
|
m = re.search(r"[((]([^))]+)[))]", label)
|
|
@@ -184,8 +207,6 @@ def parse_prices(prices: Dict[str, Any]) -> List[Dict]:
|
|
|
video_items: List[Dict] = []
|
|
video_items: List[Dict] = []
|
|
|
input_entry: Optional[Dict] = None
|
|
input_entry: Optional[Dict] = None
|
|
|
|
|
|
|
|
- _CACHE_RE = re.compile(r"缓存|cache", re.I)
|
|
|
|
|
-
|
|
|
|
|
# 预扫描:是否存在阶梯 key
|
|
# 预扫描:是否存在阶梯 key
|
|
|
_has_tiers = any(_parse_tier_key(k) is not None for k in prices)
|
|
_has_tiers = any(_parse_tier_key(k) is not None for k in prices)
|
|
|
|
|
|
|
@@ -203,10 +224,6 @@ def parse_prices(prices: Dict[str, Any]) -> List[Dict]:
|
|
|
_output_prices.sort() # 从小到大,与阶梯从低到高对应
|
|
_output_prices.sort() # 从小到大,与阶梯从低到高对应
|
|
|
|
|
|
|
|
for key, val in prices.items():
|
|
for key, val in prices.items():
|
|
|
- # 跳过缓存相关条目
|
|
|
|
|
- if _CACHE_RE.search(key):
|
|
|
|
|
- continue
|
|
|
|
|
-
|
|
|
|
|
if not isinstance(val, dict):
|
|
if not isinstance(val, dict):
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
@@ -225,16 +242,17 @@ def parse_prices(prices: Dict[str, Any]) -> List[Dict]:
|
|
|
}
|
|
}
|
|
|
for sub_key, sub_val in val.items():
|
|
for sub_key, sub_val in val.items():
|
|
|
sk = sub_key.strip()
|
|
sk = sub_key.strip()
|
|
|
- if _CACHE_RE.search(sk):
|
|
|
|
|
- continue
|
|
|
|
|
|
|
+ normalized_key = _normalize_price_label(sk)
|
|
|
price = _parse_price(sub_val)
|
|
price = _parse_price(sub_val)
|
|
|
unit = _parse_unit(sub_val)
|
|
unit = _parse_unit(sub_val)
|
|
|
if unit:
|
|
if unit:
|
|
|
entry["unit"] = unit
|
|
entry["unit"] = unit
|
|
|
- if re.match(r"^输入|^input", sk, re.I):
|
|
|
|
|
|
|
+ if normalized_key == "input":
|
|
|
entry["input_price"] = price
|
|
entry["input_price"] = price
|
|
|
- elif re.match(r"^输出|^output", sk, re.I):
|
|
|
|
|
|
|
+ elif normalized_key == "output":
|
|
|
entry["output_price"] = price
|
|
entry["output_price"] = price
|
|
|
|
|
+ elif price is not None and normalized_key != sk:
|
|
|
|
|
+ entry[normalized_key] = price
|
|
|
elif price is not None and entry["input_price"] is None:
|
|
elif price is not None and entry["input_price"] is None:
|
|
|
# 无标签的纯价格 → 当作输入价格
|
|
# 无标签的纯价格 → 当作输入价格
|
|
|
entry["input_price"] = price
|
|
entry["input_price"] = price
|
|
@@ -273,10 +291,11 @@ def parse_prices(prices: Dict[str, Any]) -> List[Dict]:
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
# ── 简单非阶梯:输入 → 暂存,输出 → 配对 ──
|
|
# ── 简单非阶梯:输入 → 暂存,输出 → 配对 ──
|
|
|
- if re.match(r"^输入|^input", key.strip(), re.I):
|
|
|
|
|
|
|
+ normalized_label = _normalize_price_label(key.strip())
|
|
|
|
|
+ if normalized_label == "input":
|
|
|
input_entry = {"price": price, "unit": unit}
|
|
input_entry = {"price": price, "unit": unit}
|
|
|
continue
|
|
continue
|
|
|
- if re.match(r"^输出|^output", key.strip(), re.I):
|
|
|
|
|
|
|
+ if normalized_label == "output":
|
|
|
result.append({
|
|
result.append({
|
|
|
"label": "input/output",
|
|
"label": "input/output",
|
|
|
"tier_min": None,
|
|
"tier_min": None,
|
|
@@ -290,6 +309,20 @@ def parse_prices(prices: Dict[str, Any]) -> List[Dict]:
|
|
|
input_entry = None
|
|
input_entry = None
|
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
|
|
+ if normalized_label != key.strip():
|
|
|
|
|
+ is_output_side = normalized_label.startswith("output")
|
|
|
|
|
+ result.append({
|
|
|
|
|
+ "label": normalized_label,
|
|
|
|
|
+ "tier_min": None,
|
|
|
|
|
+ "tier_max": None,
|
|
|
|
|
+ "tier_unit": None,
|
|
|
|
|
+ "input_price": None if is_output_side else price,
|
|
|
|
|
+ "output_price": price if is_output_side else None,
|
|
|
|
|
+ "currency": "CNY",
|
|
|
|
|
+ "unit": unit,
|
|
|
|
|
+ })
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
# 其他普通标签
|
|
# 其他普通标签
|
|
|
result.append({
|
|
result.append({
|
|
|
"label": key,
|
|
"label": key,
|