From d488e6f6f96aa20936b64598eb876b3e604a4aac Mon Sep 17 00:00:00 2001 From: DaxPay Dev Date: Sat, 11 Jul 2026 10:21:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E5=BA=94=E7=94=A8=E7=BA=A7?= =?UTF-8?q?=E8=81=9A=E5=90=88=E6=89=AB=E7=A0=81=E9=85=8D=E7=BD=AE=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增聚合扫码配置 API/页面与权限码, 应用卡片入口联动。 --- .../src/api/payment/merchant/aggregate.api.ts | 67 +++ apps/daxpay-admin/src/constants/perm-codes.ts | 5 + .../en-US/payment/merchant/aggregate.json | 32 ++ .../langs/en-US/payment/merchant/app.json | 1 + .../zh-CN/payment/merchant/aggregate.json | 32 ++ .../langs/zh-CN/payment/merchant/app.json | 1 + .../aggregate/AggregateScanConfig.vue | 450 ++++++++++++++++++ .../merchant/aggregate/shared/constants.ts | 34 ++ .../payment/merchant/app/MchAppInfoCard.vue | 23 + 9 files changed, 645 insertions(+) create mode 100644 apps/daxpay-admin/src/api/payment/merchant/aggregate.api.ts create mode 100644 apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/aggregate.json create mode 100644 apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/aggregate.json create mode 100644 apps/daxpay-admin/src/views/payment/merchant/aggregate/AggregateScanConfig.vue create mode 100644 apps/daxpay-admin/src/views/payment/merchant/aggregate/shared/constants.ts diff --git a/apps/daxpay-admin/src/api/payment/merchant/aggregate.api.ts b/apps/daxpay-admin/src/api/payment/merchant/aggregate.api.ts new file mode 100644 index 000000000..e4875cacb --- /dev/null +++ b/apps/daxpay-admin/src/api/payment/merchant/aggregate.api.ts @@ -0,0 +1,67 @@ +import type { BaseEntity, LabelValue, Result } from '#/types/web'; + +import { defHttp } from '#/api/request'; + +/** + * 聚合扫码配置 API + * 对接后端 GatewayAggregateConfigAdminController + */ +export const AggregateConfigApi = { + /** 按应用查询聚合扫码配置 */ + getByAppId(appId: string): Promise> { + return defHttp.get({ + url: '/admin/gateway/aggregate-config/get-by-app-id', + params: { appId }, + }); + }, + + /** 保存或更新聚合扫码配置 */ + saveOrUpdate(data: AggregateConfigParam): Promise> { + return defHttp.post({ + url: '/admin/gateway/aggregate-config/save-or-update', + data, + }); + }, +}; + +/** 聚合扫码配置结果 */ +export interface AggregateConfigResult extends BaseEntity { + appId?: string; + mchNo?: string; + /** 配置深度: auto/method/direct */ + level?: string; + autoLaunch?: boolean; + scenes?: AggregateSceneResult[]; +} + +/** 场景配置结果 */ +export interface AggregateSceneResult { + /** 场景编码: wechat_pay/alipay/union_pay/douyin */ + scene?: string; + /** 支付方式(METHOD 模式) */ + method?: string; + /** 通道商户号(DIRECT 模式) */ + channelMchNo?: string; + /** 支付能力(DIRECT 模式) */ + capability?: string; +} + +/** 聚合扫码配置参数 */ +export interface AggregateConfigParam { + mchNo: string; + appId: string; + level: string; + autoLaunch?: boolean; + scenes?: AggregateSceneParam[]; +} + +/** 场景配置参数 */ +export interface AggregateSceneParam { + scene?: string; + method?: string; + channelMchNo?: string; + capability?: string; +} + +// re-export LabelValue 供消费方就近引用 +export type { LabelValue }; diff --git a/apps/daxpay-admin/src/constants/perm-codes.ts b/apps/daxpay-admin/src/constants/perm-codes.ts index 7feb9cd91..cd63e2b77 100644 --- a/apps/daxpay-admin/src/constants/perm-codes.ts +++ b/apps/daxpay-admin/src/constants/perm-codes.ts @@ -69,6 +69,11 @@ export const PermCodes = { VIEW: 'merchant:app:route:view', MANAGE: 'merchant:app:route:manage', }, + /** 聚合扫码配置 menuCode=merchant:gateway-aggregate */ + GatewayAggregate: { + VIEW: 'merchant:gateway-aggregate:view', + MANAGE: 'merchant:gateway-aggregate:update', + }, /** 门店 menuCode=merchant:store */ Store: { VIEW: 'merchant:store:view', diff --git a/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/aggregate.json b/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/aggregate.json new file mode 100644 index 000000000..81069faa2 --- /dev/null +++ b/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/aggregate.json @@ -0,0 +1,32 @@ +{ + "aggregate": { + "title": "Aggregate QR Pay Config", + "editModeLabel": "Config Level", + "autoLaunch": "Auto Launch", + "autoLaunchHint": "Automatically initiate payment after scanning, no manual click needed", + "autoModeHint": "System auto-derives payment method by scan environment, resolved via basic routing. No manual config needed.", + "methodModeHint": "Manually select payment method per scene, resolved via scene routing.", + "directModeHint": "Directly specify channel merchant and capability per scene, bypassing routing.", + "scene": "Scene", + "method": "Payment Method", + "methodPlaceholder": "Select payment method", + "channelMerchant": "Channel Merchant", + "channelMerchantPlaceholder": "Select channel merchant", + "capability": "Capability", + "capabilityPlaceholder": "Select capability", + "autoDerived": "Auto-derived", + "saveConfirm": "Are you sure to save the aggregate QR pay config?", + "missingAppContext": "Please access aggregate QR config from app management", + "notSelected": "Not selected", + "levelActive": "Active", + "scenes": { + "wechat_pay": "WeChat", + "alipay": "Alipay", + "union_pay": "UnionPay", + "douyin": "Douyin" + }, + "modeAuto": "Auto", + "modeMethod": "By Method", + "modeDirect": "Direct" + } +} diff --git a/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/app.json b/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/app.json index 8255c3fd8..6279e506a 100644 --- a/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/app.json +++ b/apps/daxpay-admin/src/locales/langs/en-US/payment/merchant/app.json @@ -25,6 +25,7 @@ "validationAppName": "Please enter app name", "validationStatus": "Please select status", "payRoute": "Channel Routing", + "aggregateScan": "Aggregate QR", "notifyConfig": "Notification Config" } } diff --git a/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/aggregate.json b/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/aggregate.json new file mode 100644 index 000000000..25b98d41a --- /dev/null +++ b/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/aggregate.json @@ -0,0 +1,32 @@ +{ + "aggregate": { + "title": "聚合扫码配置", + "editModeLabel": "配置模式", + "autoLaunch": "自动拉起支付", + "autoLaunchHint": "扫码后自动发起支付,无需用户手动点击", + "autoModeHint": "系统按扫码环境自动推导支付方式,走路由基础模式解析,无需手动配置", + "methodModeHint": "每个场景手动选择支付方式,走路由场景模式解析", + "directModeHint": "每个场景直接指定通道商户号和支付能力,跳过路由直定通道", + "scene": "场景", + "method": "支付方式", + "methodPlaceholder": "请选择支付方式", + "channelMerchant": "通道商户号", + "channelMerchantPlaceholder": "请选择通道商户", + "capability": "支付能力", + "capabilityPlaceholder": "请选择支付能力", + "autoDerived": "系统自动推导", + "saveConfirm": "确定要保存聚合扫码配置吗?", + "missingAppContext": "请从应用管理进入聚合扫码配置", + "notSelected": "未选择", + "levelActive": "生效中", + "scenes": { + "wechat_pay": "微信环境", + "alipay": "支付宝环境", + "union_pay": "云闪付环境", + "douyin": "抖音环境" + }, + "modeAuto": "自动模式", + "modeMethod": "方式模式", + "modeDirect": "精确模式" + } +} diff --git a/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/app.json b/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/app.json index a263e88f6..7f5ceb381 100644 --- a/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/app.json +++ b/apps/daxpay-admin/src/locales/langs/zh-CN/payment/merchant/app.json @@ -25,6 +25,7 @@ "validationAppName": "请输入应用名称", "validationStatus": "请选择状态", "payRoute": "通道路由", + "aggregateScan": "聚合扫码", "notifyConfig": "通知配置" } } diff --git a/apps/daxpay-admin/src/views/payment/merchant/aggregate/AggregateScanConfig.vue b/apps/daxpay-admin/src/views/payment/merchant/aggregate/AggregateScanConfig.vue new file mode 100644 index 000000000..052874398 --- /dev/null +++ b/apps/daxpay-admin/src/views/payment/merchant/aggregate/AggregateScanConfig.vue @@ -0,0 +1,450 @@ + + + + + diff --git a/apps/daxpay-admin/src/views/payment/merchant/aggregate/shared/constants.ts b/apps/daxpay-admin/src/views/payment/merchant/aggregate/shared/constants.ts new file mode 100644 index 000000000..2be9b7090 --- /dev/null +++ b/apps/daxpay-admin/src/views/payment/merchant/aggregate/shared/constants.ts @@ -0,0 +1,34 @@ +// 聚合扫码配置深度(与后端 AggregateConfigLevelEnum 对齐) +export const AGGREGATE_LEVEL = { + AUTO: 'auto', + METHOD: 'method', + DIRECT: 'direct', +} as const; + +export type AggregateLevel = (typeof AGGREGATE_LEVEL)[keyof typeof AGGREGATE_LEVEL]; + +/** + * 聚合扫码场景定义 + * scene: 后端 CashierSceneEnum 编码 + * provider: 对应的支付渠道(PayProviderEnum),用于过滤支付方式候选 + * defaultMethod: L1 自动推导的默认支付方式(与后端 SceneMethodDefaultResolver 对齐) + */ +export interface AggregateSceneConfig { + scene: string; + provider: string; + defaultMethod: string; +} + +export const AGGREGATE_SCENES: AggregateSceneConfig[] = [ + { scene: 'wechat_pay', provider: 'wechat', defaultMethod: 'wechat_jsapi' }, + { scene: 'alipay', provider: 'alipay', defaultMethod: 'alipay_jsapi' }, + { scene: 'union_pay', provider: 'union_pay', defaultMethod: 'union_jsapi' }, + { scene: 'douyin', provider: 'douyin', defaultMethod: 'douyin_jsapi' }, +]; + +// 模式显示名 +export const LEVEL_DISPLAY: Record = { + auto: '自动模式', + method: '方式模式', + direct: '精确模式', +}; diff --git a/apps/daxpay-admin/src/views/payment/merchant/app/MchAppInfoCard.vue b/apps/daxpay-admin/src/views/payment/merchant/app/MchAppInfoCard.vue index 41512bf8e..3654c39bb 100644 --- a/apps/daxpay-admin/src/views/payment/merchant/app/MchAppInfoCard.vue +++ b/apps/daxpay-admin/src/views/payment/merchant/app/MchAppInfoCard.vue @@ -40,6 +40,14 @@ }); } + /** 进入聚合扫码配置 */ + function goAggregateScan() { + router.push({ + path: '/payment/merchant/aggregate', + query: { mchNo: props.mchNo, appId: props.record.appId }, + }); + } + /** * 更多操作菜单 */ @@ -117,6 +125,21 @@ + + + + +