mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-18 08:20:51 +00:00
feat: 工单多级审批 + 模版创建 (#6640)
* feat: 工单多级审批 + 模版创建 * feat: 工单权限处理 * fix: 工单关闭后 再审批bug * perf: 修改一点 Co-authored-by: feng626 <1304903146@qq.com> Co-authored-by: ibuler <ibuler@qq.com>
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
from django.utils.translation import ugettext as _
|
||||
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||
from applications.models import Application
|
||||
from applications.const import AppCategory, AppType
|
||||
from assets.models import SystemUser
|
||||
from applications.models import Application
|
||||
from perms.models import ApplicationPermission
|
||||
from assets.models import SystemUser
|
||||
|
||||
from .base import BaseHandler
|
||||
|
||||
|
||||
class Handler(BaseHandler):
|
||||
|
||||
def _on_approve(self):
|
||||
super()._on_approve()
|
||||
self._create_application_permission()
|
||||
is_finished = super()._on_approve()
|
||||
if is_finished:
|
||||
self._create_application_permission()
|
||||
|
||||
# display
|
||||
def _construct_meta_display_of_open(self):
|
||||
@@ -22,27 +24,21 @@ class Handler(BaseHandler):
|
||||
apply_type_display = AppType.get_label(apply_type)
|
||||
meta_display_values = [apply_category_display, apply_type_display]
|
||||
meta_display = dict(zip(meta_display_fields, meta_display_values))
|
||||
return meta_display
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users')
|
||||
apply_applications = self.ticket.meta.get('apply_applications')
|
||||
meta_display.update({
|
||||
'apply_system_users_display': [str(i) for i in SystemUser.objects.filter(id__in=apply_system_users)],
|
||||
'apply_applications_display': [str(i) for i in Application.objects.filter(id__in=apply_applications)]
|
||||
})
|
||||
|
||||
def _construct_meta_display_of_approve(self):
|
||||
meta_display_fields = ['approve_applications_display', 'approve_system_users_display']
|
||||
approve_application_ids = self.ticket.meta.get('approve_applications', [])
|
||||
approve_system_user_ids = self.ticket.meta.get('approve_system_users', [])
|
||||
with tmp_to_org(self.ticket.org_id):
|
||||
approve_applications = Application.objects.filter(id__in=approve_application_ids)
|
||||
system_users = SystemUser.objects.filter(id__in=approve_system_user_ids)
|
||||
approve_applications_display = [str(application) for application in approve_applications]
|
||||
approve_system_users_display = [str(system_user) for system_user in system_users]
|
||||
meta_display_values = [approve_applications_display, approve_system_users_display]
|
||||
meta_display = dict(zip(meta_display_fields, meta_display_values))
|
||||
return meta_display
|
||||
|
||||
# body
|
||||
def _construct_meta_body_of_open(self):
|
||||
apply_category_display = self.ticket.meta.get('apply_category_display')
|
||||
apply_type_display = self.ticket.meta.get('apply_type_display')
|
||||
apply_application_group = self.ticket.meta.get('apply_application_group', [])
|
||||
apply_system_user_group = self.ticket.meta.get('apply_system_user_group', [])
|
||||
apply_applications = self.ticket.meta.get('apply_applications', [])
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users', [])
|
||||
apply_date_start = self.ticket.meta.get('apply_date_start')
|
||||
apply_date_expired = self.ticket.meta.get('apply_date_expired')
|
||||
applied_body = '''{}: {},
|
||||
@@ -54,31 +50,13 @@ class Handler(BaseHandler):
|
||||
'''.format(
|
||||
_('Applied category'), apply_category_display,
|
||||
_('Applied type'), apply_type_display,
|
||||
_('Applied application group'), apply_application_group,
|
||||
_('Applied system user group'), apply_system_user_group,
|
||||
_('Applied application group'), apply_applications,
|
||||
_('Applied system user group'), apply_system_users,
|
||||
_('Applied date start'), apply_date_start,
|
||||
_('Applied date expired'), apply_date_expired,
|
||||
)
|
||||
return applied_body
|
||||
|
||||
def _construct_meta_body_of_approve(self):
|
||||
# 审批信息
|
||||
approve_applications_display = self.ticket.meta.get('approve_applications_display', [])
|
||||
approve_system_users_display = self.ticket.meta.get('approve_system_users_display', [])
|
||||
approve_date_start = self.ticket.meta.get('approve_date_start')
|
||||
approve_date_expired = self.ticket.meta.get('approve_date_expired')
|
||||
approved_body = '''{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
'''.format(
|
||||
_('Approved applications'), approve_applications_display,
|
||||
_('Approved system users'), approve_system_users_display,
|
||||
_('Approved date start'), approve_date_start,
|
||||
_('Approved date expired'), approve_date_expired
|
||||
)
|
||||
return approved_body
|
||||
|
||||
# permission
|
||||
def _create_application_permission(self):
|
||||
with tmp_to_root_org():
|
||||
@@ -88,11 +66,11 @@ class Handler(BaseHandler):
|
||||
|
||||
apply_category = self.ticket.meta.get('apply_category')
|
||||
apply_type = self.ticket.meta.get('apply_type')
|
||||
approve_permission_name = self.ticket.meta.get('approve_permission_name', '')
|
||||
approved_application_ids = self.ticket.meta.get('approve_applications', [])
|
||||
approve_system_user_ids = self.ticket.meta.get('approve_system_users', [])
|
||||
approve_date_start = self.ticket.meta.get('approve_date_start')
|
||||
approve_date_expired = self.ticket.meta.get('approve_date_expired')
|
||||
apply_permission_name = self.ticket.meta.get('apply_permission_name', '')
|
||||
apply_applications = self.ticket.meta.get('apply_applications', [])
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users', [])
|
||||
apply_date_start = self.ticket.meta.get('apply_date_start')
|
||||
apply_date_expired = self.ticket.meta.get('apply_date_expired')
|
||||
permission_created_by = '{}:{}'.format(
|
||||
str(self.ticket.__class__.__name__), str(self.ticket.id)
|
||||
)
|
||||
@@ -105,23 +83,23 @@ class Handler(BaseHandler):
|
||||
).format(
|
||||
self.ticket.title,
|
||||
self.ticket.applicant_display,
|
||||
self.ticket.processor_display,
|
||||
str(self.ticket.processor),
|
||||
str(self.ticket.id)
|
||||
)
|
||||
permissions_data = {
|
||||
'id': self.ticket.id,
|
||||
'name': approve_permission_name,
|
||||
'name': apply_permission_name,
|
||||
'category': apply_category,
|
||||
'type': apply_type,
|
||||
'comment': str(permission_comment),
|
||||
'created_by': permission_created_by,
|
||||
'date_start': approve_date_start,
|
||||
'date_expired': approve_date_expired,
|
||||
'date_start': apply_date_start,
|
||||
'date_expired': apply_date_expired,
|
||||
}
|
||||
with tmp_to_org(self.ticket.org_id):
|
||||
application_permission = ApplicationPermission.objects.create(**permissions_data)
|
||||
application_permission.users.add(self.ticket.applicant)
|
||||
application_permission.applications.set(approved_application_ids)
|
||||
application_permission.system_users.set(approve_system_user_ids)
|
||||
application_permission.applications.set(apply_applications)
|
||||
application_permission.system_users.set(apply_system_users)
|
||||
|
||||
return application_permission
|
||||
|
@@ -1,16 +1,19 @@
|
||||
from assets.models import Asset
|
||||
from assets.models import SystemUser
|
||||
|
||||
from .base import BaseHandler
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from perms.models import AssetPermission, Action
|
||||
from assets.models import Asset, SystemUser
|
||||
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||
|
||||
|
||||
class Handler(BaseHandler):
|
||||
|
||||
def _on_approve(self):
|
||||
super()._on_approve()
|
||||
self._create_asset_permission()
|
||||
is_finished = super()._on_approve()
|
||||
if is_finished:
|
||||
self._create_asset_permission()
|
||||
|
||||
# display
|
||||
def _construct_meta_display_of_open(self):
|
||||
@@ -19,32 +22,18 @@ class Handler(BaseHandler):
|
||||
apply_actions_display = Action.value_to_choices_display(apply_actions)
|
||||
meta_display_values = [apply_actions_display]
|
||||
meta_display = dict(zip(meta_display_fields, meta_display_values))
|
||||
return meta_display
|
||||
|
||||
def _construct_meta_display_of_approve(self):
|
||||
meta_display_fields = [
|
||||
'approve_actions_display', 'approve_assets_display', 'approve_system_users_display'
|
||||
]
|
||||
approve_actions = self.ticket.meta.get('approve_actions', Action.NONE)
|
||||
approve_actions_display = Action.value_to_choices_display(approve_actions)
|
||||
approve_asset_ids = self.ticket.meta.get('approve_assets', [])
|
||||
approve_system_user_ids = self.ticket.meta.get('approve_system_users', [])
|
||||
with tmp_to_org(self.ticket.org_id):
|
||||
assets = Asset.objects.filter(id__in=approve_asset_ids)
|
||||
system_users = SystemUser.objects.filter(id__in=approve_system_user_ids)
|
||||
approve_assets_display = [str(asset) for asset in assets]
|
||||
approve_system_users_display = [str(system_user) for system_user in system_users]
|
||||
meta_display_values = [
|
||||
approve_actions_display, approve_assets_display, approve_system_users_display
|
||||
]
|
||||
meta_display = dict(zip(meta_display_fields, meta_display_values))
|
||||
apply_assets = self.ticket.meta.get('apply_assets')
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users')
|
||||
meta_display.update({
|
||||
'apply_assets_display': [str(i) for i in Asset.objects.filter(id__in=apply_assets)],
|
||||
'apply_system_users_display': [str(i)for i in SystemUser.objects.filter(id__in=apply_system_users)]
|
||||
})
|
||||
return meta_display
|
||||
|
||||
# body
|
||||
def _construct_meta_body_of_open(self):
|
||||
apply_ip_group = self.ticket.meta.get('apply_ip_group', [])
|
||||
apply_hostname_group = self.ticket.meta.get('apply_hostname_group', [])
|
||||
apply_system_user_group = self.ticket.meta.get('apply_system_user_group', [])
|
||||
apply_assets = self.ticket.meta.get('apply_assets', [])
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users', [])
|
||||
apply_actions_display = self.ticket.meta.get('apply_actions_display', [])
|
||||
apply_date_start = self.ticket.meta.get('apply_date_start')
|
||||
apply_date_expired = self.ticket.meta.get('apply_date_expired')
|
||||
@@ -54,35 +43,14 @@ class Handler(BaseHandler):
|
||||
{}: {},
|
||||
{}: {}
|
||||
'''.format(
|
||||
_('Applied IP group'), apply_ip_group,
|
||||
_("Applied hostname group"), apply_hostname_group,
|
||||
_("Applied system user group"), apply_system_user_group,
|
||||
_("Applied hostname group"), apply_assets,
|
||||
_("Applied system user group"), apply_system_users,
|
||||
_("Applied actions"), apply_actions_display,
|
||||
_('Applied date start'), apply_date_start,
|
||||
_('Applied date expired'), apply_date_expired,
|
||||
)
|
||||
return applied_body
|
||||
|
||||
def _construct_meta_body_of_approve(self):
|
||||
approve_assets_display = self.ticket.meta.get('approve_assets_display', [])
|
||||
approve_system_users_display = self.ticket.meta.get('approve_system_users_display', [])
|
||||
approve_actions_display = self.ticket.meta.get('approve_actions_display', [])
|
||||
approve_date_start = self.ticket.meta.get('approve_date_start')
|
||||
approve_date_expired = self.ticket.meta.get('approve_date_expired')
|
||||
approved_body = '''{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {}
|
||||
'''.format(
|
||||
_('Approved assets'), approve_assets_display,
|
||||
_('Approved system users'), approve_system_users_display,
|
||||
_('Approved actions'), ', '.join(approve_actions_display),
|
||||
_('Approved date start'), approve_date_start,
|
||||
_('Approved date expired'), approve_date_expired,
|
||||
)
|
||||
return approved_body
|
||||
|
||||
# permission
|
||||
def _create_asset_permission(self):
|
||||
with tmp_to_root_org():
|
||||
@@ -90,12 +58,12 @@ class Handler(BaseHandler):
|
||||
if asset_permission:
|
||||
return asset_permission
|
||||
|
||||
approve_permission_name = self.ticket.meta.get('approve_permission_name', )
|
||||
approve_asset_ids = self.ticket.meta.get('approve_assets', [])
|
||||
approve_system_user_ids = self.ticket.meta.get('approve_system_users', [])
|
||||
approve_actions = self.ticket.meta.get('approve_actions', Action.NONE)
|
||||
approve_date_start = self.ticket.meta.get('approve_date_start')
|
||||
approve_date_expired = self.ticket.meta.get('approve_date_expired')
|
||||
apply_permission_name = self.ticket.meta.get('apply_permission_name', )
|
||||
apply_assets = self.ticket.meta.get('apply_assets', [])
|
||||
apply_system_users = self.ticket.meta.get('apply_system_users', [])
|
||||
apply_actions = self.ticket.meta.get('apply_actions', Action.NONE)
|
||||
apply_date_start = self.ticket.meta.get('apply_date_start')
|
||||
apply_date_expired = self.ticket.meta.get('apply_date_expired')
|
||||
permission_created_by = '{}:{}'.format(
|
||||
str(self.ticket.__class__.__name__), str(self.ticket.id)
|
||||
)
|
||||
@@ -108,23 +76,23 @@ class Handler(BaseHandler):
|
||||
).format(
|
||||
self.ticket.title,
|
||||
self.ticket.applicant_display,
|
||||
self.ticket.processor_display,
|
||||
str(self.ticket.processor),
|
||||
str(self.ticket.id)
|
||||
)
|
||||
|
||||
permission_data = {
|
||||
'id': self.ticket.id,
|
||||
'name': approve_permission_name,
|
||||
'name': apply_permission_name,
|
||||
'comment': str(permission_comment),
|
||||
'created_by': permission_created_by,
|
||||
'actions': approve_actions,
|
||||
'date_start': approve_date_start,
|
||||
'date_expired': approve_date_expired,
|
||||
'actions': apply_actions,
|
||||
'date_start': apply_date_start,
|
||||
'date_expired': apply_date_expired,
|
||||
}
|
||||
with tmp_to_org(self.ticket.org_id):
|
||||
asset_permission = AssetPermission.objects.create(**permission_data)
|
||||
asset_permission.users.add(self.ticket.applicant)
|
||||
asset_permission.assets.set(approve_asset_ids)
|
||||
asset_permission.system_users.set(approve_system_user_ids)
|
||||
asset_permission.assets.set(apply_assets)
|
||||
asset_permission.system_users.set(apply_system_users)
|
||||
|
||||
return asset_permission
|
||||
|
@@ -3,7 +3,7 @@ from common.utils import get_logger
|
||||
from tickets.utils import (
|
||||
send_ticket_processed_mail_to_applicant, send_ticket_applied_mail_to_assignees
|
||||
)
|
||||
|
||||
from tickets.const import TicketAction
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -16,48 +16,72 @@ class BaseHandler(object):
|
||||
# on action
|
||||
def _on_open(self):
|
||||
self.ticket.applicant_display = str(self.ticket.applicant)
|
||||
self.ticket.assignees_display = [str(assignee) for assignee in self.ticket.assignees.all()]
|
||||
meta_display = getattr(self, '_construct_meta_display_of_open', lambda: {})()
|
||||
self.ticket.meta.update(meta_display)
|
||||
self.ticket.save()
|
||||
self._send_applied_mail_to_assignees()
|
||||
|
||||
def _on_approve(self):
|
||||
meta_display = getattr(self, '_construct_meta_display_of_approve', lambda: {})()
|
||||
self.ticket.meta.update(meta_display)
|
||||
self.__on_process()
|
||||
if self.ticket.approval_step != len(self.ticket.process_map):
|
||||
self.ticket.approval_step += 1
|
||||
self.ticket.create_related_node()
|
||||
is_finished = False
|
||||
else:
|
||||
self.ticket.set_state_approve()
|
||||
self.ticket.set_status_closed()
|
||||
is_finished = True
|
||||
self._send_applied_mail_to_assignees()
|
||||
|
||||
self.__on_process(self.ticket.processor)
|
||||
return is_finished
|
||||
|
||||
def _on_reject(self):
|
||||
self.__on_process()
|
||||
self.ticket.set_state_reject()
|
||||
self.ticket.set_status_closed()
|
||||
self.__on_process(self.ticket.processor)
|
||||
|
||||
def _on_close(self):
|
||||
self.__on_process()
|
||||
|
||||
def __on_process(self):
|
||||
self.ticket.processor_display = str(self.ticket.processor)
|
||||
self.ticket.set_state_closed()
|
||||
self.ticket.set_status_closed()
|
||||
self._send_processed_mail_to_applicant()
|
||||
self.__on_process(self.ticket.processor)
|
||||
|
||||
def __on_process(self, processor):
|
||||
self._send_processed_mail_to_applicant(processor)
|
||||
self.ticket.save()
|
||||
|
||||
def dispatch(self, action):
|
||||
self._create_comment_on_action()
|
||||
processor = self.ticket.processor
|
||||
current_node = self.ticket.current_node.first()
|
||||
self.ticket.process_map[self.ticket.approval_step - 1].update({
|
||||
'approval_date': str(current_node.date_updated),
|
||||
'state': current_node.state,
|
||||
'processor': processor.id if processor else '',
|
||||
'processor_display': str(processor) if processor else '',
|
||||
})
|
||||
self.ticket.save()
|
||||
self._create_comment_on_action(action)
|
||||
method = getattr(self, f'_on_{action}', lambda: None)
|
||||
return method()
|
||||
|
||||
# email
|
||||
def _send_applied_mail_to_assignees(self):
|
||||
logger.debug('Send applied email to assignees: {}'.format(self.ticket.assignees_display))
|
||||
assignees = self.ticket.current_node.first().ticket_assignees.all()
|
||||
assignees_display = ', '.join([str(i.assignee) for i in assignees])
|
||||
logger.debug('Send applied email to assignees: {}'.format(assignees_display))
|
||||
send_ticket_applied_mail_to_assignees(self.ticket)
|
||||
|
||||
def _send_processed_mail_to_applicant(self):
|
||||
def _send_processed_mail_to_applicant(self, processor):
|
||||
logger.debug('Send processed mail to applicant: {}'.format(self.ticket.applicant_display))
|
||||
send_ticket_processed_mail_to_applicant(self.ticket)
|
||||
send_ticket_processed_mail_to_applicant(self.ticket, processor)
|
||||
|
||||
# comments
|
||||
def _create_comment_on_action(self):
|
||||
user = self.ticket.applicant if self.ticket.action_open else self.ticket.processor
|
||||
def _create_comment_on_action(self, action):
|
||||
user = self.ticket.processor
|
||||
# 打开或关闭工单,备注显示是自己,其他是受理人
|
||||
if self.ticket.state_open or self.ticket.state_close:
|
||||
user = self.ticket.applicant
|
||||
user_display = str(user)
|
||||
action_display = self.ticket.get_action_display()
|
||||
action_display = getattr(TicketAction, action).label
|
||||
data = {
|
||||
'body': _('{} {} the ticket').format(user_display, action_display),
|
||||
'user': user,
|
||||
@@ -85,18 +109,12 @@ class BaseHandler(object):
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {},
|
||||
{}: {}
|
||||
'''.format(
|
||||
_('Ticket title'), self.ticket.title,
|
||||
_('Ticket type'), self.ticket.get_type_display(),
|
||||
_('Ticket status'), self.ticket.get_status_display(),
|
||||
_('Ticket action'), self.ticket.get_action_display(),
|
||||
_('Ticket applicant'), self.ticket.applicant_display,
|
||||
_('Ticket assignees'), ', '.join(self.ticket.assignees_display),
|
||||
)
|
||||
if self.ticket.status_closed:
|
||||
basic_body += '''{}: {}'''.format(_('Ticket processor'), self.ticket.processor_display)
|
||||
body = self.body_html_format.format(_("Ticket basic info"), basic_body)
|
||||
return body
|
||||
|
||||
@@ -104,9 +122,6 @@ class BaseHandler(object):
|
||||
body = ''
|
||||
open_body = self._base_construct_meta_body_of_open()
|
||||
body += open_body
|
||||
if self.ticket.action_approve:
|
||||
approve_body = self._base_construct_meta_body_of_approve()
|
||||
body += approve_body
|
||||
return body
|
||||
|
||||
def _base_construct_meta_body_of_open(self):
|
||||
@@ -115,10 +130,3 @@ class BaseHandler(object):
|
||||
)()
|
||||
body = self.body_html_format.format(_('Ticket applied info'), meta_body_of_open)
|
||||
return body
|
||||
|
||||
def _base_construct_meta_body_of_approve(self):
|
||||
meta_body_of_approve = getattr(
|
||||
self, '_construct_meta_body_of_approve', lambda: _('No content')
|
||||
)()
|
||||
body = self.body_html_format.format(_('Ticket approved info'), meta_body_of_approve)
|
||||
return body
|
||||
|
Reference in New Issue
Block a user