788 lines
24 KiB
Go
788 lines
24 KiB
Go
package event
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/jxstore/financial"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
"github.com/gorilla/websocket"
|
||
)
|
||
|
||
var (
|
||
NoUseEventMap = map[string]string{
|
||
"CreateQrOrBarCode": "CreateQrOrBarCode",
|
||
"StatisticsReportForOrders": "StatisticsReportForOrders",
|
||
"UpdateUser": "UpdateUser",
|
||
}
|
||
regexpToken = regexp.MustCompile(`,"token":".*"`)
|
||
wsClient = &WSClient{}
|
||
//广播频道(通道)
|
||
broadcast = make(chan *model.ImMessageRecord)
|
||
)
|
||
|
||
const (
|
||
sysMessageTitle = "猴儿通知您:"
|
||
)
|
||
|
||
//连接的客户端,吧每个客户端都放进来
|
||
type WSClient struct {
|
||
Clients map[int]map[string]*websocket.Conn
|
||
ClientsHeart map[string]*websocket.Conn
|
||
s *sync.RWMutex
|
||
}
|
||
|
||
func init() {
|
||
clients := make(map[int]map[string]*websocket.Conn)
|
||
clientsHeart := make(map[string]*websocket.Conn)
|
||
wsClient.Clients = clients
|
||
wsClient.ClientsHeart = clientsHeart
|
||
|
||
go handleMessages()
|
||
}
|
||
|
||
//广播推送消息
|
||
func handleMessages() {
|
||
for {
|
||
//读取通道中的消息
|
||
msg := <-broadcast
|
||
if msg.GroupID == 0 {
|
||
// globals.SugarLogger.Debugf("heart %v", utils.Format4Output(msg, false))
|
||
if wsClient.ClientsHeart[msg.UserID] != nil {
|
||
if err := wsClient.ClientsHeart[msg.UserID].WriteJSON(&model.ImMessageRecord{
|
||
Key: "pang",
|
||
}); err != nil {
|
||
globals.SugarLogger.Debugf("heart client.WriteJSON error: %v", err)
|
||
wsClient.ClientsHeart[msg.UserID].Close() //关闭
|
||
delete(wsClient.ClientsHeart, msg.UserID)
|
||
}
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Debugf("clients len %v", len(wsClient.Clients))
|
||
//循环map客户端
|
||
for userID, client := range wsClient.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))
|
||
if msg.CreatedAt == utils.ZeroTimeValue {
|
||
msg.CreatedAt = time.Now()
|
||
}
|
||
err = client.WriteJSON(msg)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("client.WriteJSON error: %v", err)
|
||
client.Close() //关闭
|
||
delete(wsClient.Clients[msg.GroupID], userID)
|
||
// delete(clients, client) //删除map中的客户端
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func ImMessage(userID string, ws *websocket.Conn) (err error) {
|
||
var (
|
||
clientUser = make(map[string]*websocket.Conn)
|
||
db = dao.GetDB()
|
||
)
|
||
//将当前客户端放入map中
|
||
messageGroups, _ := dao.GetUserMessageGroups(dao.GetDB(), userID)
|
||
if len(messageGroups) == 0 {
|
||
return
|
||
}
|
||
wsClient.s.Lock()
|
||
clientUser[userID] = ws
|
||
wsClient.ClientsHeart[userID] = ws
|
||
for _, v := range messageGroups {
|
||
if len(wsClient.Clients[v.GroupID]) > 0 {
|
||
wsClient.Clients[v.GroupID][userID] = ws
|
||
} else {
|
||
wsClient.Clients[v.GroupID] = clientUser
|
||
}
|
||
}
|
||
wsClient.s.Unlock()
|
||
globals.SugarLogger.Debugf("userID :%v ,clients :%v", userID, utils.Format4Output(wsClient.Clients, false))
|
||
|
||
var s *model.ImMessageRecord
|
||
for {
|
||
//接收客户端的消息
|
||
err := ws.ReadJSON(&s)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("页面可能断开啦 ws.ReadJSON error: %v", err.Error())
|
||
for k, _ := range wsClient.Clients {
|
||
delete(wsClient.Clients[k], userID)
|
||
}
|
||
delete(wsClient.ClientsHeart, userID)
|
||
// delete(clients, ws) //删除map中的客户端
|
||
break //结束循环
|
||
} else {
|
||
//接受消息 业务逻辑
|
||
broadcast <- s
|
||
if s.GroupID != 0 {
|
||
if s.GroupID != model.SysGroupID {
|
||
//发聊天消息时,这个组所有的成员包括创建者都在userIDs里
|
||
userIDs := []string{}
|
||
if results, err := dao.GetMessageGroups(db, "", s.GroupID, 0, true, ""); err == nil {
|
||
for _, v := range results {
|
||
userIDs = append(userIDs, v.UserID)
|
||
for _, vv := range v.MessageGroupMembers {
|
||
userIDs = append(userIDs, vv.UserID)
|
||
}
|
||
}
|
||
}
|
||
//如果这些人不在这个组的ws池子里就打上未读标记
|
||
for _, v := range userIDs {
|
||
if wsClient.ClientsHeart[v] == nil {
|
||
messageGroupReads, _ := dao.GetMessageGroupRead(db, v, s.GroupID)
|
||
for _, vv := range messageGroupReads {
|
||
vv.UnReadCount++
|
||
dao.UpdateEntity(db, vv, "UnReadCount")
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if wsClient.ClientsHeart[s.ToUserID] == nil {
|
||
messageGroupReads, _ := dao.GetMessageGroupRead(db, s.ToUserID, s.GroupID)
|
||
for _, vv := range messageGroupReads {
|
||
vv.UnReadCount++
|
||
dao.UpdateEntity(db, vv, "UnReadCount")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
utils.CallFuncAsync(func() {
|
||
if s.GroupID != 0 {
|
||
dao.WrapAddIDCULDEntity(s, "")
|
||
dao.CreateEntity(db, s)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
ws.Close()
|
||
return err
|
||
}
|
||
|
||
func GetOnlineUserCount() (count int) {
|
||
wsClient.s.RLock()
|
||
count = len(wsClient.ClientsHeart)
|
||
wsClient.s.RUnlock()
|
||
return count
|
||
}
|
||
|
||
func AddOperateEvent(ctx *jxcontext.Context, accessUUID, jsonData string, errCode, errMsg string, useTime int, apiFunctionSpec string) (err error) {
|
||
var (
|
||
apiFunction string
|
||
db = dao.GetDB()
|
||
)
|
||
// if ctx.GetRequest() == nil {
|
||
// return nil
|
||
// }
|
||
if apiFunctionSpec == "" {
|
||
url := ctx.GetRequest().URL.Path
|
||
if url != "" {
|
||
apiFunction = url[strings.LastIndex(url, "/")+1 : len(url)]
|
||
}
|
||
} else {
|
||
apiFunction = apiFunctionSpec
|
||
}
|
||
if apiFunction != "" {
|
||
if apiFunction[0:3] == "Get" || NoUseEventMap[apiFunction] != "" {
|
||
return err
|
||
}
|
||
}
|
||
if accessUUID != "" {
|
||
accessUUID = accessUUID[0:strings.Index(accessUUID, ",")]
|
||
}
|
||
jsonData = strings.ReplaceAll(jsonData, regexpToken.FindString(jsonData), "")
|
||
jsonData = utils.LimitUTF8StringLen(jsonData, 3200)
|
||
errMsg = utils.LimitUTF8StringLen(errMsg, 9999)
|
||
event := &model.OperateEvent{
|
||
CreatedAt: time.Now(),
|
||
LastOperator: ctx.GetUserName(),
|
||
APIFunction: apiFunction,
|
||
UserID: ctx.GetUserID(),
|
||
AccessUUID: accessUUID,
|
||
JsonData: jsonData,
|
||
ErrCode: errCode,
|
||
ErrMsg: errMsg,
|
||
UseTime: useTime,
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
err = dao.CreateEntity(db, event)
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func AddOperateEventDetail(db *dao.DaoDB, operateEventDetail *model.OperateEventDetail) (err error) {
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
operateEventDetail.BeforeData = utils.LimitUTF8StringLen(operateEventDetail.BeforeData, 3200)
|
||
operateEventDetail.AfterData = utils.LimitUTF8StringLen(operateEventDetail.AfterData, 3200)
|
||
err = dao.CreateEntity(db, operateEventDetail)
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func DeleteOperateEventAndDetail(ctx *jxcontext.Context, deleteTime time.Time) (err error) {
|
||
db := dao.GetDB()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
dao.DeleteOperateEventDetail(db, deleteTime)
|
||
dao.DeleteOperateEvent(db, deleteTime)
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func GetOperateEvents(ctx *jxcontext.Context, name string, apiFunctions []string, operateTypes, skuIDs, storeIDs []int, fromTime, toTime, keyword string, errType, offset, pageSize int) (pageInfo *model.PagedInfo, err error) {
|
||
var (
|
||
fromTimeP time.Time
|
||
toTimeP time.Time
|
||
)
|
||
db := dao.GetDB()
|
||
if fromTime != "" {
|
||
fromTimeP = utils.Str2Time(fromTime)
|
||
}
|
||
if toTime != "" {
|
||
toTimeP = utils.Str2Time(toTime)
|
||
}
|
||
pageSize = jxutils.FormalizePageSize(pageSize)
|
||
offset = jxutils.FormalizePageOffset(offset)
|
||
operateEventExt, totalCount, err := dao.GetOperateEvents(db, name, apiFunctions, operateTypes, skuIDs, storeIDs, fromTimeP, toTimeP, keyword, errType, offset, pageSize)
|
||
if err != nil {
|
||
return pageInfo, err
|
||
}
|
||
pageInfo = &model.PagedInfo{
|
||
Data: operateEventExt,
|
||
TotalCount: totalCount,
|
||
}
|
||
return pageInfo, err
|
||
}
|
||
|
||
func CreateMessageGroup(ctx *jxcontext.Context, userID, userID2, groupName string, dividePercentage, quitPrice int) (messageGroupResult *dao.GetMessageGroupsResult, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
groupID int
|
||
)
|
||
for {
|
||
groupID = jxutils.GenRand6()
|
||
temp := &model.MessageGroup{
|
||
GroupID: groupID,
|
||
}
|
||
dao.GetEntity(db, temp, "GroupID")
|
||
if temp.UserID == "" {
|
||
break
|
||
}
|
||
}
|
||
if userID2 != "" {
|
||
messageGroups, err := dao.GetMessageGroups(db, userID, 0, model.GroupTypeSingle, true, userID2)
|
||
if len(messageGroups) > 0 && len(messageGroups[0].MessageGroupMembers) > 0 {
|
||
return messageGroups[0], err
|
||
}
|
||
user, err := dao.GetUserByID(db, "user_id", userID2)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if user == nil {
|
||
return nil, fmt.Errorf("无法找到要联系的用户!")
|
||
}
|
||
messageGroup := &model.MessageGroup{
|
||
GroupID: groupID,
|
||
UserID: userID,
|
||
// Name: user.Name,
|
||
Type: model.GroupTypeSingle,
|
||
MaxCount: 2,
|
||
}
|
||
messageGroupMember := &model.MessageGroupMember{
|
||
GroupID: groupID,
|
||
MemberUserID: userID2,
|
||
Type: model.GroupMemberTypeNormal,
|
||
}
|
||
dao.WrapAddIDCULDEntity(messageGroup, ctx.GetUserName())
|
||
dao.WrapAddIDCULDEntity(messageGroupMember, ctx.GetUserName())
|
||
err = dao.CreateEntity(db, messageGroup)
|
||
err = dao.CreateEntity(db, messageGroupMember)
|
||
if err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: groupID,
|
||
UserID: userID,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
messageGroupRead2 := messageGroupRead
|
||
messageGroupRead2.UserID = userID2
|
||
dao.CreateEntity(db, messageGroupRead)
|
||
if err = dao.CreateEntity(db, messageGroupRead2); err == nil {
|
||
if messageGroupReads, err := dao.GetMessageGroupRead(db, userID2, model.SysGroupID); len(messageGroupReads) == 0 && err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: model.SysGroupID,
|
||
UserID: userID2,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
dao.CreateEntity(db, messageGroupRead)
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
userMembers, err := dao.GetUserMember(db, userID, model.MemberTypeNormal)
|
||
messageGroupsResult, err := dao.GetMessageGroups(db, userID, 0, model.GroupTypeMulit, false, "")
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, 0, model.GroupTypeMulit, userID)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if len(userMembers) == 0 {
|
||
return nil, fmt.Errorf("抱歉,只有会员才能创建群聊!")
|
||
}
|
||
if len(messageGroupsResult) > 0 {
|
||
return nil, fmt.Errorf("您已经有群组了,请勿重复创建!群号为:%d", messageGroupsResult[0].GroupID)
|
||
}
|
||
if len(messageGroupMembers) > 0 {
|
||
return nil, fmt.Errorf("您已加入了[%v]群,请先退出后再创建!", messageGroupMembers[0].GroupID)
|
||
}
|
||
messageGroup := &model.MessageGroup{
|
||
GroupID: groupID,
|
||
UserID: userID,
|
||
Name: groupName,
|
||
Type: model.GroupTypeMulit,
|
||
MaxCount: 2000,
|
||
DividePercentage: dividePercentage,
|
||
QuitPrice: quitPrice,
|
||
}
|
||
user, err := dao.GetUserByID(db, "user_id", userID)
|
||
if groupName == "" {
|
||
messageGroup.Name = user.Name + "的集团"
|
||
}
|
||
dao.WrapAddIDCULDEntity(messageGroup, ctx.GetUserName())
|
||
if err = dao.CreateEntity(db, messageGroup); err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: groupID,
|
||
UserID: userID,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
dao.CreateEntity(db, messageGroupRead)
|
||
}
|
||
}
|
||
if err == nil {
|
||
if messageGroupReads, err := dao.GetMessageGroupRead(db, userID, model.SysGroupID); len(messageGroupReads) == 0 && err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: model.SysGroupID,
|
||
UserID: userID,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
dao.CreateEntity(db, messageGroupRead)
|
||
}
|
||
}
|
||
return messageGroupResult, err
|
||
}
|
||
|
||
func GetMessageGroupByUser(ctx *jxcontext.Context, userID string) (messageGroupResult []*dao.GetMessageGroupsResult, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
messageGroups, err := dao.GetMessageGroups(db, "", model.SysGroupID, 0, false, "")
|
||
messageGroups2, err := dao.GetMessageGroups(db, userID, 0, 0, true, "")
|
||
messageGroups = append(messageGroups, messageGroups2...)
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, 0, 0, userID)
|
||
for _, v := range messageGroupMembers {
|
||
if messageGroupList, err := dao.GetMessageGroups(db, "", v.GroupID, 0, false, ""); err == nil {
|
||
messageGroups = append(messageGroups, messageGroupList...)
|
||
}
|
||
}
|
||
for _, v := range messageGroups {
|
||
//是这个人创建的群聊,如果是单聊就返回对方的头像
|
||
if v.Type == model.GroupTypeSingle {
|
||
var userID2 string
|
||
if v.UserID == userID {
|
||
userID2 = v.MessageGroupMembers[0].MemberUserID
|
||
} else {
|
||
userID2 = userID
|
||
}
|
||
if user, err := dao.GetUserByID(db, "user_id", userID2); err == nil {
|
||
v.Avatar = user.Avatar
|
||
v.Name = user.Name
|
||
}
|
||
}
|
||
var (
|
||
imMessageRecord *model.ImMessageRecord
|
||
sql string
|
||
sqlParams = []interface{}{}
|
||
)
|
||
if v.GroupID != model.SysGroupID {
|
||
//最后一条记录和时间和人
|
||
sql = `
|
||
SELECT * FROM im_message_record WHERE group_id = ? ORDER BY created_at DESC LIMIT 1
|
||
`
|
||
sqlParams = append(sqlParams, v.GroupID)
|
||
} else {
|
||
//最后一条记录和时间和人
|
||
sql = `
|
||
SELECT * FROM im_message_record WHERE group_id = ? AND to_user_id = ? ORDER BY created_at DESC LIMIT 1
|
||
`
|
||
sqlParams = append(sqlParams, v.GroupID, userID)
|
||
}
|
||
if err = dao.GetRow(db, &imMessageRecord, sql, sqlParams); err == nil {
|
||
v.LastTime = imMessageRecord.CreatedAt
|
||
v.LastContent = imMessageRecord.Content
|
||
v.LastMessageType = imMessageRecord.MessageType
|
||
if user3, err := dao.GetUserByID(db, "user_id", imMessageRecord.UserID); err == nil {
|
||
v.LastUserName = user3.Name
|
||
}
|
||
} else {
|
||
err = nil
|
||
}
|
||
//该用户各组的未读消息数
|
||
var unReadCount int
|
||
if messageGroupReads, err := dao.GetMessageGroupRead(db, userID, v.GroupID); err == nil && len(messageGroupReads) > 0 {
|
||
for _, vv := range messageGroupReads {
|
||
unReadCount += vv.UnReadCount
|
||
}
|
||
}
|
||
v.UnReadMessageCount = unReadCount
|
||
}
|
||
return messageGroups, err
|
||
}
|
||
|
||
func AddMessageGroup(ctx *jxcontext.Context, groupID int, userID string) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, groupID, 0, userID)
|
||
messageGroupMembers3, err := dao.GetMessageGroupMembers(db, 0, 0, userID)
|
||
messageGroupsResult, err := dao.GetMessageGroups(db, userID, groupID, model.GroupTypeMulit, false, "")
|
||
messageGroupsResult2, err := dao.GetMessageGroups(db, "", groupID, model.GroupTypeMulit, false, "")
|
||
messageGroupsResult3, err := dao.GetMessageGroups(db, userID, 0, model.GroupTypeMulit, false, "")
|
||
messageGroupMembers2, err := dao.GetMessageGroupMembers(db, groupID, 0, "")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if len(messageGroupMembers) > 0 {
|
||
return fmt.Errorf("此用户已经在该群组中了!")
|
||
}
|
||
if len(messageGroupMembers3) > 0 {
|
||
return fmt.Errorf("您已经有群组[%v]了,不能申请加入其它群!", messageGroupMembers3[0].GroupID)
|
||
}
|
||
if len(messageGroupsResult) > 0 {
|
||
return fmt.Errorf("请不要加入自己创建的群!")
|
||
}
|
||
if len(messageGroupsResult2) > 0 && len(messageGroupMembers2) > 0 {
|
||
if len(messageGroupMembers2)+1 > messageGroupsResult2[0].MaxCount {
|
||
return fmt.Errorf("抱歉该群组已经满员了!")
|
||
}
|
||
}
|
||
if len(messageGroupsResult3) > 0 {
|
||
return fmt.Errorf("您已经拥有[%v]群了,不能再加入其它群!", messageGroupsResult3[0].GroupID)
|
||
}
|
||
|
||
messageGroupMember := &model.MessageGroupMember{
|
||
GroupID: groupID,
|
||
MemberUserID: userID,
|
||
Type: model.GroupMemberTypeNormal,
|
||
}
|
||
dao.WrapAddIDCULDEntity(messageGroupMember, ctx.GetUserName())
|
||
if err = dao.CreateEntity(db, messageGroupMember); err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: groupID,
|
||
UserID: userID,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
if err = dao.CreateEntity(db, messageGroupRead); err == nil {
|
||
if messageGroupReads, err := dao.GetMessageGroupRead(db, userID, model.SysGroupID); len(messageGroupReads) == 0 && err == nil {
|
||
messageGroupRead := &model.MessageGroupRead{
|
||
GroupID: model.SysGroupID,
|
||
UserID: userID,
|
||
}
|
||
dao.WrapAddIDCULEntity(messageGroupRead, ctx.GetUserName())
|
||
dao.CreateEntity(db, messageGroupRead)
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func UpdateMessageGroup(ctx *jxcontext.Context, groupID int, payload map[string]interface{}) (num int64, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
messageGroup = &model.MessageGroup{
|
||
GroupID: groupID,
|
||
}
|
||
)
|
||
if err = dao.GetEntity(db, messageGroup, "GroupID"); err != nil {
|
||
return 0, err
|
||
}
|
||
if messageGroup.UserID != ctx.GetUserID() {
|
||
return 0, fmt.Errorf("只有群主才能修改群信息!")
|
||
}
|
||
valid := dao.StrictMakeMapByStructObject(payload, messageGroup, ctx.GetUserName())
|
||
if len(valid) > 0 {
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if num, err = dao.UpdateEntityLogically(db, messageGroup, valid, ctx.GetUserName(), nil); err != nil {
|
||
dao.Rollback(db)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db)
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func DeleteMessageGroup(ctx *jxcontext.Context, groupID int, userID string, flag bool) (errCode string, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
messageGroup = &model.MessageGroup{
|
||
GroupID: groupID,
|
||
}
|
||
)
|
||
if err = dao.GetEntity(db, messageGroup, "GroupID"); err != nil {
|
||
return errCode, err
|
||
}
|
||
//解散群
|
||
if flag {
|
||
if messageGroup.UserID != ctx.GetUserID() {
|
||
return errCode, fmt.Errorf("只有群主才能解散群!")
|
||
}
|
||
messageGroup.DeletedAt = time.Now()
|
||
messageGroup.LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, messageGroup, "DeletedAt", "LastOperator")
|
||
messageGroupMembers, _ := dao.GetMessageGroupMembers(db, groupID, 0, "")
|
||
for _, v := range messageGroupMembers {
|
||
v.DeletedAt = time.Now()
|
||
v.LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, v, "DeletedAt", "LastOperator")
|
||
}
|
||
} else {
|
||
//token中用户与传入user不一致就判定为踢人
|
||
if ctx.GetUserID() != userID {
|
||
if messageGroup.UserID != ctx.GetUserID() {
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, groupID, 0, ctx.GetUserID())
|
||
if err != nil {
|
||
return errCode, err
|
||
}
|
||
if messageGroupMembers[0].Type == model.GroupMemberTypeNormal {
|
||
return errCode, fmt.Errorf("只有创建者和管理员才能踢人!")
|
||
}
|
||
}
|
||
} else {
|
||
quitPrice := messageGroup.QuitPrice
|
||
userBill, err := dao.GetUserBill(db, userID, "")
|
||
userBillGroupMaster, err := dao.GetUserBill(db, messageGroup.UserID, "")
|
||
if err != nil {
|
||
return errCode, err
|
||
}
|
||
if userBill.AccountBalance < quitPrice {
|
||
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("用户余额不足,请充值!")
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
//账户支出
|
||
if err = financial.AddExpendUpdateAccount(db, userBill, model.BillTypeQuitGroup, quitPrice, 0); err != nil {
|
||
dao.Rollback(db)
|
||
return errCode, err
|
||
}
|
||
//群主收到退团金额
|
||
if err = financial.AddIncomeUpdateAccount(db, userBillGroupMaster, model.BillTypeQuitGroup, quitPrice, 0); err != nil {
|
||
dao.Rollback(db)
|
||
return errCode, err
|
||
}
|
||
dao.Commit(db)
|
||
}
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, groupID, 0, userID)
|
||
if err != nil {
|
||
return errCode, err
|
||
}
|
||
messageGroupMembers[0].DeletedAt = time.Now()
|
||
messageGroupMembers[0].LastOperator = ctx.GetUserName()
|
||
dao.UpdateEntity(db, messageGroupMembers[0], "DeletedAt", "LastOperator")
|
||
}
|
||
return errCode, err
|
||
}
|
||
|
||
func TransferMessageGroupMaster(ctx *jxcontext.Context, groupID int, userID string) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
messageGroup = &model.MessageGroup{
|
||
GroupID: groupID,
|
||
}
|
||
)
|
||
if err = dao.GetEntity(db, messageGroup, "GroupID"); err != nil {
|
||
return err
|
||
}
|
||
if messageGroup.UserID != ctx.GetUserID() {
|
||
return fmt.Errorf("只有群主才能转让群主!")
|
||
}
|
||
//群主换成选的那个人
|
||
messageGroup.UserID = userID
|
||
messageGroup.LastOperator = ctx.GetUserName()
|
||
//之前那个群成员换成之前的群主
|
||
messageGroupMembers, err := dao.GetMessageGroupMembers(db, groupID, 0, userID)
|
||
if err != nil && len(messageGroupMembers) == 0 {
|
||
return err
|
||
}
|
||
messageGroupMember := messageGroupMembers[0]
|
||
messageGroupMember.MemberUserID = ctx.GetUserID()
|
||
messageGroupMember.LastOperator = ctx.GetUserName()
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if _, err = dao.UpdateEntity(db, messageGroup, "UserID", "LastOperator"); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
if _, err = dao.UpdateEntity(db, messageGroupMember, "MemberUserID", "LastOperator"); err != nil {
|
||
dao.Rollback(db)
|
||
return err
|
||
}
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func SendSysMessageSimple(content, toUserID string) (err error) {
|
||
return SendSysMessage(jxcontext.AdminCtx, &model.ImMessageRecord{
|
||
Content: sysMessageTitle + " " + content,
|
||
ToUserID: toUserID,
|
||
GroupID: model.SysGroupID,
|
||
MessageType: 1, // 普通文字消息
|
||
})
|
||
}
|
||
|
||
func SendSysMessage(ctx *jxcontext.Context, imMessageRecord *model.ImMessageRecord) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
userID = imMessageRecord.ToUserID
|
||
groupID = imMessageRecord.GroupID
|
||
)
|
||
if groupID != model.SysGroupID {
|
||
return fmt.Errorf("只能给系统组发消息!")
|
||
}
|
||
imMessageRecord.CreatedAt = time.Now()
|
||
imMessageRecord.LastOperator = ctx.GetUserName()
|
||
imMessageRecord.DeletedAt = utils.DefaultTimeValue
|
||
imMessageRecord.UpdatedAt = utils.DefaultTimeValue
|
||
err = dao.CreateEntity(db, imMessageRecord)
|
||
if userID == "" {
|
||
//循环map客户端
|
||
for _, client := range wsClient.Clients[groupID] {
|
||
globals.SugarLogger.Debugf("msg %v", utils.Format4Output(imMessageRecord, false))
|
||
err = client.WriteJSON(imMessageRecord)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("client.WriteJSON error: %v", err)
|
||
client.Close() //关闭
|
||
// delete(wsClient.Clients[msg.GroupID], userID)
|
||
}
|
||
}
|
||
} else {
|
||
client := wsClient.Clients[groupID][userID]
|
||
globals.SugarLogger.Debugf("msg %v", utils.Format4Output(imMessageRecord, false))
|
||
if client == nil {
|
||
return
|
||
}
|
||
err = client.WriteJSON(imMessageRecord)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("client.WriteJSON error: %v", err)
|
||
client.Close() //关闭
|
||
// delete(wsClient.Clients[msg.GroupID], userID)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func DeleteMessageRecord(ctx *jxcontext.Context) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
sql := `
|
||
DELETE FROM im_message_record WHERE created_at < ? AND group_id <> ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
time.Now().AddDate(0, 0, -3), model.SysGroupID,
|
||
}
|
||
_, err = dao.ExecuteSQL(db, sql, sqlParams)
|
||
return err
|
||
}
|
||
|
||
func UpdateUserMessageGroupRead(ctx *jxcontext.Context, reads []*model.MessageGroupRead) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
userID = ctx.GetUserID()
|
||
)
|
||
for _, v := range reads {
|
||
if messageReads, err := dao.GetMessageGroupRead(db, userID, v.GroupID); err == nil {
|
||
if len(messageReads) > 0 {
|
||
messageReads[0].UnReadCount += v.UnReadCount
|
||
dao.UpdateEntity(db, messageReads[0], "UnReadCount")
|
||
} else {
|
||
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
type GetUserStatisticsResult struct {
|
||
RegisterUserCount int `json:"registerUserCount"` //注册数
|
||
OnlineUserCount int `json:"onlineUserCount"` //在线用户数
|
||
ConsumeUserCount int `json:"consumeUserCount"` //消费用户数
|
||
MemberUserCount int `json:"memberUserCount"` //会员用户数
|
||
}
|
||
|
||
func GetUserStatistics(ctx *jxcontext.Context) (getUserStatisticsResult *GetUserStatisticsResult, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
getUserStatisticsResult = &GetUserStatisticsResult{}
|
||
sql := `
|
||
SELECT a.member_user_count, b.consume_user_count FROM
|
||
( SELECT DISTINCT COUNT(a.user_id) member_user_count
|
||
FROM user a
|
||
JOIN user_member b ON a.user_id = b.user_id AND b.deleted_at = ? )a,
|
||
( SELECT DISTINCT COUNT(a.user_id) consume_user_count
|
||
FROM user a
|
||
JOIN ` + "`order`" + `b ON a.user_id = b.user_id AND b.status = ?)b
|
||
`
|
||
sqlParams := []interface{}{
|
||
utils.DefaultTimeValue, model.OrderStatusFinished,
|
||
}
|
||
err = dao.GetRow(db, &getUserStatisticsResult, sql, sqlParams)
|
||
paged, _ := dao.GetUsers2(db, "", "", 0, "", utils.ZeroTimeValue, utils.ZeroTimeValue, 0, nil, nil, 0, -1)
|
||
getUserStatisticsResult.RegisterUserCount = paged.TotalCount
|
||
getUserStatisticsResult.OnlineUserCount = GetOnlineUserCount()
|
||
return getUserStatisticsResult, err
|
||
}
|