<template> <view class="wrap"> <up-navbar placeholder style="z-index: 100800;" @leftClick="navBack"> <template #center> <view>订单</view> </template> </up-navbar> <up-sticky bgColor="#fff"> <view style="padding: 10rpx 20rpx 0 20rpx;"> <up-search shape="round" v-model="keyword" @custom="searchOn" @search="searchOn" @clear="searchOn" :actionStyle="{color: '#20b128'}"></up-search> </view> <up-tabs :current="tabsActive" :list="tablist" lineColor="#20b128" :scrollable="false" :activeStyle=" { color: '#20b128', fontWeight: 'bold' }" @change="changeTab"></up-tabs> </up-sticky> <swiper class="swiper-box" :current="swiperCurrent" @animationfinish="animationfinish"> <swiper-item class="swiper-item" v-for="(list, k) in orderList" :key="k"> <scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="loadMoreGood" @refresherrefresh="refresherrefresh(1)" :refresher-triggered="triggered" refresher-enabled refresher-background="#F6F6F6"> <view class="page-box"> <view v-if="list.length>0" class="list"> <good v-for="(item, index) in list" :datas="item" :key="index" :type="k" :status="status" :order_id='item.order_id' @cancleOrder="cancleOrder" @takeOrder="takeOrder" @rePay="rePay" @purchaseAgain="purchaseAgain" @applyAfterSales="applyAfterSales" @showVerifyFn='showVerifyFn'></good> </view> <view v-if="!where[k].loading&&list.length==0" style="padding-top: 100rpx;"> <up-empty text="订单空空如也" icon="https://lihai001.oss-cn-chengdu.aliyuncs.com/def/29955202404260944367594.png"> </up-empty> </view> <view v-else-if="where[k].loadend" style="padding-top: 100rpx;"> <view style="text-align: center;color: #999;">没有更多了</view> </view> <view v-if="where[k].loading" style="padding-top: 100rpx;display: flex;flex-direction: column;align-items: center;"> <up-loading-icon mode="circle"></up-loading-icon> <view style="margin-top: 20rpx;color: #999;">加载中</view> </view> <view style="width: 100%;height: 300rpx;"></view> </view> </scroll-view> </swiper-item> </swiper> </view> <orderCanclePopup :show="showCancel" @close="showCancel=false" @change="submitCancel" /> <modal :show="showTake" title="确认收货" content="请确认您已收到货" @close="showTake=false" @change="confirmReceipt" /> <!-- 退款原因 --> <up-popup :show="refundShow" closeable round="10" @close="refundShow = false"> <view class="address-popup"> <view class="head-title">选择商品</view> <view class="afterSales-type"> <view class="afterSales-type-title">售后类型</view> <view class="afterSales-type-con"> <view class="afterSales-type-item" :class="{'fuck-active':afterSalesType===0}" @click="afterSalesType=0">仅退款</view> <view class="afterSales-type-item" :class="{'fuck-active':afterSalesType==1}" @click="afterSalesType=1">退款退货</view> <view class="afterSales-type-item" :class="{'fuck-active':afterSalesType==2}" @click="afterSalesType=2">换货</view> </view> <view class="afterSales-type-tip" v-if="afterSalesType===0">当前售后类型仅支持未备货商品</view> <view class="afterSales-type-tip" v-if="afterSalesType==1">当前售后类型仅支持非生鲜类商品</view> <view class="afterSales-type-tip" v-if="afterSalesType==2">当前售后类型仅支持选择单个商品</view> </view> <view class="scroll-wrap"> <scroll-view style="max-height: 50vh;padding-bottom: 20rpx;" scroll-y> <block v-for="(item,index) in goodsList" :key="index"> <view class="goods"> <view class="goods-item"> <view class="goods-item-left"> <view class="goods-item-left-img"> <up-image width="164rpx" height="164rpx" :src="item.image" radius="8rpx" /> </view> <view class="goods-item-left-info"> <view class="goods_name">{{item.store_name}}</view> <view class="goods_detail"> <view class="goods-detail_num">数量{{item.cart_num}}</view> <view class="goods_detail_price"> <text class="symbol">¥</text> <text class="numbers">{{item.price}}</text> </view> </view> </view> </view> <view class="goods-item-right" @click="onChooseGoods(item)"> <image v-if="item.isSelected" src="@/static/icon/check.png"></image> <image v-else src="@/static/icon/n-check.png"></image> </view> </view> </view> </block> </scroll-view> </view> <view style="height: 120rpx;display: flex;justify-content: center;padding: 0 30rpx;align-items: center;" @click="onPageToAfterSales"> <up-button color="#20B128" shape="circle" @click="onSubmitReason">提交</up-button> </view> </view> </up-popup> <view class="mask" v-if='showVerifyPop' @click="showVerifyPop=false"> <view style="position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);background-color: white;padding: 20rpx;"> <up-image :src="orderData.verify_img" width="404rpx" height="60rpx"></up-image> <view style="font-weight: bold;color: #333;font-size: 26;text-align: center;margin-top: 20rpx;"> 核销码 {{orderData.verify_code}} </view> </view> </view> </template> <script setup> import { onLoad, onUnload, onPullDownRefresh } from "@dcloudio/uni-app" import { ref } from 'vue'; import good from "./component/good.vue"; import orderCanclePopup from "@/components/orderCanclePopup.vue" import modal from "@/components/modal.vue" import { cancelOrderApi, rePaymentApi, confirmReceiptApi, orderListApi, purchaseAgainApi } from "@/api/order.js" const tabsActive = ref(0) const changeTab = ({ index }) => { tabsActive.value = index; swiperCurrent.value = index; } const tablist = ref([{ name: '全部' }, { name: '待付款' }, { name: '待核销' }, { name: '已核销' }, { name: '退款/售后' }]); const swiperCurrent = ref(0); const animationfinish = ({ detail: { current } }) => { swiperCurrent.value = current; tabsActive.value = current; if (swiperCurrent.value == 0 && orderList.value[0].length == 0) getOrderList(0, '', ''); //全部 if (swiperCurrent.value == 1 && orderList.value[1].length == 0) getOrderList(1, '', 0); //代付款 if (swiperCurrent.value == 2 && orderList.value[2].length == 0) getOrderList(2, 1, 1); //待核销 if (swiperCurrent.value == 3 && orderList.value[3].length == 0) getOrderList(3, 2, 1); //已核销 if (swiperCurrent.value == 4 && orderList.value[4].length == 0) getOrderList(4, -1, 1); //退款 } const showVerifyPop = ref(false) const orderData = ref({}) const showVerifyFn = (e) => { showVerifyPop.value = true orderData.value = e } // 取消订单 const showCancel = ref(false); let cancelId = ''; const submitCancel = (e) => { showCancel.value = false; cancelOrderApi({ order_id: cancelId, value: e.name }).then(res => { uni.showToast({ title: '取消成功', icon: 'none' }) orderList.value[1] = orderList.value[1].filter(item => item.id !== cancelId) }) } // 取消订单 const cancleOrder = (e) => { cancelId = e.id; showCancel.value = true; } // 确认收货 const showTake = ref(false); let takeId = ""; const takeOrder = (e) => { takeId = e.id; showTake.value = true; } // 确认收货 const confirmReceipt = () => { confirmReceiptApi({ order_id: takeId }).then(res => { showTake.value = false; uni.$u.toast('确认收货成功'); reloadAll(); }) } // 再次购买 const purchaseAgain = (e) => { purchaseAgainApi({ order_id: e.id }).then(res => { uni.$u.toast('已加入购物车'); uni.navigateTo({ url: '/pages/cart/cart' }) }) } // 申请售后<!--sb项目--> const refundShow = ref(false); const goodsList = ref([]); // 申请售后商品 const afterSalesType = ref(''); //申请售后类型 0 1 2 const orderId = ref(''); // 申请售后 const applyAfterSales = (item) => { refundShow.value = true; goodsList.value = item.goods_list; orderId.value = item.id; } // 跳转到申请售后 const onPageToAfterSales = () => { if (afterSalesType.value === '') return uni.$u.toast('请选择售后类型'); if (!goodsList.value || goodsList.value.length == 0) return uni.$u.toast('暂无可申请售后的商品'); let goods = goodsList.value.find(i => i.isSelected); if (goods == undefined) return uni.$u.toast('请选择需要申请售后的商品'); let ids = []; let goodsListSel = []; goodsList.value.map(i => { if (i.isSelected) { ids.push(i.old_cart_id); goodsListSel.push(i); } }); uni.navigateTo({ url: "/pages/afterSales/afterSales", success(res) { refundShow.value = false; // close modal res.eventChannel.emit('orderDetail', { id: orderId.value, //订单id old_cart_id: ids, refund_type: afterSalesType.value, goodsList: goodsListSel }) } }) } // 选择物品 const onChooseGoods = (item) => { if (item.hasOwnProperty('isSelected')) { item.isSelected = !item.isSelected; } else { item.isSelected = true; } } const rePay = (e) => { rePaymentApi({ order_id: e.id, address_id: e.address_id, mer_id: e.merchant, pay_type: e.pay_type }).then(res => { if (!res.data?.nonceStr) return uni.$u.toast('支付失败!'); uni.requestPayment({ provider: 'wxpay', timeStamp: res.data.timeStamp, nonceStr: res.data.nonceStr, package: res.data.package, signType: res.data.signType, paySign: res.data.paySign, success: (e) => { if (e.errMsg == 'requestPayment:ok') { uni.showToast({ title: '订单支付成功', icon: 'success' }) reloadAll(); } else uni.$u.toast('支付失败') }, fail: (e) => { uni.$u.toast('用户取消支付') } }) }).catch(err => { uni.$u.toast(err.msg || '网络错误') }) } // 订单 const where = ref([{ page_no: 1, page_size: 25, loading: false, loadend: false }, { page_no: 1, page_size: 25, loading: false, loadend: false }, { page_no: 1, page_size: 25, loading: false, loadend: false }, { page_no: 1, page_size: 25, loading: false, loadend: false }, { page_no: 1, page_size: 25, loading: false, loadend: false } ]) const keyword = ref('') const orderList = ref([ [], [], [], [], [] ]) const getOrderList = (type = 0, status = '', paid = 1, ifPullReFresh = false) => { if (where.value[type].loadend) return; where.value[type].loading = true; orderListApi({ page_no: where.value[type].page_no, page_size: where.value[type].page_size, order_id: keyword.value, status: status, paid: paid }).then(res => { if (where.value[type].page_no == 1) orderList.value[type] = []; orderList.value[type] = [...orderList.value[type], ...res.data.lists]; if (res.data.lists.length < where.value[type].page_size) where.value[type].loadend = true; where.value[type].page_no++; where.value[type].loading = false; if (ifPullReFresh) uni.stopPullDownRefresh(); }).catch(err => { where.value[type].loading = false; }) } const loadMoreGood = () => { if (swiperCurrent.value == 0) getOrderList(0, '', ''); //全部 if (swiperCurrent.value == 1) getOrderList(1, '', 0); //代付款 if (swiperCurrent.value == 2) getOrderList(2, 1, 1); //待核销 if (swiperCurrent.value == 3) getOrderList(3, 2, 1); //已核销 if (swiperCurrent.value == 4) getOrderList(4, -1, 1); //退款 } // 搜索 const searchOn = (ifPullReFresh = false) => { orderList.value[+swiperCurrent.value] = []; console.log(swiperCurrent.value) where.value[+swiperCurrent.value].page_no = 1; where.value[+swiperCurrent.value].loadend = false; if (swiperCurrent.value == 0) getOrderList(0, '', '', ifPullReFresh); //全部 if (swiperCurrent.value == 1) getOrderList(1, '', 0, ifPullReFresh); //代付款 if (swiperCurrent.value == 2) getOrderList(2, 1, 1, ifPullReFresh); //待核销 if (swiperCurrent.value == 3) getOrderList(3, 2, 1, ifPullReFresh); //已核销 if (swiperCurrent.value == 4) getOrderList(4, -1, 1, ifPullReFresh); //退款 } let back = 0; const navBack = () => { uni.navigateBack({ delta: back ? +back : 0 }) } const reloadAll = () => { //对订单进行操作时刷新页面 where.value.forEach(item => { item.page_no = 1; item.loadend = false; }); getOrderList(0, '', ''); //全部 getOrderList(1, '', 0); //代付款 getOrderList(2, 1, 1); //待核销 getOrderList(3, 2, 1); //已核销 getOrderList(4, -1, 1); //退款 } onLoad((options) => { if (options.type) { tabsActive.value = +options.type; swiperCurrent.value = +options.type; searchOn(); } if (options.back) back = options.back; uni.$on('reLoadOrderList', reloadAll); }) onUnload(() => { uni.$off('reLoadOrderList', reloadAll) }) const triggered = ref(false); let flag = false const refresherrefresh = (type = 1) => { if (flag) return flag = true triggered.value = true; searchOn() console.log("别恶心我了") setTimeout(() => { triggered.value = false; flag = false }, 500) } </script> <style lang="scss"> .wrap { display: flex; flex-direction: column; height: calc(100vh - var(--window-top)); width: 100%; } .swiper-box { flex: 1; } .swiper-item { height: 100%; } .page-box { margin: 20rpx; } .address-popup { // padding: 30rpx; background-color: #F6F6F6; .head-title { font-weight: bold; text-align: center; margin-bottom: 20rpx; padding: 20rpx; } .afterSales-type { margin: 0 20rpx 20rpx; background: #FFFFFF; border-radius: 16rpx; padding: 20rpx; box-sizing: border-box; .afterSales-type-title { font-size: 32rpx; color: #444444; margin-bottom: 28rpx; } .afterSales-type-con { display: flex; align-items: center; margin-bottom: 20rpx; .afterSales-type-item { width: 200rpx; height: 70rpx; line-height: 70rpx; border-radius: 12rpx; color: #777777; border: 2rpx solid #D3D3D3; font-size: 28rpx; text-align: center; &:not(:nth-last-child(1)) { margin-right: 24rpx; } } .fuck-active { color: #FC452F; border: 2rpx solid #FC452F; font-weight: 600; } } .afterSales-type-tip { font-size: 20rpx; color: #FC452F; } } .scroll-wrap { margin: 0 20rpx; background: #FFFFFF; border-radius: 16rpx; padding: 20rpx 20rpx 1rpx; box-sizing: border-box; .goods { .goods-item { display: flex; align-items: center; justify-content: space-between; margin-bottom: 30rpx; .goods-item-left { display: flex; align-items: center; .goods-item-left-img { margin-right: 20rpx; } .goods-item-left-info { display: flex; flex-direction: column; justify-content: space-between; height: 164rpx; .goods_name { font-size: 28rpx; color: #060606; max-width: 400rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .goods_detail { display: flex; align-items: center; .goods-detail_num { margin-right: 30rpx; font-size: 28rpx; color: #333333; } .goods_detail_price { display: flex; .symbol { align-self: flex-end; font-size: 22rpx; color: #333333; } .numbers { font-size: 32rpx; color: #333333; } } } } } .goods-item-right { image { width: 48rpx; height: 48rpx; } } } } } } @keyframes disappear { to { opacity: 0; /* 渐隐 */ transform: scale(0); /* 缩小 */ } } .mask { position: fixed; width: 100vw; height: 100vh; background-color: rgba(0, 0, 0, .5); top: 0; left: 0; z-index: 99999 !important; } </style>