From b3569fad57e675d809439d549c8a7d58ec2ff51b Mon Sep 17 00:00:00 2001 From: chenlin Date: Fri, 27 Jun 2025 17:39:36 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E4=B9=8B=E5=89=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=8A=A5=E9=94=99=E6=97=B6=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=9B=9E=E6=BB=9A=EF=BC=8C=E6=9C=89=E9=A3=8E?= =?UTF-8?q?=E9=99=A9=EF=BC=8C=E5=B7=B2=E4=BC=98=E5=8C=96=EF=BC=9B=202?= =?UTF-8?q?=E3=80=81=E6=B7=BB=E5=8A=A0=E6=B6=88=E6=81=AF=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=88=E5=85=AC=E5=91=8A?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E3=80=81=E7=94=A8=E6=88=B7=E6=B6=88=E6=81=AF?= =?UTF-8?q?=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/inventorymanage/allot.go | 2 + app/admin/apis/inventorymanage/change.go | 2 + app/admin/apis/inventorymanage/product.go | 2 + app/admin/apis/message/bus_message.go | 23 + app/admin/apis/message/sys_message.go | 560 ++++++++++++++++ app/admin/apis/message/user_message.go | 110 ++++ app/admin/apis/purchasemanage/purchase.go | 2 + .../apis/purchasemanage/purchase_change.go | 2 + app/admin/apis/repair/repair.go | 2 + app/admin/models/message.go | 170 +++++ app/admin/router/message.go | 37 ++ app/admin/router/router.go | 2 + docs/docs.go | 610 ++++++++++++++++++ docs/swagger.json | 610 ++++++++++++++++++ docs/swagger.yaml | 423 ++++++++++++ 15 files changed, 2557 insertions(+) create mode 100644 app/admin/apis/message/bus_message.go create mode 100644 app/admin/apis/message/sys_message.go create mode 100644 app/admin/apis/message/user_message.go create mode 100644 app/admin/models/message.go create mode 100644 app/admin/router/message.go diff --git a/app/admin/apis/inventorymanage/allot.go b/app/admin/apis/inventorymanage/allot.go index 5b93443..0a90ae3 100644 --- a/app/admin/apis/inventorymanage/allot.go +++ b/app/admin/apis/inventorymanage/allot.go @@ -183,6 +183,7 @@ func InventoryAllotDelete(c *gin.Context) { // 1-删除采购订单表 err = begin.Delete(inventoryAllotOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -201,6 +202,7 @@ func InventoryAllotDelete(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/apis/inventorymanage/change.go b/app/admin/apis/inventorymanage/change.go index 96ec865..a24d18f 100644 --- a/app/admin/apis/inventorymanage/change.go +++ b/app/admin/apis/inventorymanage/change.go @@ -187,6 +187,7 @@ func InventoryChangeDelete(c *gin.Context) { // 1-删除采购订单表 err = begin.Delete(inventoryChangeOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -205,6 +206,7 @@ func InventoryChangeDelete(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/apis/inventorymanage/product.go b/app/admin/apis/inventorymanage/product.go index b73f019..f77bbca 100644 --- a/app/admin/apis/inventorymanage/product.go +++ b/app/admin/apis/inventorymanage/product.go @@ -181,6 +181,7 @@ func ProductInventoryDelete(c *gin.Context) { // 1-删除采购订单表 err = begin.Delete(inventoryProductOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -199,6 +200,7 @@ func ProductInventoryDelete(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/apis/message/bus_message.go b/app/admin/apis/message/bus_message.go new file mode 100644 index 0000000..7fa5da0 --- /dev/null +++ b/app/admin/apis/message/bus_message.go @@ -0,0 +1,23 @@ +package message + +import "github.com/gin-gonic/gin" + +func BusMessageCreate(c *gin.Context) { + +} + +func BusMessageSetStatus(c *gin.Context) { + +} + +func BusMessageDelete(c *gin.Context) { + +} + +func BusMessageList(c *gin.Context) { + +} + +func BusMessageEdit(c *gin.Context) { + +} diff --git a/app/admin/apis/message/sys_message.go b/app/admin/apis/message/sys_message.go new file mode 100644 index 0000000..6d64970 --- /dev/null +++ b/app/admin/apis/message/sys_message.go @@ -0,0 +1,560 @@ +package message + +import ( + "github.com/gin-gonic/gin" + "go-admin/app/admin/models" + orm "go-admin/common/global" + "go-admin/logger" + "go-admin/tools/app" + "net/http" + "time" +) + +// SysMessageCreate 新增公告消息 +// @Summary 新增公告消息 +// @Tags 消息中心,V1.5.0 +// @Produce json +// @Accept json +// @Param request body models.SysMessageCreateReq true "新增公告消息模型" +// @Success 200 {object} models.SysMessageCreateResp +// @Router /api/v1/sys_message/create [post] +func SysMessageCreate(c *gin.Context) { + var req models.SysMessageCreateReq + + // 1. 参数绑定 + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + // 2. 解析时间 + var startTimePtr, endTimePtr *time.Time + var parsedStartTime, parsedEndTime time.Time + var err error + + if req.StartTime != "" { + parsedStartTime, err = time.Parse("2006-01-02 15:04:05", req.StartTime) + if err != nil { + app.Error(c, http.StatusBadRequest, nil, "StartTime 格式错误,应为 YYYY-MM-DD HH:MM:SS:111") + return + } + startTimePtr = &parsedStartTime + } + + if req.EndTime != "" { + parsedEndTime, err = time.Parse("2006-01-02 15:04:05", req.EndTime) + if err != nil { + app.Error(c, http.StatusBadRequest, nil, "EndTime 格式错误,应为 YYYY-MM-DD HH:MM:SS") + return + } + endTimePtr = &parsedEndTime + } + + // 3. 插入 system_message_config(公告) + message := models.SystemMessageConfig{ + MessageType: models.AnnouncementMessageType, + Title: req.Title, + ContentTemplate: req.ContentTemplate, + Level: req.Level, + DisplayMode: req.DisplayMode, + StartTime: startTimePtr, + EndTime: endTimePtr, + Status: req.Status, + } + + if err = orm.Eloquent.Create(&message).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "创建公告失败: "+err.Error()) + return + } + + // 4. 插入 system_message_target + target := models.SystemMessageTarget{ + MessageConfigID: uint(message.ID), + TargetType: req.TargetType, + TargetID: req.TargetID, + } + if err = orm.Eloquent.Create(&target).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "接收对象配置失败: "+err.Error()) + return + } + + // 5. 判断是否需要立即下发用户消息 + needPushNow := (startTimePtr == nil || !parsedStartTime.After(time.Now())) && req.Status == 1 + if needPushNow { + var userIDs []int64 + + switch req.TargetType { + case models.TargetTypeByAll: // 全员 + err = orm.Eloquent.Table("sys_user").Where("deleted_at IS NULL").Pluck("user_id", &userIDs).Error + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "获取全员用户失败: "+err.Error()) + return + } + case models.TargetTypeByRole: // 角色 + err = orm.Eloquent.Table("sys_user"). + Where("role_id = ? AND deleted_at IS NULL", req.TargetID). + Pluck("user_id", &userIDs).Error + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "获取角色用户失败: "+err.Error()) + return + } + case models.TargetTypeByUser: // 单个用户 + if req.TargetID != 0 { + userIDs = []int64{req.TargetID} + } + default: + app.Error(c, http.StatusInternalServerError, nil, "接收对象类型有误,不在取值范围") + return + } + + // 构造 system_user_message 批量插入 + var userMessages []models.SystemUserMessage + for _, uid := range userIDs { + userMessages = append(userMessages, models.SystemUserMessage{ + UserID: uid, + MessageConfigID: uint(message.ID), + MessageType: models.AnnouncementMessageType, + Title: message.Title, + Content: message.ContentTemplate, + IsRead: false, + IsVisible: true, + }) + } + + if len(userMessages) > 0 { + if err = orm.Eloquent.Create(&userMessages).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "写入用户消息失败: "+err.Error()) + return + } + } + } + + // 6. 成功响应 + app.OK(c, models.SysMessageCreateResp{ID: message.ID}, "新增成功") +} + +// SysMessageEdit 编辑公告消息 +// @Summary 编辑公告消息(仅草稿可编辑) +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param request body models.SysMessageEditReq true "编辑公告消息模型" +// @Success 200 {object} models.SysMessageCreateResp +// @Router /api/v1/sys_message/edit [post] +func SysMessageEdit(c *gin.Context) { + var req models.SysMessageEditReq + + // 1. 参数绑定 + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + if req.ID == 0 { + app.Error(c, http.StatusBadRequest, nil, "参数错误: 缺少ID") + return + } + + // 2. 查询原公告(草稿) + var message models.SystemMessageConfig + if err := orm.Eloquent.Where("id = ? AND message_type = ?", req.ID, models.AnnouncementMessageType).First(&message).Error; err != nil { + app.Error(c, http.StatusBadRequest, nil, "公告不存在") + return + } + if message.Status != models.MessageStatusOnDraft { + app.Error(c, http.StatusBadRequest, nil, "仅草稿状态的公告可以编辑") + return + } + + // 3. 解析时间 + var startTimePtr, endTimePtr *time.Time + var parsedStartTime, parsedEndTime time.Time + var err error + + if req.StartTime != "" { + parsedStartTime, err = time.Parse("2006-01-02 15:04:05", req.StartTime) + if err != nil { + app.Error(c, http.StatusBadRequest, nil, "StartTime 格式错误,应为 YYYY-MM-DD HH:MM:SS") + return + } + startTimePtr = &parsedStartTime + } + if req.EndTime != "" { + parsedEndTime, err = time.Parse("2006-01-02 15:04:05", req.EndTime) + if err != nil { + app.Error(c, http.StatusBadRequest, nil, "EndTime 格式错误,应为 YYYY-MM-DD HH:MM:SS") + return + } + endTimePtr = &parsedEndTime + } + + begin := orm.Eloquent.Begin() + // 4. 更新公告主表 + update := map[string]interface{}{ + "title": req.Title, + "content_template": req.ContentTemplate, + "level": req.Level, + "display_mode": req.DisplayMode, + "start_time": startTimePtr, + "end_time": endTimePtr, + "status": req.Status, + } + if err := begin.Model(&models.SystemMessageConfig{}).Where("id = ?", req.ID).Updates(update).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "更新公告失败: "+err.Error()) + return + } + + // 5. 更新接收对象(删除再插入) + if err := begin.Where("message_config_id = ?", req.ID).Delete(&models.SystemMessageTarget{}).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "更新接收对象失败: "+err.Error()) + return + } + newTarget := models.SystemMessageTarget{ + MessageConfigID: req.ID, + TargetType: req.TargetType, + TargetID: req.TargetID, + } + if err := begin.Create(&newTarget).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "写入接收对象失败: "+err.Error()) + return + } + + err = begin.Commit().Error + if err != nil { + begin.Rollback() + logger.Error("SysMessageDelete commit err:", logger.Field("err", err)) + app.Error(c, http.StatusInternalServerError, nil, "编辑公告失败") + return + } + + // 6. 判断是否需要立即下发消息 + needPushNow := (startTimePtr == nil || !parsedStartTime.After(time.Now())) && req.Status == models.MessageStart + if needPushNow { + var userIDs []int64 + switch req.TargetType { + case models.TargetTypeByAll: + err = orm.Eloquent.Table("sys_user"). + Where("deleted_at IS NULL"). + Pluck("user_id", &userIDs).Error + case models.TargetTypeByRole: + err = orm.Eloquent.Table("sys_user"). + Where("role_id = ? AND deleted_at IS NULL", req.TargetID). + Pluck("user_id", &userIDs).Error + case models.TargetTypeByUser: + if req.TargetID != 0 { + userIDs = []int64{req.TargetID} + } + default: + app.Error(c, http.StatusInternalServerError, nil, "接收对象类型无效") + return + } + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "获取用户失败: "+err.Error()) + return + } + + // 构建用户消息记录 + var userMessages []models.SystemUserMessage + for _, uid := range userIDs { + userMessages = append(userMessages, models.SystemUserMessage{ + UserID: uid, + MessageConfigID: req.ID, + MessageType: models.AnnouncementMessageType, + Title: req.Title, + Content: req.ContentTemplate, + IsRead: false, + IsVisible: true, + }) + } + if len(userMessages) > 0 { + if err := orm.Eloquent.Create(&userMessages).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "写入用户消息失败: "+err.Error()) + return + } + } + } + + app.OK(c, models.SysMessageCreateResp{ID: uint32(req.ID)}, "编辑成功") +} + +// SysMessageSetStatus 设置公告状态(启用/禁用) +// @Summary 设置公告状态 +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param request body models.SysMessageSetStatusReq true "状态更新请求" +// @Success 200 {object} app.Response +// @Router /api/v1/sys_message/set_status [post] +func SysMessageSetStatus(c *gin.Context) { + var req models.SysMessageSetStatusReq + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + var config models.SystemMessageConfig + if err := orm.Eloquent.Where("id = ? AND message_type = ?", req.ID, 1).First(&config).Error; err != nil { + app.Error(c, http.StatusNotFound, nil, "公告不存在") + return + } + + // 校验状态切换合法性 + switch req.Status { + case 1: // 启用 + if config.Status != models.MessageStatusOnDraft && config.Status != models.MessageStatusOnDisable { + app.Error(c, http.StatusBadRequest, nil, "只有草稿或禁用状态才能启用") + return + } + case 2: // 禁用 + if config.Status != models.MessageStatusOnStart { + app.Error(c, http.StatusBadRequest, nil, "只有启用状态才能禁用") + return + } + default: + app.Error(c, http.StatusBadRequest, nil, "不支持的目标状态") + return + } + + // 状态更新 + if err := orm.Eloquent.Model(&config).Update("status", req.Status).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "状态更新失败") + return + } + + // 状态逻辑处理 + if req.Status == models.MessageStart { + // ✅ 启用逻辑:若 start_time 已开始 → 插入或恢复用户消息 + if config.StartTime == nil || config.StartTime.Before(time.Now()) { + var target models.SystemMessageTarget + if err := orm.Eloquent.Where("message_config_id = ?", config.ID).First(&target).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "接收对象未配置") + return + } + + var userIDs []int64 + switch target.TargetType { + case models.TargetTypeByAll: // 全员 + err := orm.Eloquent.Table("sys_user").Where("deleted_at IS NULL").Pluck("user_id", &userIDs).Error + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "获取全员用户失败: "+err.Error()) + return + } + case models.TargetTypeByRole: // 角色 + err := orm.Eloquent.Table("sys_user"). + Where("role_id = ? AND deleted_at IS NULL", target.TargetID). + Pluck("user_id", &userIDs).Error + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "获取角色用户失败: "+err.Error()) + return + } + case models.TargetTypeByUser: // 单个用户 + if target.TargetType != 0 { + userIDs = []int64{target.TargetID} + } + default: + app.Error(c, http.StatusInternalServerError, nil, "接收对象类型有误,不在取值范围") + return + } + + // 已存在的 user_id + var existedUserIDs []int64 + orm.Eloquent.Table("system_user_message"). + Where("message_config_id = ? AND user_id IN (?)", config.ID, userIDs). + Pluck("user_id", &existedUserIDs) + + existedSet := make(map[int64]struct{}) + for _, uid := range existedUserIDs { + existedSet[uid] = struct{}{} + } + + var toInsert []models.SystemUserMessage + var toUpdateIDs []int64 + + for _, uid := range userIDs { + if _, ok := existedSet[uid]; ok { + toUpdateIDs = append(toUpdateIDs, uid) + } else { + toInsert = append(toInsert, models.SystemUserMessage{ + UserID: uid, + MessageConfigID: uint(config.ID), + MessageType: 1, + Title: config.Title, + Content: config.ContentTemplate, + IsRead: false, + IsVisible: true, + }) + } + } + + if len(toInsert) > 0 { + _ = orm.Eloquent.Create(&toInsert).Error + } + if len(toUpdateIDs) > 0 { + _ = orm.Eloquent.Model(&models.SystemUserMessage{}). + Where("message_config_id = ? AND user_id IN (?)", config.ID, toUpdateIDs). + Update("is_visible", true).Error + } + } + } else if req.Status == models.MessageStop { + // ✅ 禁用逻辑:隐藏用户已发送的公告消息 + _ = orm.Eloquent.Model(&models.SystemUserMessage{}). + Where("message_config_id = ?", config.ID). + Update("is_visible", false).Error + } + + app.OK(c, nil, "状态更新成功") +} + +// SysMessageDelete 删除公告消息(草稿/禁用/过期状态可删) +// @Summary 删除公告消息 +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param request body models.SysMessageDeleteReq true "删除公告请求" +// @Success 200 {object} app.Response +// @Router /api/v1/sys_message/delete [post] +func SysMessageDelete(c *gin.Context) { + var req models.SysMessageDeleteReq + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + var config models.SystemMessageConfig + if err := orm.Eloquent.Where("id = ? AND message_type = ?", req.ID, models.AnnouncementMessageType). + First(&config).Error; err != nil { + app.Error(c, http.StatusNotFound, nil, "公告不存在") + return + } + + if config.Status != models.MessageStatusOnDraft && config.Status != models.MessageStatusOnDisable && + config.Status != models.MessageStatusOnExpire { + app.Error(c, http.StatusBadRequest, nil, "仅草稿、禁用、已过期状态可删除") + return + } + + begin := orm.Eloquent.Begin() + // 删除主配置(软删除) + if err := begin.Delete(&config).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "删除公告失败") + return + } + + // 删除接收对象配置 + if err := begin.Where("message_config_id = ?", config.ID). + Delete(&models.SystemMessageTarget{}).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "删除公告失败") + return + } + + // ✅ 更新用户消息为不可见(但保留) + if err := begin.Model(&models.SystemUserMessage{}). + Where("message_config_id = ?", config.ID). + Update("is_visible", false).Error; err != nil { + begin.Rollback() + app.Error(c, http.StatusInternalServerError, nil, "删除公告失败") + return + } + + err := begin.Commit().Error + if err != nil { + begin.Rollback() + logger.Error("SysMessageDelete commit err:", logger.Field("err", err)) + app.Error(c, http.StatusInternalServerError, nil, "删除公告失败") + return + } + + app.OK(c, nil, "删除成功") +} + +// SysMessageList 公告消息列表 +// @Summary 公告消息列表 +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param request body models.SysMessageListReq true "查询条件" +// @Success 200 {object} models.SysMessageListResp +// @Router /api/v1/sys_message/list [post] +func SysMessageList(c *gin.Context) { + var req models.SysMessageListReq + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + // 分页默认处理 + if req.Page <= 0 { + req.Page = 1 + } + if req.PageSize <= 0 { + req.PageSize = 10 + } + + db := orm.Eloquent.Table("system_message_config"). + Where("message_type = ?", 1) + + if req.Title != "" { + db = db.Where("title LIKE ?", "%"+req.Title+"%") + } + if req.Level != 0 { + db = db.Where("level = ?", req.Level) + } + if req.DisplayMode != 0 { + db = db.Where("display_mode = ?", req.DisplayMode) + } + if req.Status != 0 { + db = db.Where("status = ?", req.Status) + } + if req.TargetType != 0 { + subQuery := orm.Eloquent.Table("system_message_target"). + Select("message_config_id"). + Where("target_type = ?", req.TargetType) + db = db.Where("id IN (?)", subQuery) + } + + var total int64 + if err := db.Count(&total).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "统计失败: "+err.Error()) + return + } + + var list []models.SystemMessageConfig + if err := db. + Order("created_at DESC"). + Offset((req.Page - 1) * req.PageSize). + Limit(req.PageSize). + Find(&list).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "查询失败: "+err.Error()) + return + } + + // 转换为展示数据 + var items []models.SysAnnouncementItem + for _, cfg := range list { + items = append(items, models.SysAnnouncementItem{ + ID: cfg.ID, + Title: cfg.Title, + ContentTemplate: cfg.ContentTemplate, + Level: cfg.Level, + DisplayMode: cfg.DisplayMode, + StartTime: cfg.StartTime, + EndTime: cfg.EndTime, + Status: cfg.Status, + CreatedAt: cfg.CreatedAt, + UpdatedAt: cfg.UpdatedAt, + }) + } + + resp := models.SysMessageListResp{ + List: items, + Total: total, + Page: req.Page, + PageSize: req.PageSize, + } + + app.OK(c, resp, "查询成功") +} diff --git a/app/admin/apis/message/user_message.go b/app/admin/apis/message/user_message.go new file mode 100644 index 0000000..cbe070f --- /dev/null +++ b/app/admin/apis/message/user_message.go @@ -0,0 +1,110 @@ +package message + +import ( + "github.com/gin-gonic/gin" + "go-admin/app/admin/models" + orm "go-admin/common/global" + "go-admin/tools" + "go-admin/tools/app" + "net/http" + "time" +) + +// UserMessageList 用户消息列表 +// @Summary 用户消息列表 +// @Description 获取当前用户的消息记录 +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param data body models.UserMessageListReq true "消息查询参数" +// @Success 200 {object} models.UserMessageListResp +// @Router /api/v1/user_message/list [post] +func UserMessageList(c *gin.Context) { + var req models.UserMessageListReq + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + if req.Page <= 0 { + req.Page = 1 + } + if req.PageSize <= 0 { + req.PageSize = 10 + } + + userID := tools.GetUserId(c) + query := orm.Eloquent.Where("user_id = ? AND is_visible = ?", userID, true) + + if req.IsRead != 0 && req.IsRead != 1 { + app.Error(c, http.StatusBadRequest, nil, "不支持的目标状态") + return + } else { + query = query.Where("is_read = ?", req.IsRead) + } + + var total int64 + if err := query.Model(&models.SystemUserMessage{}).Count(&total).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "查询总数失败: "+err.Error()) + return + } + + var messages []models.SystemUserMessage + if err := query.Order("created_at desc"). + Offset((req.Page - 1) * req.PageSize). + Limit(req.PageSize). + Find(&messages).Error; err != nil { + app.Error(c, http.StatusInternalServerError, nil, "查询列表失败: "+err.Error()) + return + } + + app.OK(c, models.UserMessageListResp{ + List: messages, + Total: total, + Page: req.Page, + PageSize: req.PageSize, + }, "查询成功") +} + +// UserMessageSetStatus 设置用户消息为已读(支持单条或全部) +// @Summary 设置用户消息为已读 +// @Description 设为单条或全部已读 +// @Tags 消息中心,V1.5.0 +// @Accept json +// @Produce json +// @Param data body models.UserMessageSetStatusReq true "设置参数" +// @Success 200 {object} app.Response +// @Router /api/v1/user_message/set_status [post] +func UserMessageSetStatus(c *gin.Context) { + var req models.UserMessageSetStatusReq + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, http.StatusBadRequest, nil, "参数错误: "+err.Error()) + return + } + + userID := tools.GetUserId(c) + now := time.Now() + query := orm.Eloquent.Model(&models.SystemUserMessage{}). + Where("user_id = ? AND is_read = ?", userID, false) + + if req.ReadAll { + // 全部设为已读 + } else { + if req.ID == 0 { + app.Error(c, http.StatusBadRequest, nil, "参数错误: 未提供消息ID") + return + } + query = query.Where("id = ?", req.ID) + } + + err := query.Updates(map[string]interface{}{ + "is_read": true, + "read_time": &now, + }).Error + if err != nil { + app.Error(c, http.StatusInternalServerError, nil, "设置失败: "+err.Error()) + return + } + + app.OK(c, nil, "设置成功") +} diff --git a/app/admin/apis/purchasemanage/purchase.go b/app/admin/apis/purchasemanage/purchase.go index 8a3484d..2e0fdf3 100644 --- a/app/admin/apis/purchasemanage/purchase.go +++ b/app/admin/apis/purchasemanage/purchase.go @@ -518,6 +518,7 @@ func ErpPurchaseDelete(c *gin.Context) { // 1-删除采购订单表 err = begin.Delete(erpPurchaseOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -535,6 +536,7 @@ func ErpPurchaseDelete(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/apis/purchasemanage/purchase_change.go b/app/admin/apis/purchasemanage/purchase_change.go index 2e0c15b..1ad54f0 100644 --- a/app/admin/apis/purchasemanage/purchase_change.go +++ b/app/admin/apis/purchasemanage/purchase_change.go @@ -216,6 +216,7 @@ func ErpPurchaseChangeDelete(c *gin.Context) { // 1-删除采购订单表 err = begin.Delete(erpPurchaseChangeOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -233,6 +234,7 @@ func ErpPurchaseChangeDelete(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/apis/repair/repair.go b/app/admin/apis/repair/repair.go index cce4ee3..75d5776 100644 --- a/app/admin/apis/repair/repair.go +++ b/app/admin/apis/repair/repair.go @@ -178,6 +178,7 @@ func DeleteRepair(c *gin.Context) { // 1-删除维修订单表 err = begin.Delete(repairOrder).Error if err != nil { + begin.Rollback() logger.Error("order delete1 err:", logger.Field("err", err)) app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return @@ -195,6 +196,7 @@ func DeleteRepair(c *gin.Context) { if len(commodities) != 0 { err = begin.Delete(&commodities).Error if err != nil { + begin.Rollback() logger.Error("更新商品订单信息-删除 error") app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) return diff --git a/app/admin/models/message.go b/app/admin/models/message.go new file mode 100644 index 0000000..cd1f03e --- /dev/null +++ b/app/admin/models/message.go @@ -0,0 +1,170 @@ +package models + +import ( + "time" +) + +const ( + AnnouncementMessageType = 1 // 公告消息 + + TargetTypeByAll = 1 // 接收对象类型:1=全员 + TargetTypeByRole = 2 // 接收对象类型:2=角色 + TargetTypeByUser = 3 // 接收对象类型:3=用户 + + MessageStatusOnDraft = 0 // 草稿 + MessageStatusOnStart = 1 // 启用 + MessageStatusOnDisable = 2 // 禁用 + MessageStatusOnExpire = 3 // 已过期 + + MessageStart = 1 // 启用 + MessageStop = 2 // 禁用 +) + +// SystemMessageConfig 消息配置主表(公告 + 业务统一) +type SystemMessageConfig struct { + Model + + MessageType uint8 `json:"message_type"` // 消息类型:1=公告,2=业务 + Title string `json:"title"` // 消息标题 + ContentTemplate string `json:"content_template"` // 消息模板内容,支持{{变量}} + Level uint8 `json:"level"` // 消息等级:1=普通,2=重要,3=紧急 + DisplayMode uint8 `json:"display_mode"` // 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + StartTime *time.Time `json:"start_time,omitempty"` // 公告生效时间 + EndTime *time.Time `json:"end_time,omitempty"` // 公告失效时间 + BizType string `json:"biz_type,omitempty"` // 业务类型 + Event string `json:"event,omitempty"` // 事件类型 + Status uint8 `json:"status"` // 状态:0=草稿,1=启用,2=禁用,3=已过期 +} + +// SystemMessageTarget 接收对象配置表(支持角色/部门/用户/全员) +type SystemMessageTarget struct { + Model + + MessageConfigID uint `json:"message_config_id"` // 对应消息配置 ID + TargetType uint8 `json:"target_type"` // 接收对象类型:1=全员,2=角色,3=用户 + TargetID int64 `json:"target_id,omitempty"` // 对象ID(角色ID/用户ID) +} + +// SystemEventRegistry 业务事件注册表(用于事件枚举管理) +type SystemEventRegistry struct { + Model + + BizType string `json:"biz_type"` // 业务类型 + Event string `json:"event"` // 事件名 + BizName string `json:"biz_name"` // 业务名称(展示用) + EventName string `json:"event_name"` // 事件名称(展示用) + Description string `json:"description"` // 说明 + TemplateVariables string `json:"template_variables"` // 可用变量 JSON 字符串 + IsEnabled bool `json:"is_enabled"` // 是否启用 +} + +// SystemUserMessage 用户收到的消息记录表(实际发送记录) +type SystemUserMessage struct { + Model + + UserID int64 `json:"user_id"` // 接收用户ID + MessageConfigID uint `json:"message_config_id"` // 对应消息配置ID,可为空(被删时保留记录) + MessageType uint8 `json:"message_type"` // 消息类型:1=公告,2=业务 + Title string `json:"title"` // 消息标题快照 + Content string `json:"content"` // 渲染后内容 + IsRead bool `json:"is_read"` // 是否阅读 + ReadTime *time.Time `json:"read_time,omitempty"` // 阅读时间 + IsVisible bool `json:"is_visible"` // 是否展示给用户 +} + +// SysMessageCreateReq 新增公告请求结构体 +type SysMessageCreateReq struct { + Title string `json:"title" binding:"required"` // 消息标题 + ContentTemplate string `json:"content_template" binding:"required"` // 消息内容 + Level uint8 `json:"level" binding:"required,oneof=1 2 3"` // 消息等级:1=普通,2=重要,3=紧急 + DisplayMode uint8 `json:"display_mode" binding:"required,oneof=1 2 3"` // 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + StartTime string `json:"start_time,omitempty"` // 公告生效时间 + EndTime string `json:"end_time,omitempty"` // 公告失效时间 + Status uint8 `json:"status" binding:"required,oneof=0 1"` // 状态:0=草稿,1=启用 + TargetType uint8 `json:"target_type" binding:"required,oneof=1 2 3"` // 接收对象类型:1=全员,2=角色,3=用户 + TargetID int64 `json:"target_id,omitempty"` // 对象ID(角色ID/用户ID) +} + +// SysMessageCreateResp 创建成功响应 +type SysMessageCreateResp struct { + ID uint32 `json:"id"` +} + +// SysMessageEditReq 编辑公告消息-入参 +type SysMessageEditReq struct { + ID uint `json:"id" binding:"required"` // 公告ID(必须) + Title string `json:"title" binding:"required"` // 标题 + ContentTemplate string `json:"content_template" binding:"required"` // 内容模板 + Level uint8 `json:"level" binding:"required,oneof=1 2 3"` // 重要等级 + DisplayMode uint8 `json:"display_mode" binding:"required,oneof=1 2 3"` // 展示模式 + StartTime string `json:"start_time"` // 生效时间(可空) + EndTime string `json:"end_time"` // 失效时间(可空) + Status uint8 `json:"status" binding:"required,oneof=0 1"` // 状态:0 草稿、1 启用 + TargetType uint8 `json:"target_type" binding:"required,oneof=1 2 3"` // 接收对象类型:1=全员,2=角色,3=用户 + TargetID int64 `json:"target_id,omitempty"` // 接收对象ID +} + +// SysMessageListReq 公告消息列表-入参 +type SysMessageListReq struct { + Title string `form:"title"` // 消息标题 + Level uint8 `form:"level"` // 消息等级:1=普通,2=重要,3=紧急 + DisplayMode uint8 `form:"display_mode"` // 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + Status uint8 `form:"status"` // 状态:0=草稿,1=启用,2=禁用,3=已过期 + TargetType uint8 `form:"target_type"` // 从接收对象配置表中筛选 + Page int `form:"page,default=1"` // 页码 + PageSize int `form:"page_size,default=10"` // 每页条数 +} + +// SysMessageListResp 公告消息列表-出参 +type SysMessageListResp struct { + List []SysAnnouncementItem `json:"list"` + Total int64 `json:"total"` // 总条数 + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页条数 +} + +// SysAnnouncementItem 公告消息展示结构体 +type SysAnnouncementItem struct { + ID uint32 `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Title string `json:"title"` // 消息标题 + ContentTemplate string `json:"content_template"` // 消息内容 + Level uint8 `json:"level"` // 消息等级:1=普通,2=重要,3=紧急 + DisplayMode uint8 `json:"display_mode"` // 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + StartTime *time.Time `json:"start_time,omitempty"` // 公告生效时间 + EndTime *time.Time `json:"end_time,omitempty"` // 公告失效时间 + Status uint8 `json:"status"` // 状态:0=草稿,1=启用,2=禁用,3=已过期 +} + +// SysMessageSetStatusReq 设置公告消息状态 +type SysMessageSetStatusReq struct { + ID uint `json:"id" binding:"required"` + Status uint8 `json:"status" binding:"required"` // 目标状态:1=启用,2=禁用 +} + +// SysMessageDeleteReq 删除公告消息 +type SysMessageDeleteReq struct { + ID uint `json:"id" binding:"required"` +} + +// UserMessageListReq 用户消息列表-入参 +type UserMessageListReq struct { + IsRead int `json:"is_read"` // 0-未读;1-已读 + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页数量 +} + +// UserMessageListResp 用户消息列表-出参 +type UserMessageListResp struct { + List []SystemUserMessage `json:"list"` + Total int64 `json:"total"` + Page int `json:"page"` + PageSize int `json:"page_size"` +} + +// UserMessageSetStatusReq 用户阅读消息-入参 +type UserMessageSetStatusReq struct { + ID uint `json:"id"` // 消息ID(可选,read_all 为 false 时必传) + ReadAll bool `json:"read_all"` // 是否设为全部已读 +} diff --git a/app/admin/router/message.go b/app/admin/router/message.go new file mode 100644 index 0000000..35c0b71 --- /dev/null +++ b/app/admin/router/message.go @@ -0,0 +1,37 @@ +package router + +import ( + "github.com/gin-gonic/gin" + "go-admin/app/admin/apis/message" + "go-admin/app/admin/middleware" + jwt "go-admin/pkg/jwtauth" +) + +func registerMessageCenterRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + // 公告消息(列表、新增、启用/禁用、删除) + r1 := v1.Group("/sys_message").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + r1.POST("create", message.SysMessageCreate) // 新增 + r1.POST("edit", message.SysMessageEdit) // 编辑 + r1.POST("set_status", message.SysMessageSetStatus) // 启用/禁用 + r1.POST("delete", message.SysMessageDelete) // 删除 + r1.POST("list", message.SysMessageList) // 查询列表 + } + + // 业务消息(列表、新增、编辑、启用/禁用、删除) + r2 := v1.Group("/bus_message").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + r2.POST("create", message.BusMessageCreate) // 新增 + r2.POST("edit", message.BusMessageEdit) // 编辑 + r2.POST("delete", message.BusMessageDelete) // 删除 + r2.POST("list", message.BusMessageList) // 查询列表 + r2.POST("set_status", message.BusMessageSetStatus) // 启用/禁用 + } + + // 用户消息中心(列表、详情、阅读) + r3 := v1.Group("/user_message").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + r3.POST("list", message.UserMessageList) // 列表 + r3.POST("set_status", message.UserMessageSetStatus) // 阅读 + } +} diff --git a/app/admin/router/router.go b/app/admin/router/router.go index cf3fdd1..37513df 100644 --- a/app/admin/router/router.go +++ b/app/admin/router/router.go @@ -119,4 +119,6 @@ func examplesCheckRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddle registerMarketingManageRouter(v1, authMiddleware) // 维修管理 registerRepairRouter(v1, authMiddleware) + // 消息中心 + registerMessageCenterRouter(v1, authMiddleware) } diff --git a/docs/docs.go b/docs/docs.go index 7bab0d2..40c00b1 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -7267,6 +7267,171 @@ const docTemplate = `{ } } }, + "/api/v1/sys_message/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "新增公告消息", + "parameters": [ + { + "description": "新增公告消息模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageCreateReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageCreateResp" + } + } + } + } + }, + "/api/v1/sys_message/delete": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "删除公告消息", + "parameters": [ + { + "description": "删除公告请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/sys_message/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "编辑公告消息(仅草稿可编辑)", + "parameters": [ + { + "description": "编辑公告消息模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageEditReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageCreateResp" + } + } + } + } + }, + "/api/v1/sys_message/list": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "公告消息列表", + "parameters": [ + { + "description": "查询条件", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageListReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageListResp" + } + } + } + } + }, + "/api/v1/sys_message/set_status": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "设置公告状态", + "parameters": [ + { + "description": "状态更新请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageSetStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/syscategory": { "post": { "description": "获取JSON", @@ -7697,6 +7862,74 @@ const docTemplate = `{ } } }, + "/api/v1/user_message/list": { + "post": { + "description": "获取当前用户的消息记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "用户消息列表", + "parameters": [ + { + "description": "消息查询参数", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.UserMessageListReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.UserMessageListResp" + } + } + } + } + }, + "/api/v1/user_message/set_status": { + "post": { + "description": "设为单条或全部已读", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "设置用户消息为已读", + "parameters": [ + { + "description": "设置参数", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.UserMessageSetStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/login": { "post": { "description": "获取token\nLoginHandler can be used by clients to get a jwt token.\nPayload needs to be json in the form of {\"username\": \"USERNAME\", \"password\": \"PASSWORD\"}.\nReply will be of the form {\"token\": \"TOKEN\"}.\ndev mode:It should be noted that all fields cannot be empty, and a value of 0 can be passed in addition to the account password\n注意:开发模式:需要注意全部字段不能为空,账号密码外可以传入0值", @@ -8315,6 +8548,10 @@ const docTemplate = `{ "description": "每页条数", "type": "integer" }, + "sort_type": { + "description": "排序类型:desc 降序、asc 升序", + "type": "string" + }, "start_time": { "description": "开始时间", "type": "string" @@ -21000,6 +21237,48 @@ const docTemplate = `{ } } }, + "models.SysAnnouncementItem": { + "type": "object", + "properties": { + "content_template": { + "description": "消息内容", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer" + }, + "end_time": { + "description": "公告失效时间", + "type": "string" + }, + "id": { + "type": "integer" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer" + }, + "start_time": { + "description": "公告生效时间", + "type": "string" + }, + "status": { + "description": "状态:0=草稿,1=启用,2=禁用,3=已过期", + "type": "integer" + }, + "title": { + "description": "消息标题", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "models.SysCategory": { "type": "object", "properties": { @@ -21296,6 +21575,238 @@ const docTemplate = `{ } } }, + "models.SysMessageCreateReq": { + "type": "object", + "required": [ + "content_template", + "display_mode", + "level", + "status", + "target_type", + "title" + ], + "properties": { + "content_template": { + "description": "消息内容", + "type": "string" + }, + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "end_time": { + "description": "公告失效时间", + "type": "string" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "start_time": { + "description": "公告生效时间", + "type": "string" + }, + "status": { + "description": "状态:0=草稿,1=启用", + "type": "integer", + "enum": [ + 0, + 1 + ] + }, + "target_id": { + "description": "对象ID(角色ID/用户ID)", + "type": "integer" + }, + "target_type": { + "description": "接收对象类型:1=全员,2=角色,3=用户", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "title": { + "description": "消息标题", + "type": "string" + } + } + }, + "models.SysMessageCreateResp": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "models.SysMessageDeleteReq": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + } + } + }, + "models.SysMessageEditReq": { + "type": "object", + "required": [ + "content_template", + "display_mode", + "id", + "level", + "status", + "target_type", + "title" + ], + "properties": { + "content_template": { + "description": "内容模板", + "type": "string" + }, + "display_mode": { + "description": "展示模式", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "end_time": { + "description": "失效时间(可空)", + "type": "string" + }, + "id": { + "description": "公告ID(必须)", + "type": "integer" + }, + "level": { + "description": "重要等级", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "start_time": { + "description": "生效时间(可空)", + "type": "string" + }, + "status": { + "description": "状态:0 草稿、1 启用", + "type": "integer", + "enum": [ + 0, + 1 + ] + }, + "target_id": { + "description": "接收对象ID", + "type": "integer" + }, + "target_type": { + "description": "接收对象类型:1=全员,2=角色,3=用户", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "title": { + "description": "标题", + "type": "string" + } + } + }, + "models.SysMessageListReq": { + "type": "object", + "properties": { + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页条数", + "type": "integer" + }, + "status": { + "description": "状态:0=草稿,1=启用,2=禁用,3=已过期", + "type": "integer" + }, + "target_type": { + "description": "从接收对象配置表中筛选", + "type": "integer" + }, + "title": { + "description": "消息标题", + "type": "string" + } + } + }, + "models.SysMessageListResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SysAnnouncementItem" + } + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页条数", + "type": "integer" + }, + "total": { + "description": "总条数", + "type": "integer" + } + } + }, + "models.SysMessageSetStatusReq": { + "type": "object", + "required": [ + "id", + "status" + ], + "properties": { + "id": { + "type": "integer" + }, + "status": { + "description": "目标状态:1=启用,2=禁用", + "type": "integer" + } + } + }, "models.SysOperLog": { "type": "object", "properties": { @@ -21765,6 +22276,55 @@ const docTemplate = `{ } } }, + "models.SystemUserMessage": { + "type": "object", + "properties": { + "content": { + "description": "渲染后内容", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "is_read": { + "description": "是否阅读", + "type": "boolean" + }, + "is_visible": { + "description": "是否展示给用户", + "type": "boolean" + }, + "message_config_id": { + "description": "对应消息配置ID,可为空(被删时保留记录)", + "type": "integer" + }, + "message_type": { + "description": "消息类型:1=公告,2=业务", + "type": "integer" + }, + "read_time": { + "description": "阅读时间", + "type": "string" + }, + "title": { + "description": "消息标题快照", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "user_id": { + "description": "接收用户ID", + "type": "integer" + } + } + }, "models.TableData": { "type": "object", "properties": { @@ -22230,6 +22790,56 @@ const docTemplate = `{ } } }, + "models.UserMessageListReq": { + "type": "object", + "properties": { + "is_read": { + "description": "0-未读;1-已读", + "type": "integer" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页数量", + "type": "integer" + } + } + }, + "models.UserMessageListResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SystemUserMessage" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "models.UserMessageSetStatusReq": { + "type": "object", + "properties": { + "id": { + "description": "消息ID(可选,read_all 为 false 时必传)", + "type": "integer" + }, + "read_all": { + "description": "是否设为全部已读", + "type": "boolean" + } + } + }, "models.UserShareCard": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index b249f85..f85b695 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -7256,6 +7256,171 @@ } } }, + "/api/v1/sys_message/create": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "新增公告消息", + "parameters": [ + { + "description": "新增公告消息模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageCreateReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageCreateResp" + } + } + } + } + }, + "/api/v1/sys_message/delete": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "删除公告消息", + "parameters": [ + { + "description": "删除公告请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/sys_message/edit": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "编辑公告消息(仅草稿可编辑)", + "parameters": [ + { + "description": "编辑公告消息模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageEditReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageCreateResp" + } + } + } + } + }, + "/api/v1/sys_message/list": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "公告消息列表", + "parameters": [ + { + "description": "查询条件", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageListReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.SysMessageListResp" + } + } + } + } + }, + "/api/v1/sys_message/set_status": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "设置公告状态", + "parameters": [ + { + "description": "状态更新请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.SysMessageSetStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/syscategory": { "post": { "description": "获取JSON", @@ -7686,6 +7851,74 @@ } } }, + "/api/v1/user_message/list": { + "post": { + "description": "获取当前用户的消息记录", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "用户消息列表", + "parameters": [ + { + "description": "消息查询参数", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.UserMessageListReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.UserMessageListResp" + } + } + } + } + }, + "/api/v1/user_message/set_status": { + "post": { + "description": "设为单条或全部已读", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "消息中心,V1.5.0" + ], + "summary": "设置用户消息为已读", + "parameters": [ + { + "description": "设置参数", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.UserMessageSetStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/login": { "post": { "description": "获取token\nLoginHandler can be used by clients to get a jwt token.\nPayload needs to be json in the form of {\"username\": \"USERNAME\", \"password\": \"PASSWORD\"}.\nReply will be of the form {\"token\": \"TOKEN\"}.\ndev mode:It should be noted that all fields cannot be empty, and a value of 0 can be passed in addition to the account password\n注意:开发模式:需要注意全部字段不能为空,账号密码外可以传入0值", @@ -8304,6 +8537,10 @@ "description": "每页条数", "type": "integer" }, + "sort_type": { + "description": "排序类型:desc 降序、asc 升序", + "type": "string" + }, "start_time": { "description": "开始时间", "type": "string" @@ -20989,6 +21226,48 @@ } } }, + "models.SysAnnouncementItem": { + "type": "object", + "properties": { + "content_template": { + "description": "消息内容", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer" + }, + "end_time": { + "description": "公告失效时间", + "type": "string" + }, + "id": { + "type": "integer" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer" + }, + "start_time": { + "description": "公告生效时间", + "type": "string" + }, + "status": { + "description": "状态:0=草稿,1=启用,2=禁用,3=已过期", + "type": "integer" + }, + "title": { + "description": "消息标题", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "models.SysCategory": { "type": "object", "properties": { @@ -21285,6 +21564,238 @@ } } }, + "models.SysMessageCreateReq": { + "type": "object", + "required": [ + "content_template", + "display_mode", + "level", + "status", + "target_type", + "title" + ], + "properties": { + "content_template": { + "description": "消息内容", + "type": "string" + }, + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "end_time": { + "description": "公告失效时间", + "type": "string" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "start_time": { + "description": "公告生效时间", + "type": "string" + }, + "status": { + "description": "状态:0=草稿,1=启用", + "type": "integer", + "enum": [ + 0, + 1 + ] + }, + "target_id": { + "description": "对象ID(角色ID/用户ID)", + "type": "integer" + }, + "target_type": { + "description": "接收对象类型:1=全员,2=角色,3=用户", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "title": { + "description": "消息标题", + "type": "string" + } + } + }, + "models.SysMessageCreateResp": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "models.SysMessageDeleteReq": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + } + } + }, + "models.SysMessageEditReq": { + "type": "object", + "required": [ + "content_template", + "display_mode", + "id", + "level", + "status", + "target_type", + "title" + ], + "properties": { + "content_template": { + "description": "内容模板", + "type": "string" + }, + "display_mode": { + "description": "展示模式", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "end_time": { + "description": "失效时间(可空)", + "type": "string" + }, + "id": { + "description": "公告ID(必须)", + "type": "integer" + }, + "level": { + "description": "重要等级", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "start_time": { + "description": "生效时间(可空)", + "type": "string" + }, + "status": { + "description": "状态:0 草稿、1 启用", + "type": "integer", + "enum": [ + 0, + 1 + ] + }, + "target_id": { + "description": "接收对象ID", + "type": "integer" + }, + "target_type": { + "description": "接收对象类型:1=全员,2=角色,3=用户", + "type": "integer", + "enum": [ + 1, + 2, + 3 + ] + }, + "title": { + "description": "标题", + "type": "string" + } + } + }, + "models.SysMessageListReq": { + "type": "object", + "properties": { + "display_mode": { + "description": "展示方式:1=弹窗,2=滚动,3=弹窗+滚动", + "type": "integer" + }, + "level": { + "description": "消息等级:1=普通,2=重要,3=紧急", + "type": "integer" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页条数", + "type": "integer" + }, + "status": { + "description": "状态:0=草稿,1=启用,2=禁用,3=已过期", + "type": "integer" + }, + "target_type": { + "description": "从接收对象配置表中筛选", + "type": "integer" + }, + "title": { + "description": "消息标题", + "type": "string" + } + } + }, + "models.SysMessageListResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SysAnnouncementItem" + } + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页条数", + "type": "integer" + }, + "total": { + "description": "总条数", + "type": "integer" + } + } + }, + "models.SysMessageSetStatusReq": { + "type": "object", + "required": [ + "id", + "status" + ], + "properties": { + "id": { + "type": "integer" + }, + "status": { + "description": "目标状态:1=启用,2=禁用", + "type": "integer" + } + } + }, "models.SysOperLog": { "type": "object", "properties": { @@ -21754,6 +22265,55 @@ } } }, + "models.SystemUserMessage": { + "type": "object", + "properties": { + "content": { + "description": "渲染后内容", + "type": "string" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "id": { + "description": "数据库记录编号", + "type": "integer" + }, + "is_read": { + "description": "是否阅读", + "type": "boolean" + }, + "is_visible": { + "description": "是否展示给用户", + "type": "boolean" + }, + "message_config_id": { + "description": "对应消息配置ID,可为空(被删时保留记录)", + "type": "integer" + }, + "message_type": { + "description": "消息类型:1=公告,2=业务", + "type": "integer" + }, + "read_time": { + "description": "阅读时间", + "type": "string" + }, + "title": { + "description": "消息标题快照", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "user_id": { + "description": "接收用户ID", + "type": "integer" + } + } + }, "models.TableData": { "type": "object", "properties": { @@ -22219,6 +22779,56 @@ } } }, + "models.UserMessageListReq": { + "type": "object", + "properties": { + "is_read": { + "description": "0-未读;1-已读", + "type": "integer" + }, + "page": { + "description": "页码", + "type": "integer" + }, + "page_size": { + "description": "每页数量", + "type": "integer" + } + } + }, + "models.UserMessageListResp": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SystemUserMessage" + } + }, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "models.UserMessageSetStatusReq": { + "type": "object", + "properties": { + "id": { + "description": "消息ID(可选,read_all 为 false 时必传)", + "type": "integer" + }, + "read_all": { + "description": "是否设为全部已读", + "type": "boolean" + } + } + }, "models.UserShareCard": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 1bba6c8..772fe20 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -399,6 +399,9 @@ definitions: page_size: description: 每页条数 type: integer + sort_type: + description: 排序类型:desc 降序、asc 升序 + type: string start_time: description: 开始时间 type: string @@ -9588,6 +9591,36 @@ definitions: description: 开户银行 type: string type: object + models.SysAnnouncementItem: + properties: + content_template: + description: 消息内容 + type: string + created_at: + type: string + display_mode: + description: 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + type: integer + end_time: + description: 公告失效时间 + type: string + id: + type: integer + level: + description: 消息等级:1=普通,2=重要,3=紧急 + type: integer + start_time: + description: 公告生效时间 + type: string + status: + description: 状态:0=草稿,1=启用,2=禁用,3=已过期 + type: integer + title: + description: 消息标题 + type: string + updated_at: + type: string + type: object models.SysCategory: properties: createBy: @@ -9801,6 +9834,177 @@ definitions: description: 更新时间 type: string type: object + models.SysMessageCreateReq: + properties: + content_template: + description: 消息内容 + type: string + display_mode: + description: 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + enum: + - 1 + - 2 + - 3 + type: integer + end_time: + description: 公告失效时间 + type: string + level: + description: 消息等级:1=普通,2=重要,3=紧急 + enum: + - 1 + - 2 + - 3 + type: integer + start_time: + description: 公告生效时间 + type: string + status: + description: 状态:0=草稿,1=启用 + enum: + - 0 + - 1 + type: integer + target_id: + description: 对象ID(角色ID/用户ID) + type: integer + target_type: + description: 接收对象类型:1=全员,2=角色,3=用户 + enum: + - 1 + - 2 + - 3 + type: integer + title: + description: 消息标题 + type: string + required: + - content_template + - display_mode + - level + - status + - target_type + - title + type: object + models.SysMessageCreateResp: + properties: + id: + type: integer + type: object + models.SysMessageDeleteReq: + properties: + id: + type: integer + required: + - id + type: object + models.SysMessageEditReq: + properties: + content_template: + description: 内容模板 + type: string + display_mode: + description: 展示模式 + enum: + - 1 + - 2 + - 3 + type: integer + end_time: + description: 失效时间(可空) + type: string + id: + description: 公告ID(必须) + type: integer + level: + description: 重要等级 + enum: + - 1 + - 2 + - 3 + type: integer + start_time: + description: 生效时间(可空) + type: string + status: + description: 状态:0 草稿、1 启用 + enum: + - 0 + - 1 + type: integer + target_id: + description: 接收对象ID + type: integer + target_type: + description: 接收对象类型:1=全员,2=角色,3=用户 + enum: + - 1 + - 2 + - 3 + type: integer + title: + description: 标题 + type: string + required: + - content_template + - display_mode + - id + - level + - status + - target_type + - title + type: object + models.SysMessageListReq: + properties: + display_mode: + description: 展示方式:1=弹窗,2=滚动,3=弹窗+滚动 + type: integer + level: + description: 消息等级:1=普通,2=重要,3=紧急 + type: integer + page: + description: 页码 + type: integer + page_size: + description: 每页条数 + type: integer + status: + description: 状态:0=草稿,1=启用,2=禁用,3=已过期 + type: integer + target_type: + description: 从接收对象配置表中筛选 + type: integer + title: + description: 消息标题 + type: string + type: object + models.SysMessageListResp: + properties: + list: + items: + $ref: '#/definitions/models.SysAnnouncementItem' + type: array + page: + description: 页码 + type: integer + page_size: + description: 每页条数 + type: integer + total: + description: 总条数 + type: integer + type: object + models.SysMessageSetStatusReq: + properties: + id: + type: integer + status: + description: 目标状态:1=启用,2=禁用 + type: integer + required: + - id + - status + type: object models.SysOperLog: properties: businessType: @@ -10143,6 +10347,42 @@ definitions: description: 用户名 type: string type: object + models.SystemUserMessage: + properties: + content: + description: 渲染后内容 + type: string + createdAt: + description: 创建时间 + type: string + id: + description: 数据库记录编号 + type: integer + is_read: + description: 是否阅读 + type: boolean + is_visible: + description: 是否展示给用户 + type: boolean + message_config_id: + description: 对应消息配置ID,可为空(被删时保留记录) + type: integer + message_type: + description: 消息类型:1=公告,2=业务 + type: integer + read_time: + description: 阅读时间 + type: string + title: + description: 消息标题快照 + type: string + updatedAt: + description: 更新时间 + type: string + user_id: + description: 接收用户ID + type: integer + type: object models.TableData: properties: DJ: @@ -10482,6 +10722,40 @@ definitions: description: 总条数 type: integer type: object + models.UserMessageListReq: + properties: + is_read: + description: 0-未读;1-已读 + type: integer + page: + description: 页码 + type: integer + page_size: + description: 每页数量 + type: integer + type: object + models.UserMessageListResp: + properties: + list: + items: + $ref: '#/definitions/models.SystemUserMessage' + type: array + page: + type: integer + page_size: + type: integer + total: + type: integer + type: object + models.UserMessageSetStatusReq: + properties: + id: + description: 消息ID(可选,read_all 为 false 时必传) + type: integer + read_all: + description: 是否设为全部已读 + type: boolean + type: object models.UserShareCard: properties: allot_card_goods_id: @@ -15277,6 +15551,111 @@ paths: summary: 分页列表数据 tags: - system/工具 + /api/v1/sys_message/create: + post: + consumes: + - application/json + parameters: + - description: 新增公告消息模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.SysMessageCreateReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SysMessageCreateResp' + summary: 新增公告消息 + tags: + - 消息中心,V1.5.0 + /api/v1/sys_message/delete: + post: + consumes: + - application/json + parameters: + - description: 删除公告请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.SysMessageDeleteReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 删除公告消息 + tags: + - 消息中心,V1.5.0 + /api/v1/sys_message/edit: + post: + consumes: + - application/json + parameters: + - description: 编辑公告消息模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.SysMessageEditReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SysMessageCreateResp' + summary: 编辑公告消息(仅草稿可编辑) + tags: + - 消息中心,V1.5.0 + /api/v1/sys_message/list: + post: + consumes: + - application/json + parameters: + - description: 查询条件 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.SysMessageListReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.SysMessageListResp' + summary: 公告消息列表 + tags: + - 消息中心,V1.5.0 + /api/v1/sys_message/set_status: + post: + consumes: + - application/json + parameters: + - description: 状态更新请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.SysMessageSetStatusReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 设置公告状态 + tags: + - 消息中心,V1.5.0 /api/v1/sysUser: get: description: 获取JSON @@ -15663,6 +16042,50 @@ paths: summary: 查询会员手机号 tags: - 用户信息 + /api/v1/user_message/list: + post: + consumes: + - application/json + description: 获取当前用户的消息记录 + parameters: + - description: 消息查询参数 + in: body + name: data + required: true + schema: + $ref: '#/definitions/models.UserMessageListReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.UserMessageListResp' + summary: 用户消息列表 + tags: + - 消息中心,V1.5.0 + /api/v1/user_message/set_status: + post: + consumes: + - application/json + description: 设为单条或全部已读 + parameters: + - description: 设置参数 + in: body + name: data + required: true + schema: + $ref: '#/definitions/models.UserMessageSetStatusReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 设置用户消息为已读 + tags: + - 消息中心,V1.5.0 /login: post: consumes: