lckt-server/plugin/customerservice/api/api.go

408 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"crypto/md5"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/model/common/response"
"git.echol.cn/loser/lckt/model/user"
sysModel "git.echol.cn/loser/lckt/plugin/customerservice/model"
"git.echol.cn/loser/lckt/plugin/customerservice/service"
"git.echol.cn/loser/lckt/plugin/customerservice/service/ws"
"git.echol.cn/loser/lckt/plugin/customerservice/tools"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"
"net/http"
"path/filepath"
"sort"
"strconv"
"time"
)
type CustomerServiceApi struct{}
func (cus *CustomerServiceApi) ServeWs(ctx *gin.Context) {
ws.WsServe(ctx)
}
func (cus *CustomerServiceApi) ServeWsForKefu(ctx *gin.Context) {
ws.ServeWsForKefu(ctx)
}
func (cus *CustomerServiceApi) HandleTransfer(c *gin.Context) {
var transferReq struct {
FromAgent string `json:"from_agent"`
ToAgent string `json:"to_agent"`
UserID string `json:"user_id"`
}
if err := c.ShouldBindJSON(&transferReq); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 更新用户与客服的映射关系
// 例如userAgentMap[transferReq.UserID] = transferReq.ToAgent
c.JSON(http.StatusOK, gin.H{"status": "success"})
}
func (cus *CustomerServiceApi) GetKefuInfo(c *gin.Context) {
userID, _ := c.Get("jwt_user_id")
//uidStr := strconv.Itoa(int(userID))
var serviceId int64
var recordData sysModel.SysServiceRecord
result := global.GVA_DB.Where("uid = ?", userID).Order("update_time DESC").Limit(1).Find(&recordData)
if result.RowsAffected == 0 || result.Error != nil {
//直接查询service表
result2 := global.GVA_DB.Model(&sysModel.SysService{}).
Select("id").
Where("status = ?", 1).
Order("add_time DESC").
Limit(1).Scan(&serviceId)
fmt.Println("sssssssssssss--->>>")
fmt.Println(serviceId)
if result2.Error != nil {
response.FailWithMessage("获取客服信息失败-1", c)
return
}
} else {
serviceId = recordData.ServiceId
}
var serviceData sysModel.SysService
result3 := global.GVA_DB.Select("id,uid,online,avatar,nickname,add_time,status").
Where("id = ?", serviceId).
Where("status = ?", 1).
Order("add_time DESC").
First(&serviceData)
if result3.Error != nil {
response.FailWithMessage("获取客服信息失败-2", c)
return
}
response.OkWithDetailed(serviceData, "获取成功", c)
}
func (cus *CustomerServiceApi) SendMsg(c *gin.Context) {
var msgJson ws.Message
if jsErr := c.ShouldBindJSON(&msgJson); jsErr != nil {
fmt.Println(jsErr)
response.FailWithMessage("参数有误-1", c)
return
}
fromIdStr := msgJson.Sender
toIdStr := msgJson.Receiver
content := msgJson.Content
isKf := msgJson.IsKf
msgTypeStr := msgJson.MsgType
if content == "" || fromIdStr == "" || toIdStr == "" || msgTypeStr == "" {
response.FailWithMessage("参数有误-2", c)
return
}
toId, err_1 := strconv.ParseInt(toIdStr, 10, 64)
fromId, err_2 := strconv.ParseInt(fromIdStr, 10, 64)
msgType, err_3 := strconv.ParseInt(msgTypeStr, 10, 64)
if err_1 != nil || err_2 != nil || err_3 != nil {
response.FailWithMessage("参数有误", c)
return
}
//限流
if !tools.LimitFreqSingle("send_message:"+c.ClientIP(), 1, 2) {
response.FailWithMessage("发送频率过快", c)
return
}
var kfInfo sysModel.SysService
//var userInfo sysModel.SysTestUser
var userInfo user.User
var err, err2 error
if isKf == 1 {
err = global.GVA_DB.Where("id = ?", fromId).First(&kfInfo).Error
err2 = global.GVA_DB.Where("id = ?", toId).First(&userInfo).Error
} else if isKf == 0 {
err = global.GVA_DB.Where("id = ?", toId).First(&kfInfo).Error
err2 = global.GVA_DB.Where("id = ?", fromId).First(&userInfo).Error
}
if err != nil || err2 != nil {
response.FailWithMessage("获取失败-1", c)
return
}
ser := service.ServiceGroupApp
cErr := ser.CreateMsg(kfInfo, userInfo, msgType, content, strconv.FormatInt(isKf, 10))
if cErr != nil {
response.FailWithMessage("发送失败", c)
return
}
message := ws.Message{
Sender: fromIdStr,
Receiver: toIdStr,
Content: content,
MsgType: msgTypeStr,
Role: "kf",
Timestamp: time.Now().Unix(),
}
var key string
if isKf == 1 {
//查找指定用户广播消息
key = "user" + toIdStr
message.AvatarUrl = kfInfo.Avatar
message.Nickname = kfInfo.Nickname
} else if isKf == 0 {
//查找指定客服广播消息
key = "kf" + toIdStr
message.Role = "user"
message.AvatarUrl = userInfo.Avatar
message.Nickname = userInfo.NickName
}
conn, ok := ws.Manager.Clients[key]
if conn != nil && ok {
sendMsg := ws.TypeMsg{
Type: "message",
Data: message,
}
str, _ := json.Marshal(sendMsg)
conn.Send <- str
if isKf == 0 {
//客服给用户发送自动回复消息
var autoReply sysModel.SysServiceReply
autoContent := ""
var autoMsgType int64
aErr := global.GVA_DB.Where("is_complete = ? AND `status` = ? AND keyword = ?", 1, 1, content).First(&autoReply).Error
fmt.Println(aErr)
if aErr == nil {
fmt.Println(autoReply)
autoContent = autoReply.Content
autoMsgType = autoReply.ReplyType
} else {
aErr = global.GVA_DB.Where("is_complete = ? AND `status` = ? AND keyword LIKE ?", 0, 1, "%"+content+"%").First(&autoReply).Error
if aErr == nil {
autoContent = autoReply.Content
autoMsgType = autoReply.ReplyType
}
}
if autoContent != "" {
if autoMsgType == 2 {
autoMsgType = 3 //图片
}
aErr = ser.CreateMsg(kfInfo, userInfo, autoMsgType, autoContent, "1")
if aErr == nil {
autoUidStr := strconv.FormatUint(uint64(userInfo.ID), 10)
message.Sender = strconv.FormatInt(kfInfo.Id, 10)
message.Receiver = autoUidStr
message.MsgType = strconv.FormatInt(autoMsgType, 10)
message.Content = autoContent
message.IsKf = 1
message.Role = "kf"
message.AvatarUrl = kfInfo.Avatar
message.Nickname = kfInfo.Nickname
sendMsg.Data = message
autoStr, _ := json.Marshal(sendMsg)
kfConn, isOk := ws.Manager.Clients["user"+autoUidStr]
if kfConn != nil && isOk {
kfConn.Send <- autoStr
}
}
}
}
}
response.OkWithDetailed(nil, "发送成功", c)
}
func (cus *CustomerServiceApi) GetMsgList(c *gin.Context) {
uid, ok := c.Get("jwt_user_id") //jwt里解出的
jwtServiceId, ok2 := c.Get("service_id") //jwt里解出的
if !ok2 {
//gva-shop前端用户连接请求消息列表
jwtServiceId = c.Query("kf_id")
}
if !ok {
//后台客服连接请求消息列表
uid = c.Query("uid")
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
if pageSize > 20 {
pageSize = 20
}
offset := pageSize * (page - 1)
var total int64
var list []sysModel.SysServiceMsg
db := global.GVA_DB.Model(&sysModel.SysServiceMsg{}).Where("uid = ?", uid).Where("service_id = ?", jwtServiceId)
db.Count(&total)
err := db.Limit(pageSize).Offset(offset).Order("add_time desc").Find(&list).Error
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
if len(list) > 0 {
sort.Slice(list, func(i, j int) bool {
return list[i].AddTime < list[j].AddTime
})
for k, v := range list {
decoded, _ := base64.StdEncoding.DecodeString(v.Content)
v.Content = string(decoded)
list[k] = v
}
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: page,
PageSize: pageSize,
}, "获取成功", c)
}
func (cus *CustomerServiceApi) GetMsgUser(c *gin.Context) {
kfId, _ := c.Get("service_id")
var list []sysModel.SysServiceRecord
err := global.GVA_DB.Where("service_id=?", kfId).Find(&list).Error
if err != nil {
response.FailWithMessage("获取失败", c)
return
}
if len(list) > 0 {
//判断用户在线状况
for k, v := range list {
userKey := "user" + strconv.FormatInt(v.Uid, 10)
isClent, ok := ws.Manager.Clients[userKey]
if ok && isClent != nil {
v.Online = 1
} else {
v.Online = 0
}
decoded, _ := base64.StdEncoding.DecodeString(v.Message)
v.Message = string(decoded)
//查找未读消息数
var noCount int64
global.GVA_DB.Model(&sysModel.SysServiceMsg{}).
Where("is_view=?", 0).
Where("is_kf=?", 0).
Where("service_id=?", kfId).
Where("uid=?", v.Uid).Count(&noCount)
v.NoRead = noCount
v.AddTimeStr = tools.FormatTimestamp(v.UpdateTime)
if v.MessageType == 3 {
v.Message = "[图片]"
}
list[k] = v
}
sort.Slice(list, func(i, j int) bool {
if list[i].Online != list[j].Online {
return list[i].Online > list[j].Online
}
return list[i].AddTime > list[j].AddTime
})
}
response.OkWithDetailed(list, "获取成功", c)
}
func (cus *CustomerServiceApi) SetMsgView(c *gin.Context) {
kfId, _ := c.Get("service_id")
uid := c.Query("uid")
global.GVA_DB.Model(&sysModel.SysServiceMsg{}).
Where(map[string]interface{}{"is_kf": 0, "service_id": kfId, "is_view": 0, "uid": uid}).
Update("is_view", 1)
response.Ok(c)
}
func (cus *CustomerServiceApi) UploadFile(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
extension := filepath.Ext(file.Filename)
newUUID := uuid.New().String()
hash := md5.Sum([]byte("gva-service" + newUUID))
md5Pwd := hex.EncodeToString(hash[:])
filename := md5Pwd + extension
if err := c.SaveUploadedFile(file, "./uploads/file/"+filename); err != nil {
response.FailWithMessage("上传失败-2", c)
return
}
//ser := service.ServiceGroupApp
//url := ser.GetUrlHost(c)
response.OkWithDetailed("uploads/file/"+filename, "获取成功", c)
return
}
func (cus *CustomerServiceApi) GetTestMsgList(c *gin.Context) {
uid := c.Query("uid")
serviceId := c.Query("service_id")
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if pageSize > 20 {
pageSize = 20
}
offset := pageSize * (page - 1)
var total int64
var list []sysModel.SysServiceMsg
global.GVA_DB.Model(&sysModel.SysServiceMsg{}).Where("uid=?", uid).Where("service_id=?", serviceId).Count(&total)
err := global.GVA_DB.Where("uid=?", uid).Where("service_id=?", serviceId).Limit(pageSize).Offset(offset).Order("add_time desc").Find(&list).Error
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
if len(list) > 0 {
sort.Slice(list, func(i, j int) bool {
return list[i].AddTime < list[j].AddTime
})
for k, v := range list {
decoded, _ := base64.StdEncoding.DecodeString(v.Content)
v.Content = string(decoded)
list[k] = v
}
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: page,
PageSize: pageSize,
}, "获取成功", c)
}
func (cus *CustomerServiceApi) GetUserInfo(c *gin.Context) {
//userID := utils.GetUserID(c)
userID, ok := c.Get("jwt_user_id")
if !ok {
//后台客服连接请求
userID = c.Query("uid")
}
var clientUser user.User
result := global.GVA_DB.Omit("password").Where("id = ?", userID).Where("deleted_at IS NULL").First(&clientUser)
if result.Error != nil {
response.FailWithMessage("获取用户信息失败", c)
return
}
response.OkWithDetailed(clientUser, "获取成功", c)
}
func (cus *CustomerServiceApi) GetServiceScript(c *gin.Context) {
rType := c.Query("type")
db := global.GVA_DB.Model(&sysModel.SysServiceScript{})
if rType == "1" {
serviceId, ok := c.Get("service_id")
if serviceId != "" && ok {
db = db.Where("service_id=?", serviceId)
}
} else {
db = db.Where("service_id=?", 0)
}
var list []sysModel.SysServiceScript
err := db.Order("add_time desc").Limit(20).Offset(0).Find(&list).Error
if err != nil {
response.FailWithMessage("查询失败:"+err.Error(), c)
return
}
response.OkWithDetailed(list, "获取成功", c)
}