Files
junhong_cmp_fiber/internal/routes/iot_card.go
huang 1350a9ed79
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m53s
批量
2026-05-11 14:54:23 +08:00

122 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/gateway"
"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 registerIotCardRoutes(router fiber.Router, handler *admin.IotCardHandler, importHandler *admin.IotCardImportHandler, doc *openapi.Generator, basePath string) {
iotCards := router.Group("/iot-cards")
groupPath := basePath + "/iot-cards"
Register(iotCards, doc, groupPath, "GET", "/standalone", handler.ListStandalone, RouteSpec{
Summary: "单卡列表(未绑定设备)",
Tags: []string{"IoT卡管理"},
Input: new(dto.ListStandaloneIotCardRequest),
Output: new(dto.ListStandaloneIotCardResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "POST", "/import", importHandler.Import, RouteSpec{
Summary: "批量导入IoT卡ICCID+MSISDN",
Description: `仅平台用户可操作。
## ⚠️ 接口变更说明BREAKING CHANGE
本接口已从 ` + "`multipart/form-data`" + ` 改为 ` + "`application/json`" + `
文件格式从 CSV 升级为 Excel (.xlsx),解决长数字被转为科学记数法的问题。
### 完整导入流程
1. **获取上传 URL**: 调用 ` + "`POST /api/admin/storage/upload-url`" + `
2. **上传 Excel 文件**: 使用预签名 URL 上传文件到对象存储
3. **调用本接口**: 使用返回的 ` + "`file_key`" + ` 提交导入任务
### 请求示例
` + "```" + `json
{
"carrier_id": 1,
"batch_no": "BATCH-2025-01",
"file_key": "imports/2025/01/24/abc123.xlsx"
}
` + "```" + `
### Excel 文件格式
- 文件格式:仅支持 .xlsx (Excel 2007+)
- 必填列(表头关键字):
- ` + "`ICCID`" + `(或:卡号 / 号码)
- ` + "`MSISDN`" + `(或:接入号 / 手机号 / 电话)
- ` + "`virtual_no`" + `VirtualNo / 虚拟号 / 设备号)—— **必填,缺少此列将导致整批导入失败**
- 首行为表头(可选,但建议包含)
- 列格式:设置为文本格式(避免长数字被转为科学记数法)
#### virtual_no 导入规则
- ` + "`virtual_no`" + ` 为必填字段,**不可为空**;为空的行记为失败并报告原因
- Excel 缺少 ` + "`virtual_no`" + ` 列时,整批导入直接失败(返回"Excel 文件缺少 virtual_no 列,请使用最新模板"
- ` + "`virtual_no`" + ` 与系统已有值重复时,该行记为失败`,
Tags: []string{"IoT卡管理"},
Input: new(dto.ImportIotCardRequest),
Output: new(dto.ImportIotCardResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "GET", "/import-tasks", importHandler.List, RouteSpec{
Summary: "导入任务列表",
Description: "仅平台用户可操作。",
Tags: []string{"IoT卡管理"},
Input: new(dto.ListImportTaskRequest),
Output: new(dto.ListImportTaskResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "GET", "/import-tasks/:id", importHandler.GetByID, RouteSpec{
Summary: "导入任务详情",
Description: "仅平台用户可操作。",
Tags: []string{"IoT卡管理"},
Input: new(dto.GetImportTaskRequest),
Output: new(dto.ImportTaskDetailResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "POST", "/standalone/allocate", handler.AllocateCards, RouteSpec{
Summary: "批量分配单卡",
Tags: []string{"IoT卡管理"},
Input: new(dto.AllocateStandaloneCardsRequest),
Output: new(dto.AllocateStandaloneCardsResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "POST", "/standalone/recall", handler.RecallCards, RouteSpec{
Summary: "批量回收单卡",
Tags: []string{"IoT卡管理"},
Input: new(dto.RecallStandaloneCardsRequest),
Output: new(dto.RecallStandaloneCardsResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "PATCH", "/series-binding", handler.BatchSetSeriesBinding, RouteSpec{
Summary: "批量设置卡的套餐系列绑定",
Description: "批量设置或清除卡与套餐系列分配的关联关系。series_id 为目标套餐系列ID0表示清除关联。支持 selection_type=list/range/filterlist 传 iccids兼容旧请求不传 selection_type 时默认按 iccids 处理range 传 iccid_start/iccid_endfilter 按筛选条件选择完整结果,不受列表分页限制。",
Tags: []string{"IoT卡管理"},
Input: new(dto.BatchSetCardSeriesBindngRequest),
Output: new(dto.BatchSetCardSeriesBindngResponse),
Auth: true,
})
Register(iotCards, doc, groupPath, "GET", "/:iccid/realname-link", handler.GetRealnameLink, RouteSpec{
Summary: "获取实名认证链接",
Tags: []string{"IoT卡管理"},
Input: new(dto.GetIotCardByICCIDRequest),
Output: new(gateway.RealnameLinkResp),
Auth: true,
})
}