- 添加 IoT 核心业务表:运营商、IoT 卡、设备、号卡、套餐、订单等 - 添加分佣系统表:分佣规则、分佣记录、运营商结算等 - 添加轮询和流量管理表:轮询配置、流量使用记录等 - 添加财务和系统管理表:佣金提现、换卡申请等 - 实现完整的 GORM 模型和常量定义 - 添加数据库迁移脚本和详细文档 - 集成 OpenSpec 工作流工具(opsx 命令和 skills) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.7 KiB
6.7 KiB
ADDED Requirements
Requirement: 号卡实体定义
系统 SHALL 定义号卡(NumberCard)实体,作为运营商订单回传的映射,支持代理分销和分佣。
实体字段:
id: 号卡 ID(主键,BIGINT)virtual_product_code: 虚拟商品编码(VARCHAR(100),唯一,用于对应运营商订单)product_name: 商品名称(VARCHAR(255))carrier: 运营商名称(VARCHAR(100),如 "中国移动"、"中国联通"、"中国电信")carrier_product_id: 运营商商品 ID(VARCHAR(100))package_type: 套餐类型(VARCHAR(50),如 "月套餐"、"流量包")data_amount_mb: 流量额度(BIGINT,MB 为单位,可选)voice_minutes: 语音分钟数(INT,可选)sms_count: 短信条数(INT,可选)price: 固定售价(DECIMAL(10,2),由运营商定价)status: 号卡状态(INT,1-上架 2-下架)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 创建号卡商品
- WHEN 平台创建号卡商品,虚拟商品编码为 "VC-CMCC-001",运营商为"中国移动",固定售价为 30.00 元
- THEN 系统创建号卡记录,
virtual_product_code为 "VC-CMCC-001",carrier为 "中国移动",price为 30.00,状态为 1(上架)
Scenario: 虚拟商品编码唯一性
- WHEN 平台创建号卡商品,虚拟商品编码为已存在的 "VC-CMCC-001"
- THEN 系统拒绝创建,返回错误信息"虚拟商品编码已存在"
Requirement: 号卡运营商订单回传
系统 SHALL 接收 Gateway 项目转换后的运营商订单回传,通过虚拟商品编码匹配号卡,创建订单和分佣记录。
订单回传字段:
carrier_order_id: 运营商订单 ID(VARCHAR(255),唯一)virtual_product_code: 虚拟商品编码(VARCHAR(100),用于匹配号卡)user_phone: 用户手机号(VARCHAR(20))amount: 订单金额(DECIMAL(10,2))order_time: 订单时间(TIMESTAMP)agent_id: 代理 ID(BIGINT,可空,如果通过代理推广则有值)carrier_order_data: 运营商订单原始数据(JSONB)
回传处理流程:
- Gateway 接收运营商订单,统一转换为 JSON 格式
- Gateway 通过 HTTP POST 回传给 CMP 系统
- CMP 系统根据
virtual_product_code匹配号卡 - CMP 系统创建订单记录(
order_type为 "number_card") - 如果有
agent_id,触发代理分佣流程
Scenario: 接收运营商订单回传
- WHEN Gateway 回传运营商订单,虚拟商品编码为 "VC-CMCC-001",代理 ID 为 123,订单金额为 30.00 元
- THEN 系统创建订单记录,
order_type为 "number_card",source_id为号卡 ID,agent_id为 123,触发分佣计算
Scenario: 虚拟商品编码不存在
- WHEN Gateway 回传运营商订单,虚拟商品编码为不存在的 "VC-UNKNOWN"
- THEN 系统拒绝创建订单,返回错误信息"虚拟商品编码不存在"并记录到日志
Requirement: 号卡代理分销
系统 SHALL 支持号卡的代理分销,代理通过推广链接或卡板推广号卡给终端用户。
分销规则:
- 号卡由运营商定价,平台无权修改价格
- 代理通过推广链接或卡板获取用户激活
- 用户激活充值后,资金直接支付给运营商,不经过平台
- 运营商周期性结算总佣金给平台
- 平台根据代理分佣规则分配佣金给代理
代理推广方式:
- 推广链接: 代理生成带有
agent_id的推广链接,用户点击链接激活 - 卡板: 代理线下分发印有二维码的卡板,用户扫码激活
Scenario: 代理生成推广链接
- WHEN 代理商(用户 ID 为 123)为号卡(ID 为 5001)生成推广链接
- THEN 系统生成带有
agent_id=123和product_id=5001的推广链接,如https://example.com/activate?agent=123&product=5001
Scenario: 用户通过代理链接激活
- WHEN 用户通过代理推广链接激活号卡并充值 30.00 元
- THEN 运营商接收用户支付,Gateway 回传订单时包含
agent_id=123,系统触发代理分佣流程
Requirement: 号卡分佣处理
系统 SHALL 根据号卡分佣规则计算代理佣金,支持冻结和解冻流程。
分佣规则:
- 号卡分佣配置在代理分佣规则表(
commission_rules)中 - 分佣类型:一次性分佣、长期分佣、组合分佣(参考 iot-agent-commission 规范)
- 号卡订单的分佣需要满足条件:激活(实名) + 达到充值金额 + 在网状态 + 三无校验
- 分佣记录创建时状态为"冻结",满足条件后变为"解冻中",审批通过后变为"已发放"
Scenario: 号卡订单触发分佣
- WHEN 运营商回传订单,代理 ID 为 123,订单金额为 30.00 元,该代理配置了一次性分佣 5.00 元
- THEN 系统创建分佣记录,金额为 5.00 元,状态为"冻结",等待满足解冻条件
Scenario: 号卡分佣解冻
- WHEN 号卡订单满足解冻条件(激活 + 充值 + 在网 + 三无校验)
- THEN 系统将分佣记录状态从"冻结"变更为"解冻中",创建分佣解冻审批记录
Requirement: 号卡运营商结算
系统 SHALL 记录运营商周期性结算的佣金总额,用于财务对账和利润计算。
结算字段:
settlement_id: 结算记录 ID(主键,BIGINT)carrier: 运营商名称(VARCHAR(100))settlement_period: 结算周期(VARCHAR(50),如 "2025-01")total_commission: 运营商结算的佣金总额(DECIMAL(18,2))settlement_time: 结算时间(TIMESTAMP)status: 结算状态(INT,1-待确认 2-已确认)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 记录运营商结算
- WHEN 运营商"中国移动"结算 2025 年 1 月的佣金总额 50000.00 元
- THEN 系统创建结算记录,
carrier为 "中国移动",settlement_period为 "2025-01",total_commission为 50000.00,状态为 1(待确认)
Scenario: 确认运营商结算
- WHEN 财务确认运营商结算记录(ID 为 1001)
- THEN 系统将结算记录状态从 1(待确认) 变更为 2(已确认)
Requirement: 号卡数据校验
系统 SHALL 对号卡数据进行校验,确保数据完整性和一致性。
校验规则:
- 虚拟商品编码(virtual_product_code):必填,长度 1-100 字符,唯一
- 商品名称(product_name):必填,长度 1-255 字符
- 运营商名称(carrier):必填,长度 1-100 字符
- 固定售价(price):必填,≥ 0,最多 2 位小数
- 状态(status):必填,枚举值 1(上架) | 2(下架)
Scenario: 创建号卡时虚拟商品编码为空
- WHEN 平台创建号卡,虚拟商品编码为空
- THEN 系统拒绝创建,返回错误信息"虚拟商品编码不能为空"
Scenario: 创建号卡时固定售价为负数
- WHEN 平台创建号卡,固定售价为 -10.00
- THEN 系统拒绝创建,返回错误信息"固定售价必须 ≥ 0"