Files
TakeoutSaaS.Docs/商品模块_API设计_v1.md
2026-01-29 01:58:15 +00:00

15 KiB
Raw Permalink Blame History

商品模块 API 设计v1

企业级/混合模式版

0. 目标与范围

  • 面向商业化外卖 SaaS覆盖“总部主库 + 门店私库 + 多维度经营 + 可配置开关 + 可扩展集成”。
  • 本文仅讨论 API 设计与契约,不涉及实现细节。
  • 默认对齐项目现有约束多租户、CQRS、统一响应、Snowflake ID、JWT/RBAC。

1. 通用规范

1.1 路由与版本

  • AdminApi/api/admin/v1/...
  • MiniApi/api/mini/v1/...
  • UserApi/api/user/v1/...

1.2 鉴权与租户

  • HeaderAuthorization: Bearer {token}
  • 租户:X-Tenant-IdX-Tenant-Code(必填,除白名单路径)
  • 角色权限AdminApi 必须绑定 PermissionAuthorize 权限码

1.3 响应格式

统一使用 ApiResponse<T>,与现有 Shared.Web 约定一致。

1.4 ID 与并发

  • 所有 long 类型 ID 在 API 中 序列化为 string
  • 更新类接口需携带 rowVersionBase64If-Match 以并发控制。

1.5 幂等与限流

  • 创建、批量变更、导入等写接口支持 Idempotency-Key
  • 面向公网端启用限流策略,读接口优先缓存。

1.6 分页与排序

统一参数:pagepageSizesortBysortOrderasc|desc)。

2. 产品原则10 年外卖 SaaS 视角)

  • 品牌一致性优先:总部主库保证品牌统一,门店仅允许“可控范围内的微调”。
  • 经营灵活性必备:门店私有商品与局部覆盖是应对“城市、商圈、人力”的关键。
  • C 端效率优先:类目不超过 2 级,菜单渲染优先走聚合与缓存。
  • 扩展优先:渠道/场景/时段/三方同步都必须可开关,避免“为少数租户拖累成本”。

3. 功能域拆分(可开关)

3.1 核心域

  • 公共商品库Master Library总部商品
  • 门店私有库Store Library本地特色
  • 引用/下发机制Push & Pull
  • 类目管理2 级以内 + 时段可见)
  • 商品Product/SPU与规格 SKU
  • 场景/渠道/时段维度可见性
  • 计价与打包费策略
  • 库存视图与沽清(含每日重置)

3.2 可选域

  • 加料/口味Addon/Modifier
  • 套餐/组合Bundle/N 选 M
  • 称重计价与时价
  • 后厨生产KDS/打印标签/台位)
  • 三方平台同步(美团/饿了么/抖音)
  • 审核流与定时上架
  • 多语言I18n
  • 评分/销量统计视图Stats

4. 核心架构:公共商品库 + 门店私有库 + Push/Pull

4.1 公共商品库Tenant/Master Library

  • 定义:总部创建的标准化商品。
  • 作用:维护品牌统一形象(名称、图、描述、营养、后厨分类)。
  • 管控:总部可锁定核心字段,门店仅可引用,不可篡改。

4.2 门店私有库Store Private Library

  • 定义:门店为本地市场创建的特色商品。
  • 作用:一店一策(开业活动、地域限定等)。
  • 权限:仅本门店可见,总部可审计但默认不干预。

4.3 引用与下发Push & Pull

  • 总部推送Push支持“静默上架”或“待门店确认”。
  • 门店拉取Pull门店经理从公共库勾选引入到本店经营列表。
  • 门店引用后允许“局部覆盖”,但不破坏主库锁定字段。

4.4 混合视图标识

  • API 输出 libraryType + masterProductId,便于后台列表用标签区分来源。
  • lockedFields 返回总部锁定字段,避免门店误操作。

5. 维度管理:类目、场景、渠道与时段

5.1 类目2 级以内)

  • 类目支持“生效时段”,如早餐类目 10:00 后隐藏。
  • 类目可绑定“场景”,如堂食专属类目。

5.2 场景(履约场景)

  • 堂食DineIn、外卖Delivery、自提Pickup
  • 外卖场景强制打包费规则;堂食可免打包费。

5.3 渠道(流量入口)

  • 微信小程序、POS 点餐、美团、饿了么、抖音等。
  • 支持“渠道隔离”:显示顺序、价格、上下架状态可独立配置。

5.4 维度优先级(建议)

门店覆盖 > 渠道配置 > 时段配置 > 商品基础配置。

6. 核心业务规则

6.1 覆盖机制Override Rule

  • 门店可对价格、场景、上架/沽清做覆盖。
  • 被锁定字段不允许覆盖;如需调整须总部解锁或走审核。

6.2 计价与打包费

  • 计价模式:固定单价、按克计价(称重菜)、时价(随行就市)。
  • 打包费支持按 SKU 设置,且可按场景配置(堂食可为 0
  • 打包费支持单单封顶(不超过 X 元)。

6.3 库存与自动重置

  • 支持门店级“每日自动恢复初始库存”(默认凌晨执行)。
  • 沽清为临时状态,不影响主库与其他门店。

6.4 规格、加料与套餐

  • SKU 影响价格与库存。
  • 加料支持“收费加料 + 免费属性”,可配置选配上限/下限。
  • 动态套餐支持“N 选 M”并要求库存穿透
    • 套餐内关键单品沽清时,套餐自动联动下架。

6.5 生产与后厨KDS/打印)

  • 商品可绑定“打印标签 + 后厨台位”。
  • 订单下发需标示场景,以区分堂食/外卖/自提出餐逻辑。

6.6 三方平台同步

  • 内置 Mapping 机制,支持“商品—平台商品”映射。
  • 价格/沽清变动触发事件总线,异步同步到平台接口。

7. 权限与审计

  • 总部运营:管理主库、类目、全局规则、价格上限、审核流。
  • 门店经理:门店私有商品、门店覆盖、今日沽清。
  • 字段级审计日志:记录“谁在何时修改了哪个门店商品的价格/状态”。
  • 推送审计:记录主库变更的下发范围与结果。

8. 功能开关(租户级)

用于“商业化套餐可选启用”。建议 AdminApi 提供读取能力,写入由套餐/配置管理模块控制。

示例结构:

{
  "enableMasterLibrary": true,
  "enableStoreLibrary": true,
  "enablePushPull": true,
  "enableVariant": true,
  "enableAddon": true,
  "enableBundle": true,
  "enableSceneFilter": true,
  "enableChannelIsolation": true,
  "enableChannelPrice": true,
  "enableTimePrice": true,
  "enableStoreOverride": true,
  "enablePricingWeight": true,
  "enablePricingMarket": true,
  "enablePackagingFee": true,
  "enablePackagingFeeCap": true,
  "enableDailyStockReset": true,
  "enableInventory": true,
  "enableApproval": false,
  "enableScheduledPublish": true,
  "enableKds": true,
  "enableThirdPartySync": true,
  "enableMultiLanguage": false,
  "enableNutritionInfo": false
}

9. 关键 DTO摘要

字段命名遵循现有规范,布尔值使用 Is/Has 前缀。

9.1 CategoryDto

字段 说明
id 类目 IDstring
parentId 父级类目 ID
name 类目名称
sortOrder 排序
isEnabled 是否启用
availableScenes 生效场景
availableTimeRanges 生效时段
createdAt 创建时间

9.2 ProductDtoSPU

字段 说明
id 商品 IDstring
libraryType Master/Store
masterProductId 引用的主库商品 ID
storeId 归属门店
name 商品名称
categoryId 类目 ID
unit 单位
tags 标签
coverImageUrl 封面图
imageUrls 轮播图
isEnabled 是否启用
isPublished 是否上架
hasSku 是否包含 SKU
hasAddon 是否包含加料
pricingMode Fixed/Weight/Market
basePrice 基础价格
packagingFee 打包费(基础)
packagingFeeCap 打包费封顶
availableScenes 生效场景
availableChannels 生效渠道
lockedFields 被总部锁定字段
rowVersion 并发字段

9.3 SkuDto

字段 说明
id SKU IDstring
productId 商品 ID
specValues 规格值列表
price 价格
stock 库存
isEnabled 是否启用
rowVersion 并发字段

9.4 StoreProductOverrideDto

字段 说明
storeId 门店 ID
productId 商品 ID
overridePrice 覆盖价格
overrideScenes 覆盖场景
isSoldOut 是否沽清
isApproved 是否已审核
overrideReason 覆盖原因

9.5 AddonGroupDto可选

字段 说明
id 组 ID
name 组名
minSelected 最少选择
maxSelected 最多选择
isRequired 是否必选
items 加料项列表

9.6 ChannelSettingDto可选

字段 说明
channelCode 渠道编码
price 渠道价格
sortOrder 渠道排序
isEnabled 是否启用

9.7 ProductionProfileDto可选

字段 说明
kitchenStationId 后厨台位
printTagId 打印标签

10. AdminApi管理端接口清单

10.1 公共商品库(总部)

  • GET /api/admin/v1/master-products
  • GET /api/admin/v1/master-products/{id}
  • POST /api/admin/v1/master-products
  • PUT /api/admin/v1/master-products/{id}
  • PUT /api/admin/v1/master-products/{id}/lock-fields
  • PUT /api/admin/v1/master-products/{id}/publish
  • PUT /api/admin/v1/master-products/{id}/unpublish

10.2 门店私有库与经营商品

  • GET /api/admin/v1/stores/{storeId}/products
  • POST /api/admin/v1/stores/{storeId}/products(创建门店私有商品)
  • POST /api/admin/v1/stores/{storeId}/products/pull(从主库拉取)
  • PUT /api/admin/v1/stores/{storeId}/products/{id}
  • PUT /api/admin/v1/stores/{storeId}/products/{id}/override
  • PUT /api/admin/v1/stores/{storeId}/products/{id}/publish
  • PUT /api/admin/v1/stores/{storeId}/products/{id}/unpublish
  • PUT /api/admin/v1/stores/{storeId}/products/{id}/sold-out

10.3 总部推送Push

  • POST /api/admin/v1/master-products/{id}/push(指定门店)
  • GET /api/admin/v1/master-products/{id}/push-tasks
  • POST /api/admin/v1/push-tasks/{taskId}/retry

10.4 类目

  • GET /api/admin/v1/categories
  • POST /api/admin/v1/categories
  • PUT /api/admin/v1/categories/{id}
  • DELETE /api/admin/v1/categories/{id}
  • PUT /api/admin/v1/categories/{id}/enable
  • PUT /api/admin/v1/categories/{id}/disable
  • PUT /api/admin/v1/categories/sort(批量排序)
  • PUT /api/admin/v1/categories/{id}/schedule(类目时段)
  • PUT /api/admin/v1/categories/{id}/scenes(类目场景)

10.5 规格与 SKU

  • GET /api/admin/v1/products/{id}/spec-groups
  • PUT /api/admin/v1/products/{id}/spec-groups
  • GET /api/admin/v1/products/{id}/skus
  • POST /api/admin/v1/products/{id}/skus
  • PUT /api/admin/v1/skus/{id}
  • PUT /api/admin/v1/skus/{id}/enable
  • PUT /api/admin/v1/skus/{id}/disable
  • PUT /api/admin/v1/skus/{id}/price
  • PUT /api/admin/v1/skus/{id}/stock
  • PUT /api/admin/v1/skus/{id}/pricing-mode
  • PUT /api/admin/v1/skus/{id}/packaging-fee
  • PUT /api/admin/v1/skus/{id}/inventory-policy

10.6 场景/渠道/时段

  • PUT /api/admin/v1/products/{id}/scenes
  • PUT /api/admin/v1/products/{id}/channels
  • PUT /api/admin/v1/products/{id}/time-slots
  • PUT /api/admin/v1/products/{id}/channel-mappings
  • POST /api/admin/v1/products/{id}/channel-sync

10.7 加料/口味(可选)

  • GET /api/admin/v1/products/{id}/addon-groups
  • PUT /api/admin/v1/products/{id}/addon-groups
  • PUT /api/admin/v1/addon-groups/{id}/items
  • PUT /api/admin/v1/addon-groups/{id}/enable
  • PUT /api/admin/v1/addon-groups/{id}/disable

10.8 套餐/组合(可选)

  • GET /api/admin/v1/bundles
  • POST /api/admin/v1/bundles
  • PUT /api/admin/v1/bundles/{id}
  • PUT /api/admin/v1/bundles/{id}/publish
  • PUT /api/admin/v1/bundles/{id}/unpublish
  • PUT /api/admin/v1/bundles/{id}/items
  • PUT /api/admin/v1/bundles/{id}/rulesN 选 M

10.9 后厨生产(可选)

  • PUT /api/admin/v1/products/{id}/production-profile
  • PUT /api/admin/v1/skus/{id}/production-profile

10.10 导入导出与索引

  • POST /api/admin/v1/products/import
  • GET /api/admin/v1/products/import/{taskId}
  • GET /api/admin/v1/products/export
  • POST /api/admin/v1/products/reindex

10.11 审计与日志

  • GET /api/admin/v1/products/{id}/audit-logs
  • GET /api/admin/v1/stores/{storeId}/products/{id}/override-logs
  • GET /api/admin/v1/master-products/{id}/push-logs

10.12 功能开关读取

  • GET /api/admin/v1/products/features

11. MiniApi小程序端接口清单

  • GET /api/mini/v1/categories?scene=Delivery&channel=WeChatMiniProgram
  • GET /api/mini/v1/menus/{storeId}?scene=Delivery&channel=WeChatMiniProgram
  • GET /api/mini/v1/products?storeId=...&scene=Delivery&channel=WeChatMiniProgram
  • GET /api/mini/v1/products/{id}?scene=Delivery&channel=WeChatMiniProgram
  • GET /api/mini/v1/products/hot?storeId=...
  • GET /api/mini/v1/products/recommended?storeId=...
  • POST /api/mini/v1/products/price-estimate
  • POST /api/mini/v1/products/checkout-validate
  • POST /api/mini/v1/products/snapshots(订单服务调用)

12. UserApiC 端用户)接口清单

  • GET /api/user/v1/categories?scene=Delivery&channel=H5
  • GET /api/user/v1/menus/{storeId}?scene=Delivery&channel=H5
  • GET /api/user/v1/products?storeId=...&scene=Delivery&channel=H5
  • GET /api/user/v1/products/{id}?scene=Delivery&channel=H5
  • GET /api/user/v1/products/hot?storeId=...
  • GET /api/user/v1/products/recommended?storeId=...
  • POST /api/user/v1/products/price-estimate
  • POST /api/user/v1/products/checkout-validate

13. 事件与扩展点

采用 Outbox 模式输出领域事件,便于搜索索引、缓存失效、推荐计算与三方同步。

  • MasterProductCreated
  • MasterProductUpdated
  • MasterProductPushed
  • StoreProductPulled
  • StoreProductOverridden
  • ProductPriceChanged
  • ProductAvailabilityChanged
  • ProductSoldOutChanged
  • SkuStockChanged
  • ProductChannelSyncRequested

14. 示例(关键请求)

14.1 商品创建(总部主库)

{
  "name": "黄金鸡排饭",
  "categoryId": "1782328933492367360",
  "unit": "份",
  "coverImageUrl": "https://cdn/xxx.jpg",
  "imageUrls": ["https://cdn/xxx1.jpg", "https://cdn/xxx2.jpg"],
  "pricingMode": "Fixed",
  "basePrice": 19.9,
  "isEnabled": true
}

14.2 门店覆盖(价格 + 场景)

{
  "overridePrice": 21.9,
  "overrideScenes": ["Delivery", "Pickup"],
  "isSoldOut": false,
  "overrideReason": "外卖平台佣金调整"
}

14.3 结算校验Mini/User

{
  "storeId": "1782328933492367000",
  "scene": "Delivery",
  "channel": "WeChatMiniProgram",
  "items": [
    {
      "productId": "1782328933492367360",
      "skuId": "1782328933492367400",
      "quantity": 2,
      "addonItemIds": ["1782328933492367501", "1782328933492367502"]
    }
  ]
}

15. 依赖说明

  • 文件上传:复用 Storage 模块FilesController获取 URL。
  • 库存:优先对接 Inventory 模块,商品侧仅提供视图与校验。
  • 订单:下单时生成商品快照,避免历史价格漂移。
  • 后厨KDS/打印由生产模块承接,商品仅配置绑定信息。
  • 三方同步:由集成服务监听事件并进行异步同步与重试。
  • 权限码:product.readproduct.writeproduct.publishproduct.import 等(待统一权限表配置)。

待确认渠道编码标准、称重计价精度与四舍五入规则、库存每日重置默认时间、Push 是否强制门店确认。