mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-11 15:15:34 +08:00
feat(alipay): 应用授权令牌设置弹窗+原代运营授权卡片更名
This commit is contained in:
@@ -12,6 +12,12 @@ export const AlipayIsvChannelMerchantApi = {
|
||||
create(data: AlipayIsvChannelMerchantCreateParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/alipay/isv-channel-merchant/create', data });
|
||||
},
|
||||
/**
|
||||
* 更新应用授权令牌(手动设置/更新, 适用于令牌补充或过期/变更后重新绑定)
|
||||
*/
|
||||
updateAppAuthToken(data: AlipayIsvAppAuthTokenUpdateParam): Promise<Result<void>> {
|
||||
return defHttp.post({ url: '/admin/alipay/isv-channel-merchant/update-app-auth-token', data });
|
||||
},
|
||||
/**
|
||||
* 根据通道商户号查询支付宝服务商通道商户配置
|
||||
*/
|
||||
@@ -103,3 +109,13 @@ export interface AlipayDirectChannelMerchantCreateParam {
|
||||
/** 支付宝商家用户ID(2088开头) */
|
||||
alipayUserId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用授权令牌更新参数
|
||||
*/
|
||||
export interface AlipayIsvAppAuthTokenUpdateParam {
|
||||
/** 通道商户号 */
|
||||
channelMchNo: string;
|
||||
/** 应用授权令牌 */
|
||||
appAuthToken: string;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"groupApp": "App Management",
|
||||
"cardBasicInfo": "Basic Info",
|
||||
"cardBasicInfoDesc": "View channel merchant basic configuration",
|
||||
"cardAuthOperation": "Auth Operation",
|
||||
"cardAuthOperationDesc": "Authorize platform to operate Alipay merchant, get app auth token",
|
||||
"cardAuthOperation": "App Auth Token",
|
||||
"cardAuthOperationDesc": "Set or update the app auth token for platform-operated Alipay merchant",
|
||||
"cardApp": "App Management",
|
||||
"cardAppDesc": "Channel merchant app creation and management",
|
||||
"basicInfoDrawerTitle": "Basic Info",
|
||||
@@ -75,6 +75,12 @@
|
||||
"appAuthTokenPlaceholder": "Please enter app auth token",
|
||||
"appAuthTokenHelp": "The app_auth_token value obtained after merchant authorization",
|
||||
"appAuthTokenRequired": "Please enter app auth token",
|
||||
"appAuthTokenSetTitle": "Set App Auth Token",
|
||||
"appAuthTokenCurrent": "Current Token",
|
||||
"appAuthTokenNew": "New Token",
|
||||
"appAuthTokenNewPlaceholder": "Please enter the new app auth token",
|
||||
"appAuthTokenUpdateConfirm": "Confirm updating the app auth token?",
|
||||
"appAuthTokenUpdateSuccess": "App auth token updated successfully",
|
||||
"alipayIsvApp": "Alipay Application",
|
||||
"alipayIsvAppPlaceholder": "Please select an Alipay application",
|
||||
"alipayIsvAppRequired": "Please select an Alipay application",
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"groupApp": "应用管理",
|
||||
"cardBasicInfo": "基本信息",
|
||||
"cardBasicInfoDesc": "查看通道商户基础配置信息",
|
||||
"cardAuthOperation": "代运营授权",
|
||||
"cardAuthOperationDesc": "授权平台代运营支付宝商户,获取应用授权令牌",
|
||||
"cardAuthOperation": "应用授权令牌",
|
||||
"cardAuthOperationDesc": "设置或更新应用授权令牌(授权密钥),用于平台代运营支付宝商户",
|
||||
"cardApp": "应用管理",
|
||||
"cardAppDesc": "通道商户应用创建与管理",
|
||||
"basicInfoDrawerTitle": "基本信息",
|
||||
@@ -75,6 +75,12 @@
|
||||
"appAuthTokenPlaceholder": "请输入应用授权令牌",
|
||||
"appAuthTokenHelp": "商家授权后获取到的app_auth_token值",
|
||||
"appAuthTokenRequired": "请输入应用授权令牌",
|
||||
"appAuthTokenSetTitle": "设置应用授权令牌",
|
||||
"appAuthTokenCurrent": "当前令牌",
|
||||
"appAuthTokenNew": "新令牌",
|
||||
"appAuthTokenNewPlaceholder": "请输入新的应用授权令牌",
|
||||
"appAuthTokenUpdateConfirm": "确认更新应用授权令牌?",
|
||||
"appAuthTokenUpdateSuccess": "应用授权令牌更新成功",
|
||||
"alipayIsvApp": "支付宝应用",
|
||||
"alipayIsvAppPlaceholder": "请选择支付宝应用",
|
||||
"alipayIsvAppRequired": "请选择支付宝应用",
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import {
|
||||
AlipayIsvChannelMerchantApi,
|
||||
type AlipayIsvChannelMerchantConfig,
|
||||
} from '#/api/payment/channel/alipay/channel-merchant.api';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
|
||||
defineOptions({ name: 'AlipayAppAuthTokenUpdate' });
|
||||
|
||||
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 isvConfig = ref<AlipayIsvChannelMerchantConfig>({});
|
||||
// 新令牌输入
|
||||
const newAuthToken = ref('');
|
||||
|
||||
/** 脱敏展示敏感字段 */
|
||||
function maskSecret(value?: string) {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
if (value.length <= 8) {
|
||||
return '****';
|
||||
}
|
||||
return `${value.slice(0, 4)}****${value.slice(-4)}`;
|
||||
}
|
||||
|
||||
/** 加载当前配置, 展示已有令牌 */
|
||||
function loadConfig() {
|
||||
if (!channelMchNo.value) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
isvConfig.value = {};
|
||||
AlipayIsvChannelMerchantApi.findByChannelMchNo(channelMchNo.value)
|
||||
.then(({ data }) => {
|
||||
isvConfig.value = data || {};
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
function open(mchNo: string) {
|
||||
channelMchNo.value = mchNo;
|
||||
newAuthToken.value = '';
|
||||
visible.value = true;
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
/** 关闭弹窗 */
|
||||
function close() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
/** 保存新令牌(二次确认后提交) */
|
||||
function handleSave() {
|
||||
if (!newAuthToken.value.trim()) {
|
||||
message.warning($t('payment.merchant.channelMerchant.appAuthTokenRequired'));
|
||||
return;
|
||||
}
|
||||
confirm({
|
||||
title: $t('common.confirm'),
|
||||
content: $t('payment.merchant.channelMerchant.appAuthTokenUpdateConfirm'),
|
||||
okText: $t('common.okText'),
|
||||
cancelText: $t('common.cancelText'),
|
||||
onOk() {
|
||||
saving.value = true;
|
||||
return AlipayIsvChannelMerchantApi.updateAppAuthToken({
|
||||
channelMchNo: channelMchNo.value,
|
||||
appAuthToken: newAuthToken.value.trim(),
|
||||
})
|
||||
.then(() => {
|
||||
message.success($t('payment.merchant.channelMerchant.appAuthTokenUpdateSuccess'));
|
||||
emit('success');
|
||||
close();
|
||||
})
|
||||
.finally(() => {
|
||||
saving.value = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({ open, close });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:open="visible"
|
||||
:title="$t('payment.merchant.channelMerchant.appAuthTokenSetTitle')"
|
||||
: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.merchant.channelMerchant.appAuthTokenCurrent')">
|
||||
{{ maskSecret(isvConfig.appAuthToken) }}
|
||||
</a-form-item>
|
||||
<!-- 国际化:新令牌 -->
|
||||
<a-form-item :label="$t('payment.merchant.channelMerchant.appAuthTokenNew')">
|
||||
<a-input
|
||||
v-model:value="newAuthToken"
|
||||
:placeholder="$t('payment.merchant.channelMerchant.appAuthTokenNewPlaceholder')"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
@@ -1,29 +1,30 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import type { ChannelMerchantResult } from '#/api/payment/channel/channel-merchant.api';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { IconifyIcon } from '@vben-core/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import type { ChannelMerchantResult } from '#/api/payment/channel/channel-merchant.api';
|
||||
import { useMessage } from '#/hooks/useMessage';
|
||||
import { IconifyIcon } from '@vben-core/icons';
|
||||
|
||||
import AlipayChannelMerchantBasicInfo from './AlipayChannelMerchantBasicInfo.vue';
|
||||
import AlipayAppAuthTokenUpdate from './AlipayAppAuthTokenUpdate.vue';
|
||||
import AlipayChannelMerchantBasicInfo from './AlipayChannelMerchantBasicInfo.vue';
|
||||
|
||||
defineOptions({ name: 'AlipayChannelMerchantManage' });
|
||||
defineOptions({ name: 'AlipayChannelMerchantManage' });
|
||||
|
||||
const mchNo = ref('');
|
||||
const channelMchNo = ref('');
|
||||
const channelMerchant = ref<ChannelMerchantResult>({});
|
||||
const basicInfoRef = ref<InstanceType<typeof AlipayChannelMerchantBasicInfo>>();
|
||||
const { message } = useMessage();
|
||||
const mchNo = ref('');
|
||||
const channelMchNo = ref('');
|
||||
const channelMerchant = ref<ChannelMerchantResult>({});
|
||||
const basicInfoRef = ref<InstanceType<typeof AlipayChannelMerchantBasicInfo>>();
|
||||
// 应用授权令牌更新弹窗
|
||||
const authTokenUpdateRef = ref<InstanceType<typeof AlipayAppAuthTokenUpdate>>();
|
||||
|
||||
/** 功能卡片配置(服务商通道商户:仅基本信息) */
|
||||
const functionCards = computed(() => [
|
||||
{
|
||||
// 国际化:基础管理
|
||||
group: $t('payment.merchant.channelMerchant.groupBasic'),
|
||||
color: 'blue',
|
||||
/** 功能卡片配置(服务商通道商户:仅基本信息) */
|
||||
const functionCards = computed(() => [
|
||||
{
|
||||
// 国际化:基础管理
|
||||
group: $t('payment.merchant.channelMerchant.groupBasic'),
|
||||
color: 'blue',
|
||||
cards: [
|
||||
{
|
||||
key: 'basicInfo',
|
||||
@@ -34,51 +35,50 @@ const functionCards = computed(() => [
|
||||
},
|
||||
{
|
||||
key: 'authOperation',
|
||||
// 国际化:代运营授权
|
||||
// 国际化:应用授权令牌
|
||||
title: $t('payment.merchant.channelMerchant.cardAuthOperation'),
|
||||
icon: 'ant-design:safety-certificate-outlined',
|
||||
description: $t('payment.merchant.channelMerchant.cardAuthOperationDesc'),
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
},
|
||||
]);
|
||||
|
||||
function getGroupColorClass(color: string) {
|
||||
const map: Record<string, string> = {
|
||||
blue: 'bg-blue-500',
|
||||
green: 'bg-emerald-500',
|
||||
};
|
||||
return map[color] || 'bg-gray-500';
|
||||
}
|
||||
|
||||
function getIconBgClass(color: string) {
|
||||
const map: Record<string, string> = {
|
||||
blue: 'bg-primary/10 text-primary',
|
||||
green: 'bg-success/10 text-success',
|
||||
};
|
||||
return map[color] || 'bg-muted text-muted-foreground';
|
||||
}
|
||||
|
||||
/** 初始化(由中转页调用) */
|
||||
function init(no: string, mchChannelNo: string, summary: ChannelMerchantResult) {
|
||||
mchNo.value = no;
|
||||
channelMchNo.value = mchChannelNo;
|
||||
channelMerchant.value = summary;
|
||||
}
|
||||
|
||||
function handleCardClick(card: { key: string }) {
|
||||
if (card.key === 'basicInfo') {
|
||||
basicInfoRef.value?.open();
|
||||
return;
|
||||
function getGroupColorClass(color: string) {
|
||||
const map: Record<string, string> = {
|
||||
blue: 'bg-blue-500',
|
||||
green: 'bg-emerald-500',
|
||||
};
|
||||
return map[color] || 'bg-gray-500';
|
||||
}
|
||||
if (card.key === 'authOperation') {
|
||||
// 国际化:功能开发中,敬请期待
|
||||
message.info($t('payment.merchant.channelMerchant.developing'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ init });
|
||||
function getIconBgClass(color: string) {
|
||||
const map: Record<string, string> = {
|
||||
blue: 'bg-primary/10 text-primary',
|
||||
green: 'bg-success/10 text-success',
|
||||
};
|
||||
return map[color] || 'bg-muted text-muted-foreground';
|
||||
}
|
||||
|
||||
/** 初始化(由中转页调用) */
|
||||
function init(no: string, mchChannelNo: string, summary: ChannelMerchantResult) {
|
||||
mchNo.value = no;
|
||||
channelMchNo.value = mchChannelNo;
|
||||
channelMerchant.value = summary;
|
||||
}
|
||||
|
||||
function handleCardClick(card: { key: string }) {
|
||||
if (card.key === 'basicInfo') {
|
||||
basicInfoRef.value?.open();
|
||||
return;
|
||||
}
|
||||
if (card.key === 'authOperation') {
|
||||
authTokenUpdateRef.value?.open(channelMchNo.value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ init });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -104,7 +104,9 @@ defineExpose({ init });
|
||||
>
|
||||
<IconifyIcon :icon="card.icon" class="h-7 w-7" />
|
||||
</div>
|
||||
<div class="mb-1.5 text-base font-bold text-foreground group-hover:text-primary transition-colors duration-300">
|
||||
<div
|
||||
class="mb-1.5 text-base font-bold text-foreground group-hover:text-primary transition-colors duration-300"
|
||||
>
|
||||
{{ card.title }}
|
||||
</div>
|
||||
<a-tooltip :title="card.description" placement="bottom">
|
||||
@@ -126,25 +128,27 @@ defineExpose({ init });
|
||||
:channel-mch-no="channelMchNo"
|
||||
:channel-merchant="channelMerchant"
|
||||
/>
|
||||
|
||||
<AlipayAppAuthTokenUpdate ref="authTokenUpdateRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 220px);
|
||||
gap: 24px;
|
||||
justify-content: center;
|
||||
}
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 220px);
|
||||
gap: 24px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.isv-card {
|
||||
max-height: 200px;
|
||||
}
|
||||
.isv-card {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.line-clamp-1 {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.line-clamp-1 {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user