feat(mfg-data-agent): 添加HTML可视化仪表盘和优化项目配置
- 新增6个HTML可视化仪表盘组件用于数据展示 * 人效产值损耗三维模型仪表盘 * 指标趋势分析与拐点预警仪表盘 * 一页式决策简报仪表盘 * 订单延迟预警分析仪表盘 * 供应链风险预警仪表盘 * 工单执行进度与异常节点仪表盘 - 添加VSCode工作区配置文件 - 更新businessQueries.json业务查询配置 - 优化api_client.py API客户端实现 - 更新pyproject.toml项目依赖版本 - 重组SQL查询文件结构 - 删除v2版本冗余文档配置 - 添加v2版本技能清单文档 - 更新日志文件记录
This commit is contained in:
193
lzwcai_mcpskills_mfg_data_agent/sql/人效产值损耗三维模型仪表盘.sql
Normal file
193
lzwcai_mcpskills_mfg_data_agent/sql/人效产值损耗三维模型仪表盘.sql
Normal file
@@ -0,0 +1,193 @@
|
||||
-- =====================================================
|
||||
-- 人效-产值-损耗三维模型仪表盘SQL
|
||||
-- Efficiency-Output-Loss 3D Model Dashboard
|
||||
-- 数据库: PostgreSQL
|
||||
-- 维度: 产品类别(化工/机械/电子)作为部门维度
|
||||
-- =====================================================
|
||||
|
||||
-- 1. 部门级综合仪表盘(主查询)
|
||||
WITH
|
||||
labor_stats AS (
|
||||
SELECT
|
||||
p.product_category AS department,
|
||||
COUNT(DISTINCT lr.worker_name) AS worker_count,
|
||||
SUM(lr.duration_minutes) AS total_work_minutes,
|
||||
SUM(lr.report_qty) AS total_output_qty,
|
||||
COUNT(DISTINCT lr.work_order_number) AS work_order_count
|
||||
FROM fact_labor_report lr
|
||||
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY p.product_category
|
||||
),
|
||||
|
||||
work_order_stats AS (
|
||||
SELECT
|
||||
p.product_category AS department,
|
||||
COUNT(*) AS total_work_orders,
|
||||
SUM(wo.planned_qty) AS total_planned_qty,
|
||||
SUM(wo.completed_qty) AS total_completed_qty,
|
||||
SUM(CASE WHEN wo.status = 'CLOSED' THEN 1 ELSE 0 END) AS closed_orders,
|
||||
SUM(CASE WHEN wo.status = 'STARTED' THEN 1 ELSE 0 END) AS started_orders,
|
||||
SUM(CASE WHEN wo.status = 'OPEN' THEN 1 ELSE 0 END) AS open_orders
|
||||
FROM fact_work_order wo
|
||||
INNER JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY p.product_category
|
||||
),
|
||||
|
||||
quality_stats AS (
|
||||
SELECT
|
||||
p.product_category AS department,
|
||||
SUM(qi.pass_qty) AS total_pass_qty,
|
||||
SUM(qi.fail_qty) AS total_fail_qty,
|
||||
COUNT(*) AS inspection_count
|
||||
FROM fact_quality_inspection qi
|
||||
INNER JOIN dim_product p ON qi.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY p.product_category
|
||||
),
|
||||
|
||||
sales_stats AS (
|
||||
SELECT
|
||||
AVG(deal_amount) AS avg_order_amount,
|
||||
SUM(deal_amount) AS total_sales_amount,
|
||||
COUNT(*) AS order_count
|
||||
FROM fact_sales_order
|
||||
),
|
||||
|
||||
scrap_stats AS (
|
||||
SELECT COUNT(*) AS total_scrap_count
|
||||
FROM fact_scrap
|
||||
)
|
||||
|
||||
SELECT
|
||||
ls.department,
|
||||
|
||||
-- 人效维度
|
||||
ls.worker_count,
|
||||
ROUND(ls.total_work_minutes / 60.0, 2) AS total_work_hours,
|
||||
ls.total_output_qty,
|
||||
ROUND(ls.total_output_qty / NULLIF(ls.worker_count, 0), 2) AS output_per_worker,
|
||||
ROUND(ls.total_output_qty / NULLIF(ls.total_work_minutes / 60.0, 0), 2) AS output_per_hour,
|
||||
ROUND(
|
||||
ls.total_output_qty / NULLIF(ls.worker_count, 0) / NULLIF(ls.total_work_minutes / 60.0 / ls.worker_count, 0),
|
||||
2
|
||||
) AS efficiency_index,
|
||||
|
||||
-- 产值维度
|
||||
ws.total_planned_qty AS planned_qty,
|
||||
ws.total_completed_qty AS completed_qty,
|
||||
ROUND(ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100, 2) AS plan_completion_rate,
|
||||
ROUND(ws.total_completed_qty * ss.avg_order_amount / 100, 2) AS estimated_output_value,
|
||||
ROUND(ws.total_completed_qty * ss.avg_order_amount / 100 / NULLIF(ls.worker_count, 0), 2) AS output_value_per_worker,
|
||||
|
||||
-- 损耗维度
|
||||
qs.total_pass_qty AS qc_pass_qty,
|
||||
qs.total_fail_qty AS qc_fail_qty,
|
||||
ROUND(qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100, 2) AS defect_rate,
|
||||
ROUND((ws.total_planned_qty - ws.total_completed_qty) / NULLIF(ws.total_planned_qty, 0) * 100, 2) AS production_loss_rate,
|
||||
|
||||
-- 综合评分
|
||||
ROUND(
|
||||
(ls.total_output_qty / NULLIF(ls.worker_count, 0) / NULLIF(ls.total_work_minutes / 60.0 / ls.worker_count, 0)) * 0.4 +
|
||||
(ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) * 0.35 +
|
||||
(qs.total_pass_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) * 0.25,
|
||||
2
|
||||
) AS performance_score,
|
||||
|
||||
-- 预警等级
|
||||
CASE
|
||||
WHEN (qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) >= 10
|
||||
OR (ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) < 50
|
||||
THEN 'RED'
|
||||
WHEN (qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) >= 5
|
||||
OR (ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) < 70
|
||||
THEN 'YELLOW'
|
||||
ELSE 'GREEN'
|
||||
END AS warning_level
|
||||
|
||||
FROM labor_stats ls
|
||||
LEFT JOIN work_order_stats ws ON ls.department = ws.department
|
||||
LEFT JOIN quality_stats qs ON ls.department = qs.department
|
||||
CROSS JOIN sales_stats ss
|
||||
CROSS JOIN scrap_stats scr
|
||||
ORDER BY performance_score DESC;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 2. 人员级明细报表
|
||||
-- =====================================================
|
||||
SELECT
|
||||
lr.worker_name,
|
||||
p.product_category AS department,
|
||||
COUNT(DISTINCT lr.work_order_number) AS work_order_count,
|
||||
SUM(lr.duration_minutes) AS total_work_minutes,
|
||||
ROUND(SUM(lr.duration_minutes) / 60.0, 2) AS total_work_hours,
|
||||
SUM(lr.report_qty) AS total_output,
|
||||
ROUND(SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0), 2) AS output_per_hour,
|
||||
RANK() OVER (PARTITION BY p.product_category ORDER BY SUM(lr.report_qty) DESC) AS dept_output_rank
|
||||
FROM fact_labor_report lr
|
||||
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY lr.worker_name, p.product_category
|
||||
ORDER BY p.product_category, total_output DESC;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 3. 月度趋势分析
|
||||
-- =====================================================
|
||||
SELECT
|
||||
TO_CHAR(DATE_TRUNC('month', lr.event_time_utc::timestamp), 'YYYY-MM') AS month,
|
||||
p.product_category AS department,
|
||||
COUNT(DISTINCT lr.worker_name) AS active_worker_count,
|
||||
SUM(lr.duration_minutes) AS total_work_minutes,
|
||||
SUM(lr.report_qty) AS total_output,
|
||||
ROUND(SUM(lr.report_qty) / NULLIF(COUNT(DISTINCT lr.worker_name), 0), 2) AS output_per_worker,
|
||||
ROUND(SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0), 2) AS output_per_hour
|
||||
FROM fact_labor_report lr
|
||||
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY DATE_TRUNC('month', lr.event_time_utc::timestamp), p.product_category
|
||||
ORDER BY month DESC, p.product_category;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 4. 产品级损耗分析
|
||||
-- =====================================================
|
||||
SELECT
|
||||
p.product_category AS department,
|
||||
p.product_name,
|
||||
p.product_code,
|
||||
COALESCE(SUM(qi.pass_qty), 0) AS pass_qty,
|
||||
COALESCE(SUM(qi.fail_qty), 0) AS fail_qty,
|
||||
ROUND(
|
||||
COALESCE(SUM(qi.fail_qty), 0) /
|
||||
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100,
|
||||
2
|
||||
) AS defect_rate,
|
||||
CASE
|
||||
WHEN COALESCE(SUM(qi.fail_qty), 0) /
|
||||
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100 >= 10
|
||||
THEN 'HIGH'
|
||||
WHEN COALESCE(SUM(qi.fail_qty), 0) /
|
||||
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100 >= 5
|
||||
THEN 'MEDIUM'
|
||||
ELSE 'LOW'
|
||||
END AS loss_level
|
||||
FROM dim_product p
|
||||
LEFT JOIN fact_quality_inspection qi ON p.product_id = qi.product_id
|
||||
WHERE p.is_current = 't'
|
||||
GROUP BY p.product_category, p.product_name, p.product_code
|
||||
ORDER BY defect_rate DESC NULLS LAST;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 5. 工单完成率分析
|
||||
-- =====================================================
|
||||
SELECT
|
||||
p.product_category AS department,
|
||||
wo.status,
|
||||
COUNT(*) AS order_count,
|
||||
SUM(wo.planned_qty) AS total_planned,
|
||||
SUM(wo.completed_qty) AS total_completed,
|
||||
ROUND(SUM(wo.completed_qty) / NULLIF(SUM(wo.planned_qty), 0) * 100, 2) AS completion_rate,
|
||||
ROUND(AVG(wo.completed_qty / NULLIF(wo.planned_qty, 0) * 100), 2) AS avg_completion_rate
|
||||
FROM fact_work_order wo
|
||||
INNER JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
|
||||
GROUP BY p.product_category, wo.status
|
||||
ORDER BY p.product_category, wo.status;
|
||||
Reference in New Issue
Block a user