【退款】

1、退款详情
2、退货界面
pull/1/MERGE
YunaiV 2023-08-18 19:14:39 +08:00
parent 40883fda3b
commit a4846939dd
8 changed files with 288 additions and 138 deletions

View File

@ -1,5 +1,11 @@
import request from "@/utils/request.js"; import request from "@/utils/request.js";
export function getAfterSale(id) {
return request.get("app-api/trade/after-sale/get", {
id
});
}
export function getAfterSalePage(data) { export function getAfterSalePage(data) {
return request.get("app-api/trade/after-sale/page", data); return request.get("app-api/trade/after-sale/page", data);
} }
@ -13,3 +19,11 @@ export function getAfterSaleReasonList(way) {
export function createAfterSale(data) { export function createAfterSale(data) {
return request.post("app-api/trade/after-sale/create", data); return request.post("app-api/trade/after-sale/create", data);
} }
export function cancelAfterSale(id) {
return request.delete("app-api/trade/after-sale/cancel?id=" + id);
}
export function deliveryAfterSale(data) {
return request.put("app-api/trade/after-sale/delivery", data);
}

View File

@ -16,3 +16,8 @@ export function getDeliveryPickUpStore(id) {
id id
}); });
} }
// 获得快递公司列表
export function getDeliveryExpressList() {
return request.get("app-api/trade/delivery/express/list");
}

View File

@ -361,6 +361,12 @@
"navigationBarTitleText": "申请退货" "navigationBarTitleText": "申请退货"
} }
}, },
{
"path": "goods_return_delivery/index",
"style": {
"navigationBarTitleText": "填写退货物流"
}
},
{ {
"path": "login/index", "path": "login/index",
"style": { "style": {

View File

@ -1,7 +1,8 @@
<template> <template>
<view> <view>
<view class='order-details'> <view class='order-details'>
<view class='header bg-color'> <!-- 当前状态 -->
<view class='header bg-color'>
<view class='picTxt acea-row row-middle'> <view class='picTxt acea-row row-middle'>
<!-- 状态图 --> <!-- 状态图 -->
<view class='pictrue'> <view class='pictrue'>

View File

@ -18,7 +18,7 @@
<view class='item acea-row row-between-wrapper'> <view class='item acea-row row-between-wrapper'>
<view>售后方式</view> <view>售后方式</view>
<!-- 如果未发货则只能退款 --> <!-- 如果未发货则只能退款 -->
<view class="" v-if="order.status === 20">退</view> <view class="" v-if="order.status === 10">退</view>
<picker v-else class='num' @change="wayChange" <picker v-else class='num' @change="wayChange"
:value="wayIndex" :range="ways"> :value="wayIndex" :range="ways">
<view class="picker acea-row row-between-wrapper"> <view class="picker acea-row row-between-wrapper">
@ -205,13 +205,12 @@
applyDescription: formData.applyDescription, applyDescription: formData.applyDescription,
applyPicUrls: this.applyPicUrls, applyPicUrls: this.applyPicUrls,
}).then(res => { }).then(res => {
// TODO
this.$util.Tips({ this.$util.Tips({
title: '申请成功', title: '申请成功',
icon: 'success' icon: 'success'
}, { }, {
tab: 5, tab: 5,
url: '/pages/users/user_return_list/index?isT=1' url: '/pages/users/user_return_detail/index?id=' + res.data
}); });
}).catch(err=>{ }).catch(err=>{
return this.$util.Tips({ return this.$util.Tips({

View File

@ -0,0 +1,135 @@
<template>
<view>
<!-- TODO 芋艿退货地址后续写在这里还是写在退款详情界面 -->
<form @submit="subRefund" report-submit='true'>
<view class='apply-return'>
<view class='list borRadius14'>
<view class='item acea-row row-between-wrapper'>
<view>物流公司</view>
<picker class='num' @change="bindPickerChange" :value="expressIndex"
:range="expresses" range-key="name">
<view class="picker acea-row row-between-wrapper">
<view class='reason'>{{ expresses[expressIndex].name }}</view>
<text class='iconfont icon-jiantou'></text>
</view>
</picker>
</view>
<view class='item textarea acea-row row-between'>
<view>物流单号</view>
<input placeholder='请填写物流单号' class='num' name="logisticsNo" placeholder-class='placeholder' />
</view>
<button class='returnBnt bg-color' form-type="submit">提交</button>
</view>
</view>
</form>
</view>
</template>
<script>
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import * as AfterSaleApi from '@/api/trade/afterSale.js';
import * as DeliveryApi from '@/api/trade/delivery.js';
export default {
data() {
return {
id: 0, //
expresses: [], //
expressIndex: 0, // expresses
};
},
computed: mapGetters(['isLogin']),
watch:{
isLogin:{
handler: function(newV, oldV) {
if (newV) {
this.getExpressList();
}
},
deep:true
}
},
onLoad: function (options) {
if (!this.isLogin) {
toLogin();
return;
}
if (!options.id) {
return this.$util.Tips({
title: '缺少退款编号,无法查看'
},{
tab: 3,
url:1
});
}
this.id = parseInt(options.id);
this.getExpressList();
},
methods: {
onLoadFun:function() {
this.getExpressList();
},
/**
* 获得快递公司
*/
getExpressList: function() {
DeliveryApi.getDeliveryExpressList().then(res => {
this.expresses = res.data;
})
},
/**
* 选择快递公司
*/
bindPickerChange: function(e) {
this.$set(this, 'expressIndex', e.detail.value);
},
/**
* 申请退货
*/
subRefund:function(e) {
const formData = e.detail.value;
AfterSaleApi.deliveryAfterSale({
id: this.id,
logisticsId: this.expresses[this.expressIndex].id,
logisticsNo: formData.logisticsNo,
}).then(res => {
this.$util.Tips({
title: '填写退货成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_return_detail/index?id=' + this.id
});
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
}
}
}
</script>
<style scoped lang="scss">
.apply-return{
padding: 20rpx 30rpx 70rpx 30rpx;
}
.apply-return .list{background-color:#fff;margin-top:18rpx;padding:0 24rpx 70rpx 24rpx;}
.apply-return .list .item{min-height:90rpx;border-bottom:1rpx solid #eee;font-size:30rpx;color:#333;}
.apply-return .list .item .num{color:#282828;width:427rpx;text-align:right;}
.apply-return .list .item .num .picker .reason{width:385rpx;}
.apply-return .list .item .num .picker .iconfont{color:#666;font-size:30rpx;margin-top:2rpx;}
.apply-return .list .item.textarea{padding:24rpx 0;}
.apply-return .list .item textarea{height:100rpx;font-size:30rpx;}
.apply-return .list .item .placeholder{color:#bbb;}
.apply-return .list .item .title{height:95rpx;width:100%;}
.apply-return .list .item .title .tip{font-size:30rpx;color:#bbb;}
.apply-return .list .item .upload{padding-bottom:36rpx;}
.apply-return .list .item .upload .pictrue{border-radius: 14rpx; margin:22rpx 23rpx 0 0;width:156rpx;height:156rpx;position:relative;font-size:24rpx;color:#bbb;}
.apply-return .list .item .upload .pictrue:nth-of-type(4n){margin-right:0;}
.apply-return .list .item .upload .pictrue image{width:100%;height:100%;border-radius:14rpx;}
.apply-return .list .item .upload .pictrue .icon-guanbi1{position:absolute;font-size:45rpx;top:-10rpx;right:-10rpx;}
.apply-return .list .item .upload .pictrue .icon-icon25201{color:#bfbfbf;font-size:50rpx;}
.apply-return .list .item .upload .pictrue:nth-last-child(1){border:1rpx solid #ddd;box-sizing:border-box;}
.apply-return .returnBnt{font-size:32rpx;color:#fff;width:100%;height:86rpx;border-radius:50rpx;text-align:center;line-height:86rpx;margin:43rpx auto;}
</style>

View File

@ -1,34 +1,86 @@
<template> <template>
<view> <view>
<view class='order-details'> <view class='order-details'>
<view class="pad30"> <!-- 当前状态 -->
<!-- TODO 芋艿退款各种 --> <view class='header bg-color'>
<view class='nav refund'> <view class='picTxt acea-row row-middle'>
<view class="title"> <!-- 状态图 -->
<image src="/static/images/shuoming.png" mode="" /> <view class='pictrue'>
{{order.refundStatus==1?'商家审核中':order.refundStatus==2?'商家已退款':'商家拒绝退款'}} <image v-if="afterSale.status === 10" src="@/static/images/order/status_0.gif" />
<image v-if="afterSale.status === 20" src="@/static/images/order/status_10.gif" />
<image v-if="afterSale.status === 30" src="@/static/images/order/status_20.gif" />
<image v-if="afterSale.status === 40" src="@/static/images/order/status_30a.gif" />
<image v-if="afterSale.status === 50" src="@/static/images/order/status_30b.gif" />
<image v-if="afterSale.status === 61" src="@/static/images/order/status_40.gif" />
<image v-if="afterSale.status === 62" src="@/static/images/order/status_40.gif" />
<image v-if="afterSale.status === 63" src="@/static/images/order/status_40.gif" />
</view> </view>
<view class="con pad30"> <view class='data'>
{{ <!-- 状态提示 -->
order.refundStatus==1 ? "您已成功发起退款申请,请耐心等待商家处理;退款前请与商家协商一致,有助于更好的处理售后问题": <view class='state' v-if="afterSale.status === 10">退</view>
order.refundStatus==2 ? "退款已成功受理,如商家已寄出商品请尽快退回;感谢您的支持" : "拒绝原因:" + order.refundReason <view class='state' v-if="afterSale.status === 20">退</view>
}} <view class='state' v-if="afterSale.status === 30">退退</view>
<view class='state' v-if="afterSale.status === 40">退</view>
<view class='state' v-if="afterSale.status === 50">退</view>
<view class='state' v-if="afterSale.status === 61">退</view>
<view class='state' v-if="afterSale.status === 62">退{{ afterSale.auditReason }}</view>
<view class='state' v-if="afterSale.status === 63">退{{ afterSale.auditReason }}</view> <!-- TODO -->
</view>
</view>
</view>
<view>
<view class='goodsStyle acea-row row-between borRadius14'>
<view class='pictrue'>
<image :src='afterSale.picUrl' />
</view>
<view class='text acea-row row-between'>
<view class='line2'>{{ afterSale.spuName }}</view>
<view class='attr line1' v-if="afterSale.properties">
<text v-for="property in afterSale.properties" style="padding-right: 2px">{{property.valueName}}</text>
</view>
</view> </view>
</view> </view>
<!-- TODO 芋艿退款订单详情 -->
<view class='wrapper borRadius14' > <view class='wrapper borRadius14' >
<view class='item acea-row row-between'> <view class='item acea-row row-between'>
<view>收货人</view> <view>退款金额</view>
<view class='conter'>{{order.realName}}</view> <view class='conter'> {{ fen2yuan(afterSale.refundPrice) }}</view>
</view> </view>
<view class='item acea-row row-between'> <view class='item acea-row row-between'>
<view>联系电话</view> <view>售后方式</view>
<view class='conter'>{{order.userPhone}}</view> <view class='conter'>{{ afterSale.way === 10 ? '仅退款' : '退款退货' }}</view>
</view> </view>
<view class='item acea-row row-between'> <view class='item acea-row row-between'>
<view>收货地址</view> <view>退款原因</view>
<view class='conter'>{{order.userAddress}}</view> <view class='conter'>{{ afterSale.applyReason }}</view>
</view>
</view>
<view class='wrapper borRadius14' >
<view class='item acea-row row-between'>
<view>售后单号</view>
<view class='conter'>{{ afterSale.no }}</view>
</view>
<view class='item acea-row row-between'>
<view>申请时间</view>
<view class='conter'>{{ formatDate(afterSale.createTime) }}</view>
</view>
<view class='item acea-row row-between'>
<view>数量</view>
<view class='conter'>{{ afterSale.count }}</view>
</view>
</view>
</view>
<view>
<!-- 操作区域 -->
<view class='footer acea-row row-right row-middle'>
<view class="qs-btn" v-if="[20].includes(afterSale.status)" @click.stop="cancelAfterSale">
填写退货信息
</view>
<view class="qs-btn" v-if="[10, 20, 30].includes(afterSale.status)" @click.stop="cancelAfterSale">
撤销申请
</view> </view>
</view> </view>
</view> </view>
@ -38,23 +90,14 @@
<script> <script>
import { toLogin } from '@/libs/login.js'; import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import * as TradeOrderApi from '@/api/trade/order.js';
import * as AfterSaleApi from '@/api/trade/afterSale.js'; import * as AfterSaleApi from '@/api/trade/afterSale.js';
import dayjs from '@/plugin/dayjs/dayjs.min.js';
import * as Util from '@/utils/util.js';
export default { export default {
data() { data() {
return { return {
orderId: 0, id: 0, //
orderItemId: 0, afterSale: {}, //
order: {}, //
orderItem: {}, //
wayIndex: 0, // ways
ways: ['仅退款', '退款退货'], //
reasons: [], //
reasonIndex: 0, // reasons
applyPicUrls: [], //
}; };
}, },
computed: mapGetters(['isLogin']), computed: mapGetters(['isLogin']),
@ -62,8 +105,7 @@
isLogin:{ isLogin:{
handler: function(newV, oldV) { handler: function(newV, oldV) {
if (newV) { if (newV) {
this.getOrderInfo(); this.getAfterSale();
this.getRefundReason();
} }
}, },
deep:true deep:true
@ -74,110 +116,62 @@
toLogin(); toLogin();
return; return;
} }
// if (!options.orderId || !options.orderItemId) { if (!options.id) {
// return this.$util.Tips({ return this.$util.Tips({
// title:'id,退' title: '缺少退款编号,无法查看'
// },{ },{
// tab: 3, tab: 3,
// url:1 url:1
// }); });
// } }
// this.orderId = parseInt(options.orderId); this.id = parseInt(options.id);
// this.orderItemId = parseInt(options.orderItemId); this.getAfterSale();
// this.getOrderInfo();
// this.getRefundReason();
}, },
methods: { methods: {
onLoadFun:function() {
this.getOrderInfo();
this.getRefundReason();
},
/** /**
* 获取订单详情 * 获取售后订单
*/ */
getOrderInfo:function(){ getAfterSale: function() {
TradeOrderApi.getOrderDetail(this.orderId).then(res => { AfterSaleApi.getAfterSale(this.id).then(res => {
// this.afterSale = res.data || {}
const order = res.data;
this.order = order;
//
this.orderItem = order.items.find(item => item.id === this.orderItemId) || {};
}).catch(err => { }).catch(err => {
return this.$util.Tips({ return this.$util.Tips({
title: err title: err
}); });
}) })
}, },
/** /**
* 更改售后方式 * 取消售后
*/ */
wayChange: function(e) { cancelAfterSale: function() {
this.$set(this, 'wayIndex', e.detail.value); uni.showModal({
this.getRefundReason(); title: '提示',
}, content: '确认取消该售后?',
/** success: res => {
* 获得售后方式 if (!res.confirm) {
*/ return;
getWay: function () { }
return this.wayIndex === 0 ? 10 : 20 AfterSaleApi.cancelAfterSale(this.id).then(() => {
}, this.$util.Tips({
/** title: '取消成功'
* 获取退款理由 })
*/ this.getAfterSale();
getRefundReason: function() { }).catch((err) => {
const way = this.getWay(); this.$util.Tips({
AfterSaleApi.getAfterSaleReasonList(way).then(res => { title: err
this.reasons = res.data; })
}) this.getAfterSale();
}, });
/** }
* 选择售后原因
*/
bindPickerChange: function(e) {
this.$set(this, 'reasonIndex', e.detail.value);
},
/**
* 删除图片
*/
DelPic:function(index) {
this.applyPicUrls.splice(index, 1);
},
/**
* 上传文件
*/
uploadpic:function(){
this.$util.uploadImageOne({}, res => {
this.applyPicUrls.push(res.data);
this.$set(this, 'applyPicUrls', this.applyPicUrls);
}); });
}, },
/** fen2yuan(price) {
* 申请退货 return Util.fen2yuan(price)
*/ },
subRefund:function(e) { formatDate: function(date) {
const formData = e.detail.value; return dayjs(date).format("YYYY-MM-DD HH:mm:ss");
AfterSaleApi.createAfterSale({
orderItemId: this.orderItemId,
way: this.getWay(),
refundPrice: this.orderItem.payPrice,
applyReason: this.reasons[this.reasonIndex],
applyDescription: formData.applyDescription,
applyPicUrls: this.applyPicUrls,
}).then(res => {
// TODO
this.$util.Tips({
title: '申请成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_return_list/index?isT=1'
});
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
} }
} }
} }
@ -218,7 +212,7 @@
} }
.order-details .header { .order-details .header {
height: 250rpx; height: 150rpx;
padding: 0 30rpx; padding: 0 30rpx;
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<view> <view>
<view class='return-list pad30' v-if="orderList.length"> <view class='return-list pad30' v-if="orderList.length">
<view class='goodWrapper borRadius14' v-for="(item,index) in orderList" :key="index" @click='goOrderDetails(item.orderId)'> <view class='goodWrapper borRadius14' v-for="(item,index) in orderList" :key="index" @click='goOrderDetails(item.id)'>
<!-- 根据状态展示 icon --> <!-- 根据状态展示 icon -->
<!-- TODO 芋艿需要优化下 icon目前没展示出来 --> <!-- TODO 芋艿需要优化下 icon目前没展示出来 -->
<view class='iconfont icon-shenqingzhong powder' v-if="[10].includes(item.status)" /> <view class='iconfont icon-shenqingzhong powder' v-if="[10].includes(item.status)" />
@ -89,23 +89,19 @@
this.getOrderList(); this.getOrderList();
}, },
methods: { methods: {
onLoadFun() {
this.getOrderList();
},
/** /**
* 去订单详情 * 去订单详情
*/ */
goOrderDetails: function(order_id) { goOrderDetails: function(id) {
if (!order_id) { if (!id) {
return that.$util.Tips({ return this.$util.Tips({
title: '缺少订单号无法查看订单详情' title: '缺少订单号无法查看订单详情'
}); });
} }
// TODO uni.navigateTo({
uni.navigateTo({ url: '/pages/users/user_return_detail/index?id=' + id
url: '/pages/order_details/index?order_id=' + order_id + '&isReturen=1'
}) })
}, },
/** /**
* 获取订单列表 * 获取订单列表