Files
junhong_cmp_fiber/internal/model/operations_report.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

98 lines
8.2 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 model
import "time"
// OperationsReportSnapshot 运营报表日级快照头行。
//
// 一个上海自然日一行,同时承担三件事:①「该日是否有快照」的唯一判定;
// ②日/月趋势与新增指标的序列来源O(1) 读取,不必扫明细行);
// ③合计行与分组行不变量校验的权威值。整日幂等替换,因此不设软删除列。
type OperationsReportSnapshot struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
SnapshotDate time.Time `gorm:"column:snapshot_date;type:date;not null" json:"snapshot_date"`
PurchasedDeviceCount int64 `gorm:"column:purchased_device_count;type:bigint;not null;default:0" json:"purchased_device_count"`
ActivatedDeviceCount int64 `gorm:"column:activated_device_count;type:bigint;not null;default:0" json:"activated_device_count"`
OnlineDeviceCount int64 `gorm:"column:online_device_count;type:bigint;not null;default:0" json:"online_device_count"`
ActiveDeviceCount int64 `gorm:"column:active_device_count;type:bigint;not null;default:0" json:"active_device_count"`
TotalRealTrafficMB float64 `gorm:"column:total_real_traffic_mb;type:numeric(20,2);not null;default:0" json:"total_real_traffic_mb"`
RenewalDueAssetCount int64 `gorm:"column:renewal_due_asset_count;type:bigint;not null;default:0" json:"renewal_due_asset_count"`
RenewalRenewedAssetCount int64 `gorm:"column:renewal_renewed_asset_count;type:bigint;not null;default:0" json:"renewal_renewed_asset_count"`
GeneratedAt time.Time `gorm:"column:generated_at;type:timestamp;not null" json:"generated_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
}
// TableName 指定运营报表日级快照头行表名。
func (OperationsReportSnapshot) TableName() string {
return "tb_operations_report_snapshot"
}
// OperationsReportActivationRow 运营报表设备激活快照行。
//
// 设备粒度,一行对应一台未删除设备,冻结生成时刻的设备属性、归属与四项指标。
// 归属(店铺、业务员、用户组与代理的两个取值)是一次性冻结值,不因后续变化被改写。
type OperationsReportActivationRow struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
SnapshotDate time.Time `gorm:"column:snapshot_date;type:date;not null" json:"snapshot_date"`
DeviceID uint `gorm:"column:device_id;type:bigint;not null" json:"device_id"`
VirtualNo string `gorm:"column:virtual_no;type:varchar(100);not null;default:''" json:"virtual_no"`
DeviceName string `gorm:"column:device_name;type:varchar(255);not null;default:''" json:"device_name"`
DeviceModel string `gorm:"column:device_model;type:varchar(100);not null;default:''" json:"device_model"`
Manufacturer string `gorm:"column:manufacturer;type:varchar(255);not null;default:''" json:"manufacturer"`
ShopID *uint `gorm:"column:shop_id;type:bigint" json:"shop_id,omitempty"`
ShopName string `gorm:"column:shop_name;type:varchar(100);not null;default:''" json:"shop_name"`
RootShopID *uint `gorm:"column:root_shop_id;type:bigint" json:"root_shop_id,omitempty"`
RootShopName string `gorm:"column:root_shop_name;type:varchar(100);not null;default:''" json:"root_shop_name"`
AgentAccountID *uint `gorm:"column:agent_account_id;type:bigint" json:"agent_account_id,omitempty"`
AgentAccountName string `gorm:"column:agent_account_name;type:varchar(255);not null;default:''" json:"agent_account_name"`
BusinessOwnerAccountID *uint `gorm:"column:business_owner_account_id;type:bigint" json:"business_owner_account_id,omitempty"`
BusinessOwnerName string `gorm:"column:business_owner_name;type:varchar(255);not null;default:''" json:"business_owner_name"`
BusinessUserGroupID *uint `gorm:"column:business_user_group_id;type:bigint" json:"business_user_group_id,omitempty"`
BusinessUserGroupName string `gorm:"column:business_user_group_name;type:varchar(100);not null;default:''" json:"business_user_group_name"`
Purchased bool `gorm:"column:purchased;type:boolean;not null;default:false" json:"purchased"`
Realnamed bool `gorm:"column:realnamed;type:boolean;not null;default:false" json:"realnamed"`
Online bool `gorm:"column:online;type:boolean;not null;default:false" json:"online"`
Active bool `gorm:"column:active;type:boolean;not null;default:false" json:"active"`
RealTrafficMB float64 `gorm:"column:real_traffic_mb;type:numeric(20,2);not null;default:0" json:"real_traffic_mb"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
}
// TableName 指定运营报表设备激活快照行表名。
func (OperationsReportActivationRow) TableName() string {
return "tb_operations_report_activation_row"
}
// OperationsReportRenewalRow 运营报表套餐续费快照行。
//
// 到期事件粒度,一行对应一条在快照日到期的主套餐使用记录;
// 「续费」是该到期资产在生成时刻是否已存在另一条未退款主套餐的事实,因此挂在到期行上。
type OperationsReportRenewalRow struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
SnapshotDate time.Time `gorm:"column:snapshot_date;type:date;not null" json:"snapshot_date"`
AssetType string `gorm:"column:asset_type;type:varchar(20);not null" json:"asset_type"`
AssetID uint `gorm:"column:asset_id;type:bigint;not null" json:"asset_id"`
AssetIdentifier string `gorm:"column:asset_identifier;type:varchar(100);not null;default:''" json:"asset_identifier"`
ExpiredUsageID uint `gorm:"column:expired_usage_id;type:bigint;not null" json:"expired_usage_id"`
PackageID uint `gorm:"column:package_id;type:bigint;not null" json:"package_id"`
PackageName string `gorm:"column:package_name;type:varchar(255);not null;default:''" json:"package_name"`
SeriesID *uint `gorm:"column:series_id;type:bigint" json:"series_id,omitempty"`
SeriesName string `gorm:"column:series_name;type:varchar(255);not null;default:''" json:"series_name"`
ShopID *uint `gorm:"column:shop_id;type:bigint" json:"shop_id,omitempty"`
ShopName string `gorm:"column:shop_name;type:varchar(100);not null;default:''" json:"shop_name"`
RootShopID *uint `gorm:"column:root_shop_id;type:bigint" json:"root_shop_id,omitempty"`
RootShopName string `gorm:"column:root_shop_name;type:varchar(100);not null;default:''" json:"root_shop_name"`
AgentAccountID *uint `gorm:"column:agent_account_id;type:bigint" json:"agent_account_id,omitempty"`
AgentAccountName string `gorm:"column:agent_account_name;type:varchar(255);not null;default:''" json:"agent_account_name"`
BusinessOwnerAccountID *uint `gorm:"column:business_owner_account_id;type:bigint" json:"business_owner_account_id,omitempty"`
BusinessOwnerName string `gorm:"column:business_owner_name;type:varchar(255);not null;default:''" json:"business_owner_name"`
BusinessUserGroupID *uint `gorm:"column:business_user_group_id;type:bigint" json:"business_user_group_id,omitempty"`
BusinessUserGroupName string `gorm:"column:business_user_group_name;type:varchar(100);not null;default:''" json:"business_user_group_name"`
Renewed bool `gorm:"column:renewed;type:boolean;not null;default:false" json:"renewed"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
}
// TableName 指定运营报表套餐续费快照行表名。
func (OperationsReportRenewalRow) TableName() string {
return "tb_operations_report_renewal_row"
}