feat: new
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 100622 (10.6.22-MariaDB-0ubuntu0.22.04.1)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 04/06/2025 10:50:08
|
||||
Date: 14/06/2025 12:30:47
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -25,13 +25,15 @@ CREATE TABLE `mf_callback_ticket` (
|
||||
`ticket_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Ticket ID',
|
||||
`caller_number` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT 'caller number',
|
||||
`callee_number` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'callee number',
|
||||
`status` enum('NEW','PENDING','IN_PROGRESS','FAILED','COMPLETED','TIMEOUT','RECREATED') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'NEW',
|
||||
`status` enum('NEW','IN_PROGRESS','NO_ANSWER_1','NO_ANSWER_2','TIMEOUT','PENDING','CLOSED') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'NEW' COMMENT '1:NEW/新建,2:IN_PROGRESS/处理中,3:NO_ANSWER_1/未应答1,3:NO_ANSWER_2/未应答2,4:TIMEOUT/超时,5:PENDING/挂起,6:CLOSED/关闭',
|
||||
`agent_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'agent name',
|
||||
`comment` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'comment for callback',
|
||||
`msd_data` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT 'MSD data',
|
||||
`created_at` bigint(20) NULL DEFAULT NULL COMMENT 'created at time',
|
||||
`updated_at` bigint(20) NULL DEFAULT NULL COMMENT 'updated at time',
|
||||
PRIMARY KEY (`ticket_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic;
|
||||
PRIMARY KEY (`ticket_id`) USING BTREE,
|
||||
INDEX `idx_caller_agent`(`caller_number`, `agent_name`) USING BTREE,
|
||||
INDEX `idx_created`(`created_at`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 108 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -712,8 +712,16 @@ INSERT INTO `sys_dict_data` VALUES (2201, 2201, 'table.u_auth_user', 'UDM鉴权
|
||||
INSERT INTO `sys_dict_data` VALUES (2202, 2202, 'table.u_sub_user', 'UDM签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2203, 2203, 'table.u_voip_auth', 'VoIP鉴权数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2204, 2204, 'table.u_ims_user', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2300, 2300, 'menu.psap.agent', '座席', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2301, 2301, 'menu.psap.agent.callings', '并行话务', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2302, 2302, 'menu.psap.agent.callback', '回拨管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
|
||||
INSERT INTO `sys_dict_data` VALUES (20000, 20000, 'menu.psap.agent', '座席', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (20001, 20000, 'menu.psap.agent.callings', '并行话务', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (20002, 20000, 'menu.psap.agent.callback', '回拨管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (20003, 1, 'callback.status.NEW', '新建', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20004, 2, 'callback.status.IN_PROGRESS', '处理中', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20005, 3, 'callback.status.NO_ANSWER_1', '未应答1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20006, 4, 'callback.status.NO_ANSWER_2', '未应答2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20007, 5, 'callback.status.TIMEOUT', '超时', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20008, 6, 'callback.status.PENDING', '挂起', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (20009, 7, 'callback.status.CLOSED', '关闭', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -712,8 +712,16 @@ INSERT INTO `sys_dict_data` VALUES (4201, 4201, 'table.u_auth_user', 'UDM Authen
|
||||
INSERT INTO `sys_dict_data` VALUES (4202, 4202, 'table.u_sub_user', 'UDM Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4203, 4203, 'table.u_voip_auth', 'VoIP Authentication', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4204, 4204, 'table.u_ims_user', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4300, 4300, 'menu.psap.agent', 'Agent', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4301, 4301, 'menu.psap.agent.callings', 'Calling Info', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4302, 4302, 'menu.psap.agent.callback', 'CallBack Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
|
||||
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, 25000, 'menu.psap.agent.callings', 'Calling Info', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (25002, 25000, 'menu.psap.agent.callback', 'CallBack Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (25003, 1, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25004, 2, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25005, 3, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25006, 4, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25007, 5, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25008, 6, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (25009, 7, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -56,6 +56,7 @@ INSERT INTO `sys_dict_type` VALUES (121, 'dictType.ne_host_cmd_groupId', 'ne_hos
|
||||
INSERT INTO `sys_dict_type` VALUES (122, 'dictType.ne_info_status', 'ne_info_status', '1', 'supervisor', 1702020000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_type` VALUES (123, 'dictType.ne_license_status', 'ne_license_status', '1', 'supervisor', 1702020000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_type` VALUES (124, 'dictType.cdr_cause_code', 'cdr_cause_code', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_type` VALUES (20000, 'dictType.callback_status', 'callback_status', '1', 'supervisor', 1749783964967, '', 0, NULL);
|
||||
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
@@ -93,15 +93,9 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 解析座席列表响应
|
||||
var agentResp struct {
|
||||
Code int `json:"code"`
|
||||
Data []struct {
|
||||
Domain string `json:"domain"`
|
||||
Index int `json:"index"`
|
||||
Name string `json:"name"`
|
||||
Online bool `json:"online"`
|
||||
Password string `json:"password"`
|
||||
} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
Code int `json:"code"`
|
||||
Data []ueCallBackTicket.AgentInfo `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&agentResp); err != nil {
|
||||
@@ -130,6 +124,7 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
||||
AgentName: selectedAgent,
|
||||
Comment: "",
|
||||
MsdData: cdrEvent.CDR["msdData"].(string),
|
||||
RmUid: cdrEvent.RmUID,
|
||||
CreatedAt: time.Now().UnixMicro(),
|
||||
UpdatedAt: updatedAt,
|
||||
}
|
||||
|
||||
@@ -105,10 +105,21 @@ type CallbackTicket struct {
|
||||
AgentName string `json:"agentName" gorm:"column:agent_name"` // 坐席名称
|
||||
Comment string `json:"comment" gorm:"column:comment"` // 工单备注
|
||||
MsdData string `json:"msdData" gorm:"column:msd_data"` // MSD数据
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"` // RM用户ID
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 创建时间
|
||||
UpdatedAt *int64 `json:"updatedAt" gorm:"column:updated_at;autoUpdateTime:false"` // 更新时间
|
||||
}
|
||||
|
||||
type AgentInfo struct {
|
||||
Index int `json:"index"`
|
||||
Name string `json:"name"`
|
||||
Online bool `json:"online"`
|
||||
Email string `json:"email"`
|
||||
Mobile string `json:"mobile"`
|
||||
Domain string `json:"domain"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CallbackTicket) TableName() string {
|
||||
return "mf_callback_ticket"
|
||||
|
||||
@@ -180,13 +180,7 @@ func (s *CallbackTicketService) GetLastAssignedAgent() (string, error) {
|
||||
// @param agents 座席列表
|
||||
// @param lastAgentName 上一个座席名称
|
||||
// @return string 下一个座席名称
|
||||
func (s *CallbackTicketService) SelectNextAgent(agents []struct {
|
||||
Domain string `json:"domain"`
|
||||
Index int `json:"index"`
|
||||
Name string `json:"name"`
|
||||
Online bool `json:"online"`
|
||||
Password string `json:"password"`
|
||||
}, lastAgentName string) string {
|
||||
func (s *CallbackTicketService) SelectNextAgent(agents []AgentInfo, lastAgentName string) string {
|
||||
if len(agents) == 0 {
|
||||
return ""
|
||||
}
|
||||
@@ -330,24 +324,44 @@ func (s *CallbackTicketService) FindTimeoutTickets(status string, timeoutMicros
|
||||
// @param ticket 要更新的工单
|
||||
// @param originalStatus 原工单状态
|
||||
// @return error 错误信息
|
||||
func (s *CallbackTicketService) UpdateTicketToTimeout(ticket *CallbackTicket, originalStatus string) error {
|
||||
func (s *CallbackTicketService) UpdateTicketToTimeout(ticket *CallbackTicket, originalStatus string, agents []AgentInfo) error {
|
||||
if ticket == nil {
|
||||
return fmt.Errorf("ticket cannot be nil")
|
||||
}
|
||||
|
||||
now := time.Now().UnixMicro()
|
||||
// 1. 更新原工单为超时
|
||||
updatedTicket := CallbackTicket{
|
||||
TicketId: ticket.TicketId,
|
||||
Status: TicketStatusTimeout.Enum(),
|
||||
Comment: fmt.Sprintf("%s - 工单状态为 %s 处理超时,系统自动更新为超时状态", ticket.Comment, originalStatus),
|
||||
UpdatedAt: &now,
|
||||
}
|
||||
|
||||
if err := s.db.Table("mf_callback_ticket").
|
||||
Where("ticket_id = ?", ticket.TicketId).
|
||||
Updates(updatedTicket).Error; err != nil {
|
||||
return fmt.Errorf("更新工单 %d 状态失败: %w", ticket.TicketId, err)
|
||||
}
|
||||
|
||||
// 2. 选择新座席
|
||||
lastAgent := ticket.AgentName
|
||||
newAgent := s.SelectNextAgent(agents, lastAgent)
|
||||
|
||||
// 3. 创建新工单
|
||||
newTicket := CallbackTicket{
|
||||
CallerNumber: ticket.CallerNumber,
|
||||
CalleeNumber: ticket.CalleeNumber,
|
||||
Status: TicketStatusNew.Enum(),
|
||||
AgentName: newAgent,
|
||||
Comment: fmt.Sprintf("由超时工单 %d 自动重建", ticket.TicketId),
|
||||
MsdData: ticket.MsdData,
|
||||
RmUid: ticket.RmUid,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: nil,
|
||||
}
|
||||
if err := s.db.Table("mf_callback_ticket").Create(&newTicket).Error; err != nil {
|
||||
return fmt.Errorf("创建新工单失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package psap_ticket_monitor
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
ueCallBackTicket "be.ems/features/ue/mf_callback_ticket"
|
||||
"be.ems/lib/log"
|
||||
"be.ems/src/framework/cron"
|
||||
"be.ems/src/framework/logger"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
)
|
||||
|
||||
var NewProcessor = &PsapTicketMonitor{
|
||||
@@ -92,7 +97,32 @@ func (s *PsapTicketMonitor) handleTimeoutTickets(status string, timeoutMicros in
|
||||
// 更新超时工单状态
|
||||
var updatedCount int
|
||||
for _, ticket := range tickets {
|
||||
if err := s.callbackTicketService.UpdateTicketToTimeout(&ticket, status); err != nil {
|
||||
// 获取网元信息
|
||||
neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(ticket.RmUid)
|
||||
// 构造网元MF的API地址
|
||||
url := fmt.Sprintf("http://%s:%d/ne/config/data?neType=%s&neId=%s¶mName=agents",
|
||||
neInfo.IP, neInfo.Port, neInfo.NeType, neInfo.NeId)
|
||||
// 发送HTTP请求获取座席列表
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Error("Failed to get MF agents", err)
|
||||
continue
|
||||
}
|
||||
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)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.callbackTicketService.UpdateTicketToTimeout(&ticket, status, agentResp.Data); err != nil {
|
||||
log.Errorf("更新工单 %d 状态失败: %v", ticket.TicketId, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ func (r NeInfo) neListSort(arr []model.NeInfo) []model.NeInfo {
|
||||
// neListSort 网元列表预设排序
|
||||
var list = []string{
|
||||
"OMC",
|
||||
"CBC",
|
||||
"MF",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user