mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-12 23:45:39 +08:00
feat: 支付宝通道商户应用管理(ISV/直连)拆分重构
This commit is contained in:
105
apps/daxpay-admin/src/api/payment/alipayChannelMerchant.api.ts
Normal file
105
apps/daxpay-admin/src/api/payment/alipayChannelMerchant.api.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import type { MchEntity, Result } from '#/types/web';
|
||||
|
||||
import { defHttp } from '#/api/request';
|
||||
|
||||
/**
|
||||
* 支付宝服务商通道商户 API
|
||||
*/
|
||||
export const AlipayIsvChannelMerchantApi = {
|
||||
/**
|
||||
* 创建支付宝服务商通道商户
|
||||
*/
|
||||
create(data: AlipayIsvChannelMerchantCreateParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/alipay/isv-channel-merchant/create', data });
|
||||
},
|
||||
/**
|
||||
* 根据通道商户号查询支付宝服务商通道商户配置
|
||||
*/
|
||||
findByChannelMchNo(channelMchNo: string): Promise<Result<AlipayIsvChannelMerchantConfig>> {
|
||||
return defHttp.get({
|
||||
url: '/admin/alipay/isv-channel-merchant/find-by-channel-mch-no',
|
||||
params: { channelMchNo },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 支付宝直连通道商户 API
|
||||
*/
|
||||
export const AlipayDirectChannelMerchantApi = {
|
||||
/**
|
||||
* 创建支付宝直连通道商户
|
||||
*/
|
||||
create(data: AlipayDirectChannelMerchantCreateParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/alipay/direct-channel-merchant/create', data });
|
||||
},
|
||||
/**
|
||||
* 根据通道商户号查询支付宝直连通道商户配置
|
||||
*/
|
||||
findByChannelMchNo(channelMchNo: string): Promise<Result<AlipayDirectChannelMerchantConfig>> {
|
||||
return defHttp.get({
|
||||
url: '/admin/alipay/direct-channel-merchant/find-by-channel-mch-no',
|
||||
params: { channelMchNo },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 支付宝服务商通道商户配置
|
||||
*/
|
||||
export interface AlipayIsvChannelMerchantConfig extends MchEntity {
|
||||
/** 通道商户号 */
|
||||
channelMchNo?: string;
|
||||
/** 所属支付产品 */
|
||||
product?: string;
|
||||
/** 关联服务商应用ID(系统主键, 指向 alipay_isv_app.id) */
|
||||
isvAppId?: string;
|
||||
/** 子商户支付宝识别码(2088开头) */
|
||||
alipayUserId?: string;
|
||||
/** 应用授权令牌(会过期/刷新) */
|
||||
appAuthToken?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝直连通道商户配置
|
||||
*/
|
||||
export interface AlipayDirectChannelMerchantConfig extends MchEntity {
|
||||
/** 通道商户号(系统生成雪花号) */
|
||||
channelMchNo?: string;
|
||||
/** 所属支付产品 */
|
||||
product?: string;
|
||||
/** 支付宝商家唯一识别码(2088开头) */
|
||||
alipayUserId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝服务商通道商户创建参数
|
||||
*/
|
||||
export interface AlipayIsvChannelMerchantCreateParam {
|
||||
/** 商户号 */
|
||||
mchNo: string;
|
||||
/** 通道商户名称 */
|
||||
channelMerchantName: string;
|
||||
/** 所属支付产品 */
|
||||
product: string;
|
||||
/** 服务商应用ID(系统主键) */
|
||||
appId: string;
|
||||
/** 子商户支付宝用户ID(2088开头) */
|
||||
alipayUserId: string;
|
||||
/** 应用授权令牌 */
|
||||
appAuthToken: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝直连通道商户创建参数
|
||||
*/
|
||||
export interface AlipayDirectChannelMerchantCreateParam {
|
||||
/** 商户号 */
|
||||
mchNo: string;
|
||||
/** 通道商户名称 */
|
||||
channelMerchantName: string;
|
||||
/** 所属支付产品 */
|
||||
product: string;
|
||||
/** 支付宝商家用户ID(2088开头) */
|
||||
alipayUserId: string;
|
||||
}
|
||||
@@ -108,33 +108,6 @@ export interface ChannelMerchantBaseCreateParam {
|
||||
channel: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝通道商户创建 API
|
||||
*/
|
||||
export const ChannelMerchantAlipayApi = {
|
||||
/**
|
||||
* 创建支付宝通道商户(服务商)
|
||||
*/
|
||||
create(data: Record<string, any>): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/alipay/channel-merchant/create', data });
|
||||
},
|
||||
/**
|
||||
* 创建支付宝通道商户(直连)
|
||||
*/
|
||||
createDirect(data: Record<string, any>): Promise<Result<string>> {
|
||||
return defHttp.post({ url: '/admin/alipay/channel-merchant/create-direct', data });
|
||||
},
|
||||
/**
|
||||
* 根据通道商户号查询支付宝通道商户配置
|
||||
*/
|
||||
findByChannelMchNo(channelMchNo: string): Promise<Result<AlipayChannelMerchantConfig>> {
|
||||
return defHttp.get({
|
||||
url: '/admin/alipay/channel-merchant/find-by-channel-mch-no',
|
||||
params: { channelMchNo },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 微信通道商户创建 API
|
||||
*/
|
||||
@@ -192,20 +165,6 @@ export const ChannelMerchantDouyinApi = {
|
||||
},
|
||||
};
|
||||
|
||||
/** 支付宝通道商户配置 */
|
||||
export interface AlipayChannelMerchantConfig extends MchEntity {
|
||||
/** 通道商户号 */
|
||||
channelMchNo?: string;
|
||||
/** 所属支付产品 */
|
||||
product?: string;
|
||||
/** 支付宝服务商应用 ID */
|
||||
isvAppId?: string;
|
||||
/** 子商户号 */
|
||||
alipayUserId?: string;
|
||||
/** 应用授权令牌 */
|
||||
appAuthToken?: string;
|
||||
}
|
||||
|
||||
/** 微信通道商户配置 */
|
||||
export interface WechatChannelMerchantConfig extends MchEntity {
|
||||
/** 通道商户号 */
|
||||
|
||||
@@ -2,7 +2,5 @@
|
||||
"title": "Alipay Direct Management",
|
||||
"groupApp": "App Management",
|
||||
"cardMchApp": "Alipay Channel Merchant Apps",
|
||||
"cardMchAppDesc": "Manage Alipay channel merchant applications",
|
||||
"cardAddMchApp": "Add Alipay App",
|
||||
"cardAddMchAppDesc": "Create a new Alipay channel merchant app"
|
||||
"cardMchAppDesc": "Manage Alipay channel merchant applications"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,5 @@
|
||||
"title": "支付宝直连管理",
|
||||
"groupApp": "应用管理",
|
||||
"cardMchApp": "支付宝通道商户应用",
|
||||
"cardMchAppDesc": "管理支付宝通道商户应用",
|
||||
"cardAddMchApp": "添加支付宝应用",
|
||||
"cardAddMchAppDesc": "创建新的支付宝通道商户应用"
|
||||
"cardMchAppDesc": "管理支付宝通道商户应用"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { $t } from '@vben/locales';
|
||||
|
||||
import { IconifyIcon } from '@vben-core/icons';
|
||||
|
||||
import { ChannelMerchantAlipayApi } from '#/api/payment/channelMerchant.api';
|
||||
import { AlipayDirectChannelMerchantApi } from '#/api/payment/alipayChannelMerchant.api';
|
||||
import ChannelLogo from '#/components/channel/ChannelLogo.vue';
|
||||
import { channelI18nMap, channelNameMap, productI18nMap, productNameMap } from '#/enums/payment';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
@@ -74,10 +74,9 @@ function handlePrev() {
|
||||
function handleSubmit() {
|
||||
formRef.value?.validate().then(() => {
|
||||
submitLoading.value = true;
|
||||
ChannelMerchantAlipayApi.createDirect({
|
||||
AlipayDirectChannelMerchantApi.create({
|
||||
mchNo: mchNo.value,
|
||||
product: productCode.value,
|
||||
channel: 'alipay',
|
||||
...form.value,
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
@@ -6,7 +6,10 @@ import { $t } from '@vben/locales';
|
||||
import { IconifyIcon } from '@vben-core/icons';
|
||||
|
||||
import { type AlipayIsvApp, AlipayIsvAppApi } from '#/api/payment/alipayIsvApp.api';
|
||||
import { ChannelMerchantAlipayApi } from '#/api/payment/channelMerchant.api';
|
||||
import {
|
||||
type AlipayIsvChannelMerchantCreateParam,
|
||||
AlipayIsvChannelMerchantApi,
|
||||
} from '#/api/payment/alipayChannelMerchant.api';
|
||||
import ChannelLogo from '#/components/channel/ChannelLogo.vue';
|
||||
import { channelI18nMap, channelNameMap, productI18nMap, productNameMap } from '#/enums/payment';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
@@ -26,7 +29,7 @@ const channelCode = ref('');
|
||||
const formRef = ref();
|
||||
const form = ref({
|
||||
channelMerchantName: '',
|
||||
isvAppId: undefined as string | undefined,
|
||||
appId: undefined as string | undefined,
|
||||
alipayUserId: '',
|
||||
appAuthToken: '',
|
||||
});
|
||||
@@ -61,15 +64,15 @@ const productDisplayName = computed(() => {
|
||||
|
||||
const rules = computed(() => ({
|
||||
channelMerchantName: [{ required: true, message: $t('payment.merchant.channelMerchant.channelMerchantNameRequired') }],
|
||||
isvAppId: [{ required: true, message: $t('payment.merchant.channelMerchant.alipayIsvAppRequired') }],
|
||||
appId: [{ required: true, message: $t('payment.merchant.channelMerchant.alipayIsvAppRequired') }],
|
||||
alipayUserId: [{ required: true, message: $t('payment.merchant.channelMerchant.alipaySubMerchantNoRequired') }],
|
||||
appAuthToken: [{ required: true, message: $t('payment.merchant.channelMerchant.appAuthTokenRequired') }],
|
||||
}));
|
||||
|
||||
/** 支付宝应用下拉选项(antdv-next Select 需使用 options 属性) */
|
||||
/** 支付宝应用下拉选项(值为系统主键id, 展示应用名+支付宝APPID便于识别) */
|
||||
const isvAppOptions = computed(() =>
|
||||
isvAppList.value.map((item) => ({
|
||||
value: item.aliAppId,
|
||||
value: item.id,
|
||||
label: `${item.appName} (${item.aliAppId})`,
|
||||
})),
|
||||
);
|
||||
@@ -109,10 +112,8 @@ function getData(): Record<string, any> {
|
||||
}
|
||||
|
||||
function submit(param: Record<string, any>): Promise<any> {
|
||||
return ChannelMerchantAlipayApi.create({
|
||||
...param,
|
||||
...form.value,
|
||||
});
|
||||
// param 已由 handleSubmit 组装完整(mchNo/product/form 各字段), 直接透传
|
||||
return AlipayIsvChannelMerchantApi.create(param as AlipayIsvChannelMerchantCreateParam);
|
||||
}
|
||||
|
||||
function handlePrev() {
|
||||
@@ -125,7 +126,6 @@ function handleSubmit() {
|
||||
const param = {
|
||||
mchNo: mchNo.value,
|
||||
product: productCode.value,
|
||||
channel: 'alipay',
|
||||
...form.value,
|
||||
};
|
||||
submit(param)
|
||||
@@ -142,7 +142,7 @@ function handleSubmit() {
|
||||
function resetForm() {
|
||||
form.value = {
|
||||
channelMerchantName: '',
|
||||
isvAppId: undefined,
|
||||
appId: undefined,
|
||||
alipayUserId: '',
|
||||
appAuthToken: '',
|
||||
};
|
||||
@@ -180,7 +180,7 @@ defineExpose({ init, validate, getData, submit });
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- 国际化:支付宝应用 -->
|
||||
<a-form-item name="isvAppId">
|
||||
<a-form-item name="appId">
|
||||
<template #label>
|
||||
{{ $t('payment.merchant.channelMerchant.alipayIsvApp') }}
|
||||
<a-tooltip :title="$t('payment.merchant.channelMerchant.alipayIsvAppHelp')">
|
||||
@@ -188,7 +188,7 @@ defineExpose({ init, validate, getData, submit });
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-select
|
||||
v-model:value="form.isvAppId"
|
||||
v-model:value="form.appId"
|
||||
:options="isvAppOptions"
|
||||
:loading="isvAppLoading"
|
||||
:placeholder="$t('payment.merchant.channelMerchant.alipayIsvAppPlaceholder')"
|
||||
|
||||
@@ -3,11 +3,14 @@ import { computed, ref, watch } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { type AlipayIsvApp, AlipayIsvAppApi } from '#/api/payment/alipayIsvApp.api';
|
||||
import {
|
||||
ChannelMerchantAlipayApi,
|
||||
type AlipayChannelMerchantConfig,
|
||||
type ChannelMerchantResult,
|
||||
} from '#/api/payment/channelMerchant.api';
|
||||
AlipayDirectChannelMerchantApi,
|
||||
AlipayIsvChannelMerchantApi,
|
||||
type AlipayDirectChannelMerchantConfig,
|
||||
type AlipayIsvChannelMerchantConfig,
|
||||
} from '#/api/payment/alipayChannelMerchant.api';
|
||||
import { type ChannelMerchantResult } from '#/api/payment/channelMerchant.api';
|
||||
import { ProductEnum } from '#/enums/payment/productEnum';
|
||||
|
||||
defineOptions({ name: 'AlipayChannelMerchantBasicInfo' });
|
||||
@@ -19,7 +22,12 @@ const props = defineProps<{
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const config = ref<AlipayChannelMerchantConfig>({});
|
||||
// 服务商通道商户配置(含 isvAppId / alipayUserId / appAuthToken)
|
||||
const isvConfig = ref<AlipayIsvChannelMerchantConfig>({});
|
||||
// 直连通道商户配置(含 alipayUserId)
|
||||
const directConfig = ref<AlipayDirectChannelMerchantConfig>({});
|
||||
// 关联的服务商应用详情(用于展示 aliAppId, 让用户能识别对应的应用)
|
||||
const isvAppInfo = ref<AlipayIsvApp>({});
|
||||
|
||||
/** 是否为直连产品 */
|
||||
const isDirectProduct = computed(() => props.channelMerchant.product === ProductEnum.ALIPAY);
|
||||
@@ -54,15 +62,38 @@ const sourceLabel = computed(() => {
|
||||
return props.channelMerchant.source || '-';
|
||||
});
|
||||
|
||||
/** 加载支付宝通道商户配置 */
|
||||
/**
|
||||
* 加载支付宝通道商户配置
|
||||
* 按支付产品类型分别调用服务商/直连接口
|
||||
*/
|
||||
function loadConfig() {
|
||||
if (!props.channelMchNo) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
ChannelMerchantAlipayApi.findByChannelMchNo(props.channelMchNo)
|
||||
// 重置状态
|
||||
isvConfig.value = {};
|
||||
directConfig.value = {};
|
||||
isvAppInfo.value = {};
|
||||
|
||||
const query = isIsvProduct.value
|
||||
? AlipayIsvChannelMerchantApi.findByChannelMchNo(props.channelMchNo)
|
||||
: AlipayDirectChannelMerchantApi.findByChannelMchNo(props.channelMchNo);
|
||||
|
||||
query
|
||||
.then(({ data }) => {
|
||||
config.value = data || {};
|
||||
if (isIsvProduct.value) {
|
||||
isvConfig.value = data || {};
|
||||
// 服务商场景: 查应用详情, 展示 aliAppId 让用户能识别对应应用
|
||||
const appId = isvConfig.value.isvAppId;
|
||||
if (appId) {
|
||||
return AlipayIsvAppApi.findById(appId).then(({ data: appData }) => {
|
||||
isvAppInfo.value = appData || {};
|
||||
});
|
||||
}
|
||||
} else {
|
||||
directConfig.value = data || {};
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
@@ -100,7 +131,7 @@ defineExpose({ open, close });
|
||||
<a-spin :spinning="loading">
|
||||
<a-descriptions bordered :column="1" size="small">
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.channelMerchantNo')">
|
||||
{{ channelMerchant.channelMchNo || config.channelMchNo || '-' }}
|
||||
{{ channelMerchant.channelMchNo || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.channelMerchantName')">
|
||||
{{ channelMerchant.channelMerchantName || '-' }}
|
||||
@@ -112,17 +143,17 @@ defineExpose({ open, close });
|
||||
{{ sourceLabel }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="isDirectProduct" :label="$t('payment.channel.alipay.alipayUserId')">
|
||||
{{ config.alipayUserId || '-' }}
|
||||
{{ directConfig.alipayUserId || '-' }}
|
||||
</a-descriptions-item>
|
||||
<template v-if="isIsvProduct">
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.alipayIsvApp')">
|
||||
{{ config.isvAppId || '-' }}
|
||||
{{ isvAppInfo.aliAppId || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.alipaySubMerchantNo')">
|
||||
{{ config.alipayUserId || '-' }}
|
||||
{{ isvConfig.alipayUserId || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.appAuthToken')">
|
||||
{{ config.appAuthToken ? maskSecret(config.appAuthToken) : '-' }}
|
||||
{{ isvConfig.appAuthToken ? maskSecret(isvConfig.appAuthToken) : '-' }}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
</a-descriptions>
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
import type { ChannelMerchantResult } from '#/api/payment/channelMerchant.api';
|
||||
|
||||
import { ProductEnum } from '#/enums/payment/productEnum';
|
||||
|
||||
import AlipayChannelMerchantBasicInfo from './AlipayChannelMerchantBasicInfo.vue';
|
||||
import AlipayMchAppEdit from './app/AlipayMchAppEdit.vue';
|
||||
|
||||
defineOptions({ name: 'AlipayMchManage' });
|
||||
|
||||
@@ -19,7 +20,6 @@
|
||||
const channelMchNo = ref('');
|
||||
const channelMerchant = ref<ChannelMerchantResult>({});
|
||||
const basicInfoRef = ref<InstanceType<typeof AlipayChannelMerchantBasicInfo>>();
|
||||
const mchAppEditRef = ref<InstanceType<typeof AlipayMchAppEdit>>();
|
||||
|
||||
/** 功能卡片配置 */
|
||||
const functionCards = computed(() => [
|
||||
@@ -42,14 +42,6 @@
|
||||
group: $t('payment.channel.alipayMchManage.groupApp'),
|
||||
color: 'blue',
|
||||
cards: [
|
||||
{
|
||||
key: 'addMchApp',
|
||||
// 国际化:添加支付宝应用
|
||||
title: $t('payment.channel.alipayMchManage.cardAddMchApp'),
|
||||
icon: 'ant-design:plus-circle-outlined',
|
||||
// 国际化:创建新的支付宝通道商户应用
|
||||
description: $t('payment.channel.alipayMchManage.cardAddMchAppDesc'),
|
||||
},
|
||||
{
|
||||
key: 'mchApp',
|
||||
// 国际化:通道商户应用
|
||||
@@ -88,33 +80,21 @@
|
||||
channelMerchant.value = summary;
|
||||
}
|
||||
|
||||
/** 添加应用成功,跳转到应用管理页 */
|
||||
function handleAddAppOk() {
|
||||
router.push({
|
||||
path: '/payment/merchant/channel-merchant/alipay-app-manage',
|
||||
query: {
|
||||
mchNo: mchNo.value,
|
||||
channelMchNo: channelMchNo.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 卡片点击 */
|
||||
function handleCardClick(card: { key: string; route?: string }) {
|
||||
if (card.key === 'basicInfo') {
|
||||
basicInfoRef.value?.open();
|
||||
return;
|
||||
}
|
||||
if (card.key === 'addMchApp') {
|
||||
mchAppEditRef.value?.show(mchNo.value, channelMchNo.value);
|
||||
return;
|
||||
}
|
||||
if (card.route) {
|
||||
router.push({
|
||||
path: card.route,
|
||||
query: {
|
||||
mchNo: mchNo.value,
|
||||
channelMchNo: channelMchNo.value,
|
||||
// 国际化:透传通道商户 id 与产品类型,使应用管理页返回时能回到详情页
|
||||
channelMerchantId: channelMerchant.value.id,
|
||||
product: ProductEnum.ALIPAY,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -176,7 +156,6 @@
|
||||
:channel-mch-no="channelMchNo"
|
||||
:channel-merchant="channelMerchant"
|
||||
/>
|
||||
<AlipayMchAppEdit ref="mchAppEditRef" @ok="handleAddAppOk" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user