# IoT SIM 管理系统 - 表结构详细说明 本文档详细说明了 IoT SIM 管理系统的 26 张数据库表的结构、字段定义、索引设计和业务约束。 --- ## 目录 1. [核心业务表](#核心业务表) - [carriers - 运营商](#1-carriers---运营商) - [iot_cards - IoT 卡](#2-iot_cards---iot-卡) - [devices - 设备](#3-devices---设备) - [number_cards - 号卡](#4-number_cards---号卡) 2. [套餐与流量管理表](#套餐与流量管理表) - [package_series - 套餐系列](#5-package_series---套餐系列) - [packages - 套餐](#6-packages---套餐) - [agent_package_allocations - 代理套餐分配](#7-agent_package_allocations---代理套餐分配) - [device_sim_bindings - 设备-IoT卡绑定](#8-device_sim_bindings---设备-iot卡绑定) - [package_usages - 套餐使用情况](#9-package_usages---套餐使用情况) - [polling_configs - 轮询配置](#10-polling_configs---轮询配置) - [data_usage_records - 流量使用记录](#11-data_usage_records---流量使用记录) 3. [订单管理表](#订单管理表) - [orders - 订单](#12-orders---订单) 4. [分佣系统表](#分佣系统表) - [agent_hierarchies - 代理层级关系](#13-agent_hierarchies---代理层级关系) - [commission_rules - 分佣规则](#14-commission_rules---分佣规则) - [commission_ladder - 分佣阶梯](#15-commission_ladder---分佣阶梯) - [commission_combined_conditions - 组合分佣条件](#16-commission_combined_conditions---组合分佣条件) - [commission_records - 分佣记录](#17-commission_records---分佣记录) - [commission_approvals - 分佣审批](#18-commission_approvals---分佣审批) - [commission_templates - 分佣模板](#19-commission_templates---分佣模板) - [carrier_settlements - 运营商结算](#20-carrier_settlements---运营商结算) 5. [财务管理表](#财务管理表) - [commission_withdrawal_requests - 提现申请](#21-commission_withdrawal_requests---提现申请) - [commission_withdrawal_settings - 提现设置](#22-commission_withdrawal_settings---提现设置) - [payment_merchant_settings - 收款商户设置](#23-payment_merchant_settings---收款商户设置) 6. [系统管理表](#系统管理表) - [dev_capability_configs - 开发能力配置](#24-dev_capability_configs---开发能力配置) - [card_replacement_requests - 换卡申请](#25-card_replacement_requests---换卡申请) --- ## 核心业务表 ### 1. carriers - 运营商 **表名**: `carriers` **用途**: 管理三大运营商信息及其 API 配置 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 运营商ID | | carrier_code | VARCHAR(50) | UNIQUE, NOT NULL | 运营商编码(CMCC/CUCC/CTCC) | | carrier_name | VARCHAR(100) | NOT NULL | 运营商名称(中国移动/中国联通/中国电信) | | api_endpoint | VARCHAR(500) | | API 接口地址 | | api_credentials | JSONB | | API 凭证(JSON格式) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `carrier_code` **预置数据**: ```sql INSERT INTO carriers (carrier_code, carrier_name, status) VALUES ('CMCC', '中国移动', 1), ('CUCC', '中国联通', 1), ('CTCC', '中国电信', 1); ``` **GORM 模型**: `internal/iot/model/carrier.go:5` --- ### 2. iot_cards - IoT 卡 **表名**: `iot_cards` **用途**: 物联网卡/流量卡的统一管理实体,支持平台自营、代理分销、用户购买等所有权模式 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | IoT 卡 ID | | iccid | VARCHAR(50) | UNIQUE, NOT NULL | ICCID(唯一标识,20位数字) | | card_type | VARCHAR(50) | NOT NULL | 卡类型 | | card_category | VARCHAR(20) | NOT NULL, DEFAULT 'normal' | 卡业务类型 normal-普通卡 industry-行业卡 | | carrier_id | BIGINT | NOT NULL | 运营商ID | | imsi | VARCHAR(50) | | IMSI | | msisdn | VARCHAR(20) | | MSISDN(手机号码) | | batch_no | VARCHAR(100) | | 批次号 | | supplier | VARCHAR(255) | | 供应商 | | cost_price | DECIMAL(10,2) | DEFAULT 0 | 成本价(元) | | distribute_price | DECIMAL(10,2) | DEFAULT 0 | 分销价(元) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-在库 2-已分销 3-已激活 4-已停用 | | owner_type | VARCHAR(20) | NOT NULL, DEFAULT 'platform' | 所有者类型 platform-平台 agent-代理 user-用户 device-设备 | | owner_id | BIGINT | NOT NULL, DEFAULT 0 | 所有者ID | | activated_at | TIMESTAMPTZ | | 激活时间 | | activation_status | INT | NOT NULL, DEFAULT 0 | 激活状态 0-未激活 1-已激活 | | real_name_status | INT | NOT NULL, DEFAULT 0 | 实名状态 0-未实名 1-已实名(行业卡可以保持0) | | network_status | INT | NOT NULL, DEFAULT 0 | 网络状态 0-停机 1-开机 | | data_usage_mb | BIGINT | DEFAULT 0 | 累计流量使用(MB) | | enable_polling | BOOLEAN | DEFAULT true | 是否参与轮询 true-参与 false-不参与 | | last_data_check_at | TIMESTAMPTZ | | 最后一次流量检查时间 | | last_real_name_check_at | TIMESTAMPTZ | | 最后一次实名检查时间 | | last_sync_time | TIMESTAMPTZ | | 最后一次与Gateway同步时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `iccid` - 组合索引: `(carrier_id, status)` - 组合索引: `(owner_type, owner_id)` - 单列索引: `batch_no` **业务约束**: - `iccid` 必须唯一,通常为 20 位数字 - `card_category = 'industry'` 时,`real_name_status` 可以保持 0 (行业卡无需实名) - `card_category = 'normal'` 时,必须实名才能激活 - `owner_type` 和 `owner_id` 组合表示所有权 - `enable_polling = false` 的卡不参与轮询检查 **GORM 模型**: `internal/iot/model/iot_card.go:8` --- ### 3. devices - 设备 **表名**: `devices` **用途**: 设备管理,支持 1-4 张 SIM 卡 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 设备ID | | device_code | VARCHAR(100) | UNIQUE, NOT NULL | 设备唯一编码 | | device_name | VARCHAR(255) | NOT NULL | 设备名称 | | device_type | VARCHAR(100) | | 设备类型 | | sim_slots | INT | DEFAULT 1 | SIM卡槽数量(1-4) | | owner_type | VARCHAR(20) | NOT NULL, DEFAULT 'platform' | 所有者类型 platform-平台 agent-代理 user-用户 | | owner_id | BIGINT | NOT NULL, DEFAULT 0 | 所有者ID | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-在库 2-已激活 3-已停用 | | activated_at | TIMESTAMPTZ | | 激活时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `device_code` - 组合索引: `(owner_type, owner_id)` **业务约束**: - `sim_slots` 取值范围 1-4 - 通过 `device_sim_bindings` 表管理设备与 IoT 卡的绑定关系 **GORM 模型**: `internal/iot/model/device.go:5` --- ### 4. number_cards - 号卡 **表名**: `number_cards` **用途**: 号卡业务(完全独立的业务线),从上游平台下单 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 号卡ID | | virtual_product_code | VARCHAR(100) | UNIQUE, NOT NULL | 虚拟商品编码(用于对应运营商订单) | | card_name | VARCHAR(255) | NOT NULL | 号卡名称 | | card_type | VARCHAR(50) | | 号卡类型 | | carrier | VARCHAR(50) | | 运营商 | | data_amount_mb | BIGINT | | 流量额度(MB) | | price | DECIMAL(10,2) | | 价格(元) | | agent_id | BIGINT | | 代理用户ID | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-在售 2-下架 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `virtual_product_code` - 单列索引: `agent_id` **业务说明**: - 号卡是完全独立的业务线,与 IoT 卡无关 - 使用虚拟商品编码映射运营商订单 - 从上游平台下单,不涉及本地库存管理 **GORM 模型**: `internal/iot/model/number_card.go:8` --- ## 套餐与流量管理表 ### 5. package_series - 套餐系列 **表名**: `package_series` **用途**: 套餐的分组,用于一次性分佣规则配置 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 套餐系列ID | | series_code | VARCHAR(100) | UNIQUE, NOT NULL | 系列编码 | | series_name | VARCHAR(255) | NOT NULL | 系列名称 | | description | TEXT | | 描述 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `series_code` **业务说明**: - 套餐系列用于分组管理套餐 - 分佣规则可以按套餐系列统一配置 **GORM 模型**: `internal/iot/model/package.go:7` --- ### 6. packages - 套餐 **表名**: `packages` **用途**: 套餐定义,只适用于 IoT 卡,支持真流量/虚流量共存机制 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 套餐ID | | package_code | VARCHAR(100) | UNIQUE, NOT NULL | 套餐编码 | | package_name | VARCHAR(255) | NOT NULL | 套餐名称 | | series_id | BIGINT | | 套餐系列ID | | package_type | VARCHAR(50) | NOT NULL | 套餐类型 formal-正式套餐 addon-附加套餐 | | duration_months | INT | NOT NULL | 套餐时长(月数) 1-月套餐 12-年套餐 | | data_type | VARCHAR(20) | | 流量类型 real-真流量 virtual-虚流量 | | real_data_mb | BIGINT | DEFAULT 0 | 真流量额度(MB) | | virtual_data_mb | BIGINT | DEFAULT 0 | 虚流量额度(MB,用于停机判断) | | data_amount_mb | BIGINT | DEFAULT 0 | 总流量额度(MB) | | price | DECIMAL(10,2) | NOT NULL | 套餐价格(元) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `package_code` - 单列索引: `series_id` **业务约束**: - `data_amount_mb = real_data_mb + virtual_data_mb` - 停机判断基于 `virtual_data_mb` (虚流量用完即停机) - `package_type = 'formal'` 表示正式套餐,`'addon'` 表示附加套餐 **GORM 模型**: `internal/iot/model/package.go:23` --- ### 7. agent_package_allocations - 代理套餐分配 **表名**: `agent_package_allocations` **用途**: 为直属下级代理分配套餐,设置佣金模式 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 分配ID | | agent_id | BIGINT | NOT NULL | 代理用户ID | | package_id | BIGINT | NOT NULL | 套餐ID | | cost_price | DECIMAL(10,2) | NOT NULL | 成本价(元) | | retail_price | DECIMAL(10,2) | NOT NULL | 零售价(元) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合唯一索引: `(agent_id, package_id)` **业务说明**: - 平台或上级代理为下级代理分配套餐 - `cost_price` 是代理的采购成本 - `retail_price` 是代理的零售价格 - 佣金 = `retail_price - cost_price` **GORM 模型**: `internal/iot/model/package.go:48` --- ### 8. device_sim_bindings - 设备-IoT卡绑定 **表名**: `device_sim_bindings` **用途**: 管理设备与 IoT 卡的多对多绑定关系(1 设备绑定 1-4 张 IoT 卡) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 绑定ID | | device_id | BIGINT | NOT NULL | 设备ID | | iot_card_id | BIGINT | NOT NULL | IoT卡ID | | slot_position | INT | | 插槽位置(1, 2, 3, 4) | | bind_status | INT | DEFAULT 1 | 绑定状态 1-已绑定 2-已解绑 | | bind_time | TIMESTAMPTZ | | 绑定时间 | | unbind_time | TIMESTAMPTZ | | 解绑时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合索引: `(device_id, iot_card_id)` - 单列索引: `iot_card_id` **业务约束**: - 一个设备最多绑定 4 张 IoT 卡 - `slot_position` 取值范围 1-4 - 同一设备的同一插槽位置只能绑定一张激活状态的 IoT 卡 **GORM 模型**: `internal/iot/model/package.go:66` --- ### 9. package_usages - 套餐使用情况 **表名**: `package_usages` **用途**: 跟踪单卡套餐和设备级套餐的流量使用 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 套餐使用ID | | order_id | BIGINT | NOT NULL | 订单ID | | package_id | BIGINT | NOT NULL | 套餐ID | | usage_type | VARCHAR(20) | NOT NULL | 使用类型 single_card-单卡套餐 device-设备级套餐 | | iot_card_id | BIGINT | | IoT卡ID(单卡套餐时有值) | | device_id | BIGINT | | 设备ID(设备级套餐时有值) | | data_limit_mb | BIGINT | NOT NULL | 流量限额(MB) | | data_usage_mb | BIGINT | DEFAULT 0 | 已使用流量(MB) | | real_data_usage_mb | BIGINT | DEFAULT 0 | 真流量使用(MB) | | virtual_data_usage_mb | BIGINT | DEFAULT 0 | 虚流量使用(MB) | | activated_at | TIMESTAMPTZ | NOT NULL | 套餐生效时间 | | expires_at | TIMESTAMPTZ | NOT NULL | 套餐过期时间 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-生效中 2-已用完 3-已过期 | | last_package_check_at | TIMESTAMPTZ | | 最后一次套餐流量检查时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `order_id` - 单列索引: `iot_card_id` - 单列索引: `device_id` - 组合索引: `(status, last_package_check_at)` **业务约束**: - `usage_type = 'single_card'` 时,`iot_card_id` 有值,`device_id` 为空 - `usage_type = 'device'` 时,`device_id` 有值,`iot_card_id` 为空 - `data_usage_mb = real_data_usage_mb + virtual_data_usage_mb` - 轮询检查时更新 `last_package_check_at` **GORM 模型**: `internal/iot/model/package.go:85` --- ### 10. polling_configs - 轮询配置 **表名**: `polling_configs` **用途**: 轮询配置,支持梯度轮询策略(实名检查、卡流量检查、套餐流量检查) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 轮询配置ID | | config_name | VARCHAR(100) | UNIQUE, NOT NULL | 配置名称(如 未实名卡、实名卡) | | description | VARCHAR(500) | | 配置描述 | | card_condition | VARCHAR(50) | | 卡状态条件 not_real_name-未实名 real_name-已实名 activated-已激活 suspended-已停用 | | carrier_id | BIGINT | | 运营商ID(NULL表示所有运营商) | | real_name_check_enabled | BOOLEAN | DEFAULT false | 是否启用实名检查 | | real_name_check_interval | INT | DEFAULT 60 | 实名检查间隔(秒) | | card_data_check_enabled | BOOLEAN | DEFAULT false | 是否启用卡流量检查 | | card_data_check_interval | INT | DEFAULT 60 | 卡流量检查间隔(秒) | | package_check_enabled | BOOLEAN | DEFAULT false | 是否启用套餐流量检查 | | package_check_interval | INT | DEFAULT 60 | 套餐流量检查间隔(秒) | | priority | INT | NOT NULL, DEFAULT 100 | 优先级(数字越小优先级越高) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `config_name` - 单列索引: `carrier_id` - 单列索引: `priority` **业务说明**: - 支持三种独立的轮询检查类型 - 可以按卡状态和运营商配置不同的轮询策略 - 优先级控制多个配置的执行顺序 **GORM 模型**: `internal/iot/model/polling.go:7` --- ### 11. data_usage_records - 流量使用记录 **表名**: `data_usage_records` **用途**: 记录 IoT 卡每日流量使用情况(历史数据) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 流量使用记录ID | | iot_card_id | BIGINT | NOT NULL | IoT卡ID | | usage_date | DATE | NOT NULL | 使用日期 | | data_usage_mb | BIGINT | DEFAULT 0 | 流量使用(MB) | | carrier_sync_data | JSONB | | 运营商同步数据(JSON格式) | | synced_at | TIMESTAMPTZ | | 同步时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合唯一索引: `(iot_card_id, usage_date)` - 单列索引: `usage_date` **业务说明**: - 每日记录一次 IoT 卡的流量使用情况 - `carrier_sync_data` 存储从运营商 Gateway 同步的原始数据 - 用于历史查询和统计分析 **GORM 模型**: `internal/iot/model/data_usage.go:5` --- ## 订单管理表 ### 12. orders - 订单 **表名**: `orders` **用途**: 订单管理,支持两种订单类型:套餐订单(单卡/设备级)、号卡订单 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 订单ID | | order_no | VARCHAR(100) | UNIQUE, NOT NULL | 订单号(唯一标识) | | order_type | INT | NOT NULL | 订单类型 1-套餐订单 2-号卡订单 | | iot_card_id | BIGINT | | IoT卡ID(单卡套餐订单时有值) | | device_id | BIGINT | | 设备ID(设备级套餐订单时有值) | | number_card_id | BIGINT | | 号卡ID(号卡订单时有值) | | package_id | BIGINT | | 套餐ID(套餐订单时有值) | | user_id | BIGINT | NOT NULL | 用户ID | | agent_id | BIGINT | | 代理用户ID | | amount | DECIMAL(10,2) | NOT NULL | 订单金额(元) | | payment_method | VARCHAR(20) | | 支付方式 wallet-钱包 online-在线支付 carrier-运营商支付 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-待支付 2-已支付 3-已完成 4-已取消 5-已退款 | | carrier_order_id | VARCHAR(255) | | 运营商订单ID | | carrier_order_data | JSONB | | 运营商订单原始数据(JSON) | | paid_at | TIMESTAMPTZ | | 支付时间 | | completed_at | TIMESTAMPTZ | | 完成时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `order_no` - 单列索引: `user_id` - 单列索引: `agent_id` - 组合索引: `(status, created_at)` **业务约束**: - `order_type = 1` (套餐订单): - 单卡套餐: `iot_card_id` 有值,`device_id` 为空 - 设备级套餐: `device_id` 有值,`iot_card_id` 为空 - `package_id` 必须有值 - `order_type = 2` (号卡订单): - `number_card_id` 必须有值 - `package_id` 为空 **GORM 模型**: `internal/iot/model/order.go:11` --- ## 分佣系统表 ### 13. agent_hierarchies - 代理层级关系 **表名**: `agent_hierarchies` **用途**: 管理代理的树形层级关系 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 层级ID | | agent_id | BIGINT | UNIQUE, NOT NULL | 代理用户ID | | parent_agent_id | BIGINT | | 上级代理用户ID | | agent_level | INT | NOT NULL | 代理层级(1-一级代理, 2-二级代理, ...) | | agent_path | VARCHAR(500) | | 代理路径(如 /1/2/3/) | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `agent_id` - 单列索引: `parent_agent_id` - 单列索引: `agent_level` **业务说明**: - `agent_path` 存储完整的代理路径,便于查询上级链 - 一级代理的 `parent_agent_id` 为 NULL **GORM 模型**: `internal/iot/model/commission.go:8` --- ### 14. commission_rules - 分佣规则 **表名**: `commission_rules` **用途**: 定义分佣规则,支持一次性分佣、长期分佣、组合分佣 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 规则ID | | rule_name | VARCHAR(255) | NOT NULL | 规则名称 | | rule_type | VARCHAR(50) | NOT NULL | 规则类型 one_time-一次性分佣 long_term-长期分佣 combined-组合分佣 | | package_series_id | BIGINT | | 套餐系列ID | | commission_type | VARCHAR(20) | NOT NULL | 分佣方式 fixed-固定金额 percentage-百分比 | | commission_value | DECIMAL(10,4) | NOT NULL | 分佣值 | | target_level | INT | | 目标层级(NULL表示所有层级) | | enable_ladder | BOOLEAN | DEFAULT false | 是否启用阶梯 | | freeze_days | INT | DEFAULT 0 | 冻结天数(长期分佣) | | freeze_data_mb | BIGINT | DEFAULT 0 | 冻结流量(MB,长期分佣) | | unfreeze_mode | VARCHAR(20) | DEFAULT 'auto' | 解冻模式 auto-自动 manual-手动 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `package_series_id` - 组合索引: `(rule_type, status)` **业务约束**: - `rule_type = 'one_time'`: 订单完成后立即发放 - `rule_type = 'long_term'`: 订单完成后冻结,满足解冻条件后发放 - `rule_type = 'combined'`: 同时包含一次性和长期分佣,通过 `commission_combined_conditions` 表定义条件 - `unfreeze_mode = 'auto'`: 时间到期 OR 流量达标,满足其一即可自动解冻 - `unfreeze_mode = 'manual'`: 需要人工审批解冻 **GORM 模型**: `internal/iot/model/commission.go:24` --- ### 15. commission_ladder - 分佣阶梯 **表名**: `commission_ladder` **用途**: 为分佣规则配置阶梯奖励(订单数量越多,分佣越高) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 阶梯ID | | rule_id | BIGINT | NOT NULL | 分佣规则ID | | min_quantity | INT | NOT NULL | 最小数量 | | max_quantity | INT | | 最大数量(NULL表示无上限) | | commission_type | VARCHAR(20) | NOT NULL | 分佣方式 fixed-固定金额 percentage-百分比 | | commission_value | DECIMAL(10,4) | NOT NULL | 分佣值 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `rule_id` **业务示例**: ``` 1-10 单: 10元/单 11-50 单: 15元/单 51+ 单: 20元/单 ``` **GORM 模型**: `internal/iot/model/commission.go:47` --- ### 16. commission_combined_conditions - 组合分佣条件 **表名**: `commission_combined_conditions` **用途**: 定义组合分佣规则的具体条件(一次性部分 + 长期部分) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 条件ID | | rule_id | BIGINT | NOT NULL | 分佣规则ID | | condition_type | VARCHAR(20) | NOT NULL | 条件类型 one_time-一次性 long_term-长期 | | commission_type | VARCHAR(20) | NOT NULL | 分佣方式 fixed-固定金额 percentage-百分比 | | commission_value | DECIMAL(10,4) | NOT NULL | 分佣值 | | freeze_days | INT | DEFAULT 0 | 冻结天数(长期分佣) | | freeze_data_mb | BIGINT | DEFAULT 0 | 冻结流量(MB,长期分佣) | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合索引: `(rule_id, condition_type)` **业务说明**: - 组合分佣规则可以定义多个条件 - 一次性条件立即发放 - 长期条件冻结后按规则解冻 **GORM 模型**: `internal/iot/model/commission.go:68` --- ### 17. commission_records - 分佣记录 **表名**: `commission_records` **用途**: 记录每笔分佣的详细信息,支持 OR 条件解冻 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 分佣记录ID | | order_id | BIGINT | NOT NULL | 订单ID | | agent_id | BIGINT | NOT NULL | 代理用户ID | | rule_id | BIGINT | NOT NULL | 分佣规则ID | | commission_type | VARCHAR(50) | NOT NULL | 分佣类型 one_time/long_term/combined | | commission_amount | DECIMAL(10,2) | NOT NULL | 分佣金额(元) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-待发放 2-已发放 3-已冻结 4-已取消 | | freeze_days | INT | DEFAULT 0 | 冻结天数 | | freeze_data_mb | BIGINT | DEFAULT 0 | 冻结流量(MB) | | unfreeze_conditions | JSONB | | 解冻条件(JSON格式,支持OR逻辑) | | unfrozen_at | TIMESTAMPTZ | | 解冻时间 | | distributed_at | TIMESTAMPTZ | | 发放时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `order_id` - 单列索引: `agent_id` - 组合索引: `(status, unfrozen_at)` **业务约束**: - `unfreeze_conditions` 支持 OR 条件: ```json { "time_based": {"days": 30, "deadline": "2025-02-10T00:00:00Z"}, "data_based": {"data_mb": 1000} } ``` - 满足时间到期 **OR** 流量达标,任一条件满足即可自动解冻 **GORM 模型**: `internal/iot/model/commission.go:88` --- ### 18. commission_approvals - 分佣审批 **表名**: `commission_approvals` **用途**: 管理需要手动审批的分佣记录 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 审批ID | | commission_record_id | BIGINT | UNIQUE, NOT NULL | 分佣记录ID | | agent_id | BIGINT | NOT NULL | 代理用户ID | | approval_status | INT | NOT NULL, DEFAULT 1 | 审批状态 1-待审批 2-已通过 3-已拒绝 | | approver_id | BIGINT | | 审批人ID | | approval_reason | TEXT | | 审批原因 | | approved_at | TIMESTAMPTZ | | 审批时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `commission_record_id` - 单列索引: `agent_id` - 组合索引: `(approval_status, created_at)` **业务说明**: - 当分佣规则的 `unfreeze_mode = 'manual'` 时,需要创建审批记录 - 审批通过后才能解冻和发放佣金 **GORM 模型**: `internal/iot/model/commission.go:116` --- ### 19. commission_templates - 分佣模板 **表名**: `commission_templates` **用途**: 快速创建分佣规则的预设模板 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 模板ID | | template_name | VARCHAR(255) | NOT NULL | 模板名称 | | template_data | JSONB | NOT NULL | 模板数据(JSON格式) | | description | TEXT | | 描述 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` **业务说明**: - `template_data` 存储分佣规则的完整配置 - 可以基于模板快速创建新的分佣规则 **GORM 模型**: `internal/iot/model/commission.go:137` --- ### 20. carrier_settlements - 运营商结算 **表名**: `carrier_settlements` **用途**: 记录与运营商的月度结算情况 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 结算ID | | carrier_id | BIGINT | NOT NULL | 运营商ID | | settlement_month | VARCHAR(7) | NOT NULL | 结算月份(YYYY-MM) | | total_orders | INT | DEFAULT 0 | 总订单数 | | total_amount | DECIMAL(10,2) | DEFAULT 0 | 总金额(元) | | settlement_status | INT | NOT NULL, DEFAULT 1 | 结算状态 1-待结算 2-已结算 3-已支付 | | settled_at | TIMESTAMPTZ | | 结算时间 | | paid_at | TIMESTAMPTZ | | 支付时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合唯一索引: `(carrier_id, settlement_month)` - 组合索引: `(settlement_status, settlement_month)` **业务说明**: - 按月统计与运营商的交易情况 - 支持结算和支付状态跟踪 **GORM 模型**: `internal/iot/model/commission.go:155` --- ## 财务管理表 ### 21. commission_withdrawal_requests - 提现申请 **表名**: `commission_withdrawal_requests` **用途**: 管理代理用户的佣金提现申请 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 提现申请ID | | agent_id | BIGINT | NOT NULL | 代理用户ID | | withdrawal_amount | DECIMAL(10,2) | NOT NULL | 提现金额(元) | | withdrawal_method | VARCHAR(20) | NOT NULL | 提现方式 bank_card/alipay/wechat | | account_info | JSONB | NOT NULL | 账户信息(JSON格式) | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-待审核 2-已通过 3-已拒绝 4-已打款 5-已取消 | | reviewer_id | BIGINT | | 审核人ID | | review_reason | TEXT | | 审核原因 | | reviewed_at | TIMESTAMPTZ | | 审核时间 | | paid_at | TIMESTAMPTZ | | 打款时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `agent_id` - 组合索引: `(status, created_at)` **业务说明**: - `account_info` 存储提现账户信息: ```json { "account_name": "张三", "account_number": "6222021234567890", "bank_name": "中国工商银行" } ``` **GORM 模型**: `internal/iot/model/financial.go:8` --- ### 22. commission_withdrawal_settings - 提现设置 **表名**: `commission_withdrawal_settings` **用途**: 配置代理用户的提现规则 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 设置ID | | agent_id | BIGINT | UNIQUE, NOT NULL | 代理用户ID | | min_withdrawal_amount | DECIMAL(10,2) | DEFAULT 0 | 最小提现金额(元) | | max_withdrawal_amount | DECIMAL(10,2) | DEFAULT 0 | 最大提现金额(元) | | withdrawal_fee_rate | DECIMAL(5,4) | DEFAULT 0 | 提现手续费率(小数) | | auto_approval_enabled | BOOLEAN | DEFAULT false | 是否启用自动审批 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `agent_id` **业务说明**: - 每个代理可以有独立的提现规则 - `withdrawal_fee_rate` 为 0.005 表示 0.5% 手续费 **GORM 模型**: `internal/iot/model/financial.go:31` --- ### 23. payment_merchant_settings - 收款商户设置 **表名**: `payment_merchant_settings` **用途**: 配置收款商户信息(支付宝、微信、银行) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 商户设置ID | | merchant_name | VARCHAR(255) | NOT NULL | 商户名称 | | merchant_type | VARCHAR(20) | NOT NULL | 商户类型 alipay/wechat/bank | | merchant_config | JSONB | NOT NULL | 商户配置(JSON格式) | | is_default | BOOLEAN | DEFAULT false | 是否默认商户 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 组合索引: `(merchant_type, is_default)` **业务说明**: - `merchant_config` 存储商户的 API 配置: ```json { "app_id": "2021001234567890", "private_key": "...", "public_key": "...", "notify_url": "https://..." } ``` **GORM 模型**: `internal/iot/model/financial.go:51` --- ## 系统管理表 ### 24. dev_capability_configs - 开发能力配置 **表名**: `dev_capability_configs` **用途**: 管理系统开发能力配置(如 API 开关、功能权限等) **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 配置ID | | capability_name | VARCHAR(255) | NOT NULL | 能力名称 | | capability_code | VARCHAR(100) | UNIQUE, NOT NULL | 能力编码 | | capability_config | JSONB | NOT NULL | 能力配置(JSON格式) | | description | TEXT | | 描述 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-启用 2-禁用 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 唯一索引: `capability_code` **业务说明**: - 用于配置系统的开发能力开关 - `capability_config` 存储能力的详细配置 **GORM 模型**: `internal/iot/model/system.go:5` --- ### 25. card_replacement_requests - 换卡申请 **表名**: `card_replacement_requests` **用途**: 管理 IoT 卡的换卡申请流程 **字段说明**: | 字段名 | 类型 | 约束 | 说明 | |--------|------|------|------| | id | BIGSERIAL | PRIMARY KEY | 换卡申请ID | | old_iot_card_id | BIGINT | NOT NULL | 旧卡ID | | new_iot_card_id | BIGINT | | 新卡ID | | user_id | BIGINT | NOT NULL | 用户ID | | replacement_reason | TEXT | | 换卡原因 | | status | INT | NOT NULL, DEFAULT 1 | 状态 1-待审核 2-已通过 3-已拒绝 4-已完成 | | reviewer_id | BIGINT | | 审核人ID | | reviewed_at | TIMESTAMPTZ | | 审核时间 | | completed_at | TIMESTAMPTZ | | 完成时间 | | created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 创建时间 | | updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | 更新时间 | **索引**: - 主键索引: `id` - 单列索引: `old_iot_card_id` - 单列索引: `user_id` - 组合索引: `(status, created_at)` **业务流程**: 1. 用户提交换卡申请 (status=1) 2. 管理员审核 (status=2/3) 3. 审核通过后完成换卡 (status=4) **GORM 模型**: `internal/iot/model/system.go:25` --- ## 数据库设计原则总结 ### 1. 无外键约束 - 所有表之间没有数据库级别的外键约束 - 关联关系通过存储关联 ID 字段手动维护 - 提供灵活性和性能优势 ### 2. 字段命名规范 - 数据库字段名: 下划线命名法 (snake_case) - Go 结构体字段名: 驼峰命名法 (PascalCase) - 所有字段必须添加中文注释 ### 3. 数据类型规范 - 主键: `BIGSERIAL` - 字符串: `VARCHAR(长度)` 或 `TEXT` - 数值: `INT`, `BIGINT`, `DECIMAL(10,2)` - 时间: `TIMESTAMPTZ` - JSON: `JSONB` - 布尔: `BOOLEAN` ### 4. 索引设计原则 - 所有主键自动创建索引 - 唯一字段创建唯一索引 - 外键字段创建单列索引 - 常用查询条件创建组合索引 - 时间字段按需创建索引 ### 5. 时间戳字段 - `created_at`: 创建时间,自动设置 - `updated_at`: 更新时间,自动更新 - 使用 `TIMESTAMPTZ` 类型存储带时区的时间戳 --- **文档版本**: v1.0 **最后更新**: 2026-01-12 **维护人员**: Claude Sonnet 4.5