Compare commits
3 Commits
2bd0434f2c
...
24ed4e874a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24ed4e874a | ||
|
|
fe7e4d9c88 | ||
|
|
4c2200b39b |
@@ -169,4 +169,13 @@ INSERT INTO `sys_dict_data` VALUES (141, 22, 'dictData.cdr_cause_code.42', '42',
|
|||||||
INSERT INTO `sys_dict_data` VALUES (142, 23, 'dictData.cdr_cause_code.47', '47', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (142, 23, 'dictData.cdr_cause_code.47', '47', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (143, 30, 'dictData.cdr_cause_code.50', '50', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (143, 30, 'dictData.cdr_cause_code.50', '50', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, '');
|
||||||
|
|
||||||
|
-- psap callback status
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (500, 500, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (501, 501, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (502, 502, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (503, 503, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (504, 504, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (505, 505, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (506, 506, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
@@ -713,16 +713,17 @@ INSERT INTO `sys_dict_data` VALUES (2202, 2202, 'table.u_sub_user', 'UDM签约
|
|||||||
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 (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 (2204, 2204, 'table.u_ims_user', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
|
-- psap 座席相关字典数据
|
||||||
INSERT INTO `sys_dict_data` VALUES (20000, 20000, 'menu.psap.agent', '座席', '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 (20001, 20001, '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 (20002, 20002, '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 (20003, 20003, '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 (20004, 20004, '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 (20005, 20005, '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 (20006, 20006, '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 (20007, 20007, '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 (20008, 20008, '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);
|
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 (20010, 20010, 'job.export.cdr.mf', '定期导出MF话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
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 (20011, 20011, 'job.psap.ticket.monitor', '回拨工单监控', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
|
|||||||
@@ -713,16 +713,17 @@ INSERT INTO `sys_dict_data` VALUES (4202, 4202, 'table.u_sub_user', 'UDM Subscri
|
|||||||
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 (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 (4204, 4204, 'table.u_ims_user', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
|
-- PSAP Menu and Data Dictionary
|
||||||
INSERT INTO `sys_dict_data` VALUES (25000, 25000, 'menu.psap.agent', 'Agent', '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 (25001, 25001, '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 (25002, 25002, '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 (25003, 25003, '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 (25004, 25004, '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 (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, 4, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 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, 5, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 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, 6, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 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, 7, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 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 (25010, 25010, 'job.export.cdr.mf', 'Regularly Export MF CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
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 (25011, 25011, 'job.psap.ticket.monitor', 'Callback Ticket Monitor', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,6 @@ INSERT INTO `sys_job` VALUES (9, 'job.getStateFromNE', 'SYSTEM', 'getStateFromNE
|
|||||||
INSERT INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '1', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark');
|
INSERT INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '1', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark');
|
||||||
INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/mf_cdr\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/mf_cdr\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
||||||
INSERT INTO `sys_job` VALUES (100, 'job.export.cdr.mf', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_mf\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as callerParty,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as calledParty,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.seizureTime\')) as seizureTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.answerTime\')) as answerTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.releaseTime\')) as releaseTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as callDuration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordPath\')) as recordPath,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.msdData\')) as msdData,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as serviceResult\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/mf_cdr\"}', '0 40 0 * * ?', '3', '0', '1', '1', 'admin', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', NULL, '');
|
INSERT INTO `sys_job` VALUES (100, 'job.export.cdr.mf', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_mf\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as callerParty,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as calledParty,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.seizureTime\')) as seizureTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.answerTime\')) as answerTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.releaseTime\')) as releaseTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as callDuration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordPath\')) as recordPath,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.msdData\')) as msdData,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as serviceResult\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/mf_cdr\"}', '0 40 0 * * ?', '3', '0', '1', '1', 'admin', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', NULL, '');
|
||||||
INSERT INTO `sys_job` VALUES (101, 'job.psap.ticket.monitor', 'SYSTEM', 'psap_ticket_monitor', '{}', '0/5 * * * * ?', '3', '0', '1', '1', 'admin', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', NULL, '');
|
INSERT INTO `sys_job` VALUES (101, 'job.psap.ticket.monitor', 'SYSTEM', 'psap_ticket_monitor', '', '0/5 * * * * ?', '3', '0', '1', '1', 'admin', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', NULL, '');
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
17
database/upgrade/sys_dict_data0.sql
Normal file
17
database/upgrade/sys_dict_data0.sql
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for sys_dict_data
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
-- psap callback status
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (500, 500, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (501, 501, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (502, 502, 'callback.status.NO_ANSWER_1', 'NO_ANSWER_1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (503, 503, 'callback.status.NO_ANSWER_2', 'NO_ANSWER_2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (504, 504, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (505, 505, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (506, 506, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
36
database/upgrade/upg_cb_message.sql
Executable file
36
database/upgrade/upg_cb_message.sql
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Data Transfer
|
||||||
|
|
||||||
|
Source Server : omc@192.168.2.223-psap
|
||||||
|
Source Server Type : MariaDB
|
||||||
|
Source Server Version : 100622 (10.6.22-MariaDB-0ubuntu0.22.04.1)
|
||||||
|
Source Host : 192.168.2.223:33066
|
||||||
|
Source Schema : psap_db
|
||||||
|
|
||||||
|
Target Server Type : MariaDB
|
||||||
|
Target Server Version : 100622 (10.6.22-MariaDB-0ubuntu0.22.04.1)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 30/06/2025 16:39:13
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for cb_message
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `cb_message` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||||
|
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||||
|
`message_json` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
|
||||||
|
`status` enum('ACTIVE','INACTIVE') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'INACTIVE',
|
||||||
|
`created_at` bigint(20) NULL DEFAULT current_timestamp(),
|
||||||
|
`updated_at` bigint(20) NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `id`(`id`) USING BTREE,
|
||||||
|
INDEX `idx_ne_time`(`ne_type`, `ne_id`, `created_at`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'CDR事件_MF' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
INSERT IGNORE INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `tag_class`, `tag_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (25010, 25010, 'job.export.cdr.mf', 'Regularly Export MF CDR', 'i18n_en', '', '', '1', 'supervisor', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', 0, '');
|
-- PSAP Menu and Data Dictionary
|
||||||
INSERT IGNORE INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `tag_class`, `tag_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (25011, 25011, 'job.psap.ticket.monitor', 'Callback Ticket Monitor', 'i18n_en', '', '', '1', 'supervisor', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', 0, '');
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25000, 25000, 'menu.psap.agent', 'Agent', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25001, 25001, 'menu.psap.agent.callings', 'Calling Info', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25002, 25002, 'menu.psap.agent.callback', 'CallBack Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25003, 25003, 'callback.status.NEW', 'NEW', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25004, 25004, 'callback.status.IN_PROGRESS', 'IN_PROGRESS', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||||
|
INSERT IGNORE 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 IGNORE 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 IGNORE INTO `sys_dict_data` VALUES (25007, 25007, 'callback.status.TIMEOUT', 'TIMEOUT', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25008, 25008, 'callback.status.PENDING', 'PENDING', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25009, 25009, 'callback.status.CLOSED', 'CLOSED', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25010, 25010, 'job.export.cdr.mf', 'Regularly Export MF CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (25011, 25011, 'job.psap.ticket.monitor', 'Callback Ticket Monitor', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
INSERT IGNORE INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `tag_class`, `tag_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (20010, 20010, 'job.export.cdr.mf', '定期导出MF话单', 'i18n_zh', '', '', '1', 'supervisor', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', 0, '');
|
-- psap 座席相关字典数据
|
||||||
INSERT IGNORE INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `tag_class`, `tag_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (20011, 20011, 'job.psap.ticket.monitor', '回拨工单监控', 'i18n_zh', '', '', '1', 'supervisor', (UNIX_TIMESTAMP(NOW(3)) * 1000), '', 0, '');
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20000, 20000, 'menu.psap.agent', '座席', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20001, 20001, 'menu.psap.agent.callings', '并行话务', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20002, 20002, 'menu.psap.agent.callback', '回拨管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20003, 20003, 'callback.status.NEW', '新建', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784015598, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20004, 20004, 'callback.status.IN_PROGRESS', '处理中', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784045911, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20005, 20005, 'callback.status.NO_ANSWER_1', '未应答1', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784070706, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20006, 20006, 'callback.status.NO_ANSWER_2', '未应答2', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784078301, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20007, 20007, 'callback.status.TIMEOUT', '超时', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784100809, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20008, 20008, 'callback.status.PENDING', '挂起', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784115379, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20009, 20009, 'callback.status.CLOSED', '关闭', 'callback_status', NULL, NULL, '1', 'supervisor', 1749784127612, '', 0, NULL);
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20010, 20010, 'job.export.cdr.mf', '定期导出MF话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT IGNORE INTO `sys_dict_data` VALUES (20011, 20011, 'job.psap.ticket.monitor', '回拨工单监控', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
@@ -78,11 +78,11 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MF网元类型特殊处理, 未接电话的回拨工单流转处理
|
// MF网元类型特殊处理, 未接电话的回拨工单流转处理
|
||||||
if neTypeLower == "mf" && cdrEvent.CDR["agentName"] == "" {
|
if neTypeLower == "mf" && cdrEvent.CDR["recordType"] == "MOC" && cdrEvent.CDR["agentName"] == "" {
|
||||||
// 发送到MF网元
|
// 发送到MF网元
|
||||||
// 构造网元MF的API地址
|
// 构造网元MF的API地址
|
||||||
url := fmt.Sprintf("http://%s:%d/ne/config/data?neType=%s&neId=%s¶mName=agents",
|
url := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/agents",
|
||||||
neInfo.IP, neInfo.Port, neInfo.NeType, neInfo.NeId)
|
neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||||
// 发送HTTP请求获取座席列表
|
// 发送HTTP请求获取座席列表
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -107,48 +107,44 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 调用服务获取最新一个被分配工单的座席和下一个要分配的座席
|
// 调用服务获取最新一个被分配工单的座席和下一个要分配的座席
|
||||||
mfService := ueCallBackTicket.NewCallbackTicketService()
|
mfService := ueCallBackTicket.NewCallbackTicketService()
|
||||||
lastAgent, err := mfService.GetLastAssignedAgent()
|
lastAgentName, err := mfService.GetLastAssignedAgent()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to get last assigned agent", err)
|
log.Error("Failed to get last assigned agent", err)
|
||||||
// 可以继续执行,不返回错误
|
// 可以继续执行,不返回错误
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择下一个要分配的座席
|
// 选择下一个要分配的座席
|
||||||
selectedAgent := mfService.SelectNextAgent(agentResp.Data, lastAgent)
|
selectedAgent := mfService.SelectNextAgent(agentResp.Data, lastAgentName)
|
||||||
|
|
||||||
// 获取分配座席的邮箱
|
if selectedAgent != nil {
|
||||||
agentEmail := ""
|
// 创建回调工单
|
||||||
for _, agent := range agentResp.Data {
|
var updatedAt *int64 = nil
|
||||||
if agent.Name == selectedAgent {
|
ticket := ueCallBackTicket.CallbackTicket{
|
||||||
agentEmail = agent.Email
|
CallerNumber: cdrEvent.CDR["callerParty"].(string),
|
||||||
break
|
CalleeNumber: cdrEvent.CDR["calledParty"].(string),
|
||||||
|
Status: ueCallBackTicket.TicketStatusNew.Enum(),
|
||||||
|
AgentName: selectedAgent.Name,
|
||||||
|
AgentEmail: selectedAgent.Email,
|
||||||
|
AgentMobile: selectedAgent.Mobile,
|
||||||
|
Comment: "",
|
||||||
|
MsdData: cdrEvent.CDR["msdData"].(string),
|
||||||
|
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 != "" {
|
||||||
|
subject := "新工单分配通知"
|
||||||
|
body := fmt.Sprintf("您被分配了一个新的回拨工单,主叫号码:%s", ticket.CallerNumber)
|
||||||
|
go email.SendEmail(selectedAgent.Email, subject, body) // 异步发送
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.Warn("No available agents found for callback ticket")
|
||||||
// 创建回调工单
|
|
||||||
var updatedAt *int64 = nil
|
|
||||||
ticket := ueCallBackTicket.CallbackTicket{
|
|
||||||
CallerNumber: cdrEvent.CDR["callerParty"].(string),
|
|
||||||
CalleeNumber: cdrEvent.CDR["calledParty"].(string),
|
|
||||||
Status: ueCallBackTicket.TicketStatusNew.Enum(),
|
|
||||||
AgentName: selectedAgent,
|
|
||||||
Comment: "",
|
|
||||||
MsdData: cdrEvent.CDR["msdData"].(string),
|
|
||||||
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 agentEmail != "" {
|
|
||||||
subject := "新工单分配通知"
|
|
||||||
body := fmt.Sprintf("您被分配了一个新的回拨工单,主叫号码:%s", ticket.CallerNumber)
|
|
||||||
go email.SendEmail(agentEmail, subject, body) // 异步发送
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MF网元类型特殊处理, 处理座席回拨的工单流转
|
// MF网元类型特殊处理, 处理座席回拨的工单流转
|
||||||
@@ -193,12 +189,12 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取通话信息
|
// 获取通话信息
|
||||||
answerTime, _ := cdrEvent.CDR["answerTime"].(string)
|
seizureTime, _ := cdrEvent.CDR["seizureTime"].(string)
|
||||||
releaseTime, _ := cdrEvent.CDR["releaseTime"].(string)
|
releaseTime, _ := cdrEvent.CDR["releaseTime"].(string)
|
||||||
cause, _ := cdrEvent.CDR["cause"].(string)
|
cause, _ := cdrEvent.CDR["cause"].(string)
|
||||||
|
|
||||||
// 处理回拨结果并更新工单
|
// 处理回拨结果并更新工单
|
||||||
if err := mfService.ProcessCallbackResult(ticket, callDuration, answerTime, releaseTime, cause); err != nil {
|
if err := mfService.ProcessCallbackResult(ticket, callDuration, seizureTime, releaseTime, cause); err != nil {
|
||||||
log.Error("Failed to process callback result", err)
|
log.Error("Failed to process callback result", err)
|
||||||
services.ResponseInternalServerError500ProcessError(w, err)
|
services.ResponseInternalServerError500ProcessError(w, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func ParseCallTag(s string) TicketStatus {
|
|||||||
return TicketStatus(i)
|
return TicketStatus(i)
|
||||||
}
|
}
|
||||||
// 如果转换失败,则按名称匹配(忽略大小写)
|
// 如果转换失败,则按名称匹配(忽略大小写)
|
||||||
switch strings.ToLower(s) {
|
switch strings.ToUpper(s) {
|
||||||
case "NULL":
|
case "NULL":
|
||||||
return TicketStatusNull
|
return TicketStatusNull
|
||||||
case "NEW":
|
case "NEW":
|
||||||
@@ -102,7 +102,9 @@ type CallbackTicket struct {
|
|||||||
CallerNumber string `json:"callerNumber" gorm:"column:caller_number"` // 主叫号码
|
CallerNumber string `json:"callerNumber" gorm:"column:caller_number"` // 主叫号码
|
||||||
CalleeNumber string `json:"calleeNumber" gorm:"column:callee_number"` // 被叫号码
|
CalleeNumber string `json:"calleeNumber" gorm:"column:callee_number"` // 被叫号码
|
||||||
Status string `json:"status" gorm:"column:status"` // 工单状态
|
Status string `json:"status" gorm:"column:status"` // 工单状态
|
||||||
AgentName string `json:"agentName" gorm:"column:agent_name"` // 坐席名称
|
AgentName string `json:"agentName" gorm:"column:agent_name"` // 座席名称
|
||||||
|
AgentEmail string `json:"agentEmail" gorm:"column:agent_email"` // 座席邮箱
|
||||||
|
AgentMobile string `json:"agentMobile" gorm:"column:agent_mobile"` // 座席手机号码
|
||||||
Comment string `json:"comment" gorm:"column:comment"` // 工单备注
|
Comment string `json:"comment" gorm:"column:comment"` // 工单备注
|
||||||
MsdData string `json:"msdData" gorm:"column:msd_data"` // MSD数据
|
MsdData string `json:"msdData" gorm:"column:msd_data"` // MSD数据
|
||||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"` // RM用户ID
|
RmUid string `json:"rmUid" gorm:"column:rm_uid"` // RM用户ID
|
||||||
|
|||||||
@@ -13,10 +13,20 @@ type CallbackTicketService struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构造函数示例
|
// 构造函数改为私有初始化方法
|
||||||
func NewCallbackTicketService() *CallbackTicketService {
|
func NewCallbackTicketService() *CallbackTicketService {
|
||||||
db := dborm.DefaultDB()
|
return &CallbackTicketService{db: nil} // 先不初始化数据库连接
|
||||||
return &CallbackTicketService{db: db}
|
}
|
||||||
|
|
||||||
|
// 获取数据库连接的私有方法
|
||||||
|
func (s *CallbackTicketService) getDB() *gorm.DB {
|
||||||
|
if s.db == nil {
|
||||||
|
s.db = dborm.DefaultDB()
|
||||||
|
if s.db == nil {
|
||||||
|
panic("Cannot establish database connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.db
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectCallbackTicket 根据条件分页查询回调工单
|
// SelectCallbackTicket 根据条件分页查询回调工单
|
||||||
@@ -24,7 +34,7 @@ func (s *CallbackTicketService) SelectCallbackTicket(query CallbackTicketQuery)
|
|||||||
var tickets []CallbackTicket
|
var tickets []CallbackTicket
|
||||||
var total int64
|
var total int64
|
||||||
|
|
||||||
db := s.db.Table("mf_callback_ticket")
|
db := s.getDB().Table("mf_callback_ticket")
|
||||||
|
|
||||||
if query.CallerNumber != "" {
|
if query.CallerNumber != "" {
|
||||||
db = db.Where("caller_number = ?", query.CallerNumber)
|
db = db.Where("caller_number = ?", query.CallerNumber)
|
||||||
@@ -71,13 +81,13 @@ func (s *CallbackTicketService) SelectCallbackTicketByPage(pageNum int, pageSize
|
|||||||
var total int64
|
var total int64
|
||||||
|
|
||||||
// 统计总数
|
// 统计总数
|
||||||
if err := s.db.Table("mf_callback_ticket").Count(&total).Error; err != nil {
|
if err := s.getDB().Table("mf_callback_ticket").Count(&total).Error; err != nil {
|
||||||
return nil, 0, fmt.Errorf("failed to count callback tickets: %w", err)
|
return nil, 0, fmt.Errorf("failed to count callback tickets: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页查询
|
// 分页查询
|
||||||
offset := (pageNum - 1) * pageSize
|
offset := (pageNum - 1) * pageSize
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Limit(pageSize).
|
Limit(pageSize).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Find(&tickets).Error; err != nil {
|
Find(&tickets).Error; err != nil {
|
||||||
@@ -90,7 +100,7 @@ func (s *CallbackTicketService) SelectCallbackTicketByPage(pageNum int, pageSize
|
|||||||
func (s *CallbackTicketService) InsertCallbackTicket(ticket CallbackTicket) error {
|
func (s *CallbackTicketService) InsertCallbackTicket(ticket CallbackTicket) error {
|
||||||
// 判断主叫号码是否已存在未处理完的工单
|
// 判断主叫号码是否已存在未处理完的工单
|
||||||
var existingCount int64
|
var existingCount int64
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("caller_number = ? AND status IN ('NEW', 'PENDING', 'IN_PROGRESS')", ticket.CallerNumber).
|
Where("caller_number = ? AND status IN ('NEW', 'PENDING', 'IN_PROGRESS')", ticket.CallerNumber).
|
||||||
Count(&existingCount).Error; err != nil {
|
Count(&existingCount).Error; err != nil {
|
||||||
return fmt.Errorf("failed to check existing tickets: %w", err)
|
return fmt.Errorf("failed to check existing tickets: %w", err)
|
||||||
@@ -100,7 +110,7 @@ func (s *CallbackTicketService) InsertCallbackTicket(ticket CallbackTicket) erro
|
|||||||
return fmt.Errorf("caller %s already has a pending ticket", ticket.CallerNumber)
|
return fmt.Errorf("caller %s already has a pending ticket", ticket.CallerNumber)
|
||||||
}
|
}
|
||||||
// 这里可以使用ORM或其他方式将ticket插入到数据库中
|
// 这里可以使用ORM或其他方式将ticket插入到数据库中
|
||||||
if err := s.db.Table("mf_callback_ticket").Create(&ticket).Error; err != nil {
|
if err := s.getDB().Table("mf_callback_ticket").Create(&ticket).Error; err != nil {
|
||||||
return fmt.Errorf("failed to insert callback ticket: %w", err)
|
return fmt.Errorf("failed to insert callback ticket: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -115,7 +125,7 @@ func (s *CallbackTicketService) InsertCallbackTicket(ticket CallbackTicket) erro
|
|||||||
// mfCallbackTicketService.SelectCallbackTicketById(12345)
|
// mfCallbackTicketService.SelectCallbackTicketById(12345)
|
||||||
func (s *CallbackTicketService) SelectCallbackTicketById(ticketId int64) (*CallbackTicket, error) {
|
func (s *CallbackTicketService) SelectCallbackTicketById(ticketId int64) (*CallbackTicket, error) {
|
||||||
var ticket CallbackTicket
|
var ticket CallbackTicket
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("ticket_id = ?", ticketId).
|
Where("ticket_id = ?", ticketId).
|
||||||
First(&ticket).Error; err != nil {
|
First(&ticket).Error; err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
@@ -133,7 +143,7 @@ func (s *CallbackTicketService) SelectCallbackTicketById(ticketId int64) (*Callb
|
|||||||
// @example
|
// @example
|
||||||
// mfCallbackTicketService.UpdateCallbackTicket(ticket)
|
// mfCallbackTicketService.UpdateCallbackTicket(ticket)
|
||||||
func (s *CallbackTicketService) UpdateCallbackTicket(ticket CallbackTicket) error {
|
func (s *CallbackTicketService) UpdateCallbackTicket(ticket CallbackTicket) error {
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("ticket_id = ?", ticket.TicketId).
|
Where("ticket_id = ?", ticket.TicketId).
|
||||||
Updates(ticket).Error; err != nil {
|
Updates(ticket).Error; err != nil {
|
||||||
return fmt.Errorf("failed to update callback ticket: %w", err)
|
return fmt.Errorf("failed to update callback ticket: %w", err)
|
||||||
@@ -148,7 +158,7 @@ func (s *CallbackTicketService) UpdateCallbackTicket(ticket CallbackTicket) erro
|
|||||||
// @example
|
// @example
|
||||||
// mfCallbackTicketService.DeleteCallbackTicket(12345)
|
// mfCallbackTicketService.DeleteCallbackTicket(12345)
|
||||||
func (s *CallbackTicketService) DeleteCallbackTicket(ticketId int64) error {
|
func (s *CallbackTicketService) DeleteCallbackTicket(ticketId int64) error {
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("ticket_id = ?", ticketId).
|
Where("ticket_id = ?", ticketId).
|
||||||
Delete(&CallbackTicket{}).Error; err != nil {
|
Delete(&CallbackTicket{}).Error; err != nil {
|
||||||
return fmt.Errorf("failed to delete callback ticket: %w", err)
|
return fmt.Errorf("failed to delete callback ticket: %w", err)
|
||||||
@@ -162,7 +172,7 @@ func (s *CallbackTicketService) DeleteCallbackTicket(ticketId int64) error {
|
|||||||
// @return error 错误信息
|
// @return error 错误信息
|
||||||
func (s *CallbackTicketService) GetLastAssignedAgent() (string, error) {
|
func (s *CallbackTicketService) GetLastAssignedAgent() (string, error) {
|
||||||
var lastTicket CallbackTicket
|
var lastTicket CallbackTicket
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("agent_name <> ''").
|
Where("agent_name <> ''").
|
||||||
Order("created_at DESC").
|
Order("created_at DESC").
|
||||||
First(&lastTicket).Error; err != nil {
|
First(&lastTicket).Error; err != nil {
|
||||||
@@ -181,17 +191,15 @@ func (s *CallbackTicketService) GetLastAssignedAgent() (string, error) {
|
|||||||
// @param agents 座席列表
|
// @param agents 座席列表
|
||||||
// @param lastAgentName 上一个座席名称
|
// @param lastAgentName 上一个座席名称
|
||||||
// @return string 下一个座席名称
|
// @return string 下一个座席名称
|
||||||
func (s *CallbackTicketService) SelectNextAgent(agents []AgentInfo, lastAgentName string) string {
|
func (s *CallbackTicketService) SelectNextAgent(agents []AgentInfo, lastAgentName string) *AgentInfo {
|
||||||
if len(agents) == 0 {
|
if len(agents) == 0 {
|
||||||
return ""
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认选第一个座席
|
var firstAgent *AgentInfo = &agents[0]
|
||||||
selectedAgent := agents[0].Name
|
|
||||||
|
|
||||||
// 如果没有上一个座席,直接返回第一个
|
// 如果没有上一个座席,直接返回第一个
|
||||||
if lastAgentName == "" {
|
if lastAgentName == "" {
|
||||||
return selectedAgent
|
return firstAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找到上一个座席的下一个
|
// 找到上一个座席的下一个
|
||||||
@@ -199,19 +207,19 @@ func (s *CallbackTicketService) SelectNextAgent(agents []AgentInfo, lastAgentNam
|
|||||||
for i, agent := range agents {
|
for i, agent := range agents {
|
||||||
if foundLastAgent {
|
if foundLastAgent {
|
||||||
// 找到上一个座席的下一个
|
// 找到上一个座席的下一个
|
||||||
return agent.Name
|
return &agent
|
||||||
}
|
}
|
||||||
if agent.Name == lastAgentName {
|
if agent.Name == lastAgentName {
|
||||||
foundLastAgent = true
|
foundLastAgent = true
|
||||||
// 如果是最后一个座席,则循环回第一个
|
// 如果是最后一个座席,则循环回第一个
|
||||||
if i == len(agents)-1 {
|
if i == len(agents)-1 {
|
||||||
return agents[0].Name
|
return firstAgent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没找到上一个座席(可能被删除了),使用第一个座席
|
// 如果没找到上一个座席(可能被删除了),使用第一个座席
|
||||||
return selectedAgent
|
return firstAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindCallbackTicketByAgentAndCaller 通过座席号码和主叫号码查找符合条件的工单
|
// FindCallbackTicketByAgentAndCaller 通过座席号码和主叫号码查找符合条件的工单
|
||||||
@@ -223,7 +231,7 @@ func (s *CallbackTicketService) SelectNextAgent(agents []AgentInfo, lastAgentNam
|
|||||||
func (s *CallbackTicketService) FindCallbackTicketByAgentAndCaller(agentName string, callerNumber string) (*CallbackTicket, error) {
|
func (s *CallbackTicketService) FindCallbackTicketByAgentAndCaller(agentName string, callerNumber string) (*CallbackTicket, error) {
|
||||||
var ticket CallbackTicket
|
var ticket CallbackTicket
|
||||||
|
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("agent_name = ? AND caller_number = ? AND status IN ('NEW', 'PENDING', 'IN_PROGRESS', 'NO_ANSWER_1', 'NO_ANSWER_2')",
|
Where("agent_name = ? AND caller_number = ? AND status IN ('NEW', 'PENDING', 'IN_PROGRESS', 'NO_ANSWER_1', 'NO_ANSWER_2')",
|
||||||
agentName, callerNumber).
|
agentName, callerNumber).
|
||||||
Order("created_at DESC").
|
Order("created_at DESC").
|
||||||
@@ -245,7 +253,7 @@ func (s *CallbackTicketService) FindCallbackTicketByAgentAndCaller(agentName str
|
|||||||
// @param releaseTime 释放时间
|
// @param releaseTime 释放时间
|
||||||
// @param cause 释放原因
|
// @param cause 释放原因
|
||||||
// @return error 错误信息
|
// @return error 错误信息
|
||||||
func (s *CallbackTicketService) ProcessCallbackResult(ticket *CallbackTicket, callDuration float64, answerTime string, releaseTime string, cause string) error {
|
func (s *CallbackTicketService) ProcessCallbackResult(ticket *CallbackTicket, callDuration float64, seizureTime string, releaseTime string, cause string) error {
|
||||||
if ticket == nil {
|
if ticket == nil {
|
||||||
return fmt.Errorf("ticket cannot be nil")
|
return fmt.Errorf("ticket cannot be nil")
|
||||||
}
|
}
|
||||||
@@ -258,7 +266,7 @@ func (s *CallbackTicketService) ProcessCallbackResult(ticket *CallbackTicket, ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构建评论内容
|
// 构建评论内容
|
||||||
comment := fmt.Sprintf("回拨时间: %s, 释放时间: %s, 原因: %s", answerTime, releaseTime, cause)
|
comment := fmt.Sprintf("回拨时间: %s, 释放时间: %s, 原因: %s", seizureTime, releaseTime, cause)
|
||||||
|
|
||||||
// 根据通话时长判断处理结果
|
// 根据通话时长判断处理结果
|
||||||
if callDuration > 0 {
|
if callDuration > 0 {
|
||||||
@@ -288,7 +296,7 @@ func (s *CallbackTicketService) ProcessCallbackResult(ticket *CallbackTicket, ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新工单
|
// 更新工单
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("ticket_id = ?", ticket.TicketId).
|
Where("ticket_id = ?", ticket.TicketId).
|
||||||
Updates(updatedTicket).Error; err != nil {
|
Updates(updatedTicket).Error; err != nil {
|
||||||
return fmt.Errorf("failed to update callback ticket: %w", err)
|
return fmt.Errorf("failed to update callback ticket: %w", err)
|
||||||
@@ -310,7 +318,7 @@ func (s *CallbackTicketService) FindTimeoutTickets(status string, timeoutMicros
|
|||||||
|
|
||||||
// 查询超时的工单
|
// 查询超时的工单
|
||||||
var tickets []CallbackTicket
|
var tickets []CallbackTicket
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("status = ? AND created_at < ? AND (updated_at IS NULL OR updated_at < ?)",
|
Where("status = ? AND created_at < ? AND (updated_at IS NULL OR updated_at < ?)",
|
||||||
status, timeoutBeforeMicros, timeoutBeforeMicros).
|
status, timeoutBeforeMicros, timeoutBeforeMicros).
|
||||||
Find(&tickets).Error; err != nil {
|
Find(&tickets).Error; err != nil {
|
||||||
@@ -338,7 +346,7 @@ func (s *CallbackTicketService) UpdateTicketToTimeout(ticket *CallbackTicket, or
|
|||||||
Comment: fmt.Sprintf("%s - 工单状态为 %s 处理超时,系统自动更新为超时状态", ticket.Comment, originalStatus),
|
Comment: fmt.Sprintf("%s - 工单状态为 %s 处理超时,系统自动更新为超时状态", ticket.Comment, originalStatus),
|
||||||
UpdatedAt: &now,
|
UpdatedAt: &now,
|
||||||
}
|
}
|
||||||
if err := s.db.Table("mf_callback_ticket").
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
Where("ticket_id = ?", ticket.TicketId).
|
Where("ticket_id = ?", ticket.TicketId).
|
||||||
Updates(updatedTicket).Error; err != nil {
|
Updates(updatedTicket).Error; err != nil {
|
||||||
return fmt.Errorf("更新工单 %d 状态失败: %w", ticket.TicketId, err)
|
return fmt.Errorf("更新工单 %d 状态失败: %w", ticket.TicketId, err)
|
||||||
@@ -348,37 +356,62 @@ func (s *CallbackTicketService) UpdateTicketToTimeout(ticket *CallbackTicket, or
|
|||||||
lastAgent := ticket.AgentName
|
lastAgent := ticket.AgentName
|
||||||
newAgent := s.SelectNextAgent(agents, lastAgent)
|
newAgent := s.SelectNextAgent(agents, lastAgent)
|
||||||
|
|
||||||
// 查找新座席邮箱
|
// 3. 创建新工单
|
||||||
newAgentEmail := ""
|
if newAgent != nil {
|
||||||
for _, agent := range agents {
|
newTicket := CallbackTicket{
|
||||||
if agent.Name == newAgent {
|
CallerNumber: ticket.CallerNumber,
|
||||||
newAgentEmail = agent.Email
|
CalleeNumber: ticket.CalleeNumber,
|
||||||
break
|
Status: TicketStatusNew.Enum(),
|
||||||
|
AgentName: newAgent.Name,
|
||||||
|
AgentEmail: newAgent.Email,
|
||||||
|
AgentMobile: newAgent.Mobile,
|
||||||
|
Comment: fmt.Sprintf("由超时工单 %d 自动重建", ticket.TicketId),
|
||||||
|
MsdData: ticket.MsdData,
|
||||||
|
RmUid: ticket.RmUid,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: nil,
|
||||||
|
}
|
||||||
|
if err := s.getDB().Table("mf_callback_ticket").Create(&newTicket).Error; err != nil {
|
||||||
|
return fmt.Errorf("创建新工单失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新工单分配后发送邮件通知
|
||||||
|
if newAgent.Email != "" {
|
||||||
|
subject := "新工单自动重建通知"
|
||||||
|
body := fmt.Sprintf("您被分配了一个自动重建的回拨工单,主叫号码:%s", newTicket.CallerNumber)
|
||||||
|
go email.SendEmail(newAgent.Email, subject, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
// 3. 创建新工单
|
}
|
||||||
newTicket := CallbackTicket{
|
|
||||||
CallerNumber: ticket.CallerNumber,
|
// FindNearlyTimeoutTickets 查询即将超时的工单
|
||||||
CalleeNumber: ticket.CalleeNumber,
|
func (s *CallbackTicketService) FindNearlyTimeoutTickets(status string, timeoutMicros int64, aheadMicros int64) ([]CallbackTicket, error) {
|
||||||
Status: TicketStatusNew.Enum(),
|
nowMicros := time.Now().UnixMicro()
|
||||||
AgentName: newAgent,
|
timeoutBeforeMicros := nowMicros - timeoutMicros
|
||||||
Comment: fmt.Sprintf("由超时工单 %d 自动重建", ticket.TicketId),
|
nearlyTimeoutBeforeMicros := nowMicros - (timeoutMicros - aheadMicros)
|
||||||
MsdData: ticket.MsdData,
|
|
||||||
RmUid: ticket.RmUid,
|
var tickets []CallbackTicket
|
||||||
CreatedAt: now,
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
UpdatedAt: nil,
|
Where("status = ? AND created_at >= ? AND created_at < ? AND (updated_at IS NULL OR updated_at < ?)",
|
||||||
}
|
status, timeoutBeforeMicros, nearlyTimeoutBeforeMicros, nearlyTimeoutBeforeMicros).
|
||||||
if err := s.db.Table("mf_callback_ticket").Create(&newTicket).Error; err != nil {
|
Find(&tickets).Error; err != nil {
|
||||||
return fmt.Errorf("创建新工单失败: %w", err)
|
return nil, fmt.Errorf("查询即将超时工单失败: %w", err)
|
||||||
}
|
}
|
||||||
|
return tickets, nil
|
||||||
// 新工单分配后发送邮件通知
|
}
|
||||||
if newAgentEmail != "" {
|
|
||||||
subject := "新工单自动重建通知"
|
// 新增方法:坐席开始处理工单
|
||||||
body := fmt.Sprintf("您被分配了一个自动重建的回拨工单,主叫号码:%s", newTicket.CallerNumber)
|
func (s *CallbackTicketService) StartProcessingTicket(ticketId int64) error {
|
||||||
go email.SendEmail(newAgentEmail, subject, body)
|
now := time.Now().UnixMicro()
|
||||||
}
|
if err := s.getDB().Table("mf_callback_ticket").
|
||||||
|
Where("ticket_id = ? AND status = ?", ticketId, TicketStatusNew.Enum()).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"status": TicketStatusInProgress.Enum(),
|
||||||
|
"updated_at": now,
|
||||||
|
"comment": "坐席开始处理工单",
|
||||||
|
}).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to update ticket to IN_PROGRESS: %w", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ alarm:
|
|||||||
password: "1000smtp@omc!"
|
password: "1000smtp@omc!"
|
||||||
tlsSkipVerify: true
|
tlsSkipVerify: true
|
||||||
alarmSMSForward:
|
alarmSMSForward:
|
||||||
enable: true
|
enable: false
|
||||||
mobileList: "1006,1008"
|
mobileList: "1006,1008"
|
||||||
smscAddr: "192.168.14.212:2775"
|
smscAddr: "192.168.14.212:2775"
|
||||||
systemID: "123456"
|
systemID: "123456"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
processorMonitorSysResource "be.ems/src/modules/crontask/processor/monitor_sys_resource"
|
processorMonitorSysResource "be.ems/src/modules/crontask/processor/monitor_sys_resource"
|
||||||
processorNeConfigBackup "be.ems/src/modules/crontask/processor/ne_config_backup"
|
processorNeConfigBackup "be.ems/src/modules/crontask/processor/ne_config_backup"
|
||||||
processorNeDataUDM "be.ems/src/modules/crontask/processor/ne_data_udm"
|
processorNeDataUDM "be.ems/src/modules/crontask/processor/ne_data_udm"
|
||||||
|
"be.ems/src/modules/crontask/processor/psap_ticket_monitor"
|
||||||
"be.ems/src/modules/crontask/processor/removeFile"
|
"be.ems/src/modules/crontask/processor/removeFile"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,4 +31,5 @@ func InitCronQueue() {
|
|||||||
cron.CreateQueue("genNeStateAlarm", genNeStateAlarm.NewProcessor)
|
cron.CreateQueue("genNeStateAlarm", genNeStateAlarm.NewProcessor)
|
||||||
cron.CreateQueue("exportTable", exportTable.NewProcessor)
|
cron.CreateQueue("exportTable", exportTable.NewProcessor)
|
||||||
cron.CreateQueue("removeFile", removeFile.NewProcessor)
|
cron.CreateQueue("removeFile", removeFile.NewProcessor)
|
||||||
|
cron.CreateQueue("psap_ticket_monitor", psap_ticket_monitor.NewProcessor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
ueCallBackTicket "be.ems/features/ue/mf_callback_ticket"
|
ueCallBackTicket "be.ems/features/ue/mf_callback_ticket"
|
||||||
|
"be.ems/lib/email"
|
||||||
"be.ems/lib/log"
|
"be.ems/lib/log"
|
||||||
"be.ems/src/framework/cron"
|
"be.ems/src/framework/cron"
|
||||||
"be.ems/src/framework/logger"
|
|
||||||
neService "be.ems/src/modules/network_element/service"
|
neService "be.ems/src/modules/network_element/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ func (s *PsapTicketMonitor) Execute(data any) (any, error) {
|
|||||||
s.count++ // 执行次数加一
|
s.count++ // 执行次数加一
|
||||||
options := data.(cron.JobData)
|
options := data.(cron.JobData)
|
||||||
sysJob := options.SysJob
|
sysJob := options.SysJob
|
||||||
logger.Infof("执行工单监控任务 %v 任务ID %s", options.Repeat, sysJob.JobID)
|
log.Infof("执行工单监控任务 %v 任务ID %s", options.Repeat, sysJob.JobID)
|
||||||
|
|
||||||
// 返回结果,用于记录执行结果
|
// 返回结果,用于记录执行结果
|
||||||
result := map[string]any{
|
result := map[string]any{
|
||||||
@@ -37,10 +38,10 @@ func (s *PsapTicketMonitor) Execute(data any) (any, error) {
|
|||||||
// 处理超时的NEW状态工单 (60分钟)
|
// 处理超时的NEW状态工单 (60分钟)
|
||||||
newTicketsUpdated, err := s.handleTimeoutTickets(
|
newTicketsUpdated, err := s.handleTimeoutTickets(
|
||||||
ueCallBackTicket.TicketStatusNew.Enum(),
|
ueCallBackTicket.TicketStatusNew.Enum(),
|
||||||
60*1000000, // 60分钟(微秒)
|
1*60*1000000, // 1分钟(微秒)
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("处理NEW状态超时工单失败: %v", err)
|
log.Errorf("处理NEW状态超时工单失败: %v", err)
|
||||||
}
|
}
|
||||||
result["newTicketsUpdated"] = newTicketsUpdated
|
result["newTicketsUpdated"] = newTicketsUpdated
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ func (s *PsapTicketMonitor) Execute(data any) (any, error) {
|
|||||||
60*60*1000000, // 60分钟(微秒)
|
60*60*1000000, // 60分钟(微秒)
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("处理IN_PROGRESS状态超时工单失败: %v", err)
|
log.Errorf("处理IN_PROGRESS状态超时工单失败: %v", err)
|
||||||
}
|
}
|
||||||
result["inProgressTicketsUpdated"] = inProgressTicketsUpdated
|
result["inProgressTicketsUpdated"] = inProgressTicketsUpdated
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ func (s *PsapTicketMonitor) Execute(data any) (any, error) {
|
|||||||
4*60*60*1000000, // 4小时(微秒)
|
4*60*60*1000000, // 4小时(微秒)
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("处理NO_ANSWER_1状态超时工单失败: %v", err)
|
log.Errorf("处理NO_ANSWER_1状态超时工单失败: %v", err)
|
||||||
}
|
}
|
||||||
result["noAnswer1TicketsUpdated"] = noAnswer1TicketsUpdated
|
result["noAnswer1TicketsUpdated"] = noAnswer1TicketsUpdated
|
||||||
|
|
||||||
@@ -70,15 +71,69 @@ func (s *PsapTicketMonitor) Execute(data any) (any, error) {
|
|||||||
8*60*60*1000000, // 8小时(微秒)
|
8*60*60*1000000, // 8小时(微秒)
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("处理NO_ANSWER_2状态超时工单失败: %v", err)
|
log.Errorf("处理NO_ANSWER_2状态超时工单失败: %v", err)
|
||||||
}
|
}
|
||||||
result["noAnswer2TicketsUpdated"] = noAnswer2TicketsUpdated
|
result["noAnswer2TicketsUpdated"] = noAnswer2TicketsUpdated
|
||||||
|
|
||||||
// 汇总结果
|
// 汇总结果
|
||||||
totalUpdated := newTicketsUpdated + inProgressTicketsUpdated + noAnswer1TicketsUpdated + noAnswer2TicketsUpdated
|
totalUpdated := newTicketsUpdated + inProgressTicketsUpdated +
|
||||||
|
noAnswer1TicketsUpdated + noAnswer2TicketsUpdated
|
||||||
result["totalUpdated"] = totalUpdated
|
result["totalUpdated"] = totalUpdated
|
||||||
|
|
||||||
logger.Infof("工单监控任务完成,共处理 %d 个超时工单", totalUpdated)
|
log.Infof("工单监控任务完成,共处理 %d 个超时工单", totalUpdated)
|
||||||
|
|
||||||
|
// 处理超时的NEW状态工单 (60分钟)
|
||||||
|
newTicketsNearlyTimeout, err := s.handleNearlyTimeoutTickets(
|
||||||
|
ueCallBackTicket.TicketStatusNew.Enum(),
|
||||||
|
60*60*1000000, // 60分钟(微秒)
|
||||||
|
10*60*1000000, // 提前10分钟提醒(微秒)
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("处理NEW状态超时工单失败: %v", err)
|
||||||
|
}
|
||||||
|
result["newTicketsNearlyTimeout"] = newTicketsNearlyTimeout
|
||||||
|
|
||||||
|
// 处理超时的IN_PROGRESS状态工单 (60分钟)
|
||||||
|
inProgressTicketsNearlyTimeout, err := s.handleNearlyTimeoutTickets(
|
||||||
|
ueCallBackTicket.TicketStatusInProgress.Enum(),
|
||||||
|
60*60*1000000, // 60分钟(微秒)
|
||||||
|
10*60*1000000, // 提前10分钟提醒(微秒)
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("处理IN_PROGRESS状态超时工单失败: %v", err)
|
||||||
|
}
|
||||||
|
result["inProgressTicketsNearlyTimeout"] = inProgressTicketsNearlyTimeout
|
||||||
|
|
||||||
|
// 处理超时的NO_ANSWER_1状态工单 (4小时)
|
||||||
|
noAnswer1TicketsNearlyTimeout, err := s.handleNearlyTimeoutTickets(
|
||||||
|
ueCallBackTicket.TicketStatusNoAnswer1.Enum(),
|
||||||
|
4*60*60*1000000, // 4小时(微秒)
|
||||||
|
10*60*1000000, // 提前10分钟提醒(微秒)
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("处理NO_ANSWER_1状态超时工单失败: %v", err)
|
||||||
|
}
|
||||||
|
result["noAnswer1TicketsNearlyTimeout"] = noAnswer1TicketsNearlyTimeout
|
||||||
|
|
||||||
|
// 处理超时的NO_ANSWER_2状态工单 (8小时)
|
||||||
|
noAnswer2TicketsNearlyTimeout, err := s.handleNearlyTimeoutTickets(
|
||||||
|
ueCallBackTicket.TicketStatusNoAnswer2.Enum(),
|
||||||
|
8*60*60*1000000, // 8小时(微秒)
|
||||||
|
10*60*1000000, // 提前10分钟提醒(微秒)
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("处理NO_ANSWER_2状态即将超时工单失败: %v", err)
|
||||||
|
}
|
||||||
|
result["noAnswer2TicketsNearlyTimeout"] = noAnswer2TicketsNearlyTimeout
|
||||||
|
|
||||||
|
// 汇总结果
|
||||||
|
totalTicketsNearlyTimeout := newTicketsNearlyTimeout + inProgressTicketsNearlyTimeout +
|
||||||
|
noAnswer1TicketsNearlyTimeout + noAnswer2TicketsNearlyTimeout
|
||||||
|
|
||||||
|
result["totalTicketsNearlyTimeout"] = totalTicketsNearlyTimeout
|
||||||
|
|
||||||
|
log.Infof("工单监控任务完成,共处理 %d 个即将超时工单", totalUpdated)
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,8 +155,8 @@ func (s *PsapTicketMonitor) handleTimeoutTickets(status string, timeoutMicros in
|
|||||||
// 获取网元信息
|
// 获取网元信息
|
||||||
neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(ticket.RmUid)
|
neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(ticket.RmUid)
|
||||||
// 构造网元MF的API地址
|
// 构造网元MF的API地址
|
||||||
url := fmt.Sprintf("http://%s:%d/ne/config/data?neType=%s&neId=%s¶mName=agents",
|
url := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/agents",
|
||||||
neInfo.IP, neInfo.Port, neInfo.NeType, neInfo.NeId)
|
neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||||
// 发送HTTP请求获取座席列表
|
// 发送HTTP请求获取座席列表
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -132,3 +187,65 @@ func (s *PsapTicketMonitor) handleTimeoutTickets(status string, timeoutMicros in
|
|||||||
|
|
||||||
return updatedCount, nil
|
return updatedCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleTimeoutTickets 处理指定状态的超时工单
|
||||||
|
func (s *PsapTicketMonitor) handleNearlyTimeoutTickets(status string, timeoutMicros int64, aheadMicros int64) (int, error) {
|
||||||
|
// 查询超时的工单
|
||||||
|
tickets, err := s.callbackTicketService.FindNearlyTimeoutTickets(status, timeoutMicros, aheadMicros)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tickets) == 0 {
|
||||||
|
return 0, nil // 没有即将超时工单
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新超时工单状态
|
||||||
|
var updatedCount int
|
||||||
|
for _, ticket := range tickets {
|
||||||
|
if ticket.AgentEmail != "" {
|
||||||
|
subject := "工单即将超时提醒"
|
||||||
|
body := fmt.Sprintf("您负责的回拨工单(主叫号码:%s)即将超时,请及时处理。", ticket.CallerNumber)
|
||||||
|
go email.SendEmail(ticket.AgentEmail, subject, body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedCount, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PsapTicketMonitor) GetAgentEmail(ticket ueCallBackTicket.CallbackTicket) string {
|
||||||
|
// 获取网元信息
|
||||||
|
neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(ticket.RmUid)
|
||||||
|
// 构造网元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)
|
||||||
|
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)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找当前工单分配的座席邮箱
|
||||||
|
agentEmail := ""
|
||||||
|
for _, agent := range agentResp.Data {
|
||||||
|
if agent.Name == ticket.AgentName {
|
||||||
|
agentEmail = agent.Email
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return agentEmail
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user