zhangqian
2023-08-05 e581f6e6b410a6406a86c6743d43b8d450cd3d50
文件管理
6个文件已添加
8个文件已修改
1340 ■■■■■ 已修改文件
api/v1/file.go 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constvar/file.go 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/file.go 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/file.go 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/contextx/contextx.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/httpx/httpx.go 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/file.go 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/index.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/file.go 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/file.go
New file
@@ -0,0 +1,157 @@
package v1
import (
    "aps_crm/model"
    "aps_crm/model/request"
    "aps_crm/model/response"
    "aps_crm/pkg/contextx"
    "aps_crm/pkg/ecode"
    "aps_crm/pkg/httpx"
    "aps_crm/service"
    "github.com/flipped-aurora/gin-vue-admin/server/utils/upload"
    "github.com/gin-gonic/gin"
    "os"
    "path/filepath"
    "strconv"
)
type FileApi struct{}
// Add
// @Tags        附件管理
// @Summary    添加附件
// @Produce    application/json
// @Param        object    body        request.AddFile    true    "查询参数"
// @Success    200        {object}    contextx.Response{}
// @Router        /api/file/add [post]
func (s *FileApi) Add(c *gin.Context) {
    var params request.AddFile
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    _, header, err := c.Request.FormFile("file")
    if err != nil {
        ctx.Fail(ecode.ParamsErr)
        return
    }
    oss := upload.NewOss()
    filePath, key, uploadErr := oss.UploadFile(header)
    if uploadErr != nil {
        ctx.Fail(ecode.ParamsErr)
        return
    }
    _, filename := filepath.Split(filePath)
    fileRecord := &model.File{
        Name:          filename,
        Size:          header.Size,
        FilePath:      filePath,
        Key:           key,
        DownloadCount: 0,
        PreviewCount:  0,
        FileType:      httpx.GetMimeType(filePath),
        SourceType:    params.SourceType,
        SourceId:      params.SourceId,
    }
    errCode := service.NewFileService().AddFile(fileRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Delete
// @Tags        附件管理
// @Summary    删除附件
// @Produce    application/json
// @Param        id    path        int    true    "查询参数"
// @Success    200    {object}    contextx.Response{}
// @Router        /api/file/delete/{id} [delete]
func (s *FileApi) Delete(c *gin.Context) {
    ctx, ok := contextx.NewContext(c, nil)
    if !ok {
        return
    }
    id, _ := strconv.Atoi(c.Param("id"))
    file, err := model.NewFileSearch().SetId(id).First()
    if err != nil {
        ctx.FailWithMsg(ecode.ParamsErr, "查找文件失败")
        return
    }
    err = os.Remove(file.FilePath)
    if err != nil {
        ctx.FailWithMsg(ecode.ParamsErr, "删除文件失败")
        return
    }
    errCode := service.NewFileService().DeleteFile(id)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Update
// @Tags        附件管理
// @Summary    更新附件
// @Produce    application/json
// @Param        object    body        request.UpdateFile    true    "查询参数"
// @Success    200        {object}    contextx.Response{}
// @Router        /api/file/update [put]
func (s *FileApi) Update(c *gin.Context) {
    var params request.UpdateFile
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    if params.Id == 0 {
        ctx.Fail(ecode.ParamsErr)
    }
    params.File.Id = params.Id
    errCode := service.NewFileService().UpdateFile(&params.File)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// List
// @Tags        附件管理
// @Summary    获取附件列表
// @Produce    application/json
// @Param        object    query        request.GetFileList    true    "参数"
// @Success    200    {object}    response.ListResponse{data=[]model.File}
// @Router        /api/file/list [get]
func (s *FileApi) List(c *gin.Context) {
    var params request.GetFileList
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    file, total, errCode := service.NewFileService().GetFileList()
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.OkWithDetailed(response.ListResponse{
        Data:  file,
        Count: total,
    })
}
constvar/file.go
New file
@@ -0,0 +1,12 @@
package constvar
type FileQueryClass string
const (
    FileQueryClassExpireLessThen60Days FileQueryClass = ""
)
type FileKeywordType string
const (
    FileKeywordCustomerName   FileKeywordType = ""
)
docs/docs.go
@@ -2492,6 +2492,169 @@
                }
            }
        },
        "/api/file/add": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "添加附件",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.AddFile"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/file/delete/{id}": {
            "delete": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "删除附件",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "查询参数",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/file/list": {
            "get": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "获取附件列表",
                "parameters": [
                    {
                        "type": "string",
                        "name": "keyword",
                        "in": "query"
                    },
                    {
                        "enum": [
                            ""
                        ],
                        "type": "string",
                        "x-enum-varnames": [
                            "FileKeywordCustomerName"
                        ],
                        "name": "keywordType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "页码",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "每页大小",
                        "name": "pageSize",
                        "in": "query"
                    },
                    {
                        "enum": [
                            ""
                        ],
                        "type": "string",
                        "x-enum-varnames": [
                            "FileQueryClassExpireLessThen60Days"
                        ],
                        "name": "queryClass",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/response.ListResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/definitions/model.File"
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        },
        "/api/file/update": {
            "put": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "更新附件",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.UpdateFile"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/followRecord/add": {
            "post": {
                "produces": [
@@ -8596,6 +8759,24 @@
                "FaqQueryClassExpireLessThen60Days"
            ]
        },
        "constvar.FileKeywordType": {
            "type": "string",
            "enum": [
                ""
            ],
            "x-enum-varnames": [
                "FileKeywordCustomerName"
            ]
        },
        "constvar.FileQueryClass": {
            "type": "string",
            "enum": [
                ""
            ],
            "x-enum-varnames": [
                "FileQueryClassExpireLessThen60Days"
            ]
        },
        "constvar.PaymentTypeKeywordType": {
            "type": "string",
            "enum": [
@@ -9297,6 +9478,64 @@
                    "type": "integer"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "model.File": {
            "type": "object",
            "properties": {
                "bucket": {
                    "description": "对象存储bucket",
                    "type": "string"
                },
                "content": {
                    "description": "文件内容",
                    "type": "string"
                },
                "createTime": {
                    "description": "创建时间",
                    "type": "string"
                },
                "downloadCount": {
                    "description": "下次次数",
                    "type": "integer"
                },
                "filePath": {
                    "description": "文件路径",
                    "type": "string"
                },
                "fileType": {
                    "description": "文件类型",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "key": {
                    "description": "对象存储key",
                    "type": "string"
                },
                "name": {
                    "type": "string"
                },
                "previewCount": {
                    "description": "预览次数",
                    "type": "integer"
                },
                "size": {
                    "description": "文件大小",
                    "type": "integer"
                },
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                }
            }
@@ -11027,6 +11266,23 @@
                    "type": "integer"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "request.AddFile": {
            "type": "object",
            "required": [
                "sourceId",
                "sourceType"
            ],
            "properties": {
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                }
            }
@@ -13402,6 +13658,64 @@
                }
            }
        },
        "request.UpdateFile": {
            "type": "object",
            "properties": {
                "bucket": {
                    "description": "对象存储bucket",
                    "type": "string"
                },
                "content": {
                    "description": "文件内容",
                    "type": "string"
                },
                "createTime": {
                    "description": "创建时间",
                    "type": "string"
                },
                "downloadCount": {
                    "description": "下次次数",
                    "type": "integer"
                },
                "filePath": {
                    "description": "文件路径",
                    "type": "string"
                },
                "fileType": {
                    "description": "文件类型",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "key": {
                    "description": "对象存储key",
                    "type": "string"
                },
                "name": {
                    "type": "string"
                },
                "previewCount": {
                    "description": "预览次数",
                    "type": "integer"
                },
                "size": {
                    "description": "文件大小",
                    "type": "integer"
                },
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                }
            }
        },
        "request.UpdateFollowRecord": {
            "type": "object",
            "required": [
docs/swagger.json
@@ -2480,6 +2480,169 @@
                }
            }
        },
        "/api/file/add": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "添加附件",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.AddFile"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/file/delete/{id}": {
            "delete": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "删除附件",
                "parameters": [
                    {
                        "type": "integer",
                        "description": "查询参数",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/file/list": {
            "get": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "获取附件列表",
                "parameters": [
                    {
                        "type": "string",
                        "name": "keyword",
                        "in": "query"
                    },
                    {
                        "enum": [
                            ""
                        ],
                        "type": "string",
                        "x-enum-varnames": [
                            "FileKeywordCustomerName"
                        ],
                        "name": "keywordType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "页码",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "description": "每页大小",
                        "name": "pageSize",
                        "in": "query"
                    },
                    {
                        "enum": [
                            ""
                        ],
                        "type": "string",
                        "x-enum-varnames": [
                            "FileQueryClassExpireLessThen60Days"
                        ],
                        "name": "queryClass",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/response.ListResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/definitions/model.File"
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        },
        "/api/file/update": {
            "put": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "附件管理"
                ],
                "summary": "更新附件",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.UpdateFile"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/contextx.Response"
                        }
                    }
                }
            }
        },
        "/api/followRecord/add": {
            "post": {
                "produces": [
@@ -8584,6 +8747,24 @@
                "FaqQueryClassExpireLessThen60Days"
            ]
        },
        "constvar.FileKeywordType": {
            "type": "string",
            "enum": [
                ""
            ],
            "x-enum-varnames": [
                "FileKeywordCustomerName"
            ]
        },
        "constvar.FileQueryClass": {
            "type": "string",
            "enum": [
                ""
            ],
            "x-enum-varnames": [
                "FileQueryClassExpireLessThen60Days"
            ]
        },
        "constvar.PaymentTypeKeywordType": {
            "type": "string",
            "enum": [
@@ -9285,6 +9466,64 @@
                    "type": "integer"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "model.File": {
            "type": "object",
            "properties": {
                "bucket": {
                    "description": "对象存储bucket",
                    "type": "string"
                },
                "content": {
                    "description": "文件内容",
                    "type": "string"
                },
                "createTime": {
                    "description": "创建时间",
                    "type": "string"
                },
                "downloadCount": {
                    "description": "下次次数",
                    "type": "integer"
                },
                "filePath": {
                    "description": "文件路径",
                    "type": "string"
                },
                "fileType": {
                    "description": "文件类型",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "key": {
                    "description": "对象存储key",
                    "type": "string"
                },
                "name": {
                    "type": "string"
                },
                "previewCount": {
                    "description": "预览次数",
                    "type": "integer"
                },
                "size": {
                    "description": "文件大小",
                    "type": "integer"
                },
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                }
            }
@@ -11015,6 +11254,23 @@
                    "type": "integer"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "request.AddFile": {
            "type": "object",
            "required": [
                "sourceId",
                "sourceType"
            ],
            "properties": {
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                }
            }
@@ -13390,6 +13646,64 @@
                }
            }
        },
        "request.UpdateFile": {
            "type": "object",
            "properties": {
                "bucket": {
                    "description": "对象存储bucket",
                    "type": "string"
                },
                "content": {
                    "description": "文件内容",
                    "type": "string"
                },
                "createTime": {
                    "description": "创建时间",
                    "type": "string"
                },
                "downloadCount": {
                    "description": "下次次数",
                    "type": "integer"
                },
                "filePath": {
                    "description": "文件路径",
                    "type": "string"
                },
                "fileType": {
                    "description": "文件类型",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "key": {
                    "description": "对象存储key",
                    "type": "string"
                },
                "name": {
                    "type": "string"
                },
                "previewCount": {
                    "description": "预览次数",
                    "type": "integer"
                },
                "size": {
                    "description": "文件大小",
                    "type": "integer"
                },
                "sourceId": {
                    "description": "来源id",
                    "type": "integer"
                },
                "sourceType": {
                    "description": "附件来源",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                }
            }
        },
        "request.UpdateFollowRecord": {
            "type": "object",
            "required": [
docs/swagger.yaml
@@ -23,6 +23,18 @@
    type: string
    x-enum-varnames:
    - FaqQueryClassExpireLessThen60Days
  constvar.FileKeywordType:
    enum:
    - ""
    type: string
    x-enum-varnames:
    - FileKeywordCustomerName
  constvar.FileQueryClass:
    enum:
    - ""
    type: string
    x-enum-varnames:
    - FileQueryClassExpireLessThen60Days
  constvar.PaymentTypeKeywordType:
    enum:
    - ""
@@ -512,6 +524,48 @@
      id:
        type: integer
      name:
        type: string
    type: object
  model.File:
    properties:
      bucket:
        description: 对象存储bucket
        type: string
      content:
        description: 文件内容
        type: string
      createTime:
        description: 创建时间
        type: string
      downloadCount:
        description: 下次次数
        type: integer
      filePath:
        description: 文件路径
        type: string
      fileType:
        description: 文件类型
        type: string
      id:
        type: integer
      key:
        description: 对象存储key
        type: string
      name:
        type: string
      previewCount:
        description: 预览次数
        type: integer
      size:
        description: 文件大小
        type: integer
      sourceId:
        description: 来源id
        type: integer
      sourceType:
        description: 附件来源
        type: string
      updateTime:
        type: string
    type: object
  model.FollowRecord:
@@ -1673,6 +1727,18 @@
        type: integer
      name:
        type: string
    type: object
  request.AddFile:
    properties:
      sourceId:
        description: 来源id
        type: integer
      sourceType:
        description: 附件来源
        type: string
    required:
    - sourceId
    - sourceType
    type: object
  request.AddFollowRecord:
    properties:
@@ -3281,6 +3347,48 @@
      id:
        type: integer
      name:
        type: string
    type: object
  request.UpdateFile:
    properties:
      bucket:
        description: 对象存储bucket
        type: string
      content:
        description: 文件内容
        type: string
      createTime:
        description: 创建时间
        type: string
      downloadCount:
        description: 下次次数
        type: integer
      filePath:
        description: 文件路径
        type: string
      fileType:
        description: 文件类型
        type: string
      id:
        type: integer
      key:
        description: 对象存储key
        type: string
      name:
        type: string
      previewCount:
        description: 预览次数
        type: integer
      size:
        description: 文件大小
        type: integer
      sourceId:
        description: 来源id
        type: integer
      sourceType:
        description: 附件来源
        type: string
      updateTime:
        type: string
    type: object
  request.UpdateFollowRecord:
@@ -6401,6 +6509,107 @@
      summary: 更新故障类别
      tags:
      - 故障类别管理
  /api/file/add:
    post:
      parameters:
      - description: 查询参数
        in: body
        name: object
        required: true
        schema:
          $ref: '#/definitions/request.AddFile'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/contextx.Response'
      summary: 添加附件
      tags:
      - 附件管理
  /api/file/delete/{id}:
    delete:
      parameters:
      - description: 查询参数
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/contextx.Response'
      summary: 删除附件
      tags:
      - 附件管理
  /api/file/list:
    get:
      parameters:
      - in: query
        name: keyword
        type: string
      - enum:
        - ""
        in: query
        name: keywordType
        type: string
        x-enum-varnames:
        - FileKeywordCustomerName
      - description: 页码
        in: query
        name: page
        type: integer
      - description: 每页大小
        in: query
        name: pageSize
        type: integer
      - enum:
        - ""
        in: query
        name: queryClass
        type: string
        x-enum-varnames:
        - FileQueryClassExpireLessThen60Days
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            allOf:
            - $ref: '#/definitions/response.ListResponse'
            - properties:
                data:
                  items:
                    $ref: '#/definitions/model.File'
                  type: array
              type: object
      summary: 获取附件列表
      tags:
      - 附件管理
  /api/file/update:
    put:
      parameters:
      - description: 查询参数
        in: body
        name: object
        required: true
        schema:
          $ref: '#/definitions/request.UpdateFile'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/contextx.Response'
      summary: 更新附件
      tags:
      - 附件管理
  /api/followRecord/add:
    post:
      parameters:
go.mod
@@ -36,6 +36,8 @@
require (
    github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
    github.com/KyleBanks/depth v1.2.1 // indirect
    github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible // indirect
    github.com/aws/aws-sdk-go v1.42.27 // indirect
    github.com/bytedance/sonic v1.9.1 // indirect
    github.com/cespare/xxhash/v2 v2.2.0 // indirect
    github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
@@ -49,6 +51,7 @@
    github.com/gin-contrib/sse v0.1.0 // indirect
    github.com/glebarez/go-sqlite v1.21.1 // indirect
    github.com/glebarez/sqlite v1.8.0 // indirect
    github.com/go-ole/go-ole v1.2.6 // indirect
    github.com/go-openapi/jsonpointer v0.19.6 // indirect
    github.com/go-openapi/jsonreference v0.20.2 // indirect
    github.com/go-openapi/spec v0.20.9 // indirect
@@ -62,17 +65,21 @@
    github.com/golang-sql/sqlexp v0.1.0 // indirect
    github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
    github.com/golang/protobuf v1.5.3 // indirect
    github.com/google/go-querystring v1.0.0 // indirect
    github.com/google/uuid v1.3.0 // indirect
    github.com/hashicorp/hcl v1.0.0 // indirect
    github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible // indirect
    github.com/jackc/pgpassfile v1.0.0 // indirect
    github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
    github.com/jackc/pgx/v5 v5.3.1 // indirect
    github.com/jinzhu/inflection v1.0.0 // indirect
    github.com/jinzhu/now v1.1.5 // indirect
    github.com/jmespath/go-jmespath v0.4.0 // indirect
    github.com/josharian/intern v1.0.0 // indirect
    github.com/json-iterator/go v1.1.12 // indirect
    github.com/klauspost/cpuid/v2 v2.2.4 // indirect
    github.com/leodido/go-urn v1.2.4 // indirect
    github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
    github.com/magiconair/properties v1.8.7 // indirect
    github.com/mailru/easyjson v0.7.7 // indirect
    github.com/mattn/go-isatty v0.0.19 // indirect
@@ -80,18 +87,26 @@
    github.com/mitchellh/mapstructure v1.5.0 // indirect
    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
    github.com/modern-go/reflect2 v1.0.2 // indirect
    github.com/mozillazg/go-httpheader v0.2.1 // indirect
    github.com/onsi/gomega v1.27.4 // indirect
    github.com/pelletier/go-toml/v2 v2.0.8 // indirect
    github.com/pmezard/go-difflib v1.0.0 // indirect
    github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
    github.com/qiniu/api.v7/v7 v7.4.1 // indirect
    github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
    github.com/rogpeppe/go-internal v1.10.0 // indirect
    github.com/shirou/gopsutil/v3 v3.22.5 // indirect
    github.com/spf13/afero v1.9.5 // indirect
    github.com/spf13/cast v1.5.1 // indirect
    github.com/spf13/jwalterweatherman v1.1.0 // indirect
    github.com/spf13/pflag v1.0.5 // indirect
    github.com/subosito/gotenv v1.4.2 // indirect
    github.com/tencentyun/cos-go-sdk-v5 v0.7.19 // indirect
    github.com/tklauser/go-sysconf v0.3.10 // indirect
    github.com/tklauser/numcpus v0.4.0 // indirect
    github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
    github.com/ugorji/go/codec v1.2.11 // indirect
    github.com/yusufpapurcu/wmi v1.2.2 // indirect
    go.etcd.io/etcd/api/v3 v3.5.9 // indirect
    go.uber.org/atomic v1.9.0 // indirect
    go.uber.org/multierr v1.8.0 // indirect
@@ -100,6 +115,7 @@
    golang.org/x/net v0.10.0 // indirect
    golang.org/x/sys v0.9.0 // indirect
    golang.org/x/text v0.10.0 // indirect
    golang.org/x/time v0.1.0 // indirect
    golang.org/x/tools v0.9.1 // indirect
    google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
    google.golang.org/grpc v1.55.0 // indirect
go.sum
@@ -50,6 +50,12 @@
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4=
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/aws/aws-sdk-go v1.42.27 h1:kxsBXQg3ee6LLbqjp5/oUeDgG7TENFrWYDmEVnd7spU=
github.com/aws/aws-sdk-go v1.42.27/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
@@ -125,6 +131,8 @@
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
@@ -219,7 +227,11 @@
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -236,6 +248,7 @@
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -252,6 +265,8 @@
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible h1:3kDd8PIWAdU+qGs/+0QUgsMI2ZSiJPt45Xn0su+x/Q0=
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
@@ -309,6 +324,10 @@
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -342,6 +361,8 @@
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -371,6 +392,8 @@
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
@@ -388,7 +411,11 @@
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/qiniu/api.v7/v7 v7.4.1 h1:BnNUBimLk6nrA/mIwsww9yJRupmViSsb1ndLMC7a9OY=
github.com/qiniu/api.v7/v7 v7.4.1/go.mod h1:VE5oC5rkE1xul0u1S2N0b2Uxq9/6hZzhyqjgK25XDcM=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
@@ -402,7 +429,10 @@
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shirou/gopsutil/v3 v3.22.5 h1:atX36I/IXgFiB81687vSiBI5zrMsxcIBkP9cQMJQoJA=
github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
@@ -445,6 +475,12 @@
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
github.com/tencentyun/cos-go-sdk-v5 v0.7.19 h1:janAfTO4MglOrUFuKGTQJBuMc66+F7TgtEIt1wPsJ+k=
github.com/tencentyun/cos-go-sdk-v5 v0.7.19/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA=
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
@@ -457,6 +493,8 @@
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs=
go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
@@ -591,6 +629,7 @@
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
@@ -635,6 +674,7 @@
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -658,6 +698,7 @@
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -671,6 +712,7 @@
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -704,6 +746,8 @@
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
model/file.go
New file
@@ -0,0 +1,152 @@
package model
import (
    "aps_crm/constvar"
    "aps_crm/pkg/mysqlx"
    "errors"
    "fmt"
    "gorm.io/gorm"
)
type (
    // File 附件
    File struct {
        Id            int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        Name          string `gorm:"name" json:"name"`
        Size          int64  `gorm:"size" json:"size"`                    // 文件大小
        FilePath      string `gorm:"file_path" json:"filePath"`           // 文件路径
        Key           string `gorm:"key" json:"key"`                      // 对象存储key
        Bucket        string `gorm:"bucket" json:"bucket"`                // 对象存储bucket
        DownloadCount int    `gorm:"download_count" json:"downloadCount"` // 下次次数
        PreviewCount  int    `gorm:"preview_count" json:"previewCount"`   // 预览次数
        FileType      string `gorm:"file_type" json:"fileType"`           // 文件类型
        SourceType    string `gorm:"source_type" json:"sourceType"`       // 附件来源
        SourceId      int    `gorm:"source_id" json:"sourceId"`           // 来源id
        CreateTime    string `gorm:"create_time" json:"createTime"`       // 创建时间
        UpdateTime    string `gorm:"update_time" json:"updateTime"`
        Content       string `gorm:"content" json:"content"` // 文件内容
    }
    // FileSearch 附件搜索条件
    FileSearch struct {
        File
        Orm         *gorm.DB
        QueryClass  constvar.FileQueryClass
        KeywordType constvar.FileKeywordType
        Keyword     string
        PageNum     int
        PageSize    int
    }
)
func (File) TableName() string {
    return "file"
}
func NewFileSearch() *FileSearch {
    return &FileSearch{
        Orm: mysqlx.GetDB(),
    }
}
func (slf *FileSearch) build() *gorm.DB {
    var db = slf.Orm.Model(&File{})
    if slf.Id != 0 {
        db = db.Where("id = ?", slf.Id)
    }
    return db
}
func (slf *FileSearch) Create(record *File) error {
    var db = slf.build()
    return db.Create(record).Error
}
func (slf *FileSearch) CreateBatch(records []*File) error {
    var db = slf.build()
    return db.Create(records).Error
}
func (slf *FileSearch) Delete() error {
    var db = slf.build()
    return db.Delete(&File{}).Error
}
func (slf *FileSearch) Update(record *File) error {
    var db = slf.build()
    return db.Updates(record).Error
}
func (slf *FileSearch) FindAll() ([]*File, error) {
    var db = slf.build()
    var record = make([]*File, 0)
    err := db.Find(&record).Error
    return record, err
}
func (slf *FileSearch) SetId(id int) *FileSearch {
    slf.Id = id
    return slf
}
func (slf *FileSearch) SetOrm(tx *gorm.DB) *FileSearch {
    slf.Orm = tx
    return slf
}
func (slf *FileSearch) First() (*File, error) {
    var db = slf.build()
    var record = new(File)
    err := db.First(record).Error
    return record, err
}
func (slf *FileSearch) Updates(values interface{}) error {
    var db = slf.build()
    return db.Updates(values).Error
}
func (slf *FileSearch) Save(record *File) error {
    if record.Id == 0 {
        return errors.New("id为空")
    }
    var db = slf.build()
    if err := db.Save(record).Error; err != nil {
        return fmt.Errorf("save err: %v, record: %+v", err, record)
    }
    return nil
}
func (slf *FileSearch) Find() ([]*File, int64, error) {
    var db = slf.build()
    var records = make([]*File, 0)
    var total int64
    if err := db.Count(&total).Error; err != nil {
        return records, total, err
    }
    if slf.PageNum > 0 && slf.PageSize > 0 {
        db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
    }
    err := db.Find(&records).Error
    return records, total, err
}
// InitDefaultData 初始化数据
func (slf *FileSearch) InitDefaultData() error {
    var (
        db          = slf.Orm.Table(slf.TableName())
        total int64 = 0
    )
    if err := db.Count(&total).Error; err != nil {
        return err
    }
    if total != 0 {
        return nil
    }
    records := []*File{}
    return slf.CreateBatch(records)
}
model/request/file.go
New file
@@ -0,0 +1,23 @@
package request
import (
    "aps_crm/constvar"
    "aps_crm/model"
)
type AddFile struct {
    SourceType string `gorm:"source_type" json:"sourceType" form:"sourceType" binding:"required"` // 附件来源
    SourceId   int    `gorm:"source_id" json:"sourceId" form:"sourceId"  binding:"required"`      // 来源id
}
type UpdateFile struct {
    Id int `json:"id"`
    model.File
}
type GetFileList struct {
    PageInfo
    QueryClass  constvar.FileQueryClass  `json:"queryClass" form:"queryClass"`
    KeywordType constvar.FileKeywordType `json:"keywordType"  form:"keywordType"`
    Keyword     string                   `json:"keyword" form:"keyword"`
}
pkg/contextx/contextx.go
@@ -83,6 +83,10 @@
    slf.Result(errCode, map[string]interface{}{}, ecode.GetMsg(errCode))
}
func (slf *Context) FailWithMsg(errCode int, msg string) {
    slf.Result(errCode, map[string]interface{}{}, msg)
}
func (slf *Context) FailWithDetailed(errCode int, data interface{}) {
    slf.Result(errCode, data, ecode.GetMsg(errCode))
}
pkg/httpx/httpx.go
@@ -5,6 +5,7 @@
    "encoding/json"
    "io/ioutil"
    "net/http"
    "os"
    "time"
)
@@ -39,3 +40,16 @@
    }
    return respBytes, nil
}
func GetMimeType(filePath string) string {
    file, err := os.Open(filePath)
    if err != nil {
        return ""
    }
    buffer := make([]byte, 512)
    _, _ = file.Read(buffer)
    if len(buffer) == 0 {
        return ""
    }
    return http.DetectContentType(buffer)
}
router/file.go
New file
@@ -0,0 +1,15 @@
package router
import (
    v1 "aps_crm/api/v1"
    "github.com/gin-gonic/gin"
)
func InitFileRouter(router *gin.RouterGroup) {
    FileRouter := router.Group("file")
    FileApi := v1.FileApi{}
    {
        FileRouter.POST("add", FileApi.Add)             // 添加附件
        FileRouter.DELETE("delete/:id", FileApi.Delete) // 删除附件
    }
}
router/index.go
@@ -170,6 +170,7 @@
        InitReceiptRouter(PrivateGroup)
        InitBankAccountRouter(PrivateGroup)
        InitPaymentTypeRouter(PrivateGroup)
        InitFileRouter(PrivateGroup)
    }
    return Router
}
service/file.go
New file
@@ -0,0 +1,65 @@
package service
import (
    "aps_crm/model"
    "aps_crm/model/request"
    "aps_crm/pkg/ecode"
)
type FileService struct{}
func NewFileService() FileService {
    return FileService{}
}
func (FileService) AddFile(fileRecord *model.File) int {
    err := model.NewFileSearch().Create(fileRecord)
    if err != nil {
        return ecode.DBErr
    }
    return ecode.OK
}
func (FileService) DeleteFile(id int) int {
    err := model.NewFileSearch().SetId(id).Delete()
    if err != nil {
        return ecode.DBErr
    }
    return ecode.OK
}
func (FileService) GetFileList() ([]*model.File, int64, int) {
    list, total, err := model.NewFileSearch().Find()
    if err != nil {
        return nil, 0, ecode.DBErr
    }
    return list, total, ecode.OK
}
func (FileService) UpdateFiles(Files []*request.UpdateFile) int {
    for _, v := range Files {
        // check File exist
        _, err := model.NewFileSearch().SetId(v.Id).First()
        if err != nil {
            return ecode.DBErr
        }
        err = model.NewFileSearch().SetId(v.Id).Updates(map[string]interface{}{})
        if err != nil {
            return ecode.DBErr
        }
    }
    return ecode.OK
}
func (FileService) UpdateFile(file *model.File) int {
    err := model.NewFileSearch().SetId(file.Id).Save(file)
    if err != nil {
        return ecode.DBErr
    }
    return ecode.OK
}