// Package miniappsvc 是后台管理小程序的业务逻辑。 package miniappsvc import ( "context" "encoding/json" "portal-mini-go/internal/model" "portal-mini-go/internal/pkg/errors" "portal-mini-go/internal/repository/miniapp" ) // Service 小程序管理业务服务,依赖小程序仓储。 type Service struct { repo *miniapp.Repository } func New(repo *miniapp.Repository) *Service { return &Service{repo: repo} } // CreateReq 新建小程序请求。 type CreateReq struct { Name string `json:"name" binding:"required"` Description string `json:"description"` AppID string `json:"app_id" binding:"required"` AppSecret string `json:"app_secret" binding:"required"` Status int8 `json:"status"` Ext string `json:"ext"` } // Create 新建小程序,缺省状态为启用。 func (s *Service) Create(ctx context.Context, req CreateReq) (*model.MiniProgram, error) { if req.Status == 0 { req.Status = model.MiniProgramStatusEnabled } if err := validateExt(req.Ext); err != nil { return nil, err } m := &model.MiniProgram{ Name: req.Name, Description: req.Description, AppID: req.AppID, AppSecret: req.AppSecret, Status: req.Status, Ext: req.Ext, } if err := s.repo.Create(ctx, m); err != nil { return nil, err } return m, nil } // UpdateReq 更新小程序请求;指针区分“未提供”与“置空”。 type UpdateReq struct { Name *string `json:"name"` Description *string `json:"description"` AppSecret *string `json:"app_secret"` Status *int8 `json:"status"` Ext *string `json:"ext"` } // Update 按 ID 局部更新小程序。 func (s *Service) Update(ctx context.Context, id uint64, req UpdateReq) (*model.MiniProgram, error) { cols := map[string]interface{}{} if req.Name != nil { cols["name"] = *req.Name } if req.Description != nil { cols["description"] = *req.Description } if req.AppSecret != nil { cols["app_secret"] = *req.AppSecret } if req.Status != nil { cols["status"] = *req.Status } if req.Ext != nil { if err := validateExt(*req.Ext); err != nil { return nil, err } cols["ext"] = *req.Ext } if len(cols) == 0 { return s.repo.GetByID(ctx, id) } if err := s.repo.Update(ctx, id, cols); err != nil { return nil, err } return s.repo.GetByID(ctx, id) } // GetByID 按 ID 查询小程序。 func (s *Service) GetByID(ctx context.Context, id uint64) (*model.MiniProgram, error) { return s.repo.GetByID(ctx, id) } // ListReq 列表查询条件。 type ListReq struct { Status int8 Page int Size int } // List 分页查询小程序。 func (s *Service) List(ctx context.Context, req ListReq) ([]model.MiniProgram, int64, error) { page, size := req.Page, req.Size if page <= 0 { page = 1 } if size <= 0 { size = 20 } return s.repo.List(ctx, req.Status, page, size) } // Delete 软删除小程序。 func (s *Service) Delete(ctx context.Context, id uint64) error { return s.repo.Delete(ctx, id) } // validateExt 校验扩展字段为合法 JSON(允许为空字符串)。 func validateExt(s string) error { if s == "" { return nil } if !json.Valid([]byte(s)) { return errors.New(40000, "ext 必须是合法 JSON 字符串") } return nil }