Files
junhong_cmp_fiber/internal/model/dto/export_task_dto.go
break d5bcda94fe feat(套餐真流量预警): AUG26-004 真流量预警规则、达量扫描通知与导出
新增 000228 迁移:规则表 tb_package_traffic_alert_rule(每套餐商品至多一条,无软删除,package_id
非部分唯一约束)、达量预警快照表 tb_package_traffic_alert(以主套餐使用记录 + 阈值快照为唯一键,
触发时冻结用量、额度、比例、阈值、到期时间、归属与资产快照),并为 tb_package_usage 新增扫描
范围部分索引 idx_package_usage_alert_scope;down 在预警表存在数据时阻断回滚。

新增规则维护接口 GET/POST/PUT /api/admin/package-traffic-alert-rules(仅超级管理员与平台账号):
创建校验套餐存在且真流量额度大于零,阈值为 1%~100% 的两位小数;修改只影响后续扫描,不回填也
不改写既有预警快照;全部写操作记录操作者、前后值与时间。

新增每日 06:00(Asia/Shanghai)扫描任务 package:traffic:alert:scan,与套餐临期扫描共用 data_cleanup
队列:按资产汇总当前有效套餐的真流量,分子取使用记录真已用量、分母取使用记录真总量快照,命中
主套餐规则阈值时在同一事务创建预警与可靠通知事件;重复执行以唯一冲突视为已处理,不重复投递,
不建停机锁、不调用运营商。

新增预警列表、详情与异步导出 GET /api/admin/package-traffic-alerts、GET /api/admin/package-traffic-alerts/:id、
POST /api/admin/package-traffic-alerts/export,列表与详情一律读冻结快照;新增通知类型
package.traffic.alert 与受控目标 package_traffic_alert_detail,目标解析仅对超级管理员与平台账号
返回可跳转,越权与不存在统一按资源不可见处理。

同步 OpenAPI(cmd/gendocs、cmd/api/docs.go、pkg/openapi/handlers.go)、审计动作与资源注册、上下文
健康检查证据;归档变更并同步 package-traffic-alert 主 Spec。
2026-09-16 17:05:55 +08:00

97 lines
6.9 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 dto
import "time"
// CreateExportTaskRequest 创建导出任务请求。
type CreateExportTaskRequest struct {
Scene string `json:"scene" validate:"required,oneof=device iot_card order package agent_wallet_transaction agent_recharge refund exchange commission_record package_traffic_alert" required:"true" description:"导出场景 (device:设备, iot_card:IoT卡, order:订单, package:套餐, agent_wallet_transaction:代理主钱包流水, agent_recharge:代理充值, refund:退款, exchange:换货, commission_record:佣金明细, package_traffic_alert:套餐真流量达量预警)"`
Format string `json:"format" validate:"required,oneof=xlsx csv" required:"true" description:"导出格式 (xlsx:Excel, csv:CSV)"`
Query map[string]interface{} `json:"query,omitempty" description:"导出筛选参数(JSON对象可选)"`
}
// CreateExportTaskResponse 创建导出任务响应。
type CreateExportTaskResponse struct {
TaskID uint `json:"task_id" description:"导出任务ID"`
TaskNo string `json:"task_no" description:"任务编号"`
Status int `json:"status" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:已失败, 5:已取消)"`
StatusName string `json:"status_name" description:"任务状态名称(中文)"`
Message string `json:"message" description:"提示信息"`
}
// ListExportTaskRequest 导出任务列表请求。
type ListExportTaskRequest struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
Scene string `json:"scene" query:"scene" validate:"omitempty,oneof=device iot_card order package agent_wallet_transaction agent_recharge refund exchange commission_record package_traffic_alert" description:"导出场景 (device:设备, iot_card:IoT卡, order:订单, package:套餐, agent_wallet_transaction:代理主钱包流水, agent_recharge:代理充值, refund:退款, exchange:换货, commission_record:佣金明细, package_traffic_alert:套餐真流量达量预警)"`
Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=5" minimum:"1" maximum:"5" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:已失败, 5:已取消)"`
StartTime *time.Time `json:"start_time" query:"start_time" description:"创建时间起始"`
EndTime *time.Time `json:"end_time" query:"end_time" description:"创建时间结束"`
}
// ExportTaskItem 导出任务列表项。
type ExportTaskItem struct {
ID uint `json:"id" description:"任务ID"`
TaskID uint `json:"task_id" description:"任务ID"`
TaskNo string `json:"task_no" description:"任务编号"`
Scene string `json:"scene" description:"导出场景 (device:设备, iot_card:IoT卡, order:订单, package:套餐, agent_wallet_transaction:代理主钱包流水, agent_recharge:代理充值, refund:退款, exchange:换货, commission_record:佣金明细, package_traffic_alert:套餐真流量达量预警)"`
Format string `json:"format" description:"导出格式 (xlsx:Excel, csv:CSV)"`
Status int `json:"status" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:已失败, 5:已取消)"`
StatusName string `json:"status_name" description:"任务状态名称(中文)"`
Progress int `json:"progress" description:"任务进度(0-100)"`
TotalRows int `json:"total_rows" description:"总行数"`
ProcessedRows int `json:"processed_rows" description:"已处理行数"`
TotalShards int `json:"total_shards" description:"总分片数"`
SuccessShards int `json:"success_shards" description:"成功分片数"`
FailedShards int `json:"failed_shards" description:"失败分片数"`
TotalCount int `json:"total_count" description:"统一任务总数"`
SuccessCount int `json:"success_count" description:"统一任务成功数"`
FailedCount int `json:"failed_count" description:"统一任务失败数"`
CancelRequested bool `json:"cancel_requested" description:"是否已请求取消"`
FileKey string `json:"file_key,omitempty" description:"导出文件Key"`
ErrorMessage string `json:"error_message,omitempty" description:"错误信息"`
ErrorCode string `json:"error_code,omitempty" description:"安全错误码"`
ErrorSummary string `json:"error_summary,omitempty" description:"安全失败摘要"`
CreatedAt time.Time `json:"created_at" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
StartedAt *time.Time `json:"started_at,omitempty" description:"开始处理时间"`
CompletedAt *time.Time `json:"completed_at,omitempty" description:"完成时间"`
CreatorUserID uint `json:"creator_user_id" description:"创建人用户ID"`
CreatorUserType int `json:"creator_user_type" description:"创建人用户类型 (2:平台, 3:代理, 4:企业)"`
CreatorShopID *uint `json:"creator_shop_id,omitempty" description:"创建人店铺ID"`
CreatorEnterpriseID *uint `json:"creator_enterprise_id,omitempty" description:"创建人企业ID"`
}
// ListExportTaskResponse 导出任务列表响应。
type ListExportTaskResponse struct {
List []*ExportTaskItem `json:"items" description:"任务列表"`
Total int64 `json:"total" description:"总数"`
Page int `json:"page" description:"当前页码"`
PageSize int `json:"size" description:"每页数量"`
}
// GetExportTaskRequest 导出任务详情请求。
type GetExportTaskRequest struct {
ID uint `path:"id" description:"任务ID" required:"true"`
}
// ExportTaskDetailResponse 导出任务详情响应。
type ExportTaskDetailResponse struct {
ExportTaskItem
DownloadURL string `json:"download_url,omitempty" description:"下载链接(仅已完成任务返回)"`
DownloadExpiresAt *time.Time `json:"download_expires_at,omitempty" description:"下载链接过期时间"`
}
// CancelExportTaskRequest 取消导出任务请求。
type CancelExportTaskRequest struct {
ID uint `path:"id" description:"任务ID" required:"true"`
}
// CancelExportTaskResponse 取消导出任务响应。
type CancelExportTaskResponse struct {
TaskID uint `json:"task_id" description:"任务ID"`
Status int `json:"status" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:已失败, 5:已取消)"`
StatusName string `json:"status_name" description:"任务状态名称(中文)"`
CancelRequested bool `json:"cancel_requested" description:"是否已请求取消"`
Message string `json:"message" description:"提示信息"`
}