From 6e0d5537e012ace8e95f80685823a5bf0f58cf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E5=BA=B7?= <49478192+pengkang1991@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:30:00 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"=E5=9C=A8=E5=89=8D=E7=AB=AF=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E5=B1=95=E7=A4=BA=E5=AE=A1=E6=89=B9=E6=B5=81=20(#2423?= =?UTF-8?q?)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conftest.py | 6 -- sql/notify.py | 20 +++-- sql/templates/archivedetail.html | 22 +++-- sql/templates/detail.html | 20 +++-- sql/templates/queryapplydetail.html | 20 +++-- sql/templates/workflow_display.html | 19 ----- sql/test_archiver.py | 23 +---- sql/test_notify.py | 12 +-- sql/test_workflow.py | 7 +- sql/tests.py | 46 ++++++++++ sql/utils/test_workflow_audit.py | 59 ++++++------- sql/utils/workflow_audit.py | 128 ++++++++-------------------- sql/views.py | 45 ++++++---- 13 files changed, 194 insertions(+), 233 deletions(-) delete mode 100644 sql/templates/workflow_display.html diff --git a/conftest.py b/conftest.py index 11a8ba3c12..00c2ea42a7 100644 --- a/conftest.py +++ b/conftest.py @@ -190,9 +190,3 @@ def create_audit_workflow(normal_user, create_resource_group): ) yield audit_wf audit_wf.delete() - - -@pytest.fixture -def clean_auth_group(db): - yield - Group.objects.all().delete() diff --git a/sql/notify.py b/sql/notify.py index 1ac8c0b784..c68618ca52 100755 --- a/sql/notify.py +++ b/sql/notify.py @@ -26,7 +26,7 @@ SqlWorkflowContent, ) from sql.utils.resource_group import auth_group_users -from sql.utils.workflow_audit import Audit, AuditV2 +from sql.utils.workflow_audit import Audit from sql_api.serializers import ( WorkflowContentSerializer, WorkflowAuditListSerializer, @@ -156,8 +156,9 @@ def render_audit(self): workflow_from = self.audit.create_user_display group_name = self.audit.group_name # 获取当前审批和审批流程 - audit_handler = AuditV2(workflow=self.workflow, audit=self.audit) - review_info = audit_handler.get_review_info() + workflow_auditors, current_workflow_auditors = Audit.review_info( + self.audit.workflow_id, self.audit.workflow_type + ) # workflow content, 即申请通过后要执行什么东西 # 执行的 SQL 语句, 授权的范围 if workflow_type == WorkflowType.QUERY: @@ -220,8 +221,8 @@ def render_audit(self): group_name, instance, db_name, - review_info.readable_info, - review_info.current_node.group.name, + workflow_auditors, + current_workflow_auditors, workflow_title, workflow_url, workflow_content, @@ -237,7 +238,7 @@ def render_audit(self): group_name, instance, db_name, - review_info.readable_info, + workflow_auditors, workflow_title, workflow_url, workflow_content, @@ -283,8 +284,9 @@ def render_execute(self): base_url = self.sys_config.get( "archery_base_url", "http://127.0.0.1:8000" ).rstrip("/") - audit_handler = AuditV2(workflow=self.workflow, audit=self.audit) - review_info = audit_handler.get_review_info() + audit_auth_group, current_audit_auth_group = Audit.review_info( + self.workflow.id, 2 + ) audit_id = Audit.detail_by_workflow_id(self.workflow.id, 2).audit_id url = "{base_url}/workflow/{audit_id}".format( base_url=base_url, audit_id=audit_id @@ -303,7 +305,7 @@ def render_execute(self): 组:{self.workflow.group_name} 目标实例:{self.workflow.instance.instance_name} 数据库:{self.workflow.db_name} -审批流程:{review_info.readable_info} +审批流程:{audit_auth_group} 工单名称:{self.workflow.workflow_name} 工单地址:{url} 工单详情预览:{preview}""" diff --git a/sql/templates/archivedetail.html b/sql/templates/archivedetail.html index 8e6fecc3b4..441867ce22 100644 --- a/sql/templates/archivedetail.html +++ b/sql/templates/archivedetail.html @@ -21,14 +21,6 @@

工单名称:{{ archive_config.title }}
-

- 审批流 -

-
- {% include "workflow_display.html" %} -

- 其他信息 -

@@ -36,6 +28,12 @@

+ + @@ -67,6 +65,12 @@

+ + @@ -236,7 +240,7 @@

归档条件


{% endif %} {% if archive_config.status == 0 %} - {% if can_review %} + {% if is_can_review %}
diff --git a/sql/templates/detail.html b/sql/templates/detail.html index 95e258d993..9fa999b4c7 100644 --- a/sql/templates/detail.html +++ b/sql/templates/detail.html @@ -18,14 +18,6 @@


-

- 审批流 -

-
- {% include "workflow_display.html" %} -

- 其他信息 -

申请人 + 审批流程 + + 当前审批 + 实例 {{ archive_config.user_display }} + {{ audit_auth_group }} + + {{ current_audit_auth_group }} + {{ archive_config.src_instance }}
@@ -33,6 +25,12 @@

+ + @@ -67,6 +65,12 @@

+ + diff --git a/sql/templates/queryapplydetail.html b/sql/templates/queryapplydetail.html index 402a8e4a40..324b20bf55 100644 --- a/sql/templates/queryapplydetail.html +++ b/sql/templates/queryapplydetail.html @@ -10,14 +10,6 @@

工单名称:{{ workflow_detail.title }}
-

- 审批流 -

-
- {% include "workflow_display.html" %} -

- 其他信息 -

发起人 + 审批流程 + + 当前审批 + 目标实例 {{ workflow_detail.engineer_display }} + {{ audit_auth_group }} + + {{ current_audit_auth_group }} + {{ workflow_detail.instance.instance_name }}
@@ -25,6 +17,12 @@

+ + @@ -56,6 +54,12 @@

+ + diff --git a/sql/templates/workflow_display.html b/sql/templates/workflow_display.html deleted file mode 100644 index 0507cda0d0..0000000000 --- a/sql/templates/workflow_display.html +++ /dev/null @@ -1,19 +0,0 @@ -{# review_info 应为 ReviewInfo 对象, 本模板为所有用到 audit 工作流的审批共用 #} -{% for n in review_info.nodes %} - {% if n.is_passed_node %} - {{ n.group.name }} - {% elif n.is_current_node %} - - - {{ n.group.name }}( - {% for u in n.group.user_set.all %} - {{ u.username }} - {% endfor %}) - - {% else %} - {{ n.group.name }} - {% endif %} - {% if not forloop.last %} - - {% endif %} -{% endfor %} diff --git a/sql/test_archiver.py b/sql/test_archiver.py index 6f5025fc1a..33e444e0f3 100644 --- a/sql/test_archiver.py +++ b/sql/test_archiver.py @@ -4,11 +4,10 @@ from django.conf import settings from django.contrib.auth.models import Permission from django.test import TestCase, Client -from pytest_django.asserts import assertTemplateUsed from common.config import SysConfig from common.utils.const import WorkflowStatus, WorkflowType -from sql.utils.workflow_audit import AuditSetting, AuditV2 +from sql.utils.workflow_audit import AuditSetting from sql.archiver import add_archive_task, archive from sql.models import ( Instance, @@ -300,23 +299,3 @@ def test_archive_log(self, _async_task): self.client.force_login(self.superuser) r = self.client.post(path="/archive/log/", data=data) self.assertDictEqual(json.loads(r.content), {"total": 0, "rows": []}) - - -def test_archive_detail_view( - archive_apply, - resource_group, - admin_client, - fake_generate_audit_setting, - create_auth_group, -): - audit = AuditV2(workflow=archive_apply, resource_group=resource_group.group_name) - audit.create_audit() - audit.workflow.save() - response = admin_client.get(f"/archive/{archive_apply.id}/") - assert response.status_code == 200 - assertTemplateUsed(response, "archivedetail.html") - review_info = response.context["review_info"] - assert len(review_info.nodes) == len( - fake_generate_audit_setting.return_value.audit_auth_groups - ) - assert review_info.nodes[0].group.name == create_auth_group.name diff --git a/sql/test_notify.py b/sql/test_notify.py index 71d36ec474..8cc9412595 100644 --- a/sql/test_notify.py +++ b/sql/test_notify.py @@ -131,9 +131,9 @@ def setUp(self): workflow_type=1, workflow_title="申请标题", workflow_remark="申请备注", - audit_auth_groups=",".join([str(self.aug.id)]), - current_audit=str(self.aug.id), - next_audit="-1", + audit_auth_groups="1,2,3", + current_audit="1", + next_audit="2", current_status=0, ) self.audit_query_detail = WorkflowAuditDetail.objects.create( @@ -167,9 +167,9 @@ def setUp(self): workflow_type=3, workflow_title=self.archive_apply.title, workflow_remark="申请备注", - audit_auth_groups=",".join([str(self.aug.id)]), - current_audit=str(self.aug.id), - next_audit="-1", + audit_auth_groups="1,2,3", + current_audit="1", + next_audit="2", current_status=0, ) diff --git a/sql/test_workflow.py b/sql/test_workflow.py index 87702e3eee..a36d145ad0 100644 --- a/sql/test_workflow.py +++ b/sql/test_workflow.py @@ -19,8 +19,7 @@ def test_get_sql_workflow( assert response.status_code == 200 assertTemplateUsed(response, "detail.html") # 展示审批人用户名 - review_info = response.context["review_info"] - assert len(review_info.nodes) == len( - fake_generate_audit_setting.return_value.audit_auth_groups + assert ( + response.context["current_audit_auth_group"] + == f"{create_auth_group.name}: {super_user.username}" ) - assert review_info.nodes[0].group.name == create_auth_group.name diff --git a/sql/tests.py b/sql/tests.py index f72ff2e58e..d96dab16d7 100644 --- a/sql/tests.py +++ b/sql/tests.py @@ -825,6 +825,52 @@ def test_alter_run_date(self, _can_review): r, f"/detail/{self.wf1.id}/", fetch_redirect_response=False ) + @patch("sql.utils.workflow_audit.Audit.logs") + @patch("sql.utils.workflow_audit.Audit.detail_by_workflow_id") + @patch("sql.utils.workflow_audit.Audit.review_info") + @patch("sql.utils.workflow_audit.Audit.can_review") + def testWorkflowDetailView(self, _can_review, _review_info, _detail_by_id, _logs): + """测试工单详情""" + _review_info.return_value = ("some_auth_group", "current_auth_group") + _can_review.return_value = False + _detail_by_id.return_value.audit_id = 123 + _logs.return_value.latest("id").operation_info = "" + c = Client() + c.force_login(self.u1) + r = c.get("/detail/{}/".format(self.wf1.id)) + expected_status_display = r"""id="workflow_detail_disaply">已正常结束""" + self.assertContains(r, expected_status_display) + exepcted_status = r"""id="workflow_detail_status">workflow_finish""" + self.assertContains(r, exepcted_status) + + # 测试执行详情解析失败 + self.wfc1.execute_result = "cannotbedecode:1,:" + self.wfc1.save() + r = c.get("/detail/{}/".format(self.wf1.id)) + self.assertContains(r, expected_status_display) + self.assertContains(r, exepcted_status) + + # 执行详情为空 + self.wfc1.review_content = [ + { + "id": 1, + "stage": "CHECKED", + "errlevel": 0, + "stagestatus": "Audit completed", + "errormessage": "None", + "sql": "use archery", + "affected_rows": 0, + "sequence": "'0_0_0'", + "backup_dbname": "None", + "execute_time": "0", + "sqlsha1": "", + "actual_affected_rows": "", + } + ] + self.wfc1.execute_result = "" + self.wfc1.save() + r = c.get("/detail/{}/".format(self.wf1.id)) + def testWorkflowListView(self): """测试工单列表""" c = Client() diff --git a/sql/utils/test_workflow_audit.py b/sql/utils/test_workflow_audit.py index 29315d9384..a8d2628b7e 100644 --- a/sql/utils/test_workflow_audit.py +++ b/sql/utils/test_workflow_audit.py @@ -302,6 +302,34 @@ def test_can_review_no_prem_exception( self.user, self.audit.workflow_id, self.audit.workflow_type ) + def test_review_info_no_review(self): + """测试获取当前工单审批流程和当前审核组,无需审批""" + self.audit.workflow_type = WorkflowType.SQL_REVIEW + self.audit.workflow_id = self.wf.id + self.audit.audit_auth_groups = "" + self.audit.current_audit = "-1" + self.audit.save() + audit_auth_group, current_audit_auth_group = Audit.review_info( + self.audit.workflow_id, self.audit.workflow_type + ) + self.assertEqual(audit_auth_group, "无需审批") + self.assertEqual(current_audit_auth_group, None) + + def test_review_info(self): + """测试获取当前工单审批流程和当前审核组,无需审批""" + aug = Group.objects.create(name="DBA") + self.user.groups.add(aug) + self.audit.workflow_type = WorkflowType.SQL_REVIEW + self.audit.workflow_id = self.wf.id + self.audit.audit_auth_groups = str(aug.id) + self.audit.current_audit = str(aug.id) + self.audit.save() + audit_auth_group, current_audit_auth_group = Audit.review_info( + self.audit.workflow_id, self.audit.workflow_type + ) + self.assertEqual(audit_auth_group, "DBA") + self.assertEqual(current_audit_auth_group, f"DBA: {self.user.username}") + def test_logs(self): """测试获取工单日志""" r = Audit.logs(self.audit.audit_id).first() @@ -515,34 +543,3 @@ def test_auto_review_not_applicable( audit.sys_config.set("auto_review_max_update_rows", 1000) # 全部条件满足, 自动审核通过 assert audit.is_auto_review() is True - - -def test_get_review_info( - sql_query_apply, - resource_group, - create_auth_group, - fake_generate_audit_setting, - clean_auth_group, -): - g2 = Group.objects.create(name="g2") - g3 = Group.objects.create(name="g3") - fake_generate_audit_setting.return_value = AuditSetting( - auto_pass=False, audit_auth_groups=[create_auth_group.id, g2.id, g3.id] - ) - audit = AuditV2(workflow=sql_query_apply) - audit.create_audit() - review_info = audit.get_review_info() - assert review_info.nodes[0].group.name == create_auth_group.name - assert review_info.nodes[0].is_current_node is True - assert review_info.nodes[0].is_passed_node is False - assert review_info.nodes[1].is_current_node is False - assert review_info.nodes[1].is_passed_node is False - - # 将当前节点设置为第二个节点, 重新生成 - audit.audit.current_audit = str(g2.id) - audit.audit.save() - review_info = audit.get_review_info() - assert review_info.nodes[0].is_current_node is False - 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 diff --git a/sql/utils/workflow_audit.py b/sql/utils/workflow_audit.py index aa6cc25e0f..261d64b313 100644 --- a/sql/utils/workflow_audit.py +++ b/sql/utils/workflow_audit.py @@ -35,45 +35,6 @@ class AuditException(Exception): pass -@dataclass -class ReviewNode: - group: Group - is_current_node: bool = False - is_passed_node: bool = False - - -@dataclass -class ReviewInfo: - nodes: List[ReviewNode] = field(default_factory=list) - current_node_index: int = None - - @property - def readable_info(self) -> str: - """生成可读的工作流, 形如 g1(passed) -> g2(current) -> g3 - 一般用途是渲染消息 - """ - steps = [] - for index, n in enumerate(self.nodes): - if n.is_current_node: - self.current_node_index = index - steps.append(f"{n.group.name}(current)") - continue - if n.is_passed_node: - steps.append(f"{n.group.name}(passed)") - continue - steps.append(n.group.name) - return " -> ".join(steps) - - @property - def current_node(self) -> ReviewNode: - if self.current_node_index: - return self.nodes[self.current_node_index] - for index, n in enumerate(self.nodes): - if n.is_current_node: - self.current_node_index = n - return n - - @dataclass class AuditSetting: """ @@ -322,7 +283,7 @@ def create_audit(self) -> str: return "工单已正常提交" def can_operate(self, action: WorkflowAction, actor: Users): - """检查用户是否有权限做相关操作, 如有权限问题, raise AuditException, 无问题返回 True""" + """检查用户是否有权限做相关操作, 默认不返回, 如有权限问题, raise AuditException""" # 首先检查工单状态和相关操作是否匹配, 如已通过的工单不能再通过 allowed_actions = SUPPORTED_OPERATION_GRID.get(self.audit.current_status) if not allowed_actions: @@ -345,12 +306,12 @@ def can_operate(self, action: WorkflowAction, actor: Users): if action == WorkflowAction.ABORT: if actor.username != self.audit.create_user: raise AuditException(f"只有工单提交者可以撤回工单") - return True + return if action in [WorkflowAction.PASS, WorkflowAction.REJECT]: # 需要检查权限 # 超级用户可以审批所有工单 if actor.is_superuser: - return True + return # 看是否本人审核 if actor.username == self.audit.create_user and self.sys_config.get( "ban_self_audit" @@ -367,14 +328,14 @@ def can_operate(self, action: WorkflowAction, actor: Users): raise AuditException("当前审批权限组不存在, 请联系管理员检查并清洗错误数据") if not auth_group_users([audit_auth_group.name], self.resource_group_id): raise AuditException("用户不在当前审批审批节点的用户组内, 无权限审核") - return True + return if action in [ WorkflowAction.EXECUTE_START, WorkflowAction.EXECUTE_END, WorkflowAction.EXECUTE_SET_TIME, ]: # 一般是系统自动流转, 自动通过 - return True + return raise AuditException(f"不支持的操作, 无法判断权限") @@ -504,55 +465,6 @@ def operate_abort(self, actor: Users, remark: str) -> WorkflowAuditDetail: ) return workflow_audit_detail - def get_review_info(self) -> ReviewInfo: - """提供审批流各节点的状态 - 如果总体是待审核状态, 当前节点之前为已通过, 当前节点为当前节点, 未通过, 当前节点之后为未通过 - 如果总体为其他状态, 节点的属性都不设置, 均为默认值 - """ - self.get_audit_info() - review_nodes = [] - has_met_current_node = False - current_node_group_id = int(self.audit.current_audit) - for g in self.audit.audit_auth_groups.split(","): - g = int(g) - group_in_db = Group.objects.get(id=g) - if self.audit.current_status != WorkflowStatus.WAITING: - # 总体状态不是待审核, 不设置详细的属性 - review_nodes.append( - ReviewNode( - group=group_in_db, - ) - ) - continue - if current_node_group_id == g: - # 当前节点, 一定为未通过 - has_met_current_node = True - review_nodes.append( - ReviewNode( - group=group_in_db, - is_current_node=True, - is_passed_node=False, - ) - ) - continue - if has_met_current_node: - # 当前节点之后的节点, 一定为未通过 - review_nodes.append( - ReviewNode( - group=group_in_db, - is_passed_node=False, - ) - ) - continue - # 以上情况之外的情况, 一定为已经通过的节点 - review_nodes.append( - ReviewNode( - group=group_in_db, - is_passed_node=True, - ) - ) - return ReviewInfo(nodes=review_nodes) - class Audit(object): """老版 Audit, 建议不再更新新内容, 转而使用 AuditV2""" @@ -676,6 +588,36 @@ def get_workflow_applicant(workflow_id, workflow_type): result = True return result + # 获取当前工单审批流程和当前审核组 + @staticmethod + def review_info(workflow_id, workflow_type): + audit_info = WorkflowAudit.objects.get( + workflow_id=workflow_id, workflow_type=workflow_type + ) + if audit_info.audit_auth_groups == "": + audit_auth_group = "无需审批" + else: + try: + audit_auth_group = "->".join( + [ + Group.objects.get(id=auth_group_id).name + for auth_group_id in audit_info.audit_auth_groups.split(",") + ] + ) + except Exception: + audit_auth_group = audit_info.audit_auth_groups + if audit_info.current_audit == "-1": + current_audit_auth_group = None + else: + try: + auth_group_in_db = Group.objects.get(id=audit_info.current_audit) + users = auth_group_in_db.user_set.all() + users_display = ",".join(x.username for x in users) or "组内无用户, 请联系管理员" + current_audit_auth_group = f"{auth_group_in_db.name}: {users_display}" + except Exception: + current_audit_auth_group = audit_info.current_audit + return audit_auth_group, current_audit_auth_group + # 新增工单日志 @staticmethod def add_log( diff --git a/sql/views.py b/sql/views.py index f6f9712caa..ca3d69efe7 100644 --- a/sql/views.py +++ b/sql/views.py @@ -32,7 +32,7 @@ AuditEntry, TwoFactorAuthConfig, ) -from sql.utils.workflow_audit import Audit, AuditV2, AuditException +from sql.utils.workflow_audit import Audit from sql.utils.sql_review import ( can_execute, can_timingtask, @@ -40,7 +40,7 @@ can_view, can_rollback, ) -from common.utils.const import Const, WorkflowType, WorkflowAction +from common.utils.const import Const, WorkflowType from sql.utils.resource_group import user_groups, user_instances, auth_group_users import logging @@ -185,12 +185,13 @@ def submit_sql(request): def detail(request, workflow_id): """展示SQL工单详细页面""" workflow_detail = get_object_or_404(SqlWorkflow, pk=workflow_id) - audit_handler = AuditV2(workflow=workflow_detail) if not can_view(request.user, workflow_id): raise PermissionDenied - review_info = audit_handler.get_review_info() # 自动审批不通过的不需要获取下列信息 if workflow_detail.status != "workflow_autoreviewwrong": + # 获取当前审批和审批流程 + audit_auth_group, current_audit_auth_group = Audit.review_info(workflow_id, 2) + # 是否可审核 is_can_review = Audit.can_review(request.user, workflow_id, 2) # 是否可执行 TODO 这几个判断方法入参都修改为workflow对象,可减少多次数据库交互 @@ -212,10 +213,18 @@ def detail(request, workflow_id): last_operation_info = ( Audit.logs(audit_id=audit_id).latest("id").operation_info ) + # 等待审批的展示当前全部审批人 + if workflow_detail.status == "workflow_manreviewing": + _, current_audit_users_display = Audit.review_info( + workflow_id, WorkflowType.SQL_REVIEW + ) + last_operation_info += f",当前审批节点:{current_audit_users_display}" except Exception as e: logger.debug(f"无审核日志记录,错误信息{e}") last_operation_info = "" else: + audit_auth_group = "系统自动驳回" + current_audit_auth_group = "系统自动驳回" is_can_review = False is_can_execute = False is_can_timingtask = False @@ -245,8 +254,9 @@ def detail(request, workflow_id): "is_can_timingtask": is_can_timingtask, "is_can_cancel": is_can_cancel, "is_can_rollback": is_can_rollback, - "review_info": review_info, + "audit_auth_group": audit_auth_group, "manual": manual, + "current_audit_auth_group": current_audit_auth_group, "run_date": run_date, } return render(request, "detail.html", context) @@ -338,8 +348,7 @@ def queryapplydetail(request, apply_id): """查询权限申请详情页面""" workflow_detail = QueryPrivilegesApply.objects.get(apply_id=apply_id) # 获取当前审批和审批流程 - audit_handler = AuditV2(workflow=workflow_detail) - review_info = audit_handler.get_review_info() + audit_auth_group, current_audit_auth_group = Audit.review_info(apply_id, 1) # 是否可审核 is_can_review = Audit.can_review(request.user, apply_id, 1) @@ -360,8 +369,9 @@ def queryapplydetail(request, apply_id): context = { "workflow_detail": workflow_detail, - "review_info": review_info, + "audit_auth_group": audit_auth_group, "last_operation_info": last_operation_info, + "current_audit_auth_group": current_audit_auth_group, "is_can_review": is_can_review, } return render(request, "queryapplydetail.html", context) @@ -459,15 +469,13 @@ def archive_detail(request, id): """归档详情页面""" archive_config = ArchiveConfig.objects.get(pk=id) # 获取当前审批和审批流程、是否可审核 - audit_handler = AuditV2( - workflow=archive_config, resource_group=archive_config.resource_group - ) - review_info = audit_handler.get_review_info() try: - audit_handler.can_operate(WorkflowAction.PASS, request.user) - can_review = True - except AuditException: - can_review = False + audit_auth_group, current_audit_auth_group = Audit.review_info(id, 3) + is_can_review = Audit.can_review(request.user, id, 3) + except Exception as e: + logger.debug(f"归档配置{id}无审核信息,{e}") + audit_auth_group, current_audit_auth_group = None, None + is_can_review = False # 获取审核日志 if archive_config.status == 2: try: @@ -485,9 +493,10 @@ def archive_detail(request, id): context = { "archive_config": archive_config, - "review_info": review_info, + "audit_auth_group": audit_auth_group, "last_operation_info": last_operation_info, - "can_review": can_review, + "current_audit_auth_group": current_audit_auth_group, + "is_can_review": is_can_review, } return render(request, "archivedetail.html", context)
申请人 + 审批流程 + + 当前审批 + 实例 {{ workflow_detail.user_display }} + {{ audit_auth_group }} + + {{ current_audit_auth_group }} + {{ workflow_detail.instance.instance_name }}