383 lines
14 KiB
Python
383 lines
14 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
外部任务接口API模块
|
||
提供外部系统调用的任务创建接口
|
||
"""
|
||
|
||
import json
|
||
from typing import Dict, Any
|
||
from fastapi import APIRouter, Body, Request
|
||
from routes.model.external_task_model import ExternalTaskRequest, ExternalTaskResponse, TaskTypeEnum, GenAgvSchedulingTaskRequest
|
||
from routes.model.task_edit_model import TaskEditRunRequest, TaskInputParamNew, InputParamType
|
||
from services.task_edit_service import TaskEditService
|
||
from routes.common_api import format_response, error_response
|
||
from utils.logger import get_logger
|
||
from data.enum.task_record_enum import SourceType
|
||
from config.tf_api_config import TF_API_TOKEN
|
||
|
||
# tf_api_config = get_tf_api_config()
|
||
|
||
# 创建路由
|
||
router = APIRouter(
|
||
prefix="",
|
||
tags=["外部任务接口"]
|
||
)
|
||
|
||
# 设置日志
|
||
logger = get_logger("app.external_task_api")
|
||
|
||
# 任务类型到模板ID的映射
|
||
TASK_TYPE_TEMPLATE_MAPPING = {
|
||
TaskTypeEnum.GG2MP: "template_gg2mp_id", # 高柜到MP模板ID
|
||
TaskTypeEnum.GGFK2MP: "template_ggfk2mp_id", # 高柜发库到MP模板ID
|
||
TaskTypeEnum.GT2MP: "571985c1-cfa5-4186-8acd-6e3868a5e08c", # 高台到MP模板ID
|
||
TaskTypeEnum.GTFK2MP: "template_gtfk2mp_id", # 高台发库到MP模板ID
|
||
TaskTypeEnum.ZG2MP: "template_zg2mp_id", # 中柜到MP模板ID
|
||
TaskTypeEnum.QZ2MP: "template_qz2mp_id", # 清洗到MP模板ID
|
||
TaskTypeEnum.LG2MP: "template_lg2mp_id", # 料柜到MP模板ID
|
||
TaskTypeEnum.PHZ2MP: "template_phz2mp_id", # 配货站到MP模板ID
|
||
TaskTypeEnum.MP2GG: "template_mp2gg_id", # MP到高柜模板ID
|
||
TaskTypeEnum.MP2GGFK: "571985c1-cfa5-4186-8acd-6e3868a5e08c", # MP到高柜发库模板ID
|
||
TaskTypeEnum.MP2GT: "template_mp2gt_id", # MP到高台模板ID
|
||
TaskTypeEnum.MP2GTFK: "template_mp2gtfk_id", # MP到高台发库模板ID
|
||
TaskTypeEnum.MP2ZG: "template_mp2zg_id", # MP到中柜模板ID
|
||
TaskTypeEnum.MP2QZ: "template_mp2qz_id", # MP到清洗模板ID
|
||
TaskTypeEnum.MP2LG: "template_mp2lg_id", # MP到料柜模板ID
|
||
TaskTypeEnum.MP2PHZ: "template_mp2phz_id", # MP到配货站模板ID
|
||
}
|
||
|
||
@router.post("/newTask")
|
||
async def create_new_task(request: Request, task_request: ExternalTaskRequest = Body(...)):
|
||
"""
|
||
创建新任务接口
|
||
根据任务类型自动选择对应的任务模板并执行任务
|
||
|
||
Args:
|
||
task_request: 外部任务创建请求,包含ReqCode、SourceID、TargetID、TaskType
|
||
|
||
Returns:
|
||
ExternalTaskResponse: 包含code、reqCode、message、rowCount的响应
|
||
"""
|
||
try:
|
||
logger.info(f"收到外部任务创建请求: ReqCode={task_request.ReqCode}, TaskType={task_request.TaskType}")
|
||
|
||
# 根据任务类型获取对应的模板ID
|
||
template_id = TASK_TYPE_TEMPLATE_MAPPING.get(task_request.TaskType)
|
||
# print("template_id::::", template_id, "==========")
|
||
if not template_id:
|
||
logger.error(f"不支持的任务类型: {task_request.TaskType}")
|
||
return ExternalTaskResponse(
|
||
code=400,
|
||
reqCode=task_request.ReqCode,
|
||
message=f"不支持的任务类型: {task_request.TaskType}",
|
||
rowCount=0
|
||
)
|
||
|
||
# 构造任务运行参数
|
||
task_params = []
|
||
|
||
# 添加SourceID参数(如果提供)
|
||
if task_request.SourceID:
|
||
task_params.append(TaskInputParamNew(
|
||
name="sourceId",
|
||
type=InputParamType.STRING,
|
||
label="来源ID",
|
||
required=False,
|
||
defaultValue=task_request.SourceID,
|
||
remark="外部接口传入的来源ID"
|
||
))
|
||
|
||
# 添加TargetID参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="targetId",
|
||
type=InputParamType.STRING,
|
||
label="目标ID",
|
||
required=True,
|
||
defaultValue=task_request.TargetID,
|
||
remark="外部接口传入的目标ID"
|
||
))
|
||
|
||
# 添加ReqCode参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="reqCode",
|
||
type=InputParamType.STRING,
|
||
label="请求标识码",
|
||
required=True,
|
||
defaultValue=task_request.ReqCode,
|
||
remark="外部接口传入的请求唯一标识码"
|
||
))
|
||
|
||
# 构造任务执行请求
|
||
run_request = TaskEditRunRequest(
|
||
taskId=template_id,
|
||
params=task_params,
|
||
source_type=SourceType.SYSTEM_SCHEDULING, # 第三方系统
|
||
source_system="EXTERNAL_API", # 外部接口系统标识
|
||
source_device=request.client.host if request.client else "unknown", # 使用客户端IP作为设备标识
|
||
use_modbus=False,
|
||
modbus_timeout=5000
|
||
)
|
||
|
||
# 获取客户端信息
|
||
client_ip = request.client.host if request.client else None
|
||
user_agent = request.headers.get("user-agent", "")
|
||
|
||
tf_api_token = TF_API_TOKEN
|
||
|
||
client_info = {
|
||
"user_agent": user_agent,
|
||
"headers": dict(request.headers),
|
||
"method": request.method,
|
||
"url": str(request.url)
|
||
}
|
||
client_info_str = json.dumps(client_info, ensure_ascii=False)
|
||
# print("tf_api_config::::::::::::", tf_api_token)
|
||
# print("run_request:::::::::", run_request)
|
||
# print("client_ip:::::::::", client_ip)
|
||
# print("client_info:::::::::", client_info)
|
||
# print("client_info_str:::::::::", client_info_str)
|
||
# print("tf_api_token:::::::::", tf_api_token)
|
||
# 调用任务执行服务
|
||
result = await TaskEditService.run_task(
|
||
run_request,
|
||
client_ip=client_ip,
|
||
client_info=client_info_str,
|
||
tf_api_token=tf_api_token
|
||
)
|
||
|
||
if result is None:
|
||
logger.error(f"任务启动失败: ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message="任务启动失败",
|
||
rowCount=0
|
||
)
|
||
|
||
if not result.get("success", False):
|
||
logger.error(f"任务启动失败: {result.get('message')}, ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message=result.get("message", "任务启动失败"),
|
||
rowCount=0
|
||
)
|
||
|
||
logger.info(f"任务启动成功: ReqCode={task_request.ReqCode}, TaskRecordId={result.get('taskRecordId')}")
|
||
return ExternalTaskResponse(
|
||
code=0,
|
||
reqCode=task_request.ReqCode,
|
||
message="成功",
|
||
rowCount=1
|
||
)
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建外部任务异常: {str(e)}, ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message=f"创建任务失败: {str(e)}",
|
||
rowCount=0
|
||
)
|
||
|
||
@router.post("/GenAgvSchedulingTask")
|
||
async def gen_agv_scheduling_task(request: Request, task_request: GenAgvSchedulingTaskRequest = Body(...)):
|
||
"""
|
||
AGV调度任务接口
|
||
用于生成AGV调度任务
|
||
|
||
Args:
|
||
task_request: AGV调度任务请求,包含ReqCode、TaskTyp、SecurityKey等参数
|
||
|
||
Returns:
|
||
ExternalTaskResponse: 包含code、reqCode、message、rowCount的响应
|
||
"""
|
||
try:
|
||
logger.info(f"收到AGV调度任务请求: ReqCode={task_request.ReqCode}, TaskTyp={task_request.TaskTyp}")
|
||
|
||
# # 验证安全密钥(可根据实际需求实现验证逻辑)
|
||
# if not task_request.SecurityKey:
|
||
# logger.error(f"安全密钥不能为空: ReqCode={task_request.ReqCode}")
|
||
# return ExternalTaskResponse(
|
||
# code=400,
|
||
# reqCode=task_request.ReqCode,
|
||
# message="安全密钥不能为空",
|
||
# rowCount=0GenAgvSchedulingTaskRequest
|
||
# )
|
||
|
||
# 根据任务类型获取对应的模板ID
|
||
template_id = TASK_TYPE_TEMPLATE_MAPPING.get(task_request.TaskTyp)
|
||
# if not template_id:
|
||
# logger.error(f"不支持的任务类型: {task_request.TaskTyp}, ReqCode={task_request.ReqCode}")
|
||
# return ExternalTaskResponse(
|
||
# code=400,
|
||
# reqCode=task_request.ReqCode,
|
||
# message=f"不支持的任务类型: {task_request.TaskTyp}",
|
||
# rowCount=0
|
||
# )
|
||
|
||
# 构造任务运行参数
|
||
task_params = []
|
||
|
||
# 添加任务代码参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="taskCode",
|
||
type=InputParamType.STRING,
|
||
label="任务代码",
|
||
required=True,
|
||
defaultValue=task_request.TaskCode,
|
||
remark="AGV调度任务代码"
|
||
))
|
||
|
||
# 添加类型参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="type",
|
||
type=InputParamType.STRING,
|
||
label="类型",
|
||
required=True,
|
||
defaultValue=task_request.Type,
|
||
remark="任务类型标识"
|
||
))
|
||
|
||
# 添加子类型参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="subType",
|
||
type=InputParamType.STRING,
|
||
label="子类型",
|
||
required=True,
|
||
defaultValue=task_request.SubType,
|
||
remark="任务子类型标识"
|
||
))
|
||
|
||
# 添加区域位置代码参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="areaPositonCode",
|
||
type=InputParamType.STRING,
|
||
label="区域位置代码",
|
||
required=True,
|
||
defaultValue=task_request.AreaPositonCode,
|
||
remark="区域位置代码"
|
||
))
|
||
|
||
# 添加区域位置名称参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="areaPositonName",
|
||
type=InputParamType.STRING,
|
||
label="区域位置名称",
|
||
required=True,
|
||
defaultValue=task_request.AreaPositonName,
|
||
remark="区域位置名称"
|
||
))
|
||
|
||
# 添加位置代码路径参数(转为JSON字符串)
|
||
position_path_json = json.dumps([path.dict() for path in task_request.PositionCodePath], ensure_ascii=False)
|
||
task_params.append(TaskInputParamNew(
|
||
name="positionCodePath",
|
||
type=InputParamType.STRING,
|
||
label="位置代码路径",
|
||
required=True,
|
||
defaultValue=position_path_json,
|
||
remark="位置代码路径JSON数组"
|
||
))
|
||
|
||
# 添加客户端代码参数(如果提供)
|
||
if task_request.ClientCode:
|
||
task_params.append(TaskInputParamNew(
|
||
name="clientCode",
|
||
type=InputParamType.STRING,
|
||
label="客户端代码",
|
||
required=False,
|
||
defaultValue=task_request.ClientCode,
|
||
remark="客户端代码"
|
||
))
|
||
|
||
# 添加令牌代码参数(如果提供)
|
||
if task_request.TokenCode:
|
||
task_params.append(TaskInputParamNew(
|
||
name="tokenCode",
|
||
type=InputParamType.STRING,
|
||
label="令牌代码",
|
||
required=False,
|
||
defaultValue=task_request.TokenCode,
|
||
remark="令牌代码"
|
||
))
|
||
|
||
# 添加ReqCode参数
|
||
task_params.append(TaskInputParamNew(
|
||
name="reqCode",
|
||
type=InputParamType.STRING,
|
||
label="请求标识码",
|
||
required=True,
|
||
defaultValue=task_request.ReqCode,
|
||
remark="请求唯一标识码"
|
||
))
|
||
|
||
# 构造任务执行请求
|
||
run_request = TaskEditRunRequest(
|
||
taskId=template_id,
|
||
params=task_params,
|
||
source_type=SourceType.SYSTEM_SCHEDULING, # 第三方系统
|
||
source_system="AGV_SCHEDULING", # AGV调度系统标识
|
||
source_device=request.client.host if request.client else "unknown", # 使用客户端IP作为设备标识
|
||
use_modbus=False,
|
||
modbus_timeout=5000
|
||
)
|
||
|
||
# 获取客户端信息
|
||
client_ip = request.client.host if request.client else None
|
||
user_agent = request.headers.get("user-agent", "")
|
||
|
||
tf_api_token = TF_API_TOKEN
|
||
|
||
client_info = {
|
||
"user_agent": user_agent,
|
||
"headers": dict(request.headers),
|
||
"method": request.method,
|
||
"url": str(request.url)
|
||
}
|
||
client_info_str = json.dumps(client_info, ensure_ascii=False)
|
||
|
||
# 调用任务执行服务
|
||
result = await TaskEditService.run_task(
|
||
run_request,
|
||
client_ip=client_ip,
|
||
client_info=client_info_str,
|
||
tf_api_token=tf_api_token
|
||
)
|
||
|
||
if result is None:
|
||
logger.error(f"AGV调度任务启动失败: ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message="任务启动失败",
|
||
rowCount=0
|
||
)
|
||
|
||
if not result.get("success", False):
|
||
logger.error(f"AGV调度任务启动失败: {result.get('message')}, ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message=result.get("message", "任务启动失败"),
|
||
rowCount=0
|
||
)
|
||
|
||
logger.info(f"AGV调度任务启动成功: ReqCode={task_request.ReqCode}, TaskRecordId={result.get('taskRecordId')}")
|
||
return ExternalTaskResponse(
|
||
code=0,
|
||
reqCode=task_request.ReqCode,
|
||
message="成功",
|
||
rowCount=0
|
||
)
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建AGV调度任务异常: {str(e)}, ReqCode={task_request.ReqCode}")
|
||
return ExternalTaskResponse(
|
||
code=500,
|
||
reqCode=task_request.ReqCode,
|
||
message=f"创建任务失败: {str(e)}",
|
||
rowCount=0
|
||
) |