437 lines
11 KiB
Vue
Raw Normal View History

2025-05-08 09:16:37 +08:00
<template>
<view class="whole">
<view class="info" v-if="puInfo.status === 0 || puInfo.status === 1 || puInfo.status === 9">
<view class="title1">
<text>{{pickupTime}}</text>快递员将上门取件
</view>
<view v-if="puInfo.driver == 'kdn'">
<view class="title2">
取件码<text>{{puInfo.pickup_code}}</text>
</view>
<view class="tit">请在快递员上门后出示取件码</view>
</view>
<view class="tit" v-else-if="puInfo.driver == 'jd' && puInfo.reason" style="margin-top: 30rpx;">
<text v-for="(list, index) in mobilePhoneArray(puInfo.reason)" :key="index" @click="callPhone"
:data-phone="list.type == 'phone' ? list.val : ''" :class="list.type == 'phone' ? 'phoneColor' : ''">
{{ list.val }}
</text>
</view>
</view>
<view class="info" v-if="puInfo.status === 5">
<view class="title">已取消</view>
<view class="tit">您已取消本次上门取件</view>
</view>
<view class="twolist">
<view class="addrbox">
<view class="item">
<view class="icon ji"></view>
<view class="addr addr1">
<view class="box">
<view class="tit">{{puInfo.sender_name}}&nbsp;&nbsp;{{puInfo.sender_mobile || puInfo.sender_tel}}</view>
<text>{{puInfo.sender_province_name}}{{puInfo.sender_city_name}}{{puInfo.sender_area_name}}{{puInfo.sender_address_detail}}</text>
</view>
</view>
</view>
<view class="item">
<view class="icon"></view>
<view class="addr">
<view class="box">
<view class="tit">{{puInfo.receiver_name}}&nbsp;&nbsp;{{puInfo.receiver_mobile || puInfo.receiver_tel}}</view>
<text>{{puInfo.receiver_province_name}}{{puInfo.receiver_city_name}}{{puInfo.receiver_area_name}}{{puInfo.receiver_address_detail}}</text>
</view>
</view>
</view>
</view>
<view class="sendInfo">
<view class="row"><text>寄件方式</text>快递员上门取件</view>
<view class="row"><text>寄件编号</text>{{puInfo.pickup_sn}}</view>
<view class="row"><text>下单时间</text>{{puInfo.created_at}}</view>
<view class="row" v-if="puInfo.delivery_company && puInfo.delivery_company.name"><text>快递公司</text>{{puInfo.delivery_company.name}}</view>
<view class="row" v-if="puInfo.ship_sn"><text>快递单号:</text><text style="color: #F14939;">{{puInfo.ship_sn}}</text></view>
<view class="row" v-if="puInfo.person_name || puInfo.person_tel">
<text>快递员</text>{{puInfo.person_name}}
&nbsp;<text style="color: #2282dd;" v-if="puInfo.person_tel" :data-phone="puInfo.person_tel" @click="clickMakePhoneCall()">{{puInfo.person_tel}}</text>
</view>
<view class="good" v-for="it in puInfo.items">
<image :src="it.pic_url" mode="aspectFill" class="img"></image>
<view>{{it.goods_name}}<br>{{it.sku_name}}</view>
</view>
</view>
</view>
<view class="bottom" v-if="puInfo.status === 0 || puInfo.status === 1">
<view class="btn" @click="showCancel = true">取消寄件</view>
<view class="btn red" @click="showModify = true">修改寄件信息</view>
</view>
<!-- 修改寄件信息弹出框 -->
<up-modal
:show="showModify"
title="提示信息"
content="可修改地址信息和上门时间,是否去修改?"
confirmText="去修改"
cancelText="取消"
:confirmColor="Color"
:showCancelButton="true"
@confirm="toModify()"
@cancel="showModify = false">
</up-modal>
<!-- 取消寄件 -->
<up-popup :show="showCancel" :round="10" mode="bottom" close-on-click-overlay closeable @close="showCancel = false">
<view class="typebox">
<view class="title">选择取消原因</view>
<view class="box">
<view class="row" v-for="(item, index) in reasonList" @click="selectReason(item.id)">
<text>{{item.name}}</text>
<span v-if="reason === item.id" class="iconfont icon-checked"></span>
<span v-else class="iconfont icon-circle"></span>
</view>
</view>
<view class="btn" @click="handleSelect()">确认取消</view>
</view>
</up-popup>
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import { get, post } from '@/api/request.js'
export default {
setup() {
const data = reactive({
pickup_id: '',
refund_id: '',
puInfo: {},
showModify: false,
showCancel: false,
reasonList: [
{ id: 1, name: "预约信息有误" },
{ id: 2, name: "快递员无法取件" },
{ id: 3, name: "上门太慢" },
{ id: 4, name: "运费太贵" },
{ id: 7, name: "联系不上快递员" },
{ id: 8, name: "快递员要求取消" },
{ id: 9, name: "超时未接单" },
{ id: 11, name: "其他(如疫情管控,无法寄件)" }
],
reason: 1,
pickupTime: '',
Color: uni.getStorageSync('theme_color')
})
// 获取取件详情
function getPickUpInfo() {
get(`/api/v1/pickup/${data.pickup_id}`).then((res) => {
data.puInfo = res.data
let date = res.data.start_date.split(' ')[0]
let start = res.data.start_date.split(' ')[1].substr(0, 5)
let end = res.data.end_date.split(' ')[1].substr(0, 5)
let today = new Date().setHours(0, 0, 0, 0)
let dayStr = new Date(date.replace(/-/g, "/")).setHours(0, 0, 0, 0)
let dateObj = {
0: '今天',
86400000: '明天',
172800000: '后天'
}
data.pickupTime = (dateObj[dayStr - today] || date) + start + '-' + end
})
}
function toModify() {
data.showModify = false
uni.navigateTo({
url: '/pages/mine/refund/sendgoods/index?pickup_id=' + data.pickup_id + '&refund_id=' + data.refund_id
})
}
function selectReason(id) {
data.reason = id
}
// 取消寄件
function handleSelect() {
let params = {
order_refund_apply_id: data.refund_id,
cancel_type: data.reason,
cancel_msg: ''
}
post('/api/v1/pickup/cancel/' + data.pickup_id, params).then((res) => {
data.showCancel = false
getPickUpInfo()
})
}
const clickMakePhoneCall = () => {
uni.makePhoneCall({
phoneNumber: data.puInfo.person_tel
})
}
const callPhone = (e) => {
uni.makePhoneCall({
phoneNumber: e.currentTarget.dataset.phone
})
}
const mobilePhoneArray = (strContent) => {
let list = []
const mobileReg = /(1[3|4|5|7|8][\d]{9}|0[\d]{2,3}-[\d]{7,8}|0[\d]{2,3}[\d]{7,8}|400[-]?[\d]{3}[-]?[\d]{4})/g
const phoneList = strContent.match(mobileReg)
const textList = strContent.split(mobileReg)
if (phoneList == null) {
list.push({
type: 'text',
val: textList[0],
})
return list
}
textList.forEach((item) => {
if (phoneList.indexOf(item) > -1) {
list.push({
type: 'phone',
val: item,
})
} else {
list.push({
type: 'text',
val: item,
})
}
})
return list
}
return {
...toRefs(data),
toModify,
selectReason,
handleSelect,
getPickUpInfo,
clickMakePhoneCall,
mobilePhoneArray,
callPhone
}
},
onLoad(options) {
this.pickup_id = options.pickup_id
this.refund_id = options.refund_id
},
onShow() {
this.getPickUpInfo()
}
}
</script>
<style lang="scss" scoped>
.whole {
padding: 30rpx 30rpx 110rpx;
box-sizing: border-box;
.info{
padding: 50rpx 0;
background: #fff;
text-align: center;
border-radius: 10rpx;
margin-bottom: 20rpx;
.title1{
color: #111;
font-size: 36rpx;
font-weight: bold;
text{
color: v-bind('Color');
}
}
.title2{
color: #111;
font-size: 44rpx;
font-weight: bold;
margin: 28rpx 0 16rpx;
text{
color: v-bind('Color');
}
}
.tit{
color: #7B7B7B;
font-size: 26rpx;
padding: 0 30rpx;
.phoneColor {
color: #61b8fd;
}
}
.title{
color: #98989F;
font-size: 50rpx;
font-weight: bold;
padding: 44rpx 0 40rpx;
}
}
.twolist{
background: #fff;
border-radius: 10rpx;
}
.addrbox{
padding: 0 30rpx;
.item{
display: flex;
align-items: center;
justify-content: space-between;
.addr{
width: calc(100% - 60rpx);
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
&.addr1{
border-bottom: 1rpx solid #e5e5e5;
}
.box{
.tit{
color: #000;
font-size: 30rpx;
}
text{
color: #7B7B7B;
font-size: 26rpx;
}
}
}
.icon{
color: #fff;
font-size: 24rpx;
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
background: #7B7B7B;
border-radius: 50%;
&.ji{
background: v-bind('Color');
position: relative;
&::after{
width: 0;
height: 100rpx;
content: '';
position: absolute;
border-left: 1rpx dashed #E5E5E5;
left: 20rpx;
top: 42rpx;
}
}
}
}
}
.sendInfo{
padding: 30rpx;
.row{
display: flex;
align-items: center;
color: #303030;
font-size: 28rpx;
padding: 10rpx 0;
text{
color: #7B7B7B;
margin-right: 10rpx;
}
}
.good{
display: flex;
align-items: center;
margin-top: 10rpx;
font-size: 26rpx;
color: #7B7B7B;
line-height: 50rpx;
.img{
width: 140rpx;
height: 140rpx;
margin-right: 20rpx;
}
}
}
.bottom{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: flex-end;
height: 90rpx;
background-color: #fff;
z-index: 10;
.btn{
height: 48rpx;
padding: 0 30rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #333;
border: 1px solid #BBBBBB;
margin-left: 20rpx;
border-radius: 48rpx;
&.red{
color: v-bind('Color');
border: 1px solid v-bind('Color');
}
}
}
}
.typebox{
padding: 0 30rpx 20rpx;
.title{
font-size: 30rpx;
color: #303030;
font-weight: bold;
padding: 30rpx 0;
border-bottom: 1rpx solid #E5E5E5;
text-align: center;
}
.box{
min-height: 40vh;
max-height: 80vh;
overflow: auto;
padding-bottom: 70rpx;
.row{
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1rpx solid #E5E5E5;
padding: 30rpx 0;
font-size: 28rpx;
color: #333;
}
}
.btn{
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
width: 100%;
border-radius: 80rpx;
box-sizing: border-box;
background: v-bind('Color');
color: #fff;
}
}
.iconfont{
font-size: 22px;
}
.icon-checked{
color: v-bind('Color');
}
</style>