Commit Graph
21 Commits
Author SHA1 Message Date
kate522 7f556892ad fix(vip): align modal copy fields with reference theme backend
Rename and reposition the two VIP modal copy settings to match the zibll reference backend, drop dead renew/upgrade desc config, and align copy defaults.

- pay_user_vip_desc: modal top intro -> 会员介绍, textarea -> input (one-line), zibll help text, default copy from zibll

- pay_user_vip_more: bottom note -> 开通会员更多内容, rows 4 + sanitize_type html (HTML was stripped on save), zibll help text and three-div default

- Both fields move from the member-level group to a new 界面文案 (modal-copy) group at the end of the VIP section; dependsOn any-of-two-levels adapted from zibll's pay_user_vip_1_s dependency

- Copy defaults synced in three places (SPA schema, PHP schema, PaymentRuntime fallbacks, since Settings::get_all() does not merge schema defaults): 黄金会员/钻石会员, 尊享专属特权, zibll four-item equity list

- Remove vip_renew_desc / vip_upgrade_desc: AKSRT has no renew/upgrade card render surface (render_vip_card takes no type) and zero consumers repo-wide; zibll renders them on page-level cards only

- pay_user_vip_1/2_equity and pay_vip_pass_charge_desc gain sanitize_type html so admins no longer lose list/HTML markup on save

Verification: new tests/widget-system/vip-modal-copy-fields.test.cjs (6 contract tests); node --test tests/**/*.test.cjs 634/634 pass; php -l clean on both changed PHP files; assets/admin npm run build succeeds
2026-10-18 14:30:15 +08:00
kate522 ce21cc2b9b revert fa476af70e
revert refactor(pay): 充值商品以充值金额为唯一真值,移除销售金额与折扣

充值商品行此前是双值模型:price 充值金额决定到账、pay_price 销售金额决定支付,
pay_price 为 0 时回落到 price,否则即「付更少拿更多」的折扣。该模型把三处耦合在
一起——后台 schema 暴露销售金额输入、线格式首段携带支付额、下单时计价与到账分离。
只改其中一处就会出现「后台不再可配但前端仍在展示折扣」或「展示已合并但下单仍按
旧价扣款」的静默不一致,故本次三层一并收口,充值金额即实际支付金额。

后台 schema 有两份且必须同步:SPA 侧 recharge.js 负责渲染表单,PHP 侧 SchemaPayment
负责默认值与清洗。只改一份会让界面不再可配而默认值仍在写 pay_price。

线格式三段 "支付|到账|标题" 保持不动,仅为兼容历史已存的字符串配置:支付段不再读取
任何配置来源,恒等于充值金额,故历史配置里的折扣价会被忽略。旧数据无需迁移,pay_price
键留在库中只是不再被读取,从重建后的后台保存一次即自然消失。

行为变化(需知悉):
- 已配置折扣的站点,其用户将按充值金额全额支付,即对这些用户是涨价。这是「不做优惠
  和促销」的必然结果。
- parse_packages 的校验口径随之变松:有效性只由到账段决定,故 "abc|10|x" 这类首段
  非法、到账段合法的行会被解析为 10 元档,而旧实现两段都作金额校验、会丢弃。理由是
  支付段已不表达任何含义,因一个无用字段是垃圾就丢弃一条本来有效的档位只会让运营困惑。
  既有数据不受影响——旧格式化器写出的首段恒为数字,只有手改出的脏数据才可能命中。
  该取舍已写入方法文档。

- recharge.js / SchemaPayment:删除 pay_price 字段与三档默认值中的该键,help 去掉
  「同时支持设置折扣」
- PaymentRuntime::format_product_lines:不再读取 pay_price,支付段由充值金额充当
- BalanceServiceCharge::parse_packages:不再产出 pay_price 键,金额唯一来源为到账段
- BalanceServiceCharge::create_charge_order:支付额与到账额同源于 price
- credits-wallet.php:移除销售金额行、「省X」折扣徽标及仅服务折扣的差额计算
- BalanceServiceRest:仅注释改写,说明积分路径的 pay_price 是售价而非折扣
- 新增 tests/widget-system/recharge-product-price-contract.test.cjs:5 条跨层契约

范围边界:积分商品 pay_points_product 的 pay_price 是「积分|支付|标签」里的实际售价,
本身不含折扣语义,保留不动。契约测试以正向断言固定该边界,避免日后被误当作同类问题
一并删掉。

验证:新增契约测试 5 项通过;node --test 全量 375 项 / 375 通过(原 370 项);PHPUnit
44 项 / 106 断言通过;改动的 PHP 文件 php -l 全部通过。变异验证:把 create_charge_order
改回按 pay_price 计价、把 pay_price 重新注入模板,对应断言分别转红,证明回归测试拦得
住回退。另以反射调用真实代码做端到端执行验证 11 项全过,覆盖结构化数组 -> 线格式 ->
商品数组全链路、数组内残存 pay_price 被忽略、历史折扣字符串(98|100|旧折扣档 取 100)、
到账段为 0 或非法时跳过等边界。

部署提示:assets/admin/build 为部署时构建、未入库,后台表单的改动需在目标机执行
cd assets/admin && npm ci && npm run build 后才会生效。前端 credits.js 走 filemtime
版本号,无需手工清缓存。
2026-09-19 03:25:12 +00:00
kate522 fa476af70e refactor(pay): 充值商品以充值金额为唯一真值,移除销售金额与折扣
充值商品行此前是双值模型:price 充值金额决定到账、pay_price 销售金额决定支付,
pay_price 为 0 时回落到 price,否则即「付更少拿更多」的折扣。该模型把三处耦合在
一起——后台 schema 暴露销售金额输入、线格式首段携带支付额、下单时计价与到账分离。
只改其中一处就会出现「后台不再可配但前端仍在展示折扣」或「展示已合并但下单仍按
旧价扣款」的静默不一致,故本次三层一并收口,充值金额即实际支付金额。

后台 schema 有两份且必须同步:SPA 侧 recharge.js 负责渲染表单,PHP 侧 SchemaPayment
负责默认值与清洗。只改一份会让界面不再可配而默认值仍在写 pay_price。

线格式三段 "支付|到账|标题" 保持不动,仅为兼容历史已存的字符串配置:支付段不再读取
任何配置来源,恒等于充值金额,故历史配置里的折扣价会被忽略。旧数据无需迁移,pay_price
键留在库中只是不再被读取,从重建后的后台保存一次即自然消失。

行为变化(需知悉):
- 已配置折扣的站点,其用户将按充值金额全额支付,即对这些用户是涨价。这是「不做优惠
  和促销」的必然结果。
- parse_packages 的校验口径随之变松:有效性只由到账段决定,故 "abc|10|x" 这类首段
  非法、到账段合法的行会被解析为 10 元档,而旧实现两段都作金额校验、会丢弃。理由是
  支付段已不表达任何含义,因一个无用字段是垃圾就丢弃一条本来有效的档位只会让运营困惑。
  既有数据不受影响——旧格式化器写出的首段恒为数字,只有手改出的脏数据才可能命中。
  该取舍已写入方法文档。

- recharge.js / SchemaPayment:删除 pay_price 字段与三档默认值中的该键,help 去掉
  「同时支持设置折扣」
- PaymentRuntime::format_product_lines:不再读取 pay_price,支付段由充值金额充当
- BalanceServiceCharge::parse_packages:不再产出 pay_price 键,金额唯一来源为到账段
- BalanceServiceCharge::create_charge_order:支付额与到账额同源于 price
- credits-wallet.php:移除销售金额行、「省X」折扣徽标及仅服务折扣的差额计算
- BalanceServiceRest:仅注释改写,说明积分路径的 pay_price 是售价而非折扣
- 新增 tests/widget-system/recharge-product-price-contract.test.cjs:5 条跨层契约

范围边界:积分商品 pay_points_product 的 pay_price 是「积分|支付|标签」里的实际售价,
本身不含折扣语义,保留不动。契约测试以正向断言固定该边界,避免日后被误当作同类问题
一并删掉。

验证:新增契约测试 5 项通过;node --test 全量 375 项 / 375 通过(原 370 项);PHPUnit
44 项 / 106 断言通过;改动的 PHP 文件 php -l 全部通过。变异验证:把 create_charge_order
改回按 pay_price 计价、把 pay_price 重新注入模板,对应断言分别转红,证明回归测试拦得
住回退。另以反射调用真实代码做端到端执行验证 11 项全过,覆盖结构化数组 -> 线格式 ->
商品数组全链路、数组内残存 pay_price 被忽略、历史折扣字符串(98|100|旧折扣档 取 100)、
到账段为 0 或非法时跳过等边界。

部署提示:assets/admin/build 为部署时构建、未入库,后台表单的改动需在目标机执行
cd assets/admin && npm ci && npm run build 后才会生效。前端 credits.js 走 filemtime
版本号,无需手工清缓存。
2026-09-18 23:56:31 +08:00
kate522 db0d63b99f fix(pay): 会员卡密单密码默认关闭,卡密盒与其他弹窗一致显示卡号+密码
会员购买/续费弹窗卡密盒此前仅显示卡密输入,与其他两个弹窗(卡号+密码)
不一致。根因是 pay_vip_pass_charge_only_password 的默认值偏离参考主题:

- PaymentRuntime:vip 类型 only_password 由「未设置即视为开启」改为
  !empty(),与其他两类型同构(参考主题 default false)
- ChargeCard:get_public_options 的 vip 回退值 only_password true→false
- SchemaPayment + recharge.js:会员卡密单密码模式开关 default true→false
- 契约测试同步锁定默认关闭与无 isset 回退
- admin SPA 重新构建

已保存过设置且该键被持久化为开启的站点,需在后台「余额充值 → 卡密
兑换 → 会员卡密单密码模式」手动关闭一次。
2026-09-18 17:26:50 +08:00
kate522 b88eab0bfe feat(pay): 卡密兑换入口收敛到三个购买弹窗并对齐参考主题
- 移除余额卡片独立「卡密兑换」通用弹窗,兑换入口分布到充值/积分/会员三个弹窗的支付方式中
- 充值弹窗补齐卡密 logo 与仅卡密时的金额选择隐藏逻辑
- 积分购买弹窗 1:1 复刻参考主题 points-pay modal(商品档位/自定义/支付方式/立即支付),REST 改为 product+custom 契约
- 会员弹窗注入卡密渠道:视图模型透传 card_pass,前端渲染卡密盒并直兑 /pay/card-pass/redeem type=vip
- 后台卡密兑换拆分为余额/积分/会员三个独立开关,VIP 段旧会员卡密组清理
- REST type 改为必填(balance/vip/credits),三类型独立闸门
- 测试重写为 card-pass-modal-redeem 契约,321 项全部通过
2026-09-18 12:25:18 +08:00
kate522 3481620ed0 feat(payment): 通用卡密兑换弹窗并修正核销订单实付与订单名称
- /user/balance/ 余额卡片入口改为通用「卡密兑换」弹窗:请求不带类型,
  后端按卡密自动识别余额/会员/积分;卡号输入恒展示且选填
- 后台「余额充值 → 卡密充值」语义更新为「卡密兑换」,开关更名
  「启用卡密兑换功能」(设置键不变),双源 schema 同步并重建 SPA
- 删除死代码:credits-vip.php 死文件、credits-balance.php 内联积分
  兑换块、/pay/card-pass/options 路由与 rest_options、labels 数组、
  asset_points_card_description/password_only 死字段及内联块专属 CSS
- 卡密核销订单实付恒 0:create_redeem_order 源头写 0,UserOrders
  对 card_pass 订单视图层归零覆盖历史行(不迁移数据)
- 订单名称按 note.meta 生成:卡密兑换-余额充值X / 卡密兑换-积分充值X /
  购入[会员档位名]X天(永久)
- 新增契约 card-pass-universal-redeem.test.cjs,收紧 user-assets-layout
  契约(禁 .uc-card-pass 根类回潮)
2026-09-17 19:04:47 +08:00
kate522 678143e7b9 feat(payment): 卡密管理改为独立页面并对齐参考主题
- 移除「余额充值」设置中的充值卡(card_pass_*)配置组,PHP schema 与 SPA mirror 双轨同步
- 重写后台卡密管理页:列表过滤/排序/搜索/批量删除/同款分页/点击复制、自动生成与导入、text/xls 导出
- ChargeCard 服务新增 generate_cards/rand_number/rand_password/delete_by_ids/get_export_rows,get_list 支持参考主题排序别名与标识过滤
- 删除无消费方的 /payment/charge-cards REST 路由及 batch_create/disable 死代码,数据层零迁移
2026-09-16 22:05:37 +08:00
kate522 14f9534651 fix(payment): 充值商品选项旧字符串值导致假条目且不可删除
- SchemaProvider 读取时 group/repeater 字段忽略非数组旧值(textarea 时代的
  字符串),回退默认数组,避免前端按字符渲染出 20+ 条假条目
- AksField group/repeater 渲染改为数组安全视图(非数组一律按空列表)
- 充值商品选项默认条数调整为 3 条(PHP 与前端 schema 同步)
2026-09-16 19:46:49 +08:00
kate522 a48007a44d feat(payment): 支付&付费菜单按参考主题重构并新增提现策略页
- 子菜单重组为知识付费/余额充值/VIP会员/创作分成/推广返佣/收款接口/提现策略
- 收款接口页 1:1 复刻 Zibll 双下拉结构,仅保留支付宝/微信/PayPal/Stripe/易支付
- 订单前缀/流水号前缀/提现单号前缀配置保留并移入收款接口页
- 知识付费/推广返佣按参考主题全字段复刻,余额充值并入充值卡配置
- 新增 tabbed/between_number/page_select 表单控件及后端 pages 搜索源
- 清理旧 SPA 组件、无消费者 REST 端点与废弃配置键(不写双路兼容)
- 更新存量契约测试至新 schema 文件
2026-09-16 19:18:28 +08:00
kate522 5cae5b5c93 积分与余额账务系统硬切重构 2026-08-24 15:59:11 +08:00
kate522 a0b84977a2 feat(navigation): hard-switch to Zibll navigation and Font Awesome 5 2026-08-18 20:46:21 +08:00
kate522 179d577d28 fix(credits): align asset actions and withdrawal settings
Use matching outlined controls on the points card and manage the
balance-withdrawal switch exclusively from the withdrawal settings page.
2026-08-13 15:35:01 +08:00
kate522 1247f9bf4e feat(credits): exchange balance for points
Replace the legacy points-to-balance and external points purchase flows
with direct integer balance-to-points exchange. Enforce exchange and
points-transfer limits and capability checks across the UI and REST API.
2026-08-13 15:20:06 +08:00
kate522 dacd0095bf feat(users): normalize center routes and withdrawal limits 2026-08-12 19:44:47 +08:00
kate522 3267bee71e fix(payment): wire balance wallet end-to-end when pay_balance_s is on
Opening 余额功能 alone now enables cash-wallet pay (unless 余额支付 is explicitly off). Drop points-as-balance fallback, stop fake method injection, expose real wallet in cashiers, and honor auto_to_balance on recharge fulfill.
2026-07-25 12:46:38 +08:00
kate522 d57fc6f934 feat(user-center): points buy, balance withdraw, and asset record tabs
Add cash purchase of points (points_pay_s), wallet withdraw requests via
AKSRT_Withdrawal, Zibll-style dual-card layout with tabbed balance/points
ledgers, and admin switches for buy-points packages and balance withdraw.
2026-07-16 15:38:55 +08:00
kate522 d34c954b83 feat(pay): card-pass redeem for VIP and balance (zibll-style)
Rewrite charge-card into typed single-use card_pass inventory with public redeem REST, user-center UI for balance/VIP, admin type-aware create/batch, and CAS mark-used fulfillment via Credits/activate_vip.
2026-07-14 20:13:46 +08:00
kate522 c93b303453 feat(payment): finish Zibll key contract and wire checkout gateways
Drop dual-read payment runtime fallbacks, align PHP schema to Vue keys,
read gateway credentials only from aksrt_settings with enable toggles,
expose configured adapters at checkout, fix credits pay signatures, and
apply order expiry settings. Wire orphan order/card-pass/withdrawal
schema pages; delete unused Payment* wrappers.
2026-07-11 17:42:35 +08:00
kate522 d9fbacbce6 feat(payment): align VIP/balance/order schema keys with Zibll
Extract payment readers into AKSRT_Settings_Payment_Runtime and store
canonical Zibll option IDs (pay_user_vip_*, pay_balance_*, pay_box_position,
pay_mark, pay_rebate_*, pay_income_*) in aksrt_settings with no legacy
payment_* dual-read. Update PHP/JS payment schemas and VIP sidebar gate.
2026-07-11 17:13:29 +08:00
kate522andClaude Fable 5 ba61a20b34 Schema 收口第三轮:继续对齐 payment/post-list 默认值与依赖
继续 Workstream C,对 payment 与 post-list 做高影响字段收口:

- payment.recharge:对齐 Zibll pay_balance_s 默认=true,并在 PHP schema 层补齐 recharge
  主开关下的 mode / desc / auto_to_balance / packages / product / transfer / pass-charge /
  exchange 等 dependsOn,恢复“总开关 -> 子配置”的配置展开节奏。
- payment.vip:对齐 Zibll 续费默认心智,payment_vip_renew_price_type 改为 discount,
  payment_vip_renew_discount 改为 8,payment_vip_renew_reduce 改为 20;同时补齐
  renew / upgrade 在 PHP schema 层的 dependsOn,并补上 reduce 选项。
- post_list.list:将默认卡片样式从 AKSRT 自定义的 standard 收敛到更接近 Zibll 的 thumb,
  同时补齐 card 选项,减少列表主线心智偏差。

验证:
- php -l 通过:class-aksrt-admin-schema-payment.php / class-aksrt-admin-schema-post-list.php
- node --check 通过:payment/recharge.js / payment/vip.js / post-list/list.js

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 20:07:09 +08:00
Claude Code 1268a55dd0 导入 AKSRT 主题开发源码 2026-07-03 22:50:34 +08:00