All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m23s
新增 000225 迁移:运营弹窗配置表 tb_h5_popup_configuration(页面/范围/优先级/频率/受控动作/启停/有效期/版本) 与 tb_notification 可空 JSONB 列 popup_snapshot。 新增通知直建窄接口 DirectWriter.CreateOrGetPersonal:与 Outbox 消费共用 prepareDelivery 的渲染、 展示期与 CreateIdempotent 规则,冲突时回查返回既有行;同步扩展个人通知查询与已读两处类型白名单, 并按个人客户入口补齐投递审计来源。 新增 H5 候选与风险换卡:GET /api/c/v1/popup-candidates 先判风险资格(广电卡 + 风险停机 + 无活动物流换货单),命中只返回风险候选;未命中再按时间/启停/页面/店铺/设备类型/卡类型范围/频率 匹配运营配置。POST /api/c/v1/risk-exchanges/:asset_id/address 锁资产行后幂等创建待发货物流换货单, 首次地址锁定,不沿用资产级群发通知。 新增后台运营弹窗配置 CRUD 与启停(仅超级管理员与平台账号),更新递增版本并刷新最近更新时间, 标题与正文统一拒绝 URL 与前端路由,全部写操作记录操作者、前后值、版本与时间。 同步 OpenAPI(cmd/gendocs、cmd/api/docs.go、pkg/openapi/handlers.go)与参数校验中文提示共用实现。
31 lines
2.1 KiB
Go
31 lines
2.1 KiB
Go
package model
|
||
|
||
import "time"
|
||
|
||
// Notification 是站内通知的 PostgreSQL 持久化事实。
|
||
type Notification struct {
|
||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||
EventID string `gorm:"column:event_id;type:varchar(64);not null;uniqueIndex:uq_notification_event_recipient,priority:1" json:"event_id"`
|
||
RecipientKind string `gorm:"column:recipient_kind;type:varchar(32);not null;uniqueIndex:uq_notification_event_recipient,priority:2" json:"recipient_kind"`
|
||
RecipientID uint `gorm:"column:recipient_id;not null;uniqueIndex:uq_notification_event_recipient,priority:3" json:"recipient_id"`
|
||
Category string `gorm:"column:category;type:varchar(32);not null" json:"category"`
|
||
Type string `gorm:"column:type;type:varchar(100);not null" json:"type"`
|
||
Severity string `gorm:"column:severity;type:varchar(16);not null" json:"severity"`
|
||
Title string `gorm:"column:title;type:varchar(200);not null" json:"title"`
|
||
Body string `gorm:"column:body;type:text;not null" json:"body"`
|
||
RefType string `gorm:"column:ref_type;type:varchar(64);not null;default:''" json:"ref_type"`
|
||
RefID string `gorm:"column:ref_id;type:varchar(128);not null;default:''" json:"ref_id"`
|
||
RefKey string `gorm:"column:ref_key;type:varchar(128);not null;default:''" json:"ref_key"`
|
||
IsRead bool `gorm:"column:is_read;not null;default:false" json:"is_read"`
|
||
ReadAt *time.Time `gorm:"column:read_at;type:timestamptz" json:"read_at,omitempty"`
|
||
ExpiresAt *time.Time `gorm:"column:expires_at;type:timestamptz" json:"expires_at,omitempty"`
|
||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||
// PopupSnapshot 只由弹窗投放类型(h5.popup.risk_exchange、h5.popup.operation)写入,其他通知类型保持 NULL。
|
||
PopupSnapshot *NotificationPopupSnapshot `gorm:"column:popup_snapshot;type:jsonb" json:"popup_snapshot,omitempty"`
|
||
}
|
||
|
||
// TableName 返回站内通知表名。
|
||
func (Notification) TableName() string {
|
||
return "tb_notification"
|
||
}
|