添加公告表及相关处理逻辑,支持公告列表查询

This commit is contained in:
2025-05-07 16:48:02 +08:00
parent 1738570c2b
commit 60bbe47368
7 changed files with 494 additions and 1 deletions

View File

@@ -84,6 +84,36 @@ comment on column admin_role.created_at is '创建时间';
comment on column admin_role.updated_at is '更新时间';
comment on column admin_role.deleted_at is '删除时间';
-- announcement
drop table if exists announcement cascade;
create table announcement (
id serial primary key,
title varchar(255) not null,
content text,
type int not null default 1,
pin bool not null default false,
status int not null default 1,
sort int not null default 0,
created_at timestamp default current_timestamp,
updated_at timestamp default current_timestamp,
deleted_at timestamp
);
create index announcement_status_index on announcement (status);
create index announcement_deleted_at_index on announcement (deleted_at);
-- announcement表字段注释
comment on table announcement is '公告表';
comment on column announcement.id is '公告ID';
comment on column announcement.title is '公告标题';
comment on column announcement.content is '公告内容';
comment on column announcement.type is '公告类型1-普通公告';
comment on column announcement.status is '公告状态0-禁用1-正常';
comment on column announcement.pin is '是否置顶';
comment on column announcement.sort is '公告排序';
comment on column announcement.created_at is '创建时间';
comment on column announcement.updated_at is '更新时间';
comment on column announcement.deleted_at is '删除时间';
-- endregion
-- ====================

View File

@@ -0,0 +1,64 @@
package handlers
import (
"github.com/gofiber/fiber/v2"
"platform/web/auth"
"platform/web/common"
q "platform/web/queries"
"platform/web/services"
)
// region ListAnnouncements
type ListAnnouncementsRequest struct {
common.PageReq
}
func ListAnnouncements(c *fiber.Ctx) error {
// 检查权限
_, err := auth.Protect(c, []services.PayloadType{services.PayloadUser}, []string{})
if err != nil {
return err
}
// 解析请求参数
req := new(ListAnnouncementsRequest)
if err := c.BodyParser(req); err != nil {
return err
}
// 查询公告
do := q.Announcement.
Where(q.Announcement.Status.Eq(1))
list, err := q.Announcement.
Where(do).
Offset(req.GetOffset()).
Limit(req.GetLimit()).
Order(q.Announcement.CreatedAt.Desc()).
Find()
if err != nil {
return err
}
var total int64
if len(list) < req.GetLimit() {
total = int64(len(list) + req.GetOffset())
} else {
total, err = q.Announcement.Where(do).Count()
if err != nil {
return err
}
}
// 返回结果
return c.JSON(common.PageResp{
Total: int(total),
List: list,
Page: req.GetPage(),
Size: req.GetSize(),
})
}
// endregion

View File

@@ -38,7 +38,7 @@ func ListWhitelist(c *fiber.Ctx) error {
return err
}
// 获取用户信息
// 获取白名单信息
do := q.Whitelist.
Where(q.Whitelist.UserID.Eq(authContext.Payload.Id))

View File

@@ -0,0 +1,32 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package models
import (
"platform/web/common"
"gorm.io/gorm"
)
const TableNameAnnouncement = "announcement"
// Announcement mapped from table <announcement>
type Announcement struct {
CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
Type int32 `gorm:"column:type;not null;default:1" json:"type"`
Status int32 `gorm:"column:status;not null;default:1" json:"status"`
Sort int32 `gorm:"column:sort;not null" json:"sort"`
Pin bool `gorm:"column:pin;not null" json:"pin"`
Title string `gorm:"column:title;not null" json:"title"`
Content string `gorm:"column:content;not null" json:"content"`
}
// TableName Announcement's table name
func (*Announcement) TableName() string {
return TableNameAnnouncement
}

View File

@@ -0,0 +1,355 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package queries
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"platform/web/models"
)
func newAnnouncement(db *gorm.DB, opts ...gen.DOOption) announcement {
_announcement := announcement{}
_announcement.announcementDo.UseDB(db, opts...)
_announcement.announcementDo.UseModel(&models.Announcement{})
tableName := _announcement.announcementDo.TableName()
_announcement.ALL = field.NewAsterisk(tableName)
_announcement.CreatedAt = field.NewField(tableName, "created_at")
_announcement.UpdatedAt = field.NewField(tableName, "updated_at")
_announcement.DeletedAt = field.NewField(tableName, "deleted_at")
_announcement.ID = field.NewInt32(tableName, "id")
_announcement.Type = field.NewInt32(tableName, "type")
_announcement.Status = field.NewInt32(tableName, "status")
_announcement.Sort = field.NewInt32(tableName, "sort")
_announcement.Pin = field.NewBool(tableName, "pin")
_announcement.Title = field.NewString(tableName, "title")
_announcement.Content = field.NewString(tableName, "content")
_announcement.fillFieldMap()
return _announcement
}
type announcement struct {
announcementDo
ALL field.Asterisk
CreatedAt field.Field
UpdatedAt field.Field
DeletedAt field.Field
ID field.Int32
Type field.Int32
Status field.Int32
Sort field.Int32
Pin field.Bool
Title field.String
Content field.String
fieldMap map[string]field.Expr
}
func (a announcement) Table(newTableName string) *announcement {
a.announcementDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a announcement) As(alias string) *announcement {
a.announcementDo.DO = *(a.announcementDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *announcement) updateTableName(table string) *announcement {
a.ALL = field.NewAsterisk(table)
a.CreatedAt = field.NewField(table, "created_at")
a.UpdatedAt = field.NewField(table, "updated_at")
a.DeletedAt = field.NewField(table, "deleted_at")
a.ID = field.NewInt32(table, "id")
a.Type = field.NewInt32(table, "type")
a.Status = field.NewInt32(table, "status")
a.Sort = field.NewInt32(table, "sort")
a.Pin = field.NewBool(table, "pin")
a.Title = field.NewString(table, "title")
a.Content = field.NewString(table, "content")
a.fillFieldMap()
return a
}
func (a *announcement) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *announcement) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 10)
a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["updated_at"] = a.UpdatedAt
a.fieldMap["deleted_at"] = a.DeletedAt
a.fieldMap["id"] = a.ID
a.fieldMap["type"] = a.Type
a.fieldMap["status"] = a.Status
a.fieldMap["sort"] = a.Sort
a.fieldMap["pin"] = a.Pin
a.fieldMap["title"] = a.Title
a.fieldMap["content"] = a.Content
}
func (a announcement) clone(db *gorm.DB) announcement {
a.announcementDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a announcement) replaceDB(db *gorm.DB) announcement {
a.announcementDo.ReplaceDB(db)
return a
}
type announcementDo struct{ gen.DO }
func (a announcementDo) Debug() *announcementDo {
return a.withDO(a.DO.Debug())
}
func (a announcementDo) WithContext(ctx context.Context) *announcementDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a announcementDo) ReadDB() *announcementDo {
return a.Clauses(dbresolver.Read)
}
func (a announcementDo) WriteDB() *announcementDo {
return a.Clauses(dbresolver.Write)
}
func (a announcementDo) Session(config *gorm.Session) *announcementDo {
return a.withDO(a.DO.Session(config))
}
func (a announcementDo) Clauses(conds ...clause.Expression) *announcementDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a announcementDo) Returning(value interface{}, columns ...string) *announcementDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a announcementDo) Not(conds ...gen.Condition) *announcementDo {
return a.withDO(a.DO.Not(conds...))
}
func (a announcementDo) Or(conds ...gen.Condition) *announcementDo {
return a.withDO(a.DO.Or(conds...))
}
func (a announcementDo) Select(conds ...field.Expr) *announcementDo {
return a.withDO(a.DO.Select(conds...))
}
func (a announcementDo) Where(conds ...gen.Condition) *announcementDo {
return a.withDO(a.DO.Where(conds...))
}
func (a announcementDo) Order(conds ...field.Expr) *announcementDo {
return a.withDO(a.DO.Order(conds...))
}
func (a announcementDo) Distinct(cols ...field.Expr) *announcementDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a announcementDo) Omit(cols ...field.Expr) *announcementDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a announcementDo) Join(table schema.Tabler, on ...field.Expr) *announcementDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a announcementDo) LeftJoin(table schema.Tabler, on ...field.Expr) *announcementDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a announcementDo) RightJoin(table schema.Tabler, on ...field.Expr) *announcementDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a announcementDo) Group(cols ...field.Expr) *announcementDo {
return a.withDO(a.DO.Group(cols...))
}
func (a announcementDo) Having(conds ...gen.Condition) *announcementDo {
return a.withDO(a.DO.Having(conds...))
}
func (a announcementDo) Limit(limit int) *announcementDo {
return a.withDO(a.DO.Limit(limit))
}
func (a announcementDo) Offset(offset int) *announcementDo {
return a.withDO(a.DO.Offset(offset))
}
func (a announcementDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *announcementDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a announcementDo) Unscoped() *announcementDo {
return a.withDO(a.DO.Unscoped())
}
func (a announcementDo) Create(values ...*models.Announcement) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a announcementDo) CreateInBatches(values []*models.Announcement, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a announcementDo) Save(values ...*models.Announcement) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a announcementDo) First() (*models.Announcement, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*models.Announcement), nil
}
}
func (a announcementDo) Take() (*models.Announcement, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*models.Announcement), nil
}
}
func (a announcementDo) Last() (*models.Announcement, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*models.Announcement), nil
}
}
func (a announcementDo) Find() ([]*models.Announcement, error) {
result, err := a.DO.Find()
return result.([]*models.Announcement), err
}
func (a announcementDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Announcement, err error) {
buf := make([]*models.Announcement, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a announcementDo) FindInBatches(result *[]*models.Announcement, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a announcementDo) Attrs(attrs ...field.AssignExpr) *announcementDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a announcementDo) Assign(attrs ...field.AssignExpr) *announcementDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a announcementDo) Joins(fields ...field.RelationField) *announcementDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a announcementDo) Preload(fields ...field.RelationField) *announcementDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a announcementDo) FirstOrInit() (*models.Announcement, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*models.Announcement), nil
}
}
func (a announcementDo) FirstOrCreate() (*models.Announcement, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*models.Announcement), nil
}
}
func (a announcementDo) FindByPage(offset int, limit int) (result []*models.Announcement, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a announcementDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a announcementDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a announcementDo) Delete(models ...*models.Announcement) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *announcementDo) withDO(do gen.Dao) *announcementDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@@ -21,6 +21,7 @@ var (
AdminRole *adminRole
AdminRoleLink *adminRoleLink
AdminRolePermissionLink *adminRolePermissionLink
Announcement *announcement
Bill *bill
Channel *channel
Client *client
@@ -49,6 +50,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
AdminRole = &Q.AdminRole
AdminRoleLink = &Q.AdminRoleLink
AdminRolePermissionLink = &Q.AdminRolePermissionLink
Announcement = &Q.Announcement
Bill = &Q.Bill
Channel = &Q.Channel
Client = &Q.Client
@@ -78,6 +80,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
AdminRole: newAdminRole(db, opts...),
AdminRoleLink: newAdminRoleLink(db, opts...),
AdminRolePermissionLink: newAdminRolePermissionLink(db, opts...),
Announcement: newAnnouncement(db, opts...),
Bill: newBill(db, opts...),
Channel: newChannel(db, opts...),
Client: newClient(db, opts...),
@@ -108,6 +111,7 @@ type Query struct {
AdminRole adminRole
AdminRoleLink adminRoleLink
AdminRolePermissionLink adminRolePermissionLink
Announcement announcement
Bill bill
Channel channel
Client client
@@ -139,6 +143,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
AdminRole: q.AdminRole.clone(db),
AdminRoleLink: q.AdminRoleLink.clone(db),
AdminRolePermissionLink: q.AdminRolePermissionLink.clone(db),
Announcement: q.Announcement.clone(db),
Bill: q.Bill.clone(db),
Channel: q.Channel.clone(db),
Client: q.Client.clone(db),
@@ -177,6 +182,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
AdminRole: q.AdminRole.replaceDB(db),
AdminRoleLink: q.AdminRoleLink.replaceDB(db),
AdminRolePermissionLink: q.AdminRolePermissionLink.replaceDB(db),
Announcement: q.Announcement.replaceDB(db),
Bill: q.Bill.replaceDB(db),
Channel: q.Channel.replaceDB(db),
Client: q.Client.replaceDB(db),
@@ -205,6 +211,7 @@ type queryCtx struct {
AdminRole *adminRoleDo
AdminRoleLink *adminRoleLinkDo
AdminRolePermissionLink *adminRolePermissionLinkDo
Announcement *announcementDo
Bill *billDo
Channel *channelDo
Client *clientDo
@@ -233,6 +240,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
AdminRole: q.AdminRole.WithContext(ctx),
AdminRoleLink: q.AdminRoleLink.WithContext(ctx),
AdminRolePermissionLink: q.AdminRolePermissionLink.WithContext(ctx),
Announcement: q.Announcement.WithContext(ctx),
Bill: q.Bill.WithContext(ctx),
Channel: q.Channel.WithContext(ctx),
Client: q.Client.WithContext(ctx),

View File

@@ -58,4 +58,8 @@ func ApplyRouters(app *fiber.App) {
// 交易
trade := api.Group("/trade")
trade.Post("/callback/alipay", handlers.AlipayCallback)
// 公告
announcement := api.Group("/announcement")
announcement.Post("/list", handlers.ListAnnouncements)
}