支持可配置的会话自动分配策略
- 租户可设置负载最低或轮询,以及每位坐席最大进行中会话数 - 自动分配按策略过滤在线一线客服,满并发则保持排队 - 系统设置「客服分配规则」页可保存上述配置
This commit is contained in:
@@ -60,6 +60,8 @@ func getOrCreateTenantSettings(tenantID uint) (*model.TenantSetting, error) {
|
||||
NotifyNewSession: true,
|
||||
NotifyOfflineLeave: true,
|
||||
NotifyDailyReport: false,
|
||||
AssignStrategy: assignStrategyLeastLoad,
|
||||
MaxActivePerAgent: 0,
|
||||
}
|
||||
if err := model.DB.Create(&setting).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -135,18 +137,25 @@ func isWithinWorkHours(setting *model.TenantSetting, now time.Time) bool {
|
||||
}
|
||||
|
||||
func settingsResponse(setting *model.TenantSetting) gin.H {
|
||||
strategy := normalizeAssignStrategy(setting.AssignStrategy)
|
||||
maxActive := setting.MaxActivePerAgent
|
||||
if maxActive < 0 {
|
||||
maxActive = 0
|
||||
}
|
||||
return gin.H{
|
||||
"tenant_id": setting.TenantID,
|
||||
"display_name": setting.DisplayName,
|
||||
"agent_nickname": setting.AgentNickname,
|
||||
"timezone": setting.Timezone,
|
||||
"welcome_message": setting.WelcomeMessage,
|
||||
"offline_prompt": setting.OfflinePrompt,
|
||||
"work_hours": parseWorkHours(setting.WorkHoursJSON),
|
||||
"worktime_prompt": setting.WorktimePrompt,
|
||||
"notify_new_session": setting.NotifyNewSession,
|
||||
"notify_offline_leave": setting.NotifyOfflineLeave,
|
||||
"notify_daily_report": setting.NotifyDailyReport,
|
||||
"tenant_id": setting.TenantID,
|
||||
"display_name": setting.DisplayName,
|
||||
"agent_nickname": setting.AgentNickname,
|
||||
"timezone": setting.Timezone,
|
||||
"welcome_message": setting.WelcomeMessage,
|
||||
"offline_prompt": setting.OfflinePrompt,
|
||||
"work_hours": parseWorkHours(setting.WorkHoursJSON),
|
||||
"worktime_prompt": setting.WorktimePrompt,
|
||||
"notify_new_session": setting.NotifyNewSession,
|
||||
"notify_offline_leave": setting.NotifyOfflineLeave,
|
||||
"notify_daily_report": setting.NotifyDailyReport,
|
||||
"assign_strategy": strategy,
|
||||
"max_active_per_agent": maxActive,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +184,8 @@ type updateSettingsReq struct {
|
||||
NotifyNewSession *bool `json:"notify_new_session"`
|
||||
NotifyOfflineLeave *bool `json:"notify_offline_leave"`
|
||||
NotifyDailyReport *bool `json:"notify_daily_report"`
|
||||
AssignStrategy *string `json:"assign_strategy"`
|
||||
MaxActivePerAgent *int `json:"max_active_per_agent"`
|
||||
}
|
||||
|
||||
func (h *SettingsHandler) Update(c *gin.Context) {
|
||||
@@ -284,6 +295,21 @@ func (h *SettingsHandler) Update(c *gin.Context) {
|
||||
if req.NotifyDailyReport != nil {
|
||||
updates["notify_daily_report"] = *req.NotifyDailyReport
|
||||
}
|
||||
if req.AssignStrategy != nil {
|
||||
raw := strings.TrimSpace(*req.AssignStrategy)
|
||||
if raw != assignStrategyLeastLoad && raw != assignStrategyRoundRobin {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "分配策略无效,可选 least_load / round_robin"})
|
||||
return
|
||||
}
|
||||
updates["assign_strategy"] = raw
|
||||
}
|
||||
if req.MaxActivePerAgent != nil {
|
||||
if *req.MaxActivePerAgent < 0 || *req.MaxActivePerAgent > 200 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "最大并发需为 0–200(0 表示不限制)"})
|
||||
return
|
||||
}
|
||||
updates["max_active_per_agent"] = *req.MaxActivePerAgent
|
||||
}
|
||||
if len(updates) == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "没有可更新字段"})
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user