2 Commits

Author SHA1 Message Date
zhangsz
a3950e5dc0 fix: mf cdr event adjust 2025-07-18 16:26:43 +08:00
zhangsz
f57c528c82 fix: dict data sql rename and update 2025-07-18 16:26:09 +08:00
5 changed files with 161 additions and 159 deletions

View File

@@ -717,13 +717,13 @@ INSERT INTO `sys_dict_data` VALUES (2204, 2204, 'table.u_ims_user', 'IMS签约
INSERT INTO `sys_dict_data` VALUES (20000, 20000, 'menu.psap.agent', '座席', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (20001, 20001, 'menu.psap.agent.callings', '并行话务', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (20002, 20002, 'menu.psap.agent.callback', '回拨管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (20003, 20003, 'callback.status.NEW', '新建', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20004, 20004, 'callback.status.IN_PROGRESS', '处理中', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20005, 20005, 'callback.status.NO_ANSWER_1', '未应答1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20006, 20006, 'callback.status.NO_ANSWER_2', '未应答2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20007, 20007, 'callback.status.TIMEOUT', '超时', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20008, 20008, 'callback.status.PENDING', '挂起', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20009, 20009, 'callback.status.CLOSED', '关闭', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20003, 20003, 'callback.status.NEW', '新建', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20004, 20004, 'callback.status.IN_PROGRESS', '处理中', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20005, 20005, 'callback.status.NO_ANSWER_1', '未应答1', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20006, 20006, 'callback.status.NO_ANSWER_2', '未应答2', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20007, 20007, 'callback.status.TIMEOUT', '超时', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20008, 20008, 'callback.status.PENDING', '挂起', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20009, 20009, 'callback.status.CLOSED', '关闭', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (20010, 20010, 'job.export.cdr.mf', '定期导出MF话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (20011, 20011, 'job.psap.ticket.monitor', '回拨工单监控', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (20012, 20012, 'menu.psap.cdr.mf', '紧急呼叫话单', 'i18n_zh', NULL, NULL, '1', 'supervisor', NULL, '', 0, NULL);

View File

@@ -717,13 +717,13 @@ INSERT INTO `sys_dict_data` VALUES (4204, 4204, 'table.u_ims_user', 'IMS Subscri
INSERT INTO `sys_dict_data` VALUES (25000, 25000, 'menu.psap.agent', 'Agent', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (25001, 25001, 'menu.psap.agent.callings', 'Calling Information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (25002, 25002, 'menu.psap.agent.callback', 'CallBack Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (25003, 25003, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25004, 25004, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25005, 25005, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25006, 25006, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25007, 25007, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25008, 25008, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25009, 25009, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25003, 25003, 'callback.status.NEW', 'NEW', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25004, 25004, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25005, 25005, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25006, 25006, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25007, 25007, 'callback.status.TIMEOUT', 'TIMEOUT', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25008, 25008, 'callback.status.PENDING', 'PENDING', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25009, 25009, 'callback.status.CLOSED', 'CLOSED', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
INSERT INTO `sys_dict_data` VALUES (25010, 25010, 'job.export.cdr.mf', 'Regularly Export MF CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (25011, 25011, 'job.psap.ticket.monitor', 'Callback Ticket Monitor', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (25012, 25012, 'menu.psap.cdr.mf', 'PSAP CDR', 'i18n_en', NULL, NULL, '1', 'supervisor', NULL, '', 0, NULL);

View File

@@ -11,13 +11,13 @@ REPLACE INTO `sys_dict_data` VALUES (2014, 2014, 'menu.log.neFile', '网元日
REPLACE INTO `sys_dict_data` VALUES (20000, 20000, 'menu.psap.agent', '座席', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (20001, 20001, 'menu.psap.agent.callings', '并行话务', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (20002, 20002, 'menu.psap.agent.callback', '回拨管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (20003, 20003, 'callback.status.NEW', '新建', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20004, 20004, 'callback.status.IN_PROGRESS', '处理中', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20005, 20005, 'callback.status.NO_ANSWER_1', '未应答1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20006, 20006, 'callback.status.NO_ANSWER_2', '未应答2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20007, 20007, 'callback.status.TIMEOUT', '超时', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20008, 20008, 'callback.status.PENDING', '挂起', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20009, 20009, 'callback.status.CLOSED', '关闭', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20003, 20003, 'callback.status.NEW', '新建', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20004, 20004, 'callback.status.IN_PROGRESS', '处理中', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20005, 20005, 'callback.status.NO_ANSWER_1', '未应答1', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20006, 20006, 'callback.status.NO_ANSWER_2', '未应答2', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20007, 20007, 'callback.status.TIMEOUT', '超时', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20008, 20008, 'callback.status.PENDING', '挂起', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20009, 20009, 'callback.status.CLOSED', '关闭', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (20010, 20010, 'job.export.cdr.mf', '定期导出MF话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (20011, 20011, 'job.psap.ticket.monitor', '回拨工单监控', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (20012, 20012, 'menu.psap.cdr.mf', '紧急呼叫话单', 'i18n_zh', NULL, NULL, '1', 'supervisor', NULL, '', 0, NULL);

View File

@@ -11,13 +11,13 @@ REPLACE INTO `sys_dict_data` VALUES (4014, 4014, 'menu.log.neFile', 'NE Log File
REPLACE INTO `sys_dict_data` VALUES (25000, 25000, 'menu.psap.agent', 'Agent', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (25001, 25001, 'menu.psap.agent.callings', 'Calling Information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (25002, 25002, 'menu.psap.agent.callback', 'CallBack Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (25003, 25003, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25004, 25004, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25005, 25005, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25006, 25006, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25007, 25007, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25008, 25008, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25009, 25009, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25003, 25003, 'callback.status.NEW', 'NEW', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25004, 25004, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25005, 25005, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25006, 25006, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25007, 25007, 'callback.status.TIMEOUT', 'TIMEOUT', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25008, 25008, 'callback.status.PENDING', 'PENDING', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25009, 25009, 'callback.status.CLOSED', 'CLOSED', 'i18n_en', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (25010, 25010, 'job.export.cdr.mf', 'Regularly Export MF CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (25011, 25011, 'job.psap.ticket.monitor', 'Callback Ticket Monitor', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (25012, 25012, 'menu.psap.cdr.mf', 'PSAP CDR', 'i18n_en', NULL, NULL, '1', 'supervisor', NULL, '', 0, NULL);

View File

@@ -79,151 +79,153 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
// MF网元类型特殊处理, 未接电话的回拨工单流转处理
if neTypeLower == "mf" && cdrEvent.CDR["recordType"] == "MOC" && cdrEvent.CDR["agentName"] == "" {
// 发送到MF网元
// 构造网元MF的API地址
url := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/agents",
neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
// 发送HTTP请求获取座席列表
resp, err := http.Get(url)
if err != nil {
log.Error("Failed to get MF agents", err)
if err := handleMFMissedCallCDR(url, cdrEvent); err != nil {
log.Error("Failed to handle MF missed call CDR", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
defer resp.Body.Close()
// 解析座席列表响应
var agentResp struct {
Code int `json:"code"`
Data []ueCallBackTicket.AgentInfo `json:"data"`
Msg string `json:"msg"`
}
if err := json.NewDecoder(resp.Body).Decode(&agentResp); err != nil {
log.Error("Failed to decode MF agents response", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
// 调用服务获取最新一个被分配工单的座席和下一个要分配的座席
mfService := ueCallBackTicket.NewCallbackTicketService()
lastAgentName, err := mfService.GetLastAssignedAgent()
if err != nil {
log.Error("Failed to get last assigned agent", err)
// 可以继续执行,不返回错误
}
// 选择下一个要分配的座席
selectedAgent := mfService.SelectNextAgent(agentResp.Data, lastAgentName)
if selectedAgent != nil {
// 创建回调工单
var updatedAt *int64 = nil
ticket := ueCallBackTicket.CallbackTicket{
CallerNumber: cdrEvent.CDR["callerParty"].(string),
CalleeNumber: cdrEvent.CDR["calledParty"].(string),
Status: ueCallBackTicket.TicketStatusNew.Enum(),
AgentName: selectedAgent.Name,
AgentEmail: selectedAgent.Email,
AgentMobile: selectedAgent.Mobile,
Comment: "",
RmUid: cdrEvent.RmUID,
CreatedAt: time.Now().UnixMicro(),
UpdatedAt: updatedAt,
}
if err := mfService.InsertCallbackTicket(&ticket); err != nil {
log.Error("Failed to insert MF callback ticket", err)
// services.ResponseInternalServerError500ProcessError(w, err)
// return
}
// 新工单分配后发送邮件通知
if selectedAgent.Email != "" {
// 发送邮件通知
emailConfig := config.GetSMTPConfig()
if emailConfig != nil && emailConfig.Enabled {
// 创建配置副本,避免修改全局配置
emailCopy := *emailConfig // 浅拷贝结构体
// 合并配置中的To地址和当前工单的座席邮箱
var recipients []string
// 添加配置中的原始收件人(如管理员、监控人员等)
if len(emailConfig.To) > 0 {
recipients = append(recipients, strings.Split(emailConfig.To, ",")...)
}
// 添加当前工单的座席邮箱
recipients = append(recipients, ticket.AgentEmail)
// 去重处理(避免重复邮箱)
emailCopy.To = strings.Join(email.RemoveDuplicateEmails(recipients), ",")
// 设置邮件主题和内容
emailCopy.Subject = "新工单分配通知"
emailCopy.Body = fmt.Sprintf("您被分配了一个新的回拨工单(编号:%d, 主叫号码:%s), 请及时处理.",
ticket.TicketId, ticket.CallerNumber)
go email.SendEmailWithGomail(emailCopy) // 异步发送
}
}
}
log.Warn("No available agents found for callback ticket")
}
// MF网元类型特殊处理, 处理座席回拨的工单流转
if neTypeLower == "mf" && cdrEvent.CDR["recordType"] == "MTC" {
// 获取座席号码(主叫)和被叫号码
agentNumber, ok1 := cdrEvent.CDR["callerParty"].(string)
callerNumber, ok2 := cdrEvent.CDR["calledParty"].(string)
if !ok1 || !ok2 {
log.Error("Invalid CDR format: missing callerParty or calledParty")
services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("invalid CDR format"))
return
}
// 获取通话时长
callDuration, ok := cdrEvent.CDR["callDuration"].(float64)
if !ok {
// 尝试其他可能的类型
if durationInt, ok := cdrEvent.CDR["callDuration"].(int); ok {
callDuration = float64(durationInt)
} else {
log.Error("Invalid CDR format: callDuration is not a number")
services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("invalid CDR format"))
return
}
}
// 通过座席号码和主叫号码查找符合条件的工单
mfService := ueCallBackTicket.NewCallbackTicketService()
ticket, err := mfService.FindCallbackTicketByAgentAndCaller(agentNumber, callerNumber)
if err != nil {
log.Error("Failed to find callback ticket", err)
if err := handleMFCDRCallBack(cdrEvent); err != nil {
log.Error("Failed to handle MF CDR callback", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
if ticket == nil {
// 没有找到对应的工单,可能是手动呼叫,不处理
log.Warn(fmt.Sprintf("No callback ticket found for agent %s and caller %s", agentNumber, callerNumber))
services.ResponseStatusOK204NoContent(w)
return
}
// 获取通话信息
seizureTime, _ := cdrEvent.CDR["seizureTime"].(string)
releaseTime, _ := cdrEvent.CDR["releaseTime"].(string)
cause, _ := cdrEvent.CDR["cause"].(string)
// 处理回拨结果并更新工单
if err := mfService.ProcessCallbackResult(ticket, callDuration, seizureTime, releaseTime, cause); err != nil {
log.Error("Failed to process callback result", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Info(fmt.Sprintf("Successfully processed callback for ticket %d", ticket.TicketId))
}
services.ResponseStatusOK204NoContent(w)
}
// MF网元类型特殊处理, 未接电话的回拨工单流转处理
func handleMFMissedCallCDR(url string, cdrEvent CDREvent) error {
// 发送HTTP请求获取座席列表
resp, err := http.Get(url)
if err != nil {
return fmt.Errorf("failed to get MF agents: %w", err)
}
defer resp.Body.Close()
// 解析座席列表响应
var agentResp struct {
Code int `json:"code"`
Data []ueCallBackTicket.AgentInfo `json:"data"`
Msg string `json:"msg"`
}
if err := json.NewDecoder(resp.Body).Decode(&agentResp); err != nil {
return fmt.Errorf("failed to decode MF agent response: %w", err)
}
// 调用服务获取最新一个被分配工单的座席和下一个要分配的座席
mfService := ueCallBackTicket.NewCallbackTicketService()
lastAgentName, err := mfService.GetLastAssignedAgent()
if err != nil {
return fmt.Errorf("failed to get last assigned agent: %w", err)
}
// 选择下一个要分配的座席
selectedAgent := mfService.SelectNextAgent(agentResp.Data, lastAgentName)
if selectedAgent != nil {
// 创建回调工单
var updatedAt *int64 = nil
ticket := ueCallBackTicket.CallbackTicket{
CallerNumber: cdrEvent.CDR["callerParty"].(string),
CalleeNumber: cdrEvent.CDR["calledParty"].(string),
Status: ueCallBackTicket.TicketStatusNew.Enum(),
AgentName: selectedAgent.Name,
AgentEmail: selectedAgent.Email,
AgentMobile: selectedAgent.Mobile,
Comment: "",
RmUid: cdrEvent.RmUID,
CreatedAt: time.Now().UnixMicro(),
UpdatedAt: updatedAt,
}
if err := mfService.InsertCallbackTicket(&ticket); err != nil {
return fmt.Errorf("failed to insert MF callback ticket: %w", err)
}
// 新工单分配后发送邮件通知
if selectedAgent.Email != "" {
// 发送邮件通知
emailConfig := config.GetSMTPConfig()
if emailConfig != nil && emailConfig.Enabled {
// 创建配置副本,避免修改全局配置
emailCopy := *emailConfig // 浅拷贝结构体
// 合并配置中的To地址和当前工单的座席邮箱
var recipients []string
// 添加配置中的原始收件人(如管理员、监控人员等)
if len(emailConfig.To) > 0 {
recipients = append(recipients, strings.Split(emailConfig.To, ",")...)
}
// 添加当前工单的座席邮箱
recipients = append(recipients, ticket.AgentEmail)
// 去重处理(避免重复邮箱)
emailCopy.To = strings.Join(email.RemoveDuplicateEmails(recipients), ",")
// 设置邮件主题和内容
emailCopy.Subject = "新工单分配通知"
emailCopy.Body = fmt.Sprintf("您被分配了一个新的回拨工单(编号:%d, 主叫号码:%s), 请及时处理.",
ticket.TicketId, ticket.CallerNumber)
go email.SendEmailWithGomail(emailCopy) // 异步发送
}
}
}
log.Warn("No available agents found for callback ticket")
return nil
}
func handleMFCDRCallBack(cdrEvent CDREvent) error {
// 获取座席号码(主叫)和被叫号码
agentNumber, ok1 := cdrEvent.CDR["callerParty"].(string)
callerNumber, ok2 := cdrEvent.CDR["calledParty"].(string)
if !ok1 || !ok2 {
return fmt.Errorf("invalid CDR format: missing callerParty or calledParty")
}
// 获取通话时长
callDuration, ok := cdrEvent.CDR["callDuration"].(float64)
if !ok {
// 尝试其他可能的类型
if durationInt, ok := cdrEvent.CDR["callDuration"].(int); ok {
callDuration = float64(durationInt)
} else {
return fmt.Errorf("invalid CDR format: callDuration is not a number")
}
}
// 通过座席号码和主叫号码查找符合条件的工单
mfService := ueCallBackTicket.NewCallbackTicketService()
ticket, err := mfService.FindCallbackTicketByAgentAndCaller(agentNumber, callerNumber)
if err != nil {
return fmt.Errorf("failed to find callback ticket: %w", err)
}
if ticket == nil {
// 没有找到对应的工单,可能是手动呼叫,不处理
return fmt.Errorf("no callback ticket found for agent %s and caller %s", agentNumber, callerNumber)
}
// 获取通话信息
seizureTime, _ := cdrEvent.CDR["seizureTime"].(string)
releaseTime, _ := cdrEvent.CDR["releaseTime"].(string)
cause, _ := cdrEvent.CDR["cause"].(string)
// 处理回拨结果并更新工单
if err := mfService.ProcessCallbackResult(ticket, callDuration, seizureTime, releaseTime, cause); err != nil {
return fmt.Errorf("failed to process callback result: %w", err)
}
log.Info(fmt.Sprintf("Successfully processed callback for ticket %d", ticket.TicketId))
return nil
}