Commit Graph
100 Commits
Author SHA1 Message Date
kate522andClaude Opus 5 39aed0d430 fix(admin): show the real default URL for level and VIP icons
用户等级配置的「等级图标 URL」和 VIP 的「会员图标」在后台显示为空白输入框,
但前台实际渲染的是主题自带图标——后台既看不到当前效果,也无法判断该字段
是否已被配置。根因是 schema default 写成空串,而运行时(Level::
get_level_icon_url() / PaymentRuntime::get_vip_icon_url())在值为空时回退
到 assets/img 下的内置图标。

把 schema default 改为直接写入主题自带图标 URL,与运行时回退链保持同一路径、
同一 is_file 守卫:后台展示的就是前台真正使用的图标,清空则回到文本/FA 回退。

- SchemaUsers::default_level_options():icon_img_N 写入 user-level-N.png
- SchemaPayment::vip_icon_default():vip_N_img_icon 写入 user/vip/vip-N.svg
- level.js / vip.js 同步默认值,help 与 placeholder 文案改为描述默认图标
- 两个测试 harness 补齐 get_theme_file_uri/path stub(schema 现在需要它们)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-02 14:06:52 +08:00
kate522andClaude Opus 5 427968a721 chore(branding): remove leftover upstream theme identifiers
The theme was renamed Zibll/子比 → AKSRT → Jio, but upstream branding
survived the sweeps in CSS classes, the SVG sprite prefix, a persisted
widget field ID, JS events, admin Vue class names, test infrastructure
and docblocks.

Renames:
- zib-widget / zib-widget-wrap / zib-slider → jio-widget-box /
  jio-widget-box-wrap / jio-slider-box (jio-widget is taken by the modern
  widget shell, jio-box-* by the card primitives)
- zib-partners-scroll + zps-* → jio-partners-scroll + jps-*
- zib-combo-info-card + zci-* → jio-combo-info-card + jci-*
- zibsvg- → jiosvg-, including the exported picker helpers and the
  fa-zibsvg- family-prefix guard
- zibpay_type → pay_type; the dual-read fallback in PostQuery collapses
  to a single key
- [zibajax="submit"] dropped (no PHP emitter); zib_ajax.success →
  jio_ajax.success
- aks-* admin Vue classes → jio-*
- zib_palette() → palette()

User-facing vendor traces are gone: the floating "more" button default no
longer ships a zibll.com link or 子比主题 marketing copy, the notice
widget ships no preset promo entries, and the four 官网教程 links are
removed from the post-list admin schema.

Test infrastructure renamed to neutral names (docker-compose.reference.yml,
Caddyfile, article-baseline.json, modern-widgets-contract.test.cjs) with
their DB/volume/env/slug identifiers following.

Kept intentionally, documented in tests/fixtures/README.md: the golden
fixture reference fingerprint (a SHA-256 record of an external directory,
read by validate-widget-golden / generate-widget-golden-fixture /
audit-widget-system), the doesNotMatch guards that prove the old tokens are
gone, and the reference theme's own meta key in the visual fixtures.

No backward-compat or data migration: saved widget configs holding old
icon keys or the old field ID silently lose them, per the project's
rewrite-over-compatibility rule.

Verified: 132/132 node contract tests, php tests/widget-system/run.php
(146 assertions), audit-admin-contracts, audit-psr4-paths and
validate-widget-golden all green; tracked bundles regenerated and in sync.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-02 00:06:54 +08:00
kate522andClaude Opus 5 42cc64106d docs: point the theme folder references at Jio, not Jio-theme
The mechanical rename turned AKSRT-theme into Jio-theme, but the
directory itself is Jio. Fix the three places that name the folder
(README install steps and tree, wp-cli-visual-fixtures usage comment,
DocsPage docs deep-link) and rebuild the SPA bundle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:12:25 +08:00
kate522andClaude Opus 5 35bb96e82f refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:05:04 +08:00
kate522andClaude Opus 5 5b16bc6e15 fix(frontend): route the VIP points-exchange entry through the custom currency name
/user/vip/ 档位购买卡下方的入口横条仍硬编码「积分兑换会员」,而后台
「积分配置 → 自定义货币名称」改名后不跟随。上一轮改名只覆盖了兑换弹窗
标题与会员弹窗内入口,页面自身的入口横条是另一处服务端渲染,漏改了。

入口横条(inc/helpers/aksrt-vip.php)
- aksrt_get_vip_points_exchange_entry_html 改取已加载的
  catalog.currency_name,回退 Settings::get_currency_name() 再回退「积分」

同一页面上其余漏改的兑换文案一并收口,命名与入口/弹窗保持一致:
- VipServiceModal:积分不足提示 → {货币名}不足,暂时无法兑换
- VipServicePurchase.exchange_with_points:兑换未启用 / 兑换无效 /
  不足三处 WP_Error、流水说明、订单备注(%1$s兑换会员 %2$d %1$s。)
  currency_name 在此单独解析,get_catalog 内的局部变量不在该作用域
- LedgerPresentation:vip_points_exchange 流水原因标签

契约测试新增源断言,并用两个 PHP harness 做运行时断言:入口横条
(改名后 / 已是会员不输出 / 缺 key 回退)与弹窗(余额充足 / 不足两分支)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 16:19:49 +08:00
kate522andClaude Opus 5 5c6b422866 fix(frontend): route every user-center points label through the custom currency name
后台「积分配置 → 自定义货币名称」改名后,用户中心仍有大量硬编码
「积分」:做任务赚积分 / 购买积分 / 签到领积分、积分记录 / 积分任务、
每日可免费获取 XX 积分、我的积分、积分+1、创作中心积分收益等。

get_currency_name() 早已存在且可用,问题只是这些文案没有走它。
本PR 全部替换,无双路、无迁移:

服务端渲染(用户中心 renderers)
- credits-balance.php:购买/做任务赚/签到领 + 整个购买弹窗
- profile-credits.php:积分记录 / 积分任务 页签
- credits-points-tasks.php:每日上限三态与空态
- sidebar-creator.php / profile-creator.php:积分收益
- transfer-modal.php:积分转账提示
- Signin.php:签到详情弹窗(我的积分 / 奖励 tooltip / 积分+N)
- VipServiceModal.php:我的积分 / 积分兑换会员
- download-permission-card.php:购买价格

客户端渲染(JS 无法调用 PHP,注入 currencyName 到 aksrtData)
- signin.js:签到状态行「已签到 N 天 +1」
- credits.js:转账标题/金额标签 + 购买提示 toast
- cms-download.js:积分不足视图、我的积分 入口、余额不足文案
- pay-vip.js:积分兑换会员入口(优先 catalog.currency_name)
- order-center.js:订单行单位回退

契约测试同步改为断言模板构造而非死字符串,并新增两例:
改名后跟随、未注入时回退「积分」。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 15:09:49 +08:00
kate522andClaude Opus 5 1c95f94bca refactor(admin): drop the SPA credits asset record browser
「用户近期资产记录」卡片在 SPA 积分配置页里按用户 ID + 资产类型 +
日期查 user meta 历史,再伪装成统一账本行(entries / operation_key /
ref_key)。SPA 只承载配置,运营记录归原生 用户 → 积分/余额 屏幕
(CreditsAdmin / BalanceAdmin),这条平行路径删除,不留双读或迁移。

- CmsCredits.vue: 移除卡片、表格、分页及 ledger* 状态与
  formatAssetValue/loadLedger/searchLedger/resetLedger
- users.js: 删除仅服务该卡片的 getCreditLog()
- UserController: 删除 /assets/transactions 路由、rest_get_credits_log()
  及其唯一调用方 asset_value_to_minor()
- 契约测试改为断言该能力不得回归

points_record / balance_record 本身保留,前端账本与原生后台仍在消费。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 14:20:07 +08:00
kate522 324bcfdadc fix(admin): verify the whole SPA build graph, not just the entry
find_missing_admin_chunks() only parsed index.js, but a lazily
imported page chunk pulls in its own deps (shared-api, PageHeader,
sortable-options…). A deploy that drops one of those still leaves the
entry internally consistent, so the existing notice never fires and the
failure only shows up when an admin opens that menu — every schemaPage
keeps working, which makes the breakage look arbitrary.

The same scan never looked at CSS at all: 18 stylesheets are reachable
from the graph and none of them were checked, so a missing page
stylesheet ships an unstyled screen with no warning.

Walk the module graph transitively from index.js, queueing each
discovered dependency, and match .js and .css specifiers. Deleting
PageHeader now also reports every page that depends on it.

This is a diagnostic hardening only — it makes an incomplete deploy loud
instead of guessing at the cause of a broken page.
2026-11-01 13:41:58 +08:00
kate522 df12f51199 fix(admin): stop cropping the layout preview images in image_select
AksImageSelectField pinned every preview to a 60x60 box with
object-fit:cover, but these are wide layout strips: header layouts are
597x57 (10.47:1), the footer template is 800x190 (4.21:1) and the slide
align set is 200x101. A 10:1 strip inside a square crop keeps ~6% of its
width, so the layout it is supposed to illustrate is unrecognisable.

Constrain the width instead and let the height follow, which is what the
reference theme's CSF image_select does (max-width:100%; height:auto).
Each field now declares the width that suits its images, and an option
may still override it: header 200, footer 240, slide align 160, mobile
header 120.

Only presentation changed. No image files and no stored values moved,
so existing settings are unaffected.
2026-11-01 12:18:14 +08:00
kate522 4740078135 fix(icons): repair the FA5 generator and drop the 404 font references
generate-fa5-icons.php read fa-{brands,regular,solid}.svg from
webfonts/, but only woff/woff2 ship with the theme, so the generator
died on file_get_contents() and the committed fa5-icons.php could not
be regenerated from what the theme actually distributes.

Decode the style split from each shipped woff's cmap table instead.
The split has to come from the font: FA5 assigns different drawings to
the same codepoint per style, so fas/far/fab membership is unanswerable
from the CSS alone. Output is byte-identical to the committed catalog
(1001/151/456), so the picker is unaffected.

all.min.css also declared eot / eot?#iefix / ttf / svg fallbacks for all
three families while webfonts/ holds only woff2 + woff, so a browser
that stops at woff requested six files that do not exist. Add
tools/strip-fa5-legacy-fonts.mjs to keep the src: list to what ships;
it is idempotent and touches nothing but the @font-face blocks.
2026-11-01 11:52:14 +08:00
kate522 9c70d7929a chore(assets): drop the duplicated header-layout previews
assets/admin/public/images/header-layout duplicated
assets/images/header-layout byte for byte (all five PNGs, matching
md5). The directory only existed because assets/admin/public is Vite's
default publicDir, so every build copied it into build/images.

Nothing referenced it: SchemaPageDisplay builds its preview URLs from
assets/images/header-layout via self::asset(), and a repo-wide search
finds no reference to public/images anywhere. Remove the source and let
build/images stop being regenerated.
2026-11-01 11:52:11 +08:00
kate522andClaude Fable 5 869d437485 test(admin): match invite bulk row by class token, not exact attribute
The bulk row gained the shared aksrt-native-bulk class in 1273a013, so the
exact class="aksrt-inv-bulk" string match no longer held.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-11-01 00:22:44 +08:00
kate522andClaude Fable 5 9805a371d8 feat(admin): rebuild the payment center overview with ECharts analytics
- Overview page: realtime today vs. same time yesterday, 6 KPI cards with
  period-over-period deltas, trend (paid / net / refund curves + order count
  line), category curves, payment method donut, top 10 paid content,
  conversion / close / refund rates, todos and shortcuts
- Date presets, custom range and category filter via
  GET aksrt/v1/admin/pay-overview (manage_options + wp_rest nonce)
- Metrics: paid amount by paid date including later-refunded orders, refunds
  by refund date, net = paid - refund; CNY only, points and recharge excluded,
  foreign-currency orders listed separately; integer cents internally
- Daily records cached per month in transients (today/yesterday live),
  invalidated on order status change and on purge
- ECharts 6.1.0 subset bundled to assets/js/runtime/libs/echarts-pay.min.js
  (npm run build:pay-charts), loaded only on the overview page
- Split payment-attempt methods out of OrderRepositoryCore into
  OrderRepositoryAttempts; remove dead get_stats(), cash_decimal(),
  Order::get_stats() and the old .aksrt-native-links styles

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-11-01 00:22:44 +08:00
kate522andClaude Fable 5 d98f8d7975 feat(admin): redesign withdrawal review page and drop dead withdrawal code
- Split PayWithdrawals into shell + PayWithdrawalsList flat sibling trait
- Add process/policy callout, open/paid/fee stats, status views with counts
- Filter by source and payout method; reset keeps the status view
- Show net payout with gross/fee breakdown, copyable payee, note column
- Replace inline select form with per-row actions and a confirm dialog;
  reject requires a reason; double-submit guard; retry reuses the
  idempotency key; redirect back preserving filters and paging
- Withdrawal: add get_status_counts() and method filter; get_stats() now
  returns open_gross / paid_net / paid_fee
- Remove unused REST routes (/payment/withdrawals, /transition),
  admin_withdrawals(), update_status(), has_open_withdrawal(),
  count_open(), resolve_gross_amount()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 21:06:52 +08:00
kate522andClaude Fable 5 1d6bc8f7cc feat(admin): add bulk actions and pending-record deletion to creator income
- Always render the checkbox column and bulk bar; disable with a reason
  instead of hiding when settlement is off or the page has no pending rows
- Replace the batch-settle button with a bulk action select (settle / delete)
  plus apply, matching the charge cards and invite codes pages
- Add per-row delete for pending records and Revenue::delete_pending(),
  guarded by status = 'pending' so settled ledger-backed rows are never removed
- Report done / failed counts for bulk settle and delete

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 19:51:55 +08:00
kate522andClaude Fable 5 b25ebc5fff feat(admin): redesign creator income page with status views and safer settlement
- Split PayIncome into shell + PayIncomeList flat sibling trait
- Add policy callout, per-currency stats, status views, filter card
- Show source post/order/buyer, base amount x ratio, expected settle time
- Confirm single/batch settlement, selection count, double-submit guard
- Redirect back preserving filters; report settled/failed counts
- Revenue: add get_status_counts(), share admin_list_where(), drop dead settle()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 19:37:38 +08:00
kate522andClaude Fable 5 1273a0138e fix(admin): match bulk action select and apply button sizes
- Add shared .aksrt-native-bulk row that locks select and button to the
  same height, font size and line height
- Apply it to the charge cards and invite codes bulk action rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 19:13:09 +08:00
kate522andClaude Fable 5 4f6e17ba5e feat(admin): create and batch-generate coupons in dialogs
- Move "新建优惠码" / "批量生成" into header-launched <dialog>s
- Extract forms into PayCouponsForms trait with shared rule fields,
  hints, validation and currency/percent unit switching
- Generated codes card gets a copy-all button; list codes copy on click
- Drop old inline forms, render_generated_dump and the unread
  aksrt_coupon_generated redirect arg

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 19:03:49 +08:00
kate522andClaude Fable 5 92a3c2b8c7 fix(admin): stop stretching checkboxes full-width in the pay products dialog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 18:45:56 +08:00
kate522andClaude Fable 5 dc6dbc05d8 feat(admin): quick-edit paid post settings in a dialog on the pay products page
- Rebuild aksrt_pay_products as list + in-page quick settings dialog
  (pay type, limit, cash/points prices, sales float, coupon, order expiry, copy)
- Query by _aksrt_pay_type with real pagination; drop order-summary fallback
  and the duplicate "Meta 销量" column
- Centralize pay meta writes in DomainModel::persist_pay_meta(); stop writing
  unread _aksrt_pay_modo / _aksrt_pay_limit keys

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 17:28:45 +08:00
kate522andClaude Fable 5 4083613dbe fix(admin): scroll ticket notes inside their card instead of the whole sidebar
Keep ticket info at its natural height and let the internal notes card fill
the remaining sidebar height, so only the notes list scrolls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 15:34:24 +08:00
kate522andClaude Fable 5 ed526709c8 fix(admin): align ticket sidebar and conversation pane heights
Share one --aksrt-ticket-pane-height between the conversation panel and
the sidebar cap so both columns line up, and drop the sidebar sticky
offset that no longer matches the pane height.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 15:20:45 +08:00
kate522andClaude Fable 5 b9000e1b93 feat(admin): dock ticket reply composer in conversation and move notes to a dialog
Put the reply composer at the bottom of the conversation card so the
timeline and composer form one viewport-height panel; the send button is
visible on load and Ctrl/Cmd+Enter submits. Internal notes now open in a
dialog instead of expanding inline, so the sidebar no longer grows.

Remove the shared ticket_composer helper and the inline note expansion CSS;
both dialogs share ticket_dialog_head.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 15:10:13 +08:00
kate522andClaude Fable 5 54cc5301c3 feat(admin): open ticket creation in a dialog on the list page
Move "代客提交工单" back into a native <dialog> on the ticket list while
the ticket workspace stays a full page. Closing asks before discarding
input, ignores backdrop clicks, resets the form and returns focus; an
uncertain create result keeps the form locked behind "重新加载".

Remove the ?view=new create page route and its styles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 14:57:35 +08:00
kate522andClaude Fable 5 d86a85e6a6 feat(admin): replace ticket dialogs with in-page views
Ticket handling on users.php?page=aksrt_tickets no longer uses dialogs.
The list, the workspace (?id=N) and the assisted create form (?view=new)
are server-rendered page views that carry the list filters and page
for going back. Writes still go through the ticket REST routes; on
success the page reloads with a native notice, and unsent drafts in
other forms survive the reload via sessionStorage. Uncertain or
conflicting writes lock every form and only offer a reload.

Remove dead code: UsersMenusTicketsDialogs, the aksrt_ticket_view AJAX
read and its nonce, dialog CSS/JS (backdrop, scroll lock, focus return,
read races) and the dialog runtime test. Fix the create link carrying
an unclamped page number on out-of-range list pages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 14:45:27 +08:00
kate522andClaude Fable 5 48e54dc115 fix(tests): restore green contract suite
Drop the legacy credits_added message label per the hard-cut rule, switch
three remaining Font Awesome 4 icons to FA5 solid, and align two widget
contracts with the badge rule grouping and renderer list from fc04bf65.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 14:18:01 +08:00
kate522andClaude Fable 5 b32b56f8bc feat(admin): redesign order list and detail workspace
Replace the type/method tab rows with status views backed by one GROUP BY
count, move filters into a single toolbar card, show gateway names, keep
list context across detail and actions, and split the detail page into a
summary/timeline column and an actions/buyer/note sidebar. Confirmations
move to admin-orders.js; PayOrders splits into flat List/Detail traits.

Remove dead code: unused Order AJAX endpoints and init(), get_orders_count(),
shipping flash codes, and the legacy raw-note fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 14:03:57 +08:00
kate522andClaude Fable 5 8c553c7221 fix(admin): auto-dismiss transient ticket dialog feedback
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 12:23:51 +08:00
kate522andClaude Fable 5 7b65b3c6d8 fix(admin): keep ticket internal notes compact
Show only the latest three notes and fold older ones into a details
toggle, collapse the note composer to one line until focused, and cap
the sidebar height to the dialog body so its controls stay reachable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 12:21:53 +08:00
kate522andClaude Fable 5 a9709377bb fix(admin): make ticket "view latest" jump reliably
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 12:13:57 +08:00
kate522andClaude Fable 5 d7616b193e feat(admin): redesign ticket handling dialog as conversation workspace
Render the original question and replies as one chat-style timeline,
merge editor and toolbar into a shared composer for replies and notes,
and refresh sidebar cards. Remove superseded renderers and selectors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 12:02:49 +08:00
kate522andClaude Opus 5 09f3a94cea fix(admin): merge ticket controls into information panel
Edit status, department and assignee directly in ticket information, remove the redundant handling card and its layout rules, and cover editable and closed-ticket rendering.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-31 11:46:15 +08:00
kate522andClaude Opus 5 7f1a0dbeb4 fix(admin): remove duplicate ticket dialog subtitle
Keep the ticket number and status in the sidebar only, remove the unused header description payload and bindings, and update dialog regression coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-31 11:34:21 +08:00
kate522andClaude Opus 5 264015b7e9 feat(admin): streamline ticket management with dialogs
Move on-behalf ticket creation into a header dialog and load ticket handling on demand. Reuse the admin REST write path, preserve drafts and filters, and cover dialog and server boundaries with regression tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-31 11:25:56 +08:00
kate522andClaude Fable 5 b45fd161f0 fix(reports): separate readable categories from report content
Store readable category snapshots separately from details and evidence, validate report categories, and preserve context in admin displays and moderation actions. Widen report categories to TEXT and bump the schema to 3.2.0 without legacy data conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 00:57:13 +08:00
kate522andClaude Fable 5 b2811cc248 fix(frontend): simplify report dialog controls and feedback
Use highlight-only reason choices, show the associated target on one line, and replace inline submission progress with shared toast feedback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-31 00:14:36 +08:00
kate522andClaude Fable 5 80aecab586 feat(frontend): upgrade report dialog experience
Replace manual report links with automatic target association, improve validation and evidence uploads, and remove retired report UI code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 23:56:59 +08:00
kate522andClaude Fable 5 59ddf677b6 feat(admin): review reports and ban appeals in dialogs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 23:06:04 +08:00
kate522andClaude Fable 5 32ac2112b0 fix(uploads): reclaim abandoned front-submit attachments
Mark new regular and chunked uploads as pending and claim persisted article references, including partial saves and large reference sets. Protect associated media from cleanup and add upload lifecycle regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 21:57:46 +08:00
kate522andClaude Fable 5 f9b7997ec2 fix(user): match profile validation hook argument type
Accept the stdClass user data passed by WordPress and derive the user ID only from the hook object. Cover callback registration, nonce and permission guards, and mismatched posted IDs; refresh the identity review dialog contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 20:38:00 +08:00
kate522andClaude Fable 5 bc26d62602 feat(admin): redesign identity review with dialogs
Replace inline identity review forms with focused detail and review dialogs, improve list filters and caching, and align evidence permissions and deletion feedback. Add contract and runtime regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 20:05:21 +08:00
kate522andClaude Fable 5 5732be847e fix(admin): keep invite filters inside the list card
Unify status filters, search, bulk actions and pagination in one invite list card. Remove the standalone filter summary and preserve usable search widths on small screens, with structural regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 19:10:13 +08:00
kate522andClaude Fable 5 a6776ffe0a feat(admin): upgrade invite code management with dialogs
Replace standalone add and export views with accessible dialogs, refine list interactions, and remove obsolete paths and unused counts. Fix filtered totals and reject oversized imports without truncation, with regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 18:53:01 +08:00
kate522andClaude Fable 5 1cd19434d1 fix(admin): translate credits_added notification type
Display credits_added as 积分增加 with a success badge across message
filters, list rows and details. Extend rendering regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 18:04:47 +08:00
kate522andClaude Fable 5 f208424a26 fix(admin): center message actions with balanced cell padding
Center the operations heading and row buttons, with 20px padding on both
sides of the cell. Add a regression contract for alignment and spacing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 17:56:31 +08:00
kate522andClaude Fable 5 479b324f95 fix(admin): move message row actions into a rightmost column
Add a dedicated operations column for viewing, marking read and deleting
messages. Keep the message cell focused on its title, excerpt and ID;
adjust column widths and empty-state colspan with regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 17:45:52 +08:00
kate522andClaude Fable 5 1902ba1e87 fix(admin): translate asset notification type labels
Register Chinese labels and matching badge tones for balance and points
increase/decrease types across message filters, list badges and details.
Add regression coverage without changing notification delivery behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 17:36:42 +08:00
kate522andClaude Fable 5 fe3ef82718 feat(admin): upgrade message management and broadcast interactions
Add message details, per-row actions, selection-aware bulk controls and
confirmation dialogs. Merge filters into the list card and link overview
statistics to the matching views with site-timezone today filtering.

Improve the compose dialog with Unicode character counters, recipient mode
segments, role counts and explicit broadcast confirmation verified against
the resolved role and recipient count on submission. Split rendering into
focused sibling traits and cover rendering, handlers and UI interactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 17:24:54 +08:00
kate522andClaude Fable 5 6195508481 feat(admin): move message compose into a header-button dialog
Replace the inline <details> compose card on users.php?page=aksrt_messages
with a primary header button that opens a native <dialog>. NativeUi::header()
gains dialog-type actions via NativeUi::button_dialog(). The dialog reopens
automatically after a failed send.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 16:42:56 +08:00
kate522andClaude Fable 5 8f1bbf2411 fix(admin): replace VIP expiry sort glyph with stacked CSS carets
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 16:29:46 +08:00
kate522andClaude Fable 5 117da19f16 fix(admin): hide VIP dialog radio marks and align button icons
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 16:20:06 +08:00
kate522andClaude Fable 5 1be52d75a0 feat(admin): redesign VIP membership page with modal editing
- Replace per-row inline <details> forms and the separate bulk form with a
  single <dialog> shared by single-user and bulk adjustments
- Add stats row, styled tabs, date range filter with reset, sortable expiry
- Show fallback tier, remaining time, and disable unavailable operations
- History tab: labelled operation/status badges, avatars, local time,
  batch marker and error message
- Move inline script/onclick to assets/js/admin-vip.js; add vip.css
- Surface the service error message when every user fails

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 16:12:12 +08:00
kate522andClaude Fable 5 18951b01d6 feat(admin): unify native admin pages on a shared modern UI
Add NativeUi helper + native-ui.css (tokens mirror the SPA Naive UI theme)
and move the pay center, orders, products, coupons, charge cards, income,
withdrawals, tickets, invite codes, VIP, verify, messages and report/ban
pages onto shared header, stat cards, cards, filters, badges and empty
states. Remove inline styles and dead helpers; split PayChargeCards into
sibling traits to stay under the file size limit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 15:05:38 +08:00
kate522andClaude Fable 5 aa692f3c9f fix(widgets): drop 520px control width so expanded widgets stay in the sidebar column
WP core widgets.js applies a negative margin-left to widgets whose
control width exceeds 250px, pushing the form over the available
widgets list. Use the default width like the reference theme.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 14:13:38 +08:00
kate522andClaude Fable 5 05c7ade3f5 fix(widgets): keep widget form accordions within the sidebar column
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 14:10:12 +08:00
kate522andClaude Fable 5 7650c3537a fix(widgets): disable block widget editor to restore classic widgets screen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 14:06:49 +08:00
kate522andClaude Fable 5 a579a5b00a feat(widgets): rebuild admin widgets page to match reference theme
- Replace transfer modal/admin-post flow with reference-style AJAX
  export/import/template dialogs (admin-transfer.js, TransferController)
- Customizer "移出模块" action, reference lazy form loading with t-notice
- Common fields use reference labels, dependencies, compact/inline rows,
  top/bottom-only extra spacing; form header with description/reminder
- Remove placement hint, template preview and legacy transfer code
- Fix widget audit (current_datetime stub, honor catalog common flags)
  and regenerate stale golden fixtures for posts_toc, quote, posts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-30 14:00:57 +08:00
kate522 ea80cd96cc fix(widgets): restore article table of contents behavior and styles 2026-10-30 13:18:40 +08:00
kate522 fc04bf65e6 fix(widgets): restore article list rendering and reference styles 2026-10-30 12:47:07 +08:00
kate522 4ea00f1322 fix(frontend): unify article timestamp clock icons 2026-10-29 23:13:14 +08:00
kate522 4cdde50695 fix(frontend): align post thumbnail display with reference 2026-10-29 23:07:08 +08:00
kate522 542daca457 fix(frontend): align search and header components with reference 2026-10-29 22:21:01 +08:00
kate522 4c13ef478c fix(widgets): replace old page before showing pagination skeleton 2026-10-29 21:29:17 +08:00
kate522 985f18c750 fix(widgets): align mini paid badges with reference 2026-10-29 21:15:11 +08:00
kate522 fd034ff055 fix(widgets): align tabbed post layouts with reference 2026-10-29 20:31:39 +08:00
kate522 17515cf9c5 fix(comments): center empty-state illustration 2026-10-29 19:31:16 +08:00
kate522 8aa116ec43 fix(theme): align reference layouts and restore passing contracts
Align homepage and category discovery, modern widgets, admin controls, quotes, and comments with the reference theme. Remove superseded paths and add rendering and behavior coverage. Update stale asset and finance contracts; all 760 Node tests and 139 widget assertions pass.
2026-10-29 19:16:03 +08:00
kate522 b520d29368 fix(frontend): match navigation icon divider spacing 2026-10-29 18:17:51 +08:00
kate522 f019760297 chore(frontend): normalize credits script line endings 2026-10-29 18:11:59 +08:00
kate522 9b27508a5b fix(frontend): align top navigation with reference theme 2026-10-29 18:10:00 +08:00
kate522 1c501ff713 fix(user): align badge modals with reference theme 2026-10-29 17:38:10 +08:00
kate522 8e9d3a7e49 fix(signin): align check-in feedback with reference theme 2026-10-29 17:06:25 +08:00
kate522andClaude Fable 5 1df2822f01 feat(pay): 统一收银台四种模式(站内二维码/当前页跳转/表单提交/JSAPI)
- PaymentOrchestrator 统一返回 mode + code_url/payment_url/form_html/jsapi_params
- 支付宝:当面付二维码 / 电脑网站支付 / H5;微信:Native / H5 / JSAPI(WechatOpenid 静默授权)
- 易支付:PC mapi 二维码,移动端自动提交表单
- 删除旧键 alipay_payment_type / wechat_payment_type / epay_device 与 redirect/qr_content 字段
- 新增 pay-cashier.js,移除 window.open,订单状态接口改为 /pay/order/{n}
- 拆分 credits.js(affiliate / withdraw-history)至 1000 行以内

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 14:01:28 +08:00
kate522andClaude Fable 5 b340b77d5a fix(pay): 订单缓存失效时订单列表无刷新重载
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 11:21:51 +08:00
kate522andClaude Fable 5 c3328e7279 fix(pay): 待支付浮窗无刷新同步
- modal-cache 失效时广播 aksrt:cache:invalidated
- 新增 GET /orders/wait-pay-float 返回浮窗片段
- wait-pay-float.js 监听 orders 标签失效并替换/移除浮窗、重启倒计时
- VIP/充值/下载待支付分支触发 orders 失效

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 11:11:13 +08:00
kate522andClaude Fable 5 d9d1122e9c feat(pay): add wait-pay float window aligned with reference theme
- Render pending orders (max 5, >=3 min left) in a top-right float button
  with hover list and countdown, gated by pay_wait_float_s
- Fix order countdown parsing expires_at as UTC
- Drop unused .paid-modal-lists-box thumb rule

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 10:45:23 +08:00
kate522andClaude Fable 5 7e86f2a821 用户中心侧栏工单中心图标改用 comment-color
- sidebar-nav: 工单中心 icon ticket-color -> comment-color
- 删除 assets/icons/sprite/ticket-color.svg 并重建 svg-icon.js
- 同步更新相关契约测试

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 10:10:49 +08:00
kate522andClaude Fable 5 b7a910b758 fix(scripts): bust tbquire module cache with newest runtime/*.js mtime
_win.ver only tracked main.min.js, so rebuilding svg-icon.js alone kept
serving the cached sprite and new icons (ticket-color) rendered blank.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-29 00:08:05 +08:00
kate522andClaude Fable 5 54ea83b262 feat(icons): split built-in sprite into per-icon SVG sources and add ticket icon
Move the 114 built-in sprite icons out of assets/js/runtime/svg-icon.js into
assets/icons/sprite/{key}.svg and generate svg-icon.js with
tools/build-svg-sprite.mjs. Add ticket-color and use it for the user center
ticket entry. Update sidebar contract tests for the creator card labels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:59:06 +08:00
kate522andClaude Fable 5 794d981260 revert(user-center): restore promotion center ratio label
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:41:37 +08:00
kate522andClaude Fable 5 52749bf232 feat(user-center): rename promotion center ratio label to commission ratio
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:40:41 +08:00
kate522andClaude Fable 5 72e55d95fd feat(user-center): show cash and points income on sidebar creator card
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:39:01 +08:00
kate522andClaude Fable 5 293e1121c5 fix(user-center): align sidebar card spacing with reference mb20/mb10-sm flow
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:35:53 +08:00
kate522andClaude Fable 5 5d83a81b31 fix(user-center): match reference hover/focus interaction on sidebar statistics
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:21:53 +08:00
kate522andClaude Fable 5 cfe806728d fix(user-center): restore reference 6px padding on sidebar icon boxes
widgets/frontend.css loads after main.min.css and its global
.zib-widget{padding:15px} overrode .padding-6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 23:14:48 +08:00
kate522andClaude Fable 5 c152e00501 fix(user-center): 1:1 port reference sidebar statistics row and icon box line-height
- Rewrite sidebar stats as a single zib-widget row (user-statistics-item, em14 / em09 opacity5 mt6), drop legacy .uc-stats styles
- Restore reference body line-height (1.42857143) on stats and service/settings boxes
- Move 我的订单 to the front of 我的服务 to match reference order

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 22:48:54 +08:00
kate522andClaude Fable 5 6ded62df92 fix(user-center): 1:1 port reference sidebar service/settings icon boxes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 22:10:45 +08:00
kate522andClaude Fable 5 9fbfab54c2 feat(user-center): 1:1 port reference sidebar VIP bar and creator/promotion cards
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 22:01:37 +08:00
kate522andClaude Fable 5 5dd7d14334 fix(modal): compensate scrollbar width when locking page scroll
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 21:07:27 +08:00
kate522andClaude Fable 5 fcec5b996f refactor(color): use wpColorPicker for page config nav color
Replace the native input[type=color] in the page config meta box with a
wpColorPicker-enhanced text input, enqueued only on page edit screens, and
contract-lock that no native color inputs remain in theme PHP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 21:01:54 +08:00
kate522andClaude Fable 5 ed1487d505 fix(tests): repair stale pagination/lazyload contracts and ban defaults script
- pay-pages-pagination asserts the $parent_file base URL added in b74381cf
- Drop native loading="lazy" from message avatars and medal presets per
  the lazyload contract
- verify-ban-settings-defaults requires SchemaUsersTicket and new deps

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 20:47:42 +08:00
kate522andClaude Fable 5 57ff405691 refactor(color): unify color sanitizing and picking behind shared components
- Add AKSRT\Core\Color::sanitize($value, $allow_alpha) as the single PHP
  color sanitizer; replace sanitize_hex_color calls and per-class regexes
  (FloatButtons, FieldSchema, ThemeSearch, icon cards, TicketStatusService)
- SchemaProvider / ControllerBase sanitize `color` fields as colors;
  alpha kept only when the schema sets showAlpha
- Split SchemaProvider OAuth validation and option matching into sibling
  traits to stay under the 1000-line limit
- Add AksColorPicker.vue + utils/color.js mirroring the PHP rules; AksField,
  FloatBtnCommonFields and TicketStatusPanel use it
- Widget background color input now uses wpColorPicker
- Remove dead AksCompositeField dimensions/spacing/background branches and
  the unused Gutenberg ColorPicker var
- Add color-unification contract test; update harness requires and tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 20:47:41 +08:00
kate522andClaude Fable 5 74021d26bb fix(layout): align color scheme, content width and fonts with reference theme
- Color scheme: zibll field order/labels, theme_skin_custom overrides palette,
  hex palette swatches, dark_theme_skin_custom, light/dark background images,
  close_backdrop via body.fps-accelerat, theme_main_radius drives --main-radius
- Emit --theme-color / --focus-shadow-color / --focus-color-opacity* vars
- Drop border_radius, primary_color readers and legacy value maps
- Content max width: free 1200-2200 number field; fix font family/custom stack

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 19:36:11 +08:00
kate522andClaude Fable 5 6da08d9d4f refactor(settings): remove filing info config and readers
Drop the 备案信息 group (icp_filing, police_filing, footer_text) from the
global.common PHP/Vue schemas, the FacadeBulk readers and the
get_global_settings() payload. No frontend consumer existed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 18:36:27 +08:00
kate522andClaude Fable 5 32172582ff fix(admin): shrink image previews to natural size like reference theme
Media and gallery previews now hug the image (inline box, capped height)
instead of stretching across fixed grid cells, removing empty letterbox space.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 18:30:34 +08:00
kate522andClaude Fable 5 7d61de70e3 fix(admin): keep image previews at natural aspect ratio
Media/gallery previews no longer stretch or crop: use object-fit contain,
natural sizing for single media, and the uncropped medium size instead of
the square thumbnail for gallery and native meta-box previews.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 15:58:01 +08:00
kate522andClaude Fable 5 fa89f43ac9 feat(admin): collapse provider/gateway groups by default, mask alipay private key, drop inline notice styles
- OAuth provider and payment gateway groups are collapsible and collapsed by default; remove dead expandWhen logic
- Textarea fields support secret masking; mark alipay_privatekey as secret in JS and PHP schemas
- Extract AksSecretClear shared by input and textarea secret fields
- Replace inline styles in payment/post-list notice HTML with aksrt-hint / aksrt-warn classes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 15:50:37 +08:00
kate522andClaude Fable 5 3179754670 feat(admin): polish badge, OAuth and payment gateway settings UX
- Badge page: rewrite as collapsible sortable category/item cards with
  preset medal icon picker, dirty-tracked save bar and duplicate slug check;
  drop user_badge_* dual-read and legacy name/icon_url fallbacks
- OAuth: provider config groups collapsible, expanded when provider is on;
  clogin visibility moved to group-level dependsOn
- Gateway: expandWhen accepts dependsOn-style rules; select-gated groups no
  longer always expand ('null' was truthy); mark five gateway secrets as
  secret/password in JS and PHP; class-based notice list styling
- Remove unused UserRuntime::parse_badge_dictionary

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 15:33:49 +08:00
kate522andClaude Fable 5 116b6b2223 feat(admin): make all sortable/repeater cards collapsible, collapsed by default
- Add useCollapsibleItems: key-based open state, clickable/keyboard head, aria-expanded
- sortable items with sub-fields and every inline repeater/group row now collapse
- Repeater head summary falls back to the first filled field when no listPreview
- Drop per-schema collapsible/defaultCollapsed for repeater groups (JS + PHP)
- Align FloatBtnItemPanel head with the shared collapse attrs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 14:12:13 +08:00
kate522andClaude Fable 5 8843ae4261 refactor(admin): unify sortable/draggable/repeater list UI
- Add shared sortable-list.css, SORTABLE_LIST_ATTRS and AksSortHandle
- Migrate schema sortable, selected order, inline/modal repeater, sorter,
  floating buttons, footer tabbar and ticket prereply lists to the shared design
- Split AksField.vue (1885 -> 969 lines) into focused components/helpers
- Remove dead AksArrayTable/AksRepeaterField and move-up/down helpers
- Replace hardcoded colors and --n-* vars with --aksrt-color-* tokens

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-28 13:41:26 +08:00