Ejemplo n.º 1
0
def timer_transition(ticket_id, state_id, date_time, transition_id):
    """
    定时器流转
    :param ticket_id:
    :param state_id:
    :param date_time:
    :param transition_id:
    :return:
    """
    # 需要满足工单此状态后续无其他操作才自动流转
    # 查询该工单此状态所有操作
    # flow_log_set, msg = TicketBaseService().get_ticket_flow_log(ticket_id, 'loonrobot', per_page=1000)
    flag, result = ticket_base_service_ins.get_ticket_flow_log(ticket_id,
                                                               'loonrobot',
                                                               per_page=1000)
    if flag is False:
        return False, result
    flow_log_list = result.get('ticket_flow_log_restful_list')
    for flow_log in flow_log_list:
        if flow_log.get('state').get('state_id') == state_id and flow_log.get(
                'gmt_created') > date_time:
            return True, '后续有操作,定时器失效'
    # 执行流转
    handle_ticket_data = dict(transition_id=transition_id,
                              username='******',
                              suggestion='定时器流转')
    ticket_base_service_ins.handle_ticket(ticket_id, handle_ticket_data, True)
Ejemplo n.º 2
0
    def patch(self, request, *args, **kwargs):
        """
        处理工单
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        json_str = request.body.decode('utf-8')
        if not json_str:
            return api_response(-1, 'patch参数为空', {})
        request_data_dict = json.loads(json_str)
        ticket_id = kwargs.get('ticket_id')

        app_name = request.META.get('HTTP_APPNAME')
        request_data_dict.update(dict(username=request.META.get('HTTP_USERNAME')))
        app_permission_check, msg = account_base_service_ins.app_ticket_permission_check(app_name, ticket_id)
        if not app_permission_check:
            return api_response(-1, msg, {})

        result, msg = ticket_base_service_ins.handle_ticket(ticket_id, request_data_dict)
        if result or result is not False:
            code, data = 0, dict(value=result)
        else:
            code, data = -1, {}
        return api_response(code, msg, data)
Ejemplo n.º 3
0
def run_flow_task(ticket_id, script_id_str, state_id, action_from='loonrobot'):
    """
    执行工作流脚本
    :param script_id_star:通过脚本id来执行, 保存的是字符串
    :param ticket_id:
    :param state_id:
    :param action_from:
    :return:
    """
    script_id = int(script_id_str)
    ticket_obj = TicketRecord.objects.filter(id=ticket_id,
                                             is_deleted=False).first()
    if ticket_obj.participant == script_id_str and ticket_obj.participant_type_id == constant_service_ins.PARTICIPANT_TYPE_ROBOT:
        ## 校验脚本是否合法
        # 获取脚本名称
        script_obj = WorkflowScript.objects.filter(id=script_id,
                                                   is_deleted=False,
                                                   is_active=True).first()
        if not script_obj:
            return False, '脚本未注册或非激活状态'

        script_file = os.path.join(settings.MEDIA_ROOT,
                                   script_obj.saved_name.name)
        globals = {'ticket_id': ticket_id, 'action_from': action_from}
        # 如果需要脚本执行完成后,工单不往下流转(也就脚本执行失败或调用其他接口失败的情况),需要在脚本中抛出异常
        try:
            with stdoutIO() as s:
                # execfile(script_file, globals)  # for python 2
                exec(open(script_file, encoding='utf-8').read(), globals)
            script_result = True
            # script_result_msg = ''.join(s.buflist)
            script_result_msg = ''.join(s.getvalue())
        except Exception as e:
            logger.error(traceback.format_exc())
            script_result = False
            script_result_msg = e.__str__()

        logger.info('*' * 20 + '工作流脚本回调,ticket_id:[%s]' % ticket_id + '*' * 20)
        logger.info('*******工作流脚本回调,ticket_id:{}*****'.format(ticket_id))

        # 因为上面的脚本执行时间可能会比较长,为了避免db session失效,重新获取ticket对象
        ticket_obj = TicketRecord.objects.filter(id=ticket_id,
                                                 is_deleted=False).first()
        # 新增处理记录,脚本后只允许只有一个后续直连状态
        transition_obj = Transition.objects.filter(source_state_id=state_id,
                                                   is_deleted=False).first()

        new_ticket_flow_dict = dict(
            ticket_id=ticket_id,
            transition_id=transition_obj.id,
            suggestion=script_result_msg,
            participant_type_id=constant_service_ins.PARTICIPANT_TYPE_ROBOT,
            participant='脚本:(id:{}, name:{})'.format(script_obj.id,
                                                     script_obj.name),
            state_id=state_id,
            creator='loonrobot')

        ticket_base_service_ins.add_ticket_flow_log(new_ticket_flow_dict)
        if not script_result:
            # 脚本执行失败,状态不更新,标记任务执行结果
            ticket_obj.script_run_last_result = False
            ticket_obj.save()
            return False, script_result_msg
        # 自动执行流转
        flag, msg = ticket_base_service_ins.handle_ticket(
            ticket_id,
            dict(username='******',
                 suggestion='脚本执行完成后自行流转',
                 transition_id=transition_obj.id), False, True)
        if flag:
            logger.info('******脚本执行成功,工单基础信息更新完成, ticket_id:{}******'.format(
                ticket_id))
        return flag, msg
    else:
        return False, '工单当前处理人为非脚本,不执行脚本'
Ejemplo n.º 4
0
def flow_hook_task(ticket_id):
    """
    hook 任务
    :param ticket_id:
    :return:
    """
    # 查询工单状态
    ticket_obj = TicketRecord.objects.filter(id=ticket_id,
                                             is_deleted=0).first()
    state_id = ticket_obj.state_id
    state_obj = State.objects.filter(id=state_id, is_deleted=0).first()

    participant_type_id = state_obj.participant_type_id
    if participant_type_id != constant_service_ins.PARTICIPANT_TYPE_HOOK:
        return False, ''
    hook_config = state_obj.participant
    hook_config_dict = json.loads(hook_config)
    hook_url = hook_config_dict.get('hook_url')
    hook_token = hook_config_dict.get('hook_token')
    wait = hook_config_dict.get('wait')
    extra_info = hook_config_dict.get('extra_info')

    flag, msg = common_service_ins.gen_hook_signature(hook_token)
    if not flag:
        return False, msg
    flag, all_ticket_data = ticket_base_service_ins.get_ticket_all_field_value(
        ticket_id)
    if extra_info is not None:
        all_ticket_data.update(dict(extra_info=extra_info))
    try:
        r = requests.post(hook_url,
                          headers=msg,
                          json=all_ticket_data,
                          timeout=10)
        result = r.json()
    except Exception as e:
        result = dict(code=-1, msg=e.__str__())
    if result.get('code') == 0:
        # 调用成功
        if wait:
            # date等格式需要转换为str
            for key, value in all_ticket_data.items():
                if type(value) not in [int, str, bool, float]:
                    all_ticket_data[key] = str(all_ticket_data[key])

            all_ticket_data_json = json.dumps(all_ticket_data)
            TicketBaseService().add_ticket_flow_log(
                dict(ticket_id=ticket_id,
                     transition_id=0,
                     suggestion=result.get('msg'),
                     participant_type_id=constant_service_ins.
                     PARTICIPANT_TYPE_HOOK,
                     participant='hook',
                     state_id=state_id,
                     ticket_data=all_ticket_data_json,
                     creator='loonrobot'))
            return True, ''
        else:
            # 不等待hook目标回调,直接流转
            flag, transition_queryset = workflow_transition_service_ins.get_state_transition_queryset(
                state_id)
            transition_id = transition_queryset[0].id  # hook状态只支持一个流转

            new_request_dict = {}
            new_request_dict.update({
                'transition_id': transition_id,
                'suggestion': msg,
                'username': '******'
            })
            # 执行流转
            flag, msg = ticket_base_service_ins.handle_ticket(ticket_id,
                                                              new_request_dict,
                                                              by_hook=True)
            if not flag:
                return False, msg

    else:
        ticket_base_service_ins.update_ticket_field_value(
            ticket_id, {'script_run_last_result': False})

        flag, result = ticket_base_service_ins.get_ticket_all_field_value_json(
            ticket_id)

        all_ticket_data_json = result.get('all_field_value_json')
        ticket_base_service_ins.add_ticket_flow_log(
            dict(
                ticket_id=ticket_id,
                transition_id=0,
                suggestion=result.get('msg'),
                participant_type_id=constant_service_ins.PARTICIPANT_TYPE_HOOK,
                participant='hook',
                state_id=state_id,
                ticket_data=all_ticket_data_json,
                creator='loonrobot'))