diff --git a/pipeline_platform/platform_ability.py b/pipeline_platform/platform_ability.py index 561b4ad..59fd7e0 100644 --- a/pipeline_platform/platform_ability.py +++ b/pipeline_platform/platform_ability.py @@ -720,16 +720,54 @@ async def _h_apply_model_pricing(sor, params, ctx): pp_desc = "定价出处:%s | 文档原文:%s" % (doc_url or "(未提供)", desc_quotes) now = time.strftime('%Y-%m-%d') if old_ppid: - # 幂等更新:新时序行(拉链——旧行 expired_date 截到今天) ppid = old_ppid + # 幂等核心(2026-09-05 用户纠正:时序应只有一条有效行,重复执行不得堆历史): + # 先取当前生效行比对内容—— + # 内容相同 → 跳过(不产生新时序行) + # 内容不同且生效行今天才启用 → 原地 UPDATE(同日替换无历史区间可保留, + # 拉链会产生 enabled==expired 的零宽死行,纯垃圾) + # 内容不同且生效行是历史日期 → 正常拉链(关旧行+插新行) + recs2 = await sor.sqlExe( + "SELECT id, pricing_data, enabled_date FROM pricing_program_timing " + "WHERE ppid=${p}$ AND expired_date='9999-12-31' " + "ORDER BY enabled_date DESC LIMIT 1", {"p": ppid}) + await sor.sqlExe("COMMIT", {}) + cur = recs2[0] if recs2 else None + same = False + if cur is not None: + try: + same = (yaml.safe_load(getattr(cur, 'pricing_data', '') or '{}') + == yaml.safe_load(yaml_str)) + except Exception: + same = (getattr(cur, 'pricing_data', '') or '') == yaml_str + await sor.sqlExe( + "UPDATE pricing_program SET description=${d}$ WHERE id=${i}$", + {"d": pp_desc[:1000], "i": ppid}) + await sor.sqlExe("COMMIT", {}) + if same: + results.append({"model": vmid, "ok": True, "ppid": ppid, + "action": "无变化(幂等跳过,未产生新时序行)", + "items": len(mitems), "factor": factor, + "dimensions": sorted(dims_all)}) + continue + if cur is not None and str(getattr(cur, 'enabled_date', ''))[:10] == now: + await sor.sqlExe( + "UPDATE pricing_program_timing SET pricing_data=${y}$, name=${n}$ " + "WHERE id=${i}$", + {"y": yaml_str, "n": "%s %s计价" % (vmid, factor), + "i": getattr(cur, 'id', '')}) + await sor.sqlExe("COMMIT", {}) + action = "原地更新(同日替换,不产生历史行)" + results.append({"model": vmid, "ok": True, "ppid": ppid, + "action": action, "items": len(mitems), + "factor": factor, "dimensions": sorted(dims_all)}) + continue + # 历史生效行 → 拉链 await sor.sqlExe( "UPDATE pricing_program_timing SET expired_date=${d}$ " "WHERE ppid=${p}$ AND expired_date='9999-12-31'", {"d": now, "p": ppid}) - await sor.sqlExe( - "UPDATE pricing_program SET description=${d}$ WHERE id=${i}$", - {"d": pp_desc[:1000], "i": ppid}) - action = "更新(新时序生效 %s)" % now + action = "更新(拉链:旧行截至今日,新时序生效 %s)" % now else: ppid = getID() await sor.C("pricing_program", {