diff --git a/sql/templates/workflow_display.html b/sql/templates/workflow_display.html index 0507cda0d0..d5a7188357 100644 --- a/sql/templates/workflow_display.html +++ b/sql/templates/workflow_display.html @@ -1,6 +1,8 @@ {# review_info 应为 ReviewInfo 对象, 本模板为所有用到 audit 工作流的审批共用 #} {% for n in review_info.nodes %} - {% if n.is_passed_node %} + {% if n.is_auto_pass %} + 无需审批 + {% elif n.is_passed_node %} {{ n.group.name }} {% elif n.is_current_node %} diff --git a/sql/utils/test_workflow_audit.py b/sql/utils/test_workflow_audit.py index 29315d9384..c3a0e2f45f 100644 --- a/sql/utils/test_workflow_audit.py +++ b/sql/utils/test_workflow_audit.py @@ -22,7 +22,13 @@ WorkflowAuditSetting, ) from sql.utils.tests import User -from sql.utils.workflow_audit import Audit, AuditV2, AuditSetting, AuditException +from sql.utils.workflow_audit import ( + Audit, + AuditV2, + AuditSetting, + AuditException, + ReviewNodeType, +) class TestAudit(TestCase): @@ -546,3 +552,20 @@ def test_get_review_info( assert review_info.nodes[0].is_passed_node is True assert review_info.nodes[1].is_current_node is True assert review_info.nodes[1].is_passed_node is False + + +def test_get_review_info_auto_pass( + sql_query_apply, + fake_generate_audit_setting, + admin_client, +): + # 自动通过的情况 + fake_generate_audit_setting.return_value = AuditSetting(auto_pass=True) + audit = AuditV2(workflow=sql_query_apply) + audit.create_audit() + review_info = audit.get_review_info() + assert review_info.nodes[0].node_type == ReviewNodeType.AUTO_PASS + # 测一下详情页 get + response = admin_client.get(f"/queryapplydetail/{sql_query_apply.apply_id}/") + assert response.status_code == 200 + assert "无需审批" in response.content.decode("utf-8") diff --git a/sql/utils/workflow_audit.py b/sql/utils/workflow_audit.py index aa6cc25e0f..3e87b0bcc4 100644 --- a/sql/utils/workflow_audit.py +++ b/sql/utils/workflow_audit.py @@ -4,6 +4,7 @@ import json import re from dataclasses import dataclass, field +from enum import Enum from typing import Union, Optional, List import logging @@ -35,12 +36,28 @@ class AuditException(Exception): pass +class ReviewNodeType(Enum): + GROUP = "group" + AUTO_PASS = "auto_pass" + + @dataclass class ReviewNode: - group: Group + group: Optional[Group] = None + node_type: ReviewNodeType = ReviewNodeType.GROUP is_current_node: bool = False is_passed_node: bool = False + def __post_init__(self): + if self.node_type == ReviewNodeType.GROUP and not self.group: + raise ValueError( + f"group not provided and node_type is set as {self.node_type}" + ) + + @property + def is_auto_pass(self): + return self.node_type == ReviewNodeType.AUTO_PASS + @dataclass class ReviewInfo: @@ -514,6 +531,15 @@ def get_review_info(self) -> ReviewInfo: has_met_current_node = False current_node_group_id = int(self.audit.current_audit) for g in self.audit.audit_auth_groups.split(","): + if not g: + # 空的值, 代表的是自动通过 + review_nodes.append( + ReviewNode( + node_type=ReviewNodeType.AUTO_PASS, + is_passed_node=True, + ) + ) + continue g = int(g) group_in_db = Group.objects.get(id=g) if self.audit.current_status != WorkflowStatus.WAITING: diff --git a/sql/views.py b/sql/views.py index f6f9712caa..ae849fee06 100644 --- a/sql/views.py +++ b/sql/views.py @@ -1,7 +1,6 @@ # -*- coding: UTF-8 -*- import os import traceback -from django.conf import settings from django.contrib.auth.decorators import permission_required from django.contrib.auth.models import Group @@ -32,7 +31,7 @@ AuditEntry, TwoFactorAuthConfig, ) -from sql.utils.workflow_audit import Audit, AuditV2, AuditException +from sql.utils.workflow_audit import Audit, AuditV2, AuditException, ReviewNodeType from sql.utils.sql_review import ( can_execute, can_timingtask,