campus-errand/miniapp/pages/mine/mine.vue
18631081161 b359070a0e
All checks were successful
continuous-integration/drone/push Build is passing
聊天修改
2026-04-02 01:09:02 +08:00

360 lines
8.7 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="mine-page">
<!-- 顶部渐变导航栏 -->
<view class="header-bg">
<view :style="{ height: statusBarHeight + 'px' }"></view>
<view class="nav-bar">
<text class="nav-title">我的</text>
</view>
</view>
<!-- 用户信息卡片 -->
<view class="user-card" @click="onUserClick">
<image class="user-avatar" :src="userInfo.avatarUrl || '/static/logo.png'" mode="aspectFill"></image>
<view class="user-info">
<text class="user-name">{{ isLoggedIn ? (userInfo.nickname || '用户') : '点击注册/登录' }}</text>
<text class="user-uid" v-if="isLoggedIn">UID{{ userInfo.uid || userInfo.id }}</text>
</view>
<image class="arrow-icon" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<!-- 我的订单 -->
<view class="card" @click="goMyOrders">
<view class="card-header">
<text class="card-title">我的订单</text>
<image class="arrow-icon" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="card-stats">
<view class="stat-item" @click.stop="goMyOrders('InProgress')">
<text class="stat-label">进行中</text>
<text class="stat-num">{{ stats.orderOngoing }}</text>
</view>
<view class="stat-divider"></view>
<view class="stat-item" @click.stop="goMyOrders('Completed')">
<text class="stat-label">已完成</text>
<text class="stat-num">{{ stats.orderCompleted }}</text>
</view>
</view>
</view>
<!-- 我的接单 -->
<view class="card" @click="goMyTaken">
<view class="card-header">
<text class="card-title">我的接单</text>
<image class="arrow-icon" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="card-stats">
<view class="stat-item" @click.stop="goMyTaken('InProgress')">
<text class="stat-label">进行中</text>
<text class="stat-num">{{ stats.takenOngoing }}</text>
</view>
<view class="stat-divider"></view>
<view class="stat-item" @click.stop="goMyTaken('Completed')">
<text class="stat-label">已完成</text>
<text class="stat-num">{{ stats.takenCompleted }}</text>
</view>
</view>
</view>
<!-- 菜单列表 -->
<view class="menu-list">
<view class="menu-item" @click="goQrcode">
<image class="menu-icon" src="/static/ic_customer_service.png" mode="aspectFit"></image>
<text class="menu-text">联系客服</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="menu-item" @click="goCertification">
<image class="menu-icon" src="/static/ic_certification.png" mode="aspectFit"></image>
<text class="menu-text">跑腿认证</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="menu-item" @click="goEarnings">
<image class="menu-icon" src="/static/ic_revenue.png" mode="aspectFit"></image>
<text class="menu-text">我的收益</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="menu-item" @click="goAgreement">
<image class="menu-icon" src="/static/ic_agreement1.png" mode="aspectFit"></image>
<text class="menu-text">用户协议</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="menu-item" @click="goPrivacy">
<image class="menu-icon" src="/static/ic_agreement2.png" mode="aspectFit"></image>
<text class="menu-text">隐私协议</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
<view class="menu-item" @click="goRunnerAgreement">
<image class="menu-icon" src="/static/ic_agreement3.png" mode="aspectFit"></image>
<text class="menu-text">跑腿协议</text>
<image class="menu-arrow" src="/static/ic_arrow.png" mode="aspectFit"></image>
</view>
</view>
<!-- 退出登录 -->
<view v-if="isLoggedIn" class="logout-section" @click="onLogout">
<text class="logout-text">退出登录</text>
</view>
</view>
</template>
<script>
import { getMyOrders, getMyTaken } from '../../utils/api'
import { useUserStore } from '../../stores/user'
export default {
data() {
return {
userInfo: {},
isLoggedIn: false,
statusBarHeight: 0,
stats: {
orderOngoing: 0,
orderCompleted: 0,
takenOngoing: 0,
takenCompleted: 0
}
}
},
onShow() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
const userStore = useUserStore()
this.userInfo = userStore.userInfo || {}
this.isLoggedIn = userStore.isLoggedIn
if (this.isLoggedIn) {
this.loadStats()
}
},
methods: {
/** 加载订单统计 */
async loadStats() {
try {
const [ordersRes, takenRes] = await Promise.all([
getMyOrders({}),
getMyTaken({})
])
const orders = ordersRes?.items || ordersRes || []
const taken = takenRes?.items || takenRes || []
this.stats.orderOngoing = orders.filter(o => o.status === 'InProgress' || o.status === 'WaitConfirm').length
this.stats.orderCompleted = orders.filter(o => o.status === 'Completed').length
this.stats.takenOngoing = taken.filter(o => o.status === 'InProgress' || o.status === 'WaitConfirm').length
this.stats.takenCompleted = taken.filter(o => o.status === 'Completed').length
} catch (e) {
// 静默处理
}
},
/** 点击用户区域 */
onUserClick() {
if (!this.isLoggedIn) {
uni.navigateTo({ url: '/pages/login/login' })
} else {
uni.navigateTo({ url: '/pages/mine/profile' })
}
},
goMyOrders(status) {
const query = status ? `?status=${status}` : ''
uni.navigateTo({ url: '/pages/order/my-orders' + query })
},
goMyTaken(status) {
const query = status ? `?status=${status}` : ''
uni.navigateTo({ url: '/pages/order/my-taken' + query })
},
goQrcode() { uni.navigateTo({ url: '/pages/config/qrcode' }) },
goCertification() { uni.navigateTo({ url: '/pages/runner/certification' }) },
goEarnings() { uni.navigateTo({ url: '/pages/mine/earnings' }) },
goAgreement() { uni.navigateTo({ url: '/pages/config/agreement' }) },
goPrivacy() { uni.navigateTo({ url: '/pages/config/privacy' }) },
goRunnerAgreement() {
uni.navigateTo({ url: '/pages/config/runner-agreement' })
},
/** 退出登录 */
onLogout() {
uni.showModal({
title: '提示',
content: '确定退出登录?',
success: (res) => {
if (res.confirm) {
const userStore = useUserStore()
userStore.logout()
}
}
})
}
}
}
</script>
<style scoped>
.mine-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 140rpx;
}
/* 顶部渐变背景 */
.header-bg {
background: linear-gradient(90deg, #FFB700 0%, #FFD59B 100%);
}
.nav-bar {
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
}
.nav-title {
font-size: 34rpx;
color: #333;
font-weight: bold;
}
/* 用户信息卡片 */
.user-card {
display: flex;
align-items: center;
margin: 20rpx 30rpx 0;
background: #fff;
border-radius: 20rpx;
padding: 30rpx;
}
.user-avatar {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
margin-right: 24rpx;
background-color: #f0f0f0;
}
.user-info {
flex: 1;
display: flex;
flex-direction: column;
}
.user-name {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.user-uid {
font-size: 24rpx;
color: #999;
margin-top: 6rpx;
}
.arrow-icon {
width: 32rpx;
height: 32rpx;
}
/* 卡片 */
.card {
margin: 20rpx 30rpx 0;
background: #fff;
border-radius: 20rpx;
padding: 30rpx;
}
.card-header {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-bottom: 30rpx;
}
.card-title {
font-size: 32rpx;
color: #FFB700;
font-weight: bold;
}
.card-header .arrow-icon {
position: absolute;
right: 0;
}
.card-stats {
display: flex;
align-items: center;
justify-content: center;
}
.stat-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.stat-label {
font-size: 26rpx;
color: #999;
margin-bottom: 12rpx;
}
.stat-num {
font-size: 48rpx;
color: #333;
font-weight: bold;
}
.stat-divider {
width: 2rpx;
height: 60rpx;
background-color: #e0e0e0;
}
/* 菜单列表 */
.menu-list {
margin: 20rpx 30rpx 0;
background: #fff;
border-radius: 20rpx;
padding: 0 30rpx;
}
.menu-item {
display: flex;
align-items: center;
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.menu-item:last-child {
border-bottom: none;
}
.menu-icon {
width: 44rpx;
height: 44rpx;
margin-right: 24rpx;
}
.menu-text {
flex: 1;
font-size: 30rpx;
color: #333;
}
.menu-arrow {
width: 28rpx;
height: 28rpx;
}
/* 退出登录 */
.logout-section {
margin: 40rpx 30rpx 120rpx;
background: #fff;
border-radius: 20rpx;
padding: 28rpx 0;
text-align: center;
}
.logout-text {
font-size: 30rpx;
color: #e64340;
}
</style>