Commit Graph
1738 Commits
Author SHA1 Message Date
kate522 1875470ac7 fix(after-sale): 售后工单已完结仍可再次申请,改由订单是否已退款决定
上一个提交把「工单 completed」当成了不能再申请售后的判据,方向搞反了:
能否再售后应该看订单有没有被标「已退款」,而不是看工单状态。订单已退款时
status_group 变成 refunded、enabled 直接为 false,那道闸门本来就够用;用工单
状态再判一次,反而把「工单已完结但订单没退款」的用户堵死,售后详细弹窗底部
也只剩下一个「我知道了」死胡同。

- reapplyable_statuses 补上 STATUS_COMPLETED:rejected / cancelled / completed
  一律放行再次申请,售后详细弹窗底部按钮对已完成订单渲染「再次申请售后」
- can_apply 还原为只看有没有进行中的工单(!open),不再二次校验工单状态
- create() 的重复申请闸门还原为 find_active():只挡仍在流转的工单,
  completed 不挡;订单已退款由上面的 STATUS_PAID 校验先挡掉
- 点「再次申请售后」后清 has_application 落回申请表单,提交走 create()
  新建工单,链路本来就通,无需改动

harness 场景名改为 settled_ticket_still_allows_reapply,断言 completed /
rejected / cancelled 三种已终结状态都能新建工单;待审核工单同因幂等、换因
挡住的场景保留。

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;after-sale-log-harness
7/7。未做浏览器视觉验收。
2026-10-09 18:38:18 +08:00
kate522 c955fd35f2 fix(after-sale): 售后工单已完结即不可再申请,不看订单是否另标已退款
原来的重复申请闸门只看「进行中」的工单(find_active = pending/processing),
于是工单已 completed、但订单没被另标「已退款」时,订单还能再发起一次售后。
已退款订单之所以不能再申请,是因为 status_group 变了导致 enabled 为 false,
属于间接效果;工单层面的规则一直是漏的。

- create() 改为以 latest_for_order() 为准:completed 直接挡掉;待审核/处理中
  仍走同人同因幂等(返回原工单),rejected / cancelled 放行再次发起
- after_sale_state() 的 can_apply 同步收紧,与 can_reapply 同一口径:
  有工单时只有 rejected / cancelled 才放行,completed 不再漏过去
- 界面上售后详细弹窗的「再次申请」本就只对 rejected / cancelled 渲染,
  这条改动把服务端与 API 口径补齐,堵住绕过前端直接打 REST 的口子

harness 补两个场景:completed 挡住而 rejected / cancelled 放行;待审核工单
同因幂等返回原单、换因挡住。

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;after-sale-log-harness
7/7(新增两场景);dev harness 渲染两个后台页面与 unchecked 处理场景均正常。
未做浏览器视觉验收。
2026-10-09 18:25:02 +08:00
kate522 36b3ba6f45 fix(after-sale): 订单详情弹窗不再渲染售后状态节点进程
订单详情弹窗的「售后记录」卡片把整条处理时间线铺在了卡片里,和点开
「查看详细」后的售后详细弹窗重复,卡片本身也被拉得很长。改为只保留状态
徽章 + 申请时间、原因/申请理由、退款金额与「查看详细」入口;完整处理记录
由售后详细弹窗独占呈现,信息不缺、入口也还在。

- 删掉卡片里的 orderDetailHandlingLogHtml(item.handling_log) 调用
- 连带删除随之无人调用的 orderDetailHandlingLogHtml / handlingEntryTitle /
  AFTER_SALE_STATUS_LABELS 三个助手
- recordPayload 仍带 handling_log,点开详情弹窗照旧能看到时间线
- modal-runtime.css 的时间线规则不动:售后详细弹窗还在用,无需重打包

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;契约测试改为断言
订单详情弹窗不再出现 timeline 标记与三个助手,同时锁住「查看详细」载荷仍带
handling_log;node --check 通过。未做浏览器视觉验收。
2026-10-09 18:12:48 +08:00
kate522 039fa6d863 feat(after-sale): 处理记录时间线改为「节点 + 状态 + 时间」同一行
原实现把状态与时间竖排在节点右侧的 88px 固定列里,状态文字一长就折行、
时间被挤到第三行,和右侧备注也对不齐。改为节点独占一列,状态与时间包在
head 里紧随其后,处理备注另起一行:

- [节点][处理状态][时间] 一行,状态色仍按工单状态走 --as-accent
- 竖线改挂到条目的 ::before(原来是 aside 的),top 从 12px 调到 14px,
  与加了 4px 上边距的节点底部对齐,绳子依旧穿过每个节且末项不收口
- head 用 flex + baseline + gap:8px,状态过长时时间自然换行而不重叠
- 售后详细弹窗与订单详情弹窗共用同一套标记,两侧同步改

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;用 node 分别抽取
两个 JS 里的时间线构造函数跑样例载荷,确认输出为
[节点][状态][时间] + 另起一行的备注;重建 public.css / public.min.css,
diff 仅限时间线规则。未做浏览器视觉验收。
2026-10-09 18:01:16 +08:00
kate522 26ce9a5904 feat(after-sale): 售后处理记录改为每次提交留痕并新增时间线
工单行内新增 handling_log 列,用户申请、用户撤销与后台每次改状态都落一条
「状态 + 备注 + 来源 + 时间」,按时间正序存放、上限 50 条(对齐
MetaAssetService::MAX_RECORDS)。set_status 因此变成读-改-写,补上
GET_LOCK/RELEASE_LOCK 包裹,并在锁内重读工单快照——锁外取快照仍会被并发
追加覆盖。

三处界面由「只显示最后一条」改为回放整条处理链路:

- 后台订单明细「售后记录」按工单渲染头部(状态/金额/申请时间)+ 原因 +
  完整处理记录
- 售后面板手风琴「处理备注」单独占整行并置于「申请说明」上方,删掉已无
  意义的「审核时间」
- 前台售后详细弹窗与订单详情弹窗的售后记录改为时间线:左列绳结状态条
  (节点 + 状态 + 时间),右列处理备注;样式只在 modal-runtime.css 定义
  一份,两个弹窗共用

清理随之失效的死代码:工单的 admin_note / reviewed_at / completed_at,以及
全仓库无写入方的 gateway_request_id / gateway_refund_id / gateway_result;
连带删掉 gatewayResultText()、uninstall 里从未存在过的 aksrt_after_sale
表项,并把两处后台页面重复的状态标签数组收成 after_sale_status_labels()、
重复的 .aksrt-as-log 样式收成 after_sale_log_css()。

顺带修复 88669f69 重构退款流水线时误删 refund_amount()、却仍在 create()
里调用的问题——此前任何用户提交售后都会直接 fatal。

验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;新增
after-sale-log-harness.php 驱动真实 AfterSaleService,覆盖首条日志、空备注
也留痕、撤销记录、50 条上限与畸形行规范化;两个后台页面经 dev harness
渲染校验「处理备注」宽行位于「申请说明」之前;未做浏览器视觉验收。
2026-10-09 13:59:50 +08:00
kate522 31e6ba00af fix(after-sale): 售后举证缩略图去掉原生 loading 属性
lazyload 契约测试全仓库禁 loading=lazy/eager,售后服务 accordion 详情里的
举证缩略图带着该属性,是唯一一处违规(80373746 引入,早于本次分页改造)。

去掉它:后台页面不加载 lazySizes 运行时,原生 loading 也不会被主题那套
接管;与 UsersMenusVerify 的后台缩略图保持一致(光 <img src>)。

验证:tests/widget-system/ 459/459 通过(此前 458/459)。
2026-10-09 12:04:48 +08:00
kate522 89ae462610 Merge pull request 'fix(admin): 支付中心分页条改回四按钮式' (#39) from worktree/pay-pages-pagination-style into main
Reviewed-on: #39
2026-10-09 03:56:25 +00:00
kate522 afd08885fc fix(admin): 支付中心分页条改回四按钮式
AdminListPagination 的输出标记从 WP 原生 paginate_links() 换回「卡密管理」
原版的四按钮式:`« ‹ 第 X 页,共 Y 页 › »` +「每页 X 共Y」计数,没有数字页码
链接。七个页面调用点不变,外观统一为卡密管理那一套。

- 删除 $total_pages <= 1 早退:只要总数 > 0 就渲染分页条,单页时四枚按钮全
  disabled —— 与原版 render_pagenavi 行为一致
- 基准 URL 与页码夹取沿用现有实现(显式拼装、夹到 [1, total_pages]),
  这两处缺陷修复不动
- 标题属性由 esc_attr_e() 改为 esc_attr__():输出相同,且同文件与 dev harness
  都只用后者
- 新增私有静态 print_assets(),由 render() 调用并以 $assets_printed 保证每页
  只输出一次;内容只有 .tablenav-pages a.disabled { pointer-events: none; }
  及其注释。这些原生后台页面不加载主题 CSS,故随标记内联

清理 harness 中已无人调用的 number_format_i18n() 与 paginate_links() stub。

验证:tests/admin/ 76 项通过;tests/widget-system/ 458/459(仅剩与本次无关的
lazyload-contract 既有失败);用 git show HEAD~1 取出原 render_pagenavi() 与
新助手在 8 组输入(含单页、总数为 0、per_page 为 0、页码越界)下比对,规范化
空白后输出逐字节一致;harness 渲染售后面板确认四按钮标记与内联样式就位。
2026-10-09 11:49:16 +08:00
kate522 536ac67f3c Merge pull request 'feat(admin): 支付中心列表页统一为 WP 原生分页' (#38) from worktree/pay-pages-pagination into main
Reviewed-on: #38
2026-10-08 14:23:19 +00:00
kate522 7b83893cf6 feat(admin): 支付中心列表页统一为 WP 原生分页
七个支付中心列表页(订单明细 / 售后服务 / 付费文章 / 优惠码 / 创作分成 /
提现审核 / 卡密管理)的分页收敛到共享助手 AdminListPagination,改用 WP 原生
paginate_links() 渲染。

- 基准 URL 显式以 page 参数 + 当前筛选参数拼装,不再让两个参数的
  add_query_arg('paged', ...) 退回 $_SERVER['REQUEST_URI']:链接不再随当前
  请求形态漂移,列条件也不再丢失
- 售后服务从写死的 limit => 100 改为 limit/offset 分页,总数接上原本零调用的
  AfterSaleService::count();after_sale_status 先按状态常量归一,保证 count()
  与 admin_list() 口径一致,分页条不说谎
- 每页 20 条,统一来自 AdminListPagination::DEFAULT_PER_PAGE
- 每页在查询前夹取页码,越界时回退到最后一页并重查,杜绝「空表且没有分页条」
  的死胡同;页码夹取与早退也一并收敛到助手
- 提现审核的翻页链接排除 retry_id / retry_key 两个一次性动作参数
- 订单明细的标签页与翻页链接共用同一份筛选参数,不再各写一份

清理死代码:五个页面里近乎复制的 render_pagination()(其中订单明细与提现审核
两份从未被调用)、两页重复的内联 paginate_links 块、卡密管理的 render_pagenavi()
及其 docblock、PayChargeCards::DEFAULT_PER_PAGE 常量,以及只服务自定义禁用
按钮的 .tablenav-pages a.disabled 规则。

验证:tests/admin/ 76 项通过(新增 pay-pages-pagination.test.cjs,重写
charge-cards-pagination.test.cjs);用 git show HEAD 取出原文件对比,订单明细
与售后服务两页在新旧实现下渲染输出逐字节相同。
2026-10-08 22:22:08 +08:00
kate522 83c164a427 feat(admin): 订单明细页已支付订单新增「退款」按钮
操作栏「详情」右侧为已支付订单渲染「退款」按钮:点击经 aksrt_pay_refund_order 把订单推到已退款。

退款沿既有的受闸路径执行:OrderRepository::update_status 要求 allow_refund,且 can_finalize_order_refund 要求该售后工单仍为待审核/处理中。因此工单号由服务端按订单号反查 find_active 得到,客户端只提交订单号;没有进行中的工单时整次操作中止并给出可操作提示,不会出现订单已退款但无工单依据的状态。

按钮仅在已支付订单上渲染——已退款是已支付的唯一后继状态,其他状态点击也只会在服务端被拒。附带清理 AfterSaleService::find_active 上方一处早已错配的 @param 文档注释(描述的是 \,与该函数签名无关)。
2026-10-08 21:14:56 +08:00
kate522 5fd8c6fc31 feat(after-sale): 售后面板新增「标记订单已退款」勾选项
展开的操作面板在状态下拉与备注旁新增「标记订单已退款」勾选框:勾选后点击确认,会先把关联订单推到已退款,再更新售后工单状态。订单本已退款时勾选框呈现为不可改的已选状态,且不提交该标记。

顺序不能反:OrderRepository::update_status 的退款闸门要求售后工单仍为待审核/处理中,一旦 set_status 先执行就不再放行。因此退款失败时整次操作中止,避免出现「工单已关、订单未退」的半完成状态。订单号由服务端按 after_sale_id 反查,不经客户端传递。

AfterSaleService::get() 由 private 改为 public 以支撑该反查。dev harness 扩展为可驱动 handler 的六个场景,覆盖勾选/未勾选、重复退款、非已支付订单、已关闭工单与非法状态。
2026-10-08 21:03:23 +08:00
kate522 b733e41993 fix(admin): 售后展开面板删除渠道结果并铺满状态面板宽度
展开详情去掉「渠道结果」字段,并清理其已无人读取的 gateway_result / gateway_text 解析。详情字段栅格由 auto-fill 改为按断点固定列数:普通字段 10 项可被 2 / 5 整除,配合整行的「申请说明」,行尾不再留白。状态面板去掉 max-width:720px,改为整行 flex——售后状态下拉与备注横向排布占满左侧,取消/确认贴右端,消除右侧大片空白。
2026-10-08 19:01:56 +08:00
kate522 88669f6989 refactor(after-sale): replace review decisions with direct status panel
售后面板改为状态下拉(待审核/处理中/已完成/已拒绝/已取消)加确认/取消按钮:取消仅收起手风琴,确认为纯状态更新;删除已通过状态、review() 决策机制及其专用退款流水线,无双路无迁移;举证图片并入申请说明列与详情整行。
2026-10-08 11:05:08 +08:00
kate522 80373746f8 feat(admin): 售后列表改为手风琴展开详情并内联审核表单 2026-10-07 23:38:30 +08:00
kate522 d2034f5031 test(admin): 契约覆盖点击展开的操作面板与批量操作 2026-10-07 08:46:43 +00:00
kate522 ad2290cbb7 feat(admin): 售后操作列改为点击「操作」展开快捷面板;新增顶部批量通过/批量拒绝(含复选框与全选) 2026-10-07 08:46:41 +00:00
kate522 c870f08395 test(admin): 契约覆盖售后快捷操作 2026-10-07 08:42:09 +00:00
kate522 80fb4068d1 feat(admin): 售后操作列改为 WP 文章列表式 row-actions 悬停快捷操作(JS POST 提交,拒绝时 prompt 填备注) 2026-10-07 08:42:07 +00:00
kate522 01cd734989 test(admin): 契约覆盖举证图片列 2026-10-07 08:36:05 +00:00
kate522 f44180d06c feat(admin): 售后服务表格新增「举证图片」列,展示申请上传的图片缩略图 2026-10-07 08:36:03 +00:00
kate522 c7d18d426c test(admin): 契约覆盖售后表格新列与策略摘要 2026-10-07 08:32:16 +00:00
kate522 0ec405f566 fix(admin): 售后服务页表头对齐售后策略配置项:原因/申请资料/申请说明分列,页头展示策略摘要 2026-10-07 08:32:14 +00:00
kate522 dd320c99c1 test(admin): 契约测试同步菜单结构调整(无 Tab/独立售后菜单) 2026-10-07 08:28:30 +00:00
kate522 fc75d7b810 chore(admin): 删除统计页专用的 get_admin_order_stats(已无调用) 2026-10-07 08:28:27 +00:00
kate522 b3012b3133 feat(admin): 订单明细页去掉 Tab 分页;售后独立为「售后服务」子菜单;删除统计页 2026-10-07 08:28:25 +00:00
kate522 ab6c2339a0 feat(admin): 支付中心新增「售后服务」子菜单 2026-10-07 08:28:23 +00:00
kate522 3eb9cc739c style(modal): 售后与订单弹窗底部按钮满幅化并优化悬停反馈 2026-10-07 10:18:48 +08:00
kate522 e9a1a75259 fix(styles): 还原弹窗 footer 相邻按钮分界线并补悬停阴影
被平铺规则的 border:0 抹掉的 legacy 分隔线按家族色还原,售后四弹窗与订单详情同款;更新构建产物与契约测试。
2026-10-07 09:53:10 +08:00
kate522 d69e1d33c3 fix(orders): 修复再次申请售后被 has_application 分流回售后详细的问题并对齐底部按钮观感 2026-10-07 09:43:22 +08:00
kate522 8023e2e472 feat(after-sale): 支持撤销售后工单并接入人机验证 2026-10-07 09:20:59 +08:00
kate522 918ca371be chore(repo): 行尾规范化,恢复索引 LF 契约
远端 9 个文件以 CRLF 入库,违反 .gitattributes「索引一律 LF」声明,
在 autocrlf=true 的工作区产生永久假脏并阻塞合并。仅行尾变化,无内容改动。
2026-10-07 09:13:42 +08:00
kate522 9e3267fef4 test(payment): 契约测试同步弹窗底部与记录卡片新行为 2026-10-06 23:50:33 +00:00
kate522 6081e8dcc9 style(payment): 订单详情底部适配主题按钮网格;记录卡片新增样式 2026-10-06 23:50:31 +00:00
kate522 c801ff5047 feat(payment): 订单详情底部改用主题按钮样式;记录卡片加查看详细与原因/申请理由 2026-10-06 23:50:30 +00:00
kate522 8460132feb feat(payment): 售后详细弹窗底部精简为单个主按钮,去掉阻断文案 2026-10-06 23:50:28 +00:00
kate522 732f615a09 style(payment): 炫彩标题区样式扩展到订单详情弹窗 2026-10-06 18:27:27 +00:00
kate522 738abe5102 style(payment): 订单详情弹窗 modal-mini 几何(400px) 2026-10-06 18:27:25 +00:00
kate522 915311dcb6 feat(payment): 订单详情弹窗统一为 modal-mini + 蓝色炫彩标题区 2026-10-06 18:27:23 +00:00
kate522 c200427358 test(payment): 售后契约测试同步结构化表单与可再次申请新行为 2026-10-06 18:08:08 +00:00
kate522 7b5dcf16a1 style(payment): 订单详情弹窗售后记录卡片样式 2026-10-06 18:08:06 +00:00
kate522 2db2414270 style(payment): 订单详情弹窗售后记录改为卡片式 UI 2026-10-06 18:08:04 +00:00
kate522 365b2eafe5 feat(payment): 售后详细弹窗申请表单分行展示(原因/申请资料/申请说明) 2026-10-06 18:08:02 +00:00
kate522 ea88499996 feat(payment): schema 版本升至 2.5.2(apply_form 列迁移) 2026-10-06 18:08:00 +00:00
kate522 f4ff3e16d4 feat(payment): schema 2.5.2 新增 order_aftersale.apply_form 列 2026-10-06 18:07:58 +00:00
kate522 c67d5ae4bc feat(payment): 可再次申请售后按工单状态判定(rejected/cancelled 可再次申请) 2026-10-06 18:07:56 +00:00
kate522 00a087b1a4 feat(payment): 售后申请表单结构化入库(预置原因/申请资料/申请说明独立存储) 2026-10-06 18:07:53 +00:00
kate522 a0f59826fe fix(payment): 售后弹窗滚动容器改用 no-scrollbar,消除弹窗边缘滚动栏
mini-scrollbar 是 3px 可见细滚动条(举报弹窗 600px 宽弹窗用的写法);
modal-mini 这类带炫彩横幅的表单弹窗,主题统一走禁封申诉/记录弹窗的口径:
scroll-y + no-scrollbar 完全隐藏滚动条(含细滚动条)+ 50vh 内层滚动。
申请与售后详细两个滚动容器一并切换,滚动行为不变、只是不再露出滚动栏。
2026-10-06 23:38:18 +08:00
kate522 e7e281f10c fix(payment): 售后入口监听改为脚本加载即挂载,去掉 auto_fun 时序依赖
入口本就是 document 级委托、不需要 DOM 扫描,此前只挂在 auto_fun 上等于
多依赖一次全局重扫的触发时机;脚本加载时立即挂载(auto_fun 钩子保留作幂等
重扫),任何时刻的首次点击都能同步弹窗。
2026-10-06 23:32:19 +08:00
kate522 93579cbc9f fix(payment): 售后弹窗改为按钮载荷同步弹出,修复首次点击无反馈
原实现是「点击 → 先请求 /orders/{n} → 再弹窗」,与项目里所有可用弹窗
(含举报链路 report.js)不同构:举报弹窗把数据放在按钮 data-* 属性里同步
弹出。前置请求会让首次点击在请求返回前毫无反应,体感就是"得二次点击"。

- 按钮 data-aksrt-after-sale-apply / -detail 携带订单与售后状态载荷
  (PHP 模板与 order-center.js 的 actionHtml 同构生成),点击当拍即开
  对应弹窗:申请表单 / 超时效提示 / 售后详细,零前置请求
- 「再次申请售后」同样使用已渲染载荷,不再重新拉取订单
- 提交与图片上传仍走 REST,服务端校验不变;列表刷新后载荷随之更新
- jsdom 多脚本环境实测:三种入口均在点击同一拍弹出且 fetch 计数为 0
2026-10-06 23:29:59 +08:00