package admin import ( "context" "server/internal/db" "server/internal/db/sqlc" "server/internal/model/common" "server/internal/model/request" "server/internal/pkg/dberr" "server/internal/pkg/errs" ) type PostService struct { store *db.Store } func NewPostService(store *db.Store) *PostService { return &PostService{ store: store, } } func (s *PostService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.ListPostsRow], error) { params := sqlc.ListPostsParams{ Limit: p.PageSize, Offset: (p.Page - 1) * p.PageSize, } total, err := s.store.CountPosts(ctx) if err != nil { return nil, err } list, err := s.store.ListPosts(ctx, params) if err != nil { return nil, err } return &common.PageResult[sqlc.ListPostsRow]{ List: list, Total: total, }, nil } func (s *PostService) FindByID(ctx context.Context, id int32) (*sqlc.GetPostByIDRow, error) { post, err := s.store.GetPostByID(ctx, id) if err != nil { return nil, dberr.MapNoRows(err, errs.ErrPostNotFound) } return &post, nil } func (s *PostService) Create(ctx context.Context, req request.CreatePostRequest) (int32, error) { postID, err := db.WithTxResult(ctx, s.store, func(q *sqlc.Queries) (int32, error) { params := sqlc.CreatePostParams{ Title: req.Title, CoverID: req.CoverID, Slug: req.Slug, Content: req.Content, Summary: req.Summary, Status: *req.Status, Sort: req.Sort, PublishedAt: req.PublishedAt, } // 创建博客 postID, err := q.CreatePost(ctx, params) if err != nil { return 0, dberr.MapUniqueViolation(err, dberr.PostSlugKey, errs.ErrSlugAlreadyExists) } // 关联分类 if err = q.CreatePostCategory(ctx, sqlc.CreatePostCategoryParams{ PostID: postID, CategoryID: *req.CategoryID, }); err != nil { return 0, err } var tagsParams []sqlc.CreatePostTagParams for _, tagID := range req.Tags { tagsParams = append(tagsParams, sqlc.CreatePostTagParams{ PostID: postID, TagID: tagID, }) } if _, err = q.CreatePostTag(ctx, tagsParams); err != nil { return 0, err } return postID, nil }) if err != nil { return 0, err } return postID, nil } func (s *PostService) Update(ctx context.Context, id int32, req request.UpdatePostRequest) error { return s.store.WithTx(ctx, func(q *sqlc.Queries) error { params := sqlc.UpdatePostParams{ Title: req.Title, Slug: req.Slug, Content: req.Content, Summary: req.Summary, Status: req.Status, Sort: req.Sort, PublishedAt: req.PublishedAt, ID: id, } if req.CoverID.Set { params.UpdateCoverID = true if req.CoverID.Valid { params.CoverID = &req.CoverID.Value } } rows, err := q.UpdatePost(ctx, params) if err != nil { return dberr.MapUniqueViolation(err, dberr.PostSlugKey, errs.ErrSlugAlreadyExists) } if err = dberr.MapRowsAffected(rows, nil, errs.ErrPostNotFound); err != nil { return err } // 先删除分类 if err = q.DeletePostCategoryByPostID(ctx, id); err != nil { return err } if err = q.CreatePostCategory(ctx, sqlc.CreatePostCategoryParams{ PostID: id, CategoryID: *req.CategoryID, }); err != nil { return err } // 先删除标签 if err = q.DeletePostTagByPostID(ctx, id); err != nil { return err } var tagsParams []sqlc.CreatePostTagParams for _, tagID := range req.Tags { tagsParams = append(tagsParams, sqlc.CreatePostTagParams{ PostID: id, TagID: tagID, }) } if _, err = q.CreatePostTag(ctx, tagsParams); err != nil { return err } return nil }) } func (s *PostService) Delete(ctx context.Context, id int32) error { return s.store.WithTx(ctx, func(q *sqlc.Queries) error { err := q.DeletePostCategoryByPostID(ctx, id) if err != nil { return err } rows, err := q.DeletePost(ctx, id) return dberr.MapRowsAffected(rows, err, errs.ErrPostNotFound) }) }