| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | package entities | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2025-07-31 15:41:00 +08:00
										 |  |  |  | 	"errors" | 
					
						
							|  |  |  |  | 	"fmt" | 
					
						
							|  |  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | 	"time" | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-20 20:53:26 +08:00
										 |  |  |  | 	"github.com/google/uuid" | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | 	"gorm.io/gorm" | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ProductDocumentation 产品文档实体 | 
					
						
							|  |  |  |  | type ProductDocumentation struct { | 
					
						
							| 
									
										
										
										
											2025-07-31 15:41:00 +08:00
										 |  |  |  | 	ID              string `gorm:"primaryKey;type:varchar(36)" comment:"文档ID"` | 
					
						
							|  |  |  |  | 	ProductID       string `gorm:"type:varchar(36);not null;uniqueIndex" comment:"产品ID"` | 
					
						
							|  |  |  |  | 	RequestURL      string `gorm:"type:varchar(500);not null" comment:"请求链接"` | 
					
						
							|  |  |  |  | 	RequestMethod   string `gorm:"type:varchar(20);not null" comment:"请求方法"` | 
					
						
							|  |  |  |  | 	BasicInfo       string `gorm:"type:text" comment:"基础说明(请求头配置、参数加密等)"` | 
					
						
							|  |  |  |  | 	RequestParams   string `gorm:"type:text" comment:"请求参数"` | 
					
						
							|  |  |  |  | 	ResponseFields  string `gorm:"type:text" comment:"返回字段说明"` | 
					
						
							|  |  |  |  | 	ResponseExample string `gorm:"type:text" comment:"响应示例"` | 
					
						
							|  |  |  |  | 	ErrorCodes      string `gorm:"type:text" comment:"错误代码"` | 
					
						
							|  |  |  |  | 	Version         string `gorm:"type:varchar(20);default:'1.0'" comment:"文档版本"` | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | 	// 关联关系 | 
					
						
							|  |  |  |  | 	Product *Product `gorm:"foreignKey:ProductID" comment:"产品"` | 
					
						
							| 
									
										
										
										
											2025-07-31 15:41:00 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | 	CreatedAt time.Time      `gorm:"autoCreateTime" comment:"创建时间"` | 
					
						
							|  |  |  |  | 	UpdatedAt time.Time      `gorm:"autoUpdateTime" comment:"更新时间"` | 
					
						
							|  |  |  |  | 	DeletedAt gorm.DeletedAt `gorm:"index" comment:"软删除时间"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-20 20:53:26 +08:00
										 |  |  |  | // BeforeCreate GORM钩子:创建前自动生成UUID | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) BeforeCreate(tx *gorm.DB) error { | 
					
						
							|  |  |  |  | 	if pd.ID == "" { | 
					
						
							|  |  |  |  | 		pd.ID = uuid.New().String() | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | // IsValid 检查文档是否有效 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) IsValid() bool { | 
					
						
							|  |  |  |  | 	return pd.DeletedAt.Time.IsZero() | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UpdateContent 更新文档内容 | 
					
						
							| 
									
										
										
										
											2025-07-31 15:41:00 +08:00
										 |  |  |  | func (pd *ProductDocumentation) UpdateContent(requestURL, requestMethod, basicInfo, requestParams, responseFields, responseExample, errorCodes string) { | 
					
						
							|  |  |  |  | 	pd.RequestURL = requestURL | 
					
						
							|  |  |  |  | 	pd.RequestMethod = requestMethod | 
					
						
							|  |  |  |  | 	pd.BasicInfo = basicInfo | 
					
						
							|  |  |  |  | 	pd.RequestParams = requestParams | 
					
						
							|  |  |  |  | 	pd.ResponseFields = responseFields | 
					
						
							|  |  |  |  | 	pd.ResponseExample = responseExample | 
					
						
							|  |  |  |  | 	pd.ErrorCodes = errorCodes | 
					
						
							| 
									
										
										
										
											2025-07-15 13:21:34 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // IncrementVersion 增加版本号 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) IncrementVersion() { | 
					
						
							|  |  |  |  | 	// 简单的版本号递增逻辑,实际项目中可能需要更复杂的版本管理 | 
					
						
							|  |  |  |  | 	if pd.Version == "" { | 
					
						
							|  |  |  |  | 		pd.Version = "1.0" | 
					
						
							|  |  |  |  | 	} else { | 
					
						
							|  |  |  |  | 		// 这里可以实现更复杂的版本号递增逻辑 | 
					
						
							|  |  |  |  | 		pd.Version = pd.Version + ".1" | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-31 15:41:00 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Validate 验证文档完整性 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) Validate() error { | 
					
						
							|  |  |  |  | 	if pd.RequestURL == "" { | 
					
						
							|  |  |  |  | 		return errors.New("请求链接不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.RequestMethod == "" { | 
					
						
							|  |  |  |  | 		return errors.New("请求方法不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.ProductID == "" { | 
					
						
							|  |  |  |  | 		return errors.New("产品ID不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 验证请求方法 | 
					
						
							|  |  |  |  | 	validMethods := []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"} | 
					
						
							|  |  |  |  | 	methodValid := false | 
					
						
							|  |  |  |  | 	for _, method := range validMethods { | 
					
						
							|  |  |  |  | 		if strings.ToUpper(pd.RequestMethod) == method { | 
					
						
							|  |  |  |  | 			methodValid = true | 
					
						
							|  |  |  |  | 			break | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if !methodValid { | 
					
						
							|  |  |  |  | 		return fmt.Errorf("无效的请求方法: %s", pd.RequestMethod) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 验证URL格式(简单验证) | 
					
						
							|  |  |  |  | 	if !strings.HasPrefix(pd.RequestURL, "http://") && !strings.HasPrefix(pd.RequestURL, "https://") { | 
					
						
							|  |  |  |  | 		return errors.New("请求链接必须以http://或https://开头") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 验证版本号格式 | 
					
						
							|  |  |  |  | 	if pd.Version != "" { | 
					
						
							|  |  |  |  | 		if !isValidVersion(pd.Version) { | 
					
						
							|  |  |  |  | 			return fmt.Errorf("无效的版本号格式: %s", pd.Version) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // CanPublish 检查是否可以发布 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) CanPublish() error { | 
					
						
							|  |  |  |  | 	if err := pd.Validate(); err != nil { | 
					
						
							|  |  |  |  | 		return fmt.Errorf("文档验证失败: %w", err) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.BasicInfo == "" { | 
					
						
							|  |  |  |  | 		return errors.New("基础说明不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.RequestParams == "" { | 
					
						
							|  |  |  |  | 		return errors.New("请求参数不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UpdateDocumentation 更新文档内容并自动递增版本 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) UpdateDocumentation(requestURL, requestMethod, basicInfo, requestParams, responseFields, responseExample, errorCodes string) error { | 
					
						
							|  |  |  |  | 	// 验证必填字段 | 
					
						
							|  |  |  |  | 	if requestURL == "" || requestMethod == "" { | 
					
						
							|  |  |  |  | 		return errors.New("请求链接和请求方法不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 更新内容 | 
					
						
							|  |  |  |  | 	pd.UpdateContent(requestURL, requestMethod, basicInfo, requestParams, responseFields, responseExample, errorCodes) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 自动递增版本 | 
					
						
							|  |  |  |  | 	pd.IncrementVersion() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetDocumentationSummary 获取文档摘要 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) GetDocumentationSummary() map[string]interface{} { | 
					
						
							|  |  |  |  | 	return map[string]interface{}{ | 
					
						
							|  |  |  |  | 		"id":          pd.ID, | 
					
						
							|  |  |  |  | 		"product_id":  pd.ProductID, | 
					
						
							|  |  |  |  | 		"request_url": pd.RequestURL, | 
					
						
							|  |  |  |  | 		"method":      pd.RequestMethod, | 
					
						
							|  |  |  |  | 		"version":     pd.Version, | 
					
						
							|  |  |  |  | 		"created_at":  pd.CreatedAt, | 
					
						
							|  |  |  |  | 		"updated_at":  pd.UpdatedAt, | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // HasRequiredFields 检查是否包含必需字段 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) HasRequiredFields() bool { | 
					
						
							|  |  |  |  | 	return pd.RequestURL != "" && | 
					
						
							|  |  |  |  | 		pd.RequestMethod != "" && | 
					
						
							|  |  |  |  | 		pd.ProductID != "" && | 
					
						
							|  |  |  |  | 		pd.BasicInfo != "" && | 
					
						
							|  |  |  |  | 		pd.RequestParams != "" | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // IsComplete 检查文档是否完整 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) IsComplete() bool { | 
					
						
							|  |  |  |  | 	return pd.HasRequiredFields() && | 
					
						
							|  |  |  |  | 		pd.ResponseFields != "" && | 
					
						
							|  |  |  |  | 		pd.ResponseExample != "" && | 
					
						
							|  |  |  |  | 		pd.ErrorCodes != "" | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetCompletionPercentage 获取文档完成度百分比 | 
					
						
							|  |  |  |  | func (pd *ProductDocumentation) GetCompletionPercentage() int { | 
					
						
							|  |  |  |  | 	totalFields := 8 // 总字段数 | 
					
						
							|  |  |  |  | 	completedFields := 0 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if pd.RequestURL != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.RequestMethod != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.BasicInfo != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.RequestParams != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.ResponseFields != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.ResponseExample != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if pd.ErrorCodes != "" { | 
					
						
							|  |  |  |  | 		completedFields++ | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return (completedFields * 100) / totalFields | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // isValidVersion 验证版本号格式 | 
					
						
							|  |  |  |  | func isValidVersion(version string) bool { | 
					
						
							|  |  |  |  | 	// 简单的版本号验证:x.y.z 格式 | 
					
						
							|  |  |  |  | 	parts := strings.Split(version, ".") | 
					
						
							|  |  |  |  | 	if len(parts) < 1 || len(parts) > 3 { | 
					
						
							|  |  |  |  | 		return false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for _, part := range parts { | 
					
						
							|  |  |  |  | 		if part == "" { | 
					
						
							|  |  |  |  | 			return false | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		// 检查是否为数字 | 
					
						
							|  |  |  |  | 		for _, char := range part { | 
					
						
							|  |  |  |  | 			if char < '0' || char > '9' { | 
					
						
							|  |  |  |  | 				return false | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return true | 
					
						
							|  |  |  |  | } |