add 站内通知、私信、websocket服务
This commit is contained in:
parent
8efecfb712
commit
1ddb117172
133
api/v1/system/sys_notice.go
Normal file
133
api/v1/system/sys_notice.go
Normal file
@ -0,0 +1,133 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成api操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: api/v1/system/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告相关参数
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
// SysNoticeSearchReq 分页请求参数
|
||||
type SysNoticeSearchReq struct {
|
||||
g.Meta `path:"/list" tags:"通知私信" method:"get" summary:"通知公告列表(管理)"`
|
||||
commonApi.Author
|
||||
model.SysNoticeSearchReq
|
||||
}
|
||||
|
||||
// SysNoticeSearchRes 列表返回结果
|
||||
type SysNoticeSearchRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeSearchRes
|
||||
}
|
||||
|
||||
// SysNoticeSearchReq 分页请求参数
|
||||
type SysNoticeShowSearchReq struct {
|
||||
g.Meta `path:"/listShow" tags:"通知私信" method:"get" summary:"通知公告列表(浏览)"`
|
||||
commonApi.Author
|
||||
model.SysNoticeSearchReq
|
||||
}
|
||||
|
||||
// SysNoticeSearchRes 列表返回结果
|
||||
type SysNoticeShowSearchRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeSearchRes
|
||||
}
|
||||
|
||||
// SysNoticeAddReq 添加操作请求参数
|
||||
type SysNoticeAddReq struct {
|
||||
g.Meta `path:"/add" tags:"通知私信" method:"post" summary:"通知公告添加"`
|
||||
commonApi.Author
|
||||
*model.SysNoticeAddReq
|
||||
}
|
||||
|
||||
// SysNoticeAddRes 添加操作返回结果
|
||||
type SysNoticeAddRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
// SysNoticeEditReq 修改操作请求参数
|
||||
type SysNoticeEditReq struct {
|
||||
g.Meta `path:"/edit" tags:"通知私信" method:"put" summary:"通知公告修改"`
|
||||
commonApi.Author
|
||||
*model.SysNoticeEditReq
|
||||
}
|
||||
|
||||
// SysNoticeEditRes 修改操作返回结果
|
||||
type SysNoticeEditRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
// SysNoticeGetReq 获取一条数据请求
|
||||
type SysNoticeGetReq struct {
|
||||
g.Meta `path:"/get" tags:"通知私信" method:"get" summary:"获取通知公告信息"`
|
||||
commonApi.Author
|
||||
Id int64 `p:"id" v:"required#主键必须"` //通过主键获取
|
||||
}
|
||||
|
||||
// SysNoticeGetRes 获取一条数据结果
|
||||
type SysNoticeGetRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeInfoRes
|
||||
}
|
||||
|
||||
// SysNoticeDeleteReq 删除数据请求
|
||||
type SysNoticeDeleteReq struct {
|
||||
g.Meta `path:"/delete" tags:"通知私信" method:"delete" summary:"删除通知公告"`
|
||||
commonApi.Author
|
||||
Ids []int64 `p:"ids" v:"required#主键必须"` //通过主键删除
|
||||
}
|
||||
|
||||
// SysNoticeDeleteRes 删除数据返回
|
||||
type SysNoticeDeleteRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
type SysNoticeIndexDataReq struct {
|
||||
g.Meta `path:"getIndexData" tags:"通知私信" method:"get" summary:"获取首页通知预览数据"`
|
||||
commonApi.Author
|
||||
}
|
||||
type SysNoticeIndexDataRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeIndexRes
|
||||
}
|
||||
type SysNoticeUnReadCountReq struct {
|
||||
g.Meta `path:"unReadCount" tags:"通知私信" method:"get" summary:"获取未读数量"`
|
||||
commonApi.Author
|
||||
}
|
||||
type SysNoticeUnReadCountRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeUnreadCount
|
||||
}
|
||||
|
||||
// SysNoticeShowSearchReq 通知展示分页请求参数
|
||||
type SysNoticeUserSearchReq struct {
|
||||
g.Meta `path:"/userList" tags:"通知私信" method:"get" summary:"获取待指定的用户"`
|
||||
commonApi.Author
|
||||
UserNickName string `p:"userNickname"`
|
||||
}
|
||||
|
||||
// SysNoticeSearchRes 通知展示列表返回结果
|
||||
type SysNoticeUserSearchRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
UserList []*model.SysNoticeUserNickname `json:"userList"`
|
||||
}
|
||||
|
||||
// SysNoticeShowSearchReq 通知展示分页请求参数
|
||||
type SysNoticeUserReadReq struct {
|
||||
g.Meta `path:"/userList" tags:"通知私信" method:"get" summary:"获取待指定的用户"`
|
||||
commonApi.Author
|
||||
string `p:"userNickName"`
|
||||
}
|
||||
|
||||
// SysNoticeSearchRes 通知展示列表返回结果
|
||||
type SysNoticeUserReadRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
90
api/v1/system/sys_notice_read.go
Normal file
90
api/v1/system/sys_notice_read.go
Normal file
@ -0,0 +1,90 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成api操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: api/v1/system/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录相关参数
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
// SysNoticeReadSearchReq 分页请求参数
|
||||
type SysNoticeReadSearchReq struct {
|
||||
g.Meta `path:"/list" tags:"已读记录" method:"get" summary:"已读记录列表"`
|
||||
commonApi.Author
|
||||
model.SysNoticeReadSearchReq
|
||||
}
|
||||
|
||||
// SysNoticeReadSearchRes 列表返回结果
|
||||
type SysNoticeReadSearchRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeReadSearchRes
|
||||
}
|
||||
|
||||
// SysNoticeReadAddReq 添加操作请求参数
|
||||
type SysNoticeReadAddReq struct {
|
||||
g.Meta `path:"/add" tags:"已读记录" method:"post" summary:"已读记录添加"`
|
||||
commonApi.Author
|
||||
*model.SysNoticeReadAddReq
|
||||
}
|
||||
|
||||
// SysNoticeReadAddRes 添加操作返回结果
|
||||
type SysNoticeReadAddRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
// SysNoticeReadAddReq 添加操作请求参数
|
||||
type SysNoticeReadNoticeAddReq struct {
|
||||
g.Meta `path:"/readNotice" tags:"已读记录" method:"post" summary:"已读记录"`
|
||||
commonApi.Author
|
||||
*model.SysNoticeReadNoticeReq
|
||||
}
|
||||
|
||||
// SysNoticeReadAddRes 添加操作返回结果
|
||||
type SysNoticeReadNoticeAddRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
// SysNoticeReadEditReq 修改操作请求参数
|
||||
type SysNoticeReadEditReq struct {
|
||||
g.Meta `path:"/edit" tags:"已读记录" method:"put" summary:"已读记录修改"`
|
||||
commonApi.Author
|
||||
*model.SysNoticeReadEditReq
|
||||
}
|
||||
|
||||
// SysNoticeReadEditRes 修改操作返回结果
|
||||
type SysNoticeReadEditRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
||||
|
||||
// SysNoticeReadGetReq 获取一条数据请求
|
||||
type SysNoticeReadGetReq struct {
|
||||
g.Meta `path:"/get" tags:"已读记录" method:"get" summary:"获取已读记录信息"`
|
||||
commonApi.Author
|
||||
Id int64 `p:"id" v:"required#主键必须"` //通过主键获取
|
||||
}
|
||||
|
||||
// SysNoticeReadGetRes 获取一条数据结果
|
||||
type SysNoticeReadGetRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
*model.SysNoticeReadInfoRes
|
||||
}
|
||||
|
||||
// SysNoticeReadDeleteReq 删除数据请求
|
||||
type SysNoticeReadDeleteReq struct {
|
||||
g.Meta `path:"/delete" tags:"已读记录" method:"delete" summary:"删除已读记录"`
|
||||
commonApi.Author
|
||||
Ids []int64 `p:"ids" v:"required#主键必须"` //通过主键删除
|
||||
}
|
||||
|
||||
// SysNoticeReadDeleteRes 删除数据返回
|
||||
type SysNoticeReadDeleteRes struct {
|
||||
commonApi.EmptyRes
|
||||
}
|
20
internal/app/common/controller/ping.go
Normal file
20
internal/app/common/controller/ping.go
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @desc:ping
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/30 15:59
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/tiger1103/gfast/v3/library/libWebsocket"
|
||||
)
|
||||
|
||||
var Ping = new(pingController)
|
||||
|
||||
type pingController struct{}
|
||||
|
||||
func (c *pingController) Ping(client *libWebsocket.Client, req *libWebsocket.WRequest) {
|
||||
libWebsocket.SendSuccess(client, req.Event)
|
||||
}
|
@ -18,7 +18,7 @@ func init() {
|
||||
service.RegisterBigUpload(New())
|
||||
}
|
||||
|
||||
func New() *sBigUpload {
|
||||
func New() service.IBigUpload {
|
||||
return &sBigUpload{}
|
||||
}
|
||||
|
||||
|
2
internal/app/common/logic/cache/cache.go
vendored
2
internal/app/common/logic/cache/cache.go
vendored
@ -19,7 +19,7 @@ func init() {
|
||||
service.RegisterCache(New())
|
||||
}
|
||||
|
||||
func New() *sCache {
|
||||
func New() service.ICache {
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
cacheContainer *cache.GfCache
|
||||
|
@ -24,7 +24,7 @@ func init() {
|
||||
service.RegisterCaptcha(New())
|
||||
}
|
||||
|
||||
func New() *sCaptcha {
|
||||
func New() service.ICaptcha {
|
||||
return &sCaptcha{
|
||||
driver: &base64Captcha.DriverString{
|
||||
Height: 80,
|
||||
|
@ -16,7 +16,7 @@ func init() {
|
||||
service.RegisterMiddleware(New())
|
||||
}
|
||||
|
||||
func New() *sMiddleware {
|
||||
func New() service.IMiddleware {
|
||||
return &sMiddleware{}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ func init() {
|
||||
service.RegisterSysConfig(New())
|
||||
}
|
||||
|
||||
func New() *sSysConfig {
|
||||
func New() service.ISysConfig {
|
||||
return &sSysConfig{}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ func init() {
|
||||
service.RegisterSysDictData(New())
|
||||
}
|
||||
|
||||
func New() *sSysDictData {
|
||||
func New() service.ISysDictData {
|
||||
return &sSysDictData{}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ func (s *sSysDictData) GetDictWithDataByType(ctx context.Context, dictType, defa
|
||||
err = dao.SysDictType.Ctx(ctx).Where(dao.SysDictType.Columns().DictType, dictType).
|
||||
Where(dao.SysDictType.Columns().Status, 1).Fields(model.DictTypeRes{}).Scan(&dict.Info)
|
||||
liberr.ErrIsNil(ctx, err, "获取字典类型失败")
|
||||
if dict.Info==nil{
|
||||
if dict.Info == nil {
|
||||
return
|
||||
}
|
||||
err = dao.SysDictData.Ctx(ctx).Fields(model.DictDataRes{}).
|
||||
|
@ -29,7 +29,7 @@ func init() {
|
||||
service.RegisterSysDictType(New())
|
||||
}
|
||||
|
||||
func New() *sSysDictType {
|
||||
func New() service.ISysDictType {
|
||||
return &sSysDictType{}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ func init() {
|
||||
service.RegisterUpload(New())
|
||||
}
|
||||
|
||||
func New() *sUpload {
|
||||
func New() service.IUpload {
|
||||
return &sUpload{}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
PageSize = 10 //分页长度
|
||||
// PageSize 分页长度
|
||||
PageSize = 10
|
||||
// SysNoticeType 系统通知
|
||||
SysNoticeType = 1
|
||||
// SysLetterType 系统私信
|
||||
SysLetterType = 2
|
||||
)
|
||||
|
88
internal/app/system/controller/sys_notice.go
Normal file
88
internal/app/system/controller/sys_notice.go
Normal file
@ -0,0 +1,88 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成controller操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/controller/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/system"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
)
|
||||
|
||||
type sysNoticeController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
var SysNotice = new(sysNoticeController)
|
||||
|
||||
// List 列表(管理)
|
||||
func (c *sysNoticeController) List(ctx context.Context, req *system.SysNoticeSearchReq) (res *system.SysNoticeSearchRes, err error) {
|
||||
res = new(system.SysNoticeSearchRes)
|
||||
res.SysNoticeSearchRes, err = service.SysNotice().List(ctx, &req.SysNoticeSearchReq)
|
||||
return
|
||||
}
|
||||
|
||||
// ShoWList(展示)
|
||||
func (c *sysNoticeController) ShowList(ctx context.Context, req *system.SysNoticeShowSearchReq) (res *system.SysNoticeShowSearchRes, err error) {
|
||||
res = new(system.SysNoticeShowSearchRes)
|
||||
res.SysNoticeSearchRes, err = service.SysNotice().ListShow(ctx, &req.SysNoticeSearchReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Get 获取通知公告
|
||||
func (c *sysNoticeController) Get(ctx context.Context, req *system.SysNoticeGetReq) (res *system.SysNoticeGetRes, err error) {
|
||||
res = new(system.SysNoticeGetRes)
|
||||
res.SysNoticeInfoRes, err = service.SysNotice().GetById(ctx, req.Id)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 添加通知公告
|
||||
func (c *sysNoticeController) Add(ctx context.Context, req *system.SysNoticeAddReq) (res *system.SysNoticeAddRes, err error) {
|
||||
req.CreatedBy = service.Context().GetUserId(ctx)
|
||||
err = service.SysNotice().Add(ctx, req.SysNoticeAddReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Edit 修改通知公告
|
||||
func (c *sysNoticeController) Edit(ctx context.Context, req *system.SysNoticeEditReq) (res *system.SysNoticeEditRes, err error) {
|
||||
req.UpdatedBy = service.Context().GetUserId(ctx)
|
||||
err = service.SysNotice().Edit(ctx, req.SysNoticeEditReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除通知公告
|
||||
func (c *sysNoticeController) Delete(ctx context.Context, req *system.SysNoticeDeleteReq) (res *system.SysNoticeDeleteRes, err error) {
|
||||
err = service.SysNotice().Delete(ctx, req.Ids)
|
||||
return
|
||||
}
|
||||
|
||||
// IndexData 获取首页数据
|
||||
func (c *sysNoticeController) IndexData(ctx context.Context, req *system.SysNoticeIndexDataReq) (res *system.SysNoticeIndexDataRes, err error) {
|
||||
//res.SysNoticeIndexRes, err = service.SysNotice().IndexData(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
// UnReadCount
|
||||
func (c *sysNoticeController) UnReadCount(ctx context.Context, req *system.SysNoticeUnReadCountReq) (res *system.SysNoticeUnReadCountRes, err error) {
|
||||
res = new(system.SysNoticeUnReadCountRes)
|
||||
currentUser := service.Context().Get(ctx).User.Id
|
||||
//noticeids, err := service.SysNotice().CurrentUseWithIds(ctx, currentUser)
|
||||
res.SysNoticeUnreadCount, err = service.SysNotice().UnReadCount(ctx, currentUser)
|
||||
fmt.Println(res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserNameList 得到供选择用户列表
|
||||
func (c *sysNoticeController) GetUserNameList(ctx context.Context, req *system.SysNoticeUserSearchReq) (res *system.SysNoticeUserSearchRes, err error) {
|
||||
res = new(system.SysNoticeUserSearchRes)
|
||||
list, err := service.SysNotice().GetUserNameList(ctx, req.UserNickName)
|
||||
res.UserList = list
|
||||
return
|
||||
}
|
61
internal/app/system/controller/sys_notice_read.go
Normal file
61
internal/app/system/controller/sys_notice_read.go
Normal file
@ -0,0 +1,61 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成controller操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/controller/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tiger1103/gfast/v3/api/v1/system"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
)
|
||||
|
||||
type sysNoticeReadController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
var SysNoticeRead = new(sysNoticeReadController)
|
||||
|
||||
// List 列表
|
||||
func (c *sysNoticeReadController) List(ctx context.Context, req *system.SysNoticeReadSearchReq) (res *system.SysNoticeReadSearchRes, err error) {
|
||||
res = new(system.SysNoticeReadSearchRes)
|
||||
res.SysNoticeReadSearchRes, err = service.SysNoticeRead().List(ctx, &req.SysNoticeReadSearchReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Get 获取已读记录
|
||||
func (c *sysNoticeReadController) Get(ctx context.Context, req *system.SysNoticeReadGetReq) (res *system.SysNoticeReadGetRes, err error) {
|
||||
res = new(system.SysNoticeReadGetRes)
|
||||
res.SysNoticeReadInfoRes, err = service.SysNoticeRead().GetById(ctx, req.Id)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 添加已读记录
|
||||
func (c *sysNoticeReadController) Add(ctx context.Context, req *system.SysNoticeReadAddReq) (res *system.SysNoticeReadAddRes, err error) {
|
||||
err = service.SysNoticeRead().Add(ctx, req.SysNoticeReadAddReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 添加已读记录
|
||||
func (c *sysNoticeReadController) ReadNotice(ctx context.Context, req *system.SysNoticeReadNoticeAddReq) (res *system.SysNoticeReadNoticeAddRes, err error) {
|
||||
err = service.SysNoticeRead().ReadNotice(ctx, req.SysNoticeReadNoticeReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Edit 修改已读记录
|
||||
func (c *sysNoticeReadController) Edit(ctx context.Context, req *system.SysNoticeReadEditReq) (res *system.SysNoticeReadEditRes, err error) {
|
||||
err = service.SysNoticeRead().Edit(ctx, req.SysNoticeReadEditReq)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除已读记录
|
||||
func (c *sysNoticeReadController) Delete(ctx context.Context, req *system.SysNoticeReadDeleteReq) (res *system.SysNoticeReadDeleteRes, err error) {
|
||||
err = service.SysNoticeRead().Delete(ctx, req.Ids)
|
||||
return
|
||||
}
|
103
internal/app/system/dao/internal/sys_notice.go
Normal file
103
internal/app/system/dao/internal/sys_notice.go
Normal file
@ -0,0 +1,103 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成dao internal操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/dao/internal/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SysNoticeDao is the manager for logic model data accessing and custom defined data operations functions management.
|
||||
type SysNoticeDao struct {
|
||||
table string // Table is the underlying table name of the DAO.
|
||||
group string // Group is the database configuration group name of current DAO.
|
||||
columns SysNoticeColumns // Columns is the short type for Columns, which contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysNoticeColumns defines and stores column names for table sys_notice.
|
||||
type SysNoticeColumns struct {
|
||||
Id string // ID
|
||||
Title string // 标题
|
||||
Type string // 类型
|
||||
Tag string // 标签
|
||||
Content string // 内容
|
||||
Remark string // 备注
|
||||
Sort string // 排序
|
||||
Status string // 状态
|
||||
Receiver string //接收者
|
||||
CreatedBy string // 发送人
|
||||
UpdatedBy string // 修改人
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
var sysNoticeColumns = SysNoticeColumns{
|
||||
Id: "id",
|
||||
Title: "title",
|
||||
Type: "type",
|
||||
Tag: "tag",
|
||||
Content: "content",
|
||||
Remark: "remark",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
Receiver: "receiver",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedBy: "updated_by",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewSysNoticeDao creates and returns a new DAO object for table data access.
|
||||
func NewSysNoticeDao() *SysNoticeDao {
|
||||
return &SysNoticeDao{
|
||||
group: "default",
|
||||
table: "sys_notice",
|
||||
columns: sysNoticeColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysNoticeDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysNoticeDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysNoticeDao) Columns() SysNoticeColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysNoticeDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysNoticeDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysNoticeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
85
internal/app/system/dao/internal/sys_notice_read.go
Normal file
85
internal/app/system/dao/internal/sys_notice_read.go
Normal file
@ -0,0 +1,85 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成dao internal操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/dao/internal/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SysNoticeReadDao is the manager for logic model data accessing and custom defined data operations functions management.
|
||||
type SysNoticeReadDao struct {
|
||||
table string // Table is the underlying table name of the DAO.
|
||||
group string // Group is the database configuration group name of current DAO.
|
||||
columns SysNoticeReadColumns // Columns is the short type for Columns, which contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysNoticeReadColumns defines and stores column names for table sys_notice_read.
|
||||
type SysNoticeReadColumns struct {
|
||||
Id string // id
|
||||
NoticeId string // 信息id
|
||||
UserId string // 用户id
|
||||
UpdatedAt string // 更新时间
|
||||
CreatedAt string // 阅读时间
|
||||
}
|
||||
|
||||
var sysNoticeReadColumns = SysNoticeReadColumns{
|
||||
Id: "id",
|
||||
NoticeId: "notice_id",
|
||||
UserId: "user_id",
|
||||
UpdatedAt: "updated_at",
|
||||
CreatedAt: "created_at",
|
||||
}
|
||||
|
||||
// NewSysNoticeReadDao creates and returns a new DAO object for table data access.
|
||||
func NewSysNoticeReadDao() *SysNoticeReadDao {
|
||||
return &SysNoticeReadDao{
|
||||
group: "default",
|
||||
table: "sys_notice_read",
|
||||
columns: sysNoticeReadColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysNoticeReadDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysNoticeReadDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysNoticeReadDao) Columns() SysNoticeReadColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysNoticeReadDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysNoticeReadDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysNoticeReadDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
29
internal/app/system/dao/sys_notice.go
Normal file
29
internal/app/system/dao/sys_notice.go
Normal file
@ -0,0 +1,29 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成dao操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/dao/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/dao/internal"
|
||||
)
|
||||
|
||||
// sysNoticeDao is the manager for logic model data accessing and custom defined data operations functions management.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysNoticeDao struct {
|
||||
*internal.SysNoticeDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysNotice is globally public accessible object for table tools_gen_table operations.
|
||||
SysNotice = sysNoticeDao{
|
||||
internal.NewSysNoticeDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
29
internal/app/system/dao/sys_notice_read.go
Normal file
29
internal/app/system/dao/sys_notice_read.go
Normal file
@ -0,0 +1,29 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成dao操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/dao/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/dao/internal"
|
||||
)
|
||||
|
||||
// sysNoticeReadDao is the manager for logic model data accessing and custom defined data operations functions management.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysNoticeReadDao struct {
|
||||
*internal.SysNoticeReadDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysNoticeRead is globally public accessible object for table tools_gen_table operations.
|
||||
SysNoticeRead = sysNoticeReadDao{
|
||||
internal.NewSysNoticeReadDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
@ -1,19 +1,23 @@
|
||||
package logic
|
||||
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/context"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/middleware"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/personal"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysAuthRule"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysDept"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysJob"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysJobLog"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysLoginLog"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysOperLog"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysPost"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysRole"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysUser"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysUserOnline"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/token"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/toolsGenTable"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/toolsGenTableColumn"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/system/logic/timeTask"
|
||||
import (
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/context"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/middleware"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/personal"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysAuthRule"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysDept"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysJob"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysJobLog"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysLoginLog"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysNotice"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysNoticeRead"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysOperLog"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysPost"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysRole"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysUser"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/sysUserOnline"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/timeTask"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/token"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/toolsGenTable"
|
||||
_ "github.com/tiger1103/gfast/v3/internal/app/system/logic/toolsGenTableColumn"
|
||||
)
|
||||
|
359
internal/app/system/logic/sysNotice/sys_notice.go
Normal file
359
internal/app/system/logic/sysNotice/sys_notice.go
Normal file
@ -0,0 +1,359 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成logic操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/logic/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
||||
sysDao "github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
"github.com/tiger1103/gfast/v3/library/libWebsocket"
|
||||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterSysNotice(New())
|
||||
}
|
||||
|
||||
func New() service.ISysNotice {
|
||||
return &sSysNotice{}
|
||||
}
|
||||
|
||||
type sSysNotice struct{}
|
||||
|
||||
func (s *sSysNotice) List(ctx context.Context, req *model.SysNoticeSearchReq) (listRes *model.SysNoticeSearchRes, err error) {
|
||||
listRes = new(model.SysNoticeSearchRes)
|
||||
currentUserId := service.Context().GetUserId(ctx)
|
||||
if currentUserId <= 0 {
|
||||
err = errors.New("用户信息查询失败")
|
||||
return
|
||||
}
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
m := dao.SysNotice.Ctx(ctx).WithAll().As("n")
|
||||
if req.Id != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Id+" = ?", req.Id)
|
||||
}
|
||||
if req.Title != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Title+" = ?", req.Title)
|
||||
}
|
||||
if req.Type != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Type+" = ?", gconv.Int64(req.Type))
|
||||
}
|
||||
if req.Tag != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Tag+" = ?", gconv.Int(req.Tag))
|
||||
}
|
||||
if req.Status != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Status+" = ?", gconv.Int(req.Status))
|
||||
}
|
||||
if len(req.DateRange) != 0 {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().CreatedAt+" >=? AND "+dao.SysNotice.Columns().CreatedAt+" <=?", req.DateRange[0], req.DateRange[1])
|
||||
}
|
||||
listRes.Total, err = m.Count()
|
||||
liberr.ErrIsNil(ctx, err, "获取总行数失败")
|
||||
if req.PageNum == 0 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
listRes.CurrentPage = req.PageNum
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = consts.PageSize
|
||||
}
|
||||
order := "n.id desc"
|
||||
if req.OrderBy != "" {
|
||||
order = req.OrderBy
|
||||
}
|
||||
m = m.LeftJoin("sys_notice_read as nr", "nr.notice_id=n.id")
|
||||
//Where("nr.user_id=?", currentUserId)
|
||||
var res []*model.SysNoticeListRes
|
||||
|
||||
err = m.Page(req.PageNum, req.PageSize).Fields("" +
|
||||
"n.*," +
|
||||
"SUM(nr.clicks) as clickNumber" +
|
||||
//"(nr.user_id=" + strconv.FormatUint(currentUserId, 10) + ") as isRead" +
|
||||
"").Order(order).Group("n.id").Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
listRes.List = res
|
||||
|
||||
})
|
||||
return
|
||||
}
|
||||
func (s *sSysNotice) ListShow(ctx context.Context, req *model.SysNoticeSearchReq) (listRes *model.SysNoticeSearchRes, err error) {
|
||||
listRes = new(model.SysNoticeSearchRes)
|
||||
currentUserId := service.Context().GetUserId(ctx)
|
||||
if currentUserId <= 0 {
|
||||
err = errors.New("用户信息查询失败")
|
||||
return
|
||||
}
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
m := dao.SysNotice.Ctx(ctx).WithAll().As("n")
|
||||
if req.Id != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Id+" = ?", req.Id)
|
||||
}
|
||||
if req.Title != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Title+" = ?", req.Title)
|
||||
}
|
||||
if req.Type != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Type+" = ?", gconv.Int64(req.Type))
|
||||
if req.Type == "2" {
|
||||
ids, _ := s.CurrentUseWithIds(ctx, currentUserId, 2)
|
||||
m = m.WhereIn("n."+dao.SysNotice.Columns().Id, ids)
|
||||
}
|
||||
}
|
||||
if req.Tag != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Tag+" = ?", gconv.Int(req.Tag))
|
||||
}
|
||||
if req.Status != "" {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().Status+" = ?", gconv.Int(req.Status))
|
||||
}
|
||||
if len(req.DateRange) != 0 {
|
||||
m = m.Where("n."+dao.SysNotice.Columns().CreatedAt+" >=? AND "+dao.SysNotice.Columns().CreatedAt+" <=?", req.DateRange[0], req.DateRange[1])
|
||||
}
|
||||
listRes.Total, err = m.Count()
|
||||
liberr.ErrIsNil(ctx, err, "获取总行数失败")
|
||||
if req.PageNum == 0 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
listRes.CurrentPage = req.PageNum
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = consts.PageSize
|
||||
}
|
||||
order := "n.id desc"
|
||||
if req.OrderBy != "" {
|
||||
order = req.OrderBy
|
||||
}
|
||||
m = m.LeftJoin("sys_notice_read as nr", "nr.notice_id=n.id")
|
||||
/*Where("nr.user_id=?", currentUserId)*/
|
||||
var res []*model.SysNoticeListRes
|
||||
|
||||
err = m.Page(req.PageNum, req.PageSize).Fields("" +
|
||||
"n.*," +
|
||||
"(nr.user_id=" + strconv.FormatUint(currentUserId, 10) + ") as isRead" + //查询是否已读
|
||||
"").Order(order).Group("n.id").Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
listRes.List = res
|
||||
})
|
||||
return
|
||||
}
|
||||
func (s *sSysNotice) GetById(ctx context.Context, id int64) (res *model.SysNoticeInfoRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
err = dao.SysNotice.Ctx(ctx).WithAll().Where(dao.SysNotice.Columns().Id, id).Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) Add(ctx context.Context, req *model.SysNoticeAddReq) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
data := do.SysNotice{
|
||||
Title: req.Title,
|
||||
Type: req.Type,
|
||||
Tag: req.Tag,
|
||||
Content: req.Content,
|
||||
Remark: req.Remark,
|
||||
Receiver: req.Receiver,
|
||||
Sort: req.Sort,
|
||||
Status: req.Status,
|
||||
CreatedBy: req.CreatedBy,
|
||||
}
|
||||
var rows sql.Result
|
||||
rows, err = dao.SysNotice.Ctx(ctx).Insert(data)
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
data.Id, err = rows.LastInsertId()
|
||||
liberr.ErrIsNil(ctx, err, "获取ID失败")
|
||||
response := &libWebsocket.WResponse{
|
||||
Event: "notice",
|
||||
Data: data,
|
||||
}
|
||||
if req.Type == consts.SysLetterType {
|
||||
//系统私信
|
||||
if len(req.Receiver) > 0 {
|
||||
for _, id := range req.Receiver {
|
||||
libWebsocket.SendToUser(id, response)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//系统通知
|
||||
libWebsocket.SendToAll(response)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) Edit(ctx context.Context, req *model.SysNoticeEditReq) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
data := do.SysNotice{
|
||||
Title: req.Title,
|
||||
Tag: req.Tag,
|
||||
Content: req.Content,
|
||||
Remark: req.Remark,
|
||||
Sort: req.Sort,
|
||||
Status: req.Status,
|
||||
Receiver: req.Receiver,
|
||||
UpdatedBy: req.UpdatedBy,
|
||||
}
|
||||
_, err = dao.SysNotice.Ctx(ctx).WherePri(req.Id).Update(data)
|
||||
liberr.ErrIsNil(ctx, err, "修改失败")
|
||||
data.Id = req.Id
|
||||
data.Type = req.Type
|
||||
response := &libWebsocket.WResponse{
|
||||
Event: "notice",
|
||||
Data: data,
|
||||
}
|
||||
if data.Type == consts.SysLetterType {
|
||||
//系统私信
|
||||
if len(req.Receiver) > 0 {
|
||||
for _, id := range req.Receiver {
|
||||
libWebsocket.SendToUser(id, response)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//系统通知
|
||||
libWebsocket.SendToAll(response)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) Delete(ctx context.Context, ids []int64) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.SysNotice.Ctx(ctx).Delete(dao.SysNotice.Columns().Id+" in (?)", ids)
|
||||
liberr.ErrIsNil(ctx, err, "删除失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
func (s *sSysNotice) IndexData(ctx context.Context) (res *model.SysNoticeIndexRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
userInfo := service.Context().GetLoginUser(ctx)
|
||||
readIdMap, err := dao.SysNoticeRead.Ctx(ctx).Where(dao.SysNoticeRead.Columns().UserId, userInfo.Id).Fields(dao.SysNoticeRead.Columns().NoticeId).All()
|
||||
fmt.Println(readIdMap, err)
|
||||
dao.SysNotice.Ctx(ctx).Where(dao.SysNotice.Columns().Type, "1").Order("id desc").Scan(res.Type1List)
|
||||
dao.SysNotice.Ctx(ctx)
|
||||
|
||||
})
|
||||
return
|
||||
}
|
||||
*/
|
||||
//未读消息列表
|
||||
func (s *sSysNotice) UnReadList(ctx context.Context) (res *model.SysNoticeListRes, err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *sSysNotice) UnReadCount(ctx context.Context, currentUserId uint64) (sysNoticeUnreadCount *model.SysNoticeUnreadCount, err error) {
|
||||
if currentUserId <= 0 {
|
||||
err = errors.New("获取用户信息失败")
|
||||
return
|
||||
}
|
||||
countFunc := func(t int) (count int) {
|
||||
noticeIds, serr := s.CurrentUseWithIds(ctx, currentUserId, t)
|
||||
if serr != nil {
|
||||
return 0
|
||||
}
|
||||
all, serr := dao.SysNotice.Ctx(ctx).
|
||||
WhereIn(dao.SysNotice.Columns().Id, noticeIds).
|
||||
Where(dao.SysNotice.Columns().Type, t).Count()
|
||||
if serr != nil {
|
||||
return 0
|
||||
}
|
||||
read, serr := dao.SysNoticeRead.Ctx(ctx).
|
||||
WhereIn(dao.SysNoticeRead.Columns().NoticeId, noticeIds).
|
||||
Where(dao.SysNoticeRead.Columns().UserId, currentUserId).
|
||||
Count()
|
||||
if serr != nil {
|
||||
return 0
|
||||
}
|
||||
count = all - read
|
||||
return
|
||||
}
|
||||
sysNoticeUnreadCount = new(model.SysNoticeUnreadCount)
|
||||
sysNoticeUnreadCount.NotifyCount = countFunc(1) //获取未读通知数量
|
||||
sysNoticeUnreadCount.NoticeCount = countFunc(2) //获取未读私信数量
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) ReadAll(ctx context.Context, nType string) (err error) {
|
||||
currentUserId := service.Context().GetUserId(ctx)
|
||||
if currentUserId <= 0 {
|
||||
err = errors.New("获取当前用户信息失败")
|
||||
return
|
||||
}
|
||||
subQuery := g.Model("sys_notice_read").Where("user_id=?", currentUserId).Fields("id")
|
||||
/* dao.SysNoticeRead.Ctx(ctx).Where(dao.SysNoticeRead.Columns().UserId, currentUserId)*/
|
||||
unReadIdMap, err := dao.SysNotice.Ctx(ctx).WhereNotIn("id", subQuery).Fields("id").All()
|
||||
if unReadIdMap != nil {
|
||||
insertList := make([]*model.SysNoticeReadAddReq, 0)
|
||||
for _, record := range unReadIdMap {
|
||||
insertList = append(insertList, &model.SysNoticeReadAddReq{
|
||||
NoticeId: record["id"].Int64(),
|
||||
UserId: int64(currentUserId),
|
||||
CreatedAt: gtime.Now(),
|
||||
})
|
||||
}
|
||||
_, err = dao.SysNoticeRead.Ctx(ctx).Data(insertList).Insert()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) GetUserNameList(ctx context.Context, search string) (res []*model.SysNoticeUserNickname, err error) {
|
||||
res = make([]*model.SysNoticeUserNickname, 0)
|
||||
err = sysDao.SysUser.Ctx(ctx).Where("user_nickname like ?", "%"+search+"%").Fields("id,user_nickname").Page(1, 6).Scan(&res)
|
||||
return
|
||||
}
|
||||
|
||||
/*func (s *sSysNotice) NoticeReadLengthAdd(ctx context.Context, id int64) (err error) {
|
||||
_, err = g.DB().Exec(ctx, "update sys_notice set read_len=(read_len+1) where id = ?", id)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func (s *sSysNotice) NoticeReadAddUserId(ctx context.Context, req *model.SysNoticeReadAddUserReq) (err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNotice) CurrentUseWithIds(ctx context.Context, currentUserId uint64, noticeType int) (ids []int64, err error) {
|
||||
/* columns, err := s.Model(ctx, &handler.Option{FilterAuth: false}).
|
||||
Fields("id").
|
||||
Where("status", consts.StatusEnabled).
|
||||
Where("(`type` IN(?) OR (`type` = ? and JSON_CONTAINS(`receiver`,'"+gconv.String(memberId)+"')))",
|
||||
[]int{consts.NoticeTypeNotify, consts.NoticeTypeNotice}, consts.NoticeTypeLetter,
|
||||
).Array()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, "获取我的消息失败!")
|
||||
return
|
||||
}
|
||||
|
||||
ids = g.NewVar(columns).Int64s()*/
|
||||
m := dao.SysNotice.Ctx(ctx)
|
||||
m = m.Where("status =?", 1).
|
||||
Where("type=?", noticeType).
|
||||
Where("(`type` IN(?) OR (`type` = ? and JSON_CONTAINS(`receiver`,'"+gconv.String(currentUserId)+"')))", 1, 2)
|
||||
all, err := m.Fields("id").All()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, record := range all {
|
||||
ids = append(ids, record["id"].Int64())
|
||||
}
|
||||
return
|
||||
}
|
128
internal/app/system/logic/sysNoticeRead/sys_notice_read.go
Normal file
128
internal/app/system/logic/sysNoticeRead/sys_notice_read.go
Normal file
@ -0,0 +1,128 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成logic操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/logic/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterSysNoticeRead(New())
|
||||
}
|
||||
|
||||
func New() service.ISysNoticeRead {
|
||||
return &sSysNoticeRead{}
|
||||
}
|
||||
|
||||
type sSysNoticeRead struct{}
|
||||
|
||||
func (s *sSysNoticeRead) List(ctx context.Context, req *model.SysNoticeReadSearchReq) (listRes *model.SysNoticeReadSearchRes, err error) {
|
||||
listRes = new(model.SysNoticeReadSearchRes)
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
m := dao.SysNoticeRead.Ctx(ctx).WithAll()
|
||||
listRes.Total, err = m.Count()
|
||||
liberr.ErrIsNil(ctx, err, "获取总行数失败")
|
||||
if req.PageNum == 0 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
listRes.CurrentPage = req.PageNum
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = consts.PageSize
|
||||
}
|
||||
order := "id desc"
|
||||
if req.OrderBy != "" {
|
||||
order = req.OrderBy
|
||||
}
|
||||
var res []*model.SysNoticeReadListRes
|
||||
err = m.Page(req.PageNum, req.PageSize).Order(order).Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
listRes.List = make([]*model.SysNoticeReadListRes, len(res))
|
||||
for k, v := range res {
|
||||
listRes.List[k] = &model.SysNoticeReadListRes{
|
||||
Id: v.Id,
|
||||
NoticeId: v.NoticeId,
|
||||
UserId: v.UserId,
|
||||
CreatedAt: v.CreatedAt,
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNoticeRead) GetById(ctx context.Context, id int64) (res *model.SysNoticeReadInfoRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
err = dao.SysNoticeRead.Ctx(ctx).WithAll().Where(dao.SysNoticeRead.Columns().Id, id).Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNoticeRead) Add(ctx context.Context, req *model.SysNoticeReadAddReq) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.SysNoticeRead.Ctx(ctx).Insert(do.SysNoticeRead{})
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNoticeRead) ReadNotice(ctx context.Context, req *model.SysNoticeReadNoticeReq) (err error) {
|
||||
currentUser := service.Context().Get(ctx).User.Id
|
||||
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
//判断是否有数据
|
||||
count, err := dao.SysNoticeRead.Ctx(ctx).Where(dao.SysNoticeRead.Columns().NoticeId, req.NoticeId).
|
||||
Where(dao.SysNoticeRead.Columns().UserId, currentUser).Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if count > 0 {
|
||||
_, err := g.DB().Exec(ctx, " update sys_notice_read set clicks=(clicks+1) where user_id =? and notice_id=?", currentUser, req.NoticeId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
_, err = dao.SysNoticeRead.Ctx(ctx).Insert(do.SysNoticeRead{
|
||||
NoticeId: req.NoticeId,
|
||||
UserId: currentUser,
|
||||
CreatedAt: gtime.Now(),
|
||||
Clicks: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
func (s *sSysNoticeRead) Edit(ctx context.Context, req *model.SysNoticeReadEditReq) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.SysNoticeRead.Ctx(ctx).WherePri(req.Id).Update(do.SysNoticeRead{})
|
||||
liberr.ErrIsNil(ctx, err, "修改失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysNoticeRead) Delete(ctx context.Context, ids []int64) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.SysNoticeRead.Ctx(ctx).Delete(dao.SysNoticeRead.Columns().Id+" in (?)", ids)
|
||||
liberr.ErrIsNil(ctx, err, "删除失败")
|
||||
})
|
||||
return
|
||||
}
|
34
internal/app/system/model/do/sys_notice.go
Normal file
34
internal/app/system/model/do/sys_notice.go
Normal file
@ -0,0 +1,34 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model entity操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/model/entity/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
)
|
||||
|
||||
// SysNotice is the golang structure for table sys_notice.
|
||||
type SysNotice struct {
|
||||
gmeta.Meta `orm:"table:sys_notice, do:true"`
|
||||
Id interface{} `orm:"id,primary" json:"id"` // ID
|
||||
Title interface{} `orm:"title" json:"title"` // 标题
|
||||
Type interface{} `orm:"type" json:"type"` // 类型
|
||||
Tag interface{} `orm:"tag" json:"tag"` // 标签
|
||||
Content interface{} `orm:"content" json:"content"` // 内容
|
||||
Remark interface{} `orm:"remark" json:"remark"` // 备注
|
||||
Sort interface{} `orm:"sort" json:"sort"` // 排序
|
||||
Status interface{} `orm:"status" json:"status"` // 状态
|
||||
Receiver interface{} `orm:"receiver" json:"receiver"` //接收者
|
||||
CreatedBy interface{} `orm:"created_by" json:"createdBy"` // 发送人
|
||||
UpdatedBy interface{} `orm:"updated_by" json:"updatedBy"` // 修改人
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间
|
||||
DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间
|
||||
}
|
26
internal/app/system/model/do/sys_notice_read.go
Normal file
26
internal/app/system/model/do/sys_notice_read.go
Normal file
@ -0,0 +1,26 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model entity操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/model/entity/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
)
|
||||
|
||||
// SysNoticeRead is the golang structure for table sys_notice_read.
|
||||
type SysNoticeRead struct {
|
||||
gmeta.Meta `orm:"table:sys_notice_read, do:true"`
|
||||
Id interface{} `orm:"id,primary" json:"id"` // id
|
||||
NoticeId interface{} `orm:"notice_id" json:"noticeId"` // 信息id
|
||||
UserId interface{} `orm:"user_id" json:"userId"` // 用户id
|
||||
Clicks interface{} `orm:"clicks" json:"clicks"` //点击次数
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 阅读时间
|
||||
}
|
33
internal/app/system/model/entity/sys_notice.go
Normal file
33
internal/app/system/model/entity/sys_notice.go
Normal file
@ -0,0 +1,33 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model entity操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/model/entity/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
)
|
||||
|
||||
// SysNotice is the golang structure for table sys_notice.
|
||||
type SysNotice struct {
|
||||
gmeta.Meta `orm:"table:sys_notice"`
|
||||
Id int64 `orm:"id,primary" json:"id"` // ID
|
||||
Title string `orm:"title" json:"title"` // 标题
|
||||
Type int64 `orm:"type" json:"type"` // 类型
|
||||
Tag int `orm:"tag" json:"tag"` // 标签
|
||||
Content string `orm:"content" json:"content"` // 内容
|
||||
Remark string `orm:"remark" json:"remark"` // 备注
|
||||
Sort int `orm:"sort" json:"sort"` // 排序
|
||||
Status int `orm:"status" json:"status"` // 状态
|
||||
CreatedBy int64 `orm:"created_by" json:"createdBy"` // 发送人
|
||||
UpdatedBy int64 `orm:"updated_by" json:"updatedBy"` // 修改人
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间
|
||||
DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间
|
||||
}
|
25
internal/app/system/model/entity/sys_notice_read.go
Normal file
25
internal/app/system/model/entity/sys_notice_read.go
Normal file
@ -0,0 +1,25 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model entity操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/model/entity/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
)
|
||||
|
||||
// SysNoticeRead is the golang structure for table sys_notice_read.
|
||||
type SysNoticeRead struct {
|
||||
gmeta.Meta `orm:"table:sys_notice_read"`
|
||||
Id int64 `orm:"id,primary" json:"id"` // id
|
||||
NoticeId int64 `orm:"notice_id" json:"noticeId"` // 信息id
|
||||
UserId int64 `orm:"user_id" json:"userId"` // 用户id
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 阅读时间
|
||||
}
|
120
internal/app/system/model/sys_notice.go
Normal file
120
internal/app/system/model/sys_notice.go
Normal file
@ -0,0 +1,120 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/model/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
comModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
|
||||
)
|
||||
|
||||
// SysNoticeInfoRes is the golang structure for table sys_notice.
|
||||
type SysNoticeInfoRes struct {
|
||||
gmeta.Meta `orm:"table:sys_notice"`
|
||||
Id int64 `orm:"id,primary" json:"id" dc:"ID"` // ID
|
||||
Title string `orm:"title" json:"title" dc:"标题"` // 标题
|
||||
Type int64 `orm:"type" json:"type" dc:"类型"` // 类型
|
||||
Tag int `orm:"tag" json:"tag" dc:"标签"` // 标签
|
||||
Content string `orm:"content" json:"content" dc:"内容"` // 内容
|
||||
Remark string `orm:"remark" json:"remark" dc:"备注"` // 备注
|
||||
Sort int `orm:"sort" json:"sort" dc:"排序"` // 排序
|
||||
Status int `orm:"status" json:"status" dc:"状态"` // 状态
|
||||
CreatedBy int64 `orm:"created_by" json:"createdBy" dc:"发送人"` // 发送人
|
||||
CreatedUser *LinkUserRes `orm:"with:id=created_by" json:"createdUser"`
|
||||
UpdatedBy int64 `orm:"updated_by" json:"updatedBy" dc:"修改人"` // 修改人
|
||||
UpdatedUser *LinkUserRes `orm:"with:id=updated_by" json:"updatedUser"`
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt" dc:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt" dc:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt" dc:"删除时间"` // 删除时间
|
||||
Receiver []uint64 `json:"receiver" orm:"receiver"`
|
||||
ReceiverUser []*LinkUserRes `orm:"with:id=receiver" json:"receiverUser"`
|
||||
}
|
||||
|
||||
type SysNoticeListRes struct {
|
||||
Id int64 `json:"id" dc:"ID"`
|
||||
Title string `json:"title" dc:"标题"`
|
||||
Type int64 `json:"type" dc:"类型"`
|
||||
Tag int `json:"tag" dc:"标签"`
|
||||
Content string `json:"content" dc:"内容"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
IsRead bool `json:"isRead" dc:"当前用户是否已读"`
|
||||
ClickNumber int `json:"clickNumber"`
|
||||
CreatedUser *LinkUserRes `orm:"with:id=created_by" json:"createdUser"`
|
||||
CreatedBy int64 `json:"createdBy" dc:"发送人"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// SysNoticeSearchReq 分页请求参数
|
||||
type SysNoticeSearchReq struct {
|
||||
comModel.PageReq
|
||||
Id string `p:"id" dc:"ID"` //ID
|
||||
Title string `p:"title" dc:"标题"` //标题
|
||||
Type string `p:"type" v:"type@integer#类型需为整数" dc:"类型"` //类型
|
||||
Tag string `p:"tag" v:"tag@integer#标签需为整数" dc:"标签"` //标签
|
||||
Status string `p:"status" v:"status@integer#状态需为整数" dc:"状态"` //状态
|
||||
CreatedAt string `p:"createdAt" v:"createdAt@datetime#创建时间需为YYYY-MM-DD hh:mm:ss格式" dc:"创建时间"` //创建时间
|
||||
}
|
||||
|
||||
// SysNoticeSearchRes 列表返回结果
|
||||
type SysNoticeSearchRes struct {
|
||||
comModel.ListRes
|
||||
List []*SysNoticeListRes `json:"list"`
|
||||
}
|
||||
|
||||
type SysNoticeUserNickname struct {
|
||||
Id int64 `json:"id"`
|
||||
UserNickName string `json:"userNickname"`
|
||||
}
|
||||
|
||||
// SysNoticeAddReq 添加操作请求参数
|
||||
type SysNoticeAddReq struct {
|
||||
Title string `p:"title" v:"required#标题不能为空" dc:"标题"`
|
||||
Type int64 `p:"type" v:"required#类型不能为空" dc:"类型"`
|
||||
Tag int `p:"tag" dc:"标签"`
|
||||
Content string `p:"content" v:"required#内容不能为空" dc:"内容"`
|
||||
Remark string `p:"remark" dc:"备注"`
|
||||
Sort int `p:"sort" dc:"排序"`
|
||||
Status int `p:"status" v:"required#状态不能为空" dc:"状态"`
|
||||
Receiver []uint64 `p:"receiver"`
|
||||
CreatedBy uint64
|
||||
}
|
||||
|
||||
// SysNoticeEditReq 修改操作请求参数
|
||||
type SysNoticeEditReq struct {
|
||||
Id int64 `p:"id" v:"required#主键ID不能为空" dc:"ID"`
|
||||
Title string `p:"title" v:"required#标题不能为空" dc:"标题"`
|
||||
Type int64 `p:"type" v:"required#类型不能为空" dc:"类型"`
|
||||
Tag int `p:"tag" dc:"标签"`
|
||||
Content string `p:"content" v:"required#内容不能为空" dc:"内容"`
|
||||
Remark string `p:"remark" dc:"备注"`
|
||||
Sort int `p:"sort" dc:"排序"`
|
||||
Status int `p:"status" v:"required#状态不能为空" dc:"状态"`
|
||||
Receiver []uint64 `p:"receiver"`
|
||||
UpdatedBy uint64
|
||||
}
|
||||
|
||||
type SysNoticeIndexRes struct {
|
||||
Type1Total int `json:"type1Total"`
|
||||
Type2Total int `json:"type2Total"`
|
||||
Type1List *SysNoticeListRes `json:"type1List"`
|
||||
Type2List *SysNoticeListRes `json:"type2List"`
|
||||
}
|
||||
|
||||
type SysNoticeUnreadCount struct {
|
||||
NotifyCount int `json:"notifyCount"`
|
||||
NoticeCount int `json:"noticeCount"`
|
||||
}
|
||||
|
||||
type SysNoticeReadAddUserReq struct {
|
||||
UserId int64
|
||||
NoticeId int64 `p:"noticeId"`
|
||||
}
|
63
internal/app/system/model/sys_notice_read.go
Normal file
63
internal/app/system/model/sys_notice_read.go
Normal file
@ -0,0 +1,63 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成model操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/model/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
comModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
|
||||
)
|
||||
|
||||
// SysNoticeReadInfoRes is the golang structure for table sys_notice_read.
|
||||
type SysNoticeReadInfoRes struct {
|
||||
gmeta.Meta `orm:"table:sys_notice_read"`
|
||||
Id int64 `orm:"id,primary" json:"id" dc:"id"` // id
|
||||
NoticeId int64 `orm:"notice_id" json:"noticeId" dc:"信息id"` // 信息id
|
||||
UserId int64 `orm:"user_id" json:"userId" dc:"用户id"` // 用户id
|
||||
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt" dc:"更新时间"` // 更新时间
|
||||
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt" dc:"阅读时间"` // 阅读时间
|
||||
}
|
||||
|
||||
type SysNoticeReadListRes struct {
|
||||
Id int64 `json:"id" dc:"id"`
|
||||
NoticeId int64 `json:"noticeId" dc:"信息id"`
|
||||
UserId int64 `json:"userId" dc:"用户id"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"阅读时间"`
|
||||
}
|
||||
|
||||
// SysNoticeReadSearchReq 分页请求参数
|
||||
type SysNoticeReadSearchReq struct {
|
||||
comModel.PageReq
|
||||
}
|
||||
|
||||
// SysNoticeReadSearchRes 列表返回结果
|
||||
type SysNoticeReadSearchRes struct {
|
||||
comModel.ListRes
|
||||
List []*SysNoticeReadListRes `json:"list"`
|
||||
}
|
||||
|
||||
// SysNoticeReadAddReq 添加操作请求参数
|
||||
type SysNoticeReadAddReq struct {
|
||||
NoticeId int64 `json:"noticeId" dc:"信息id"`
|
||||
UserId int64 `json:"userId" dc:"用户id"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"阅读时间"`
|
||||
}
|
||||
|
||||
// SysNoticeReadAddReq 添加操作请求参数
|
||||
type SysNoticeReadNoticeReq struct {
|
||||
NoticeId int64 `p:"noticeId" dc:"信息id"`
|
||||
UserId int64
|
||||
CreatedAt *gtime.Time
|
||||
}
|
||||
|
||||
// SysNoticeReadEditReq 修改操作请求参数
|
||||
type SysNoticeReadEditReq struct {
|
||||
Id int64 `p:"id" v:"required#主键ID不能为空" dc:"id"`
|
||||
}
|
25
internal/app/system/router/sys_notice.go
Normal file
25
internal/app/system/router/sys_notice.go
Normal file
@ -0,0 +1,25 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成router操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/router/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/controller"
|
||||
)
|
||||
|
||||
func (router *Router) BindSysNoticeController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
group.Group("/sysNotice", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
controller.SysNotice,
|
||||
)
|
||||
})
|
||||
}
|
25
internal/app/system/router/sys_notice_read.go
Normal file
25
internal/app/system/router/sys_notice_read.go
Normal file
@ -0,0 +1,25 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成router操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/router/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/controller"
|
||||
)
|
||||
|
||||
func (router *Router) BindSysNoticeReadController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
group.Group("/sysNoticeRead", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
controller.SysNoticeRead,
|
||||
)
|
||||
})
|
||||
}
|
48
internal/app/system/service/sys_notice.go
Normal file
48
internal/app/system/service/sys_notice.go
Normal file
@ -0,0 +1,48 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成service操作代码。
|
||||
// 生成日期:2023-11-09 11:41:17
|
||||
// 生成路径: internal/app/system/service/sys_notice.go
|
||||
// 生成人:gfast
|
||||
// desc:通知公告
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
type ISysNotice interface {
|
||||
List(ctx context.Context, req *model.SysNoticeSearchReq) (res *model.SysNoticeSearchRes, err error)
|
||||
ListShow(ctx context.Context, req *model.SysNoticeSearchReq) (res *model.SysNoticeSearchRes, err error)
|
||||
|
||||
GetById(ctx context.Context, Id int64) (res *model.SysNoticeInfoRes, err error)
|
||||
Add(ctx context.Context, req *model.SysNoticeAddReq) (err error)
|
||||
Edit(ctx context.Context, req *model.SysNoticeEditReq) (err error)
|
||||
Delete(ctx context.Context, Id []int64) (err error)
|
||||
//IndexData(ctx context.Context) (res *model.SysNoticeIndexRes, err error)
|
||||
/*首页相关数据接口*/
|
||||
UnReadList(ctx context.Context) (res *model.SysNoticeListRes, err error)
|
||||
UnReadCount(ctx context.Context, currentUser uint64) (sysNoticeUnreadIds *model.SysNoticeUnreadCount, err error)
|
||||
ReadAll(ctx context.Context, nType string) (err error)
|
||||
GetUserNameList(ctx context.Context, search string) (res []*model.SysNoticeUserNickname, err error)
|
||||
//NoticeReadLengthAdd(ctx context.Context, id int64) (err error)
|
||||
NoticeReadAddUserId(ctx context.Context, req *model.SysNoticeReadAddUserReq) (err error)
|
||||
//获取有我的消息的所有私信
|
||||
//CurrentUseWithIds(ctx context.Context, currentUserId uint64) (ids []int64, err error)
|
||||
}
|
||||
|
||||
var localSysNotice ISysNotice
|
||||
|
||||
func SysNotice() ISysNotice {
|
||||
if localSysNotice == nil {
|
||||
panic("implement not found for interface ISysNotice, forgot register?")
|
||||
}
|
||||
return localSysNotice
|
||||
}
|
||||
|
||||
func RegisterSysNotice(i ISysNotice) {
|
||||
localSysNotice = i
|
||||
}
|
38
internal/app/system/service/sys_notice_read.go
Normal file
38
internal/app/system/service/sys_notice_read.go
Normal file
@ -0,0 +1,38 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成service操作代码。
|
||||
// 生成日期:2023-11-09 17:37:25
|
||||
// 生成路径: internal/app/system/service/sys_notice_read.go
|
||||
// 生成人:gfast
|
||||
// desc:已读记录
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
type ISysNoticeRead interface {
|
||||
List(ctx context.Context, req *model.SysNoticeReadSearchReq) (res *model.SysNoticeReadSearchRes, err error)
|
||||
ReadNotice(ctx context.Context, req *model.SysNoticeReadNoticeReq) (err error)
|
||||
GetById(ctx context.Context, Id int64) (res *model.SysNoticeReadInfoRes, err error)
|
||||
Add(ctx context.Context, req *model.SysNoticeReadAddReq) (err error)
|
||||
Edit(ctx context.Context, req *model.SysNoticeReadEditReq) (err error)
|
||||
Delete(ctx context.Context, Id []int64) (err error)
|
||||
}
|
||||
|
||||
var localSysNoticeRead ISysNoticeRead
|
||||
|
||||
func SysNoticeRead() ISysNoticeRead {
|
||||
if localSysNoticeRead == nil {
|
||||
panic("implement not found for interface ISysNoticeRead, forgot register?")
|
||||
}
|
||||
return localSysNoticeRead
|
||||
}
|
||||
|
||||
func RegisterSysNoticeRead(i ISysNoticeRead) {
|
||||
localSysNoticeRead = i
|
||||
}
|
82
internal/app/websocket/router/router.go
Normal file
82
internal/app/websocket/router/router.go
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* @desc:websocket路由
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/30 15:06
|
||||
*/
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/guid"
|
||||
"github.com/gorilla/websocket"
|
||||
commonController "github.com/tiger1103/gfast/v3/internal/app/common/controller"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
"github.com/tiger1103/gfast/v3/library/libUtils"
|
||||
"github.com/tiger1103/gfast/v3/library/libWebsocket"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var R = new(Router)
|
||||
|
||||
type Router struct{}
|
||||
|
||||
// WsPage ws入口
|
||||
func WsPage(r *ghttp.Request) {
|
||||
upGrader := websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
conn, err := upGrader.Upgrade(r.Response.ResponseWriter, r.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
currentTime := uint64(gtime.Now().Unix())
|
||||
client := NewClient(r, conn, currentTime)
|
||||
go client.Read()
|
||||
go client.Write()
|
||||
// 用户连接事件
|
||||
libWebsocket.Register(client)
|
||||
}
|
||||
|
||||
// NewClient 初始化
|
||||
func NewClient(r *ghttp.Request, socket *websocket.Conn, firstTime uint64) (client *libWebsocket.Client) {
|
||||
client = &libWebsocket.Client{
|
||||
Addr: socket.RemoteAddr().String(),
|
||||
ID: guid.S(),
|
||||
Socket: socket,
|
||||
Send: make(chan *libWebsocket.WResponse, 100),
|
||||
SendClose: false,
|
||||
CloseSignal: make(chan struct{}, 1),
|
||||
FirstTime: firstTime,
|
||||
HeartbeatTime: firstTime,
|
||||
User: service.Context().GetLoginUser(r.Context()),
|
||||
IP: libUtils.GetClientIp(r.Context()),
|
||||
UserAgent: r.UserAgent(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (router *Router) BindController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
group.Group("/websocket", func(group *ghttp.RouterGroup) {
|
||||
//登录验证拦截
|
||||
service.GfToken().Middleware(group)
|
||||
//context拦截器
|
||||
group.Middleware(service.Middleware().Ctx)
|
||||
|
||||
group.GET("/", WsPage)
|
||||
})
|
||||
// 启动websocket监听
|
||||
libWebsocket.Start()
|
||||
|
||||
// 注册消息路由
|
||||
libWebsocket.RegisterMsg(libWebsocket.EventHandlers{
|
||||
"ping": commonController.Ping.Ping, // 心跳
|
||||
})
|
||||
}
|
11
internal/router/websocket.go
Normal file
11
internal/router/websocket.go
Normal file
@ -0,0 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
websocketRouter "github.com/tiger1103/gfast/v3/internal/app/websocket/router"
|
||||
)
|
||||
|
||||
func (router *Router) BindWebsocketModuleController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
websocketRouter.R.BindController(ctx, group)
|
||||
}
|
172
library/libWebsocket/client.go
Normal file
172
library/libWebsocket/client.go
Normal file
@ -0,0 +1,172 @@
|
||||
package libWebsocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gorilla/websocket"
|
||||
systemModel "github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
const (
|
||||
// 用户连接超时时间
|
||||
heartbeatExpirationTime = 5 * 60
|
||||
)
|
||||
|
||||
// 用户登录
|
||||
type login struct {
|
||||
UserId uint64
|
||||
Client *Client
|
||||
}
|
||||
|
||||
// GetKey 读取客户端数据
|
||||
func (l *login) GetKey() string {
|
||||
return GetUserKey(l.UserId)
|
||||
}
|
||||
|
||||
// Client 客户端连接
|
||||
type Client struct {
|
||||
Addr string // 客户端地址
|
||||
ID string // 连接唯一标识
|
||||
Socket *websocket.Conn // 用户连接
|
||||
Send chan *WResponse // 待发送的数据
|
||||
SendClose bool // 发送是否关闭
|
||||
CloseSignal chan struct{} // 关闭信号
|
||||
FirstTime uint64 // 首次连接时间
|
||||
HeartbeatTime uint64 // 用户上次心跳时间
|
||||
Tags garray.StrArray // 标签
|
||||
User *systemModel.ContextUser // 用户信息
|
||||
context context.Context // Custom context for internal usage purpose.
|
||||
IP string // 客户端IP
|
||||
UserAgent string // 用户代理
|
||||
}
|
||||
|
||||
// 读取客户端数据
|
||||
func (c *Client) Read() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Warningf(mctx, "client read err: %+v, stack:%+v, user:%+v", r, string(debug.Stack()), c.User)
|
||||
}
|
||||
}()
|
||||
|
||||
defer c.close()
|
||||
|
||||
for {
|
||||
_, message, err := c.Socket.ReadMessage()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 处理消息
|
||||
handlerMsg(c, message)
|
||||
}
|
||||
}
|
||||
|
||||
// 向客户端写数据
|
||||
func (c *Client) Write() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Warningf(mctx, "client write err: %+v, stack:%+v, user:%+v", r, string(debug.Stack()), c.User)
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
clientManager.Unregister <- c
|
||||
_ = c.Socket.Close()
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case <-c.CloseSignal:
|
||||
g.Log().Infof(mctx, "websocket client quit, user:%+v", c.User)
|
||||
return
|
||||
case message, ok := <-c.Send:
|
||||
if !ok {
|
||||
// 发送数据错误 关闭连接
|
||||
g.Log().Warningf(mctx, "client write message, user:%+v", c.User)
|
||||
return
|
||||
}
|
||||
_ = c.Socket.WriteJSON(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SendMsg 发送数据
|
||||
func (c *Client) SendMsg(msg *WResponse) {
|
||||
if c == nil || c.SendClose {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Infof(mctx, "SendMsg err:%+v, stack:%+v", r, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
c.Send <- msg
|
||||
}
|
||||
|
||||
// Context is alias for function GetCtx.
|
||||
func (c *Client) Context() context.Context {
|
||||
if c.context == nil {
|
||||
c.context = gctx.New()
|
||||
}
|
||||
return c.context
|
||||
}
|
||||
|
||||
// Heartbeat 心跳更新
|
||||
func (c *Client) Heartbeat(currentTime uint64) {
|
||||
c.HeartbeatTime = currentTime
|
||||
}
|
||||
|
||||
// IsHeartbeatTimeout 心跳是否超时
|
||||
func (c *Client) IsHeartbeatTimeout(currentTime uint64) (timeout bool) {
|
||||
if c.HeartbeatTime+heartbeatExpirationTime <= currentTime {
|
||||
timeout = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 关闭客户端
|
||||
func (c *Client) close() {
|
||||
if c.SendClose {
|
||||
return
|
||||
}
|
||||
c.SendClose = true
|
||||
c.CloseSignal <- struct{}{}
|
||||
}
|
||||
|
||||
// Close 关闭指定客户端连接
|
||||
func Close(client *Client) {
|
||||
client.close()
|
||||
}
|
||||
|
||||
// SendSuccess 发送成功消息
|
||||
func SendSuccess(client *Client, event string, data ...interface{}) {
|
||||
d := interface{}(nil)
|
||||
if len(data) > 0 {
|
||||
d = data[0]
|
||||
}
|
||||
client.SendMsg(&WResponse{
|
||||
Event: event,
|
||||
Data: d,
|
||||
Code: gcode.CodeOK.Code(),
|
||||
Timestamp: gtime.Now().Unix(),
|
||||
})
|
||||
before(client)
|
||||
}
|
||||
|
||||
// SendError 发送错误消息
|
||||
func SendError(client *Client, event string, err error) {
|
||||
client.SendMsg(&WResponse{
|
||||
Event: event,
|
||||
Code: gcode.CodeNil.Code(),
|
||||
ErrorMsg: err.Error(),
|
||||
Timestamp: gtime.Now().Unix(),
|
||||
})
|
||||
before(client)
|
||||
}
|
||||
|
||||
// before
|
||||
func before(client *Client) {
|
||||
client.Heartbeat(uint64(gtime.Now().Unix()))
|
||||
}
|
321
library/libWebsocket/client_manager.go
Normal file
321
library/libWebsocket/client_manager.go
Normal file
@ -0,0 +1,321 @@
|
||||
package libWebsocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcron"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ClientManager 客户端管理
|
||||
type ClientManager struct {
|
||||
Clients map[*Client]bool // 全部的连接
|
||||
ClientsLock sync.RWMutex // 读写锁
|
||||
Users map[string][]*Client // 登录的用户
|
||||
UserLock sync.RWMutex // 读写锁
|
||||
Register chan *Client // 连接连接处理
|
||||
Login chan *login // 用户登录处理
|
||||
Unregister chan *Client // 断开连接处理程序
|
||||
Broadcast chan *WResponse // 广播 向全部成员发送数据
|
||||
ClientBroadcast chan *ClientWResponse // 广播 向某个客户端发送数据
|
||||
TagBroadcast chan *TagWResponse // 广播 向某个标签成员发送数据
|
||||
UserBroadcast chan *UserWResponse // 广播 向某个用户的所有链接发送数据
|
||||
closeSignal chan struct{} // 关闭信号
|
||||
}
|
||||
|
||||
func NewClientManager() (clientManager *ClientManager) {
|
||||
clientManager = &ClientManager{
|
||||
Clients: make(map[*Client]bool),
|
||||
Users: make(map[string][]*Client),
|
||||
Register: make(chan *Client, 1000),
|
||||
Unregister: make(chan *Client, 1000),
|
||||
Broadcast: make(chan *WResponse, 1000),
|
||||
TagBroadcast: make(chan *TagWResponse, 1000),
|
||||
UserBroadcast: make(chan *UserWResponse, 1000),
|
||||
closeSignal: make(chan struct{}, 1),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Manager() *ClientManager {
|
||||
return clientManager
|
||||
}
|
||||
|
||||
// GetUserKey 获取用户key
|
||||
func GetUserKey(userId uint64) (key string) {
|
||||
key = fmt.Sprintf("%s_%d", "ws", userId)
|
||||
return
|
||||
}
|
||||
|
||||
// InClient 客户端是否存在
|
||||
func (manager *ClientManager) InClient(client *Client) (ok bool) {
|
||||
manager.ClientsLock.RLock()
|
||||
defer manager.ClientsLock.RUnlock()
|
||||
_, ok = manager.Clients[client]
|
||||
return
|
||||
}
|
||||
|
||||
// GetClients 获取所有客户端
|
||||
func (manager *ClientManager) GetClients() (clients map[*Client]bool) {
|
||||
clients = make(map[*Client]bool)
|
||||
manager.ClientsRange(func(client *Client, value bool) (result bool) {
|
||||
clients[client] = value
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// ClientsRange 遍历
|
||||
func (manager *ClientManager) ClientsRange(f func(client *Client, value bool) (result bool)) {
|
||||
manager.ClientsLock.RLock()
|
||||
defer manager.ClientsLock.RUnlock()
|
||||
for key, value := range manager.Clients {
|
||||
if !f(key, value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetClientsLen 获取客户端总数
|
||||
func (manager *ClientManager) GetClientsLen() (clientsLen int) {
|
||||
clientsLen = len(manager.Clients)
|
||||
return
|
||||
}
|
||||
|
||||
// AddClients 添加客户端
|
||||
func (manager *ClientManager) AddClients(client *Client) {
|
||||
manager.ClientsLock.Lock()
|
||||
defer manager.ClientsLock.Unlock()
|
||||
manager.Clients[client] = true
|
||||
}
|
||||
|
||||
// DelClients 删除客户端
|
||||
func (manager *ClientManager) DelClients(client *Client) {
|
||||
manager.ClientsLock.Lock()
|
||||
defer manager.ClientsLock.Unlock()
|
||||
delete(manager.Clients, client)
|
||||
}
|
||||
|
||||
// GetClient 通过socket ID获取客户端的连接
|
||||
func (manager *ClientManager) GetClient(id string) (client *Client) {
|
||||
for c := range manager.Clients {
|
||||
if c.ID == id {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserClient 获取用户的连接
|
||||
func (manager *ClientManager) GetUserClient(userId uint64) (clients []*Client) {
|
||||
manager.UserLock.RLock()
|
||||
defer manager.UserLock.RUnlock()
|
||||
userKey := GetUserKey(userId)
|
||||
if value, ok := manager.Users[userKey]; ok {
|
||||
clients = value
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddUsers 添加用户
|
||||
func (manager *ClientManager) AddUsers(key string, client *Client) {
|
||||
manager.UserLock.Lock()
|
||||
defer manager.UserLock.Unlock()
|
||||
manager.Users[key] = append(manager.Users[key], client)
|
||||
}
|
||||
|
||||
// DelUsers 删除用户
|
||||
func (manager *ClientManager) DelUsers(client *Client) (result bool) {
|
||||
manager.UserLock.Lock()
|
||||
defer manager.UserLock.Unlock()
|
||||
key := GetUserKey(client.User.Id)
|
||||
if clients, ok := manager.Users[key]; ok {
|
||||
for _, value := range clients {
|
||||
// 判断是否为相同的用户
|
||||
if value.Addr != client.Addr {
|
||||
return
|
||||
}
|
||||
delete(manager.Users, key)
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUsersLen 已登录用户数
|
||||
func (manager *ClientManager) GetUsersLen() (userLen int) {
|
||||
userLen = len(manager.Users)
|
||||
return
|
||||
}
|
||||
|
||||
// EventRegister 用户建立连接事件
|
||||
func (manager *ClientManager) EventRegister(client *Client) {
|
||||
manager.AddClients(client)
|
||||
// 用户登录
|
||||
manager.EventLogin(&login{
|
||||
UserId: client.User.Id,
|
||||
Client: client,
|
||||
})
|
||||
// 发送当前客户端标识
|
||||
// SendSuccess(client, "connected", g.Map{"id": client.ID, "userInfo": client.User})
|
||||
}
|
||||
|
||||
// EventLogin 用户登录事件
|
||||
func (manager *ClientManager) EventLogin(login *login) {
|
||||
client := login.Client
|
||||
if manager.InClient(client) {
|
||||
userKey := login.GetKey()
|
||||
manager.AddUsers(userKey, login.Client)
|
||||
}
|
||||
}
|
||||
|
||||
// EventUnregister 用户断开连接事件
|
||||
func (manager *ClientManager) EventUnregister(client *Client) {
|
||||
manager.DelClients(client)
|
||||
// 删除用户连接
|
||||
deleteResult := manager.DelUsers(client)
|
||||
if !deleteResult {
|
||||
// 不是当前连接的客户端
|
||||
return
|
||||
}
|
||||
|
||||
client.close()
|
||||
}
|
||||
|
||||
// ClearTimeoutConnections 定时清理超时连接
|
||||
func (manager *ClientManager) clearTimeoutConnections() {
|
||||
currentTime := uint64(gtime.Now().Unix())
|
||||
clients := clientManager.GetClients()
|
||||
for client := range clients {
|
||||
if client.IsHeartbeatTimeout(currentTime) {
|
||||
_ = client.Socket.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebsocketPing 心跳处理
|
||||
func (manager *ClientManager) ping() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Warningf(mctx, "websocket gcron ping recover:%+v, stack:%+v", r, string(debug.Stack()))
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
// 定时任务,发送心跳包
|
||||
// gcron.Add(ctx, "0 */1 * * * *", func(ctx context.Context) {
|
||||
// res := &WResponse{
|
||||
// Event: "ping",
|
||||
// Timestamp: gtime.Now().Unix(),
|
||||
// }
|
||||
// SendToAll(res)
|
||||
// })
|
||||
|
||||
// 定时任务,清理超时连接
|
||||
_, _ = gcron.Add(mctx, "*/30 * * * * *", func(ctx context.Context) {
|
||||
manager.clearTimeoutConnections()
|
||||
})
|
||||
}
|
||||
|
||||
// 管道处理程序
|
||||
func (manager *ClientManager) start() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Warningf(mctx, "websocket start recover:%+v, stack:%+v", r, string(debug.Stack()))
|
||||
return
|
||||
}
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case conn := <-manager.Register:
|
||||
// 建立连接事件
|
||||
manager.EventRegister(conn)
|
||||
case login := <-manager.Login:
|
||||
// 用户登录
|
||||
manager.EventLogin(login)
|
||||
|
||||
case conn := <-manager.Unregister:
|
||||
// 断开连接事件
|
||||
manager.EventUnregister(conn)
|
||||
|
||||
case message := <-manager.Broadcast:
|
||||
// 全部客户端广播事件
|
||||
clients := manager.GetClients()
|
||||
for conn := range clients {
|
||||
conn.SendMsg(message)
|
||||
}
|
||||
case message := <-manager.TagBroadcast:
|
||||
// 标签广播事件
|
||||
clients := manager.GetClients()
|
||||
for conn := range clients {
|
||||
if conn.Tags.Contains(message.Tag) {
|
||||
if message.WResponse.Timestamp == 0 {
|
||||
message.WResponse.Timestamp = gtime.Now().Timestamp()
|
||||
}
|
||||
conn.SendMsg(message.WResponse)
|
||||
}
|
||||
}
|
||||
case message := <-manager.UserBroadcast:
|
||||
// 用户广播事件
|
||||
clients := manager.GetClients()
|
||||
|
||||
for conn := range clients {
|
||||
if conn.User.Id == message.UserID {
|
||||
if message.WResponse.Timestamp == 0 {
|
||||
message.WResponse.Timestamp = gtime.Now().Timestamp()
|
||||
}
|
||||
conn.SendMsg(message.WResponse)
|
||||
}
|
||||
}
|
||||
case message := <-manager.ClientBroadcast:
|
||||
// 单个客户端广播事件
|
||||
clients := manager.GetClients()
|
||||
for conn := range clients {
|
||||
if conn.ID == message.ID {
|
||||
if message.WResponse.Timestamp == 0 {
|
||||
message.WResponse.Timestamp = gtime.Now().Timestamp()
|
||||
}
|
||||
conn.SendMsg(message.WResponse)
|
||||
}
|
||||
}
|
||||
case <-manager.closeSignal:
|
||||
g.Log().Debug(mctx, "websocket CloseSignal quit..")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SendToAll 发送全部客户端
|
||||
func SendToAll(response *WResponse) {
|
||||
clientManager.Broadcast <- response
|
||||
}
|
||||
|
||||
// SendToClientID 发送单个客户端
|
||||
func SendToClientID(id string, response *WResponse) {
|
||||
clientRes := &ClientWResponse{
|
||||
ID: id,
|
||||
WResponse: response,
|
||||
}
|
||||
clientManager.ClientBroadcast <- clientRes
|
||||
}
|
||||
|
||||
// SendToUser 发送单个用户
|
||||
func SendToUser(userID uint64, response *WResponse) {
|
||||
userRes := &UserWResponse{
|
||||
UserID: userID,
|
||||
WResponse: response,
|
||||
}
|
||||
clientManager.UserBroadcast <- userRes
|
||||
}
|
||||
|
||||
// SendToTag 发送某个标签
|
||||
func SendToTag(tag string, response *WResponse) {
|
||||
tagRes := &TagWResponse{
|
||||
Tag: tag,
|
||||
WResponse: response,
|
||||
}
|
||||
clientManager.TagBroadcast <- tagRes
|
||||
}
|
30
library/libWebsocket/init.go
Normal file
30
library/libWebsocket/init.go
Normal file
@ -0,0 +1,30 @@
|
||||
package libWebsocket
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/grpool"
|
||||
)
|
||||
|
||||
var (
|
||||
mctx = gctx.GetInitCtx() // 上下文
|
||||
clientManager = NewClientManager() // 客户端管理
|
||||
routers = make(map[string]EventHandler) // 消息路由
|
||||
msgGo = grpool.New(20) // 消息处理协程池
|
||||
)
|
||||
|
||||
// Start 启动
|
||||
func Start() {
|
||||
go clientManager.start()
|
||||
go clientManager.ping()
|
||||
g.Log().Debug(mctx, "start websocket..")
|
||||
}
|
||||
|
||||
// Stop 关闭
|
||||
func Stop() {
|
||||
clientManager.closeSignal <- struct{}{}
|
||||
}
|
||||
|
||||
func Register(client *Client) {
|
||||
clientManager.Register <- client
|
||||
}
|
38
library/libWebsocket/model.go
Normal file
38
library/libWebsocket/model.go
Normal file
@ -0,0 +1,38 @@
|
||||
package libWebsocket
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// WRequest 输入对象
|
||||
type WRequest struct {
|
||||
Event string `json:"event"` // 事件名称
|
||||
Data g.Map `json:"data"` // 数据
|
||||
}
|
||||
|
||||
// WResponse 输出对象
|
||||
type WResponse struct {
|
||||
Event string `json:"event"` // 事件名称
|
||||
Data interface{} `json:"data,omitempty"` // 数据
|
||||
Code int `json:"code"` // 状态码
|
||||
ErrorMsg string `json:"errorMsg,omitempty"` // 错误消息
|
||||
Timestamp int64 `json:"timestamp"` // 服务器时间
|
||||
}
|
||||
|
||||
type TagWResponse struct {
|
||||
Tag string
|
||||
WResponse *WResponse
|
||||
}
|
||||
|
||||
type UserWResponse struct {
|
||||
UserID uint64
|
||||
WResponse *WResponse
|
||||
}
|
||||
|
||||
type ClientWResponse struct {
|
||||
ID string
|
||||
WResponse *WResponse
|
||||
}
|
||||
|
||||
// EventHandler 消息处理器
|
||||
type EventHandler func(client *Client, req *WRequest)
|
||||
|
||||
type EventHandlers map[string]EventHandler
|
59
library/libWebsocket/router.go
Normal file
59
library/libWebsocket/router.go
Normal file
@ -0,0 +1,59 @@
|
||||
package libWebsocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
// handlerMsg 处理消息
|
||||
func handlerMsg(client *Client, message []byte) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
g.Log().Warningf(mctx, "handlerMsg recover, err:%+v, stack:%+v", r, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
var request *WRequest
|
||||
if err := gconv.Struct(message, &request); err != nil {
|
||||
g.Log().Warningf(mctx, "handlerMsg 数据解析失败,err:%+v, message:%+v", err, string(message))
|
||||
return
|
||||
}
|
||||
|
||||
if request.Event == "" {
|
||||
g.Log().Warning(mctx, "handlerMsg request.Event is null")
|
||||
return
|
||||
}
|
||||
|
||||
fun, ok := routers[request.Event]
|
||||
if !ok {
|
||||
g.Log().Warningf(mctx, "handlerMsg function id %v: not registered", request.Event)
|
||||
return
|
||||
}
|
||||
|
||||
err := msgGo.AddWithRecover(mctx,
|
||||
func(ctx context.Context) {
|
||||
fun(client, request)
|
||||
},
|
||||
func(ctx context.Context, err error) {
|
||||
g.Log().Warningf(mctx, "handlerMsg msgGo exec err:%+v", err)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
g.Log().Warningf(mctx, "handlerMsg msgGo Add err:%+v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterMsg 注册消息
|
||||
func RegisterMsg(handlers EventHandlers) {
|
||||
for id, f := range handlers {
|
||||
if _, ok := routers[id]; ok {
|
||||
g.Log().Fatalf(mctx, "RegisterMsg function id %v: already registered", id)
|
||||
return
|
||||
}
|
||||
routers[id] = f
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user