B2B、B2C、C2C、O2O 平台架构全面分析

拆解 B2B、B2C、C2C、O2O 等商业模式的本质,从供给方、需求方、交付方式三个维度深入分析平台架构。

1. 商业模式的本质不是字母,是"谁卖给谁,在哪交付"

把这些字母拆成两个维度来看:

维度选项含义
供给方B(企业) / C(个人)谁提供商品或服务
需求方B(企业) / C(个人)谁购买商品或服务
交付方式Online / Offline线上交付还是线下履约

所以 6 种排列组合:

模式供给→需求典型例子交付
B2B企业→企业1688、找钢网线下物流
B2C企业→个人京东自营、天猫线下物流
C2C个人→个人闲鱼、转转线下快递
C2B个人→企业猪八戒、Upwork线上/线下
O2O线上交易→线下履约美团、滴滴线下
B2B2C平台→商家→消费者京东POP、拼多多线下物流

O2O 其实不是第五种,而是"交付方式=线下"的修饰词。 任何 B2C/C2C/B2B 只要线下履约,都可以叫 O2O。

2. 现实中没有纯种模式,都是组合体

京东的演化就是最好的例子:

京东 1.0(纯B2C)
  京东自己采购 → 卖给消费者
  账号:京东采购员(内部) + 消费者(sys_user)

京东 2.0(B2C + B2B2C)
  新增:第三方商家入驻(POP),商家自己定价发货
  账号新增:商家后台账号(sys_employee + provider_id)

京东 3.0(B2C + B2B2C + O2O)
  新增:京东到家,附近超市/药店 → 即时配送
  账号新增:线下门店账号(也是 sys_employee + provider_id)
                + 骑手端账号(配送员)

京东 4.0(B2C + B2B2C + O2O + C2C)
  新增:拍拍二手/闲置交易
  账号新增:个人卖家(入驻为 freelancer type provider)

最后京东一张 sys_user 就能承载所有消费者,一张 sys_provider + sys_employee 承载所有供给方——因为底层结构是一样的。

3. 所有组合的账号体系统一模型

无论你怎么组合,本质上就是 三类人 + 一张关系表

                    平台方 (Platform)
                   sys_employee (provider_id=NULL)
                         │
                         │ 管理
                         ▼
              ┌──────────────────────┐
              │   供给方 (Provider)    │
              │   sys_provider       │
              │                      │
              │  type枚举决定身份:    │
              │  · self(自营)         │
              │  · merchant(商家)     │
              │  · freelancer(个人)   │
              │  · store(线下门店)    │
              │                      │
              │  背后是:              │
              │  sys_employee        │
              │  (商家后台账号)       │
              └──────────┬───────────┘
                         │
                         │ 提供服务/商品
                         ▼
              ┌──────────────────────┐
              │   需求方 (Consumer)    │
              │   sys_user           │
              │                      │
              │  可以是:              │
              │  · 个人消费者(C)      │
              │  · 企业采购员(B)      │
              │  · 发布约拍的用户     │
              └──────────────────────┘

关键洞察:B和C在表结构上不需要两张不同的表。 因为一个账号的行为取决于它在某笔交易中扮演的角色,而不是它天生是什么类型。

4. 像匠的完整组合对应

像匠的业务模式标签供给方 provider.type需求方
自营门店拍照B2C + O2Oselfsys_user
加盟店拍照B2B2C + O2Ofranchisesys_user
共享图像工具B2B + B2C工具不需要供给方概念sys_employee + sys_user
自由摄影师接单C2C + O2Ofreelancersys_user
用户约拍C2B(用户找服务)反向:sys_user发布需求freelancer/self/franchise 竞标
企业团购拍照B2Bself/franchisesys_user(企业采购员身份)

所以像匠一张 sys_providertype 字段全装下了,和京东的架构本质上一样。

5. 总结:别被字母吓住

所有平台模式的本质 =

    三个角色:  平台方  +  供给方  +  需求方
    三张表:    sys_employee  +  sys_provider  +  sys_user

    type字段决定了供给方是B(企业)还是C(个人)
    业务场景决定了需求方是B还是C
    O2O只是告诉你:交付在线下,需要加地址/预约/核销

京东从 B2C 变成大杂烩组合,底层账号表并没有从 2 张变成 6 张。它只是 sys_provider.type 多了几个枚举值,sys_employee 的权限体系更丰富了。真正变化的不是账号结构,是业务流程——配送、结算、售后这些链路。

这是一个典型的平台演进路径,从单品牌连锁 → 多边服务市场。让我梳理清楚。

现状分析:你的四种供给方

        像匠平台
           │
   ┌───────┼───────┬──────────┐
   ▼       ▼       ▼          ▼
 自营     加盟    自由职业    共享工具
(自己人) (外部)  (个人接单)  (所有人用)

这四种供给方对系统的需求有 80% 相同、20% 不同

统一供给方模型

核心结论:一张 sys_provider 表全部装下,用 type + source 区分。

class Provider(Base, TimestampMixin, SoftDeleteMixin):
    """服务提供方(自营/加盟/自由职业者 统一表)"""
    __tablename__ = "sys_provider"

    id: int
    name: str                          # 名称(自营=门店名,加盟=企业名,个人=昵称)
    code: str                          # 唯一编码
    type: str                          # self | franchise | freelancer
    source: str                        # invite(邀请入驻) | apply(自主申请) | platform(平台创建)

    # --- 企业信息(自营/加盟必填,个人可空) ---
    business_license: str | None
    legal_person: str | None
    registered_capital: int | None

    # --- 个人认证(自由职业者必填,企业可空) ---
    real_name: str | None              # 真实姓名
    id_card: str | None                # 身份证
    certification_type: str | None     # photographer/makeup/retoucher

    # --- 共用字段 ---
    logo: str | None                   # 头像/logo
    contact_name: str
    contact_phone: str
    status: int                        # 0待审核 1启用 2禁用 3驳回
    settle_ratio: float                # 结算比例
    max_employees: int                 # 员工上限(个人=1)

四种类型的差异只需用 type 字段区分,后端返回时可附带不同表单验证规则、不同审核流程,无需多张表。

完整账号体系架构

┌────────────────────────────────────────────────────────────────────┐
│                    像匠平台账号体系                                   │
├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│  【后台管理端】入口:admin.xiangjiang.com                            │
│  ┌──────────────────────────────────────────────────────────────┐ │
│  │  表:sys_employee + sys_provider_id                          │ │
│  │                                                              │ │
│  │  provider_id=NULL  →  像匠平台运营                             │ │
│  │    · 平台超管、运营、财务、客服                                  │ │
│  │    · 权限:审核入驻、管理所有供给方、配置抽佣、仲裁纠纷           │ │
│  │                                                              │ │
│  │  provider_id=1, type=self →  自营店(如"像匠·朝阳大悦城店")   │ │
│  │  provider_id=2, type=franchise →  加盟店(如"小陈摄影工作室")   │ │
│  │  provider_id=3, type=freelancer →  自由摄影师张三               │ │
│  │                                                              │ │
│  │  每个供给方的后台功能 80% 一致:                                 │ │
│  │  ✅ 员工管理(个人型最多1人,企业型可多人)                       │ │
│  │  ✅ 服务/产品管理(上架/下架/改价)                              │ │
│  │  ✅ 订单管理(接单/履约/退款)                                  │ │
│  │  ✅ 收入结算(查看流水/提现)                                   │ │
│  │  ✅ 共享工具(图像处理工具全部可用)                             │ │
│  │  ✅ 约拍广场(查看需求/报价接单)← 新功能                         │ │
│  └──────────────────────────────────────────────────────────────┘ │
│                                                                    │
│  【C端用户端】入口:xiangjiang.com / 小程序 / App                    │
│  ┌──────────────────────────────────────────────────────────────┐ │
│  │  表:sys_user(已有)                                         │ │
│  │                                                              │ │
│  │  ✅ 浏览服务商/作品 → 下单 → 支付 → 评价                        │ │
│  │  ✅ 发布约拍需求 → 查看报价 → 选人成交  ← 新功能                 │ │
│  │  ✅ 查看订单/约拍记录                                          │ │
│  │  ✅ 个人中心(收藏/足迹/优惠券)                                 │ │
│  │  ✅ 成为供给方(用户可申请入驻为自由职业者)                     │ │
│  └──────────────────────────────────────────────────────────────┘ │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

约拍功能需要新增的表

class BookingRequest(Base, TimestampMixin):
    """用户发布的约拍需求"""
    __tablename__ = "sys_booking_request"

    id: int
    user_id: int                       # 发布需求的人
    title: str                         # 如"6月婚礼跟拍"
    category: str                      # wedding/portrait/family/commercial
    description: str                   # 详细需求描述
    budget_min: int | None             # 预算下限(分)
    budget_max: int | None             # 预算上限(分)
    city: str                          # 服务城市
    district: str | None               # 区域
    shoot_date: str                    # 拍摄日期 YYYY-MM-DD
    shoot_time_start: str | None       # 开始时间 HH:mm
    shoot_duration: int | None         # 预计时长(分钟)

    # 状态流转
    status: int                        # 0待审核 1待报价 2已有报价 3已选服务商
                                       # 4进行中 5已完成 6已取消 7已过期
    expire_at: datetime                # 需求过期时间
    selected_provider_id: int | None   # 选定的服务商
    selected_bid_id: int | None        # 选定的报价

    # 辅助信息
    tags: str | None                   # 标签(json数组)
    image_urls: str | None             # 参考图
    view_count: int                    # 浏览次数
    bid_count: int                     # 报价数
class BookingBid(Base, TimestampMixin):
    """服务商对约拍需求的报价"""
    __tablename__ = "sys_booking_bid"

    id: int
    request_id: int                    # 约拍需求ID
    provider_id: int                   # 报价的服务商
    employee_id: int | None            # 报价的具体员工(企业型才有)

    price: int                         # 报价金额(分)
    message: str | None                # 报价附言/方案说明
    available_time: str | None         # 可服务时间段

    status: int                        # 0待查看 1已查看 2已接受 3已拒绝 4已撤回

关键设计决策:一个人能不能"既是提供方又是消费者"?

可以,但分开账号。 张三用手机号注册了 sys_user 是消费者,浏览并下了个约拍单。后来他发现可以入驻当自由摄影师,申请入驻后平台创建:

  • sys_provider 记录(自由摄影师张三)
  • sys_employee 记录(provider_id=张三, 他就是他自己店唯一员工)
  • 前端登录页提供角色切换:用户端(消费者) / 管理端(供给方后台)

sys_user.idsys_employee.id两张独立的表,这是正确的设计——消费者身份和服务商身份是不同的数据域,权限体系、展示信息、操作路径都不一样。

总结:四层对比

层级谁用典型用户
平台运营层sys_employee (provider_id=NULL)后台管理像匠员工
供给方管理层sys_employee (provider_id=有值)后台管理自营/加盟/个人摄影师的后台账号
供给方主体sys_provider元数据每个店/个人的主体信息
C端消费者sys_user用户端来拍照/发约拍的普通用户

你的核心设计其实只需要 sys_provider 一张表加 type 字段,sys_employeeprovider_id。约拍需求另开两张表 sys_booking_request + sys_booking_bid。需要我开始写代码吗?

sys_tenant和sys_provider区别

因为 sys_tenantsys_provider 不是同一个概念的两种叫法,而是两种完全不同的架构模式

核心区别:隔离 vs 共享

sys_tenant  →  竖井隔离模型
sys_provider → 平台共享模型

用一句话说:

Tenant 解决的是"你看不见我的数据",Provider 解决的是"我能在平台上卖东西"。

场景对比

sys_tenant 的世界:
┌─────────┐  ┌─────────┐  ┌─────────┐
│ 租户A    │  │ 租户B    │  │ 租户C    │
│ 金蝶云   │  │ 用友云   │  │ SAP云   │
│         │  │         │  │         │
│ ·员工    │  │ ·员工    │  │ ·员工    │
│ ·报表    │  │ ·报表    │  │ ·报表    │
│ ·审批流  │  │ ·审批流  │  │ ·审批流  │
│         │  │         │  │         │
│ 完全不   │  │ 完全不   │  │ 完全不   │
│ 知道A/B  │  │ 知道B    │  │ 知道A/B  │
│ 的存在   │  │ 的存在   │  │ 的存在   │
└─────────┘  └─────────┘  └─────────┘
     ↑           ↑           ↑
     └───────────┴───────────┘
              数据库
            各自只查自己的 tenant_id

sys_provider 的世界:
┌─────────────────────────────────────────┐
│              平台                        │
│                                         │
│  ┌──────┐  ┌──────┐  ┌──────┐          │
│  │摄影A  │  │化妆B  │  │修图C  │          │
│  │ ★4.8 │  │ ★4.7 │  │ ★4.9 │          │
│  │ ¥299 │  │ ¥199 │  │ ¥99  │          │
│  └──┬───┘  └──┬───┘  └──┬───┘          │
│     │         │         │               │
│     └─────────┼─────────┘               │
│               ▼                         │
│         消费者搜索、比价、下单             │
│                                         │
│  供给方知道彼此存在,且在竞争!            │
└─────────────────────────────────────────┘

为什么不能用 Provider 替代 Tenant

维度sys_tenantsys_provider
核心诉求数据隔离,安全合规服务曝光,获取订单
是否可见租户不知其他租户存在供给方公开竞争
是否有 C 端没有,只对内必须有,对外展示
计费方式按功能/席位/存储收费按成交抽佣/入驻费
个性化字段/流程/界面可定制标准服务项,差异化靠内容和口碑
关系垂直独立,井水不犯河水水平竞争,用户比价选择

典型 Tenant 场景:

  • 飞书/钉钉/企业微信 — 每个企业一个租户,内部管理自己的组织架构
  • 金蝶云 — 每家企业独立账套
  • Jira/Slack/Notion 的 Workspace 概念

典型 Provider 场景:

  • 淘宝/美团/滴滴 — 商家入驻,平台撮合交易
  • 猪八戒/Upwork — 自由职业者竞标项目
  • 像匠 — 门店和个人入驻,服务消费者

像匠到底该用哪个?

如果你的平台具备以下特征,就是 Provider 模式(其实是你现在的情况):

  1. 供给方之间存在竞争关系(用户比价)
  2. 供给方需要对 C 端曝光(评分、作品、价格)
  3. 平台按成交抽佣而非收 SaaS 年费
  4. 供给方的服务内容不同但同属一个品类

如果有一天,你开始给供给方提供 SaaS 工具(独立的进销存、独立的CRM、独立的财务报表),且供给方之间不应看到彼此数据——那时才需要 Tenant 隔离

现实中很多平台是混合的

美团外卖:
├── sys_provider 模式 → 商家互相竞争,用户比价选店
└── sys_tenant 模式  → 每个商家后台独立,看不到隔壁店的订单明细

滴滴出行:
├── sys_provider 模式 → 司机在乘客面前是可选的(派单/抢单)
└── sys_tenant 模式  → 司机A永远看不到司机B的收入明细

像匠的混合:
├── sys_provider 模式 → 供给方面向用户端展示、竞争
├── sys_tenant 模式  → 每个供给方后台管理自己的员工/角色/菜单(就是你现在
│                       用 provider_id 隔离数据的部分)
└── 共享工具         → 图像工具对所有供给方可见可用,没有数据隔离

结论

Provider 不是升级版的 Tenant,它们是两个正交的维度。

Tenant = 解决数据归属(这条记录是谁的?) Provider = 解决交易参与(谁在提供服务?)

你的 sys_provider 模型同时做到了 Provider(前端展示、竞争接单)和 Tenant(后台用 provider_id 做数据隔离),所以看起来"万能",但实际上是把两道题做进了一道。之所以这样做是对的,是因为 O2O 服务市场的供给方天然需要这两重身份。