400电话增强功能方案 v3.0

一、CRM客户通讯录来电识别

1.1 功能说明

400电话来电时,系统自动与CRM客户通讯录比对,显示正确的客户信息:

  • 客户公司名称
  • 联系人姓名
  • 所属部门/职位
  • 历史订单信息
  • 上次联系时间
  • 客户等级/标签
  • 1.2 来电弹屏信息展示

    ┌─────────────────────────────────────────┐
    │  ☎️ 来电弹屏 - 4008-320-160              │
    ├─────────────────────────────────────────┤
    │  📞 来电号码: 138****8888               │
    │  🏢 客户公司: 宁波奥克斯空调有限公司     │
    │  👤 联系人: 张经理 (采购部)             │
    │  ⭐ 客户等级: VIP金牌客户               │
    │  📊 年交易额: ¥580万                    │
    │  📋 历史订单: 12笔                      │
    │  🕐 上次联系: 2024-06-10 (5天前)        │
    │  📝 备注: 正在洽谈PCR-ABS批量订单        │
    ├─────────────────────────────────────────┤
    │  🎯 本次来电意图: 产品咨询 (按1)         │
    │  📌 建议处理: 优先转接销售经理A           │
    │  ⚡ 紧急度: 高 (VIP客户)                │
    ├─────────────────────────────────────────┤
    │  [接听] [转接] [留言] [挂断] [查看详情]  │
    └─────────────────────────────────────────┘

    1.3 通讯录比对逻辑

    # 来电识别与CRM匹配
    async def match_caller_with_crm(caller_number: str) -> dict:
        """
        来电号码与CRM客户通讯录比对
        """
        # 1. 格式化号码(去除区号、空格等)
        formatted_number = format_phone_number(caller_number)
        
        # 2. 精确匹配
        customer = await db.query("""
            SELECT c.*, cp.name as contact_name, cp.department, cp.position
            FROM customers c
            LEFT JOIN customer_contacts cp ON c.id = cp.customer_id
            WHERE cp.phone = ? OR cp.mobile = ? OR c.phone = ?
            LIMIT 1
        """, (formatted_number, formatted_number, formatted_number))
        
        if customer:
            return {
                "matched": True,
                "customer_id": customer["id"],
                "company_name": customer["company_name"],
                "contact_name": customer["contact_name"],
                "department": customer["department"],
                "position": customer["position"],
                "customer_level": customer["level"],  # VIP/普通/潜在客户
                "annual_revenue": customer["annual_revenue"],
                "order_count": customer["order_count"],
                "last_contact": customer["last_contact_date"],
                "tags": customer["tags"],  # 标签: 大客户/长期合作/价格敏感
                "notes": customer["notes"]
            }
        
        # 3. 模糊匹配(号码部分匹配)
        similar_customers = await db.query("""
            SELECT * FROM customers 
            WHERE phone LIKE ? OR mobile LIKE ?
        """, (f"%{formatted_number[-8:]}%", f"%{formatted_number[-8:]}%"))
        
        # 4. 未匹配到 - 标记为新线索
        return {
            "matched": False,
            "caller_number": caller_number,
            "status": "new_lead",
            "suggestion": "创建新客户档案"
        }

    1.4 数据库表扩展

    -- 客户通讯录扩展表
    ALTER TABLE customer_contacts ADD COLUMN IF NOT EXISTS 
        phone_type VARCHAR(20) DEFAULT 'mobile',  -- mobile/landline/wechat
        is_primary BOOLEAN DEFAULT FALSE,          -- 是否主联系人
        call_preference VARCHAR(20) DEFAULT 'any', -- any/morning/afternoon
        last_call_date TIMESTAMP,
        call_count INTEGER DEFAULT 0;
    
    -- 来电识别记录表
    CREATE TABLE IF NOT EXISTS caller_identifications (
        id SERIAL PRIMARY KEY,
        call_record_id INTEGER REFERENCES phone_call_records(id),
        caller_number VARCHAR(32) NOT NULL,
        matched_customer_id VARCHAR(64),
        matched_contact_id INTEGER,
        match_confidence DECIMAL(3,2),  -- 匹配置信度
        company_name VARCHAR(128),
        contact_name VARCHAR(64),
        department VARCHAR(64),
        position VARCHAR(64),
        customer_level VARCHAR(32),
        identified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    ---

    二、通话记录自动推送CRM沟通记录

    2.1 功能说明

    每次400电话通话结束后,自动将通话内容推送到CRM系统的客户沟通记录中:

  • 通话文字记录(语音识别)
  • 通话日期时间
  • 通话时长
  • 通话录音链接
  • 来电意图/分类
  • 跟进事项
  • 客户反馈
  • 2.2 语音识别与文字记录

    # 通话录音转文字
    async def transcribe_call_recording(call_record_id: str) -> dict:
        """
        使用AI语音识别将通话录音转为文字
        """
        # 1. 获取录音文件
        recording = await get_recording_file(call_record_id)
        
        # 2. 调用语音识别API(本地模型或云服务)
        # 方案A: 本地Whisper模型(MacStudio)
        # 方案B: 阿里云语音识别API
        # 方案C: 科大讯飞API
        
        transcription = await speech_to_text(
            audio_file=recording,
            model="whisper-large-v3",  # 或阿里云/讯飞
            language="zh",
            speaker_diarization=True    # 区分说话人
        )
        
        # 3. 提取关键信息
        key_info = extract_call_insights(transcription["text"])
        
        return {
            "call_record_id": call_record_id,
            "full_transcript": transcription["text"],
            "speakers": transcription["speakers"],  # 销售/客户对话分离
            "duration": transcription["duration"],
            "key_points": key_info["key_points"],
            "customer_intent": key_info["intent"],
            "follow_up_items": key_info["follow_ups"],
            "sentiment": key_info["sentiment"]  # 正面/中性/负面
        }
    
    # 关键信息提取
    async def extract_call_insights(text: str) -> dict:
        """
        使用AI提取通话关键信息
        """
        prompt = f"""
        分析以下电话通话记录,提取关键信息:
        
        通话内容:
        {text}
        
        请提取:
        1. 客户意图(询价/投诉/技术支持/合作洽谈/其他)
        2. 关键需求点
        3. 客户情绪(正面/中性/负面)
        4. 需要跟进的事项
        5. 提到的产品型号
        6. 提到的价格/数量
        7. 下次联系建议
        
        输出JSON格式。
        """
        
        # 调用本地模型或API
        result = await model_router.route_request("A10", prompt, "medium")
        return json.loads(result["result"])

    2.3 CRM沟通记录自动创建

    # 通话结束后自动创建CRM沟通记录
    async def create_crm_communication_record(call_data: dict, transcription: dict) -> dict:
        """
        自动创建CRM客户沟通记录
        """
        # 1. 构建沟通记录
        record = {
            "record_id": f"COMM-{datetime.now().strftime('%Y%m%d')}-{uuid.uuid4().hex[:8]}",
            "customer_id": call_data["matched_customer_id"],
            "contact_id": call_data["matched_contact_id"],
            
            # 沟通基本信息
            "communication_type": "phone",  # 电话沟通
            "direction": "inbound",         # 呼入
            "channel": "400电话",            # 渠道
            
            # 时间信息
            "call_time": call_data["call_time"],
            "call_duration": call_data["duration"],
            "call_end_time": call_data["end_time"],
            
            # 通话内容
            "summary": transcription["key_points"]["summary"],
            "full_transcript": transcription["full_transcript"],
            "recording_url": call_data["recording_url"],
            
            # 客户意图
            "customer_intent": transcription["key_points"]["intent"],
            "intent_category": classify_intent(transcription["key_points"]["intent"]),
            
            # 关键信息
            "products_mentioned": transcription["key_points"].get("products", []),
            "price_discussed": transcription["key_points"].get("price", None),
            "quantity_discussed": transcription["key_points"].get("quantity", None),
            
            # 跟进事项
            "follow_up_required": True,
            "follow_up_items": transcription["key_points"]["follow_ups"],
            "follow_up_deadline": calculate_follow_up_deadline(
                transcription["key_points"]["intent"]
            ),
            
            # 情绪分析
            "customer_sentiment": transcription["key_points"]["sentiment"],
            "urgency_level": calculate_urgency(
                call_data["customer_level"],
                transcription["key_points"]["sentiment"]
            ),
            
            # 负责人
            "handled_by": call_data["answered_by"],  # 接听人
            "assigned_to": call_data["assigned_sales"],  # 分配销售
            
            # 系统信息
            "created_at": datetime.now(),
            "source_system": "400_phone_system",
            "call_record_id": call_data["call_record_id"]
        }
        
        # 2. 保存到CRM沟通记录表
        await db.insert("customer_communications", record)
        
        # 3. 更新客户最后联系时间
        await db.execute("""
            UPDATE customers 
            SET last_contact_date = ?, last_contact_type = 'phone'
            WHERE id = ?
        """, (datetime.now(), call_data["matched_customer_id"]))
        
        # 4. 创建待办事项(如需要跟进)
        if record["follow_up_required"]:
            await create_todo_task({
                "title": f"跟进客户:{call_data['company_name']} - {record['follow_up_items'][0]}",
                "customer_id": call_data["matched_customer_id"],
                "deadline": record["follow_up_deadline"],
                "priority": record["urgency_level"],
                "source": "400_phone",
                "related_record_id": record["record_id"]
            })
        
        # 5. 推送企业微信通知
        await send_wechat_notification({
            "type": "call_record_saved",
            "customer_name": call_data["company_name"],
            "call_duration": record["call_duration"],
            "summary": record["summary"],
            "follow_up": record["follow_up_items"],
            "recording_url": record["recording_url"]
        })
        
        return record

    2.4 CRM沟通记录表结构

    -- 客户沟通记录表(扩展)
    CREATE TABLE IF NOT EXISTS customer_communications (
        id SERIAL PRIMARY KEY,
        record_id VARCHAR(64) NOT NULL UNIQUE,
        tenant_id VARCHAR(64) DEFAULT 'T001',
        
        -- 关联信息
        customer_id VARCHAR(64) NOT NULL,
        contact_id INTEGER,
        project_id VARCHAR(64),
        opportunity_id VARCHAR(64),
        
        -- 沟通类型
        communication_type VARCHAR(32) NOT NULL,  -- phone/email/meeting/wechat/visit
        direction VARCHAR(16),  -- inbound/outbound
        channel VARCHAR(32),     -- 400电话/企业微信/邮件/面谈
        
        -- 时间信息
        communication_time TIMESTAMP NOT NULL,
        duration INTEGER,  -- 时长(秒)
        
        -- 内容信息
        summary TEXT,  -- AI摘要
        content TEXT,  -- 完整内容/文字记录
        recording_url VARCHAR(256),  -- 录音链接
        attachment_urls JSONB,  -- 附件
        
        -- 意图分析
        intent_category VARCHAR(32),  -- 询价/投诉/技术支持/合作洽谈
        intent_detail VARCHAR(128),
        
        -- 关键信息
        products_mentioned JSONB,
        price_discussed DECIMAL(12,2),
        quantity_discussed INTEGER,
        
        -- 跟进信息
        follow_up_required BOOLEAN DEFAULT FALSE,
        follow_up_items JSONB,
        follow_up_deadline TIMESTAMP,
        
        -- 情绪分析
        sentiment VARCHAR(16),  -- positive/neutral/negative
        urgency_level VARCHAR(16),  -- high/medium/low
        
        -- 负责人
        handled_by VARCHAR(64),  -- 实际处理人
        assigned_to VARCHAR(64),  -- 分配跟进人
        
        -- 系统字段
        source_system VARCHAR(32),  -- 400_phone_system/crm_manual/wechat
        source_record_id VARCHAR(64),  -- 源系统记录ID
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    
    -- 索引
    CREATE INDEX idx_comm_customer ON customer_communications(customer_id);
    CREATE INDEX idx_comm_time ON customer_communications(communication_time);
    CREATE INDEX idx_comm_type ON customer_communications(communication_type);
    CREATE INDEX idx_comm_intent ON customer_communications(intent_category);

    ---

    三、移动电话转接方案

    3.1 功能说明

    400电话来电可以转接到销售人员的移动电话,确保:

  • 7×24小时有人接听
  • 外出时不错过重要来电
  • 按时间段/按人员智能转接
  • 3.2 转接策略配置

    # 400电话转接策略
    CALL_FORWARDING_CONFIG = {
        "basic_rules": {
            "work_hours": {  # 工作时间
                "weekday": "09:00-18:00",
                "saturday": "09:00-12:00",
                "sunday": "closed"
            },
            "after_hours": "forward_to_mobile",  # 非工作时间转手机
            "holiday": "forward_to_duty"  # 节假日转值班人员
        },
        
        "forwarding_strategies": {
            # 策略1: 顺序转接(先办公室,后手机)
            "sequential": {
                "description": "先响办公室话机,无人接听转手机",
                "steps": [
                    {"timeout": 15, "target": "office_phone"},  # 响15秒
                    {"timeout": 20, "target": "mobile_phone"},  # 转手机响20秒
                    {"timeout": 10, "target": "voicemail"}     # 最后留言
                ]
            },
            
            # 策略2: 同时振铃(办公室+手机同时响)
            "simultaneous": {
                "description": "办公室和手机同时响铃",
                "targets": ["office_phone", "mobile_phone"],
                "timeout": 30,
                "overflow": "voicemail"
            },
            
            # 策略3: 智能转接(根据销售状态)
            "smart": {
                "description": "根据销售状态智能选择",
                "rules": [
                    {"condition": "status == 'in_office'", "target": "office_phone"},
                    {"condition": "status == 'in_field'", "target": "mobile_phone"},
                    {"condition": "status == 'in_meeting'", "target": "colleague"},
                    {"condition": "status == 'off_duty'", "target": "duty_person"}
                ]
            }
        },
        
        # 销售人员移动电话配置
        "sales_mobile_numbers": {
            "sales_manager_a": {
                "name": "销售经理A",
                "office_ext": "8001",
                "mobile": "138****0001",
                "duty_days": ["mon", "tue", "wed", "thu", "fri"],
                "duty_hours": "09:00-22:00",
                "max_daily_calls": 50
            },
            "sales_manager_b": {
                "name": "销售经理B",
                "office_ext": "8002",
                "mobile": "138****0002",
                "duty_days": ["mon", "tue", "wed", "thu", "fri", "sat"],
                "duty_hours": "09:00-20:00",
                "max_daily_calls": 50
            },
            "sales_manager_c": {
                "name": "销售经理C",
                "office_ext": "8003",
                "mobile": "138****0003",
                "duty_days": ["wed", "thu", "fri", "sat", "sun"],
                "duty_hours": "10:00-21:00",
                "max_daily_calls": 50
            },
            "duty_person": {
                "name": "值班人员",
                "mobile": "138****9999",
                "duty_days": ["sun"],  # 周日值班
                "duty_hours": "09:00-18:00"
            }
        }
    }

    3.3 按时间段智能转接

    # 时间段转接策略
    TIME_BASED_ROUTING = {
        "weekday": {
            "09:00-12:00": {
                "primary": "office_phone",      # 上午在办公室
                "backup": "mobile_phone",
                "strategy": "sequential"
            },
            "12:00-13:30": {
                "primary": "mobile_phone",        # 午休时间
                "backup": "voicemail",
                "strategy": "direct"
            },
            "13:30-18:00": {
                "primary": "office_phone",        # 下午在办公室
                "backup": "mobile_phone",
                "strategy": "sequential"
            },
            "18:00-22:00": {
                "primary": "mobile_phone",        # 下班后手机
                "backup": "voicemail",
                "strategy": "direct"
            },
            "22:00-09:00": {
                "primary": "duty_person",         # 夜间值班
                "backup": "voicemail",
                "strategy": "direct"
            }
        },
        
        "weekend": {
            "09:00-18:00": {
                "primary": "mobile_phone",        # 周末手机
                "backup": "duty_person",
                "strategy": "sequential"
            },
            "18:00-09:00": {
                "primary": "duty_person",         # 夜间值班
                "backup": "voicemail",
                "strategy": "direct"
            }
        }
    }

    3.4 语音网关转接配置

    # 鼎信通达语音网关转接配置
    VOIP_FORWARDING_CONFIG = {
        "device": "鼎信通达 DAG1000-4S",
        
        # 基本转接规则
        "call_forwarding": {
            "unconditional": {  # 无条件转接
                "enabled": False,
                "target": None
            },
            "busy": {  # 忙时转接
                "enabled": True,
                "target": "mobile_phone",
                "timeout": 10
            },
            "no_answer": {  # 无应答转接
                "enabled": True,
                "target": "mobile_phone",
                "timeout": 15
            },
            "offline": {  # 离线转接
                "enabled": True,
                "target": "duty_person",
                "timeout": 5
            }
        },
        
        # 移动电话绑定
        "mobile_bindings": {
            "8001": {
                "sales": "sales_manager_a",
                "mobile": "138****0001",
                "forwarding_type": "simultaneous",  # 同时响铃
                "office_timeout": 10,  # 办公室响10秒
                "mobile_timeout": 25   # 手机响25秒
            },
            "8002": {
                "sales": "sales_manager_b",
                "mobile": "138****0002",
                "forwarding_type": "sequential",  # 顺序转接
                "office_timeout": 15,
                "mobile_timeout": 20
            }
        }
    }

    3.5 销售状态管理

    # 销售状态管理(用于智能转接)
    class SalesStatusManager:
        """
        管理销售人员状态,用于智能转接
        """
        
        async def update_status(self, sales_id: str, status: str, location: str = None):
            """
            更新销售状态
            status: in_office / in_field / in_meeting / off_duty / on_leave
            """
            await redis.setex(
                f"sales:{sales_id}:status",
                3600,  # 1小时过期
                json.dumps({
                    "status": status,
                    "location": location,
                    "updated_at": datetime.now().isoformat()
                })
            )
        
        async def get_status(self, sales_id: str) -> dict:
            """获取销售当前状态"""
            data = await redis.get(f"sales:{sales_id}:status")
            if data:
                return json.loads(data)
            return {"status": "unknown", "location": None}
        
        async def get_best_contact(self, sales_id: str) -> str:
            """
            根据状态获取最佳联系方式
            """
            status = await self.get_status(sales_id)
            
            if status["status"] == "in_office":
                return "office_phone"
            elif status["status"] in ["in_field", "in_meeting"]:
                return "mobile_phone"
            elif status["status"] == "off_duty":
                return "duty_person"
            else:
                return "sequential"  # 默认顺序转接
    
    # 状态更新接口(销售可通过企业微信/小程序更新)
    @app.post("/api/sales/status")
    async def update_sales_status(
        sales_id: str,
        status: str,  # in_office / in_field / in_meeting / off_duty
        location: str = None
    ):
        """
        销售更新自己的状态
        """
        await sales_status_manager.update_status(sales_id, status, location)
        return {"success": True, "status": status}

    ---

    四、7×24小时接听保障方案

    4.1 轮班制度

    ┌─────────────────────────────────────────┐
    │         7×24小时接听排班表               │
    ├─────────────────────────────────────────┤
    │  时间段      │ 主接听人    │ 备用接听人  │
    ├─────────────────────────────────────────┤
    │  09:00-18:00 │ 销售A/B/C   │ 值班人员    │  (工作日)
    │  18:00-22:00 │ 销售A/B     │ 值班人员    │  (晚间)
    │  22:00-09:00 │ 值班人员    │ 语音留言    │  (夜间)
    ├─────────────────────────────────────────┤
    │  周六 09:00-18:00 │ 销售B/C  │ 值班人员  │
    │  周日 09:00-18:00 │ 值班人员  │ 语音留言  │
    └─────────────────────────────────────────┘

    4.2 值班人员配置

    DUTY_SCHEDULE = {
        "weekday_night": {  # 工作日夜间
            "22:00-09:00": {
                "duty_person": "值班人员",
                "mobile": "138****9999",
                "response_time": "15分钟内",
                "escalation": "销售总监"
            }
        },
        
        "weekend": {  # 周末
            "saturday": {
                "09:00-18:00": {
                    "duty_person": "销售B/C",
                    "mobile": "138****0002",
                    "response_time": "即时"
                }
            },
            "sunday": {
                "09:00-18:00": {
                    "duty_person": "值班人员",
                    "mobile": "138****9999",
                    "response_time": "15分钟内"
                }
            }
        },
        
        "holiday": {  # 节假日
            "duty_person": "值班人员",
            "mobile": "138****9999",
            "response_time": "30分钟内",
            "note": "节假日仅处理紧急咨询"
        }
    }

    4.3 语音留言自动处理

    # 非工作时间语音留言处理
    async def process_voicemail(call_data: dict):
        """
        处理语音留言
        """
        # 1. 保存语音留言
        voicemail = {
            "id": f"VM-{datetime.now().strftime('%Y%m%d')}-{uuid.uuid4().hex[:8]}",
            "caller_number": call_data["caller_number"],
            "call_time": call_data["call_time"],
            "recording_url": call_data["recording_url"],
            "duration": call_data["duration"]
        }
        
        # 2. 语音转文字
        transcription = await transcribe_call_recording(voicemail["id"])
        voicemail["transcript"] = transcription["text"]
        
        # 3. 提取关键信息
        insights = await extract_call_insights(transcription["text"])
        
        # 4. 判断紧急程度
        urgency = calculate_urgency(insights)
        
        # 5. 创建紧急通知
        if urgency == "high":
            # 立即通知值班人员
            await send_urgent_notification({
                "type": "urgent_voicemail",
                "caller": call_data["caller_number"],
                "summary": insights["summary"],
                "recording_url": voicemail["recording_url"],
                "duty_person": DUTY_SCHEDULE["weekday_night"]["22:00-09:00"]["duty_person"]
            })
        
        # 6. 创建待办事项(工作时间处理)
        await create_todo_task({
            "title": f"处理语音留言:{call_data['caller_number']}",
            "description": insights["summary"],
            "priority": urgency,
            "deadline": get_next_workday_morning(),
            "recording_url": voicemail["recording_url"]
        })
        
        return voicemail

    ---

    五、完整通话流程(增强版)

    客户拨打 4008-320-160
        ↓
    【步骤1: 来电识别】
    系统自动识别来电号码
        ↓
    【步骤2: CRM比对】
    查询CRM客户通讯录
        ├─ 匹配成功 → 显示客户信息(公司/姓名/部门/等级)
        └─ 未匹配 → 标记为新线索
        ↓
    【步骤3: 智能路由】
    根据时间/销售状态选择转接策略
        ├─ 工作时间 → 办公室话机(顺序/同时响铃)
        ├─ 外出时间 → 移动电话转接
        ├─ 非工作时间 → 值班人员/语音留言
        └─ 节假日 → 值班人员/语音留言
        ↓
    【步骤4: 接听处理】
    销售接听电话
        ├─ 来电弹屏显示客户信息
        ├─ CRM自动创建沟通记录
        └─ 通话录音开始
        ↓
    【步骤5: 通话结束】
        ├─ 录音保存
        ├─ 语音转文字
        ├─ AI提取关键信息
        ├─ 自动创建CRM沟通记录
        ├─ 生成待办事项
        └─ 推送企业微信通知
        ↓
    【步骤6: 跟进管理】
        ├─ 待办事项提醒
        ├─ 跟进记录更新
        ├─ 客户状态更新
        └─ 全生命周期追溯

    ---

    六、实施建议

    6.1 分阶段实施

    阶段时间内容优先级
    第1阶段第1周基础400电话配置(IVR+录音)
    第2阶段第2周CRM来电弹屏+客户识别
    第3阶段第3周移动电话转接配置
    第4阶段第4周语音识别+自动推送CRM
    第5阶段第5周7×24值班制度+智能路由

    6.2 技术选型建议

    功能推荐方案说明
    语音识别本地Whisper (MacStudio)隐私好,免费
    语音合成阿里云语音合成中文效果好
    通话录音语音网关自带无需额外设备
    移动转接运营商呼叫转移稳定可靠
    状态管理Redis + 企业微信实时更新

    ---

    **文档版本**:v3.0(增强版)

    **日期**:2026-06-15

    **更新内容**:

  • CRM客户通讯录来电识别
  • 通话记录自动推送CRM沟通记录
  • 语音识别与文字保存
  • 移动电话转接方案
  • 7×24小时接听保障
  • **审批人**:admin@topcentral.cn / 麻一明

    **执行状态**:待确认