feat :init

This commit is contained in:
2025-11-02 19:34:16 +08:00
commit b767041311
617 changed files with 124099 additions and 0 deletions

View File

@@ -0,0 +1,481 @@
// pages/index/index.js
const app = getApp();
const { memberAPI } = require('../../utils/api');
const {
formatRelativeTime,
getMemberLevelText,
calculateMemberExpire,
showError,
showSuccess,
debounce
} = require('../../utils/util');
Page({
/**
* 页面的初始数据
*/
data: {
// 用户信息
userInfo: {},
isLoggedIn: false,
// 会员信息
memberInfo: {},
// 快捷权益
quickBenefits: [],
// 功能菜单
menuItems: [
{
id: 'member-center',
name: '会员中心',
icon: '/images/menu/member.png',
path: '/pages/member/center/center'
},
{
id: 'member-bind',
name: '绑定会员',
icon: '/images/menu/bind.png',
path: '/pages/member/bind/bind'
},
{
id: 'benefits',
name: '权益说明',
icon: '/images/menu/benefits.png',
path: '/pages/member/benefits/benefits'
},
{
id: 'upgrade',
name: '升级会员',
icon: '/images/menu/upgrade.png',
path: '/pages/member/upgrade/upgrade'
},
{
id: 'history',
name: '使用记录',
icon: '/images/menu/history.png',
path: '/pages/member/history/history'
},
{
id: 'invite',
name: '邀请好友',
icon: '/images/menu/invite.png',
path: '/pages/member/invite/invite'
},
{
id: 'support',
name: '客服支持',
icon: '/images/menu/support.png',
path: '/pages/support/support'
},
{
id: 'settings',
name: '设置',
icon: '/images/menu/settings.png',
path: '/pages/settings/settings'
}
],
// 最近活动
recentActivities: [],
// 升级提示
showUpgradePrompt: false,
// 权益弹窗
showBenefitModal: false,
selectedBenefit: {},
// 加载状态
loading: false,
refreshing: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.initPage();
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
this.refreshUserInfo();
this.refreshMemberInfo();
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.refreshPage();
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
// 可以在这里加载更多数据
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
return {
title: '小智AI会员 - 享受专属特权',
path: '/pages/index/index',
imageUrl: '/images/share-cover.png'
};
},
/**
* 初始化页面
*/
initPage() {
this.setData({ loading: true });
// 检查登录状态
this.checkLoginStatus();
// 初始化菜单徽章
this.updateMenuBadges();
this.setData({ loading: false });
},
/**
* 检查登录状态
*/
checkLoginStatus() {
const isLoggedIn = app.checkLoginStatus();
const userInfo = app.globalData.userInfo || {};
this.setData({
isLoggedIn,
userInfo
});
},
/**
* 刷新页面数据
*/
refreshPage: debounce(function() {
this.setData({ refreshing: true });
Promise.all([
this.refreshUserInfo(),
this.refreshMemberInfo(),
this.loadRecentActivities()
]).finally(() => {
this.setData({ refreshing: false });
wx.stopPullDownRefresh();
});
}, 1000),
/**
* 刷新用户信息
*/
async refreshUserInfo() {
if (!this.data.isLoggedIn) return;
try {
const result = await memberAPI.getUserInfo();
if (result.code === 0) {
const userInfo = result.data;
app.globalData.userInfo = userInfo;
this.setData({ userInfo });
}
} catch (error) {
console.error('获取用户信息失败:', error);
}
},
/**
* 刷新会员信息
*/
async refreshMemberInfo() {
if (!this.data.isLoggedIn) return;
try {
const result = await memberAPI.getMemberInfo();
if (result.code === 0) {
const memberData = result.data;
const memberInfo = this.processMemberInfo(memberData);
app.globalData.memberInfo = memberInfo;
this.setData({ memberInfo });
// 加载会员权益
this.loadMemberBenefits();
// 检查是否显示升级提示
this.checkUpgradePrompt(memberInfo);
}
} catch (error) {
console.error('获取会员信息失败:', error);
}
},
/**
* 处理会员信息
*/
processMemberInfo(memberData) {
const { level, expireTime } = memberData;
const levelText = getMemberLevelText(level);
const expireInfo = calculateMemberExpire(expireTime);
return {
...memberData,
levelText,
expireInfo
};
},
/**
* 加载会员权益
*/
async loadMemberBenefits() {
try {
const result = await memberAPI.getMemberBenefits();
if (result.code === 0) {
const benefits = result.data || [];
// 只显示前4个权益作为快捷入口
const quickBenefits = benefits.slice(0, 4).map(benefit => ({
...benefit,
icon: benefit.icon || '/images/benefits/default.png'
}));
this.setData({ quickBenefits });
}
} catch (error) {
console.error('获取会员权益失败:', error);
}
},
/**
* 加载最近活动
*/
async loadRecentActivities() {
if (!this.data.isLoggedIn) return;
try {
const result = await memberAPI.getBenefitUsage(1, 5);
if (result.code === 0) {
const activities = (result.data.list || []).map(activity => ({
...activity,
timeText: formatRelativeTime(activity.createTime),
statusClass: this.getActivityStatusClass(activity.status),
statusText: this.getActivityStatusText(activity.status),
icon: activity.icon || '/images/activity/default.png'
}));
this.setData({ recentActivities: activities });
}
} catch (error) {
console.error('获取最近活动失败:', error);
}
},
/**
* 获取活动状态样式类
*/
getActivityStatusClass(status) {
const classMap = {
'success': 'text-success',
'failed': 'text-danger',
'pending': 'text-warning'
};
return classMap[status] || 'text-muted';
},
/**
* 获取活动状态文本
*/
getActivityStatusText(status) {
const textMap = {
'success': '成功',
'failed': '失败',
'pending': '处理中'
};
return textMap[status] || '未知';
},
/**
* 检查升级提示
*/
checkUpgradePrompt(memberInfo) {
const { level, expireInfo } = memberInfo;
// 普通用户或会员即将过期时显示升级提示
const showPrompt = level === 'free' ||
(expireInfo && !expireInfo.isExpired && expireInfo.daysLeft <= 7);
this.setData({ showUpgradePrompt: showPrompt });
},
/**
* 更新菜单徽章
*/
updateMenuBadges() {
const menuItems = this.data.menuItems.map(item => {
// 这里可以根据实际需求添加徽章逻辑
if (item.id === 'member-bind' && !this.data.isLoggedIn) {
item.badge = 'NEW';
}
return item;
});
this.setData({ menuItems });
},
/**
* 处理登录
*/
handleLogin() {
wx.navigateTo({
url: '/pages/login/login'
});
},
/**
* 处理菜单点击
*/
handleMenuClick(e) {
const { menu } = e.currentTarget.dataset;
// 检查是否需要登录
if (!this.data.isLoggedIn && this.needLogin(menu.id)) {
this.handleLogin();
return;
}
// 特殊处理
switch (menu.id) {
case 'support':
this.handleCustomerService();
break;
default:
wx.navigateTo({
url: menu.path
});
}
},
/**
* 检查功能是否需要登录
*/
needLogin(menuId) {
const loginRequiredMenus = [
'member-center', 'member-bind', 'upgrade',
'history', 'invite'
];
return loginRequiredMenus.includes(menuId);
},
/**
* 处理客服
*/
handleCustomerService() {
wx.makePhoneCall({
phoneNumber: '400-123-4567',
fail: () => {
showError('拨打客服电话失败');
}
});
},
/**
* 处理权益点击
*/
handleBenefitClick(e) {
const { benefit } = e.currentTarget.dataset;
this.setData({
selectedBenefit: benefit,
showBenefitModal: true
});
},
/**
* 关闭权益弹窗
*/
closeBenefitModal() {
this.setData({
showBenefitModal: false,
selectedBenefit: {}
});
},
/**
* 阻止事件冒泡
*/
stopPropagation() {
// 阻止事件冒泡
},
/**
* 使用权益
*/
async useBenefit() {
const { selectedBenefit } = this.data;
try {
const result = await memberAPI.verifyBenefit(selectedBenefit.type);
if (result.code === 0) {
showSuccess('权益使用成功');
this.closeBenefitModal();
this.loadMemberBenefits(); // 刷新权益信息
} else {
showError(result.message || '权益使用失败');
}
} catch (error) {
console.error('使用权益失败:', error);
showError('权益使用失败');
}
},
/**
* 导航到会员中心
*/
navigateToCenter() {
if (!this.data.isLoggedIn) {
this.handleLogin();
return;
}
wx.switchTab({
url: '/pages/member/center/center'
});
},
/**
* 导航到升级页面
*/
navigateToUpgrade() {
if (!this.data.isLoggedIn) {
this.handleLogin();
return;
}
wx.navigateTo({
url: '/pages/member/upgrade/upgrade'
});
},
/**
* 导航到历史记录
*/
navigateToHistory() {
if (!this.data.isLoggedIn) {
this.handleLogin();
return;
}
wx.navigateTo({
url: '/pages/member/history/history'
});
}
});

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "小智AI会员",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50,
"backgroundTextStyle": "dark"
}

View File

@@ -0,0 +1,152 @@
<!--pages/index/index.wxml-->
<view class="container">
<!-- 顶部用户信息卡片 -->
<view class="user-card card">
<view class="user-info flex align-center">
<image class="avatar" src="{{userInfo.avatarUrl || '/images/default-avatar.png'}}" mode="aspectFill"></image>
<view class="user-details flex-1 ml-3">
<view class="username text-lg font-bold">{{userInfo.nickName || '未登录'}}</view>
<view class="member-status flex align-center mt-1">
<view class="member-badge {{memberInfo.level || 'free'}}">
{{memberInfo.levelText || '普通用户'}}
</view>
<view class="expire-info text-sm text-muted ml-2" wx:if="{{memberInfo.expireInfo}}">
{{memberInfo.expireInfo.text}}
</view>
</view>
</view>
<view class="login-btn" wx:if="{{!isLoggedIn}}" bindtap="handleLogin">
<text class="btn btn-primary btn-small">登录</text>
</view>
</view>
</view>
<!-- 会员权益快捷入口 -->
<view class="benefits-card card" wx:if="{{isLoggedIn}}">
<view class="card-header">
<view class="flex align-center justify-between">
<text class="text-lg font-bold">会员权益</text>
<text class="text-primary text-sm" bindtap="navigateToCenter">查看全部</text>
</view>
</view>
<view class="card-body">
<view class="benefits-grid">
<view class="benefit-item" wx:for="{{quickBenefits}}" wx:key="id" bindtap="handleBenefitClick" data-benefit="{{item}}">
<view class="benefit-icon">
<image src="{{item.icon}}" mode="aspectFit"></image>
</view>
<view class="benefit-name text-sm">{{item.name}}</view>
<view class="benefit-status text-xs" wx:if="{{item.available}}">
<text class="text-success">可用</text>
</view>
<view class="benefit-status text-xs" wx:else>
<text class="text-muted">不可用</text>
</view>
</view>
</view>
</view>
</view>
<!-- 功能菜单 -->
<view class="menu-card card">
<view class="card-header">
<text class="text-lg font-bold">功能菜单</text>
</view>
<view class="card-body">
<view class="menu-grid">
<view class="menu-item" wx:for="{{menuItems}}" wx:key="id" bindtap="handleMenuClick" data-menu="{{item}}">
<view class="menu-icon">
<image src="{{item.icon}}" mode="aspectFit"></image>
</view>
<view class="menu-name text-sm">{{item.name}}</view>
<view class="menu-badge" wx:if="{{item.badge}}">
<text class="text-xs">{{item.badge}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 会员升级提示 -->
<view class="upgrade-card card" wx:if="{{showUpgradePrompt}}">
<view class="upgrade-content">
<view class="upgrade-icon">
<image src="/images/upgrade-icon.png" mode="aspectFit"></image>
</view>
<view class="upgrade-text">
<view class="upgrade-title text-lg font-bold">升级会员,享受更多特权</view>
<view class="upgrade-desc text-sm text-muted mt-1">
解锁专属功能,提升使用体验
</view>
</view>
<view class="upgrade-action">
<text class="btn btn-primary btn-small" bindtap="navigateToUpgrade">立即升级</text>
</view>
</view>
</view>
<!-- 最近活动 -->
<view class="activity-card card" wx:if="{{recentActivities.length > 0}}">
<view class="card-header">
<view class="flex align-center justify-between">
<text class="text-lg font-bold">最近活动</text>
<text class="text-primary text-sm" bindtap="navigateToHistory">查看更多</text>
</view>
</view>
<view class="card-body">
<view class="activity-list">
<view class="activity-item" wx:for="{{recentActivities}}" wx:key="id">
<view class="activity-icon">
<image src="{{item.icon}}" mode="aspectFit"></image>
</view>
<view class="activity-content flex-1">
<view class="activity-title text-sm">{{item.title}}</view>
<view class="activity-time text-xs text-muted">{{item.timeText}}</view>
</view>
<view class="activity-status">
<text class="text-xs {{item.statusClass}}">{{item.statusText}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 空状态提示 -->
<view class="empty-state" wx:if="{{!isLoggedIn}}">
<image class="empty-icon" src="/images/empty-login.png" mode="aspectFit"></image>
<view class="empty-text">登录后查看更多功能</view>
<view class="empty-desc">享受专属会员权益和服务</view>
<text class="btn btn-primary mt-3" bindtap="handleLogin">立即登录</text>
</view>
</view>
<!-- 权益详情弹窗 -->
<view class="benefit-modal" wx:if="{{showBenefitModal}}" bindtap="closeBenefitModal">
<view class="modal-content" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">{{selectedBenefit.name}}</text>
<view class="modal-close" bindtap="closeBenefitModal">
<image src="/images/close-icon.png" mode="aspectFit"></image>
</view>
</view>
<view class="modal-body">
<view class="benefit-detail">
<image class="benefit-large-icon" src="{{selectedBenefit.icon}}" mode="aspectFit"></image>
<view class="benefit-description">{{selectedBenefit.description}}</view>
<view class="benefit-usage" wx:if="{{selectedBenefit.usage}}">
<text class="text-sm text-muted">使用次数:{{selectedBenefit.usage.used}}/{{selectedBenefit.usage.total}}</text>
</view>
</view>
</view>
<view class="modal-footer">
<text class="btn btn-secondary" bindtap="closeBenefitModal">关闭</text>
<text class="btn btn-primary ml-2" wx:if="{{selectedBenefit.available}}" bindtap="useBenefit">立即使用</text>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="loading" wx:if="{{loading}}">
<view class="loading-spinner"></view>
<text>加载中...</text>
</view>

View File

@@ -0,0 +1,428 @@
/* pages/index/index.wxss */
.container {
padding: 20rpx;
background: #F8F9FA;
min-height: 100vh;
}
/* 用户信息卡片 */
.user-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #FFFFFF;
margin-bottom: 30rpx;
}
.user-info {
padding: 40rpx 30rpx;
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 4rpx solid rgba(255, 255, 255, 0.3);
}
.user-details {
margin-left: 30rpx;
}
.username {
color: #FFFFFF;
margin-bottom: 10rpx;
}
.member-status {
align-items: center;
}
.member-badge {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 20rpx;
font-weight: bold;
text-transform: uppercase;
}
.member-badge.free {
background: rgba(255, 255, 255, 0.2);
color: #FFFFFF;
}
.member-badge.vip {
background: linear-gradient(135deg, #FFD700, #FFA500);
color: #FFFFFF;
}
.member-badge.svip {
background: linear-gradient(135deg, #FF6B35, #F7931E);
color: #FFFFFF;
}
.expire-info {
color: rgba(255, 255, 255, 0.8);
}
.login-btn {
margin-left: 20rpx;
}
/* 会员权益卡片 */
.benefits-card {
margin-bottom: 30rpx;
}
.benefits-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30rpx;
}
.benefit-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 20rpx 10rpx;
border-radius: 12rpx;
background: #F8F9FA;
transition: all 0.3s ease;
}
.benefit-item:active {
background: #E9ECEF;
transform: scale(0.95);
}
.benefit-icon {
width: 60rpx;
height: 60rpx;
margin-bottom: 12rpx;
}
.benefit-icon image {
width: 100%;
height: 100%;
}
.benefit-name {
margin-bottom: 8rpx;
color: #333333;
}
.benefit-status {
margin-top: 4rpx;
}
/* 功能菜单卡片 */
.menu-card {
margin-bottom: 30rpx;
}
.menu-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30rpx;
}
.menu-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 30rpx 20rpx;
border-radius: 12rpx;
background: #FFFFFF;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
position: relative;
}
.menu-item:active {
background: #F8F9FA;
transform: scale(0.95);
}
.menu-icon {
width: 80rpx;
height: 80rpx;
margin-bottom: 16rpx;
}
.menu-icon image {
width: 100%;
height: 100%;
}
.menu-name {
color: #333333;
}
.menu-badge {
position: absolute;
top: 20rpx;
right: 20rpx;
background: #FF4757;
color: #FFFFFF;
padding: 4rpx 8rpx;
border-radius: 10rpx;
min-width: 32rpx;
text-align: center;
}
/* 升级提示卡片 */
.upgrade-card {
margin-bottom: 30rpx;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: #FFFFFF;
}
.upgrade-content {
display: flex;
align-items: center;
padding: 30rpx;
}
.upgrade-icon {
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
}
.upgrade-icon image {
width: 100%;
height: 100%;
}
.upgrade-text {
flex: 1;
}
.upgrade-title {
color: #FFFFFF;
margin-bottom: 8rpx;
}
.upgrade-desc {
color: rgba(255, 255, 255, 0.8);
}
.upgrade-action {
margin-left: 20rpx;
}
/* 最近活动卡片 */
.activity-card {
margin-bottom: 30rpx;
}
.activity-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.activity-item {
display: flex;
align-items: center;
padding: 20rpx;
background: #F8F9FA;
border-radius: 12rpx;
}
.activity-icon {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
}
.activity-icon image {
width: 100%;
height: 100%;
}
.activity-content {
flex: 1;
}
.activity-title {
color: #333333;
margin-bottom: 8rpx;
}
.activity-time {
color: #6C757D;
}
.activity-status {
margin-left: 20rpx;
}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 40rpx;
text-align: center;
}
.empty-icon {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
opacity: 0.5;
}
.empty-text {
font-size: 32rpx;
color: #333333;
margin-bottom: 16rpx;
}
.empty-desc {
font-size: 28rpx;
color: #6C757D;
margin-bottom: 40rpx;
}
/* 权益详情弹窗 */
.benefit-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-content {
background: #FFFFFF;
border-radius: 20rpx;
margin: 40rpx;
max-width: 600rpx;
width: 100%;
max-height: 80vh;
overflow: hidden;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #E9ECEF;
}
.modal-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.modal-close {
width: 40rpx;
height: 40rpx;
padding: 8rpx;
}
.modal-close image {
width: 100%;
height: 100%;
}
.modal-body {
padding: 30rpx;
max-height: 400rpx;
overflow-y: auto;
}
.benefit-detail {
text-align: center;
}
.benefit-large-icon {
width: 120rpx;
height: 120rpx;
margin-bottom: 20rpx;
}
.benefit-description {
font-size: 28rpx;
color: #333333;
line-height: 1.6;
margin-bottom: 20rpx;
}
.benefit-usage {
padding: 16rpx 20rpx;
background: #F8F9FA;
border-radius: 8rpx;
}
.modal-footer {
display: flex;
justify-content: flex-end;
padding: 20rpx 30rpx;
border-top: 1rpx solid #E9ECEF;
}
/* 加载状态 */
.loading {
display: flex;
align-items: center;
justify-content: center;
padding: 80rpx 40rpx;
color: #6C757D;
}
.loading-spinner {
width: 40rpx;
height: 40rpx;
border: 4rpx solid #F3F3F3;
border-top: 4rpx solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-right: 20rpx;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 响应式适配 */
@media (max-width: 400px) {
.benefits-grid,
.menu-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 320px) {
.benefits-grid,
.menu-grid {
grid-template-columns: repeat(2, 1fr);
}
.user-info {
flex-direction: column;
text-align: center;
}
.user-details {
margin-left: 0;
margin-top: 20rpx;
}
.login-btn {
margin-left: 0;
margin-top: 20rpx;
}
}

View File

@@ -0,0 +1,271 @@
<!--pages/member/bind/bind.wxml-->
<view class="container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-content">
<image class="header-icon" src="/images/bind/member-icon.png" mode="aspectFit"></image>
<view class="header-text">
<view class="header-title">会员绑定</view>
<view class="header-desc">绑定会员账号,享受专属权益</view>
</view>
</view>
</view>
<!-- 当前状态卡片 -->
<view class="status-card card">
<view class="status-content">
<view class="status-icon">
<image src="{{statusInfo.icon}}" mode="aspectFit"></image>
</view>
<view class="status-text">
<view class="status-title">{{statusInfo.title}}</view>
<view class="status-desc">{{statusInfo.desc}}</view>
</view>
<view class="status-badge {{statusInfo.badgeClass}}" wx:if="{{statusInfo.badge}}">
{{statusInfo.badge}}
</view>
</view>
</view>
<!-- 绑定表单 -->
<view class="bind-form card" wx:if="{{!memberInfo.isBound}}">
<view class="card-header">
<text class="text-lg font-bold">绑定会员账号</text>
</view>
<view class="card-body">
<form bindsubmit="handleSubmit">
<!-- 手机号输入 -->
<view class="form-group">
<view class="form-label">手机号码</view>
<view class="input-group">
<input
class="form-input"
type="number"
placeholder="请输入手机号码"
value="{{formData.phone}}"
bindinput="onPhoneInput"
maxlength="11"
/>
<view class="input-suffix" wx:if="{{formData.phone && isValidPhone}}">
<image src="/images/icons/check-green.png" mode="aspectFit"></image>
</view>
</view>
<view class="form-error" wx:if="{{errors.phone}}">{{errors.phone}}</view>
</view>
<!-- 验证码输入 -->
<view class="form-group">
<view class="form-label">验证码</view>
<view class="input-group">
<input
class="form-input flex-1"
type="number"
placeholder="请输入验证码"
value="{{formData.verifyCode}}"
bindinput="onVerifyCodeInput"
maxlength="6"
/>
<button
class="verify-btn {{canSendCode ? 'active' : 'disabled'}}"
bindtap="sendVerifyCode"
disabled="{{!canSendCode}}"
>
{{verifyCodeText}}
</button>
</view>
<view class="form-error" wx:if="{{errors.verifyCode}}">{{errors.verifyCode}}</view>
</view>
<!-- 会员卡号输入 -->
<view class="form-group">
<view class="form-label">会员卡号</view>
<view class="input-group">
<input
class="form-input"
type="text"
placeholder="请输入会员卡号"
value="{{formData.memberCard}}"
bindinput="onMemberCardInput"
/>
<view class="input-suffix" bindtap="scanMemberCard">
<image src="/images/icons/scan.png" mode="aspectFit"></image>
</view>
</view>
<view class="form-error" wx:if="{{errors.memberCard}}">{{errors.memberCard}}</view>
</view>
<!-- 密码输入 -->
<view class="form-group">
<view class="form-label">会员密码</view>
<view class="input-group">
<input
class="form-input"
type="{{showPassword ? 'text' : 'password'}}"
placeholder="请输入会员密码"
value="{{formData.password}}"
bindinput="onPasswordInput"
/>
<view class="input-suffix" bindtap="togglePassword">
<image src="/images/icons/{{showPassword ? 'eye-off' : 'eye'}}.png" mode="aspectFit"></image>
</view>
</view>
<view class="form-error" wx:if="{{errors.password}}">{{errors.password}}</view>
</view>
<!-- 协议同意 -->
<view class="agreement-group">
<label class="agreement-item">
<checkbox
value="agree"
checked="{{agreeTerms}}"
bindchange="onAgreeChange"
/>
<text class="agreement-text">
我已阅读并同意
<text class="link" bindtap="showTerms">《会员服务协议》</text>
<text class="link" bindtap="showPrivacy">《隐私政策》</text>
</text>
</label>
</view>
<!-- 提交按钮 -->
<button
class="btn btn-primary btn-block btn-large {{canSubmit ? '' : 'btn-disabled'}}"
form-type="submit"
disabled="{{!canSubmit || submitting}}"
>
{{submitting ? '绑定中...' : '立即绑定'}}
</button>
</form>
</view>
</view>
<!-- 已绑定状态 -->
<view class="bound-info card" wx:if="{{memberInfo.isBound}}">
<view class="card-header">
<text class="text-lg font-bold">会员信息</text>
</view>
<view class="card-body">
<view class="member-details">
<view class="detail-item">
<view class="detail-label">会员等级</view>
<view class="detail-value">
<view class="member-badge {{memberInfo.level}}">{{memberInfo.levelText}}</view>
</view>
</view>
<view class="detail-item">
<view class="detail-label">会员卡号</view>
<view class="detail-value">{{memberInfo.memberCard}}</view>
</view>
<view class="detail-item">
<view class="detail-label">绑定手机</view>
<view class="detail-value">{{memberInfo.phone}}</view>
</view>
<view class="detail-item">
<view class="detail-label">绑定时间</view>
<view class="detail-value">{{memberInfo.bindTimeText}}</view>
</view>
<view class="detail-item" wx:if="{{memberInfo.expireTime}}">
<view class="detail-label">到期时间</view>
<view class="detail-value {{memberInfo.expireInfo.isExpired ? 'text-danger' : 'text-success'}}">
{{memberInfo.expireInfo.text}}
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<button class="btn btn-outline btn-block" bindtap="showUnbindConfirm">
解除绑定
</button>
<button class="btn btn-primary btn-block mt-2" bindtap="navigateToCenter">
查看权益
</button>
</view>
</view>
</view>
<!-- 绑定说明 -->
<view class="help-card card">
<view class="card-header">
<text class="text-lg font-bold">绑定说明</text>
</view>
<view class="card-body">
<view class="help-list">
<view class="help-item">
<view class="help-icon">
<image src="/images/icons/info.png" mode="aspectFit"></image>
</view>
<view class="help-text">绑定后可享受会员专属权益和服务</view>
</view>
<view class="help-item">
<view class="help-icon">
<image src="/images/icons/security.png" mode="aspectFit"></image>
</view>
<view class="help-text">您的个人信息将被严格保护</view>
</view>
<view class="help-item">
<view class="help-icon">
<image src="/images/icons/support.png" mode="aspectFit"></image>
</view>
<view class="help-text">如有问题请联系客服400-123-4567</view>
</view>
</view>
</view>
</view>
</view>
<!-- 解绑确认弹窗 -->
<view class="unbind-modal" wx:if="{{showUnbindModal}}" bindtap="hideUnbindConfirm">
<view class="modal-content" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">确认解除绑定</text>
</view>
<view class="modal-body">
<view class="unbind-warning">
<image class="warning-icon" src="/images/icons/warning.png" mode="aspectFit"></image>
<view class="warning-text">
<view class="warning-title">解除绑定后将失去以下权益:</view>
<view class="warning-list">
<text>• 会员专属功能和服务</text>
<text>• 积分和优惠券</text>
<text>• 会员等级和特权</text>
</view>
</view>
</view>
</view>
<view class="modal-footer">
<button class="btn btn-secondary" bindtap="hideUnbindConfirm">取消</button>
<button class="btn btn-danger ml-2" bindtap="confirmUnbind">确认解绑</button>
</view>
</view>
</view>
<!-- 协议弹窗 -->
<view class="agreement-modal" wx:if="{{showAgreementModal}}" bindtap="hideAgreement">
<view class="modal-content" catchtap="stopPropagation">
<view class="modal-header">
<text class="modal-title">{{agreementTitle}}</text>
<view class="modal-close" bindtap="hideAgreement">
<image src="/images/icons/close.png" mode="aspectFit"></image>
</view>
</view>
<view class="modal-body">
<scroll-view class="agreement-content" scroll-y="true">
<rich-text nodes="{{agreementContent}}"></rich-text>
</scroll-view>
</view>
<view class="modal-footer">
<button class="btn btn-primary btn-block" bindtap="hideAgreement">我知道了</button>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="loading-overlay" wx:if="{{loading}}">
<view class="loading-content">
<view class="loading-spinner"></view>
<text>{{loadingText}}</text>
</view>
</view>