You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yanzong_qianduan/pages/order/detail.vue

915 lines
25 KiB

<template>
<view v-if="!isLoading" class="container" :style="appThemeStyle">
<view class="header">
<!-- 订单状态 -->
<view class="order-status">
<view class="status-icon">
<!-- 进行中的订单 -->
<block v-if="order.order_status == OrderStatusEnum.NORMAL.value">
<!-- 待支付 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<image class="image" src="/static/order/status/wait_pay.png" mode="aspectFit"></image>
</block>
<!-- 待发货 -->
<block v-else-if="order.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<image class="image" src="/static/order/status/wait_deliver.png" mode="aspectFit"></image>
</block>
<!-- 待收货 -->
<block v-else-if="order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
<image class="image" src="/static/order/status/wait_receipt.png" mode="aspectFit"></image>
</block>
</block>
<!-- 已完成 -->
<block v-if="order.order_status == OrderStatusEnum.COMPLETED.value">
<image class="image" src="/static/order/status/received.png" mode="aspectFit"></image>
</block>
<!-- 已取消/待取消 -->
<block v-if="order.order_status == OrderStatusEnum.CANCELLED.value || order.order_status == OrderStatusEnum.APPLY_CANCEL.value">
<image class="image" src="/static/order/status/close.png" mode="aspectFit"></image>
</block>
</view>
<view class="status-text">
<text>{{ order.state_text }}</text>
</view>
</view>
<!-- 下一步操作 -->
<view class="next-action" v-if="order.order_status == OrderStatusEnum.NORMAL.value">
<view v-if="order.pay_status == PayStatusEnum.PENDING.value" class="action-btn" @click="onPay(order.order_id)">
去支付</view>
<view
v-if="order.delivery_status == DeliveryStatusEnum.DELIVERED.value && order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value"
class="action-btn" @click="onReceipt(order.order_id)">确认收货</view>
</view>
</view>
<view class="card-area">
<!-- 实物订单 -->
<block v-if="order.order_type == OrderTypeEnum.PHYSICAL.value">
<!-- 快递配送:配送地址 -->
<view v-if="order.delivery_type == DeliveryTypeEnum.EXPRESS.value" class="delivery-address i-card">
<view class="link-man">
<text class="name">{{ order.address.name }}</text>
<text class="phone">{{ order.address.phone }}</text>
</view>
<view class="address">
<text class="region" v-for="(region, idx) in order.address.region" :key="idx">{{ region }}</text>
<text class="detail">{{ order.address.detail }}</text>
</view>
</view>
<!-- 快递配送:门店自提 -->
<view v-if="order.delivery_type == DeliveryTypeEnum.EXTRACT.value" class="delivery-extract i-card"
@click="handleTargetExtract(order.extract_shop.shop_id)">
<view class="extract-top">
<text class="title">自提门店</text>
<text class="subtitle">您须到该自提点取货</text>
</view>
<view class="shop-info">
<view class="icon-location">
<text class="iconfont icon-dingwei"></text>
</view>
<view class="shop-content">
<view class="shop-name">
<text>{{ order.extract_shop.shop_name }}</text>
</view>
<view class="shop-describe">
<text class="item-text">{{ order.extract_shop.region.province }}</text>
<text class="item-text">{{ order.extract_shop.region.city }}</text>
<text class="item-text">{{ order.extract_shop.region.region }}</text>
<text class="item-text">{{ order.extract_shop.address }}</text>
</view>
</view>
<view class="icon-arrow">
<text class="iconfont icon-arrow-right"></text>
</view>
</view>
</view>
</block>
<!-- 物流信息 -->
<view v-if="order.delivery_type == DeliveryTypeEnum.EXPRESS.value
&& order.delivery_status == DeliveryStatusEnum.DELIVERED.value
&& order.delivery
&& order.delivery.length" class="express i-card" @click="handleTargetExpress()">
<view v-if="order.delivery.length > 1" class="main">
<view class="info-item">
<view class="item-content">
<text>订单已拆分多个包裹发货</text>
</view>
</view>
<view class="info-item">
<view class="item-content">
<text>已发货{{ order.delivery.length }}个包裹</text>
</view>
</view>
</view>
<view v-else class="main">
<view class="info-item">
<view class="item-lable">物流公司</view>
<view class="item-content">
<text
v-if="order.delivery[0].delivery_method != DeliveryMethodEnum.UNWANTED.value">{{ order.delivery[0].express ? order.delivery[0].express.express_name : '--' }}</text>
<text v-else>无需物流</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">物流单号</view>
<view class="item-content">
<text>{{ order.delivery[0].express_no ? order.delivery[0].express_no : '--' }}</text>
<view v-if="order.delivery[0].express_no" class="act-copy" @click.stop="handleCopy(order.delivery[0].express_no)">
<text>复制</text>
</view>
</view>
</view>
</view>
<view class="right-arrow">
<text class="iconfont icon-arrow-right"></text>
</view>
</view>
<!-- 商品列表 -->
<view class="goods-list i-card">
<view class="goods-item" v-for="(goods, idx) in order.goods" :key="idx">
<view class="goods-main" @click="handleTargetGoods(goods.goods_id)">
<!-- 商品图片 -->
<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>
</view>
<!-- 商品售后 -->
<view class="goods-refund">
<text v-if="goods.refund" class="stata-text">已申请售后</text>
<view v-else-if="order.isAllowRefund" class="action-btn" @click.stop="handleApplyRefund(goods.order_goods_id)">申请售后</view>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="order-info i-card">
<view class="info-item">
<view class="item-lable">订单编号</view>
<view class="item-content">
<text>{{ order.order_no }}</text>
<view class="act-copy" @click="handleCopy(order.order_no)">
<text>复制</text>
</view>
</view>
</view>
<view class="info-item">
<view class="item-lable">下单时间</view>
<view class="item-content">
<text>{{ order.create_time }}</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">买家留言</view>
<view class="item-content">
<text>{{ order.buyer_remark ? order.buyer_remark : '--' }}</text>
</view>
</view>
</view>
<!-- 结算信息 -->
<view class="trade-info i-card">
<view class="info-item">
<view class="item-lable">订单金额</view>
<view class="item-content">
<text>¥{{ order.total_price }}</text>
</view>
</view>
<view v-if="order.coupon_money > 0" class="info-item">
<view class="item-lable">优惠券抵扣</view>
<view class="item-content">
<text>-¥{{ order.coupon_money }}</text>
</view>
</view>
<view v-if="order.points_money > 0" class="info-item">
<view class="item-lable">{{ setting.points_name }}抵扣</view>
<view class="item-content">
<text>-¥{{ order.points_money }}</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">运费</view>
<view class="item-content">
<text>+¥{{ order.express_price }}</text>
</view>
</view>
<view v-if="order.update_price.value != '0.00'" class="info-item">
<view class="item-lable">后台改价</view>
<view class="item-content">
<text>{{ order.update_price.symbol }}</text>
<text>¥{{ order.update_price.value }}</text>
</view>
</view>
<view class="divider"></view>
<view class="trade-total">
<text class="lable">实付款</text>
<view class="goods-price">
<text class="unit">¥</text>
<text class="value">{{ order.pay_price }}</text>
</view>
</view>
</view>
</view>
<!-- 底部操作按钮 -->
<view v-if="order.order_status != OrderStatusEnum.CANCELLED.value" class="footer-fixed">
<view class="btn-wrapper">
<!-- 未支付取消订单 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item" @click="onCancel(order.order_id)">取消</view>
</block>
<!-- 已支付进行中的订单 -->
<block v-if="order.order_status != OrderStatusEnum.APPLY_CANCEL.value">
<block v-if="order.pay_status == PayStatusEnum.SUCCESS.value && order.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<view class="btn-item" @click="onCancel(order.order_id)">申请取消</view>
</block>
<!-- 订单核销码 -->
<block v-if="order.pay_status == PayStatusEnum.SUCCESS.value && order.delivery_type == DeliveryTypeEnum.EXTRACT.value
&& order.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<view class="btn-item active" @click="onExtractQRCode(order.order_id)">
<text class="iconfont icon-qr-extract"></text>
<text class="m-l-10">核销码</text>
</view>
</block>
</block>
<!-- 已申请取消 -->
<view v-else class="f-28 col-8">取消申请中</view>
<!-- 未支付的订单 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item active" @click="onPay(order.order_id)">去支付</view>
</block>
<!-- 确认收货 -->
<block
v-if="order.delivery_status == DeliveryStatusEnum.DELIVERED.value && order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
<view class="btn-item active" @click="onReceipt(order.order_id)">确认收货</view>
</block>
<!-- 订单评价 -->
<block v-if="order.order_status == OrderStatusEnum.COMPLETED.value && order.is_comment == 0">
<view class="btn-item" @click="handleTargetComment(order.order_id)">评价</view>
</block>
</view>
</view>
<!-- 核销二维码弹窗 -->
<u-popup v-model="showQRCodePopup" mode="center" border-radius="26" :closeable="true">
<view class="qrcode-popup">
<view class="title">自提核销二维码</view>
<view class="pop-content">
<image v-if="qrcodeImage" class="image" :src="qrcodeImage"></image>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
OrderTypeEnum,
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
ReceiptStatusEnum
} from '@/common/enum/order'
import { DeliveryMethodEnum } from '@/common/enum/order/delivery'
import * as OrderApi from '@/api/order'
export default {
data() {
return {
// 枚举类
OrderTypeEnum,
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
ReceiptStatusEnum,
DeliveryMethodEnum,
// 当前订单ID
orderId: null,
// 加载中
isLoading: true,
// 当前订单详情
order: {},
// 当前设置
setting: {},
// 核销二维码弹窗
showQRCodePopup: false,
// 核销二维码图片url (通过后端获取)
qrcodeImage: '',
// 控制onShow事件是否刷新订单信息
canReset: false,
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad({ orderId }) {
// 当前订单ID
this.orderId = orderId
// 获取当前订单信息
this.getOrderDetail()
// 注册全局事件订阅: 是否刷新当前订单数据
uni.$on('syncRefresh', (val, isCur) => {
if (!isCur) {
this.canReset = val
}
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
this.canReset && this.getOrderDetail()
this.canReset = false
},
methods: {
// 获取当前订单信息
getOrderDetail(canReset = false) {
const app = this
app.isLoading = true
OrderApi.detail(app.orderId)
.then(result => {
app.order = result.data.order
app.setting = result.data.setting
app.isLoading = false
})
// 相应全局事件订阅: 刷新上级页面数据
canReset && uni.$emit('syncRefresh', true, true)
},
// 复制指定内容
handleCopy(value) {
const app = this
uni.setClipboardData({
data: value,
success: () => app.$toast('复制成功'),
fail: ({ errMsg }) => app.$toast('复制失败 ' + errMsg)
})
},
// 跳转到门店详情页
handleTargetExtract(shopId) {
this.$navTo('pages/shop/detail', { shopId })
},
// 跳转到物流跟踪页面
handleTargetExpress() {
this.$navTo('pages/order/express/index', { orderId: this.orderId })
},
// 跳转到商品详情页面
handleTargetGoods(goodsId) {
this.$navTo('pages/goods/detail', { goodsId })
},
// 跳转到申请售后页面
handleApplyRefund(orderGoodsId) {
this.$navTo('pages/refund/apply', { orderGoodsId })
},
// 取消订单
onCancel(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认要取消该订单吗?',
success(o) {
if (o.confirm) {
OrderApi.cancel(orderId)
.then(result => {
// 显示成功信息
app.$toast(result.message)
setTimeout(() => {
// 刷新当前订单数据
app.getOrderDetail(true)
}, 1500)
})
}
}
});
},
// 确认收货
onReceipt(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认收到商品了吗?',
success(o) {
if (o.confirm) {
OrderApi.receipt(orderId)
.then(result => {
// 显示成功信息
app.$success(result.message)
setTimeout(() => {
// 刷新当前订单数据
app.getOrderDetail(true)
}, 1500)
})
}
}
});
},
// 获取核销二维码
onExtractQRCode(orderId) {
const app = this
OrderApi.extractQrcode(orderId, { channel: app.platform })
.then(result => {
app.qrcodeImage = result.data.qrcode
app.showQRCodePopup = true
})
},
// 点击去支付
onPay(orderId) {
this.$navTo('pages/checkout/cashier/index', { orderId })
},
// 跳转到订单评价页
handleTargetComment(orderId) {
this.$navTo('pages/order/comment/index', { orderId })
},
},
}
</script>
<style>
page {
background: #f4f4f4;
}
</style>
<style lang="scss" scoped>
.container {
// 设置ios刘海屏底部横线安全区域
padding-bottom: calc(constant(safe-area-inset-bottom) + 106rpx + 6rpx);
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx + 6rpx);
}
// 页面顶部
.header {
display: flex;
justify-content: space-between;
background-color: #e8c269;
height: 280rpx;
padding: 56rpx 30rpx 0 30rpx;
.order-status {
display: flex;
align-items: center;
height: 128rpx;
.status-icon {
width: 128rpx;
height: 128rpx;
.image {
display: block;
width: 100%;
height: 100%;
}
}
.status-text {
padding-left: 20rpx;
color: #fff;
font-size: 38rpx;
font-weight: bold;
}
}
.next-action {
display: flex;
align-items: center;
height: 128rpx;
.action-btn {
min-width: 152rpx;
height: 56rpx;
padding: 0 30rpx;
background-color: #fff;
border-radius: 28rpx;
border-color: rgb(102, 102, 102);
cursor: pointer;
user-select: none;
color: #c7a157;
display: flex;
justify-content: center;
align-items: center;
}
}
}
// 卡片区域
.card-area {
margin-top: -50rpx;
}
// 通栏卡片
.i-card {
background: #fff;
padding: 24rpx 24rpx;
width: 94%;
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
margin: 0 auto 20rpx auto;
border-radius: 20rpx;
}
// 自提门店
.delivery-extract {
.extract-top {
margin-bottom: 20rpx;
.title {
font-size: 28rpx;
margin-right: 30rpx;
}
.subtitle {
font-size: 24rpx;
color: #888;
}
}
.shop-info {
display: flex;
align-items: center;
}
.icon-location {
font-size: 34rpx;
}
.shop-content {
flex: 1;
margin-left: 26rpx;
font-size: 24rpx;
.shop-name {
font-size: 28rpx;
margin-bottom: 8rpx;
}
.shop-describe {
color: #777;
.item-text {
margin-right: 8rpx;
}
}
}
}
// 收货地址
.delivery-address {
.link-man {
line-height: 46rpx;
color: #333;
.name {
margin-right: 10rpx;
}
}
.address {
margin-top: 12rpx;
color: #999;
font-size: 24rpx;
.detail {
margin-left: 6rpx;
}
}
}
// 物流公司
.express {
display: flex;
align-items: center;
.main {
flex: 1;
}
.info-item {
display: flex;
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
.item-lable {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
margin-right: 30rpx;
}
.item-content {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
.act-copy {
margin-left: 20rpx;
padding: 2rpx 20rpx;
font-size: 22rpx;
color: #666;
border: 1rpx solid #c1c1c1;
border-radius: 16rpx;
}
}
}
// 右侧箭头
.right-arrow {
margin-left: 16rpx;
font-size: 26rpx;
}
}
// 商品列表
.goods-list {
// 商品项
.goods-item {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
// 商品信息
.goods-main {
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;
color: #ababab;
font-size: 24rpx;
overflow: hidden;
.goods-props-item {
padding: 4rpx 16rpx;
border-radius: 12rpx;
background-color: #fcfcfc;
}
}
}
// 交易信息
.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;
}
}
}
// 商品售后
.goods-refund {
display: flex;
justify-content: flex-end;
.stata-text {
font-size: 24rpx;
color: #999;
}
.action-btn {
border-radius: 28rpx;
padding: 8rpx 26rpx;
font-size: 24rpx;
color: #383838;
border: 1rpx solid #a8a8a8;
}
}
}
}
// 订单信息
.order-info {
.info-item {
display: flex;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.item-lable {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
margin-right: 30rpx;
}
.item-content {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
.act-copy {
margin-left: 20rpx;
padding: 2rpx 20rpx;
font-size: 22rpx;
color: #666;
border: 1rpx solid #c1c1c1;
border-radius: 16rpx;
}
}
}
}
// 交易信息
.trade-info {
.info-item {
display: flex;
margin-bottom: 24rpx;
.item-lable {
font-size: 24rpx;
color: #999;
margin-right: 24rpx;
}
.item-content {
flex: 1;
font-size: 26rpx;
color: #333;
text-align: right;
}
}
.divider {
height: 1rpx;
background: #f1f1f1;
margin-bottom: 24rpx;
}
.trade-total {
display: flex;
justify-content: flex-end;
.goods-price {
margin-left: 12rpx;
vertical-align: bottom;
color: $main-bg;
.unit {
margin-right: -2rpx;
font-size: 24rpx;
}
}
}
}
// 底部操作栏
.footer-fixed {
position: fixed;
bottom: var(--window-bottom);
left: 0;
right: 0;
z-index: 11;
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
background: #fff;
// 设置ios刘海屏底部横线安全区域
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btn-wrapper {
height: 106rpx;
display: flex;
align-items: center;
justify-content: flex-end;
padding: 0 30rpx;
}
.btn-item {
min-width: 180rpx;
border-radius: 30rpx;
padding: 12rpx 26rpx;
font-size: 28rpx;
color: #383838;
text-align: center;
border: 1rpx solid #a8a8a8;
margin-left: 24rpx;
&.active {
border: none;
background: linear-gradient(to right, $main-bg, $main-bg2);
color: $main-text;
}
}
}
// 弹出层 - 核销二维码
.qrcode-popup {
padding: 36rpx 30rpx;
.title {
font-size: 30rpx;
margin-bottom: 26rpx;
font-weight: bold;
text-align: center;
}
.pop-content {
min-height: 260rpx;
padding: 0 10rpx;
.image {
display: block;
width: 510rpx;
height: 510rpx;
}
}
}
</style>