|
|
|
@ -5,6 +5,11 @@ |
|
|
|
<div class="title">订单信息</div> |
|
|
|
<div>订单编号:{{orderData.numberCode}}</div> |
|
|
|
<div>支付订单编号:{{'ORDER'+orderData.id}}</div> |
|
|
|
<div>订单状态:{{getOrderStatusText(orderData)}}</div> |
|
|
|
<div>创建时间:{{orderData.createTime | formatDateTime}}</div> |
|
|
|
<div v-if="orderData.payTime">支付时间:{{orderData.payTime | formatDateTime}}</div> |
|
|
|
<div v-if="orderData.groupInfo && orderData.groupInfo.successTime">成团时间:{{orderData.groupInfo.successTime | formatDateTime}}</div> |
|
|
|
<div v-if="orderData.deliveryType == 2 && orderData.shopMakeTime">核销时间:{{orderData.shopMakeTime | formatDateTime}}</div> |
|
|
|
</div> |
|
|
|
<div class="waiceng"> |
|
|
|
<div class="title">用户信息</div> |
|
|
|
@ -27,51 +32,44 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style="display: flex;" v-if="orderData.status ==7 || orderData.status ==11"> |
|
|
|
<div class="waiceng" style="width: 70%;"> |
|
|
|
<div class="title" style="color:red">申请退款信息-用户全部退款</div> |
|
|
|
<div class="box" v-for="(item,index) in orderData.goodsList" :key="index"> |
|
|
|
<div style="flex:1;">{{item.productName}}</div> |
|
|
|
<div class="price"> X{{item.quantity}}</div> |
|
|
|
<div class="price">¥{{item.price}}</div> |
|
|
|
</div> |
|
|
|
<div class="box"> |
|
|
|
<div style="flex:1;">餐盒费</div> |
|
|
|
<div class="price">¥{{orderData.packageFee}}</div> |
|
|
|
</div> |
|
|
|
<div class="box"> |
|
|
|
<div style="flex:1;">配送费</div> |
|
|
|
<div class="price">¥{{orderData.deliveryFee}}</div> |
|
|
|
</div> |
|
|
|
<div class="zong"> |
|
|
|
合计退款:<span style="color:red;">¥{{orderData.totalAmount}}</span></div> |
|
|
|
</div> |
|
|
|
<div style="background: #fff;padding: 10px;border-radius: 10px;width: 30%;margin: 10;"> |
|
|
|
<div style="background: #fff;padding: 10px;border-radius: 10px;width: 100%;margin: 10;"> |
|
|
|
<div class="title">售后原因说明</div> |
|
|
|
<textarea name="" id="" cols="30" rows="10" style="width: 100%;border: 1px solid #eee;"></textarea> |
|
|
|
<textarea name="" id="" cols="30" rows="10" style="width: 100%;border: 1px solid #eee;" :value="getCurrentRefundRecord().reason || orderData.reason || ''" readonly></textarea> |
|
|
|
<div style="display: flex;"> |
|
|
|
<div class='btn' @click="returnAmountAllow(orderData,1)">同意退款</div> |
|
|
|
<div class='btn' @click="returnAmountAllow(orderData,0)">拒绝退款</div> |
|
|
|
<div class='btn' @click="returnAmountAllow(getCurrentRefundRecord(),1)">同意退款</div> |
|
|
|
<div class='btn' @click="returnAmountAllow(getCurrentRefundRecord(),0)">拒绝退款</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style="display: flex;"> |
|
|
|
<div class="waiceng" style="width: 69%;"> |
|
|
|
<div class="title">商品信息</div> |
|
|
|
<div class="box" v-for="(item,index) in orderData.goodsList" :key="index"> |
|
|
|
<div style="flex:1;">{{item.productName}}</div> |
|
|
|
<div class="goods-row" v-for="(item,index) in orderData.goodsList" :key="index"> |
|
|
|
<img v-if="item.productPicture" class="goods-img" :src="item.productPicture" /> |
|
|
|
<div class="goods-info"> |
|
|
|
<div>{{item.productName}}</div> |
|
|
|
<div v-if="item.specs" class="goods-spec">{{formatSpecs(item.specs)}}</div> |
|
|
|
</div> |
|
|
|
<div class="price"> X{{item.quantity}}</div> |
|
|
|
<div class="price">¥{{item.price}}</div> |
|
|
|
</div> |
|
|
|
<div class="box"> |
|
|
|
<div class="box" v-if="orderData.packageFee != null && orderData.packageFee > 0"> |
|
|
|
<div style="flex:1;">餐盒费</div> |
|
|
|
<div class="price">¥{{orderData.packageFee}}</div> |
|
|
|
</div> |
|
|
|
<div class="box"> |
|
|
|
<div class="box" v-if="orderData.deliveryType == 1"> |
|
|
|
<div style="flex:1;">配送费</div> |
|
|
|
<div class="price">¥{{orderData.deliveryFee}}</div> |
|
|
|
</div> |
|
|
|
<div class="zong">活动优惠:<span style="color:red;">¥0</span> 下单返佣:<span style="color:red;">¥0</span> |
|
|
|
合计:<span style="color:#11cd6e;">¥{{orderData.totalAmount}}</span></div> |
|
|
|
<div class="box" v-if="orderData.freeAmount != null && orderData.freeAmount > 0"> |
|
|
|
<div style="flex:1;color:#ff6f2c;font-weight:700;">锦鲤免单</div> |
|
|
|
<div class="price" style="color:#ff6f2c;font-weight:700;">¥{{orderData.freeAmount}}</div> |
|
|
|
</div> |
|
|
|
<div class="box" v-if="orderData.userCouponNum != null && orderData.userCouponNum > 0"> |
|
|
|
<div style="flex:1;">优惠券</div> |
|
|
|
<div class="price">-¥{{orderData.userCouponNum}}</div> |
|
|
|
</div> |
|
|
|
<div class="zong">{{orderData.status == 0 ? '待支付' : '实付'}}:<span style="color:#11cd6e;">¥{{orderData.totalAmount}}</span></div> |
|
|
|
<div v-if="orderData.chouyong" class="zong">平台服务费:<span class="blue-color">¥{{(orderData.chouyong).toFixed(2)}}</span> </div> |
|
|
|
<div v-if="orderData.yujishouru" class="zong">商家预计收入:<span class="blue-color">¥{{(orderData.yujishouru).toFixed(2)}}</span> </div> |
|
|
|
</div> |
|
|
|
@ -92,6 +90,59 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="waiceng" v-if="orderData.mallRefundRecord && orderData.mallRefundRecord.length > 0"> |
|
|
|
<div class="title">退款/售后</div> |
|
|
|
<div class="refund-card" v-for="(item,index) in orderData.mallRefundRecord" :key="index"> |
|
|
|
<div class="refund-row"> |
|
|
|
<span>申请时间</span> |
|
|
|
<span>{{item.createTime | formatDateTime}}</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row"> |
|
|
|
<span>金额</span> |
|
|
|
<span>¥{{item.refundAmount}}</span> |
|
|
|
</div> |
|
|
|
<div class="refund-goods-row" v-for="(goods,goodsIndex) in getRefundItems(item)" :key="goodsIndex"> |
|
|
|
<img v-if="goods.productPicture" class="goods-img" :src="goods.productPicture" /> |
|
|
|
<div class="goods-info"> |
|
|
|
<div>{{goods.productName}}</div> |
|
|
|
<div v-if="goods.specs" class="goods-spec">{{formatSpecs(goods.specs)}}</div> |
|
|
|
<div v-if="goods.packageFee != undefined && goods.packageFee > 0 && orderData.packageFee > 0" class="goods-spec">餐盒费 ¥{{goods.packageFee}}</div> |
|
|
|
</div> |
|
|
|
<div class="price">X{{goods.quantity}}</div> |
|
|
|
<div class="price">¥{{goods.price}}</div> |
|
|
|
</div> |
|
|
|
<div class="refund-row"> |
|
|
|
<span>原因</span> |
|
|
|
<span>{{item.reason || ""}}</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row" v-if="item.pictures != null && item.pictures != ''"> |
|
|
|
<span>图片</span> |
|
|
|
<span> |
|
|
|
<img class="refund-image" v-for="(picture,pictureIndex) in getPictureList(item.pictures)" :key="pictureIndex" :src="picture" /> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row"> |
|
|
|
<span>退款/售后类型</span> |
|
|
|
<span>{{getRefundTypeText(item)}}<template v-if="item.refundTypeStatus != null"> | {{getRefundTypeStatusText(item)}}</template></span> |
|
|
|
</div> |
|
|
|
<div class="refund-row"> |
|
|
|
<span>退款/售后状态</span> |
|
|
|
<span>{{getRefundStatusText(item.status)}}</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row" v-if="(item.status == 2 || item.status == 5) && item.rejectReason"> |
|
|
|
<span>拒绝原因</span> |
|
|
|
<span>{{item.rejectReason}}</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row" v-if="item.status == 0 || item.status == 3"> |
|
|
|
<span>自动退款时间</span> |
|
|
|
<span>{{getAutoRefundTime(item.createTime)}} 之前对方未处理系统会自动退款</span> |
|
|
|
</div> |
|
|
|
<div class="refund-row" v-if="item.successTime != null"> |
|
|
|
<span>处理退款/售后时间</span> |
|
|
|
<span>{{item.successTime | formatDateTime}}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
@ -108,10 +159,15 @@ |
|
|
|
name: "logisticsAddress", |
|
|
|
data() { |
|
|
|
return { |
|
|
|
orderData: {}, |
|
|
|
orderData: { |
|
|
|
deliveryInfo: {}, |
|
|
|
goodsList: [], |
|
|
|
mallRefundRecord: [] |
|
|
|
}, |
|
|
|
returnFormData:{}, |
|
|
|
refundReason: "", |
|
|
|
refundLoading: false |
|
|
|
refundLoading: false, |
|
|
|
refundActionData: null |
|
|
|
}; |
|
|
|
}, |
|
|
|
filters: { |
|
|
|
@ -130,43 +186,69 @@ |
|
|
|
methods: { |
|
|
|
initRecharge(data) { |
|
|
|
this.refundReason = ""; |
|
|
|
if(data.status == 7 || data.status == 11){ |
|
|
|
this.orderData = data |
|
|
|
this.orderData.goodsList = this.orderData.items |
|
|
|
this.orderData.deliveryInfo = this.orderData.mallDeliveryOrder |
|
|
|
this.orderData.deliveryType = this.orderData.deliveryInfo.deliveryType |
|
|
|
this.orderData.deliveryFee = this.orderData.deliveryInfo.deliveryFee |
|
|
|
this.orderData.packageFee = data.mallOrder.packageFee |
|
|
|
this.orderData.numberCode = this.orderData.mallDeliveryOrder.numberCode |
|
|
|
}else{ |
|
|
|
this.refundActionData = data; |
|
|
|
const orderId = data.orderId || (data.mallOrder && data.mallOrder.id) || data.id; |
|
|
|
const shopId = data.shopId || (data.mallOrder && data.mallOrder.shopId); |
|
|
|
if (shopId) { |
|
|
|
getByShopId({ |
|
|
|
"shopId": data.shopId |
|
|
|
"shopId": shopId |
|
|
|
}).then((res) => { |
|
|
|
if (res.success) { |
|
|
|
this.orderDetail(data.id,res.result) |
|
|
|
this.orderDetail(orderId, res.result, data) |
|
|
|
} else { |
|
|
|
this.orderDetail(orderId, {}, data) |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
this.orderDetail(orderId, {}, data) |
|
|
|
} |
|
|
|
}, |
|
|
|
orderDetail(id,shopTakeaway) { |
|
|
|
orderDetail(id,shopTakeaway, sourceData) { |
|
|
|
getOrderDetail(id).then((res) => { |
|
|
|
this.loading = false; |
|
|
|
if (res.success) { |
|
|
|
this.orderData = res.result |
|
|
|
this.orderData = this.normalizeOrderData(res.result) |
|
|
|
if ((!this.orderData.mallRefundRecord || this.orderData.mallRefundRecord.length == 0) && sourceData && sourceData.refundAmount != null) { |
|
|
|
this.orderData.mallRefundRecord = [sourceData]; |
|
|
|
} |
|
|
|
//商家预计收入的计算 |
|
|
|
let price = this.orderData.goodsAmount+this.orderData.packageFee |
|
|
|
let price = (this.orderData.goodsAmount || 0) + (this.orderData.packageFee || 0) |
|
|
|
if(this.orderData.orderType == 1){ |
|
|
|
this.orderData.chouyong = price/100 * shopTakeaway.commissionRateOne |
|
|
|
this.orderData.chouyong = price/100 * (shopTakeaway.commissionRateOne || 0) |
|
|
|
this.orderData.yujishouru = price - this.orderData.chouyong |
|
|
|
}else{ |
|
|
|
this.orderData.chouyong = price/100 * shopTakeaway.commissionRateMore |
|
|
|
this.orderData.chouyong = price/100 * (shopTakeaway.commissionRateMore || 0) |
|
|
|
this.orderData.yujishouru = price - this.orderData.chouyong |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
}, |
|
|
|
normalizeOrderData(data) { |
|
|
|
return Object.assign({ |
|
|
|
deliveryInfo: {}, |
|
|
|
goodsList: [], |
|
|
|
mallRefundRecord: [] |
|
|
|
}, data || {}, { |
|
|
|
deliveryInfo: (data && data.deliveryInfo) || {}, |
|
|
|
goodsList: (data && data.goodsList) || [], |
|
|
|
mallRefundRecord: (data && data.mallRefundRecord) || [] |
|
|
|
}); |
|
|
|
}, |
|
|
|
getCurrentRefundRecord() { |
|
|
|
const records = this.orderData.mallRefundRecord || []; |
|
|
|
const pendingRecord = records.find((item) => item.status == 0 || item.status == 3); |
|
|
|
return pendingRecord || this.refundActionData || this.orderData; |
|
|
|
}, |
|
|
|
getRefundItems(item) { |
|
|
|
if (item && item.items && item.items.length > 0) return item.items; |
|
|
|
return []; |
|
|
|
}, |
|
|
|
returnAmountAllow(item,status){ |
|
|
|
if (!item) { |
|
|
|
this.$Message.warning("未找到退款/售后记录"); |
|
|
|
return; |
|
|
|
} |
|
|
|
let titleText = status == 1 ? '确定同意该申请吗?' : '确定拒绝该申请吗?'; |
|
|
|
//退款提示 |
|
|
|
|
|
|
|
@ -199,16 +281,17 @@ |
|
|
|
}); |
|
|
|
}, |
|
|
|
processReturn(item,status){ |
|
|
|
if (!item) return; |
|
|
|
let url = '' |
|
|
|
//退款 |
|
|
|
if(item.status == 7){ |
|
|
|
if(item.status == 7 || item.status == 0){ |
|
|
|
//不同意 |
|
|
|
if(status == 0){ |
|
|
|
this.returnFormData.status = 2 |
|
|
|
}else{ |
|
|
|
this.returnFormData.status = 1 |
|
|
|
} |
|
|
|
}else if(item.status == 11){ |
|
|
|
}else if(item.status == 11 || item.status == 3){ |
|
|
|
//售后 |
|
|
|
if(status == 0){ |
|
|
|
this.returnFormData.status = 5 |
|
|
|
@ -216,11 +299,12 @@ |
|
|
|
this.returnFormData.status = 4 |
|
|
|
} |
|
|
|
} |
|
|
|
const order = item.mallOrder || this.orderData || {}; |
|
|
|
this.returnFormData.id = item.id; |
|
|
|
this.returnFormData.linkId = item.linkId; |
|
|
|
this.returnFormData.orderId = item.orderId; |
|
|
|
this.returnFormData.deliveryType = item.mallOrder.deliveryType; |
|
|
|
this.returnFormData.orderType = item.mallOrder.orderType; |
|
|
|
this.returnFormData.orderId = item.orderId || order.id; |
|
|
|
this.returnFormData.deliveryType = order.deliveryType; |
|
|
|
this.returnFormData.orderType = order.orderType; |
|
|
|
this.returnFormData.refundAmount = item.refundAmount; |
|
|
|
this.returnFormData.refundType = item.refundType; |
|
|
|
this.returnFormData.refundTypeStatus = item.refundTypeStatus; |
|
|
|
@ -246,7 +330,73 @@ |
|
|
|
return diffMinutes; |
|
|
|
}, |
|
|
|
canAdminRefundOrder() { |
|
|
|
return this.orderData.status != 6 && this.orderData.status != 8 && this.orderData.status != 12; |
|
|
|
return this.orderData.status != 0 && this.orderData.status != 6 && this.orderData.status != 8 && this.orderData.status != 12; |
|
|
|
}, |
|
|
|
formatSpecs(data) { |
|
|
|
if (data == null || data === "") return ""; |
|
|
|
let str = typeof data === "object" ? JSON.stringify(data) : String(data); |
|
|
|
return str.replace(/[{}"]/g, ""); |
|
|
|
}, |
|
|
|
getPictureList(pictures) { |
|
|
|
if (pictures == null || pictures === "") return []; |
|
|
|
if (Array.isArray(pictures)) { |
|
|
|
return pictures.filter((item) => item != null && item !== ""); |
|
|
|
} |
|
|
|
return String(pictures).split(",").map((item) => item.trim()).filter((item) => item !== ""); |
|
|
|
}, |
|
|
|
getRefundTypeText(item) { |
|
|
|
if (!item) return ""; |
|
|
|
if (item.refundType == 1) return "退商品"; |
|
|
|
if (item.refundType == 2) return "退配送费"; |
|
|
|
return "全额退款"; |
|
|
|
}, |
|
|
|
getRefundTypeStatusText(item) { |
|
|
|
if (!item) return ""; |
|
|
|
if (item.refundTypeStatus == 1) return "商家退款"; |
|
|
|
if (item.refundTypeStatus == 2) return "配送员退款"; |
|
|
|
if (item.refundTypeStatus == 3) { |
|
|
|
return item.linkId && String(item.linkId).indexOf("W") != -1 ? "配送员退款" : "商家退款"; |
|
|
|
} |
|
|
|
return "平台退款"; |
|
|
|
}, |
|
|
|
getRefundStatusText(status) { |
|
|
|
if (status == 0) return "处理退款中"; |
|
|
|
if (status == 1) return "同意退款"; |
|
|
|
if (status == 2) return "拒绝退款"; |
|
|
|
if (status == 3) return "处理售后中"; |
|
|
|
if (status == 4) return "同意售后"; |
|
|
|
if (status == 5) return "拒绝售后"; |
|
|
|
return ""; |
|
|
|
}, |
|
|
|
getOrderStatusText(item) { |
|
|
|
if (!item) return ""; |
|
|
|
if (item.status == 0) return "待支付"; |
|
|
|
if (item.status == 2) return item.shopDelivery == 1 ? "等待商家配送接单" : "等待配送员接单"; |
|
|
|
if (item.status == 3 && item.deliveryType == 1 && item.deliveryInfo && item.deliveryInfo.transferDelivery == 1 && !item.deliveryInfo.transferArriveTime) return "等待商家送达中转点"; |
|
|
|
if (item.status == 3 && item.deliveryType == 1 && item.deliveryInfo && item.deliveryInfo.transferDelivery == 1 && item.deliveryInfo.transferArriveTime) return "待配送员取货"; |
|
|
|
if (item.status == 3 && item.deliveryType == 1) return item.shopDelivery == 1 ? "商家配送已接单" : "配送员已接单"; |
|
|
|
if (item.status == 3 && item.deliveryType == 2) return "待消费"; |
|
|
|
if (item.status == 4 && item.deliveryType == 1) return item.deliveryInfo && item.deliveryInfo.transferDelivery == 1 ? "中转配送中" : "配送员已取货"; |
|
|
|
if (item.status == 5) return "订单已完成"; |
|
|
|
if (item.status == 6) return "订单已取消"; |
|
|
|
if (item.status == 7) return "等待同意退款"; |
|
|
|
if (item.status == 8) return "订单已退款"; |
|
|
|
if (item.status == 11) return "售后中"; |
|
|
|
if (item.status == 12) return "订单已售后"; |
|
|
|
return ""; |
|
|
|
}, |
|
|
|
getAutoRefundTime(value) { |
|
|
|
if (!value) return ""; |
|
|
|
const date = new Date(value); |
|
|
|
if (isNaN(date.getTime())) return ""; |
|
|
|
date.setHours(date.getHours() + 1); |
|
|
|
const year = date.getFullYear(); |
|
|
|
const month = String(date.getMonth() + 1).padStart(2, "0"); |
|
|
|
const day = String(date.getDate()).padStart(2, "0"); |
|
|
|
const hours = String(date.getHours()).padStart(2, "0"); |
|
|
|
const minutes = String(date.getMinutes()).padStart(2, "0"); |
|
|
|
const seconds = String(date.getSeconds()).padStart(2, "0"); |
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
|
|
|
}, |
|
|
|
adminRefundOrder() { |
|
|
|
if (this.refundLoading || !this.orderData.id) return; |
|
|
|
@ -320,6 +470,63 @@ |
|
|
|
height: 30px px; |
|
|
|
} |
|
|
|
|
|
|
|
.goods-row, |
|
|
|
.refund-goods-row { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
padding: 8px 0; |
|
|
|
border-bottom: 1px solid #eee; |
|
|
|
} |
|
|
|
|
|
|
|
.goods-img { |
|
|
|
width: 54px; |
|
|
|
height: 54px; |
|
|
|
margin-right: 10px; |
|
|
|
border-radius: 4px; |
|
|
|
object-fit: cover; |
|
|
|
} |
|
|
|
|
|
|
|
.goods-info { |
|
|
|
flex: 2; |
|
|
|
} |
|
|
|
|
|
|
|
.goods-spec { |
|
|
|
margin-top: 4px; |
|
|
|
color: #999; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.refund-card { |
|
|
|
margin-top: 10px; |
|
|
|
padding: 10px; |
|
|
|
border: 1px solid #eee; |
|
|
|
border-radius: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
.refund-row { |
|
|
|
display: flex; |
|
|
|
padding: 6px 0; |
|
|
|
border-bottom: 1px solid #f3f3f3; |
|
|
|
} |
|
|
|
|
|
|
|
.refund-row span:first-child { |
|
|
|
width: 130px; |
|
|
|
color: #777; |
|
|
|
font-weight: 700; |
|
|
|
} |
|
|
|
|
|
|
|
.refund-row span:last-child { |
|
|
|
flex: 1; |
|
|
|
} |
|
|
|
|
|
|
|
.refund-image { |
|
|
|
width: 80px; |
|
|
|
height: 80px; |
|
|
|
margin-right: 8px; |
|
|
|
border-radius: 4px; |
|
|
|
object-fit: cover; |
|
|
|
} |
|
|
|
|
|
|
|
.text { |
|
|
|
font-weight: bold; |
|
|
|
color: #777; |
|
|
|
|