|
|
<!-- 订单详情 --><template> <s-layout title="订单详情" class="index-wrap" navbar="inner"> <!-- 订单状态 TODO --> <view class="state-box ss-flex-col ss-col-center ss-row-right" :style="[ { marginTop: '-' + Number(statusBarHeight + 88) + 'rpx', paddingTop: Number(statusBarHeight + 88) + 'rpx', }, ]" > <view class="ss-flex ss-m-t-32 ss-m-b-20"> <image v-if=" state.orderInfo.status_code == 'unpaid' || state.orderInfo.status === 10 || // 待发货
state.orderInfo.status_code == 'nocomment' " class="state-img" :src="sheep.$url.static('/static/img/shop/order/order_loading.png')" > </image> <image v-if=" state.orderInfo.status_code == 'completed' || state.orderInfo.status_code == 'refund_agree' " class="state-img" :src="sheep.$url.static('/static/img/shop/order/order_success.png')" > </image> <image v-if="state.orderInfo.status_code == 'cancel' || state.orderInfo.status_code == 'closed'" class="state-img" :src="sheep.$url.static('/static/img/shop/order/order_close.png')" > </image> <image v-if="state.orderInfo.status_code == 'noget'" class="state-img" :src="sheep.$url.static('/static/img/shop/order/order_express.png')" > </image> <view class="ss-font-30">{{ formatOrderStatus(state.orderInfo) }}</view> </view> <view class="ss-font-26 ss-m-x-20 ss-m-b-70"> {{ formatOrderStatusDescription(state.orderInfo) }} </view> </view>
<!-- 收货地址 --> <view class="order-address-box" v-if="state.orderInfo.receiverAreaId > 0"> <view class="ss-flex ss-col-center"> <text class="address-username"> {{ state.orderInfo.receiverName }} </text> <text class="address-phone">{{ state.orderInfo.receiverMobile }}</text> </view> <view class="address-detail"> {{ state.orderInfo.receiverAreaName }} {{ state.orderInfo.receiverDetailAddress }} </view> </view>
<view class="detail-goods" :style="[{ marginTop: state.orderInfo.receiverAreaId > 0 ? '0' : '-40rpx' }]" > <!-- 订单信 --> <view class="order-list" v-for="item in state.orderInfo.items" :key="item.goods_id"> <view class="order-card"> <s-goods-item @tap="onGoodsDetail(item.spuId)" :img="item.picUrl" :title="item.spuName" :skuText="item.properties.map((property) => property.valueName).join(' ')" :price="item.price" :num="item.count" > <template #tool> <view class="ss-flex"> <button class="ss-reset-button apply-btn" v-if="[10, 20, 30].includes(state.orderInfo.status) && item.afterSaleStatus === 0" @tap.stop=" sheep.$router.go('/pages/order/aftersale/apply', { orderId: state.orderInfo.id, itemId: item.id, }) " > 申请售后 </button> <button class="ss-reset-button apply-btn" v-if="item.afterSaleStatus === 10" @tap.stop=" sheep.$router.go('/pages/order/aftersale/detail', { id: item.afterSaleId, }) " > 退款中 </button> <button class="ss-reset-button apply-btn" v-if="item.afterSaleStatus === 20" @tap.stop=" sheep.$router.go('/pages/order/aftersale/detail', { id: item.afterSaleId, }) " > 退款成功 </button> </view> </template> <template #priceSuffix> <button class="ss-reset-button tag-btn" v-if="item.status_text"> {{ item.status_text }} </button> </template> </s-goods-item> </view> </view> </view>
<!-- 自提核销 --> <PickUpVerify :order-info="state.orderInfo" :systemStore="systemStore" ref="pickUpVerifyRef" ></PickUpVerify>
<!-- 订单信息 --> <view class="notice-box"> <view class="notice-box__content"> <view class="notice-item--center"> <view class="ss-flex ss-flex-1"> <text class="title">订单编号:</text> <text class="detail">{{ state.orderInfo.no }}</text> </view> <button class="ss-reset-button copy-btn" @tap="onCopy">复制</button> </view> <view class="notice-item"> <text class="title">下单时间:</text> <text class="detail"> {{ sheep.$helper.timeFormat(state.orderInfo.createTime, 'yyyy-mm-dd hh:MM:ss') }} </text> </view> <view class="notice-item" v-if="state.orderInfo.payTime"> <text class="title">支付时间:</text> <text class="detail"> {{ sheep.$helper.timeFormat(state.orderInfo.payTime, 'yyyy-mm-dd hh:MM:ss') }} </text> </view> <view class="notice-item"> <text class="title">支付方式:</text> <text class="detail">{{ state.orderInfo.payChannelName || '-' }}</text> </view> </view> </view>
<!-- 价格信息 --> <view class="order-price-box"> <view class="notice-item ss-flex ss-row-between"> <text class="title">商品总额</text> <view class="ss-flex"> <text class="detail">¥{{ fen2yuan(state.orderInfo.totalPrice) }}</text> </view> </view> <view class="notice-item ss-flex ss-row-between"> <text class="title">运费</text> <text class="detail">¥{{ fen2yuan(state.orderInfo.deliveryPrice) }}</text> </view> <view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.couponPrice > 0"> <text class="title">优惠劵金额</text> <text class="detail">-¥{{ fen2yuan(state.orderInfo.couponPrice) }}</text> </view> <view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.pointPrice > 0"> <text class="title">积分抵扣</text> <text class="detail">-¥{{ fen2yuan(state.orderInfo.pointPrice) }}</text> </view> <view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.discountPrice > 0"> <text class="title">活动优惠</text> <text class="detail">¥{{ fen2yuan(state.orderInfo.discountPrice) }}</text> </view> <view class="notice-item ss-flex ss-row-between" v-if="state.orderInfo.vipPrice > 0"> <text class="title">会员优惠</text> <text class="detail">-¥{{ fen2yuan(state.orderInfo.vipPrice) }}</text> </view> <view class="notice-item all-rpice-item ss-flex ss-m-t-20"> <text class="title">{{ state.orderInfo.payStatus ? '已付款' : '需付款' }}</text> <text class="detail all-price">¥{{ fen2yuan(state.orderInfo.payPrice) }}</text> </view> <view class="notice-item all-rpice-item ss-flex ss-m-t-20" v-if="state.orderInfo.refundPrice > 0" > <text class="title">已退款</text> <text class="detail all-price">¥{{ fen2yuan(state.orderInfo.refundPrice) }}</text> </view> </view>
<!-- 底部按钮 --> <!-- TODO: 查看物流、等待成团、评价完后返回页面没刷新页面 --> <su-fixed bottom placeholder bg="bg-white" v-if="state.orderInfo.buttons?.length"> <view class="footer-box ss-flex ss-col-center ss-row-right"> <button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('cancel')" @tap="onCancel(state.orderInfo.id)" > 取消订单 </button> <button class="ss-reset-button pay-btn ui-BG-Main-Gradient" v-if="state.orderInfo.buttons?.includes('pay')" @tap="onPay(state.orderInfo.payOrderId)" > 继续支付 </button> <button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('combination')" @tap=" sheep.$router.go('/pages/activity/groupon/detail', { id: state.orderInfo.combinationRecordId, }) " > 拼团详情 </button> <button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('express')" @tap="onExpress(state.orderInfo.id)" > 查看物流 </button> <button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('confirm')" @tap="onConfirm(state.orderInfo.id)" > 确认收货 </button> <button class="ss-reset-button cancel-btn" v-if="state.orderInfo.buttons?.includes('comment')" @tap="onComment(state.orderInfo.id)" > 评价 </button> </view> </su-fixed> </s-layout></template>
<script setup> import sheep from '@/sheep'; import { onLoad, onShow } from '@dcloudio/uni-app'; import { reactive, ref } from 'vue'; import { isEmpty } from 'lodash-es'; import { fen2yuan, formatOrderStatus, formatOrderStatusDescription, handleOrderButtons, } from '@/sheep/hooks/useGoods'; import OrderApi from '@/sheep/api/trade/order'; import DeliveryApi from '@/sheep/api/trade/delivery'; import PickUpVerify from '@/pages/order/pickUpVerify.vue';
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2; const headerBg = sheep.$url.css('/static/img/shop/order/order_bg.png');
const state = reactive({ orderInfo: {}, merchantTradeNo: '', // 商户订单号
comeinType: '', // 进入订单详情的来源类型
});
// ========== 门店自提(核销) ==========
const systemStore = ref({}); // 门店信息
// 复制
const onCopy = () => { sheep.$helper.copyText(state.orderInfo.no); };
// 去支付
function onPay(payOrderId) { sheep.$router.go('/pages/pay/index', { id: payOrderId, }); }
// 查看商品
function onGoodsDetail(id) { sheep.$router.go('/pages/goods/index', { id, }); }
// 取消订单
async function onCancel(orderId) { uni.showModal({ title: '提示', content: '确定要取消订单吗?', success: async function (res) { if (!res.confirm) { return; } const { code } = await OrderApi.cancelOrder(orderId); if (code === 0) { await getOrderDetail(orderId); } }, }); }
// 查看物流
async function onExpress(id) { sheep.$router.go('/pages/order/express/log', { id, }); }
// 确认收货
async function onConfirm(orderId, ignore = false) { // 需开启确认收货组件
// todo: 芋艿:待接入微信
// 1.怎么检测是否开启了发货组件功能?如果没有开启的话就不能在这里return出去
// 2.如果开启了走mpConfirm方法,需要在App.vue的show方法中拿到确认收货结果
let isOpenBusinessView = true; if ( sheep.$platform.name === 'WechatMiniProgram' && !isEmpty(state.orderInfo.wechat_extra_data) && isOpenBusinessView && !ignore ) { mpConfirm(orderId); return; }
uni.showModal({ title: '提示', content: '确认收货吗?', success: async function (res) { if (!res.confirm) { return; } // 正常的确认收货流程
const { code } = await OrderApi.receiveOrder(orderId); if (code === 0) { await getOrderDetail(orderId); } }, }); }
// #ifdef MP-WEIXIN
// 小程序确认收货组件
function mpConfirm(orderId) { if (!wx.openBusinessView) { sheep.$helper.toast(`请升级微信版本`); return; } wx.openBusinessView({ businessType: 'weappOrderConfirm', extraData: { merchant_trade_no: state.orderInfo.wechat_extra_data.merchant_trade_no, transaction_id: state.orderInfo.wechat_extra_data.transaction_id, }, success(response) { console.log('success:', response); if (response.errMsg === 'openBusinessView:ok') { if (response.extraData.status === 'success') { onConfirm(orderId, true); } } }, fail(error) { console.log('error:', error); }, complete(result) { console.log('result:', result); }, }); }
// #endif
// 评价
function onComment(id) { sheep.$router.go('/pages/goods/comment/add', { id, }); }
const pickUpVerifyRef = ref();
async function getOrderDetail(id) { // 对详情数据进行适配
let res; if (state.comeinType === 'wechat') { // TODO 芋艿:微信场景下
res = await OrderApi.getOrderDetail(id, { merchant_trade_no: state.merchantTradeNo, }); } else { res = await OrderApi.getOrderDetail(id); } if (res.code === 0) { state.orderInfo = res.data; handleOrderButtons(state.orderInfo); // 配送方式:门店自提
if (res.data.pickUpStoreId) { const { data } = await DeliveryApi.getDeliveryPickUpStore(res.data.pickUpStoreId); systemStore.value = data || {}; } if (state.orderInfo.deliveryType === 2 && state.orderInfo.payStatus) { pickUpVerifyRef.value && pickUpVerifyRef.value.markCode(res.data.pickUpVerifyCode); } } else { sheep.$router.back(); } }
onShow(async () => { //onShow中获取订单列表,保证跳转后页面为最新状态
await getOrderDetail(state.orderInfo.id); })
onLoad(async (options) => { let id = 0; if (options.id) { id = options.id; } // TODO 芋艿:下面两个变量,后续接入
state.comeinType = options.comein_type; if (state.comeinType === 'wechat') { state.merchantTradeNo = options.merchant_trade_no; } state.orderInfo.id = id });</script>
<style lang="scss" scoped> .score-img { width: 36rpx; height: 36rpx; margin: 0 4rpx; }
.apply-btn { width: 140rpx; height: 50rpx; border-radius: 25rpx; font-size: 24rpx; border: 2rpx solid #dcdcdc; line-height: normal; margin-left: 16rpx; }
.state-box { color: rgba(#fff, 0.9); width: 100%; background: v-bind(headerBg) no-repeat, linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient)); background-size: 750rpx 100%; box-sizing: border-box;
.state-img { width: 60rpx; height: 60rpx; margin-right: 20rpx; } }
.order-address-box { background-color: #fff; border-radius: 10rpx; margin: -50rpx 20rpx 16rpx 20rpx; padding: 44rpx 34rpx 42rpx 20rpx; font-size: 30rpx; box-sizing: border-box; font-weight: 500; color: rgba(51, 51, 51, 1);
.address-username { margin-right: 20rpx; }
.address-detail { font-size: 26rpx; font-weight: 500; color: rgba(153, 153, 153, 1); margin-top: 20rpx; } }
.detail-goods { border-radius: 10rpx; margin: 0 20rpx 20rpx 20rpx;
.order-list { margin-bottom: 20rpx; background-color: #fff;
.order-card { padding: 20rpx 0;
.order-sku { font-size: 24rpx;
font-weight: 400; color: rgba(153, 153, 153, 1); width: 450rpx; margin-bottom: 20rpx;
.order-num { margin-right: 10rpx; } }
.tag-btn { margin-left: 16rpx; font-size: 24rpx; height: 36rpx; color: var(--ui-BG-Main); border: 2rpx solid var(--ui-BG-Main); border-radius: 14rpx; padding: 0 4rpx; } } } }
// 订单信息。
.notice-box { background: #fff; border-radius: 10rpx; margin: 0 20rpx 20rpx 20rpx;
.notice-box__head { font-size: 30rpx;
font-weight: 500; color: rgba(51, 51, 51, 1); line-height: 80rpx; border-bottom: 1rpx solid #dfdfdf; padding: 0 25rpx; }
.notice-box__content { padding: 20rpx;
.self-pickup-box { width: 100%;
.self-pickup--img { width: 200rpx; height: 200rpx; margin: 40rpx 0; } } }
.notice-item, .notice-item--center { display: flex; align-items: center; line-height: normal; margin-bottom: 24rpx;
.title { font-size: 28rpx; color: #999; }
.detail { font-size: 28rpx; color: #333; flex: 1; } } }
.copy-btn { width: 100rpx; line-height: 50rpx; border-radius: 25rpx; padding: 0; background: rgba(238, 238, 238, 1); font-size: 22rpx; font-weight: 400; color: rgba(51, 51, 51, 1); }
// 订单价格信息
.order-price-box { background-color: #fff; border-radius: 10rpx; padding: 20rpx; margin: 0 20rpx 20rpx 20rpx;
.notice-item { line-height: 70rpx;
.title { font-size: 28rpx; color: #999; }
.detail { font-size: 28rpx; color: #333; font-family: OPPOSANS; } }
.all-rpice-item { justify-content: flex-end; align-items: center;
.title { font-size: 26rpx; font-weight: 500; color: #333333; line-height: normal; }
.all-price { font-size: 26rpx; font-family: OPPOSANS; line-height: normal; color: $red; } } }
// 底部
.footer-box { height: 100rpx; width: 100%; box-sizing: border-box; border-radius: 10rpx; padding-right: 20rpx;
.cancel-btn { width: 160rpx; height: 60rpx; background: #eeeeee; border-radius: 30rpx; margin-right: 20rpx; font-size: 26rpx; font-weight: 400; color: #333333; }
.pay-btn { width: 160rpx; height: 60rpx; font-size: 26rpx; border-radius: 30rpx; font-weight: 500; color: #fff; } }</style>
|