# 产品模块 + 供应链模块 功能设计规范 > 版本: 1.0 | 日期: 2026-06-19 > 模块: product_management + supplychain --- ## 一、总体架构 ``` 平台方(owner) │ ├── product_management ← 产品目录层(定义+展示+消费) │ ├── 产品分类树 (product_category) │ ├── 产品注册 (product) │ ├── 产品资源绑定 (product_resource + product_resource_supplier) │ ├── 客户订购 (product_subscription) │ └── 消费记录 (product_usage_log) │ └── supplychain ← 供应链层(供应+定价+结算) ├── 供应商 (suppliers) ├── 供销关系 (platform_supply_relations) ├── 供销产品 (platform_supply_products) ├── 供应商资源定价 (supplier_resource_price) ← NEW ├── 分销协议 (distribution_agreements + items) ├── 销售记账 (sales_ledger) └── 对账结算 (provider_reconcile / reseller_reconcile) ``` **职责边界:** - product_management: 产品是什么、挂哪里、卖多少、客户买了什么、用了多少、成本多少 - supplychain: 谁来供货、供货价多少、分销折扣、对账结算 **数据流向:** ``` 供应商资源定价(supplychain) → 产品资源绑定(product_mgmt) → 消费成本计算(product_mgmt) → 销售记账(supplychain) → 对账结算(supplychain) ``` --- ## 二、新增数据模型 ### 2.1 product_management 新增表 #### product_resource (产品资源绑定表) 产品绑定的底层资源,一个产品可绑定多个资源。 | 字段 | 类型 | 说明 | |------|------|------| | id | VARCHAR(32) PK | 主键 | | product_id | VARCHAR(32) | 产品ID → product.id | | resource_type | VARCHAR(32) | 资源类型: llm_model/llm_monthly/compute | | resource_ref_id | VARCHAR(32) | 资源引用ID (如 llm.id) | | resource_ref_name | VARCHAR(255) | 资源显示名(冗余,展示用) | | quota | DOUBLE(15,4) | 配额量(包月类用), 0=不限 | | quota_unit | VARCHAR(32) | 配额单位: tokens/requests/gpu_hours | | priority | INT | 多供应商时的优先级(1=最高) | | overflow_product_id | VARCHAR(32) | 超额后转用的按量产品ID | | status | CHAR(1) | 1=启用 0=禁用 | | created_at | DATETIME | | | updated_at | DATETIME | | 索引: idx_pr_product(product_id), idx_pr_resource(resource_type,resource_ref_id) #### product_resource_supplier (产品资源-供应商关联表) 同一产品资源可关联多个供应商,按优先级路由消耗。 | 字段 | 类型 | 说明 | |------|------|------| | id | VARCHAR(32) PK | 主键 | | product_resource_id | VARCHAR(32) | → product_resource.id | | supplier_org_id | VARCHAR(32) | 供应商机构ID → organization.id | | priority | INT | 优先级(1=最高,消耗时优先用高优先级供应商) | | weight | INT | 权重(priority相同时按权重分配) | | status | CHAR(1) | 1=启用 0=禁用 | | created_at | DATETIME | | 索引: idx_prs_resource(product_resource_id), UNIQUE idx_prs_unique(product_resource_id,supplier_org_id) #### product_subscription (客户订购表) 客户购买包月/包量产品后的订购记录。 | 字段 | 类型 | 说明 | |------|------|------| | id | VARCHAR(32) PK | 主键 | | product_id | VARCHAR(32) | → product.id | | user_id | VARCHAR(32) | 客户用户ID | | user_org_id | VARCHAR(32) | 客户机构ID | | subscription_type | CHAR(1) | 1=包月 2=包量 3=一次性 | | status | CHAR(1) | 1=活跃 2=已过期 3=已取消 4=已超额 | | start_date | DATE | 生效日期 | | end_date | DATE | 到期日期 | | quota_total | DOUBLE(15,4) | 总配额 | | quota_used | DOUBLE(15,4) | 已使用量 | | quota_unit | VARCHAR(32) | 配额单位 | | overflow_mode | CHAR(1) | 超额模式: 1=转按量 2=停服 | | overflow_rate | DOUBLE(15,6) | 超额后单价(转按量时) | | purchase_price | DOUBLE(15,2) | 购买价格 | | purchase_currency | CHAR(8) | 货币 | | created_at | DATETIME | | | updated_at | DATETIME | | 索引: idx_ps_product(product_id), idx_ps_user(user_id,user_org_id), idx_ps_status(status), idx_ps_dates(start_date,end_date) #### product_usage_log (产品消费记录表) 每次资源消耗的详细记录,含成本精确计算。 | 字段 | 类型 | 说明 | |------|------|------| | id | VARCHAR(32) PK | 主键 | | product_id | VARCHAR(32) | → product.id | | subscription_id | VARCHAR(32) | → product_subscription.id (可空,按量产品无订购) | | user_id | VARCHAR(32) | 消费者用户ID | | user_org_id | VARCHAR(32) | 消费者机构ID | | product_resource_id | VARCHAR(32) | → product_resource.id | | supplier_org_id | VARCHAR(32) | 实际供应商机构ID | | resource_type | VARCHAR(32) | 资源类型 | | resource_ref_id | VARCHAR(32) | 资源引用ID | | used_amount | DOUBLE(15,4) | 消耗量 | | used_unit | VARCHAR(32) | 消耗单位 | | unit_cost | DOUBLE(15,8) | 单位成本(来自supplier_resource_price) | | total_cost | DOUBLE(15,6) | 总成本 = used_amount × unit_cost | | sell_price | DOUBLE(15,6) | 客户侧售价 | | billing_mode | CHAR(1) | 1=配额内 2=超额按量 | | source_ref_table | VARCHAR(64) | 来源表(如llmusage) | | source_ref_id | VARCHAR(32) | 来源记录ID | | use_time | DATETIME | 消费时间 | | created_at | DATETIME | | 索引: idx_pul_product(product_id), idx_pul_subscription(subscription_id), idx_pul_user(user_id,user_org_id), idx_pul_supplier(supplier_org_id), idx_pul_time(use_time) ### 2.2 supplychain 新增表 #### supplier_resource_price (供应商资源定价表) 供应商对各资源的基准定价,是成本计算的源头。 | 字段 | 类型 | 说明 | |------|------|------| | id | VARCHAR(32) PK | 主键 | | supplier_org_id | VARCHAR(32) | 供应商机构ID | | resource_type | VARCHAR(32) | 资源类型 | | resource_ref_id | VARCHAR(32) | 资源引用ID (如 llm.id) | | resource_ref_name | VARCHAR(255) | 资源名称(冗余) | | unit_price | DOUBLE(15,8) | 单位价格 | | price_unit | VARCHAR(32) | 价格单位: per_1k_tokens/per_request/per_gpu_hour | | input_price | DOUBLE(15,8) | 输入价格(LLM专用,可空) | | output_price | DOUBLE(15,8) | 输出价格(LLM专用,可空) | | currency | CHAR(8) | 货币 CNY/USD | | effective_date | DATE | 生效日期 | | expiry_date | DATE | 失效日期(可空=长期有效) | | status | CHAR(1) | 1=有效 0=无效 | | created_at | DATETIME | | | updated_at | DATETIME | | 索引: idx_srp_supplier(supplier_org_id), idx_srp_resource(resource_type,resource_ref_id), idx_srp_dates(effective_date,expiry_date), UNIQUE idx_srp_unique(supplier_org_id,resource_type,resource_ref_id,effective_date) --- ## 三、appcodes 初始化数据 ``` resource_type: llm_model = 大模型按量 llm_monthly = 大模型包月 compute = 算力 quota_unit / price_unit: tokens = tokens requests = 次 gpu_hours = GPU时 per_1k_tokens = 每千tokens per_request = 每次 per_gpu_hour = 每GPU时 subscription_status: 1 = 活跃 2 = 已过期 3 = 已取消 4 = 已超额(转按量) overflow_mode: 1 = 转按量 2 = 停服 billing_mode: 1 = 配额内 2 = 超额按量 ``` --- ## 四、功能清单与实现逻辑 ### 模块A: product_management (产品目录层) #### A1. 产品资源绑定管理 (管理端) | 功能 | API | 逻辑 | |------|-----|------| | 查看产品的资源绑定列表 | GET /api/product_resources?product_id=X | 查 product_resource WHERE product_id=X, JOIN product_resource_supplier 获取供应商列表 | | 为产品绑定资源 | POST /api/product_resource_bind | 插入 product_resource + 校验 product 存在且属于当前 org | | 解绑资源 | DELETE /api/product_resource_unbind?id=X | 删除 product_resource + 级联删除 product_resource_supplier | | 添加供应商到资源绑定 | POST /api/resource_supplier_add | 插入 product_resource_supplier, 校验 supplier_org_id 在 supplychain.suppliers 中存在 | | 移除供应商 | DELETE /api/resource_supplier_remove?id=X | 删除 product_resource_supplier | | 调整供应商优先级 | PUT /api/resource_supplier_priority | 更新 priority/weight | | 设置超额产品 | PUT /api/resource_overflow | 更新 product_resource.overflow_product_id | #### A2. 客户订购 (管理端创建 + 客户端查看) | 功能 | API | 逻辑 | |------|-----|------| | 创建订购(客户购买包月产品) | POST /api/subscribe | 1.校验产品存在+状态+日期范围 2.读取product_resource获取quota 3.插入product_subscription(status=1) 4.设置overflow_rate(从超额产品的price取) | | 查看订购列表(管理端) | GET /api/subscriptions | 查 product_subscription, 可按user_id/product_id/status筛选 | | 查看我的订购(客户端) | GET /api/my_subscriptions | 查 product_subscription WHERE user_id=当前用户 | | 订购详情 | GET /api/subscription_detail?id=X | 返回订购信息 + 配额使用百分比 + 关联产品信息 | | 取消订购 | PUT /api/subscription_cancel?id=X | status改为3, 停止配额使用 | #### A3. 产品消费 (核心引擎) | 功能 | API | 逻辑 | |------|-----|------| | 消费资源 | POST /api/product_use | **核心流程(见下方详细逻辑)** | | 查看消费记录 | GET /api/usage_logs | 查 product_usage_log, 支持按product_id/user_id/日期/供应商筛选 | | 消费统计 | GET /api/usage_stats | 聚合查询: 按产品/供应商/日期汇总消耗量和成本 | | 配额检查 | GET /api/quota_check?subscription_id=X | 返回 quota_total/quota_used/remaining/percentage | **product_use 核心流程:** ``` 1. 接收参数: product_id, user_id, user_org_id, used_amount, used_unit, source_ref_table, source_ref_id, resource_ref_id 2. 查找产品: product WHERE id=product_id AND status='1' 3. 判断产品类型: IF product_type 是包月类(llm_monthly): a. 查找活跃订购: product_subscription WHERE product_id AND user_id AND status='1' AND start_date<=today AND end_date>=today b. 如果有活跃订购: - 计算剩余配额 = quota_total - quota_used - IF used_amount <= 剩余: billing_mode = '1'(配额内) unit_cost = 0 (配额内不计单次成本) 更新 quota_used += used_amount - ELSE (超额): 先用完配额: quota_used = quota_total 超额部分 = used_amount - 剩余 billing_mode = '2'(超额按量) 查找 overflow_product 获取 overflow_rate sell_price = 超额部分 × overflow_rate subscription.status = '4'(已超额) c. 如果无活跃订购(已过期/未订购): billing_mode = '2' 按产品自身 price 计算 ELSE (按量产品): billing_mode = '2' 直接按量计费 4. 路由供应商(确定成本来源): 查找 product_resource WHERE product_id AND resource_ref_id 查找 product_resource_supplier WHERE product_resource_id AND status='1' ORDER BY priority ASC, weight DESC 选择第一个可用供应商 → supplier_org_id 5. 计算成本: 查找 supplier_resource_price WHERE supplier_org_id AND resource_ref_id AND effective_date<=today AND (expiry_date IS NULL OR expiry_date>=today) unit_cost = supplier_resource_price.unit_price (或 input_price/output_price) total_cost = used_amount × unit_cost 6. 计算售价(给客户的计费): 按量产品: sell_price = used_amount × product.price 包月超额: sell_price = 超额部分 × subscription.overflow_rate 7. 写入 product_usage_log 8. 返回: {success, billing_mode, used_amount, total_cost, sell_price, supplier_org_id, remaining_quota} ``` #### A4. 产品目录展示 (面向客户端) | 功能 | API | 逻辑 | |------|-----|------| | 分类树(客户端) | GET /api/public_categories | 现有 get_category_tree, 只返回 status='1' AND has_product='1' 的叶子节点 | | 分类下产品列表 | GET /api/public_products?category_id=X | 现有 get_products_by_category, 返回产品摘要+价格+是否有资源绑定 | | 产品详情 | GET /api/public_product_detail?id=X | 现有 get_product_detail, 增加资源绑定信息(绑定了几种资源,各多少配额) | ### 模块B: supplychain (供应链层) #### B1. 供应商资源定价管理 | 功能 | API | 逻辑 | |------|-----|------| | 查看供应商资源定价列表 | GET /api/supplier_resource_prices | 查 supplier_resource_price, 可按supplier_org_id/resource_type筛选 | | 创建/更新定价 | POST /api/supplier_resource_price_save | UPSERT supplier_resource_price, 校验supplier存在 | | 删除定价(置为无效) | DELETE /api/supplier_resource_price_disable?id=X | status改为'0' | | 批量导入定价 | POST /api/supplier_resource_price_import | 接收JSON数组,批量插入 | | 查询指定资源的供应商价格 | GET /api/resource_supplier_cost?resource_type=X&resource_ref_id=Y | 返回所有供应商对该资源的定价,用于成本比较 | #### B2. 消费成本对账 (连接 product_management 和 supplychain) | 功能 | API | 逻辑 | |------|-----|------| | 按供应商汇总成本 | GET /api/cost_by_supplier | 跨库JOIN: product_usage_log GROUP BY supplier_org_id, SUM(total_cost) | | 按产品汇总成本 | GET /api/cost_by_product | product_usage_log GROUP BY product_id | | 生成销售记账条目 | POST /api/generate_sales_ledger | 从 product_usage_log 汇总后写入 sales_ledger (周期任务或手动触发) | | 成本趋势 | GET /api/cost_trend | 按日期汇总成本, 最近30天 | --- ## 五、业务流程推演 ### 场景1: 大模型按量产品 ``` 1. 供应商(OpenAI代理商)在 supplychain 注册, 在 supplier_resource_price 设置 GPT-4 价格: input_price=0.03/1Ktokens, output_price=0.06/1Ktokens 2. 平台在 product_management 创建产品: product: "GPT-4智能对话" product_type=llm_model price=0.05/1Ktokens 3. 产品绑定资源: product_resource: resource_type=llm_model, resource_ref_id=llm.id(GPT-4) product_resource_supplier: supplier_org_id=OpenAI代理商, priority=1 4. 客户调用GPT-4, 消耗2000 tokens: product_use → 路由到OpenAI代理商 unit_cost = 0.03/1K × 2 = 0.06 (成本) sell_price = 0.05/1K × 2 = 0.10 (售价) 写入 product_usage_log 5. 月末对账: supplychain 从 product_usage_log 汇总: 供应商: OpenAI代理商, 总成本 = SUM(total_cost) → 写入 sales_ledger → 供应商结算 ``` ### 场景2: 大模型包月产品 + 超额转按量 ``` 1. 平台创建包月产品: product: "AI助手月度套餐" product_type=llm_monthly price=99.00/月 2. 产品绑定资源: product_resource: resource_type=llm_monthly, resource_ref_id=llm.id, quota=1000000(100万tokens), quota_unit=tokens, overflow_product_id=指向"GPT-4按量产品" 3. 绑定两个供应商(同资源多供应商): product_resource_supplier: - supplier_A: priority=1, weight=70 - supplier_B: priority=1, weight=30 4. 客户购买: product_subscription: quota_total=1000000, start=2026-06-01, end=2026-06-30 5. 客户使用中(配额内): 每次调用 → billing_mode='1', 更新 quota_used 按 weight 比例分配供应商: 70%走A, 30%走B 成本分别按各供应商的 supplier_resource_price 计算 6. 配额用完(第25天用完100万tokens): subscription.status → '4'(已超额) 后续调用 → billing_mode='2' sell_price = 超额量 × overflow_rate(从overflow_product的price取) total_cost = 超额量 × supplier_unit_price(实时成本) 7. 月末: 订购到期 → 定时任务将 status='1' 且 end_date