ApprovalSystem
Features#
The approval system is mainly used to handle approval requests,Plug -in developers can be in processing approval request logic,Send the approval request to different third -party systems,After the third -party system has processed the approval request,You can send the processing results back
Implementation#
-
First create approval action,Specify the interface PATH, Method and the approval system plug -in responsible for processing
-
In the middle partarkid.core.approve_request_middlewareAccording to the scanning approval action,Intercept http Request,
- If an approval action does not create an approval request,Then create approval requests,distributionCREATE_APPROVE_REQUESTevent,HTTP Request stored in the approval request, Interrupt http Request
- If an approval action has been created for approval request,Determine the approval request status,If the state is passed,Continue to execute HTTP Request,If the status is rejected,Interrupt http Request
-
Supervise in the approval system plug -inCREATE_APPROVE_REQUESTevent,Through Create_approve_request Send the approval request to other third -party system processing
-
After other third -party approval systems process the approval request,You can return the approval results through the interface
-
agreeApproval requestinterface
- path:/approve_requests/{{request_id}}/pass/
- method: PUT
- Processing function:pass_approve_request_handler
- Need to implement abstract methods: pass_approve_request
-
rejectApproval requestinterface
- path:/approve_requests/{{request_id}}/deny/'
- method: PUT
- Processing function:deny_approve_request_handler
- Need to implement abstract methods: deny_approve_request
-
Abstract method#
Foundation definition#
arkid.core.extension.approve_system.ApproveSystemExtension (Extension)
#
Source code in arkid/core/extension/approve_system.py
class ApproveSystemExtension(Extension):
TYPE = "approve_system"
composite_schema_map = {}
created_composite_schema_list = []
composite_key = 'type'
composite_model = TenantExtensionConfig
@property
def type(self):
return ApproveSystemExtension.TYPE
def load(self):
self.listen_event(
core_event.CREATE_APPROVE_REQUEST, self.create_approve_request
)
self.pass_path = self.register_api(
f'/approve_requests/{{request_id}}/pass/',
'PUT',
self.pass_approve_request_handler,
response=ApproveRequestOut,
)
self.deny_path = self.register_api(
f'/approve_requests/{{request_id}}/deny/',
'PUT',
self.deny_approve_request_handler,
response=ApproveRequestOut,
)
super().load()
@abstractmethod
def create_approve_request(self, event, **kwargs):
"""
抽象方法
Args:
event (arkid.core.event.Event): 创建审批请求事件
"""
pass
@operation(roles=[TENANT_ADMIN, PLATFORM_ADMIN])
def pass_approve_request_handler(self, request, request_id):
approve_request = ApproveRequest.valid_objects.get(id=request_id)
self.pass_approve_request(request, approve_request)
approve_request.status = 'pass'
approve_request.save()
return ErrorDict(ErrorCode.OK)
@abstractmethod
def pass_approve_request(self, request, approve_request):
"""
抽象方法
Args:
request (django.http.HttpRequest): HTTP 请求
approve_request (arkid.core.models.ApproveRequest): 需要同意的审批请求
"""
pass
@operation(roles=[TENANT_ADMIN, PLATFORM_ADMIN])
def deny_approve_request_handler(self, request, request_id):
approve_request = ApproveRequest.valid_objects.get(id=request_id)
self.deny_approve_request(request, approve_request)
approve_request.status = 'deny'
approve_request.save()
return ErrorDict(ErrorCode.OK)
@abstractmethod
def deny_approve_request(self, request, approve_request):
"""
抽象方法
Args:
request (django.http.HttpRequest): HTTP 请求
approve_request (arkid.core.models.ApproveRequest): 需要拒绝的审批请求
"""
pass
def create_tenant_config(self, tenant, config, name, type):
tenant_config = super().create_tenant_config(tenant, config, name, type)
tenant_config.config["pass_request_url"] = self.pass_path
tenant_config.config["deny_request_url"] = self.deny_path
tenant_config.save()
return tenant_config
def register_approve_system_schema(self, schema, system_type):
self.register_config_schema(schema, self.package + '_' + system_type)
self.register_composite_config_schema(
schema, system_type, exclude=['extension']
)
composite_model (BaseModel)
django-model
#
TenantExtensionConfig(id, is_del, is_active, updated, created, tenant, extension, config, name, type)
Source code in arkid/core/extension/approve_system.py
class TenantExtensionConfig(BaseModel):
class Meta(object):
verbose_name = _("插件运行时配置")
verbose_name_plural = _("插件运行时配置")
tenant = models.ForeignKey('core.Tenant', blank=False, on_delete=models.PROTECT, verbose_name=_('租户'))
extension = models.ForeignKey('Extension', blank=False, on_delete=models.PROTECT, verbose_name=_('插件'))
config = models.JSONField(blank=True, default=dict, verbose_name=_('Runtime Config','运行时配置'))
name = models.CharField(max_length=128, default='', verbose_name=_('名称'))
type = models.CharField(max_length=128, default='', verbose_name=_('类型'))
config: JSONField
blank
django-field
#
Runtime Config
created: DateTimeField
blank
django-field
nullable
#
创建时间
extension: ForeignKey
django-field
#
插件
id: UUIDField
django-field
#
ID
is_active: BooleanField
django-field
#
是否可用
is_del: BooleanField
django-field
#
是否删除
name: CharField
django-field
#
名称
tenant: ForeignKey
django-field
#
租户
type: CharField
django-field
#
类型
updated: DateTimeField
blank
django-field
nullable
#
更新时间
create_approve_request(self, event, **kwargs)
#
create_tenant_config(self, tenant, config, name, type)
#
创建运行时配置
Parameters:
Name | Type | Description | Default |
---|---|---|---|
tenant |
Tenant |
租户 |
required |
config |
dict |
config |
required |
name |
str |
运行时配置名字 |
required |
type |
str |
配置类型 |
required |
Returns:
Type | Description |
---|---|
TenantExtensionConfig |
创建的对象 |
Source code in arkid/core/extension/approve_system.py
deny_approve_request(self, request, approve_request)
#
抽象方法
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request |
django.http.HttpRequest |
HTTP 请求 |
required |
approve_request |
arkid.core.models.ApproveRequest |
需要拒绝的审批请求 |
required |
load(self)
#
抽象方法,插件加载的入口方法
Source code in arkid/core/extension/approve_system.py
def load(self):
self.listen_event(
core_event.CREATE_APPROVE_REQUEST, self.create_approve_request
)
self.pass_path = self.register_api(
f'/approve_requests/{{request_id}}/pass/',
'PUT',
self.pass_approve_request_handler,
response=ApproveRequestOut,
)
self.deny_path = self.register_api(
f'/approve_requests/{{request_id}}/deny/',
'PUT',
self.deny_approve_request_handler,
response=ApproveRequestOut,
)
super().load()
pass_approve_request(self, request, approve_request)
#
抽象方法
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request |
django.http.HttpRequest |
HTTP 请求 |
required |
approve_request |
arkid.core.models.ApproveRequest |
需要同意的审批请求 |
required |
Exemplary#
extension_root.com_longgui_approve_system_arkid.ApproveSystemArkIDExtension (ApproveSystemExtension)
#
Source code in extension_root/com_longgui_approve_system_arkid/__init__.py
class ApproveSystemArkIDExtension(ApproveSystemExtension):
def load(self):
super().load()
self.register_api(
f'/approve_requests/',
'GET',
self.list_tenant_approve_requests,
response=List[ApproveRequestListItemOut],
tenant_path=True,
)
self.register_approve_system_schema(
ApproveSystemArkIDConfigSchema, 'approve_system_arkid'
)
self.register_front_pages([router_page, waiting_page, approved_page])
self.register_front_routers(router, approve_manage_router)
@operation(List[ApproveRequestListItemOut], roles=[TENANT_ADMIN, PLATFORM_ADMIN])
@paginate(CustomPagination)
def list_tenant_approve_requests(
self, request, tenant_id: str, is_approved: str = ''
):
package = 'com.longgui.approve.system.arkid'
requests = ApproveRequest.valid_objects.filter(
tenant=request.tenant, action__extension__package=package
)
if is_approved == 'true':
requests = requests.exclude(status="wait")
elif is_approved == 'false':
requests = requests.filter(status="wait")
return requests
def create_approve_request(self, event, **kwargs):
pass
def pass_approve_request(self, request, approve_request):
response = restore_approve_request(approve_request)
logger.info(f'Restore approve request with result: {response}')
def deny_approve_request(self, request, approve_request):
pass
create_approve_request(self, event, **kwargs)
#
deny_approve_request(self, request, approve_request)
#
抽象方法
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request |
django.http.HttpRequest |
HTTP 请求 |
required |
approve_request |
arkid.core.models.ApproveRequest |
需要拒绝的审批请求 |
required |
load(self)
#
抽象方法,插件加载的入口方法
Source code in extension_root/com_longgui_approve_system_arkid/__init__.py
def load(self):
super().load()
self.register_api(
f'/approve_requests/',
'GET',
self.list_tenant_approve_requests,
response=List[ApproveRequestListItemOut],
tenant_path=True,
)
self.register_approve_system_schema(
ApproveSystemArkIDConfigSchema, 'approve_system_arkid'
)
self.register_front_pages([router_page, waiting_page, approved_page])
self.register_front_routers(router, approve_manage_router)
pass_approve_request(self, request, approve_request)
#
抽象方法
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request |
django.http.HttpRequest |
HTTP 请求 |
required |
approve_request |
arkid.core.models.ApproveRequest |
需要同意的审批请求 |
required |