Files
wagoo-douy3/src/pages/client/order/list.vue
2026-03-06 13:41:22 +08:00

699 lines
19 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="flex-column-start order-list-container">
<tabs-list :list="tabsList" :isScroll="true" :currentIndex="curTabIndex" @change="onTabChange" />
<view class="order-list-content">
<scroll-view class="list-template-wrapper" :scroll-y="!disableScroll" :refresher-enabled="true"
:refresher-triggered="refreshTriggered" @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
<view class="list-content">
<view v-for="(data, index) in list" :key="data.order_id" :class="{ left: index % 2 === 0 }"
class="flex-column-start news-item">
<order-item :data="data" @disableScroll="disableScrollAction" @cancelOrder="cancelOrderAction"
@concactService="jumpToWeChat" @confirmSliver="confirmSliver" @remindSilver="remindSliver" @pay="pay"
@afterSale="afterSale" @checkSliver="checkSliver" @remark="remark" @remarkDetails="remarkDetails"
@jumpToDetails="jumpToDetails" />
</view>
<uni-load-more v-if="isLoading || (!isLoading && total && total === list.length)"
:status="isLoading ? 'loading' : 'nomore'"></uni-load-more>
</view>
</scroll-view>
<!-- <list-page-temp
:getDataPromise="getShopOrderList"
:requestData="{ status: tabsList[curTabIndex].id }"
:reloadFlag="reloadFlag"
:disableScroll="disableScroll"
>
<template v-slot:item="{ data }">
<order-item
:data="data"
@disableScroll="disableScrollAction"
@cancelOrder="cancelOrderAction"
@concactService="showConcact = true"
@confirmSliver="confirmSliver"
@remindSilver="remindSliver"
@pay="pay"
@afterSale="afterSale"
@checkSliver="checkSliver"
@remark="remark"
@remarkDetails="remarkDetails"
/>
</template>
</list-page-temp> -->
<view v-if="elasticLayer" class="elastic-layer" />
</view>
<!-- 右侧浮动联系客服按钮 -->
<view class="contact-float-btn" :style="{ right: contactBtnRight + 'rpx', bottom: contactBtnBottom + 'rpx' }"
@touchstart="onContactBtnTouchStart" @touchmove="onContactBtnTouchMove" @touchend="onContactBtnTouchEnd"
@click="handleContactBtnClick">
<image class="contact-icon" :src="`${imgPrefix}supportStaff.png`" />
<view class="contact-btn fs-20">
联系客服
</view>
</view>
<view class="additional-bottom" v-if="additionalBom">
<view class="recharge-method">
<view class="method-header">
<text class="payment-title">支付方式</text>
<image src="@/static/images/close.png" mode="aspectFit" class="close-icon"
@click="(additionalBom = false), (elasticLayer = false)" />
</view>
<view class="wechat" @click.stop="selectOption1('1')">
<view class="select">
<image class="w" src="@/static/images/wx.png" mode="widthFix" />
<text class="x">微信</text>
</view>
<image v-if="selected1" class="not-selected" src="@/static/images/w.png" mode="widthFix" />
<image v-if="selected2" class="not-selected" src="@/static/images/y.png" mode="widthFix" />
</view>
<view class="wechat" @click.stop="selectOption2('2')">
<view class="select">
<image class="w" src="@/static/images/wallet.png" mode="widthFix" />
<text class="x">钱包支付</text>
</view>
<image v-if="selected3" class="not-selected" src="@/static/images/w.png" mode="widthFix" />
<image v-if="selected4" class="not-selected" src="@/static/images/y.png" mode="widthFix" />
</view>
</view>
<view class="payment" @click="rechargeNow">
<text class="Z"> 支付 </text>
</view>
</view>
<pop-up-modal v-if="showCancelModal" content="确定要取消该订单吗?" @confirm="orderCancel"
@cancel="showCancelModal = false" />
<contact-modal v-if="showConcact" @close="showConcact = false" />
<pop-up-modal v-if="showSliverModal" content="是否要确认收货?" @confirm="confirmReceiveOrder"
@cancel="showSliverModal = false" />
<success-modal v-if="showRemindSliver" title="提醒成功" message="已通知商家,请耐心等待商家发货" @close="showRemindSliver = false"
@ok="showRemindSliver = false" />
<sliver-info v-if="showSliverRouteModal" :orderId="orderInfo.order_id" :orderInfo="orderInfo"
@close="showSliverRouteModal = false" />
</view>
</template>
<script>
import TabsList from "@/components/TabsList.vue";
import ListPageTemp from "@/components/ListPageTemp.vue";
import OrderItem from "./components/OrderItem.vue";
import PopUpModal from "@/components/PopUpModal.vue";
import SuccessModal from "@/components/SuccessModal.vue";
import ContactModal from "@/components/ContactModal.vue";
import SliverInfo from "./components/SliverInfo.vue";
import { walletTransaction, cancelPetOrderRefund, cancelPetOrderMall } from "../../../api/login";
import {
payOrder,
remindOrder,
getShopOrderList,
cancelOrder,
confirmOrder,
} from "@/api/shop";
import {
SHOP_ORDER_UNPAY,
SHOP_ORDER_UNSLIVER,
SHOP_ORDER_UNRECEIVE,
SHOP_ORDER_DONE,
SHOP_ORDER_CANCEL,
SHOP_ORDER_UNREMARK,
} from "@/constants/app.business";
import { jumpToWeChat, imgPrefix } from "@/utils/common";
export default {
components: {
TabsList,
ListPageTemp,
OrderItem,
PopUpModal,
ContactModal,
SuccessModal,
SliverInfo,
},
data() {
return {
selected1: true,
selected2: false,
selected3: true,
selected4: false,
recharge: true,
record: false,
WeChat: "",
wallet: "",
curTabIndex: 0,
reloadFlag: 0,
additionalBom: false,
elasticLayer: false,
disableScroll: false,
showCancelModal: false,
showConcact: false,
showRemindSliver: false,
showSliverModal: false,
showSliverRouteModal: false,
orderInfo: {},
isLoading: false,
total: 0,
list: [],
refreshTriggered: false,
p: 1,
num: 10,
imgPrefix,
// 联系客服按钮拖拽相关
contactBtnRight: 0, // 默认右侧距离始终为0
contactBtnBottom: 0, // 默认底部距离,需要计算
isDragging: false, // 是否正在拖拽
touchStartX: 0, // 触摸开始X坐标
touchStartY: 0, // 触摸开始Y坐标
initialRight: 0, // 初始右侧距离
initialBottom: 0, // 初始底部距离
};
},
computed: {
tabsList() {
return [
{
name: "全部",
id: 0,
},
{
name: "待支付",
id: SHOP_ORDER_UNPAY,
},
{
name: "待发货",
id: SHOP_ORDER_UNSLIVER,
},
{
name: "待收货",
id: SHOP_ORDER_UNRECEIVE,
},
{
name: "待评价",
id: SHOP_ORDER_UNREMARK,
},
{
name: "已取消",
id: SHOP_ORDER_CANCEL,
},
];
},
},
options: {
styleIsolation: "shared",
},
onLoad() {
this.reloadData();
// 初始化联系客服按钮位置
const systemInfo = uni.getSystemInfoSync();
const windowHeight = systemInfo.windowHeight;
// 计算底部距离calc(35vh - 130rpx - 48rpx) 转换为rpx
// 35vh = windowHeight * 0.35转换为rpx (750rpx = windowHeight px)
const vh35InRpx = (windowHeight * 0.35 / windowHeight) * 750;
this.contactBtnBottom = vh35InRpx - 130 - 48;
},
methods: {
jumpToWeChat,
getShopOrderList,
getList() {
this.isLoading = true;
getShopOrderList({ status: this.tabsList[this.curTabIndex].id })
.then((res) => {
const list = res?.data || [];
this.list = this.p === 1 ? list : [...this.list, data];
this.total = res?.count || 0;
})
.finally(() => {
this.isLoading = false;
this.refreshTriggered = false;
uni.stopPullDownRefresh();
});
},
reloadData() {
this.page = 1;
this.total = 0;
this.getList();
},
onTabChange(item, index) {
this.curTabIndex = index;
this.reloadData();
},
disableScrollAction(val) {
this.disableScroll = val;
},
onRefresh() {
if (this.refreshTriggered) return;
this.refreshTriggered = true;
this.p = 1;
this.num = 10;
this.total = 0;
this.getList();
},
onLoadMore() {
if (!this.isLoading && this.total > this.list.length) {
this.p++;
this.getList();
}
},
orderCancel() {
uni.showLoading({
icon: "none",
title: "处理中",
mask: true,
});
const data = {
order_id: this.orderInfo.order_id,
// business_type:1
}
cancelPetOrderMall(data).then((res) => {
uni.hideLoading();
this.showCancelModal = false;
this.reloadData();
});
},
// 确认收货
confirmSliver(data) {
this.showSliverModal = true;
this.orderInfo = data;
},
// 确认收货
confirmReceiveOrder() {
uni.showLoading({
icon: "none",
title: "处理中",
mask: true,
});
confirmOrder(this.orderInfo.order_id).then((res) => {
uni.hideLoading();
this.reloadData();
this.showSliverModal = false;
});
},
selectOption1(v) {
this.WeChat = v;
this.wallet = "";
console.log(this.WeChat);
this.selected1 = false;
this.selected2 = true;
this.selected3 = true;
this.selected4 = false;
},
selectOption2(v) {
this.WeChat = "";
this.wallet = v;
console.log(this.wallet);
this.selected1 = true;
this.selected2 = false;
this.selected3 = false;
this.selected4 = true;
},
// 支付
pay(data) {
this.additionalBom = true;
this.elasticLayer = true;
this.dataList = data;
},
async rechargeNow() {
// console.log(this.wallet, "???");
if (!this.WeChat && !this.wallet) {
uni.showToast({
title: "请选择充值方式",
icon: "none",
});
return;
}
if (this.WeChat == 1) {
uni.showLoading({
icon: "none",
title: "支付中",
mask: true,
});
payOrder({
type: 4,
total_fee: Number(this.dataList.actual_price),
order_id: this.dataList.order_id,
order_no: this.dataList.order_no
}).then((res) => {
const payData = res?.data || {};
uni.requestPayment({
provider: "wxpay",
timeStamp: payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign,
success: (res) => {
uni.hideLoading();
uni.showToast({
title: "支付成功",
icon: "none",
});
this.additionalBom = false,
this.elasticLayer = false,
this.reloadData();
},
fail: (err) => {
uni.hideLoading();
uni.showToast({
title: err?.msg || "支付失败",
icon: "none",
});
},
});
});
} else if (this.wallet == 2) {
const value = (this.$store.state && this.$store.state.user && this.$store.state.user.userInfo) || {};
// console.log(data, "???");
// console.log(this.selectService,'---')
const data = {
wallet_id: value.wallet_id,
total_fee: this.dataList.actual_price,
type: 4,
order_id: this.dataList.order_id,
order_no: this.dataList.order_no
// business_type: 2,
// wallet_id: value.wallet_id,
// user_id: value.user_id,
// amount: Number(this.dataList.pay_price),
// business_id: this.dataList.order_id,
};
walletTransaction(data).then((res) => {
if (res.code == 0) {
uni.showToast({
title: "支付成功",
icon: "none",
});
this.additionalBom = false,
this.elasticLayer = false,
uni.hideLoading();
this.reloadData();
} else if (res.code == 100) {
uni.showToast({
title: res.message,
icon: "none",
});
}
});
}
// if (!this.giftLabel) {
// uni.showToast({
// title: "请选择充值金额",
// icon: "none",
// });
// return;
// }
},
// 提醒发货
remindSliver(data) {
this.showRemindSliver = true;
// remindOrder(data.order_id).then(() => {
// this.showRemindSliver = true;
// });
},
// 申请售后
afterSale() {
// 如果正在拖拽,不触发点击事件
if (this.isDragging) {
return;
}
this.jumpToWeChat();
},
// afterSale(data) {
// uni.navigateTo({
// url: `/pages/client/order/refund?orderId=${data.order_id}`,
// events: {
// refreshData: () => this.reloadData(),
// },
// });
// },
// 订单详情
jumpToDetails(data) {
uni.navigateTo({
url: `/pages/client/order/details?id=${data?.order_id}`,
events: {
refreshData: () => this.reloadData(),
},
});
},
// 查看物流
checkSliver(data) {
this.showSliverRouteModal = true;
this.orderInfo = data;
},
// 立即评价
remark(data) {
uni.navigateTo({
url: `/pages/client/order/remark?orderId=${data.order_id}`,
events: {
refreshData: () => this.reloadData(),
},
});
},
// 查看评价
remarkDetails(data) {
if (!data.pinglun_id) {
uni.showToast({
title: "暂无评价",
icon: "none",
});
return;
}
uni.navigateTo({
url: `/pages/client/remark/details?remarkId=${data.pinglun_id}`,
});
},
// 取消订单
cancelOrderAction(data) {
this.showCancelModal = true;
this.orderInfo = data;
},
// 联系客服按钮触摸开始
onContactBtnTouchStart(e) {
this.isDragging = false;
const touch = e.touches[0];
this.touchStartX = touch.clientX;
this.touchStartY = touch.clientY;
this.initialRight = this.contactBtnRight;
this.initialBottom = this.contactBtnBottom;
},
// 联系客服按钮触摸移动
onContactBtnTouchMove(e) {
const touch = e.touches[0];
const deltaX = touch.clientX - this.touchStartX;
const deltaY = touch.clientY - this.touchStartY;
// 如果移动距离超过10px认为是拖拽
if (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10) {
this.isDragging = true;
}
if (this.isDragging) {
const systemInfo = uni.getSystemInfoSync();
const windowHeight = systemInfo.windowHeight;
// 只处理上下移动将px转换为rpx
const deltaYRpx = (deltaY / windowHeight) * 750;
// 计算新位置只改变bottomright始终保持为0
// 向上移动时deltaY为负但bottom值应该减小
let newBottom = this.initialBottom - deltaYRpx;
// 限制在屏幕范围内
// 按钮高度约120rpx
const btnHeight = 120;
newBottom = Math.max(0, Math.min(newBottom, windowHeight * 2 - btnHeight));
// right始终保持为0
this.contactBtnRight = 0;
this.contactBtnBottom = newBottom;
}
},
// 联系客服按钮触摸结束
onContactBtnTouchEnd(e) {
// 松手后right重置为0
this.contactBtnRight = 0;
this.isDragging = false;
},
// 联系客服按钮点击
handleContactBtnClick() {
// 如果正在拖拽,不触发点击事件
if (this.isDragging) {
return;
}
this.jumpToWeChat();
},
},
};
</script>
<style lang="scss" scoped>
.order-list-container {
height: 100%;
align-items: stretch;
justify-content: flex-start;
.elastic-layer {
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: flex-end;
z-index: 999;
}
.additional-bottom {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 9999;
background: #fff;
border-radius: 30rpx 30rpx 0 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.recharge-method {
display: flex;
flex-direction: column;
background: #fff;
padding: 40rpx 0 30rpx;
border-radius: 30rpx;
width: 100%;
box-sizing: border-box;
.method-header {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30rpx;
position: relative;
padding: 0 30rpx;
box-sizing: border-box;
}
.payment-title {
font-family: PingFangSC;
font-size: 32rpx;
font-weight: 500;
color: #272427;
text-align: center;
flex: 1;
}
.close-icon {
width: 50rpx;
height: 50rpx;
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
}
.wechat {
width: 100%;
height: 116rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 60rpx;
box-sizing: border-box;
.select {
display: flex;
align-items: center;
.w {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.x {
font-size: 32rpx;
color: #272427;
}
}
.not-selected {
width: 40rpx;
height: 40rpx;
}
}
}
.payment {
position: relative;
border-radius: 100rpx;
margin: auto;
width: calc(100% - 60rpx);
height: 96rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #FF19A0;
background: #FF19A0;
box-sizing: border-box;
.Z {
font-family: PingFang SC;
font-size: 32rpx;
font-weight: normal;
color: #fff;
}
}
}
.order-list-content {
flex: 1;
overflow: hidden;
background: #f7f8fa;
.list-template-wrapper {
height: 100%;
width: 100%;
.list-content {
width: 100%;
}
.news-item {
width: 100%;
}
}
}
.contact-float-btn {
position: fixed;
text-align: center;
z-index: 100;
.contact-icon {
width: 66rpx;
height: 66rpx;
margin: auto;
}
.contact-btn {
color: #FFFFFF;
background-color: #FF19A0;
border-radius: 257px;
padding: 6rpx 8rpx;
transform: translateY(-8px);
}
}
}
</style>