github.com/SupenBysz/gf-admin-community@v0.7.4/internal/logic/sys_message/sys_message.go (about) 1 package sys_message 2 3 import ( 4 "context" 5 "github.com/SupenBysz/gf-admin-community/sys_model" 6 "github.com/SupenBysz/gf-admin-community/sys_model/sys_dao" 7 "github.com/SupenBysz/gf-admin-community/sys_model/sys_do" 8 "github.com/SupenBysz/gf-admin-community/sys_model/sys_entity" 9 "github.com/SupenBysz/gf-admin-community/sys_model/sys_enum" 10 "github.com/SupenBysz/gf-admin-community/sys_model/sys_hook" 11 "github.com/SupenBysz/gf-admin-community/sys_service" 12 "github.com/gogf/gf/v2/container/garray" 13 "github.com/gogf/gf/v2/database/gdb" 14 "github.com/gogf/gf/v2/frame/g" 15 "github.com/gogf/gf/v2/os/gtime" 16 "github.com/gogf/gf/v2/util/gconv" 17 "github.com/kysion/base-library/base_hook" 18 "github.com/kysion/base-library/base_model" 19 "github.com/kysion/base-library/utility/daoctl" 20 "github.com/kysion/base-library/utility/kconv" 21 "github.com/yitter/idgenerator-go/idgen" 22 ) 23 24 type sMessage struct { 25 MessageHook base_hook.BaseHook[sys_enum.MessageType, sys_hook.MessageTypeHookFunc] 26 } 27 28 func NewMessage() sys_service.IMessage { 29 return &sMessage{} 30 } 31 32 func init() { 33 sys_service.RegisterMessage(NewMessage()) 34 } 35 36 // GetMessageById 根据id查询消息 37 func (s *sMessage) GetMessageById(ctx context.Context, id int64) (*sys_model.SysMessageRes, error) { 38 result, err := daoctl.GetByIdWithError[sys_entity.SysMessage](sys_dao.SysMessage.Ctx(ctx), id) 39 if err != nil { 40 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "根据id查询消息失败"+err.Error(), sys_dao.SysMessage.Table()) 41 } 42 43 // 业务层 Hook处理渲染,如果没有Hook的话,那就直接格式化成默认的个人资质 44 s.MessageHook.Iterator(func(key sys_enum.MessageType, value sys_hook.MessageTypeHookFunc) { 45 // 判断注入的Hook业务类型是否一致 46 if key.Code()&result.Type == result.Type { 47 // 业务类型一致则调用注入的Hook函数 48 g.Try(ctx, func(ctx context.Context) { 49 err = value(ctx, sys_enum.Message.State.New(result.Type), (*sys_model.SysMessageRes)(result)) 50 }) 51 } 52 }) 53 54 return (*sys_model.SysMessageRes)(result), err 55 } 56 57 // GetMessageDetailById 根据id查询消息详情 58 func (s *sMessage) GetMessageDetailById(ctx context.Context, messageId, userId int64) (*sys_model.SysMessageRes, error) { 59 result, err := daoctl.GetByIdWithError[sys_entity.SysMessage](sys_dao.SysMessage.Ctx(ctx), messageId) 60 if err != nil { 61 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "根据id查询消息失败"+err.Error(), sys_dao.SysMessage.Table()) 62 } 63 64 // TODO 修改消息状态,改变为已读 65 //_, err = s.SetMessageState(ctx, id, unionMainId, sys_enum.Message.State.Readed) 66 //if err != nil { 67 // return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "根据id查询消息详情失败"+err.Error(), sys_dao.SysMessage.Table()) 68 //} 69 70 // TODO 直接追加消息的已读用户 71 _, err = s.SetMessageReadUserIds(ctx, messageId, userId) 72 if err != nil { 73 return nil, err 74 } 75 76 return (*sys_model.SysMessageRes)(result), nil 77 } 78 79 // CreateMessage 添加消息 80 func (s *sMessage) CreateMessage(ctx context.Context, info *sys_model.SysMessage) (*sys_model.SysMessageRes, error) { 81 // 订阅附加数据 82 83 //ctx = base_funs.AttrBuilder[co_model.IEmployeeRes, co_model.IEmployeeRes](ctx, co_dao.CompanyEmployee.Columns().Id) //toUserId不但是学生、可以是老师 84 85 //ctx = base_funs.AttrBuilder[sys_model.SysUser, *sys_entity.SysUserDetail](ctx, sys_dao.SysUser.Columns().Id) 86 87 idStrArr, err := s.checkUser(ctx, info.ToUserIds) 88 if err != nil { 89 return nil, err 90 } 91 92 data := kconv.Struct(info, &sys_do.SysMessage{}) 93 data.Id = idgen.NextId() 94 95 if len(idStrArr) > 0 { 96 slice := garray.NewStrArrayFrom(idStrArr).Unique().Slice() 97 data.ToUserIds = slice 98 } 99 100 // 赋值接收者类型 101 //data.ToUserType = employee.Data().User.Type 102 // 未读状态 103 //data.State = sys_enum.Message.State.UnRead.Code() 104 105 if info.ExtJson == "" { 106 data.ExtJson = nil 107 } 108 109 err = sys_dao.SysMessage.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { 110 data.CreatedAt = gtime.Now() 111 affected, err := daoctl.InsertWithError(sys_dao.SysMessage.Ctx(ctx).Data(data)) 112 113 if affected == 0 || err != nil { 114 return sys_service.SysLogs().ErrorSimple(ctx, err, "添加消息失败"+err.Error(), sys_dao.SysMessage.Table()) 115 } 116 117 return nil 118 }) 119 120 if err != nil { 121 return nil, err 122 } 123 124 return s.GetMessageById(ctx, gconv.Int64(data.Id)) 125 } 126 127 // UpdateMessage 编辑消息 (限制是还未发送的) 128 func (s *sMessage) UpdateMessage(ctx context.Context, id int64, info *sys_model.UpdateSysMessage) (*sys_model.SysMessageRes, error) { 129 //var employee co_model.IEmployeeRes 130 var err error 131 132 // 判断消息是否存在 133 message, err := s.GetMessageById(ctx, id) 134 if err != nil || message == nil { 135 return nil, err 136 } 137 138 // 判断消息状态,只有未发送的消息支持编辑 139 if message.SendAt != nil { 140 return nil, sys_service.SysLogs().ErrorSimple(ctx, nil, "只有未发送的消息支持编辑", sys_dao.SysMessage.Table()) 141 } 142 143 // 消息接受者是否全部存在 144 idStrArr, err := s.checkUser(ctx, info.ToUserIds) 145 146 if err != nil { 147 return nil, err 148 } 149 data := kconv.Struct(info, &sys_do.SysMessage{}) 150 if len(idStrArr) > 0 { 151 slice := garray.NewStrArrayFrom(idStrArr).Unique().Slice() 152 data.ToUserIds = slice 153 } else { 154 data.ToUserIds = nil 155 } 156 157 if info.ExtJson == "" { 158 data.ExtJson = nil 159 } 160 161 err = sys_dao.SysMessage.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { 162 affected, err := daoctl.UpdateWithError(sys_dao.SysMessage.Ctx(ctx).Where( 163 sys_do.SysMessage{ 164 Id: id, 165 }, 166 ).OmitNilData().Data(data)) 167 168 if affected == 0 || err != nil { 169 return sys_service.SysLogs().ErrorSimple(ctx, err, "信息修改失败"+err.Error(), sys_dao.SysMessage.Table()) 170 } 171 172 return nil 173 }) 174 175 if err != nil { 176 return nil, err 177 } 178 179 return s.GetMessageById(ctx, gconv.Int64(id)) 180 } 181 182 // QueryMessage 查询消息列表 183 func (s *sMessage) QueryMessage(ctx context.Context, params *base_model.SearchParams, isExport bool) (*sys_model.SysMessageListRes, error) { 184 if ¶ms.Pagination == nil { 185 params.Pagination = base_model.Pagination{ 186 PageNum: 1, 187 PageSize: 20, 188 } 189 } 190 191 params.Filter = append(params.Filter, base_model.FilterInfo{ 192 Field: sys_dao.SysMessage.Columns().Id, 193 Where: ">", 194 IsOrWhere: false, 195 Value: 0, 196 IsNullValue: false, 197 }) 198 199 res, err := daoctl.Query[sys_model.SysMessageRes](sys_dao.SysMessage.Ctx(ctx), params, isExport) 200 201 if err != nil { 202 return &sys_model.SysMessageListRes{}, sys_service.SysLogs().ErrorSimple(ctx, err, "消息列表查询失败"+err.Error(), sys_dao.SysMessage.Table()) 203 } 204 205 return (*sys_model.SysMessageListRes)(res), nil 206 } 207 208 // QueryUserMessage 查询指定用户的消息|列表 209 func (s *sMessage) QueryUserMessage(ctx context.Context, userId int64, params *base_model.SearchParams, isExport bool) (*sys_model.SysMessageListRes, error) { 210 211 res, err := daoctl.Query[sys_model.SysMessageRes](sys_dao.SysMessage.Ctx(ctx). 212 WhereLike(sys_dao.SysMessage.Columns().ToUserIds, "%"+gconv.String(userId)+"%"), 213 214 params, isExport) 215 216 if err != nil { 217 return &sys_model.SysMessageListRes{}, sys_service.SysLogs().ErrorSimple(ctx, err, "消息列表查询失败"+err.Error(), sys_dao.SysMessage.Table()) 218 } 219 220 return (*sys_model.SysMessageListRes)(res), nil 221 } 222 223 // QueryUnionMainMessage 查询指定主体发送的消息列表 (支持未发送消息列表,添加params参数) 224 func (s *sMessage) QueryUnionMainMessage(ctx context.Context, unionMainId int64, params *base_model.SearchParams, isExport bool) (*sys_model.SysMessageListRes, error) { 225 res, err := daoctl.Query[sys_model.SysMessageRes](sys_dao.SysMessage.Ctx(ctx).Where(sys_do.SysMessage{ 226 FromUserId: unionMainId, 227 //SendAt: nil, 228 }), params, isExport) 229 230 if err != nil { 231 return &sys_model.SysMessageListRes{}, sys_service.SysLogs().ErrorSimple(ctx, err, "消息列表查询失败"+err.Error(), sys_dao.SysMessage.Table()) 232 } 233 234 return (*sys_model.SysMessageListRes)(res), nil 235 } 236 237 // HasUnReadMessage 是否存在未读消息 238 func (s *sMessage) HasUnReadMessage(ctx context.Context, userId int64) (int, error) { 239 240 count, err := sys_dao.SysMessage.Ctx(ctx). 241 WhereLike(sys_dao.SysMessage.Columns().ToUserIds, "%"+gconv.String(userId)+"%"). 242 WhereNotLike(sys_dao.SysMessage.Columns().ReadUserIds, "%"+gconv.String(userId)+"%"). 243 Count() 244 245 if err != nil { 246 return 0, sys_service.SysLogs().ErrorSimple(ctx, err, "查询未读的消息失败"+err.Error(), sys_dao.SysMessage.Table()) 247 248 } 249 return count, nil 250 } 251 252 //// SetMessageState 设置消息状态 有已读UserIds,就不需要消息状态了 253 //func (s *sMessage) setMessageState(ctx context.Context, id, unionMainId int64, state sys_enum.MessageState) (bool, error) { 254 // affected, err := daoctl.UpdateWithError(sys_dao.SysMessage.Ctx(ctx).Where(sys_do.SysMessage{ 255 // Id: id, 256 // FromUserId: unionMainId, 257 // }).Data(sys_do.SysMessage{ 258 // State: state.Code(), 259 // ReadAt: gtime.Now(), 260 // })) 261 // 262 // if affected == 0 || err != nil { 263 // return false, sys_service.SysLogs().ErrorSimple(ctx, err, "消息状态修改失败"+err.Error(), sys_dao.SysMessage.Table()) 264 // } 265 // 266 // return affected > 0, nil 267 //} 268 269 // SetMessageReadUserIds 追加公告已读用户 270 func (s *sMessage) SetMessageReadUserIds(ctx context.Context, messageId int64, userId int64) (bool, error) { 271 message, err := s.GetMessageById(ctx, messageId) 272 if err != nil { 273 return false, err 274 } 275 var ids []string 276 gconv.Struct(message.ReadUserIds, &ids) 277 278 //oldArr := garray.NewSortedStrArrayFrom(ids).Unique().Slice() 279 280 arr := garray.NewSortedStrArrayFrom( 281 append([]string{gconv.String(userId)}, ids...)).Unique().Slice() 282 283 affected, err := daoctl.UpdateWithError(sys_dao.SysMessage.Ctx(ctx).Where(sys_do.SysMessage{Id: messageId}).Data(sys_do.SysMessage{ReadUserIds: arr})) 284 285 if err != nil || affected <= 0 { 286 return false, sys_service.SysLogs().ErrorSimple(ctx, err, "追加公告已读用户失败"+err.Error(), sys_dao.SysMessage.Table()) 287 } 288 289 return affected > 0, nil 290 } 291 292 // checkUser 校验消息接受者toUserIds是否全部存在 293 func (s *sMessage) checkUser(ctx context.Context, toUserIds []int64) (idStrArr []string, err error) { 294 for _, userId := range toUserIds { 295 idStrArr = append(idStrArr, gconv.String(userId)) 296 sysUser, err := sys_service.SysUser().GetSysUserById(ctx, userId) 297 if err != nil || sysUser == nil { 298 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "消息接收者中有用户不存在", sys_dao.SysMessage.Table()) 299 } 300 } 301 302 return idStrArr, err 303 }