|
|
|
@ -63,6 +63,24 @@ |
|
|
|
padding-top: 8px; |
|
|
|
text-align: right; |
|
|
|
} |
|
|
|
|
|
|
|
.feedback-preview { |
|
|
|
text-align: center; |
|
|
|
} |
|
|
|
|
|
|
|
.feedback-preview-img { |
|
|
|
max-width: 100%; |
|
|
|
max-height: 70vh; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.feedback-preview-actions { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
margin-top: 12px; |
|
|
|
gap: 12px; |
|
|
|
} |
|
|
|
</style> |
|
|
|
<template> |
|
|
|
<div class="search"> |
|
|
|
@ -70,7 +88,7 @@ |
|
|
|
<Tabs v-model="tabName" :animated="false" @on-click="changeOrderTab"> |
|
|
|
<TabPane v-for="item in orderTypeTabs" :key="item.name" :label="getOrderTypeTabLabel(item)" :name="item.name"></TabPane> |
|
|
|
</Tabs> |
|
|
|
<Tabs v-if="!isRefundTab" v-model="tabName1" :animated="false" @on-click="changeTab"> |
|
|
|
<Tabs v-if="!isRefundTab && !isFeedbackTab" v-model="tabName1" :animated="false" @on-click="changeTab"> |
|
|
|
<TabPane v-for="item in currentStatusTabs" :key="item.name" :label="item.label" :name="item.name"></TabPane> |
|
|
|
</Tabs> |
|
|
|
<Row v-show="openSearch" @keydown.enter.native="handleSearch"> |
|
|
|
@ -93,7 +111,7 @@ |
|
|
|
<Row align="middle" justify="space-between" class="operation"> |
|
|
|
<div class="icons"> |
|
|
|
<Tooltip content="刷新" placement="top" transfer> |
|
|
|
<Icon type="md-refresh" size="18" class="item" @click="getLogisticsInfo" /> |
|
|
|
<Icon type="md-refresh" size="18" class="item" @click="refreshWholePage" /> |
|
|
|
</Tooltip> |
|
|
|
<Tooltip :content="openSearch ? '关闭搜索' : '开启搜索'" placement="top" transfer> |
|
|
|
<Icon type="ios-search" size="18" class="item tip" @click="openSearch = !openSearch" /> |
|
|
|
@ -183,6 +201,39 @@ |
|
|
|
<Button type="primary" @click="groupOrderVisible = false">关闭</Button> |
|
|
|
</div> |
|
|
|
</Modal> |
|
|
|
<Modal title="投诉吐槽详情" v-model="feedbackDetailVisible" :mask-closable="false" :width="720"> |
|
|
|
<Form :label-width="90"> |
|
|
|
<FormItem label="反馈类型">{{ feedbackDetail.feedbackType || "投诉吐槽" }}</FormItem> |
|
|
|
<FormItem label="反馈用户">{{ feedbackDetail.userName || feedbackDetail.userId || "未知用户" }}</FormItem> |
|
|
|
<FormItem label="联系电话">{{ feedbackDetail.contactPhone || "无" }}</FormItem> |
|
|
|
<FormItem label="所属区域">{{ feedbackDetail.regionName || feedbackDetail.regionId || "无" }}</FormItem> |
|
|
|
<FormItem label="反馈内容">{{ feedbackDetail.problemContent || "无" }}</FormItem> |
|
|
|
<FormItem label="反馈图片"> |
|
|
|
<a v-if="getPictureList(feedbackDetail.problemPicture).length > 0" @click="previewFeedbackImage(feedbackDetail.problemPicture)">查看图片</a> |
|
|
|
<span v-else>无</span> |
|
|
|
</FormItem> |
|
|
|
<FormItem label="提交时间">{{ formatDateTime(feedbackDetail.createTime) }}</FormItem> |
|
|
|
<FormItem label="处理意见"> |
|
|
|
<Input type="textarea" v-model="feedbackReplyContent" :rows="4" maxlength="300" show-word-limit |
|
|
|
:disabled="feedbackDetail.status == 1" placeholder="请输入处理意见" /> |
|
|
|
</FormItem> |
|
|
|
<FormItem v-if="feedbackDetail.status == 1" label="处理时间">{{ formatDateTime(feedbackDetail.handleTime) }}</FormItem> |
|
|
|
</Form> |
|
|
|
<div slot="footer"> |
|
|
|
<Button @click="feedbackDetailVisible = false">关闭</Button> |
|
|
|
<Button v-if="feedbackDetail.status != 1" type="primary" :loading="feedbackSubmitLoading" @click="submitFeedbackReply">回复</Button> |
|
|
|
</div> |
|
|
|
</Modal> |
|
|
|
<Modal title="图片预览" v-model="feedbackPreviewVisible" :footer-hide="true" :width="760"> |
|
|
|
<div class="feedback-preview" v-if="feedbackPreviewList.length > 0"> |
|
|
|
<img class="feedback-preview-img" :src="feedbackPreviewList[feedbackPreviewIndex]" /> |
|
|
|
<div class="feedback-preview-actions" v-if="feedbackPreviewList.length > 1"> |
|
|
|
<Button size="small" @click="changeFeedbackPreview(-1)">上一张</Button> |
|
|
|
<span>{{ feedbackPreviewIndex + 1 }} / {{ feedbackPreviewList.length }}</span> |
|
|
|
<Button size="small" @click="changeFeedbackPreview(1)">下一张</Button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Modal> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
@ -191,7 +242,9 @@ |
|
|
|
getOrderList, |
|
|
|
getReturnOrderList, |
|
|
|
returnOrNoOrder, |
|
|
|
getGroupOrdersByOrderId |
|
|
|
getGroupOrdersByOrderId, |
|
|
|
getProblemFeedbackList, |
|
|
|
replyProblemFeedback |
|
|
|
} from "@/api/index"; |
|
|
|
import addEdit from "./addEdit.vue"; |
|
|
|
import logisticsAddress from "@/views/sys/order-manage/logisticsAddress"; |
|
|
|
@ -220,6 +273,14 @@ |
|
|
|
refundGoodsList: [], |
|
|
|
groupOrderVisible: false, |
|
|
|
groupOrderList: [], |
|
|
|
feedbackTodoCount: 0, |
|
|
|
feedbackDetailVisible: false, |
|
|
|
feedbackDetail: {}, |
|
|
|
feedbackReplyContent: "", |
|
|
|
feedbackSubmitLoading: false, |
|
|
|
feedbackPreviewVisible: false, |
|
|
|
feedbackPreviewList: [], |
|
|
|
feedbackPreviewIndex: 0, |
|
|
|
drop: false, |
|
|
|
dropDownContent: "展开", |
|
|
|
dropDownIcon: "ios-arrow-down", |
|
|
|
@ -246,6 +307,11 @@ |
|
|
|
label: "待退款/售后", |
|
|
|
name: "refund", |
|
|
|
badge: true |
|
|
|
}, |
|
|
|
{ |
|
|
|
label: "投诉吐槽", |
|
|
|
name: "feedback", |
|
|
|
badge: true |
|
|
|
} |
|
|
|
], |
|
|
|
statusTabs: [{ |
|
|
|
@ -387,6 +453,17 @@ |
|
|
|
pageSize: 100, |
|
|
|
statusList: [0, 3], |
|
|
|
}, |
|
|
|
feedbackForm: { |
|
|
|
regionId: JSON.parse(this.getStore("user")).departmentId, |
|
|
|
pageNum: 1, |
|
|
|
pageSize: 10 |
|
|
|
}, |
|
|
|
feedbackCountForm: { |
|
|
|
regionId: JSON.parse(this.getStore("user")).departmentId, |
|
|
|
pageNum: 1, |
|
|
|
pageSize: 1, |
|
|
|
status: 0 |
|
|
|
}, |
|
|
|
searchForm: { |
|
|
|
pageNum: 1, |
|
|
|
pageSize: 10, |
|
|
|
@ -690,6 +767,94 @@ |
|
|
|
}, |
|
|
|
}, |
|
|
|
], |
|
|
|
feedbackColumns: [{ |
|
|
|
type: "index", |
|
|
|
width: 60, |
|
|
|
align: "center", |
|
|
|
fixed: "left", |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "反馈类型", |
|
|
|
key: "feedbackType", |
|
|
|
width: 110, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("span", params.row.feedbackType || "投诉吐槽"); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "反馈用户", |
|
|
|
key: "userName", |
|
|
|
width: 150, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("span", params.row.userName || params.row.userId || ""); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "联系电话", |
|
|
|
key: "contactPhone", |
|
|
|
width: 130, |
|
|
|
align: "center", |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "反馈内容", |
|
|
|
key: "problemContent", |
|
|
|
minWidth: 260, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("Tooltip", { |
|
|
|
props: { |
|
|
|
content: params.row.problemContent || "无", |
|
|
|
transfer: true, |
|
|
|
} |
|
|
|
}, [h("span", params.row.problemContent || "无")]); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "状态", |
|
|
|
key: "status", |
|
|
|
width: 100, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("span", params.row.status == 1 ? "已回复" : "待回复"); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "提交时间", |
|
|
|
key: "createTime", |
|
|
|
width: 180, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("span", this.formatDateTime(params.row.createTime)); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "处理意见", |
|
|
|
key: "handleOpinion", |
|
|
|
minWidth: 200, |
|
|
|
align: "center", |
|
|
|
render: (h, params) => { |
|
|
|
return h("span", params.row.handleOpinion || "未回复"); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "操作", |
|
|
|
key: "action", |
|
|
|
width: 130, |
|
|
|
align: "center", |
|
|
|
fixed: "right", |
|
|
|
render: (h, params) => { |
|
|
|
return h("a", { |
|
|
|
on: { |
|
|
|
click: () => { |
|
|
|
this.showFeedbackDetail(params.row); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, params.row.status == 1 ? "查看详情" : "查看/回复"); |
|
|
|
}, |
|
|
|
}, |
|
|
|
], |
|
|
|
data: [], |
|
|
|
total: 0, |
|
|
|
}; |
|
|
|
@ -706,16 +871,25 @@ |
|
|
|
return this.statusTabs; |
|
|
|
}, |
|
|
|
currentColumns() { |
|
|
|
return this.isRefundTab ? this.refundColumns : this.columns; |
|
|
|
if (this.isRefundTab) return this.refundColumns; |
|
|
|
if (this.isFeedbackTab) return this.feedbackColumns; |
|
|
|
return this.columns; |
|
|
|
}, |
|
|
|
isRefundTab() { |
|
|
|
return this.tabName == "refund"; |
|
|
|
}, |
|
|
|
isFeedbackTab() { |
|
|
|
return this.tabName == "feedback"; |
|
|
|
}, |
|
|
|
currentPageNum() { |
|
|
|
return this.isRefundTab ? this.returnForm.pageNum : this.searchForm.pageNum; |
|
|
|
if (this.isRefundTab) return this.returnForm.pageNum; |
|
|
|
if (this.isFeedbackTab) return this.feedbackForm.pageNum; |
|
|
|
return this.searchForm.pageNum; |
|
|
|
}, |
|
|
|
currentPageSize() { |
|
|
|
return this.isRefundTab ? this.returnForm.pageSize : this.searchForm.pageSize; |
|
|
|
if (this.isRefundTab) return this.returnForm.pageSize; |
|
|
|
if (this.isFeedbackTab) return this.feedbackForm.pageSize; |
|
|
|
return this.searchForm.pageSize; |
|
|
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
@ -724,6 +898,7 @@ |
|
|
|
methods: { |
|
|
|
init() { |
|
|
|
this.getRefundTodoCount(); |
|
|
|
this.getFeedbackTodoCount(); |
|
|
|
this.getLogisticsInfo() |
|
|
|
}, |
|
|
|
closePage(){ |
|
|
|
@ -745,6 +920,9 @@ |
|
|
|
if (item.name == "refund") { |
|
|
|
return this.renderRefundTabLabel; |
|
|
|
} |
|
|
|
if (item.name == "feedback") { |
|
|
|
return this.renderFeedbackTabLabel; |
|
|
|
} |
|
|
|
return item.label; |
|
|
|
}, |
|
|
|
renderRefundTabLabel(h) { |
|
|
|
@ -759,6 +937,18 @@ |
|
|
|
}, "待退款/售后") |
|
|
|
]); |
|
|
|
}, |
|
|
|
renderFeedbackTabLabel(h) { |
|
|
|
return h("Badge", { |
|
|
|
props: { |
|
|
|
count: this.feedbackTodoCount, |
|
|
|
overflowCount: 99 |
|
|
|
} |
|
|
|
}, [ |
|
|
|
h("span", { |
|
|
|
class: "order-tab-label" |
|
|
|
}, "投诉吐槽") |
|
|
|
]); |
|
|
|
}, |
|
|
|
getOrderStatusText(item) { |
|
|
|
if (!item) return ""; |
|
|
|
if (item.status == 0) return "待支付"; |
|
|
|
@ -794,10 +984,15 @@ |
|
|
|
changeOrderTab(v){ |
|
|
|
this.searchForm.pageNum = 1; |
|
|
|
this.returnForm.pageNum = 1; |
|
|
|
this.feedbackForm.pageNum = 1; |
|
|
|
if (v == "refund") { |
|
|
|
this.getReturnOrder(); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (v == "feedback") { |
|
|
|
this.getProblemFeedback(); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.searchForm.searchType = v |
|
|
|
if (!this.currentStatusTabs.some((item) => item.name == this.tabName1)) { |
|
|
|
this.tabName1 = this.currentStatusTabs[0].name; |
|
|
|
@ -811,6 +1006,8 @@ |
|
|
|
changePage(v) { |
|
|
|
if (this.isRefundTab) { |
|
|
|
this.returnForm.pageNum = v; |
|
|
|
} else if (this.isFeedbackTab) { |
|
|
|
this.feedbackForm.pageNum = v; |
|
|
|
} else { |
|
|
|
this.searchForm.pageNum = v; |
|
|
|
} |
|
|
|
@ -820,6 +1017,8 @@ |
|
|
|
changePageSize(v) { |
|
|
|
if (this.isRefundTab) { |
|
|
|
this.returnForm.pageSize = v; |
|
|
|
} else if (this.isFeedbackTab) { |
|
|
|
this.feedbackForm.pageSize = v; |
|
|
|
} else { |
|
|
|
this.searchForm.pageSize = v; |
|
|
|
} |
|
|
|
@ -849,12 +1048,35 @@ |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
getFeedbackTodoCount() { |
|
|
|
getProblemFeedbackList(this.feedbackCountForm).then((res) => { |
|
|
|
if (res.success && res.result) { |
|
|
|
this.feedbackTodoCount = res.result.total || (res.result.records || []).length; |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
getProblemFeedback() { |
|
|
|
this.loading = true; |
|
|
|
getProblemFeedbackList(this.feedbackForm).then((res) => { |
|
|
|
this.loading = false; |
|
|
|
if (res.success) { |
|
|
|
this.data = (res.result && res.result.records) || []; |
|
|
|
this.total = (res.result && res.result.total) || 0; |
|
|
|
} |
|
|
|
}).catch(() => { |
|
|
|
this.loading = false; |
|
|
|
}); |
|
|
|
}, |
|
|
|
//查询订单 |
|
|
|
getLogisticsInfo() { |
|
|
|
if (this.isRefundTab) { |
|
|
|
this.getReturnOrder(); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (this.isFeedbackTab) { |
|
|
|
this.getProblemFeedback(); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.loading = true; |
|
|
|
getOrderList(this.searchForm).then((res) => { |
|
|
|
this.loading = false; |
|
|
|
@ -871,6 +1093,9 @@ |
|
|
|
if (this.isRefundTab) { |
|
|
|
this.returnForm.pageNum = 1; |
|
|
|
this.returnForm.pageSize = 10; |
|
|
|
} else if (this.isFeedbackTab) { |
|
|
|
this.feedbackForm.pageNum = 1; |
|
|
|
this.feedbackForm.pageSize = 10; |
|
|
|
} else { |
|
|
|
this.searchForm.pageNum = 1; |
|
|
|
this.searchForm.pageSize = 10; |
|
|
|
@ -883,6 +1108,8 @@ |
|
|
|
this.searchForm.pageSize = 10; |
|
|
|
this.returnForm.pageNum = 1; |
|
|
|
this.returnForm.pageSize = 10; |
|
|
|
this.feedbackForm.pageNum = 1; |
|
|
|
this.feedbackForm.pageSize = 10; |
|
|
|
// 重新加载数据 |
|
|
|
this.getLogisticsInfo(); |
|
|
|
}, |
|
|
|
@ -945,6 +1172,52 @@ |
|
|
|
if (list.length == 0) return; |
|
|
|
window.open(list[0], "_blank"); |
|
|
|
}, |
|
|
|
previewFeedbackImage(pictures, index = 0) { |
|
|
|
const list = this.getPictureList(pictures); |
|
|
|
if (list.length == 0) return; |
|
|
|
this.feedbackPreviewList = list; |
|
|
|
this.feedbackPreviewIndex = index >= 0 && index < list.length ? index : 0; |
|
|
|
this.feedbackPreviewVisible = true; |
|
|
|
}, |
|
|
|
changeFeedbackPreview(step) { |
|
|
|
if (this.feedbackPreviewList.length == 0) return; |
|
|
|
const length = this.feedbackPreviewList.length; |
|
|
|
this.feedbackPreviewIndex = (this.feedbackPreviewIndex + step + length) % length; |
|
|
|
}, |
|
|
|
showFeedbackDetail(row) { |
|
|
|
this.feedbackDetail = Object.assign({}, row); |
|
|
|
this.feedbackReplyContent = row.handleOpinion || ""; |
|
|
|
this.feedbackDetailVisible = true; |
|
|
|
}, |
|
|
|
submitFeedbackReply() { |
|
|
|
const opinion = (this.feedbackReplyContent || "").trim(); |
|
|
|
if (opinion == "") { |
|
|
|
this.$Message.warning("请输入处理意见"); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.feedbackSubmitLoading = true; |
|
|
|
replyProblemFeedback({ |
|
|
|
id: this.feedbackDetail.id, |
|
|
|
handleOpinion: opinion |
|
|
|
}).then((res) => { |
|
|
|
this.feedbackSubmitLoading = false; |
|
|
|
if (res.success) { |
|
|
|
this.$Message.success(res.message || "回复成功"); |
|
|
|
this.feedbackDetailVisible = false; |
|
|
|
this.refreshWholePage(); |
|
|
|
} else { |
|
|
|
this.$Message.error(res.message || "回复失败"); |
|
|
|
} |
|
|
|
}).catch((err) => { |
|
|
|
this.feedbackSubmitLoading = false; |
|
|
|
this.$Message.error((err && err.message) || "回复失败"); |
|
|
|
}); |
|
|
|
}, |
|
|
|
refreshWholePage() { |
|
|
|
this.getRefundTodoCount(); |
|
|
|
this.getFeedbackTodoCount(); |
|
|
|
this.getLogisticsInfo(); |
|
|
|
}, |
|
|
|
showRefundGoods(row) { |
|
|
|
this.refundGoodsList = row.items || []; |
|
|
|
this.refundGoodsVisible = true; |
|
|
|
@ -1021,8 +1294,7 @@ |
|
|
|
this.submitRefundId = ""; |
|
|
|
if (res.success) { |
|
|
|
this.$Message.success(res.message || "处理成功"); |
|
|
|
this.getReturnOrder(); |
|
|
|
this.getRefundTodoCount(); |
|
|
|
this.refreshWholePage(); |
|
|
|
} else { |
|
|
|
this.$Message.error(res.message || "处理失败"); |
|
|
|
} |
|
|
|
|