""" 推送办理经过。 对应文档接口: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))