703 lines
20 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="whole" v-if="!loading">
<view class="staTit" v-if="orderInfo.status === 0">待团长处理</view>
<view class="staTit" v-if="orderInfo.status === 11">团员已撤销</view>
<view class="staTit" v-if="orderInfo.status === 20">待团员退货</view>
<view class="staTit" v-if="orderInfo.status === 21">团长已拒绝</view>
<view class="staTit" v-if="orderInfo.status === 22">团员已退货</view>
<view class="staTit" v-if="orderInfo.status === 30">团员已退货</view>
<view class="staTit" v-if="orderInfo.status === 31">退款中</view>
<view class="staTit" v-if="orderInfo.status === 32">已退款</view>
<view class="staTit" v-if="orderInfo.status === 33">退款失败</view>
<!-- 已申请退款未退货 -->
<view class="method" v-if="orderInfo.status === 20 && !orderInfo.ship_sn && orderInfo.pickup_id === 0">
<view class="row">
<view class="tit">方式1预约上门取件</view>
<view class="btn flex" @click="toSendGoods()">立即寄回</view>
</view>
<view class="row row1">
<view class="tit">方式2自己联系快递寄回需填写快递单号</view>
<view class="ed">退货地址</view>
<view class="arrdbox flex1">
<view class="arrd">
<text>{{orderInfo.refund_address_name}}&nbsp;&nbsp;{{orderInfo.refund_address_mobile || orderInfo.refund_address_tel}}</text><br>
<text>
{{orderInfo.refund_address_province_name}}{{orderInfo.refund_address_city_name}}{{orderInfo.refund_address_area_name}}{{orderInfo.refund_address_detail}}
</text>
</view>
<view class="copybtn flex" @click="copyAddress()">复制</view>
</view>
<view class="btn btn1 flex" @click="toFillNo()">填写快递单号</view>
</view>
</view>
<!-- 已申请退款未上门取件 -->
<view class="hasback flex1" @click="tosendDetail()" v-if="orderInfo.status === 20 && orderInfo.pickup_id !== 0">
<view>
<view class="tit">已预约上门取件</view>
<text>本次寄件费用由团长承担</text>
</view>
<up-icon name="arrow-right" />
</view>
<view class="pickcode" v-if="orderInfo.status === 20 && orderInfo.pickup_id !== 0 && pickup_code">取件码
<text>{{pickup_code}}</text>
</view>
<!-- 已申请退款且退货 -->
<view class="expInfo" v-if="(orderInfo.status === 22 || orderInfo.status === 30 || orderInfo.status === 31) && orderInfo.ship_sn">
<view class="tit flex1">
<text>退货物流信息</text>
<view class="view" @click="viewExpress()">查看&nbsp;<up-icon name="arrow-right" /></view>
</view>
<view class="expno">
<text>{{orderInfo.delivery_company.name}}&nbsp;&nbsp;{{orderInfo.ship_sn}}</text>
<view class="copybtn" @click="copyExpress()">复制</view>
</view>
</view>
<view class="refInfo">
<view class="title">团员申请退款</view>
<view class="info">
<view class="item">
<view class="left">退款金额:</view>
<view class="right">
<view class="amount">¥{{orderInfo.total_amount}}</view>
</view>
</view>
<view class="item">
<view class="left">退款明细:</view>
<view class="right">
<view class="row" v-for="(it, index) in orderInfo.refunds" :key="index">
<text>{{it.item.goods_name}}<template v-if="it.item.sku_name">{{it.item.sku_name}}</template></text>
<text style="white-space: nowrap;padding-left: 10rpx;">退款<text class="red">¥{{((parseFloat(it.amount) * 100 - parseFloat(it.freight_price_refund) * 100) / 100).toFixed(2)}}</text></text>
</view>
<view class="row" v-if="orderInfo.freight_price">
<text>运费</text>
<text>退款<text class="red">¥{{orderInfo.freight_price}}</text></text>
</view>
</view>
</view>
<view class="item">
<view class="left">申请原因:</view>
<view class="right">
<view class="row">
<text>{{refoundReasonObj[orderInfo.refund_reason]}}</text>
</view>
</view>
</view>
<view class="item">
<view class="left">售后类型:</view>
<view class="right">
<view class="row">
<text>{{orderInfo.type == 2 ? '退货退款' : '仅退款(无需退货)'}}</text>
</view>
</view>
</view>
<view class="item">
<view class="left">申请描述:</view>
<view class="right">
<view class="row">
<text>{{orderInfo.apply_desc || ''}}</text>
</view>
<view class="imgbox" v-if="orderInfo.apply_pic_urls">
<image v-for="(it, index) in orderInfo.apply_pic_urls" :key="index" :src="it" mode="aspectFill" class="img" @click="preViewImg(it)"></image>
</view>
</view>
</view>
<view class="item">
<view class="left">申请时间:</view>
<view class="right">
<view class="row">
<text>{{orderInfo.created_at || ''}}</text>
</view>
</view>
</view>
</view>
</view>
<view class="history">
<view class="tit flex1" @click="showInfo = !showInfo">
<text>售后历史</text>
<up-icon name="arrow-up" v-if="showInfo" />
<up-icon name="arrow-down" v-else />
</view>
<view v-show="showInfo" class="info">
<view class="row" v-for="(item, index) in historyInfo" :key="index" :class="index == 0 ? 'is-done' : ''">
<view class="tt" v-if="item.operator_type === 0">团员发起退款申请</view>
<view class="tt" v-if="item.operator_type === 10">团员修改退款申请</view>
<view class="tt" v-if="item.operator_type === 11">团员取消退款申请</view>
<view class="tt" v-if="item.operator_type === 13">系统取消申请</view>
<view class="tt" v-if="item.operator_type === 20">申请已通过</view>
<view class="tt" v-if="item.operator_type === 21">申请拒绝</view>
<view class="tt" v-if="item.operator_type === 22 && item.ship_sn">团员开始寄件</view>
<view class="tt" v-if="item.operator_type === 30 && item.extend_info.pickup">团员开始寄件</view>
<view class="tt" v-if="item.operator_type === 30 && !item.extend_info.pickup">团员填写物流信息</view>
<view class="tt" v-if="item.operator_type === 31">团员修改寄件</view>
<view class="tt" v-if="item.operator_type === 32">团员取消寄件</view>
<view class="tt" v-if="item.operator_type === 33">快递平台取消寄件</view>
<view class="tt" v-if="item.operator_type === 34">团长填写物流</view>
<view class="tt" v-if="item.operator_type === 40">待退款</view>
<view class="tt" v-if="item.operator_type === 41">退款中</view>
<view class="tt" v-if="item.operator_type === 42">退款已完成</view>
<view class="tt" v-if="item.operator_type === 43">退款失败</view>
<view class="time">{{item.created_at}}</view>
<text v-if="item.operator_type === 21">拒绝理由:{{item.approve_msg}}</text>
<text v-if="item.operator_type === 32 &&
item.extend_info &&
item.extend_info.pickup
">取消理由:{{reasonObj[item.extend_info.pickup.cancel_type]}}</text>
<template v-if="item.operator_type === 30 && item.extend_info.pickup">
<text>寄件类型:{{sendTypeObj[item.extend_info.pickup.consign_type] || ''}}</text><br>
</template>
<template v-if="item.operator_type === 30 && !item.extend_info.pickup">
<text style="color: #409eff;" @click="viewExpress()">物流信息:{{item.ship_sn || ''}}</text>
</template>
<template v-if="item.operator_type === 34">
<text style="color: #409eff;" @click="viewExpress()">物流信息:{{item.ship_sn || ''}}</text>
</template>
<template v-if="item.operator_type === 22 && item.ship_sn">
<text>物流单号:{{item.ship_sn || ''}}</text>
</template>
<template v-if="item.operator_type === 0 || item.operator_type === 10">
<view v-for="(it, i) in item.extend_info.refunds" :key="i">
<text>{{it.item.goods_name}}{{it.item.sku_name}}退款{{((parseFloat(it.amount) * 100 - parseFloat(it.freight_price_refund) * 100) / 100).toFixed(2)}}</text>
</view>
<text v-if="item.freight_price">运费退款{{item.freight_price}}</text><br>
<text>售后类型{{item.type == 2 ? '退货退款' : '仅退款(无需退货)'}}</text><br>
<text>退款原因{{refoundReasonObj[orderInfo.refund_reason]}}</text><br>
<text>申请说明{{item.apply_desc || ''}}</text>
<view class="imgbox">
<image v-for="(it, i) in item.apply_pic_urls" :key="i" :src="it" mode="aspectFill" class="img" @click="preViewImg(it)"></image>
</view>
</template>
</view>
</view>
</view>
<!-- 退款申请状态 0-发起申请;11-申请取消;20-申请通过待退货;21-申请拒绝;22-团员已填写物流单号待团长退款;30-待退款已退货待退款;31-退款中;32-退款完成;33-退款失败 -->
<view class="bottom" v-if="orderInfo.status === 0 || orderInfo.status === 11 || orderInfo.status === 20 || orderInfo.status === 21 || ((orderInfo.status === 22 || orderInfo.status === 30 || orderInfo.status === 31) && orderInfo.ship_sn)">
<view class="btn flex" v-if="(orderInfo.status === 22 || orderInfo.status === 30 || orderInfo.status === 31) && orderInfo.ship_sn" @click="modifyExpress()">修改物流单号</view>
<view class="btn flex" v-if="orderInfo.status === 0 || orderInfo.status === 20 || orderInfo.status === 21 || orderInfo.status === 22" @click="showCommit = true">撤销申请</view>
<view class="btn flex" v-if="orderInfo.status === 0 || orderInfo.status === 11 || orderInfo.status === 21" @click="toModifyApply()">修改申请</view>
</view>
<up-modal
:show="showCommit"
title="确定撤销退款申请吗?"
:confirmColor="Color"
:showCancelButton="true"
@confirm="revokeRefound()"
@cancel="showCommit = false">
</up-modal>
<!-- 隐私协议弹窗 -->
<privacy-popup :show-dialog="showPrivacy" @close="showPrivacy = false" @agree="showPrivacy = false" @refuse="showPrivacy = false" />
</view>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import { refoundReasonObj } from '@/utils/list.js'
import { get } from '@/api/request.js'
import { showToast, judgePrivacy } from '@/components/common.js'
import { sendTypeObj, reasonObj, Style } from '@/utils/list.js'
import privacyPopup from '@/components/privacyPopup/index.vue'
export default {
components: {
privacyPopup
},
setup() {
const data = reactive({
refund_id: '',
orderInfo: {},
historyInfo: [],
showInfo: false,
showCommit: false,
loading: true,
cancelLoad: false,
Color: uni.getStorageSync('theme_color'),
priceColor: Style[uni.getStorageSync('theme_index') * 1].priceColor,
showPrivacy: false,
pickup_code: ''
})
// 获取退款详情
function getOrderInfo() {
get(`/api/v1/orderRefundApply/${data.refund_id}`).then((res) => {
data.orderInfo = res.data
data.loading = false
if(res.data.status === 20 && res.data.pickup_id !== 0) {
getPickCode(res.data.pickup_id)
}
})
}
function getPickCode(pickup_id) {
get(`/api/v1/pickup/${pickup_id}`).then((res) => {
data.pickup_code = res.data.pickup_code
})
}
// 获取售后历史
function getHistory() {
get(`/api/v1/orderRefundApply/history/${data.refund_id}`, {page: 1, pageSize: 100}).then((res) => {
data.historyInfo = res.data
})
}
// 撤销申请
function revokeRefound() {
if(!data.cancelLoad) {
data.cancelLoad = true
uni.showLoading({
title: '正在取消',
mask: true
})
get(`/api/v1/orderRefundApply/cancel/${data.refund_id}`).then((res) => {
uni.hideLoading()
showToast('退款申请已取消')
data.showCommit = false
data.cancelLoad = false
getOrderInfo()
getHistory()
}).catch(() => {
data.cancelLoad = false
})
}
}
function toSendGoods() {
uni.navigateTo({
url: '/pages/mine/refund/sendgoods/index?order_id=' + data.orderInfo.order_id + '&refund_id=' + data.refund_id
})
}
function toFillNo() {
uni.navigateTo({
url: '/pages/mine/refund/fillno/index?refund_id=' + data.refund_id
})
}
function viewExpress() {
uni.navigateTo({
url: '/pages/mine/refund/expressinfo/index?refund_id=' + data.refund_id
})
}
function tosendDetail() {
uni.navigateTo({
url: '/pages/mine/refund/senddetail/index?pickup_id=' + data.orderInfo.pickup_id + '&refund_id=' + data.refund_id
})
}
// 复制物流单号
const copyExpress = async () => {
if(await judgePrivacy()) {
data.showPrivacy = true
return false
}
uni.setClipboardData({
data: String(data.orderInfo.ship_sn),
success: function () {
uni.showToast({
icon: 'none',
title: '物流单号已复制'
})
},
fail: function () {
uni.showToast({
icon: 'none',
title: '复制失败'
})
}
})
}
// 修改申请
function toModifyApply() {
uni.navigateTo({
url: '/pages/mine/refund/apply/index?order_id=' + data.orderInfo.order_id + '&refund_id=' + data.refund_id + '&type=' + data.orderInfo.type
})
}
// 修改物流单号
function modifyExpress() {
uni.navigateTo({
url: '/pages/mine/refund/fillno/index?refund_id=' + data.refund_id + '&modify=1'
})
}
async function copyAddress() {
if(await judgePrivacy()) {
data.showPrivacy = true
return false
}
let address = data.orderInfo.refund_address_name + ' ' +
(data.orderInfo.refund_address_mobile || data.orderInfo.refund_address_tel) + ' ' +
data.orderInfo.refund_address_province_name +
data.orderInfo.refund_address_city_name +
data.orderInfo.refund_address_area_name +
data.orderInfo.refund_address_detail
uni.setClipboardData({
data: address,
success: function () {
uni.showToast({
icon: 'none',
title: '地址信息已复制'
})
},
fail: function () {
uni.showToast({
icon: 'none',
title: '复制失败'
})
}
})
}
function preViewImg(img) {
uni.previewImage({
urls: [img],
current: 0
})
}
return {
sendTypeObj,
reasonObj,
refoundReasonObj,
...toRefs(data),
getOrderInfo,
getHistory,
revokeRefound,
toSendGoods,
toFillNo,
viewExpress,
tosendDetail,
copyExpress,
toModifyApply,
modifyExpress,
copyAddress,
preViewImg
}
},
onLoad(options) {
this.refund_id = options.refund_id
},
onShow() {
this.getOrderInfo()
this.getHistory()
}
}
</script>
<style lang="scss" scoped>
.flex{
display: flex;
align-items: center;
justify-content: center;
}
.flex1{
display: flex;
align-items: center;
justify-content: space-between;
}
.whole {
padding-bottom: 110rpx;
box-sizing: border-box;
.staTit{
font-size: 50rpx;
color: #111111;
font-weight: 600;
padding: 50rpx 0;
background: #fff;
text-align: center;
}
.refInfo{
margin-top: 20rpx;
background: #fff;
.title{
font-size: 32rpx;
color: #111111;
font-weight: bold;
padding: 30rpx;
border-bottom: 1rpx solid #E5E5E5;
}
.info{
padding: 10rpx 30rpx;
.item{
display: flex;
align-items: flex-start;
padding: 10rpx 0;
.left{
font-size: 30rpx;
color: #7B7B7B;
width: 150rpx;
}
.right{
width: calc(100% - 150rpx);
.amount{
font-size: 40rpx;
color: v-bind('priceColor');
font-weight: bold;
line-height: 1;
}
.row{
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
.row1{
margin-bottom: 10rpx;
}
text{
font-size: 30rpx;
color: #000;
&.red{
color: v-bind('priceColor');
}
}
}
.imgbox{
margin-top: 10rpx;
.img{
width: 140rpx;
height: 140rpx;
margin: 0 16rpx 16rpx 0;
}
}
}
}
}
}
.history{
margin-top: 20rpx;
background: #fff;
.tit{
font-size: 34rpx;
color: #111111;
font-weight: bold;
padding: 30rpx;
width: 100%;
box-sizing: border-box;
}
.info{
border-top: 1rpx solid #eee;
padding: 30rpx;
.row{
padding-left: 54rpx;
position: relative;
padding-bottom: 16rpx;
.tt{
font-size: 30rpx;
color: #7B7B7B;
font-weight: 600;
}
.time{
font-size: 24rpx;
color: #98989F;
}
text{
font-size: 26rpx;
color: #666;
line-height: 40rpx;
}
&:before {
position: absolute;
margin-top: 16rpx;
left: 9rpx;
content: ' ';
height: 20rpx;
width: 20rpx;
border-radius: 50%;
background-color: #e8e8e8;
}
&:after {
position: absolute;
top: 32rpx;
left: 16rpx;
bottom: -38rpx;
content: ' ';
width: 2rpx;
border-right: 2rpx solid #e8e8e8;
}
&:not(:first-child) {
padding-top: 16rpx;
}
&:last-child {
&:after {
display: none;
}
}
&.is-done {
.tt{
color: #333;
}
&:after {
border-color: v-bind('Color');
}
&:before {
background-color: v-bind('Color');
box-shadow: v-bind('Color') 0 0 10px;
}
}
}
}
.imgbox{
margin-top: 10rpx;
.img{
width: 140rpx;
height: 140rpx;
margin: 0 16rpx 16rpx 0;
}
}
}
.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;
font-size: 24rpx;
color: #333;
border: 1px solid #BBBBBB;
margin-left: 20rpx;
border-radius: 48rpx;
}
}
.method{
padding: 30rpx;
margin-top: 20rpx;
background: #fff;
box-sizing: border-box;
.row{
&.row1{
margin-top: 60rpx;
}
.tit{
font-size: 32rpx;
color: #111;
font-weight: 600;margin-bottom: 30rpx;
}
.btn{
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
width: 100%;
color: #fff;
border-radius: 80rpx;
background: v-bind('Color');
box-sizing: border-box;
&.btn1{
border: 1rpx solid v-bind('Color');
color: v-bind('Color');
background: #fff;
}
}
.ed{
margin-bottom: 10rpx;
}
.arrdbox{
font-size: 26rpx;
color: #303030;
margin-bottom: 50rpx;
.arrd{
width: calc(100% - 140rpx);
text{
color: #7B7B7B;
line-height: 44rpx;
}
}
.copybtn{
height: 48rpx;
padding: 0 30rpx;
font-size: 24rpx;
color: #333;
border: 1rpx solid #BBBBBB;
border-radius: 48rpx;
}
}
}
}
.hasback{
margin-top: 20rpx;
background: #fff;
border-radius: 10rpx;
padding: 30rpx;
.tit{
font-size: 32rpx;
font-weight: bold;
color: #111;
margin-bottom: 20rpx;
}
text{
font-size: 28rpx;
color: #7B7B7B;
}
}
.expInfo{
margin-top: 20rpx;
background: #fff;
border-radius: 10rpx;
padding: 30rpx;
.tit{
font-size: 32rpx;
font-weight: bold;
color: #111;
margin-bottom: 20rpx;
.view{
font-size: 28rpx;
font-weight: normal;
}
}
.expno{
display: flex;
align-items: center;
text{
font-size: 28rpx;
color: #7B7B7B;
}
.copybtn{
padding: 2rpx 20rpx;
color: #7B7B7B;
font-size: 24rpx;
border: 1px solid #7B7B7B;
border-radius: 4rpx;
margin-left: 20rpx;
}
}
}
}
</style>