From 053d98dffd93c2e5cfe1a48a66b875199d9415f5 Mon Sep 17 00:00:00 2001 From: yuanzhipeng <2501363769@qq.com> Date: Wed, 7 Jan 2026 22:05:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(analyzeWorkOrder):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E5=88=86=E6=9E=90MCP=E6=8A=80=E8=83=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=B9=B6=E6=9B=B4=E6=96=B0=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将项目名称从 lzwcai-mcp-sqlexecutor 重命名为 lzwcai-mcpskills-analyzeWorkOrder - 更新 README.md 中的安装命令、使用说明和配置示例 - 本地化业务查询名称,将中文业务名称改为英文,如"查询列表"改为"QueryList" - 优化SQL模板,移除中文列别名,使用英文字段名 - 新增销售订单相关查询功能,包括订单列表、订单详情、交付风险预测 - 添加部门人效产值损耗三维仪表盘查询 - 更新包的初始化信息和版本号 --- lzwcai_mcpskills_analyzeWorkOrder/README.md | 10 +- .../README.md | 10 +- .../__init__.py | 2 +- .../businessQueries.json | 51 +++++- .../lzwcai_mcpskills_analyzeWorkOrder/main.py | 28 ++- .../pyproject.toml | 10 +- .../lzwcai_mcpskills_analyzeWorkOrder/sql11 | 169 ++++++++++++++++++ .../lzwcai_mcpskills_analyzeWorkOrder/uv.lock | 2 +- lzwcai_mcpskills_analyzeWorkOrder/main.py | 2 +- .../pyproject.toml | 2 +- 10 files changed, 255 insertions(+), 31 deletions(-) create mode 100644 lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/sql11 diff --git a/lzwcai_mcpskills_analyzeWorkOrder/README.md b/lzwcai_mcpskills_analyzeWorkOrder/README.md index 44ee71d..dd1d1dc 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/README.md +++ b/lzwcai_mcpskills_analyzeWorkOrder/README.md @@ -1,4 +1,4 @@ -# lzwcai-mcp-sqlexecutor +# lzwcai-mcpskills-analyzeWorkOrder 一个基于 MCP (Model Context Protocol) 的 SQL 查询执行服务器,支持从 JSON 配置文件动态生成查询工具。 @@ -14,7 +14,7 @@ ### 使用 pip 安装 ```bash -pip install lzwcai-mcp-sqlexecutor +pip install lzwcai-mcpskills-analyzeWorkOrder ``` ### 从源码安装 @@ -28,7 +28,7 @@ pip install -e . ### 使用 uv 安装(推荐) ```bash -uv pip install lzwcai-mcp-sqlexecutor +uv pip install lzwcai-mcpskills-analyzeWorkOrder ``` ## 使用方法 @@ -38,7 +38,7 @@ uv pip install lzwcai-mcp-sqlexecutor 安装后,可以直接通过命令启动: ```bash -lzwcai-mcp-sqlexecutor +lzwcai-mcpskills-analyzeWorkOrder ``` ### 作为 Python 模块运行 @@ -55,7 +55,7 @@ python -m lzwcai_mcp_sqlexecutor.main { "mcpServers": { "lzwcai-sqlexecutor": { - "command": "lzwcai-mcp-sqlexecutor" + "command": "lzwcai-mcpskills-analyzeWorkOrder" } } } diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/README.md b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/README.md index 7352630..0ec9671 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/README.md +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/README.md @@ -1,4 +1,4 @@ -# lzwcai-mcp-sqlexecutor +# lzwcai-mcpskills-analyzeWorkOrder 一个基于 MCP (Model Context Protocol) 的 SQL 查询执行服务器,支持从 JSON 配置文件动态生成查询工具。 @@ -14,7 +14,7 @@ ### 使用 pip 安装 ```bash -pip install lzwcai-mcp-sqlexecutor +pip install lzwcai-mcpskills-analyzeWorkOrder ``` ### 从源码安装 @@ -28,7 +28,7 @@ pip install -e . ### 使用 uv 安装(推荐) ```bash -uv pip install lzwcai-mcp-sqlexecutor +uv pip install lzwcai-mcpskills-analyzeWorkOrder ``` ## 使用方法 @@ -38,7 +38,7 @@ uv pip install lzwcai-mcp-sqlexecutor 安装后,可以直接通过命令启动: ```bash -lzwcai-mcp-sqlexecutor +lzwcai-mcpskills-analyzeWorkOrder ``` ### 作为 Python 模块运行 @@ -55,7 +55,7 @@ python -m lzwcai_mcp_sqlexecutor.main { "mcpServers": { "lzwcai-sqlexecutor": { - "command": "lzwcai-mcp-sqlexecutor" + "command": "lzwcai-mcpskills-analyzeWorkOrder" } } } diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/__init__.py b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/__init__.py index 5df6d9c..4798f49 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/__init__.py +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/__init__.py @@ -1,5 +1,5 @@ """ -lzwcai-mcp-sqlexecutor - MCP server for executing business SQL queries +lzwcai-mcpskills-analyzeWorkOrder - MCP server for executing business SQL queries """ __version__ = "0.1.2" diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json index 9065654..2b30e05 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json @@ -1,7 +1,7 @@ [ { "id": "2006300000000000000", - "businessName": "查询列表", + "businessName": "QueryList", "businessDescription": "查询所有工单列表,返回fact_work_order表的全部数据", "datasourceId": "19", "sqlTemplate": "SELECT * FROM fact_work_order", @@ -9,10 +9,10 @@ }, { "id": "2006300000000000004", - "businessName": "工单详情", + "businessName": "WorkOrderDetail", "businessDescription": "根据工单编号查询工单详情,包括工单基本信息、产品信息、委外供应商、工艺路线等", "datasourceId": "19", - "sqlTemplate": "SELECT wo.work_order_id, wo.work_order_number AS 工单编号, wo.status AS 工单状态, wo.planned_qty AS 计划数量, wo.completed_qty AS 完成数量, wo.operation_good_qty AS 工序良品数, wo.operation_bad_qty AS 工序不良品数, wo.qc_good_qty AS 质检良品数, wo.qc_bad_qty AS 质检不良品数, wo.source_doc_number AS 来源单据编号, wo.event_time_utc AS 事件时间, p.product_code AS 产品编码, p.product_name AS 产品名称, p.product_spec AS 产品规格, s.supplier_name AS 委外供应商, r.routing_name AS 工艺路线 FROM fact_work_order wo LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = true LEFT JOIN dim_supplier s ON wo.supplier_id = s.supplier_id AND s.is_current = true LEFT JOIN dim_routing r ON wo.routing_id = r.routing_id AND r.is_current = true WHERE wo.work_order_number = '{workOrderNumber}'", + "sqlTemplate": "SELECT wo.work_order_id, wo.work_order_number, wo.status, wo.planned_qty, wo.completed_qty, wo.operation_good_qty, wo.operation_bad_qty, wo.qc_good_qty, wo.qc_bad_qty, wo.source_doc_number, wo.event_time_utc, p.product_code, p.product_name, p.product_spec, s.supplier_name, r.routing_name FROM fact_work_order wo LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = true LEFT JOIN dim_supplier s ON wo.supplier_id = s.supplier_id AND s.is_current = true LEFT JOIN dim_routing r ON wo.routing_id = r.routing_id AND r.is_current = true WHERE wo.work_order_number = '{workOrderNumber}'", "parameters": { "workOrderNumber": { "type": "string", @@ -26,10 +26,51 @@ }, { "id": "2006300000000000005", - "businessName": "工单执行进度与异常节点看板", + "businessName": "WorkOrderProgressDashboard", "businessDescription": "工单执行进度与异常节点看板,展示工单完工进度、工序良率、质检良率、异常标识等关键监控指标", "datasourceId": "19", - "sqlTemplate": "WITH work_order_progress AS (SELECT wo.work_order_number, wo.status AS work_order_status, wo.planned_qty, wo.completed_qty, wo.operation_good_qty, wo.operation_bad_qty, wo.qc_good_qty, wo.qc_bad_qty, wo.source_doc_number AS sales_order_number, wo.event_time_utc, p.product_code, p.product_name, CASE WHEN wo.planned_qty > 0 THEN ROUND(wo.completed_qty * 100.0 / wo.planned_qty, 2) ELSE 0 END AS completion_pct, CASE WHEN (wo.operation_good_qty + wo.operation_bad_qty) > 0 THEN ROUND(wo.operation_good_qty * 100.0 / (wo.operation_good_qty + wo.operation_bad_qty), 2) ELSE NULL END AS operation_yield_pct, CASE WHEN (wo.qc_good_qty + wo.qc_bad_qty) > 0 THEN ROUND(wo.qc_good_qty * 100.0 / (wo.qc_good_qty + wo.qc_bad_qty), 2) ELSE NULL END AS qc_yield_pct FROM fact_work_order wo LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = true), task_summary AS (SELECT work_order_number, COUNT(*) AS total_tasks, SUM(CASE WHEN actual_end_time_utc IS NOT NULL THEN 1 ELSE 0 END) AS completed_tasks, SUM(CASE WHEN actual_start_time_utc IS NOT NULL AND actual_end_time_utc IS NULL THEN 1 ELSE 0 END) AS in_progress_tasks, SUM(CASE WHEN actual_start_time_utc IS NULL THEN 1 ELSE 0 END) AS pending_tasks, SUM(bad_qty) AS total_bad_qty FROM fact_operation_task GROUP BY work_order_number), labor_summary AS (SELECT work_order_number, SUM(report_qty) AS total_report_qty, SUM(good_qty) AS total_good_qty, SUM(bad_qty) AS total_bad_qty, SUM(duration_minutes) AS total_work_minutes FROM fact_labor_report GROUP BY work_order_number), qc_summary AS (SELECT work_order_number, COUNT(*) AS qc_record_count, SUM(pass_qty) AS total_pass_qty, SUM(fail_qty) AS total_fail_qty FROM fact_quality_inspection WHERE work_order_number IS NOT NULL GROUP BY work_order_number) SELECT wp.work_order_number AS 工单编号, wp.product_code AS 产品编码, wp.product_name AS 产品名称, wp.sales_order_number AS 关联销售订单, wp.work_order_status AS 工单状态, wp.planned_qty AS 计划数量, wp.completed_qty AS 完成数量, wp.completion_pct AS 完工进度百分比, COALESCE(ts.total_tasks, 0) AS 工序总数, COALESCE(ts.completed_tasks, 0) AS 已完成工序, COALESCE(ts.in_progress_tasks, 0) AS 进行中工序, COALESCE(ts.pending_tasks, 0) AS 待开始工序, COALESCE(ls.total_report_qty, 0) AS 累计报工数, COALESCE(ls.total_work_minutes, 0) AS 累计工时_分钟, wp.operation_yield_pct AS 工序良率, wp.qc_yield_pct AS 质检良率, COALESCE(qc.total_pass_qty, 0) AS 质检通过数, COALESCE(qc.total_fail_qty, 0) AS 质检不通过数, CASE WHEN wp.completion_pct < 50 AND wp.work_order_status = 'STARTED' THEN '进度滞后' WHEN wp.operation_yield_pct < 90 THEN '工序良率异常' WHEN wp.qc_yield_pct < 95 THEN '质检良率异常' WHEN ts.total_bad_qty > 0 THEN '存在不良品' ELSE '正常' END AS 异常标识, wp.event_time_utc AS 最后更新时间 FROM work_order_progress wp LEFT JOIN task_summary ts ON wp.work_order_number = ts.work_order_number LEFT JOIN labor_summary ls ON wp.work_order_number = ls.work_order_number LEFT JOIN qc_summary qc ON wp.work_order_number = qc.work_order_number ORDER BY CASE wp.work_order_status WHEN 'STARTED' THEN 1 WHEN 'RELEASED' THEN 2 WHEN 'PLANNED' THEN 3 ELSE 4 END, wp.event_time_utc DESC", + "sqlTemplate": "WITH work_order_progress AS (SELECT wo.work_order_number, wo.status AS work_order_status, wo.planned_qty, wo.completed_qty, wo.operation_good_qty, wo.operation_bad_qty, wo.qc_good_qty, wo.qc_bad_qty, wo.source_doc_number AS sales_order_number, wo.event_time_utc, p.product_code, p.product_name, CASE WHEN wo.planned_qty > 0 THEN ROUND(wo.completed_qty * 100.0 / wo.planned_qty, 2) ELSE 0 END AS completion_pct, CASE WHEN (wo.operation_good_qty + wo.operation_bad_qty) > 0 THEN ROUND(wo.operation_good_qty * 100.0 / (wo.operation_good_qty + wo.operation_bad_qty), 2) ELSE NULL END AS operation_yield_pct, CASE WHEN (wo.qc_good_qty + wo.qc_bad_qty) > 0 THEN ROUND(wo.qc_good_qty * 100.0 / (wo.qc_good_qty + wo.qc_bad_qty), 2) ELSE NULL END AS qc_yield_pct FROM fact_work_order wo LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = true), task_summary AS (SELECT work_order_number, COUNT(*) AS total_tasks, SUM(CASE WHEN actual_end_time_utc IS NOT NULL THEN 1 ELSE 0 END) AS completed_tasks, SUM(CASE WHEN actual_start_time_utc IS NOT NULL AND actual_end_time_utc IS NULL THEN 1 ELSE 0 END) AS in_progress_tasks, SUM(CASE WHEN actual_start_time_utc IS NULL THEN 1 ELSE 0 END) AS pending_tasks, SUM(bad_qty) AS total_bad_qty FROM fact_operation_task GROUP BY work_order_number), labor_summary AS (SELECT work_order_number, SUM(report_qty) AS total_report_qty, SUM(good_qty) AS total_good_qty, SUM(bad_qty) AS total_bad_qty, SUM(duration_minutes) AS total_work_minutes FROM fact_labor_report GROUP BY work_order_number), qc_summary AS (SELECT work_order_number, COUNT(*) AS qc_record_count, SUM(pass_qty) AS total_pass_qty, SUM(fail_qty) AS total_fail_qty FROM fact_quality_inspection WHERE work_order_number IS NOT NULL GROUP BY work_order_number) SELECT wp.work_order_number, wp.product_code, wp.product_name, wp.sales_order_number, wp.work_order_status, wp.planned_qty, wp.completed_qty, wp.completion_pct, COALESCE(ts.total_tasks, 0) AS total_tasks, COALESCE(ts.completed_tasks, 0) AS completed_tasks, COALESCE(ts.in_progress_tasks, 0) AS in_progress_tasks, COALESCE(ts.pending_tasks, 0) AS pending_tasks, COALESCE(ls.total_report_qty, 0) AS total_report_qty, COALESCE(ls.total_work_minutes, 0) AS total_work_minutes, wp.operation_yield_pct, wp.qc_yield_pct, COALESCE(qc.total_pass_qty, 0) AS qc_pass_qty, COALESCE(qc.total_fail_qty, 0) AS qc_fail_qty, CASE WHEN wp.completion_pct < 50 AND wp.work_order_status = 'STARTED' THEN 'PROGRESS_DELAY' WHEN wp.operation_yield_pct < 90 THEN 'OPERATION_YIELD_ABNORMAL' WHEN wp.qc_yield_pct < 95 THEN 'QC_YIELD_ABNORMAL' WHEN ts.total_bad_qty > 0 THEN 'HAS_DEFECTS' ELSE 'NORMAL' END AS abnormal_flag, wp.event_time_utc AS last_update_time FROM work_order_progress wp LEFT JOIN task_summary ts ON wp.work_order_number = ts.work_order_number LEFT JOIN labor_summary ls ON wp.work_order_number = ls.work_order_number LEFT JOIN qc_summary qc ON wp.work_order_number = qc.work_order_number ORDER BY CASE wp.work_order_status WHEN 'STARTED' THEN 1 WHEN 'RELEASED' THEN 2 WHEN 'PLANNED' THEN 3 ELSE 4 END, wp.event_time_utc DESC", + "parameters": {} + }, + { + "id": "2006300000000000006", + "businessName": "SalesOrderList", + "businessDescription": "历史订单列表:查询所有销售订单,包含客户信息、订单金额、收款状态、交货日期等关键信息", + "datasourceId": "19", + "sqlTemplate": "SELECT so.sales_order_id, so.sales_order_number, c.customer_name, so.contract_number, so.order_date_utc, so.delivery_date_utc, so.deal_amount, so.currency_code, so.payment_status, so.stage, so.result, so.transport_mode, so.production_doc_number, so.event_time_utc FROM fact_sales_order so LEFT JOIN dim_customer c ON so.customer_id = c.customer_id AND c.is_current = true ORDER BY so.order_date_utc DESC", + "parameters": {} + }, + { + "id": "2006300000000000007", + "businessName": "SalesOrderDetail", + "businessDescription": "订单详情:根据订单编号查询订单详细信息,包含客户信息、销售员、合同、金额、交货日期、收款状态等完整信息", + "datasourceId": "19", + "sqlTemplate": "SELECT so.sales_order_id, so.sales_order_number, c.customer_name, c.customer_level, c.phone AS customer_phone, c.email AS customer_email, c.address AS customer_address, p.person_name AS sales_person_name, so.contract_number, ct.contract_name, ct.contract_amount, so.order_date_utc, so.delivery_date_utc, so.deal_amount, so.currency_code, so.fx_rate, so.payment_status, so.transport_mode, so.packaging, so.customs_number, so.production_doc_number, so.stage, so.result, so.event_time_utc FROM fact_sales_order so LEFT JOIN dim_customer c ON so.customer_id = c.customer_id AND c.is_current = true LEFT JOIN dim_person p ON so.sales_person_id = p.person_id AND p.is_current = true LEFT JOIN dim_contract ct ON so.contract_id = ct.contract_id AND ct.is_current = true WHERE so.sales_order_number = '{salesOrderNumber}'", + "parameters": { + "salesOrderNumber": { + "type": "string", + "description": "销售订单编号", + "required": true, + "examples": [ + "SO20251225001" + ] + } + } + }, + { + "id": "2006300000000000008", + "businessName": "DeliveryRiskPrediction", + "businessDescription": "交付风险预测:基于历史订单的生产周期、物流延误、设备故障等特征,计算延迟概率与红/黄/绿预警等级", + "datasourceId": "19", + "sqlTemplate": "WITH global_production AS (SELECT COUNT(*) AS total_wo_count, AVG(CASE WHEN planned_qty > 0 THEN completed_qty / planned_qty ELSE 0 END) AS avg_completion_rate, SUM(CASE WHEN status IN ('OPEN', 'STARTED') THEN 1 ELSE 0 END) AS pending_wo_count, SUM(CASE WHEN status = 'CLOSED' THEN 1 ELSE 0 END) AS closed_wo_count FROM fact_work_order), global_quality AS (SELECT COUNT(*) AS total_inspection_count, SUM(COALESCE(pass_qty, 0)) AS total_pass_qty, SUM(COALESCE(fail_qty, 0)) AS total_fail_qty, CASE WHEN SUM(COALESCE(pass_qty, 0) + COALESCE(fail_qty, 0)) > 0 THEN SUM(COALESCE(pass_qty, 0))::FLOAT / SUM(COALESCE(pass_qty, 0) + COALESCE(fail_qty, 0)) ELSE 1 END AS qc_pass_rate FROM fact_quality_inspection), global_operation AS (SELECT COUNT(*) AS total_task_count, SUM(COALESCE(good_qty, 0)) AS total_good_qty, SUM(COALESCE(bad_qty, 0)) AS total_bad_qty, CASE WHEN SUM(COALESCE(good_qty, 0) + COALESCE(bad_qty, 0)) > 0 THEN SUM(COALESCE(bad_qty, 0))::FLOAT / SUM(COALESCE(good_qty, 0) + COALESCE(bad_qty, 0)) ELSE 0 END AS operation_defect_rate FROM fact_operation_task), customer_shipment AS (SELECT customer_id, COUNT(*) AS shipment_count, SUM(COALESCE(amount, 0)) AS total_shipment_amount FROM fact_sales_shipment GROUP BY customer_id), customer_return AS (SELECT customer_id, COUNT(*) AS return_count, SUM(COALESCE(amount, 0)) AS total_return_amount FROM fact_sales_return GROUP BY customer_id), order_risk AS (SELECT so.sales_order_id, so.sales_order_number, c.customer_name, so.order_date_utc, so.deal_amount, so.payment_status, gp.avg_completion_rate AS production_completion_rate, gp.pending_wo_count, gp.total_wo_count AS work_order_count, gq.qc_pass_rate, gq.total_fail_qty, go.operation_defect_rate, COALESCE(cs.shipment_count, 0) AS shipment_count, COALESCE(cr.return_count, 0) AS return_count, CASE WHEN COALESCE(cs.shipment_count, 0) > 0 THEN COALESCE(cr.return_count, 0)::FLOAT / cs.shipment_count ELSE 0 END AS return_rate FROM fact_sales_order so LEFT JOIN dim_customer c ON so.customer_id = c.customer_id AND c.is_current = true CROSS JOIN global_production gp CROSS JOIN global_quality gq CROSS JOIN global_operation go LEFT JOIN customer_shipment cs ON so.customer_id = cs.customer_id LEFT JOIN customer_return cr ON so.customer_id = cr.customer_id) SELECT sales_order_id, sales_order_number, customer_name, order_date_utc, deal_amount, payment_status, work_order_count, ROUND(production_completion_rate::NUMERIC, 2) AS production_completion_rate, pending_wo_count, ROUND(qc_pass_rate::NUMERIC, 2) AS qc_pass_rate, ROUND(operation_defect_rate::NUMERIC, 4) AS operation_defect_rate, return_count, ROUND(return_rate::NUMERIC, 4) AS return_rate, ROUND((CASE WHEN production_completion_rate < 0.3 THEN 0.30 WHEN production_completion_rate < 0.5 THEN 0.20 WHEN production_completion_rate < 0.8 THEN 0.10 ELSE 0 END + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 WHEN qc_pass_rate < 0.9 THEN 0.15 WHEN qc_pass_rate < 0.95 THEN 0.08 ELSE 0 END + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 WHEN operation_defect_rate > 0.05 THEN 0.12 WHEN operation_defect_rate > 0.02 THEN 0.05 ELSE 0 END + CASE WHEN return_rate > 0.1 THEN 0.15 WHEN return_rate > 0.05 THEN 0.08 WHEN return_rate > 0.02 THEN 0.03 ELSE 0 END + CASE WHEN payment_status = 'UNPAID' THEN 0.10 WHEN payment_status = 'PARTIAL' THEN 0.05 ELSE 0 END)::NUMERIC, 2) AS delay_probability, CASE WHEN (CASE WHEN production_completion_rate < 0.3 THEN 0.30 WHEN production_completion_rate < 0.5 THEN 0.20 WHEN production_completion_rate < 0.8 THEN 0.10 ELSE 0 END + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 WHEN qc_pass_rate < 0.9 THEN 0.15 WHEN qc_pass_rate < 0.95 THEN 0.08 ELSE 0 END + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 WHEN operation_defect_rate > 0.05 THEN 0.12 WHEN operation_defect_rate > 0.02 THEN 0.05 ELSE 0 END + CASE WHEN return_rate > 0.1 THEN 0.15 WHEN return_rate > 0.05 THEN 0.08 WHEN return_rate > 0.02 THEN 0.03 ELSE 0 END + CASE WHEN payment_status = 'UNPAID' THEN 0.10 WHEN payment_status = 'PARTIAL' THEN 0.05 ELSE 0 END) >= 0.50 THEN 'RED' WHEN (CASE WHEN production_completion_rate < 0.3 THEN 0.30 WHEN production_completion_rate < 0.5 THEN 0.20 WHEN production_completion_rate < 0.8 THEN 0.10 ELSE 0 END + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 WHEN qc_pass_rate < 0.9 THEN 0.15 WHEN qc_pass_rate < 0.95 THEN 0.08 ELSE 0 END + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 WHEN operation_defect_rate > 0.05 THEN 0.12 WHEN operation_defect_rate > 0.02 THEN 0.05 ELSE 0 END + CASE WHEN return_rate > 0.1 THEN 0.15 WHEN return_rate > 0.05 THEN 0.08 WHEN return_rate > 0.02 THEN 0.03 ELSE 0 END + CASE WHEN payment_status = 'UNPAID' THEN 0.10 WHEN payment_status = 'PARTIAL' THEN 0.05 ELSE 0 END) >= 0.25 THEN 'YELLOW' ELSE 'GREEN' END AS risk_level, CONCAT_WS(' | ', CASE WHEN production_completion_rate < 0.5 THEN '生产进度滞后' END, CASE WHEN qc_pass_rate < 0.9 THEN '质检通过率低' END, CASE WHEN operation_defect_rate > 0.05 THEN '工序不良率高' END, CASE WHEN return_rate > 0.05 THEN '历史退货率高' END, CASE WHEN payment_status = 'UNPAID' THEN '未付款' END) AS risk_reasons FROM order_risk ORDER BY delay_probability DESC, deal_amount DESC", + "parameters": {} + }, + { + "id": "2006300000000000009", + "businessName": "DepartmentEfficiencyDashboard", + "businessDescription": "部门人效产值损耗三维仪表盘:关联订单量×工时×人员数×成本,构建人效—产值—损耗三维模型,按部门汇总展示", + "datasourceId": "19", + "sqlTemplate": "WITH order_summary AS (SELECT COUNT(DISTINCT so.sales_order_id) AS total_order_count, SUM(COALESCE(so.deal_amount, 0)) AS total_order_amount FROM fact_sales_order so), labor_by_dept AS (SELECT p.department, COUNT(DISTINCT lr.worker_name) AS worker_count, SUM(COALESCE(lr.duration_minutes, 0)) AS total_work_minutes, SUM(COALESCE(lr.report_qty, 0)) AS total_report_qty, SUM(COALESCE(lr.good_qty, 0)) AS total_good_qty, SUM(COALESCE(lr.bad_qty, 0)) AS total_bad_qty FROM fact_labor_report lr LEFT JOIN dim_person p ON lr.worker_name = p.person_name AND p.is_current = true GROUP BY p.department), work_order_output AS (SELECT p.department, SUM(COALESCE(wo.completed_qty, 0)) AS completed_qty, SUM(COALESCE(wo.operation_bad_qty, 0)) AS operation_bad_qty, SUM(COALESCE(wo.qc_bad_qty, 0)) AS qc_bad_qty, COUNT(DISTINCT wo.work_order_id) AS work_order_count FROM fact_work_order wo LEFT JOIN dim_person p ON wo.production_manager_id = p.person_id AND p.is_current = true GROUP BY p.department), scrap_by_dept AS (SELECT p.department, COUNT(*) AS scrap_count FROM fact_scrap s LEFT JOIN dim_person p ON s.operator_id = p.person_id AND p.is_current = true GROUP BY p.department), qc_by_dept AS (SELECT p.department, SUM(COALESCE(qi.pass_qty, 0)) AS qc_pass_qty, SUM(COALESCE(qi.fail_qty, 0)) AS qc_fail_qty FROM fact_quality_inspection qi LEFT JOIN dim_person p ON qi.inspector_id = p.person_id AND p.is_current = true GROUP BY p.department) SELECT COALESCE(ld.department, '未分配') AS department, os.total_order_count, os.total_order_amount, COALESCE(ld.worker_count, 0) AS worker_count, COALESCE(ld.total_work_minutes, 0) AS total_work_minutes, ROUND(COALESCE(ld.total_work_minutes, 0) / 60.0, 2) AS total_work_hours, COALESCE(ld.total_report_qty, 0) AS total_report_qty, COALESCE(ld.total_good_qty, 0) AS total_good_qty, COALESCE(ld.total_bad_qty, 0) AS labor_bad_qty, COALESCE(wo.completed_qty, 0) AS completed_qty, COALESCE(wo.work_order_count, 0) AS work_order_count, COALESCE(wo.operation_bad_qty, 0) AS operation_bad_qty, COALESCE(wo.qc_bad_qty, 0) AS qc_bad_qty, COALESCE(sc.scrap_count, 0) AS scrap_count, COALESCE(qc.qc_pass_qty, 0) AS qc_pass_qty, COALESCE(qc.qc_fail_qty, 0) AS qc_fail_qty, CASE WHEN COALESCE(ld.worker_count, 0) > 0 THEN ROUND(COALESCE(ld.total_report_qty, 0)::NUMERIC / ld.worker_count, 2) ELSE 0 END AS output_per_worker, CASE WHEN COALESCE(ld.total_work_minutes, 0) > 0 THEN ROUND(COALESCE(ld.total_report_qty, 0)::NUMERIC * 60 / ld.total_work_minutes, 2) ELSE 0 END AS output_per_hour, CASE WHEN COALESCE(ld.worker_count, 0) > 0 THEN ROUND(os.total_order_amount::NUMERIC / ld.worker_count, 2) ELSE 0 END AS order_value_per_worker, CASE WHEN (COALESCE(ld.total_good_qty, 0) + COALESCE(ld.total_bad_qty, 0)) > 0 THEN ROUND(COALESCE(ld.total_good_qty, 0)::NUMERIC * 100 / (ld.total_good_qty + ld.total_bad_qty), 2) ELSE 100 END AS labor_yield_pct, CASE WHEN (COALESCE(qc.qc_pass_qty, 0) + COALESCE(qc.qc_fail_qty, 0)) > 0 THEN ROUND(COALESCE(qc.qc_pass_qty, 0)::NUMERIC * 100 / (qc.qc_pass_qty + qc.qc_fail_qty), 2) ELSE 100 END AS qc_yield_pct, COALESCE(ld.total_bad_qty, 0) + COALESCE(wo.operation_bad_qty, 0) + COALESCE(wo.qc_bad_qty, 0) + COALESCE(qc.qc_fail_qty, 0) AS total_loss_qty, CASE WHEN COALESCE(ld.worker_count, 0) > 0 AND COALESCE(ld.total_work_minutes, 0) > 0 AND (COALESCE(ld.total_good_qty, 0) + COALESCE(ld.total_bad_qty, 0)) > 0 THEN CASE WHEN (COALESCE(ld.total_report_qty, 0)::NUMERIC / ld.worker_count) >= 100 AND (COALESCE(ld.total_report_qty, 0)::NUMERIC * 60 / ld.total_work_minutes) >= 10 AND (COALESCE(ld.total_good_qty, 0)::NUMERIC * 100 / (ld.total_good_qty + ld.total_bad_qty)) >= 95 THEN 'EXCELLENT' WHEN (COALESCE(ld.total_report_qty, 0)::NUMERIC / ld.worker_count) >= 50 AND (COALESCE(ld.total_report_qty, 0)::NUMERIC * 60 / ld.total_work_minutes) >= 5 AND (COALESCE(ld.total_good_qty, 0)::NUMERIC * 100 / (ld.total_good_qty + ld.total_bad_qty)) >= 90 THEN 'GOOD' ELSE 'NEEDS_IMPROVEMENT' END ELSE 'NO_DATA' END AS efficiency_rating FROM labor_by_dept ld CROSS JOIN order_summary os LEFT JOIN work_order_output wo ON ld.department = wo.department LEFT JOIN scrap_by_dept sc ON ld.department = sc.department LEFT JOIN qc_by_dept qc ON ld.department = qc.department ORDER BY total_report_qty DESC", "parameters": {} } ] \ No newline at end of file diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/main.py b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/main.py index 2e95c81..0607ec1 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/main.py +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/main.py @@ -94,7 +94,7 @@ def generate_tool_schema_from_query(query: dict) -> types.Tool: # 创建 MCP 服务器实例 -server = Server("lzwcai-mcp-sqlexecutor") +server = Server("lzwcai-mcpskills-analyzeWorkOrder") # 缓存查询配置,避免重复加载 _queries_cache = None @@ -226,16 +226,30 @@ async def handle_call_tool( api_response = test_sql_with_schema(request_data) mcp_logger.info("测试SQL API调用成功") - # 只返回 API 响应结果 - result_text = json.dumps(api_response, ensure_ascii=False, indent=2) + # 返回包含 data 字段的结果 + result = { + "success": True, + "data": api_response + } + result_text = json.dumps(result, ensure_ascii=False, indent=2) except Exception as e: error_msg = f"调用测试SQL API失败: {str(e)}" mcp_logger.error(error_msg, exc_info=True) - result_text = json.dumps({"error": error_msg}, ensure_ascii=False, indent=2) + result = { + "success": False, + "error": error_msg, + "data": None + } + result_text = json.dumps(result, ensure_ascii=False, indent=2) else: error_msg = f"未找到工具 {name} 对应的配置" - result_text = json.dumps({"error": error_msg}, ensure_ascii=False, indent=2) + result = { + "success": False, + "error": error_msg, + "data": None + } + result_text = json.dumps(result, ensure_ascii=False, indent=2) mcp_logger.debug(f"工具调用结果: {result_text}") @@ -297,7 +311,7 @@ async def async_main(): """MCP 服务器异步主函数""" try: mcp_logger.info("=" * 60) - mcp_logger.info("正在启动 MCP 服务器: lzwcai-mcp-sqlexecutor") + mcp_logger.info("正在启动 MCP 服务器: lzwcai-mcpskills-analyzeWorkOrder") mcp_logger.info("版本: 0.1.0") mcp_logger.info("=" * 60) @@ -318,7 +332,7 @@ async def async_main(): read_stream, write_stream, InitializationOptions( - server_name="lzwcai-mcp-sqlexecutor", + server_name="lzwcai-mcpskills-analyzeWorkOrder", server_version="0.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions(), diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml index 33d9c30..c12ec43 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml @@ -3,8 +3,8 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "lzwcai-mcp-sqlexecutor" -version = "0.1.6" +name = "lzwcai-mcpskills-analyzeWorkOrder" +version = "0.1.10" description = "MCP server for executing business SQL queries with dynamic tool generation" readme = "README.md" requires-python = ">=3.13" @@ -26,10 +26,10 @@ dependencies = [ ] [project.scripts] -lzwcai-mcp-sqlexecutor = "lzwcai_mcp_sqlexecutor.main:main" +lzwcai-mcpskills-analyzeWorkOrder = "lzwcai_mcpskills_analyzeWorkOrder.main:main" [tool.hatch.build.targets.wheel] -packages = ["lzwcai_mcp_sqlexecutor"] +packages = ["lzwcai_mcpskills_analyzeWorkOrder"] [tool.hatch.build.targets.wheel.force-include] -"lzwcai_mcp_sqlexecutor/businessQueries.json" = "lzwcai_mcp_sqlexecutor/businessQueries.json" +"lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json" = "lzwcai_mcpskills_analyzeWorkOrder/businessQueries.json" diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/sql11 b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/sql11 new file mode 100644 index 0000000..39b7319 --- /dev/null +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/sql11 @@ -0,0 +1,169 @@ +-- ===================================================== +-- 交付风险预测:延迟概率与红/黄/绿预警等级 +-- 基于历史订单的生产周期、物流延误、设备故障等特征 +-- ===================================================== + +WITH +-- 1. 全局生产特征(汇总所有工单) +global_production AS ( + SELECT + COUNT(*) AS total_wo_count, + AVG(CASE WHEN planned_qty > 0 THEN completed_qty / planned_qty ELSE 0 END) AS avg_completion_rate, + SUM(CASE WHEN status IN ('OPEN', 'STARTED') THEN 1 ELSE 0 END) AS pending_wo_count, + SUM(CASE WHEN status = 'CLOSED' THEN 1 ELSE 0 END) AS closed_wo_count + FROM fact_work_order +), + +-- 2. 全局质检特征 +global_quality AS ( + SELECT + COUNT(*) AS total_inspection_count, + SUM(COALESCE(pass_qty, 0)) AS total_pass_qty, + SUM(COALESCE(fail_qty, 0)) AS total_fail_qty, + CASE WHEN SUM(COALESCE(pass_qty, 0) + COALESCE(fail_qty, 0)) > 0 + THEN SUM(COALESCE(pass_qty, 0))::FLOAT / SUM(COALESCE(pass_qty, 0) + COALESCE(fail_qty, 0)) + ELSE 1 END AS qc_pass_rate + FROM fact_quality_inspection +), + +-- 3. 全局工序不良特征 +global_operation AS ( + SELECT + COUNT(*) AS total_task_count, + SUM(COALESCE(good_qty, 0)) AS total_good_qty, + SUM(COALESCE(bad_qty, 0)) AS total_bad_qty, + CASE WHEN SUM(COALESCE(good_qty, 0) + COALESCE(bad_qty, 0)) > 0 + THEN SUM(COALESCE(bad_qty, 0))::FLOAT / SUM(COALESCE(good_qty, 0) + COALESCE(bad_qty, 0)) + ELSE 0 END AS operation_defect_rate + FROM fact_operation_task +), + +-- 4. 客户级别发货统计 +customer_shipment AS ( + SELECT + customer_id, + COUNT(*) AS shipment_count, + SUM(COALESCE(amount, 0)) AS total_shipment_amount + FROM fact_sales_shipment + GROUP BY customer_id +), + +-- 5. 客户级别退货统计 +customer_return AS ( + SELECT + customer_id, + COUNT(*) AS return_count, + SUM(COALESCE(amount, 0)) AS total_return_amount + FROM fact_sales_return + GROUP BY customer_id +), + +-- 6. 订单风险评估 +order_risk AS ( + SELECT + so.sales_order_id, + so.sales_order_number, + c.customer_name, + so.order_date_utc, + so.deal_amount, + so.payment_status, + + -- 全局生产指标 + gp.avg_completion_rate AS production_completion_rate, + gp.pending_wo_count, + gp.total_wo_count AS work_order_count, + + -- 全局质检指标 + gq.qc_pass_rate, + gq.total_fail_qty, + + -- 全局工序指标 + go.operation_defect_rate, + + -- 客户级别指标 + COALESCE(cs.shipment_count, 0) AS shipment_count, + COALESCE(cr.return_count, 0) AS return_count, + CASE WHEN COALESCE(cs.shipment_count, 0) > 0 + THEN COALESCE(cr.return_count, 0)::FLOAT / cs.shipment_count + ELSE 0 END AS return_rate + + FROM fact_sales_order so + LEFT JOIN dim_customer c ON so.customer_id = c.customer_id AND c.is_current = true + CROSS JOIN global_production gp + CROSS JOIN global_quality gq + CROSS JOIN global_operation go + LEFT JOIN customer_shipment cs ON so.customer_id = cs.customer_id + LEFT JOIN customer_return cr ON so.customer_id = cr.customer_id +) + +-- 7. 最终输出 +SELECT + sales_order_id, + sales_order_number, + customer_name, + order_date_utc, + deal_amount, + payment_status, + + -- 风险特征 + work_order_count, + ROUND(production_completion_rate::NUMERIC, 2) AS production_completion_rate, + pending_wo_count, + ROUND(qc_pass_rate::NUMERIC, 2) AS qc_pass_rate, + ROUND(operation_defect_rate::NUMERIC, 4) AS operation_defect_rate, + return_count, + ROUND(return_rate::NUMERIC, 4) AS return_rate, + + -- 延迟概率 + ROUND(( + CASE WHEN production_completion_rate < 0.3 THEN 0.30 + WHEN production_completion_rate < 0.5 THEN 0.20 + WHEN production_completion_rate < 0.8 THEN 0.10 + ELSE 0 END + + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 + WHEN qc_pass_rate < 0.9 THEN 0.15 + WHEN qc_pass_rate < 0.95 THEN 0.08 + ELSE 0 END + + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 + WHEN operation_defect_rate > 0.05 THEN 0.12 + WHEN operation_defect_rate > 0.02 THEN 0.05 + ELSE 0 END + + CASE WHEN return_rate > 0.1 THEN 0.15 + WHEN return_rate > 0.05 THEN 0.08 + WHEN return_rate > 0.02 THEN 0.03 + ELSE 0 END + + CASE WHEN payment_status = 'UNPAID' THEN 0.10 + WHEN payment_status = 'PARTIAL' THEN 0.05 + ELSE 0 END + )::NUMERIC, 2) AS delay_probability, + + -- 红/黄/绿预警 + CASE + WHEN ( + CASE WHEN production_completion_rate < 0.3 THEN 0.30 WHEN production_completion_rate < 0.5 THEN 0.20 WHEN production_completion_rate < 0.8 THEN 0.10 ELSE 0 END + + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 WHEN qc_pass_rate < 0.9 THEN 0.15 WHEN qc_pass_rate < 0.95 THEN 0.08 ELSE 0 END + + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 WHEN operation_defect_rate > 0.05 THEN 0.12 WHEN operation_defect_rate > 0.02 THEN 0.05 ELSE 0 END + + CASE WHEN return_rate > 0.1 THEN 0.15 WHEN return_rate > 0.05 THEN 0.08 WHEN return_rate > 0.02 THEN 0.03 ELSE 0 END + + CASE WHEN payment_status = 'UNPAID' THEN 0.10 WHEN payment_status = 'PARTIAL' THEN 0.05 ELSE 0 END + ) >= 0.50 THEN 'RED' + WHEN ( + CASE WHEN production_completion_rate < 0.3 THEN 0.30 WHEN production_completion_rate < 0.5 THEN 0.20 WHEN production_completion_rate < 0.8 THEN 0.10 ELSE 0 END + + CASE WHEN qc_pass_rate < 0.8 THEN 0.25 WHEN qc_pass_rate < 0.9 THEN 0.15 WHEN qc_pass_rate < 0.95 THEN 0.08 ELSE 0 END + + CASE WHEN operation_defect_rate > 0.1 THEN 0.20 WHEN operation_defect_rate > 0.05 THEN 0.12 WHEN operation_defect_rate > 0.02 THEN 0.05 ELSE 0 END + + CASE WHEN return_rate > 0.1 THEN 0.15 WHEN return_rate > 0.05 THEN 0.08 WHEN return_rate > 0.02 THEN 0.03 ELSE 0 END + + CASE WHEN payment_status = 'UNPAID' THEN 0.10 WHEN payment_status = 'PARTIAL' THEN 0.05 ELSE 0 END + ) >= 0.25 THEN 'YELLOW' + ELSE 'GREEN' + END AS risk_level, + + -- 风险原因 + CONCAT_WS(' | ', + CASE WHEN production_completion_rate < 0.5 THEN '生产进度滞后' END, + CASE WHEN qc_pass_rate < 0.9 THEN '质检通过率低' END, + CASE WHEN operation_defect_rate > 0.05 THEN '工序不良率高' END, + CASE WHEN return_rate > 0.05 THEN '历史退货率高' END, + CASE WHEN payment_status = 'UNPAID' THEN '未付款' END + ) AS risk_reasons + +FROM order_risk +ORDER BY delay_probability DESC, deal_amount DESC; diff --git a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/uv.lock b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/uv.lock index c541de4..017ec10 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/uv.lock +++ b/lzwcai_mcpskills_analyzeWorkOrder/lzwcai_mcpskills_analyzeWorkOrder/uv.lock @@ -146,7 +146,7 @@ wheels = [ ] [[package]] -name = "lzwcai-mcp-sqlexecutor" +name = "lzwcai-mcpskills-analyzeWorkOrder" version = "0.1.0" source = { virtual = "." } dependencies = [ diff --git a/lzwcai_mcpskills_analyzeWorkOrder/main.py b/lzwcai_mcpskills_analyzeWorkOrder/main.py index ef71819..5b16dc8 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/main.py +++ b/lzwcai_mcpskills_analyzeWorkOrder/main.py @@ -1,5 +1,5 @@ """ -Entry point for lzwcai-mcp-sqlexecutor +Entry point for lzwcai-mcpskills-analyzeWorkOrder Runs the MCP server for SQL query execution """ import os diff --git a/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml b/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml index 0483906..06bad03 100644 --- a/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml +++ b/lzwcai_mcpskills_analyzeWorkOrder/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "lzwcai-mcpskills-analyzeWorkOrder" -version = "0.1.8" +version = "0.1.12" description = "MCP server for executing business SQL queries with dynamic tool generation" readme = "README.md" requires-python = ">=3.13"