1770 lines
54 KiB
Vue
1770 lines
54 KiB
Vue
<script setup lang="ts">
|
||
import type { GoodsItem } from '@/api/pay';
|
||
import { CircleCheck, Loading } from '@element-plus/icons-vue';
|
||
import { ElMessage } from 'element-plus';
|
||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
import { createOrder, getOrderStatus } from '@/api';
|
||
import { getGoodsList, GoodsCategoryType } from '@/api/pay';
|
||
import SupportModelList from '@/components/userPersonalCenter/components/SupportModelList.vue';
|
||
import ProductPage from '@/pages/products/index.vue';
|
||
import { useUserStore } from '@/stores';
|
||
|
||
const emit = defineEmits(['close']);
|
||
|
||
// 商品数据类型定义
|
||
interface PackageItem {
|
||
id: number;
|
||
name: string;
|
||
desc: string;
|
||
price: number; // 用户实际支付价格(最终专属价)
|
||
originalPrice?: number; // 原价(官方价格)
|
||
perMonth?: number; // 会员:月均价;Token:模型官方价格
|
||
tag: string;
|
||
discount: string; // 累计优惠描述,如"根据累加充值已优惠 ¥47.00"
|
||
goodsName: string; // 用于创建订单
|
||
discountAmount?: number; // 优惠金额(从discount字段解析)
|
||
goodsType?: any; // 商品枚举
|
||
}
|
||
|
||
// 商品数据(从接口获取)
|
||
const packagesData = ref<{
|
||
member: PackageItem[];
|
||
token: PackageItem[];
|
||
}>({
|
||
member: [],
|
||
token: [],
|
||
});
|
||
|
||
const userStore = useUserStore();
|
||
|
||
const visible = ref(true);
|
||
const activeTab = ref('member');
|
||
const selectedId = ref<number | null>(null);
|
||
const selectedPrice = ref(0);
|
||
const selectPackageObject = ref<PackageItem | null>(null);
|
||
const showDetails = ref(false);
|
||
const isMobile = ref(false);
|
||
const isLoading = ref(false);
|
||
const isLoadingGoods = ref(false); // 商品加载状态
|
||
const paymentWindow = ref<Window | null>(null);
|
||
const pollInterval = ref<NodeJS.Timeout | null>(null);
|
||
|
||
function checkMobile() {
|
||
isMobile.value = window.innerWidth < 768;
|
||
}
|
||
|
||
// 获取商品列表(逻辑不变,仅保留字段映射正确性)
|
||
async function fetchGoodsList() {
|
||
isLoadingGoods.value = true;
|
||
try {
|
||
const [vipRes, tokenRes] = await Promise.all([
|
||
getGoodsList(GoodsCategoryType.Vip),
|
||
getGoodsList(GoodsCategoryType.PremiumPackage),
|
||
]);
|
||
|
||
// 转换VIP商品数据
|
||
packagesData.value.member = (vipRes.data || []).map((item: GoodsItem, index: number) => ({
|
||
id: index + 1,
|
||
name: item.goodsName,
|
||
desc: '',
|
||
price: item.goodsPrice,
|
||
originalPrice: item.originalPrice !== item.goodsPrice ? item.originalPrice : undefined,
|
||
perMonth: item.referencePrice,
|
||
tag: item.remark || '',
|
||
discount: item.discountDescription || '',
|
||
goodsName: item.goodsName,
|
||
goodsType: item.goodsType,
|
||
}));
|
||
|
||
// 转换Token商品数据(字段含义保持原定义)
|
||
packagesData.value.token = (tokenRes.data || []).map((item: GoodsItem, index: number) => {
|
||
let discountAmount = 0;
|
||
if (item.discountDescription) {
|
||
const match = item.discountDescription.match(/¥([\d.]+)/);
|
||
if (match) {
|
||
discountAmount = Number.parseFloat(match[1]);
|
||
}
|
||
}
|
||
|
||
return {
|
||
id: index + 100, // 避免ID冲突
|
||
name: item.goodsName,
|
||
desc: '',
|
||
price: item.goodsPrice, // 用户专属价格(最终支付价格)
|
||
originalPrice: item.originalPrice, // 意心平台优惠价(主价格)
|
||
perMonth: item.referencePrice, // 模型官方价格
|
||
tag: item.remark || '',
|
||
discount: item.discountDescription || '',
|
||
goodsName: item.goodsName,
|
||
goodsType: item.goodsType,
|
||
discountAmount,
|
||
};
|
||
});
|
||
|
||
// 设置默认选中第一个会员套餐
|
||
if (packagesData.value.member.length > 0) {
|
||
const defaultPackage = packagesData.value.member[0];
|
||
selectedId.value = defaultPackage.id;
|
||
selectedPrice.value = defaultPackage.price;
|
||
selectPackageObject.value = defaultPackage;
|
||
}
|
||
}
|
||
catch (error) {
|
||
console.error('获取商品列表失败:', error);
|
||
ElMessage.error('获取商品列表失败,请刷新重试');
|
||
}
|
||
finally {
|
||
isLoadingGoods.value = false;
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
checkMobile();
|
||
window.addEventListener('resize', checkMobile);
|
||
fetchGoodsList();
|
||
});
|
||
|
||
onBeforeUnmount(() => {
|
||
window.removeEventListener('resize', checkMobile);
|
||
cleanupPayment();
|
||
});
|
||
|
||
// 支付相关逻辑(无修改)
|
||
function cleanupPayment() {
|
||
if (pollInterval.value) {
|
||
clearInterval(pollInterval.value);
|
||
pollInterval.value = null;
|
||
}
|
||
retryCount = 0;
|
||
}
|
||
|
||
const tabs = [
|
||
{ key: 'member', label: '会员套餐' },
|
||
{ key: 'token', label: '尊享Token包' },
|
||
{ key: 'activation', label: '激活码' },
|
||
];
|
||
|
||
const benefitsData = {
|
||
member: [
|
||
{ name: '站点全模型解锁使用', value: '' },
|
||
{ name: '全站所有Ai日常“无限制”使用,(除尊享外)', value: '' },
|
||
{ name: 'Ai专线超级加速', value: '' },
|
||
{ name: '专属Api接口提供', value: '' },
|
||
{ name: '支持文件/图片/知识库功能', value: '' },
|
||
{ name: '支持各类第三方工具集成(IDE/翻译/Utools等)', value: '' },
|
||
{ name: '支持Mcp/FunctionCall开发', value: '' },
|
||
{ name: '支持安卓/ios/web/客户端使用', value: '' },
|
||
{ name: '支持售后群服务,一起畅玩前沿Ai', value: '' },
|
||
{ name: '如果需大量使用Agent,请选择尊享Token包', value: '' },
|
||
],
|
||
token: [
|
||
{ name: '超值优惠', value: '相比官方价格,我们的价格更实惠' },
|
||
{ name: '灵活计费', value: '按调用量扣费,用多少付多少' },
|
||
{ name: '支持多模型', value: '适配多种主流AI模型' },
|
||
{ name: 'Token用途', value: '用于调用API或模型生成内容' },
|
||
{ name: '永久有效', value: 'Token永不过期,随时使用' },
|
||
],
|
||
};
|
||
const benefitsData2 = {
|
||
qy: [
|
||
{ name: '需先成为意心会员后方可购买使用', value: '' },
|
||
{ name: '意心会员过期后,尊享Token包会临时冻结', value: '' },
|
||
{ name: '可重复购买,将自动累积Token,在个人中心查看', value: '' },
|
||
{ name: 'Token长期有效,无限流限制', value: '' },
|
||
{ name: '几乎是全网最低价,让人人用的起Agent', value: '' },
|
||
{ name: '附带claude code独家教程,手把手对接', value: '' },
|
||
{ name: '一手直连!非跑路!非套壳!非黑产!(行业普遍现象)', value: '' },
|
||
{ name: '橙子老哥担保,拒绝套路、拒绝跑路,可进售后群', value: '' },
|
||
],
|
||
yt: [
|
||
{ name: '可全站解锁claude4.5地表编程最强模型', value: '' },
|
||
{ name: '可直接接入claude code地表编程最强模Agent工具', value: '' },
|
||
{ name: '可暴力使用claude4.5,无黑名单限流机制', value: '' },
|
||
{ name: '可使用claude接口/openai接口格式,接入claude4.5', value: '' },
|
||
],
|
||
};
|
||
|
||
const fullBenefitsData = {
|
||
member: [
|
||
{ category: 'YiXinAI AI Pro', free: '1项', vip: '5项', value: '价值68/月' },
|
||
{ category: '基础对话', free: '3条/天', vip: '不限条款', value: 'DeepSeek-R1 32b蒸馏版、AI-4o mini' },
|
||
{ category: '高级对话', free: '-', vip: '400条/月', value: 'DeepSeek-R1 671b满血版、4o、Cd3.5s、Code、文档对话' },
|
||
{ category: 'AI基础绘画', free: '-', vip: '500条/月', value: '' },
|
||
{ category: 'AI高级绘画', free: '-', vip: '50条/月', value: '' },
|
||
{ category: 'AI-4.0联网搜索', free: '-', vip: '支持', value: '' },
|
||
{ category: 'AI PPT', free: '1项', vip: '12项', value: '价值99/月' },
|
||
{ category: 'AI 思维导图', free: '1项', vip: '8项', value: '价值99/月' },
|
||
{ category: '文档对话', free: '0项', vip: '6项', value: '价值99/月' },
|
||
{ category: 'AI 绘图', free: '0项', vip: '5项', value: '价值99/月' },
|
||
{ category: 'AI 写作', free: '1项', vip: '6项', value: '价值99/月' },
|
||
],
|
||
};
|
||
|
||
const currentPackages = computed(() => packagesData.value[activeTab.value as 'member' | 'token']);
|
||
const currentBenefits = computed(() => benefitsData[activeTab.value]);
|
||
|
||
function selectPackage(pkg: any) {
|
||
selectedId.value = pkg.id;
|
||
selectedPrice.value = pkg.price;
|
||
selectPackageObject.value = pkg;
|
||
}
|
||
|
||
watch(activeTab, () => {
|
||
if (activeTab.value === 'activation') {
|
||
return;
|
||
}
|
||
const packages = packagesData.value[activeTab.value as 'member' | 'token'];
|
||
if (packages && packages.length > 0) {
|
||
const firstPackage = packages[0];
|
||
selectedId.value = firstPackage.id;
|
||
selectedPrice.value = firstPackage.price;
|
||
selectPackageObject.value = firstPackage;
|
||
}
|
||
});
|
||
|
||
function handleClickLogin() {
|
||
userStore.openLoginDialog();
|
||
}
|
||
|
||
async function pay() {
|
||
if (!selectedId.value || !selectPackageObject.value) {
|
||
ElMessage.warning('请选择一个套餐');
|
||
return;
|
||
}
|
||
|
||
isLoading.value = true;
|
||
try {
|
||
const returnUrl = `${window.location.origin}/pay-result`;
|
||
const params = {
|
||
GoodsType: selectPackageObject.value.goodsType,
|
||
ReturnUrl: returnUrl,
|
||
};
|
||
|
||
const response = await createOrder(params);
|
||
if (response.data.paymentPageHtml) {
|
||
handlePaymentPage(response.data.paymentPageHtml, response.data.orderId, response.data.outTradeNo);
|
||
}
|
||
else {
|
||
throw new Error('未获取到支付页面');
|
||
}
|
||
}
|
||
catch (error: any) {
|
||
console.error('支付失败:', error);
|
||
ElMessage.error(`支付失败: ${error.message || '未知错误'}`);
|
||
}
|
||
finally {
|
||
isLoading.value = false;
|
||
}
|
||
}
|
||
|
||
function handlePaymentPage(html: string, orderId: string, outTradeNo: string) {
|
||
close();
|
||
paymentWindow.value = window.open('', '_blank');
|
||
if (!paymentWindow.value) {
|
||
ElMessage.error('无法打开支付窗口,请检查浏览器弹窗设置或允许弹窗');
|
||
return;
|
||
}
|
||
|
||
paymentWindow.value.document.open();
|
||
paymentWindow.value.document.write(html);
|
||
setTimeout(() => {
|
||
startPolling(outTradeNo);
|
||
}, 3000);
|
||
}
|
||
|
||
function startPolling(outTradeNo: string) {
|
||
cleanupPayment();
|
||
checkPaymentStatus(outTradeNo);
|
||
pollInterval.value = setInterval(() => {
|
||
checkPaymentStatus(outTradeNo);
|
||
}, 3000);
|
||
}
|
||
|
||
let retryCount = 0;
|
||
async function checkPaymentStatus(outTradeNo: string) {
|
||
try {
|
||
const result = await getOrderStatus(outTradeNo);
|
||
if (result.data.tradeStatus === 'TRADE_SUCCESS') {
|
||
cleanupPayment();
|
||
ElMessage.success('支付成功!');
|
||
close();
|
||
}
|
||
else if (result.data.tradeStatus === 'TRADE_CLOSED' || result.data.tradeStatus === 'TRADE_FAILED') {
|
||
cleanupPayment();
|
||
ElMessage.warning(`支付失败: ${result.data.tradeStatusDesc || '未知原因'}`);
|
||
}
|
||
}
|
||
catch (error) {
|
||
console.error('检查订单状态失败:', error);
|
||
if (retryCount > 3) {
|
||
cleanupPayment();
|
||
ElMessage.error('检查支付状态失败,请手动刷新页面确认');
|
||
}
|
||
retryCount++;
|
||
}
|
||
}
|
||
|
||
const router = useRouter();
|
||
|
||
function toggleDetails() {
|
||
showDetails.value = !showDetails.value;
|
||
}
|
||
|
||
function close() {
|
||
visible.value = false;
|
||
emit('close');
|
||
}
|
||
|
||
function onClose() {
|
||
emit('close');
|
||
}
|
||
|
||
function goToActivation() {
|
||
close();
|
||
userStore.openUserCenter('activationCode');
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<el-dialog
|
||
v-model="visible" :width="isMobile ? '90%' : '1000px'" :fullscreen="isMobile && showDetails"
|
||
:show-close="false" destroy-on-close class="product-package-dialog" @close="onClose"
|
||
>
|
||
<!-- 详情页(无修改) -->
|
||
<div v-if="showDetails" class="details-view">
|
||
<div class="flex items-center mb-6 sticky top-0 bg-white z-10 pt-2 pb-4">
|
||
<el-button text circle size="small" class="mr-2" @click="toggleDetails">
|
||
←
|
||
</el-button>
|
||
<div class="text-xl font-bold">
|
||
YiXinAI会员详细权益
|
||
</div>
|
||
</div>
|
||
<ProductPage />
|
||
<div v-if="false" class="benefits-table">
|
||
<div class="table-header">
|
||
<div class="table-cell">
|
||
服务项
|
||
</div>
|
||
<div class="table-cell">
|
||
免费用户
|
||
</div>
|
||
<div class="table-cell">
|
||
AI大会员
|
||
</div>
|
||
</div>
|
||
<div v-for="(item, index) in fullBenefitsData.member" :key="index" class="table-row">
|
||
<div class="table-cell font-medium">
|
||
{{ item.category }}
|
||
</div>
|
||
<div class="table-cell">
|
||
{{ item.free }}
|
||
</div>
|
||
<div class="table-cell">
|
||
<div>{{ item.vip }}</div>
|
||
<div v-if="item.value" class="text-gray-500 text-xs">
|
||
{{ item.value }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主页面 -->
|
||
<div v-else>
|
||
<!-- 顶部标题和关闭按钮(无修改) -->
|
||
<div class="flex justify-between items-center mb-4">
|
||
<div class="text-xl font-bold">
|
||
购买套餐
|
||
</div>
|
||
<el-button circle size="small" @click="close">
|
||
✕
|
||
</el-button>
|
||
</div>
|
||
|
||
<!-- Tab 切换(无修改) -->
|
||
<div class="flex border-b mb-6 overflow-x-auto">
|
||
<div
|
||
v-for="tab in tabs" :key="tab.key"
|
||
class="cursor-pointer px-5 py-2 -mb-px border-b-2 transition whitespace-nowrap"
|
||
:class="activeTab === tab.key ? 'border-orange-500 text-orange-500 font-semibold' : 'border-transparent text-gray-500 hover:text-orange-500'"
|
||
@click="activeTab = tab.key"
|
||
>
|
||
{{ tab.label }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 激活码引导页 -->
|
||
<div v-if="activeTab === 'activation'" class="activation-guide-container">
|
||
<div class="activation-content">
|
||
<div class="guide-icon">
|
||
🎁
|
||
</div>
|
||
<h3 class="guide-title">
|
||
激活码兑换
|
||
</h3>
|
||
<p class="guide-desc">
|
||
如果您持有意心AI的会员激活码或Token兑换码,<br>请点击下方按钮前往控制台进行兑换。
|
||
</p>
|
||
<el-button
|
||
type="primary"
|
||
size="large"
|
||
class="redeem-jump-btn"
|
||
round
|
||
@click="goToActivation"
|
||
>
|
||
前往兑换中心
|
||
</el-button>
|
||
|
||
<div class="guide-tips">
|
||
<p>💡 兑换成功后权益将立即生效</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 移动端布局 -->
|
||
<div v-else-if="isMobile" class="mobile-layout">
|
||
<!-- 商品加载状态(无修改) -->
|
||
<div v-if="isLoadingGoods" class="loading-container">
|
||
<el-icon class="is-loading" :size="40">
|
||
<Loading />
|
||
</el-icon>
|
||
<p>加载商品中...</p>
|
||
</div>
|
||
|
||
<!-- 套餐卡片列表(核心修改:Token套餐价格展示) -->
|
||
<div v-else-if="currentPackages.length > 0" class="package-list">
|
||
<div
|
||
v-for="pkg in currentPackages" :key="pkg.id" class="package-card"
|
||
:class="{ selected: pkg.id === selectedId }" @click="selectPackage(pkg)"
|
||
>
|
||
<!-- 标签(无修改) -->
|
||
<div v-if="pkg.discount" class="discount-tag">
|
||
{{ pkg.discount }}
|
||
</div>
|
||
<div v-if="pkg.tag" class="tag">
|
||
{{ pkg.tag }}
|
||
</div>
|
||
|
||
<!-- 套餐信息(无修改) -->
|
||
<div class="package-info">
|
||
<div class="package-name">
|
||
{{ pkg.name }}
|
||
</div>
|
||
<div class="package-desc">
|
||
{{ pkg.desc }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 价格区域(核心调整:Token套餐突出平台优惠价) -->
|
||
<div class="package-price">
|
||
<!-- Token套餐:尊享包价格展示优化 -->
|
||
<template v-if="activeTab === 'token'">
|
||
<!-- 1. 官方参考价(弱化展示) -->
|
||
<div v-if="pkg.perMonth && pkg.perMonth > (pkg.originalPrice || pkg.price)" class="official-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text">❌ 官方参考价</span>
|
||
</div>
|
||
<div class="official-price">
|
||
¥{{ pkg.perMonth.toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2. 平台优惠价(主价格:放大字号+加重颜色) -->
|
||
<div v-if="pkg.originalPrice" class="platform-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text main-label">⭐ 意心平台优惠价</span>
|
||
</div>
|
||
<div class="platform-price main-price">
|
||
¥{{ pkg.originalPrice.toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 3. 个人优惠券(辅助信息) -->
|
||
<div v-if="pkg.discountAmount && pkg.discountAmount > 0" class="coupon-card">
|
||
<div class="coupon-header">
|
||
<span class="coupon-icon">🎁</span>
|
||
<span class="coupon-title">您的个人尊享优惠券</span>
|
||
</div>
|
||
<div class="coupon-amount">
|
||
-¥{{ pkg.discountAmount.toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4. 最终专属价格(弱化:缩小字号+浅色调,非核心视觉) -->
|
||
<div v-if="false" class="final-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text light-label">👑 您的最终专属价(支付价)</span>
|
||
</div>
|
||
<div class="final-price-value light-price">
|
||
<span class="price-symbol">¥</span>
|
||
<span class="price-number">{{ pkg.price.toFixed(2) }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 5. 总优惠提示(无修改) -->
|
||
<div v-if="pkg.perMonth && pkg.perMonth > pkg.price" class="total-discount-bar">
|
||
<span class="bar-icon">🎉</span>
|
||
<span class="bar-text">相比官方价已为您节省 ¥{{ (pkg.perMonth - pkg.price).toFixed(2) }}</span>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 会员套餐:保持原有逻辑(无修改) -->
|
||
<template v-else>
|
||
<div class="current-price-section">
|
||
<span class="price-label">会员价</span>
|
||
<div class="price-row">
|
||
<span class="price">¥{{ pkg.price }}</span>
|
||
<span v-if="pkg.perMonth" class="per-month">仅¥{{ pkg.perMonth }}/月</span>
|
||
</div>
|
||
</div>
|
||
<div v-if="pkg.discount" class="discount-info">
|
||
<el-icon class="discount-icon">
|
||
<CircleCheck />
|
||
</el-icon>
|
||
<span class="discount-text">{{ pkg.discount }}</span>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 其他辅助信息(无修改) -->
|
||
<div v-if="activeTab === 'token'" class="recharge-tip-card">
|
||
<div class="tip-icon">
|
||
💝
|
||
</div>
|
||
<div class="tip-content">
|
||
<div class="tip-title">
|
||
累计充值优惠
|
||
</div>
|
||
<div class="tip-desc">
|
||
充值越多,优惠越多,长期使用更划算
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: flex;justify-content: space-between;margin-top: 15px;">
|
||
<div>
|
||
<p style="color: #f97316;font-weight: 800">
|
||
全站任意充值,每累计充值10元永久优惠尊享包10元,最高可优惠50元
|
||
</p>
|
||
<p style="margin-top: 10px;">
|
||
充值后,加客服微信回复账号名,可专享vip售后服务
|
||
</p>
|
||
<p style="margin-top: 10px;">
|
||
客服微信号:chengzilaoge520 或扫描右侧二维码
|
||
</p>
|
||
</div>
|
||
<div><img style="height: 80px;width: 80px;" src="/src/assets/images/wx.png" alt=""></div>
|
||
</div>
|
||
|
||
<!-- 权益预览(无修改) -->
|
||
<div class="benefits-preview max-h-200px overflow-y-auto">
|
||
<div class="section-title">
|
||
专属权益
|
||
</div>
|
||
<ul class="benefits-list">
|
||
<li v-for="(b, index) in currentBenefits" :key="index" class="benefit-item">
|
||
<span class="dot"><el-icon><CircleCheck /></el-icon></span>
|
||
<span>
|
||
<span class="benefit-name">{{ b.name }}</span>
|
||
<span v-if="b.value">:{{ b.value }}</span>
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
<SupportModelList />
|
||
</div>
|
||
|
||
<!-- 支付区域(无修改) -->
|
||
<div class="payment-area">
|
||
<div v-if="false" class="agreement-text">
|
||
登录和注册都代表同意YiXinAI的会员协议
|
||
</div>
|
||
<div class="payment-info">
|
||
<div class="actual-payment">
|
||
<span>实际支付:</span>
|
||
<span class="price">¥{{ selectedPrice || 0 }}</span>
|
||
</div>
|
||
<el-button text type="primary" class="view-details-btn" @click="toggleDetails">
|
||
了解更多
|
||
</el-button>
|
||
<el-button
|
||
v-if="userStore.userInfo"
|
||
type="primary" :disabled="!selectedId || isLoading" :loading="isLoading" class="pay-button"
|
||
@click="pay"
|
||
>
|
||
立即支付
|
||
</el-button>
|
||
<el-button
|
||
v-else
|
||
type="primary" class="pay-button"
|
||
@click="handleClickLogin"
|
||
>
|
||
立即登录/注册
|
||
</el-button>
|
||
</div>
|
||
<div class="note-text">
|
||
可叠加购买次数,过期时间以最后订单为准。<br>
|
||
最终解释权归YiXinAI所有。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 桌面端布局(与移动端逻辑一致,仅适配样式) -->
|
||
<div v-else class="flex gap-6 desktop-layout">
|
||
<!-- 商品加载状态(无修改) -->
|
||
<div v-if="isLoadingGoods" class="loading-container-desktop">
|
||
<el-icon class="is-loading" :size="50">
|
||
<Loading />
|
||
</el-icon>
|
||
<p>加载商品中...</p>
|
||
</div>
|
||
|
||
<!-- 左栏 套餐卡片 + 支付(核心修改:Token套餐价格展示) -->
|
||
<div v-else class="w-[60%] flex flex-col justify-between">
|
||
<div class="flex flex-wrap gap-4">
|
||
<div
|
||
v-for="pkg in currentPackages" :key="pkg.id" class="package-card"
|
||
:class="{ selected: pkg.id === selectedId }" @click="selectPackage(pkg)"
|
||
>
|
||
<!-- 标签(无修改) -->
|
||
<div v-if="pkg.tag" class="tag">
|
||
{{ pkg.tag }}
|
||
</div>
|
||
|
||
<!-- 套餐信息(无修改) -->
|
||
<div class="package-info">
|
||
<div class="package-name">
|
||
{{ pkg.name }}
|
||
</div>
|
||
<div class="package-desc">
|
||
{{ pkg.desc }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 价格区域(桌面端同移动端逻辑:突出平台优惠价) -->
|
||
<div class="package-price">
|
||
<template v-if="activeTab === 'token'">
|
||
<!-- 1. 官方参考价(弱化) -->
|
||
<div v-if="pkg.perMonth && pkg.perMonth > (pkg.originalPrice || pkg.price)" class="official-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text">❌ 官方参考价:</span>
|
||
<span class="label-text-number">¥{{ pkg.perMonth.toFixed(2) }} </span>
|
||
</div>
|
||
<!-- <div class="official-price"> -->
|
||
<!-- ¥{{ pkg.perMonth.toFixed(2) }} -->
|
||
<!-- </div> -->
|
||
</div>
|
||
|
||
<!-- 2. 平台优惠价(主价格:放大+加重) -->
|
||
<div v-if="pkg.originalPrice" class="platform-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text main-label">⭐ 意心平台优惠价</span>
|
||
</div>
|
||
<div class="platform-price main-price">
|
||
¥{{ pkg.originalPrice.toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 3. 个人优惠券(辅助) -->
|
||
<div v-if="pkg.discountAmount && pkg.discountAmount > 0" class="coupon-card">
|
||
<div class="coupon-header">
|
||
<span class="coupon-icon">🎁</span>
|
||
<span class="coupon-title">您的个人尊享优惠券</span>
|
||
</div>
|
||
<div class="coupon-amount">
|
||
-¥{{ pkg.discountAmount.toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4. 最终专属价(弱化) -->
|
||
<div v-if="false" class="final-price-section">
|
||
<div class="price-label-row">
|
||
<span class="label-text light-label">👑 您的最终专属价(支付价)</span>
|
||
</div>
|
||
<div class="final-price-value light-price">
|
||
<span class="price-symbol">¥</span>
|
||
<span class="price-number">{{ pkg.price.toFixed(2) }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 5. 总优惠提示 -->
|
||
<!-- <div v-if="pkg.perMonth && pkg.perMonth > pkg.price" class="total-discount-bar"> -->
|
||
<!-- <span class="bar-icon">🎉</span> -->
|
||
<!-- <span class="bar-text">相比官方价已为您节省 ¥{{ (pkg.perMonth - pkg.price).toFixed(2) }}</span> -->
|
||
<!-- </div> -->
|
||
</template>
|
||
|
||
<!-- 会员套餐(无修改) -->
|
||
<template v-else>
|
||
<div class="current-price-section">
|
||
<span class="price-label">会员价</span>
|
||
<div class="price-row">
|
||
<span class="price">¥{{ pkg.price }}</span>
|
||
<span v-if="pkg.perMonth" class="per-month">仅¥{{ pkg.perMonth }}/月</span>
|
||
</div>
|
||
</div>
|
||
<div v-if="pkg.discount" class="discount-info">
|
||
<el-icon class="discount-icon">
|
||
<CircleCheck />
|
||
</el-icon>
|
||
<span class="discount-text">{{ pkg.discount }}</span>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 其他辅助信息(无修改) -->
|
||
<div v-if="activeTab === 'token'" class="recharge-tip-card">
|
||
<div class="tip-icon">
|
||
💝
|
||
</div>
|
||
<div class="tip-content">
|
||
<div class="tip-title">
|
||
累计充值优惠
|
||
</div>
|
||
<div class="tip-desc">
|
||
{{ selectPackageObject?.discount }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: flex;justify-content: space-between;margin-top: 15px;">
|
||
<div>
|
||
<p style="color: #f97316;font-weight: 800">
|
||
全站任意充值,每累计充值10元永久优惠尊享包10元,最高可优惠50元
|
||
</p>
|
||
|
||
<p style="margin-top: 10px;">
|
||
充值后,加客服微信回复账号名,可专享vip售后服务
|
||
</p>
|
||
<p style="margin-top: 10px;">
|
||
客服微信号:chengzilaoge520 或扫描右侧二维码
|
||
</p>
|
||
</div>
|
||
<div><img style="height: 80px;width: 80px;" src="/src/assets/images/wx.png" alt=""></div>
|
||
</div>
|
||
|
||
<!-- 支付按钮(无修改) -->
|
||
<div class="payment-section">
|
||
<div v-if="false" class="agreement-text">
|
||
登录和注册都代表同意YiXinAI的会员协议
|
||
</div>
|
||
<div class="payment-action">
|
||
<div class="actual-payment">
|
||
<span>实际支付:</span>
|
||
<span class="price">¥{{ selectedPrice || 0 }}</span>
|
||
</div>
|
||
<div>
|
||
<el-button class="pay-button" text type="primary" @click="toggleDetails">
|
||
了解更多
|
||
</el-button>
|
||
<el-button
|
||
v-if="userStore.userInfo"
|
||
type="primary" size="large" :disabled="!selectedId || isLoading" :loading="isLoading"
|
||
class="pay-button" @click="pay"
|
||
>
|
||
立即支付
|
||
</el-button>
|
||
<el-button
|
||
v-else
|
||
type="primary" size="large"
|
||
class="pay-button" @click="handleClickLogin"
|
||
>
|
||
立即登录/注册
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
<div class="note-text">
|
||
可叠加购买次数,过期时间以最后订单为准。<br>
|
||
最终解释权归YiXinAI所有。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右栏 套餐权益(无修改) -->
|
||
<div class="w-[40%] flex flex-col justify-between right-panel max-h-400px overflow-y-auto">
|
||
<div>
|
||
<div v-if="activeTab === 'member'">
|
||
<div class="section-title">
|
||
会员权益
|
||
</div>
|
||
<ul class="benefits-list ">
|
||
<li v-for="(b, index) in currentBenefits" :key="index" class="benefit-item ">
|
||
<span class="dot"><el-icon><CircleCheck /></el-icon></span>
|
||
<span>
|
||
<span class="benefit-name">{{ b.name }}</span>
|
||
<span v-if="b.value">:{{ b.value }}</span>
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div v-if="activeTab === 'token'">
|
||
<div class="section-title">
|
||
尊享Token包权益
|
||
</div>
|
||
<ul class="benefits-list ">
|
||
<li v-for="(b, index) in benefitsData2.qy" :key="index" class="benefit-item ">
|
||
<span class="dot"><el-icon><CircleCheck /></el-icon></span>
|
||
<span>
|
||
<span class="benefit-name">{{ b.name }}</span>
|
||
<span v-if="b.value">:{{ b.value }}</span>
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
<br>
|
||
<div class="section-title">
|
||
尊享Token包用途
|
||
</div>
|
||
<ul class="benefits-list ">
|
||
<li v-for="(b, index) in benefitsData2.yt" :key="index" class="benefit-item ">
|
||
<span class="dot"><el-icon><CircleCheck /></el-icon></span>
|
||
<span>
|
||
<span class="benefit-name">{{ b.name }}</span>
|
||
<span v-if="b.value">:{{ b.value }}</span>
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div v-if="activeTab === 'member'" class="extra-description ">
|
||
<SupportModelList />
|
||
</div>
|
||
</div>
|
||
<div class="view-details" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
.product-package-dialog {
|
||
.el-dialog__header { display: none; }
|
||
|
||
/* 详情页样式(无修改) */
|
||
.details-view {
|
||
height: 600px; overflow-y: auto; padding-right: 8px;
|
||
.benefits-table {
|
||
display: table; width: 100%; border-collapse: collapse;
|
||
.table-header, .table-row { display: table-row; }
|
||
.table-cell {
|
||
display: table-cell; padding: 12px 16px;
|
||
border-bottom: 1px solid #eee; vertical-align: middle;
|
||
}
|
||
.table-header {
|
||
font-weight: bold; background-color: #f8f8f8;
|
||
.table-cell { border-bottom: 2px solid #ddd; }
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 激活码引导页样式 */
|
||
.activation-guide-container {
|
||
padding: 40px 20px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
min-height: 400px;
|
||
background: linear-gradient(to bottom, #fff, #fdfdfd);
|
||
border-radius: 8px;
|
||
|
||
.activation-content {
|
||
text-align: center;
|
||
max-width: 400px;
|
||
|
||
.guide-icon {
|
||
font-size: 64px;
|
||
margin-bottom: 24px;
|
||
animation: float-icon 3s ease-in-out infinite;
|
||
}
|
||
|
||
.guide-title {
|
||
font-size: 24px;
|
||
font-weight: 800;
|
||
color: #2c3e50;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.guide-desc {
|
||
color: #606266;
|
||
line-height: 1.6;
|
||
margin-bottom: 32px;
|
||
font-size: 15px;
|
||
}
|
||
|
||
.redeem-jump-btn {
|
||
width: 200px;
|
||
height: 48px;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
letter-spacing: 1px;
|
||
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
|
||
border: none;
|
||
box-shadow: 0 4px 12px rgba(255, 117, 140, 0.3);
|
||
transition: all 0.3s;
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 16px rgba(255, 117, 140, 0.4);
|
||
}
|
||
}
|
||
|
||
.guide-tips {
|
||
margin-top: 24px;
|
||
font-size: 13px;
|
||
color: #909399;
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes float-icon {
|
||
0%, 100% { transform: translateY(0); }
|
||
50% { transform: translateY(-10px); }
|
||
}
|
||
|
||
/* 移动端样式(核心新增:主价格/弱化价格样式) */
|
||
.mobile-layout {
|
||
display: flex; flex-direction: column; gap: 24px;
|
||
.package-list { display: grid; grid-template-columns: 1fr; gap: 12px; }
|
||
.package-card {
|
||
position: relative; border: 1px solid #e5e7eb; border-radius: 8px;
|
||
padding: 16px; transition: all 0.3s; cursor: pointer;
|
||
&.selected {
|
||
border: 3px solid #fde19d;
|
||
background-image: url('@/assets/images/product_background.svg');
|
||
background-repeat: no-repeat;
|
||
/* 按需设置是否重复 */
|
||
background-size: cover;
|
||
/* 按需设置背景图尺寸适配方式,比如 cover、contain 等 */
|
||
background-position: bottom;
|
||
/* 按需设置背景图位置 */
|
||
|
||
box-shadow: 0 4px 6px -1px #fff4e3;
|
||
}
|
||
.discount-tag {
|
||
position: absolute; top: -6px; left: 8px;
|
||
background-color: #ef4444; color: white; font-size: 12px;
|
||
padding: 2px 8px; border-radius: 4px;
|
||
}
|
||
.tag {
|
||
position: absolute; top: -6px; right: 8px;
|
||
background-color: #f97316; color: white; font-size: 12px;
|
||
padding: 2px 8px; border-radius: 4px;
|
||
}
|
||
.package-info {
|
||
margin-bottom: 12px;
|
||
|
||
.package-name {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.package-desc {
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
/* Token套餐价格样式优化 */
|
||
.package-price {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
|
||
// 官方参考价
|
||
.reference-price-section {
|
||
padding: 6px 10px;
|
||
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
|
||
border-radius: 6px;
|
||
border: 1px dashed #f87171;
|
||
|
||
.reference-label {
|
||
font-size: 11px;
|
||
color: #991b1b;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.reference-value {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #dc2626;
|
||
text-decoration: line-through;
|
||
}
|
||
}
|
||
|
||
// 当前价格
|
||
.current-price-section {
|
||
.price-label {
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
display: block;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.price-row {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 6px;
|
||
}
|
||
|
||
.price {
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
color: #f97316;
|
||
}
|
||
|
||
.per-month {
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
// 优惠说明
|
||
.discount-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 6px 10px;
|
||
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
||
border-radius: 6px;
|
||
font-size: 11px;
|
||
color: #1e40af;
|
||
line-height: 1.4;
|
||
|
||
.discount-icon {
|
||
color: #3b82f6;
|
||
flex-shrink: 0;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.discount-text {
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
// 节省金额
|
||
.save-amount {
|
||
padding: 8px 10px;
|
||
background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
color: #15803d;
|
||
text-align: center;
|
||
box-shadow: 0 2px 4px rgba(34, 197, 94, 0.2);
|
||
}
|
||
|
||
// Token套餐四层价格展示样式 - 移动端
|
||
.official-price-section {
|
||
padding: 6px 10px;
|
||
background: linear-gradient(135deg, #fef1f2 0%, #ffe4e6 100%);
|
||
border-radius: 6px;
|
||
border: 1px solid #fecdd3;
|
||
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 3px;
|
||
|
||
.label-text {
|
||
font-size: 11px;
|
||
color: #9f1239;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.official-price {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #be123c;
|
||
text-decoration: line-through;
|
||
text-decoration-thickness: 2px;
|
||
}
|
||
}
|
||
|
||
.platform-price-section {
|
||
padding: 8px 10px; background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
|
||
border-radius: 6px; border: 1px solid #fbbf24;
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 3px;
|
||
|
||
.label-text {
|
||
font-size: 11px;
|
||
color: #78350f;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.save-tag {
|
||
background: #dc2626;
|
||
color: white;
|
||
font-size: 9px;
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.platform-price {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #b45309;
|
||
}
|
||
}
|
||
|
||
.coupon-card {
|
||
padding: 8px 10px; background: linear-gradient(135deg, #fef3c7 0%, #ffedd5 100%);
|
||
border-radius: 6px; border: 1px dashed #fb923c; display: flex; align-items: center; justify-content: space-between;
|
||
.coupon-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
|
||
.coupon-icon {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.coupon-title {
|
||
font-size: 10px;
|
||
color: #78350f;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.coupon-amount {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #ea580c;
|
||
}
|
||
}
|
||
|
||
.our-price-section {
|
||
padding: 10px 12px;
|
||
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
|
||
border-radius: 8px;
|
||
border: 1px solid #fbbf24;
|
||
|
||
.price-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 6px;
|
||
|
||
.price-tag-small {
|
||
font-size: 12px;
|
||
color: #78350f;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.save-badge {
|
||
background: #dc2626;
|
||
color: white;
|
||
font-size: 10px;
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.our-price {
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
color: #b45309;
|
||
}
|
||
}
|
||
|
||
.final-price-section {
|
||
padding: 10px;
|
||
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
||
border-radius: 8px;
|
||
border: 2px solid #60a5fa;
|
||
box-shadow: 0 4px 6px rgba(59, 130, 246, 0.2);
|
||
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 6px;
|
||
|
||
.label-text.special {
|
||
font-size: 12px;
|
||
color: #1e40af;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
.final-price-value {
|
||
display: flex;
|
||
align-items: baseline;
|
||
margin-bottom: 4px;
|
||
|
||
.price-symbol {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #1e40af;
|
||
margin-right: 2px;
|
||
}
|
||
|
||
.price-number {
|
||
font-size: 26px;
|
||
font-weight: 700;
|
||
color: #1e40af;
|
||
}
|
||
}
|
||
|
||
.discount-desc {
|
||
font-size: 10px;
|
||
color: #1e3a8a;
|
||
font-weight: 500;
|
||
line-height: 1.3;
|
||
}
|
||
}
|
||
|
||
.total-discount-bar {
|
||
display: flex; align-items: center; justify-content: center; gap: 6px;
|
||
padding: 8px 10px; background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
|
||
border-radius: 8px; border: 1px solid #34d399; box-shadow: 0 2px 6px rgba(16, 185, 129, 0.25);
|
||
.bar-icon {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.bar-text {
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
color: #065f46;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 累计充值优惠提示卡片样式
|
||
.recharge-tip-card {
|
||
display: flex; align-items: center; gap: 12px; padding: 12px 16px;
|
||
background: linear-gradient(135deg, #fef3c7 0%, #ffedd5 100%);
|
||
border-radius: 8px; border: 1px solid #fbbf24; margin-top: 16px;
|
||
.tip-icon {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.tip-content {
|
||
flex: 1;
|
||
|
||
.tip-title {
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
color: #78350f;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.tip-desc {
|
||
font-size: 12px;
|
||
color: #92400e;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
}
|
||
|
||
.benefits-preview {
|
||
background-color: #f9fafb; border-radius: 8px; padding: 16px;
|
||
.section-title { font-weight: 600; margin-bottom: 12px; }
|
||
.benefits-list {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
|
||
.benefit-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
margin-bottom: 8px;
|
||
font-size: 14px;
|
||
color: #4b5563;
|
||
white-space: normal;
|
||
|
||
.dot {
|
||
color: #f97316;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.benefit-name {
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.view-details-btn {
|
||
width: 100%;
|
||
margin-top: 16px;
|
||
justify-content: flex-end;
|
||
}
|
||
}
|
||
|
||
.payment-area {
|
||
border-top: 1px solid #e5e7eb; padding-top: 16px;
|
||
.agreement-text { font-size: 12px; color: #6b7280; margin-bottom: 12px; }
|
||
.payment-info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 8px;
|
||
|
||
.actual-payment {
|
||
.price {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #f97316;
|
||
}
|
||
}
|
||
|
||
.pay-button {
|
||
width: 120px;
|
||
}
|
||
}
|
||
|
||
.note-text {
|
||
font-size: 12px;
|
||
color: #9ca3af;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 桌面端样式 */
|
||
.desktop-layout {
|
||
.package-card {
|
||
cursor: pointer; position: relative; width: calc(50% - 0.5rem);
|
||
border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px;
|
||
transition: all 0.3s; display: flex; flex-direction: column; justify-content: space-between;
|
||
background: linear-gradient(90deg, #f1f2ebb5, white);
|
||
&.selected {
|
||
border: 3px solid #fde19d;
|
||
background-image: url('@/assets/images/product_background.svg');
|
||
background-repeat: no-repeat;
|
||
/* 按需设置是否重复 */
|
||
background-size: cover;
|
||
/* 按需设置背景图尺寸适配方式,比如 cover、contain 等 */
|
||
background-position: bottom;
|
||
/* 按需设置背景图位置 */
|
||
|
||
box-shadow: 0 4px 6px -1px #fff4e3;
|
||
}
|
||
|
||
.discount-tag {
|
||
position: absolute;
|
||
top: -6px;
|
||
left: 8px;
|
||
background-color: #ef4444;
|
||
color: white;
|
||
font-size: 12px;
|
||
padding: 2px 8px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.tag {
|
||
position: absolute; top: -6px; right: 8px;
|
||
background-color: #f97316; color: white; font-size: 12px;
|
||
padding: 2px 8px; border-radius: 4px;
|
||
}
|
||
.package-info {
|
||
margin-bottom: 12px;
|
||
|
||
.package-name {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.package-desc {
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
/* 桌面端Token套餐价格样式优化 */
|
||
.package-price {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
margin-top: 12px;
|
||
|
||
// 官方参考价
|
||
.reference-price-section {
|
||
padding: 8px 12px;
|
||
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
|
||
border-radius: 8px;
|
||
border: 1px dashed #f87171;
|
||
|
||
.reference-label {
|
||
font-size: 12px;
|
||
color: #991b1b;
|
||
margin-bottom: 4px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.reference-value {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #dc2626;
|
||
text-decoration: line-through;
|
||
}
|
||
}
|
||
|
||
// 当前价格
|
||
.current-price-section {
|
||
.price-label {
|
||
font-size: 13px;
|
||
color: #6b7280;
|
||
display: block;
|
||
margin-bottom: 6px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.price-row {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 8px;
|
||
}
|
||
|
||
.price {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
color: #f97316;
|
||
}
|
||
|
||
.per-month {
|
||
font-size: 13px;
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
// 优惠说明
|
||
.discount-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 8px 12px;
|
||
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
||
border-radius: 8px;
|
||
font-size: 12px;
|
||
color: #1e40af;
|
||
line-height: 1.5;
|
||
|
||
.discount-icon {
|
||
color: #3b82f6;
|
||
flex-shrink: 0;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.discount-text {
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
// 节省金额
|
||
.save-amount {
|
||
padding: 10px 12px;
|
||
background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
|
||
border-radius: 8px;
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #15803d;
|
||
text-align: center;
|
||
box-shadow: 0 2px 6px rgba(34, 197, 94, 0.25);
|
||
}
|
||
|
||
// Token套餐四层价格展示样式 - 桌面端
|
||
.official-price-section {
|
||
padding: 4px 6px;
|
||
background: linear-gradient(15deg, rgb(155, 155, 155) 0%, #999a9d 100%);
|
||
border-radius: 8px; border: 1px solid rgba(156, 163, 175, 0.67);
|
||
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 4px;
|
||
|
||
.label-text {
|
||
font-size: 12px;
|
||
color: #ffffff;
|
||
font-weight: 700;
|
||
}
|
||
.label-text-number { font-size: 14px; color: #ffffff; font-weight: 700;text-decoration: line-through; }
|
||
}
|
||
|
||
.official-price {
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
color: #be123c;
|
||
text-decoration: line-through;
|
||
text-decoration-thickness: 2px;
|
||
}
|
||
}
|
||
|
||
.platform-price-section {
|
||
padding: 10px 12px; background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
|
||
border-radius: 8px; border: 1px solid #fbbf24;
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 4px;
|
||
|
||
.label-text {
|
||
font-size: 12px;
|
||
color: #78350f;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.save-tag {
|
||
background: #dc2626;
|
||
color: white;
|
||
font-size: 10px;
|
||
padding: 2px 8px;
|
||
border-radius: 4px;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.platform-price {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
color: #b45309;
|
||
}
|
||
}
|
||
|
||
.coupon-card {
|
||
padding: 10px 12px; background: linear-gradient(135deg, #fef3c7 0%, #ffedd5 100%);
|
||
border-radius: 8px; border: 1px dashed #fb923c; display: flex; align-items: center; justify-content: space-between;
|
||
.coupon-header { display: flex; align-items: center; gap: 6px; .coupon-icon { font-size: 16px; } .coupon-title { font-size: 11px; color: #78350f; font-weight: 700; } }
|
||
.coupon-amount {
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
color: #ea580c;
|
||
}
|
||
}
|
||
|
||
.final-price-section {
|
||
padding: 12px;
|
||
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
||
border-radius: 10px;
|
||
border: 2px solid #60a5fa;
|
||
box-shadow: 0 4px 8px rgba(59, 130, 246, 0.25);
|
||
|
||
.price-label-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 8px;
|
||
|
||
.label-text.special {
|
||
font-size: 14px;
|
||
color: #1e40af;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
.final-price-value {
|
||
display: flex;
|
||
align-items: baseline;
|
||
margin-bottom: 6px;
|
||
|
||
.price-symbol {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #1e40af;
|
||
margin-right: 2px;
|
||
}
|
||
|
||
.price-number {
|
||
font-size: 30px;
|
||
font-weight: 700;
|
||
color: #1e40af;
|
||
}
|
||
}
|
||
|
||
.discount-desc {
|
||
font-size: 11px;
|
||
color: #1e3a8a;
|
||
font-weight: 500;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
.total-discount-bar {
|
||
display: flex; align-items: center; justify-content: center; gap: 8px;
|
||
padding: 10px 12px; background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
|
||
border-radius: 10px; border: 1px solid #34d399; box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
|
||
.bar-icon {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.bar-text {
|
||
font-size: 13px;
|
||
font-weight: 700;
|
||
color: #065f46;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 累计充值优惠提示卡片样式 - 桌面端
|
||
.recharge-tip-card {
|
||
display: flex; align-items: center; gap: 12px; padding: 12px 16px;
|
||
background: linear-gradient(135deg, #fef3c7 0%, #ffedd5 100%);
|
||
border-radius: 8px; border: 1px solid #fbbf24; margin-top: 16px;
|
||
.tip-icon {
|
||
font-size: 28px;
|
||
}
|
||
|
||
.tip-content {
|
||
flex: 1;
|
||
|
||
.tip-title {
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
color: #78350f;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.tip-desc {
|
||
font-size: 13px;
|
||
color: #92400e;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
}
|
||
|
||
.payment-section {
|
||
border-top: 1px solid #e5e7eb; padding-top: 16px; margin-top: 16px;
|
||
.agreement-text { font-size: 12px; color: #6b7280; margin-bottom: 12px; }
|
||
.payment-action {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 8px;
|
||
|
||
.actual-payment {
|
||
.price {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #f97316;
|
||
}
|
||
}
|
||
}
|
||
|
||
.note-text {
|
||
font-size: 12px;
|
||
color: #9ca3af;
|
||
}
|
||
}
|
||
|
||
.right-panel {
|
||
.section-title { font-weight: 600; margin-bottom: 12px; }
|
||
.benefits-list {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
|
||
.benefit-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
margin-bottom: 8px;
|
||
font-size: 14px;
|
||
color: #4b5563;
|
||
white-space: normal;
|
||
|
||
.dot {
|
||
color: #f97316;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.benefit-name {
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.extra-description {
|
||
margin-top: 24px;
|
||
|
||
.description-card {
|
||
background-color: #f9fafb;
|
||
border-radius: 8px;
|
||
padding: 12px;
|
||
margin-bottom: 12px;
|
||
|
||
.title {
|
||
font-weight: 600;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.subtext {
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
}
|
||
|
||
.view-details {
|
||
border-top: 1px solid #e5e7eb;
|
||
padding-top: 16px;
|
||
margin-top: 16px;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 响应式调整 */
|
||
@media (max-width: 768px) {
|
||
.el-dialog { margin-top: 20px !important; margin-bottom: 20px !important; }
|
||
.details-view {
|
||
height: auto; max-height: 80vh;
|
||
.benefits-table {
|
||
display: block;
|
||
overflow-x: auto;
|
||
white-space: nowrap;
|
||
|
||
.table-header,
|
||
.table-row {
|
||
display: table;
|
||
width: 100%;
|
||
table-layout: fixed;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
::-webkit-scrollbar-thumb {
|
||
background-color: #ccc;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
/* 加载状态样式 */
|
||
.loading-container {
|
||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||
padding: 60px 20px; color: #909399;
|
||
p {
|
||
margin-top: 16px;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.loading-container-desktop {
|
||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||
width: 100%; min-height: 400px; color: #909399;
|
||
p { margin-top: 20px; font-size: 16px; }
|
||
}
|
||
}
|
||
</style>
|