Commit f3517e22 by chenxianqi

update

parent 9e9a2058
......@@ -4,6 +4,8 @@ runmode = "dev"
httpport = 8080
copyrequestbody = true
viewspath = "public"
# 用于本地服务今天地址
static_host = "http://localhost:8080/static/uploads/images"
# 进程监控
......
......@@ -189,7 +189,7 @@ func (c *AdminController) Delete() {
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限删除该账号!", nil)
}
......
......@@ -8,8 +8,10 @@ import (
"kefu_server/models"
"kefu_server/services"
"kefu_server/utils"
"strconv"
"time"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/validation"
)
......@@ -46,7 +48,7 @@ func (c *AuthController) Finish() {}
type LoginRequest struct {
AuthType int64 `json:"auth_type"`
UserName string `json:"username"`
Password string `ojson:"password"`
Password string `json:"password"`
}
// Login admin login
......@@ -146,3 +148,56 @@ func (c *AuthController) Logout() {
}
c.JSON(configs.ResponseSucess, "退出成功!", nil)
}
// RobotFetchTokenRequest struct
type RobotFetchTokenRequest struct {
AppID string `json:"app_id"`
AppKey string `json:"app_key"`
AppSecret string `json:"app_secret"`
}
// RobotFetchToken admin logout
func (c *AuthController) RobotFetchToken() {
var request RobotFetchTokenRequest
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &request); err != nil {
c.JSON(configs.ResponseFail, "参数有误,请检查", nil)
}
// valid
valid := validation.Validation{}
valid.Required(request.AppID, "app_id").Message("app_id不能为空!")
valid.Required(request.AppKey, "app_key").Message("app_key不能为空!")
valid.Required(request.AppSecret, "app_secret").Message("app_secret不能为空!")
if valid.HasErrors() {
for _, err := range valid.Errors {
c.JSON(configs.ResponseFail, err.Message, nil)
}
}
// MD5
m5 := md5.New()
m5.Write([]byte(request.AppID + request.AppKey + request.AppSecret))
reqyestSecret := hex.EncodeToString(m5.Sum(nil))
// current app Secret
_AppID, _ := beego.AppConfig.Int64("mimc_appId")
_AppKey := beego.AppConfig.String("mimc_appKey")
_AppSecret := beego.AppConfig.String("mimc_appSecret")
m51 := md5.New()
m51.Write([]byte(strconv.FormatInt(_AppID, 10) + _AppKey + _AppSecret))
currentAppSecret := hex.EncodeToString(m51.Sum(nil))
// check
if reqyestSecret != currentAppSecret {
c.JSON(configs.ResponseFail, "server error~", currentAppSecret)
c.JSON(configs.ResponseFail, "server error~", reqyestSecret)
}
// create token
newToken := utils.GenerateToken(models.JwtKeyDto{ID: _AppID, UserName: _AppKey, AuthType: 0})
c.JSON(configs.ResponseSucess, "授权成功!", &newToken)
}
package controllers
import (
"encoding/base64"
"encoding/json"
"kefu_server/configs"
"kefu_server/models"
robotlbrary "kefu_server/robot"
"kefu_server/services"
"kefu_server/utils"
"strconv"
"time"
"github.com/astaxie/beego/logs"
......@@ -67,9 +64,10 @@ func (c *MessageController) List() {
}
// push notify update current service contacts list
if len(robotlbrary.Robots) > 0 {
robotlbrary.PushNewContacts(auth.UID, robotlbrary.Robots[0])
}
// 待处理888 推送给客户的的聊天列表
// if len(robotlbrary.Robots) > 0 {
// robotlbrary.PushNewContacts(auth.UID, robotlbrary.Robots[0])
// }
c.JSON(configs.ResponseSucess, "success", &returnMessagePaginationDto)
}
......@@ -102,7 +100,7 @@ func (c *MessageController) Remove() {
c.JSON(configs.ResponseSucess, "删除成!", row)
}
// Transfer transfer user to user
// Transfer transfer admin to admin
func (c *MessageController) Transfer() {
// GetAuthInfo
......@@ -126,9 +124,6 @@ func (c *MessageController) Transfer() {
}
}
robot := robotlbrary.Robots[0]
robotID, _ := strconv.ParseInt(robot.AppAccount(), 10, 64)
type adminData struct {
ID int64 `orm:"column(id)" json:"id"`
NickName string `json:"nickname"`
......@@ -148,6 +143,12 @@ func (c *MessageController) Transfer() {
c.JSON(configs.ResponseFail, "转接失败用户ID不存在!", nil)
}
// get one online robot
// robot, _ := services.GetRobotRepositoryInstance().GetRobotWithRandomOnline()
// 待处理888 记得要使用toAdminJSON
logs.Info(toAdminJSON)
// message
message := models.Message{}
message.BizType = "transfer"
......@@ -156,29 +157,40 @@ func (c *MessageController) Transfer() {
message.TransferAccount = transferDto.ToAccount
// Send to forwarder
message.ToAccount = admin.ID
message.Payload = "您将" + user.NickName + "转接给" + toAdmin.NickName
messageJSONOne, _ := json.Marshal(message)
messageStringOne := base64.StdEncoding.EncodeToString([]byte(messageJSONOne))
robot.SendMessage(strconv.FormatInt(admin.ID, 10), []byte(messageStringOne))
// message.ToAccount = admin.ID
// message.Payload = "您将" + user.NickName + "转接给" + toAdmin.NickName
// messageJSONOne, _ := json.Marshal(message)
// messageStringOne := base64.StdEncoding.EncodeToString([]byte(messageJSONOne))
// 待处理888 发送消息
// robot.SendMessage(strconv.FormatInt(admin.ID, 10), []byte(messageStringOne))
utils.MessageInto(message, true)
// Send to forwarded customer service
message.ToAccount = transferDto.ToAccount
message.Payload = admin.NickName + "将" + user.NickName + "转接给您"
messageJSONTwo, _ := json.Marshal(message)
messageStringTwo := base64.StdEncoding.EncodeToString([]byte(messageJSONTwo))
robot.SendMessage(strconv.FormatInt(transferDto.ToAccount, 10), []byte(messageStringTwo))
// message.ToAccount = transferDto.ToAccount
// message.Payload = admin.NickName + "将" + user.NickName + "转接给您"
// messageJSONTwo, _ := json.Marshal(message)
// messageStringTwo := base64.StdEncoding.EncodeToString([]byte(messageJSONTwo))
// 待处理888 发送消息
// robot.SendMessage(strconv.FormatInt(transferDto.ToAccount, 10), []byte(messageStringTwo))
utils.MessageInto(message, true)
// send to user
message.FromAccount = robotID
message.ToAccount = transferDto.UserAccount
message.Delete = 1
message.Payload = string(toAdminJSON)
messageJSONThree, _ := json.Marshal(message)
messageString3 := base64.StdEncoding.EncodeToString([]byte(messageJSONThree))
robot.SendMessage(strconv.FormatInt(transferDto.UserAccount, 10), []byte(messageString3))
// message.FromAccount = robot.ID
// message.ToAccount = transferDto.UserAccount
// message.Delete = 1
// message.Payload = string(toAdminJSON)
// messageJSONThree, _ := json.Marshal(message)
// messageString3 := base64.StdEncoding.EncodeToString([]byte(messageJSONThree))
// 待处理888 发送消息
// robot.SendMessage(strconv.FormatInt(transferDto.UserAccount, 10), []byte(messageString3))
utils.MessageInto(message, false)
// Transfer to the library for counting service times
......
......@@ -5,7 +5,6 @@ import (
"encoding/json"
"kefu_server/configs"
"kefu_server/models"
robotlbrary "kefu_server/robot"
"kefu_server/services"
"kefu_server/utils"
"os"
......@@ -100,7 +99,7 @@ func (c *PublicController) Register() {
if user != nil {
// fetchResult
fetchResult, fetchError = robotlbrary.GetMiMcToken(strconv.FormatInt(user.ID, 10))
fetchResult, fetchError = utils.GetMiMcToken(strconv.FormatInt(user.ID, 10))
if err := json.Unmarshal([]byte(fetchResult), &imTokenDto); err != nil {
c.JSON(configs.ResponseFail, "注册失败!", &err)
}
......@@ -126,7 +125,7 @@ func (c *PublicController) Register() {
if accountID, err := c.UserRepository.Add(user); err == nil {
fetchResult, fetchError = robotlbrary.GetMiMcToken(strconv.FormatInt(accountID, 10))
fetchResult, fetchError = utils.GetMiMcToken(strconv.FormatInt(accountID, 10))
if err := json.Unmarshal([]byte(fetchResult), &imTokenDto); err != nil {
c.JSON(configs.ResponseFail, "注册失败!", &err)
}
......@@ -149,7 +148,7 @@ func (c *PublicController) Register() {
admin = c.AdminRepository.GetAdmin(auth.UID)
// fetchResult
fetchResult, fetchError = robotlbrary.GetMiMcToken(strconv.FormatInt(admin.ID, 10))
fetchResult, fetchError = utils.GetMiMcToken(strconv.FormatInt(admin.ID, 10))
// imTokenDto
if err := json.Unmarshal([]byte(fetchResult), &imTokenDto); err != nil {
......
......@@ -38,7 +38,7 @@ func (c *QiniuController) Get() {
// GetAuthInfo
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限获取配置!", nil)
}
......@@ -63,7 +63,7 @@ func (c *QiniuController) Put() {
// GetAuthInfo
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限获取配置!", nil)
}
......
......@@ -8,7 +8,6 @@ import (
"kefu_server/configs"
"kefu_server/models"
robotlbrary "kefu_server/robot"
"kefu_server/services"
"strconv"
"strings"
......@@ -59,7 +58,7 @@ func (c *RobotController) Delete() {
// GetAuthInfo
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限删除机器人!", nil)
}
......@@ -81,7 +80,8 @@ func (c *RobotController) Delete() {
}
// init robots
robotlbrary.RobotInit()
// 待处理888 删除成功后处理重启机器人
// robotlbrary.RobotInit()
c.JSON(configs.ResponseSucess, "删除成功!", nil)
}
......@@ -92,7 +92,7 @@ func (c *RobotController) Post() {
// GetAuthInfo
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限添加机器人!", nil)
}
......@@ -134,7 +134,8 @@ func (c *RobotController) Post() {
c.JSON(configs.ResponseFail, "添加失败!", nil)
}
robotlbrary.RobotInit()
// 待处理888 处理重启机器人
// robotlbrary.RobotInit()
c.JSON(configs.ResponseSucess, "添加成功!", id)
}
......@@ -145,7 +146,7 @@ func (c *RobotController) Put() {
// GetAuthInfo
auth := c.GetAuthInfo()
admin := c.AdminRepository.GetAdmin(auth.UID)
if admin.Root != 1 {
if admin == nil || admin.Root != 1 {
c.JSON(configs.ResponseFail, "您没有权限修改机器人!", nil)
}
......@@ -217,7 +218,8 @@ func (c *RobotController) Put() {
robot.Artificial = strings.Trim(robot.Artificial, "|")
robot.KeyWord = strings.Trim(robot.KeyWord, "|")
robot.CreateAt = oldRobot.CreateAt
robotlbrary.RobotInit()
// 待处理888 处理重启机器人
// robotlbrary.RobotInit()
c.JSON(configs.ResponseSucess, "修改成功!", &robot)
}
......
package robotlbrary
import (
"encoding/base64"
"encoding/json"
"kefu_server/models"
"strconv"
"time"
"github.com/Xiaomi-mimc/mimc-go-sdk"
"github.com/astaxie/beego/orm"
)
// PushNewContacts 推送最新聊天列表给客服
func PushNewContacts(accountID int64, robot *mimc.MCUser) {
o := orm.NewOrm()
var contactDto []models.ContactDto
// 消息体
message := models.Message{}
message.BizType = "contacts"
robotAccount, _ := strconv.ParseInt(robot.AppAccount(), 10, 64)
message.FromAccount = robotAccount
message.Timestamp = time.Now().Unix()
rCount, _ := o.Raw("SELECT c.id AS cid,c.to_account,c.is_session_end, c.last_message,c.last_message_type,c.from_account, c.create_at AS contact_create_at,u.*, IFNULL(m.`count`,0) AS `read` FROM `contact` c LEFT JOIN `user` u ON c.from_account = u.id LEFT JOIN (SELECT to_account,from_account, COUNT(*) as `count` FROM message WHERE `read` = 1 GROUP BY to_account,from_account) m ON m.to_account = c.to_account AND m.from_account = c.from_account WHERE c.to_account = ? AND c.delete = 0 ORDER BY c.create_at DESC", accountID).QueryRows(&contactDto)
if rCount == 0 {
contactDto = []models.ContactDto{}
}
// base 64转换回来
for index, contact := range contactDto {
payload, _ := base64.StdEncoding.DecodeString(contact.LastMessage)
contactDto[index].LastMessage = string(payload)
}
message.ToAccount = accountID
messageContentByte, _ := json.Marshal(contactDto)
message.Payload = string(messageContentByte)
messageJSON, _ := json.Marshal(message)
messageString := base64.StdEncoding.EncodeToString([]byte(messageJSON))
robot.SendMessage(strconv.FormatInt(accountID, 10), []byte(messageString))
}
package robotlbrary
import (
"container/list"
"encoding/base64"
"encoding/json"
"kefu_server/models"
msg "github.com/Xiaomi-mimc/mimc-go-sdk/message"
)
// MsgHandler ...
type MsgHandler struct {
appAccount string
}
// NewMsgHandler ...
func NewMsgHandler(appAccount string) *MsgHandler {
return &MsgHandler{appAccount}
}
// HandleMessage ...
func (c MsgHandler) HandleMessage(packets *list.List) {
for ele := packets.Front(); ele != nil; ele = ele.Next() {
// 收到的原始消息
p2pMsg := ele.Value.(*msg.P2PMessage)
// get message
var message models.Message
msgContentByte, err := base64.StdEncoding.DecodeString(string(p2pMsg.Payload()))
err = json.Unmarshal(msgContentByte, &message)
switch message.BizType {
// 消息入库
case "into":
return
// 撤销消息
case "cancel":
return
// 搜索知识库
case "search_knowledge":
return
// 与机器人握手
case "handshake":
return
default:
}
if err == nil {
MessageP2P(message)
}
}
}
// HandleGroupMessage 下面可以自己去实现一些东西(顾名思义MIMC接口)
func (c MsgHandler) HandleGroupMessage(packets *list.List) {
//for ele := packets.Front(); ele != nil; ele = ele.Next() {
// p2tmsg := ele.Value.(*msg.P2TMessage)
// logger.Info("[%v] [handle p2t msg]%v -> %v: %v, pcktId: %v, timestamp: %v.", c.appAccount, *(p2tmsg.FromAccount()), *(p2tmsg.GroupId()), string(p2tmsg.Payload()), *(p2tmsg.PacketId()), *(p2tmsg.Timestamp()))
//}
}
// HandleServerAck ...
func (c MsgHandler) HandleServerAck(packetID *string, sequence, timestamp *int64, errMsg *string) {
//logs.Info("[%v] [handle server ack] packetId:%v, seqId: %v, timestamp:%v.", c.appAccount, *packetId, *sequence, *timestamp)
}
// HandleSendMessageTimeout ...
func (c MsgHandler) HandleSendMessageTimeout(message *msg.P2PMessage) {
//logs.Info("[%v] [handle p2pmsg timeout] packetId:%v, msg:%v, time: %v.", c.appAccount, *(message.PacketId()), string(message.Payload()), time.Now())
}
// HandleSendGroupMessageTimeout ...
func (c MsgHandler) HandleSendGroupMessageTimeout(message *msg.P2TMessage) {
// logger.Info("[%v] [handle p2tmsg timeout] packetId:%v, msg:%v.", c.appAccount, *(message.PacketId()), string(message.Payload()))
}
package robotlbrary
import "github.com/astaxie/beego/logs"
// StatusHandler struct
type StatusHandler struct {
appAccount string
}
// NewStatusHandler newStatusHandler
func NewStatusHandler(appAccount string) *StatusHandler {
return &StatusHandler{appAccount}
}
// HandleChange handleChange
func (c StatusHandler) HandleChange(isOnline bool, errType, errReason, errDescription *string) {
if isOnline {
logs.Info("机器人霸道上线 status changed: online.", "")
} else {
// 有机器人掉线,重新登录
logs.Error("[机器人挂掉了] status changed: offline,errType:%v, errReason:%v, errDes:%v", *errType, *errReason, *errDescription)
}
}
package robotlbrary
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"strings"
"github.com/astaxie/beego"
)
// NewTokenHandler ...
func NewTokenHandler(appAccount string) *TokenHandler {
tokenHandler := new(TokenHandler)
tokenHandler.httpURL = beego.AppConfig.String("mimc_HttpUrl")
tokenHandler.AppID, _ = beego.AppConfig.Int64("mimc_appId")
tokenHandler.AppKey = beego.AppConfig.String("mimc_appKey")
tokenHandler.AppSecret = beego.AppConfig.String("mimc_appSecret")
tokenHandler.AppAccount = appAccount
return tokenHandler
}
// FetchToken ...
func (c *TokenHandler) FetchToken() *string {
jsonBytes, err := json.Marshal(*c)
if err != nil {
return nil
}
requestJSONBodygo := bytes.NewBuffer(jsonBytes).String()
request, err := http.Post(c.httpURL, "application/json", strings.NewReader(requestJSONBodygo))
if err != nil {
return nil
}
defer request.Body.Close()
body, err := ioutil.ReadAll(request.Body)
if err != nil {
return nil
}
token := string(body)
return &token
}
package robotlbrary
func main() {
// robot run
RobotInit()
}
package robotlbrary
import (
"kefu_server/models"
"kefu_server/services"
"strconv"
"github.com/Xiaomi-mimc/mimc-go-sdk"
"github.com/astaxie/beego"
)
// Robots 工作中的机器人
var Robots []*mimc.MCUser
// CreateRobot 创建机器人
func CreateRobot(appAccount string) *mimc.MCUser {
appID, _ := beego.AppConfig.Int64("mimc_appId")
mcUser := mimc.NewUser(uint64(appID), appAccount)
mcUser.RegisterStatusDelegate(NewStatusHandler(appAccount))
mcUser.RegisterTokenDelegate(NewTokenHandler(appAccount))
mcUser.RegisterMessageDelegate(NewMsgHandler(appAccount))
mcUser.InitAndSetup()
return mcUser
}
// GetRobots get robot all
func GetRobots() []models.Robot {
// RobotRepository instance
robotRepository := services.GetRobotRepositoryInstance()
var robots []models.Robot
robots, _ = robotRepository.GetRobots()
return robots
}
// RobotInit 初始化机器人
func RobotInit() {
// 如果有机器人在工作先退出登录
if len(Robots) > 0 {
for _, robot := range Robots {
robot.Logout()
robot.Destory()
}
Robots = []*mimc.MCUser{}
}
robotsData := GetRobots()
var tempRobots []*mimc.MCUser
for _, robot := range robotsData {
if robot.Switch == 1 {
rb := CreateRobot(strconv.FormatInt(robot.ID, 10))
tempRobots = append(tempRobots, rb)
rb.Login()
}
}
Robots = tempRobots
}
......@@ -31,6 +31,7 @@ func init() {
beego.NSNamespace("/auth",
beego.NSRouter("/login", &controllers.AuthController{}, "post:Login"),
beego.NSRouter("/logout", &controllers.AuthController{}, "get:Logout"),
beego.NSRouter("/token", &controllers.AuthController{}, "post:RobotFetchToken"),
),
// public
......
......@@ -14,7 +14,8 @@ import (
type RobotRepositoryInterface interface {
GetRobot(id int64) *models.Robot
GetRobotWithNickName(nickName string) *models.Robot
GetRobotWithOnline(id int64) (*models.Robot, error)
GetRobotWithOnline(platformID int64) (*models.Robot, error)
GetRobotWithRandomOnline() *models.Robot
GetRobots() ([]models.Robot, error)
GetRobotWithInIds(ids ...int64) ([]models.Robot, error)
Delete(id int64) (int64, error)
......@@ -108,10 +109,22 @@ func (r *RobotRepository) GetRobotWithNickName(nickName string) *models.Robot {
return &robot
}
// GetRobotWithRandomOnline get one Robot with Random Online
func (r *RobotRepository) GetRobotWithRandomOnline() (*models.Robot, error) {
var robot *models.Robot
if err := r.q.Filter("switch", 1).One(&robot); err != nil {
logs.Warn("GetRobotWithRandomOnline get one Robot with Random Online------------", err)
return nil, err
}
robot.Artificial = strings.Trim(robot.Artificial, "|")
robot.KeyWord = strings.Trim(robot.KeyWord, "|")
return robot, nil
}
// GetRobotWithOnline get one Robot with Online
func (r *RobotRepository) GetRobotWithOnline(id int64) (*models.Robot, error) {
func (r *RobotRepository) GetRobotWithOnline(platformID int64) (*models.Robot, error) {
var robots []*models.Robot
if _, err := r.q.Filter("platform__in", id, 1).Filter("switch", 1).All(&robots); err != nil {
if _, err := r.q.Filter("platform__in", platformID, 1).Filter("switch", 1).All(&robots); err != nil {
logs.Warn("GetRobotWithRandom get one Robot with Random------------", err)
return nil, err
}
......
package robotlbrary
package utils
import (
"bytes"
......
......@@ -4,6 +4,7 @@ import (
"io/ioutil"
"math/rand"
"net/http"
"net/url"
"strings"
"time"
......@@ -43,10 +44,10 @@ type HTTPResponse struct {
// method post, get 等
// data body 数据
// token 授权token
func HTTPRequest(url string, method string, bodyData string, token string) *HTTPResponse {
func HTTPRequest(path string, method string, bodyData url.Values, token string) *HTTPResponse {
client := &http.Client{}
response := new(HTTPResponse)
req, err := http.NewRequest(method, url, strings.NewReader(bodyData))
req, err := http.NewRequest(method, path, strings.NewReader(bodyData.Encode()))
if err != nil {
response.Code = 500
response.Message = "链接错误"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment