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 |