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.
 
 
 
 
 
 

23 KiB

08-保健品商城关联模块

目标

实现保健品数据管理和 AI 问诊时的产品推荐功能,关联外部保健品商城。


前置要求

  • AI 对话模块已完成
  • 体质辨识模块已完成

实施步骤

步骤 1:创建产品数据模型

创建 server/internal/model/product.go

package model

import "time"

// Product 保健品
type Product struct {
	ID          uint      `gorm:"primaryKey" json:"id"`
	Name        string    `gorm:"size:100;not null" json:"name"`
	Category    string    `gorm:"size:50" json:"category"`
	Description string    `gorm:"type:text" json:"description"`
	Efficacy    string    `gorm:"type:text" json:"efficacy"`
	Suitable    string    `gorm:"type:text" json:"suitable"`
	Price       float64   `gorm:"type:decimal(10,2)" json:"price"`
	ImageURL    string    `gorm:"size:255" json:"image_url"`
	MallURL     string    `gorm:"size:255" json:"mall_url"`
	IsActive    bool      `gorm:"default:true" json:"is_active"`
	CreatedAt   time.Time `json:"created_at"`
}

// ConstitutionProduct 体质-产品关联
type ConstitutionProduct struct {
	ID               uint   `gorm:"primaryKey" json:"id"`
	ConstitutionType string `gorm:"size:20;not null;index" json:"constitution_type"`
	ProductID        uint   `gorm:"not null;index" json:"product_id"`
	Priority         int    `gorm:"default:0" json:"priority"`
	Reason           string `gorm:"size:200" json:"reason"`
}

// SymptomProduct 症状-产品关联
type SymptomProduct struct {
	ID        uint   `gorm:"primaryKey" json:"id"`
	Keyword   string `gorm:"size:50;not null;index" json:"keyword"`
	ProductID uint   `gorm:"not null;index" json:"product_id"`
	Priority  int    `gorm:"default:0" json:"priority"`
}

// 产品分类常量
const (
	CategoryBuqi       = "补气类"
	CategoryWenyang    = "温阳类"
	CategoryZiyin      = "滋阴类"
	CategoryQushi      = "祛湿类"
	CategoryHuoxue     = "活血类"
	CategoryLiqi       = "理气类"
	CategoryKangmin    = "抗敏类"
	CategoryXinnao     = "心脑血管类"
	CategoryGuguanjie  = "骨关节类"
	CategoryXuetang    = "血糖调节类"
	CategoryZhumian    = "助眠安神类"
	CategoryJiannao    = "健脑益智类"
	CategoryRunchang   = "润肠通便类"
	CategoryHuyan      = "护眼明目类"
	CategoryMianyi     = "增强免疫类"
	CategoryZonghe     = "综合类"
)

步骤 2:创建种子数据

创建 server/internal/database/seed_products.go

package database

import (
	"health-ai/internal/model"
	"log"
)

// SeedProducts 初始化保健品模拟数据
func SeedProducts() {
	var count int64
	DB.Model(&model.Product{}).Count(&count)
	if count > 0 {
		log.Println("产品数据已存在,跳过初始化")
		return
	}

	products := getProductSeeds()
	for _, p := range products {
		DB.Create(&p)
	}
	log.Printf("已初始化 %d 条产品数据", len(products))

	// 初始化体质-产品关联
	constitutionProducts := getConstitutionProductSeeds()
	for _, cp := range constitutionProducts {
		DB.Create(&cp)
	}
	log.Printf("已初始化 %d 条体质-产品关联", len(constitutionProducts))

	// 初始化症状-产品关联
	symptomProducts := getSymptomProductSeeds()
	for _, sp := range symptomProducts {
		DB.Create(&sp)
	}
	log.Printf("已初始化 %d 条症状-产品关联", len(symptomProducts))
}

func getProductSeeds() []model.Product {
	return []model.Product{
		// ========== 体质调养类 ==========
		// 补气类
		{ID: 1, Name: "黄芪精口服液", Category: "补气类", 
			Efficacy: "补气固表,增强免疫力", 
			Suitable: "气虚质、易疲劳人群",
			Price: 68.00, MallURL: "https://mall.example.com/product/1", IsActive: true},
		{ID: 2, Name: "人参蜂王浆", Category: "补气类", 
			Efficacy: "补气养血,改善疲劳", 
			Suitable: "气虚质、体力不足人群",
			Price: 128.00, MallURL: "https://mall.example.com/product/2", IsActive: true},
		{ID: 3, Name: "西洋参含片", Category: "补气类", 
			Efficacy: "益气养阴,清热生津", 
			Suitable: "气虚质、气阴两虚人群",
			Price: 98.00, MallURL: "https://mall.example.com/product/3", IsActive: true},

		// 温阳类
		{ID: 4, Name: "鹿茸参精胶囊", Category: "温阳类", 
			Efficacy: "温肾壮阳,补气养血", 
			Suitable: "阳虚质、畏寒怕冷人群",
			Price: 268.00, MallURL: "https://mall.example.com/product/4", IsActive: true},
		{ID: 5, Name: "桂圆红枣茶", Category: "温阳类", 
			Efficacy: "温中补血,养心安神", 
			Suitable: "阳虚质、手脚冰凉人群",
			Price: 45.00, MallURL: "https://mall.example.com/product/5", IsActive: true},

		// 滋阴类
		{ID: 6, Name: "枸杞原浆", Category: "滋阴类", 
			Efficacy: "滋补肝肾,明目润肺", 
			Suitable: "阴虚质、眼睛干涩人群",
			Price: 158.00, MallURL: "https://mall.example.com/product/6", IsActive: true},
		{ID: 7, Name: "即食燕窝", Category: "滋阴类", 
			Efficacy: "滋阴润肺,美容养颜", 
			Suitable: "阴虚质、皮肤干燥人群",
			Price: 398.00, MallURL: "https://mall.example.com/product/7", IsActive: true},
		{ID: 8, Name: "铁皮石斛粉", Category: "滋阴类", 
			Efficacy: "滋阴清热,养胃生津", 
			Suitable: "阴虚质、口干舌燥人群",
			Price: 188.00, MallURL: "https://mall.example.com/product/8", IsActive: true},

		// 祛湿类
		{ID: 9, Name: "红豆薏米粉", Category: "祛湿类", 
			Efficacy: "健脾祛湿,消肿利水", 
			Suitable: "痰湿质、湿热质、身体沉重人群",
			Price: 39.00, MallURL: "https://mall.example.com/product/9", IsActive: true},
		{ID: 10, Name: "茯苓山药糕", Category: "祛湿类", 
			Efficacy: "健脾益气,祛湿止泻", 
			Suitable: "痰湿质、脾胃虚弱人群",
			Price: 56.00, MallURL: "https://mall.example.com/product/10", IsActive: true},
		{ID: 11, Name: "清热祛湿茶", Category: "祛湿类", 
			Efficacy: "清热利湿,解毒消肿", 
			Suitable: "湿热质、口苦口干人群",
			Price: 35.00, MallURL: "https://mall.example.com/product/11", IsActive: true},

		// 活血类
		{ID: 12, Name: "三七粉", Category: "活血类", 
			Efficacy: "活血化瘀,消肿止痛", 
			Suitable: "血瘀质、面色晦暗人群",
			Price: 128.00, MallURL: "https://mall.example.com/product/12", IsActive: true},
		{ID: 13, Name: "丹参片", Category: "活血类", 
			Efficacy: "活血化瘀,通经止痛", 
			Suitable: "血瘀质、易生斑点人群",
			Price: 48.00, MallURL: "https://mall.example.com/product/13", IsActive: true},

		// 理气类
		{ID: 14, Name: "玫瑰花茶", Category: "理气类", 
			Efficacy: "疏肝理气,美容养颜", 
			Suitable: "气郁质、情绪低落人群",
			Price: 38.00, MallURL: "https://mall.example.com/product/14", IsActive: true},
		{ID: 15, Name: "陈皮普洱茶", Category: "理气类", 
			Efficacy: "理气健脾,消食化痰", 
			Suitable: "气郁质、胸闷不适人群",
			Price: 68.00, MallURL: "https://mall.example.com/product/15", IsActive: true},

		// 抗敏类
		{ID: 16, Name: "益生菌粉", Category: "抗敏类", 
			Efficacy: "调节肠道,增强免疫", 
			Suitable: "特禀质、过敏体质人群",
			Price: 98.00, MallURL: "https://mall.example.com/product/16", IsActive: true},
		{ID: 17, Name: "蜂胶软胶囊", Category: "抗敏类", 
			Efficacy: "抗菌消炎,增强体质", 
			Suitable: "特禀质、免疫力低下人群",
			Price: 168.00, MallURL: "https://mall.example.com/product/17", IsActive: true},

		// 综合类
		{ID: 18, Name: "阿胶固元糕", Category: "综合类", 
			Efficacy: "补血养颜,滋阴润燥", 
			Suitable: "平和质、日常滋补人群",
			Price: 88.00, MallURL: "https://mall.example.com/product/18", IsActive: true},
		{ID: 19, Name: "蜂蜜", Category: "综合类", 
			Efficacy: "润肠通便,美容养颜", 
			Suitable: "各种体质日常调养",
			Price: 68.00, MallURL: "https://mall.example.com/product/19", IsActive: true},
		{ID: 20, Name: "复合维生素片", Category: "综合类", 
			Efficacy: "补充营养,增强体质", 
			Suitable: "各种体质日常补充",
			Price: 78.00, MallURL: "https://mall.example.com/product/20", IsActive: true},

		// ========== 中老年常见问题类 ==========
		// 心脑血管类
		{ID: 21, Name: "深海鱼油软胶囊", Category: "心脑血管类", 
			Efficacy: "辅助降血脂,保护心脑血管", 
			Suitable: "高血脂、动脉硬化人群",
			Price: 128.00, MallURL: "https://mall.example.com/product/21", IsActive: true},
		{ID: 22, Name: "纳豆激酶胶囊", Category: "心脑血管类", 
			Efficacy: "溶解血栓,改善血液循环", 
			Suitable: "中老年心脑血管亚健康人群",
			Price: 198.00, MallURL: "https://mall.example.com/product/22", IsActive: true},
		{ID: 23, Name: "大豆卵磷脂", Category: "心脑血管类", 
			Efficacy: "调节血脂,保护肝脏", 
			Suitable: "高血脂、脂肪肝人群",
			Price: 88.00, MallURL: "https://mall.example.com/product/23", IsActive: true},

		// 骨关节类
		{ID: 24, Name: "氨糖软骨素钙片", Category: "骨关节类", 
			Efficacy: "修复软骨,润滑关节,补充钙质", 
			Suitable: "关节疼痛、骨质疏松人群",
			Price: 168.00, MallURL: "https://mall.example.com/product/24", IsActive: true},
		{ID: 25, Name: "液体钙维D软胶囊", Category: "骨关节类", 
			Efficacy: "补钙,促进钙吸收,预防骨质疏松", 
			Suitable: "中老年人、骨质疏松人群",
			Price: 78.00, MallURL: "https://mall.example.com/product/25", IsActive: true},
		{ID: 26, Name: "骨胶原蛋白肽", Category: "骨关节类", 
			Efficacy: "增加骨密度,改善关节灵活性", 
			Suitable: "骨关节退化人群",
			Price: 218.00, MallURL: "https://mall.example.com/product/26", IsActive: true},

		// 血糖调节类
		{ID: 27, Name: "苦瓜洋参软胶囊", Category: "血糖调节类", 
			Efficacy: "辅助降血糖,改善糖代谢", 
			Suitable: "血糖偏高人群",
			Price: 138.00, MallURL: "https://mall.example.com/product/27", IsActive: true},
		{ID: 28, Name: "桑叶茶", Category: "血糖调节类", 
			Efficacy: "辅助稳定血糖,清热降火", 
			Suitable: "血糖偏高、糖尿病人群",
			Price: 45.00, MallURL: "https://mall.example.com/product/28", IsActive: true},

		// 助眠安神类
		{ID: 29, Name: "褪黑素维生素B6片", Category: "助眠安神类", 
			Efficacy: "改善睡眠,调节生物钟", 
			Suitable: "失眠、睡眠质量差人群",
			Price: 68.00, MallURL: "https://mall.example.com/product/29", IsActive: true},
		{ID: 30, Name: "酸枣仁百合膏", Category: "助眠安神类", 
			Efficacy: "养心安神,改善睡眠", 
			Suitable: "心烦失眠、多梦易醒人群",
			Price: 58.00, MallURL: "https://mall.example.com/product/30", IsActive: true},

		// 健脑益智类
		{ID: 31, Name: "银杏叶提取物片", Category: "健脑益智类", 
			Efficacy: "改善记忆力,促进脑部血液循环", 
			Suitable: "记忆力减退、脑供血不足人群",
			Price: 98.00, MallURL: "https://mall.example.com/product/31", IsActive: true},
		{ID: 32, Name: "DHA藻油软胶囊", Category: "健脑益智类", 
			Efficacy: "补充脑营养,改善认知功能", 
			Suitable: "中老年脑功能下降人群",
			Price: 158.00, MallURL: "https://mall.example.com/product/32", IsActive: true},

		// 润肠通便类
		{ID: 33, Name: "膳食纤维粉", Category: "润肠通便类", 
			Efficacy: "促进肠道蠕动,改善便秘", 
			Suitable: "便秘、肠道功能紊乱人群",
			Price: 48.00, MallURL: "https://mall.example.com/product/33", IsActive: true},
		{ID: 34, Name: "综合酵素原液", Category: "润肠通便类", 
			Efficacy: "促进消化,排毒通便", 
			Suitable: "消化不良、便秘人群",
			Price: 128.00, MallURL: "https://mall.example.com/product/34", IsActive: true},

		// 护眼明目类
		{ID: 35, Name: "叶黄素蓝莓护眼片", Category: "护眼明目类", 
			Efficacy: "保护视网膜,缓解眼疲劳", 
			Suitable: "视力下降、眼睛干涩人群",
			Price: 118.00, MallURL: "https://mall.example.com/product/35", IsActive: true},

		// 增强免疫类
		{ID: 36, Name: "灵芝孢子粉胶囊", Category: "增强免疫类", 
			Efficacy: "增强免疫力,抗疲劳", 
			Suitable: "免疫力低下、体质虚弱人群",
			Price: 298.00, MallURL: "https://mall.example.com/product/36", IsActive: true},
	}
}

func getConstitutionProductSeeds() []model.ConstitutionProduct {
	return []model.ConstitutionProduct{
		// 气虚质推荐
		{ConstitutionType: "qixu", ProductID: 1, Priority: 1, Reason: "补气固表"},
		{ConstitutionType: "qixu", ProductID: 2, Priority: 2, Reason: "补气养血"},
		{ConstitutionType: "qixu", ProductID: 3, Priority: 3, Reason: "益气养阴"},
		{ConstitutionType: "qixu", ProductID: 36, Priority: 4, Reason: "增强免疫"},

		// 阳虚质推荐
		{ConstitutionType: "yangxu", ProductID: 4, Priority: 1, Reason: "温肾壮阳"},
		{ConstitutionType: "yangxu", ProductID: 5, Priority: 2, Reason: "温中补血"},

		// 阴虚质推荐
		{ConstitutionType: "yinxu", ProductID: 6, Priority: 1, Reason: "滋补肝肾"},
		{ConstitutionType: "yinxu", ProductID: 7, Priority: 2, Reason: "滋阴润肺"},
		{ConstitutionType: "yinxu", ProductID: 8, Priority: 3, Reason: "滋阴清热"},

		// 痰湿质推荐
		{ConstitutionType: "tanshi", ProductID: 9, Priority: 1, Reason: "健脾祛湿"},
		{ConstitutionType: "tanshi", ProductID: 10, Priority: 2, Reason: "健脾益气"},

		// 湿热质推荐
		{ConstitutionType: "shire", ProductID: 11, Priority: 1, Reason: "清热利湿"},
		{ConstitutionType: "shire", ProductID: 9, Priority: 2, Reason: "祛湿利水"},

		// 血瘀质推荐
		{ConstitutionType: "xueyu", ProductID: 12, Priority: 1, Reason: "活血化瘀"},
		{ConstitutionType: "xueyu", ProductID: 13, Priority: 2, Reason: "活血通经"},
		{ConstitutionType: "xueyu", ProductID: 21, Priority: 3, Reason: "改善血液循环"},

		// 气郁质推荐
		{ConstitutionType: "qiyu", ProductID: 14, Priority: 1, Reason: "疏肝理气"},
		{ConstitutionType: "qiyu", ProductID: 15, Priority: 2, Reason: "理气健脾"},
		{ConstitutionType: "qiyu", ProductID: 30, Priority: 3, Reason: "安神助眠"},

		// 特禀质推荐
		{ConstitutionType: "tebing", ProductID: 16, Priority: 1, Reason: "调节免疫"},
		{ConstitutionType: "tebing", ProductID: 17, Priority: 2, Reason: "增强体质"},

		// 平和质推荐
		{ConstitutionType: "pinghe", ProductID: 18, Priority: 1, Reason: "日常滋补"},
		{ConstitutionType: "pinghe", ProductID: 20, Priority: 2, Reason: "营养补充"},
	}
}

func getSymptomProductSeeds() []model.SymptomProduct {
	return []model.SymptomProduct{
		// 疲劳相关
		{Keyword: "疲劳", ProductID: 1, Priority: 1},
		{Keyword: "乏力", ProductID: 1, Priority: 1},
		{Keyword: "没精神", ProductID: 2, Priority: 1},
		{Keyword: "体力差", ProductID: 2, Priority: 1},

		// 睡眠相关
		{Keyword: "失眠", ProductID: 29, Priority: 1},
		{Keyword: "睡不着", ProductID: 29, Priority: 1},
		{Keyword: "多梦", ProductID: 30, Priority: 1},
		{Keyword: "睡眠差", ProductID: 30, Priority: 1},

		// 心脑血管相关
		{Keyword: "血压高", ProductID: 21, Priority: 1},
		{Keyword: "高血压", ProductID: 21, Priority: 1},
		{Keyword: "血脂高", ProductID: 21, Priority: 1},
		{Keyword: "高血脂", ProductID: 23, Priority: 1},
		{Keyword: "头晕", ProductID: 22, Priority: 1},
		{Keyword: "动脉硬化", ProductID: 22, Priority: 1},

		// 骨关节相关
		{Keyword: "关节痛", ProductID: 24, Priority: 1},
		{Keyword: "膝盖疼", ProductID: 24, Priority: 1},
		{Keyword: "腿疼", ProductID: 24, Priority: 1},
		{Keyword: "骨质疏松", ProductID: 25, Priority: 1},
		{Keyword: "缺钙", ProductID: 25, Priority: 1},

		// 血糖相关
		{Keyword: "血糖高", ProductID: 27, Priority: 1},
		{Keyword: "糖尿病", ProductID: 28, Priority: 1},

		// 记忆力相关
		{Keyword: "记忆力差", ProductID: 31, Priority: 1},
		{Keyword: "健忘", ProductID: 31, Priority: 1},
		{Keyword: "脑供血不足", ProductID: 32, Priority: 1},

		// 消化相关
		{Keyword: "便秘", ProductID: 33, Priority: 1},
		{Keyword: "排便困难", ProductID: 33, Priority: 1},
		{Keyword: "消化不良", ProductID: 34, Priority: 1},

		// 眼睛相关
		{Keyword: "眼睛干", ProductID: 35, Priority: 1},
		{Keyword: "视力差", ProductID: 35, Priority: 1},
		{Keyword: "眼疲劳", ProductID: 35, Priority: 1},

		// 免疫相关
		{Keyword: "感冒", ProductID: 36, Priority: 1},
		{Keyword: "免疫力差", ProductID: 36, Priority: 1},
		{Keyword: "体质差", ProductID: 36, Priority: 1},

		// 体质相关症状
		{Keyword: "怕冷", ProductID: 4, Priority: 1},
		{Keyword: "手脚冰凉", ProductID: 5, Priority: 1},
		{Keyword: "口干", ProductID: 6, Priority: 1},
		{Keyword: "上火", ProductID: 11, Priority: 1},
		{Keyword: "湿气重", ProductID: 9, Priority: 1},
	}
}

步骤 3:创建产品 Repository

创建 server/internal/repository/impl/product.go

package impl

import (
	"health-ai/internal/database"
	"health-ai/internal/model"
)

type ProductRepository struct{}

func NewProductRepository() *ProductRepository {
	return &ProductRepository{}
}

// GetAll 获取所有产品
func (r *ProductRepository) GetAll(category string) ([]model.Product, error) {
	var products []model.Product
	query := database.DB.Where("is_active = ?", true)
	if category != "" {
		query = query.Where("category = ?", category)
	}
	err := query.Find(&products).Error
	return products, err
}

// GetByID 获取产品详情
func (r *ProductRepository) GetByID(id uint) (*model.Product, error) {
	var product model.Product
	err := database.DB.First(&product, id).Error
	return &product, err
}

// GetByConstitution 根据体质获取推荐产品
func (r *ProductRepository) GetByConstitution(constitutionType string, limit int) ([]model.Product, error) {
	var products []model.Product
	err := database.DB.
		Joins("JOIN constitution_products ON constitution_products.product_id = products.id").
		Where("constitution_products.constitution_type = ?", constitutionType).
		Where("products.is_active = ?", true).
		Order("constitution_products.priority ASC").
		Limit(limit).
		Find(&products).Error
	return products, err
}

// GetByKeywords 根据症状关键词获取推荐产品
func (r *ProductRepository) GetByKeywords(keywords []string, limit int) ([]model.Product, error) {
	var products []model.Product
	err := database.DB.
		Joins("JOIN symptom_products ON symptom_products.product_id = products.id").
		Where("symptom_products.keyword IN ?", keywords).
		Where("products.is_active = ?", true).
		Order("symptom_products.priority ASC").
		Distinct().
		Limit(limit).
		Find(&products).Error
	return products, err
}

// GetRecommendations 综合推荐(体质+关键词)
func (r *ProductRepository) GetRecommendations(constitutionType string, keywords []string, limit int) ([]model.Product, error) {
	// 优先获取体质相关产品
	products, _ := r.GetByConstitution(constitutionType, limit)
	
	// 如果不够,补充关键词匹配的产品
	if len(products) < limit && len(keywords) > 0 {
		remaining := limit - len(products)
		keywordProducts, _ := r.GetByKeywords(keywords, remaining)
		
		// 去重合并
		existingIDs := make(map[uint]bool)
		for _, p := range products {
			existingIDs[p.ID] = true
		}
		for _, p := range keywordProducts {
			if !existingIDs[p.ID] {
				products = append(products, p)
			}
		}
	}
	
	return products, nil
}

步骤 4:更新对话 Service

conversation.go 中添加产品推荐:

// 更新系统提示词模板,添加产品列表
func (s *ConversationService) buildSystemPrompt(userID uint) string {
	// ... 原有代码 ...

	// 获取用户体质相关产品(用于 AI 推荐)
	var productList string
	if constitution != nil {
		products, _ := s.productRepo.GetByConstitution(constitution.PrimaryConstitution, 5)
		if len(products) > 0 {
			productList = "可推荐产品:\n"
			for _, p := range products {
				productList += fmt.Sprintf("- %s ¥%.0f %s\n", p.Name, p.Price, p.MallURL)
			}
		}
	}

	return fmt.Sprintf(systemPromptTemplate, userProfile, constitutionInfo, medicationHistory, productList)
}

步骤 5:创建产品 Handler

创建 server/internal/api/handler/product.go

package handler

import (
	"health-ai/internal/api/middleware"
	"health-ai/internal/repository/impl"
	"health-ai/pkg/response"

	"github.com/gin-gonic/gin"
)

type ProductHandler struct {
	productRepo      *impl.ProductRepository
	constitutionRepo *impl.ConstitutionRepository
}

func NewProductHandler() *ProductHandler {
	return &ProductHandler{
		productRepo:      impl.NewProductRepository(),
		constitutionRepo: impl.NewConstitutionRepository(),
	}
}

// GetProducts 获取产品列表
func (h *ProductHandler) GetProducts(c *gin.Context) {
	category := c.Query("category")
	products, err := h.productRepo.GetAll(category)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}
	response.Success(c, products)
}

// GetProduct 获取产品详情
func (h *ProductHandler) GetProduct(c *gin.Context) {
	var id uint
	fmt.Sscanf(c.Param("id"), "%d", &id)

	product, err := h.productRepo.GetByID(id)
	if err != nil {
		response.Error(c, 404, "产品不存在")
		return
	}
	response.Success(c, product)
}

// GetRecommendProducts 获取推荐产品
func (h *ProductHandler) GetRecommendProducts(c *gin.Context) {
	userID := middleware.GetUserID(c)

	// 获取用户体质
	constitution, err := h.constitutionRepo.GetLatestAssessment(userID)
	if err != nil {
		response.Error(c, 400, "请先完成体质测评")
		return
	}

	products, err := h.productRepo.GetByConstitution(constitution.PrimaryConstitution, 6)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}
	response.Success(c, products)
}

// SearchProducts 搜索产品
func (h *ProductHandler) SearchProducts(c *gin.Context) {
	keyword := c.Query("keyword")
	if keyword == "" {
		response.Error(c, 400, "请输入搜索关键词")
		return
	}

	products, err := h.productRepo.GetByKeywords([]string{keyword}, 10)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}
	response.Success(c, products)
}

步骤 6:更新路由

router.go 中添加:

// 产品路由
products := api.Group("/products")
{
	products.GET("", productHandler.GetProducts)
	products.GET("/:id", productHandler.GetProduct)
	products.GET("/recommend", authMiddleware, productHandler.GetRecommendProducts)
	products.GET("/search", productHandler.SearchProducts)
}

步骤 7:更新数据库初始化

main.go 中调用:

// 初始化产品数据
database.SeedProducts()

需要创建的文件清单

文件路径 说明
internal/model/product.go 产品数据模型
internal/database/seed_products.go 产品种子数据(36条)
internal/repository/impl/product.go 产品 Repository
internal/api/handler/product.go 产品 Handler

模拟数据统计

分类 数量 说明
体质调养类 20 补气、温阳、滋阴、祛湿、活血、理气、抗敏、综合
中老年常见类 16 心脑血管、骨关节、血糖、助眠、健脑、润肠、护眼、免疫
总计 36 -

验收标准

  • 产品列表正常显示
  • 按分类筛选正常
  • 根据体质推荐产品正常
  • 根据症状搜索产品正常
  • AI 回答中包含产品推荐链接
  • 种子数据正确初始化

预计耗时

30-40 分钟


下一步

后端开发全部完成!进入 03-Web前端开发/01-项目结构初始化.md