Migration 096 created a custom_menu_items entry with hardcoded English
label "Purchase" and empty icon_svg. This migration updates existing
records where id='migrated_purchase_subscription':
- label: "Purchase" → "充值/订阅"
- icon_svg: "" → CreditCard SVG (Heroicons outline)
- apiBase, notifyUrl, returnUrl: remove optional flag (required — backend
relies on these in provider config, no fallback)
- Only wxpay publicKeyId + certSerial remain optional
- Show red * for required fields, (可选) for optional fields
- Create provider dialog: only show provider types whose payment types
are enabled (e.g. no Stripe option if stripe not enabled above)
- Provider cards: grey out + disable edit when their type is disabled
- Show "(类型已禁用)" warning on greyed-out provider cards
- Delete still allowed on disabled providers (cleanup)
- Merge amount fields, toggles and limits into fewer rows
- Put payment types + load balance strategy on same line
- Compact provider cards (single-line info, inline edit/delete buttons)
- Reduce padding and gaps throughout
Add formatOrderID/parseOrderID helpers to prepend "sub2_" prefix to
order IDs sent to EasyPay, Alipay, Wxpay, and Stripe. This makes our
orders identifiable in third-party dashboards and prevents ID collision.
Callback handlers strip the prefix before looking up the DB record.
Internal audit logs keep using raw DB IDs.
- Delete AdminPaymentConfigView.vue (duplicated in SettingsView Payment tab)
- Remove /admin/orders/config route
- Plans table: show red "缺失/Missing" badge for deleted groups
- Plans table: group_id column shows group name or missing indicator
- Create utils/apiError.ts with extractApiErrorMessage() utility
- Replace all raw err.message/String(err) patterns in payment views
- Fix error display for API client interceptor's plain object errors
- Update CLAUDE.md with API error handling convention (section 13)
- Copy CLAUDE.md to AGENTS.md
Replace the single AdminOrdersView with 4-tab layout with separate pages:
- /admin/orders/dashboard — payment dashboard with 7/30/90 day switcher
- /admin/orders — pure order list (removed channels/plans tabs)
- /admin/orders/config — payment config + provider management
- /admin/orders/plans — subscription plans (group dropdown) + user subscriptions
Delete AdminProvidersView (merged into config page).
Update sidebar to show 4 menu items instead of 1.
Replace Go startup code with SQL migration 096 to migrate
purchase_subscription_url to custom_menu_items. Database migrations
run exactly once and are tracked by the migration system.
- Restore MigrateLegacyPurchaseURL auto-call on startup: converts old
purchase_subscription_url into a custom menu item (id: migrated_purchase_subscription)
and clears the legacy settings
- Delete PurchaseRouter.vue and PurchaseSubscriptionView.vue (replaced
by existing CustomPageView.vue via custom menu system)
- /purchase route now exclusively serves the new built-in payment system
- Remove purchase_subscription_enabled from sidebar, router, settings UI,
TypeScript types, and i18n keys
- Legacy purchase URL users will see their link as a custom menu entry
after upgrade, editable in admin custom menu settings