feat: 优化 API 文档生成和 Swagger UI 服务

- 优化 make docs 命令:
  * 自动检查并安装 swag 工具
  * 自动过滤 swag 生成过程中的警告信息
  * 自动修复生成的 docs.go 文件中的兼容性问题(移除 LeftDelim 和 RightDelim 字段)

- 优化 make docs-serve 命令:
  * 使用 Docker 运行 Swagger UI 容器,提供完整的 Swagger UI 界面
  * 新增 make docs-stop 命令,用于停止 Swagger UI 容器
  * 引入 SWAGGER_PORT 变量统一管理 Swagger UI 端口配置(默认 8081)

- 修复应用内置 Swagger UI 无法加载文档问题:
  * 在 main.go 中导入生成的 docs 包(_ "yinli-api/doc/dev")
  * 修复 docs.go 文件中的兼容性问题
  * 解决 "Failed to load API definition" 错误

- 更新 CHANGELOG.md,记录所有变更
This commit is contained in:
Table 2025-11-29 20:07:24 +08:00
parent 757abb799c
commit 84055fecfe
3 changed files with 93 additions and 5 deletions

View File

@ -24,6 +24,17 @@
- 支持本地模式和 Docker 模式的动态切换 - 支持本地模式和 Docker 模式的动态切换
- `make dev/stage/prod` 使用 `localhost` - `make dev/stage/prod` 使用 `localhost`
- `make docker-up-*` 使用 `host.docker.internal` - `make docker-up-*` 使用 `host.docker.internal`
- **Docker 命令命名优化**
- 将 `docker-logs` 重命名为 `docker-logs-dev`,保持与 `docker-logs-stage``docker-logs-prod` 的命名一致性
- 统一日志查看命令命名规范
- **API 文档生成优化**
- `make docs` 命令自动检查并安装 swag 工具
- 自动过滤 swag 生成过程中的警告信息
- 自动修复生成的 `docs.go` 文件中的兼容性问题
- **Swagger UI 服务优化**
- `make docs-serve` 使用 Docker 运行 Swagger UI 容器,提供完整的 Swagger UI 界面
- 新增 `make docs-stop` 命令,用于停止 Swagger UI 容器
- 引入 `SWAGGER_PORT` 变量统一管理 Swagger UI 端口配置
### 🐛 问题修复 ### 🐛 问题修复
- **修复 Docker 模式下 SERVER_PORT 未生效问题** - **修复 Docker 模式下 SERVER_PORT 未生效问题**
@ -38,13 +49,19 @@
- 增加优雅关闭时间到 60 秒 - 增加优雅关闭时间到 60 秒
- 使用 `init` 进程管理子进程 - 使用 `init` 进程管理子进程
- 添加自动检测和重试机制 - 添加自动检测和重试机制
- **修复应用内置 Swagger UI 无法加载文档问题**
- 在 `main.go` 中导入生成的 docs 包
- 修复 `docs.go` 文件中的兼容性问题(移除不兼容的 `LeftDelim``RightDelim` 字段)
- 解决 "Failed to load API definition" 错误
### 📚 文档更新 ### 📚 文档更新
- 新增 CHANGELOG.md 文件,记录项目所有重要变更,按功能类型分类
- 添加 SERVER_PORT 配置说明,包括影响范围和修改方法 - 添加 SERVER_PORT 配置说明,包括影响范围和修改方法
- 添加 Docker 容器连接宿主机服务的完整排查指南 - 添加 Docker 容器连接宿主机服务的完整排查指南
- 添加端口进程管理说明 - 添加端口进程管理说明
- 添加 Docker 权限问题解决方案 - 添加 Docker 权限问题解决方案
- 添加常见错误信息和排查步骤 - 添加常见错误信息和排查步骤
- 清理项目中的 PDF 文件PROJECT_SUMMARY.pdf、README.pdf
--- ---

View File

@ -19,6 +19,9 @@ DOCKER_COMPOSE := $(DOCKER) compose
# 应用端口 # 应用端口
SERVER_PORT := 1234 SERVER_PORT := 1234
# Swagger UI 端口
SWAGGER_PORT := 8081
# 默认目标 # 默认目标
.PHONY: help .PHONY: help
help: ## 显示帮助信息 help: ## 显示帮助信息
@ -245,13 +248,78 @@ benchmark: ## 运行基准测试
docs: ## 生成API文档 docs: ## 生成API文档
@echo "生成API文档..." @echo "生成API文档..."
@mkdir -p $(DOC_DIR)/dev $(DOC_DIR)/stage $(DOC_DIR)/prod @mkdir -p $(DOC_DIR)/dev $(DOC_DIR)/stage $(DOC_DIR)/prod
@echo "请先安装 swag: go install github.com/swaggo/swag/cmd/swag@latest" @if ! command -v swag >/dev/null 2>&1; then \
@echo "然后运行: swag init -g src/main.go -o doc/dev --parseDependency --parseInternal" echo "⚠️ swag 未安装,正在安装..."; \
$(GO) install github.com/swaggo/swag/cmd/swag@latest; \
if ! command -v swag >/dev/null 2>&1; then \
echo "❌ 安装失败,请手动执行: go install github.com/swaggo/swag/cmd/swag@latest"; \
echo " 然后运行: swag init -g src/main.go -o doc/dev --dir src --parseDependency --parseInternal"; \
exit 1; \
fi; \
fi; \
echo "✅ swag 已安装,开始生成文档..."; \
swag init -g src/main.go -o $(DOC_DIR)/dev --parseDependency --parseInternal 2>&1 | \
grep -vE "(failed to evaluate const mProfCycleWrap|failed to get package name in dir: ./|cannot find all dependencies|^$$)" || true; \
if [ -f "$(DOC_DIR)/dev/swagger.json" ]; then \
echo "修复生成的 docs.go 文件兼容性问题..."; \
sed -i.tmp '/^[[:space:]]*LeftDelim:/d; /^[[:space:]]*RightDelim:/d' $(DOC_DIR)/dev/docs.go 2>/dev/null || true; \
rm -f $(DOC_DIR)/dev/docs.go.tmp 2>/dev/null || true; \
echo "✅ API 文档已生成到 $(DOC_DIR)/dev/"; \
else \
echo "❌ 文档生成失败"; \
exit 1; \
fi
.PHONY: docs-serve .PHONY: docs-serve
docs-serve: docs ## 启动文档服务器 docs-serve: docs ## 启动 Swagger UI 文档服务器(使用 Docker
@echo "启动文档服务器..." @echo "启动 Swagger UI 文档服务器..."
@cd $(DOC_DIR) && python3 -m http.server 8081 @if command -v docker >/dev/null 2>&1; then \
if $(DOCKER) ps -a --format "{{.Names}}" | grep -q "^swagger-ui$$"; then \
echo "⚠️ Swagger UI 容器已存在,正在停止旧容器..."; \
$(DOCKER) stop swagger-ui >/dev/null 2>&1; \
$(DOCKER) rm swagger-ui >/dev/null 2>&1; \
fi; \
echo "使用 Docker 启动 Swagger UI..."; \
cd $(DOC_DIR)/dev && \
$(DOCKER) run --rm -d \
--name swagger-ui \
-p $(SWAGGER_PORT):8080 \
-e SWAGGER_JSON=/doc/swagger.json \
-v $$(pwd):/doc \
swaggerapi/swagger-ui:latest >/dev/null 2>&1 && \
sleep 2 && \
echo "✅ Swagger UI 已启动: http://localhost:$(SWAGGER_PORT)"; \
echo ""; \
echo "提示:"; \
echo " - 停止服务器: make docs-stop"; \
echo " - 或直接启动应用访问: http://localhost:$(SERVER_PORT)/swagger/index.html"; \
echo ""; \
echo "按 Ctrl+C 退出(容器将继续运行,使用 'make docs-stop' 停止)"; \
trap 'echo ""; echo "提示: 使用 make docs-stop 停止 Swagger UI 容器"; exit' INT TERM; \
while true; do sleep 1; done; \
else \
echo "⚠️ Docker 未安装"; \
echo ""; \
echo "方案 1: 安装 Docker 后使用: make docs-serve"; \
echo "方案 2: 启动应用后访问: http://localhost:$(SERVER_PORT)/swagger/index.html"; \
echo ""; \
echo "当前提供静态文件服务(仅文件列表): http://localhost:$(SWAGGER_PORT)"; \
cd $(DOC_DIR)/dev && python3 -m http.server $(SWAGGER_PORT); \
fi
.PHONY: docs-stop
docs-stop: ## 停止 Swagger UI 文档服务器
@if command -v docker >/dev/null 2>&1; then \
if $(DOCKER) ps -a --format "{{.Names}}" | grep -q "^swagger-ui$$"; then \
$(DOCKER) stop swagger-ui >/dev/null 2>&1 && \
echo "✅ Swagger UI 容器已停止" || \
echo "❌ 停止 Swagger UI 容器失败"; \
else \
echo " Swagger UI 容器未运行"; \
fi; \
else \
echo "⚠️ Docker 未安装"; \
fi
# Docker 相关 # Docker 相关
.PHONY: docker-build .PHONY: docker-build

View File

@ -13,6 +13,9 @@ import (
"yinli-api/src/pkg/database" "yinli-api/src/pkg/database"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
// 导入 Swagger 文档(根据环境动态导入)
_ "yinli-api/doc/dev" // 默认使用 dev 环境的文档
) )
// @title Yinli API // @title Yinli API