更新日志

改了什么,
一条条记在这里。

已经上线的直接写;还没上线的会标明「尚未上线」。 目前共 794 条
同一条更新可能同时属于多个模块,因此各模块条数相加会大于总数。

第 11 页

2026-09-285 条

全站

自动转采购单和补货遇坏单位不再整批中断;提成页码非数字不报500;股东启用停用人数改由后端给真数

  • 自动转采购单和补货下单草稿,遇到某件商品的计量单位识别不出来时,不再让整批操作直接失败——审批通过后一键转单遇到问题商品,会明确列出是哪几件商品出了问题,不建立任何订单;补货下单草稿遇到问题商品会跳过这一件,同一个供应商的其他商品和其他供应商照常生成订单
  • 后台「提成」相关页面(个人业绩、门店汇总、外部推广员汇总、提成明细及其按人/按日/按类别汇总等)如果地址栏或分页参数不是数字,以前会报「服务器错误」,现在会明确提示参数错误,不会误报成系统故障
  • 股东名册页面「启用 N · 停用 M」这两个数字,以前超过200人时会算少,现在改由后端给出真实总数,不受清单显示上限影响

采购提成/推广股东与分红

财务

待批、异议、券、交班等数字改显示后端真实总数;提成明细超过 2000 笔时明示合计可能少算

  • 提成明细每类流水超过 2000 笔时,网页、小程序、App 都在提成合计旁明示「提成明细超过 2000 笔,合计可能少算」(App 写在应发/已结/待发和日结提成卡上)。
  • 待批请假、入职待审(App)、对账异议、会员手上的券、客人可用券(小程序)、交班留言(App)改显示后端给的真实总数,不再停在 50、20、100 这类上限;真的被截断时才加「只列了前 N 张」一类说明。
  • App 的供货申请改读后端的「是否截断」,不再用「笔数到 200」去猜。
  • App「我的请假」待批数改为翻完全部再数,不再只数最近 50 张;读不到时写「读不到」。
  • 股东「启用 N · 停用 M」优先读后端计数(后端计数上线前沿用原写法,到上限时注明可能偏小)。
  • 旧后端没给总数时照原写法显示笔数,只有笔数撞到上限时才写「至少 N」。
采购

采购单的供应商名称、到货提醒、逾期天数三栏曾悄悄回空,已补齐结构修法

  • 建单确认页、采购单详情页、供应商门户的采购单列表与详情等多处读取采购单时,「供应商名称」「是否今天到货」「逾期天数」三栏原本在一部分入口会悄悄回空(不是页面上看得到的错误,只是那三格显示不出来)
  • 这三栏现在改由后端统一算好再给出去,不管从哪个入口读采购单都不会漏

采购供应商门户

财务

App 换店或换人后,不再带着上一家店或上一个人的班次、桌台和购物车

  • 同一台机器换人(PIN 或生物识别)或换店时,当前班次立刻清掉、显示「班次读取中」再重读;交班、班中盘点、现金异动不会再拿上一个人或上一家店的班去送。
  • 读取中时不说「未开班」、不开开班单;结账前会先等这次读完再判断。
  • 换店时清掉上一家店的挂单、选中的桌、绑定的会员、桌台与订单缓存、扫码索引,再重新载入新店的菜单和桌台,不会再用旧店的桌和商品在新店开单。换店前如果这台机器上还有没送出的品项,先弹框「还有没送出的单」,默认「留在本店」;选「清掉并换店」才清。
  • 离线队列每一批都记下是哪家店排进去的,补送时只送目前这家店的,回到那家店才补送其他批。
  • 开店准备情况换店时清掉,读失败时标记读不到,不再沿用上一家店的资料。
财务

网页和小程序换店或换人后,不再带着上一家店或上一个人的单、桌和班次;爽约统计改算近 90 天

  • 网页收银断线暂存的单记下是哪家店的,换店后只在本店补送,不会再用新店身份送出旧店的桌和商品。
  • 登出后换另一家店的人登入,页面整页重新载入,不再沿用上一家店的收银台、选中的桌、绑定的会员和缓存。
  • 同一家店换人(PIN 切人或登出后下一位接手)时,重置该人相关的数据,不再显示上一个人的当前班次;菜单、分类、桌台不受影响,收银台的单继续保留。
  • 切换门店前,如果有还没送出的品项,先弹框「还有没送出的单」,默认「留在本店」;选「清掉并换店」时,这几张单在断线队列里的批次一起丢掉。
  • 小程序客人购物车绑定门店和桌台,换桌或换店就清空,同一桌重扫不清。
  • 预约页的爽约统计原本只算今天以后的预约,现在改算截至今天营业日的近 90 天,卡片注明区间。

2026-09-2715 条

采购

付款申请可以只看自己提交的,被驳回的申请能看到驳回理由

  • 网页采购页的付款申请新增「只看我提交的」筛选(默认关);打开后会多显示已驳回的申请,并显示驳回理由。
  • 小程序付款申请页新增同样的「只看我提交的」筛选,和「要处理/全部」分页叠加。
  • 后端付款申请列表支持 mine=1,只返回自己提交的;不带该参数行为不变,权限检查沿用原有门店级校验。
  • 顺带修正 approval-submitter-path 检查脚本的路由前缀推导,并把提现申请转入基准线。

采购

财务

后端清单翻页不再重复或漏掉同值的项;自己截断的清单回真实总数并标明被截断

  • 所有分页清单的排序最后都补上唯一键,同名同价的商品(例如收银菜单)翻页时不会一页重复、一页漏掉。
  • 待批请假、我的请假、入职审核、交班留言、券模板、会员可用券、客人可用券、供货申请、对账异议、股东、分红批次、个人打卡、今晚订位、客人菜单、活动等清单:回传里带上截断前的真实总数和「是否被截断」,供货申请的待处理数不再最多只到 200。
  • 今晚订位改在数据库里按状态过滤,总数是真数;客人菜单先过滤隐藏品项再截断;客人首页可用券张数改为数据库计数。
  • 提成明细每类流水仍有 2000 笔上限,超过时回传标明被截断(前端提示另开票)。
  • 会员相关接口的页码等参数不是数字时回 400 并点名参数,不再 500。
全站

收银班次、库存预警、补货下单、客人菜单等多处读取失败时,不再误判成「没有」或「找不到」

  • 客人扫码点单的菜单页读取失败时会提示重试,不再显示成「没有菜品」
  • 后台库存预警中心的缺货、临期批次、滞销三张卡片读取失败时明确提示读不到,不再显示成「没有xx」
  • 采购、调拨、进价历史、损耗记录、班次详情等多个后台页面统一了读取失败的判断,弱网或断线重试期间不再误判成「没有」
  • 班次详情读不到时不再笼统显示「找不到这个班次」,并说清楚三种可能原因(没有查看权限/班次不属于这家店/这个班次本身不存在)
  • 补货下单不再要求员工额外的「商品查看」权限才能看到计量单位名称——单位名称改由后端直接给出
  • App(iOS/安卓/Mac/Windows)收银点单菜单读取失败时给出重试按钮,不再显示成「没有菜品」
  • App 的库存台账、入库、出库、临期批次、跨店调拨、进价历史、记损耗、在途采购等页面读取失败时不再误判成空
  • App 有 4 个页面原本把「读到了」的标记写反,已改对
  • App 入库时如果读不到仓库列表,不会再悄悄把商品入到默认仓库,而是提示读取失败
  • 建采购单时,商品计量单位的名称改由后端按 unit_id 查表解出,不再采信客户端传的字符串;已停用的单位仍能正确解出原名;查不到对应单位时会提示具体是哪个商品的单位有问题,不会显示成一串数字

开班交班进销存采购调拨客人扫码点单

财务

网页和小程序的清单翻完所有页,不再把第一页当全部;浏览型明示只列最近 N 笔

  • 应收账龄、逾期合计、线上收款、寄存、礼品卡、会员、提成、采购、退款、交班等清单改为翻完所有页,任何一页读失败就整体提示读不到,不再给半份。
  • 供应商端的应付(未到期/已逾期金额)翻完全部应付再加总,不再只算前 20 笔。
  • 拿掉已经不成立的「仅统计前200笔」「这个数偏小」「只列了最近」「只读得到50条」「只统计了最近」等提示。
  • 浏览型的长清单明示「只列最近 N 笔」。
  • 第二批:库存注意徽章、在架与临期批次、滞销、菜单复制、订位与爽约统计、总部调拨、供应商入驻审批(原本只看得到 20 张)、供应商清单、待跟进、员工与排班名册,小程序的库存、临期、订位、调拨、在途采购、我的客户、进行中盘点与班次等,都翻完所有页。
  • 会员积分/订位/跟进历史、集团采购单、平台模板库改成明示只列最近 N 笔,并可分页或载入更多;搜索结果满上限才提示「只列前 N 笔,请输入更精确的关键词」。
  • 滞销数读失败显示「—」,不再显示 0;储值沉睡改名「余额最高前 5 位」、进货改名「最近 N 次进货」。
财务

HQ跨店对比导出合计漏算读失败的店、日结净销售读不到时误显示¥0,两处已修正

  • 老板/店长看的「HQ跨店营收对比」页面,导出 CSV 时如果某天有店铺数据读取失败,合计栏以前会悄悄把那家店排除、看起来像正常合计——现在跟画面上的「集团合计」用同一份数据,读不到时明确标注「N 家店没读到,合计不含」,不再悄悄漏算
  • 同一张表里,如果某家店在选定的这几天里有几天读失败,它自己那一行的合计以前也是悄悄按「读到的那几天」合计、看起来像完整合计——现在会显示「读不到(N天缺)」
  • 员工在小程序「日结」历史记录里看到的「净销售」,如果这笔记录数据本身有问题(读不到),以前会显示成 ¥0,跟「今天真的没有营业额」分不清——现在会明确显示「读不到」

连锁 HQ财务/日结/流水

财务

读不到当前班次或日结报表时,不再当成「没开班」或「可以日结」

  • App 收银端读不到当前班次时,显示「读不到当前班次,不确定有没有开班——检查网络后重试」,按钮改成重读,不再推「去开班」、不再弹开班单、结账前也不再先弹开班单。
  • 读不到时,只有同一家店、同一个人、那班还开着,才沿用上次读到的班继续收银,并标明「班次状态刷新失败,显示的是上次读到的」;换店、换人一律清掉。
  • 开班单打开前会先重读一次;读不到就不开单,发现其实开着也不开单。
  • 网页角色首页在日结报表读不到或还在读时:收银不再显示「今天还没开班」;确认日结按钮灰掉,并写明「今天的未结台/未交班/现金差异读不到,刷新确认后再日结」;会计不再显示「本期已关账」。
财务

Flutter 营运首页读不到的提醒不再消失,也不再显示「一切正常」

  • 待核准退款、采购待收货、在途采购、门口候位、库存见底、财务异常雷达、现金对账、开太久没交的班、要付的钱、此刻脉搏等提醒:读失败时照样出现在原位,写「读不到,不是没有」,数字位置写「读不到」,不再显示 0 或整张卡消失。
  • 只要有提醒类来源读不到,首页就不画「一切正常」。
  • 当前班次读失败不再当成「未开班」、不再推「去开班」;开店准备读失败不再用上一家店的旧资料推引导。
  • 角色首页在日结报表读不到时,各待办数字写「读不到」,现金差异不再写「无」。
  • 换店时先重设读失败标记,换店期间才回来的旧请求一律丢弃。
财务

月度目标、工资成本、股东分红、滞留退款等多个页面读取失败时,不再显示成「没有」或算出错误数字

  • 「月度目标」卡片:本月营业额或月度目标读取失败时,不再拿失败当「没有」去算一个假的达成率,会明确提示「读不到本月营业额/目标」
  • 成本页面的「默认时薪」和「本月工资成本」:读取失败时不再显示成「未设置」或干脆不显示,会提示「读不到,不确定有没有设过」;导出成本明细表时如果这一项读不到,表里也会写清楚「读不到」,不会悄悄漏掉这一行
  • 股东分红页面:损益表到底是「已冻结的数字」还是「现在重新算的数字」,在读取失败或还没读完时不再擅自认定成其中一种,会提示「暂时读不到,刷新再试」
  • 后台待审批页面里「已批准但钱还没退给客人」的滞留退款提醒,读取失败时不再安静地整块不显示,会明确提示「读不到,不代表没有,点重试再看一次」
  • App(iOS/安卓/Mac/Windows)的「退款收件箱」:读取滞留退款失败时不再当成「没有滞留退款」,会提示「读不到,不是没有」并可以点重试
  • App 的「门店成本」页面:保存失败时不会再误显示成「保存成功」
  • App「日结」页面的提成明细:读取失败时不再显示成 ¥0.00,会明确提示「读不到提成明细」

财务/日结/流水成本与毛利股东与分红审批收件箱

财务

Flutter 清单不再只拿第一页当全部;读不到的不再显示成「没有」或 0

  • 收银主菜单、供应商入口的订单/应付/对账/退货/商品、逾期应付合计、退款没退出去的清单、提成明细、采购商品目录、员工名册、会员礼品卡:都翻完所有页,任何一页读失败就整体提示读不到,不再给半份。
  • 库存流水与批次、采购追踪与草稿、请购、调拨审批、会员跟进、订位、寄存、菜单提成:同样翻完所有页。
  • 只显示数量的地方(进行中盘点、待收货)改读后端总数,读不到明说,不再显示 0。
  • 会员目录、会员详情的储值/积分/跟进/订位、单品流水、跨店调拨:显示「已载入 x / 共 N」并提供载入更多;搜索结果到上限时提示输入更完整的关键词。
  • 日结与月账单的应计提成、已结、待发以前一直是空,现在对上后端数字;日结「酒水基数」接上后端,并注明「计入提成的基数,不是酒水净销售」。
  • 会员详情 9 个子区块、调拨该发/该收张数、结账礼品卡、角色与指派、提成口径读失败时原位显示读不到;提成口径读不到时不让整表保存,避免用默认值盖掉店家设置。
权限

班次清單 meta.scope 補上 orders:shift 全店放行的情況,三端拿掉各自的猜測繞過邏輯改直接信任

  • 背景:`GET /shifts/` 在 `status=open` 時,只要使用者在這家店有 `orders:shift`(即使沒有 `accounting:view`/`reports:view`),後端本來就會放行看到全店進行中的班次(WALK-172 既有設計)——但回應的 `meta.scope` 欄位只看 `accounting:view`/`reports:view`,完全沒把這個放寬算進去,錯誤地回報 `"mine"`,對前端撒謊。這個欄位(T-2772 加的)本來的目的正是讓前端不用再靠登入時快取的權限聯集猜,要看這個欄位才知道「這次請求我真的看得到全店嗎」——結果它自己在這個組合下也不準。
  • 後端修法:`apps/payments/views.py` `ShiftViewSet.list()` 抽出單一布爾值 `narrowed_to_mine`(等於原本判斷「查詢有沒有被收窄成只看自己」的那份邏輯),`qs.filter()` 跟 `meta["scope"]` 都讀同一份,不再各自維護兩份可能分岔的判準。補了正反兩格測試(status=open+只有orders:shift→scope必須是store;顯式mine=1、以及非open歷史→scope必須是mine),拿掉修法時正格測試會真的變紅,已驗證。
  • 三端因為不信任這個欄位,各自寫了「土法煉鋼」的繞過邏輯:拿到清單後,自己檢查清單裡有沒有出現別人的資料,反推真正的範圍——web(`useOpenShifts()`)甚至完全不讀 `scope`,靠「沒權限的人會 403、有權限的人拿到全店列表」這種經驗行為側面判斷。後端修好之後,三端都拿掉了這套反推邏輯,改成直接讀 `meta.scope` 三態(全店/只有自己/讀不到),連帶清乾淨所有「後端修好後刪掉」的舊注解。
  • web:`useOpenShifts()` 改回傳 `{ rows, scope }`(跟既有 `fetchAllShiftHistory()` 同一種形狀),五個消費端(班次紀錄、日結阻塞明細、隔夜未交清單、店長治理屏「未交班N班」)都補上依範圍分流的文案——scope不是「全店」時,清單旁邊會提醒「這個帳號目前只看得到自己開的班,清單可能不完整」,不會讓使用者誤以為清單已經涵蓋全店。
  • 小程序:今日班次頁拿掉「拿全部查詢原始列反推scope真假」的交叉核對函式,改直接映射scope三態,文案邏輯不變(全店/只有自己/讀不到範圍三選一講清楚)。
  • Flutter:`lib/domain/shift/shift_list_scope.dart` 拿掉 `OpenShiftsCoverage`/`openShiftsCoverage()` 反推邏輯,今日班次的標題與空狀態文案改直接吃後端回的 `ShiftListScope`。
  • 2026-09-27 部署當天採取的安全過渡期設計:部署順序是後端先上(11:25)、三端後上(web/小程序19:49,Flutter隨後),前端改動在後端還沒上線的窗口期就已經是安全的——舊後端對 status=open+只有orders:shift 的組合仍會錯誤回 scope=mine,新前端此時會顯示「只看得到自己」這種保守文案,不會顯示「全店都沒有」這種樂觀文案,不需要額外的相容邏輯。
  • 驗收:web、小程序各截兩張真實畫面(有店級查看權限的帳號 vs 只有orders:shift的收銀帳號),負例畫面文案逐字核對過;web `npx tsc -b`、小程序 `npx tsc --noEmit` 皆0錯誤;Flutter `flutter analyze`0 issue、`flutter test`3/3過(合併前另外由rico1跑過全套test/analyze);後端班次相關既有測試4支跑動,2支因本機環境限制(名冊密碼登入、真實LLM key)跳過,與本次改動無關。
登入尚未上线

Flutter 登录后不再先对一家写死的门店发请求;门店列表读不到时给重试

  • App 里不再有写死的默认门店:登录后只有一家店的账号直接进店,多店账号在选店页选择(上次进过的店只做预选)。
  • 选店之前不会对任何门店发出门店范围的请求,也不会先把门店设成别人的店。
  • 「上次进过的店」按账号分开记,换人登录不会带到上一个人的店。
  • 门店列表读不到时显示「读不到你能进的门店,不是没有——检查网络后点重试」,附重试按钮。
体验

9處「讀不到」被誤顯示成「沒有」的介面文案修正:帶位開台/出品看板/供應商付款申請/股東預約/分紅確認/耗材調撥,web+小程序已上線

  • 帶位開台頁(網頁後台+小程序員工端):查桌況讀取失敗時,原本會誤顯示「沒有空桌/可併桌/使用中/待清潔的桌」,現在先顯示讀取失敗提示並可重試,不會誤導員工去追不存在的空桌。
  • 廚房出品看板讀取失敗時,原本誤顯示「今晚沒有待出餐點」,現在先顯示讀取失敗提示與重試按鈕。
  • 供應商付款申請列表讀取失敗時,原本誤顯示「沒有付款申請」,現在先提示讀取失敗、請刷新重試。
  • 股東預約頁切換分區時若該分區讀取失敗,原本可能誤顯示「這區沒有空桌」,現在先提示讀取失敗。
  • 分紅確認流程裡,「雙重計入確認」的核取方塊原本在資料還沒真的讀到時也可能出現,現在只在確定讀到資料後才出現。
  • 小程序耗材調撥頁搜尋不到結果時,若其實是讀取失敗,原本誤顯示「沒有匹配的商品」,現在先提示讀取失敗。
供应商

供应商和商户的合作改成双方同意:供应商申请、商户同意或邀请,可以随时撤回

  • 供应商在门户「申请供货」只会送出申请,商户那边不再被自动建档;商户同意后才开始合作。
  • 商户后台新增「供应商」页:合作中、申请、邀请三个页签。同意申请时如果可能是同一家,必须选合并到哪份档案或新建。
  • 商户可以产生 6 位邀请码、链接和二维码,供应商输入后直接建立合作;一个码只能用一次,可以作废、重新产生。
  • 商户可以随时撤回门户:撤回前会显示未结应付和进行中的采购单数,撤回后对方在门户看不到你店的任何单据。
  • 停用的供应商不能再下新采购单,补货建议也不会再推荐它;下单短信只发给已经开通门户的供应商。
  • 供应商门户显示「合作门店」数、我的申请状态(申请中/已合作/被拒/合作已结束),采购单链接只在合作中才看得到内容。
  • 网页、小程序、Flutter 三端都能处理申请;邀请码在网页和小程序产生。
会员储值

門店管理範本補齊會員儲值跳過簡訊驗證權限,三端SMS卡關文案改按權限描述,web/小程序/Flutter三端已上線

  • 背景:T-2926全流程走查(rico1指派)发现会员储值扣费简讯验证码的「无码时店长级跳过」权限(orders:member_pay_override,apps/core/permission_catalog.py,標SENSITIVE)从建置起就登记在权限目录里,却从未被种进任何一份默认权限范本——只有tenant_admin(全通道admin)能用。店里只有店长以下班底在场、客人手机收不到简讯(信号差/换号)时,储值支付会完全卡死,挡住真实营收。
  • 後端修法:seed_default_permission_templates.py只把这条码种进manager(店长)范本(v0.6.0→v0.7.0),cashier/lead/server/bartender/kitchen/finance/purchasing_clerk/group_ops_director/group_finance_director/group_hr等其余范本刻意不给——这条码本身是SENSITIVE(有审计),店长是这次裁定认为合适的授权层级。
  • 文案修法:member_pay_sms.py「无码+无跳过权限」分支原本回泛用的MEMBER_PAY_CODE_REQUIRED(400,「使用会员储值前请先向会员手机发送并填写验证码」),这句话对真的收不到简讯、又没有人有跳过权限的现场是死路不是提示。改回专属码MEMBER_PAY_OVERRIDE_REQUIRED(403),訊息直接點名權限本身(按權限描述,不按職稱)——「客人收不到验证码时,请找有「跳过储值扣费短信验证」权限的人来处理这笔支付」,web/miniapp既有的错误显示惯例(catch一律用error.message原样显示)不需要额外接线就会显示新文案。
  • 顺带修复:_audit()此前没有传user_id给AuditService.log(),导致「谁跳过了简讯验证」这条SENSITIVE动作的审计记录里,操作人栏位一直是空的(其余栏位都记得到)。已补上从request.user反推,匹配同档其余稽核呼叫点的既有惯例。
  • Flutter三端契约检查发现的连带问题:complete_billing_copy.dart既有的12码白名单机制会在没有识别的文案后自动补一句「请重试完成收款」,新文案不含既有识别关键字,会被接成「……请找有权限的人处理这笔支付。请重试完成收款」——语意矛盾(叫人去找别人处理,又叫他自己重试)。修法:白名单新增本条文案(逐字跟web/miniapp同一句)+ _ensureRetryHint()新增关键字「跳过」使其不被接上重试提示,不改动既有12码任何一条。
  • 门店权限落地:一号店(cfff14e9)店长范本用官方既有的「同步到最新平台范本」机制(sync_group_to_latest_platform_template(),既有的per-group可审机制,非临时脚本)补齐这条权限,顺带一并补上该群组此前遗漏的members:view_full_phone(同一支同步机制附带修复)。
  • 验收:web/小程序各拍到正例(有权限的店长账号直接用会员储值付款成功、无SMS码)与负例(无权限的收银账号触发403、逐字显示新文案)两组真实画面,数据库audit log核对skipped_by_manager_override与操作人id均正确;Flutter端用4项纯函式测试验证文案与「不含重试」两件事,另有既有的memberPayOverride能力位既能正确驱动结账画面的「店长跳过验证」按钮主动出现(不需先触发错误)。
财务

撤銷結帳重結路徑三合一修復:COGS重複入帳/訂單永久卡billing/退款找不到儲值流水,正式機只讀核對零遺留

  • 背景:T-2926全流程走查(rico1指派)抓到「撤销结账(reverse_checkout)后换付款方式重新结账(complete_order())」这条二次路径上,同一支状态机藏了三个各自独立的钱/状态缺口。
  • ①COGS重复入账:complete_order() Step4的sale_cogs会计分录原本没有跟Step2/Step3同一个is_recomplete守卫,重结时存货并没有再出库一次,COGS分录却借贷各多记一次。修法:Step4补上跟Step2/Step3同一个is_recomplete判断,不新发明判准。
  • ②订单永久卡在billing:前端complete()的Idempotency-Key按付款内容定址,撤销后若重结时付款内容跟撤销前一字不差,同一把key会撞回撤销前就已存档的COMPLETED快照原样回放——挖到两层缺口:(a)apps/core/idempotency.py的.create()撞唯一约束时没包savepoint,导致MySQL一报IntegrityError就把外层事务标记needs_rollback,下面的fallback查询被挡成TransactionManagementError,重放路径因此每次500;(b)修完500之后,重放路径会原样回放撤销前的快照(HTTP 200但订单在DB里其实还卡在billing、无新状态记录)。修法:(a)用嵌套事务(savepoint)圈住.create() (b)reverse_checkout()撤销当下删掉这张单COMPLETED的幂等记录,强迫之后任何重放请求真的重跑一次业务。
  • ④退款找不到储值扣款流水:退款分摊查询原本用Payment.objects_unscoped(连软删的旧付款列都捞回来),撤销+换付款方式重结后会把已撤销退回的旧付款也算进这次退款的分摊比例,炸MEMBER_BALANCE_CONSUME_NOT_FOUND、挡死这张单的任何退款。中途一度改成Payment.objects,经rico1指出这会让跨店/无请求上下文(如背景任务)发起的退款查询变成0笔付款、静默分摊出错,已订正为保留objects_unscoped、只额外加is_deleted=False过滤,不改动租户/门店范围语意。
  • 新增回归测试scripts/test_t2933_reverse_recomplete_triad_flow.py(A-E五格,27项断言),每个修法都先还原成修复前代码确认真的会红、再还原修法确认转绿,含订正后的跨店context反向验证格。
  • 回归验证:run_local_tests.py对84支涉及complete_order/reverse_checkout的既有脚本全跑,74 PASS/0因本票改动而FAIL(3支FAIL经比对未修改代码确认是既有环境限制,与本票无关)/7 SKIP(需要真实HTTP服务器或名册密码登录);另加跑18支refund/checkout相关脚本全绿。
  • 正式机只读核对(零写入,用atomic+force-rollback包住):reverse_checkout相关AuditLog历史13笔,但对应Order/OrderStatusLog均已不存在于当前表中(demo/测试店数据清理所致);当前表中重结成功/COGS重复入账/卡在billing三项计数均为0——平台目前零真实商户,此前没有遗留数据需要人工订正。

这份日志从 2026 年 7 月记起,更早的没有逐条列。想看它现在都会什么,回全部功能,或者进演示店自己点一点。