改价,售后

This commit is contained in:
donqi 2022-09-26 02:30:57 +08:00
parent 99084cf6be
commit 9536ab543f
7 changed files with 469 additions and 62 deletions

View File

@ -26,5 +26,10 @@ export default {
seconds: seconds
}
return this.countDownDiffCache;
},
addHours(dateStr, hourAmount) {
let date = new Date(dateStr);
date.setHours(date.getHours() + hourAmount);
return date;
}
}

View File

@ -13,9 +13,9 @@ export default {
})
let userInfo = _this.getCurUserInfo();
// request 触发前拼接 url
// args.url = 'https://www.opsoul.com' + args.url;
args.url = 'http://127.0.0.1:80' + args.url;
// args.url = 'http://192.168.2.42:80' + args.url;
args.url = 'https://www.opsoul.com' + args.url;
// args.url = 'http://127.0.0.1:80' + args.url;
// args.url = 'http://192.168.2.20:80' + args.url;
if (!args.data) {
args.data = {}
@ -567,6 +567,14 @@ export default {
})
return res[1].data;
},
async priceAddedQrPay(params = {}) {
let res = await uni.request({
url: '/pay/ali/addQr',
method: 'POST',
data: params.orderDetailId
})
return res[1].data;
},
async updateMasterOrder(params = {}) {
let res = await uni.request({
url: '/order/master/editOrderMaster',
@ -622,5 +630,25 @@ export default {
data: params
})
return res[1].data;
},
async getAfterList() {
let res = await uni.request({
url: '/order/detail/after/list',
method: 'POST',
data: {}
})
return res[1].data;
},
async editAfterServiceRecord(params = {}) {
let res = await uni.request({
url: '/worker/record/edit',
method: 'POST',
data: params,
header: {
pageNum: params.pageNum,
pageSize: params.pageSize
}
})
return res[1].data;
}
}

View File

@ -0,0 +1,118 @@
<template>
<view class="cu-modal" :class="show?'show':''">
<view class="cu-dialog bg-white">
<view class="cu-bar">
<view class="content">同意售后</view>
<view class="action" data-modal="agreeAfterSale" @click="hideModal">
<text class="cuIcon-close text-red"></text>
</view>
</view>
<view class="padding text-left">
<view class="text-lg">
<text>本单售后到帐额</text>
<text class="text-price text-red">{{data.explainRefund}}</text>
</view>
<view class="text-lg padding-top">
<text>更改到帐额</text>
<input class="radius-input inline-input" v-model="agreedRefund"></input>
<text class="margin-left-xs"></text>
</view>
<view class="padding-top">
<view class="flex justify-start">
<view>原因选择</view>
<radio-group @change="changeReasonRadio">
<label class="radio margin-right-sm">
<radio style="transform:scale(0.7)" class="main-color" value="1" :checked="data.reasonType === 1"/>
<text>客户原因</text>
</label>
<label class="radio">
<radio style="transform:scale(0.7)" class="main-color" value="2" :checked="data.reasonType === 2"/>
<text>师傅原因</text>
</label>
<label class="radio">
<radio style="transform:scale(0.7)" class="main-color" value="3" :checked="data.reasonType === 3"/>
<text>其他</text>
</label>
</radio-group>
</view>
<view class="margin-top">
<textarea style="width: 100%; height: 200rpx;" class="solid radius text-left padding-sm"
v-model="remark" maxlength="-1"
placeholder="请输入具体原因或直接同意,更改到帐金额需与客户协商一致,否则可能被拒绝或引起客诉升级"></textarea>
</view>
</view>
</view>
<view class="cu-bar solid-top">
<view class="action margin-0 flex-sub text-black" data-modal="agreeAfterSale" @click="hideModal">取消</view>
<view class="action margin-0 flex-sub text-main-color solid-left" data-modal="agreeAfterSale"
@click="submit">确认</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'agreeAfterSale',
props: {
show: {
type: Boolean,
default: false
},
data: {
type: Object,
default: {}
}
},
data() {
return {
agreedRefund: null,
reasonType: null,
remark: null
}
},
methods: {
hideModal(e) {
this.resetData();
uni.$emit(this.$globalFun.HIDE_MODAL, e);
},
resetData() {
this.data = null;
this.agreedRefund = null;
this.reasonType = null;
this.remark = null;
},
changeReasonRadio(e) {
this.reasonType = e.detail.value;
},
async submit(e) {
let res = await this.$request.editAfterServiceRecord({
id: this.data.afterServiceRecordList[0].id,
workerFeedbackReasonType: this.reasonType,
agreedRefund: this.agreedRefund,
workerFeedbackReason: this.remark,
updateBy: 2
});
if (res && res.code === 0) {
uni.showToast({
icon: 'success',
duration: 1000
})
this.hideModal(e);
this.$emit('confirmFeedback');
return;
}
uni.showToast({
icon: 'error',
duration: 1000
})
}
},
}
</script>
<style scoped>
.inline-input {
flex-basis: 25%;
}
</style>

View File

@ -90,13 +90,15 @@
newPriceForA2: null,
newPriceForA1: null,
newPrice: null,
showPayQrcodeModal: false
showPayQrcodeModal: false,
remark: ""
}
},
methods: {
init(priceObj) {
this.priceObj = priceObj;
if (priceObj && priceObj.type) {
this.remark = priceObj.remark;
this.payAction = priceObj.type;
let money = priceObj.changeMoney;
if (this.payAction === 1) {
@ -112,6 +114,7 @@
this.newPriceForA2 = null;
this.newPriceForA1 = null;
this.priceObj = null;
this.remark = "";
},
hideModal(e) {
this.resetData();
@ -131,7 +134,8 @@
let res = await this.$request.changeOrderPrice({
orderDetailId: this.data.orderDetailId,
changeMoney: newPrice,
type: this.payAction
type: this.payAction,
remark: this.remark
});
if (res && res.code === 0) {
this.resetPriceChangedInfo();
@ -143,7 +147,7 @@
}
},
async makePayQrcode(e) {
let res = await this.$request.qrPay(this.data);
let res = await this.$request.priceAddedQrPay(this.data);
if (res && res.code === 0) {
this.showPayQrcodeModal = true;
this.$refs.payQrcode.showQrcode(res.data.expend.qrcode_url);

View File

@ -90,13 +90,15 @@
newPriceForA2: null,
newPriceForA1: null,
newPrice: null,
showPayQrcodeModal: false
showPayQrcodeModal: false,
remark: ""
}
},
methods: {
init(priceObj) {
this.priceObj = priceObj;
if (priceObj && priceObj.type) {
this.remark = priceObj.remark;
this.payAction = priceObj.type;
let money = priceObj.changeMoney;
if (this.payAction === 1) {
@ -112,6 +114,7 @@
this.newPriceForA2 = null;
this.newPriceForA1 = null;
this.priceObj = null;
this.remark = "";
},
hideModal(e) {
this.resetData();
@ -131,7 +134,8 @@
let res = await this.$request.changeOrderPrice({
orderDetailId: this.data.orderDetailId,
changeMoney: newPrice,
type: this.payAction
type: this.payAction,
remark: this.remark
});
if (res && res.code === 0) {
this.resetPriceChangedInfo();
@ -143,7 +147,7 @@
}
},
async makePayQrcode(e) {
let res = await this.$request.qrPay(this.data);
let res = await this.$request.priceAddedQrPay(this.data);
if (res && res.code === 0) {
this.showPayQrcodeModal = true;
this.$refs.payQrcode.showQrcode(res.data.expend.qrcode_url);

View File

@ -0,0 +1,171 @@
<template>
<view class="cu-modal" :class="show?'show':''">
<view class="cu-dialog bg-white">
<view class="cu-bar">
<view class="content">拒绝售后</view>
<view class="action" data-modal="rejectAfterSale" @click="hideModal">
<text class="cuIcon-close text-red"></text>
</view>
</view>
<view class="padding text-left">
<view>
<view class="flex justify-start">
<view>原因选择</view>
<radio-group @change="changeReasonRadio">
<label class="radio margin-right-sm">
<radio style="transform:scale(0.7)" class="main-color" value="1" :checked="data.reasonType === 1"/>
<text>客户原因</text>
</label>
<label class="radio">
<radio style="transform:scale(0.7)" class="main-color" value="2" :checked="data.reasonType === 2"/>
<text>师傅原因</text>
</label>
<label class="radio">
<radio style="transform:scale(0.7)" class="main-color" value="3" :checked="data.reasonType === 3"/>
<text>其他</text>
</label>
</radio-group>
</view>
<view class="margin-top">
<textarea style="width: 100%; height: 200rpx;" class="solid radius text-left padding-sm"
v-model="remark" maxlength="-1"
placeholder="请输入具体原因或直接同意,更改到帐金额需与客户协商一致,否则可能被拒绝或引起客诉升级"></textarea>
</view>
</view>
<!-- 上传图片 -->
<view class="padding-top">
<view class="grid col-3 grid-square flex-sub margin-top-sm">
<view class="bg-img" v-for="(item,index) in imgList" :key="index"
@tap="viewImage($event, imgList)" :data-url="item">
<image :src="item" mode="aspectFill"></image>
<view class="cu-tag bg-red" @tap.stop="delImg($event, imgList)" :data-index="index">
<text class='cuIcon-close'></text>
</view>
</view>
<view class="solids" @tap="chooseImgList(e, imgList)" v-if="imgList.length < 3">
<text class='cuIcon-cameraadd'></text>
</view>
</view>
</view>
</view>
<view class="cu-bar solid-top">
<view class="action margin-0 flex-sub text-black" data-modal="rejectAfterSale" @click="hideModal">取消</view>
<view class="action margin-0 flex-sub text-main-color solid-left" data-modal="rejectAfterSale"
@click="submit">确认</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'rejectAfterSale',
props: {
show: {
type: Boolean,
default: false
},
data: {
type: Object,
default: {}
}
},
data() {
return {
show: false,
reasonType: null,
remark: null,
imgList: []
}
},
methods: {
hideModal(e) {
this.resetData();
uni.$emit(this.$globalFun.HIDE_MODAL, e);
},
resetData() {
this.data = null;
this.reasonType = null;
this.remark = null;
},
changeReasonRadio(e) {
this.reasonType = e.detail.value;
},
chooseImgList(e, imgList) {
uni.chooseImage({
count: 3 - imgList.length, //9
sizeType: ['original', 'compressed'], //
sourceType: ['album'], //
success: (res) => {
uni.showLoading({
title: '上传中',
mask: true
});
res.tempFilePaths.forEach((tmpUrl, index) => {
this.$request.uploadFile(tmpUrl).then((url) => {
imgList.push(url);
if (index === res.tempFilePaths.length - 1) {
uni.hideLoading();
}
});
});
}
});
},
viewImage(e, imgList) {
uni.previewImage({
urls: imgList,
current: e.currentTarget.dataset.url
});
},
delImg(e, imgList) {
uni.showModal({
title: '',
content: '确定要删除这张图片吗?',
cancelText: '取消',
confirmText: '确定',
success: res => {
if (res.confirm) {
imgList.splice(e.currentTarget.dataset.index, 1)
}
}
})
},
async submit(e) {
let imgObjList = [];
this.imgList.forEach(url => {
imgObjList.push({
imgUrl: url,
imgUploadBy: 2
})
})
let res = await this.$request.editAfterServiceRecord({
id: this.data.afterServiceRecordList[0].id,
workerFeedbackReasonType: this.reasonType,
workerFeedbackReason: this.remark,
imgsList: imgObjList,
updateBy: 2
});
if (res && res.code === 0) {
uni.showToast({
icon: 'success',
duration: 1000
})
this.hideModal(e);
this.$emit('confirmFeedback');
return;
}
uni.showToast({
icon: 'error',
duration: 1000
})
}
},
}
</script>
<style scoped>
.inline-input {
flex-basis: 25%;
}
</style>

View File

@ -189,51 +189,112 @@
<button class="cu-btn bg-main-color margin-right-xs shadow-blur margin-top-sm" data-modal="showEditTimeArrangeModal" @tap="showModal($event, order)">修改时间</button>
<button class="cu-btn bg-main-color margin-right-xs shadow-blur margin-top-sm">立即上门</button>
</view> -->
<view class="margin-top-sm solid-top padding-top-sm" v-if="order.afterSaleType === 'finished'">
<view class="flex justify-start align-end">
<text>退单申请</text>
<view v-if="order.afterServiceRecordList && order.afterServiceRecordList.length" class="bg-white margin-top-sm">
<view v-for="(afterServiceRecord, afterServiceRecordIndex) in order.afterServiceRecordList" class="solid-top padding-tb">
<view v-if="afterServiceRecord.createBy == 1">
<view class='cu-tag bg-main-color radius light'>客户发起</view>
<view v-if="afterServiceRecord.operType === 1">
<view class="margin-top-sm">
<text>退款申请</text>
<uni-countdown :show-colon="false" :backgroundColor="'#eee'"
:day="$dateUtil.countDownDiff(order.applyRefundLastTime).day"
:hour="$dateUtil.countDownDiff(order.applyRefundLastTime).hour"
:minute="$dateUtil.countDownDiff(order.applyRefundLastTime).min"
:second="$dateUtil.countDownDiff(order.applyRefundLastTime).seconds">
:day="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).day"
:hour="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).hour"
:minute="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).min"
:second="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).seconds">
</uni-countdown>
</view>
<view class="margin-top-xs">
<text>退款金额</text><text class="text-price">{{order.refundAmount}}</text>
<text class="margin-left-sm">到帐金额</text><text class="text-price">{{order.refundReachAmount}}</text>
<view class="margin-top-sm">
<text>退款金额</text>
<text>{{afterServiceRecord.refund}}</text>
</view>
<view class="margin-top-xs">
<text>退款原因</text><text>{{order.refundReason}}</text>
<view class="margin-top-sm">
<text>退款原因</text>
<text>{{afterServiceRecord.customerReason}}</text>
</view>
<view class="flex justify-end margin-top-xs">
<button class="cu-btn sm bg-yellow margin-right-sm" @click="showAfterSalePic(index)" @tap="showModalByRef('showPicModal')">查看</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-if="order.refundStatus !== 'rejected'" @click="updateRefundStatus('rejected', index)">拒绝处理</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-else disabled type="">已拒绝</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-if="order.refundStatus !== 'recevied'" @click="updateRefundStatus('recevied', index)">同意退单</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-else disabled type="">已同意</button>
<view class="grid col-3 grid-square flex-sub margin-top-sm">
<view class="bg-img" v-for="(imgObj, imgIndex) in afterServiceRecord.imgsList" :key="imgIndex">
<image :src="imgObj.imgUrl" @tap="viewImage($event, [imgObj.imgUrl])" :data-url="imgObj.imgUrl" mode="aspectFill"></image>
</view>
</view>
<view class="margin-top-sm solid-top padding-top-sm" v-else-if="order.afterSaleType === 'unfinished'">
</view>
<view v-else-if="afterServiceRecord.operType === 2">
<view class="flex justify-start align-end">
<text>待处理售后</text>
<uni-countdown :show-colon="false" :backgroundColor="'#eee'"
:day="$dateUtil.countDownDiff(order.waitAfterSaleLastTime).day"
:hour="$dateUtil.countDownDiff(order.waitAfterSaleLastTime).hour"
:minute="$dateUtil.countDownDiff(order.waitAfterSaleLastTime).min"
:second="$dateUtil.countDownDiff(order.waitAfterSaleLastTime).seconds">
:day="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).day"
:hour="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).hour"
:minute="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).min"
:second="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).seconds">
</uni-countdown>
</view>
<view class="margin-top-xs">
<text>售后原因</text><text>{{order.afterSaleReason}}</text>
<view>
<text>售后原因</text>
<text>{{afterServiceRecord.customerReason}}</text>
</view>
<view class="margin-top-sm">
<text>完成操作点击处理完成提交由客服回访</text>
</view>
<view class="grid col-3 grid-square flex-sub margin-top-sm">
<view class="bg-img" v-for="(imgObj, imgIndex) in afterServiceRecord.imgsList" :key="imgIndex">
<image :src="imgObj.imgUrl" @tap="viewImage($event, [imgObj.imgUrl])" :data-url="imgObj.imgUrl" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<view v-if="afterServiceRecord.updateBy == 2">
<view class='cu-tag bg-main-color radius light'>师傅反馈</view>
<view v-if="afterServiceRecord.operType === 1">
<view class="margin-top-sm">
<text>退款申请</text>
<uni-countdown :show-colon="false" :backgroundColor="'#eee'"
:day="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).day"
:hour="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).hour"
:minute="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).min"
:second="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).seconds">
</uni-countdown>
</view>
<view class="margin-top-sm">
<text>退款金额</text>
<text>{{afterServiceRecord.agreedRefund ? afterServiceRecord.agreedRefund : afterServiceRecord.refund}}</text>
</view>
<view class="margin-top-sm">
<text>退款原因</text>
<text>{{afterServiceRecord.workerFeedbackReason}}</text>
</view>
<view class="grid col-3 grid-square flex-sub margin-top-sm">
<view class="bg-img" v-for="(imgObj, imgIndex) in afterServiceRecord.imgsList" :key="imgIndex">
<image :src="imgObj.imgUrl" @tap="viewImage($event, [imgObj.imgUrl])" :data-url="imgObj.imgUrl" mode="aspectFill"></image>
</view>
</view>
</view>
<view v-else-if="afterServiceRecord.operType === 2">
<view class="flex justify-start align-end">
<text>待处理售后</text>
<uni-countdown :show-colon="false" :backgroundColor="'#eee'"
:day="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).day"
:hour="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).hour"
:minute="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).min"
:second="$dateUtil.countDownDiff($dateUtil.addHours(afterServiceRecord.createTime, 24)).seconds">
</uni-countdown>
</view>
<view>
<text>售后原因</text>
<text>{{afterServiceRecord.workerFeedbackReason}}</text>
</view>
<view class="margin-top-sm">
<text>完成操作点击处理完成提交由客服回访</text>
</view>
<view class="grid col-3 grid-square flex-sub margin-top-sm">
<view class="bg-img" v-for="(imgObj, imgIndex) in afterServiceRecord.imgsList" :key="imgIndex">
<image :src="imgObj.imgUrl" @tap="viewImage($event, [imgObj.imgUrl])" :data-url="imgObj.imgUrl" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<view class="flex justify-end align-end">
<button class="cu-btn sm bg-yellow margin-right-sm" data-modal="rejectAfterSale" @tap="showModal($event, order)">拒绝处理</button>
<button class="cu-btn sm bg-yellow margin-right-sm" data-modal="agreeAfterSale" @tap="showModal($event, order)">处理完成</button>
</view>
<view class="margin-top-xs">完成操作点击处理完成提交由客服回访</view>
<view class="flex justify-end align-end margin-top-xs">
<button class="cu-btn sm bg-yellow margin-right-sm" @click="showAfterSalePic(index)" @tap="showModalByRef('showPicModal')">查看</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-if="order.afterSaleDealStatus !== 'rejected'" @click="updateAfterSaleDealStatus('rejected', index)">拒绝处理</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-else disabled type="">已拒绝</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-if="order.afterSaleDealStatus !== 'recevied'" @click="updateAfterSaleDealStatus('recevied', index)">处理完成</button>
<button class="cu-btn sm bg-yellow margin-right-sm" v-else disabled type="">已同意</button>
</view>
</view>
<view class="margin-top-sm solid-top padding-top-sm" v-if="Boolean(order.customerRemark)">
@ -242,7 +303,7 @@
</view>
</view>
<view :class="tabCur !== 4 ? 'cu-tabbar-height' : ''"></view>
<load-status-bar v-show="tabCur === 4" ref="loadStatusBar" @loadMore="loadMasterOrderPage"></load-status-bar>
<load-status-bar v-show="tabCur === 4 || tabCur === 5" ref="loadStatusBar" @loadMore="loadMasterOrderPage"></load-status-bar>
<!-- 模态框 -->
<time-arrange :show="showTimeArrangeModal" :data="curOrder" :curDate="curDate" @showArrangeFailTime="showArrangeFailTime" @editServTime="editServTime"></time-arrange>
<time-arrange-fail :show="showArrangeFailTimeModal" :data="curOrder"></time-arrange-fail>
@ -266,6 +327,8 @@
<!-- 账户及实名弹窗 -->
<vertify-bank-bind ref="vertifyBankBind"></vertify-bank-bind>
<vertify-certify ref="vertifyCertify"></vertify-certify>
<agree-after-sale :show="agreeAfterSale" :data="curOrder" @confirmFeedback="reloadMasterOrderPage"></agree-after-sale>
<reject-after-sale :show="rejectAfterSale" :data="curOrder" @confirmFeedback="reloadMasterOrderPage"></reject-after-sale>
</view>
</template>
@ -281,6 +344,8 @@
import urgentMsg from '@/pages/order-manage/modal/urgent-msg.vue';
import picModal from '@/components/modal/pic-modal.vue';
import loadStatusBar from '@/components/custom-bar/load-status-bar.vue';
import agreeAfterSale from '@/pages/order-manage/modal/agree-after-sale.vue';
import rejectAfterSale from '@/pages/order-manage/modal/reject-after-sale.vue';
export default {
components: {
@ -294,7 +359,9 @@
payQrcode,
urgentMsg,
picModal,
loadStatusBar
loadStatusBar,
agreeAfterSale,
rejectAfterSale
},
data() {
return {
@ -341,6 +408,9 @@
// name: ''
// },
{
// code: 5,
name: '售后中'
}, {
code: 5,
name: '已完成'
}],
@ -362,6 +432,8 @@
showPayQrcodeModal: false,
showEditTimeArrangeModal: false,
sendUrgentMsgModal: false,
agreeAfterSale: false,
rejectAfterSale: false,
ifShowPageMeta: false,
picModalImgList: [],
curDate: '',
@ -449,10 +521,14 @@
try {
let res = null;
//
if (this.tabCur === 4 || this.stateCur === 1 || this.stateCur === 2) {
if (this.tabCur === 4 || this.tabCur === 5 || this.stateCur === 1 || this.stateCur === 2) {
//
this.$refs.loadStatusBar.showLoading();
res = await this.$request.qryDetailOrderPage(params);
let funName = "qryDetailOrderPage";
if (this.tabCur === 4) {
funName = "getAfterList";
}
res = await this.$request[funName](params);
if (res && res.rows) {
let rowsLength = res.rows.length;
if (rowsLength > 0) {
@ -655,8 +731,9 @@
}
this[e.currentTarget.dataset.modal] = true;
},
showModalByRef(refName) {
this.$refs[refName].showModal();
showModalByRef(refName, curOrder, params) {
this.$refs[refName].showModal(curOrder, params);
this.curOrder = curOrder;
},
hideModal(e) {
this.curOrder = null;