Files
frontend-app/pages/other_package/douyin_pay_test/douyin_pay_test.vue
T

326 lines
6.3 KiB
Vue
Raw Normal View History

2026-09-09 11:46:36 +08:00
<template>
<view class="test_page">
<NavHeader leftTitle="抖音支付测试" leftPathType="navigateTo" />
<view class="test_container">
<view class="card_box">
<view class="card_title">抖音 App 原生支付联调</view>
<view class="tip_box">
<text class="tip_text">粘贴 /order/payment 返回的完整 JSON(含 data.orderNum 和 data.douyin)。使用已集成 tb-douyin-pay 的自定义基座或完整安装包。测试将使用真实订单发起支付;最终结果以服务端查单为准。</text>
</view>
<view class="form_item">
<text class="form_label">接口返回 JSON</text>
<textarea class="form_textarea" v-model="paymentJson" placeholder="粘贴接口返回 JSON;也支持直接粘贴含 orderNum、douyin 的 data 对象" />
</view>
<button class="main_pay_btn" :loading="loading" :disabled="loading" @click="handleTestPay">发起该订单支付</button>
</view>
<view class="card_box">
<view class="card_title">联调结果</view>
<text>{{ resultText }}</text>
</view>
</view>
</view>
2026-09-09 11:46:36 +08:00
</template>
<script>
import NavHeader from "@/components/header.vue";
import { appDypayFun } from "@/utils/douyin-pay.js";
2026-09-09 11:46:36 +08:00
export default {
components: { NavHeader },
data() {
return { paymentJson: "", loading: false, resultText: "尚未调用支付" };
},
methods: {
async handleTestPay() {
if (this.loading) return;
// #ifndef APP-PLUS
this.resultText = "请使用已集成原生插件的 Android/iOS App 测试";
return;
// #endif
// #ifdef APP-PLUS
this.loading = true;
try {
const response = JSON.parse(this.paymentJson);
if (response.bizcode != null && response.bizcode !== 100) throw new Error("请使用下单成功的接口返回");
const payment = response.data || response;
if (!payment.orderNum || !payment.douyin) throw new Error("缺少 orderNum 或 douyin");
this.resultText = "正在调用原生 SDK,返回后查询订单状态";
const result = await appDypayFun(payment);
const labels = { paid: "服务端确认支付成功", failed: "服务端确认支付未成功", pending: "结果待确认,请稍后查看订单", error: "调用失败" };
this.resultText = result ? (result.message || labels[result.state] || "结果待确认") : "支付正在处理中";
} catch (error) {
this.resultText = error.message || "调用失败";
} finally {
this.loading = false;
}
// #endif
},
},
2026-09-09 11:46:36 +08:00
};
</script>
<style lang="scss" scoped>
.test_page {
min-height: 100vh;
background-color: #F6F7FB;
padding-bottom: 60rpx;
}
.test_container {
padding: 24rpx;
}
.card_box {
background: #FFFFFF;
border-radius: 20rpx;
padding: 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
.card_title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
.title_text {
font-size: 30rpx;
font-weight: 600;
color: #1F2937;
}
.tag_badge {
font-size: 22rpx;
padding: 4rpx 14rpx;
border-radius: 20rpx;
font-weight: 500;
&.badge_app {
background-color: #EDE9FE;
color: #7934F6;
}
&.badge_h5 {
background-color: #E0F2FE;
color: #0284C7;
}
}
.clear_link {
font-size: 24rpx;
color: #7934F6;
}
}
}
.info_grid {
background: #F9FAFB;
border-radius: 12rpx;
padding: 16rpx 20rpx;
.info_row {
display: flex;
justify-content: space-between;
font-size: 26rpx;
margin-bottom: 8rpx;
&:last-child {
margin-bottom: 0;
}
.info_label {
color: #6B7280;
}
.info_val {
font-weight: 500;
color: #111827;
}
}
}
.btn_row {
display: flex;
gap: 16rpx;
.mini_btn {
flex: 1;
font-size: 24rpx;
border-radius: 12rpx;
line-height: 2.2;
margin: 0;
border: none;
&.check_btn {
background: #F3F4F6;
color: #374151;
}
&.open_btn {
background: #EDE9FE;
color: #7934F6;
}
}
}
.preset_section {
margin-bottom: 20rpx;
.section_label {
font-size: 24rpx;
color: #6B7280;
display: block;
margin-bottom: 12rpx;
}
.preset_btn_group {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
.preset_chip {
font-size: 24rpx;
color: #7934F6;
background: #F4EFFF;
border: 1rpx solid #E4D4FF;
border-radius: 30rpx;
padding: 8rpx 22rpx;
}
}
}
.tip_box {
background: #FFFBEB;
border: 1rpx solid #FDE68A;
border-radius: 12rpx;
padding: 16rpx 20rpx;
margin-bottom: 24rpx;
.tip_text {
font-size: 24rpx;
color: #B45309;
line-height: 1.5;
}
}
.form_item {
margin-bottom: 20rpx;
.form_label {
font-size: 26rpx;
color: #374151;
font-weight: 500;
display: block;
margin-bottom: 10rpx;
}
.form_input {
background: #F9FAFB;
border: 1rpx solid #E5E7EB;
border-radius: 12rpx;
height: 72rpx;
padding: 0 20rpx;
font-size: 26rpx;
color: #111827;
}
.form_textarea {
width: 100%;
box-sizing: border-box;
background: #F9FAFB;
border: 1rpx solid #E5E7EB;
border-radius: 12rpx;
padding: 16rpx 20rpx;
font-size: 26rpx;
color: #111827;
height: 140rpx;
}
.radio_group {
display: flex;
gap: 30rpx;
.radio_item {
display: flex;
align-items: center;
font-size: 26rpx;
color: #374151;
}
}
&.half {
flex: 1;
margin-bottom: 0;
}
}
.form_row {
display: flex;
gap: 20rpx;
}
.action_section {
margin-bottom: 24rpx;
.main_pay_btn {
background: linear-gradient(135deg, #8B5CF6 0%, #7934F6 100%);
color: #FFFFFF;
font-size: 30rpx;
font-weight: 600;
height: 88rpx;
line-height: 88rpx;
border-radius: 44rpx;
box-shadow: 0 8rpx 20rpx rgba(121, 52, 246, 0.3);
border: none;
&:active {
opacity: 0.9;
}
}
}
.log_console {
background: #1E1E2E;
border-radius: 16rpx;
padding: 20rpx;
height: 380rpx;
box-sizing: border-box;
.empty_log {
color: #6C7086;
font-size: 24rpx;
text-align: center;
padding: 60rpx 0;
}
.log_item {
font-size: 24rpx;
font-family: monospace;
line-height: 1.6;
margin-bottom: 10rpx;
word-break: break-all;
.log_time {
color: #A6ADC8;
margin-right: 12rpx;
}
&.log_info .log_content {
color: #CDD6F4;
}
&.log_success .log_content {
color: #A6E3A1;
}
&.log_warn .log_content {
color: #F9E2AF;
}
&.log_error .log_content {
color: #F38BA8;
}
}
}
</style>