package model import ( "database/sql/driver" "encoding/json" "errors" "sundynix-micro-go/common/model" "time" ) // ========== 用户扩展表 ========== type UserProfile struct { model.BaseModel UserID string `gorm:"size:50;uniqueIndex;column:user_id" json:"userId"` MiniOpenID string `gorm:"size:80;column:mini_open_id" json:"miniOpenId"` NickName string `gorm:"size:100;column:nick_name" json:"nickName"` AvatarID string `gorm:"size:50;column:avatar_id" json:"avatarId"` LevelID string `gorm:"size:50;column:level_id" json:"levelId"` CurrentSunlight int64 `gorm:"not null;default:0;column:current_sunlight" json:"currentSunlight"` TotalSunlight int64 `gorm:"not null;default:0;column:total_sunlight" json:"totalSunlight"` PlantCount int64 `gorm:"not null;default:0;column:plant_count" json:"plantCount"` CareCount int64 `gorm:"not null;default:0;column:care_count" json:"careCount"` PostCount int64 `gorm:"not null;default:0;column:post_count" json:"postCount"` WaterCount int64 `gorm:"not null;default:0;column:water_count" json:"waterCount"` FertilizeCount int64 `gorm:"not null;default:0;column:fertilize_count" json:"fertilizeCount"` RepotCount int64 `gorm:"not null;default:0;column:repot_count" json:"repotCount"` PruneCount int64 `gorm:"not null;default:0;column:prune_count" json:"pruneCount"` PhotoCount int64 `gorm:"not null;default:0;column:photo_count" json:"photoCount"` } func (UserProfile) TableName() string { return "sundynix_plant_user_profile" } // ========== 我的植物 ========== type MyPlant struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` Name string `gorm:"size:20;column:name" json:"name"` PlantTime time.Time `gorm:"column:plant_time" json:"plantTime"` Status int `gorm:"column:status" json:"status"` Placement string `gorm:"size:50;column:placement" json:"placement"` PotMaterial string `gorm:"size:50;column:pot_material" json:"potMaterial"` PotSize string `gorm:"size:50;column:pot_size" json:"potSize"` Sunlight string `gorm:"size:50;column:sunlight" json:"sunlight"` PlantingMaterial string `gorm:"size:50;column:planting_material" json:"plantingMaterial"` // 关联(使用 Preload 加载,仅限本地 sundynix_plant_* 表) CarePlans []*CarePlan `gorm:"foreignKey:PlantID" json:"carePlans"` CareRecords []*CareRecord `gorm:"foreignKey:PlantID" json:"careRecords"` GrowthRecords []*GrowthRecord `gorm:"foreignKey:PlantID" json:"growthRecords"` CareTasks []*CareTask `gorm:"foreignKey:PlantID" json:"careTasks"` } func (MyPlant) TableName() string { return "sundynix_plant_my_plant" } type MyPlantOss struct { MyPlantID string `gorm:"size:50;primaryKey;column:sundynix_my_plant_id" json:"myPlantId"` OssID string `gorm:"size:50;primaryKey;column:sundynix_oss_id" json:"ossId"` } func (MyPlantOss) TableName() string { return "sundynix_plant_my_plant_oss" } // ========== 养护计划/记录/任务 ========== type CarePlan struct { model.BaseModel UserID string `gorm:"size:50;column:user_id" json:"userId"` PlantID string `gorm:"size:50;index;column:plant_id" json:"plantId"` Icon string `gorm:"type:text;column:icon" json:"icon"` Name string `gorm:"size:50;column:name" json:"name"` Period int `gorm:"column:period" json:"period"` TargetAction string `gorm:"size:32;index;column:target_action" json:"targetAction"` } func (CarePlan) TableName() string { return "sundynix_plant_care_plan" } type CareRecord struct { model.BaseModel UserID string `gorm:"size:50;column:user_id" json:"userId"` PlantID string `gorm:"size:50;index;column:plant_id" json:"plantId"` PlanID string `gorm:"size:50;index;column:plan_id" json:"planId"` Name string `gorm:"size:50;column:name" json:"name"` Remark string `gorm:"size:200;column:remark" json:"remark"` Icon string `gorm:"type:text;column:icon" json:"icon"` } func (CareRecord) TableName() string { return "sundynix_plant_care_record" } // CareTask 养护任务 status: 1=待完成 2=已完成 3=已过期 type CareTask struct { model.BaseModel UserID string `gorm:"size:50;column:user_id" json:"userId"` PlantID string `gorm:"size:50;index;column:plant_id" json:"plantId"` PlanID string `gorm:"size:50;index;column:plan_id" json:"planId"` Name string `gorm:"size:50;column:name" json:"name"` Icon string `gorm:"type:text;column:icon" json:"icon"` TargetAction string `gorm:"size:32;column:target_action" json:"targetAction"` DueDate time.Time `gorm:"column:due_date" json:"dueDate"` CompletedAt *time.Time `gorm:"column:completed_at" json:"completedAt"` Status int `gorm:"default:1;column:status" json:"status"` } func (CareTask) TableName() string { return "sundynix_plant_care_task" } // ========== 成长记录 ========== type GrowthRecord struct { model.BaseModel PlantID string `gorm:"size:50;index;column:plant_id" json:"plantId"` UserID string `gorm:"size:50;index;column:user_id" json:"userId"` Name string `gorm:"size:50;column:name" json:"name"` Tag string `gorm:"size:50;column:tag" json:"tag"` Desc string `gorm:"size:200;column:desc" json:"desc"` Content string `gorm:"size:200;column:content" json:"content"` } func (GrowthRecord) TableName() string { return "sundynix_plant_growth_record" } // ========== 百科 ========== type Wiki struct { model.BaseModel IsHot int `gorm:"column:is_hot" json:"isHot"` IsVectorSynced int `gorm:"column:is_vector_synced;type:tinyint;default:0" json:"isVectorSynced"` Name string `gorm:"size:50;column:name" json:"name"` LatinName string `gorm:"size:100;column:latin_name" json:"latinName"` Aliases string `gorm:"size:100;column:aliases" json:"aliases"` DistributionArea string `gorm:"type:text;column:distribution_area" json:"distributionArea"` Genus string `gorm:"size:20;column:genus" json:"genus"` Difficulty int `gorm:"column:difficulty" json:"difficulty"` LifeCycle string `gorm:"type:text;column:life_cycle" json:"lifeCycle"` GrowthHabit string `gorm:"type:text;column:growth_habit" json:"growthHabit"` ReproductionMethod string `gorm:"size:200;column:reproduction_method" json:"reproductionMethod"` PestsDiseases string `gorm:"size:200;column:pests_diseases" json:"pestsDiseases"` LightIntensity string `gorm:"size:50;column:light_intensity" json:"lightIntensity"` LightType string `gorm:"size:50;column:light_type" json:"lightType"` OptimalTempPeriod string `gorm:"size:30;column:optimal_temp_period" json:"optimalTempPeriod"` Stem string `gorm:"size:200;column:stem" json:"stem"` FoliageType string `gorm:"size:200;column:foliage_type" json:"foliageType"` FoliageColor string `gorm:"size:200;column:foliage_color" json:"foliageColor"` FoliageShape string `gorm:"size:200;column:foliage_shape" json:"foliageShape"` Height int `gorm:"column:height" json:"height"` FloweringPeriod string `gorm:"size:100;column:flowering_period" json:"floweringPeriod"` FloweringColor string `gorm:"size:100;column:flowering_color" json:"floweringColor"` FloweringShape string `gorm:"size:100;column:flowering_shape" json:"floweringShape"` FlowerDiameter int `gorm:"column:flower_diameter" json:"flowerDiameter"` Fruit string `gorm:"size:200;column:fruit" json:"fruit"` ClassID string `gorm:"size:50;index;column:class_id" json:"classId"` } func (Wiki) TableName() string { return "sundynix_plant_wiki" } type WikiClass struct { model.BaseModel Name string `gorm:"size:50;column:name" json:"name"` OssID string `gorm:"size:50;column:oss_id" json:"ossId"` } func (WikiClass) TableName() string { return "sundynix_plant_wiki_class" } type WikiOss struct { WikiID string `gorm:"size:50;primaryKey;column:wiki_id" json:"wikiId"` OssID string `gorm:"size:50;primaryKey;column:oss_id" json:"ossId"` } func (WikiOss) TableName() string { return "sundynix_plant_wiki_oss" } type WikiClassRelation struct { WikiID string `gorm:"size:50;primaryKey;column:wiki_id" json:"wikiId"` ClassID string `gorm:"size:50;primaryKey;column:class_id" json:"classId"` } func (WikiClassRelation) TableName() string { return "sundynix_plant_wiki_class_rel" } type WikiRelated struct { WikiID string `gorm:"size:50;primaryKey;column:wiki_id" json:"wikiId"` RelatedWikiID string `gorm:"size:50;primaryKey;column:related_wiki_id" json:"relatedWikiId"` } func (WikiRelated) TableName() string { return "sundynix_plant_wiki_related" } type UserStar struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` TargetID string `gorm:"size:50;index;column:target_id" json:"targetId"` Type string `gorm:"size:20;column:type" json:"type"` // wiki/post } func (UserStar) TableName() string { return "sundynix_plant_user_star" } // ========== 社区 ========== type Post struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` Title string `gorm:"size:100;column:title" json:"title"` Content string `gorm:"size:500;column:content" json:"content"` ViewCount int `gorm:"default:0;column:view_count" json:"viewCount"` CommentCount int `gorm:"default:0;column:comment_count" json:"commentCount"` LikeCount int `gorm:"default:0;column:like_count" json:"likeCount"` StarCount int `gorm:"default:0;column:star_count" json:"starCount"` Location string `gorm:"size:100;column:location" json:"location"` HasReviewed int `gorm:"default:0;column:has_reviewed" json:"hasReviewed"` TopicID string `gorm:"size:50;index;column:topic_id" json:"topicId"` // 关联(使用 Preload 加载,仅限本地 sundynix_plant_* 表) CommentList []*PostComment `gorm:"foreignKey:PostID" json:"commentList"` LikeList []*PostLike `gorm:"foreignKey:PostID" json:"likeList"` HasLiked int `gorm:"-" json:"hasLiked"` HasStar int `gorm:"-" json:"hasStar"` } func (Post) TableName() string { return "sundynix_plant_post" } type PostComment struct { model.BaseModel PostID string `gorm:"size:50;index;column:post_id" json:"postId"` UserID string `gorm:"size:50;column:user_id" json:"userId"` Content string `gorm:"size:500;column:content" json:"content"` ParentID string `gorm:"size:50;column:parent_id" json:"parentId"` } func (PostComment) TableName() string { return "sundynix_plant_post_comment" } type PostLike struct { model.BaseModel PostID string `gorm:"size:50;index;column:post_id" json:"postId"` UserID string `gorm:"size:50;index;column:user_id" json:"userId"` } type PostOss struct { PostID string `gorm:"size:50;primaryKey;column:post_id" json:"postId"` OssID string `gorm:"size:50;primaryKey;column:oss_id" json:"ossId"` } func (PostOss) TableName() string { return "sundynix_plant_post_oss" } type Topic struct { model.BaseModel Name string `gorm:"size:50;column:name" json:"name"` Title string `gorm:"size:100;column:title" json:"title"` Icon string `gorm:"type:text;column:icon" json:"icon"` Desc string `gorm:"size:200;column:desc" json:"desc"` Remark string `gorm:"size:500;column:remark" json:"remark"` StartTime *time.Time `gorm:"column:start_time" json:"startTime"` EndTime *time.Time `gorm:"column:end_time" json:"endTime"` PostCount int `gorm:"default:0;column:post_count" json:"postCount"` } func (Topic) TableName() string { return "sundynix_plant_topic" } // ========== 积分商城 ========== // ExchangeItem status: 1=上架 2=下架 type ExchangeItem struct { model.BaseModel Name string `gorm:"size:100;column:name" json:"name"` Desc string `gorm:"size:200;column:desc" json:"desc"` Description string `gorm:"type:text;column:description" json:"description"` ImgID string `gorm:"size:50;column:img_id" json:"imgId"` ImageID string `gorm:"size:50;column:image_id" json:"imageId"` Type string `gorm:"size:20;default:'PHYSICAL';column:type" json:"type"` Cost int64 `gorm:"column:cost" json:"cost"` CostSunlight int64 `gorm:"column:cost_sunlight" json:"costSunlight"` Stock int `gorm:"column:stock;default:-1" json:"stock"` LimitPerUser int `gorm:"column:limit_per_user;default:0" json:"limitPerUser"` Status int `gorm:"default:1;column:status" json:"status"` Sort int `gorm:"default:0;column:sort" json:"sort"` StartTime *time.Time `gorm:"column:start_time" json:"startTime"` EndTime *time.Time `gorm:"column:end_time" json:"endTime"` } func (ExchangeItem) TableName() string { return "sundynix_plant_exchange_item" } // ExchangeOrder status: 0=待处理 1=已完成 2=已取消 type ExchangeOrder struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` ItemID string `gorm:"size:50;column:item_id" json:"itemId"` ItemName string `gorm:"size:100;column:item_name" json:"itemName"` Cost int64 `gorm:"column:cost" json:"cost"` CostSunlight int64 `gorm:"column:cost_sunlight" json:"costSunlight"` Quantity int `gorm:"column:quantity;default:1" json:"quantity"` Status int `gorm:"default:1;column:status" json:"status"` ItemType string `gorm:"size:20;column:item_type" json:"itemType"` RecipientName string `gorm:"size:50;column:recipient_name" json:"recipientName"` Phone string `gorm:"size:20;column:phone" json:"phone"` Address string `gorm:"size:255;column:address" json:"address"` TrackingNo string `gorm:"size:100;column:tracking_no" json:"trackingNo"` Remark string `gorm:"size:255;column:remark" json:"remark"` CompletedAt *time.Time `gorm:"column:completed_at" json:"completedAt"` } func (ExchangeOrder) TableName() string { return "sundynix_plant_exchange_order" } // ========== 等级/徽章配置 ========== type LevelConfig struct { model.BaseModel Level int `gorm:"column:level" json:"level"` Title string `gorm:"size:50;column:title" json:"title"` MinSunlight int64 `gorm:"column:min_sunlight" json:"minSunlight"` Perks string `gorm:"size:200;column:perks" json:"perks"` } func (LevelConfig) TableName() string { return "sundynix_plant_level_config" } type BadgeConfig struct { model.BaseModel Name string `gorm:"size:64;column:name" json:"name"` Description string `gorm:"size:255;column:description" json:"description"` IconID string `gorm:"size:50;column:icon_id" json:"iconId"` Dimension string `gorm:"size:32;index;column:dimension" json:"dimension"` GroupID string `gorm:"size:64;index;column:group_id" json:"groupId"` Tier int `gorm:"default:1;column:tier" json:"tier"` TargetAction string `gorm:"size:32;index;column:target_action" json:"targetAction"` Threshold int64 `gorm:"column:threshold" json:"threshold"` Comparator string `gorm:"size:10;default:'>=';column:comparator" json:"comparator"` RewardSunlight int64 `gorm:"column:reward_sunlight" json:"rewardSunlight"` Sort int `gorm:"default:1;column:sort" json:"sort"` } func (BadgeConfig) TableName() string { return "sundynix_plant_badge_config" } type UserBadge struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` BadgeID string `gorm:"size:50;index;column:badge_id" json:"badgeId"` AcquiredAt time.Time `gorm:"autoCreateTime;column:acquired_at" json:"acquiredAt"` } func (UserBadge) TableName() string { return "sundynix_plant_user_badge" } // ========== AI ========== // AiChatHistory 匹配旧项目 question/answer 字段 type AiChatHistory struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` Question string `gorm:"type:text;column:question" json:"question"` Answer string `gorm:"type:text;column:answer" json:"answer"` Role string `gorm:"size:20;column:role" json:"role"` Content string `gorm:"type:text;column:content" json:"content"` } func (AiChatHistory) TableName() string { return "sundynix_plant_ai_chat_history" } // ========== 成长记录图片关联 ========== // GrowthRecordOss 成长记录与图片关联表 type GrowthRecordOss struct { GrowthRecordID string `gorm:"size:50;index;column:growth_record_id" json:"growthRecordId"` OssID string `gorm:"size:50;index;column:oss_id" json:"ossId"` } func (GrowthRecordOss) TableName() string { return "sundynix_plant_growth_record_oss" } // ========== Banner ========== type Banner struct { model.BaseModel Title string `gorm:"size:100;column:title" json:"title"` ImageID string `gorm:"size:50;column:image_id" json:"imageId"` Sort int `gorm:"default:0;column:sort" json:"sort"` IsActive int `gorm:"default:1;column:is_active" json:"isActive"` TargetURL string `gorm:"size:255;column:target_url" json:"targetUrl"` } func (Banner) TableName() string { return "sundynix_plant_banner" } type MediaCheckResult struct { model.BaseModel TraceID string `gorm:"size:100;uniqueIndex;column:trace_id" json:"traceId"` PostID string `gorm:"size:50;index;column:post_id" json:"postId"` OssID string `gorm:"size:50;column:oss_id" json:"ossId"` UserID string `gorm:"size:50;column:user_id" json:"userId"` Status int `gorm:"column:status;default:0" json:"status"` Type int `gorm:"column:type" json:"type"` ErrMsg string `gorm:"size:255;column:err_msg" json:"errMsg"` } func (MediaCheckResult) TableName() string { return "sundynix_plant_media_check_result" } // ========== AI RAG 配置 ========== type SysAiConfig struct { model.BaseModel IsActive int `gorm:"column:is_active;type:tinyint;default:0;comment:是否激活(1是0否)" json:"isActive"` QdrantUrl string `gorm:"column:qdrant_url;type:varchar(255);comment:Qdrant接口地址" json:"qdrantUrl"` QdrantApiKey string `gorm:"column:qdrant_api_key;type:varchar(255);comment:Qdrant密钥" json:"qdrantApiKey"` QdrantCollection string `gorm:"column:qdrant_collection;type:varchar(100);comment:Qdrant集合名" json:"qdrantCollection"` VectorDimension int `gorm:"column:vector_dimension;type:int;comment:向量维度" json:"vectorDimension"` ChatProvider string `gorm:"column:chat_provider;type:varchar(50);comment:对话模型供应商" json:"chatProvider"` ChatApiUrl string `gorm:"column:chat_api_url;type:varchar(255);comment:对话模型接口地址" json:"chatApiUrl"` ChatApiKey string `gorm:"column:chat_api_key;type:varchar(255);comment:对话模型ApiKey" json:"chatApiKey"` ChatModelName string `gorm:"column:chat_model_name;type:varchar(100);comment:对话模型名称" json:"chatModelName"` EmbeddingProvider string `gorm:"column:embedding_provider;type:varchar(50);comment:Embedding模型供应商" json:"embeddingProvider"` EmbeddingApiUrl string `gorm:"column:embedding_api_url;type:varchar(255);comment:Embedding模型接口地址" json:"embeddingApiUrl"` EmbeddingApiKey string `gorm:"column:embedding_api_key;type:varchar(255);comment:Embedding模型ApiKey" json:"embeddingApiKey"` EmbeddingModelName string `gorm:"column:embedding_model_name;type:varchar(100);comment:Embedding模型名称" json:"embeddingModelName"` DailyQueryLimit int `gorm:"column:daily_query_limit;type:int;default:20;comment:每用户每日问答上限(0=不限)" json:"dailyQueryLimit"` } func (SysAiConfig) TableName() string { return "sundynix_plant_ai_config" } // ========== 植物识别记录 ========== type BaikeInfo struct { BaikeUrl string `json:"baike_url"` // 百度百科链接 ImageUrl string `json:"image_url"` // 植物图片链接 Description string `json:"description"` // 植物百科描述文本 } type ResultItem struct { Score float64 `json:"score"` // 匹配相似度得分(0-1) Name string `json:"name"` // 植物名称 BaikeInfo *BaikeInfo `json:"baike_info"` // 植物百科信息 } type ResultsArray []ResultItem // Scan 实现 sql.Scanner 接口:JSON String -> Go Struct (读库) func (r *ResultsArray) Scan(value interface{}) error { if value == nil { *r = make([]ResultItem, 0) return nil } bytes, ok := value.([]byte) if !ok { if str, ok := value.(string); ok { bytes = []byte(str) } else { return errors.New("type assertion to []byte/string failed") } } return json.Unmarshal(bytes, r) } // Value 实现 driver.Valuer 接口:Go Struct -> JSON String (存库) func (r ResultsArray) Value() (driver.Value, error) { if len(r) == 0 { return "[]", nil } return json.Marshal(r) } type ClassifyRecord struct { model.BaseModel UserID string `gorm:"size:50;index;column:user_id" json:"userId"` LogID uint64 `gorm:"column:log_id;index" json:"logId"` AllResults ResultsArray `gorm:"type:json;column:all_results" json:"allResults"` } func (ClassifyRecord) TableName() string { return "sundynix_plant_classify_record" }