daShangDao_miniProgram/pages/user/memberSelect.vue
2025-11-24 10:25:20 +08:00

1281 lines
36 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="member-select-container">
<!-- 页面标题 -->
<view class="page-header">
<!-- <view class="header-title">会员等级选择</view> -->
<view class="header-subtitle">选择适合您的会员等级享受更多权益</view>
</view>
<!-- 用户会员状态统一显示区域 -->
<view class="member-status-overview" v-if="showTabs">
<!-- 根据当前Tab显示对应的会员状态 - 已开通 -->
<view class="status-card" v-if="getCurrentTabMemberStatus().isVip">
<view class="status-card-header">
<text class="status-type">{{ getCurrentTabName() }}</text>
<text class="status-badge vip">已开通</text>
</view>
<view class="status-card-content">
<!-- 小程序上书会员显示上书本数 -->
<view class="status-detail" v-if="getCurrentTabType() === 'xcx'">
<text class="detail-label">已上书本数:</text>
<text class="detail-value">{{ getCurrentTabMemberStatus().count }}本</text>
</view>
<view class="status-detail" v-if="getCurrentTabMemberStatus().expirationDateStr">
<text class="detail-label">到期时间:</text>
<text class="detail-value">{{ getCurrentTabMemberStatus().expirationDateStr }}</text>
</view>
<view class="status-detail" v-if="getCurrentTabMemberStatus().daysRemaining > 0">
<text class="detail-label">剩余天数:</text>
<text
class="detail-value remaining-days">{{ getCurrentTabMemberStatus().daysRemaining }}天</text>
</view>
<view class="status-detail" v-else-if="getCurrentTabMemberStatus().daysRemaining === 0">
<text class="detail-label expired">会员已到期</text>
</view>
</view>
</view>
<!-- 根据当前Tab显示对应的会员状态 - 已过期 -->
<view class="status-card expired-card"
v-if="!getCurrentTabMemberStatus().isVip && getCurrentTabMemberStatus().isExpired">
<view class="status-card-header">
<text class="status-type">{{ getCurrentTabName() }}</text>
<text class="status-badge expired">已到期</text>
</view>
<view class="status-card-content">
<!-- 小程序上书会员显示上书本数 -->
<view class="status-detail" v-if="getCurrentTabType() === 'xcx'">
<text class="detail-label">已上书本数:</text>
<text class="detail-value">{{ getCurrentTabMemberStatus().count }}本</text>
</view>
<view class="status-detail" v-if="getCurrentTabMemberStatus().expirationDateStr">
<text class="detail-label">过期时间:</text>
<text class="detail-value">{{ getCurrentTabMemberStatus().expirationDateStr }}</text>
</view>
</view>
</view>
<!-- 未开通当前Tab对应会员时的提示 -->
<view class="no-member-tip"
v-if="!getCurrentTabMemberStatus().isVip && !getCurrentTabMemberStatus().isExpired">
<text class="tip-text">您还未开通{{ getCurrentTabName() }},选择下方套餐开始享受会员权益</text>
</view>
</view>
<!-- 未显示Tab时显示所有已开通的会员状态 -->
<view class="member-status-overview" v-if="!showTabs">
<!-- 小程序上书会员状态 -->
<view class="status-card" v-if="userMemberStatus.xcx.isVip">
<view class="status-card-header">
<text class="status-type">小程序上书会员</text>
<text class="status-badge vip">已开通</text>
</view>
<view class="status-card-content">
<view class="status-detail">
<text class="detail-label">已上书本数:</text>
<text class="detail-value">{{ userMemberStatus.xcx.count }}本</text>
</view>
<view class="status-detail" v-if="userMemberStatus.xcx.expirationDateStr">
<text class="detail-label">到期时间:</text>
<text class="detail-value">{{ userMemberStatus.xcx.expirationDateStr }}</text>
</view>
<view class="status-detail" v-if="userMemberStatus.xcx.daysRemaining > 0">
<text class="detail-label">剩余天数:</text>
<text class="detail-value remaining-days">{{ userMemberStatus.xcx.daysRemaining }}天</text>
</view>
<view class="status-detail" v-else-if="userMemberStatus.xcx.daysRemaining === 0">
<text class="detail-label expired">会员已到期</text>
</view>
</view>
</view>
<!-- 小程序上书会员过期状态 -->
<view class="status-card expired-card" v-if="!userMemberStatus.xcx.isVip && userMemberStatus.xcx.isExpired">
<view class="status-card-header">
<text class="status-type">小程序上书会员</text>
<text class="status-badge expired">已过期</text>
</view>
<view class="status-card-content">
<view class="status-detail">
<text class="detail-label">已上书本数:</text>
<text class="detail-value">{{ userMemberStatus.xcx.count }}本</text>
</view>
<view class="status-detail" v-if="userMemberStatus.xcx.expirationDateStr">
<text class="detail-label">过期时间:</text>
<text class="detail-value">{{ userMemberStatus.xcx.expirationDateStr }}</text>
</view>
</view>
</view>
<!-- 孔网翻新会员状态 -->
<view class="status-card" v-if="userMemberStatus.kwfw.isVip">
<view class="status-card-header">
<text class="status-type">孔网翻新会员</text>
<text class="status-badge vip">已开通</text>
</view>
<view class="status-card-content">
<view class="status-detail" v-if="userMemberStatus.kwfw.expirationDateStr">
<text class="detail-label">到期时间:</text>
<text class="detail-value">{{ userMemberStatus.kwfw.expirationDateStr }}</text>
</view>
<view class="status-detail" v-if="userMemberStatus.kwfw.daysRemaining > 0">
<text class="detail-label">剩余天数:</text>
<text class="detail-value remaining-days">{{ userMemberStatus.kwfw.daysRemaining }}天</text>
</view>
<view class="status-detail" v-else-if="userMemberStatus.kwfw.daysRemaining === 0">
<text class="detail-label expired">会员已到期</text>
</view>
</view>
</view>
<!-- 孔网翻新会员过期状态 -->
<view class="status-card expired-card"
v-if="!userMemberStatus.kwfw.isVip && userMemberStatus.kwfw.isExpired">
<view class="status-card-header">
<text class="status-type">孔网翻新会员</text>
<text class="status-badge expired">已过期</text>
</view>
<view class="status-card-content">
<view class="status-detail" v-if="userMemberStatus.kwfw.expirationDateStr">
<text class="detail-label">过期时间:</text>
<text class="detail-value">{{ userMemberStatus.kwfw.expirationDateStr }}</text>
</view>
</view>
</view>
<!-- 未开通任何会员时的提示 -->
<view class="no-member-tip"
v-if="!userMemberStatus.xcx.isVip && !userMemberStatus.kwfw.isVip && !userMemberStatus.xcx.isExpired && !userMemberStatus.kwfw.isExpired">
<text class="tip-text">您还未开通任何会员,选择下方套餐开始享受会员权益</text>
</view>
</view>
<!-- Tab切换 - 只在展示所有会员时显示 -->
<view class="tab-container" v-if="showTabs">
<view class="tab-list">
<view v-for="(tab, index) in tabs" :key="index" class="tab-item"
:class="{ 'active': activeTabIndex === index }" @click="switchTab(index)">
{{ tab.name }}
</view>
</view>
</view>
<!-- 会员卡片列表 -->
<view class="member-cards">
<view v-for="(item, index) in memberLevels" :key="index" class="member-card"
:class="{ 'selected': selectedIndex === index }" @click="selectMember(index)">
<!-- 会员卡片头部 -->
<view class="card-header" :style="{ backgroundColor: item.color || '#4A5CFF' }">
<view class="card-title">{{ item.name }}</view>
<view class="card-price">¥{{ item.price }}</view>
</view>
<!-- 会员卡片内容 -->
<view class="card-content">
<!-- 会员权益列表 -->
<view class="benefit-item" v-for="(benefit, bIndex) in item.benefits || defaultBenefits"
:key="bIndex">
<text class="benefit-icon"></text>
<text class="benefit-text">{{ benefit }}</text>
</view>
</view>
</view>
<!-- 选择标记 -->
<view class="select-mark" v-if="selectedIndex === index">
<text class="select-icon">✓</text>
</view>
</view>
<!-- 底部支付按钮 -->
<view class="bottom-bar">
<view class="selected-info" v-if="selectedIndex !== -1">
<text class="selected-name">{{ memberLevels[selectedIndex] && memberLevels[selectedIndex].name }}</text>
<text
class="selected-price">¥{{ memberLevels[selectedIndex] && memberLevels[selectedIndex].price }}</text>
</view>
<view class="pay-button" :class="{ 'disabled': selectedIndex === -1 }" @click="handlePay">
立即支付
</view>
</view>
</view>
</template>
<script>
import {
callWxPay,
checkPayStatus,
getMemberLevelList,
createKwfwMemberOrder,
updateKwfwMemberOrder,
updateUserBooksCountLimit,
getUserRecbusiness,
checkKwfwMemberStatus
} from '@/components/MemberBookCheck.js';
export default {
data() {
return {
memberLevels: [],
selectedIndex: -1,
isLoading: false,
defaultBenefits: [
'上传书籍数量增加',
'优先展示您的商品',
'专属客服服务',
'更多增值服务'
],
// 会员等级颜色配置
levelColors: [
'#4A5CFF', // 蓝色
'#FF7D3C', // 橙色
'#8A2BE2', // 紫色
'#FF4757', // 红色
'#2ED573' // 绿色
],
// Tab相关数据
showTabs: false, // 是否显示tab切换
activeTabIndex: 0, // 当前激活的tab索引
tabs: [{
name: '小程序上书会员',
type: 'xcx'
},
{
name: '孔网翻新会员',
type: 'kwfw'
}
],
// 存储所有会员数据
allMemberData: {
xcx: [], // 小程序上书会员数据
kwfw: [] // 孔网翻新会员数据
},
// 用户会员状态信息
userMemberStatus: {
xcx: {
isVip: false,
isExpired: false,
count: 0,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
},
kwfw: {
isVip: false,
isExpired: false,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
}
}
};
},
async onLoad(options) {
// 获取来源页面传递的参数
this.fromPage = options.from || '';
this.callback = options.callback || '';
this.memberType = options.type || ''; // 新增会员类型参数
// 加载会员等级数据和用户会员状态
await Promise.all([
this.loadMemberLevels(),
this.loadUserMemberStatus()
]);
},
async onShow() {
// 每次页面显示时刷新用户会员状态
await this.loadUserMemberStatus();
console.log('页面显示,会员状态已刷新:', this.userMemberStatus);
},
methods: {
// 加载会员等级数据
async loadMemberLevels() {
try {
uni.showLoading({
title: '加载中...'
});
console.log('加载会员等级数据,来源:', this.fromPage, '类型:', this.memberType);
// 根据不同的入口来源展示不同的会员卡片
if (this.fromPage === 'memberCheck' && this.memberType === 'xcx') {
// 从checkMemberBooksCount进入只显示小程序上书会员
this.showTabs = false;
await this.loadXcxMemberLevels();
} else if (this.fromPage === 'kwfw' && this.memberType === 'kwfw') {
// 从checkKwfwMember进入只显示翻新会员
this.showTabs = false;
this.setKwfwMemberLevels();
} else {
// 从toMemberSelect进入或其他情况显示所有会员卡片
this.showTabs = true;
await this.loadAllMemberLevels();
// 默认显示第一个tab的内容
this.switchTab(0);
}
} catch (error) {
console.error('加载会员等级数据失败:', error);
uni.showToast({
title: '加载会员价格失败',
icon: 'none'
});
// 加载失败时使用默认数据
this.setDefaultMemberLevels();
} finally {
uni.hideLoading();
}
},
// 加载小程序上书会员等级数据
async loadXcxMemberLevels() {
try {
// 调用接口获取会员等级列表
const levelList = await getMemberLevelList();
console.log('获取到的会员等级列表:', levelList);
if (levelList && levelList.length > 0) {
// 清空原有的会员等级数据
this.memberLevels = [];
// 查找memberType为1的配置
const memberTypeConfig = levelList.find(item => item.memberType === 1);
const settledId = memberTypeConfig.id;
console.log('找到的memberType为1的配置:', memberTypeConfig);
if (memberTypeConfig && memberTypeConfig.constraintJson) {
let parsedConfig;
// 解析constraintJson数据
if (typeof memberTypeConfig.constraintJson === 'string') {
parsedConfig = JSON.parse(memberTypeConfig.constraintJson);
} else {
parsedConfig = memberTypeConfig.constraintJson;
}
console.log('解析后的配置:', parsedConfig);
// 确认数据中有miniapp字段
if (parsedConfig.miniapp) {
const miniapp = parsedConfig.miniapp;
console.log('miniapp数据:', miniapp);
// 创建月付会员卡
if (miniapp.month_fee) {
const monthFee = Number(miniapp.month_fee);
console.log("月费:", monthFee);
this.memberLevels.push({
id: settledId,
name: '月付会员 (点击开通)',
price: monthFee.toFixed(2),
originalPrice: monthFee * 100, // 转换为分
// price: '0.01',
// originalPrice: 1, // 以分为单位
color: this.levelColors[0],
unit: '月',
length: 1,
serviceName: 'xcx上书会员',
benefits: [
'每月上传书籍数量增加',
// '优先展示您的商品',
// '专属客服服务',
'月度VIP标识'
]
});
}
// 创建年付会员卡
if (miniapp.year_fee) {
const yearFee = Number(miniapp.year_fee);
console.log("年费:", yearFee);
this.memberLevels.push({
id: settledId,
name: '年度会员 (点击开通)',
price: yearFee.toFixed(2),
originalPrice: yearFee * 100, // 转换为分
color: this.levelColors[1],
unit: '月',
length: 12,
serviceName: 'xcx上书会员',
benefits: [
'无限制上传书籍数量',
// '优先展示您的商品',
// '24小时专属客服服务',
// '年度VIP专属标识',
'更多增值服务特权'
]
});
}
}
}
}
// 如果没有获取到会员等级数据,显示默认的小程序上书会员数据
if (this.memberLevels.length === 0) {
this.setDefaultXcxMemberLevels();
}
} catch (error) {
console.error('加载小程序上书会员数据失败:', error);
this.setDefaultXcxMemberLevels();
}
},
// 加载所有会员等级数据(小程序上书会员 + 翻新会员)
async loadAllMemberLevels() {
try {
// 清空之前的数据
this.allMemberData.xcx = [];
this.allMemberData.kwfw = [];
// 加载小程序上书会员数据
await this.loadXcxMemberLevels();
// 将当前的memberLevels保存到xcx数据中
this.allMemberData.xcx = [...this.memberLevels];
// 加载翻新会员数据
this.setKwfwMemberLevels();
// 将当前的memberLevels保存到kwfw数据中
this.allMemberData.kwfw = [...this.memberLevels];
} catch (error) {
console.error('加载所有会员数据失败:', error);
this.setDefaultAllMemberLevels();
}
},
// 设置默认小程序上书会员等级数据
setDefaultXcxMemberLevels() {
this.memberLevels = [{
id: 1,
name: '月付会员 (点击开通)',
price: '39.90',
originalPrice: 3990, // 以分为单位
color: this.levelColors[0],
unit: '月',
length: 1,
sort: 1,
serviceName: 'xcx上书会员',
benefits: [
'每月上传书籍数量增加',
'优先展示您的商品',
'专属客服服务',
'月度VIP标识'
]
},
{
id: 2,
name: '年度会员 (点击开通)',
price: '399.00',
originalPrice: 39900, // 以分为单位
color: this.levelColors[1],
unit: '月',
length: 12,
sort: 2,
serviceName: 'xcx上书会员',
benefits: [
'无限制上传书籍数量',
'优先展示您的商品',
'24小时专属客服服务',
'年度VIP专属标识',
'更多增值服务特权'
]
}
];
},
// 设置默认会员等级数据(兼容旧版本)
setDefaultMemberLevels() {
this.setDefaultXcxMemberLevels();
},
// 设置默认所有会员等级数据(小程序上书会员 + 翻新会员)
setDefaultAllMemberLevels() {
this.setDefaultXcxMemberLevels();
// 添加翻新会员
this.memberLevels.push({
id: 'kwfw',
name: '孔网翻新会员/月 (点击开通)',
price: '98.00',
originalPrice: 9800, // 以分为单位
color: this.levelColors[2], // 使用紫色
unit: '月',
length: 1,
sort: 1,
serviceName: 'xcx翻新会员',
benefits: [
'无限制使用孔网商品翻新功能',
'批量处理商品信息',
'优先获得新功能体验'
],
type: 'kwfw' // 标识为孔网翻新会员
});
},
// 设置孔网翻新会员等级数据
setKwfwMemberLevels() {
this.memberLevels = [{
id: 'kwfw',
name: '孔网翻新会员/月',
price: '98.00',
originalPrice: 9800, // 以分为单位
// price: '0.01',
// originalPrice: 1, // 以分为单位
color: this.levelColors[2], // 使用紫色
unit: '月',
length: 1,
sort: 1,
serviceName: 'xcx翻新会员',
benefits: [
'无限制使用孔网商品翻新功能',
'批量处理商品信息',
'优先获得新功能体验'
],
type: 'kwfw' // 标识为孔网翻新会员
}];
},
// 选择会员等级
selectMember(index) {
this.selectedIndex = index;
},
// 处理支付
async handlePay() {
if (this.selectedIndex === -1 || this.isLoading) {
return;
}
const selectedLevel = this.memberLevels[this.selectedIndex];
console.log('selectedLevel:', selectedLevel);
uni.showModal({
title: '确认支付',
content: `您选择了${selectedLevel.name},需支付¥${selectedLevel.price},确认继续吗?`,
success: async (res) => {
if (res.confirm) {
this.isLoading = true;
uni.showLoading({
title: '发起支付...'
});
try {
// 如果是孔网翻新会员,使用特殊的支付处理逻辑
if (selectedLevel.type === 'kwfw') {
await this.handleKwfwMemberPay(selectedLevel);
} else {
// 普通会员支付逻辑
await this.handleNormalMemberPay(selectedLevel);
}
} catch (error) {
console.error('支付过程出错:', error);
uni.showToast({
title: '支付过程出错,请重试',
icon: 'none'
});
} finally {
uni.hideLoading();
this.isLoading = false;
}
}
}
});
},
// 处理普通会员支付
async handleNormalMemberPay(selectedLevel) {
try {
const userId = uni.getStorageSync('userId')
// 第一步:支付前创建订单记录
const orderData = {
userId: userId,
memberType: 'normal',
amount: selectedLevel.price,
originalPrice: selectedLevel.originalPrice,
createTime: new Date().toISOString(),
unit: selectedLevel.unit,
length: selectedLevel.length,
serviceName: selectedLevel.serviceName,
};
console.log('支付前创建普通会员订单:', orderData);
const createResult = await createKwfwMemberOrder(orderData);
console.log('创建普通会员订单:', createResult);
if (!createResult.success) {
throw new Error('创建订单失败: ' + createResult.error);
}
// const orderId = createResult.orderId;
// console.log('普通会员订单创建成功订单ID:', orderId);
// 第二步:发起支付
// 使用原始价格(分)进行支付
const originalPrice = selectedLevel.originalPrice;
// 获取会员等级ID
const settledId = selectedLevel.id;
// console.log('支付会员等级ID:', settledId);
console.log('订单id:', createResult.orderId.orderId);
const payResult = await callWxPay(originalPrice, settledId, 'normal', createResult.orderId
.orderId);
// console.log('支付结果:', payResult);
// console.log('订单更新结果:', updateResult);
// 调用更新用户书籍数量限制接口
// const userId = uni.getStorageSync('userId');
// const limitUpdateResult = await updateUserBooksCountLimit(payResult, orderId, userId, settledId);
// console.log('用户书籍数量限制更新结果:', limitUpdateResult);
// 孔网翻新会员的订单状态更新在 memberSelect.vue 中通过 updateKwfwMemberOrder 处理
// console.log('上书会员支付成功,订单状态将通过专用接口更新');
if (payResult.success) {
const updateResult = await updateKwfwMemberOrder(createResult.orderId.orderId, payResult, userId);
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 支付成功后的处理
setTimeout(() => {
// 如果有回调函数,调用它
const app = getApp();
if (app.memberSelectCallback) {
app.memberSelectCallback(true);
}
// 返回上一页
// uni.navigateBack();
uni.navigateTo({
url: '/pages/user/index'
});
}, 1500);
} else {
uni.showToast({
title: '支付未完成',
icon: 'none'
});
}
} catch (error) {
console.error('普通会员支付过程出错:', error);
uni.showToast({
title: '支付过程出错: ' + error.message,
icon: 'none',
duration: 3000
});
}
},
// 处理孔网翻新会员支付
async handleKwfwMemberPay(selectedLevel) {
// 导入孔网翻新会员订单相关函数
try {
const userId = uni.getStorageSync('userId')
// 第一步:支付前创建订单记录
const orderData = {
userId: userId,
memberType: 'kwfw',
amount: selectedLevel.price,
originalPrice: selectedLevel.originalPrice,
createTime: new Date().toISOString(),
unit: selectedLevel.unit,
length: selectedLevel.length,
serviceName: selectedLevel.serviceName,
sort: selectedLevel.sort,
};
console.log('支付前创建订单:', orderData);
const createResult = await createKwfwMemberOrder(orderData);
console.log('createResult:', createResult);
if (!createResult.success) {
throw new Error('创建订单失败: ' + createResult.error);
}
// orderId = createResult.orderId;
// console.log('订单创建成功订单ID:', orderId);
// 第二步:发起支付
// 使用原始价格(分)进行支付
const originalPrice = selectedLevel.originalPrice;
// 孔网翻新会员使用特殊的ID标识
const settledId = 'kwfw_member';
console.log('支付孔网翻新会员ID:', settledId);
console.log('订单id:', createResult.orderId.orderId);
const payResult = await callWxPay(originalPrice, settledId, 'kwfw', createResult.orderId.orderId);
console.log('支付结果:', payResult);
// 孔网翻新会员的订单状态更新在 memberSelect.vue 中通过 updateKwfwMemberOrder 处理
if (payResult.success) {
await updateKwfwMemberOrder(createResult.orderId.orderId, payResult, userId);
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 支付成功后的处理
setTimeout(() => {
// 如果有孔网翻新会员回调函数,调用它
const app = getApp();
if (app.kwfwMemberCallback) {
app.kwfwMemberCallback(true);
}
// 返回上一页
// uni.navigateBack();
uni.navigateTo({
url: '/pages/user/index'
});
}, 1500);
} else {
uni.showToast({
title: '支付未完成',
icon: 'none'
});
}
} catch (error) {
console.error('孔网翻新会员支付过程出错:', error);
uni.showToast({
title: '支付过程出错: ' + error.message,
icon: 'none',
duration: 3000
});
}
},
// Tab切换方法
switchTab(index) {
this.activeTabIndex = index;
this.selectedIndex = -1; // 重置选择状态
const tabType = this.tabs[index].type;
if (tabType === 'xcx') {
// 显示小程序上书会员
this.memberLevels = [...this.allMemberData.xcx];
} else if (tabType === 'kwfw') {
// 显示孔网翻新会员
this.memberLevels = [...this.allMemberData.kwfw];
}
},
// 时间戳转换为北京时间字符串
formatTimestamp(timestamp) {
if (!timestamp) return '';
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}${month}${day}${hours}:${minutes}:${seconds}`;
},
// 计算距离到期还有多少天
calculateDaysRemaining(timestamp) {
if (!timestamp) return 0;
const now = new Date().getTime();
const expiration = new Date(timestamp).getTime();
const diffTime = expiration - now;
if (diffTime <= 0) return 0;
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
},
// 获取用户小程序上书会员状态
async getUserXcxMemberStatus() {
try {
const userId = uni.getStorageSync('userId');
if (!userId) {
console.log('用户未登录');
return;
}
const response = await getUserRecbusiness(userId);
console.log('小程序上书会员状态响应:', response);
if (response && response.data) {
if (response.data.code === 200 && response.data.data) {
// 成功获取用户会员状态
const data = response.data.data;
// 判断是否过期有expirationDate但isVip为false
const isExpired = !data.isVip && data.expirationDate;
this.userMemberStatus.xcx = {
isVip: data.isVip,
isExpired: isExpired,
count: data.count || 0,
expirationDate: data.expirationDate,
expirationDateStr: data.expirationDate ? this.formatTimestamp(data
.expirationDate) : '',
daysRemaining: data.expirationDate ? this.calculateDaysRemaining(data
.expirationDate) : 0
};
console.log('小程序上书会员状态更新成功:', this.userMemberStatus.xcx);
} else {
// 其他错误情况,设置为未开通状态
console.log('小程序上书会员:获取状态失败,设置为未开通状态', response);
this.userMemberStatus.xcx = {
isVip: false,
isExpired: false,
count: 0,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
}
} else {
// 响应为空,设置为未开通状态
console.log('小程序上书会员:响应为空,设置为未开通状态');
this.userMemberStatus.xcx = {
isVip: false,
isExpired: false,
count: 0,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
}
} catch (error) {
console.error('获取小程序上书会员状态失败:', error);
// 发生异常时也设置为未开通状态
this.userMemberStatus.xcx = {
isVip: false,
isExpired: false,
count: 0,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
}
},
// 获取用户孔网翻新会员状态
async getUserKwfwMemberStatus() {
try {
const userId = uni.getStorageSync('userId');
if (!userId) {
console.log('用户未登录');
return;
}
const response = await checkKwfwMemberStatus(userId);
console.log('孔网翻新会员状态响应:', response);
if (response) {
if (response.data.code === 200 && response.data.data) {
// 用户存在,处理会员状态
const data = response.data.data;
// 判断是否过期有expirationDate但isVip为false
const isExpired = !data.isVip && data.expirationDate;
this.userMemberStatus.kwfw = {
isVip: data.isVip || false,
isExpired: isExpired,
expirationDate: data.expirationDate,
expirationDateStr: data.expirationDate ? this.formatTimestamp(data
.expirationDate) : '',
daysRemaining: data.expirationDate ? this.calculateDaysRemaining(data
.expirationDate) : 0
};
} else if (response.data.code === 40001) {
// 用户未找到,设置为未开通状态
console.log('孔网翻新会员:用户未找到,设置为未开通状态');
this.userMemberStatus.kwfw = {
isVip: false,
isExpired: false,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
} else {
// 其他错误情况,也设置为未开通状态
console.log('孔网翻新会员:其他错误,设置为未开通状态', response);
this.userMemberStatus.kwfw = {
isVip: false,
isExpired: false,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
}
}
} catch (error) {
console.error('获取孔网翻新会员状态失败:', error);
// 发生异常时也设置为未开通状态
this.userMemberStatus.kwfw = {
isVip: false,
isExpired: false,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
}
},
// 获取所有用户会员状态
async loadUserMemberStatus() {
await Promise.all([
this.getUserXcxMemberStatus(),
this.getUserKwfwMemberStatus()
]);
},
// 根据会员卡片类型获取对应的用户会员状态
// 获取当前Tab的会员状态
getCurrentTabMemberStatus() {
const currentTabType = this.getCurrentTabType();
if (currentTabType === 'xcx' && this.userMemberStatus.xcx) {
return this.userMemberStatus.xcx;
} else if (currentTabType === 'kwfw' && this.userMemberStatus.kwfw) {
return this.userMemberStatus.kwfw;
}
return {
isVip: false,
isExpired: false,
count: 0,
expirationDate: null,
expirationDateStr: '',
daysRemaining: 0
};
},
// 获取当前Tab的类型
getCurrentTabType() {
if (this.showTabs && this.tabs && this.tabs[this.activeTabIndex] && this.tabs[this.activeTabIndex].type) {
return this.tabs[this.activeTabIndex].type;
}
return '';
},
// 获取当前Tab的名称
getCurrentTabName() {
if (this.showTabs && this.tabs && this.tabs[this.activeTabIndex] && this.tabs[this.activeTabIndex].name) {
return this.tabs[this.activeTabIndex].name;
}
return '会员';
}
}
};
</script>
<style lang="scss" scoped>
.member-select-container {
min-height: 100vh;
background-color: #f8f9fc;
padding: 30rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.page-header {
margin-bottom: 40rpx;
text-align: center;
}
.header-title {
font-size: 40rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.header-subtitle {
font-size: 28rpx;
color: #666;
}
/* 会员状态统一显示区域样式 */
.member-status-overview {
margin-bottom: 30rpx;
}
.status-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.15);
}
.status-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.status-type {
font-size: 32rpx;
font-weight: bold;
color: #fff;
}
.status-badge.vip {
background-color: #FFD700;
color: #333;
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
font-weight: bold;
}
.status-badge.expired {
background-color: rgba(255, 255, 255, 0.2);
color: #FF6B6B;
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
font-weight: bold;
border: 1rpx solid #FF6B6B;
}
.status-card-content {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 12rpx;
padding: 20rpx;
}
.status-detail {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
}
.status-detail:last-child {
margin-bottom: 0;
}
.detail-label {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
.detail-label.expired {
color: #FF6B6B;
font-weight: bold;
}
.detail-value {
font-size: 26rpx;
color: #fff;
font-weight: 500;
}
.detail-value.remaining-days {
color: #FFD700;
font-weight: bold;
}
.no-member-tip {
background-color: #fff;
border-radius: 16rpx;
padding: 40rpx 30rpx;
text-align: center;
border: 2rpx dashed #ddd;
}
.tip-text {
font-size: 28rpx;
color: #999;
line-height: 1.5;
}
.tab-container {
margin-bottom: 30rpx;
}
.tab-list {
display: flex;
background-color: #f5f5f5;
border-radius: 12rpx;
padding: 6rpx;
}
.tab-item {
flex: 1;
text-align: center;
padding: 20rpx 0;
font-size: 28rpx;
color: #666;
border-radius: 8rpx;
transition: all 0.3s ease;
}
.tab-item.active {
background-color: #fff;
color: #4A5CFF;
font-weight: bold;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.member-cards {
display: flex;
flex-direction: column;
gap: 30rpx;
margin-bottom: 40rpx;
flex: 1;
}
.member-card {
background-color: #fff;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
position: relative;
transition: all 0.3s ease;
}
.member-card.selected {
transform: scale(1.02);
box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
}
.card-header {
padding: 30rpx;
color: #fff;
position: relative;
overflow: hidden;
}
.card-header::after {
content: '';
position: absolute;
right: -40rpx;
top: -40rpx;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.1);
}
.card-title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.card-price {
font-size: 48rpx;
font-weight: bold;
}
.card-content {
padding: 30rpx;
}
.benefit-item {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.benefit-item:last-child {
margin-bottom: 0;
}
.benefit-icon {
width: 40rpx;
height: 40rpx;
background-color: #f0f5ff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #4A5CFF;
margin-right: 20rpx;
font-size: 24rpx;
}
.benefit-text {
font-size: 28rpx;
color: #666;
}
.select-mark {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.select-icon {
color: #4A5CFF;
font-size: 24rpx;
font-weight: bold;
}
.bottom-bar {
position: sticky;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 -4rpx 10rpx rgba(0, 0, 0, 0.05);
border-radius: 16rpx;
margin-top: 20rpx;
}
.selected-info {
display: flex;
flex-direction: column;
}
.selected-name {
font-size: 28rpx;
color: #666;
}
.selected-price {
font-size: 40rpx;
font-weight: bold;
color: #FF4757;
}
.pay-button {
background: linear-gradient(to right, #4A5CFF, #6979FF);
color: #fff;
padding: 20rpx 60rpx;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
box-shadow: 0 10rpx 20rpx rgba(74, 92, 255, 0.3);
}
.pay-button.disabled {
background: linear-gradient(to right, #ccc, #ddd);
box-shadow: none;
opacity: 0.8;
}
</style>