Files
junhong_cmp_fiber/internal/model/dto/operations_report_dto.go
break 5e78809b93
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 15m33s
feat(运营报表): AUG26-015 设备激活与套餐续费日报快照、查询趋势与受控导出
- 新增成对迁移 000231 与三张快照表:日级头行、设备粒度激活行、到期事件粒度续费行,以快照日期为唯一键
- 新增每日 03:30(Asia/Shanghai)日报快照生成任务与幂等整日替换,失败重试沿用同一目标日
- 新增六条受控入口:两张报表的汇总、日/月趋势与受控导出,配套查询层只读快照事实
- 新增 operations_activation 与 operations_renewal 两个导出场景,创建期冻结筛选与可见店铺范围、派发期冻结表头、执行期只按冻结值复核资格
- 采购数量口径按系统内未删除设备数实施并在 PRD 标注,附实测差额依据
- 同步证据链 requirement-evidence.json 与入口能力矩阵、ARCHITECTURE 与验证记录
- 归档 change add-operations-reports 并新建主 Spec openspec/specs/operations-report/spec.md
2026-09-18 09:42:28 +08:00

121 lines
11 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
// OperationsActivationSummaryRequest 是设备激活情况汇总查询请求。
// 时间筛选只接受带显式时区的 RFC3339 秒级时间与闭区间;快照日期按「零点落入区间」判定。
type OperationsActivationSummaryRequest struct {
StartTime string `json:"start_time" query:"start_time" description:"快照日期起始(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
EndTime string `json:"end_time" query:"end_time" description:"快照日期结束(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
GroupBy string `json:"group_by" query:"group_by" validate:"omitempty,oneof=device_name device_model manufacturer business_user_group agent shop business_owner" description:"分组维度 (device_name:设备名称, device_model:设备型号, manufacturer:制造商, business_user_group:用户组, agent:代理, shop:店铺, business_owner:业务员);不传则汇总为一行「全部」"`
}
// OperationsActivationTrendRequest 是设备激活情况趋势查询请求。
type OperationsActivationTrendRequest struct {
StartTime string `json:"start_time" query:"start_time" description:"快照日期起始(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
EndTime string `json:"end_time" query:"end_time" description:"快照日期结束(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-30T00:00:00+08:00"`
Granularity string `json:"granularity" query:"granularity" validate:"omitempty,oneof=day month" description:"趋势粒度 (day:按日, month:按月);不传按日"`
GroupBy string `json:"group_by" query:"group_by" validate:"omitempty,oneof=device_name device_model manufacturer business_user_group agent shop business_owner" description:"分组维度;不传则每个期返回一行「全部」"`
}
// OperationsRenewalSummaryRequest 是套餐续费情况汇总查询请求。
type OperationsRenewalSummaryRequest struct {
StartTime string `json:"start_time" query:"start_time" description:"快照日期起始(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
EndTime string `json:"end_time" query:"end_time" description:"快照日期结束(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
GroupBy string `json:"group_by" query:"group_by" validate:"omitempty,oneof=package_series package_name business_user_group agent shop business_owner" description:"分组维度 (package_series:套餐系列, package_name:套餐名称, business_user_group:用户组, agent:代理, shop:店铺, business_owner:业务员);不传则汇总为一行「全部」"`
}
// OperationsRenewalTrendRequest 是套餐续费情况趋势查询请求。
type OperationsRenewalTrendRequest struct {
StartTime string `json:"start_time" query:"start_time" description:"快照日期起始(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
EndTime string `json:"end_time" query:"end_time" description:"快照日期结束(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-30T00:00:00+08:00"`
Granularity string `json:"granularity" query:"granularity" validate:"omitempty,oneof=day month" description:"趋势粒度 (day:按日, month:按月);不传按日"`
GroupBy string `json:"group_by" query:"group_by" validate:"omitempty,oneof=package_series package_name business_user_group agent shop business_owner" description:"分组维度;不传则每个期返回一行「全部」"`
}
// OperationsActivationSummaryItem 是设备激活情况的一行指标。
// 累计类与其派生指标取所选结束日的快照;结束日无快照时全部为空值(不回退更早快照)。
// 分母为零的比率与卡均为空值;新增激活数允许为负,不设零下限。
type OperationsActivationSummaryItem struct {
GroupValue string `json:"group_value" description:"分组列值(未选择分组维度时为「全部」)"`
PurchasedDeviceCount *int64 `json:"purchased_device_count" description:"采购数量:截至快照日系统内未删除的设备数"`
ActivatedDeviceCount *int64 `json:"activated_device_count" description:"累计激活数:任一当前有效关联卡已实名的设备数"`
ActivationRate *float64 `json:"activation_rate" description:"激活率:累计激活数 / 采购数量,保留两位小数;采购数量为零时为空"`
NewActivatedDeviceCount *int64 `json:"new_activated_device_count" description:"新增激活数:结束日累计减去基期累计,允许为负"`
OnlineDeviceCount *int64 `json:"online_device_count" description:"累计在网数:已实名且存在有效主套餐的设备数"`
ActiveDeviceCount *int64 `json:"active_device_count" description:"活跃用户数:真流量合计大于零的设备数"`
TotalRealTrafficGB *float64 `json:"total_real_traffic_gb" description:"累计用量(GB):按 1 GB = 1024 MB 折算,保留两位小数"`
PerUserAverageGB *float64 `json:"per_user_average_gb" description:"单用户卡均(GB):累计用量 / 累计在网数,保留两位小数;在网数为零时为空"`
ForecastAverageIncludingZeroGB *float64 `json:"forecast_average_including_zero_gb" description:"含零预测卡均(GB):按累计在网数为分母、结束日所在当月年化"`
ForecastAverageExcludingZeroGB *float64 `json:"forecast_average_excluding_zero_gb" description:"不含零预测卡均(GB):按活跃用户数为分母、结束日所在当月年化"`
}
// OperationsActivationSummaryResponse 是设备激活情况汇总响应。
// HasSnapshot 表示所选结束日是否存在快照SnapshotDates 是区间内实际命中的快照日期集合。
type OperationsActivationSummaryResponse struct {
HasSnapshot bool `json:"has_snapshot" description:"结束日是否存在快照;为 false 时累计类与派生指标为空且分组行为空集"`
SnapshotDates []string `json:"snapshot_dates" description:"区间内实际命中的快照日期yyyy-MM-dd"`
GroupBy string `json:"group_by" description:"分组维度编码;空表示未分组"`
GroupName string `json:"group_name" description:"分组维度中文名;未分组时为「全部」"`
Totals *OperationsActivationSummaryItem `json:"totals" description:"头行合计;结束日无快照时为空"`
Items []OperationsActivationSummaryItem `json:"items" description:"分组行;未选择分组维度时只有一行「全部」"`
}
// OperationsActivationTrendPoint 是设备激活情况趋势的一个期点。
// 累计类指标取该期最后一个有快照日的快照值;新增激活数取相邻期同口径之差,任一侧无快照时为空。
type OperationsActivationTrendPoint struct {
Period string `json:"period" description:"期标识(按日为 yyyy-MM-dd按月为 yyyy-MM"`
OperationsActivationSummaryItem
}
// OperationsActivationTrendResponse 是设备激活情况趋势响应。
// 无快照的期不出现;后端只返回数据,图表渲染由前端负责。
type OperationsActivationTrendResponse struct {
Granularity string `json:"granularity" description:"趋势粒度 (day|month)"`
GroupBy string `json:"group_by" description:"分组维度编码;空表示未分组"`
GroupName string `json:"group_name" description:"分组维度中文名;未分组时为「全部」"`
Points []OperationsActivationTrendPoint `json:"points" description:"趋势点;无快照的期不出现"`
}
// OperationsRenewalSummaryItem 是套餐续费情况的一行指标。
// 到期与续费均按资产去重,续费资产恒为到期资产的子集,续费率不超过 100% 由构造保证。
type OperationsRenewalSummaryItem struct {
GroupValue string `json:"group_value" description:"分组列值(未选择分组维度时为「全部」)"`
DueAssetCount *int64 `json:"due_asset_count" description:"到期资产数:未退款主套餐到期日为统计期的资产数(按资产去重)"`
RenewedAssetCount *int64 `json:"renewed_asset_count" description:"续费资产数:到期资产中已续费的资产数(按资产去重)"`
RenewalRate *float64 `json:"renewal_rate" description:"续费率:续费资产数 / 到期资产数,保留两位小数;到期数为零时为空"`
NewUnrenewedAssetCount *int64 `json:"new_unrenewed_asset_count" description:"新增未续费数:到期资产数减续费资产数,不小于零"`
}
// OperationsRenewalSummaryResponse 是套餐续费情况汇总响应。
type OperationsRenewalSummaryResponse struct {
HasSnapshot bool `json:"has_snapshot" description:"结束日是否存在快照;为 false 时全部指标为空且分组行为空集"`
SnapshotDates []string `json:"snapshot_dates" description:"区间内实际命中的快照日期yyyy-MM-dd"`
GroupBy string `json:"group_by" description:"分组维度编码;空表示未分组"`
GroupName string `json:"group_name" description:"分组维度中文名;未分组时为「全部」"`
Totals *OperationsRenewalSummaryItem `json:"totals" description:"头行合计;结束日无快照时为空"`
Items []OperationsRenewalSummaryItem `json:"items" description:"分组行;未选择分组维度时只有一行「全部」"`
}
// OperationsRenewalTrendPoint 是套餐续费情况趋势的一个期点。
// 到期与续费都是期内流式指标:期内同一资产多次到期或多条续费各计一次。
type OperationsRenewalTrendPoint struct {
Period string `json:"period" description:"期标识(按日为 yyyy-MM-dd按月为 yyyy-MM"`
OperationsRenewalSummaryItem
}
// OperationsRenewalTrendResponse 是套餐续费情况趋势响应。
type OperationsRenewalTrendResponse struct {
Granularity string `json:"granularity" description:"趋势粒度 (day|month)"`
GroupBy string `json:"group_by" description:"分组维度编码;空表示未分组"`
GroupName string `json:"group_name" description:"分组维度中文名;未分组时为「全部」"`
Points []OperationsRenewalTrendPoint `json:"points" description:"趋势点;无快照的期不出现"`
}
// ExportOperationsReportRequest 是设备激活情况与套餐续费情况报表的受控导出请求。
// 时间边界在创建期冻结为 UTC RFC3339 秒级字符串,执行期只按冻结值严格解析。
type ExportOperationsReportRequest struct {
Format string `json:"format" validate:"required,oneof=xlsx csv" required:"true" description:"导出格式 (xlsx:Excel, csv:CSV)"`
StartTime string `json:"start_time" description:"快照日期起始(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-01T00:00:00+08:00"`
EndTime string `json:"end_time" description:"快照日期结束(带时区的 RFC3339 秒级时间,闭区间含该时刻,如 2026-09-30T00:00:00+08:00"`
GroupBy string `json:"group_by" description:"分组维度编码;不传则导出唯一一行「全部」"`
}