153 lines
5.5 KiB
Go
153 lines
5.5 KiB
Go
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
|
|
}
|