Explorar o código

fix:客服结束列表接口修改

duxin %!s(int64=2) %!d(string=hai) anos
pai
achega
89281c38c9
Modificáronse 2 ficheiros con 173 adicións e 107 borrados
  1. 1 0
      entity/util.go
  2. 172 107
      service/message_mail_box.go

+ 1 - 0
entity/util.go

@@ -17,6 +17,7 @@ const (
 	SOCIALIZE_TENANT_ROBOT    = "socialize_tenant_robot"
 	BASE_USER                 = "base_user"
 	SOCIALIZE_APPRAISE        = "socialize_message_appraise"
+	User_message_list         = "user_message_list"
 )
 const (
 	SUCCESS_CODE = int64(0)

+ 172 - 107
service/message_mail_box.go

@@ -3,12 +3,14 @@ package service
 import (
 	quitl "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/encrypt"
+	"app.yhyue.com/moapp/jybase/redis"
 	util "bp.jydev.jianyu360.cn/SocialPlatform/messageCenter/entity"
 	"bp.jydev.jianyu360.cn/SocialPlatform/messageCenter/rpc/messagecenter/messagecenter"
 	"database/sql"
 	"fmt"
 	"log"
 	"strings"
+	"sync"
 	"time"
 )
 
@@ -153,31 +155,27 @@ func (b MessaggeService) UserList(in *messagecenter.UserReq) (data *[]map[string
 			util.SOCIALIZE_TENANT_ROBOT,
 			customerMessageId)
 	} else {
-		phoneSql := ""
+		idSql := fmt.Sprintf(" (a.customer_service_id = %d OR a.customer_service_id = 0) ", in.EntUserId)
+		if in.IsArtificial == 1 {
+			idSql = fmt.Sprintf(" a.customer_service_id = %d ", in.EntUserId)
+		} else if in.IsArtificial == 2 {
+			idSql = " a.customer_service_id = 0 "
+		}
+		if in.StartTime != "" {
+			idSql += " AND  DATE_FORMAT(a.update_time,'%Y-%m-%d') >= '" + in.StartTime + "' "
+		}
+		if in.EndTime != "" {
+			idSql += "AND DATE_FORMAT(a.update_time,'%Y-%m-%d') <= '" + in.EndTime + "' "
+		}
 		if in.Phone != "" {
-			phoneSql = " AND  b.phone like '%" + in.Phone + "%'"
+			idSql += " AND  b.phone like '%" + in.Phone + "%'"
 		}
-		screening := phoneSql
 		if in.FiltrationId != "" {
 			var ids []string
 			for _, v := range strings.Split(in.FiltrationId, ",") {
 				ids = append(ids, encrypt.SE.Decode4Hex(v))
 			}
-			screening += fmt.Sprintf(" AND  b.id not in (%s)", strings.Join(ids, ","))
-		}
-		startTimeSql := ""
-		if in.StartTime != "" {
-			startTimeSql = " AND  DATE_FORMAT(c.create_time,'%Y-%m-%d') >= '" + in.StartTime + "' "
-		}
-		idSql := fmt.Sprintf("(SELECT COUNT(e.id)  FROM socialize_chat_session e WHERE e.customer_service_id > 0 AND e.user_id = d.user_id ) =0 or d.customer_service_id=%d ", in.EntUserId)
-		if in.IsArtificial == 1 {
-			idSql = fmt.Sprintf("d.customer_service_id = %d ", in.EntUserId)
-		} else if in.IsArtificial == 2 {
-			idSql = "(SELECT COUNT(e.id)  FROM socialize_chat_session e WHERE e.customer_service_id > 0 AND e.user_id = d.user_id ) =0 "
-		}
-		endTimeSql := ""
-		if in.EndTime != "" {
-			endTimeSql = "AND DATE_FORMAT(c.create_time,'%Y-%m-%d') <= '" + in.EndTime + "' "
+			idSql += fmt.Sprintf(" AND  b.id not in (%s)", strings.Join(ids, ","))
 		}
 		if in.Page <= 0 {
 			in.Page = 1
@@ -185,62 +183,61 @@ func (b MessaggeService) UserList(in *messagecenter.UserReq) (data *[]map[string
 		if in.Size <= 0 || in.Size > 100 {
 			in.Size = 50
 		}
-		userSql := fmt.Sprintf("SELECT   MAX( c.id ) as messageId   FROM  %s c   "+
-			"INNER JOIN %s b ON if (c.send_user_type=1 ,c.receive_user_id,c.send_user_id)=b.id  "+
-			"LEFT JOIN %s d ON   c.own_type=1 AND  c.own_id=d.id   "+
-			"WHERE   c.own_type = 1  "+
-			"AND c.iswithdraw = 0 "+
-			"AND (%s)   "+
-			"AND ( c.type = 4 OR c.type = 5 or  c.type=6 or  c.type=7 )   "+
-			"  %s %s %s "+
-			"GROUP BY   (   CASE  WHEN  c.send_user_type =2 THEN  CONCAT( c.send_user_id )   WHEN c.send_user_type =1 THEN  CONCAT( c.receive_user_id )  END  ) ",
-			util.SOCIALIZE_MESSAGE_MAILBOX, util.BASE_USER, util.SOCIALIZE_CHAT_SESSION,
-			idSql, startTimeSql, endTimeSql, screening)
-		countSql := fmt.Sprintf("SELECT * FROM (%s) as data  order by messageId desc ", userSql)
-		countData := util.Mysql.SelectBySql(countSql)
-		log.Println("查询最新消息数量sql:", countSql)
-		if countData != nil && len(*countData) > 0 {
-			log.Printf("查询耗时1:%d;查询数量:%d", time.Since(tm), count)
-			count = quitl.Int64All(len(*countData))
-			var d []map[string]interface{}
-			if in.Page*in.Size >= count {
-				d = (*countData)[(in.Page-1)*in.Size:]
-			} else {
-				d = (*countData)[(in.Page-1)*in.Size : in.Page*in.Size]
-			}
-			customerMessageId := util.Inhandle(&d)
-			//客服的用户列表
-			sqlStr = fmt.Sprintf("SELECT  "+
-				"(  CASE        WHEN SUBSTR( b.nickname, 1, 3 ) = 'JY_' THEN    CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) )     WHEN b.nickname = '' or b.nickname is null THEN    CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) ELSE b.nickname    END    )"+
-				" AS name,  b.id,  e.title,  b.headimg,  e.type,  e.link,  e.content,  a.create_time,  "+
-				"(  SELECT   count( h.id )   FROM   %s h   "+
-				"LEFT JOIN %s i ON h.own_type = 1 AND h.own_id = i.id     "+
-				"WHERE  h.own_type = 1  "+
-				"AND i.ent_id=f.ent_id "+
-				"AND  i.user_id=f.user_id    "+
-				"AND h.isread = 0  "+
-				"AND h.iswithdraw = 0 "+
-				"AND  i.customer_service_id= %d) AS number "+
-				"FROM  %s a  "+
-				"INNER JOIN %s b ON if (a.send_user_type=1 ,a.receive_user_id,a.send_user_id)=b.id  "+
-				"LEFT JOIN %s e ON e.id = a.messag_id  "+
-				"LEFT JOIN %s f ON a.own_type=1 AND  a.own_id=f.id   "+
-				"WHERE  a.id IN  ( %s) %s ORDER BY  a.create_time DESC",
-				util.SOCIALIZE_MESSAGE_MAILBOX, util.SOCIALIZE_CHAT_SESSION,
-				in.EntUserId, util.SOCIALIZE_MESSAGE_MAILBOX, util.BASE_USER, util.SOCIALIZE_MESSAGE, util.SOCIALIZE_CHAT_SESSION, customerMessageId, phoneSql)
-		}
+		sqlStr = fmt.Sprintf(`SELECT(
+			CASE
+			WHEN SUBSTR( b.nickname, 1, 3 ) = 'JY_' THEN
+			CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) 
+			WHEN b. IS NULL THEN
+				CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) ELSE b.nickname 
+			END nickname = '' 
+			OR b.nickname
+			) AS NAME,
+			b.id,
+			e.title,
+			b.headimg,
+			e.type,
+			e.link,
+			e.content,
+			a.update_time,
+			(
+			SELECT
+				count( h.id ) 
+			FROM
+				 %s h
+				LEFT JOIN  %s i ON h.own_id = i.id 
+			WHERE
+				h.own_type = 1 
+				AND i.ent_id = a.ent_id 
+				AND i.user_id = a.user_id 
+				AND h.isread = 0 
+				AND h.iswithdraw = 0 
+				AND i.customer_service_id = %d 
+			) AS number 
+		FROM
+			%s a
+			INNER JOIN %s b ON  %s 
+			AND a.user_id = b.id
+			INNER JOIN  %s e ON e.id = a.message_id 
+	ORDER BY
+	a.update_time DESC`, util.SOCIALIZE_MESSAGE_MAILBOX, util.SOCIALIZE_CHAT_SESSION, in.EntUserId, util.User_message_list, util.BASE_USER, idSql, util.SOCIALIZE_MESSAGE)
 	}
 	if sqlStr != "" {
 		log.Println("查询列表sql:", sqlStr)
-		data = util.Mysql.SelectBySql(sqlStr)
-		log.Println("查询耗时2:", time.Since(tm), count)
-		if in.UserType == 2 && data != nil && len(*data) > 0 {
-			count = quitl.Int64All(len(*data))
+		dataAll := util.Mysql.SelectBySql(sqlStr)
+		if dataAll != nil && len(*dataAll) > 0 {
+			log.Println("查询列表耗时2:", time.Since(tm), count)
+			count = quitl.Int64All(len(*dataAll))
+			if in.Page*in.Size >= count {
+				*data = (*dataAll)[(in.Page-1)*in.Size:]
+			} else {
+				*data = (*dataAll)[(in.Page-1)*in.Size : in.Page*in.Size]
+			}
 		}
 	}
 	return
 }
 
+// 客服会话列表
 func (b MessaggeService) ConversationList(in *messagecenter.ConversationReq) (data *[]map[string]interface{}, count int64, err error) {
 	sqlStr := ""
 	tm := time.Now()
@@ -249,46 +246,46 @@ func (b MessaggeService) ConversationList(in *messagecenter.ConversationReq) (da
 		for _, v := range strings.Split(in.FiltrationId, ",") {
 			ids = append(ids, encrypt.SE.Decode4Hex(v))
 		}
-		screening := fmt.Sprintf(" AND  b.id  in (%s)", strings.Join(ids, ","))
 
-		idSql := fmt.Sprintf("d.customer_service_id = %d ", in.EntUserId)
-		userSql := fmt.Sprintf("SELECT   MAX( c.id ) as messageId   FROM  %s c   "+
-			"INNER JOIN %s b ON if (c.send_user_type=1 ,c.receive_user_id,c.send_user_id)=b.id  "+
-			"LEFT JOIN %s d ON   c.own_type=1 AND  c.own_id=d.id   "+
-			"WHERE   c.own_type = 1  "+
-			"AND c.iswithdraw = 0 "+
-			"AND %s   "+
-			"AND ( c.type = 4 OR c.type = 5 or  c.type=6 or  c.type=7 )  %s "+
-			"GROUP BY   (   CASE  WHEN  c.send_user_type =2 THEN  CONCAT( c.send_user_id )   WHEN c.send_user_type =1 THEN  CONCAT( c.receive_user_id )  END  ) ",
-			util.SOCIALIZE_MESSAGE_MAILBOX, util.BASE_USER, util.SOCIALIZE_CHAT_SESSION,
-			idSql, screening)
-		countData := util.Mysql.SelectBySql(userSql)
-		log.Println("查询最新消息数量sql:", userSql)
-		if countData != nil && len(*countData) > 0 {
-			log.Printf("查询耗时1:%d;查询数量:%d", time.Since(tm), count)
-			count = quitl.Int64All(len(*countData))
-			customerMessageId := util.Inhandle(countData)
-			//客服的用户列表
-			sqlStr = fmt.Sprintf("SELECT  "+
-				"(  CASE        WHEN SUBSTR( b.nickname, 1, 3 ) = 'JY_' THEN    CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) )     WHEN b.nickname = '' or b.nickname is null THEN    CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) ELSE b.nickname    END    )"+
-				" AS name,  b.id,  e.title,  b.headimg,  e.type,  e.link,  e.content,  a.create_time,  "+
-				"(  SELECT   count( h.id )   FROM   %s h   "+
-				"LEFT JOIN %s i ON h.own_type = 1 AND h.own_id = i.id     "+
-				"WHERE  h.own_type = 1  "+
-				"AND i.ent_id=f.ent_id "+
-				"AND  i.user_id=f.user_id    "+
-				"AND h.isread = 0  "+
-				"AND h.iswithdraw = 0 "+
-				"AND  i.customer_service_id= %d) AS number "+
-				"FROM  %s a  "+
-				"INNER JOIN %s b ON if (a.send_user_type=1 ,a.receive_user_id,a.send_user_id)=b.id  "+
-				"LEFT JOIN %s e ON e.id = a.messag_id  "+
-				"LEFT JOIN %s f ON a.own_type=1 AND  a.own_id=f.id   "+
-				"WHERE  a.id IN  ( %s)  ORDER BY  a.create_time DESC",
-				util.SOCIALIZE_MESSAGE_MAILBOX, util.SOCIALIZE_CHAT_SESSION,
-				in.EntUserId, util.SOCIALIZE_MESSAGE_MAILBOX, util.BASE_USER, util.SOCIALIZE_MESSAGE, util.SOCIALIZE_CHAT_SESSION, customerMessageId)
-		}
+		idSql := fmt.Sprintf("a.customer_service_id = %d AND  b.id  in (%s) ", in.EntUserId, strings.Join(ids, ","))
+		sqlStr = fmt.Sprintf(`SELECT(
+			CASE
+			WHEN SUBSTR( b.nickname, 1, 3 ) = 'JY_' THEN
+			CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) 
+			WHEN b. IS NULL THEN
+				CONCAT( SUBSTR( b.phone, 1, 3 ), '****', SUBSTR( b.phone, 8, 11 ) ) ELSE b.nickname 
+			END nickname = '' 
+			OR b.nickname
+			) AS NAME,
+			b.id,
+			e.title,
+			b.headimg,
+			e.type,
+			e.link,
+			e.content,
+			a.update_time,
+			(
+			SELECT
+				count( h.id ) 
+			FROM
+				 %s h
+				LEFT JOIN  %s i ON h.own_id = i.id 
+			WHERE
+				h.own_type = 1 
+				AND i.ent_id = a.ent_id 
+				AND i.user_id = a.user_id 
+				AND h.isread = 0 
+				AND h.iswithdraw = 0 
+				AND i.customer_service_id = %d 
+			) AS number 
+		FROM
+			%s a
+			INNER JOIN %s b ON  %s 
+			AND a.user_id = b.id
+			INNER JOIN  %s e ON e.id = a.message_id`,
+			util.SOCIALIZE_MESSAGE_MAILBOX, util.SOCIALIZE_CHAT_SESSION, in.EntUserId, util.User_message_list, util.BASE_USER, idSql, util.SOCIALIZE_MESSAGE)
 	}
+
 	if sqlStr != "" {
 		log.Println("查询列表sql:", sqlStr)
 		data = util.Mysql.SelectBySql(sqlStr)
@@ -301,7 +298,9 @@ func (b MessaggeService) ConversationList(in *messagecenter.ConversationReq) (da
 func (b MessaggeService) SaveMessage(in *messagecenter.MessageEntity) (fool bool, errorMsg string, content string, messageId, nowInt int64) {
 	//先插入信息表
 	//判断会话标识是否属于本人
+	var customer_service_id, userid, entid, message_id int64
 	nowForm := time.Now().Local()
+	create_time := nowForm.Format(util.Date_Full_Layout)
 	if in.ItemType != 2 {
 		userId := int64(0)
 		sessionId := int64(0)
@@ -340,10 +339,12 @@ func (b MessaggeService) SaveMessage(in *messagecenter.MessageEntity) (fool bool
 				return false, "会话标识不属于此用户", "", 0, nowForm.Unix()
 			}
 		}
+		customer_service_id = quitl.Int64All((*chatJson)["customer_service_id"])
+		entid = quitl.Int64All((*chatJson)["ent_id"])
+		userid = userId
 	}
 	fool = util.Mysql.ExecTx("聊天信息保存", func(tx *sql.Tx) bool {
 		//先插入信息表
-		create_time := nowForm.Format(util.Date_Full_Layout)
 		userType := int64(1)
 		userId := int64(0)
 		message := map[string]interface{}{
@@ -512,17 +513,67 @@ func (b MessaggeService) SaveMessage(in *messagecenter.MessageEntity) (fool bool
 			}
 			util.SetData(userType, userId, map[string]interface{}{"data": data, "count": count}, util.SurvivalTime)
 		}
+		message_id = receiveOk
 		return ok > 1 && receiveOk > 1
 	})
+	if fool && in.ItemType != 2 && in.ItemType != 3 {
+		go UserSynchronousList(customer_service_id, userid, entid, message_id, create_time)
+	}
 	return fool, "", in.Content, messageId, nowForm.Unix()
 }
 
+var rwLock = new(sync.RWMutex)
+
+// 客服 用户聊天消息列表同步
+func UserSynchronousList(customerServiceId, userId, entId, messageId int64, createTime string) {
+	rwLock.Lock()
+	defer rwLock.Unlock()
+	if util.Mysql.Count(util.User_message_list, map[string]interface{}{"user_id": userId}) > 0 {
+		upData := map[string]interface{}{
+			"message_id":  messageId,
+			"update_time": createTime,
+		}
+		//判断是否机器人聊天
+		if customerServiceId > 0 && util.Mysql.Count(util.User_message_list, map[string]interface{}{"user_id": userId, "customer_service_id": 0}) > 0 {
+			//将机器人列表更新成用户
+			upData["customer_service_id"] = customerServiceId
+			//转人工 机器人聊天类型修改
+			upData["type"] = 1
+		}
+		//已于人工客服联系过 只同步最后消息
+		util.Mysql.Update(util.User_message_list, map[string]interface{}{"user_id": userId},
+			map[string]interface{}{"$set": upData})
+	}
+	//不存在消息列表 创建
+	util.Mysql.Insert(util.User_message_list, map[string]interface{}{
+		"ent_id":              entId,
+		"user_id":             userId,
+		"message_id":          messageId,
+		"update_time":         createTime,
+		"customer_service_id": customerServiceId,
+		"type":                quitl.If(customerServiceId == 0, 0, 1),
+	})
+}
+
 // 历史信息查询
 func (b MessaggeService) FindMessage(in *messagecenter.MessageReq) *[]map[string]interface{} {
 	sqlStr := ""
 	lastStr := ""
+	lastRedisKey := fmt.Sprintf("lastRedisKey_%d_%d_%d_%d", in.UserType, in.LastId, in.SendId, in.NewUserId)
 	if in.LastId > 0 {
 		if in.Sort == "asc" {
+			//判断缓存是否有数据或 已有查询
+			if ok, _ := redis.Exists("msgCount", lastRedisKey); ok {
+				data := redis.Get("msgCount", lastRedisKey)
+				if data != nil {
+					vle, _ := data.([]interface{})
+					log.Println("存在存储消息 直接返回", len(vle))
+					d := quitl.ObjArrToMapArr(vle)
+					return &d
+				}
+				return nil
+			}
+			redis.Put("msgCount", lastRedisKey, nil, 10)
 			lastStr = fmt.Sprintf("AND  a.messag_id > %d ", in.LastId)
 		} else {
 			lastStr = fmt.Sprintf("AND  a.messag_id < %d ", in.LastId)
@@ -628,6 +679,11 @@ func (b MessaggeService) FindMessage(in *messagecenter.MessageReq) *[]map[string
 			b.Count(in.NewUserId, in.UserType, in.EntUserId, true)
 		}
 	}()
+	if in.LastId > 0 && in.Sort == "asc" {
+		if data != nil && len(*data) > 0 {
+			redis.Put("msgCount", lastRedisKey, *data, 10)
+		}
+	}
 	return data
 }
 
@@ -681,8 +737,9 @@ func (b MessaggeService) CloseChatSession(in *messagecenter.CloseSessionReq) boo
 
 // 创建会话并保存信息
 func (b *MessaggeService) SaveAutoReplyMsg(userType, entId, entUserId, userId int64, content, appId, nowFormat string) (bool, int64) {
+	var customer_service_id, userid, entid, message_id int64
 	messageId := int64(0)
-	return util.Mysql.ExecTx("保存自动回复消息", func(tx *sql.Tx) bool {
+	ok1 := util.Mysql.ExecTx("保存自动回复消息", func(tx *sql.Tx) bool {
 		entUserName := ""
 		if entUserId > 0 {
 			list := util.Mysql.SelectBySql(`select ? from socialize_tenant_seat where appid=? AND ent_id=? AND customer_service_id=?`, util.SOCIALIZE_CHAT_SESSION, appId, entId, entUserId)
@@ -702,8 +759,16 @@ func (b *MessaggeService) SaveAutoReplyMsg(userType, entId, entUserId, userId in
 		} else if userType == 2 {
 			ok = util.Mysql.InsertBySqlByTx(tx, `insert into socialize_message_mailbox (appid,messag_id,type,send_user_id,send_user_type,receive_user_id,receive_user_type,own_id,own_type,create_time) values (?,?,?,?,?,?,?,?,?,?)`, appId, messageId, 7, sessionId, 1, userId, 2, userId, 2, nowFormat) > 0
 		}
+		message_id = messageId
 		return messageId > 0 && sessionId > 0 && ok
-	}), messageId
+	})
+	if ok1 {
+		customer_service_id = entUserId
+		userid = userId
+		entid = entId
+		go UserSynchronousList(customer_service_id, userid, entid, message_id, nowFormat)
+	}
+	return ok1, messageId
 }
 
 // 修改未读状态