Files
license-manager/backend/internal/service/package_service.go
T

231 lines
5.7 KiB
Go

package service
import (
"context"
"encoding/json"
"fmt"
"license-manager/internal/models"
"license-manager/internal/repository"
pkgcontext "license-manager/pkg/context"
"license-manager/pkg/i18n"
"time"
"gorm.io/gorm"
)
// PackageService 套餐服务接口
type PackageService interface {
// 管理端接口
CreatePackage(ctx context.Context, req *models.PackageCreateRequest) (*models.Package, error)
UpdatePackage(ctx context.Context, id string, req *models.PackageUpdateRequest) (*models.Package, error)
DeletePackage(ctx context.Context, id string) error
GetPackageList(ctx context.Context, req *models.PackageListRequest) (*models.PackageListResponse, error)
GetPackageDetail(ctx context.Context, id string) (*models.Package, error)
// 用户端接口
GetCuPackageList(ctx context.Context) ([]*models.CuPackageResponse, error)
}
type packageService struct {
repo repository.PackageRepository
db *gorm.DB
}
// NewPackageService 创建套餐服务
func NewPackageService(repo repository.PackageRepository, db *gorm.DB) PackageService {
return &packageService{
repo: repo,
db: db,
}
}
// ========== 管理端接口实现 ==========
func (s *packageService) CreatePackage(ctx context.Context, req *models.PackageCreateRequest) (*models.Package, error) {
lang := pkgcontext.GetLanguageFromContext(ctx)
pkg := &models.Package{
Name: req.Name,
Type: req.Type,
Price: req.Price,
PriceDescription: req.PriceDescription,
DurationDescription: req.DurationDescription,
Description: req.Description,
Features: req.Features,
Status: req.Status,
SortOrder: req.SortOrder,
Remark: req.Remark,
}
if err := s.repo.Create(pkg); err != nil {
return nil, i18n.NewI18nError("800001", lang)
}
return pkg, nil
}
func (s *packageService) UpdatePackage(ctx context.Context, id string, req *models.PackageUpdateRequest) (*models.Package, error) {
lang := pkgcontext.GetLanguageFromContext(ctx)
pkg, err := s.repo.GetByID(id)
if err != nil {
return nil, i18n.NewI18nError("800002", lang)
}
// 更新字段
if req.Name != "" {
pkg.Name = req.Name
}
if req.Type != "" {
pkg.Type = req.Type
}
if req.Price >= 0 {
pkg.Price = req.Price
}
if req.PriceDescription != "" {
pkg.PriceDescription = req.PriceDescription
}
if req.DurationDescription != "" {
pkg.DurationDescription = req.DurationDescription
}
if req.Description != "" {
pkg.Description = req.Description
}
if req.Features != "" {
pkg.Features = req.Features
}
if req.Status != nil {
pkg.Status = *req.Status
}
if req.SortOrder != nil {
pkg.SortOrder = *req.SortOrder
}
if req.Remark != "" {
pkg.Remark = req.Remark
}
pkg.UpdatedAt = time.Now()
if err := s.repo.Update(pkg); err != nil {
return nil, i18n.NewI18nError("800003", lang)
}
return pkg, nil
}
func (s *packageService) DeletePackage(ctx context.Context, id string) error {
lang := pkgcontext.GetLanguageFromContext(ctx)
// 检查是否存在
_, err := s.repo.GetByID(id)
if err != nil {
return i18n.NewI18nError("800002", lang)
}
if err := s.repo.Delete(id); err != nil {
return i18n.NewI18nError("800004", lang)
}
return nil
}
func (s *packageService) GetPackageList(ctx context.Context, req *models.PackageListRequest) (*models.PackageListResponse, error) {
packages, total, err := s.repo.GetList(ctx, req)
if err != nil {
lang := pkgcontext.GetLanguageFromContext(ctx)
return nil, i18n.NewI18nError("800005", lang)
}
responses := make([]*models.PackageResponse, len(packages))
for i, pkg := range packages {
responses[i] = pkg.ToResponse()
}
return &models.PackageListResponse{
Packages: responses,
TotalCount: total,
}, nil
}
func (s *packageService) GetPackageDetail(ctx context.Context, id string) (*models.Package, error) {
lang := pkgcontext.GetLanguageFromContext(ctx)
pkg, err := s.repo.GetByID(id)
if err != nil {
return nil, i18n.NewI18nError("800002", lang)
}
return pkg, nil
}
// ========== 用户端接口实现 ==========
func (s *packageService) GetCuPackageList(ctx context.Context) ([]*models.CuPackageResponse, error) {
packages, err := s.repo.GetEnabledList(ctx)
if err != nil {
return nil, err
}
responses := make([]*models.CuPackageResponse, len(packages))
for i, pkg := range packages {
responses[i] = s.toCuPackageResponse(pkg)
}
return responses, nil
}
// toCuPackageResponse 转换为用户端套餐响应(兼容原有结构)
func (s *packageService) toCuPackageResponse(pkg *models.Package) *models.CuPackageResponse {
// 从features中解析max_devices
maxDevices := 1000 // 默认值
if pkg.Features != "" {
var features []string
if err := json.Unmarshal([]byte(pkg.Features), &features); err == nil {
for _, f := range features {
// 尝试解析"X个许可"格式
var n int
if _, err := fmt.Sscanf(f, "%d个许可", &n); err == nil {
maxDevices = n
break
}
}
}
}
// 构建details字符串
details := pkg.Description
if pkg.DurationDescription != "" {
if details != "" {
details += "|"
}
details += pkg.DurationDescription
}
if maxDevices > 0 {
if details != "" {
details += "|"
}
details += fmt.Sprintf("%d个许可", maxDevices)
}
// 计算 display_price
displayPrice := ""
if pkg.Price != 0 {
displayPrice = fmt.Sprintf("¥%g", pkg.Price)
} else {
displayPrice = pkg.PriceDescription
}
return &models.CuPackageResponse{
ID: pkg.ID,
Name: pkg.Name,
Type: pkg.Type,
Price: pkg.Price,
DisplayPrice: displayPrice,
PriceDescription: pkg.PriceDescription,
MaxDevices: maxDevices,
Description: pkg.Description,
Features: pkg.Features,
Details: details,
}
}