2025-07-31 15:41:00 +08:00
|
|
|
|
package product
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
2025-12-03 12:03:42 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
|
"strings"
|
2025-07-31 15:41:00 +08:00
|
|
|
|
|
|
|
|
|
|
"tyapi-server/internal/application/product/dto/commands"
|
|
|
|
|
|
"tyapi-server/internal/application/product/dto/responses"
|
|
|
|
|
|
"tyapi-server/internal/domains/product/entities"
|
|
|
|
|
|
"tyapi-server/internal/domains/product/services"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// DocumentationApplicationServiceInterface 文档应用服务接口
|
|
|
|
|
|
type DocumentationApplicationServiceInterface interface {
|
|
|
|
|
|
// CreateDocumentation 创建文档
|
|
|
|
|
|
CreateDocumentation(ctx context.Context, cmd *commands.CreateDocumentationCommand) (*responses.DocumentationResponse, error)
|
|
|
|
|
|
|
|
|
|
|
|
// UpdateDocumentation 更新文档
|
|
|
|
|
|
UpdateDocumentation(ctx context.Context, id string, cmd *commands.UpdateDocumentationCommand) (*responses.DocumentationResponse, error)
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentation 获取文档
|
|
|
|
|
|
GetDocumentation(ctx context.Context, id string) (*responses.DocumentationResponse, error)
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentationByProductID 通过产品ID获取文档
|
|
|
|
|
|
GetDocumentationByProductID(ctx context.Context, productID string) (*responses.DocumentationResponse, error)
|
|
|
|
|
|
|
|
|
|
|
|
// DeleteDocumentation 删除文档
|
|
|
|
|
|
DeleteDocumentation(ctx context.Context, id string) error
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentationsByProductIDs 批量获取文档
|
|
|
|
|
|
GetDocumentationsByProductIDs(ctx context.Context, productIDs []string) ([]responses.DocumentationResponse, error)
|
2025-12-03 12:03:42 +08:00
|
|
|
|
|
|
|
|
|
|
// GenerateFullDocumentation 生成完整的接口文档(Markdown格式)
|
|
|
|
|
|
GenerateFullDocumentation(ctx context.Context, productID string) (string, error)
|
2025-07-31 15:41:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DocumentationApplicationService 文档应用服务
|
|
|
|
|
|
type DocumentationApplicationService struct {
|
|
|
|
|
|
docService *services.ProductDocumentationService
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewDocumentationApplicationService 创建文档应用服务实例
|
|
|
|
|
|
func NewDocumentationApplicationService(docService *services.ProductDocumentationService) *DocumentationApplicationService {
|
|
|
|
|
|
return &DocumentationApplicationService{
|
|
|
|
|
|
docService: docService,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CreateDocumentation 创建文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) CreateDocumentation(ctx context.Context, cmd *commands.CreateDocumentationCommand) (*responses.DocumentationResponse, error) {
|
|
|
|
|
|
// 创建文档实体
|
|
|
|
|
|
doc := &entities.ProductDocumentation{
|
|
|
|
|
|
RequestURL: cmd.RequestURL,
|
|
|
|
|
|
RequestMethod: cmd.RequestMethod,
|
|
|
|
|
|
BasicInfo: cmd.BasicInfo,
|
|
|
|
|
|
RequestParams: cmd.RequestParams,
|
|
|
|
|
|
ResponseFields: cmd.ResponseFields,
|
|
|
|
|
|
ResponseExample: cmd.ResponseExample,
|
|
|
|
|
|
ErrorCodes: cmd.ErrorCodes,
|
2025-12-03 12:03:42 +08:00
|
|
|
|
PDFFilePath: cmd.PDFFilePath,
|
2025-07-31 15:41:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 调用领域服务创建文档
|
|
|
|
|
|
err := s.docService.CreateDocumentation(ctx, cmd.ProductID, doc)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回响应
|
|
|
|
|
|
resp := responses.NewDocumentationResponse(doc)
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UpdateDocumentation 更新文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) UpdateDocumentation(ctx context.Context, id string, cmd *commands.UpdateDocumentationCommand) (*responses.DocumentationResponse, error) {
|
|
|
|
|
|
// 调用领域服务更新文档
|
|
|
|
|
|
err := s.docService.UpdateDocumentation(ctx, id,
|
|
|
|
|
|
cmd.RequestURL,
|
|
|
|
|
|
cmd.RequestMethod,
|
|
|
|
|
|
cmd.BasicInfo,
|
|
|
|
|
|
cmd.RequestParams,
|
|
|
|
|
|
cmd.ResponseFields,
|
|
|
|
|
|
cmd.ResponseExample,
|
|
|
|
|
|
cmd.ErrorCodes,
|
|
|
|
|
|
)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取更新后的文档
|
|
|
|
|
|
doc, err := s.docService.GetDocumentation(ctx, id)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 12:03:42 +08:00
|
|
|
|
// 更新PDF文件路径(如果提供)
|
|
|
|
|
|
if cmd.PDFFilePath != "" {
|
|
|
|
|
|
doc.PDFFilePath = cmd.PDFFilePath
|
|
|
|
|
|
err = s.docService.UpdateDocumentationEntity(ctx, doc)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("更新PDF文件路径失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 重新获取更新后的文档以确保获取最新数据
|
|
|
|
|
|
doc, err = s.docService.GetDocumentation(ctx, id)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-31 15:41:00 +08:00
|
|
|
|
// 返回响应
|
|
|
|
|
|
resp := responses.NewDocumentationResponse(doc)
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentation 获取文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) GetDocumentation(ctx context.Context, id string) (*responses.DocumentationResponse, error) {
|
|
|
|
|
|
doc, err := s.docService.GetDocumentation(ctx, id)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回响应
|
|
|
|
|
|
resp := responses.NewDocumentationResponse(doc)
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentationByProductID 通过产品ID获取文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) GetDocumentationByProductID(ctx context.Context, productID string) (*responses.DocumentationResponse, error) {
|
|
|
|
|
|
doc, err := s.docService.GetDocumentationByProductID(ctx, productID)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回响应
|
|
|
|
|
|
resp := responses.NewDocumentationResponse(doc)
|
|
|
|
|
|
return &resp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DeleteDocumentation 删除文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) DeleteDocumentation(ctx context.Context, id string) error {
|
|
|
|
|
|
return s.docService.DeleteDocumentation(ctx, id)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetDocumentationsByProductIDs 批量获取文档
|
|
|
|
|
|
func (s *DocumentationApplicationService) GetDocumentationsByProductIDs(ctx context.Context, productIDs []string) ([]responses.DocumentationResponse, error) {
|
|
|
|
|
|
docs, err := s.docService.GetDocumentationsByProductIDs(ctx, productIDs)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var docResponses []responses.DocumentationResponse
|
|
|
|
|
|
for _, doc := range docs {
|
|
|
|
|
|
docResponses = append(docResponses, responses.NewDocumentationResponse(doc))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return docResponses, nil
|
|
|
|
|
|
}
|
2025-12-03 12:03:42 +08:00
|
|
|
|
|
|
|
|
|
|
// GenerateFullDocumentation 生成完整的接口文档(Markdown格式)
|
|
|
|
|
|
func (s *DocumentationApplicationService) GenerateFullDocumentation(ctx context.Context, productID string) (string, error) {
|
|
|
|
|
|
// 通过产品ID获取文档
|
|
|
|
|
|
doc, err := s.docService.GetDocumentationByProductID(ctx, productID)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", fmt.Errorf("获取文档失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取文档时已经包含了产品信息(通过GetDocumentationWithProduct)
|
|
|
|
|
|
// 如果没有产品信息,通过文档ID获取
|
|
|
|
|
|
if doc.Product == nil && doc.ID != "" {
|
|
|
|
|
|
docWithProduct, err := s.docService.GetDocumentationWithProduct(ctx, doc.ID)
|
|
|
|
|
|
if err == nil && docWithProduct != nil {
|
|
|
|
|
|
doc = docWithProduct
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var markdown strings.Builder
|
|
|
|
|
|
|
|
|
|
|
|
// 添加文档标题
|
|
|
|
|
|
productName := "产品"
|
|
|
|
|
|
if doc.Product != nil {
|
|
|
|
|
|
productName = doc.Product.Name
|
|
|
|
|
|
}
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("# %s 接口文档\n\n", productName))
|
|
|
|
|
|
|
|
|
|
|
|
// 添加产品基本信息
|
|
|
|
|
|
if doc.Product != nil {
|
|
|
|
|
|
markdown.WriteString("## 产品信息\n\n")
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("- **产品名称**: %s\n", doc.Product.Name))
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("- **产品编号**: %s\n", doc.Product.Code))
|
|
|
|
|
|
if doc.Product.Description != "" {
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("- **产品描述**: %s\n", doc.Product.Description))
|
|
|
|
|
|
}
|
|
|
|
|
|
markdown.WriteString("\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加请求方式
|
|
|
|
|
|
markdown.WriteString("## 请求方式\n\n")
|
|
|
|
|
|
if doc.RequestURL != "" {
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("- **请求方法**: %s\n", doc.RequestMethod))
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("- **请求地址**: %s\n", doc.RequestURL))
|
|
|
|
|
|
markdown.WriteString("\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加请求方式详细说明
|
|
|
|
|
|
if doc.BasicInfo != "" {
|
|
|
|
|
|
markdown.WriteString("### 请求方式说明\n\n")
|
|
|
|
|
|
markdown.WriteString(doc.BasicInfo)
|
|
|
|
|
|
markdown.WriteString("\n\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加请求参数
|
|
|
|
|
|
if doc.RequestParams != "" {
|
|
|
|
|
|
markdown.WriteString("## 请求参数\n\n")
|
|
|
|
|
|
markdown.WriteString(doc.RequestParams)
|
|
|
|
|
|
markdown.WriteString("\n\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加返回字段说明
|
|
|
|
|
|
if doc.ResponseFields != "" {
|
|
|
|
|
|
markdown.WriteString("## 返回字段说明\n\n")
|
|
|
|
|
|
markdown.WriteString(doc.ResponseFields)
|
|
|
|
|
|
markdown.WriteString("\n\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加响应示例
|
|
|
|
|
|
if doc.ResponseExample != "" {
|
|
|
|
|
|
markdown.WriteString("## 响应示例\n\n")
|
|
|
|
|
|
markdown.WriteString(doc.ResponseExample)
|
|
|
|
|
|
markdown.WriteString("\n\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加错误代码
|
|
|
|
|
|
if doc.ErrorCodes != "" {
|
|
|
|
|
|
markdown.WriteString("## 错误代码\n\n")
|
|
|
|
|
|
markdown.WriteString(doc.ErrorCodes)
|
|
|
|
|
|
markdown.WriteString("\n\n")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加文档版本信息
|
|
|
|
|
|
markdown.WriteString("---\n\n")
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("**文档版本**: %s\n\n", doc.Version))
|
|
|
|
|
|
if doc.UpdatedAt.Year() > 1900 {
|
|
|
|
|
|
markdown.WriteString(fmt.Sprintf("**更新时间**: %s\n", doc.UpdatedAt.Format("2006-01-02 15:04:05")))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return markdown.String(), nil
|
|
|
|
|
|
}
|