爱简收旧衣按件回收前端代码仓库
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.
 
 
 
 

954 lines
22 KiB

<template>
<view class="container" >
<!-- 顶部banner -->
<view class="banner">
<swiper
:indicator-dots="false"
:autoplay="true"
:interval="3000"
:duration="500"
circular
style="width: 100%; height: 400rpx;"
>
<swiper-item v-for="(item, index) in bannerList" :key="item.id || index">
<image :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" />
</swiper-item>
</swiper>
</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">
<image class="avatar" :src="userInfo.headImage" mode="aspectFill"></image>
<view class="info">
<text class="name">{{userInfo.nickName}}</text>
<text class="id">{{userInfo.id}}</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}}</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">341</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="order-section" v-if="login_status">
<view class="section-header">
<text class="title">我的订单</text>
<view class="view-all" @tap="viewAllOrders">
<text>查看全部</text>
<text class="arrow">></text>
</view>
</view>
<view class="order-tabs">
<view
v-for="(tab, index) in orderTabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@tap="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}} 件</text>
<text class="order-info-price">¥{{order.onePrice || 0}} /件</text>
</view>
<view class="order-info-estimate">
预估 ¥ {{order.price}}
</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: []
}
},
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/customer',
'/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
}
})
} else {
this.login_status = false;
}
},
fetchOrderList() {
let status = ''
if (this.currentTab === 1) status = 0 // 进行中
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 = []
}
})
},
},
computed: {
customStyle() {
return {
// height: '80rpx',
width: '70%',
}
},
bannerList() {
return getApp().globalData.bannerList || []
}
},
onLoad() {
// 移除自动下拉刷新
// uni.startPullDownRefresh()
uni.$on('refreshUserInfo', () => {
this.fetchUserInfo()
})
this.fetchUserInfo()
this.fetchOrderList()
uni.$on('bannerListUpdated', () => {
this.$forceUpdate && this.$forceUpdate()
})
if (getApp().globalData.bannerList && getApp().globalData.bannerList.length > 0) {
this.$forceUpdate && this.$forceUpdate()
}
},
onShow() {
this.fetchUserInfo()
},
onPullDownRefresh() {
this.fetchUserInfo()
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: 400rpx;
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 {
width: 110rpx;
height: 110rpx;
border-radius: 12rpx;
margin-right: 24rpx;
}
.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);
}
.badge {
position: absolute;
top: 4rpx;
right: 50%;
transform: translateX(24rpx);
background: #ff6b35;
color: #fff;
font-size: 20rpx;
padding: 0 8rpx;
border-radius: 20rpx;
min-width: 28rpx;
height: 28rpx;
line-height: 28rpx;
}
}
}
.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>