Files
oil/mobile-uniapp/pages/order/index.vue
T
vipnub fafd3e2c16 1、合作商余额查询
2、分油账户司机可用额度
2026-10-20 23:21:10 +08:00

695 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="container">
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }" @down="downCallback" :up="upOption" @up="upCallback">
<!-- tab栏 -->
<u-tabs :list="tabs" :is-scroll="false" :current="curTab" active-color="#FA2209" :duration="0.2" @change="onChangeTab" />
<!-- 订单列表 -->
<view class="order-list">
<view class="order-item" v-for="(item, index) in list.data" :key="index">
<view class="item-top">
<view class="item-top-left">
<text class="order-time">{{ item.create_time }}</text>
</view>
<view class="item-top-right">
<text class="state-text">{{ item.state_text }}</text>
</view>
</view>
<!-- 商品列表 -->
<view class="goods-list" @click="handleTargetDetail(item.order_id)">
<view class="goods-child" v-for="(goods, idx) in item.goods" :key="idx">
<view class="goods-item">
<!-- 商品图片 -->
<view class="goods-image">
<image class="image" :src="goods.goods_image" mode="scaleToFill"></image>
</view>
<!-- 商品信息 -->
<view class="goods-content">
<view class="goods-title"><text class="twoline-hide">{{ goods.goods_name }}</text></view>
<view class="goods-props clearfix">
<view class="goods-props-item" v-for="(props, idx) in goods.goods_props" :key="idx">
<text>{{ props.value.name }}</text>
</view>
</view>
</view>
<!-- 交易信息 -->
<view class="goods-trade">
<view class="goods-price">
<text class="unit">¥</text>
<text class="value">{{ goods.is_user_grade ? goods.grade_goods_price : goods.goods_price }}</text>
</view>
<view class="goods-num">
<text>×{{ goods.total_num }}</text>
</view>
<!-- 申请支付码 -->
<view class="goods-refund">
<text v-if="goods.refund_status == 2" class="stata-text">已退款</text>
<text v-else-if="goods.oil_status && oilRemain(goods) <= 0" class="stata-text">已加完</text>
<!-- #ifdef MP-WEIXIN -->
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="layerPayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
<!-- #ifdef !MP-WEIXIN -->
<view v-else-if="item.order_status === 10 && goods.oil_status" class="action-btn" @click.stop="handlePayQrcode(goods.order_goods_id)">去加油</view>
<!-- #endif -->
</view>
</view>
</view>
<!-- 发放进度:7.7 运单油费下发是异步的,受理后要等上游发放结果 -->
<view v-if="goods.oilCardType === 'zsy_ticket' && goods.oilCardNo && !goods.oil_status" class="order-countdown">
<text v-if="goods.oil_status_zsy == 3" class="f-24 col-m">发放失败:{{ goods.oil_text || '请联系客服' }}</text>
<text v-else class="f-24 col-9">油费发放中,请稍候…</text>
</view>
<!-- 加油进度:一张订单可以分多次加油 -->
<view v-if="goods.used_num > 0" class="order-countdown">
<text class="f-24 col-9">已加油¥{{ goods.used_amount }}({{ goods.used_num }}次),剩余¥{{ oilRemain(goods).toFixed(2) }}</text>
</view>
<!-- 过期剩余时间 -->
<view v-if="item.order_status === 10 && goods.oil_status && !goods.use_status && goods.expiration_time > 0" class="order-countdown">
<text class="m-r-6">剩余时间</text>
<count-down :date="goods.expiration_time" separator="zh" theme="text" />
</view>
</view>
</view>
<!-- 订单合计 -->
<view class="order-total">
<text>共{{ item.total_num }}件商品,总金额</text>
<text class="unit">¥</text>
<text class="money">{{ item.pay_price }}</text>
</view>
<!-- 订单操作 -->
<view v-if="item.order_status != OrderStatusEnum.CANCELLED.value" class="order-handle">
<view class="btn-group clearfix">
<!-- 未支付取消订单 -->
<!--<block v-if="item.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item" @click="onCancel(item.order_id)">取消</view>
</block>-->
<!-- 已支付进行中的订单 -->
<!-- <block v-if="item.order_status != OrderStatusEnum.APPLY_CANCEL.value">
<block v-if="item.pay_status == PayStatusEnum.SUCCESS.value && item.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<view class="btn-item" @click="onCancel(item.order_id)">申请取消</view>
</block>
</block> -->
<!-- 已申请取消 -->
<!-- <view v-else class="f-28 col-8">取消申请中</view> -->
<!-- 未支付的订单 -->
<!-- <block v-if="item.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item active" @click="onPay(item.order_id)">去支付</view>
</block> -->
<!-- 确认收货 -->
<!-- <block v-if="item.delivery_status == DeliveryStatusEnum.DELIVERED.value && item.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
<view class="btn-item active" @click="onReceipt(item.order_id)">确认收货</view>
</block> -->
<!-- 订单评价 -->
<!-- <block v-if="item.order_status == OrderStatusEnum.COMPLETED.value && item.is_comment == 0">
<view class="btn-item" @click="handleTargetComment(item.order_id)">评价</view>
</block> -->
</view>
</view>
</view>
</view>
</mescroll-body>
<!-- 支付方式弹窗 -->
<u-popup v-model="showPayPopup" mode="bottom" border-radius="26" :closeable="true">
<view class="pay-popup">
<view class="title">请选择支付方式</view>
<view class="pop-content">
<!-- 微信支付 -->
<!-- #ifdef MP-WEIXIN -->
<view class="pay-item dis-flex flex-x-between" @click="onSelectPayType(PayTypeEnum.WECHAT.value)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon wechat">
<text class="iconfont icon-wechat-pay"></text>
</view>
<view class="item-left_text">
<text>{{ PayTypeEnum.WECHAT.name }}</text>
</view>
</view>
</view>
<!-- #endif -->
<!-- 余额支付 -->
<view class="pay-item dis-flex flex-x-between" @click="onSelectPayType(PayTypeEnum.BALANCE.value)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon balance">
<text class="iconfont icon-balance-pay"></text>
</view>
<view class="item-left_text">
<text>{{ PayTypeEnum.BALANCE.name }}</text>
</view>
</view>
</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
PayTypeEnum,
ReceiptStatusEnum
} from '@/common/enum/order'
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
import * as OrderApi from '@/api/order'
import { wxPayment } from '@/core/app'
import CountDown from '@/components/countdown'
// 每页记录数量
const pageSize = 15
// tab栏数据
const tabs = [{
name: `全部`,
value: 'all'
}, {
name: `待支付`,
value: 'payment'
},
{
name: `进行中`,
value: 'progress'
},
{
name: `已完成`,
value: 'complete'
}
/*{
name: `待发货`,
value: 'delivery'
}, {
name: `待收货`,
value: 'received'
}, {
name: `待评价`,
value: 'comment'
}*/]
export default {
components: {
MescrollBody,
CountDown
},
mixins: [MescrollMixin],
data() {
return {
// 枚举类
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
PayTypeEnum,
ReceiptStatusEnum,
// 当前页面参数
options: { dataType: 'all' },
// tab栏数据
tabs,
// 当前标签索引
curTab: 0,
// 订单列表数据
list: getEmptyPaginateObj(),
// 上拉加载配置
upOption: {
// 首次自动执行
auto: true,
// 每页数据的数量; 默认10
page: { size: pageSize },
// 数量要大于4条才显示无更多数据
noMoreSize: 4,
// 空布局
empty: {
tip: '亲,暂无订单记录'
}
},
// 控制onShow事件是否刷新订单列表
canReset: false,
// 支付方式弹窗
showPayPopup: false
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 初始化当前选中的标签
this.initCurTab(options)
// 注册全局事件订阅: 是否刷新订单列表
uni.$on('syncRefresh', canReset => {
this.canReset = canReset
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
this.canReset && this.onRefreshList()
this.canReset = false
},
/**
* 生命周期函数--监听页面的卸载
*/
onUnload() {
// 卸载全局事件订阅
uni.$off('syncRefresh')
},
methods: {
// 初始化当前选中的标签
initCurTab(options) {
const app = this
if (options.dataType) {
const index = app.tabs.findIndex(item => item.value == options.dataType)
app.curTab = index > -1 ? index : 0
}
},
/**
* 上拉加载的回调 (页面初始化时也会执行一次)
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
* @param {Object} page
*/
upCallback(page) {
const app = this
// 设置列表数据
app.getOrderList(page.num)
.then(list => {
const curPageLen = list.data.length
const totalSize = list.data.total
app.mescroll.endBySize(curPageLen, totalSize)
})
.catch(() => app.mescroll.endErr())
},
// 获取订单列表
getOrderList(pageNo = 1) {
const app = this
return new Promise((resolve, reject) => {
OrderApi.list({ dataType: app.getTabValue(), page: pageNo }, { load: false })
.then(result => {
// 合并新数据
const newList = app.initList(result.data.list)
app.list.data = getMoreListData(newList, app.list, pageNo)
resolve(newList)
})
})
},
// 初始化订单列表数据
initList(newList) {
newList.data.forEach(item => {
item.total_num = 0
item.goods.forEach(goods => {
item.total_num += goods.total_num
})
})
return newList
},
// 获取当前标签项的值
getTabValue() {
return this.tabs[this.curTab].value
},
// 切换标签项
onChangeTab(index) {
const app = this
// 设置当前选中的标签
app.curTab = index
// 刷新订单列表
app.onRefreshList()
},
// 刷新订单列表
onRefreshList() {
this.list = getEmptyPaginateObj()
setTimeout(() => {
this.mescroll.resetUpScroll()
}, 120)
},
// 取消订单
onCancel(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认要取消该订单吗?',
success(o) {
if (o.confirm) {
OrderApi.cancel(orderId)
.then(result => {
// 显示成功信息
app.$toast(result.message)
// 刷新订单列表
app.onRefreshList()
})
}
}
});
},
// 剩余可加油金额 = 发放金额 - 已加油 - 已退款(一单可分多次加油)
oilRemain(goods) {
const total = Number(goods.total_price || 0)
const used = Number(goods.used_amount || 0)
const refund = Number(goods.refund_amount || 0)
return Math.max(0, Math.round((total - used - refund) * 100) / 100)
},
// 获取核销码,弹窗展示二维码
layerPayQrcode(orderGoodsId) {
uni.navigateTo({
url: `/pages/qrcode/index?id=`+orderGoodsId
});
},
// 获取核销码,跳转第三方连接
handlePayQrcode(orderGoodsId) {
const app = this
app.isLoading = true
OrderApi.qrCode(app.orderId, {orderGoodsId: orderGoodsId})
.then(result => {
uni.navigateTo({
url: `/pages/webview/webview?url=`+encodeURIComponent(result.data.qrCode)
});
app.isLoading = false
})
},
// 确认收货
onReceipt(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认收到商品了吗?',
success(o) {
if (o.confirm) {
OrderApi.receipt(orderId)
.then(result => {
// 显示成功信息
app.$success(result.message)
// 刷新订单列表
app.onRefreshList()
})
}
}
});
},
// 点击去支付
onPay(orderId) {
// 记录订单id
this.payOrderId = orderId
// 显示支付方式弹窗
this.showPayPopup = true
},
// 选择支付方式
onSelectPayType(payType) {
const app = this
// 隐藏支付方式弹窗
this.showPayPopup = false
// 发起支付请求
OrderApi.pay(app.payOrderId, payType)
.then(result => app.onSubmitCallback(result))
},
// 订单提交成功后回调
onSubmitCallback(result) {
const app = this
// 发起微信支付
if (result.data.pay_type == PayTypeEnum.WECHAT.value) {
wxPayment(result.data.payment)
.then(() => {
app.$success('支付成功')
setTimeout(() => {
app.onRefreshList()
}, 1500)
})
.catch(err => {
app.$error('订单未支付')
})
.finally(() => {
app.disabled = false
})
}
// 余额支付
if (result.data.pay_type == PayTypeEnum.BALANCE.value) {
app.$success('支付成功')
app.disabled = false
setTimeout(() => {
app.onRefreshList()
}, 1500)
}
},
// 跳转到订单详情页
handleTargetDetail(orderId) {
this.$navTo('pages/order/detail', { orderId })
},
// 跳转到订单评价页
handleTargetComment(orderId) {
this.$navTo('pages/order/comment/index', { orderId })
}
},
}
</script>
<style lang="scss" scoped>
// 项目内容
.order-item {
margin: 20rpx auto 20rpx auto;
padding: 30rpx 30rpx;
width: 94%;
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
border-radius: 16rpx;
background: #fff;
}
// 项目顶部
.item-top {
display: flex;
justify-content: space-between;
font-size: 26rpx;
margin-bottom: 40rpx;
.order-time {
color: #777;
}
.state-text {
color: $uni-text-color-active;
}
}
// 商品列表
.goods-list {
.goods-child{
margin-bottom: 40rpx;
.order-countdown {
display: flex;
justify-content: flex-end;
font-size: 14px;
color: #fa2209;
align-items: center;
gap: 10px;
margin-top: 10px;
}
}
// 商品项
.goods-item {
display: flex;
// 商品图片
.goods-image {
width: 180rpx;
height: 180rpx;
.image {
display: block;
width: 100%;
height: 100%;
border-radius: 8rpx;
}
}
// 商品内容
.goods-content {
flex: 1;
padding-left: 16rpx;
padding-top: 16rpx;
.goods-title {
font-size: 26rpx;
max-height: 76rpx;
}
.goods-props {
margin-top: 14rpx;
height: 40rpx;
color: #ababab;
font-size: 24rpx;
overflow: hidden;
.goods-props-item {
display: inline-block;
margin-right: 14rpx;
padding: 4rpx 16rpx;
border-radius: 12rpx;
background-color: #F5F5F5;
width: auto;
}
}
}
// 交易信息
.goods-trade {
padding-top: 16rpx;
width: 150rpx;
text-align: right;
color: $uni-text-color-grey;
font-size: 26rpx;
.goods-price {
vertical-align: bottom;
margin-bottom: 16rpx;
.unit {
margin-right: -2rpx;
font-size: 24rpx;
}
}
}
}
}
// 订单合计
.order-total {
font-size: 26rpx;
vertical-align: bottom;
text-align: right;
height: 40rpx;
margin-bottom: 30rpx;
.unit {
margin-left: 8rpx;
margin-right: -2rpx;
font-size: 26rpx;
}
.money {
font-size: 28rpx;
}
}
// 订单操作
.order-handle {
.btn-group {
.btn-item {
border-radius: 10rpx;
padding: 6rpx 20rpx;
margin-left: 15rpx;
font-size: 28rpx;
float: right;
color: #383838;
border: 1rpx solid #a8a8a8;
&:last-child {
margin-left: 0;
}
&.active {
color: $uni-text-color-active;
border: 1rpx solid $uni-text-color-active;
}
}
}
}
// 弹出层-支付方式
.pay-popup {
padding: 24rpx;
.title {
font-size: 30rpx;
margin-bottom: 40rpx;
font-weight: bold;
text-align: center;
}
.pop-content {
min-height: 260rpx;
padding: 0 10rpx;
.pay-item {
padding: 24rpx 35rpx;
font-size: 28rpx;
border-bottom: 1rpx solid #f1f1f1;
&:last-child {
border-bottom: none;
}
.item-left_icon {
margin-right: 20rpx;
font-size: 32rpx;
&.wechat {
color: #00c800;
}
&.balance {
color: #ff9700;
}
}
}
}
}
// 商品售后
.goods-refund {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.stata-text {
font-size: 24rpx;
color: #999;
}
.action-btn {
border-radius: 28rpx;
padding: 8rpx 26rpx;
font-size: 24rpx;
color: #383838;
border: 1rpx solid #a8a8a8;
}
}
</style>