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,