Merge branch 'refs/heads/master' into master-pg
This commit is contained in:
commit
7cd3a36d72
|
|
@ -51,6 +51,11 @@ func Init() error {
|
|||
fmt.Println("message table:", err)
|
||||
}
|
||||
|
||||
err = db.AutoMigrate(&File{})
|
||||
if err != nil {
|
||||
fmt.Println("file table:", err)
|
||||
}
|
||||
|
||||
err = db.AutoMigrate(&Group{})
|
||||
if err != nil {
|
||||
fmt.Println("usergroup table:", err)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package dao
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type File struct {
|
||||
gorm.Model
|
||||
// 存储文件名
|
||||
FileStoreName string `gorm:"column:file_store_name;uniqueIndex:idx_file_name"`
|
||||
FileName string `gorm:"column:file_name"`
|
||||
FileSize int `gorm:"column:file_size"`
|
||||
FileType string `gorm:"column:file_type"`
|
||||
FilePath string `gorm:"column:file_path"`
|
||||
AuthID int `gorm:"column:auth_id"`
|
||||
}
|
||||
|
||||
func CreateFile(fileStoreName, fileName, fileType, filePath string, fileSize, authID int) uint {
|
||||
file := File{FileStoreName: fileStoreName, FileName: fileName, FileType: fileType, FilePath: filePath, FileSize: fileSize, AuthID: authID}
|
||||
result := DB.Debug().Create(&file)
|
||||
if result.Error != nil {
|
||||
return 0
|
||||
}
|
||||
return file.ID
|
||||
}
|
||||
|
||||
func DeleteFileByID(id, user int) bool {
|
||||
res := DB.Debug().Model(&File{}).Where("id = ? and auth_id = ?", id, user).Delete(&File{})
|
||||
if res.Error != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FindFileByID(id, auth_id int) File {
|
||||
var file File
|
||||
DB.Debug().Where("id = ? and auth_id = ?", id, auth_id).First(&file)
|
||||
return file
|
||||
}
|
||||
|
||||
func FindFileByNames(fileName string, auth_id int) File {
|
||||
var file File
|
||||
DB.Debug().Where("file_name = ? and auth_id = ?", fileName, auth_id).First(&file)
|
||||
return file
|
||||
}
|
||||
|
||||
func FindFileByAuthID(auth_id int) []File {
|
||||
var files []File
|
||||
DB.Debug().Where("auth_id = ?", auth_id).Find(&files)
|
||||
return files
|
||||
}
|
||||
|
||||
func UpdateFileByID(id, auth_id int, fileStoreName, fileName, fileType, filePath string, fileSize int) bool {
|
||||
pd := FindFileByID(id, auth_id)
|
||||
if pd.ID == 0 {
|
||||
return false
|
||||
}
|
||||
result := DB.Debug().Model(&File{}).Where("id = ? and auth_id = ?", id, auth_id).Updates(File{FileStoreName: fileStoreName, FileName: fileName, FileType: fileType, FilePath: filePath, FileSize: fileSize})
|
||||
if result.Error != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
37
dao/im.go
37
dao/im.go
|
|
@ -78,6 +78,18 @@ func GetMsgGroupByIndex(group_id, index int) ([]GroupMessage, error) {
|
|||
|
||||
}
|
||||
|
||||
func GetGroupRequestUsers(user_id int) []FriendRequest {
|
||||
var users []FriendRequest
|
||||
DB.Debug().Raw("select id,im_id,name,email FROM (SELECT im_id,from_user_id,group_id FROM (( SELECT id as im_id,from_user_id,group_id FROM messages WHERE type=? and status=? ) as m JOIN groups as g on g.id=m.group_id ) where g.auth_id=? ) as e JOIN users as u ON e.from_user_id=u.id", proto.MSG_TYPE_GROUP_INVI, 0, user_id).Scan(&users)
|
||||
return users
|
||||
}
|
||||
|
||||
func GetMsgUserGroupReq(from_user_id, group_id int) ([]Message, error) {
|
||||
var msgs []Message
|
||||
res := DB.Debug().Where("from_user_id = ? and group_id = ? and type = ? and status = ?", from_user_id, group_id, 5, 0).Find(&msgs)
|
||||
return msgs, res.Error
|
||||
}
|
||||
|
||||
// 获取邀请消息
|
||||
func GetFriendGroupReq(user_id int) ([]Message, error) {
|
||||
var msgs []Message
|
||||
|
|
@ -193,6 +205,25 @@ func QuitGroup(group_id, user_id int) error {
|
|||
return res.Error
|
||||
}
|
||||
|
||||
// 根据群id查找群
|
||||
func FindGroup(group_id int) []Group {
|
||||
var groups []Group
|
||||
DB.Debug().Where("id = ?", group_id).Find(&groups)
|
||||
return groups
|
||||
}
|
||||
|
||||
// 删除群聊
|
||||
func DeleteGroup(group_id int, auth_id int) error {
|
||||
res := DB.Debug().Delete(&Group{}, "id = ? and auth_id = ?", group_id, auth_id)
|
||||
return res.Error
|
||||
}
|
||||
|
||||
// 删除群里的用户
|
||||
func DeleteGroupUsers(group_id int) error {
|
||||
res := DB.Debug().Delete(&GroupUser{}, "group_id = ?", group_id)
|
||||
return res.Error
|
||||
}
|
||||
|
||||
func FindFriend(from_user_id, to_user_id int) []Friend {
|
||||
var friends []Friend
|
||||
DB.Debug().Where("user_id = ? and friend_id = ?", from_user_id, to_user_id).Find(&friends)
|
||||
|
|
@ -252,3 +283,9 @@ func FindGroupUsers(group_id int) []GroupUser {
|
|||
DB.Debug().Where("group_id = ?", group_id).Find(&groupUsers)
|
||||
return groupUsers
|
||||
}
|
||||
|
||||
func FindGroupByNameLike(groupName string) []Group {
|
||||
var groups []Group
|
||||
DB.Debug().Where("group_name like ?", "%"+groupName+"%").Limit(20).Find(&groups)
|
||||
return groups
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ type User struct {
|
|||
Role string `gorm:"column:role"`
|
||||
Redis bool `gorm:"column:redis"`
|
||||
Run bool `gorm:"column:run"`
|
||||
Upload bool `gorm:"column:upload"`
|
||||
CreateTime string `gorm:"column:create_time"`
|
||||
UpdateTime string `gorm:"column:update_time"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ func SetUpIMGroup(router *gin.Engine) {
|
|||
imGroup.POST("/accept_invite", AcceptInvite)
|
||||
imGroup.POST("/create_group", CreateGroup)
|
||||
imGroup.POST("/get_group", GetGroups)
|
||||
imGroup.POST("/get_group_req_user", GetFriendRequest)
|
||||
imGroup.GET("/sse_msg", ServerSendMsg)
|
||||
imGroup.GET("/ws_v2", ServerSsendMsgV2)
|
||||
imGroup.POST("/get_friend_list", GetFriendList) //获取好友列表,包括群聊
|
||||
|
|
@ -112,12 +113,25 @@ func DelFriendOrGroup(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, gin.H{"error": "parameter error", "code": proto.ParameterError, "message": "failed"})
|
||||
return
|
||||
}
|
||||
//退出群聊
|
||||
err2 := service.QuitGroupService(cid, req.GroupID)
|
||||
if err2 == nil {
|
||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "message": "success"})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{"error": err2.Error(), "code": proto.OperationFailed, "message": "failed"})
|
||||
}
|
||||
} else if req.Type == 3 {
|
||||
//群主解散群
|
||||
if req.GroupID == 0 {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "parameter error", "code": proto.ParameterError, "message": "failed"})
|
||||
return
|
||||
}
|
||||
err2 := service.DelGroupService(cid, req.GroupID)
|
||||
if err2 == nil {
|
||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "message": "success"})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{"error": err2.Error(), "code": proto.OperationFailed, "message": "failed"})
|
||||
}
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "parameter error", "code": proto.ParameterError, "message": "failed"})
|
||||
}
|
||||
|
|
@ -162,10 +176,22 @@ func GetMessage(c *gin.Context) {
|
|||
}
|
||||
|
||||
func GetFriendRequest(c *gin.Context) {
|
||||
var req Message
|
||||
id, _ := c.Get("id")
|
||||
user_id := int(id.(float64))
|
||||
data := service.GetFriendRequest(user_id)
|
||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "data": data, "message": "success"})
|
||||
|
||||
if err := c.ShouldBind(&req); err == nil {
|
||||
if req.Type == 1 {
|
||||
data := service.GetGroupRequestUsers(user_id)
|
||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "data": data, "message": "success"})
|
||||
} else {
|
||||
data := service.GetFriendRequest(user_id)
|
||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "data": data, "message": "success"})
|
||||
}
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{"error": err.Error(), "code": proto.ParameterError, "message": "failed"})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func CreateGroup(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,66 @@ func SetUpToolGroup(router *gin.Engine) {
|
|||
toolGroup := router.Group("/tool")
|
||||
toolGroup.POST("/set_redis", SetRedis)
|
||||
toolGroup.POST("/get_redis", GetRedis)
|
||||
|
||||
//文件上传、下载
|
||||
toolGroup.POST("/upload", UploadFile)
|
||||
toolGroup.GET("/download/:filename", DownloadFile)
|
||||
}
|
||||
|
||||
func UploadFile(c *gin.Context) {
|
||||
//先查看是否有权限
|
||||
id, _ := c.Get("id")
|
||||
id1 := int(id.(float64))
|
||||
//从请求头获取upload_type
|
||||
uploadType := c.GetHeader("upload_type")
|
||||
if uploadType == "" {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "upload_type is empty", "code": proto.ParameterError, "message": "failed"})
|
||||
return
|
||||
}
|
||||
|
||||
user := dao.FindUserByUserID(id1)
|
||||
if user.Upload == false {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "no upload Permissions", "code": proto.NoUploadPermissions, "message": "failed"})
|
||||
return
|
||||
}
|
||||
//上传文件
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "upload file failed", "code": proto.UploadFileFailed, "message": "failed"})
|
||||
return
|
||||
}
|
||||
|
||||
//保存文件
|
||||
filePath, fileStoreName, err := service.SaveFile(file, uploadType)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "save file failed", "code": proto.SaveFileFailed, "message": "failed"})
|
||||
return
|
||||
}
|
||||
//保存文件信息
|
||||
fileSize := int(file.Size)
|
||||
fileName := file.Filename
|
||||
fileType := file.Header.Get("file_type")
|
||||
fileID := dao.CreateFile(fileStoreName, fileName, fileType, filePath, fileSize, id1)
|
||||
if fileID == 0 {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "save file info failed", "code": proto.SaveFileInfoFailed, "message": "failed"})
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func DownloadFile(c *gin.Context) {
|
||||
//参数
|
||||
filename := c.Param("filename")
|
||||
//file_id, _ := strconv.Atoi(c.Query("id"))
|
||||
id, _ := c.Get("id")
|
||||
//查询文件信息
|
||||
file := dao.FindFileByNames(filename, int(id.(float64)))
|
||||
if file.ID == 0 {
|
||||
c.JSON(http.StatusOK, gin.H{"error": "file not found", "code": proto.FileNotFound, "message": "failed"})
|
||||
return
|
||||
}
|
||||
//下载文件
|
||||
c.File(file.FilePath + file.FileStoreName)
|
||||
}
|
||||
|
||||
func SetRedis(c *gin.Context) {
|
||||
|
|
|
|||
|
|
@ -194,11 +194,13 @@ func SearchHandler(c *gin.Context) {
|
|||
if err := c.ShouldBind(&req_data); err == nil {
|
||||
if req_data.ID != -1 {
|
||||
user := service.GetUserByID(req_data.ID)
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": user})
|
||||
group := service.GetGroupByID(req_data.ID)
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": user, "group": group})
|
||||
return
|
||||
} else if req_data.Keyword != "" {
|
||||
users := service.GetUserByNameLike(req_data.Keyword)
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": users})
|
||||
groups := service.GetGroupByNameLike(req_data.Keyword)
|
||||
c.JSON(200, gin.H{"code": proto.SuccessCode, "message": "success", "data": users, "group": groups})
|
||||
return
|
||||
} else {
|
||||
c.JSON(200, gin.H{"code": proto.ParameterError, "message": "error", "data": "无ID 与 关键字"})
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ const (
|
|||
|
||||
// 以下是持续集成、部署的配置
|
||||
CID_BASE_DIR = "/home/lijun/cid/"
|
||||
|
||||
// 以下是文件上传的配置
|
||||
FILE_BASE_DIR = "/home/lijun/file/"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -39,6 +42,13 @@ const (
|
|||
MSG_STATUS_UNREAD = 0 // 未读
|
||||
)
|
||||
|
||||
const (
|
||||
//文件上传类型
|
||||
File_TYPE = 1 // 通用文件
|
||||
//用于视频解析
|
||||
Video_TYPE = 2 // 视频文件
|
||||
)
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
Name string `gorm:"column:name"`
|
||||
|
|
|
|||
|
|
@ -49,4 +49,12 @@ const (
|
|||
|
||||
//消息错误码
|
||||
MsgSendFailed = 61 // 消息发送失败
|
||||
|
||||
//文件错误码
|
||||
FileNotFound = 71 // 文件不存在
|
||||
FileUploadFailed = 72 // 文件上传失败
|
||||
SaveFileInfoFailed = 73 // 保存文件信息失败
|
||||
SaveFileFailed = 74 // 保存文件失败
|
||||
UploadFileFailed = 75 // 上传文件失败
|
||||
NoUploadPermissions = 76 // 无上传权限
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
"videoplayer/proto"
|
||||
"videoplayer/worker"
|
||||
)
|
||||
|
||||
// 检查path是否存在当前日期文件夹如(2024-08-09),不存在则path下当前日期文件夹创建,存在则返回
|
||||
func getFilePath(path string) string {
|
||||
//当前日期,格式为2024-08-09
|
||||
date := time.Now().Format("2006-01-02")
|
||||
//拼接文件路径
|
||||
filePath := path + "/" + date
|
||||
//判断文件夹是否存在
|
||||
_, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
//不存在则创建
|
||||
os.MkdirAll(filePath, os.ModePerm)
|
||||
}
|
||||
return filePath
|
||||
}
|
||||
|
||||
func SaveFile(file *multipart.FileHeader, uploadType string) (string, string, error) {
|
||||
//获取文件后缀
|
||||
fileSuffix := path.Ext(file.Filename)
|
||||
//生成文件名
|
||||
fileStoreName := uuid.NewString() + fileSuffix
|
||||
//生成文件路径
|
||||
path_ := getFilePath(proto.FILE_BASE_DIR)
|
||||
filePath := path_ + "/" + fileStoreName
|
||||
|
||||
//保存文件file
|
||||
dst, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
// 复制文件内容
|
||||
file_, err := file.Open()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
_, err = io.Copy(dst, file_)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if uploadType == "2" {
|
||||
worker.PushRedisList("video_need_handle", filePath)
|
||||
}
|
||||
|
||||
return path_, fileStoreName, nil
|
||||
}
|
||||
|
|
@ -66,6 +66,17 @@ func CreateGeneralMessageService(from_id, to_id, msg_type, group_id int, content
|
|||
err, id = dao.CreateGeneralMessage(from_id, to_id, msg_type, 0, group_id, content)
|
||||
case proto.MSG_TYPE_GROUP_ADD:
|
||||
//加入群聊请求
|
||||
//判断是否在群里
|
||||
groupUser := dao.FindGroupUser(from_id, group_id)
|
||||
if len(groupUser) > 0 {
|
||||
return errors.New("已在群里"), 0
|
||||
}
|
||||
//查看是否已经发送过请求
|
||||
res, _ := dao.GetMsgUserGroupReq(from_id, group_id)
|
||||
if len(res) > 0 {
|
||||
return errors.New("已发送请求"), res[0].ID
|
||||
}
|
||||
err, id = dao.CreateGeneralMessage(from_id, to_id, msg_type, 0, group_id, content)
|
||||
|
||||
case proto.MSG_TYPE_GROUP_INVI:
|
||||
//邀请加群,直接加入
|
||||
|
|
@ -110,6 +121,9 @@ func GetMsgUserByIndexService(from_id, to_id, index, msq_type, from_user_id, gro
|
|||
func AddFriendService(id, from_user_id, to_user_id int) error {
|
||||
// 业务逻辑
|
||||
res := dao.FindMessageByID(uint(id))
|
||||
if len(res) == 0 {
|
||||
return errors.New("no such message")
|
||||
}
|
||||
if res[0].FromUserID == to_user_id && res[0].ToUserID == from_user_id {
|
||||
friend := dao.FindFriend(from_user_id, to_user_id)
|
||||
if len(friend) > 0 {
|
||||
|
|
@ -179,9 +193,41 @@ func QuitGroupService(user_id, group_id int) error {
|
|||
err := dao.QuitGroup(group_id, user_id)
|
||||
return err
|
||||
}
|
||||
func DelGroupService(user_id, group_id int) error {
|
||||
//查找群聊
|
||||
groups := dao.FindGroup(group_id)
|
||||
if len(groups) == 0 {
|
||||
return errors.New("no such group")
|
||||
}
|
||||
if groups[0].AuthID != user_id {
|
||||
return errors.New("no permission")
|
||||
}
|
||||
//删除群聊
|
||||
err := dao.DeleteGroup(group_id, user_id)
|
||||
err = dao.DeleteGroupUsers(group_id)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetGroups(user_id int) []dao.Group {
|
||||
//获取群聊
|
||||
groups := dao.GetGroups(user_id)
|
||||
return groups
|
||||
}
|
||||
|
||||
func GetGroupByID(group_id int) []dao.Group {
|
||||
//获取群聊
|
||||
groups := dao.FindGroupByID(group_id)
|
||||
return groups
|
||||
}
|
||||
|
||||
func GetGroupByNameLike(name string) []dao.Group {
|
||||
//获取群聊
|
||||
groups := dao.FindGroupByNameLike(name)
|
||||
return groups
|
||||
}
|
||||
|
||||
func GetGroupRequestUsers(user_id int) []dao.FriendRequest {
|
||||
//获取群聊请求
|
||||
users := dao.GetGroupRequestUsers(user_id)
|
||||
return users
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ func InitRedis() error {
|
|||
ctx := context.Background()
|
||||
// 连接redis
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
Addr: proto.REDIS_ADDR, // Redis 服务器地址
|
||||
//Password: proto.REDIS_PASSWORD, // 如果 Redis 设置了密码
|
||||
DB: proto.REIDS_DB, // 使用的数据库编号
|
||||
Addr: proto.REDIS_ADDR, // Redis 服务器地址
|
||||
Password: proto.REDIS_PASSWORD, // 如果 Redis 设置了密码
|
||||
DB: proto.REIDS_DB, // 使用的数据库编号
|
||||
})
|
||||
|
||||
// 验证 Redis 客户端是否可以正常工作
|
||||
|
|
|
|||
Loading…
Reference in New Issue