healthapp
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

143 lines
3.9 KiB

package service
import (
"errors"
"time"
"health-ai/internal/model"
"health-ai/internal/repository/impl"
)
type ProductService struct {
productRepo *impl.ProductRepository
constitutionRepo *impl.ConstitutionRepository
}
func NewProductService() *ProductService {
return &ProductService{
productRepo: impl.NewProductRepository(),
constitutionRepo: impl.NewConstitutionRepository(),
}
}
// ================= 请求/响应结构体 =================
// ProductListResponse 产品列表响应
type ProductListResponse struct {
Products []model.Product `json:"products"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// ProductRecommendResponse 产品推荐响应
type ProductRecommendResponse struct {
ConstitutionType string `json:"constitution_type"`
ConstitutionName string `json:"constitution_name"`
Products []model.Product `json:"products"`
}
// PurchaseSyncRequest 购买同步请求
type PurchaseSyncRequest struct {
UserID uint `json:"user_id" binding:"required"`
OrderNo string `json:"order_no" binding:"required"`
Products []struct {
ID uint `json:"id" binding:"required"`
Name string `json:"name" binding:"required"`
} `json:"products" binding:"required"`
CreatedAt time.Time `json:"created_at"`
}
// ================= Service 方法 =================
// GetProducts 获取产品列表
func (s *ProductService) GetProducts(page, pageSize int) (*ProductListResponse, error) {
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 20
}
products, total, err := s.productRepo.GetAll(page, pageSize)
if err != nil {
return nil, err
}
return &ProductListResponse{
Products: products,
Total: total,
Page: page,
PageSize: pageSize,
}, nil
}
// GetProductByID 获取产品详情
func (s *ProductService) GetProductByID(id uint) (*model.Product, error) {
product, err := s.productRepo.GetByID(id)
if err != nil {
return nil, errors.New("产品不存在")
}
return product, nil
}
// GetProductsByCategory 按分类获取产品
func (s *ProductService) GetProductsByCategory(category string) ([]model.Product, error) {
return s.productRepo.GetByCategory(category)
}
// GetRecommendedProducts 根据用户体质获取推荐产品
func (s *ProductService) GetRecommendedProducts(userID uint) (*ProductRecommendResponse, error) {
// 获取用户最新体质
assessment, err := s.constitutionRepo.GetLatestAssessment(userID)
if err != nil {
return nil, errors.New("请先完成体质测评")
}
// 获取该体质的推荐产品
products, err := s.productRepo.GetByConstitution(assessment.PrimaryConstitution)
if err != nil {
return nil, err
}
return &ProductRecommendResponse{
ConstitutionType: assessment.PrimaryConstitution,
ConstitutionName: model.ConstitutionNames[assessment.PrimaryConstitution],
Products: products,
}, nil
}
// SearchProducts 根据关键词搜索产品
func (s *ProductService) SearchProducts(keyword string) ([]model.Product, error) {
if keyword == "" {
return nil, errors.New("请输入搜索关键词")
}
return s.productRepo.SearchByKeyword(keyword)
}
// SyncPurchase 同步商城购买记录
func (s *ProductService) SyncPurchase(req *PurchaseSyncRequest) error {
purchasedAt := req.CreatedAt
if purchasedAt.IsZero() {
purchasedAt = time.Now()
}
histories := make([]model.PurchaseHistory, len(req.Products))
for i, p := range req.Products {
histories[i] = model.PurchaseHistory{
UserID: req.UserID,
OrderNo: req.OrderNo,
ProductID: p.ID,
ProductName: p.Name,
PurchasedAt: purchasedAt,
Source: "mall",
}
}
return s.productRepo.BatchCreatePurchaseHistory(histories)
}
// GetPurchaseHistory 获取用户购买历史
func (s *ProductService) GetPurchaseHistory(userID uint) ([]model.PurchaseHistory, error) {
return s.productRepo.GetPurchaseHistory(userID)
}