wangfukang 3 weeks ago
parent
commit
6d088ee52f
  1. 10
      src/api/index.js
  2. 288
      src/views/sys/order-manage/orderManage.vue

10
src/api/index.js

@ -804,6 +804,16 @@ export const returnOrNoOrder = (params) => {
return postBodyRequest('/mall/refund/allowOrReject', params) return postBodyRequest('/mall/refund/allowOrReject', params)
} }
// 投诉吐槽分页
export const getProblemFeedbackList = (params) => {
return postBodyRequest('/app/problemFeedback/getProblemFeedbackList', params)
}
// 投诉吐槽回复
export const replyProblemFeedback = (params) => {
return postBodyRequest('/app/problemFeedback/replyProblemFeedback', params)
}
//查询物流自取 //查询物流自取
export const getSaleByCompanyId = (params) => { export const getSaleByCompanyId = (params) => {

288
src/views/sys/order-manage/orderManage.vue

@ -63,6 +63,24 @@
padding-top: 8px; padding-top: 8px;
text-align: right; 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> </style>
<template> <template>
<div class="search"> <div class="search">
@ -70,7 +88,7 @@
<Tabs v-model="tabName" :animated="false" @on-click="changeOrderTab"> <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> <TabPane v-for="item in orderTypeTabs" :key="item.name" :label="getOrderTypeTabLabel(item)" :name="item.name"></TabPane>
</Tabs> </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> <TabPane v-for="item in currentStatusTabs" :key="item.name" :label="item.label" :name="item.name"></TabPane>
</Tabs> </Tabs>
<Row v-show="openSearch" @keydown.enter.native="handleSearch"> <Row v-show="openSearch" @keydown.enter.native="handleSearch">
@ -93,7 +111,7 @@
<Row align="middle" justify="space-between" class="operation"> <Row align="middle" justify="space-between" class="operation">
<div class="icons"> <div class="icons">
<Tooltip content="刷新" placement="top" transfer> <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>
<Tooltip :content="openSearch ? '关闭搜索' : '开启搜索'" placement="top" transfer> <Tooltip :content="openSearch ? '关闭搜索' : '开启搜索'" placement="top" transfer>
<Icon type="ios-search" size="18" class="item tip" @click="openSearch = !openSearch" /> <Icon type="ios-search" size="18" class="item tip" @click="openSearch = !openSearch" />
@ -183,6 +201,39 @@
<Button type="primary" @click="groupOrderVisible = false">关闭</Button> <Button type="primary" @click="groupOrderVisible = false">关闭</Button>
</div> </div>
</Modal> </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> </div>
</template> </template>
@ -191,7 +242,9 @@
getOrderList, getOrderList,
getReturnOrderList, getReturnOrderList,
returnOrNoOrder, returnOrNoOrder,
getGroupOrdersByOrderId getGroupOrdersByOrderId,
getProblemFeedbackList,
replyProblemFeedback
} from "@/api/index"; } from "@/api/index";
import addEdit from "./addEdit.vue"; import addEdit from "./addEdit.vue";
import logisticsAddress from "@/views/sys/order-manage/logisticsAddress"; import logisticsAddress from "@/views/sys/order-manage/logisticsAddress";
@ -220,6 +273,14 @@
refundGoodsList: [], refundGoodsList: [],
groupOrderVisible: false, groupOrderVisible: false,
groupOrderList: [], groupOrderList: [],
feedbackTodoCount: 0,
feedbackDetailVisible: false,
feedbackDetail: {},
feedbackReplyContent: "",
feedbackSubmitLoading: false,
feedbackPreviewVisible: false,
feedbackPreviewList: [],
feedbackPreviewIndex: 0,
drop: false, drop: false,
dropDownContent: "展开", dropDownContent: "展开",
dropDownIcon: "ios-arrow-down", dropDownIcon: "ios-arrow-down",
@ -246,6 +307,11 @@
label: "待退款/售后", label: "待退款/售后",
name: "refund", name: "refund",
badge: true badge: true
},
{
label: "投诉吐槽",
name: "feedback",
badge: true
} }
], ],
statusTabs: [{ statusTabs: [{
@ -387,6 +453,17 @@
pageSize: 100, pageSize: 100,
statusList: [0, 3], 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: { searchForm: {
pageNum: 1, pageNum: 1,
pageSize: 10, 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: [], data: [],
total: 0, total: 0,
}; };
@ -706,16 +871,25 @@
return this.statusTabs; return this.statusTabs;
}, },
currentColumns() { currentColumns() {
return this.isRefundTab ? this.refundColumns : this.columns; if (this.isRefundTab) return this.refundColumns;
if (this.isFeedbackTab) return this.feedbackColumns;
return this.columns;
}, },
isRefundTab() { isRefundTab() {
return this.tabName == "refund"; return this.tabName == "refund";
}, },
isFeedbackTab() {
return this.tabName == "feedback";
},
currentPageNum() { 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() { 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() { mounted() {
@ -724,6 +898,7 @@
methods: { methods: {
init() { init() {
this.getRefundTodoCount(); this.getRefundTodoCount();
this.getFeedbackTodoCount();
this.getLogisticsInfo() this.getLogisticsInfo()
}, },
closePage(){ closePage(){
@ -745,6 +920,9 @@
if (item.name == "refund") { if (item.name == "refund") {
return this.renderRefundTabLabel; return this.renderRefundTabLabel;
} }
if (item.name == "feedback") {
return this.renderFeedbackTabLabel;
}
return item.label; return item.label;
}, },
renderRefundTabLabel(h) { 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) { getOrderStatusText(item) {
if (!item) return ""; if (!item) return "";
if (item.status == 0) return "待支付"; if (item.status == 0) return "待支付";
@ -794,10 +984,15 @@
changeOrderTab(v){ changeOrderTab(v){
this.searchForm.pageNum = 1; this.searchForm.pageNum = 1;
this.returnForm.pageNum = 1; this.returnForm.pageNum = 1;
this.feedbackForm.pageNum = 1;
if (v == "refund") { if (v == "refund") {
this.getReturnOrder(); this.getReturnOrder();
return; return;
} }
if (v == "feedback") {
this.getProblemFeedback();
return;
}
this.searchForm.searchType = v this.searchForm.searchType = v
if (!this.currentStatusTabs.some((item) => item.name == this.tabName1)) { if (!this.currentStatusTabs.some((item) => item.name == this.tabName1)) {
this.tabName1 = this.currentStatusTabs[0].name; this.tabName1 = this.currentStatusTabs[0].name;
@ -811,6 +1006,8 @@
changePage(v) { changePage(v) {
if (this.isRefundTab) { if (this.isRefundTab) {
this.returnForm.pageNum = v; this.returnForm.pageNum = v;
} else if (this.isFeedbackTab) {
this.feedbackForm.pageNum = v;
} else { } else {
this.searchForm.pageNum = v; this.searchForm.pageNum = v;
} }
@ -820,6 +1017,8 @@
changePageSize(v) { changePageSize(v) {
if (this.isRefundTab) { if (this.isRefundTab) {
this.returnForm.pageSize = v; this.returnForm.pageSize = v;
} else if (this.isFeedbackTab) {
this.feedbackForm.pageSize = v;
} else { } else {
this.searchForm.pageSize = v; 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() { getLogisticsInfo() {
if (this.isRefundTab) { if (this.isRefundTab) {
this.getReturnOrder(); this.getReturnOrder();
return; return;
} }
if (this.isFeedbackTab) {
this.getProblemFeedback();
return;
}
this.loading = true; this.loading = true;
getOrderList(this.searchForm).then((res) => { getOrderList(this.searchForm).then((res) => {
this.loading = false; this.loading = false;
@ -871,6 +1093,9 @@
if (this.isRefundTab) { if (this.isRefundTab) {
this.returnForm.pageNum = 1; this.returnForm.pageNum = 1;
this.returnForm.pageSize = 10; this.returnForm.pageSize = 10;
} else if (this.isFeedbackTab) {
this.feedbackForm.pageNum = 1;
this.feedbackForm.pageSize = 10;
} else { } else {
this.searchForm.pageNum = 1; this.searchForm.pageNum = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 10;
@ -883,6 +1108,8 @@
this.searchForm.pageSize = 10; this.searchForm.pageSize = 10;
this.returnForm.pageNum = 1; this.returnForm.pageNum = 1;
this.returnForm.pageSize = 10; this.returnForm.pageSize = 10;
this.feedbackForm.pageNum = 1;
this.feedbackForm.pageSize = 10;
// //
this.getLogisticsInfo(); this.getLogisticsInfo();
}, },
@ -945,6 +1172,52 @@
if (list.length == 0) return; if (list.length == 0) return;
window.open(list[0], "_blank"); 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) { showRefundGoods(row) {
this.refundGoodsList = row.items || []; this.refundGoodsList = row.items || [];
this.refundGoodsVisible = true; this.refundGoodsVisible = true;
@ -1021,8 +1294,7 @@
this.submitRefundId = ""; this.submitRefundId = "";
if (res.success) { if (res.success) {
this.$Message.success(res.message || "处理成功"); this.$Message.success(res.message || "处理成功");
this.getReturnOrder(); this.refreshWholePage();
this.getRefundTodoCount();
} else { } else {
this.$Message.error(res.message || "处理失败"); this.$Message.error(res.message || "处理失败");
} }

Loading…
Cancel
Save