爱简收旧衣按件回收前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1033 lines
31 KiB

<template>
<view class="container">
<!-- 顶部banner -->
<view class="banner">
<image v-if="myBannerImage" :src="myBannerImage" mode="aspectFill" style="width: 100%; height: 100%;" />
</view>
<view class="user-cards" v-if="!login_status">
<view class="user-info">
<image class="avatars" src="/static/暂未登录 请先登录.png" mode="aspectFill"></image>
<view class="info">
<text class="names">暂未登录请先登录</text>
</view>
</view>
</view>
<view class="btns" v-if="!login_status">
<uv-button class="btn" type="primary" text="立即登录" :custom-style="customStyle"
color="linear-gradient(to right, rgb(255, 190, 61), rgb(255, 171, 2))" shape="circle"
@click="logout"></uv-button>
<text>暂未登录请先登录</text>
</view>
<!-- 用户信息卡片 -->
<view class="user-card" v-if="login_status">
<view class="user-info">
<view class="avatar-badge-box">
<image class="avatar" :src="userInfo.headImage" mode="aspectFill"></image>
<view class="avatar-badge" :class="userTypeBadgeClass">{{ userTypeText }}</view>
</view>
<view class="info">
<text class="name">{{ userInfo.nickName }}</text>
<text class="id">ID: {{ userInfo.intentioCode }}</text>
</view>
</view>
<view class="wallet-info">
<view class="balance">
<text class="label">我的余额</text>
<view class="amount">
<text class="symbol">¥</text>
<text class="value">{{ userInfo.money || '0.00' }}</text>
</view>
<view class="withdraw-btn" @tap="goWithdraw">
<text>去提现</text>
<uni-icons type="right" size="10" color="#df8155" class="arrow"></uni-icons>
</view>
</view>
<view class="recycle-count">
<text class="label">累计回收</text>
<view class="count">
<text class="value">{{ totalOrders }}</text>
<text class="unit"></text>
</view>
</view>
</view>
</view>
<!-- 分享赚佣金模块 -->
<view class="share-commission-card" @tap="onShareCommission" v-if="login_status">
<text class="share-commission-text">分享赚佣金</text>
</view>
<!-- <view class="share-commission-card" @tap="onShareCommission" v-if="login_status && userInfo.isUser === 'N'">
<text class="share-commission-text">申请成为推广官</text>
</view> -->
<!-- 订单区域 -->
<view class="order-section" v-if="login_status" @tap="viewAllOrders">
<view class="section-header">
<text class="title">我的订单</text>
<view class="view-all">
<text>查看全部</text>
<text class="arrow">></text>
</view>
</view>
<view class="order-tabs" @tap.stop>
<view v-for="(tab, index) in orderTabs" :key="index" class="tab-item"
:class="{ active: currentTab === index }" @tap.stop="switchTab(index)">
<text>{{ tab.name }}</text>
<!-- <text class="badge" v-if="tab.badge">{{tab.badge}}</text> -->
</view>
</view>
<!-- 订单列表 -->
<view class="order-list">
<view class="order-item" v-for="order in orderList" :key="order.id">
<view class="order-header">
<text class="order-id">订单编号 {{ order.ordeNo }}</text>
</view>
<view class="order-content">
<image class="goods-image" :src="order.image || '/static/回收/衣物.png'" mode="aspectFill"></image>
<view class="order-info-opt">
<view class="order-info-top">
<text class="order-info-count">{{ order.num || 1 }} {{ order.unit }}</text>
<!-- <text class="order-info-price">¥{{ order.onePrice || 0 }} /件</text> -->
</view>
<view class="order-info-estimate" v-if="order.price">
结算 ¥ {{ order.price }}
</view>
<view class="order-info-estimate" v-else>
预估 ¥ {{ order.estimatedPrice }}
</view>
</view>
</view>
<view class="order-footer">
<view class="delivery-info">
<text class="status">{{ order.status === 0 ? '【在线预约】' : order.status === 1 ? '【快递上门】' :
order.status === 2 ? '【透明质检】' : order.status === 3 ? '【现金打款】' : ''}}</text>
<text class="time">{{ order.goTime }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 管理中心列表型卡片 -->
<view class="function-list manage-list"
v-if="login_status && (userInfo.isOrderRole === 'Y' || userInfo.isAppletUserRole === 'Y' || userInfo.isUserRole === 'Y' || userInfo.isTuiRole === 'Y')">
<view class="function-item" v-if="userInfo.isOrderRole === 'Y'" @tap="goOrderManage">
<view class="item-left">
<image class="icon" src="/static/my/订单管理.png" mode="aspectFit"></image>
<text>订单管理</text>
</view>
<uni-icons type="right" size="15"></uni-icons>
</view>
<view class="function-item" v-if="userInfo.isAppletUserRole === 'Y'" @tap="goAppletUserManage">
<view class="item-left">
<image class="icon" src="/static/my/用户管理.png" mode="aspectFit"></image>
<text>用户管理</text>
</view>
<uni-icons type="right" size="15"></uni-icons>
</view>
<view class="function-item" v-if="userInfo.isUserRole === 'Y'" @tap="goStaffManage">
<view class="item-left">
<image class="icon" src="/static/my/员工管理.png" mode="aspectFit"></image>
<text>员工管理</text>
</view>
<uni-icons type="right" size="15"></uni-icons>
</view>
<view class="function-item" v-if="userInfo.isTuiRole === 'Y'" @tap="goTuiManage">
<view class="item-left">
<image class="icon" src="/static/my/推广官管理.png" mode="aspectFit"></image>
<text>推广官管理</text>
</view>
<uni-icons type="right" size="15"></uni-icons>
</view>
</view>
<!-- 功能列表 -->
<view class="function-list" v-if="login_status">
<view class="function-item" v-for="(item, index) in functionList" :key="index" @tap="handleFunction(index)">
<view class="item-left">
<image class="icon" :src="item.icon" mode="aspectFit"></image>
<text>{{ item.name }}</text>
</view>
<uni-icons type="right" size="15"></uni-icons>
</view>
</view>
<!-- 根据角色显示不同的导航栏 -->
<uv-tabbar :value="value" :fixed="true" @change="changeTo">
<uv-tabbar-item text="首页">
<template v-slot:active-icon>
<image class="icon" src="/static/home/首页-点击.png"></image>
</template>
<template v-slot:inactive-icon>
<image class="icon" src="/static/home/首页-未点击.png"></image>
</template>
</uv-tabbar-item>
<uv-tabbar-item text="回收">
<template v-slot:active-icon>
<image class="icon" src="/static/home/回收-点击.png"></image>
</template>
<template v-slot:inactive-icon>
<image class="icon" src="/static/home/回收-未点击.png"></image>
</template>
</uv-tabbar-item>
<uv-tabbar-item text="我的">
<template v-slot:active-icon>
<image class="icon" src="/static/home/我的-点击.png"></image>
</template>
<template v-slot:inactive-icon>
<image class="icon" src="/static/home/我的-未点击.png"></image>
</template>
</uv-tabbar-item>
</uv-tabbar>
</view>
</template>
<script>
import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
export default {
mixins: [pullRefreshMixin],
data() {
return {
value: 2,
currentTab: 1,
login_status: false,
userInfo: {},
orderTabs: [
{ name: '全部' },
{ name: '进行中', badge: '2' },
{ name: '已完成' }
],
functionList: [
// { name: '推广官', icon: '/static/my/promote.png' },
{ name: '我的地址', icon: '/static/my/地址.png' },
{ name: '联系客服', icon: '/static/my/客服.png' },
{ name: '修改信息', icon: '/static/my/修改信息.png' },
{ name: '退出登录', icon: '/static/my/退出登录.png' }
],
orderList: [],
totalOrders: 0 // 添加累计回收单数字段
}
},
methods: {
async onRefresh() {
console.log('开始刷新')
try {
await this.fetchUserInfo()
console.log('刷新完成')
return true // 返回 true 表示刷新成功
} catch (error) {
console.error('刷新失败', error)
throw error // 抛出错误表示刷新失败
}
},
changeTo(e) {
this.value = e
console.log(e, '111')
if (e == 0) {
uni.reLaunch({
url: '/pages/component/home'
});
} else if (e == 1) {
uni.reLaunch({
url: '/pages/component/recycle'
});
}
},
goWithdraw() {
uni.navigateTo({
url: '/pages/subcomponent/wallet'
})
},
viewAllOrders() {
uni.navigateTo({
url: '/pages/subcomponent/order'
})
},
switchTab(index) {
this.currentTab = index
this.fetchOrderList()
},
handleFunction(index) {
const pages = [
// '/pages/subcomponent/promotion',
'/pages/subcomponent/select',
'/pages/subcomponent/admin_faq',
'/pages/subcomponent/edit_profile',
'logout'
]
if (pages[index] === 'logout') {
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
// 执行退出登录逻辑
getApp().globalData.login_status = false;
console.log(getApp().globalData.login_status);
this.login_status = false;
uni.removeStorageSync('token');
}
}
})
return
}
uni.navigateTo({
url: pages[index]
})
},
logout() {
uni.reLaunch({
url: '/pages/index/index'
});
},
onShareCommission() {
uni.showToast({ title: '分享赚佣金', icon: 'none' });
uni.navigateTo({ url: '/pages/subcomponent/promotion' })
},
goOrderManage() {
uni.navigateTo({ url: '/pages/manager/order' })
},
goAppletUserManage() {
uni.navigateTo({ url: '/pages/manager/user' })
},
goStaffManage() {
uni.navigateTo({ url: '/pages/manager/staff' })
},
goTuiManage() {
uni.navigateTo({ url: '/pages/manager/tui' })
},
fetchUserInfo() {
if (uni.getStorageSync('token')) {
this.login_status = getApp().globalData.login_status;
this.$api("getUserByToken", {}, (res) => {
if (res.code == 200) {
this.userInfo = res.result
// isTuiType 为0用户,1推广达人,2推广大使
}
})
} else {
this.login_status = false;
}
},
fetchOrderList() {
let status = ''
if (this.currentTab === 1) status = 1 // 进行中
if (this.currentTab === 2) status = 3 // 已完成
const params = { pageSize: 1, current: 1 }
if (status !== '') params.status = status
this.$api && this.$api('getOrderListPage', params, res => {
if (res && res.code === 200 && res.result && Array.isArray(res.result.records)) {
this.orderList = res.result.records
// 更新累计回收单数
} else {
this.orderList = []
}
})
},
getCumulativeRecoveryCount() {
this.$api && this.$api('getCumulativeRecoveryCount', {}, res => {
if (res && res.code === 200 && res.result) {
this.totalOrders = res.result
} else {
this.totalOrders = 0
}
})
},
// 初始化页面数据的方法
initializePageData() {
// 移除自动下拉刷新
// uni.startPullDownRefresh()
uni.$on('refreshUserInfo', () => {
this.fetchUserInfo()
})
this.fetchUserInfo()
this.fetchOrderList()
this.getCumulativeRecoveryCount()
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
}
},
goAbout() {
}
},
computed: {
customStyle() {
return {
// height: '80rpx',
width: '70%',
}
},
bannerList() {
return getApp().globalData.bannerList || []
},
myBannerImage() {
const item = getApp().globalData.configData.find(i => i.keyName === 'user_banner')
return item ? item.keyContent : ''
},
userTypeText() {
return this.userInfo.isTuiTypeTitle || '推广官'
},
userTypeBadgeClass() {
// 根据用户类型返回不同的样式类
switch (this.userInfo.isTuiTypeTitle) {
case '推广达人':
return 'avatar-badge-expert' // 推广达人
case '推广大使':
return 'avatar-badge-ambassador' // 推广大使
default:
return 'avatar-badge-user' // 普通用户
}
},
},
onLoad() {
// 检查App数据是否已经准备好
if (!getApp().globalData.isAppDataReady) {
// 显示加载状态
uni.showLoading({
title: '加载中...',
mask: true
})
// 监听App数据准备完成事件
uni.$on('appDataReady', () => {
uni.hideLoading()
this.initializePageData()
})
} else {
// App数据已经准备好,直接初始化页面数据
this.initializePageData()
}
},
onShow() {
this.fetchUserInfo()
this.getCumulativeRecoveryCount()
},
onPullDownRefresh() {
this.fetchUserInfo()
this.getCumulativeRecoveryCount()
setTimeout(() => {
uni.stopPullDownRefresh()
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 2000
})
}, 1000)
},
onUnload() {
uni.$off('bannerListUpdated')
},
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background: #f8f8f8;
padding-bottom: 120rpx;
}
.banner {
height: 320rpx;
background: #ff6b35;
position: relative;
overflow: hidden;
border-radius: 0 0 30rpx 30rpx;
.banner-title {
position: absolute;
top: 30%;
left: 20%;
color: #fff;
font-family: DingTalk JinBuTi;
font-weight: 400;
font-style: italic;
font-size: 30px;
line-height: 100%;
letter-spacing: 0%;
vertical-align: bottom;
z-index: 2;
}
.banner-bg {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
}
.user-card {
margin: -50rpx 30rpx 0;
background: #fff;
border-radius: 24rpx;
padding: 30rpx;
position: relative;
z-index: 2;
// box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
.user-info {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.avatar-badge-box {
position: relative;
width: 110rpx;
height: 110rpx;
border-radius: 12rpx;
overflow: hidden;
background: #fff;
flex-shrink: 0;
margin-right: 24rpx;
display: flex;
align-items: flex-end;
justify-content: center;
}
.avatar {
width: 100%;
height: 100%;
border-radius: 12rpx;
display: block;
}
.avatar-badge {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 32rpx;
line-height: 32rpx;
background: rgba(238, 238, 238, 0.95);
color: #999;
font-size: 24rpx;
text-align: center;
border-bottom-left-radius: 12rpx;
border-bottom-right-radius: 12rpx;
font-weight: 400;
letter-spacing: 2rpx;
z-index: 2;
// 普通用户样式(默认)
&.avatar-badge-user {
background: rgba(238, 238, 238, 0.95);
color: #999;
}
// 推广达人样式
&.avatar-badge-expert {
background: linear-gradient(90deg, #ff8917, #ffd01e);
color: #fff;
font-weight: 600;
}
// 推广大使样式
&.avatar-badge-ambassador {
background: linear-gradient(90deg, #b2f08d, #39e9d2);
color: #fff;
font-weight: 600;
}
}
.info {
.name {
font-size: 34rpx;
font-weight: 600;
color: #222;
margin-bottom: 12rpx;
display: block;
}
.id {
font-size: 26rpx;
color: #999;
display: flex;
align-items: center;
&::before {
// content: 'ID: ';
color: #999;
margin-right: 4rpx;
}
}
}
}
.wallet-info {
display: flex;
padding: 30rpx;
background: #fff8ea;
border-radius: 16rpx;
position: relative;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 1rpx;
height: 50%;
background: #FFE4D9;
}
.balance {
flex: 1;
padding-right: 30rpx;
.label {
font-size: 26rpx;
color: #999;
margin-bottom: 12rpx;
display: block;
}
.amount {
display: flex;
align-items: baseline;
margin-bottom: 20rpx;
.symbol {
font-size: 30rpx;
color: #FF5B05;
font-weight: normal;
margin-right: 4rpx;
}
.value {
font-size: 46rpx;
font-weight: 600;
color: #FF5B05;
line-height: 1;
}
}
.withdraw-btn {
display: inline-flex;
align-items: center;
padding: 8rpx 16rpx;
background: #fff0d2;
border: 1rpx solid rgba(255, 91, 5, 0.2);
border-radius: 13rpx;
color: #FF5B05;
font-size: 24rpx;
.arrow {
margin-left: 6rpx;
font-family: "PingFang SC";
}
}
}
.recycle-count {
flex: 1;
padding-left: 30rpx;
.label {
font-size: 26rpx;
color: #999;
margin-bottom: 12rpx;
display: block;
}
.count {
display: flex;
align-items: baseline;
.value {
font-size: 46rpx;
font-weight: 600;
color: #222;
line-height: 1;
}
.unit {
font-size: 26rpx;
color: #999;
margin-left: 8rpx;
font-weight: normal;
}
}
}
}
}
.order-section {
margin: 20rpx 30rpx;
background: linear-gradient(to bottom, #fff4e0 0%, #fff 10%);
border-radius: 20rpx;
padding: 20rpx 30rpx;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.title {
font-size: 34rpx;
font-weight: bold;
color: #333;
}
.view-all {
font-size: 26rpx;
color: #999;
display: flex;
align-items: center;
.arrow {
margin-left: 4rpx;
}
}
}
.order-tabs {
display: flex;
margin-bottom: 30rpx;
background: #f8f8f8;
border-radius: 8rpx;
padding: 4rpx;
.tab-item {
flex: 1;
text-align: center;
padding: 16rpx 0;
position: relative;
color: #666;
font-size: 28rpx;
border-radius: 6rpx;
&.active {
color: #333;
font-weight: bold;
background: #fff;
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.05);
}
}
}
.order-item {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
border: none;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.02);
.order-header {
margin-bottom: 24rpx;
.order-id {
font-size: 26rpx;
color: #666;
}
}
.order-content {
display: flex;
margin-bottom: 24rpx;
align-items: center;
justify-content: space-between;
position: relative;
&::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 60rpx;
height: 60rpx;
background: #f8f8f8;
border-radius: 50%;
z-index: 1;
}
&::before {
content: '⇌';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #999;
font-size: 32rpx;
z-index: 2;
}
.goods-image {
width: 200rpx;
height: 200rpx;
border-radius: 16rpx;
background: #fffbe6;
padding: 20rpx;
box-sizing: border-box;
display: block;
}
.order-info-opt {
width: 200rpx;
min-height: 110rpx;
background: linear-gradient(180deg, #fffbe6 0%, #fff 100%);
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 24rpx 0 16rpx 0;
box-sizing: border-box;
margin-left: 16rpx;
}
.order-info-top {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 8rpx;
}
.order-info-count {
font-size: 32rpx;
color: #222;
font-weight: bold;
margin-bottom: 4rpx;
}
.order-info-price {
font-size: 22rpx;
color: #999;
}
.order-info-estimate {
background: linear-gradient(90deg, #ffd01e 0%, #ff8917 100%);
color: #fff;
font-size: 24rpx;
font-weight: bold;
border-radius: 0 0 16rpx 16rpx;
padding: 12rpx 0;
width: 100%;
text-align: center;
margin-top: 8rpx;
box-shadow: 0 2rpx 8rpx rgba(255, 156, 0, 0.08);
}
}
.order-footer {
display: flex;
align-items: center;
padding: 24rpx;
border-top: 1rpx solid #f5f5f5;
background: #fafafa;
border-radius: 12rpx;
margin: 0 -24rpx -24rpx;
.courier-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 12rpx;
margin-right: 20rpx;
background: #fff;
}
.delivery-info {
flex: 1;
display: flex;
flex-direction: column;
.status {
font-size: 28rpx;
color: #333;
margin-bottom: 8rpx;
font-weight: bold;
}
.time {
font-size: 26rpx;
color: #999;
}
}
}
}
}
.function-list {
margin: 20rpx 30rpx;
background: #fff;
border-radius: 20rpx;
padding: 0 30rpx;
.function-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.item-left {
display: flex;
align-items: center;
.icon {
width: 40rpx;
height: 40rpx;
margin-right: 16rpx;
}
text {
font-size: 28rpx;
color: #333;
}
}
.arrow {
color: #999;
font-size: 24rpx;
}
}
}
.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background: #fff;
display: flex;
padding-bottom: env(safe-area-inset-bottom);
border-top: 1rpx solid #f5f5f5;
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10rpx 0;
image {
width: 48rpx;
height: 48rpx;
margin-bottom: 6rpx;
}
text {
font-size: 20rpx;
color: #999;
}
&.active {
text {
color: #ff6b35;
}
}
}
}
.user-cards {
margin: -50rpx 30rpx 0;
background: #fff;
border-radius: 24rpx;
padding: 30rpx;
position: relative;
z-index: 2;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
.user-info {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.avatars {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
margin-right: 24rpx;
}
}
.info {
.name {
font-size: 34rpx;
font-weight: 600;
color: #222;
margin-bottom: 12rpx;
display: block;
}
}
}
.btns {
width: 100%;
margin: 0 auto;
margin-top: 30%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.uv-button,
.btn {
width: 100%;
height: 100rpx;
background: linear-gradient(90deg, #FFD36D 0%, #FFA800 100%);
color: #fff;
font-size: 36rpx;
border-radius: 50rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(255, 168, 0, 0.08);
border: none;
margin: 0 auto;
}
text {
margin-top: 20rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
line-height: 100%;
letter-spacing: 0%;
text-align: center;
color: #a3a3a3;
}
}
.share-commission-card {
width: 90%;
margin: 32rpx auto 24rpx auto;
height: 90rpx;
background: linear-gradient(90deg, #ffd01e 0%, #ff8917 100%);
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(255, 156, 0, 0.08);
cursor: pointer;
}
.share-commission-text {
color: #fff;
font-size: 32rpx;
font-weight: bold;
letter-spacing: 2rpx;
}
.manage-list {
margin-bottom: 20rpx;
}
</style>