| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package daytask
- import (
- "app/commons/model/entity"
- "app/commons/services"
- "github.com/gin-gonic/gin"
- )
- // NoticeList 消息列表
- func (s *Server) NoticeList(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- noticeType := ctx.QueryString("type", "") // system/task/wallet/team
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- query := db.Model(&entity.DtNotice{}).
- Where("(user_id = ? OR user_id = 0) AND status = ?", userId, 1)
- if noticeType != "" {
- query = query.Where("type = ?", noticeType)
- }
- query.Count(&paging.Total)
- paging.Computer()
- type NoticeInfo struct {
- Id int64 `json:"id"`
- Title string `json:"title"`
- Content string `json:"content"`
- Type string `json:"type"`
- IsRead int8 `json:"isRead"`
- CreatedAt int64 `json:"createdAt"`
- }
- notices := make([]*NoticeInfo, 0)
- query.Select("id, title, content, type, is_read, created_at").
- Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Scan(¬ices)
- // 对于全局通知(user_id=0),批量查询已读状态(避免N+1)
- unreadIds := make([]int64, 0)
- for _, n := range notices {
- if n.IsRead == 0 {
- unreadIds = append(unreadIds, n.Id)
- }
- }
- if len(unreadIds) > 0 {
- var readRecords []entity.DtNoticeRead
- db.Where("user_id = ? AND notice_id IN ?", userId, unreadIds).Find(&readRecords)
- readMap := make(map[int64]bool)
- for _, r := range readRecords {
- readMap[r.NoticeId] = true
- }
- for _, n := range notices {
- if n.IsRead == 0 && readMap[n.Id] {
- n.IsRead = 1
- }
- }
- }
- ctx.OK(gin.H{
- "list": notices,
- "paging": paging,
- })
- }
- // NoticeRead 标记消息已读
- func (s *Server) NoticeRead(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type Req struct {
- Id int64 `json:"id" form:"id" binding:"required"`
- }
- var req Req
- if err := c.ShouldBind(&req); err != nil {
- ctx.Fail("invalid_params")
- return
- }
- // 查询通知
- var notice entity.DtNotice
- if err := db.Where("id = ?", req.Id).First(¬ice).Error; err != nil {
- ctx.Fail("notice_not_found")
- return
- }
- if notice.UserId == 0 {
- // 全局通知:写入关联表记录已读
- readRecord := &entity.DtNoticeRead{
- UserId: userId,
- NoticeId: req.Id,
- }
- db.Where("user_id = ? AND notice_id = ?", userId, req.Id).
- FirstOrCreate(readRecord)
- } else {
- // 个人通知:直接更新
- db.Model(&entity.DtNotice{}).
- Where("id = ? AND user_id = ?", req.Id, userId).
- Update("is_read", 1)
- }
- ctx.OK(gin.H{})
- }
- // NoticeReadAll 标记所有消息已读
- func (s *Server) NoticeReadAll(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- noticeType := ctx.QueryString("type", "")
- // 1. 更新个人通知
- personalQuery := db.Model(&entity.DtNotice{}).
- Where("user_id = ? AND is_read = ?", userId, 0)
- if noticeType != "" {
- personalQuery = personalQuery.Where("type = ?", noticeType)
- }
- personalQuery.Update("is_read", 1)
- // 2. 全局通知:查出未读的全局通知,批量写入关联表
- globalQuery := db.Model(&entity.DtNotice{}).
- Where("user_id = 0 AND status = 1")
- if noticeType != "" {
- globalQuery = globalQuery.Where("type = ?", noticeType)
- }
- var globalNotices []entity.DtNotice
- globalQuery.Select("id").Find(&globalNotices)
- for _, n := range globalNotices {
- readRecord := &entity.DtNoticeRead{
- UserId: userId,
- NoticeId: n.Id,
- }
- db.Where("user_id = ? AND notice_id = ?", userId, n.Id).
- FirstOrCreate(readRecord)
- }
- ctx.OK(gin.H{})
- }
- // NoticeUnread 未读消息数量
- func (s *Server) NoticeUnread(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- // 个人未读通知数
- var personalCount int64
- db.Model(&entity.DtNotice{}).
- Where("user_id = ? AND is_read = ? AND status = ?", userId, 0, 1).
- Count(&personalCount)
- // 全局未读通知数(排除已在关联表中标记已读的)
- var globalCount int64
- db.Model(&entity.DtNotice{}).
- Where("user_id = 0 AND status = 1").
- Where("id NOT IN (SELECT notice_id FROM dt_notice_read WHERE user_id = ?)", userId).
- Count(&globalCount)
- total := personalCount + globalCount
- ctx.OK(gin.H{
- "personal": personalCount,
- "global": globalCount,
- "total": total,
- })
- }
- // NoticeDelete 删除消息
- func (s *Server) NoticeDelete(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type Req struct {
- Id int64 `json:"id" form:"id" binding:"required"`
- }
- var req Req
- if err := c.ShouldBind(&req); err != nil {
- ctx.Fail("invalid_params")
- return
- }
- // 只能删除自己的消息(全局通知不可删除)
- db.Where("id = ? AND user_id = ?", req.Id, userId).Delete(&entity.DtNotice{})
- ctx.OK(gin.H{})
- }
|