← 返回文档中心

销售管理

销售管理

优先级: P1(业务增长模块)
开发周期: 2 周

目标

管理平台的两端客户——采购方(代理商/OTA)和供应方(酒店/批发商),以及他们之间的合同关系。

核心功能

功能 描述
代理商管理 代理商注册、资质审核、开通/关闭
供应商管理 供应商接入、API 凭证管理、合同信息
渠道管理 多渠道管理(直客、OTA渠道、批发渠道等)
合同管理 合同录入、条款管理、有效期管理
SLA 管理 服务等级协议(响应时间、可用性要求)
API 凭证管理 API Key 分发、权限配置、调用统计
客户等级 根据交易量/信用评估客户等级,差异化服务

6.5.1 精细化管控

优先级: P0(平台安全与商业策略核心) 开发周期: 3 周

6.5.1.1 供应商×代理商可见性控制

功能描述

控制代理商能够看到哪些供应商和酒店的报价,支持白名单和黑名单两种模式。查价时根据代理商身份自动过滤可见的供应商和酒店,避免代理商看到不应接触的资源。

数据模型

-- 渠道可见性规则表
CREATE TABLE channel_visibility (
    id              BIGSERIAL PRIMARY KEY,
    agent_id        BIGINT NOT NULL REFERENCES agents(id),
    supplier_id     BIGINT NOT NULL REFERENCES suppliers(id),
    hotel_id        BIGINT REFERENCES hotels(id),             -- NULL = 该供应商下所有酒店
    country_code    VARCHAR(3),                               -- NULL = 不限国家
    visibility_type VARCHAR(16) NOT NULL DEFAULT 'whitelist', -- whitelist/blacklist
    priority        SMALLINT DEFAULT 0,                      -- 规则优先级,数值越大优先级越高
    effective_date  DATE DEFAULT CURRENT_DATE,
    expire_date     DATE,                                    -- NULL = 永久有效
    created_by      VARCHAR(64) NOT NULL,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_visibility_agent ON channel_visibility (agent_id, visibility_type, effective_date, expire_date);
CREATE INDEX idx_visibility_supplier ON channel_visibility (supplier_id, visibility_type);

API 接口

PUT    /api/admin/visibility/rules             # 批量设置可见性规则(全量覆盖)
GET    /api/admin/visibility/rules/:agent_id   # 查询代理商的可见性规则
DELETE /api/admin/visibility/rules/:id         # 删除单条规则
GET    /api/internal/visibility/:agent_id      # 内部接口:查价时获取代理商可见供应商列表

业务逻辑

  1. 查价时,先加载代理商的所有可见性规则(有效期内),按优先级排序
  2. 白名单模式:只有出现在白名单中的供应商/酒店才可见
  3. 黑名单模式:出现在黑名单中的供应商/酒店不可见
  4. 同时存在白名单和黑名单时,白名单优先
  5. 规则支持设置生效日期和过期日期,过期自动失效
  6. 规则变更后更新 Redis 缓存(TTL 5min),减少数据库查询
6.5.1.2 熔断机制

功能描述

对代理商和供应商实施熔断保护。当代理商出现异常行为(异常流量暴增、试单失败率突增、欠费、投诉)或供应商出现服务异常(API 故障率超阈值、响应超时、数据异常)时,自动触发熔断,暂停其服务访问权限。支持半开、全开、关闭三种状态,支持自动恢复和手动恢复。

数据模型

-- 熔断记录表
CREATE TABLE circuit_breaker (
    id              BIGSERIAL PRIMARY KEY,
    party_type      VARCHAR(16) NOT NULL,       -- agent/supplier
    party_id        BIGINT NOT NULL,            -- agents.id 或 suppliers.id
    reason          VARCHAR(128) NOT NULL,      -- 触发原因
    status          VARCHAR(16) NOT NULL DEFAULT 'open',  -- open(熔断中)/ half_open(半开)/ closed(正常)
    triggered_at    TIMESTAMPTZ NOT NULL,       -- 熔断触发时间
    recovered_at    TIMESTAMPTZ,               -- 恢复时间
    config          JSONB NOT NULL DEFAULT '{}', -- 熔断配置(阈值、恢复策略等)
    operated_by     VARCHAR(64) NOT NULL,       -- 操作人(system/manual)
    notes           TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_cb_party ON circuit_breaker (party_type, party_id, status);
CREATE INDEX idx_cb_status ON circuit_breaker (status, triggered_at);

config JSON 字段说明

{
  "agent": {
    "traffic_spike_threshold": 5.0,       // 流量暴增倍数阈值
    "trial_failure_rate_threshold": 0.8,  // 试单失败率阈值
    "auto_recovery_minutes": 30,          // 自动恢复等待时间(分钟)
    "half_open_max_requests": 10          // 半开状态最大放行请求数
  },
  "supplier": {
    "error_rate_threshold": 0.3,          // API 故障率阈值
    "timeout_ms": 10000,                  // 响应超时阈值
    "data_anomaly_rate": 0.1,             // 数据异常率阈值
    "auto_recovery_minutes": 15           // 自动恢复等待时间(分钟)
  }
}

API 接口

POST   /api/admin/circuit-breaker/{party_type}/{party_id}/trigger    # 手动触发熔断
POST   /api/admin/circuit-breaker/{party_type}/{party_id}/recover    # 手动恢复
PUT    /api/admin/circuit-breaker/{party_type}/{party_id}/config     # 更新熔断配置
GET    /api/admin/circuit-breaker/{party_type}/{party_id}/status     # 查询熔断状态
GET    /api/admin/circuit-breaker/history                           # 熔断历史记录
GET    /api/internal/circuit-breaker/{party_type}/{party_id}        # 内部:检查是否熔断

业务逻辑

  1. 代理商熔断条件
  2. 异常流量暴增:1 小时内请求数超过过去 24 小时平均值的 N 倍
  3. 试单失败率:近 1 小时试单(下单后短时间内取消)比例超过阈值
  4. 欠费:信用额度使用率达到 100%
  5. 投诉:短时间内收到多起投诉(人工触发)
  6. 供应商熔断条件
  7. API 故障率:近 10 分钟内错误率超过阈值(如 30%)
  8. 响应超时:连续 N 次请求超时
  9. 数据异常:返回数据格式错误、价格异常等比例超阈值
  10. 熔断状态机:closed(正常)→ open(熔断)→ half_open(半开探测)→ closed/recovered
  11. 半开探测:熔断一段时间后自动进入半开状态,放行少量请求验证是否恢复
  12. 恢复策略:自动恢复(定时器触发半开探测)+ 手动恢复(管理员手动操作)
  13. 熔断状态缓存到 Redis(cb:{party_type}:{party_id}),TTL 60s
6.5.1.3 动态准入

功能描述

代理商新注册时进入试用期,有请求量和试单数上限,达标后自动升级为正式代理商。供应商接入后需经过上架审核流程(技术验证 + 商务审核),通过后才正式上架。

数据模型

-- agents 表增加字段
ALTER TABLE agents ADD COLUMN onboarding_status VARCHAR(20) DEFAULT 'trial';  -- trial/active/rejected
ALTER TABLE agents ADD COLUMN trial_start_date TIMESTAMPTZ;
ALTER TABLE agents ADD COLUMN trial_max_requests INT DEFAULT 1000;           -- 试用期内最大请求数
ALTER TABLE agents ADD COLUMN trial_max_test_orders INT DEFAULT 50;         -- 试用期内最大试单数
ALTER TABLE agents ADD COLUMN trial_requests_used INT DEFAULT 0;             -- 已使用请求数
ALTER TABLE agents ADD COLUMN trial_test_orders_used INT DEFAULT 0;         -- 已使用试单数
ALTER TABLE agents ADD COLUMN trial_upgrade_criteria JSONB DEFAULT '{}';     -- 升级标准配置
ALTER TABLE agents ADD COLUMN upgraded_at TIMESTAMPTZ;
ALTER TABLE agents ADD COLUMN rejected_reason TEXT;

-- suppliers 表增加字段
ALTER TABLE suppliers ADD COLUMN onboarding_status VARCHAR(20) DEFAULT 'pending';  -- pending/tech_verify/commercial_review/active/rejected
ALTER TABLE suppliers ADD COLUMN onboarding_applied_at TIMESTAMPTZ DEFAULT NOW();
ALTER TABLE suppliers ADD COLUMN tech_verified_at TIMESTAMPTZ;
ALTER TABLE suppliers ADD COLUMN tech_verified_by VARCHAR(64);
ALTER TABLE suppliers ADD COLUMN tech_verify_result JSONB;                        -- 技术验证结果(连通性、响应时间等)
ALTER TABLE suppliers ADD COLUMN commercial_reviewed_at TIMESTAMPTZ;
ALTER TABLE suppliers ADD COLUMN commercial_reviewed_by VARCHAR(64);
ALTER TABLE suppliers ADD COLUMN rejected_reason TEXT;

-- 准入审核记录表
CREATE TABLE onboarding_reviews (
    id              BIGSERIAL PRIMARY KEY,
    party_type      VARCHAR(16) NOT NULL,        -- agent/supplier
    party_id        BIGINT NOT NULL,
    review_type     VARCHAR(32) NOT NULL,         -- tech_verify/commercial_review/trial_upgrade
    reviewer        VARCHAR(64) NOT NULL,
    result          VARCHAR(16) NOT NULL,         -- approved/rejected/pending
    comments        TEXT,
    metadata        JSONB DEFAULT '{}',           -- 审核元数据
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

API 接口

# 代理商试用管理
GET    /api/admin/agents/trials                           # 试用代理商列表
POST   /api/admin/agents/:id/upgrade                      # 手动升级代理商
POST   /api/admin/agents/:id/reject                       # 驳回代理商
PUT    /api/admin/agents/:id/trial-config                 # 修改试用期配置

# 供应商上架审核
GET    /api/admin/suppliers/onboarding                    # 待审核供应商列表
POST   /api/admin/suppliers/:id/tech-verify               # 提交技术验证结果
PUT    /api/admin/suppliers/:id/tech-verify               # 更新技术验证结果
POST   /api/admin/suppliers/:id/commercial-review         # 提交商务审核结果
POST   /api/admin/suppliers/:id/approve                   # 审核通过,上架
POST   /api/admin/suppliers/:id/reject                    # 驳回上架

# 准入记录
GET    /api/admin/onboarding/reviews                      # 审核记录列表

业务逻辑

  1. 代理商试用期流程
  2. 新注册代理商默认 onboarding_status = trial,开始试用
  3. 试用期内每次请求递增 trial_requests_used,每次试单递增 trial_test_orders_used
  4. 当请求量或试单数达到上限时,自动暂停服务并通知审核
  5. 管理员审核通过后 onboarding_status 升级为 active
  6. 也支持手动调整试用期上限和自动升级标准
  7. 供应商上架审核流程
  8. 供应商接入后 onboarding_status = pending
  9. 运维/技术团队进行技术验证(API 连通性、数据格式、响应时间等),结果记录到 tech_verify_result
  10. 技术验证通过后 onboarding_status 变为 commercial_review
  11. 商务团队审核合同、价格等,通过后 onboarding_status 变为 active,正式上架
  12. 任何环节可驳回,记录驳回原因
  13. 试用和审核状态变更时发送通知(邮件/站内信)
6.5.1.4 信用额度实时管控

功能描述

对代理商的信用额度进行实时监控和管控。查价时检查额度是否正常,下单时实时扣减额度。额度用尽后自动降级为只读模式(只能查价不能下单)。额度使用达到 80%/90%/100% 时分级告警。

数据模型

-- 信用额度变更记录表
CREATE TABLE credit_ledger (
    id              BIGSERIAL PRIMARY KEY,
    agent_id        BIGINT NOT NULL REFERENCES agents(id),
    amount          DECIMAL(12, 2) NOT NULL,     -- 正数=充值/释放,负数=扣减/冻结
    balance_after   DECIMAL(12, 2) NOT NULL,     -- 变更后余额
    transaction_type VARCHAR(32) NOT NULL,       -- recharge/freeze/unfreeze/deduct/refund/adjust
    reference_id    BIGINT,                       -- 关联单据(订单号/充值单号等)
    reference_type  VARCHAR(32),                  -- order/recharge/adjustment
    description     TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_credit_ledger_agent ON credit_ledger (agent_id, created_at DESC);

-- 额度预警记录表
CREATE TABLE credit_alerts (
    id              BIGSERIAL PRIMARY KEY,
    agent_id        BIGINT NOT NULL REFERENCES agents(id),
    alert_level     VARCHAR(8) NOT NULL,          -- warning(80%)/critical(90%)/exhausted(100%)
    usage_rate      DECIMAL(5, 2) NOT NULL,       -- 使用率百分比
    credit_limit    DECIMAL(12, 2) NOT NULL,
    credit_used     DECIMAL(12, 2) NOT NULL,
    is_resolved     BOOLEAN DEFAULT FALSE,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_credit_alerts_agent ON credit_alerts (agent_id, is_resolved);

API 接口

GET    /api/internal/credit/:agent_id/balance        # 内部:实时查询额度余额
POST   /api/internal/credit/:agent_id/freeze         # 内部:下单时冻结额度
POST   /api/internal/credit/:agent_id/unfreeze       # 内部:取消订单时释放额度
POST   /api/internal/credit/:agent_id/deduct         # 内部:确认订单时扣减额度
GET    /api/admin/credit/:agent_id/ledger            # 管理后台:额度变更流水
POST   /api/admin/credit/:agent_id/recharge          # 管理后台:充值/调整额度
GET    /api/admin/credit/alerts                      # 管理后台:额度预警列表

业务逻辑

  1. 查价检查:查价请求前检查代理商额度状态,若已降级为只读则正常返回查价结果(只读模式不影响查价)
  2. 下单冻结:下单时按预估金额冻结额度(credit_used 增加),实际扣款在订单确认后执行
  3. 取消释放:订单取消或超时自动释放冻结额度
  4. 额度告警
  5. 80%:发送邮件提醒代理商和销售
  6. 90%:发送紧急邮件 + 站内通知
  7. 100%:自动降级为只读模式,停止接受新订单,通知代理商充值
  8. 只读模式agents.status 标记为 credit_limited,API 网关拦截下单请求,返回 403 + 提示信息
  9. 额度数据缓存在 Redis(credit:{agent_id}),保证高并发下的实时性
6.5.1.5 渠道隔离

功能描述

同一代理商可创建多个渠道(直客/OTA 渠道/批发渠道等),每个渠道拥有独立的定价规则、可见供应商、请求配额和结算方式,实现业务完全隔离。

数据模型

-- 渠道扩展表(在原 channels 表基础上增加字段)
ALTER TABLE channels ADD COLUMN agent_id BIGINT REFERENCES agents(id);          -- 所属代理商
ALTER TABLE channels ADD COLUMN pricing_strategy_id BIGINT;                     -- 关联定价策略
ALTER TABLE channels ADD COLUMN rate_limit INT DEFAULT 1000;                    -- 每分钟请求配额
ALTER TABLE channels ADD COLUMN daily_limit INT DEFAULT 50000;                  -- 每日请求配额
ALTER TABLE channels ADD COLUMN independent_settlement BOOLEAN DEFAULT FALSE;   -- 独立结算
ALTER TABLE channels ADD COLUMN settlement_account VARCHAR(64);                 -- 结算账号
ALTER TABLE channels ADD COLUMN allowed_suppliers JSONB DEFAULT '[]';           -- 可见供应商ID列表
ALTER TABLE channels ADD COLUMN config JSONB DEFAULT '{}';                      -- 渠道自定义配置
ALTER TABLE channels ADD COLUMN UNIQUE(agent_id, channel_name);                 -- 同一代理商下渠道名唯一

API 接口

GET    /api/v1/agents/:code/channels                  # 代理商的渠道列表
POST   /api/v1/agents/:code/channels                  # 创建渠道
GET    /api/v1/channels/:id                           # 渠道详情
PUT    /api/v1/channels/:id                           # 更新渠道配置
PUT    /api/v1/channels/:id/status                    # 启用/禁用渠道
DELETE /api/v1/channels/:id                           # 删除渠道
GET    /api/v1/channels/:id/statistics                # 渠道统计信息

业务逻辑

  1. 代理商创建多个渠道,每个渠道绑定不同的业务场景
  2. 每个渠道独立配置:
  3. 定价规则:关联不同 pricing_strategy_id,实现不同渠道不同加价
  4. 可见供应商:通过 allowed_suppliers 限制该渠道可查询的供应商
  5. 请求配额rate_limit(每分钟)和 daily_limit(每日),超限返回 429
  6. 结算方式independent_settlement = true 时该渠道独立结算
  7. API 请求携带 X-Channel-Id 头标识当前渠道
  8. 查价引擎根据渠道 ID 过滤供应商和定价规则
  9. 渠道级别的统计独立计算(订单量、GMV、利润等)

数据模型

-- 代理商表
CREATE TABLE agents (
    id              BIGSERIAL PRIMARY KEY,
    agent_code      VARCHAR(32) NOT NULL UNIQUE,     -- AGT-XXXXX
    company_name    VARCHAR(255) NOT NULL,
    contact_name    VARCHAR(64),
    contact_email   VARCHAR(64) NOT NULL UNIQUE,
    contact_phone   VARCHAR(32),
    country_code    VARCHAR(3) DEFAULT 'CN',
    city            VARCHAR(64),
    address         TEXT,
    business_license VARCHAR(128),                   # 营业执照号
    credit_limit    DECIMAL(12, 2) DEFAULT 0,        # 信用额度
    credit_used     DECIMAL(12, 2) DEFAULT 0,        # 已用额度
    level           VARCHAR(16) DEFAULT 'standard',  -- standard/silver/gold/platinum
    status          VARCHAR(20) DEFAULT 'pending',   -- pending/active/suspended/closed
    api_key_hash    VARCHAR(128),                    # API Key 哈希
    api_secret_hash VARCHAR(128),
    webhook_url     VARCHAR(512),
    contract_id     BIGINT,                          -- 关联合同
    notes           TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

-- 供应商表
CREATE TABLE suppliers (
    id              BIGSERIAL PRIMARY KEY,
    supplier_code   VARCHAR(32) NOT NULL UNIQUE,     -- SUP-XXXXX
    company_name    VARCHAR(255) NOT NULL,
    supplier_type   VARCHAR(32) NOT NULL,            -- wholesaler/chain_hotel/independent_hotel
    contact_name    VARCHAR(64),
    contact_email   VARCHAR(64) NOT NULL,
    contact_phone   VARCHAR(32),
    country_code    VARCHAR(3),
    api_endpoint    VARCHAR(512),                    # 供应商API地址
    api_auth_type   VARCHAR(32),                     -- api_key/oauth2/basic
    api_credentials JSONB,                           # 加密存储
    webhook_url     VARCHAR(512),                    # 回调地址
    status          VARCHAR(20) DEFAULT 'pending',   -- pending/active/suspended/closed
    priority        SMALLINT DEFAULT 0,              # 查价优先级
    avg_response_ms INT,                             # 平均响应时间
    availability    DECIMAL(5, 2),                   # 可用率百分比
    contract_id     BIGINT,
    notes           TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

-- 渠道表
CREATE TABLE channels (
    id              SERIAL PRIMARY KEY,
    channel_code    VARCHAR(32) NOT NULL UNIQUE,     -- CHN-XXXXX
    channel_name    VARCHAR(128) NOT NULL,
    channel_type    VARCHAR(32) NOT NULL,            -- direct/ota/wholesale/corporate
    description     TEXT,
    commission_rate DECIMAL(5, 2) DEFAULT 0,        # 默认佣金率 %
    markup_type     VARCHAR(16) DEFAULT 'percentage',# percentage/fixed
    markup_value    DECIMAL(8, 2) DEFAULT 0,        # 加价值
    status          VARCHAR(20) DEFAULT 'active',
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

-- 合同表
CREATE TABLE contracts (
    id              BIGSERIAL PRIMARY KEY,
    contract_no     VARCHAR(32) NOT NULL UNIQUE,
    contract_type   VARCHAR(32) NOT NULL,            -- supplier/agent/channel
    party_code      VARCHAR(32) NOT NULL,            -- 对方编码(供应商/代理商)
    party_name      VARCHAR(255) NOT NULL,
    start_date      DATE NOT NULL,
    end_date        DATE,
    status          VARCHAR(20) DEFAULT 'draft',     -- draft/active/expired/terminated

    -- 商务条款
    payment_terms   VARCHAR(64) DEFAULT 'prepaid',   -- prepaid/postpaid/credit
    credit_days     SMALLINT DEFAULT 0,              # 账期天数
    commission_rate DECIMAL(5, 2) DEFAULT 0,
    cancellation_policy JSONB,
    special_terms   JSONB,

    -- 合同文件
    file_url        VARCHAR(512),

    -- SLA
    sla_response_time_ms INT DEFAULT 3000,
    sla_availability   DECIMAL(5, 2) DEFAULT 99.5,

    notes           TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

接口设计

# 代理商管理 API (内部 + 管理后台)
GET    /api/v1/agents                      # 代理商列表
POST   /api/v1/agents                      # 创建代理商
GET    /api/v1/agents/:code                # 代理商详情
PUT    /api/v1/agents/:code                # 更新代理商
PUT    /api/v1/agents/:code/status         # 变更状态
POST   /api/v1/agents/:code/api-keys       # 重新生成API Key
GET    /api/v1/agents/:code/statistics     # 代理商统计(订单量、金额等)

# 供应商管理 API
GET    /api/v1/suppliers                   # 供应商列表
POST   /api/v1/suppliers                   # 创建供应商
GET    /api/v1/suppliers/:code             # 供应商详情
PUT    /api/v1/suppliers/:code             # 更新供应商
PUT    /api/v1/suppliers/:code/status      # 变更状态
POST   /api/v1/suppliers/:code/test-connection  # 测试供应商API连通性
GET    /api/v1/suppliers/:code/statistics  # 供应商统计

# 合同管理 API
GET    /api/v1/contracts                   # 合同列表
POST   /api/v1/contracts                   # 创建合同
PUT    /api/v1/contracts/:id               # 更新合同
PUT    /api/v1/contracts/:id/status        # 变更状态
GET    /api/v1/contracts/:id               # 合同详情

与其他模块的关系

关联模块 关系
API 网关 代理商 API Key 鉴权
风控体系 信用额度管理
价格管理 按代理商/渠道配置加价策略
查价引擎 按供应商优先级排序查询
结算管理 获取合同结算条款
订单管理 记录代理商/供应商信息
管理后台 完整的管理界面

技术选型建议