文档优化

This commit is contained in:
xh
2025-11-30 02:44:35 +08:00
parent fd453b3d7f
commit 66bbb4c6bf
11 changed files with 327 additions and 95 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "x_admin",
"version": "0.0.1",
"version": "2.0.0",
"license": "MIT",
"type": "module",
"scripts": {

View File

@@ -1,4 +1,6 @@
# swag 2024-07-04
# swag 2025-11-30
[swag Go Doc](https://godoc.org/github.com/swaggo/swag)
@@ -28,7 +30,7 @@ Swag将Go的注释转换为Swagger2.0文档。我们为流行的 [Go Web Framewo
- [将扩展信息添加到结构字段](#将扩展信息添加到结构字段)
- [对展示的模型重命名](#对展示的模型重命名)
- [如何使用安全性注释](#如何使用安全性注释)
- [项目相关](#项目相关)
## 快速开始
@@ -79,6 +81,7 @@ OPTIONS:
--output value, -o value 文件(swagger.json, swagger.yaml and doc.go)输出目录 (默认: "./docs")
--parseVendor 是否解析vendor目录里的go源文件默认不
--parseDependency 是否解析依赖目录中的go源文件默认不
--parseDependencyLevel, --pdl 对'--parseDependency'参数进行增强, 是否解析依赖目录中的go源文件, 0 不解析, 1 只解析对象模型, 2 只解析API, 3 对象模型和API都解析 (default: 0)
--markdownFiles value, --md value 指定API的描述信息所使用的markdown文件所在的目录
--generatedTime 是否输出时间到输出文件docs.go的顶部默认是
--codeExampleFiles value, --cef value 解析包含用于 x-codeSamples 扩展的代码示例文件的文件夹,默认禁用
@@ -281,13 +284,13 @@ func (c *Controller) ListAccounts(ctx *gin.Context) {
swag init
```
4. 运行程序,然后在浏览器中访问 [here](http://localhost:8080/swagger/index.html) 。将看到Swagger 2.0 Api文档如下所示
4. 运行程序,然后在浏览器中访问 http://localhost:8080/swagger/index.html 。将看到Swagger 2.0 Api文档如下所示
![swagger_index.html](https://raw.githubusercontent.com/swaggo/swag/master/assets/swagger-image.png)
## 格式化说明
可以针对Swag的注释自动格式化就像`go fmt`
可以针对Swag的注释自动格式化就像`go fmt`
此处查看格式化结果 [here](https://github.com/swaggo/swag/tree/master/example/celler).
示例:
@@ -405,6 +408,7 @@ Example [celler/controller](https://github.com/swaggo/swag/tree/master/example/c
| png | image/png |
| jpeg | image/jpeg |
| gif | image/gif |
| event-stream | text/event-stream |
## 参数类型
@@ -475,7 +479,7 @@ type Foo struct {
| minLength | `integer` | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.2. |
| enums | [\*] | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1. |
| format | `string` | 上面提到的[类型](#parameterType)的扩展格式。有关更多详细信息,请参见[数据类型格式](https://swagger.io/specification/v2/#dataTypeFormat)。 |
| collectionFormat | `string` | 指定query数组参数的格式。 可能的值为: <ul><li>`csv` - 逗号分隔值 `foo,bar`.</li> <li>`ssv` - 空格分隔值 `foo bar`. </li><li>`tsv` - 制表符分隔值 `foo\tbar`. </li><li>`pipes` - 管道符分隔值 <code>foo&#124;bar</code>. </li><li>`multi` - 对应于多个参数实例,而不是单个实例 `foo=barfoo=baz` 的多个值。这仅对“`query`”或“`formData`”中的参数有效。</li> </ul> 默认值是 `csv`。 |
| collectionFormat | `string` | 指定query数组参数的格式。 可能的值为: <ul><li>`csv` - 逗号分隔值 `foo,bar`. <li>`ssv` - 空格分隔值 `foo bar`. <li>`tsv` - 制表符分隔值 `foo\tbar`. <li>`pipes` - 管道符分隔值 <code>foo&#124;bar</code>. <li>`multi` - 对应于多个参数实例,而不是单个实例 `foo=barfoo=baz` 的多个值。这仅对“`query`”或“`formData`”中的参数有效。 </ul> 默认值是 `csv`。 |
### 进一步的
@@ -720,6 +724,5 @@ type Resp struct {
使用AND条件。
```go
// @Security ApiKeyAuth
// @Security OAuth2Application[write, admin]
// @Security ApiKeyAuth && OAuth2Application[write, admin]
```

View File

@@ -54,6 +54,7 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) List(c *gin.Context) {
// @Summary {{{ .FunctionName }}}列表-所有
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
// @Produce json
// @Param token header string true "token"
{{{- range .Columns }}}
{{{- if .IsQuery }}}
{{{- if eq .HtmlType "datetime" }}}
@@ -64,7 +65,7 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) List(c *gin.Context) {
{{{- end }}}
{{{- end }}}
{{{- end }}}
// @Success 200 {object} response.Response{ data=[]{{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Success 200 {object} response.Response{data=[]{{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Router /api/admin/{{{ .ModuleName }}}/listAll [get]
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ListAll(c *gin.Context) {
var listReq schema.{{{ toUpperCamelCase .EntityName }}}ListReq
@@ -84,7 +85,7 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ListAll(c *gin.Context)
// @Param {{{toUpperCamelCase .GoField }}} query {{{goToTsType .GoType }}} false "{{{ .ColumnComment }}}"
{{{- end }}}
{{{- end }}}
// @Success 200 {object} response.Response{ data={{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Success 200 {object} response.Response{data={{{ toUpperCamelCase .EntityName }}}Resp} "成功"
// @Router /api/admin/{{{ .ModuleName }}}/detail [get]
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) Detail(c *gin.Context) {
var detailReq schema.{{{ toUpperCamelCase .EntityName }}}Primarykey
@@ -181,7 +182,7 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) DelBatch(c *gin.Context)
// @Summary {{{ .FunctionName }}}导出
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
// @Produce json
// @Produce octet-stream,json
// @Param token header string true "token"
{{{- range .Columns }}}
{{{- if .IsQuery }}}
@@ -193,6 +194,8 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) DelBatch(c *gin.Context)
{{{- end }}}
{{{- end }}}
{{{- end }}}
// @Success 200 {file} string "成功"
// @Failure 500 {object} response.Response "失败"
// @Router /api/admin/{{{ .ModuleName }}}/ExportFile [get]
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ExportFile(c *gin.Context) {
var listReq schema.{{{ toUpperCamelCase .EntityName }}}ListReq
@@ -215,6 +218,9 @@ func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ExportFile(c *gin.Contex
// @Summary {{{ .FunctionName }}}导入
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
// @Produce json
// @Param token header string true "token"
// @Param file formData file true "导入文件"
// @Success 200 {object} response.Response "成功"
// @Router /api/admin/{{{ .ModuleName }}}/ImportFile [post]
func (hd *{{{ toUpperCamelCase .ModuleName }}}Handler) ImportFile(c *gin.Context) {
file, _, err := c.Request.FormFile("file")

View File

@@ -63,9 +63,9 @@ type {{{ toUpperCamelCase .EntityName }}}Resp struct {
{{{- range .Columns }}}
{{{- if or .IsList .IsPk }}}
{{{- if .IsPk }}}
{{{ toUpperCamelCase .GoField }}} {{{.GoType }}} // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{.GoType }}} `swaggertype:"{{{goToTsType .GoType }}}"`// {{{ .ColumnComment }}}
{{{- else }}}
{{{ toUpperCamelCase .GoField }}} {{{goWithRespType .GoType }}} // {{{ .ColumnComment }}}
{{{ toUpperCamelCase .GoField }}} {{{goWithRespType .GoType }}} `swaggertype:"{{{goToTsType .GoType }}}"`// {{{ .ColumnComment }}}
{{{- end }}}
{{{- end }}}
{{{- end }}}

View File

@@ -307,7 +307,7 @@ func (gu genUtil) GoWithRespType(s string) string {
// 拼接字符串
func (gu genUtil) GetPageResp(s string) string {
return `response.Response{ data=response.PageResp{ lists=[]schema.` + s + `Resp}}`
return `response.Response{data=response.PageResp{lists=[]schema.` + s + `Resp}}`
}
// NameToPath 下划线文件路径

View File

@@ -12,7 +12,7 @@ type appConfig struct {
var AppConfig = appConfig{
AppName: "x_admin",
Version: "1.0.0",
Version: "0.0.0",
Port: 8080,
GinMode: "",
OssDomain: "",

View File

@@ -11,9 +11,9 @@ const docTemplate = `{
"title": "{{.Title}}",
"termsOfService": "http://x.adtk.cn",
"contact": {
"name": "API Support",
"name": "xh",
"url": "http://x.adtk.cn",
"email": "11675084@qq.com"
"email": "x@adtk.cn"
},
"license": {
"name": "MIT License",
@@ -24,6 +24,15 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/admin/apiList": {
"get": {
"tags": [
"公共接口"
],
"summary": "获取所有接口",
"responses": {}
}
},
"/api/admin/flow/flow_apply/add": {
"post": {
"produces": [
@@ -2953,7 +2962,20 @@ const docTemplate = `{
"in": "query"
}
],
"responses": {}
"responses": {
"200": {
"description": "成功",
"schema": {
"type": "file"
}
},
"500": {
"description": "失败",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/api/admin/user_protocol/ImportFile": {
@@ -2965,7 +2987,30 @@ const docTemplate = `{
"user_protocol-用户协议"
],
"summary": "用户协议导入",
"responses": {}
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "file",
"description": "导入文件",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "成功",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/api/admin/user_protocol/add": {
@@ -3127,7 +3172,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
" data": {
"data": {
"$ref": "#/definitions/schema.UserProtocolResp"
}
}
@@ -3283,7 +3328,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
" data": {
"data": {
"allOf": [
{
"$ref": "#/definitions/response.PageResp"
@@ -3291,7 +3336,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
" lists": {
"lists": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.UserProtocolResp"
@@ -3319,6 +3364,13 @@ const docTemplate = `{
],
"summary": "用户协议列表-所有",
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "string",
"description": "标题",
@@ -3373,7 +3425,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
" data": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.UserProtocolResp"
@@ -3387,6 +3439,47 @@ const docTemplate = `{
}
}
},
"/api/ws": {
"get": {
"tags": [
"公共接口"
],
"summary": "websocket连接",
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "string",
"description": "用户ID",
"name": "uid",
"in": "query",
"required": true
},
{
"type": "string",
"description": "房间ID",
"name": "room",
"in": "query",
"required": true
}
],
"responses": {}
}
},
"/swagger/doc.json": {
"get": {
"tags": [
"公共接口"
],
"summary": "swagger文档数据",
"responses": {}
}
},
"/system/admin/ListByDeptId/{deptId}": {
"get": {
"description": "获取部门的用户",
@@ -3857,11 +3950,6 @@ const docTemplate = `{
}
}
},
"securityDefinitions": {
"BasicAuth": {
"type": "basic"
}
},
"externalDocs": {
"description": "OpenAPI",
"url": "https://swagger.io/resources/open-api/"
@@ -3870,11 +3958,11 @@ const docTemplate = `{
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "0.0.1",
Version: "",
Host: "",
BasePath: "/",
Schemes: []string{},
Title: "x_admin文档",
Title: "",
Description: "x_admin是一个完整的后台管理系统",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,

View File

@@ -2,21 +2,28 @@
"swagger": "2.0",
"info": {
"description": "x_admin是一个完整的后台管理系统",
"title": "x_admin文档",
"termsOfService": "http://x.adtk.cn",
"contact": {
"name": "API Support",
"name": "xh",
"url": "http://x.adtk.cn",
"email": "11675084@qq.com"
"email": "x@adtk.cn"
},
"license": {
"name": "MIT License",
"url": "https://gitee.com/xiangheng/x_admin/blob/main/LICENSE"
},
"version": "0.0.1"
}
},
"basePath": "/",
"paths": {
"/api/admin/apiList": {
"get": {
"tags": [
"公共接口"
],
"summary": "获取所有接口",
"responses": {}
}
},
"/api/admin/flow/flow_apply/add": {
"post": {
"produces": [
@@ -2946,7 +2953,20 @@
"in": "query"
}
],
"responses": {}
"responses": {
"200": {
"description": "成功",
"schema": {
"type": "file"
}
},
"500": {
"description": "失败",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/api/admin/user_protocol/ImportFile": {
@@ -2958,7 +2978,30 @@
"user_protocol-用户协议"
],
"summary": "用户协议导入",
"responses": {}
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "file",
"description": "导入文件",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "成功",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/api/admin/user_protocol/add": {
@@ -3120,7 +3163,7 @@
{
"type": "object",
"properties": {
" data": {
"data": {
"$ref": "#/definitions/schema.UserProtocolResp"
}
}
@@ -3276,7 +3319,7 @@
{
"type": "object",
"properties": {
" data": {
"data": {
"allOf": [
{
"$ref": "#/definitions/response.PageResp"
@@ -3284,7 +3327,7 @@
{
"type": "object",
"properties": {
" lists": {
"lists": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.UserProtocolResp"
@@ -3312,6 +3355,13 @@
],
"summary": "用户协议列表-所有",
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "string",
"description": "标题",
@@ -3366,7 +3416,7 @@
{
"type": "object",
"properties": {
" data": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/schema.UserProtocolResp"
@@ -3380,6 +3430,47 @@
}
}
},
"/api/ws": {
"get": {
"tags": [
"公共接口"
],
"summary": "websocket连接",
"parameters": [
{
"type": "string",
"description": "token",
"name": "token",
"in": "header",
"required": true
},
{
"type": "string",
"description": "用户ID",
"name": "uid",
"in": "query",
"required": true
},
{
"type": "string",
"description": "房间ID",
"name": "room",
"in": "query",
"required": true
}
],
"responses": {}
}
},
"/swagger/doc.json": {
"get": {
"tags": [
"公共接口"
],
"summary": "swagger文档数据",
"responses": {}
}
},
"/system/admin/ListByDeptId/{deptId}": {
"get": {
"description": "获取部门的用户",
@@ -3850,11 +3941,6 @@
}
}
},
"securityDefinitions": {
"BasicAuth": {
"type": "basic"
}
},
"externalDocs": {
"description": "OpenAPI",
"url": "https://swagger.io/resources/open-api/"

View File

@@ -300,17 +300,21 @@ externalDocs:
url: https://swagger.io/resources/open-api/
info:
contact:
email: 11675084@qq.com
name: API Support
email: x@adtk.cn
name: xh
url: http://x.adtk.cn
description: x_admin是一个完整的后台管理系统
license:
name: MIT License
url: https://gitee.com/xiangheng/x_admin/blob/main/LICENSE
termsOfService: http://x.adtk.cn
title: x_admin文档
version: 0.0.1
paths:
/api/admin/apiList:
get:
responses: {}
summary: 获取所有接口
tags:
- 公共接口
/api/admin/flow/flow_apply/add:
post:
parameters:
@@ -2150,15 +2154,38 @@ paths:
type: string
produces:
- application/json
responses: {}
responses:
"200":
description: 成功
schema:
type: file
"500":
description: 失败
schema:
$ref: '#/definitions/response.Response'
summary: 用户协议导出
tags:
- user_protocol-用户协议
/api/admin/user_protocol/ImportFile:
post:
parameters:
- description: token
in: header
name: token
required: true
type: string
- description: 导入文件
in: formData
name: file
required: true
type: file
produces:
- application/json
responses: {}
responses:
"200":
description: 成功
schema:
$ref: '#/definitions/response.Response'
summary: 用户协议导入
tags:
- user_protocol-用户协议
@@ -2262,7 +2289,7 @@ paths:
allOf:
- $ref: '#/definitions/response.Response'
- properties:
' data':
data:
$ref: '#/definitions/schema.UserProtocolResp'
type: object
summary: 用户协议详情
@@ -2361,11 +2388,11 @@ paths:
allOf:
- $ref: '#/definitions/response.Response'
- properties:
' data':
data:
allOf:
- $ref: '#/definitions/response.PageResp'
- properties:
' lists':
lists:
items:
$ref: '#/definitions/schema.UserProtocolResp'
type: array
@@ -2377,6 +2404,11 @@ paths:
/api/admin/user_protocol/listAll:
get:
parameters:
- description: token
in: header
name: token
required: true
type: string
- description: 标题
in: query
name: Title
@@ -2414,7 +2446,7 @@ paths:
allOf:
- $ref: '#/definitions/response.Response'
- properties:
' data':
data:
items:
$ref: '#/definitions/schema.UserProtocolResp'
type: array
@@ -2422,6 +2454,34 @@ paths:
summary: 用户协议列表-所有
tags:
- user_protocol-用户协议
/api/ws:
get:
parameters:
- description: token
in: header
name: token
required: true
type: string
- description: 用户ID
in: query
name: uid
required: true
type: string
- description: 房间ID
in: query
name: room
required: true
type: string
responses: {}
summary: websocket连接
tags:
- 公共接口
/swagger/doc.json:
get:
responses: {}
summary: swagger文档数据
tags:
- 公共接口
/system/admin/ListByDeptId/{deptId}:
get:
description: 获取部门的用户
@@ -2439,7 +2499,4 @@ paths:
summary: 获取部门的用户
tags:
- 管理员
securityDefinitions:
BasicAuth:
type: basic
swagger: "2.0"

View File

@@ -9,7 +9,6 @@ import (
"x_admin/config"
"x_admin/core"
"x_admin/core/response"
"x_admin/docs"
"x_admin/middleware"
"x_admin/routes"
@@ -71,19 +70,16 @@ func initServer(router *gin.Engine) *http.Server {
}
}
// @title x_admin文档
// @version 0.0.1
// @description x_admin是一个完整的后台管理系统
// @termsOfService http://x.adtk.cn
// @contact.name API Support
// @contact.name xh
// @contact.url http://x.adtk.cn
// @contact.email 11675084@qq.com
// @contact.email x@adtk.cn
// @license.name MIT License
// @license.url https://gitee.com/xiangheng/x_admin/blob/main/LICENSE
// @BasePath /
// @securityDefinitions.basic BasicAuth
// @license.name MIT License
// @license.url https://gitee.com/xiangheng/x_admin/blob/main/LICENSE
// @BasePath /
//
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
@@ -98,11 +94,7 @@ func main() {
// 初始化router
router := initRouter()
// router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
router.GET("/api/swagger/doc.json", func(c *gin.Context) {
docs.SwaggerInfo.Host = fmt.Sprintf("localhost:%v", config.AppConfig.Port)
c.String(200, docs.SwaggerInfo.ReadDoc())
})
fmt.Println("格式化文档注释:", "swag fmt")
fmt.Println("生成文档:", "swag init")
// fmt.Printf("文档: http://localhost:%v/swagger/index.html", config.AppConfig.Port)

View File

@@ -12,29 +12,29 @@
<script src="./api-reference.js"></script>
<script>
var x_admin_token_str = localStorage.getItem("x_admin_token");
if (!x_admin_token_str) {
alert("请先登录");
} else {
var x_admin_token_json = JSON.parse(x_admin_token_str);
Scalar.createApiReference("#app", {
url: "/api/swagger/doc.json",
theme: "Kepler-11e",
withDefaultFonts: false,
hideClientButton: true,
// authentication: {
// securitySchemes: {
// httpBearer: {
// token: "aaa",
// },
// },
// },
onBeforeRequest: ({ request }) => {
// Add a custom header to all requests
request.headers.set("token", x_admin_token_json.value);
},
});
var token = "";
if (x_admin_token_str) {
try {
var x_admin_token_json = JSON.parse(x_admin_token_str);
token = x_admin_token_json.value;
} catch (error) {}
}
Scalar.createApiReference("#app", {
url: "/api/swagger/doc.json",
theme: "kepler",
withDefaultFonts: false,
hideClientButton: true,
onBeforeRequest: ({ request }) => {
// Add a custom header to all requests
// console.log("request", request.headers.get("token"));
if (!request.headers.get("token")) {
if (token) {
request.headers.set("token", token);
}
}
},
});
</script>
</body>
</html>