mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-11 23:25:33 +08:00
feat(wechat): 管理端支持配置服务商认证应用类型
在特约商户应用管理中新增认证应用配置弹窗,创建与基本信息同步暴露 authAppType。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,6 +21,12 @@ export const WechatIsvChannelMerchantApi = {
|
||||
params: { channelMchNo },
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 更新认证应用类型
|
||||
*/
|
||||
updateAuthAppType(data: WechatIsvAuthAppTypeUpdateParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/wechat/isv-channel-merchant/update-auth-app-type', data });
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,6 +75,8 @@ export interface WechatIsvChannelMerchantConfig extends MchEntity {
|
||||
product?: string;
|
||||
/** 微信特约商户号/二级商户号 */
|
||||
subMchId?: string;
|
||||
/** 认证应用类型: SP_APP=服务商应用, SUB_APP=子商户应用 */
|
||||
authAppType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +103,18 @@ export interface WechatIsvChannelMerchantCreateParam {
|
||||
product: string;
|
||||
/** 微信特约商户号/二级商户号 */
|
||||
subMchId: string;
|
||||
/** 认证应用类型: SP_APP=服务商应用, SUB_APP=子商户应用, 默认 SP_APP */
|
||||
authAppType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信服务商认证应用类型更新参数
|
||||
*/
|
||||
export interface WechatIsvAuthAppTypeUpdateParam {
|
||||
/** 通道商户号 */
|
||||
channelMchNo: string;
|
||||
/** 认证应用类型: SP_APP=服务商应用, SUB_APP=子商户应用 */
|
||||
authAppType: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,6 +57,16 @@
|
||||
"capabilityIspDefault": "ISP Default",
|
||||
"capabilityIspNotConfigured": "Not configured",
|
||||
"capabilityNoMchAppTip": "No sub-merchant app created; all capabilities will use the ISP default app",
|
||||
"cardAuthApp": "Auth App Config",
|
||||
"cardAuthAppDesc": "Choose whether OpenId authorization uses the service provider app or the sub-merchant app",
|
||||
"authAppConfigTitle": "Auth App Config",
|
||||
"authAppType": "Auth Application Type",
|
||||
"authAppTypeSpApp": "Service Provider App",
|
||||
"authAppTypeSubApp": "Sub-merchant App",
|
||||
"authAppTypeRequired": "Please select auth application type",
|
||||
"authAppTypeSubTip": "When using a sub-merchant app, create one in App Management and configure auth settings first",
|
||||
"authAppTypeConfirm": "Confirm changing the auth application type?",
|
||||
"authAppTypeSaveSuccess": "Auth application type saved successfully",
|
||||
"validation": {
|
||||
"appSecret": "App secret is required",
|
||||
"authCallbackUrl": "Auth callback URL is required"
|
||||
|
||||
@@ -57,6 +57,16 @@
|
||||
"capabilityIspDefault": "服务商默认",
|
||||
"capabilityIspNotConfigured": "未配置",
|
||||
"capabilityNoMchAppTip": "尚未创建子商户应用,所有能力将使用服务商默认应用",
|
||||
"cardAuthApp": "认证应用配置",
|
||||
"cardAuthAppDesc": "选择 OpenId 授权使用服务商应用还是子商户应用",
|
||||
"authAppConfigTitle": "认证应用配置",
|
||||
"authAppType": "认证应用类型",
|
||||
"authAppTypeSpApp": "服务商应用",
|
||||
"authAppTypeSubApp": "子商户应用",
|
||||
"authAppTypeRequired": "请选择认证应用类型",
|
||||
"authAppTypeSubTip": "选择子商户应用时,请先在应用管理中创建并配置授权认证参数",
|
||||
"authAppTypeConfirm": "确认修改认证应用类型?",
|
||||
"authAppTypeSaveSuccess": "认证应用类型保存成功",
|
||||
"validation": {
|
||||
"appSecret": "请输入应用密钥",
|
||||
"authCallbackUrl": "请输入授权回调地址"
|
||||
|
||||
@@ -29,6 +29,8 @@ const formRef = ref();
|
||||
const form = ref({
|
||||
channelMerchantName: '',
|
||||
subMchId: '',
|
||||
// 认证应用类型, 默认服务商应用
|
||||
authAppType: 'SP_APP',
|
||||
});
|
||||
|
||||
const visible = ref(false);
|
||||
@@ -49,6 +51,7 @@ const productDisplayName = computed(() => {
|
||||
const rules = computed(() => ({
|
||||
channelMerchantName: [{ required: true, message: $t('payment.merchant.channelMerchant.channelMerchantNameRequired') }],
|
||||
subMchId: [{ required: true, message: $t('payment.merchant.channelMerchant.wechatSubMerchantNoRequired') }],
|
||||
authAppType: [{ required: true, message: $t('payment.channel.wechatManage.authAppTypeRequired') }],
|
||||
}));
|
||||
|
||||
function init(no: string, product: string, channel: string) {
|
||||
@@ -86,6 +89,7 @@ function resetForm() {
|
||||
form.value = {
|
||||
channelMerchantName: '',
|
||||
subMchId: '',
|
||||
authAppType: 'SP_APP',
|
||||
};
|
||||
nextTick(() => {
|
||||
formRef.value?.resetFields();
|
||||
@@ -128,6 +132,24 @@ defineExpose({ init });
|
||||
:placeholder="$t('payment.merchant.channelMerchant.wechatSubMerchantNoPlaceholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- 国际化:认证应用类型 -->
|
||||
<a-form-item :label="$t('payment.channel.wechatManage.authAppType')" name="authAppType">
|
||||
<a-radio-group v-model:value="form.authAppType" button-style="solid">
|
||||
<a-radio-button value="SP_APP">
|
||||
{{ $t('payment.channel.wechatManage.authAppTypeSpApp') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="SUB_APP">
|
||||
{{ $t('payment.channel.wechatManage.authAppTypeSubApp') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.authAppType === 'SUB_APP'" :wrapper-col="{ offset: 6, span: 16 }">
|
||||
<a-alert
|
||||
type="info"
|
||||
show-icon
|
||||
:message="$t('payment.channel.wechatManage.authAppTypeSubTip')"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<div class="flex justify-center gap-4 mt-8 pt-6 border-t border-border">
|
||||
<a-button @click="handlePrev">
|
||||
|
||||
@@ -34,6 +34,17 @@ const sourceLabel = computed(() => {
|
||||
return props.channelMerchant.source || '-';
|
||||
});
|
||||
|
||||
/** 认证应用类型展示文案 */
|
||||
const authAppTypeLabel = computed(() => {
|
||||
if (config.value.authAppType === 'SUB_APP') {
|
||||
return $t('payment.channel.wechatManage.authAppTypeSubApp');
|
||||
}
|
||||
if (config.value.authAppType === 'SP_APP' || !config.value.authAppType) {
|
||||
return $t('payment.channel.wechatManage.authAppTypeSpApp');
|
||||
}
|
||||
return config.value.authAppType;
|
||||
});
|
||||
|
||||
/** 加载微信服务商通道商户配置 */
|
||||
function loadConfig() {
|
||||
if (!props.channelMchNo) {
|
||||
@@ -96,6 +107,9 @@ defineExpose({ open, close });
|
||||
<a-descriptions-item :label="$t('payment.merchant.channelMerchant.wechatSubMerchantNo')">
|
||||
{{ config.subMchId || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('payment.channel.wechatManage.authAppType')">
|
||||
{{ authAppTypeLabel }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-spin>
|
||||
</a-drawer>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import ChannelMerchantNameEditModal from '#/views/payment/merchant/channel-merchant/detail/ChannelMerchantNameEditModal.vue';
|
||||
|
||||
import WechatChannelMerchantBasicInfo from './WechatChannelMerchantBasicInfo.vue';
|
||||
import WechatIsvAuthAppConfig from './WechatIsvAuthAppConfig.vue';
|
||||
import WechatIsvMchAppCapability from './WechatIsvMchAppCapability.vue';
|
||||
|
||||
defineOptions({ name: 'WechatChannelMerchantManage' });
|
||||
@@ -29,6 +30,7 @@
|
||||
const channelMerchant = ref<ChannelMerchantResult>({});
|
||||
const basicInfoRef = ref<InstanceType<typeof WechatChannelMerchantBasicInfo>>();
|
||||
const capabilityRef = ref<InstanceType<typeof WechatIsvMchAppCapability>>();
|
||||
const authAppConfigRef = ref<InstanceType<typeof WechatIsvAuthAppConfig>>();
|
||||
const editNameRef = ref<InstanceType<typeof ChannelMerchantNameEditModal>>();
|
||||
|
||||
/** 功能卡片配置 */
|
||||
@@ -73,6 +75,13 @@
|
||||
icon: 'ant-design:api-outlined',
|
||||
description: $t('payment.channel.wechatManage.cardCapabilityBindingDesc'),
|
||||
},
|
||||
{
|
||||
key: 'authApp',
|
||||
// 国际化:认证应用配置
|
||||
title: $t('payment.channel.wechatManage.cardAuthApp'),
|
||||
icon: 'ant-design:safety-certificate-outlined',
|
||||
description: $t('payment.channel.wechatManage.cardAuthAppDesc'),
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -125,6 +134,10 @@
|
||||
capabilityRef.value?.show(mchNo.value, channelMchNo.value);
|
||||
return;
|
||||
}
|
||||
if (card.key === 'authApp') {
|
||||
authAppConfigRef.value?.open(channelMchNo.value);
|
||||
return;
|
||||
}
|
||||
message.info($t('payment.merchant.channelMerchant.developing'));
|
||||
}
|
||||
|
||||
@@ -182,6 +195,8 @@
|
||||
<ChannelMerchantNameEditModal ref="editNameRef" :channel-merchant="channelMerchant" @success="emit('success')" />
|
||||
|
||||
<WechatIsvMchAppCapability ref="capabilityRef" />
|
||||
|
||||
<WechatIsvAuthAppConfig ref="authAppConfigRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { WechatIsvChannelMerchantApi } from '#/api/payment/channel/wechat/channel-merchant.api';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
|
||||
defineOptions({ name: 'WechatIsvAuthAppConfig' });
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'success'): void;
|
||||
}>();
|
||||
|
||||
const { confirm, message } = useMessage();
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const saving = ref(false);
|
||||
const channelMchNo = ref('');
|
||||
// 表单选中的认证应用类型
|
||||
const authAppType = ref('SP_APP');
|
||||
|
||||
/** 加载当前配置 */
|
||||
function loadConfig() {
|
||||
if (!channelMchNo.value) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
WechatIsvChannelMerchantApi.findByChannelMchNo(channelMchNo.value)
|
||||
.then(({ data }) => {
|
||||
authAppType.value = data?.authAppType || 'SP_APP';
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
function open(mchChannelNo: string) {
|
||||
channelMchNo.value = mchChannelNo;
|
||||
authAppType.value = 'SP_APP';
|
||||
visible.value = true;
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
/** 关闭弹窗 */
|
||||
function close() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
/** 保存认证应用类型 */
|
||||
function handleSave() {
|
||||
confirm({
|
||||
title: $t('common.confirm'),
|
||||
content: $t('payment.channel.wechatManage.authAppTypeConfirm'),
|
||||
okText: $t('common.okText'),
|
||||
cancelText: $t('common.cancelText'),
|
||||
onOk() {
|
||||
saving.value = true;
|
||||
return WechatIsvChannelMerchantApi.updateAuthAppType({
|
||||
channelMchNo: channelMchNo.value,
|
||||
authAppType: authAppType.value,
|
||||
})
|
||||
.then(() => {
|
||||
message.success($t('payment.channel.wechatManage.authAppTypeSaveSuccess'));
|
||||
emit('success');
|
||||
close();
|
||||
})
|
||||
.finally(() => {
|
||||
saving.value = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({ open, close });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:open="visible"
|
||||
:title="$t('payment.channel.wechatManage.authAppConfigTitle')"
|
||||
:confirm-loading="saving"
|
||||
:ok-text="$t('common.save')"
|
||||
:cancel-text="$t('common.cancelText')"
|
||||
destroy-on-hidden
|
||||
@ok="handleSave"
|
||||
>
|
||||
<a-spin :spinning="loading">
|
||||
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
||||
<!-- 国际化:认证应用类型 -->
|
||||
<a-form-item :label="$t('payment.channel.wechatManage.authAppType')">
|
||||
<a-radio-group v-model:value="authAppType" button-style="solid">
|
||||
<a-radio-button value="SP_APP">
|
||||
{{ $t('payment.channel.wechatManage.authAppTypeSpApp') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="SUB_APP">
|
||||
{{ $t('payment.channel.wechatManage.authAppTypeSubApp') }}
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-alert
|
||||
v-if="authAppType === 'SUB_APP'"
|
||||
type="info"
|
||||
show-icon
|
||||
:message="$t('payment.channel.wechatManage.authAppTypeSubTip')"
|
||||
/>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
Reference in New Issue
Block a user