165 lines
6.7 KiB
Python
165 lines
6.7 KiB
Python
"""
|
|
推送办理经过。
|
|
|
|
对应文档接口:6、推送办理经过
|
|
"""
|
|
import asyncio
|
|
import json
|
|
from typing import Optional, Union
|
|
|
|
import pandas as pd
|
|
from sqlalchemy import select, desc
|
|
from tornado.httpclient import HTTPResponse, HTTPRequest
|
|
|
|
import dock
|
|
import models
|
|
from dock.oa import oa_api_request
|
|
from models.dcm_push_status import DcmPushStatus
|
|
from models.dcm_task import DcmTask
|
|
from models.dcm_task_process_info import DcmTaskProcessInfo
|
|
from paste.core.logging import echo_log
|
|
from paste.util import udict
|
|
from paste.web import requests
|
|
|
|
DcmTaskProcessInfoMapping = {
|
|
DcmTaskProcessInfo.id.key: 'id',
|
|
DcmTaskProcessInfo.action_time.key: 'actionTime',
|
|
DcmTaskProcessInfo.act_def_name.key: 'actDefName',
|
|
DcmTaskProcessInfo.human_name.key: 'humanName',
|
|
DcmTaskProcessInfo.unit_name.key: 'unitName',
|
|
DcmTaskProcessInfo.action_name.key: 'actionName',
|
|
DcmTaskProcessInfo.next_act_def_name.key: 'nextActDefName',
|
|
DcmTaskProcessInfo.detail.key: 'detail',
|
|
}
|
|
|
|
|
|
async def after_push_process_info_request(response: HTTPResponse, retry_queue: asyncio.Queue[HTTPRequest]):
|
|
"""
|
|
工单推送请求响应后的处理程序。
|
|
|
|
:param response: 响应对象
|
|
:param retry_queue: 重试队列
|
|
"""
|
|
body = response.body.decode()
|
|
echo_log(body)
|
|
body_data = json.loads(body)
|
|
code = udict.get_by_path(body_data, 'code')
|
|
message = udict.get_by_path(body_data, 'msg')
|
|
if code==200:
|
|
dcm_task_id = getattr(response.request, "dcm_task_id")
|
|
await DcmPushStatus.set_push_task_process_info_status(dcm_task_id)
|
|
echo_log(f"推送企业待办过程成功.")
|
|
else:
|
|
echo_log(f"推送企业待办过程失败:{message}")
|
|
|
|
if retry_queue:
|
|
echo_log(f"企业待办过程重试队列中有:{retry_queue.qsize()} 个请求在等待.")
|
|
|
|
|
|
async def push_process_info(fetch_size: int = 50,
|
|
task_id: Optional[Union[str, int, list[Union[str, int]]]] = None):
|
|
"""
|
|
推送待办附件数据及其数据。
|
|
|
|
:param fetch_size: 本次推送数量
|
|
:param task_id: 待办任务 ID 可选
|
|
"""
|
|
# 根据条件获取目标任务 ID 列表(支持指定 task_id 或分页获取)
|
|
task_query = select(DcmTask.id).order_by(desc(DcmTask.act_id))
|
|
if task_id:
|
|
if isinstance(task_id, list):
|
|
task_query = task_query.where(DcmTask.id.in_(task_id))
|
|
echo_log(f"本次推送待办列表:{task_id} 的过程数据...")
|
|
else:
|
|
task_query = task_query.where(DcmTask.id == task_id)
|
|
echo_log(f"本次推送待办:{task_id} 的过程数据...")
|
|
else:
|
|
task_query = task_query.limit(fetch_size)
|
|
echo_log(f"本次推送前 {fetch_size} 条待办过程数据...")
|
|
dcm_task_df = await DcmTask.query_as_df(task_query)
|
|
|
|
# 格式化为字符串
|
|
dcm_task_df[DcmTask.id.key] = dcm_task_df[DcmTask.id.key].astype(str)
|
|
dcm_task_ids = dcm_task_df[DcmTask.id.key].unique().tolist()
|
|
dcm_task_check_info = {f'{tid}': '' for tid in dcm_task_ids}
|
|
|
|
# 预处理数据方法
|
|
def preprocess(df: pd.DataFrame):
|
|
# 格式化时间字段为 yyyy-MM-dd HH:mm:ss
|
|
df[DcmTaskProcessInfo.action_time.key] = (
|
|
pd.to_datetime(
|
|
df[DcmTaskProcessInfo.action_time.key], unit='ms', errors='coerce'
|
|
).dt.strftime('%Y-%m-%d %H:%M:%S')
|
|
)
|
|
|
|
# 设置 check_info
|
|
for tid in dcm_task_ids:
|
|
filtered = df[df[DcmTaskProcessInfo.dcm_task_id.key] == tid].copy()
|
|
if not filtered.empty:
|
|
min_row = filtered.loc[filtered[DcmTaskProcessInfo.item_id.key].idxmin()].iloc[0]
|
|
dcm_task_check_info[tid] = (
|
|
f"{min_row[DcmTaskProcessInfo.action_time.key]}"
|
|
f"{min_row[DcmTaskProcessInfo.human_name.key]}"
|
|
f"在{min_row[DcmTaskProcessInfo.act_def_name.key]}阶段"
|
|
f"{min_row[DcmTaskProcessInfo.action_name.key]}"
|
|
)
|
|
|
|
# 更名,并仅保留需要的列
|
|
df = df.rename(columns=DcmTaskProcessInfoMapping)
|
|
df = df[list(DcmTaskProcessInfoMapping.values()) + [DcmTaskProcessInfo.dcm_task_id.key]]
|
|
return df
|
|
|
|
# 填充处理过程
|
|
await DcmTaskProcessInfo.fill_process_info(dcm_task_df, column_name='handlingProcessList', preprocessing=preprocess)
|
|
|
|
# 处理无待办工单处理过程状态
|
|
empty_dcm_task_df = dcm_task_df[dcm_task_df['handlingProcessList'].apply(lambda x: len(x) == 0)]
|
|
empty_dcm_task_df[DcmPushStatus.dcm_task_id.key] = empty_dcm_task_df[DcmTask.id.key]
|
|
empty_dcm_task_df[DcmPushStatus.push_task_process_info_status.key] = 1
|
|
empty_dcm_task_df = empty_dcm_task_df[[DcmPushStatus.dcm_task_id.key, DcmPushStatus.push_task_process_info_status.key]]
|
|
await DcmPushStatus.save_batch(empty_dcm_task_df)
|
|
|
|
# 过滤空数组
|
|
full_dcm_task_df = dcm_task_df[dcm_task_df['handlingProcessList'].apply(lambda x: len(x) > 0)]
|
|
# 删除 DcmTaskAttachment.dcm_task_id.key 字段
|
|
def remove_dcm_task_id(attachment_list):
|
|
for item in attachment_list:
|
|
if isinstance(item, dict) and DcmTaskProcessInfo.dcm_task_id.key in item:
|
|
del item[DcmTaskProcessInfo.dcm_task_id.key]
|
|
return attachment_list
|
|
# 执行替换
|
|
full_dcm_task_df['handlingProcessList'] = full_dcm_task_df['handlingProcessList'].apply(remove_dcm_task_id)
|
|
# 增加 checkContent 字段,来自办理流程数据合并
|
|
full_dcm_task_df['checkContent'] = full_dcm_task_df[DcmTask.id.key].apply(
|
|
lambda x: dcm_task_check_info.get(x, '')
|
|
)
|
|
|
|
# 处理数据映射,适应接口推送
|
|
mapped_df = full_dcm_task_df.rename(columns={DcmTask.id.key: 'gdId'})
|
|
# 这里把空数据都换成 None,以便存入数据库时是 null
|
|
mapped_df.replace(models.EmptyInDF + models.EmptyDatetimeInDF, '', inplace=True)
|
|
|
|
echo_log(f"正在准备请求队列...")
|
|
# 构建请求队列
|
|
dcm_push_queue = asyncio.Queue()
|
|
|
|
# 向队列中填充请求对象
|
|
for _h, row in mapped_df.iterrows():
|
|
push_request = await oa_api_request.get_push_process_info_request(**row.to_dict())
|
|
setattr(push_request, "dcm_task_id", row.get('gdId'))
|
|
await dcm_push_queue.put(push_request)
|
|
|
|
# 并发提交推送请求
|
|
echo_log(f"开始推送待办过程数据...")
|
|
await requests.async_concurrency(
|
|
dcm_push_queue, con_count=dock.CONCURRENCY_COUNT, retry=dock.MAX_RETRY_COUNT,
|
|
after_request=after_push_process_info_request
|
|
)
|
|
echo_log(f"待办过程数据推送已经完成...")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from paste.core import aio_pool
|
|
_runner = aio_pool.get_aio_runner()
|
|
_runner(push_process_info(task_id=2054174091237265408))
|