Пример #1
0
def queryprivaudit(request):
    # 获取用户信息
    user = request.user
    apply_id = int(request.POST['apply_id'])
    audit_status = int(request.POST['audit_status'])
    audit_remark = request.POST.get('audit_remark')

    if audit_remark is None:
        audit_remark = ''

    if Audit.can_review(request.user, apply_id, 1) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=apply_id,
                workflow_type=WorkflowDict.workflow_type['query']).audit_id

            # 调用工作流接口审核
            audit_result = Audit.audit(audit_id, audit_status, user.username,
                                       audit_remark)

            # 按照审核结果更新业务表审核状态
            audit_detail = Audit.detail(audit_id)
            if audit_detail.workflow_type == WorkflowDict.workflow_type[
                    'query']:
                # 更新业务表审核状态,插入权限信息
                query_audit_call_back(audit_detail.workflow_id,
                                      audit_result['data']['workflow_status'])

    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        sys_config = SysConfig()
        if sys_config.get('mail') or sys_config.get('ding'):
            # 再次获取审核信息
            audit_detail = Audit.detail_by_workflow_id(
                workflow_id=apply_id,
                workflow_type=WorkflowDict.workflow_type['query'])
            base_url = sys_config.get('archery_base_url',
                                      'http://127.0.0.1:8000').rstrip('/')
            workflow_url = "{base_url}/workflow/{audit_id}".format(
                base_url=base_url, audit_id=audit_detail.audit_id)
            async_task(notify,
                       audit_info=audit_detail,
                       workflow_url=workflow_url,
                       audit_remark=audit_remark,
                       timeout=60)

    return HttpResponseRedirect(
        reverse('sql:queryapplydetail', args=(apply_id, )))
Пример #2
0
def passed(request):
    workflow_id = request.POST.get('workflow_id')
    if workflow_id == '' or workflow_id is None:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)
    workflow_id = int(workflow_id)
    workflow_detail = SqlWorkflow.objects.get(id=workflow_id)
    audit_remark = request.POST.get('audit_remark', '')

    user = request.user
    if Audit.can_review(request.user, workflow_id, 2) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口审核
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            audit_result = Audit.audit(
                audit_id, WorkflowDict.workflow_status['audit_success'],
                user.username, audit_remark)

            # 按照审核结果更新业务表审核状态
            if audit_result['data'][
                    'workflow_status'] == WorkflowDict.workflow_status[
                        'audit_success']:
                # 将流程状态修改为审核通过,并更新reviewok_time字段
                workflow_detail.status = 'workflow_review_pass'
                workflow_detail.reviewok_time = timezone.now()
                workflow_detail.audit_remark = audit_remark
                workflow_detail.save()
    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        sys_config = SysConfig()
        if sys_config.get('mail') or sys_config.get('ding'):
            # 再次获取审核信息
            audit_detail = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview'])
            base_url = sys_config.get('archery_base_url',
                                      'http://127.0.0.1:8000').rstrip('/')
            workflow_url = "{base_url}/workflow/{audit_id}".format(
                base_url=base_url, audit_id=audit_detail.audit_id)
            async_task(notify,
                       audit_info=audit_detail,
                       workflow_url=workflow_url,
                       audit_remark=audit_remark,
                       timeout=60)

    return HttpResponseRedirect(reverse('sql:detail', args=(workflow_id, )))
Пример #3
0
def passed(request):
    """
    审核通过,不执行
    :param request:
    :return:
    """
    workflow_id = int(request.POST.get('workflow_id', 0))
    audit_remark = request.POST.get('audit_remark', '')
    if workflow_id == 0:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)
    sql_workflow = SqlWorkflow.objects.get(id=workflow_id)

    user = request.user
    if Audit.can_review(user, workflow_id, 2) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口审核
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            audit_result = Audit.audit(
                audit_id, WorkflowDict.workflow_status['audit_success'],
                user.username, audit_remark)

            # 按照审核结果更新业务表审核状态
            if audit_result['data'][
                    'workflow_status'] == WorkflowDict.workflow_status[
                        'audit_success']:
                if sql_workflow.order_type == 'common_order':
                    sql_workflow.status = 'workflow_review_pass'
                elif sql_workflow.order_type == 'sqlcron_order':
                    sql_workflow.schedule.repeats = -1  # 开启调度任务
                    sql_workflow.schedule.save()
                    sql_workflow.status = 'workflow_review_pass'
                sql_workflow.save()
    except Exception as msg:
        logger.error(f"审核工单报错,错误信息:{traceback.format_exc()}")
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        async_task(notify_for_audit,
                   audit_id=audit_id,
                   audit_remark=audit_remark,
                   timeout=60,
                   task_name=f'sqlreview-pass-{workflow_id}')

    redirect = reverse('sql:sqlcrondetail', args=(workflow_id,))\
        if sql_workflow.order_type == 'sqlcron_order' \
        else reverse('sql:detail', args=(workflow_id,))
    return HttpResponseRedirect(redirect)
def query_priv_audit(request):
    """
    查询权限审核
    :param request:
    :return:
    """
    # 获取用户信息
    user = request.user
    apply_id = int(request.POST['apply_id'])
    audit_status = int(request.POST['audit_status'])
    audit_remark = request.POST.get('audit_remark')

    if audit_remark is None:
        audit_remark = ''

    if Audit.can_review(request.user, apply_id, 1) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=apply_id,
                workflow_type=WorkflowDict.workflow_type['query']).audit_id

            # 调用工作流接口审核
            audit_result = Audit.audit(audit_id, audit_status, user.username,
                                       audit_remark)

            # 按照审核结果更新业务表审核状态
            audit_detail = Audit.detail(audit_id)
            if audit_detail.workflow_type == WorkflowDict.workflow_type[
                    'query']:
                # 更新业务表审核状态,插入权限信息
                _query_apply_audit_call_back(
                    audit_detail.workflow_id,
                    audit_result['data']['workflow_status'])

    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        async_task(notify_for_audit,
                   audit_id=audit_id,
                   audit_remark=audit_remark,
                   timeout=60,
                   task_name=f'query-priv-audit-{apply_id}')

    return HttpResponseRedirect(
        reverse('sql:queryapplydetail', args=(apply_id, )))
Пример #5
0
def archive_audit(request):
    """
    审核数据归档申请
    :param request:
    :return:
    """
    # 获取用户信息
    user = request.user
    archive_id = int(request.POST['archive_id'])
    audit_status = int(request.POST['audit_status'])
    audit_remark = request.POST.get('audit_remark')

    if audit_remark is None:
        audit_remark = ''

    if Audit.can_review(request.user, archive_id, 3) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=archive_id,
                workflow_type=WorkflowDict.workflow_type['archive']).audit_id

            # 调用工作流插入审核信息,更新业务表审核状态
            audit_status = Audit.audit(audit_id, audit_status, user.username,
                                       audit_remark)['data']['workflow_status']
            ArchiveConfig(id=archive_id,
                          status=audit_status,
                          state=True if audit_status
                          == WorkflowDict.workflow_status['audit_success'] else
                          False).save(update_fields=['status', 'state'])
    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:

        # 消息通知
        async_task(notify_for_audit,
                   audit_id=audit_id,
                   audit_remark=audit_remark,
                   timeout=60,
                   task_name=f'archive-audit-{archive_id}')

    return HttpResponseRedirect(
        reverse('sql:archive_detail', args=(archive_id, )))
Пример #6
0
def passed(request):
    """
    审核通过,不执行
    :param request:
    :return:
    """
    workflow_id = int(request.POST.get('workflow_id', 0))
    audit_remark = request.POST.get('audit_remark', '')
    if workflow_id == 0:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)

    user = request.user
    if Audit.can_review(user, workflow_id, 2) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口审核
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            audit_result = Audit.audit(
                audit_id, WorkflowDict.workflow_status['audit_success'],
                user.username, audit_remark)

            # 按照审核结果更新业务表审核状态
            if audit_result['data'][
                    'workflow_status'] == WorkflowDict.workflow_status[
                        'audit_success']:
                # 将流程状态修改为审核通过
                SqlWorkflow(id=workflow_id,
                            status='workflow_review_pass').save(
                                update_fields=['status'])
    except Exception as msg:
        logger.error(f"审核工单报错,错误信息:{traceback.format_exc()}")
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        async_task(notify_for_audit,
                   audit_id=audit_id,
                   audit_remark=audit_remark,
                   timeout=60)

    return HttpResponseRedirect(reverse('sql:detail', args=(workflow_id, )))
Пример #7
0
def passed(request):
    workflow_id = request.POST.get('workflow_id')
    if workflow_id == '' or workflow_id is None:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)
    workflow_id = int(workflow_id)
    workflow_detail = SqlWorkflow.objects.get(id=workflow_id)
    audit_remark = request.POST.get('audit_remark', '')

    user = request.user
    if Audit.can_review(request.user, workflow_id, 2) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口审核
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            audit_result = Audit.audit(
                audit_id, WorkflowDict.workflow_status['audit_success'],
                user.username, audit_remark)

            # 按照审核结果更新业务表审核状态
            if audit_result['data'][
                    'workflow_status'] == WorkflowDict.workflow_status[
                        'audit_success']:
                # 将流程状态修改为审核通过,并更新reviewok_time字段
                workflow_detail.status = 'workflow_review_pass'
                workflow_detail.reviewok_time = timezone.now()
                workflow_detail.audit_remark = audit_remark
                workflow_detail.save()
    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        async_task(notify_for_audit,
                   audit_id=audit_id,
                   audit_remark=audit_remark,
                   timeout=60)

    return HttpResponseRedirect(reverse('sql:detail', args=(workflow_id, )))
Пример #8
0
def cancel(request):
    """
    终止流程
    :param request:
    :return:
    """
    workflow_id = int(request.POST.get('workflow_id', 0))
    if workflow_id == 0:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)
    workflow_detail = SqlWorkflow.objects.get(id=workflow_id)
    audit_remark = request.POST.get('cancel_remark')
    if audit_remark is None:
        context = {'errMsg': '终止原因不能为空'}
        return render(request, 'error.html', context)

    user = request.user
    if can_cancel(request.user, workflow_id) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口取消或者驳回
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            # 仅待审核的需要调用工作流,审核通过的不需要
            if workflow_detail.status != 'workflow_manreviewing':
                # 增加工单日志
                if user.username == workflow_detail.engineer:
                    Audit.add_log(
                        audit_id=audit_id,
                        operation_type=3,
                        operation_type_desc='取消执行',
                        operation_info="取消原因:{}".format(audit_remark),
                        operator=request.user.username,
                        operator_display=request.user.display)
                else:
                    Audit.add_log(
                        audit_id=audit_id,
                        operation_type=2,
                        operation_type_desc='审批不通过',
                        operation_info="审批备注:{}".format(audit_remark),
                        operator=request.user.username,
                        operator_display=request.user.display)
            else:
                if user.username == workflow_detail.engineer:
                    Audit.audit(audit_id,
                                WorkflowDict.workflow_status['audit_abort'],
                                user.username, audit_remark)
                # 非提交人需要校验审核权限
                elif user.has_perm('sql.sql_review'):
                    Audit.audit(audit_id,
                                WorkflowDict.workflow_status['audit_reject'],
                                user.username, audit_remark)
                else:
                    raise PermissionDenied

            # 删除定时执行job
            if workflow_detail.status == 'workflow_timingtask':
                job_id = Const.workflowJobprefix['sqlreview'] + '-' + str(
                    workflow_id)
                del_sqlcronjob(job_id)
            # 将流程状态修改为人工终止流程
            workflow_detail.status = 'workflow_abort'
            workflow_detail.save()
    except Exception as msg:
        logger.error(f"取消工单报错,错误信息:{traceback.format_exc()}")
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 仅未审核通过又取消的工单需要发送消息,审核通过的不发送
        audit_detail = Audit.detail_by_workflow_id(
            workflow_id=workflow_id,
            workflow_type=WorkflowDict.workflow_type['sqlreview'])
        if audit_detail.current_status == WorkflowDict.workflow_status[
                'audit_abort']:
            async_task(notify_for_audit,
                       audit_id=audit_detail.audit_id,
                       audit_remark=audit_remark,
                       timeout=60)
    return HttpResponseRedirect(reverse('sql:detail', args=(workflow_id, )))
Пример #9
0
    def post(self, request):
        # 参数验证
        serializer = AuditWorkflowSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

        audit_type = request.data['audit_type']
        workflow_type = request.data['workflow_type']
        workflow_id = request.data['workflow_id']
        audit_remark = request.data['audit_remark']
        engineer = request.data['engineer']
        user = Users.objects.get(username=engineer)

        # 审核查询权限申请
        if workflow_type == 1:
            audit_status = 1 if audit_type == 'pass' else 2

            if audit_remark is None:
                audit_remark = ''

            if Audit.can_review(user, workflow_id, workflow_type) is False:
                raise serializers.ValidationError({"errors": "你无权操作当前工单!"})

            # 使用事务保持数据一致性
            try:
                with transaction.atomic():
                    audit_id = Audit.detail_by_workflow_id(
                        workflow_id=workflow_id,
                        workflow_type=WorkflowDict.workflow_type['query']
                    ).audit_id

                    # 调用工作流接口审核
                    audit_result = Audit.audit(audit_id, audit_status,
                                               user.username, audit_remark)

                    # 按照审核结果更新业务表审核状态
                    audit_detail = Audit.detail(audit_id)
                    if audit_detail.workflow_type == WorkflowDict.workflow_type[
                            'query']:
                        # 更新业务表审核状态,插入权限信息
                        _query_apply_audit_call_back(
                            audit_detail.workflow_id,
                            audit_result['data']['workflow_status'])

            except Exception as msg:
                logger.error(traceback.format_exc())
                raise serializers.ValidationError({'errors': msg})
            else:
                # 消息通知
                async_task(notify_for_audit,
                           audit_id=audit_id,
                           audit_remark=audit_remark,
                           timeout=60,
                           task_name=f'query-priv-audit-{workflow_id}')
                return Response({
                    'msg': 'passed'
                }) if audit_type == 'pass' else Response({'msg': 'canceled'})
        # 审核SQL上线申请
        elif workflow_type == 2:
            # SQL上线申请通过
            if audit_type == 'pass':
                # 权限验证
                if Audit.can_review(user, workflow_id, workflow_type) is False:
                    raise serializers.ValidationError({"errors": "你无权操作当前工单!"})

                # 使用事务保持数据一致性
                try:
                    with transaction.atomic():
                        # 调用工作流接口审核
                        audit_id = Audit.detail_by_workflow_id(
                            workflow_id=workflow_id,
                            workflow_type=WorkflowDict.
                            workflow_type['sqlreview']).audit_id
                        audit_result = Audit.audit(
                            audit_id,
                            WorkflowDict.workflow_status['audit_success'],
                            user.username, audit_remark)

                        # 按照审核结果更新业务表审核状态
                        if audit_result['data'][
                                'workflow_status'] == WorkflowDict.workflow_status[
                                    'audit_success']:
                            # 将流程状态修改为审核通过
                            SqlWorkflow(id=workflow_id,
                                        status='workflow_review_pass').save(
                                            update_fields=['status'])
                except Exception as msg:
                    logger.error(traceback.format_exc())
                    raise serializers.ValidationError({'errors': msg})
                else:
                    # 开启了Pass阶段通知参数才发送消息通知
                    sys_config = SysConfig()
                    is_notified = 'Pass' in sys_config.get('notify_phase_control').split(',') \
                        if sys_config.get('notify_phase_control') else True
                    if is_notified:
                        async_task(notify_for_audit,
                                   audit_id=audit_id,
                                   audit_remark=audit_remark,
                                   timeout=60,
                                   task_name=f'sqlreview-pass-{workflow_id}')
                    return Response({'msg': 'passed'})
            # SQL上线申请驳回/取消
            elif audit_type == 'cancel':
                workflow_detail = SqlWorkflow.objects.get(id=workflow_id)

                if audit_remark is None:
                    raise serializers.ValidationError({"errors": "终止原因不能为空"})

                if can_cancel(user, workflow_id) is False:
                    raise serializers.ValidationError({"errors": "你无权操作当前工单!"})

                # 使用事务保持数据一致性
                try:
                    with transaction.atomic():
                        # 调用工作流接口取消或者驳回
                        audit_id = Audit.detail_by_workflow_id(
                            workflow_id=workflow_id,
                            workflow_type=WorkflowDict.
                            workflow_type['sqlreview']).audit_id
                        # 仅待审核的需要调用工作流,审核通过的不需要
                        if workflow_detail.status != 'workflow_manreviewing':
                            # 增加工单日志
                            if user.username == workflow_detail.engineer:
                                Audit.add_log(audit_id=audit_id,
                                              operation_type=3,
                                              operation_type_desc='取消执行',
                                              operation_info="取消原因:{}".format(
                                                  audit_remark),
                                              operator=user.username,
                                              operator_display=user.display)
                            else:
                                Audit.add_log(audit_id=audit_id,
                                              operation_type=2,
                                              operation_type_desc='审批不通过',
                                              operation_info="审批备注:{}".format(
                                                  audit_remark),
                                              operator=user.username,
                                              operator_display=user.display)
                        else:
                            if user.username == workflow_detail.engineer:
                                Audit.audit(
                                    audit_id, WorkflowDict.
                                    workflow_status['audit_abort'],
                                    user.username, audit_remark)
                            # 非提交人需要校验审核权限
                            elif user.has_perm('sql.sql_review'):
                                Audit.audit(
                                    audit_id, WorkflowDict.
                                    workflow_status['audit_reject'],
                                    user.username, audit_remark)
                            else:
                                raise serializers.ValidationError(
                                    {"errors": "Permission Denied"})

                        # 删除定时执行task
                        if workflow_detail.status == 'workflow_timingtask':
                            schedule_name = f"sqlreview-timing-{workflow_id}"
                            del_schedule(schedule_name)
                        # 将流程状态修改为人工终止流程
                        workflow_detail.status = 'workflow_abort'
                        workflow_detail.save()
                except Exception as msg:
                    logger.error(f"取消工单报错,错误信息:{traceback.format_exc()}")
                    raise serializers.ValidationError({'errors': msg})
                else:
                    # 发送取消、驳回通知,开启了Cancel阶段通知参数才发送消息通知
                    sys_config = SysConfig()
                    is_notified = 'Cancel' in sys_config.get('notify_phase_control').split(',') \
                        if sys_config.get('notify_phase_control') else True
                    if is_notified:
                        audit_detail = Audit.detail_by_workflow_id(
                            workflow_id=workflow_id,
                            workflow_type=WorkflowDict.
                            workflow_type['sqlreview'])
                        if audit_detail.current_status in (
                                WorkflowDict.workflow_status['audit_abort'],
                                WorkflowDict.workflow_status['audit_reject']):
                            async_task(
                                notify_for_audit,
                                audit_id=audit_detail.audit_id,
                                audit_remark=audit_remark,
                                timeout=60,
                                task_name=f'sqlreview-cancel-{workflow_id}')
                    return Response({'msg': 'canceled'})
        # 审核数据归档申请
        elif workflow_type == 3:
            audit_status = 1 if audit_type == 'pass' else 2

            if audit_remark is None:
                audit_remark = ''

            if Audit.can_review(user, workflow_id, workflow_type) is False:
                raise serializers.ValidationError({"errors": "你无权操作当前工单!"})

            # 使用事务保持数据一致性
            try:
                with transaction.atomic():
                    audit_id = Audit.detail_by_workflow_id(
                        workflow_id=workflow_id,
                        workflow_type=WorkflowDict.workflow_type['archive']
                    ).audit_id

                    # 调用工作流插入审核信息,更新业务表审核状态
                    audit_status = Audit.audit(
                        audit_id, audit_status, user.username,
                        audit_remark)['data']['workflow_status']
                    ArchiveConfig(
                        id=workflow_id,
                        status=audit_status,
                        state=True if audit_status
                        == WorkflowDict.workflow_status['audit_success'] else
                        False).save(update_fields=['status', 'state'])
            except Exception as msg:
                logger.error(traceback.format_exc())
                raise serializers.ValidationError({'errors': msg})
            else:
                # 消息通知
                async_task(notify_for_audit,
                           audit_id=audit_id,
                           audit_remark=audit_remark,
                           timeout=60,
                           task_name=f'archive-audit-{workflow_id}')
                return Response({
                    'msg': 'passed'
                }) if audit_type == 'pass' else Response({'msg': 'canceled'})
Пример #10
0
def cancel(request):
    workflow_id = request.POST.get('workflow_id')
    if workflow_id == '' or workflow_id is None:
        context = {'errMsg': 'workflow_id参数为空.'}
        return render(request, 'error.html', context)

    workflow_id = int(workflow_id)
    workflow_detail = SqlWorkflow.objects.get(id=workflow_id)
    audit_remark = request.POST.get('cancel_remark')
    if audit_remark is None:
        context = {'errMsg': '终止原因不能为空'}
        return render(request, 'error.html', context)

    user = request.user
    if can_cancel(request.user, workflow_id) is False:
        context = {'errMsg': '你无权操作当前工单!'}
        return render(request, 'error.html', context)

    # 使用事务保持数据一致性
    try:
        with transaction.atomic():
            # 调用工作流接口取消或者驳回
            audit_id = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview']).audit_id
            # 仅待审核的需要调用工作流,审核通过的不需要
            if workflow_detail.status != 'workflow_manreviewing':
                # 增加工单日志
                if user.username == workflow_detail.engineer:
                    Audit.add_log(
                        audit_id=audit_id,
                        operation_type=3,
                        operation_type_desc='取消执行',
                        operation_info="取消原因:{}".format(audit_remark),
                        operator=request.user.username,
                        operator_display=request.user.display)
                else:
                    Audit.add_log(
                        audit_id=audit_id,
                        operation_type=2,
                        operation_type_desc='审批不通过',
                        operation_info="审批备注:{}".format(audit_remark),
                        operator=request.user.username,
                        operator_display=request.user.display)
            else:
                if user.username == workflow_detail.engineer:
                    Audit.audit(audit_id,
                                WorkflowDict.workflow_status['audit_abort'],
                                user.username, audit_remark)
                # 非提交人需要校验审核权限
                elif user.has_perm('sql.sql_review'):
                    Audit.audit(audit_id,
                                WorkflowDict.workflow_status['audit_reject'],
                                user.username, audit_remark)
                else:
                    raise PermissionDenied

            # 删除定时执行job
            if workflow_detail.status == 'workflow_timingtask':
                job_id = Const.workflowJobprefix['sqlreview'] + '-' + str(
                    workflow_id)
                del_sqlcronjob(job_id)
            # 将流程状态修改为人工终止流程
            workflow_detail.status = 'workflow_abort'
            workflow_detail.audit_remark = audit_remark
            workflow_detail.save()
    except Exception as msg:
        logger.error(traceback.format_exc())
        context = {'errMsg': msg}
        return render(request, 'error.html', context)
    else:
        # 消息通知
        sys_config = SysConfig()
        if sys_config.get('mail') or sys_config.get('ding'):
            # 再次获取审核信息
            audit_detail = Audit.detail_by_workflow_id(
                workflow_id=workflow_id,
                workflow_type=WorkflowDict.workflow_type['sqlreview'])
            base_url = sys_config.get('archery_base_url',
                                      'http://127.0.0.1:8000').rstrip('/')
            workflow_url = "{base_url}/workflow/{audit_id}".format(
                base_url=base_url, audit_id=audit_detail.audit_id)
            async_task(notify,
                       audit_info=audit_detail,
                       workflow_url=workflow_url,
                       audit_remark=audit_remark,
                       timeout=60)
    return HttpResponseRedirect(reverse('sql:detail', args=(workflow_id, )))