package product import ( "backend/internal/dto" "backend/internal/model" "backend/utils" "errors" "gorm.io/gorm" ) // ProductService 产品业务逻辑层 // Logan.Li type ProductService struct { db *gorm.DB } // NewProductService 创建 service 实例 // Logan.Li func NewProductService(db *gorm.DB) *ProductService { return &ProductService{db: db} } // List 分页查询产品 // Logan.Li func (s *ProductService) List(page, pageSize int, keyword string) ([]dto.ProductResponse, int64, error) { var products []model.Product var total int64 query := s.db.Model(&model.Product{}) if keyword != "" { query = query.Where("name LIKE ? OR code LIKE ?", "%"+keyword+"%", "%"+keyword+"%") } query.Count(&total) if err := query.Order("created_at DESC"). Offset((page - 1) * pageSize).Limit(pageSize). Find(&products).Error; err != nil { return nil, 0, err } results := make([]dto.ProductResponse, 0, len(products)) for _, p := range products { results = append(results, toProductResponse(p)) } return results, total, nil } // GetAll 获取全部产品(下拉选项用) // Logan.Li func (s *ProductService) GetAll() ([]dto.ProductResponse, error) { var products []model.Product if err := s.db.Where("status = ?", 1).Order("created_at DESC").Find(&products).Error; err != nil { return nil, err } results := make([]dto.ProductResponse, 0, len(products)) for _, p := range products { results = append(results, toProductResponse(p)) } return results, nil } // GetByID 根据 ID 获取产品 // Logan.Li func (s *ProductService) GetByID(id uint) (*dto.ProductResponse, error) { var product model.Product if err := s.db.First(&product, id).Error; err != nil { return nil, errors.New("产品不存在") } resp := toProductResponse(product) return &resp, nil } // Create 创建产品 // Logan.Li func (s *ProductService) Create(req dto.ProductCreate) (*dto.ProductResponse, error) { // 检查 code 唯一性 // Logan.Li var count int64 s.db.Model(&model.Product{}).Where("code = ?", req.Code).Count(&count) if count > 0 { return nil, errors.New("产品编码已存在") } status := 1 if req.Status != nil { status = *req.Status } priceModel := req.PriceModel if priceModel == "" { priceModel = "subscription" } product := model.Product{ Name: req.Name, Code: req.Code, Version: req.Version, Description: req.Description, Features: utils.FormatFeatures(req.Features), Price: req.Price, PriceModel: priceModel, Status: status, } if err := s.db.Create(&product).Error; err != nil { return nil, errors.New("创建产品失败") } resp := toProductResponse(product) return &resp, nil } // Update 更新产品 // Logan.Li func (s *ProductService) Update(id uint, req dto.ProductUpdate) (*dto.ProductResponse, error) { var product model.Product if err := s.db.First(&product, id).Error; err != nil { return nil, errors.New("产品不存在") } updates := map[string]interface{}{} if req.Name != "" { updates["name"] = req.Name } if req.Version != "" { updates["version"] = req.Version } updates["description"] = req.Description if req.Features != nil { updates["features"] = utils.FormatFeatures(req.Features) } if req.Price != nil { updates["price"] = *req.Price } if req.PriceModel != "" { updates["price_model"] = req.PriceModel } if req.Status != nil { updates["status"] = *req.Status } if err := s.db.Model(&product).Updates(updates).Error; err != nil { return nil, errors.New("更新产品失败") } // 重新查询获取最新数据 // Logan.Li s.db.First(&product, id) resp := toProductResponse(product) return &resp, nil } // Delete 删除产品(软删除) // Logan.Li func (s *ProductService) Delete(id uint) error { var count int64 s.db.Model(&model.License{}).Where("product_id = ?", id).Count(&count) if count > 0 { return errors.New("该产品下存在 License,无法删除") } return s.db.Delete(&model.Product{}, id).Error } // UpdateStatus 切换产品上下架状态 // Logan.Li func (s *ProductService) UpdateStatus(id uint, status int) error { return s.db.Model(&model.Product{}).Where("id = ?", id).Update("status", status).Error } // toProductResponse 模型转响应 DTO // Logan.Li func toProductResponse(p model.Product) dto.ProductResponse { return dto.ProductResponse{ ID: p.ID, Name: p.Name, Code: p.Code, Version: p.Version, Description: p.Description, Features: utils.ParseFeatures(p.Features), Price: p.Price, PriceModel: p.PriceModel, Status: p.Status, CreatedAt: p.CreatedAt.Format("2006-01-02 15:04:05"), UpdatedAt: p.UpdatedAt.Format("2006-01-02 15:04:05"), } }