将所有 IoT 相关的数据模型从 internal/iot/model/ 迁移到 internal/model/, 实现全局统一的模型层架构,符合项目横向分层设计原则。 变更内容: - 迁移 11 个 IoT 模型文件(carrier, iot_card, device, order, package 等) - 删除 internal/iot/model/ 目录 - 更新文档中的模型路径引用(25 处) - 创建重构总结文档 - 归档 OpenSpec 变更为 2026-01-12-refactor-iot-model-location - 创建 model-organization 规格文档 验证结果: - 编译通过(go build 成功) - 静态分析通过(go vet 无错误) - 代码格式通过(go fmt 无变更) - 无 Go 代码引用旧路径 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
package openapi
|
||
|
||
import (
|
||
"encoding/json"
|
||
"os"
|
||
"path/filepath"
|
||
|
||
"github.com/swaggest/openapi-go/openapi3"
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// Generator OpenAPI 文档生成器
|
||
type Generator struct {
|
||
Reflector *openapi3.Reflector
|
||
}
|
||
|
||
// NewGenerator 创建一个新的生成器实例
|
||
func NewGenerator(title, version string) *Generator {
|
||
reflector := openapi3.Reflector{}
|
||
reflector.Spec = &openapi3.Spec{
|
||
Openapi: "3.0.3",
|
||
Info: openapi3.Info{
|
||
Title: title,
|
||
Version: version,
|
||
},
|
||
}
|
||
return &Generator{Reflector: &reflector}
|
||
}
|
||
|
||
// AddOperation 向 OpenAPI 规范中添加一个操作
|
||
func (g *Generator) AddOperation(method, path, summary string, input interface{}, output interface{}, tags ...string) {
|
||
op := openapi3.Operation{
|
||
Summary: &summary,
|
||
Tags: tags,
|
||
}
|
||
|
||
// 反射输入 (请求参数/Body)
|
||
if input != nil {
|
||
// SetRequest 根据结构体标签自动检测 Body、Query 或 Path 参数
|
||
if err := g.Reflector.SetRequest(&op, input, method); err != nil {
|
||
panic(err) // 生成过程中出错直接 panic,以便快速发现问题
|
||
}
|
||
}
|
||
|
||
// 反射输出 (响应 Body)
|
||
if output != nil {
|
||
if err := g.Reflector.SetJSONResponse(&op, output, 200); err != nil {
|
||
panic(err)
|
||
}
|
||
}
|
||
|
||
// 将操作添加到规范中
|
||
if err := g.Reflector.Spec.AddOperation(method, path, op); err != nil {
|
||
panic(err)
|
||
}
|
||
}
|
||
|
||
// Save 将规范导出为 YAML 文件
|
||
func (g *Generator) Save(filename string) error {
|
||
// 确保目录存在
|
||
dir := filepath.Dir(filename)
|
||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 安全的方法:MarshalJSON -> Unmarshal -> MarshalYAML
|
||
// 这确保了我们遵守 openapi3 库中定义的 `json` 标签
|
||
jsonBytes, err := g.Reflector.Spec.MarshalJSON()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var obj interface{}
|
||
if err := json.Unmarshal(jsonBytes, &obj); err != nil {
|
||
return err
|
||
}
|
||
|
||
yamlBytes, err := yaml.Marshal(obj)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return os.WriteFile(filename, yamlBytes, 0644)
|
||
}
|