mrr.sj.front/pages/order/userorder-list.vue

970 lines
23 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="order-list">
<view v-if="isLogin">
<!-- 订单状态标签 -->
<view class="status">
<scroll-view scroll-x class="status-tabs" :show-scrollbar="false">
<view style="padding-left: 20rpx;">
<view class="tab-item" v-for="(tab, index) in OrderType" :key="tab.id"
:class="{ active: OrderTypeIndex === tab.id }" @click="switchOrderTab(tab.id)">
{{tab.title}}
</view>
</view>
</scroll-view>
<scroll-view scroll-x class="status-tabs2" :show-scrollbar="false">
<view class="tab-item2" v-for="(tab, index) in tabs" :key="tab.id"
:class="{ active: currentTab === tab.id }" @click="switchTab(tab.id)">
{{tab.title}}
</view>
</scroll-view>
</view>
<!-- 订单列表 -->
<scroll-view scroll-y class="order-scroll" @scrolltolower="loadMore" refresher-enabled
:refresher-triggered="isRefreshing" @refresherrefresh="onRefresh"
:style="{height:`calc(100vh - ${210}rpx)`}">
<view class="order-item" v-for="(order, index) in orderList" :key="index">
<!-- 订单编号和状态 -->
<view class="order-header">
<view class="order-tag" v-if="!order.team_buy_id || order.team_buy_id==`0`">
<text
class="order-tag-text">{{order.order_kind == 1 ? '到家' : order.order_kind == 2 ? '到店' : order.order_kind == 3 ? '到家' : ''}}</text>
</view>
<text class="order-number">订单编号:{{order.number}}</text>
<text class="order-status"
:class="order.statusClass">{{order.state == 1 ? '待支付' : order.state == 2 ? '待接单' : order.state == 3 ? '待服务' : order.state == 4 ? '待完成' : order.state == 5 ? '已完成' : order.state == 6 ? '待评价' : order.state == 7 ? '已取消' : ''}}</text>
</view>
<!-- 订单内容 -->
<view class="order-content" @click="goDetail(order)">
<image v-if="order.order_photo" :src="order.order_photo[0]" mode="aspectFill"
class="service-image"></image>
<view class="service-image" v-else></view>
<view class="service-info">
<view class="service-name">
<image v-if="order.team_buy_id && order.team_buy_id!=0"
:src="getGroupType(order.team_buy_order_state)" class="service-name-type"
mode="heightFix"></image>
<text class="service-name-text">
{{order.server_title}}
</text>
</view>
<view class="service-time" v-if="order.order_kind == 1 || order.order_kind == 3">
<!-- <image src="/static/images/time_icon.png" class="time-icon"></image> -->
<text>下单时间:{{order.reservation_time }}</text>
</view>
<view class="service-time"
v-if="order.order_kind == 2 && (!order.team_buy_id || order.team_buy_id==0)">
<!-- <image src="/static/images/time_icon.png" class="time-icon"></image> -->
<text>下单时间:{{order.add_time}}</text>
</view>
<view class="service-address" v-if="order.order_kind == 1 || order.order_kind == 3">
<!-- <image src="/static/images/position_icon.png" class="location-icon"></image> -->
<text
class="text-overflow-1">到家地址:{{Object.assign({},order.reservation_address_arr).server_address}}</text>
</view>
<view class="service-group" v-if="order.team_buy_id && order.team_buy_id!=0">
<view class="service-group-time">
下单时间:{{ order.add_time }}
</view>
<view class="service-group-price">
团购价:<text style="font-size: 34rpx;">{{ order.order_money }}</text>
</view>
</view>
</view>
</view>
<!-- 订单操作按钮 -->
<view class="order-actions">
<view class="action-left">
<image src="/static/images/evaluate/delete-icon.png" class="delete-icon"
@click="deleteOrder(order)"
v-if="order.state == 5 || order.state == 6 || order.state == 7"></image>
</view>
<view class="action-right">
<text class="action-btn contact" @click="cancelService(order)"
v-if="order.state == 1">取消订单</text>
<text class="action-btn contact" @click="refoundService(order)"
v-if="order.state == 2 || order.state == 3">申请退款</text>
<text class="action-btn contact" @click="contactService(order.order_shopphone)">联系客服</text>
<text class="action-btn review" v-if="order.state == 1" @click="payOrder(order)">立即支付</text>
<text class="action-btn again" v-if="order.state == 5 || order.state == 6"
@click="orderAgain(order)">再来一单</text>
<text class="action-btn again" v-if="order.state == 5 && order.appeal == 1"
@click="addComplaint(order)">投诉</text>
<text class="action-btn again" v-if="order.state == 5 && order.appeal == 2"
@click="lookComplaint(order)">查看投诉</text>
<text class="action-btn review" v-if="order.state == 5 && order.evaluate==2"
@click="reviewOrder(order)">立即评价</text>
<text class="action-btn again" v-if="order.state == 5 && order.evaluate==1"
@click="goEvaluateDetail(order)">已评价</text>
</view>
</view>
</view>
<!-- 加载更多 -->
<view class="loading-more" v-if="hasMore">加载中...</view>
<view class="no-more" v-if="!hasMore && orderList.length">暂无数据哦~</view>
<!-- 没数据的情况 -->
<noData v-if="orderList.length==0"></noData>
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer }">
<view class="per-tit">美融融plus 对拨打电话权限申请说明</view>
<view class="per-cont">当您需要联系商家或平台客服的时候,需要获取拨打电话权限。</view>
</view>
</scroll-view>
</view>
<view class="nologin_part" v-else>
<image src="/static/images/no_login.png" class="nologin_icon" mode="aspectFit"></image>
<view class="btn-login">
<text class="login-text" @click="goLogin">前去登录</text>
</view>
</view>
<!-- 自定义TabBar -->
<TabBar :selected="1"></TabBar>
</view>
</template>
<script>
import TabBar from "@/components/tabbar/tabbar.vue"
import request from '../../utils/request'
import locationService from '../../utils/locationService';
import permissionUtils from '../../utils/per'
import {
debounce
} from '@/utils/debounce.js'
import {
url
} from '../../uni_modules/uv-ui-tools/libs/function/test';
export default {
components: {
TabBar,
},
data() {
return {
isShowPer: false,
OrderType: [{
id: 0,
title: '全部订单',
url: "/user/order/list",
}, {
id: 1,
title: '普通订单',
url: "/user/userorders",
}, {
id: 2,
title: '自营订单',
url: "/user/orderSelf/list",
}],
urls: {
order: {
cancelorder: "/user/cancelorder",
deleteorder: "/user/deleteorder"
},
order_self: {
cancelorder: "/user/orderSelf/cancel",
deleteorder: "/user/orderSelf/del"
}
},
OrderTypeIndex: 0,
tabs: [{
id: 0,
title: '全部'
}, {
id: 1,
title: '待支付'
}, {
id: 2,
title: '待接单'
}, {
id: 3,
title: '待服务'
}, {
id: 4,
title: '服务中'
}, {
id: 5,
title: '已完成'
}, {
id: 7,
title: '已取消'
}],
// ,{id: 6,title: '待评价'}
currentTab: 0,
isRefreshing: false,
hasMore: true,
orderList: [],
formData: {
page: 1,
limit: 10
},
isLogin: false
}
},
computed: {
},
onLoad() {
//隐藏原生Tabar
uni.hideTabBar()
// this.loadOrders();
this.handleOrderTypeFromGlobal();
},
onShow() {
this.isLogin = uni.getStorageSync('accessToken') ? true : false;
if (!this.isLogin) return;
// 在 onShow 中也处理全局变量
this.handleOrderTypeFromGlobal();
this.orderList = [];
this.formData.page = 1;
this.loadOrders();
},
methods: {
//获取拼团状态文字
// getGroupType(id) {
// let list = [{
// id: 1,
// text: "团购中",
// },
// {
// id: 2,
// text: "已成团",
// },
// {
// id: 3,
// text: "拼团失败",
// },
// ];
// let name = list.find((it) => it.id == id)?.text;
// return name;
getGroupType(id) {
const imageBasePath = '/static/images/';
const imageMap = {
1: imageBasePath + 'pintuan_ing.png', // 团购中
2: imageBasePath + 'pintuan_done.png', // 已成团
3: imageBasePath + 'pintuan_fail.png' // 拼团失败
};
return imageMap[id] || ''; // 如果id不在1-3范围内返回空字符串
},
// 切换标签
switchOrderTab(index) {
this.OrderTypeIndex = index;
this.orderList = [];
this.formData.page = 1;
// TODO: 根据当前标签加载对应订单数据
delete this.formData.state;
this.currentTab = 0;
this.loadOrders()
},
// 切换标签
switchTab(index) {
this.currentTab = index;
this.orderList = [];
this.formData.page = 1;
// TODO: 根据当前标签加载对应订单数据
if (this.currentTab != 0) {
this.formData.state = this.currentTab;
} else {
delete this.formData.state;
}
this.loadOrders()
},
// 加载订单数据
loadOrders() {
request.post(this.OrderType[this.OrderTypeIndex].url, this.formData).then(res => {
this.orderList = [...this.orderList, ...res.data];
if (res.count == this.orderList.length) {
this.hasMore = false
} else {
this.hasMore = true
this.formData.page = this.formData.page + 1;
}
this.isRefreshing = false
})
},
// 下拉刷新
onRefresh() {
this.isRefreshing = true
this.formData.page = 1;
this.orderList = [];
this.loadOrders()
},
// 加载更多
loadMore() {
if (!this.hasMore) return
// TODO: 加载更多订单数据
this.loadOrders();
},
// 跳转订单详情
goDetail(order) {
console.log('order', order)
if (order.table_source == "order") {
//如果是普通订单
uni.navigateTo({
url: `/pages/order/userorder-detail?id=${order.id}`
})
} else if (order.table_source == "order_self") {
//如果是自营订单
uni.navigateTo({
url: `/pages/order/userorder-detail?id=${order.id}&serviceType=2`
})
}
},
// 删除订单
deleteOrder: debounce(async function(order) {
uni.showModal({
title: '提示',
content: '确定要删除该订单吗?',
success: (res) => {
if (res.confirm) {
// TODO: 删除订单
request.post(this.urls[order.table_source].deleteorder, {
id: order.id
}).then(res => {
uni.showToast({
title: '删除成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.loadOrders();
})
}
}
})
}, 500),
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 订单状态全局变量
handleOrderTypeFromGlobal() {
const orderType = getApp().globalData.selectedOrderType;
console.log('接收到的订单类型:', orderType);
if (orderType) {
// 创建类型映射
const typeMap = {
'unpaid': 1, // 待支付
'unaccepted': 2, // 待接单
'unserved': 3, // 待服务
'finnish': 5 // 已完成
};
// 映射到对应的数字类型
this.currentTab = typeMap[orderType] || 0;
console.log('映射后的currentTab:', this.currentTab);
// 根据currentTab设置formData.state
if (this.currentTab !== 0) {
this.formData.state = this.currentTab;
} else {
delete this.formData.state;
}
// 清除全局变量
getApp().globalData.selectedOrderType = null;
}
},
// 联系客服
async contactService(phone) {
// TODO: 实现联系客服功能
uni.navigateTo({
url: '/pages/contact/contact'
})
// const systemInfo = uni.getSystemInfoSync()
// if(systemInfo.platform === 'ios') {
// uni.makePhoneCall({
// phoneNumber: phone //仅为示例
// })
// }else {
// let permission = '';
// if(systemInfo.platform === 'ios') {
// permission = 'phone'
// }else {
// permission = 'android.permission.CALL_PHONE'
// }
// this.isShowPer = true;
// const firstRequest = !plus.storage.getItem(`perm_${permission}`)
// if(firstRequest) {
// this.isShowPer = true;
// }
// // 1. 检查权限
// const { granted } = await permissionUtils.checkPermission('phone', '需要拨打电话权限,方便您联系商家或平台');
// if (granted) {
// this.isShowPer = false;
// uni.makePhoneCall({
// phoneNumber: phone //仅为示例
// })
// return;
// }
// this.isShowPer = false;
// // 2. 显示权限说明弹窗
// const confirm = await this.showPermissionDialog(
// '拨打电话权限申请',
// '我们需要拨打电话权限,方便您联系商家或平台'
// );
// if (!confirm) return;
// // 3. 请求权限
// const result = await permissionUtils.requestPermission('phone', '需要拨打电话权限,方便您联系商家或平台');
// console.log('result',result)
// if (result) {
// uni.makePhoneCall({
// phoneNumber: phone //仅为示例
// })
// return;
// } else {
// locationService.openAppSettings();
// return;
// // uni.showToast({ title: '相机权限被拒绝', icon: 'none' });
// }
// }
},
// 取消订单
async cancelService(order) {
let id = '';
await request.post('/user/getuser', {
type: 1
}).then(res => {
console.log(res)
id = res.data.id
})
console.log(order)
uni.showModal({
title: '取消订单',
content: '确定要取消该订单吗?',
success: (res) => {
if (res.confirm) {
// TODO: 取消订单
let data = {
orderNo: order.number,
amount: order.pay_money,
cancel_state: 1,
cancel_id: id
}
request.post(this.urls[order.table_source].cancelorder, data).then(res => {
uni.showToast({
title: '取消成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.loadOrders();
}).catch(err => {
console.log(err)
})
}
}
})
},
// 申请退款
async refoundService(order) {
let id = '';
await request.post('/user/getuser', {
type: 1
}).then(res => {
console.log(res)
id = res.data.id
})
uni.showModal({
title: '申请退款',
content: '确定申请退款?退款后则订单取消!',
success: (res) => {
if (res.confirm) {
// TODO: 申请退款
let data = {
orderNo: order.number,
amount: order.pay_money,
cancel_state: 1,
cancel_id: id
}
let url = '';
if (order.pay_kind == 1) {
url = ''
} else if (order.pay_kind == 2) {
url = '/user/wechatrefund'
} else if (order.pay_kind == 3) {
url = '/user/alirefund'
}
console.log(data, url)
request.post(url, data).then(res => {
console.log('申请退款订单返回结果', res)
uni.showToast({
title: '申请退款成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.loadOrders();
}).catch(err => {
console.log(err)
})
}
}
})
},
// 支付订单
payOrder(order) {
if(order.table_source == "order_self"){
// TODO: 实现支付功能
uni.navigateTo({
url: `/pages/order/pay?id=${order.id}&money=${order.order_money}&title=${order.server_title}&number=${order.number}&table_source=order_self`
})
}else{
// TODO: 实现支付功能
uni.navigateTo({
url: `/pages/order/pay?id=${order.id}&money=${order.order_money}&title=${order.server_title}&number=${order.number}`
})
}
},
// 评价订单
reviewOrder(order) {
uni.navigateTo({
url: `/pages/evaluate/comment?id=${order.id}&evaluator_type=3&order_type=1&order_kind=${order.order_kind}`
})
},
goEvaluateDetail(order) {
uni.navigateTo({
url: `/pages/evaluate/evaluationDetails?order_id=${order.id}&order_type=1`
});
},
// 再次下单
orderAgain(order) {
console.log(1111111,order)
if(order.table_source=="order_self"){
// TODO: 实现再次下单功能
uni.navigateTo({
url: '/pages/selfOperated/detail?id=' + order.server_id
})
}else{
// TODO: 实现再次下单功能
uni.navigateTo({
url: '/pages/service/detail?id=' + order.server_id
})
}
},
// 投诉
addComplaint(order) {
uni.navigateTo({
url: '/pages/complaint/add-complaint?number=' + order.number
})
},
// 查看投诉
lookComplaint(order) {
uni.navigateTo({
url: '/pages/complaint/detail?number=' + order.number
})
},
goLogin() {
// uni.oprPresentLogin()
uni.navigateTo({
url: '/pages/blogPopup/blogPopup'
});
}
}
}
</script>
<style lang="less">
/* 状态标签栏 */
.status {
position: sticky;
top: 0;
/* #ifdef H5 */
top: 88rpx;
/* H5端顶部适配 */
/* #endif */
left: 0;
right: 0;
}
.status-tabs {
height: 94rpx;
background-color: #FFFFFF;
z-index: 99;
white-space: nowrap;
// padding-left: 20rpx;
}
.tab-item {
display: inline-block;
height: 48rpx;
position: relative;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 42rpx;
text-align: left;
font-style: normal;
margin: 20rpx 50rpx 26rpx 0rpx;
}
.tab-item.active {
color: #E8101E;
font-weight: 500;
}
.tab-item.active::after {
content: '';
position: absolute;
width: 28rpx;
height: 6rpx;
left: 50%;
bottom: 0;
transform: translateX(-50%);
background-color: #E8101E;
border-radius: 3rpx;
}
.status-tabs2 {
height: 56rpx;
background-color: #FFFFFF;
z-index: 99;
white-space: nowrap;
padding-bottom: 30rpx;
}
.tab-item2 {
display: inline-block;
height: 56rpx;
padding: 0 20rpx;
background: #F3F5F6;
border-radius: 10rpx;
position: relative;
margin: 0 18rpx;
font-weight: 400;
font-size: 28rpx;
color: #333333;
line-height: 56rpx;
text-align: left;
font-style: normal;
}
.tab-item2.active {
color: #E8101E;
font-weight: 500;
background: #FEE5E7;
}
/* 订单列表 */
.order-scroll {
padding: 0 20rpx 24rpx;
margin-top: 24rpx;
height: calc(100vh - 112rpx - 24rpx);
box-sizing: border-box;
}
.order-item {
background-color: #FFFFFF;
border-radius: 16rpx;
margin-bottom: 24rpx;
padding: 20rpx;
box-sizing: border-box;
}
.order-header {
display: flex;
align-items: center;
margin-bottom: 34rpx;
}
.order-tag {
padding: 2rpx 6rpx;
background: #E8101E;
border-radius: 6rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10rpx;
}
.order-tag-text {
font-weight: 400;
font-size: 20rpx;
color: #FFFFFF;
line-height: 25rpx;
text-align: left;
font-style: normal;
}
.order-number {
flex: 1;
font-size: 24rpx;
color: #666666;
}
.order-status {
font-weight: 400;
font-size: 26rpx;
color: #E8101E;
line-height: 39rpx;
text-align: left;
font-style: normal;
}
.status-pending {
color: #E8101E;
}
.status-cancelled {
color: #E8101E;
}
.status-completed {
color: #E8101E;
}
.order-content {
display: flex;
margin-bottom: 24rpx;
}
.service-image {
width: 182rpx;
height: 182rpx;
border-radius: 16rpx;
margin-right: 24rpx;
background-color: #000000;
}
.service-info {
flex: 1;
}
.service-name {
width: 400rpx;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 34rpx;
text-align: left;
font-style: normal;
display: flex;
align-items: center;
.service-name-type {
height: 28rpx;
margin-right: 10rpx;
}
.service-name-text {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.service-time,
.service-address {
display: flex;
align-items: center;
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
text-align: left;
font-style: normal;
margin-top: 6rpx;
}
.service-time {
margin-top: 16rpx;
}
.time-icon,
.location-icon {
width: 24rpx;
height: 24rpx;
margin-right: 4rpx;
flex-shrink: 0;
}
.order-actions {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1rpx solid #EEEEEE;
padding-top: 24rpx;
}
.delete-icon {
width: 36rpx;
height: 40rpx;
}
.action-left {
display: flex;
align-items: center;
}
.action-right {
display: flex;
align-items: center;
padding: 4rpx 0;
gap: 18rpx;
}
.action-btn {
display: flex;
align-items: center;
justify-content: center;
width: 129rpx;
height: 56rpx;
border-radius: 32rpx;
border: 2rpx solid #979797;
font-weight: 400;
font-size: 24rpx;
color: #333333;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
.action-btn.contact {
background-color: #FFFFFF;
border: 1rpx solid #999999;
color: #333333;
}
.action-btn.primary {
background-color: #E8101E;
color: #FFFFFF;
}
.action-btn.review {
border-color: transparent;
background: linear-gradient(143deg, #F52540 0%, #E8101E 100%);
color: #FFFFFF;
}
.action-btn.again {
background-color: #FFFFFF;
border: 1rpx solid #999999;
color: #666666;
}
.nologin_part {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.nologin_icon {
width: 360rpx;
height: 360rpx;
margin-top: 100rpx;
margin-bottom: 40rpx;
}
.btn-login {
width: 200rpx;
height: 68rpx;
background-color: yellowgreen;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
.login-text {
font-size: 36rpx;
color: #fff;
text-shadow:
1px 1px 1px #919191,
2px 2px 1px #919191,
2px 3px 1px #919191,
2px 4px 1px #919191,
2px 5px 1px #919191,
2px 6px 1px #919191,
2px 7px 2px rgba(16, 16, 16, 0.4);
}
/* 加载更多 */
.loading-more,
.no-more {
text-align: center;
font-size: 26rpx;
color: #999999;
padding: 24rpx 0;
}
/* #ifdef APP-PLUS */
/* APP端权限弹窗位置适配 */
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
.service-group {
display: flex;
flex-wrap: wrap;
align-content: space-between;
flex: 1;
margin-top: 16rpx;
.service-group-time {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
text-align: left;
font-style: normal;
width: 100%;
}
.service-group-price {
margin-top: 56rpx;
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 24rpx;
color: #E8101E;
line-height: 34rpx;
text-align: left;
font-style: normal;
}
}
</style>