class QueryOrderDetailTool: name = 'query_order_detail' route_path = '/mcp/tools/queryOrderDetail' sections = ( '订单概览', '箱单信息', '箱单商品', 'DW授权信息', '附件信息', '入库信息', '查验信息', '订单轨迹', '操作日志', '应收与结算日志', '派送信息', '全部', ) def __init__(self, api_client=None): self.api_client = api_client def metadata(self): return { 'name': self.name, 'description': ( '使用场景:用户明确提供订单号并要求查看订单详情时使用。可查询订单概览、' '箱单、箱单商品、DW授权、附件、入库、查验、订单轨迹、操作日志、应收与' '结算日志及派送信息。用户要求完整详情时可使用“全部”一次取得所有模块;' '各明细模块仍按独立分页信息展示,任何模块为空都不能作为跳过其他模块的依据。' '本工具只用于单个订单的详情查询;用户要求订单列表、批量筛选或多个订单汇总时,' '必须改用 query_order_exact,不得使用本工具替代。即使用户提供了订单号,' '只要目标是列表或批量结果,也不能调用本工具。用户要求分别查询多个订单详情时,' '必须按订单号逐个调用本工具,每次只传一个订单号,不得合并成列表查询。' '只接受订单号,不接受订单ID、箱单ID、查验ID、公司、员工' '或权限字段。不得猜测号码类型或把同一号码跨工具试查。参数名仅用于工具' '调用;向用户回答时只能展示固定中文业务名称,不得展示内部参数名。' ), 'input_schema': { 'type': 'object', 'properties': { 'order_number': { 'type': 'string', 'minLength': 1, 'maxLength': 100, 'description': '明确的订单号。', }, 'section': { 'type': 'string', 'enum': list(self.sections), 'default': '全部', 'description': '要查看的中文详情模块;未指定时返回全部模块。', }, 'page': { 'type': 'integer', 'minimum': 1, 'maximum': 100, 'default': 1, }, 'limit': { 'type': 'integer', 'minimum': 1, 'maximum': 100, 'default': 20, }, }, 'required': ['order_number'], 'additionalProperties': False, }, } def call( self, order_number=None, section='全部', page=1, limit=20, request_id='rq_query_order_detail', ): if self.api_client is None: raise RuntimeError('api client is required for query_order_detail') if not isinstance(order_number, str): raise ValueError('order_number is required') order_number = order_number.strip() if not order_number or len(order_number) > 100: raise ValueError('order_number is required') if not isinstance(section, str) or section.strip() not in self.sections: raise ValueError('section is invalid') section = section.strip() page = self._bounded_integer(page, 'page') limit = self._bounded_integer(limit, 'limit') return self.api_client.call_tool( self.name, self.route_path, { 'order_number': order_number, 'section': section, 'page': page, 'limit': limit, }, request_id, ) @staticmethod def _bounded_integer(value, field): if isinstance(value, bool): raise ValueError('{0} is invalid'.format(field)) if isinstance(value, int): number = value elif isinstance(value, str) and value.isdigit() and not value.startswith('0'): number = int(value) else: raise ValueError('{0} is invalid'.format(field)) if number < 1 or number > 100: raise ValueError('{0} is invalid'.format(field)) return number