Bläddra i källkod

master_task_7059469405

jackson 3 veckor sedan
förälder
incheckning
d036f52dff

+ 2 - 2
README.md

@@ -34,8 +34,8 @@ Gateway 保持“薄网关”边界:
 | `query_order_exact` | 按明确号码类型精准查询订单 | `/mcp/tools/queryOrderExact` | 安全表格 |
 | `query_order_detail` | 按明确订单号查询订单详情,支持“全部”聚合 | `/mcp/tools/queryOrderDetail` | 安全中文详情 |
 | `query_customs_declaration_files` | 按订单号或排舱单号查询报关资料 | `/mcp/tools/queryCustomsDeclarationFiles` | 安全表格 |
-| `query_outbound_list` | 按业务阶段和筛选条件查询排舱列表 | `/mcp/tools/queryOutboundList` | 安全表格 |
-| `query_outbound_detail` | 按排舱单号查询排舱汇总与订单明细 | `/mcp/tools/queryOutboundDetail` | 安全详情 |
+| `query_outbound_list` | 按业务阶段和筛选条件查询排舱列表 | `/mcp/tools/queryOutboundList` | 固定 31 列安全表格 |
+| `query_outbound_detail` | 按排舱单号查询排舱汇总与订单明细 | `/mcp/tools/queryOutboundDetail` | 11 项汇总 + 38 项明细 |
 | `list_outbound_filter_options` | 查询七类排舱筛选项 | `/mcp/tools/listOutboundFilterOptions` | 安全筛选项 |
 | `list_order_filter_options` | 查询精准订单筛选项 | `/mcp/tools/listOrderFilterOptions` | 安全筛选项 |
 | `export_pending_outbound_orders` | 提交未排舱订单异步导出 | `/mcp/tools/exportPendingOutboundOrders` | 签名任务引用 |

+ 16 - 0
services/output_presenter.py

@@ -253,6 +253,18 @@ class OutputPresenter:
             'operator': ('操作人',),
             'operation_modes': ('拖报清方式',),
             'operation_time': ('操作时间',),
+            'ship_company': ('船司',),
+            'vessel_name': ('船名航次',),
+            'cutoff_time_si': ('截SI时间',),
+            'clearance_port': ('清关口岸',),
+            'loading_port': ('起运港',),
+            'destination_port': ('目的港',),
+            'transit_port': ('中转港',),
+            'etd': ('ETD',),
+            'eta': ('ETA',),
+            'has_fda': ('是否含FDA认证商品',),
+            'has_cpsc': ('是否含CPSC商品',),
+            'has_food': ('是否含食品',),
         },
         'query_outbound_detail': {
             'order_number': ('订单号',),
@@ -289,6 +301,10 @@ class OutputPresenter:
             'is_abnormal': ('是否问题件',),
             'package_method': ('包装类型',),
             'order_reply': ('到货回复',),
+            'is_must_load': ('订单是否必装',),
+            'has_fda': ('是否含FDA认证商品',),
+            'has_cpsc': ('是否含CPSC商品',),
+            'has_food': ('是否含食品',),
         },
     }
 

+ 8 - 4
tests/test_outbound_query_tools.py

@@ -16,6 +16,9 @@ LIST_KEYS = [
     'seal_number', 'container_type', 'shipping_method', 'total_volume',
     'total_weight', 'ship_schedule', 'closing_time', 'est_loading_time',
     'operator', 'operation_modes', 'operation_time',
+    'ship_company', 'vessel_name', 'cutoff_time_si', 'clearance_port',
+    'loading_port', 'destination_port', 'transit_port', 'etd', 'eta',
+    'has_fda', 'has_cpsc', 'has_food',
 ]
 
 DETAIL_KEYS = [
@@ -28,6 +31,7 @@ DETAIL_KEYS = [
     'delivery_type', 'delivery_way', 'channel', 'country_name',
     'importer_name', 'vat_type', 'packing_type', 'is_abnormal',
     'package_method', 'order_reply',
+    'is_must_load', 'has_fda', 'has_cpsc', 'has_food',
 ]
 
 
@@ -355,8 +359,8 @@ class OutboundQueryToolTest(unittest.TestCase):
 
         self.assertFalse(result['is_error'])
         content = result['structured_content']
-        self.assertEqual(19, len(content['headers']))
-        self.assertEqual(19, len(content['rows'][0]))
+        self.assertEqual(31, len(content['headers']))
+        self.assertEqual(31, len(content['rows'][0]))
         serialized = json.dumps(content, ensure_ascii=False)
         for key in LIST_KEYS:
             self.assertNotIn(key, serialized)
@@ -401,8 +405,8 @@ class OutboundQueryToolTest(unittest.TestCase):
         content = result['structured_content']
         self.assertEqual(11, len(content['summary']['headers']))
         self.assertEqual(11, len(content['summary']['row']))
-        self.assertEqual(34, len(content['details']['headers']))
-        self.assertEqual(34, len(content['details']['rows'][0]))
+        self.assertEqual(38, len(content['details']['headers']))
+        self.assertEqual(38, len(content['details']['rows'][0]))
         serialized = json.dumps(content, ensure_ascii=False)
         for key in list(summary) + DETAIL_KEYS:
             self.assertNotIn(key, serialized)

+ 2 - 2
tests/test_tool_description_boundaries.py

@@ -63,8 +63,8 @@ class ToolDescriptionBoundaryTest(unittest.TestCase):
             QueryOrderDetailTool(): ('单个订单的详情', '逐个调用', 'query_order_exact', '订单列表'),
             QueryTrackTool(): ('物流轨迹', '订单资料', '报关资料文件'),
             QueryCustomsDeclarationFilesTool(): ('报关资料文件', '完整排舱详情', '文件链接'),
-            QueryOutboundListTool(): ('排舱列表', '19个字段', '排舱详情'),
-            QueryOutboundDetailTool(): ('排舱详情', '11项汇总', '34项订单明细'),
+            QueryOutboundListTool(): ('排舱列表', '31个字段', '排舱详情'),
+            QueryOutboundDetailTool(): ('排舱详情', '11项汇总', '38项订单明细'),
             ListOrderFilterOptionsTool(): ('query_order_exact', '授权筛选值', '业务数据'),
             ListPendingOutboundExportFilterOptionsTool(): (
                 'export_pending_outbound_orders', '授权筛选值', 'query_outbound_list',

+ 1 - 1
tools/query_outbound_detail.py

@@ -10,7 +10,7 @@ class QueryOutboundDetailTool:
             'name': self.name,
             'description': (
                 '使用场景:用户明确要查看一张排舱单的排舱详情,并明确提供排舱单号时'
-                '使用。返回第一层11项汇总和第二层34项订单明细,包括明细表中的报关资料。'
+                '使用。返回第一层11项汇总和第二层38项订单明细,包括明细表中的报关资料。'
                 '只接受排舱单号,不接受订单号、柜号、SO号、提单号或数据库ID。用户明确'
                 '要看排舱详情但只提供订单号时,应先用query_outbound_list按订单号定位;'
                 '多条命中必须让用户选择。号码类型不明确时必须先询问用户。'

+ 1 - 1
tools/query_outbound_list.py

@@ -97,7 +97,7 @@ class QueryOutboundListTool:
             'name': self.name,
             'description': (
                 '使用场景:用户明确要查看或筛选排舱列表时使用,返回后台排舱单列表权限'
-                '范围内固定的19个字段。运输方式未指定时查询全部;排舱阶段必须由用户明确,未明确时'
+                '范围内固定的31个字段。运输方式未指定时查询全部;排舱阶段必须由用户明确,未明确时'
                 '必须先询问,不得默认选择。号码类型不明确时必须先'
                 '询问用户,确认是排舱单号、订单号、柜号、SO号还是提单号后再调用。'
                 '只有用户明确分别提供多个不同类型条件时才按AND组合。阶段、运输方式、仓库、'