peixue-dev/peidu/uniapp/user-package/pages/user/friends.vue

483 lines
11 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="friends-page">
<!-- 页面头部 -->
<view class="page-header">
<text class="header-title">我的友邦</text>
<text class="header-desc">邀请好友共享优惠</text>
</view>
<!-- 功能入口 -->
<view class="function-grid">
<!-- 拼团 -->
<view class="function-item" @click="goGroupBuy">
<view class="item-icon group-icon">🎁</view>
<view class="item-info">
<text class="item-title">拼团活动</text>
<text class="item-desc">邀请好友下单享受优惠</text>
</view>
<view class="item-badge" v-if="groupCount > 0">{{ groupCount }}</view>
<text class="item-arrow"></text>
</view>
<!-- 分销 -->
<view class="function-item" @click="goDistribution">
<view class="item-icon dist-icon">💰</view>
<view class="item-info">
<text class="item-title">分销推广</text>
<text class="item-desc">推广课程,赚取佣金</text>
</view>
<view class="item-tag" v-if="isDistributor">已认证</view>
<text class="item-arrow"></text>
</view>
<!-- 加盟 -->
<view class="function-item" @click="goFranchise">
<view class="item-icon franchise-icon">🏢</view>
<view class="item-info">
<text class="item-title">加盟合作</text>
<text class="item-desc">成为合作伙伴,共创未来</text>
</view>
<text class="item-arrow"></text>
</view>
<!-- 专业服务商 -->
<view class="function-item" @click="goServiceProvider">
<view class="item-icon provider-icon">🎓</view>
<view class="item-info">
<text class="item-title">专业服务商</text>
<text class="item-desc">提供专业教育服务</text>
</view>
<view class="item-tag" v-if="isProvider">已入驻</view>
<text class="item-arrow"></text>
</view>
</view>
<!-- 我的邀请统计 -->
<view class="stats-section">
<view class="section-title">邀请统计</view>
<view class="stats-grid">
<view class="stat-item">
<text class="stat-value">{{ inviteStats.totalInvite }}</text>
<text class="stat-label">邀请人数</text>
</view>
<view class="stat-item">
<text class="stat-value">{{ inviteStats.successInvite }}</text>
<text class="stat-label">成功下单</text>
</view>
<view class="stat-item">
<text class="stat-value">¥{{ inviteStats.totalReward }}</text>
<text class="stat-label">累计奖励</text>
</view>
</view>
</view>
<!-- 邀请好友 -->
<view class="invite-section">
<view class="section-title">邀请好友</view>
<view class="invite-card">
<view class="invite-qrcode">
<image :src="qrcodeUrl" mode="aspectFit" class="qrcode-img" v-if="qrcodeUrl"></image>
<view class="qrcode-placeholder" v-else>
<text>生成中...</text>
</view>
</view>
<view class="invite-info">
<text class="invite-code">邀请码:{{ inviteCode }}</text>
<view class="invite-btns">
<button class="btn-copy" @click="copyInviteCode">复制邀请码</button>
<button class="btn-share" open-type="share">分享给好友</button>
</view>
</view>
</view>
</view>
<!-- 邀请记录 -->
<view class="record-section">
<view class="section-header">
<text class="section-title">邀请记录</text>
<text class="section-more" @click="goInviteRecords">查看全部 </text>
</view>
<view class="record-list" v-if="inviteRecords.length > 0">
<view class="record-item" v-for="(item, index) in inviteRecords" :key="index">
<view class="record-avatar">{{ item.nickname.substring(0, 1) }}</view>
<view class="record-info">
<text class="record-name">{{ item.nickname }}</text>
<text class="record-time">{{ item.createTime }}</text>
</view>
<view class="record-status" :class="item.status === 1 ? 'success' : 'pending'">
{{ item.status === 1 ? '已下单' : '待下单' }}
</view>
</view>
</view>
<view class="empty-tip" v-else>
<text>暂无邀请记录快去邀请好友吧~</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isDistributor: false,
isProvider: false,
groupCount: 0,
inviteCode: '',
qrcodeUrl: '',
inviteStats: {
totalInvite: 0,
successInvite: 0,
totalReward: 0
},
inviteRecords: []
}
},
onLoad() {
this.loadData()
},
onShareAppMessage() {
return {
title: '习正陪伴 - 专业的教育陪伴服务',
path: `/pages/index/index?inviteCode=${this.inviteCode}`,
imageUrl: '/static/share-cover.png'
}
},
methods: {
async loadData() {
// 模拟数据
this.inviteCode = 'XZ' + Date.now().toString().slice(-6)
this.inviteStats = {
totalInvite: 12,
successInvite: 5,
totalReward: 150
}
this.inviteRecords = [
{ nickname: '张妈妈', createTime: '2026-01-03 14:30', status: 1 },
{ nickname: '李爸爸', createTime: '2026-01-02 10:20', status: 0 }
]
},
goGroupBuy() {
uni.navigateTo({ url: '/activity-package/pages/group-buy/index' })
},
goDistribution() {
if (this.isDistributor) {
uni.navigateTo({ url: '/distributor-package/pages/distributor/index' })
} else {
uni.navigateTo({ url: '/distributor-package/pages/distributor/apply' })
}
},
goFranchise() {
uni.navigateTo({ url: '/training-package/pages/franchise/index' })
},
goServiceProvider() {
if (this.isProvider) {
uni.navigateTo({ url: '/provider-package/pages/provider/index' })
} else {
uni.navigateTo({ url: '/provider-package/pages/service-provider/apply' })
}
},
copyInviteCode() {
uni.setClipboardData({
data: this.inviteCode,
success: () => {
uni.showToast({ title: '邀请码已复制', icon: 'success' })
}
})
},
goInviteRecords() {
uni.showToast({ title: '功能开发中', icon: 'none' })
}
}
}
</script>
<style lang="scss" scoped>
.friends-page {
min-height: 100vh;
background: #f5f5f5;
padding-bottom: 40rpx;
}
.page-header {
background: linear-gradient(135deg, #5fc9ba 0%, #7dd9ca 100%);
padding: 60rpx 30rpx 40rpx;
.header-title {
display: block;
font-size: 40rpx;
font-weight: bold;
color: #fff;
margin-bottom: 10rpx;
}
.header-desc {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
}
.function-grid {
background: #fff;
margin: -20rpx 20rpx 20rpx;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
.function-item {
display: flex;
align-items: center;
padding: 24rpx 16rpx;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.item-icon {
width: 80rpx;
height: 80rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
margin-right: 20rpx;
}
.group-icon { background: #fff3e0; }
.dist-icon { background: #e8f5e9; }
.franchise-icon { background: #e3f2fd; }
.provider-icon { background: #fce4ec; }
.item-info {
flex: 1;
.item-title {
display: block;
font-size: 30rpx;
font-weight: 500;
color: #333;
margin-bottom: 6rpx;
}
.item-desc {
font-size: 24rpx;
color: #999;
}
}
.item-badge {
background: #ff4d4f;
color: #fff;
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 20rpx;
margin-right: 10rpx;
}
.item-tag {
background: #e8f5e9;
color: #4caf50;
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 6rpx;
margin-right: 10rpx;
}
.item-arrow {
font-size: 32rpx;
color: #ccc;
}
}
.stats-section, .invite-section, .record-section {
background: #fff;
margin: 0 20rpx 20rpx;
border-radius: 16rpx;
padding: 24rpx;
}
.section-title {
font-size: 30rpx;
font-weight: 500;
color: #333;
margin-bottom: 20rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.section-more {
font-size: 26rpx;
color: #5fc9ba;
}
}
.stats-grid {
display: flex;
.stat-item {
flex: 1;
text-align: center;
.stat-value {
display: block;
font-size: 40rpx;
font-weight: bold;
color: #5fc9ba;
margin-bottom: 8rpx;
}
.stat-label {
font-size: 24rpx;
color: #999;
}
}
}
.invite-card {
display: flex;
align-items: center;
background: #f9f9f9;
border-radius: 12rpx;
padding: 24rpx;
.invite-qrcode {
width: 160rpx;
height: 160rpx;
background: #fff;
border-radius: 8rpx;
margin-right: 24rpx;
display: flex;
align-items: center;
justify-content: center;
.qrcode-img {
width: 140rpx;
height: 140rpx;
}
.qrcode-placeholder {
font-size: 24rpx;
color: #999;
}
}
.invite-info {
flex: 1;
.invite-code {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
}
.invite-btns {
display: flex;
gap: 16rpx;
button {
flex: 1;
height: 60rpx;
line-height: 60rpx;
font-size: 24rpx;
border-radius: 30rpx;
padding: 0;
margin: 0;
}
.btn-copy {
background: #fff;
color: #5fc9ba;
border: 1rpx solid #5fc9ba;
}
.btn-share {
background: #5fc9ba;
color: #fff;
}
}
}
}
.record-list {
.record-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.record-avatar {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: #5fc9ba;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
margin-right: 20rpx;
}
.record-info {
flex: 1;
.record-name {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 6rpx;
}
.record-time {
font-size: 24rpx;
color: #999;
}
}
.record-status {
font-size: 24rpx;
padding: 6rpx 16rpx;
border-radius: 20rpx;
&.success {
background: #e8f5e9;
color: #4caf50;
}
&.pending {
background: #fff3e0;
color: #ff9800;
}
}
}
}
.empty-tip {
text-align: center;
padding: 40rpx;
color: #999;
font-size: 26rpx;
}
</style>