DavidLiu преди 3 месеца
родител
ревизия
9970d5894c
променени са 3 файла, в които са добавени 71 реда и са изтрити 22 реда
  1. 7 0
      src/core/__init__.py
  2. 63 14
      src/core/callcenter/agent.py
  3. 1 8
      src/core/callcenter/data_handler.py

+ 7 - 0
src/core/__init__.py

@@ -1,4 +1,11 @@
+from functools import wraps
 
+def with_app_context(func):
+    @wraps(func)
+    def wrapper(self, *args, **kwargs):
+        with self.app.app_context():
+            return func(self, *args, **kwargs)
+    return wrapper
 
 def singleton(cls):
     _instance = {}

+ 63 - 14
src/core/callcenter/agent.py

@@ -1,26 +1,27 @@
 #!/usr/bin/env python3
 # encoding:utf-8
 
-import traceback
-from typing import List
+import threading
 from collections import defaultdict
+from concurrent.futures import ThreadPoolExecutor
+from typing import List
 
+from sqlalchemy import or_
+
+import src.core.callcenter.esl.utils.esl_event_util as EslEventUtil
+from src.core import with_app_context
+from src.core.callcenter.api import AgentActionRequest, AgentQueryRequest, AgentRequest, AgentEventData, \
+    AgentStateData, HumanServiceQueryRequest, AgentMonitorData, CallInfo, DeviceInfo
 from src.core.callcenter.cache import Cache
-from src.core.callcenter.constant import START_AGENT_NUM
+from src.core.callcenter.dao import *
 from src.core.callcenter.data_handler import DataHandleServer
 from src.core.callcenter.enumeration import AgentState, AgentCheck, AgentHeartState, AgentServiceState, AgentLogState, \
     AgentScene, BizErrorCode, WorkStatus, DownEvent, HumanState, DeviceType, ServiceDirect
-from sqlalchemy import or_
-from src.core.callcenter.dao import *
+from src.core.callcenter.esl.constant.event_names import *
 from src.core.callcenter.exception import BizException
-from src.core.callcenter.api import AgentActionRequest, AgentInfo, AgentQueryRequest, AgentRequest, AgentEventData, \
-    AgentStateData, HumanServiceQueryRequest, AgentMonitorData, CallInfo, DeviceInfo
 from src.core.callcenter.push import PushHandler
 from src.core.datasource import RedisHandler
-import src.core.callcenter.esl.utils.esl_event_util as EslEventUtil
-from src.core.callcenter.esl.constant.event_names import *
-from concurrent.futures import ThreadPoolExecutor
-import threading
+
 
 class AgentEventService:
     def __init__(self, app):
@@ -33,7 +34,6 @@ class AgentEventService:
         self.agent_state_service = AgentStateService(app)
         self.agent_actionlog_service = AgentActionLogService(app)
 
-
     def agent_event_channel(self, event, call_info: CallInfo, device_info: DeviceInfo):
         event_name = EslEventUtil.getEventName(event)
         saas_id = call_info.saas_id
@@ -94,12 +94,12 @@ class AgentEventService:
                     self.cache.set_call_is_end(call_id)
 
             self.agent_monitor_service.update_processing(agent_monitor)
+            self.reprocessing_idle(saas_id, flow_id, agent_num, AgentServiceState.REPROCESSING, AgentScene.MANUAL)
             self.push_handler.push_on_call_end(saas_id, flow_id, AgentScene.MANUAL, ServiceDirect.MANUAL_CALL.service_direct, '0')
             self.push_handler.push_on_agent_work_report(saas_id, flow_id, agent_num, call_id, AgentScene.MANUAL, WorkStatus.AGENT_HANG_REPROCESSING)
             self.push_handler.push_on_agent_report(saas_id, agent_num, AgentScene.MANUAL, AgentServiceState.REPROCESSING)
 
-            self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.REPROCESSING,
-                                                              AgentLogState.CHANNEL_HANG_UP)
+            self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.REPROCESSING, AgentLogState.CHANNEL_HANG_UP)
 
             # 同步处理后处理置闲
             # reprocessingIdle(statusDto);
@@ -166,15 +166,29 @@ class AgentEventService:
                                                   AgentLogState.CHANNEL_HANG_UP, service_id=human_service_id)
 
 
+    def reprocessing_idle(self, saas_id, flow_id, agent_num, service_state:AgentServiceState, scene: AgentScene):
+        agent = self.data_handle_server.get_agent(saas_id, agent_num)
+        if not agent:
+            return
+        agent_monitor = self.data_handle_server.get_agent_monitor(saas_id, agent_num)
+        if not agent_monitor:
+            return
+        self.agent_monitor_service.update_idle(agent_monitor)
+        self.push_handler.push_on_agent_work_report(saas_id, flow_id, agent_num, "", scene, WorkStatus.AGENT_HANG_IDLE)
+        self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.IDLE, AgentLogState.REPROCESSING_IDLE)
+
+
 class AgentOperService:
 
     def __init__(self, app):
+        self.app = app
         self.push_handler = PushHandler(app.logger)
         self.data_handle_server = DataHandleServer(app)
         self.agent_monitor_service = AgentMonitorService(app)
         self.agent_actionlog_service = AgentActionLogService(app)
         self.agent_state_service = AgentStateService(app)
 
+    @with_app_context
     def enable(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_number, req.out_id)
         if agent.agent_state == AgentState.ENABLE.code:
@@ -182,6 +196,7 @@ class AgentOperService:
         agent.agent_state = AgentState.ENABLE.code
         db.session.commit()
 
+    @with_app_context
     def disable(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if agent.agent_state == AgentState.DISABLE.code:
@@ -199,6 +214,7 @@ class AgentOperService:
         phone.is_delete = 1
         db.session.commit()
 
+    @with_app_context
     def checkin(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if not agent or agent.agent_state == AgentState.DISABLE.code:
@@ -214,6 +230,8 @@ class AgentOperService:
         #     # 如果是手动外呼增加置忙
         #     self._handle_idle(req.scene, agent)
         return self._push_event_for_checkin(agent, agent_monitor, phone, req.scene)
+
+    @with_app_context
     def checkout(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if not agent or agent.agent_state == AgentState.DISABLE.code:
@@ -232,6 +250,7 @@ class AgentOperService:
 
         return self._push_event_for_checkout(agent, req.scene)
 
+    @with_app_context
     def busy(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if not agent or agent.agent_state == AgentState.DISABLE.code:
@@ -253,22 +272,27 @@ class AgentOperService:
         self.agent_actionlog_service.insert_service_state(agent_monitor, AgentServiceState.BUSY, AgentLogState.BUSY)
         self._push_event_for_busy(agent, req.scene)
 
+    @with_app_context
     def idle(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if not agent or agent.agent_state == AgentState.DISABLE.code:
             raise BizException(BizErrorCode.AGENT_DISABLE_NOT_ALLOW_OPERATE)
         self._handle_idle(req.scene, agent)
 
+    @with_app_context
     def assign(self, req: AgentActionRequest):
         return self.agent_state_service.assign_agent(req.saas_id, req.service_id)
 
     def idle_agent_exist(self, request: AgentActionRequest):
         pass
+
+    @with_app_context
     def agent_state(self,req: AgentActionRequest):
         # agent = _get_agent(req.saas_id, req.agent_id)
         agent_monitor = self.data_handle_server.get_agent_monitor(req.saas_id, req.agent_id)
         return agent_monitor.service_state
 
+    @with_app_context
     def turn_on(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         agent_monitor = self.data_handle_server.get_agent_monitor(req.saas_id, agent.agent_num)
@@ -284,6 +308,7 @@ class AgentOperService:
         self.agent_state_service.busy(agent.saas_id, agent.out_id, agent.phone_num)
         self.push_handler.push_on_agent_report(agent.saas_id, agent.out_id, agent_scene, AgentServiceState.BUSY)
 
+    @with_app_context
     def _handle_idle(self, scene, agent):
         agent_monitor = self.data_handle_server.get_agent_monitor(agent.saas_id, agent.agent_num)
         if agent_monitor.check_state == AgentCheck.OUT.code:
@@ -348,9 +373,11 @@ class AgentOperService:
 class AgentService:
 
     def __init__(self, app):
+        self.app = app
         self.data_handle_server = DataHandleServer(app)
         self.agent_monitor_service = AgentMonitorService(app)
 
+    @with_app_context
     def get_and_check(self, req: AgentActionRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_id)
         if not agent:
@@ -358,6 +385,7 @@ class AgentService:
         phone = self.data_handle_server.get_phone(req.saas_id, agent.phone_num)
         return phone.to_dict()
 
+    @with_app_context
     def watch_agent_state(self, req: HumanServiceQueryRequest):
         pos = HumanServiceMap.query.filter(HumanServiceMap.is_delete == 0, HumanServiceMap.saas_id == req.saas_id,
                                            HumanServiceMap.service_id == req.serviceId).all()
@@ -365,6 +393,7 @@ class AgentService:
         monitors = self.agent_monitor_service.detail_monitor_out_ids(req.saas_id, agent_ids)
         return monitors
 
+    @with_app_context
     def add(self, req: AgentRequest):
         new_agent_num = self.data_handle_server.get_newest_agent_number(req.saas_id)
         agent = Agent(saas_id=req.saas_id, agent_num=new_agent_num, agent_name=req.agent_name, out_id=req.out_id,
@@ -378,6 +407,7 @@ class AgentService:
         db.session.commit()
         return new_agent_num
 
+    @with_app_context
     def update(self, req: AgentRequest):
         agent = self.data_handle_server.get_agent(req.saas_id, req.agent_number, req.out_id)
         if not agent:
@@ -399,10 +429,12 @@ class AgentService:
             if phone:
                 db.session.delete(phone)
 
+    @with_app_context
     def detail(self, saas_id, agent_number):
         agent = self.data_handle_server.get_agent(saas_id, agent_number=agent_number, out_id='')
         return agent
 
+    @with_app_context
     def count(self, req: AgentQueryRequest):
         cnt = Agent.query.filter(Agent.saas_id == req.saas_id,
                                  or_(Agent.agent_num == req.agent_number,
@@ -413,6 +445,7 @@ class AgentService:
                                  ).count()
         return cnt
 
+    @with_app_context
     def query_page(self, req: AgentQueryRequest):
         pagination = Agent.query.filter(Agent.saas_id == req.saas_id,
                                         or_(Agent.agent_num == req.agent_number,
@@ -438,6 +471,7 @@ class AgentService:
         # }
         return pagination
 
+    @with_app_context
     def delete(self, saas_id, agent_number):
         agent = self.data_handle_server.get_agent(saas_id, agent_number=agent_number, out_id='')
         if not agent:
@@ -456,8 +490,10 @@ class AgentService:
 class AgentMonitorService:
 
     def __init__(self, app):
+        self.app = app
         self.data_handle_server = DataHandleServer(app)
 
+    @with_app_context
     def detail_monitor_out_ids(self, saas_id, out_ids, check_scene=None):
         if not out_ids:
             return []
@@ -499,6 +535,7 @@ class AgentMonitorService:
             res.append(data.__dict__)
         return res
 
+    @with_app_context
     def update_checkin(self, agent_monitor):
         agent_monitor.check_state = AgentCheck.IN.code
         agent_monitor.check_in_time = datetime.utcnow()
@@ -506,6 +543,7 @@ class AgentMonitorService:
         agent_monitor.heart_time = datetime.utcnow()
         db.session.commit()
 
+    @with_app_context
     def update_checkout(self, agent_monitor):
         agent_monitor.check_state = AgentCheck.OUT.code
         agent_monitor.check_out_time = datetime.utcnow()
@@ -515,34 +553,41 @@ class AgentMonitorService:
         self.logger.info("update_checkout %s", agent_monitor.check_out_time)
         db.session.commit()
 
+    @with_app_context
     def update_idle(self, agent_monitor):
         agent_monitor.service_state = AgentServiceState.IDLE.code
         agent_monitor.idle_time = datetime.utcnow()
         db.session.commit()
 
+    @with_app_context
     def update_busy(self, agent_monitor):
         agent_monitor.service_state = AgentServiceState.BUSY.code
         agent_monitor.busy_time = datetime.utcnow()
         db.session.commit()
 
+    @with_app_context
     def update_dialing(self, agent_monitor):
         agent_monitor.service_state = AgentServiceState.DIALING.code
         db.session.commit()
 
+    @with_app_context
     def update_calling(self, agent_monitor):
         agent_monitor.service_state = AgentServiceState.CALLING.code
         agent_monitor.call_time = datetime.utcnow()
         db.session.commit()
 
+    @with_app_context
     def update_processing(self, agent_monitor):
         agent_monitor.service_state = AgentServiceState.REPROCESSING.code
         agent_monitor.hang_time = datetime.utcnow()
         db.session.commit()
 
+    @with_app_context
     def update_session_id(self, agent_monitor, session_id):
         agent_monitor.session_id = session_id
         db.session.commit()
 
+    @with_app_context
     def update_heart_error(self, agent_monitor):
         agent_monitor.heart_state = AgentHeartState.ABNORMAL.code
         agent_monitor.heart_time = datetime.utcnow()
@@ -556,8 +601,10 @@ class AgentMonitorService:
 class AgentActionLogService:
 
     def __init__(self, app):
+        self.app = app
         self.data_handle_server = DataHandleServer(app)
 
+    @with_app_context
     def insert_check_state(self, agent_monitor, agent_check_enum: AgentCheck, agent_log_enum: AgentLogState):
         action_log = AgentActionLog()
         action_log.saas_id = agent_monitor.saas_id
@@ -583,6 +630,7 @@ class AgentActionLogService:
         db.session.add(action_log)
         db.session.commit()
 
+    @with_app_context
     def insert_service_state(self, agent_monitor, agent_service_state: AgentServiceState, agent_log_enum: AgentLogState,
                              task_id=None, service_id=None):
         if agent_monitor.service_state == agent_service_state.code:
@@ -624,6 +672,7 @@ class AgentActionLogService:
 class AgentStateService:
 
     def __init__(self, app):
+        self.app = app
         self.logger = app.logger
         self.redis_handler = RedisHandler()
         self.assigned_recycle_millisecond = 60000

+ 1 - 8
src/core/callcenter/data_handler.py

@@ -1,15 +1,8 @@
+from src.core import with_app_context
 from src.core.callcenter.constant import START_AGENT_NUM
 from src.core.callcenter.dao import *
-from functools import wraps
 from sqlalchemy import or_
 
-def with_app_context(func):
-    @wraps(func)
-    def wrapper(self, *args, **kwargs):
-        with self.app.app_context():
-            return func(self, *args, **kwargs)
-    return wrapper
-
 class DataHandleServer:
     """通话记录服务"""
     def __init__(self,app):