feat: 增加支付宝在线支付、套餐订购弹窗、会员权益、支持模型展示等
This commit is contained in:
201
Yi.Ai.Vue3/src/pages/payResult/index.vue
Normal file
201
Yi.Ai.Vue3/src/pages/payResult/index.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<script setup lang="ts">
|
||||
import { ElButton, ElDivider } from 'element-plus';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { getUserInfo } from '@/api';
|
||||
import {
|
||||
SSO_CLIENT_LOGIN_AGAIN,
|
||||
SSO_SEVER_URL,
|
||||
} from '@/config/sso.ts';
|
||||
|
||||
import { useUserStore } from '@/stores';
|
||||
import { useSessionStore } from '@/stores/modules/session.ts';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
const sessionStore = useSessionStore();
|
||||
|
||||
interface PayResult {
|
||||
out_trade_no: string;
|
||||
trade_no: string;
|
||||
total_amount: string;
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
const payResult = ref<PayResult>({
|
||||
out_trade_no: '',
|
||||
trade_no: '',
|
||||
total_amount: '',
|
||||
});
|
||||
|
||||
function parseUrlParams() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const result: PayResult = {
|
||||
out_trade_no: params.get('out_trade_no') || '',
|
||||
trade_no: params.get('trade_no') || '',
|
||||
total_amount: params.get('total_amount') || '',
|
||||
};
|
||||
params.forEach((value, key) => {
|
||||
if (!(key in result))
|
||||
result[key] = value;
|
||||
});
|
||||
payResult.value = result;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
parseUrlParams();
|
||||
});
|
||||
function handleThirdPartyLogin(type: any) {
|
||||
const redirectUri = encodeURIComponent(`${window.location.origin}/chat`);
|
||||
console.log('cccc', type);
|
||||
const popup = window.open(
|
||||
`${SSO_SEVER_URL}/login?client_id=${type}&redirect_uri=${redirectUri}`,
|
||||
'SSOLogin',
|
||||
'width=1000,height=800',
|
||||
);
|
||||
|
||||
// 使用标志位防止重复执行
|
||||
let isHandled = false;
|
||||
|
||||
const messageHandler = async (event: any) => {
|
||||
if (event.origin === new URL(SSO_SEVER_URL).origin
|
||||
&& event.data.type === 'SSO_LOGIN_SUCCESS'
|
||||
&& !isHandled) {
|
||||
isHandled = true;
|
||||
try {
|
||||
// 清理监听
|
||||
window.removeEventListener('message', messageHandler);
|
||||
const { token, refreshToken } = event.data;
|
||||
userStore.setToken(token, refreshToken);
|
||||
const resUserInfo = await getUserInfo();
|
||||
userStore.setUserInfo(resUserInfo.data);
|
||||
// 关闭弹窗
|
||||
if (popup && !popup.closed) {
|
||||
popup.close();
|
||||
}
|
||||
|
||||
// 后续逻辑
|
||||
ElMessage.success('登录成功');
|
||||
userStore.closeLoginDialog();
|
||||
await sessionStore.requestSessionList(1, true);
|
||||
await router.replace('/');
|
||||
}
|
||||
catch (error) {
|
||||
console.error('登录处理失败:', error);
|
||||
ElMessage.error('登录失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 先移除旧监听,再添加新监听
|
||||
window.removeEventListener('message', messageHandler);
|
||||
window.addEventListener('message', messageHandler);
|
||||
|
||||
// 超时自动清理
|
||||
// setTimeout(() => {
|
||||
// if (!isHandled) {
|
||||
// window.removeEventListener('message', messageHandler);
|
||||
// if (popup && !popup.closed)
|
||||
// popup.close();
|
||||
// ElMessage.warning('登录超时');
|
||||
// }
|
||||
// }, 60 * 1000); // 60分钟超时关闭
|
||||
}
|
||||
|
||||
function toHome() {
|
||||
router.replace('/');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pay-result-container flex flex-col items-center justify-center p-6 min-h-screen bg-gray-50">
|
||||
<div class="card bg-white rounded-xl shadow-lg p-8 max-w-md w-full text-center">
|
||||
<!-- 成功提示 -->
|
||||
<h1 class="text-4xl font-extrabold mb-4 text-orange-500">
|
||||
🎉 恭喜!
|
||||
</h1>
|
||||
<p class="text-xl font-semibold mb-6">
|
||||
您已成为尊贵的 <span class="text-orange-500">YixinAI VIP</span>
|
||||
</p>
|
||||
|
||||
<!-- 订单信息卡片 -->
|
||||
<div class="order-info bg-gray-100 p-4 rounded-lg mb-4 text-left">
|
||||
<p class="mb-2">
|
||||
<strong>商户订单号:</strong>{{ payResult.out_trade_no }}
|
||||
</p>
|
||||
<p class="mb-2">
|
||||
<strong>支付交易号:</strong>{{ payResult.trade_no }}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<strong>支付金额:</strong><span class="text-red-500 font-bold">¥{{ payResult.total_amount }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 更多信息提示 -->
|
||||
<div class="mb-6 text-gray-600 text-sm">
|
||||
更多订单信息和会员详情<br>请前往 <strong>用户中心 → 充值记录</strong> 查看。<br>
|
||||
用户中心在首页右上角个人头像点击下拉菜单。
|
||||
</div>
|
||||
|
||||
<!-- 重新登录提示 -->
|
||||
<div class="mb-4 text-gray-600">
|
||||
开通 VIP 后,需要重新登录意社区生效
|
||||
</div>
|
||||
|
||||
<ElDivider content-position="center">
|
||||
<span class="text-gray-400 text-sm">操作</span>
|
||||
</ElDivider>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="flex flex-col gap-3 mt-4">
|
||||
<ElButton
|
||||
class="w-full py-3 text-lg font-medium"
|
||||
type="primary"
|
||||
size="large"
|
||||
@click="handleThirdPartyLogin(SSO_CLIENT_LOGIN_AGAIN)"
|
||||
>
|
||||
意社区重新登录
|
||||
</ElButton>
|
||||
|
||||
<ElButton
|
||||
class="w-full py-3 text-lg font-medium"
|
||||
type="default"
|
||||
size="large"
|
||||
@click="toHome()"
|
||||
>
|
||||
返回首页
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pay-result-container {
|
||||
.card {
|
||||
transition: transform 0.2s;
|
||||
&:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
.order-info p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.el-button {
|
||||
border-radius: 8px;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.card {
|
||||
padding: 6vw;
|
||||
}
|
||||
.order-info p {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.el-button {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts" setup>
|
||||
import { CircleCheck } from '@element-plus/icons-vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import SupportModelProducts from '@/components/SupportModelProducts/indexl.vue';
|
||||
|
||||
@@ -193,46 +192,124 @@ function openContact() {
|
||||
</p>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-6 flex justify-center">
|
||||
<el-card
|
||||
style="width: 400px;"
|
||||
v-for="(plan, index) in pricing"
|
||||
:key="index"
|
||||
class="rounded-2xl shadow hover:shadow-lg transition-all" :class="[plan.isPopular ? 'border-2 border-blue-500' : '']"
|
||||
>
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<h2 class="text-2xl font-semibold mb-2">
|
||||
{{ plan.name }}
|
||||
</h2>
|
||||
<p class="text-3xl font-bold text-blue-600 mb-2" style="color: #E8CB96">
|
||||
<span>优惠后:</span>¥{{ plan.newPrice }} <del style="color: #889F9F;font-size: 16px">¥{{ plan.price }}</del>
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 mb-4">
|
||||
{{ plan.period }}
|
||||
</p>
|
||||
<el-divider />
|
||||
<ul class="text-left space-y-2 w-full min-h-200px">
|
||||
<li v-for="(feature, i) in plan.features" :key="i" class="flex items-start gap-2">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
<span>{{ feature }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<el-button
|
||||
class="mt-6 w-full"
|
||||
type="primary"
|
||||
size="large"
|
||||
style="background: #D7BD8D;color: white;border: #191919"
|
||||
@click="openContact"
|
||||
<div class="text-center relative">
|
||||
<h3 class="text-lg font-bold mb-3">
|
||||
请扫码加入微信交流群<br>
|
||||
获取专属客服支持
|
||||
</h3>
|
||||
<div class="mb-4 flex items-center justify-center space-x-2">
|
||||
<!-- <span class="font-semibold">站长微信账号:</span> -->
|
||||
<!-- <span id="wechat-id" class="text-blue-600 font-mono select-text">chengzilaoge520</span> -->
|
||||
<span
|
||||
v-if="false"
|
||||
class="cursor-pointer" onclick="navigator.clipboard.writeText('chengzilaoge520').then(() => { window.parent.ElMessage({
|
||||
message: '微信号已复制到剪贴板',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
});})"
|
||||
title="点击复制"
|
||||
>
|
||||
立即订阅
|
||||
</el-button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 opacity-70 hover:opacity-100" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v16h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 18H8V7h11v16z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-divider class="my-16">
|
||||
<div class="flex justify-center mb-4">
|
||||
<div v-if="false">
|
||||
<h4>
|
||||
站长微信
|
||||
</h4>
|
||||
<img
|
||||
:src="wxSrc"
|
||||
class="w-50 h-70 border border-gray-200 rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-transform hover:scale-105"
|
||||
onclick="document.getElementById('wechat-qrcode-fullscreen').style.display = 'flex'"
|
||||
alt="微信二维码"
|
||||
>
|
||||
</div><div>
|
||||
<h4>
|
||||
微信交流群
|
||||
</h4>
|
||||
<img
|
||||
:src="wxGroupQD"
|
||||
|
||||
class="w-50 h-70 border border-gray-200 rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-transform hover:scale-105"
|
||||
onclick="document.getElementById('wx-group-qrcode-fullscreen').style.display = 'flex'"
|
||||
alt="微信二维码"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="false" class="text-sm text-gray-600">
|
||||
<p class="mb-1">
|
||||
请备注 <span class="inline-block bg-yellow-100 text-yellow-800 px-2 py-0.5 rounded text-xs">ai</span> 快速通过验证
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 全屏放大二维码 -->
|
||||
<div
|
||||
id="wechat-qrcode-fullscreen"
|
||||
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.8); z-index:9999; justify-content:center; align-items:center;"
|
||||
onclick="this.style.display='none'"
|
||||
>
|
||||
<img
|
||||
:src="wxSrc"
|
||||
style="max-width:90%; max-height:90%; border:8px solid white; border-radius:16px; box-shadow:0 0 40px rgba(255,255,255,0.2);"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
id="wx-group-qrcode-fullscreen"
|
||||
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.8); z-index:9999; justify-content:center; align-items:center;"
|
||||
onclick="this.style.display='none'"
|
||||
>
|
||||
<img
|
||||
:src="wxGroupQD"
|
||||
|
||||
style="max-width:90%; max-height:90%; border:8px solid white; border-radius:16px; box-shadow:0 0 40px rgba(255,255,255,0.2);"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <el-card -->
|
||||
<!-- style="width: 400px;" -->
|
||||
<!-- v-for="(plan, index) in pricing" -->
|
||||
<!-- :key="index" -->
|
||||
<!-- class="rounded-2xl shadow hover:shadow-lg transition-all" :class="[plan.isPopular ? 'border-2 border-blue-500' : '']" -->
|
||||
<!-- > -->
|
||||
<!-- <div class="flex flex-col items-center text-center"> -->
|
||||
<!-- <h2 class="text-2xl font-semibold mb-2"> -->
|
||||
<!-- {{ plan.name }} -->
|
||||
<!-- </h2> -->
|
||||
<!-- <p class="text-3xl font-bold text-blue-600 mb-2" style="color: #E8CB96"> -->
|
||||
<!-- <span>优惠后:</span>¥{{ plan.newPrice }} <del style="color: #889F9F;font-size: 16px">¥{{ plan.price }}</del> -->
|
||||
<!-- </p> -->
|
||||
<!-- <p class="text-sm text-gray-500 mb-4"> -->
|
||||
<!-- {{ plan.period }} -->
|
||||
<!-- </p> -->
|
||||
<!-- <el-divider /> -->
|
||||
<!-- <ul class="text-left space-y-2 w-full min-h-200px"> -->
|
||||
<!-- <li v-for="(feature, i) in plan.features" :key="i" class="flex items-start gap-2"> -->
|
||||
<!-- <el-icon><CircleCheck /></el-icon> -->
|
||||
<!-- <span>{{ feature }}</span> -->
|
||||
<!-- </li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- <el-button -->
|
||||
<!-- class="mt-6 w-full" -->
|
||||
<!-- type="primary" -->
|
||||
<!-- size="large" -->
|
||||
<!-- style="background: #D7BD8D;color: white;border: #191919" -->
|
||||
<!-- @click="openContact" -->
|
||||
<!-- > -->
|
||||
<!-- 立即订阅 -->
|
||||
<!-- </el-button> -->
|
||||
<!-- </div> -->
|
||||
<!-- </el-card> -->
|
||||
</div>
|
||||
<!-- <SupportModelList /> -->
|
||||
<el-divider v-if="false" class="my-16">
|
||||
充值流程说明
|
||||
</el-divider>
|
||||
<el-card class="max-w-2xl mx-auto shadow-md rounded-2xl">
|
||||
<el-card v-if="false" class="max-w-2xl mx-auto shadow-md rounded-2xl">
|
||||
<h3 class="text-xl font-semibold mb-4">
|
||||
如何充值 VIP
|
||||
</h3>
|
||||
@@ -270,7 +347,7 @@ function openContact() {
|
||||
<el-divider class="my-16">
|
||||
加入群聊
|
||||
</el-divider>
|
||||
<el-collapse class="max-w-3xl mx-auto flex justify-center" accordion >
|
||||
<el-collapse class="max-w-3xl mx-auto flex justify-center" accordion>
|
||||
<el-image
|
||||
style="width: 500px; height: auto;"
|
||||
:src="wxGroupQD"
|
||||
|
||||
Reference in New Issue
Block a user