mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-21 23:41:39 +08:00
fix(strategy): 规则底稿补充列表店铺去重SKU口径与摘要一致
竞争结构节在 shops_from_list.unique_sku_basis 存在时输出对照行,便于策略 LLM 与人工复核;新增单测。 Made-with: Cursor
This commit is contained in:
parent
1af6aa00a5
commit
1a569ce727
@ -77,6 +77,25 @@ def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
|
|||||||
return f"- **{label}**:头部为「{top_s}」(缺少占比时可结合列表与商详数据补全)。"
|
return f"- **{label}**:头部为「{top_s}」(缺少占比时可结合列表与商详数据补全)。"
|
||||||
|
|
||||||
|
|
||||||
|
def _shop_unique_sku_basis_lines(shops: dict[str, Any]) -> list[str]:
|
||||||
|
"""
|
||||||
|
``shops_from_list.unique_sku_basis`` 与竞品报告/摘要一致:按去重 SKU 的店铺集中度对照口径。
|
||||||
|
"""
|
||||||
|
usb = shops.get("unique_sku_basis") if isinstance(shops, dict) else None
|
||||||
|
if not isinstance(usb, dict) or not usb.get("n_unique_skus"):
|
||||||
|
return []
|
||||||
|
u1 = concentration_first_share(usb)
|
||||||
|
u3 = concentration_top_three_share(usb)
|
||||||
|
utop = _esc(usb.get("top_label") or "")
|
||||||
|
if u1 is None or not utop:
|
||||||
|
return []
|
||||||
|
return [
|
||||||
|
f"- **列表侧店铺(按去重 SKU)**:共 **{_num(usb.get('n_unique_skus'))}** 个去重 SKU;"
|
||||||
|
f"第一大店铺「{utop}」约占 **{_pct(u1)}**;前三合计 **{_pct(u3)}**。"
|
||||||
|
"*(与上行「按列表行」可能因同一 SKU 多行曝光而差异;非销量/市占。)*"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def _goal_bullet(label: str, user_val: str, placeholder: str) -> str:
|
def _goal_bullet(label: str, user_val: str, placeholder: str) -> str:
|
||||||
v = _esc(user_val).strip()
|
v = _esc(user_val).strip()
|
||||||
if v:
|
if v:
|
||||||
@ -230,6 +249,8 @@ def build_strategy_draft_markdown(
|
|||||||
)
|
)
|
||||||
if n_shop:
|
if n_shop:
|
||||||
lines.append(n_shop)
|
lines.append(n_shop)
|
||||||
|
for uline in _shop_unique_sku_basis_lines(shops):
|
||||||
|
lines.append(uline)
|
||||||
if n_brand:
|
if n_brand:
|
||||||
lines.append(n_brand)
|
lines.append(n_brand)
|
||||||
if not n_shop and not n_brand:
|
if not n_shop and not n_brand:
|
||||||
|
|||||||
@ -105,3 +105,31 @@ class StrategyDraftTests(SimpleTestCase):
|
|||||||
)
|
)
|
||||||
self.assertIn("「口感」:子串统计命中约 **501** 次", md)
|
self.assertIn("「口感」:子串统计命中约 **501** 次", md)
|
||||||
self.assertIn("场景「控糖/血糖相关」:约 **305** 条", md)
|
self.assertIn("场景「控糖/血糖相关」:约 **305** 条", md)
|
||||||
|
|
||||||
|
def test_shops_unique_sku_basis_rendered(self) -> None:
|
||||||
|
brief = {
|
||||||
|
"schema_version": 1,
|
||||||
|
"keyword": "测试",
|
||||||
|
"concentration": {
|
||||||
|
"shops_from_list": {
|
||||||
|
"first_share": 0.6,
|
||||||
|
"top_three_combined_share": 0.85,
|
||||||
|
"top_label": "京东自营",
|
||||||
|
"unique_sku_basis": {
|
||||||
|
"first_share": 0.35,
|
||||||
|
"top_three_combined_share": 0.7,
|
||||||
|
"top_label": "京东自营",
|
||||||
|
"n_unique_skus": 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"detail_brand_among_merged": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
md = build_strategy_draft_markdown(
|
||||||
|
job_id=1,
|
||||||
|
keyword="测试",
|
||||||
|
brief=brief,
|
||||||
|
)
|
||||||
|
self.assertIn("按去重 SKU", md)
|
||||||
|
self.assertIn("120", md)
|
||||||
|
self.assertIn("35.0%", md)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user