chore: 并入 iotlcm-admin-svr 历史到 admin-svr/(原提交 49818c6)

This commit is contained in:
MiFaZhan
2026-11-02 13:27:59 +08:00
1250 changed files with 154111 additions and 0 deletions
@@ -0,0 +1,152 @@
package iot
import (
"bytes"
"context"
"io"
"time"
v1 "git.5iot.com/iotlcm-public/iotlcm-admin-svr/api/iot/v1"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/exportcenter"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/simcardquery"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/iot_excelize"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
// simCardQueryService 两个查询功能共用同一份实现,避免重复注册。
var simCardQueryService = simcardquery.New()
// SimCardBaseQueryTemplate 下载卡基础信息查询模板
func (c *ControllerV1) SimCardBaseQueryTemplate(ctx context.Context, req *v1.SimCardBaseQueryTemplateReq) (res *v1.SimCardBaseQueryTemplateRes, err error) {
file, name, err := simCardQueryService.BaseTemplate(ctx)
if err != nil {
return nil, err
}
defer file.Close()
return &v1.SimCardBaseQueryTemplateRes{}, iot_excelize.WriteHTTP(ctx, file, name)
}
// SimCardBaseQueryColumns 卡基础信息查询可选导出列
func (c *ControllerV1) SimCardBaseQueryColumns(ctx context.Context, req *v1.SimCardBaseQueryColumnsReq) (res *v1.SimCardBaseQueryColumnsRes, err error) {
return &v1.SimCardBaseQueryColumnsRes{Items: simCardQueryService.BaseColumnOptions()}, nil
}
// SimCardBaseQueryExport 提交卡基础信息查询导出
func (c *ControllerV1) SimCardBaseQueryExport(ctx context.Context, req *v1.SimCardBaseQueryExportReq) (res *v1.SimCardBaseQueryExportRes, err error) {
input, err := excelInput(ctx, req.Mode)
if err != nil {
return nil, err
}
submit, err := simCardQueryService.ExportBase(ctx, &req.SimCardQueryExportParam, input)
if err != nil {
return nil, err
}
return &v1.SimCardBaseQueryExportRes{SimCardQuerySubmitRes: toSubmitRes(submit)}, nil
}
// SimCardUsageHistoryTemplate 下载月历史用量查询模板
func (c *ControllerV1) SimCardUsageHistoryTemplate(ctx context.Context, req *v1.SimCardUsageHistoryTemplateReq) (res *v1.SimCardUsageHistoryTemplateRes, err error) {
file, name, err := simCardQueryService.UsageHistoryTemplate(ctx)
if err != nil {
return nil, err
}
defer file.Close()
return &v1.SimCardUsageHistoryTemplateRes{}, iot_excelize.WriteHTTP(ctx, file, name)
}
// SimCardUsageHistoryColumns 月历史用量查询固定列与近12个月月份清单
func (c *ControllerV1) SimCardUsageHistoryColumns(ctx context.Context, req *v1.SimCardUsageHistoryColumnsReq) (res *v1.SimCardUsageHistoryColumnsRes, err error) {
return &v1.SimCardUsageHistoryColumnsRes{
Items: simCardQueryService.UsageHistoryColumnOptions(),
Months: simCardQueryService.UsageHistoryMonths(time.Now()),
}, nil
}
// SimCardUsageHistoryDeptOptions 月历史用量查询可选公司
func (c *ControllerV1) SimCardUsageHistoryDeptOptions(ctx context.Context, req *v1.SimCardUsageHistoryDeptOptionsReq) (res *v1.SimCardUsageHistoryDeptOptionsRes, err error) {
items, err := simCardQueryService.DeptOptions(ctx)
if err != nil {
return nil, err
}
return &v1.SimCardUsageHistoryDeptOptionsRes{
Items: items,
CurrentDeptId: contexts.GetDeptId(ctx),
}, nil
}
// SimCardUsageHistoryExport 提交月历史用量查询导出
func (c *ControllerV1) SimCardUsageHistoryExport(ctx context.Context, req *v1.SimCardUsageHistoryExportReq) (res *v1.SimCardUsageHistoryExportRes, err error) {
input, err := excelInput(ctx, req.Mode)
if err != nil {
return nil, err
}
submit, err := simCardQueryService.ExportUsageHistory(ctx, &req.SimCardUsageHistoryExportParam, input)
if err != nil {
return nil, err
}
return &v1.SimCardUsageHistoryExportRes{SimCardQuerySubmitRes: toSubmitRes(submit)}, nil
}
// excelInput 只在 Excel 模式下读取上传文件。
// 一次性读进内存再交给后台解析:提交接口必须立即返回,
// 而 HTTP 请求结束后临时上传文件可能被清理,不能在后台协程里再读。
func excelInput(ctx context.Context, mode string) (simcardquery.ExcelInput, error) {
if mode != model.SimCardQueryModeExcel {
return nil, nil
}
request := g.RequestFromCtx(ctx)
if request == nil {
return nil, gerror.New("当前上下文不是HTTP请求")
}
file := request.GetUploadFile("file")
if file == nil {
return nil, gerror.New("请先上传 Excel 文件")
}
content, err := readUploadContent(file)
if err != nil {
return nil, err
}
if len(content) == 0 {
return nil, gerror.New("上传的 Excel 文件为空")
}
return func() (io.Reader, error) {
return bytes.NewReader(content), nil
}, nil
}
func toSubmitRes(submit *exportcenter.SubmitResult) *model.SimCardQuerySubmitRes {
if submit == nil {
return nil
}
return &model.SimCardQuerySubmitRes{
TaskId: submit.TaskId,
TaskNo: submit.TaskNo,
Total: submit.Total,
}
}
// maxUploadBytes Excel 上传大小上限(MB 换算后的字节数)。
// 20MB 足够容纳 20000 行三列号码,再大基本是用户传错文件。
const maxUploadBytes = 20 << 20
// readUploadContent 一次性读出上传文件内容。
func readUploadContent(file *ghttp.UploadFile) ([]byte, error) {
reader, err := file.Open()
if err != nil {
return nil, gerror.Wrap(err, "读取上传文件失败")
}
defer reader.Close()
if file.Size > maxUploadBytes {
return nil, gerror.Newf("上传文件超过 %dMB 上限", maxUploadBytes>>20)
}
content, err := io.ReadAll(reader)
if err != nil {
return nil, gerror.Wrap(err, "读取上传文件失败")
}
return content, nil
}