upload project source code
This commit is contained in:
367
前端源码/uni-app/components/examples/PaymentExample.vue
Normal file
367
前端源码/uni-app/components/examples/PaymentExample.vue
Normal file
@@ -0,0 +1,367 @@
|
||||
<template>
|
||||
<view class="payment-example">
|
||||
<view class="example-header">
|
||||
<text class="example-title">支付功能示例</text>
|
||||
</view>
|
||||
|
||||
<!-- 示例1: 购买报告 -->
|
||||
<view class="example-section">
|
||||
<text class="example-section-title">示例1: 购买命名报告</text>
|
||||
<view class="example-card">
|
||||
<view class="example-card-content">
|
||||
<text class="example-card-name">张三命名报告</text>
|
||||
<text class="example-card-desc">包含六维分析、周易卦象等</text>
|
||||
<text class="example-card-price">¥99</text>
|
||||
</view>
|
||||
<view class="example-card-btn" @click="buyReport">
|
||||
<text class="example-card-btn-text">立即购买</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 示例2: 推广合伙人 -->
|
||||
<view class="example-section">
|
||||
<text class="example-section-title">示例2: 开通推广合伙人</text>
|
||||
<view class="example-card">
|
||||
<view class="example-card-content">
|
||||
<text class="example-card-name">推广合伙人权益</text>
|
||||
<text class="example-card-desc">开启睡后收入之旅</text>
|
||||
<text class="example-card-price">¥99</text>
|
||||
</view>
|
||||
<view class="example-card-btn" @click="buyPartner">
|
||||
<text class="example-card-btn-text">立即开通</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 示例3: 测试支付 -->
|
||||
<view class="example-section">
|
||||
<text class="example-section-title">示例3: 测试支付(0.01元)</text>
|
||||
<view class="example-card">
|
||||
<view class="example-card-content">
|
||||
<text class="example-card-name">测试商品</text>
|
||||
<text class="example-card-desc">用于测试支付流程</text>
|
||||
<text class="example-card-price">¥0.01</text>
|
||||
</view>
|
||||
<view class="example-card-btn" @click="testPay">
|
||||
<text class="example-card-btn-text">测试支付</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<view class="example-section">
|
||||
<text class="example-section-title">最近订单</text>
|
||||
<view v-if="orders.length === 0" class="example-empty">
|
||||
<text class="example-empty-text">暂无订单</text>
|
||||
</view>
|
||||
<view v-else class="example-orders">
|
||||
<view v-for="order in orders" :key="order.out_trade_no" class="example-order">
|
||||
<view class="example-order-info">
|
||||
<text class="example-order-name">{{ order.business_type }}</text>
|
||||
<text class="example-order-time">{{ order.paid_at || '待支付' }}</text>
|
||||
</view>
|
||||
<view class="example-order-right">
|
||||
<text class="example-order-amount">¥{{ order.total_amount }}</text>
|
||||
<text class="example-order-status" :class="`status-${order.status}`">
|
||||
{{ getStatusText(order.status) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付弹窗 -->
|
||||
<PaymentModal :visible="showPayment" :product-name="paymentInfo.productName"
|
||||
:product-desc="paymentInfo.productDesc" :product-icon="paymentInfo.productIcon" :amount="paymentInfo.amount"
|
||||
:business-type="paymentInfo.businessType" :business-id="paymentInfo.businessId" @close="showPayment = false"
|
||||
@success="handlePaymentSuccess" @fail="handlePaymentFail" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import PaymentModal from '../PaymentModal.vue';
|
||||
import type { QueryOrderResponse } from '@/api/types';
|
||||
|
||||
declare const uni: any;
|
||||
|
||||
const showPayment = ref(false);
|
||||
const orders = ref<QueryOrderResponse[]>([]);
|
||||
|
||||
const paymentInfo = reactive({
|
||||
productName: '',
|
||||
productDesc: '',
|
||||
productIcon: '📦',
|
||||
amount: 0,
|
||||
businessType: '',
|
||||
businessId: 0
|
||||
});
|
||||
|
||||
// 购买报告
|
||||
const buyReport = () => {
|
||||
paymentInfo.productName = '张三命名报告';
|
||||
paymentInfo.productDesc = '包含六维分析、周易卦象、开运建议等';
|
||||
paymentInfo.productIcon = '📊';
|
||||
paymentInfo.amount = 99;
|
||||
paymentInfo.businessType = 'naming_report';
|
||||
paymentInfo.businessId = 123;
|
||||
showPayment.value = true;
|
||||
};
|
||||
|
||||
// 购买推广合伙人
|
||||
const buyPartner = () => {
|
||||
paymentInfo.productName = '推广合伙人权益';
|
||||
paymentInfo.productDesc = '开启睡后收入之旅';
|
||||
paymentInfo.productIcon = '💼';
|
||||
paymentInfo.amount = 99;
|
||||
paymentInfo.businessType = 'partner_apply';
|
||||
paymentInfo.businessId = 456;
|
||||
showPayment.value = true;
|
||||
};
|
||||
|
||||
// 测试支付
|
||||
const testPay = () => {
|
||||
paymentInfo.productName = '测试商品';
|
||||
paymentInfo.productDesc = '用于测试支付流程';
|
||||
paymentInfo.productIcon = '🧪';
|
||||
paymentInfo.amount = 0.01;
|
||||
paymentInfo.businessType = 'test';
|
||||
paymentInfo.businessId = 999;
|
||||
showPayment.value = true;
|
||||
};
|
||||
|
||||
// 支付成功回调
|
||||
const handlePaymentSuccess = (outTradeNo: string) => {
|
||||
|
||||
// Web环境使用alert,uni-app环境使用showModal
|
||||
if (typeof uni?.showModal === 'function') {
|
||||
uni.showModal({
|
||||
title: '支付成功',
|
||||
content: `订单号:${outTradeNo}\n感谢您的购买!`,
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
// 刷新订单列表
|
||||
loadOrders();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Web环境使用原生alert
|
||||
alert(`支付成功\n\n订单号:${outTradeNo}\n感谢您的购买!`);
|
||||
loadOrders();
|
||||
}
|
||||
};
|
||||
|
||||
// 支付失败回调
|
||||
const handlePaymentFail = (message: string) => {
|
||||
console.log('支付失败:', message);
|
||||
|
||||
// Web环境使用alert,uni-app环境使用showModal
|
||||
if (typeof uni?.showModal === 'function') {
|
||||
uni.showModal({
|
||||
title: '支付失败',
|
||||
content: message || '支付过程中出现问题,请重试',
|
||||
showCancel: false
|
||||
});
|
||||
} else {
|
||||
// Web环境使用原生alert
|
||||
alert(`支付失败\n\n${message || '支付过程中出现问题,请重试'}`);
|
||||
}
|
||||
};
|
||||
|
||||
// 加载订单列表(示例数据)
|
||||
const loadOrders = () => {
|
||||
// 实际应该调用API获取订单列表
|
||||
orders.value = [
|
||||
{
|
||||
out_trade_no: 'ORDER_001',
|
||||
status: 'paid',
|
||||
total_amount: 99,
|
||||
paid_amount: 99,
|
||||
paid_at: '2026-01-15 10:30:00',
|
||||
business_type: 'naming_report',
|
||||
business_id: 123
|
||||
},
|
||||
{
|
||||
out_trade_no: 'ORDER_002',
|
||||
status: 'pending',
|
||||
total_amount: 99,
|
||||
business_type: 'partner_apply',
|
||||
business_id: 456
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
pending: '待支付',
|
||||
paid: '已支付',
|
||||
cancelled: '已取消',
|
||||
refunded: '已退款'
|
||||
};
|
||||
return statusMap[status] || status;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadOrders();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.payment-example {
|
||||
padding: 32rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.example-header {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.example-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.example-section {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.example-section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.example-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.example-card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.example-card-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.example-card-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.example-card-price {
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #8b2323;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.example-card-btn {
|
||||
width: 100%;
|
||||
padding: 20rpx 0;
|
||||
background-color: #8b2323;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.example-card-btn-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.example-empty {
|
||||
text-align: center;
|
||||
padding: 64rpx 0;
|
||||
}
|
||||
|
||||
.example-empty-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.example-orders {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.example-order {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.example-order-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.example-order-name {
|
||||
font-size: 28rpx;
|
||||
color: #2c2c2c;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.example-order-time {
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.example-order-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.example-order-amount {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.example-order-status {
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.status-paid {
|
||||
background-color: #e8f5e9;
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background-color: #fff3e0;
|
||||
color: #ff9800;
|
||||
}
|
||||
|
||||
.status-cancelled {
|
||||
background-color: #f5f5f5;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.status-refunded {
|
||||
background-color: #ffebee;
|
||||
color: #f44336;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user