调整客户消息展示

This commit is contained in:
huangdeliang
2021-06-08 18:26:00 +08:00
parent c57defc800
commit 02e5110d2c
13 changed files with 332 additions and 79 deletions

View File

@ -1,5 +1,13 @@
import request from "@/utils/request";
export function fetchCustomerList(query) {
return request({
url: "/services/topic/customers",
method: "get",
params: query
});
}
export function fetchTopicList(query) {
return request({
url: "/services/topic/list",

View File

@ -1,4 +1,7 @@
import { getCustomerPhysicalSignsByCusId } from "@/api/custom/customer";
import {
getCustomerPhysicalSignsByCusId,
getCustomer
} from "@/api/custom/customer";
import { dealHealthy } from "@/utils/healthyData";
import {
listRecipesPlanByCusId,
@ -6,6 +9,7 @@ import {
} from "@/api/custom/recipesPlan";
import {
fetchCustomerList,
fetchTopicList,
postTopicReply,
fetchTopicDetail,
@ -14,14 +18,24 @@ import {
const oriState = {
pageNum: 1,
cusLoading: false,
customerList: [],
selCusId: "",
//
topicList: [],
detailData: {},
topicLoading: false,
selTopicId: "",
//
detailData: {},
detailLoading: false,
//
healthyData: {},
healthDataLoading: false,
healthyDataType: 0,
avoidFoodIds: [],
//
customerData: {},
//
planList: [],
planListLoading: false
};
@ -44,42 +58,71 @@ const mutations = {
const actions = {
async init({ dispatch }, payload) {
dispatch("fetchTopicListApi", {});
dispatch("fetchCustomerListActions", {});
},
async fetchTopicListApi({ dispatch, commit, rootGetters, state }, payload) {
const {
roles: [role],
userId
} = rootGetters;
const { detailData, pageNum, topicList } = state;
const result = await fetchTopicList({
async fetchCustomerListActions(
{ dispatch, commit, rootGetters, state },
payload
) {
// prettier-ignore
const { roles: [role], userId } = rootGetters;
const { customerList, pageNum } = state;
commit("save", { cusLoading: true });
const result = await fetchCustomerList({
role,
uid: userId,
pageSize: 20,
pageNum
});
if (result.code === 200) {
if (!detailData.topicId) {
// 默认展示第一个
const [defTopic] = result.rows;
dispatch("fetchTopicDetailActions", {
topicId: defTopic.topicId,
id: defTopic.id,
uid: defTopic.uid
});
}
if (result.rows.length) {
commit("save", {
pageNum: pageNum + 1,
topicList: [...topicList, ...result.rows]
});
let mPageNum = pageNum,
mCustomerList = customerList;
if (result.code === 200 && result.rows.length) {
//
if (!customerList.length) {
const [defCustomer] = result.rows;
dispatch("fetchTopicListApi", { fromUid: defCustomer.uid });
}
//
mPageNum += 1;
mCustomerList = [...customerList, ...result.rows];
}
commit("save", {
pageNum: mPageNum,
cusLoading: false,
customerList: mCustomerList
});
},
async fetchTopicListApi({ dispatch, commit, rootGetters, state }, payload) {
// prettier-ignore
const { roles: [role], userId } = rootGetters;
const { fromUid } = payload;
commit("save", { selCusId: fromUid, topicLoading: true });
const result = await fetchTopicList({
role,
uid: userId,
fromUid
});
let mTopicList = [];
if (result.code === 200 && result.rows.length) {
// 默认展示第一个
const [defTopic] = result.rows;
dispatch("fetchTopicDetailActions", {
topicId: defTopic.topicId,
id: defTopic.id,
uid: defTopic.uid
});
mTopicList = result.rows;
}
commit("save", {
topicList: mTopicList,
topicLoading: false
});
},
async fetchTopicDetailActions({ commit, dispatch, state }, payload) {
const { topicId, id, uid } = payload;
const { healthyData, planList } = state;
commit("save", { selTopicId: topicId });
const { topicId, id = 0, uid } = payload;
const { healthyData, planList, customerData } = state;
commit("save", { selTopicId: topicId, detailLoading: true });
// 客户信息
if (healthyData.customerId !== parseInt(uid)) {
dispatch("getHealthyData", { cusId: uid, callback: payload.callback });
@ -88,11 +131,20 @@ const actions = {
if (!planList.length || planList[0].cusId !== parseInt(uid)) {
dispatch("getRecipesPlanActions", { cusId: uid });
}
// 客户档案
if (customerData.id !== parseInt(uid)) {
dispatch("getCustomerFileActions", { cusId: uid });
}
//
const result = await fetchTopicDetail({ topicId, id });
if (result.code === 200) {
commit("save", { detailData: result.data[0] });
commit("save", { detailData: result.data[0], detailLoading: false });
}
},
async getCustomerFileActions({ commit }, payload) {
const result = await getCustomer(payload.cusId);
if (result.code === 200) {
commit("save", { customerData: result.data });
}
},
async postTopicReplyActions(

View File

@ -1,8 +1,8 @@
<template>
<div class="topic_comment_item" @click="handOnClick(data)">
<div class="comment_avatar">
<el-avatar size="medium" :src="data.fromAvatar || ''">{{
data.fromName.substr(-1)
<el-avatar size="medium" :src="data.fromAvatar">{{
data.fromName && data.fromName.substr(-1)
}}</el-avatar>
</div>
<div class="comment_content">

View File

@ -1,6 +1,25 @@
<template>
<div class="message_browser_wrapper">
<div class="topic_list" @scroll="handleOnScroll">
<div class="customers_list" @scroll="handleOnScroll" v-loading="cusLoading">
<div v-if="customerList && customerList.length">
<div
v-for="customer in customerList"
:key="customer.uid"
:class="`customer_item ${
customer.uid === selCusId ? 'customer_item_sel' : ''
}`"
@click="handleOnCustomerClick(customer)"
>
<el-avatar size="medium" :src="customer.avatar">
{{ customer.name && customer.name.substr(-1) }}
</el-avatar>
<span class="customer_name">
{{ customer.name }}
</span>
</div>
</div>
</div>
<div class="topic_list" v-loading="topicLoading">
<div v-if="topicList && topicList.length">
<div
v-for="topic in topicList"
@ -29,7 +48,7 @@
</div>
<div v-else class="topic_list_empty">暂无消息</div>
</div>
<div class="topic_detail">
<div class="topic_detail" v-loading="detailLoading">
<div class="topic_detail_list">
<div
class="topic_detail_title"
@ -125,7 +144,16 @@ export default {
window.removeEventListener("message", this.handleOnMessage);
},
computed: {
...mapState(["topicList", "selTopicId", "detailData"]),
...mapState([
"cusLoading",
"topicLoading",
"detailLoading",
"topicList",
"selCusId",
"selTopicId",
"detailData",
"customerList",
]),
},
methods: {
handleOnScroll({ target }) {
@ -133,7 +161,7 @@ export default {
target.clientHeight + parseInt(target.scrollTop) ===
target.scrollHeight
) {
this.fetchTopicListApi();
this.fetchCustomerListActions();
}
},
handleOnMessage({ data }) {
@ -181,6 +209,14 @@ export default {
formatDate(date) {
return dayjs(date).format("MM-DD HH:mm");
},
handleOnCustomerClick(data) {
if (this.selCusId !== data.uid) {
this.replyTarget = "";
this.replyContent = "";
this.replyObj = {};
this.fetchTopicListApi({ fromUid: data.uid });
}
},
handleOnTopicClick(data) {
if (data.topicId !== this.selTopicId) {
this.replyTarget = "";
@ -242,6 +278,7 @@ export default {
"fetchTopicDetailActions",
"postTopicReplyActions",
"fetchTopicListApi",
"fetchCustomerListActions",
]),
...mapMutations(["clean", "save"]),
...globalMapActions(["updateUnreadCount"]),
@ -251,13 +288,40 @@ export default {
<style lang="scss" scoped>
.message_browser_wrapper {
display: flex;
.customers_list {
flex: 1;
overflow: auto;
border-right: 1px solid #f0f0f0;
.customer_item {
padding: 8px 12px;
cursor: pointer;
display: flex;
align-items: center;
&:hover {
background: #dedede;
}
.customer_name {
margin-left: 8px;
}
}
.customer_item_sel {
background: #f0f0f0;
}
}
.topic_list {
flex: 2;
overflow: auto;
border-right: 1px solid #f0f0f0;
.topic_item {
display: flex;
padding: 8px 16px;
padding: 8px 12px;
cursor: pointer;
&:hover {
@ -318,7 +382,7 @@ export default {
}
.topic_item_sel {
background: #dedede;
background: #f0f0f0;
}
.topic_list_empty {

View File

@ -1,5 +1,5 @@
<template>
<el-tabs v-model="activeName">
<el-tabs v-model="activeName" class="message_userinfo_wrapper">
<el-tab-pane label="客户信息" name="health">
<div
v-loading="healthDataLoading"
@ -15,6 +15,22 @@
:data="healthyDataType === 1 ? healthyData : {}"
v-show="healthyDataType === 1"
/>
<div v-if="customerData.id" class="customer_service_info">
<div class="info_item">
<span>主任营养师</span>
<span>
{{ customerData.dietitianName || "无" }}
</span>
</div>
<div class="info_item">
<span>营养师助理</span>
<span>{{ customerData.assDietitianName || "无" }}</span>
</div>
<div class="info_item">
<span>售后营养师</span>
<span>{{ customerData.afterDietitianName || "无" }}</span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="食谱计划" name="plan">
@ -53,9 +69,30 @@ export default {
},
},
computed: {
...mapState(["healthyData", "healthyDataType", "healthDataLoading"]),
...mapState([
"healthyData",
"healthyDataType",
"healthDataLoading",
"customerData",
]),
},
};
</script>
<style lang="scss" scoped>
.message_userinfo_wrapper {
.customer_service_info {
position: absolute;
right: 30%;
top: 68px;
.info_item {
margin-bottom: 10px;
font-size: 14px;
& > span:nth-child(1) {
color: #8c8c8c;
}
}
}
}
</style>