Files
junhong_cmp_fiber/docs/iot-sim-management/数据模型总结.md
huang 034f00e2e7 实现 IoT SIM 管理模块数据模型和数据库结构
- 添加 IoT 核心业务表:运营商、IoT 卡、设备、号卡、套餐、订单等
- 添加分佣系统表:分佣规则、分佣记录、运营商结算等
- 添加轮询和流量管理表:轮询配置、流量使用记录等
- 添加财务和系统管理表:佣金提现、换卡申请等
- 实现完整的 GORM 模型和常量定义
- 添加数据库迁移脚本和详细文档
- 集成 OpenSpec 工作流工具(opsx 命令和 skills)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 15:44:23 +08:00

18 KiB
Raw Blame History

IoT SIM 管理系统 - 数据模型总结

概述

本文档总结了 IoT SIM 管理系统的数据模型层实现,包括 26 张数据库表和对应的 GORM 模型定义。

实现范围

  • 数据库迁<E5BA93><E8BF81><EFBFBD>脚本 (migrations/000005_create_iot_sim_management_tables.up/down.sql)
  • GORM 模型定义 (internal/iot/model/*.go)
  • 业务常量定义 (pkg/constants/iot.go)
  • API Handler 层 (不在本阶段范围)
  • Service 业务逻辑层 (不在本阶段范围)
  • Store 数据访问层 (不在本阶段范围)

核心业务实体

1. 运营商管理 (Carrier)

表名: carriers

核心字段:

  • carrier_code: 运营商编码 (CMCC/CUCC/CTCC)
  • carrier_name: 运营商名称 (中国移动/中国联通/中国电信)
  • api_endpoint: API 接口地址
  • api_credentials: API 凭证 (JSONB)

预置数据: 初始化三大运营商数据

文件位置: internal/iot/model/carrier.go:5


2. IoT 卡管理 (IotCard)

表名: iot_cards

核心字段:

  • iccid: IoT 卡唯一标识 (20 位数字)
  • card_category: 卡业务类型 (normal-普通卡, industry-行业卡)
  • carrier_id: 所属运营商 ID
  • owner_type: 所有者类型 (platform/agent/user/device)
  • owner_id: 所有者 ID
  • activation_status: 激活状态 (0-未激活, 1-已激活)
  • real_name_status: 实名状态 (0-未实名, 1-已实名)
  • network_status: 网络状态 (0-停机, 1-开机)
  • enable_polling: 是否参与轮询

特殊机制:

  • 支持行业卡(无需实名)和普通卡(需实名)
  • 多所有者模式 (owner_type + owner_id)
  • 轮询开关控制 (enable_polling)
  • 流量使用累计 (data_usage_mb)
  • Gateway 同步时间戳 (last_sync_time)

文件位置: internal/iot/model/iot_card.go:8


3. 设备管理 (Device)

表名: devices

核心字段:

  • device_code: 设备唯一编码
  • device_name: 设备名称
  • device_type: 设备类型
  • sim_slots: SIM 卡槽数量 (1-4)
  • owner_type: 所有者类型 (platform/agent/user)
  • owner_id: 所有者 ID

关联关系:

  • 通过 device_sim_bindings 表关联 1-4 张 IoT 卡

文件位置: internal/iot/model/device.go:5


4. 号卡管理 (NumberCard)

表名: number_cards

核心字段:

  • virtual_product_code: 虚拟商品编码 (用于对应运营商订单)
  • card_name: 号卡名称
  • carrier: 运营商
  • data_amount_mb: 流量额度 (MB)
  • price: 价格 (元)

业务说明: 号卡是完全独立的业务线,从上游平台下单,使用虚拟商品编码映射运营商订单。

文件位置: internal/iot/model/number_card.go:8


套餐与流量管理

5. 套餐系列 (PackageSeries)

表名: package_series

核心字段:

  • series_code: 系列编码
  • series_name: 系列名称
  • description: 描述

用途: 套餐分组,用于一次性分佣规则配置。

文件位置: internal/iot/model/package.go:7


6. 套餐 (Package)

表名: packages

核心字段:

  • package_code: 套餐编码
  • package_name: 套餐名称
  • series_id: 所属套餐系列 ID
  • package_type: 套餐类型 (formal-正式套餐, addon-附加套餐)
  • duration_months: 套餐时长 (月数)
  • data_type: 流量类型 (real-真流量, virtual-虚流量)
  • real_data_mb: 真流量额度 (MB)
  • virtual_data_mb: 虚流量额度 (MB)
  • data_amount_mb: 总流量额度 (MB)
  • price: 套餐价格 (元)

特殊机制:

  • 支持真流量/虚流量共存
  • 停机判断基于虚流量
  • 支持正式套餐和附加套餐

文件位置: internal/iot/model/package.go:23


7. 代理套餐分配 (AgentPackageAllocation)

表名: agent_package_allocations

核心字段:

  • agent_id: 代理用户 ID
  • package_id: 套餐 ID
  • cost_price: 成本价 (元)
  • retail_price: 零售价 (元)

用途: 为直属下级代理分配套餐,设置佣金模式。

文件位置: internal/iot/model/package.go:48


8. 设备-IoT 卡绑定 (DeviceSimBinding)

表名: device_sim_bindings

核心字段:

  • device_id: 设备 ID
  • iot_card_id: IoT 卡 ID
  • slot_position: 插槽位置 (1, 2, 3, 4)
  • bind_status: 绑定状态 (1-已绑定, 2-已解绑)
  • bind_time: 绑定时间
  • unbind_time: 解绑时间

用途: 管理设备与 IoT 卡的多对多绑定关系 (1 设备绑定 1-4 张 IoT 卡)。

文件位置: internal/iot/model/package.go:66


9. 套餐使用情况 (PackageUsage)

表名: package_usages

核心字段:

  • order_id: 订单 ID
  • package_id: 套餐 ID
  • usage_type: 使用类型 (single_card-单卡套餐, device-设备级套餐)
  • iot_card_id: IoT 卡 ID (单卡套餐时有值)
  • device_id: 设备 ID (设备级套餐时有值)
  • data_limit_mb: 流量限额 (MB)
  • data_usage_mb: 已使用流量 (MB)
  • real_data_usage_mb: 真流量使用 (MB)
  • virtual_data_usage_mb: 虚流量使用 (MB)
  • activated_at: 套餐生效时间
  • expires_at: 套餐过期时间
  • status: 状态 (1-生效中, 2-已用完, 3-已过期)
  • last_package_check_at: 最后一次套餐流量检查时间

用途: 跟踪单卡套餐和设备级套餐的流量使用。

文件位置: internal/iot/model/package.go:85


10. 轮询配置 (PollingConfig)

表名: polling_configs

核心字段:

  • config_name: 配置名称 (如 未实名卡、实名卡)
  • card_condition: 卡状态条件 (not_real_name/real_name/activated/suspended)
  • carrier_id: 运营商 ID (NULL 表示所有运营商)
  • real_name_check_enabled: 是否启用实名检查
  • real_name_check_interval: 实名检查间隔 (秒)
  • card_data_check_enabled: 是否启用卡流量检查
  • card_data_check_interval: 卡流量检查间隔 (秒)
  • package_check_enabled: 是否启用套餐流量检查
  • package_check_interval: 套餐流量检查间隔 (秒)
  • priority: 优先级 (数字越小优先级越高)

特殊机制: 支持梯度轮询策略 (实名检查、卡流量检查、套餐流量检查)。

文件位置: internal/iot/model/polling.go:7


11. 流量使用记录 (DataUsageRecord)

表名: data_usage_records

核心字段:

  • iot_card_id: IoT 卡 ID
  • usage_date: 使用日期
  • data_usage_mb: 流量使用 (MB)
  • carrier_sync_data: 运营商同步数据 (JSONB)
  • synced_at: 同步时间

用途: 记录 IoT 卡每日流量使用情况 (历史数据)。

文件位置: internal/iot/model/data_usage.go:5


订单管理

12. 订单 (Order)

表名: orders

核心字段:

  • order_no: 订单号 (唯一标识)
  • order_type: 订单类型 (1-套餐订单, 2-号卡订单)
  • iot_card_id: IoT 卡 ID (单卡套餐订单时有值)
  • device_id: 设备 ID (设备级套餐订单时有值)
  • number_card_id: 号卡 ID (号卡订单时有值)
  • package_id: 套餐 ID (套餐订单时有值)
  • user_id: 用户 ID
  • agent_id: 代理用户 ID
  • amount: 订单金额 (元)
  • payment_method: 支付方式 (wallet/online/carrier)
  • status: 状态 (1-待支付, 2-已支付, 3-已完成, 4-已取消, 5-已退款)
  • carrier_order_id: 运营商订单 ID
  • carrier_order_data: 运营商订单原始数据 (JSONB)

支持场景:

  • 套餐订单 (单卡套餐 / 设备级套餐)
  • 号卡订单

文件位置: internal/iot/model/order.go:11


分佣系统

13. 代理层级关系 (AgentHierarchy)

表名: agent_hierarchies

核心字段:

  • agent_id: 代理用户 ID
  • parent_agent_id: 上级代理用户 ID
  • agent_level: 代理层级 (1-一级代理, 2-二级代理, ...)
  • agent_path: 代理路径 (如 /1/2/3/)

用途: 管理代理的树形层级关系。

文件位置: internal/iot/model/commission.go:8


14. 分佣规则 (CommissionRule)

表名: commission_rules

核心字段:

  • rule_name: 规则名称
  • rule_type: 规则类型 (one_time-一次性分佣, long_term-长期分佣, combined-组合分佣)
  • package_series_id: 套餐系列 ID
  • commission_type: 分佣方式 (fixed-固定金额, percentage-百分比)
  • commission_value: 分佣值
  • target_level: 目标层级 (NULL 表示所有层级)
  • enable_ladder: 是否启用阶梯
  • freeze_days: 冻结天数 (长期分佣)
  • freeze_data_mb: 冻结流量 (MB, 长期分佣)
  • unfreeze_mode: 解冻模式 (auto-自动, manual-手动)

分佣类型说明:

  • 一次性分佣: 订单完成后立即发放
  • 长期分佣: 订单完成后冻结,满足解冻条件后发放
  • 组合分佣: 同时包含一次性和长期分佣

文件位置: internal/iot/model/commission.go:24


15. 分佣阶梯 (CommissionLadder)

表名: commission_ladder

核心字段:

  • rule_id: 分佣规则 ID
  • min_quantity: 最小数量
  • max_quantity: 最大数量
  • commission_type: 分佣方式 (fixed/percentage)
  • commission_value: 分佣值

用途: 为分佣规则配置阶梯奖励 (订单数量越多,分佣越高)。

文件位置: internal/iot/model/commission.go:47


16. 组合分佣条件 (CommissionCombinedCondition)

表名: commission_combined_conditions

核心字段:

  • rule_id: 分佣规则 ID
  • condition_type: 条件类型 (one_time-一次性, long_term-长期)
  • commission_type: 分佣方式 (fixed/percentage)
  • commission_value: 分佣值
  • freeze_days: 冻结天数 (长期分佣)
  • freeze_data_mb: 冻结流量 (MB, 长期分佣)

用途: 定义组合分佣规则的具体条件 (一次性部分 + 长期部分)。

文件位置: internal/iot/model/commission.go:68


17. 分佣记录 (CommissionRecord)

表名: commission_records

核心字段:

  • order_id: 订单 ID
  • agent_id: 代理用户 ID
  • rule_id: 分佣规则 ID
  • commission_type: 分佣类型 (one_time/long_term/combined)
  • commission_amount: 分佣金额 (元)
  • status: 状态 (1-待发放, 2-已发放, 3-已冻结, 4-已取消)
  • freeze_days: 冻结天数
  • freeze_data_mb: 冻结流量 (MB)
  • unfreeze_conditions: 解冻条件 (JSONB)
  • unfrozen_at: 解冻时间
  • distributed_at: 发放时间

特殊机制: 支持 OR 条件解冻 (时间到期 OR 流量达标,满足其一即可解冻)。

文件位置: internal/iot/model/commission.go:88


18. 分佣审批 (CommissionApproval)

表名: commission_approvals

核心字段:

  • commission_record_id: 分佣记录 ID
  • agent_id: 代理用户 ID
  • approval_status: 审批状态 (1-待审批, 2-已通过, 3-已拒绝)
  • approver_id: 审批人 ID
  • approval_reason: 审批原因
  • approved_at: 审批时间

用途: 管理需要手动审批的分佣记录。

文件位置: internal/iot/model/commission.go:116


19. 分佣模板 (CommissionTemplate)

表名: commission_templates

核心字段:

  • template_name: 模板名称
  • template_data: 模板数据 (JSONB)
  • description: 描述

用途: 快速创建分佣规则的预设模板。

文件位置: internal/iot/model/commission.go:137


20. 运营商结算 (CarrierSettlement)

表名: carrier_settlements

核心字段:

  • carrier_id: 运营商 ID
  • settlement_month: 结算月份 (YYYY-MM)
  • total_orders: 总订单数
  • total_amount: 总金额 (元)
  • settlement_status: 结算状态 (1-待结算, 2-已结算, 3-已支付)
  • settled_at: 结算时间
  • paid_at: 支付时间

用途: 记录与运营商的月度结算情况。

文件位置: internal/iot/model/commission.go:155


财务管理

21. 提现申请 (CommissionWithdrawalRequest)

表名: commission_withdrawal_requests

核心字段:

  • agent_id: 代理用户 ID
  • withdrawal_amount: 提现金额 (元)
  • withdrawal_method: 提现方式 (bank_card/alipay/wechat)
  • account_info: 账户信息 (JSONB)
  • status: 状态 (1-待审核, 2-已通过, 3-已拒绝, 4-已打款, 5-已取消)
  • reviewer_id: 审核人 ID
  • review_reason: 审核原因
  • reviewed_at: 审核时间
  • paid_at: 打款时间

用途: 管理代理用户的佣金提现申请。

文件位置: internal/iot/model/financial.go:8


22. 提现设置 (CommissionWithdrawalSetting)

表名: commission_withdrawal_settings

核心字段:

  • agent_id: 代理用户 ID
  • min_withdrawal_amount: 最小提现金额 (元)
  • max_withdrawal_amount: 最大提现金额 (元)
  • withdrawal_fee_rate: 提现手续费率 (小数)
  • auto_approval_enabled: 是否启用自动审批

用途: 配置代理用户的提现规则。

文件位置: internal/iot/model/financial.go:31


23. 收款商户设置 (PaymentMerchantSetting)

表名: payment_merchant_settings

核心字段:

  • merchant_name: 商户名称
  • merchant_type: 商户类型 (alipay/wechat/bank)
  • merchant_config: 商户配置 (JSONB)
  • is_default: 是否默认商户

用途: 配置收款商户信息 (支付宝、微信、银行)。

文件位置: internal/iot/model/financial.go:51


系统管理

24. 开发能力配置 (DevCapabilityConfig)

表名: dev_capability_configs

核心字段:

  • capability_name: 能力名称
  • capability_code: 能力编码
  • capability_config: 能力配置 (JSONB)
  • description: 描述

用途: 管理系统开发能力配置 (如 API 开关、功能权限等)。

文件位置: internal/iot/model/system.go:5


25. 换卡申请 (CardReplacementRequest)

表名: card_replacement_requests

核心字段:

  • old_iot_card_id: 旧卡 ID
  • new_iot_card_id: 新卡 ID
  • user_id: 用户 ID
  • replacement_reason: 换卡原因
  • status: 状态 (1-待审核, 2-已通过, 3-已拒绝, 4-已完成)
  • reviewer_id: 审核人 ID
  • reviewed_at: 审核时间
  • completed_at: 完成时间

用途: 管理 IoT 卡的换卡申请流程。

文件位置: internal/iot/model/system.go:25


数据库设计原则

1. 无外键约束

  • 数据库表之间禁止建立外键约束 (Foreign Key Constraints)
  • 关联关系通过存储关联 ID 字段手动维护
  • 关联数据查询在代码层面显式执行

设计理由:

  • 灵活性:业务逻辑完全在代码中控制
  • 性能:无数据库层面的引用完整性检查开销
  • 可控性:开发者完全掌控何时查询关联数据
  • 分布式友好:在微服务场景下更容易扩展

2. GORM 模型规范

  • 所有字段必须显式指定 column: 标签
  • 禁止使用 ORM 关联关系 (foreignKey, references, hasMany, belongsTo)
  • 所有字段必须添加中文注释
  • 字符串字段长度必须明确定义 (VARCHAR(100)/VARCHAR(255)/TEXT)
  • 数值字段精度必须明确定义 (DECIMAL(10,2)/BIGINT)
  • 时间字段使用 GORM 自动管理 (autoCreateTime, autoUpdateTime)

3. 命名规范

  • 数据库字段名:下划线命名法 (snake_case),如 user_id, created_at
  • Go 结构体字段名:驼峰命名法 (PascalCase),如 UserID, CreatedAt
  • 表名:复数形式,如 iot_cards, orders, commission_rules
  • 常量名:大写驼峰 + 前缀,如 IotOrderStatusPending, CarrierCodeCMCC

常量定义

所有业务常量统一定义在 pkg/constants/iot.go 文件中,包括:

  • 卡类型、卡业务类型、激活状态、实名状态、网络状态
  • 所有者类型、卡状态、设备状态
  • 套餐类型、流量类型、套餐使用状态
  • 订单类型、订单状态、支付方式
  • 轮询卡状态条件
  • 分佣规则类型、分佣方式、分佣状态、解冻模式
  • 提现状态、提现方式、商户类型
  • 换卡申请状态、审批状态

文件位置: pkg/constants/iot.go:1


数据库迁移

迁移脚本

  • UP 脚本: migrations/000005_create_iot_sim_management_tables.up.sql

    • 创建 26 张表
    • 创建所有必需的索引
    • 添加完整的中文注释
    • 初始化三大运营商数据
  • DOWN 脚本: migrations/000005_create_iot_sim_management_tables.down.sql

    • 按反向依赖顺序删除所有表

迁移测试

# 应用迁移
source .env && migrate -database "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE}" -path migrations up

# 回滚迁移
source .env && migrate -database "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE}" -path migrations down 1

# 查看版本
source .env && migrate -database "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE}" -path migrations version

测试结果

  • UP 迁移成功 (耗时 616ms)
  • DOWN 迁移成功 (耗时 602ms)
  • 数据库版本正确切换 (4 → 5 → 4 → 5)

文件清单

数据库迁移脚本

  • migrations/000005_create_iot_sim_management_tables.up.sql (1102 行)
  • migrations/000005_create_iot_sim_management_tables.down.sql (27 行)

GORM 模型定义

  • internal/iot/model/carrier.go (17 行)
  • internal/iot/model/iot_card.go (40 行)
  • internal/iot/model/device.go (27 行)
  • internal/iot/model/number_card.go (26 行)
  • internal/iot/model/package.go (108 行)
  • internal/iot/model/order.go (36 行)
  • internal/iot/model/polling.go (29 行)
  • internal/iot/model/data_usage.go (20 行)
  • internal/iot/model/commission.go (175 行)
  • internal/iot/model/financial.go (70 行)
  • internal/iot/model/system.go (46 行)

常量定义

  • pkg/constants/iot.go (164 行)

代码质量

  • go fmt 格式化通过
  • goimports 导入整理通过
  • golangci-lint 质量检查通过 (0 issues)
  • go build 编译通过
  • go mod tidy 依赖管理通过

下一步工作

根据 OpenSpec 规范,本阶段只实现数据模型层,以下工作不在本阶段范围:

  • API Handler 层
  • Service 业务逻辑层
  • Store 数据访问层
  • 单元测试
  • 集成测试
  • API 文档生成

这些工作将在后续阶段按照 OpenSpec 流程逐步实现。


参考文档


文档版本: v1.0 最后更新: 2026-01-12 维护人员: Claude Sonnet 4.5