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>
This commit is contained in:
1 parent
116b6b2223
commit
3179754670
13 files changed
+502
-239
No files matched your search
@@ -91,7 +91,7 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>以下收款接口,主题仅提供API接入服务,收款平台的可靠性请自行斟酌!</li><li>涉及到资金及信息安全,有相关执照的商家推荐使用官方接口</li><li>微信 / 支付宝接口可在「官方」与「易支付」之间选择;PayPal 与 Stripe 独立开关</li><li>异步回调由各网关验签,无需额外口令;回调地址固定为 /wp-json/aksrt/v1/payment/{gateway}/{notify|return}</li></ul>',
|
||||
content: '<ul><li>以下收款接口,主题仅提供API接入服务,收款平台的可靠性请自行斟酌!</li><li>涉及到资金及信息安全,有相关执照的商家推荐使用官方接口</li><li>微信 / 支付宝接口可在「官方」与「易支付」之间选择;PayPal 与 Stripe 独立开关</li><li>异步回调由各网关验签,无需额外口令;回调地址固定为 /wp-json/aksrt/v1/payment/{gateway}/{notify|return}</li></ul>',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -198,7 +198,6 @@ export const gatewaySchema = {
|
||||
icon: 'fa fas fa-credit-card',
|
||||
description: '支付宝官方接口(当面付 / 网站应用)。',
|
||||
collapsible: true,
|
||||
expandWhen: 'pay_alipay_sdk_options',
|
||||
dependsOn: { key: 'pay_alipay_sdk_options', value: 'official_alipay' },
|
||||
fields: [
|
||||
{
|
||||
@@ -206,7 +205,7 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>支付宝公钥为必填项目(公钥错误可以成功付款,但会回调失败)</li><li>回调地址固定为 /wp-json/aksrt/v1/payment/alipay/{notify|return}</li><li>同时填写了企业支付以及当面付参数,则优先使用当面付</li></ul>',
|
||||
content: '<ul><li>支付宝公钥为必填项目(公钥错误可以成功付款,但会回调失败)</li><li>回调地址固定为 /wp-json/aksrt/v1/payment/alipay/{notify|return}</li><li>同时填写了企业支付以及当面付参数,则优先使用当面付</li></ul>',
|
||||
},
|
||||
{ key: 'alipay_appid', label: '当面付:APPID', type: 'input', default: '' },
|
||||
{ key: 'alipay_privatekey', label: '当面付:应用私钥', type: 'textarea', sanitize_type: 'code', default: '', rows: 4 },
|
||||
@@ -231,7 +230,6 @@ export const gatewaySchema = {
|
||||
icon: 'fa fab fa-weixin',
|
||||
description: '微信企业支付官方接口。',
|
||||
collapsible: true,
|
||||
expandWhen: 'pay_wechat_sdk_options',
|
||||
dependsOn: { key: 'pay_wechat_sdk_options', value: 'official_wechat' },
|
||||
fields: [
|
||||
{
|
||||
@@ -239,7 +237,7 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>微信企业支付:官方接口,商家可申请,有年费,申请较为复杂</li><li>回调地址固定为 /wp-json/aksrt/v1/payment/wechatpay/{notify|return},请配置 Native 支付回调链接</li></ul>',
|
||||
content: '<ul><li>微信企业支付:官方接口,商家可申请,有年费,申请较为复杂</li><li>回调地址固定为 /wp-json/aksrt/v1/payment/wechatpay/{notify|return},请配置 Native 支付回调链接</li></ul>',
|
||||
},
|
||||
{ key: 'wechat_merchantid', label: '商户号 PartnerID', type: 'input', default: '' },
|
||||
{ key: 'wechat_appid', label: '授权绑定的AppID', type: 'input', default: '' },
|
||||
@@ -253,7 +251,7 @@ export const gatewaySchema = {
|
||||
{ label: 'H5支付', value: 'h5' },
|
||||
],
|
||||
},
|
||||
{ key: 'wechat_api_v3_key', label: '支付APIv3密钥', type: 'input', default: '', help: '微信商户平台设置的 APIv3 密钥(32位)。' },
|
||||
{ key: 'wechat_api_v3_key', label: '支付APIv3密钥', type: 'input', inputType: 'password', secret: true, default: '', help: '微信商户平台设置的 APIv3 密钥(32位)。' },
|
||||
{ key: 'wechat_private_key_path', label: '商户私钥路径', type: 'input', default: '', help: 'apiclient_key.pem 绝对路径,用于签名。' },
|
||||
{ key: 'wechat_cert_path', label: '商户API证书路径', type: 'input', default: '', help: 'apiclient_cert.pem 绝对路径。' },
|
||||
],
|
||||
@@ -264,7 +262,6 @@ export const gatewaySchema = {
|
||||
icon: 'fa fab fa-paypal',
|
||||
description: '常见的海外支付接口。',
|
||||
collapsible: true,
|
||||
expandWhen: 'pay_paypal_sdk_s',
|
||||
dependsOn: { key: 'pay_paypal_sdk_s', value: true },
|
||||
fields: [
|
||||
{
|
||||
@@ -272,10 +269,10 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>PayPal(贝宝)是常见的海外支付接口</li><li>如果您的收款账户为中国大陆地区,则账户类型必须是企业,且只能收取非中国大陆区的PayPal付款</li><li>REST 应用申请:https://developer.paypal.com/dashboard/applications</li></ul>',
|
||||
content: '<ul><li>PayPal(贝宝)是常见的海外支付接口</li><li>如果您的收款账户为中国大陆地区,则账户类型必须是企业,且只能收取非中国大陆区的PayPal付款</li><li>REST 应用申请:https://developer.paypal.com/dashboard/applications</li></ul>',
|
||||
},
|
||||
{ key: 'paypal_client_id', label: 'Client ID', type: 'input', default: '' },
|
||||
{ key: 'paypal_client_secret', label: 'Client Secret', type: 'input', default: '' },
|
||||
{ key: 'paypal_client_secret', label: 'Client Secret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
{ key: 'paypal_currency', label: '结算货币', type: 'select', case_insensitive: true, default: 'USD', options: currencyOptions },
|
||||
{ key: 'paypal_rates', label: '货币汇率', type: 'input', default: '0.14', help: '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137' },
|
||||
{ key: 'paypal_sandbox', label: '沙盒调试模式', type: 'switch', default: false, help: '沙箱模式(Sandbox)是PayPal支付的测试环境。开启后请使用沙箱环境生成的收款账户和付款账户进行测试。' },
|
||||
@@ -287,7 +284,6 @@ export const gatewaySchema = {
|
||||
icon: 'fa fab fa-cc-stripe',
|
||||
description: '常见的海外信用卡收款接口。',
|
||||
collapsible: true,
|
||||
expandWhen: 'pay_stripe_sdk_s',
|
||||
dependsOn: { key: 'pay_stripe_sdk_s', value: true },
|
||||
fields: [
|
||||
{
|
||||
@@ -295,11 +291,11 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>Stripe 是常见的海外信用卡收款接口</li><li>API 密钥申请:https://dashboard.stripe.com/apikeys</li><li>Webhook 事件:checkout.session.completed</li><li>测试环境请使用 sk_test_ 开头的 Secret Key</li></ul>',
|
||||
content: '<ul><li>Stripe 是常见的海外信用卡收款接口</li><li>API 密钥申请:https://dashboard.stripe.com/apikeys</li><li>Webhook 事件:checkout.session.completed</li><li>测试环境请使用 sk_test_ 开头的 Secret Key</li></ul>',
|
||||
},
|
||||
{ key: 'stripe_secret_key', label: '私钥Secret Key', type: 'input', default: '', help: 'Stripe Dashboard → Developers → API keys → Secret key' },
|
||||
{ key: 'stripe_secret_key', label: '私钥Secret Key', type: 'input', inputType: 'password', secret: true, default: '', help: 'Stripe Dashboard → Developers → API keys → Secret key' },
|
||||
{ key: 'stripe_publishable_key', label: 'Publishable Key', type: 'input', default: '' },
|
||||
{ key: 'stripe_webhook_secret', label: '签名密钥Webhook Secret', type: 'input', default: '', help: 'Developers → Webhooks → 端点 → Signing secret(whsec_ 开头)' },
|
||||
{ key: 'stripe_webhook_secret', label: '签名密钥Webhook Secret', type: 'input', inputType: 'password', secret: true, default: '', help: 'Developers → Webhooks → 端点 → Signing secret(whsec_ 开头)' },
|
||||
{ key: 'stripe_currency', label: '结算货币', type: 'select', case_insensitive: true, default: 'USD', options: currencyOptions },
|
||||
{ key: 'stripe_rates', label: '货币汇率', type: 'input', default: '0.14', help: '根据你选择的货币类型与您定价货币的汇率进行填写,例如1元人民币兑换0.137美元(USD),则此处填0.137' },
|
||||
{ key: 'stripe_test_mode', label: '测试模式', type: 'switch', default: false, help: '如果使用的测试开放模式,则请使用 sk_test_ 测试密钥与 Stripe 测试卡进行配置' },
|
||||
@@ -311,7 +307,6 @@ export const gatewaySchema = {
|
||||
icon: 'fa fas fa-university',
|
||||
description: '易支付(彩虹协议)聚合收银台;通道由上方微信/支付宝接口选择控制。',
|
||||
collapsible: true,
|
||||
expandWhen: 'pay_wechat_sdk_options',
|
||||
dependsOn: {
|
||||
any: [
|
||||
{ key: 'pay_wechat_sdk_options', value: 'epay' },
|
||||
@@ -324,11 +319,11 @@ export const gatewaySchema = {
|
||||
label: '',
|
||||
type: 'content',
|
||||
ui_only: true,
|
||||
content: '<ul style="margin:0 0 0 18px;line-height:1.9"><li>易支付是一个常见的支付系统源码,任何人都可以下载并搭建</li><li>同时市面上多数的小规模支付平台都是由易支付修改而来,例如部分码支付、源支付等等</li><li>由于此接口服务商众多,主题只负责技术接入,平台可靠性请自行斟酌</li></ul>',
|
||||
content: '<ul><li>易支付是一个常见的支付系统源码,任何人都可以下载并搭建</li><li>同时市面上多数的小规模支付平台都是由易支付修改而来,例如部分码支付、源支付等等</li><li>由于此接口服务商众多,主题只负责技术接入,平台可靠性请自行斟酌</li></ul>',
|
||||
},
|
||||
{ key: 'epay_apiurl', label: 'API接口网址', type: 'input', default: '', help: '请填写接口地址,例如:https://pay.xxxxxxx.cn/' },
|
||||
{ key: 'epay_pid', label: '商户号', type: 'input', default: '' },
|
||||
{ key: 'epay_key', label: '商户秘钥', type: 'input', default: '', help: 'MD5 通信密钥。' },
|
||||
{ key: 'epay_key', label: '商户秘钥', type: 'input', inputType: 'password', secret: true, default: '', help: 'MD5 通信密钥。' },
|
||||
{
|
||||
key: 'epay_device',
|
||||
label: '下单终端',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* User medal catalog (SPA route remains /users/badge).
|
||||
* Storage keys: user_medal_* (legacy user_medal_s / user_medal_args parity).
|
||||
* 用户徽章字典(路由 /users/badge,存储键 user_medal_*)。
|
||||
* 自定义页 pages/users/UsersBadge.vue 负责编辑,本文件提供获取条件、预设图标与默认字典。
|
||||
*/
|
||||
|
||||
export const MEDAL_GET_TYPES = [
|
||||
@@ -23,7 +23,10 @@ const MEDAL_BASE = (() => {
|
||||
return root ? String(root).replace(/\/$/, '') + '/assets/img/medal' : '/assets/img/medal'
|
||||
})()
|
||||
|
||||
const medalIcon = (n) => `${MEDAL_BASE}/medal-${n}.svg`
|
||||
export const medalIcon = (n) => `${MEDAL_BASE}/medal-${n}.svg`
|
||||
|
||||
/** 主题自带的 30 枚预设勋章图标(assets/img/medal/medal-1..30.svg)。 */
|
||||
export const MEDAL_PRESET_ICONS = Array.from({ length: 30 }, (_, i) => medalIcon(i + 1))
|
||||
|
||||
export const defaultMedalArgs = () => [
|
||||
{
|
||||
@@ -90,7 +93,7 @@ export const badgeSchema = {
|
||||
key: 'users.badge',
|
||||
title: '用户徽章',
|
||||
icon: 'fa fas fa-trophy',
|
||||
description: '配置勋章分类、自动授予条件与前台展示。路由仍为 /users/badge;存储键为 user_medal_*。',
|
||||
description: '配置勋章分类、自动授予条件与前台展示。',
|
||||
defaults: {
|
||||
user_medal_s: false,
|
||||
user_medal_public_display: true,
|
||||
|
||||
@@ -83,6 +83,8 @@ export const oauthSchema = {
|
||||
key: 'github',
|
||||
title: 'GitHub配置',
|
||||
icon: 'fa fab fa-github',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_github_s',
|
||||
fields: [
|
||||
{ key: 'github_appid', label: 'Client ID', type: 'input', default: '' },
|
||||
{ key: 'github_appkey', label: 'Client Secret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -92,6 +94,8 @@ export const oauthSchema = {
|
||||
key: 'gitee',
|
||||
title: 'Gitee配置',
|
||||
icon: 'fa fas fa-code-branch',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_gitee_s',
|
||||
fields: [
|
||||
{ key: 'gitee_appid', label: 'Client ID', type: 'input', default: '' },
|
||||
{ key: 'gitee_appkey', label: 'Client Secret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -101,6 +105,8 @@ export const oauthSchema = {
|
||||
key: 'qq',
|
||||
title: 'QQ配置',
|
||||
icon: 'fa fab fa-qq',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_qq_s',
|
||||
fields: [
|
||||
{ key: 'qq_appid', label: 'App ID', type: 'input', default: '' },
|
||||
{ key: 'qq_appkey', label: 'App Key', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -110,6 +116,8 @@ export const oauthSchema = {
|
||||
key: 'google',
|
||||
title: 'Google配置',
|
||||
icon: 'fa fab fa-google',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_google_s',
|
||||
fields: [
|
||||
{ key: 'google_client_id', label: 'Client ID', type: 'input', default: '' },
|
||||
{ key: 'google_client_secret', label: 'Client Secret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -119,6 +127,8 @@ export const oauthSchema = {
|
||||
key: 'weibo',
|
||||
title: '微博配置',
|
||||
icon: 'fa fab fa-weibo',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_weibo_s',
|
||||
fields: [
|
||||
{ key: 'weibo_appid', label: 'App Key', type: 'input', default: '' },
|
||||
{ key: 'weibo_appkey', label: 'App Secret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -128,6 +138,8 @@ export const oauthSchema = {
|
||||
key: 'weixin',
|
||||
title: '微信开放平台配置',
|
||||
icon: 'fa fab fa-weixin',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_weixin_s',
|
||||
fields: [
|
||||
{ key: 'weixin_appid', label: 'AppID', type: 'input', default: '' },
|
||||
{ key: 'weixin_appsecret', label: 'AppSecret', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -137,6 +149,8 @@ export const oauthSchema = {
|
||||
key: 'weixingzh',
|
||||
title: '微信公众号配置',
|
||||
icon: 'fa fab fa-weixin',
|
||||
collapsible: true,
|
||||
expandWhen: 'oauth_weixingzh_s',
|
||||
fields: [
|
||||
{ key: 'weixingzh_gzh_type', label: '公众号类型', type: 'radio', default: 'service', options: [{ label: '服务号', value: 'service' }, { label: '订阅号', value: 'subscribe' }] },
|
||||
{ key: 'weixingzh_token', label: 'Token', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
@@ -153,15 +167,17 @@ export const oauthSchema = {
|
||||
key: 'clogin',
|
||||
title: '彩虹聚合登录',
|
||||
icon: 'fa fas fa-cloud',
|
||||
collapsible: true,
|
||||
dependsOn: { key: 'clogin_s', value: true },
|
||||
fields: [
|
||||
{ key: 'clogin_url', label: '接口地址', type: 'input', default: '', help: '如 https://xxx.com,不要带 connect.php', dependsOn: { key: 'clogin_s', value: true } },
|
||||
{ key: 'clogin_id', label: 'AppID', type: 'input', default: '', dependsOn: { key: 'clogin_s', value: true } },
|
||||
{ key: 'clogin_key', label: 'AppKey', type: 'input', inputType: 'password', secret: true, default: '', dependsOn: { key: 'clogin_s', value: true } },
|
||||
{ key: 'clogin_url', label: '接口地址', type: 'input', default: '', help: '如 https://xxx.com,不要带 connect.php' },
|
||||
{ key: 'clogin_id', label: 'AppID', type: 'input', default: '' },
|
||||
{ key: 'clogin_key', label: 'AppKey', type: 'input', inputType: 'password', secret: true, default: '' },
|
||||
{ key: 'clogin_oauth_s', label: '启用平台', type: 'checkbox', default: ['qq', 'weixin', 'weibo'], options: [
|
||||
{ label: 'QQ', value: 'qq' },
|
||||
{ label: '微信', value: 'weixin' },
|
||||
{ label: '微博', value: 'weibo' },
|
||||
], dependsOn: { key: 'clogin_s', value: true } },
|
||||
] },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user