| @@ -20,10 +20,16 @@ public class SysServiceTopicController extends BaseController { | ||||
|  | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo list(SysServicesTopic topic) { | ||||
|         startPage(); | ||||
|         return getDataTable(servicesTopicService.selectSysServicesTopicByUserIdAndRole(topic)); | ||||
|         return getDataTable(servicesTopicService.selectTopicListByUid(topic)); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/customers") | ||||
|     public TableDataInfo customers(SysServicesTopic topic) { | ||||
|         startPage(); | ||||
|         return getDataTable(servicesTopicService.selectCustomerListByUserIdAndRole(topic)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| //    @PutMapping("/update/status") | ||||
| //    public AjaxResult status(@RequestBody SysServicesQuestion sysServicesQuestion) { | ||||
| //        return toAjax(sysServicesQuestionService.updateSysServicesQuestionStatus(sysServicesQuestion)); | ||||
|   | ||||
| @@ -71,18 +71,26 @@ public class SysCustomer extends BaseEntity | ||||
|  | ||||
|     /** 主营养师 */ | ||||
|     @Excel(name = "主营养师") | ||||
|     private String dietitianName; | ||||
|  | ||||
|     private Long mainDietitian; | ||||
|  | ||||
|     /** 营养师助理 */ | ||||
|     @Excel(name = "营养师助理") | ||||
|     private String assDietitianName; | ||||
|  | ||||
|     private Long assistantDietitian; | ||||
|  | ||||
|     /** 售后营养师 */ | ||||
|     @Excel(name = "售后营养师") | ||||
|     private String afterDietitianName; | ||||
|  | ||||
|     private Long afterDietitian; | ||||
|  | ||||
|     /** 销售人员 */ | ||||
|     @Excel(name = "销售人员") | ||||
|     private String salesName; | ||||
|  | ||||
|     private Long salesman; | ||||
|  | ||||
|     /** 负责人 */ | ||||
|   | ||||
| @@ -7,6 +7,8 @@ import java.util.List; | ||||
| public interface SysServicesTopicMapper { | ||||
|     List<SysServicesTopic> selectSysServicesTopicByUserIdAndRole(SysServicesTopic topic); | ||||
|  | ||||
|     List<SysServicesTopic> selectCustomerListByUserIdAndRole(SysServicesTopic topic); | ||||
|  | ||||
|     int insertSysServicesTopic(SysServicesTopic topic); | ||||
|  | ||||
|     int insertSysServicesTopicStatus(List<SysServicesTopic> topics); | ||||
| @@ -20,4 +22,6 @@ public interface SysServicesTopicMapper { | ||||
|     List<SysServicesTopic> selectSysServicesTopicSessionByTopicId(String topicId); | ||||
|  | ||||
|     List<SysServicesTopic> selectUnreadTopicCount(List<SysServicesTopic> topics); | ||||
|  | ||||
|     List<SysServicesTopic> selectTopicListByUid(SysServicesTopic topic); | ||||
| } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ public class WebSocketServer { | ||||
|     //private static ConcurrentHashMap<String,WebSocketServer> websocketList = new ConcurrentHashMap<>(); | ||||
|     // 与某个客户端的连接会话,需要通过它来给客户端发送数据 | ||||
|     private Session session; | ||||
|     // 接收sid | ||||
|     // 接收sidw | ||||
|     private String sid = ""; | ||||
|  | ||||
|     public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() { | ||||
|   | ||||
| @@ -8,6 +8,8 @@ public interface ISysServicesTopicService { | ||||
|  | ||||
|     List<SysServicesTopic> selectSysServicesTopicByUserIdAndRole(SysServicesTopic topic); | ||||
|  | ||||
|     List<SysServicesTopic> selectCustomerListByUserIdAndRole(SysServicesTopic topic); | ||||
|  | ||||
|     SysServicesTopic insertSysServicesTopic(SysServicesTopic topic); | ||||
|  | ||||
|     int updateSysServicesTopicStatus(SysServicesTopic topic); | ||||
| @@ -19,4 +21,6 @@ public interface ISysServicesTopicService { | ||||
|     List<SysServicesTopic> selectSysServicesTopicSessionByTopicId(String topicId); | ||||
|  | ||||
|     List<SysServicesTopic> selectUnreadTopicCount(List<SysServicesTopic> topic); | ||||
|  | ||||
|     List<SysServicesTopic> selectTopicListByUid(SysServicesTopic topic); | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,10 @@ public class SysServicesTopicServiceImp implements ISysServicesTopicService { | ||||
|         return servicesTopicMapper.selectSysServicesTopicByUserIdAndRole(topic); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SysServicesTopic> selectCustomerListByUserIdAndRole(SysServicesTopic topic) { | ||||
|         return servicesTopicMapper.selectCustomerListByUserIdAndRole(topic); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public SysServicesTopic insertSysServicesTopic(SysServicesTopic topic) { | ||||
| @@ -187,4 +191,9 @@ public class SysServicesTopicServiceImp implements ISysServicesTopicService { | ||||
|     public List<SysServicesTopic> selectUnreadTopicCount(List<SysServicesTopic> statusList) { | ||||
|         return servicesTopicMapper.selectUnreadTopicCount(statusList); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SysServicesTopic> selectTopicListByUid(SysServicesTopic topic) { | ||||
|         return servicesTopicMapper.selectTopicListByUid(topic); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,38 +5,50 @@ | ||||
| <mapper namespace="com.stdiet.custom.mapper.SysCustomerMapper"> | ||||
|  | ||||
|     <resultMap type="SysCustomer" id="SysCustomerResult"> | ||||
|         <result property="id"    column="id"    /> | ||||
|         <result property="name"    column="name"    /> | ||||
|         <result property="phone"    column="phone"    /> | ||||
|         <result property="email"    column="email"    /> | ||||
|         <result property="address"    column="address"    /> | ||||
|         <result property="payDate"    column="pay_date"    /> | ||||
|         <result property="startDate"    column="start_date"    /> | ||||
|         <result property="fansTime" column="fans_time" /> | ||||
|         <result property="fansChannel" column="fans_channel" /> | ||||
|         <result property="purchaseNum"    column="purchase_num"    /> | ||||
|         <result property="payTotal"    column="pay_total"    /> | ||||
|         <result property="mainDietitian"    column="main_dietitian"    /> | ||||
|         <result property="assistantDietitian"    column="assistant_dietitian"    /> | ||||
|         <result property="afterDietitian"    column="after_dietitian"    /> | ||||
|         <result property="salesman"    column="salesman"    /> | ||||
|         <result property="chargePerson"    column="charge_person"    /> | ||||
|         <result property="followStatus"    column="follow_status"    /> | ||||
|         <result property="createTime"    column="create_time"    /> | ||||
|         <result property="createBy"    column="create_by"    /> | ||||
|         <result property="updateTime"    column="update_time"    /> | ||||
|         <result property="updateBy"    column="update_by"    /> | ||||
|         <result property="channelId"    column="channel_id"    /> | ||||
|         <result property="id" column="id"/> | ||||
|         <result property="name" column="name"/> | ||||
|         <result property="phone" column="phone"/> | ||||
|         <result property="email" column="email"/> | ||||
|         <result property="address" column="address"/> | ||||
|         <result property="payDate" column="pay_date"/> | ||||
|         <result property="startDate" column="start_date"/> | ||||
|         <result property="fansTime" column="fans_time"/> | ||||
|         <result property="fansChannel" column="fans_channel"/> | ||||
|         <result property="purchaseNum" column="purchase_num"/> | ||||
|         <result property="payTotal" column="pay_total"/> | ||||
|         <result property="chargePerson" column="charge_person"/> | ||||
|         <result property="followStatus" column="follow_status"/> | ||||
|         <result property="createTime" column="create_time"/> | ||||
|         <result property="createBy" column="create_by"/> | ||||
|         <result property="updateTime" column="update_time"/> | ||||
|         <result property="updateBy" column="update_by"/> | ||||
|         <result property="channelId" column="channel_id"/> | ||||
|  | ||||
|         <result property="mainDietitian" column="main_dietitian"/> | ||||
|         <result property="assistantDietitian" column="assistant_dietitian"/> | ||||
|         <result property="afterDietitian" column="after_dietitian"/> | ||||
|         <result property="salesman" column="salesman"/> | ||||
|  | ||||
|         <association property="dietitianName" column="{id=main_dietitian}" select="selectUserName"/> | ||||
|         <association property="assDietitianName" column="{id=assistant_dietitian}" select="selectUserName"/> | ||||
|         <association property="afterDietitianName" column="{id=after_dietitian}" select="selectUserName"/> | ||||
|         <association property="salesName" column="{id=salesman}" select="selectUserName"/> | ||||
|     </resultMap> | ||||
|  | ||||
|     <select id="selectUserName" parameterType="java.util.Map" resultType="String"> | ||||
|         select nick_name from sys_user where user_id = #{id} | ||||
|     </select> | ||||
|  | ||||
|     <sql id="selectSysCustomerVo"> | ||||
|         select id, name, phone, email, fans_time, fans_channel, address, pay_date, start_date, purchase_num, pay_total, main_dietitian, assistant_dietitian, after_dietitian, salesman, charge_person, follow_status, create_time, create_by, update_time, update_by, channel_id from sys_customer | ||||
|     </sql> | ||||
|  | ||||
|     <select id="selectSysCustomerList" parameterType="SysCustomer" resultMap="SysCustomerResult"> | ||||
|         select | ||||
|         sc.id, sc.name, sc.phone, sc.email, sc.fans_time, sc.fans_channel, sc.address, sc.pay_date, sc.start_date, sc.purchase_num, sc.pay_total, sc.main_dietitian, | ||||
|         sc.assistant_dietitian, sc.after_dietitian, sc.salesman, sc.charge_person, sc.follow_status, sc.create_time,sc.channel_id | ||||
|         sc.id, sc.name, sc.phone, sc.email, sc.fans_time, sc.fans_channel, sc.address, sc.pay_date, sc.start_date, | ||||
|         sc.purchase_num, sc.pay_total, sc.main_dietitian, | ||||
|         sc.assistant_dietitian, sc.after_dietitian, sc.salesman, sc.charge_person, sc.follow_status, | ||||
|         sc.create_time,sc.channel_id | ||||
|         from sys_customer sc | ||||
|         left join sys_customer_healthy as sch | ||||
|         on sch.customer_id = sc.id and sch.del_flag = 0 | ||||
| @@ -44,16 +56,18 @@ | ||||
|         <if test="name != null  and name != ''"> | ||||
|             and (sc.name like concat('%', #{name}, '%') or sc.phone like concat('%', #{name}, '%')) | ||||
|         </if> | ||||
|         <if test="mainDietitian != null  and mainDietitian != ''"> and sc.main_dietitian = #{mainDietitian}</if> | ||||
|         <if test="mainDietitian == 0"> and (isnull(sc.main_dietitian) or sc.main_dietitian=0)</if> | ||||
|         <if test="salesman != null  and salesman != ''"> and sc.salesman = #{salesman}</if> | ||||
|         <if test="salesman == 0"> and (isnull(sc.salesman) or sc.salesman=0)</if> | ||||
|         <if test="afterDietitian != null  and afterDietitian != ''"> and sc.after_dietitian = #{afterDietitian}</if> | ||||
|         <if test="afterDietitian == 0"> and (isnull(sc.after_dietitian) or sc.after_dietitian=0)</if> | ||||
|         <if test="assistantDietitian != null  and assistantDietitian != ''"> and sc.assistant_dietitian = #{assistantDietitian}</if> | ||||
|         <if test="assistantDietitian == 0"> and (isnull(sc.assistant_dietitian) or sc.assistant_dietitian=0)</if> | ||||
|         <if test="fansChannel != null "> and sc.fans_channel = #{fansChannel}</if> | ||||
|         <if test="channelId != null "> and sc.channel_id = #{channelId}</if> | ||||
|         <if test="mainDietitian != null  and mainDietitian != ''">and sc.main_dietitian = #{mainDietitian}</if> | ||||
|         <if test="mainDietitian == 0">and (isnull(sc.main_dietitian) or sc.main_dietitian=0)</if> | ||||
|         <if test="salesman != null  and salesman != ''">and sc.salesman = #{salesman}</if> | ||||
|         <if test="salesman == 0">and (isnull(sc.salesman) or sc.salesman=0)</if> | ||||
|         <if test="afterDietitian != null  and afterDietitian != ''">and sc.after_dietitian = #{afterDietitian}</if> | ||||
|         <if test="afterDietitian == 0">and (isnull(sc.after_dietitian) or sc.after_dietitian=0)</if> | ||||
|         <if test="assistantDietitian != null  and assistantDietitian != ''">and sc.assistant_dietitian = | ||||
|             #{assistantDietitian} | ||||
|         </if> | ||||
|         <if test="assistantDietitian == 0">and (isnull(sc.assistant_dietitian) or sc.assistant_dietitian=0)</if> | ||||
|         <if test="fansChannel != null ">and sc.fans_channel = #{fansChannel}</if> | ||||
|         <if test="channelId != null ">and sc.channel_id = #{channelId}</if> | ||||
|         <if test="channels != null"> | ||||
|             and sc.channel_id in | ||||
|             <foreach collection="channels" item="cn" separator="," open="(" close=")"> | ||||
|   | ||||
| @@ -16,8 +16,57 @@ | ||||
|         <result column="create_time" property="createTime"/> | ||||
|         <result column="update_time" property="updateTime"/> | ||||
|         <association column="{uid=uid,role=role}" property="name" select="selectUserInfo"/> | ||||
|         <association property="avatar" column="{uid=uid,role=role}" select="selectUserAvatar"/> | ||||
|     </resultMap> | ||||
|  | ||||
|     <select id="selectCustomerListByUserIdAndRole" parameterType="SysServicesTopic" resultMap="SysServicesTopicResult"> | ||||
|         SELECT DISTINCT(uid)AS uid, MAX(update_time) AS update_time, MIN(create_time) AS create_time, MIN(`read`) AS | ||||
|         `read`, role FROM ( | ||||
|         SELECT * FROM ( | ||||
|         SELECT topic_id, `read`, create_time, update_time, 'customer' AS role FROM sys_services_topic_status | ||||
|         <choose> | ||||
|             <when test="role == 'admin' or role == 'manager' or role == 'admin-dev'"> | ||||
|                 WHERE role = 'dietician' | ||||
|             </when> | ||||
|             <otherwise> | ||||
|                 WHERE role = #{role} AND uid = #{uid} | ||||
|             </otherwise> | ||||
|         </choose> | ||||
|  | ||||
|         ) AS status | ||||
|         LEFT JOIN (SELECT topic_id, uid, del_flag FROM sys_services_topic ) AS topic USING(topic_id) | ||||
|         WHERE del_flag = 0 | ||||
|         ORDER BY `read` ASC, update_time DESC | ||||
|         ) AS userList GROUP BY uid | ||||
|     </select> | ||||
|  | ||||
|     <select id="selectTopicListByUid" parameterType="SysServicesTopic" resultMap="SysServicesTopicResult"> | ||||
|         SELECT * FROM( | ||||
|         SELECT topic_id, topic_type, content, uid, img, 'customer' AS role FROM sys_services_topic | ||||
|         WHERE uid = #{fromUid} AND del_flag = 0 | ||||
|         ) AS topic | ||||
|         LEFT JOIN (SELECT topic_id, create_time, update_time, `read`, | ||||
|         <choose> | ||||
|             <when test="role == 'admin' or role == 'manager' or role == 'admin-dev'"> | ||||
|                 '0' AS id | ||||
|             </when> | ||||
|             <otherwise> | ||||
|                 id | ||||
|             </otherwise> | ||||
|         </choose> | ||||
|         FROM sys_services_topic_status | ||||
|         <choose> | ||||
|             <when test="role == 'admin' or role == 'manager' or role == 'admin-dev'"> | ||||
|                 WHERE role = 'dietician' | ||||
|             </when> | ||||
|             <otherwise> | ||||
|                 WHERE role = #{role} AND uid = #{uid} | ||||
|             </otherwise> | ||||
|         </choose> | ||||
|         ) AS state | ||||
|         USING(topic_id) | ||||
|         ORDER BY `read` ASC, update_time DESC | ||||
|     </select> | ||||
|  | ||||
|     <!--    根据userId和角色查询问题列表--> | ||||
|     <select id="selectSysServicesTopicByUserIdAndRole" parameterType="SysServicesTopic" | ||||
| @@ -36,8 +85,6 @@ | ||||
|                 ORDER BY `read` ASC, update_time DESC | ||||
|             </otherwise> | ||||
|         </choose> | ||||
|  | ||||
|  | ||||
|     </select> | ||||
|  | ||||
|     <!--    查询主题--> | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
| @@ -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"> | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user