mrr.sj.front/pages/shop/buy-order.vue

737 lines
17 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">
<!-- 订单状态标签 -->
<scroll-view scroll-x class="status-tabs" :show-scrollbar="false">
<view class="tab-item" v-for="(tab, index) in tabs" :key="tab.id"
:class="{ active: currentTab === tab.id }" @click="switchTab(tab.id)">
{{tab.title}}
</view>
</scroll-view>
<!-- 订单列表 -->
<scroll-view scroll-y class="order-scroll" @scrolltolower="loadMore" refresher-enabled
:refresher-triggered="isRefreshing" @refresherrefresh="onRefresh">
<view class="order-item" v-for="(order, index) in orderList" :key="index">
<!-- 顶部订单编号 + 状态 -->
<view class="order-top">
<text class="order-number">订单编号{{order.number}}</text>
<view class="order-status-badge" :class="{
'order-status-badge2': order.state > 4 && order.state !== 7,
'order-status-badge3': order.state === 7
}">
{{ getStatusText(order.state) }}
</view>
</view>
<!-- 订单内容 -->
<view class="order-content" @click="goDetail(order)">
<image v-if="order.order_photo && order.order_photo.length" :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">{{order.server_title}}</view>
<view class="service-time" v-if="getDisplayTime(order)">
<text class="label-text">下单时间:</text>
<text class="value-text">{{ getDisplayTime(order) }}</text>
</view>
<view class="service-address" v-if="order.order_kind == 1 && getFullAddress(order)">
<image src="/static/images/position_icon.png" class="location-icon"></image>
<text class="address-text">{{ getFullAddress(order) }}</text>
</view>
<view class="price-row">
<text class="price-symbol">¥</text>
<text class="price-now">{{ getDisplayPrice(order) }}</text>
<text class="price-old" v-if="getOriginalPrice(order)">{{ getOriginalPrice(order) }}</text>
</view>
</view>
</view>
<!-- 订单操作按钮 -->
<view class="order-actions">
<view class="action-left">
<image src="/static/images/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 gray-btn" @click="cancelService(order)" v-if="order.state == 1">
取消订单
</text>
<text class="action-btn gray-btn" @click="refoundService(order)"
v-if="order.state == 2 || order.state == 3">
申请退款
</text>
<!-- <text class="action-btn gray-btn" @click="contactService(order.order_shopphone)"
v-if="order.state != 7 && order.state != 2">
联系客服
</text> -->
<text class="action-btn red-btn" v-if="order.state == 1" @click="payOrder(order)">
立即支付
</text>
<text class="action-btn red-btn" v-if="order.state == 6" @click="reviewOrder(order)">
评价
</text>
<text class="action-btn gray-btn" v-if="order.state == 5 || order.state == 6 || order.state == 7"
@click="orderAgain(order)">
再次购买
</text>
<text class="action-btn gray-btn" v-if="order.state == 5 && order.appeal == 2"
@click="lookComplaint(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>
</view>
</template>
<script>
import request from '../../utils/request'
import locationService from '../../utils/locationService';
import permissionUtils from '../../utils/per'
import {
debounce
} from '@/utils/debounce.js'
export default {
data() {
return {
isShowPer: false,
sjid: null,
tabs: [{
id: 0,
title: '全部'
}, {
id: 1,
title: '待支付'
}, {
id: 2,
title: '待接单'
}, {
id: 3,
title: '待服务'
}, {
id: 4,
title: '服务中'
}, {
id: 5,
title: '已完成'
}, {
id: 7,
title: '已取消'
}],
currentTab: 0,
isRefreshing: false,
hasMore: true,
orderList: [],
formData: {
page: 1,
limit: 10
},
isLogin: false
}
},
onLoad() {
// this.loadOrders();
},
async onShow() {
this.isLogin = uni.getStorageSync('accessToken') ? true : false;
if (!this.isLogin) return;
const shopInfo = await request.post('/user/getuser', {
type: 3
});
this.sjid = shopInfo.data.id;
this.orderList = [];
this.formData.page = 1;
this.formData.sjid = shopInfo.data.id;
this.loadOrders();
},
methods: {
// 切换标签
switchTab(index) {
this.currentTab = index;
this.orderList = [];
this.formData.page = 1;
if (this.currentTab != 0) {
this.formData.state = this.currentTab;
} else {
delete this.formData.state;
}
this.loadOrders()
},
// 加载订单数据
loadOrders() {
request.post('/sj/sjselforder', 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.hasMore = true;
this.loadOrders()
},
// 加载更多
loadMore() {
if (!this.hasMore) return
this.loadOrders();
},
// 跳转订单详情
goDetail(order) {
console.log('order', order)
uni.navigateTo({
url: `/pages/shop/buyorder-detail?id=${order.id}`
})
},
getStatusText(state) {
const map = {
1: '待支付',
2: '待接单',
3: '待服务',
4: '服务中',
5: '已完成',
6: '待评价',
7: '已取消'
}
return map[state] || ''
},
getDisplayTime(order) {
return order.create_time || order.createtime || order.add_time || order.reservation_time || ''
},
getDisplayPrice(order) {
const price = order.pay_money || order.order_money || 0
return Number(price).toFixed(2)
},
getOriginalPrice(order) {
const orderMoney = Number(order.order_money || 0)
const payMoney = Number(order.pay_money || 0)
if (orderMoney > 0 && payMoney > 0 && orderMoney !== payMoney) {
return orderMoney.toFixed(2)
}
return ''
},
getFullAddress(order) {
const arr = order.reservation_address_arr || {}
const dependency = arr.dependency || ''
const address = arr.address || ''
return `${dependency}${address}`
},
// 删除订单
deleteOrder: debounce(async function(order) {
uni.showModal({
title: '提示',
content: '确定要删除该订单吗?',
success: (res) => {
if (res.confirm) {
request.post('/sj/deleteorder', {
id: order.id,
sjid: this.sjid
}).then(res => {
uni.showToast({
title: '删除成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.hasMore = true;
this.loadOrders();
})
}
}
})
}, 500),
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 联系客服
async contactService(phone) {
uni.navigateTo({
url: '/pages/contact/contact'
})
},
// 取消订单
async cancelService(order) {
console.log(order)
uni.showModal({
title: '取消订单',
content: '确定要取消该订单吗?',
success: (res) => {
if (res.confirm) {
let data = {
orderNo: order.number,
amount: order.pay_money,
sjid: this.sjid
}
request.post('/sj/cancelorder', data).then(res => {
uni.showToast({
title: '取消成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.hasMore = true;
this.loadOrders();
}).catch(err => {
console.log(err)
})
}
}
})
},
// 申请退款
async refoundService(order) {
uni.showModal({
title: '申请退款',
content: '确定申请退款?退款后则订单取消!',
success: (res) => {
if (res.confirm) {
let data = {
orderNo: order.number,
amount: order.pay_money,
sjid: this.sjid
}
let url = '';
if (order.pay_kind == 1) {
url = '/'
} else if (order.pay_kind == 2) {
url = '/sj/selfwechatrefund'
} else if (order.pay_kind == 3) {
url = '/sj/selfalirefund'
}
console.log('==========', order, data, url)
request.post(url, data).then(res => {
console.log('申请退款订单返回结果', res)
uni.showToast({
title: '申请退款成功!',
icon: 'none'
})
this.formData.page = 1;
this.orderList = [];
this.hasMore = true;
this.loadOrders();
}).catch(err => {
console.log(err)
})
}
}
})
},
// 支付订单
payOrder(order) {
uni.navigateTo({
url: `/pages/shop/pay-order?id=${order.id}&money=${order.order_money}&title=${order.server_title}&number=${order.number}`
})
},
// 评价订单
reviewOrder(order) {
// uni.navigateTo({
// url: `/pages/order/pay?id=${order.id}`
// })
},
// 再次下单
orderAgain(order) {
uni.navigateTo({
url: '/pages/shop/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.navigateTo({
url: '/pages/blogPopup/blogPopup'
});
}
}
}
</script>
<style>
/* 状态标签栏 */
.status-tabs {
position: sticky;
top: 0;
/* #ifdef H5 */
top: 88rpx;
/* #endif */
left: 0;
right: 0;
height: 112rpx;
background-color: #FFFFFF;
z-index: 99;
white-space: nowrap;
}
.tab-item {
display: inline-block;
height: 88rpx;
line-height: 88rpx;
font-size: 30rpx;
color: #666666;
position: relative;
margin: 0 20rpx;
}
.tab-item.active {
color: #000000;
font-weight: 500;
}
.tab-item.active::after {
content: '';
position: absolute;
width: 32rpx;
height: 6rpx;
left: 50%;
bottom: 0;
transform: translateX(-50%);
background-color: #E8101E;
border-radius: 3rpx;
}
/* 订单列表 */
.order-scroll {
padding: 0 24rpx 24rpx;
margin-top: 24rpx;
height: calc(100vh - 112rpx - 24rpx);
box-sizing: border-box;
}
.order-item {
background-color: #FFFFFF;
border-radius: 20rpx;
margin-bottom: 24rpx;
padding: 24rpx;
box-sizing: border-box;
position: relative;
}
.order-top {
position: relative;
padding-right: 120rpx;
min-height: 40rpx;
}
.order-number {
display: block;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.order-status-badge {
font-weight: 400;
font-size: 26rpx;
color: #E8101E;
text-align: left;
font-style: normal;
position: absolute;
right: -24rpx;
top: -24rpx;
background-image: url("/static/images/icons/tabBj.png");
background-size: 100% auto;
background-position: center top;
background-repeat: no-repeat;
width: 128rpx;
height: 49rpx;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.order-status-badge2 {
background-image: url("/static/images/icons/tabBj2.png");
color: #333333;
}
.order-status-badge3 {
background-image: url("/static/images/icons/tabBj2.png");
color: #999999 !important;
}
.order-content {
display: flex;
align-items: flex-start;
margin-top: 20rpx;
}
.service-image {
width: 162rpx;
height: 162rpx;
border-radius: 24rpx;
margin-right: 20rpx;
background-color: #F5F5F5;
flex-shrink: 0;
}
.service-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.service-name {
font-size: 30rpx;
color: #333333;
line-height: 42rpx;
margin-bottom: 12rpx;
word-break: break-all;
}
.service-time {
display: flex;
align-items: center;
font-size: 24rpx;
line-height: 34rpx;
margin-bottom: 8rpx;
}
.label-text {
color: #666666;
}
.value-text {
color: #999999;
margin-left: 8rpx;
}
.service-address {
display: flex;
align-items: flex-start;
margin-bottom: 10rpx;
}
.location-icon {
width: 24rpx;
height: 24rpx;
margin-right: 6rpx;
margin-top: 4rpx;
flex-shrink: 0;
}
.address-text {
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
word-break: break-all;
}
.price-row {
display: flex;
align-items: baseline;
margin-top: 6rpx;
}
.price-symbol {
font-size: 24rpx;
color: #FF0037;
line-height: 1;
}
.price-now {
font-size: 36rpx;
font-weight: 500;
color: #FF0037;
line-height: 1;
margin-left: 2rpx;
}
.price-old {
font-size: 22rpx;
color: #999999;
text-decoration: line-through;
margin-left: 10rpx;
line-height: 1;
}
.order-actions {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1rpx solid #EEEEEE;
padding-top: 24rpx;
margin-top: 24rpx;
}
.action-left {
display: flex;
align-items: center;
}
.delete-icon {
width: 36rpx;
height: 36rpx;
}
.action-right {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
}
.action-btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 128rpx;
height: 60rpx;
padding: 0 28rpx;
margin-left: 16rpx;
border-radius: 30rpx;
font-size: 24rpx;
box-sizing: border-box;
}
.gray-btn {
background-color: #FFFFFF;
border: 1rpx solid #999999;
color: #333333;
}
.red-btn {
background-color: #FFFFFF;
border: 1rpx solid #E8101E;
color: #E8101E;
}
.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;
}
/* APP适配 */
/* #ifdef APP-PLUS */
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
/* 平台适配 */
/* #ifdef H5 */
/* .order-list {
padding-bottom: env(safe-area-inset-bottom);
} */
/* #endif */
</style>