From a266d3cd8357d1613636d7a88c49bd294f14f8ad Mon Sep 17 00:00:00 2001 From: qian Date: Mon, 7 Sep 2026 23:29:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(pay):=E6=B7=BB=E5=8A=A0=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E9=85=8D=E7=BD=AE=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/logic/admin/permission.go | 9 + internal/logic/admin/role.go | 6 + internal/middleware/rbac.go | 11 +- web/admin/src/router/admin.ts | 6 + web/admin/src/views/AdminLayout.vue | 1 + .../src/views/finance/PaymentChannelsPage.vue | 175 ++++++++++++++ .../payment-channels/EpayChannelCard.vue | 216 ++++++++++++++++++ web/admin/src/views/system/SettingsPage.vue | 6 +- 8 files changed, 424 insertions(+), 6 deletions(-) create mode 100644 web/admin/src/views/finance/PaymentChannelsPage.vue create mode 100644 web/admin/src/views/finance/payment-channels/EpayChannelCard.vue diff --git a/internal/logic/admin/permission.go b/internal/logic/admin/permission.go index 8c6cc5a..43be5b2 100644 --- a/internal/logic/admin/permission.go +++ b/internal/logic/admin/permission.go @@ -65,6 +65,15 @@ var predefinedPermissionGroups = []v1.PermissionGroup{ "order:view", "order:refund", }, }, + { + Name: "payment", + Label: "支付渠道", + Permissions: []string{ + // 渠道配置含商户密钥明文,独立于 system:* 权限点:必须显式授予才能 + // 查看/修改支付渠道,避免"能进系统设置就能拿到收款密钥" + "payment:view", "payment:edit", + }, + }, { Name: "audit", Label: "审计日志", diff --git a/internal/logic/admin/role.go b/internal/logic/admin/role.go index b1c79e6..90c22f9 100644 --- a/internal/logic/admin/role.go +++ b/internal/logic/admin/role.go @@ -74,6 +74,11 @@ var tierPermissions = map[string]map[string][]string{ TierRead: {"order:view"}, TierFull: {"order:view", "order:refund"}, }, + // 支付渠道只有查看/编辑两个动作,无删除档:密钥类配置宁可少放开 + "payment": { + TierRead: {"payment:view"}, + TierOperate: {"payment:view", "payment:edit"}, + }, "promo": { TierRead: {"promo:view"}, TierOperate: {"promo:view", "promo:create", "promo:edit"}, @@ -130,6 +135,7 @@ var tierPermissions = map[string]map[string][]string{ var dangerousPermissions = map[string]string{ "billing:refund": "可对任意租户钱包退款/调账", "order:refund": "可对订单发起退款到支付渠道", + "payment:edit": "可修改支付渠道配置与商户密钥,直接影响线上收款", "audit:read_sensitive": "可查看敏感数据访问日志", "audit:clear": "可硬删除全部拦截日志(不可恢复)", "system:edit": "可修改支付、汇率、存储、邮件等全站配置", diff --git a/internal/middleware/rbac.go b/internal/middleware/rbac.go index 0025e71..38dcaf8 100644 --- a/internal/middleware/rbac.go +++ b/internal/middleware/rbac.go @@ -215,11 +215,12 @@ var adminPermissionRules = []permissionRule{ {method: "PUT", prefix: "/api/admin/settings/", perm: "system:edit"}, // 配置连通性测试(对象存储 / 邮件):会真实调用外部服务并可能发信,按写权限管控 {method: "POST", prefix: "/api/admin/settings/", perm: "system:edit"}, - // Payment settings & channels (system scope) - {method: "GET", path: "/api/admin/payment-channels", perm: "system:view"}, - {method: "PUT", prefix: "/api/admin/payment-channels/", perm: "system:edit"}, - {method: "GET", path: "/api/admin/payment-settings", perm: "system:view"}, - {method: "PUT", path: "/api/admin/payment-settings", perm: "system:edit"}, + // Payment settings & channels:渠道配置含商户密钥明文,使用独立的 payment:* + // 权限点,与 system:*(系统设置)解耦,必须显式授予才能访问 + {method: "GET", path: "/api/admin/payment-channels", perm: "payment:view"}, + {method: "PUT", prefix: "/api/admin/payment-channels/", perm: "payment:edit"}, + {method: "GET", path: "/api/admin/payment-settings", perm: "payment:view"}, + {method: "PUT", path: "/api/admin/payment-settings", perm: "payment:edit"}, {method: "GET", path: "/api/admin/data-governance/settings", perm: "system:view"}, {method: "PUT", path: "/api/admin/data-governance/settings", perm: "system:edit"}, {method: "POST", prefix: "/api/admin/data-governance/", perm: "system:edit"}, diff --git a/web/admin/src/router/admin.ts b/web/admin/src/router/admin.ts index 27a2b8e..d0c5d44 100644 --- a/web/admin/src/router/admin.ts +++ b/web/admin/src/router/admin.ts @@ -103,6 +103,12 @@ const adminRoutes: RouteRecordRaw[] = [ path: 'payment-settings', redirect: { name: 'AdminSettings' }, }, + { + path: 'payment-channels', + name: 'AdminPaymentChannels', + component: () => import('@/views/finance/PaymentChannelsPage.vue'), + meta: { title: '支付渠道', perm: 'payment:view' }, + }, { path: 'redemptions', name: 'AdminRedemptions', diff --git a/web/admin/src/views/AdminLayout.vue b/web/admin/src/views/AdminLayout.vue index 53c138e..6e9ef65 100644 --- a/web/admin/src/views/AdminLayout.vue +++ b/web/admin/src/views/AdminLayout.vue @@ -403,6 +403,7 @@ const ALL_MENU_GROUPS = [ { name: 'AdminPermissions', label: '角色权限', icon: IconSafe, superOnly: true }, { name: 'AdminPlugins', label: '插件管理', icon: IconCodeBlock, perm: 'system:plugin' }, { name: 'AdminSettings', label: '系统设置', icon: IconSettings, perm: 'system:view' }, + { name: 'AdminPaymentChannels', label: '支付渠道', icon: IconIdcard, perm: 'payment:view' }, { name: 'AdminFiles', label: '文件管理', icon: IconStorage, perm: 'file:view' }, ], }, diff --git a/web/admin/src/views/finance/PaymentChannelsPage.vue b/web/admin/src/views/finance/PaymentChannelsPage.vue new file mode 100644 index 0000000..c9b8ef3 --- /dev/null +++ b/web/admin/src/views/finance/PaymentChannelsPage.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/web/admin/src/views/finance/payment-channels/EpayChannelCard.vue b/web/admin/src/views/finance/payment-channels/EpayChannelCard.vue new file mode 100644 index 0000000..884b91f --- /dev/null +++ b/web/admin/src/views/finance/payment-channels/EpayChannelCard.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/web/admin/src/views/system/SettingsPage.vue b/web/admin/src/views/system/SettingsPage.vue index 7081713..1c93be4 100644 --- a/web/admin/src/views/system/SettingsPage.vue +++ b/web/admin/src/views/system/SettingsPage.vue @@ -1,5 +1,6 @@