用戶進線 Session 過程規格說明書

版本: v1.0\ 最後更新: 2026-06-13\ 服務範圍: aile-service-tenant(核心)、aile-service-room(協同)


1. 概述

用戶進線 Session(ServiceSession)是 Aile 客服系統的核心會話管理機制。每當客戶透過 LINE 私聊或其他渠道向服務號發起對話時,系統會建立一條 ServiceSession 記錄,追蹤從機器人接待到人工服務的完整生命週期。

1.1 核心概念

概念說明
ServiceSession一次客戶進線的完整會話記錄
Session 狀態9 種狀態:RobotActive → DistributeActive → AgentActive → ... → End
機器人接待客戶進線後首先由機器人(AI 助手)接待
轉人工客戶請求或系統判定需要轉接人工客服
分配策略基於員工權重(RoomWeight)的自動分配

2. ServiceSessionModel(會話持久化模型)

2.1 資料結構

MongoDB 集合:aile.tenant.servicenumber.session


    
    
    
  // aile-api/aile-tenant-api/.../model/servicenumber/ServiceSessionModel.java
@Document("aile.tenant.servicenumber.session")

@CompoundIndexes({
    @CompoundIndex(name = "serviceNumberId", def = "{'serviceNumberId': 1}"),
    @CompoundIndex(name = "roomId_1_updateTime_1", def = "{'roomId': 1, 'updateTime': 1}"),
    @CompoundIndex(name = "roomId_1_channel_1_updateTime_1", def = "{'roomId': 1, 'channel': 1, 'updateTime': 1}"),
    @CompoundIndex(name = "gwSessionId_1", def = "{'gwSessionId': 1}"),
    @CompoundIndex(name = "serviceNumberId_1_status_1", def = "{'serviceNumberId': 1, 'status': 1}"),
    @CompoundIndex(name = "serviceNumberId_1_status_1_agentId_1", def = "{'serviceNumberId': 1, 'status': 1, 'agentId': 1}"),
    @CompoundIndex(name = "agentId_1_status_1", def = "{'agentId': 1, 'status': 1}"),
    @CompoundIndex(name = "serviceNumberId_1_scopeId_1", def = "{'serviceNumberId': 1, 'scopeId': 1}"),
    @CompoundIndex(name = "status_1_activeTime_1", def = "{'status': 1, 'activeTime': 1}"),
    @CompoundIndex(name = "status_1_distributeTime_1", def = "{'status': 1, 'distributeTime': 1}"),
    @CompoundIndex(name = "serviceNumberId_1_startTime_1", def = "{'serviceNumberId': 1, 'startTime': 1}")
})

public
 class ServiceSessionModel extends BaseModel {
    String tenantId;                   // 租戶 ID
    String serviceNumberId;            // 服務號 ID
    ServiceNumberType serviceNumberType; // 服務號類型
    String roomId;                     // 聊天室 ID
    String accountId;                  // 帳號 ID
    String customerId;                 // 客戶(聯繫人)ID
    String scopeId;                    // 客戶渠道 scopeId
    String agentId;                    // 接待客服的 memberId
    String gwSessionId;                // Gateway 側的 session ID
    ServiceSessionStatus status;       // 會話狀態
    Channel channel;                   // 進線渠道(Line / WhatsApp 等)
    Long startTime;                    // 會話開始時間
    Long activeTime;                   // 最近活躍時間
    Long endTime;                      // 會話結束時間
    Long distributeTime;               // 人工分配時間
    Long robotActiveTime;              // 機器人開始接待時間
    Long robotStopTime;                // 機器人接待結束時間
    Long timeoutTime;                  // 超時時間
    // 滿意度

    Integer satisfactionScore;         // 滿意度評分
    String satisfactionComment;        // 滿意度備註
}

3. Session 生命週期狀態機

3.1 狀態定義


    
    
    
  // aile-api/aile-tenant-api/.../enums/ServiceSessionStatus.java
public
 enum ServiceSessionStatus {
    RobotActive,       // 機器人服務中
    RobotStop,         // 機器人服務結束
    DistributeActive,  // 轉人工,剛進件(等待分配)
    AgentActive,       // 客服人員服務中
    AgentStop,         // 客服人員服務結束
    CustomerStop,      // 客戶主動結束
    Timeout,           // 服務超時結束
    NoWorkTimeStop,    // 非上班時間結束
    Deleted            // 標記刪除
}

3.2 狀態轉換圖


    
    
    
  客戶進線
  │
  ▼
RobotActive ──────────────────────────────────────┐
  │                                                │
  ├──→ RobotStop(機器人主動結束)                   │
  │                                                │
  ├──→ DistributeActive(轉人工)                    │
  │       │                                        │
  │       ├──→ AgentActive(分配成功)               │
  │       │       │                                │
  │       │       ├──→ AgentStop(客服結束)          │
  │       │       ├──→ CustomerStop(客戶結束)       │
  │       │       └──→ Timeout(超時)               │
  │       │                                        │
  │       └──→ NoWorkTimeStop(非工作時間)           │
  │                                                │
  ├──→ CustomerStop(客戶主動結束)                   │
  ├──→ Timeout(超時)                               │
  └──→ NoWorkTimeStop(非工作時間)                   │
                                                    │
  (所有結束狀態可被標記為 Deleted) ◄──────────────────┘

3.3 活躍狀態判斷


    
    
    
  // 以下三個狀態為「活躍中」
activeStatus = [RobotActive, DistributeActive, AgentActive]

// 「主要活躍」(人工相關)

isMainActive() → DistributeActive || AgentActive

// 「已離線」

isOffline() → RobotStop || AgentStop || CustomerStop || Timeout || NoWorkTimeStop || Deleted

4. ServiceSessionService(會話服務接口)

位置:aile-service/aile-service-tenant/.../service/servicenumber/ServiceSessionService.java

4.1 核心方法

方法說明狀態變更
start(dto)客戶進線,開始新會話→ RobotActive
startRobotActive(model)啟動機器人接待→ RobotActive
stopRobotService(model)停止機器人接待RobotActive → RobotStop
warningRobotService(model)機器人接待預警RobotActive(不變)
startDistributeService(model, context)轉人工分配→ DistributeActive
agentStartService(dto, employeeId)客服接起DistributeActive → AgentActive
agentStopService(dto)客服結束AgentActive → AgentStop
customerStopService(dto)客戶結束RobotActive/AgentActive → CustomerStop
timeout(model)超時結束活躍狀態 → Timeout
agentSwitchRobot(dto)客服轉機器人AgentActive → RobotActive
transfer(model, memberId)轉接給其他客服AgentActive → AgentActive(更換 agentId)
refreshSession(dto)刷新會話活躍時間更新 activeTime
ownerStopService(model)管理員強制結束任意活躍 → AgentStop
getLastSession(roomId)查詢最近一次會話-

4.2 分配上下文


    
    
    
  // aile-service/aile-service-tenant/.../service/servicenumber/dto/ServiceSessionDistributeContext.java
public
 class ServiceSessionDistributeContext {
    String serviceNumberId;
    String roomId;
    String employeeId;          // 指定客服(選填,不指定則自動分配)
    RoomWeightEventCode eventCode; // 分配事件碼
    boolean
 checkWorkTime;      // 是否檢查工作時間
}

5. 會話啟動流程

5.1 客戶進線


    
    
    
  Gateway Webhook(LINE 私聊消息)
  │
  └── aile-service-tenant (GatewayController)
        │
        ├── 解析 Webhook:提取 sender.code、to.code、message
        ├── 查找/建立 TenantContactModel(聯繫人)
        ├── 查找/建立 ServiceNumberScopeModel(渠道關聯)
        ├── 查找/建立 Services Room(私聊聊天室)
        │
        ├── ServiceSessionService.start(startDto)
        │     ├── 檢查是否已有活躍會話(同一 roomId + channel)
        │     │     ├── 有 → 刷新現有會話(refreshSession)
        │     │     └── 無 → 建立新會話
        │     ├── status = RobotActive
        │     └── 記錄 startTime、robotActiveTime
        │
        ├── 消息寫入 Services Room
        │
        └── 觸發助手管線(AssistantTriggerPublishService)
              └── 若無助手或助手不匹配 → 直接轉人工

5.2 機器人接待結束


    
    
    
  客戶發送特定關鍵詞(如「轉人工」)或系統規則觸發
  │
  └── ServiceSessionService.stopRobotService(session)
        ├── status: RobotActive → RobotStop
        ├── 記錄 robotStopTime
        └── 可選:自動觸發 startDistributeService

6. 轉人工分配流程

6.1 分配觸發

轉人工有三種觸發方式:

方式觸發條件
客戶請求客戶發送「轉人工」等關鍵詞
機器人無法處理AI 助手判斷需轉人工(返回特定信號)
系統規則無助手配置的服務號,直接轉人工

6.2 分配邏輯


    
    
    
  ServiceSessionService.startDistributeService(session, context)
  │
  ├── 檢查工作時間(context.checkWorkTime = true)
  │     ├── 非工作時間 → status = NoWorkTimeStop → return null
  │     └── 工作時間 → 繼續
  │
  ├── 若指定 employeeId(指定客服)
  │     └── 查詢該客服是否在線且可接待
  │
  ├── 若未指定(自動分配)
  │     └── 基於 RoomWeight 系統自動選擇最合適的客服
  │           ├── 查詢該服務號的在線客服列表
  │           ├── 依權重排序(空閒度、技能匹配、接待數量等)
  │           └── 選擇權重最高的客服
  │
  ├── status: RobotActive → DistributeActive(若需等待)或直接 → AgentActive
  ├── 記錄 distributeTime
  │
  └── 發送分配通知(Socket.IO / PubSub)

6.3 客服接起


    
    
    
  ServiceSessionService.agentStartService(dto, employeeId)
  │
  ├── 驗證 employeeId 是否為分配目標
  ├── status: DistributeActive → AgentActive
  ├── 記錄 agentId
  └── 發送會話開始消息(AgentStartMessageEvent)

7. 會話結束流程

7.1 客服結束


    
    
    
  客服點擊「結束會話」
  │
  └── ServiceSessionService.agentStopService(dto)
        ├── status: AgentActive → AgentStop
        ├── 記錄 endTime
        └── 發送 AgentStopMessageEvent

7.2 客戶結束


    
    
    
  客戶發送結束信號或 Gateway 推送 ServiceEnd 事件
  │
  └── ServiceSessionService.customerStopService(dto)
        ├── status: RobotActive/AgentActive → CustomerStop
        ├── 記錄 endTime
        └── 清除活躍會話緩存

7.3 超時結束


    
    
    
  SessionTimeoutScheduleTask(定時掃描)
  │
  └── 掃描 activeTime 超過配置閾值的活躍會話
        ├── status → Timeout
        └── 發送 SessionTimeoutEvent

8. 定時任務

8.1 會話超時

任務位置說明
SessionTimeoutScheduleTaskaile-service-tenant/.../task/定時掃描超時會話
OnceSessionTimeoutTaskaile-service-tenant/.../task/單次超時處理

8.2 會話空閒

任務位置說明
SessionIdleScheduleTaskaile-service-tenant/.../task/掃描空閒過久的會話
OnceSessionIdleTaskaile-service-tenant/.../task/單次空閒處理

8.3 自動轉接

任務位置說明
OwnerAutoTransferScheduleTaskaile-service-tenant/.../task/客服離線自動轉接
OnceOwnerAutoTransferTaskaile-service-tenant/.../task/單次自動轉接處理

8.4 自動結束

任務位置說明
OwnerAutoStopScheduleTaskaile-service-tenant/.../task/客服離線自動結束會話
OnceOwnerAutoStopTaskaile-service-tenant/.../task/單次自動結束處理

9. 會話統計

9.1 統計接口

路由:/servicenumber/session/statistics

維度說明
按服務號每個服務號的會話總數、活躍數、結束數
按時間按月/按日統計會話趨勢
按客服每個客服的接待量、平均處理時間
按機器人機器人接待比例、轉人工率

9.2 統計資料結構


    
    
    
  // aile-api/aile-tenant-api/.../vo/servicenumber/statistics/ServiceSessionStatisticsVO.java
public
 class ServiceSessionStatisticsVO {
    long
 totalCount;           // 總會話數
    long
 activeCount;          // 活躍會話數
    long
 robotActiveCount;     // 機器人接待數
    long
 agentActiveCount;    // 人工接待數
    long
 endedCount;          // 已結束數
    long
 timeoutCount;        // 超時數
    double
 avgHandleTime;     // 平均處理時間(秒)
    double
 robotRatio;        // 機器人處理比例
    double
 transferRatio;     // 轉人工比例
}

10. 會話通知機制

10.1 通知事件

位置:aile-service/aile-service-tenant/.../notice/session/

事件類觸發時機
SessionRobotActiveEvent機器人開始接待
SessionRobotStopEvent機器人接待結束
SessionRobotWarningEvent機器人接待預警
SessionDistributeActiveEvent進入分配佇列
SessionAgentActiveEvent客服接起
SessionAgentStopEvent客服結束
SessionTimeoutEvent會話超時

10.2 會話消息

位置:aile-service/aile-service-tenant/.../session/message/

事件說明
SessionStartMessageEvent會話開始卡片消息
RobotActiveMessageEvent機器人接待中卡片消息
RobotStopMessageEvent機器人接待結束消息
AgentStartMessageEvent人工客服接入消息
AgentStopMessageEvent人工客服結束消息
TimeoutMessageEvent會話超時消息

11. 滿意度評價

11.1 評價服務

位置:aile-service/aile-service-tenant/.../service/servicenumber/SatisfactionSurveyService.java


    
    
    
  會話結束(AgentStop / CustomerStop)
  │
  └── SatisfactionSurveyService.sendSurvey(session)
        ├── 向客戶推送滿意度評價卡片
        ├── 客戶評分 → 記錄 satisfactionScore
        └── 客戶可選填評論 → 記錄 satisfactionComment

12. 與其他模組的協作

模組互動方式說明
Room 服務Feign(ServiceSessionFeign刷新會話、檢查房間狀態
GatewayWebhook 事件接收 ServiceStart/ServiceEnd 事件
助手PubSub + Feign機器人接待階段的助手觸發
配額配額檢查會話建立時檢查配額
進線原因ServiceInboundReasonSessionService會話關聯進線原因
SagaProcessServiceSessionMergeStep客戶合併時的會話處理

13. 關鍵檔案索引

層級檔案說明
API Modelaile-api/aile-tenant-api/.../model/servicenumber/ServiceSessionModel.java會話持久化模型
API Enumaile-api/aile-tenant-api/.../enums/ServiceSessionStatus.java會話狀態枚舉
Serviceaile-service/aile-service-tenant/.../service/servicenumber/ServiceSessionService.java會話服務接口
Service Implaile-service/aile-service-tenant/.../service/servicenumber/impl/ServiceSessionServiceImpl.java會話服務實現
Controlleraile-service/aile-service-tenant/.../controller/servicenumber/ServiceSessionController.java會話 API
DTOaile-service/aile-service-tenant/.../service/servicenumber/dto/ServiceSessionDistributeContext.java分配上下文
通知aile-service/aile-service-tenant/.../notice/session/SessionNoticeUtil.java會話通知工具
通知事件aile-service/aile-service-tenant/.../notice/session/event/*.java各類通知事件
消息事件aile-service/aile-service-tenant/.../session/message/*.java會話消息事件
消息工具aile-service/aile-service-tenant/.../session/SessionMessageUtil.java會話消息工具
定時任務aile-service/aile-service-tenant/.../task/SessionTimeoutScheduleTask.java超時掃描
定時任務aile-service/aile-service-tenant/.../task/SessionIdleScheduleTask.java空閒掃描
定時任務aile-service/aile-service-tenant/.../task/OwnerAutoTransferScheduleTask.java自動轉接
定時任務aile-service/aile-service-tenant/.../task/OwnerAutoStopScheduleTask.java自動結束
滿意度aile-service/aile-service-tenant/.../service/servicenumber/SatisfactionSurveyService.java滿意度評價
Sagaaile-service/aile-service-tenant/.../saga/step/ProcessServiceSessionMergeStep.javaSaga 會話合併
Gateway 事件aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceStartEventImpl.javaGateway 開始事件
Gateway 事件aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceEndEventImpl.javaGateway 結束事件