Forráskód Böngészése

tojson问题修复

刘威 5 hónapja
szülő
commit
34ec917db4

+ 227 - 158
src/core/callcenter/api.py

@@ -2,16 +2,29 @@
 # encoding:utf-8
 
 import json
-from urllib.parse import urlparse
-from typing import Dict, Any, Optional
+from typing import Dict, Any, Optional, List
 
+from src.core.callcenter.constant import get_json_dict
 from src.core.callcenter.exception import SipUriSyntaxException
 from src.core.datasource import SIP_SERVER
 from src.core.callcenter.esl.constant.esl_constant import SPLIT, SIP_HEADER
-from src.core.callcenter.enumeration import CallType, DeviceType
+from src.core.callcenter.enumeration import CallType, DeviceType, Direction, CdrType, NextType
 
 
-class AgentCallRequest:
+class BaseApi:
+    @classmethod
+    def from_json(cls, json_string):
+        data = get_json_dict(json_string)
+        return cls(**data)
+
+    def to_json_string(self):
+        return json.dumps(self, default=lambda x: x.__dict__, ensure_ascii=False)
+
+    def __repr__(self):
+        return self.to_json_string()
+
+
+class AgentCallRequest(BaseApi):
     """
     呼叫请求对象
     """
@@ -39,16 +52,8 @@ class AgentCallRequest:
         # 随路数据
         self.follow_data = follow_data
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
 
-    @classmethod
-    def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
-
-
-class AgentRequest:
+class AgentRequest(BaseApi):
     def __init__(self, saas_id, agent_number, agent_name, out_id, agent_password, agent_type, phone_number, distribute,
                  agent_state, identity_type):
         # 租户隔离
@@ -73,7 +78,7 @@ class AgentRequest:
         self.identity_type = identity_type
 
 
-class AgentQueryRequest:
+class AgentQueryRequest(BaseApi):
     def __init__(self, saas_id, agent_number, out_id, agent_type, agent_name, page=1, size=10):
         # 租户隔离
         self.saas_id = saas_id
@@ -89,13 +94,13 @@ class AgentQueryRequest:
         self.size = size
 
 
-class AgentActionRequest:
+class AgentActionRequest(BaseApi):
     """
     坐席操作
     """
 
     def __init__(self, saas_id, agent_id, agent_number=None, out_id=None, identity_type=None, scene='manual'):
-        self.saas_id =saas_id
+        self.saas_id = saas_id
         # 坐席工号
         self.agent_id = agent_id
         # # 坐席工号
@@ -107,26 +112,20 @@ class AgentActionRequest:
         # 场景 manual:手动外呼; robot:机器人外呼; monitor:监听
         self.scene = scene
 
-    @classmethod
-    def from_json(cls, data):
-        return cls(**data)
-
 
-class HumanServiceQueryRequest:
+class HumanServiceQueryRequest(BaseApi):
     """人工组查询"""
+
     def __init__(self, saas_id, service_id, agent_state, agent_ids: Dict[str, Any] = {}):
         self.saasId = saas_id
         self.serviceId = service_id
         self.agentState = agent_state,
         self.agentIds = agent_ids
 
-    @classmethod
-    def from_json(cls, data):
-        return cls(**data)
 
-
-class AgentMonitorData:
+class AgentMonitorData(BaseApi):
     """坐席状态信息"""
+
     def __init__(self, saas_id=None, agent_num=None, agent_name=None, out_id=None,
                  check_state=None, online_state=None, check_in_time=None, check_out_time=None,
                  service_state=None, busy_time=None, idle_time=None, call_time=None, hang_time=None,
@@ -150,20 +149,14 @@ class AgentMonitorData:
         self.check_scene = check_scene
 
 
-class AgentEventData:
+class AgentEventData(BaseApi):
     def __init__(self, app_code, user_id, data: Dict[str, Any] = {}):
         self.appCode = app_code
         self.userId = user_id
         self.data = data
 
-    def __repr__(self):
-        return self.to_json_string()
-
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
 
-class AgentStateData:
+class AgentStateData(BaseApi):
     def __init__(self, _s=None, _t=None, status=None, time=None, assign_time=None, phone_num=None):
         self._s = _s
         self._t = _t
@@ -172,11 +165,8 @@ class AgentStateData:
         self.assign_time = assign_time
         self.phone_num = phone_num
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
 
-class HangupCallRequest:
+class HangupCallRequest(BaseApi):
     def __init__(self, saas_id, call_id, agent_number):
         # saasId(必填)
         self.saas_id = saas_id
@@ -186,7 +176,7 @@ class HangupCallRequest:
         self.agent_number = agent_number
 
 
-class CheckInCallRequest:
+class CheckInCallRequest(BaseApi):
     """检查是否在通话中实体"""
 
     def __init__(self, saas_id, agent_number):
@@ -194,9 +184,9 @@ class CheckInCallRequest:
         self.agent_number = agent_number
 
 
-class MakeCallContext:
+class MakeCallContext(BaseApi):
 
-    def __init__(self, 
+    def __init__(self,
                  pbx_server=SIP_SERVER,
                  route_gateway_name="gateway-fxo",
                  display: Optional[str] = None,
@@ -372,12 +362,12 @@ class SipURI:
         return self.userinfo
 
 
-class AgentInfo:
-    def __init__(self, sass_id=None, agent_number=None, realm=None, sip_server=None,
+class AgentInfo(BaseApi):
+    def __init__(self, saas_id=None, agent_number=None, realm=None, sip_server=None,
                  call_id=None, device_id=None, real_device_id=None, line_id=None, fs_user=None, domain=None,
                  service_time=0, max_ready_time=0, total_ready_time=0, ready_times=0, not_ready_times=0,
                  total_after_time=0, max_talk_time=0, total_talk_time=0, total_ring_times=0, total_answer_times=0):
-        self.sass_id = sass_id
+        self.saas_id = saas_id
         self.agent_number = agent_number
         self.realm = realm
         self.sip_server = sip_server
@@ -429,16 +419,8 @@ class AgentInfo:
         """
         return self.fs_user is None or self.fs_user is True
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
-    @classmethod
-    def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
-
 
-class CallInfo:
+class CallInfo(BaseApi):
     def __init__(self, core_uuid=None, call_id=None, conference=None, saas_id=None, group_id=None,
                  hidden_customer=0, caller_display=None, caller=None, called_display=None, called=None,
                  number_location=None, agent_key=None, agent_name=None, login_type=None, ivr_id=None, task_id=None,
@@ -446,8 +428,9 @@ class CallInfo:
                  call_time=None, call_type=None, direction=None, answer_flag=None, wait_time=None, answer_count=0,
                  hangup_dir=None, sdk_hangup=0, hangup_code=None, answer_time=None, end_time=None, talk_time=None,
                  frist_queue_time=None, queue_start_time=None, queue_end_time=None, overflow_count=0,
-                 uuid1=None, uuid2=None, cdr_notify_url=None, queue_level=None, device_list=[], device_info_map={},
-                 follow_data={}, process_data={}, next_commands=[], call_details=[]):
+                 uuid1=None, uuid2=None, cdr_notify_url=None, queue_level=None, device_list=[],
+                 device_info_map: Dict[str, Any] = {}, follow_data: Dict[str, Any] = {},
+                 process_data: Dict[str, Any] = {}, next_commands=[], call_details=[]):
         self.core_uuid = core_uuid  # 通话唯一标识
         self.call_id = call_id  # 通话唯一标识
         self.conference = conference  # 会议号
@@ -497,31 +480,94 @@ class CallInfo:
         self.next_commands = next_commands  # 执行下一步命令
         self.call_details = call_details  # 电话流程
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
     @classmethod
     def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
+        data = get_json_dict(json_string)
+        call_type = CallType.get_by_code(data.get('call_type'))
+        direction = Direction.get_by_code(data.get('direction'))
+        device_list = [DeviceInfo(**x) for x in data.get('device_list', [])]
+        device_info_map: Dict[str, Any] = {key: DeviceInfo(**value) for key, value in data.get('device_info_map', {}).items()}
+        follow_data: Dict[str, Any] = {key: value for key, value in data.get('follow_data', {}).items()}
+        process_data: Dict[str, Any] = {key: value for key, value in data.get('process_data', {}).items()}
+        next_commands = [NextCommand(**x) for x in data.get('next_commands', [])]
+        call_details = [CallDetail(**x) for x in data.get('call_details', [])]
+
+        return cls(core_uuid=data.get('core_uuid'), call_id=data.get('call_id'), conference=data.get('conference'),
+                   saas_id=data.get('saas_id'), group_id=data.get('group_id'),
+                   hidden_customer=data.get('hidden_customer'), caller_display=data.get('caller_display'),
+                   caller=data.get('caller'), called_display=data.get('called_display'), called=data.get('called'),
+                   number_location=data.get('number_location'), agent_key=data.get('agent_key'),
+                   agent_name=data.get('agent_name'), login_type=data.get('login_type'), ivr_id=data.get('ivr_id'),
+                   task_id=data.get('task_id'), media_host=data.get('media_host'), cti_host=data.get('cti_host'),
+                   client_host=data.get('client_host'), record=data.get('record'), record2=data.get('record2'),
+                   record_time=data.get('record_time'), call_time=data.get('call_time'),
+                   call_type=call_type, direction=direction,
+                   answer_flag=data.get('answer_flag'), wait_time=data.get('wait_time'),
+                   answer_count=data.get('answer_count'), hangup_dir=data.get('hangup_dir'),
+                   sdk_hangup=data.get('sdk_hangup'), hangup_code=data.get('hangup_code'),
+                   answer_time=data.get('answer_time'), end_time=data.get('end_time'), talk_time=data.get('talk_time'),
+                   frist_queue_time=data.get('frist_queue_time'), queue_start_time=data.get('queue_start_time'),
+                   queue_end_time=data.get('queue_end_time'), overflow_count=data.get('overflow_count'),
+                   uuid1=data.get('uuid1'), uuid2=data.get('uuid2'), cdr_notify_url=data.get('cdr_notify_url'),
+                   queue_level=data.get('queue_level'), device_list=device_list,
+                   device_info_map=device_info_map, follow_data=follow_data, process_data=process_data,
+                   next_commands=next_commands, call_details=call_details)
 
-    # def __repr__(self):
-    #     return (f"CallInfo(core_uuid={self.core_uuid}, call_id={self.call_id}, conference={self.conference}, "
-    #             f"company_id={self.company_id}, group_id={self.group_id}, hidden_customer={self.hidden_customer}, "
-    #             f"caller_display={self.caller_display}, caller={self.caller}, called_display={self.called_display}, "
-    #             f"called={self.called}, number_location={self.number_location}, agent_key={self.agent_key}, "
-    #             f"agent_name={self.agent_name}, login_type={self.login_type}, ivr_id={self.ivr_id}, task_id={self.task_id}, "
-    #             f"media_host={self.media_host}, cti_host={self.cti_host}, client_host={self.client_host}, record={self.record}, "
-    #             f"record2={self.record2}, record_time={self.record_time}, call_time={self.call_time}, call_type={self.call_type}, "
-    #             f"direction={self.direction}, answer_flag={self.answer_flag}, wait_time={self.wait_time}, "
-    #             f"answer_count={self.answer_count}, hangup_dir={self.hangup_dir}, sdk_hangup={self.sdk_hangup}, "
-    #             f"hangup_code={self.hangup_code}, answer_time={self.answer_time}, end_time={self.end_time}, "
-    #             f"talk_time={self.talk_time}, frist_queue_time={self.frist_queue_time}, queue_start_time={self.queue_start_time}, "
-    #             f"queue_end_time={self.queue_end_time}, overflow_count={self.overflow_count}, uuid1={self.uuid1}, uuid2={self.uuid2}, "
-    #             f"cdr_notify_url={self.cdr_notify_url}, queue_level={self.queue_level})")
-
-
-class DeviceInfo:
+    def to_json_string(self):
+        new_dict = {
+            "core_uuid": self.core_uuid,
+            "call_id": self.call_id,
+            "conference": self.conference,
+            "saas_id": self.saas_id,
+            "group_id": self.group_id,
+            "hidden_customer": self.hidden_customer,
+            "caller_display": self.caller_display,
+            "caller": self.caller,
+            "called_display": self.called_display,
+            "called": self.called,
+            "number_location": self.number_location,
+            "agent_key": self.agent_key,
+            "agent_name": self.agent_name,
+            "login_type": self.login_type,
+            "ivr_id": self.ivr_id,
+            "task_id": self.task_id,
+            "media_host": self.media_host,
+            "cti_host": self.cti_host,
+            "client_host": self.client_host,
+            "record": self.record,
+            "record2": self.record2,
+            "record_time": self.record_time,
+            "call_time": self.call_time,
+            "call_type": self.call_type.code if self.call_type else None,
+            "direction": self.direction.code if self.direction else None,
+            "answer_flag": self.answer_flag,
+            "wait_time": self.wait_time,
+            "answer_count": self.answer_count,
+            "hangup_dir": self.hangup_dir,
+            "sdk_hangup": self.sdk_hangup,
+            "hangup_code": self.hangup_code,
+            "answer_time": self.answer_time,
+            "end_time": self.end_time,
+            "talk_time": self.talk_time,
+            "frist_queue_time": self.frist_queue_time,
+            "queue_start_time": self.queue_start_time,
+            "queue_end_time": self.queue_end_time,
+            "overflow_count": self.overflow_count,
+            "uuid1": self.uuid1,
+            "uuid2": self.uuid2,
+            "cdr_notify_url": self.cdr_notify_url,
+            "queue_level": self.queue_level,
+            "device_list": [x for x in self.device_list],
+            "device_info_map": {key: value for key, value in self.device_info_map.items()},
+            "follow_data": {key: value for key, value in self.follow_data.items()},
+            "process_data": {key: value for key, value in self.process_data.items()},
+            "next_commands": [x for x in self.next_commands],
+            "call_details": [x for x in self.call_details],
+        }
+        return json.dumps(new_dict, default=lambda x: x.__dict__, ensure_ascii=False)
+
+
+class DeviceInfo(BaseApi):
     def __init__(self, call_id=None, conference=None, device_id=None, agent_key=None, agent_name=None, device_type=None,
                  cdr_type=None, from_agent=None, caller=None, called=None, display=None, called_location=None,
                  caller_location=None, call_time=None, ring_start_time=None, ring_end_time=None, answer_time=None,
@@ -557,33 +603,84 @@ class DeviceInfo:
         self.record_time = record_time  # 录音时长
         self.record_start_time = record_start_time  # 录音开始时间
         self.state = state  # 当前设备状态
-        self.apparent_number = apparent_number #外显号
-        self.caller_display = caller_display   # 主叫号
-
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
+        self.apparent_number = apparent_number  # 外显号
+        self.caller_display = caller_display  # 主叫号
 
     @classmethod
     def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
-
-    # def __repr__(self):
-    #     return (f"DeviceInfo(call_id={self.call_id}, conference={self.conference}, device_id={self.device_id}, "
-    #             f"agent_key={self.agent_key}, agent_name={self.agent_name}, device_type={self.device_type}, "
-    #             f"cdr_type={self.cdr_type}, from_agent={self.from_agent}, caller={self.caller}, called={self.called}, "
-    #             f"display={self.display}, called_location={self.called_location}, caller_location={self.caller_location}, "
-    #             f"call_time={self.call_time}, ring_start_time={self.ring_start_time}, ring_end_time={self.ring_end_time}, "
-    #             f"answer_time={self.answer_time}, bridge_time={self.bridge_time}, end_time={self.end_time}, "
-    #             f"talk_time={self.talk_time}, sip_protocol={self.sip_protocol}, channel_name={self.channel_name}, "
-    #             f"hangup_cause={self.hangup_cause}, ring_cause={self.ring_cause}, sip_status={self.sip_status}, "
-    #             f"record={self.record}, record_time={self.record_time}, record_start_time={self.record_start_time}, "
-    #             f"state={self.state})")
-
-
-class NextCommand:
+        data = get_json_dict(json_string)
+        device_type = DeviceType.get_by_code(data.get("device_type"))
+        cdr_type = CdrType.get_by_code(data.get("cdr_type"))
+        return cls(call_id=data.get("call_id"),
+                   conference=data.get("conference"),
+                   device_id=data.get("device_id"),
+                   agent_key=data.get("agent_key"),
+                   agent_name=data.get("agent_name"),
+                   device_type=device_type,
+                   cdr_type=cdr_type,
+                   from_agent=data.get("from_agent"),
+                   caller=data.get("caller"),
+                   called=data.get("called"),
+                   display=data.get("display"),
+                   called_location=data.get("called_location"),
+                   caller_location=data.get("caller_location"),
+                   call_time=data.get("call_time"),
+                   ring_start_time=data.get("ring_start_time"),
+                   ring_end_time=data.get("ring_end_time"),
+                   answer_time=data.get("answer_time"),
+                   bridge_time=data.get("bridge_time"),
+                   end_time=data.get("end_time"),
+                   talk_time=data.get("talk_time"),
+                   sip_protocol=data.get("sip_protocol"),
+                   channel_name=data.get("channel_name"),
+                   hangup_cause=data.get("hangup_cause"),
+                   ring_cause=data.get("ring_cause"),
+                   sip_status=data.get("sip_status"),
+                   record=data.get("record"),
+                   record_time=data.get("record_time"),
+                   record_start_time=data.get("record_start_time"),
+                   state=data.get("state"),
+                   apparent_number=data.get("apparent_number"),
+                   caller_display=data.get("caller_display"))
 
-    def __init__(self, device_id, next_type, next_value):
+    def to_json_string(self):
+        new_dict = {"call_id": self.call_id,
+                    "conference": self.conference,
+                    "device_id": self.device_id,
+                    "agent_key": self.agent_key,
+                    "agent_name": self.agent_name,
+                    "device_type": self.device_type.code if self.device_type else None,
+                    "cdr_type": self.cdr_type.code if self.cdr_type else None,
+                    "from_agent": self.from_agent,
+                    "caller": self.caller,
+                    "called": self.called,
+                    "display": self.display,
+                    "called_location": self.called_location,
+                    "caller_location": self.caller_location,
+                    "call_time": self.call_time,
+                    "ring_start_time": self.ring_start_time,
+                    "ring_end_time": self.ring_end_time,
+                    "answer_time": self.answer_time,
+                    "bridge_time": self.bridge_time,
+                    "end_time": self.end_time,
+                    "talk_time": self.talk_time,
+                    "sip_protocol": self.sip_protocol,
+                    "channel_name": self.channel_name,
+                    "hangup_cause": self.hangup_cause,
+                    "ring_cause": self.ring_cause,
+                    "sip_status": self.sip_status,
+                    "record": self.record,
+                    "record_time": self.record_time,
+                    "record_start_time": self.record_start_time,
+                    "state": self.state,
+                    "apparent_number": self.apparent_number,
+                    "caller_display": self.caller_display}
+        return json.dumps(new_dict, default=lambda x: x.__dict__, ensure_ascii=False)
+
+
+class NextCommand(BaseApi):
+
+    def __init__(self, device_id, next_type, next_value=None):
         # 记录执行设备
         self.device_id = device_id
         # 下一步执行命令
@@ -591,16 +688,22 @@ class NextCommand:
         # 执行参数
         self.next_value = next_value
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
     @classmethod
     def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
+        data = get_json_dict(json_string)
+        next_type = NextType.get_by_code(data.get("next_type"))
+        return cls(device_id=data.get("device_id"), next_type=next_type, next_value=data.get("next_value"))
+
+    def to_json_string(self):
+        new_dict = {
+            "device_id": self.device_id,
+            "next_type": self.next_type.code,
+            "next_value": self.next_value
+        }
+        return json.dumps(new_dict, default=lambda x: x.__dict__, ensure_ascii=False)
 
 
-class CallDetail:
+class CallDetail(BaseApi):
     def __init__(self, id=None, cts=None, start_time=None, end_time=None, call_id=None,
                  detail_index=None, transfer_type=None, transfer_id=None, reason=None,
                  month=None, ext1=None, ext2=None, status=None):
@@ -618,22 +721,8 @@ class CallDetail:
         self.ext2 = ext2  # 扩展字段2
         self.status = status  # 状态
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
-    @classmethod
-    def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
-
-    # def __repr__(self):
-    #     return (f"CallDetail(id={self.id}, cts={self.cts}, start_time={self.start_time}, "
-    #             f"end_time={self.end_time}, call_id={self.call_id}, detail_index={self.detail_index}, "
-    #             f"transfer_type={self.transfer_type}, transfer_id={self.transfer_id}, reason={self.reason}, "
-    #             f"month={self.month}, ext1={self.ext1}, ext2={self.ext2}, status={self.status})")
-
 
-class RouteGateway:
+class RouteGateway(BaseApi):
     def __init__(self, id=None, saas_id=None, cts=None, uts=None, name=None, media_host=None,
                  media_port=None, caller_prefix=None, called_prefix=None,
                  profile='gateway/gateway-fxo', sip_header1='P-LIBRA-CallId=#{[callId]}',
@@ -653,30 +742,11 @@ class RouteGateway:
         self.sip_header3 = sip_header3  # SIP头3
         self.status = status  # 状态
 
-    def to_json_string(self):
-        return json.dumps(self.__dict__, ensure_ascii=False)
-
-    @classmethod
-    def from_json(cls, json_string):
-        data = json.loads(json_string)
-        return cls(**data)
-
-    # def __repr__(self):
-    #     return (f"RouteGateway(id={self.id}, cts={self.cts}, uts={self.uts}, name={self.name}, "
-    #             f"media_host={self.media_host}, media_port={self.media_port}, caller_prefix={self.caller_prefix}, "
-    #             f"called_prefix={self.called_prefix}, profile={self.profile}, "
-    #             f"sip_header1={self.sip_header1}, sip_header2={self.sip_header2}, "
-    #             f"sip_header3={self.sip_header3}, status={self.status})")
-
-
-
 
-
-
-
-#机器人外呼
+# 机器人外呼
 class BotChatRequest:
-    def __init__(self, nodeId=None, userId=None, sessionId=None, taskId=None, asrText=None, recordId=None, ext:Dict={}):
+    def __init__(self, nodeId=None, userId=None, sessionId=None, taskId=None, asrText=None, recordId=None,
+                 ext: Dict = {}):
         self.nodeId = nodeId  # 节点id
         self.userId = userId  # 用户id
         self.sessionId = sessionId  # 会话id
@@ -699,11 +769,10 @@ class BotChatRequest:
     #             f"event_type={self.event_type}, asr_text={self.asr_text}, key_input={self.key_input})")
 
 
-
 class ChatAction:
     def __init__(self, actionCode=None, actionContent=None):
-        self.actionCode = actionCode         # normal:正常通话;hang:挂断;transfer:转人工
-        self.actionContent = actionContent   # 动作内容
+        self.actionCode = actionCode  # normal:正常通话;hang:挂断;transfer:转人工
+        self.actionContent = actionContent  # 动作内容
 
     def to_json_string(self):
         return json.dumps(self.__dict__, ensure_ascii=False)
@@ -718,10 +787,10 @@ class ChatAction:
 
 class ChatContent:
     def __init__(self, contentType=None, content=None, voiceUrl=None, voiceContent=None):
-        self.contentType = contentType   # 播放类型
-        self.content = content             # 播放内容
-        self.voiceUrl = voiceUrl         # 语音地址
-        self.voiceContent = voiceContent # 语音文本
+        self.contentType = contentType  # 播放类型
+        self.content = content  # 播放内容
+        self.voiceUrl = voiceUrl  # 语音地址
+        self.voiceContent = voiceContent  # 语音文本
 
     def to_json_string(self):
         return json.dumps(self.__dict__, ensure_ascii=False)
@@ -737,13 +806,13 @@ class ChatContent:
 
 
 class ChatMessage:
-    def __init__(self, nodeId=None, contents=None,  waitTime=None,
-                 action=None,inputType=None):
-        self.nodeId = nodeId   # 节点id
-        self.contents = contents if contents is not None else []   # 内容列表
-        self.waitTime = waitTime   # 用户静默时长
-        self.action = action        # 动作代码
-        self.inputType = inputType   # dtmf类型
+    def __init__(self, nodeId=None, contents=None, waitTime=None,
+                 action=None, inputType=None):
+        self.nodeId = nodeId  # 节点id
+        self.contents = contents if contents is not None else []  # 内容列表
+        self.waitTime = waitTime  # 用户静默时长
+        self.action = action  # 动作代码
+        self.inputType = inputType  # dtmf类型
 
     def to_json_string(self):
         return json.dumps({
@@ -788,4 +857,4 @@ class ChatResponse:
             data=response_data,
             message=data.get("message"),
             code=data.get("code")
-        )
+        )

+ 2 - 1
src/core/callcenter/cache.py

@@ -54,7 +54,8 @@ def add_agent_info(call_info: CallInfo = None, agent: AgentInfo = None, call_id=
 def add_call_info(call: CallInfo):
     for k, v in call.device_info_map.items():
         add_device(k, call.call_id)
-    redis_handler.set(CALL_INFO + call.call_id, json.dumps(call), cacheDay * 24 * 60 * 60)
+    print(call.to_json_string())
+    redis_handler.set(CALL_INFO + call.call_id, call.to_json_string(), cacheDay * 24 * 60 * 60)
 
 
 def get_call_info_by_device_id(device_id):

+ 4 - 4
src/core/callcenter/call.py

@@ -20,8 +20,8 @@ class CallService:
         self.snowflake = Snowflake(worker_id=1, data_center_id=1)
 
     def call(self, request: AgentCallRequest):
-        call_id = 'C' + self.snowflake.next_id()
-        device_id = 'D' + self.snowflake.next_id()
+        call_id = 'C' + str(self.snowflake.next_id())
+        device_id = 'D' + str(self.snowflake.next_id())
         now = lambda: int(round(time.time() * 1000))
 
         agent = Cache.get_agent_info(request.saas_id, request.agent_id)
@@ -35,7 +35,7 @@ class CallService:
                                  agent_key=agent.agent_number, caller_display=route_gateway.name)
         call_info.device_list.append(device_info)
         call_info.next_commands.append(NextCommand(device_id, NextType.NEXT_CALL_OTHER))
-        call_info.device_info_map[device_id] = device_info
+        call_info.device_info_map = {device_id: device_info}
         Cache.add_call_info(call_info)
 
         context = MakeCallContext(display=request.called, caller=request.called, called=request.caller,
@@ -58,7 +58,7 @@ class CallService:
         caller = call_info.called
         call_id = call_info.call_id
         agent = Cache.get_agent_info(call_info.saas_id, call_info.agent_key)
-        device_id = 'D' + self.snowflake.next_id()
+        device_id = 'D' + str(self.snowflake.next_id())
         now = lambda: int(round(time.time() * 1000))
 
         device_info = DeviceInfo(device_id=device_id, caller=caller, display=caller, called=agent_number, call_id=call_id,

+ 7 - 0
src/core/callcenter/constant.py

@@ -78,6 +78,13 @@ CALL_INFO = "CALL_INFO:"
 START_AGENT_NUM = "1000"
 
 
+def get_json_dict(json_string):
+    data = json_string
+    if isinstance(json_string, str):
+        data = json.loads(json_string)
+    return data
+
+
 def success_response(data=None, code=0, msg=""):
     response = json.dumps({"code": code, "msg": msg, "data": data})
     return response, 200, {"Content-Type": "application/json"}

+ 69 - 1
src/core/callcenter/enumeration.py

@@ -13,6 +13,10 @@ class HumanState(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AgentState(Enum):
     ENABLE = (0, '可用')
@@ -22,6 +26,10 @@ class AgentState(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AgentCheck(Enum):
     IN = (0, "签入")
@@ -31,6 +39,10 @@ class AgentCheck(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AgentHeartState(Enum):
     DEFAULT = (0, "默认")
@@ -55,6 +67,10 @@ class AgentServiceState(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AgentLogState(Enum):
     CREATE = (0, "创建")
@@ -88,6 +104,10 @@ class AgentLogState(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AgentScene(Enum):
     MANUAL = (1, "manual", "手动外呼")
@@ -137,6 +157,10 @@ class WorkStatus(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class DownEvent(Enum):
 
@@ -166,6 +190,10 @@ class DownEvent(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class ServiceDirect(Enum):
     NORMAL = (0, "正常呼叫")
@@ -193,6 +221,10 @@ class ServiceDirect(Enum):
         self.service_direct = service_direct
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class AnswerFlag(Enum):
     INIT = (0, "均未拨通")
@@ -207,6 +239,10 @@ class AnswerFlag(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class DeviceType(Enum):
     AGENT = (1, "坐席")
@@ -219,6 +255,10 @@ class DeviceType(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class CallType(Enum):
     IM = (0, 'IM')
@@ -234,15 +274,23 @@ class CallType(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class Direction(Enum):
     INBOUND = (1, '呼入')
     OUTBOUND = (2, '外呼')
 
     def __init__(self, code=None, description=None):
-        self._code = code
+        self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class NextType(Enum):
     NORNAL = (1, '默认')
@@ -275,6 +323,10 @@ class NextType(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class CallCause(Enum):
     DEFAULT = (0, "默认")
@@ -298,6 +350,10 @@ class CallCause(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class CdrType(Enum):
 
@@ -315,6 +371,10 @@ class CdrType(Enum):
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class HangupDir:
 
@@ -326,6 +386,10 @@ class HangupDir:
         self.code = code
         self.description = description
 
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)
+
 
 class BizErrorCode(Enum):
     PARAM_ERROR = (10001, "参数错误")
@@ -384,3 +448,7 @@ class BizErrorCode(Enum):
     def __init__(self, code, message):
         self.code = code
         self.message = message
+
+    @classmethod
+    def get_by_code(cls, code):
+        return next((member for member in cls if member.code == code), None)

+ 1 - 1
src/core/callcenter/esl/handler/channel_answer_handler.py

@@ -60,7 +60,7 @@ class ChannelAnswerHandler(EslEventHandler):
         call.direction = Direction.OUTBOUND
         call.answer_flag = AnswerFlag.AGENT_ANSWER
 
-        new_device_id = 'D' + self.snowflake.next_id()
+        new_device_id = 'D' + str(self.snowflake.next_id())
         call.device_list.append(new_device_id)
         called = call.called
 

+ 3 - 0
src/core/callcenter/exception.py

@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 # encoding:utf-8
 
+import traceback
 from . import app
 from .constant import error_response
 
@@ -21,11 +22,13 @@ class SipUriSyntaxException(Exception):
 
 @app.errorhandler(BizException)
 def handle_biz_exception(error):
+    traceback.print_exc()
     return error_response(msg=str(error), http_code=200)
 
 # Generic error handler for uncaught exceptions
 @app.errorhandler(Exception)
 def handle_generic_exception(error):
+    traceback.print_exc()
     return error_response(msg=str(error), http_code=500)
 
 # Specific error handler for 404 Not Found errors

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2 - 33
src/core/callcenter/test.py


+ 5 - 5
src/core/callcenter/views.py

@@ -142,9 +142,9 @@ def manual_call():
     # circuitUid: string
     # ext?: object
     # callId: string
-    data = request.json()
+    data = request.get_json()
     req = AgentCallRequest(saas_id=data.get('saas_id'), call_type=CallType.OUTBOUND_CALL, caller=data.get('caller'),
-                           agent_id=data.get('caller'), called=data.get('called'), follow_data=data.get('ext'))
+                           agent_id=data.get('caller'), called=data.get('called'))
     res = call_service.call(req)
     return success_response(res)
 
@@ -152,9 +152,9 @@ def manual_call():
 @app.route('/open/agent/manual-hang', methods=['POST'])
 def manual_hang():
     """挂断"""
-    data = request.json()
-    agent = Cache.get_agent_info(data.get('saasId'), data.get('agentId'))
-    req = HangupCallRequest(saas_id=data.get('saasId'), call_id=data.get('callId'), agent_number=agent.agent_number)
+    data = request.get_json()
+    agent = Cache.get_agent_info(data.get('saas_id'), data.get('agent_id'))
+    req = HangupCallRequest(saas_id=data.get('saas_id'), call_id=data.get('call_id'), agent_number=agent.agent_number)
     call_service.hangup(req)
     return success_response()
 

+ 2 - 2
src/core/server.py

@@ -5,5 +5,5 @@ from src.core.callcenter.views import app
 from src.core.callcenter.ws import socketio
 
 if __name__ == '__main__':
-    # socketio.run(app, host='0.0.0.0', port=8000, allow_unsafe_werkzeug=True, debug=True)
-    app.run(host='127.0.0.1', port=8000, debug=True)
+    socketio.run(app, host='0.0.0.0', port=8000, allow_unsafe_werkzeug=True, debug=True)
+    # app.run(host='0.0.0.0', port=8000, debug=True)

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott