143 lines
3.7 KiB
Go
143 lines
3.7 KiB
Go
// 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)
|
|
}
|
|
|
|
// StatusReq 更新小程序状态请求。状态仅允许 0(禁用)或 1(启用)。
|
|
type StatusReq struct {
|
|
Status int8 `json:"status" binding:"required,oneof=0 1"`
|
|
}
|
|
|
|
// UpdateStatus 按 ID 更新小程序状态(0 禁用、1 启用),返回更新后的小程序。
|
|
func (s *Service) UpdateStatus(ctx context.Context, id uint64, status int8) (*model.MiniProgram, error) {
|
|
if err := s.repo.Update(ctx, id, map[string]interface{}{"status": status}); err != nil {
|
|
return nil, err
|
|
}
|
|
return s.repo.GetByID(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
|
|
}
|