308 lines
11 KiB
Go
308 lines
11 KiB
Go
package controllers
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"net/http"
|
||
"path"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxstore/event"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||
"git.rosy.net.cn/jx-callback/globals/api"
|
||
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
|
||
"github.com/gorilla/websocket"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
|
||
"github.com/astaxie/beego"
|
||
)
|
||
|
||
// 操作事件明细相关API
|
||
type EventController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
//连接的客户端,吧每个客户端都放进来
|
||
var clients = make(map[int]map[string]*websocket.Conn)
|
||
|
||
//广播频道(通道)
|
||
var broadcast = make(chan *model.ImMessageRecord)
|
||
|
||
// 配置升级程序(升级为websocket)
|
||
var upgrader = websocket.Upgrader{}
|
||
|
||
// 定义我们的消息对象
|
||
type Message struct {
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
// @Title 得到微信小程序码
|
||
// @Description 得到微信小程序码
|
||
// @Param token header string true "认证token"
|
||
// @Param scene formData string true "最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)"
|
||
// @Param page formData string false "必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /GetWeixinUnlimited [post]
|
||
func (c *EventController) GetWeixinUnlimited() {
|
||
c.callGetWeixinUnlimited(func(params *tEventGetWeixinUnlimitedParams) (retVal interface{}, errCode string, err error) {
|
||
// api.WeixinMiniAPI2.CBRetrieveToken()
|
||
result, err := api.WeixinMiniAPI2.GetUnlimited(params.Scene, params.Page)
|
||
if err != nil || result == nil {
|
||
return retVal, "", err
|
||
}
|
||
fileName := "wxcode" + utils.Int64ToStr(time.Now().Unix()) + ".jpg"
|
||
retVal, err = jxutils.UploadExportContent([]byte(result["fakeData"].(string)), fileName)
|
||
// tasks.RefreshWeixinToken()
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 测试websocket
|
||
// @Description 测试websocket
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /TestWebsocket [get]
|
||
func (c *EventController) TestWebsocket() {
|
||
// 解决跨域问题(微信小程序)
|
||
upgrader.CheckOrigin = func(r *http.Request) bool {
|
||
return true
|
||
}
|
||
//升级将HTTP服务器连接升级到WebSocket协议。
|
||
//responseHeader包含在对客户端升级的响应中
|
||
//请求。使用responseHeader指定Cookie(设置Cookie)和
|
||
//应用程序协商的子目录(Sec WebSocket协议)。
|
||
//如果升级失败,则升级将向客户端答复一个HTTP错误
|
||
ws, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
defer ws.Close()
|
||
var (
|
||
userID = c.GetString("userID")
|
||
clientUser = make(map[string]*websocket.Conn)
|
||
)
|
||
//将当前客户端放入map中
|
||
messageGroups, _ := dao.GetUserMessageGroups(dao.GetDB(), userID)
|
||
if len(messageGroups) == 0 {
|
||
return
|
||
}
|
||
clientUser[userID] = ws
|
||
for _, v := range messageGroups {
|
||
if len(clients[v.GroupID]) > 0 {
|
||
clients[v.GroupID][userID] = ws
|
||
} else {
|
||
clients[v.GroupID] = clientUser
|
||
}
|
||
}
|
||
db := dao.GetDB()
|
||
if globals.IsProductEnv() {
|
||
_, _, err = jxcontext.New(nil, c.GetString("token"), c.Ctx.ResponseWriter, c.Ctx.Request)
|
||
if err != nil {
|
||
msg := &CallResult{
|
||
Code: model.ErrCodeGeneralFailed,
|
||
Desc: err.Error(),
|
||
}
|
||
ws.WriteJSON(&msg)
|
||
}
|
||
globals.SugarLogger.Debugf("TestWebsocket connection...")
|
||
}
|
||
globals.SugarLogger.Debugf("userID :%v ,clients :%v", userID, utils.Format4Output(clients, false))
|
||
c.EnableRender = false //Beego不启用渲染
|
||
|
||
var s *model.ImMessageRecord
|
||
for {
|
||
//接收客户端的消息
|
||
err := ws.ReadJSON(&s)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("页面可能断开啦 ws.ReadJSON error: %v", err.Error())
|
||
for k, _ := range clients {
|
||
delete(clients[k], userID)
|
||
}
|
||
// delete(clients, ws) //删除map中的客户端
|
||
break //结束循环
|
||
} else {
|
||
//接受消息 业务逻辑
|
||
broadcast <- s
|
||
utils.CallFuncAsync(func() {
|
||
dao.WrapAddIDCULDEntity(s, "")
|
||
dao.CreateEntity(db, s)
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
go handleMessages()
|
||
}
|
||
|
||
//广播推送消息
|
||
func handleMessages() {
|
||
for {
|
||
//读取通道中的消息
|
||
msg := <-broadcast
|
||
globals.SugarLogger.Debugf("clients len %v", len(clients))
|
||
//循环map客户端
|
||
for userID, client := range clients[msg.GroupID] {
|
||
//把通道中的消息发送给客户端
|
||
user, err := dao.GetUser(dao.GetDB(), msg.UserID)
|
||
if err == nil {
|
||
msg.UserInfo = user
|
||
}
|
||
globals.SugarLogger.Debugf("msg %v", utils.Format4Output(msg, false))
|
||
err = client.WriteJSON(msg)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("client.WriteJSON error: %v", err)
|
||
client.Close() //关闭
|
||
delete(clients[msg.GroupID], userID)
|
||
// delete(clients, client) //删除map中的客户端
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// @Title 查询聊天记录
|
||
// @Description 查询聊天记录
|
||
// @Param token header string true "认证token"
|
||
// @Param groupID query int true "组ID"
|
||
// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)"
|
||
// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /GetImMessageRecord [get]
|
||
func (c *EventController) GetImMessageRecord() {
|
||
c.callGetImMessageRecord(func(params *tEventGetImMessageRecordParams) (retVal interface{}, errCode string, err error) {
|
||
retVal, err = dao.GetImMessageRecord(dao.GetDB(), params.GroupID, "", 0, -1, params.Offset, params.PageSize)
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 创建聊天组
|
||
// @Description 创建聊天组
|
||
// @Param token header string true "认证token"
|
||
// @Param userID formData string true "创建者id"
|
||
// @Param userID2 formData string false "被拉的id 如果userID2为空就默认为是创建的群聊"
|
||
// @Param name formData string false "如果是群聊,则要传入群名"
|
||
// @Param dividePercentage formData int false "如果是群聊,则要传入分成比例"
|
||
// @Param quitPrice formData int false "如果是群聊,则要传入退团金额"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /CreateMessageGroup [post]
|
||
func (c *EventController) CreateMessageGroup() {
|
||
c.callCreateMessageGroup(func(params *tEventCreateMessageGroupParams) (retVal interface{}, errCode string, err error) {
|
||
retVal, err = event.CreateMessageGroup(params.Ctx, params.UserID, params.UserID2, params.Name, params.DividePercentage, params.QuitPrice)
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 查询某个用户所有聊天组
|
||
// @Description 查询某个用户所有聊天组
|
||
// @Param token header string true "认证token"
|
||
// @Param userID query string true "userid"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /GetMessageGroupByUser [get]
|
||
func (c *EventController) GetMessageGroupByUser() {
|
||
c.callGetMessageGroupByUser(func(params *tEventGetMessageGroupByUserParams) (retVal interface{}, errCode string, err error) {
|
||
retVal, err = event.GetMessageGroupByUser(params.Ctx, params.UserID)
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 查询聊天组
|
||
// @Description 查询聊天组
|
||
// @Param token header string true "认证token"
|
||
// @Param groupID query int true "groupID"
|
||
// @Param isMember query bool true "是否查询组员"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /GetMessageGroups [get]
|
||
func (c *EventController) GetMessageGroups() {
|
||
c.callGetMessageGroups(func(params *tEventGetMessageGroupsParams) (retVal interface{}, errCode string, err error) {
|
||
retVal, err = dao.GetMessageGroups(dao.GetDB(), "", params.GroupID, model.GroupTypeMulit, params.IsMember, "")
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 加入用户组
|
||
// @Description 加入用户组
|
||
// @Param token header string true "认证token"
|
||
// @Param groupID formData int true "组号"
|
||
// @Param userID formData string true "被邀请人ID"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /AddMessageGroup [post]
|
||
func (c *EventController) AddMessageGroup() {
|
||
c.callAddMessageGroup(func(params *tEventAddMessageGroupParams) (retVal interface{}, errCode string, err error) {
|
||
err = event.AddMessageGroup(params.Ctx, params.GroupID, params.UserID)
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 修改群组信息
|
||
// @Description 修改群组信息
|
||
// @Param token header string true "认证token"
|
||
// @Param groupID formData int true "组号"
|
||
// @Param payload formData string true "群组 payload"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /UpdateMessageGroup [put]
|
||
func (c *EventController) UpdateMessageGroup() {
|
||
c.callUpdateMessageGroup(func(params *tEventUpdateMessageGroupParams) (retVal interface{}, errCode string, err error) {
|
||
payload := make(map[string]interface{})
|
||
if err = utils.UnmarshalUseNumber([]byte(params.Payload), &payload); err == nil {
|
||
retVal, err = event.UpdateMessageGroup(params.Ctx, params.GroupID, payload)
|
||
}
|
||
return retVal, "", err
|
||
})
|
||
}
|
||
|
||
// @Title 退出用户组(踢人)
|
||
// @Description 退出用户组(踢人)
|
||
// @Param token header string true "认证token"
|
||
// @Param groupID formData int true "组号"
|
||
// @Param userID formData string true "userID"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /DeleteMessageGroup [delete]
|
||
func (c *EventController) DeleteMessageGroup() {
|
||
c.callDeleteMessageGroup(func(params *tEventDeleteMessageGroupParams) (retVal interface{}, errCode string, err error) {
|
||
errCode, err = event.DeleteMessageGroup(params.Ctx, params.GroupID, params.UserID)
|
||
return retVal, errCode, err
|
||
})
|
||
}
|
||
|
||
// @Title 上传图片
|
||
// @Description 上传图片
|
||
// @Param token header string true "认证token"
|
||
// @Success 200 {object} controllers.CallResult
|
||
// @Failure 200 {object} controllers.CallResult
|
||
// @router /UploadImg [post]
|
||
func (c *EventController) UploadImg() {
|
||
c.callUploadImg(func(params *tEventUploadImgParams) (retVal interface{}, errCode string, err error) {
|
||
file, head, err := c.GetFile("rsmImg")
|
||
defer file.Close()
|
||
if head.Size > 1024*1024*5 {
|
||
err = fmt.Errorf("图片太大,请重新选择!")
|
||
}
|
||
if path.Ext(head.Filename) != ".jpg" && path.Ext(head.Filename) != ".png" {
|
||
err = fmt.Errorf("不支持的图片格式,请重新选择!")
|
||
}
|
||
if err != nil {
|
||
return retVal, "", err
|
||
}
|
||
fileName := utils.GetUUID() + "_" + time.Now().Format("20060102") + path.Ext(head.Filename)
|
||
c.SaveToFile("rsmImg", "/jxdata/static/img/"+fileName)
|
||
return "http://139.155.88.29/img/" + fileName, "", err
|
||
})
|
||
}
|