feat: 添加环境变量管理工具和部署配置改版
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m33s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m33s
主要改动: - 新增交互式环境配置脚本 (scripts/setup-env.sh) - 新增本地启动快捷脚本 (scripts/run-local.sh) - 新增环境变量模板文件 (.env.example) - 部署模式改版:使用嵌入式配置 + 环境变量覆盖 - 添加对象存储功能支持 - 改进 IoT 卡片导入任务 - 优化 OpenAPI 文档生成 - 删除旧的配置文件,改用嵌入式默认配置
This commit is contained in:
@@ -58,6 +58,9 @@ func RegisterAdminRoutes(router fiber.Router, handlers *bootstrap.Handlers, midd
|
||||
if handlers.AssetAllocationRecord != nil {
|
||||
registerAssetAllocationRecordRoutes(authGroup, handlers.AssetAllocationRecord, doc, basePath)
|
||||
}
|
||||
if handlers.Storage != nil {
|
||||
registerStorageRoutes(authGroup, handlers.Storage, doc, basePath)
|
||||
}
|
||||
}
|
||||
|
||||
func registerAdminAuthRoutes(router fiber.Router, handler interface{}, authMiddleware fiber.Handler, doc *openapi.Generator, basePath string) {
|
||||
|
||||
@@ -21,11 +21,36 @@ func registerIotCardRoutes(router fiber.Router, handler *admin.IotCardHandler, i
|
||||
})
|
||||
|
||||
Register(iotCards, doc, groupPath, "POST", "/import", importHandler.Import, RouteSpec{
|
||||
Summary: "批量导入ICCID",
|
||||
Tags: []string{"IoT卡管理"},
|
||||
Input: new(dto.ImportIotCardRequest),
|
||||
Output: new(dto.ImportIotCardResponse),
|
||||
Auth: true,
|
||||
Summary: "批量导入IoT卡(ICCID+MSISDN)",
|
||||
Description: `## ⚠️ 接口变更说明(BREAKING CHANGE)
|
||||
|
||||
本接口已从 ` + "`multipart/form-data`" + ` 改为 ` + "`application/json`" + `。
|
||||
|
||||
### 完整导入流程
|
||||
|
||||
1. **获取上传 URL**: 调用 ` + "`POST /api/admin/storage/upload-url`" + `
|
||||
2. **上传 CSV 文件**: 使用预签名 URL 上传文件到对象存储
|
||||
3. **调用本接口**: 使用返回的 ` + "`file_key`" + ` 提交导入任务
|
||||
|
||||
### 请求示例
|
||||
|
||||
` + "```" + `json
|
||||
{
|
||||
"carrier_id": 1,
|
||||
"batch_no": "BATCH-2025-01",
|
||||
"file_key": "imports/2025/01/24/abc123.csv"
|
||||
}
|
||||
` + "```" + `
|
||||
|
||||
### CSV 文件格式
|
||||
|
||||
- 必须包含两列:` + "`iccid`" + `, ` + "`msisdn`" + `
|
||||
- 首行为表头
|
||||
- 编码:UTF-8`,
|
||||
Tags: []string{"IoT卡管理"},
|
||||
Input: new(dto.ImportIotCardRequest),
|
||||
Output: new(dto.ImportIotCardResponse),
|
||||
Auth: true,
|
||||
})
|
||||
|
||||
Register(iotCards, doc, groupPath, "GET", "/import-tasks", importHandler.List, RouteSpec{
|
||||
|
||||
@@ -8,13 +8,22 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
)
|
||||
|
||||
// FileUploadField 定义文件上传字段
|
||||
type FileUploadField struct {
|
||||
Name string // 字段名
|
||||
Description string // 字段描述
|
||||
Required bool // 是否必填
|
||||
}
|
||||
|
||||
// RouteSpec 定义接口文档元数据
|
||||
type RouteSpec struct {
|
||||
Summary string
|
||||
Input interface{} // 请求参数结构体 (Query/Path/Body)
|
||||
Output interface{} // 响应参数结构体
|
||||
Tags []string
|
||||
Auth bool // 是否需要认证图标 (预留)
|
||||
Summary string // 简短摘要(中文,一行)
|
||||
Description string // 详细说明,支持 Markdown 语法(可选)
|
||||
Input interface{} // 请求参数结构体 (Query/Path/Body)
|
||||
Output interface{} // 响应参数结构体
|
||||
Tags []string // 分类标签
|
||||
Auth bool // 是否需要认证图标 (预留)
|
||||
FileUploads []FileUploadField // 文件上传字段列表(设置此字段时请求类型为 multipart/form-data)
|
||||
}
|
||||
|
||||
// pathParamRegex 用于匹配 Fiber 的路径参数格式 /:param
|
||||
@@ -33,6 +42,19 @@ func Register(router fiber.Router, doc *openapi.Generator, basePath, method, pat
|
||||
if doc != nil {
|
||||
fullPath := basePath + path
|
||||
openapiPath := pathParamRegex.ReplaceAllString(fullPath, "/{$1}")
|
||||
doc.AddOperation(method, openapiPath, spec.Summary, spec.Input, spec.Output, spec.Auth, spec.Tags...)
|
||||
|
||||
if len(spec.FileUploads) > 0 {
|
||||
fileFields := make([]openapi.FileUploadField, len(spec.FileUploads))
|
||||
for i, f := range spec.FileUploads {
|
||||
fileFields[i] = openapi.FileUploadField{
|
||||
Name: f.Name,
|
||||
Description: f.Description,
|
||||
Required: f.Required,
|
||||
}
|
||||
}
|
||||
doc.AddMultipartOperation(method, openapiPath, spec.Summary, spec.Description, spec.Input, spec.Output, spec.Auth, fileFields, spec.Tags...)
|
||||
} else {
|
||||
doc.AddOperation(method, openapiPath, spec.Summary, spec.Description, spec.Input, spec.Output, spec.Auth, spec.Tags...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
71
internal/routes/storage.go
Normal file
71
internal/routes/storage.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
)
|
||||
|
||||
func registerStorageRoutes(router fiber.Router, handler *admin.StorageHandler, doc *openapi.Generator, basePath string) {
|
||||
storage := router.Group("/storage")
|
||||
groupPath := basePath + "/storage"
|
||||
|
||||
Register(storage, doc, groupPath, "POST", "/upload-url", handler.GetUploadURL, RouteSpec{
|
||||
Summary: "获取文件上传预签名 URL",
|
||||
Description: `## 文件上传流程
|
||||
|
||||
本接口用于获取对象存储的预签名上传 URL,实现前端直传文件到对象存储。
|
||||
|
||||
### 完整流程
|
||||
|
||||
1. **调用本接口** 获取预签名 URL 和 file_key
|
||||
2. **使用预签名 URL 上传文件** 发起 PUT 请求直接上传到对象存储
|
||||
3. **调用业务接口** 使用 file_key 调用相关业务接口(如 ICCID 导入)
|
||||
|
||||
### 前端上传示例
|
||||
|
||||
` + "```" + `javascript
|
||||
// 1. 获取预签名 URL
|
||||
const { data } = await api.post('/storage/upload-url', {
|
||||
file_name: 'cards.csv',
|
||||
content_type: 'text/csv',
|
||||
purpose: 'iot_import'
|
||||
});
|
||||
|
||||
// 2. 上传文件到对象存储
|
||||
await fetch(data.upload_url, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'text/csv' },
|
||||
body: file
|
||||
});
|
||||
|
||||
// 3. 调用业务接口
|
||||
await api.post('/iot-cards/import', {
|
||||
carrier_id: 1,
|
||||
batch_no: 'BATCH-2025-01',
|
||||
file_key: data.file_key
|
||||
});
|
||||
` + "```" + `
|
||||
|
||||
### purpose 可选值
|
||||
|
||||
| 值 | 说明 | 生成路径格式 |
|
||||
|---|------|-------------|
|
||||
| iot_import | ICCID 导入 | imports/YYYY/MM/DD/uuid.csv |
|
||||
| export | 数据导出 | exports/YYYY/MM/DD/uuid.xlsx |
|
||||
| attachment | 附件上传 | attachments/YYYY/MM/DD/uuid.ext |
|
||||
|
||||
### 注意事项
|
||||
|
||||
- 预签名 URL 有效期 **15 分钟**,请及时使用
|
||||
- 上传时 Content-Type 需与请求时一致
|
||||
- file_key 在上传成功后永久有效,用于后续业务接口调用
|
||||
- 上传失败时可重新调用本接口获取新的 URL`,
|
||||
Tags: []string{"对象存储"},
|
||||
Input: new(dto.GetUploadURLRequest),
|
||||
Output: new(dto.GetUploadURLResponse),
|
||||
Auth: true,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user