初始化项目
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
全局参数。
|
||||
"""
|
||||
from paste.core import config
|
||||
|
||||
|
||||
__package_name__ = "D3I"
|
||||
|
||||
__version__ = config.get_config('version')
|
||||
|
||||
__author__ = "苏州皓楷信息技术有限公司"
|
||||
|
||||
__email__ = "waynezwf@qq.com"
|
||||
|
||||
|
||||
def get_version(ver = __version__):
|
||||
"""
|
||||
系统版本。
|
||||
|
||||
:param ver:
|
||||
:return:
|
||||
"""
|
||||
return f"{__package_name__} version: V{ver}, written by {__author__}."
|
||||
|
||||
|
||||
def get_active_env():
|
||||
"""
|
||||
取得激活的环境。
|
||||
|
||||
:return:
|
||||
"""
|
||||
return config.get_config('active_env')
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
数字城管接口。
|
||||
"""
|
||||
|
||||
ApiPrefix = "/system/digital/city/management"
|
||||
"""
|
||||
API 前缀。
|
||||
"""
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
接受OA请求,操作数字城管工单延期
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_push_apply_postpone
|
||||
from models.dcm_apply_delay import DcmApplyPostpone
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/applyDelay')
|
||||
class ApplyPostponeHandler(AppHandler):
|
||||
"""
|
||||
申请延期接口。
|
||||
|
||||
对接数字城管系统的申请延期接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.dcm_task: Optional[DcmTask] = None
|
||||
self.dcm_apply_postpone: Optional[DcmApplyPostpone] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
DcmApplyPostpone.flow_token.key: kwargs.get('flowToken', ''),
|
||||
DcmApplyPostpone.dcm_task_id.key: kwargs.get('gdId', ''),
|
||||
DcmApplyPostpone.task_number.key: kwargs.get('taskNumber', ''),
|
||||
DcmApplyPostpone.apply_act_id.key: self.dcm_task.act_id,
|
||||
DcmApplyPostpone.reply_part_id.key: kwargs.get('replyPartID', 39),
|
||||
DcmApplyPostpone.ard_level.key: kwargs.get('ardLevel', 0),
|
||||
DcmApplyPostpone.ard_type_id.key: kwargs.get('ardTypeId', 12),
|
||||
DcmApplyPostpone.apply_memo.key: kwargs.get('opinion', ''),
|
||||
DcmApplyPostpone.apply_type.key: kwargs.get('applyType', '延期'),
|
||||
DcmApplyPostpone.attachments.key: kwargs.get('attachments', ''),
|
||||
DcmApplyPostpone.delay_multiple.key: kwargs.get('delayMultiple', 2),
|
||||
DcmApplyPostpone.time_num.key: kwargs.get('timeNum', 48),
|
||||
DcmApplyPostpone.time_unit.key: kwargs.get('timeUnit', 4),
|
||||
DcmApplyPostpone.postpone_date.key: kwargs.get('postponeDate', ''),
|
||||
}
|
||||
|
||||
async def apply_postpone(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'taskNumber', 'applyType', 'opinion', 'delayMultiple', 'flowToken'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
if kwargs.get('delayMultiple') not in (1, 2, '1', '2'):
|
||||
raise ValueError('延期倍数只能为1或2')
|
||||
|
||||
# 读取待办任务对象
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
self.dcm_task = await DcmTask.async_find_by_id(dcm_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.dcm_apply_postpone = DcmApplyPostpone().copy_from_dict(params)
|
||||
self.dcm_apply_postpone.status = 0
|
||||
await self.dcm_apply_postpone.async_save()
|
||||
|
||||
# 后台执行提交申请延期请求到数字城管
|
||||
await aio_pool.run_background_task(
|
||||
dcm_push_apply_postpone.push_apply_postpone(self.dcm_apply_postpone, self.dcm_task)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '申请延期成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 申请延期接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.apply_postpone(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,97 @@
|
||||
"""
|
||||
接受OA请求,操作数字城管的申请回退接口
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_push_apply_rollback
|
||||
from models.dcm_apply_rollback import DcmApplyRollback
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/applyRollback')
|
||||
class ApplyRollbackHandler(AppHandler):
|
||||
"""
|
||||
申请回退接口。
|
||||
|
||||
对接数字城管系统的申请回退接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.dcm_task: Optional[DcmTask] = None
|
||||
self.dcm_apply_rollback: Optional[DcmApplyRollback] = None
|
||||
|
||||
def _extract_params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
DcmApplyRollback.flow_token.key: kwargs.get('flowToken', ''),
|
||||
DcmApplyRollback.dcm_task_id.key: kwargs.get('gdId', ''),
|
||||
DcmApplyRollback.act_id.key: self.dcm_task.act_id,
|
||||
DcmApplyRollback.task_number.key: kwargs.get('taskNumber', ''),
|
||||
DcmApplyRollback.reply_part_id.key: kwargs.get('replyPartID', 39),
|
||||
DcmApplyRollback.ard_level.key: kwargs.get('ardLevel', 0),
|
||||
DcmApplyRollback.ard_type_id.key: 18 if kwargs.get('applyType', '拒签') == '拒签' else 62,
|
||||
DcmApplyRollback.opinion.key: kwargs.get('opinion', ''),
|
||||
DcmApplyRollback.apply_type.key: kwargs.get('applyType', '拒签'),
|
||||
DcmApplyRollback.trans_info.key: kwargs.get('transInfo', '52,254,0'),
|
||||
DcmApplyRollback.attachments.key: kwargs.get('attachments', '')
|
||||
}
|
||||
|
||||
async def apply_rollback(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'taskNumber', 'opinion', 'applyType', 'flowToken']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
if kwargs['applyType'] not in ('拒签', '处置阶段照片未公开'):
|
||||
raise ValueError('申请类型只能为拒签或处置阶段照片未公开')
|
||||
|
||||
# 读取待办任务对象
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
self.dcm_task = await DcmTask.async_find_by_id(dcm_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._extract_params_for_db(**kwargs)
|
||||
self.dcm_apply_rollback = DcmApplyRollback().copy_from_dict(params)
|
||||
self.dcm_apply_rollback.status = 0
|
||||
await self.dcm_apply_rollback.async_save()
|
||||
|
||||
# 后台执行提交申请回退请求到数字城管
|
||||
await aio_pool.run_background_task(
|
||||
dcm_push_apply_rollback.push_apply_rollback(self.dcm_apply_rollback, self.dcm_task)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '申请回退成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 申请回退接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.apply_rollback(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
接受OA请求,操作数字城管的工单批转接口
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_push_dispose
|
||||
from models.dcm_dispose import DcmDispose
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/transfer')
|
||||
class DisposeHandler(AppHandler):
|
||||
"""
|
||||
批转接口。
|
||||
|
||||
对接数字城管系统的批转接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.dcm_task: Optional[DcmTask] = None
|
||||
self.dcm_dispose: Optional[DcmDispose] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
DcmDispose.flow_token.key: kwargs.get('flowToken', ''),
|
||||
DcmDispose.dcm_task_id.key: kwargs.get('gdId', ''),
|
||||
DcmDispose.act_id.key: self.dcm_task.act_id,
|
||||
DcmDispose.task_number.key: kwargs.get('taskNumber', ''),
|
||||
DcmDispose.opinion.key: kwargs.get('opinion', ''),
|
||||
DcmDispose.attachments.key: kwargs.get('attachments', ''),
|
||||
DcmDispose.send_message.key: kwargs.get('sendMessage', '1'),
|
||||
DcmDispose.trans_info.key: '52,254,0,0',
|
||||
DcmDispose.add_num.key: kwargs.get('addNum', '0'),
|
||||
DcmDispose.task_list_id.key: kwargs.get('taskListId', '600058'),
|
||||
DcmDispose.undertake_user_name.key: kwargs.get('undertakeUserName', ''),
|
||||
DcmDispose.undertake_phone.key: kwargs.get('undertakePhone', '')
|
||||
}
|
||||
|
||||
async def dispose(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'taskNumber', 'opinion', 'attachments', 'flowToken']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
self.dcm_task = await DcmTask.async_find_by_id(dcm_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.dcm_dispose = DcmDispose().copy_from_dict(params)
|
||||
self.dcm_dispose.status = 0
|
||||
await self.dcm_dispose.async_save()
|
||||
|
||||
# 后台执行提交批转请求到数字城管
|
||||
await aio_pool.run_background_task(
|
||||
dcm_push_dispose.push_dispose(self.dcm_dispose, self.dcm_task)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '批转成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 批转接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.dispose(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,58 @@
|
||||
"""
|
||||
接受OA请求,读取数字城管的是否允许申请延期。
|
||||
"""
|
||||
import logging
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_scrape_allow_postpone
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/fetchAllowPostpone')
|
||||
class AllowPostponeHandler(AppHandler):
|
||||
"""
|
||||
获取是否允许申请延期接口。
|
||||
|
||||
对接数字城管系统的获取是否允许申请延期接口,用于判断工单有哪些是否允许申请延期。
|
||||
"""
|
||||
|
||||
async def fetch_allow_postpone(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
dcm_task = await DcmTask(id=dcm_task_id).async_find_first()
|
||||
assert dcm_task, f"未找到待办工单,工单ID:{dcm_task_id}"
|
||||
success, message = await dcm_scrape_allow_postpone.fetch_allow_postpone(dcm_task)
|
||||
return {
|
||||
'success': success,
|
||||
'msg': message,
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 获取是否允许申请延期接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.fetch_allow_postpone(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
接受OA请求,读取数字城管的便民表单。
|
||||
"""
|
||||
import logging
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_scrape_conv_dispose
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/fetchDisposeForm')
|
||||
class FetchConvenientFormHandler(AppHandler):
|
||||
"""
|
||||
获取便民表单接口。
|
||||
|
||||
对接数字城管系统的获取便民表单接口,用于判断工单有哪些便民表单。
|
||||
"""
|
||||
|
||||
async def fetch_form(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'formId']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
dcm_task = await DcmTask(id=dcm_task_id).async_find_first()
|
||||
assert dcm_task, f"未找到待办工单,工单ID:{dcm_task_id}"
|
||||
|
||||
form = await dcm_scrape_conv_dispose.fetch_form(dcm_task)
|
||||
return {
|
||||
'msg': '获取便民批转表单成功.',
|
||||
'form': form,
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 获取便民表单接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.fetch_form(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,58 @@
|
||||
"""
|
||||
接受OA请求,读取数字城管的可用操作。
|
||||
"""
|
||||
import logging
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_scrape_operation
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/fetchOperation')
|
||||
class FetchOperationHandler(AppHandler):
|
||||
"""
|
||||
获取可用操作接口。
|
||||
|
||||
对接数字城管系统的获取可用操作接口,用于判断工单有哪些可用操作。
|
||||
"""
|
||||
|
||||
async def fetch_operations(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
dcm_task = await DcmTask(id=dcm_task_id).async_find_first()
|
||||
assert dcm_task, f"未找到待办工单,工单ID:{dcm_task_id}"
|
||||
operations = await dcm_scrape_operation.fetch_operation(dcm_task)
|
||||
return {
|
||||
'msg': '获取可用操作成功.',
|
||||
'operations': operations,
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 获取可用操作接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.fetch_operations(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
接受OA请求,读取数字城管的便民表单。
|
||||
"""
|
||||
import logging
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_scrape_conv_rollback
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/fetchRollbackForm')
|
||||
class FetchRollbackFormHandler(AppHandler):
|
||||
"""
|
||||
获取便民表单接口。
|
||||
|
||||
对接数字城管系统的获取便民表单接口,用于判断工单有哪些便民表单。
|
||||
"""
|
||||
|
||||
async def fetch_form(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'formId']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
dcm_task = await DcmTask(id=dcm_task_id).async_find_first()
|
||||
assert dcm_task, f"未找到待办工单,工单ID:{dcm_task_id}"
|
||||
|
||||
form = await dcm_scrape_conv_rollback.fetch_form(dcm_task)
|
||||
return {
|
||||
'msg': '获取便民回退表单成功.',
|
||||
'form': form,
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 获取便民表单接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.fetch_form(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
接受OA请求,操作数字城管的回退接口
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_push_rollback
|
||||
from models.dcm_rollback import DcmRollback
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/rollback')
|
||||
class RollbackHandler(AppHandler):
|
||||
"""
|
||||
回退接口。
|
||||
|
||||
对接数字城管系统的回退接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.dcm_task: Optional[DcmTask] = None
|
||||
self.dcm_rollback: Optional[DcmRollback] = None
|
||||
|
||||
def _extract_params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
DcmRollback.flow_token.key: kwargs.get('flowToken', ''),
|
||||
DcmRollback.dcm_task_id.key: kwargs.get('gdId', ''),
|
||||
DcmRollback.act_id.key: self.dcm_task.act_id,
|
||||
DcmRollback.task_number.key: kwargs.get('taskNumber', ''),
|
||||
DcmRollback.opinion.key: kwargs.get('opinion', ''),
|
||||
DcmRollback.attachments.key: kwargs.get('attachments', ''),
|
||||
DcmRollback.send_message.key: kwargs.get('sendMessage', '1'),
|
||||
DcmRollback.trans_info.key: kwargs.get('transInfo', '50,254,0'),
|
||||
DcmRollback.save_old_act_flag.key: kwargs.get('saveOldActFlag', False),
|
||||
DcmRollback.rollback_reason_id.key: kwargs.get('rollbackReasonId', -1),
|
||||
DcmRollback.not_assigned.key: kwargs.get('notAssigned', '0'),
|
||||
DcmRollback.not_assigned_reason.key: kwargs.get('notAssignedReason', ''),
|
||||
DcmRollback.undertake_user_name.key: kwargs.get('undertakeUserName', ''),
|
||||
DcmRollback.undertake_phone.key: kwargs.get('undertakePhone', '')
|
||||
}
|
||||
|
||||
async def rollback(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'taskNumber', 'opinion', 'flowToken']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
self.dcm_task = await DcmTask.async_find_by_id(dcm_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._extract_params_for_db(**kwargs)
|
||||
self.dcm_rollback = DcmRollback().copy_from_dict(params)
|
||||
self.dcm_rollback.status = 0
|
||||
await self.dcm_rollback.async_save()
|
||||
|
||||
# 后台执行提交回退请求到数字城管
|
||||
await aio_pool.run_background_task(
|
||||
dcm_push_rollback.push_rollback(self.dcm_rollback, self.dcm_task)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '回退成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 回退接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.rollback(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
接受OA请求,操作数字城管的阶段回复接口
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from apps.api import dcm
|
||||
from apps.app_handler import AppHandler
|
||||
from dock.dcm import dcm_push_stage_reply
|
||||
from models.dcm_stage_reply import DcmStageReply
|
||||
from models.dcm_task import DcmTask
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from paste.web.decorators import route
|
||||
|
||||
|
||||
@route(f'{dcm.ApiPrefix}/stageReply')
|
||||
class StageReplyHandler(AppHandler):
|
||||
"""
|
||||
阶段回复接口。
|
||||
|
||||
对接数字城管系统的阶段回复接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.dcm_task: Optional[DcmTask] = None
|
||||
self.dcm_stage_reply: Optional[DcmStageReply] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
DcmStageReply.flow_token.key: kwargs.get('flowToken', ''),
|
||||
DcmStageReply.dcm_task_id.key: kwargs.get('gdId', ''),
|
||||
DcmStageReply.rec_id.key: self.dcm_task.rec_id,
|
||||
DcmStageReply.act_id.key: self.dcm_task.act_id,
|
||||
DcmStageReply.content.key: kwargs.get('content', ''),
|
||||
DcmStageReply.task_number.key: kwargs.get('taskNumber', ''),
|
||||
DcmStageReply.item_type.key: kwargs.get('itemType', 'stage_reply'),
|
||||
}
|
||||
|
||||
async def stage_reply(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = ['gdId', 'taskNumber', 'content', 'flowToken']
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
dcm_task_id = kwargs.get('gdId', '')
|
||||
self.dcm_task = await DcmTask.async_find_by_id(dcm_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.dcm_stage_reply = DcmStageReply().copy_from_dict(params)
|
||||
self.dcm_stage_reply.status = 1
|
||||
await self.dcm_stage_reply.async_save()
|
||||
|
||||
# 后台执行提交阶段回复请求到数字城管
|
||||
await aio_pool.run_background_task(
|
||||
dcm_push_stage_reply.push_stage_reply(self.dcm_stage_reply, self.dcm_task)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '阶段回复成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 阶段回复接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.stage_reply(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
省12345接口。
|
||||
"""
|
||||
|
||||
ApiPrefix = "/system"
|
||||
"""
|
||||
API 前缀。
|
||||
"""
|
||||
Binary file not shown.
@@ -0,0 +1,101 @@
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from apps.api import govs
|
||||
from apps.app_handler import AppHandler
|
||||
from paste.web.decorators import route
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from dock.govs import govs_create_order_delay
|
||||
from models.govs_order_master import GovsOrderMaster
|
||||
from models.govs_create_delay import GovsApplicationForDelay
|
||||
|
||||
|
||||
@route(f'{govs.ApiPrefix}/application-for-delay-formal/create')
|
||||
class CreateDelayHandler(AppHandler):
|
||||
"""
|
||||
申请延期接口。
|
||||
|
||||
对接省12345的申请延期接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.govs_order: Optional[GovsOrderMaster] = None
|
||||
self.govs_delay: Optional[GovsApplicationForDelay] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
GovsApplicationForDelay.master_id.key: kwargs.get('gdId', ''),
|
||||
GovsApplicationForDelay.gd_id.key: kwargs.get('gdId', ''),
|
||||
GovsApplicationForDelay.finally_time_after_approve.key: kwargs.get('finallyTimeAfterApprove', ''),
|
||||
GovsApplicationForDelay.finally_time_before_approve.key: kwargs.get('finallyTimeBeforeApprove', ''),
|
||||
GovsApplicationForDelay.request_delay.key: kwargs.get('requestDelay', ''),
|
||||
GovsApplicationForDelay.is_nature_day.key: kwargs.get('isNatureDay', ''),
|
||||
GovsApplicationForDelay.already_notify_order_user.key: kwargs.get('alreadyNotifyOrderUser', ''),
|
||||
GovsApplicationForDelay.request_reason.key: kwargs.get('requestReason', ''),
|
||||
GovsApplicationForDelay.remarks.key: kwargs.get('remarks', ''),
|
||||
GovsApplicationForDelay.contact_name.key: kwargs.get('contactName', ''),
|
||||
GovsApplicationForDelay.contact_time.key: kwargs.get('contactTime', ''),
|
||||
GovsApplicationForDelay.contact_type.key: kwargs.get('contactType', ''),
|
||||
GovsApplicationForDelay.contact_type_name.key: kwargs.get('contactTypeName', ''),
|
||||
GovsApplicationForDelay.reply_script.key: kwargs.get('replyScript', ''),
|
||||
GovsApplicationForDelay.file_id_str.key: kwargs.get('fileIdStr', ''),
|
||||
GovsApplicationForDelay.request_delay_time.key: kwargs.get('requestDelayTime', ''),
|
||||
GovsApplicationForDelay.flow_token.key: kwargs.get('flowToken', '')
|
||||
}
|
||||
|
||||
async def create_delay(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'flowToken', 'finallyTimeAfterApprove', 'requestDelay', 'isNatureDay',
|
||||
'alreadyNotifyOrderUser', 'requestReason'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
govs_task_id = kwargs.get('gdId', '')
|
||||
self.govs_order = await GovsOrderMaster.async_find_by_id(govs_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.govs_delay = GovsApplicationForDelay().copy_from_dict(params)
|
||||
self.govs_delay.status = 0
|
||||
await self.govs_delay.async_save()
|
||||
|
||||
# 后台执行提交申请延期请求到省12345
|
||||
await aio_pool.run_background_task(
|
||||
govs_create_order_delay.create_delay(self.govs_delay, self.govs_order)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '申请延期成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 申请延期接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.create_delay(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,102 @@
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from apps.api import govs
|
||||
from apps.app_handler import AppHandler
|
||||
from paste.web.decorators import route
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from dock.govs import govs_create_order_return
|
||||
from models.govs_order_master import GovsOrderMaster
|
||||
from models.govs_create_return import GovsWorkOrderReturnFormal
|
||||
|
||||
|
||||
@route(f'{govs.ApiPrefix}/work-order-return-formal/create')
|
||||
class CreateDelayHandler(AppHandler):
|
||||
"""
|
||||
申请工单退回接口。
|
||||
|
||||
对接省12345的申请退回接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.govs_order: Optional[GovsOrderMaster] = None
|
||||
self.govs_return: Optional[GovsWorkOrderReturnFormal] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
GovsWorkOrderReturnFormal.master_id.key: kwargs.get('gdId', ''),
|
||||
GovsWorkOrderReturnFormal.flow_token.key: kwargs.get('flowToken', ''),
|
||||
GovsWorkOrderReturnFormal.gd_id.key: kwargs.get('gdId', ''),
|
||||
GovsWorkOrderReturnFormal.return_reason.key: kwargs.get('returnReason', ''),
|
||||
GovsWorkOrderReturnFormal.return_reason_name.key: kwargs.get('returnReasonName', ''),
|
||||
GovsWorkOrderReturnFormal.return_auditor_name.key: kwargs.get('returnAuditorName', ''),
|
||||
GovsWorkOrderReturnFormal.return_auditor_id.key: kwargs.get('returnAuditorId', ''),
|
||||
GovsWorkOrderReturnFormal.deal_opinion.key: kwargs.get('dealOpinion', ''),
|
||||
GovsWorkOrderReturnFormal.reason.key: kwargs.get('reason', ''),
|
||||
GovsWorkOrderReturnFormal.remark.key: kwargs.get('remark', ''),
|
||||
GovsWorkOrderReturnFormal.file_id_str.key: kwargs.get('fileIdStr', ''),
|
||||
GovsWorkOrderReturnFormal.process_instance_id.key: kwargs.get('processInstanceId', ''),
|
||||
GovsWorkOrderReturnFormal.action_name.key: kwargs.get('actionName', ''),
|
||||
GovsWorkOrderReturnFormal.order_id.key: kwargs.get('orderId', ''),
|
||||
GovsWorkOrderReturnFormal.task_id.key: kwargs.get('taskId', ''),
|
||||
GovsWorkOrderReturnFormal.order_no.key: kwargs.get('orderNo', ''),
|
||||
GovsWorkOrderReturnFormal.case_accord_type_one_name.key: kwargs.get('caseAccordTypeOneName', ''),
|
||||
GovsWorkOrderReturnFormal.case_accord_type_two_name.key: kwargs.get('caseAccordTypeTwoName', ''),
|
||||
GovsWorkOrderReturnFormal.case_accord_type_three_name.key: kwargs.get('caseAccordTypeThreeName', '')
|
||||
}
|
||||
|
||||
async def create_return(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'flowToken', 'returnReason', 'returnReasonName', 'dealOpinion', 'reason'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
govs_task_id = kwargs.get('gdId', '')
|
||||
self.govs_order = await GovsOrderMaster.async_find_by_id(govs_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.govs_return = GovsWorkOrderReturnFormal().copy_from_dict(params)
|
||||
self.govs_return.status = 0
|
||||
await self.govs_return.async_save()
|
||||
|
||||
# 后台执行提交申请延期请求到省12345
|
||||
await aio_pool.run_background_task(
|
||||
govs_create_order_return.create_return(self.govs_return, self.govs_order)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '申请退回成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 申请退回接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.create_return(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,102 @@
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from apps.api import govs
|
||||
from apps.app_handler import AppHandler
|
||||
from paste.web.decorators import route
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from dock.govs import govs_create_reply
|
||||
from models.govs_order_master import GovsOrderMaster
|
||||
from models.govs_create_reply import GovsReplyFormal
|
||||
|
||||
|
||||
@route(f'{govs.ApiPrefix}/reply-formal/create')
|
||||
class CreateDelayHandler(AppHandler):
|
||||
"""
|
||||
答复办结接口。
|
||||
|
||||
对接省12345的答复办结接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.govs_order: Optional[GovsOrderMaster] = None
|
||||
self.govs_reply: Optional[GovsReplyFormal] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
GovsReplyFormal.master_id.key: kwargs.get('gdId', ''),
|
||||
GovsReplyFormal.flow_token.key: kwargs.get('flowToken', ''),
|
||||
GovsReplyFormal.gd_id.key: kwargs.get('gdId', ''),
|
||||
GovsReplyFormal.is_contact.key: kwargs.get('isContact', ''),
|
||||
GovsReplyFormal.contact_name.key: kwargs.get('contactName', ''),
|
||||
GovsReplyFormal.contact_time.key: kwargs.get('contactTime', ''),
|
||||
GovsReplyFormal.contact_type.key: kwargs.get('contactType', ''),
|
||||
GovsReplyFormal.advice.key: kwargs.get('advice', ''),
|
||||
GovsReplyFormal.reason.key: kwargs.get('reason', ''),
|
||||
GovsReplyFormal.remarks.key: kwargs.get('remarks', ''),
|
||||
GovsReplyFormal.file_id_str.key: kwargs.get('fileIdStr', ''),
|
||||
GovsReplyFormal.save_id.key: kwargs.get('saveId', ''),
|
||||
GovsReplyFormal.process_instance_id.key: kwargs.get('processInstanceId', ''),
|
||||
GovsReplyFormal.business_key.key: kwargs.get('businessKey', ''),
|
||||
GovsReplyFormal.order_no.key: kwargs.get('orderNo', ''),
|
||||
GovsReplyFormal.action_name.key: kwargs.get('actionName', ''),
|
||||
GovsReplyFormal.case_accord_type_one_name.key: kwargs.get('caseAccordTypeOneName', ''),
|
||||
GovsReplyFormal.case_accord_type_two_name.key: kwargs.get('caseAccordTypeTwoName', ''),
|
||||
GovsReplyFormal.case_accord_type_three_name.key: kwargs.get('caseAccordTypeThreeName', ''),
|
||||
}
|
||||
|
||||
async def create_delay(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'flowToken', 'isContact', 'contactType', 'advice', 'reason'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
govs_task_id = kwargs.get('gdId', '')
|
||||
self.govs_order = await GovsOrderMaster.async_find_by_id(govs_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.govs_reply = GovsReplyFormal().copy_from_dict(params)
|
||||
self.govs_reply.status = 0
|
||||
await self.govs_reply.async_save()
|
||||
|
||||
# 后台执行提交答复办结请求到省12345
|
||||
await aio_pool.run_background_task(
|
||||
govs_create_reply.create_reply(self.govs_reply, self.govs_order)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '答复办结成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 答复办结接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.create_delay(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,101 @@
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from apps.api import govs
|
||||
from apps.app_handler import AppHandler
|
||||
from paste.web.decorators import route
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from dock.govs import govs_phase_wise_completion
|
||||
from models.govs_order_master import GovsOrderMaster
|
||||
from models.govs_phase_wise_completion import GovsPhaseWiseCompletion
|
||||
|
||||
|
||||
@route(f'{govs.ApiPrefix}/phase-wise-completion/create')
|
||||
class CreateDelayHandler(AppHandler):
|
||||
"""
|
||||
阶段性办结接口。
|
||||
|
||||
对接省12345的阶段性办结接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.govs_order: Optional[GovsOrderMaster] = None
|
||||
self.phase_wise_completion: Optional[GovsPhaseWiseCompletion] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
GovsPhaseWiseCompletion.master_id.key: kwargs.get('gdId', ''),
|
||||
GovsPhaseWiseCompletion.flow_token.key: kwargs.get('flowToken', ''),
|
||||
GovsPhaseWiseCompletion.gd_id.key: kwargs.get('gdId', ''),
|
||||
GovsPhaseWiseCompletion.is_contact.key: kwargs.get('isContact', ''),
|
||||
GovsPhaseWiseCompletion.contact_name.key: kwargs.get('contactName', ''),
|
||||
GovsPhaseWiseCompletion.contact_time.key: kwargs.get('contactTime', ''),
|
||||
GovsPhaseWiseCompletion.contact_type.key: kwargs.get('contactType', ''),
|
||||
GovsPhaseWiseCompletion.next_feedback_time.key: kwargs.get('nextFeedbackTime', ''),
|
||||
GovsPhaseWiseCompletion.advice.key: kwargs.get('advice', ''),
|
||||
GovsPhaseWiseCompletion.reason.key: kwargs.get('reason', ''),
|
||||
GovsPhaseWiseCompletion.remark.key: kwargs.get('remark', ''),
|
||||
GovsPhaseWiseCompletion.action_name.key: kwargs.get('actionName', ''),
|
||||
GovsPhaseWiseCompletion.case_accord_type_one_name.key: kwargs.get('caseAccordTypeOneName', ''),
|
||||
GovsPhaseWiseCompletion.case_accord_type_two_name.key: kwargs.get('caseAccordTypeTwoName', ''),
|
||||
GovsPhaseWiseCompletion.case_accord_type_three_name.key: kwargs.get('caseAccordTypeThreeName', ''),
|
||||
GovsPhaseWiseCompletion.order_id.key: kwargs.get('orderId', ''),
|
||||
GovsPhaseWiseCompletion.task_id.key: kwargs.get('taskId', '')
|
||||
}
|
||||
|
||||
async def create_delay(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'flowToken', 'isContact', 'contactName', 'contactTime', 'contactType', 'nextFeedbackTime', 'advice',
|
||||
'reason'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
govs_task_id = kwargs.get('gdId', '')
|
||||
self.govs_order = await GovsOrderMaster.async_find_by_id(govs_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.phase_wise_completion = GovsPhaseWiseCompletion().copy_from_dict(params)
|
||||
self.phase_wise_completion.status = 0
|
||||
await self.phase_wise_completion.async_save()
|
||||
|
||||
# 后台执行提交阶段性办结请求到省12345
|
||||
await aio_pool.run_background_task(
|
||||
govs_phase_wise_completion.create_phase_wise_completion(self.phase_wise_completion, self.govs_order)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '阶段性办结成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 阶段性办结接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.create_delay(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,91 @@
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
from apps.api import govs
|
||||
from apps.app_handler import AppHandler
|
||||
from paste.web.decorators import route
|
||||
from paste.core import aio_pool
|
||||
from paste.core.logging import echo_log
|
||||
from dock.govs import govs_save_sign
|
||||
from models.govs_order_master import GovsOrderMaster
|
||||
from models.govs_save_sign import GovsSaveSign
|
||||
|
||||
|
||||
@route(f'{govs.ApiPrefix}/save-sign-for/create')
|
||||
class CreateDelayHandler(AppHandler):
|
||||
"""
|
||||
申请延期接口。
|
||||
|
||||
对接省12345的申请延期接口,请求后本接口先将数据保存本地,然后响应客户端,然后开始后台启动推送。
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.govs_order: Optional[GovsOrderMaster] = None
|
||||
self.govs_sign: Optional[GovsSaveSign] = None
|
||||
|
||||
def _params_for_db(self, **kwargs: dict) -> dict:
|
||||
"""
|
||||
提取数据库所需参数。
|
||||
"""
|
||||
return {
|
||||
GovsSaveSign.gd_id.key: kwargs.get('gdId', ''),
|
||||
GovsSaveSign.flow_token.key: kwargs.get('flowToken', ''),
|
||||
GovsSaveSign.order_id.key: kwargs.get('orderId', ''),
|
||||
GovsSaveSign.order_no.key: kwargs.get('orderNo', ''),
|
||||
GovsSaveSign.master_id.key: kwargs.get('gdId', ''),
|
||||
GovsSaveSign.order_process_id.key: kwargs.get('orderProcessId', ''),
|
||||
GovsSaveSign.task_id.key: kwargs.get('taskId', ''),
|
||||
GovsSaveSign.flag.key: kwargs.get('flag', '')
|
||||
}
|
||||
|
||||
async def create_delay(self, **kwargs) -> dict:
|
||||
# 必填参数校验
|
||||
required_keys = [
|
||||
'gdId', 'flowToken'
|
||||
]
|
||||
missing = [
|
||||
k for k in required_keys
|
||||
if k not in kwargs or kwargs[k] is None
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"缺少必要参数: {missing}")
|
||||
|
||||
# 读取待办任务对象
|
||||
govs_task_id = kwargs.get('gdId', '')
|
||||
self.govs_order = await GovsOrderMaster.async_find_by_id(govs_task_id)
|
||||
|
||||
# 保存请求数据
|
||||
params = self._params_for_db(**kwargs)
|
||||
self.govs_sign = GovsSaveSign().copy_from_dict(params)
|
||||
self.govs_sign.status = 0
|
||||
await self.govs_sign.async_save()
|
||||
|
||||
# 后台执行提交申请延期请求到省12345
|
||||
await aio_pool.run_background_task(
|
||||
govs_save_sign.sign_order(self.govs_sign, self.govs_order)
|
||||
)
|
||||
|
||||
return {
|
||||
'msg': '确认签收成功.'
|
||||
}
|
||||
|
||||
# @auth_token
|
||||
async def post(self):
|
||||
"""
|
||||
处理 POST 请求。
|
||||
|
||||
---
|
||||
tags:
|
||||
- D3I API
|
||||
summary: 申请延期接口
|
||||
"""
|
||||
try:
|
||||
echo_log(self.request.body.decode())
|
||||
_, params = self.get_request_params()
|
||||
_result = await self.create_delay(**params)
|
||||
self.response_ok(code=0, data=_result)
|
||||
except Exception as e:
|
||||
self.response_error(e, status_code=200, api_status_code=500)
|
||||
self.log(msg=e, level=logging.ERROR, is_log_exc=True)
|
||||
@@ -0,0 +1,183 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
from abc import ABC
|
||||
from typing import Optional, Callable, Awaitable
|
||||
|
||||
from paste.rbac.rbac_user import RbacUser
|
||||
from paste.util.encoder import JsonDumpsEncoder
|
||||
from paste.web.handler import RequestHandler
|
||||
from paste.web.param_aware_loader import ParamAwareLoader
|
||||
|
||||
|
||||
class AppHandler(RequestHandler, ABC):
|
||||
"""
|
||||
控制器基类。
|
||||
"""
|
||||
|
||||
commands: dict[str, Callable] = {}
|
||||
"""
|
||||
API 接口命令字典,其结构为命令名称指向对应的方法。
|
||||
|
||||
其结构如下::
|
||||
|
||||
{
|
||||
command_name: method
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.user: Optional[RbacUser] = None
|
||||
"""
|
||||
当前登录用户对象。
|
||||
"""
|
||||
|
||||
self.start_at = datetime.datetime.now()
|
||||
"""
|
||||
实例初始化时间。
|
||||
"""
|
||||
|
||||
self.command = ""
|
||||
"""
|
||||
命令。
|
||||
"""
|
||||
|
||||
self.request_params = {}
|
||||
"""
|
||||
命令参数。
|
||||
"""
|
||||
|
||||
async def after_auth_token(self, token_payload: dict):
|
||||
"""
|
||||
初始化登录用户信息。
|
||||
"""
|
||||
from paste.security import token
|
||||
if token_payload != token.PRIVATE_ISS:
|
||||
from jwt import InvalidTokenError
|
||||
raise InvalidTokenError()
|
||||
|
||||
async def run_command(self):
|
||||
"""
|
||||
根据请求参数运行命令方法,返回命令执行结果。
|
||||
"""
|
||||
self.get_request_params()
|
||||
assert self.command in self.commands, '请提供正确的命令参数.'
|
||||
|
||||
# 读取命令方法对象,并执行
|
||||
_cmd_func = self.commands[self.command]
|
||||
_result = _cmd_func(self, **self.request_params)
|
||||
# 处理异步方法执行
|
||||
if isinstance(_result, Awaitable):
|
||||
_result = await _result
|
||||
return _result
|
||||
|
||||
async def gen_html(self, template_file: str, **kwargs):
|
||||
"""
|
||||
生成 HTML 内容。
|
||||
|
||||
:param template_file: 模板文件
|
||||
:param kwargs: 参数数据字典
|
||||
:return: 返回生成的 HTML 文件内容
|
||||
"""
|
||||
# 将参数字典转换为 namedtuple,名称固定
|
||||
template_data_obj = self.dict_to_namedtuple('TemplateData', {**kwargs})
|
||||
# 手动构建完整命名空间,加入自定义参数,传给生成器
|
||||
namespace = self.get_template_namespace()
|
||||
namespace.update({'td': template_data_obj})
|
||||
|
||||
# 获取模板文件
|
||||
template_file = f"{self.application.settings.get('template_path')}/{template_file}"
|
||||
# 用参数感知模板加载器,加载模板文件,并传入 namespace 以便在加载完成后,执行数据准备
|
||||
loader = ParamAwareLoader(os.path.dirname(template_file), namespace=namespace)
|
||||
# 从文件中加载模板,同步完成数据准备
|
||||
template = await loader.load_with_prepare(os.path.basename(template_file))
|
||||
|
||||
# 渲染模板,传入需要的数据
|
||||
output = template.generate(**namespace)
|
||||
return output
|
||||
|
||||
def response_ok(self, **kwargs):
|
||||
self.log_request_end()
|
||||
super().response_ok(**kwargs)
|
||||
|
||||
def response_error(self, e: Exception, status_code: int = 200, api_status_code: int = None, **kwargs):
|
||||
self.log_request_end()
|
||||
if api_status_code is None:
|
||||
api_status_code = status_code
|
||||
|
||||
self.set_status(status_code=status_code)
|
||||
chunk = {'code': api_status_code, 'status': 'error'}
|
||||
chunk.update(kwargs)
|
||||
if len(e.args) > 0 and isinstance(e.args[0], str):
|
||||
chunk['msg'] = e.args[0]
|
||||
if len(e.args) > 1:
|
||||
if isinstance(e.args[1], dict):
|
||||
chunk.update(e.args[1])
|
||||
elif isinstance(e.args[1], list):
|
||||
chunk['errors'] = e.args[1]
|
||||
self.write(json.dumps(chunk, cls=JsonDumpsEncoder, ensure_ascii=False))
|
||||
self.set_header('Content-Type', 'application/json')
|
||||
|
||||
def get_request_params(self):
|
||||
"""
|
||||
读取命令名称及请求参数。注意,参数命名应当避开 cmd 和 params。
|
||||
|
||||
该方法自动合并参数,并输出请求开始日志。
|
||||
|
||||
支持通过 Form 或 Json 两种方式提交请求并读取相应参数。
|
||||
|
||||
如使用 Form 方式,则应当在 form-data 中包含名为 cmd 的输入项,其值为对应的命令,其他输入项为命令参数。
|
||||
注意:不会自动读取上传的文件数据,可通过::
|
||||
|
||||
self.request.files
|
||||
|
||||
方法读取上传的文件。
|
||||
|
||||
如使用 Json 方式,则应当遵循以下结构::
|
||||
|
||||
{
|
||||
cmd: command_name,
|
||||
params:
|
||||
{
|
||||
key: value
|
||||
}
|
||||
}
|
||||
|
||||
:return: 命令,命令对应的参数
|
||||
"""
|
||||
_arguments = self.request_arguments()
|
||||
_cmd = _arguments.get('cmd', None)
|
||||
_params = _arguments.get('params', None)
|
||||
if _params is None:
|
||||
_arguments.pop('cmd', None)
|
||||
_params = _arguments
|
||||
|
||||
self.command = _cmd
|
||||
self.request_params = _params
|
||||
# 合成规则参数到参数字典,规则参数可在相应规则中修改
|
||||
self.request_params.update(self.rule_kwargs)
|
||||
# 取得命令和参数之后,记录请求开始日志
|
||||
self.log_request_start()
|
||||
|
||||
return self.command, self.request_params
|
||||
|
||||
def log_request_end(self):
|
||||
end_at = datetime.datetime.now()
|
||||
total_delta = (end_at - self.start_at).total_seconds()
|
||||
_spend = f"耗时:{total_delta:f} 秒."
|
||||
|
||||
_user_name = self.user.username if self.user else 'Unknown'
|
||||
_log = f"O 用户:{_user_name} 完成 {self.request.uri}"
|
||||
_log = f"{_log} 接口命令 {self.command},{_spend}" if self.command else f"{_log} 请求,{_spend}"
|
||||
self.log(_log)
|
||||
|
||||
def log_request_start(self):
|
||||
"""
|
||||
收到请求时记录的日志
|
||||
"""
|
||||
_user_name = self.user.username if self.user else 'Unknown'
|
||||
_log = f"I 用户:{_user_name} 请求 {self.request.uri}"
|
||||
_log = f"{_log} 接口命令 {self.command}." if self.command else f"{_log}."
|
||||
self.log(_log)
|
||||
Reference in New Issue
Block a user