|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
|
|
<!DOCTYPE mapper
|
|
|
|
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
|
|
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
|
|
|
@ -295,21 +295,28 @@
|
|
|
|
|
ORDER BY ppd.real_begin_time DESC, ppi.plan_id DESC
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 在制品跟踪报表 - 高性能优化版本(进一步优化:限制工序统计范围到已过滤订单,避免全表扫描;使用索引友好时间过滤) -->
|
|
|
|
|
<!-- 在制品跟踪报表 - 高性能优化版本(进一步优化:限制工序统计范围到已过滤订单,避免全表扫描) -->
|
|
|
|
|
<select id="wipTrackingReportList" resultType="org.dromara.mes.domain.vo.WipTrackingReportVo">
|
|
|
|
|
WITH Orders AS (
|
|
|
|
|
-- 先根据筛选条件提取订单范围,避免后续工序统计对全库扫描(索引友好)
|
|
|
|
|
SELECT o.product_order_id, o.tenant_id
|
|
|
|
|
FROM prod_order_info o
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = o.material_id
|
|
|
|
|
WITH Plans AS (
|
|
|
|
|
SELECT p.plan_code, p.tenant_id
|
|
|
|
|
FROM (
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_2
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_3
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_4
|
|
|
|
|
) p
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = p.material_id
|
|
|
|
|
WHERE m.del_flag = '0'
|
|
|
|
|
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
|
|
|
|
|
-- 时间范围过滤:避免对列使用函数,保持索引可用
|
|
|
|
|
AND o.plan_begin_time >= CAST(#{map.beginDate} AS DATETIME)
|
|
|
|
|
AND o.plan_begin_time < DATEADD(day, 1, CAST(#{map.endDate} AS DATETIME))
|
|
|
|
|
<if test="map.tenantId != null and map.tenantId != ''">
|
|
|
|
|
AND p.tenant_id = #{map.tenantId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.orderCode != null and map.orderCode != ''">
|
|
|
|
|
AND o.order_code LIKE CONCAT('%', #{map.orderCode}, '%')
|
|
|
|
|
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
|
|
|
|
|
AND p.plan_begin_time >= CAST(#{map.beginDate} AS DATETIME)
|
|
|
|
|
AND p.plan_begin_time < DATEADD(day, 1, CAST(#{map.endDate} AS DATETIME))
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.planCode != null and map.planCode != ''">
|
|
|
|
|
AND p.plan_code LIKE CONCAT('%', #{map.planCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialName != null and map.materialName != ''">
|
|
|
|
|
AND m.material_name LIKE CONCAT('%', #{map.materialName}, '%')
|
|
|
|
|
@ -317,86 +324,99 @@
|
|
|
|
|
<if test="map.materialCode != null and map.materialCode != ''">
|
|
|
|
|
AND m.material_code LIKE CONCAT('%', #{map.materialCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
GROUP BY p.plan_code, p.tenant_id
|
|
|
|
|
),
|
|
|
|
|
ProcessRows AS (
|
|
|
|
|
-- 订单范围内的所有工序计划行(UNION ALL 提升性能)
|
|
|
|
|
SELECT p2.plan_code, p2.tenant_id, p2.process_id, p2.process_order, p2.plan_status,
|
|
|
|
|
p2.plan_amount, p2.complete_amount, pr2.process_name
|
|
|
|
|
FROM prod_plan_info_2 p2
|
|
|
|
|
LEFT JOIN prod_base_process_info pr2 ON pr2.process_id = p2.process_id
|
|
|
|
|
INNER JOIN Plans pl ON pl.plan_code = p2.plan_code AND pl.tenant_id = p2.tenant_id
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
SELECT p3.plan_code, p3.tenant_id, p3.process_id, p3.process_order, p3.plan_status,
|
|
|
|
|
p3.plan_amount, p3.complete_amount, pr3.process_name
|
|
|
|
|
FROM prod_plan_info_3 p3
|
|
|
|
|
LEFT JOIN prod_base_process_info pr3 ON pr3.process_id = p3.process_id
|
|
|
|
|
INNER JOIN Plans pl ON pl.plan_code = p3.plan_code AND pl.tenant_id = p3.tenant_id
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
SELECT p4.plan_code, p4.tenant_id, p4.process_id, p4.process_order, p4.plan_status,
|
|
|
|
|
p4.plan_amount, p4.complete_amount, pr4.process_name
|
|
|
|
|
FROM prod_plan_info_4 p4
|
|
|
|
|
LEFT JOIN prod_base_process_info pr4 ON pr4.process_id = p4.process_id
|
|
|
|
|
INNER JOIN Plans pl ON pl.plan_code = p4.plan_code AND pl.tenant_id = p4.tenant_id
|
|
|
|
|
),
|
|
|
|
|
DistinctProcess AS (
|
|
|
|
|
-- 按计划+工序聚合为唯一工序,避免同一工序多行导致工序数偏大
|
|
|
|
|
SELECT
|
|
|
|
|
plan_code,
|
|
|
|
|
tenant_id,
|
|
|
|
|
process_id,
|
|
|
|
|
MAX(ISNULL(process_order,0)) AS process_order,
|
|
|
|
|
MAX(CASE WHEN plan_status = '3' THEN 1 ELSE 0 END) AS isCompleted,
|
|
|
|
|
MAX(CASE WHEN plan_status = '2' THEN 1 ELSE 0 END) AS isInProgress,
|
|
|
|
|
SUM(ISNULL(plan_amount,0)) AS plan_amount,
|
|
|
|
|
SUM(ISNULL(complete_amount,0)) AS complete_amount,
|
|
|
|
|
MAX(process_name) AS process_name
|
|
|
|
|
FROM ProcessRows
|
|
|
|
|
GROUP BY plan_code, tenant_id, process_id
|
|
|
|
|
),
|
|
|
|
|
ProcessStats AS (
|
|
|
|
|
-- 统计每个订单的工序进度信息,仅统计已过滤的订单范围(UNION ALL 提升性能)
|
|
|
|
|
-- 统计每个订单的工序进度(以唯一工序为单位)
|
|
|
|
|
SELECT
|
|
|
|
|
ap.product_order_id,
|
|
|
|
|
ap.tenant_id,
|
|
|
|
|
dp.plan_code,
|
|
|
|
|
dp.tenant_id,
|
|
|
|
|
COUNT(*) AS totalProcessCount,
|
|
|
|
|
SUM(CASE WHEN ap.plan_status = '3' THEN 1 ELSE 0 END) AS completedProcessCount,
|
|
|
|
|
SUM(CASE WHEN ap.plan_status = '2' THEN 1 ELSE 0 END) AS wipProcessCount,
|
|
|
|
|
MAX(CASE WHEN ap.plan_status = '3' THEN ap.process_order ELSE 0 END) AS maxCompletedOrder,
|
|
|
|
|
-- 在制工序名称(进行中的工序)
|
|
|
|
|
STRING_AGG(CASE WHEN ap.plan_status = '2' THEN ap.process_name END, ',') AS wipProcessNames,
|
|
|
|
|
-- 剩余工序名称(未派工和已派工但未开始的工序)
|
|
|
|
|
STRING_AGG(CASE WHEN ap.plan_status IN ('0','1') THEN ap.process_name END, ',') AS remainingProcessNames,
|
|
|
|
|
-- 在制品数量加权计算
|
|
|
|
|
SUM(CASE WHEN ap.plan_status = '2' THEN ISNULL(ap.plan_amount - ap.complete_amount, 0) * ap.process_order ELSE 0 END) AS wipWeightedSum
|
|
|
|
|
SUM(dp.isCompleted) AS completedProcessCount,
|
|
|
|
|
SUM(dp.isInProgress) AS wipProcessCount,
|
|
|
|
|
MAX(CASE WHEN dp.isCompleted = 1 THEN dp.process_order ELSE 0 END) AS maxCompletedOrder,
|
|
|
|
|
STRING_AGG(CASE WHEN dp.isInProgress = 1 THEN dp.process_name END, ',') AS wipProcessNames,
|
|
|
|
|
STRING_AGG(CASE WHEN dp.isCompleted = 0 AND dp.isInProgress = 0 THEN dp.process_name END, ',') AS remainingProcessNames,
|
|
|
|
|
SUM(CASE WHEN dp.isInProgress = 1 THEN ISNULL(dp.plan_amount - dp.complete_amount, 0) * dp.process_order ELSE 0 END) AS wipWeightedSum
|
|
|
|
|
FROM DistinctProcess dp
|
|
|
|
|
GROUP BY dp.plan_code, dp.tenant_id
|
|
|
|
|
),
|
|
|
|
|
PlanAgg AS (
|
|
|
|
|
-- 按计划聚合计划信息(按 plan_code 维度)
|
|
|
|
|
SELECT
|
|
|
|
|
p.plan_code,
|
|
|
|
|
p.tenant_id,
|
|
|
|
|
MIN(p.plan_begin_time) AS plan_begin_time,
|
|
|
|
|
MIN(p.real_begin_time) AS real_begin_time,
|
|
|
|
|
MAX(p.plan_end_time) AS plan_end_time,
|
|
|
|
|
SUM(ISNULL(p.plan_amount,0)) AS plan_amount,
|
|
|
|
|
SUM(ISNULL(p.complete_amount,0)) AS complete_amount,
|
|
|
|
|
MAX(p.material_id) AS material_id
|
|
|
|
|
FROM (
|
|
|
|
|
-- 半制品工序(prod_plan_info_2)
|
|
|
|
|
SELECT
|
|
|
|
|
p2.product_order_id,
|
|
|
|
|
p2.tenant_id,
|
|
|
|
|
p2.process_id,
|
|
|
|
|
p2.process_order,
|
|
|
|
|
p2.plan_status,
|
|
|
|
|
p2.plan_amount,
|
|
|
|
|
p2.complete_amount,
|
|
|
|
|
pr2.process_name
|
|
|
|
|
FROM prod_plan_info_2 p2
|
|
|
|
|
LEFT JOIN prod_base_process_info pr2 ON pr2.process_id = p2.process_id
|
|
|
|
|
INNER JOIN Orders ord ON ord.product_order_id = p2.product_order_id AND ord.tenant_id = p2.tenant_id
|
|
|
|
|
WHERE p2.product_order_id IS NOT NULL
|
|
|
|
|
|
|
|
|
|
SELECT plan_code, tenant_id, plan_begin_time, real_begin_time, plan_end_time, plan_amount, complete_amount, material_id
|
|
|
|
|
FROM prod_plan_info_2
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
-- 成型工序(prod_plan_info_3)
|
|
|
|
|
SELECT
|
|
|
|
|
p3.product_order_id,
|
|
|
|
|
p3.tenant_id,
|
|
|
|
|
p3.process_id,
|
|
|
|
|
p3.process_order,
|
|
|
|
|
p3.plan_status,
|
|
|
|
|
p3.plan_amount,
|
|
|
|
|
p3.complete_amount,
|
|
|
|
|
pr3.process_name
|
|
|
|
|
FROM prod_plan_info_3 p3
|
|
|
|
|
LEFT JOIN prod_base_process_info pr3 ON pr3.process_id = p3.process_id
|
|
|
|
|
INNER JOIN Orders ord ON ord.product_order_id = p3.product_order_id AND ord.tenant_id = p3.tenant_id
|
|
|
|
|
WHERE p3.product_order_id IS NOT NULL
|
|
|
|
|
|
|
|
|
|
SELECT plan_code, tenant_id, plan_begin_time, real_begin_time, plan_end_time, plan_amount, complete_amount, material_id
|
|
|
|
|
FROM prod_plan_info_3
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
-- 硫化工序(prod_plan_info_4)
|
|
|
|
|
SELECT
|
|
|
|
|
p4.product_order_id,
|
|
|
|
|
p4.tenant_id,
|
|
|
|
|
p4.process_id,
|
|
|
|
|
p4.process_order,
|
|
|
|
|
p4.plan_status,
|
|
|
|
|
p4.plan_amount,
|
|
|
|
|
p4.complete_amount,
|
|
|
|
|
pr4.process_name
|
|
|
|
|
FROM prod_plan_info_4 p4
|
|
|
|
|
LEFT JOIN prod_base_process_info pr4 ON pr4.process_id = p4.process_id
|
|
|
|
|
INNER JOIN Orders ord ON ord.product_order_id = p4.product_order_id AND ord.tenant_id = p4.tenant_id
|
|
|
|
|
WHERE p4.product_order_id IS NOT NULL
|
|
|
|
|
) AS ap
|
|
|
|
|
GROUP BY ap.product_order_id, ap.tenant_id
|
|
|
|
|
SELECT plan_code, tenant_id, plan_begin_time, real_begin_time, plan_end_time, plan_amount, complete_amount, material_id
|
|
|
|
|
FROM prod_plan_info_4
|
|
|
|
|
) p
|
|
|
|
|
INNER JOIN Plans pl ON pl.plan_code = p.plan_code AND pl.tenant_id = p.tenant_id
|
|
|
|
|
GROUP BY p.plan_code, p.tenant_id
|
|
|
|
|
)
|
|
|
|
|
SELECT
|
|
|
|
|
o.product_order_id AS productOrderId,
|
|
|
|
|
o.order_code AS orderCode,
|
|
|
|
|
NULL AS productOrderId,
|
|
|
|
|
'' AS orderCode,
|
|
|
|
|
oa.plan_code AS planCode,
|
|
|
|
|
m.material_code AS materialCode,
|
|
|
|
|
m.material_name AS materialName,
|
|
|
|
|
ISNULL(m.material_spec, '') AS materialSpec,
|
|
|
|
|
CAST(o.plan_amount AS DECIMAL(18,2)) AS planAmount,
|
|
|
|
|
CAST(ISNULL(o.plan_amount,0) - ISNULL(o.complete_amount,0) AS DECIMAL(18,2)) AS wipAmount,
|
|
|
|
|
CAST(ISNULL(o.complete_amount,0) AS DECIMAL(18,2)) AS completeAmount,
|
|
|
|
|
o.plan_begin_time AS planBeginTime,
|
|
|
|
|
o.real_begin_time AS realBeginTime,
|
|
|
|
|
o.plan_end_time AS planEndTime,
|
|
|
|
|
CAST(oa.plan_amount AS DECIMAL(18,2)) AS planAmount,
|
|
|
|
|
CAST(ISNULL(oa.plan_amount,0) - ISNULL(oa.complete_amount,0) AS DECIMAL(18,2)) AS wipAmount,
|
|
|
|
|
CAST(ISNULL(oa.complete_amount,0) AS DECIMAL(18,2)) AS completeAmount,
|
|
|
|
|
oa.plan_begin_time AS planBeginTime,
|
|
|
|
|
oa.real_begin_time AS realBeginTime,
|
|
|
|
|
oa.plan_end_time AS planEndTime,
|
|
|
|
|
GETDATE() AS currentTime,
|
|
|
|
|
CAST(ISNULL(ps.totalProcessCount, 0) AS VARCHAR(10)) + '道' AS totalProcessCount,
|
|
|
|
|
|
|
|
|
|
@ -406,15 +426,15 @@
|
|
|
|
|
CONCAT(
|
|
|
|
|
CAST(
|
|
|
|
|
CASE
|
|
|
|
|
WHEN o.plan_amount > 0
|
|
|
|
|
THEN (CAST(ISNULL(o.complete_amount,0) AS DECIMAL(18,6)) / CAST(o.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
WHEN oa.plan_amount > 0
|
|
|
|
|
THEN (CAST(ISNULL(oa.complete_amount,0) AS DECIMAL(18,6)) / CAST(oa.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
END
|
|
|
|
|
AS DECIMAL(10,2)), '%'
|
|
|
|
|
) AS overallProgress,
|
|
|
|
|
-- 进度状态判断:延期或正常
|
|
|
|
|
CASE
|
|
|
|
|
WHEN o.plan_end_time IS NOT NULL AND GETDATE() > o.plan_end_time AND ISNULL(o.complete_amount,0) < o.plan_amount
|
|
|
|
|
WHEN oa.plan_end_time IS NOT NULL AND GETDATE() > oa.plan_end_time AND ISNULL(oa.complete_amount,0) < oa.plan_amount
|
|
|
|
|
THEN '延期'
|
|
|
|
|
ELSE '正常'
|
|
|
|
|
END AS progressStatus,
|
|
|
|
|
@ -423,58 +443,123 @@
|
|
|
|
|
-- 数值型整体进度(不带百分号)
|
|
|
|
|
CAST(
|
|
|
|
|
CASE
|
|
|
|
|
WHEN o.plan_amount > 0
|
|
|
|
|
THEN (CAST(ISNULL(o.complete_amount,0) AS DECIMAL(18,6)) / CAST(o.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
WHEN oa.plan_amount > 0
|
|
|
|
|
THEN (CAST(ISNULL(oa.complete_amount,0) AS DECIMAL(18,6)) / CAST(oa.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
END
|
|
|
|
|
AS DECIMAL(10,2)) AS overallProgressNum
|
|
|
|
|
FROM prod_order_info o
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = o.material_id
|
|
|
|
|
INNER JOIN Orders ord ON ord.product_order_id = o.product_order_id AND ord.tenant_id = o.tenant_id
|
|
|
|
|
LEFT JOIN ProcessStats ps ON ps.product_order_id = o.product_order_id AND ps.tenant_id = o.tenant_id
|
|
|
|
|
FROM PlanAgg oa
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = oa.material_id
|
|
|
|
|
LEFT JOIN ProcessStats ps ON ps.plan_code = oa.plan_code AND ps.tenant_id = oa.tenant_id
|
|
|
|
|
<where>
|
|
|
|
|
<!-- 进度状态过滤单独保留在最终结果上 -->
|
|
|
|
|
<if test="map.progressStatus != null and map.progressStatus != ''">
|
|
|
|
|
AND CASE
|
|
|
|
|
WHEN o.plan_end_time IS NOT NULL AND GETDATE() > o.plan_end_time AND ISNULL(o.complete_amount,0) < o.plan_amount
|
|
|
|
|
WHEN oa.plan_end_time IS NOT NULL AND GETDATE() > oa.plan_end_time AND ISNULL(oa.complete_amount,0) < oa.plan_amount
|
|
|
|
|
THEN '延期'
|
|
|
|
|
ELSE '正常'
|
|
|
|
|
END = #{map.progressStatus}
|
|
|
|
|
</if>
|
|
|
|
|
</where>
|
|
|
|
|
ORDER BY o.order_code DESC
|
|
|
|
|
-- 为避免首屏仅出现以 'PLAN' 开头的计划编号(字符串排序导致),
|
|
|
|
|
-- 改为按时间优先降序,其次按计划编号升序,确保不同编码规则的计划均能出现在第一页
|
|
|
|
|
ORDER BY oa.plan_begin_time DESC, oa.real_begin_time DESC, oa.plan_code ASC
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 在制品跟踪报表总数(简化版 count):避免复杂 CTE/聚合,保持与筛选条件一致 -->
|
|
|
|
|
<!-- 在制品跟踪报表总数(按工序维度计数):统计筛选范围内存在数据的工序数量 -->
|
|
|
|
|
<select id="wipTrackingReportCount" resultType="java.lang.Long">
|
|
|
|
|
SELECT COUNT(*)
|
|
|
|
|
FROM prod_order_info o
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = o.material_id
|
|
|
|
|
WHERE m.del_flag = '0'
|
|
|
|
|
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
|
|
|
|
|
AND o.plan_begin_time <![CDATA[>=]]> CAST(#{map.beginDate} AS DATETIME)
|
|
|
|
|
AND o.plan_begin_time <![CDATA[<]]> DATEADD(day, 1, CAST(#{map.endDate} AS DATETIME))
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.orderCode != null and map.orderCode != ''">
|
|
|
|
|
AND o.order_code LIKE CONCAT('%', #{map.orderCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialName != null and map.materialName != ''">
|
|
|
|
|
AND m.material_name LIKE CONCAT('%', #{map.materialName}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialCode != null and map.materialCode != ''">
|
|
|
|
|
AND m.material_code LIKE CONCAT('%', #{map.materialCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.progressStatus != null and map.progressStatus != ''">
|
|
|
|
|
AND CASE
|
|
|
|
|
WHEN o.plan_end_time IS NOT NULL AND GETDATE() > o.plan_end_time AND ISNULL(o.complete_amount,0) <![CDATA[<]]> o.plan_amount THEN '延期'
|
|
|
|
|
ELSE '正常'
|
|
|
|
|
END = #{map.progressStatus}
|
|
|
|
|
</if>
|
|
|
|
|
WITH Plans AS (
|
|
|
|
|
SELECT p.plan_code, p.tenant_id
|
|
|
|
|
FROM (
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_2
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_3
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT product_order_id, tenant_id, material_id, plan_begin_time, plan_code FROM prod_plan_info_4
|
|
|
|
|
) p
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = p.material_id
|
|
|
|
|
WHERE m.del_flag = '0'
|
|
|
|
|
<if test="map.tenantId != null and map.tenantId != ''">
|
|
|
|
|
AND p.tenant_id = #{map.tenantId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
|
|
|
|
|
AND p.plan_begin_time <![CDATA[>=]]> CAST(#{map.beginDate} AS DATETIME)
|
|
|
|
|
AND p.plan_begin_time <![CDATA[<]]> DATEADD(day, 1, CAST(#{map.endDate} AS DATETIME))
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.planCode != null and map.planCode != ''">
|
|
|
|
|
AND p.plan_code LIKE CONCAT('%', #{map.planCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialName != null and map.materialName != ''">
|
|
|
|
|
AND m.material_name LIKE CONCAT('%', #{map.materialName}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialCode != null and map.materialCode != ''">
|
|
|
|
|
AND m.material_code LIKE CONCAT('%', #{map.materialCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
GROUP BY p.plan_code, p.tenant_id
|
|
|
|
|
),
|
|
|
|
|
PlanAgg AS (
|
|
|
|
|
-- 计划级聚合(用于进度状态筛选)
|
|
|
|
|
SELECT
|
|
|
|
|
p.plan_code,
|
|
|
|
|
p.tenant_id,
|
|
|
|
|
MAX(p.material_id) AS material_id,
|
|
|
|
|
MAX(p.plan_end_time) AS plan_end_time,
|
|
|
|
|
SUM(ISNULL(p.plan_amount,0)) AS plan_amount,
|
|
|
|
|
SUM(ISNULL(p.complete_amount,0)) AS complete_amount
|
|
|
|
|
FROM (
|
|
|
|
|
SELECT plan_code, tenant_id, plan_end_time, plan_amount, complete_amount, material_id FROM prod_plan_info_2
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT plan_code, tenant_id, plan_end_time, plan_amount, complete_amount, material_id FROM prod_plan_info_3
|
|
|
|
|
UNION ALL
|
|
|
|
|
SELECT plan_code, tenant_id, plan_end_time, plan_amount, complete_amount, material_id FROM prod_plan_info_4
|
|
|
|
|
) p
|
|
|
|
|
INNER JOIN Plans pl ON pl.plan_code = p.plan_code AND pl.tenant_id = p.tenant_id
|
|
|
|
|
GROUP BY p.plan_code, p.tenant_id
|
|
|
|
|
),
|
|
|
|
|
EligiblePlans AS (
|
|
|
|
|
-- 应用进度状态筛选(如有),得到符合条件的计划集合
|
|
|
|
|
SELECT oa.plan_code, oa.tenant_id
|
|
|
|
|
FROM PlanAgg oa
|
|
|
|
|
INNER JOIN base_material_info m ON m.material_id = oa.material_id
|
|
|
|
|
WHERE m.del_flag = '0'
|
|
|
|
|
<if test="map.progressStatus != null and map.progressStatus != ''">
|
|
|
|
|
AND CASE
|
|
|
|
|
WHEN oa.plan_end_time IS NOT NULL AND GETDATE() > oa.plan_end_time AND ISNULL(oa.complete_amount,0) <![CDATA[<]]> oa.plan_amount THEN '延期'
|
|
|
|
|
ELSE '正常'
|
|
|
|
|
END = #{map.progressStatus}
|
|
|
|
|
</if>
|
|
|
|
|
),
|
|
|
|
|
ProcessRows AS (
|
|
|
|
|
-- 订单范围内且符合状态筛选的所有工序行
|
|
|
|
|
SELECT p2.plan_code, p2.tenant_id, p2.process_id, ISNULL(pr2.process_name, N'未知工序') AS process_name
|
|
|
|
|
FROM prod_plan_info_2 p2
|
|
|
|
|
LEFT JOIN prod_base_process_info pr2 ON pr2.process_id = p2.process_id
|
|
|
|
|
INNER JOIN EligiblePlans ep ON ep.plan_code = p2.plan_code AND ep.tenant_id = p2.tenant_id
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
SELECT p3.plan_code, p3.tenant_id, p3.process_id, ISNULL(pr3.process_name, N'未知工序') AS process_name
|
|
|
|
|
FROM prod_plan_info_3 p3
|
|
|
|
|
LEFT JOIN prod_base_process_info pr3 ON pr3.process_id = p3.process_id
|
|
|
|
|
INNER JOIN EligiblePlans ep ON ep.plan_code = p3.plan_code AND ep.tenant_id = p3.tenant_id
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
SELECT p4.plan_code, p4.tenant_id, p4.process_id, ISNULL(pr4.process_name, N'未知工序') AS process_name
|
|
|
|
|
FROM prod_plan_info_4 p4
|
|
|
|
|
LEFT JOIN prod_base_process_info pr4 ON pr4.process_id = p4.process_id
|
|
|
|
|
INNER JOIN EligiblePlans ep ON ep.plan_code = p4.plan_code AND ep.tenant_id = p4.tenant_id
|
|
|
|
|
)
|
|
|
|
|
SELECT COUNT(DISTINCT process_name)
|
|
|
|
|
FROM ProcessRows
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 获取订单的工序进度详情 - 高性能优化版本(保留单订单查询,不返回productOrderId以兼容旧用法) -->
|
|
|
|
|
<select id="getOrderProcessProgress" resultType="org.dromara.mes.domain.vo.ProcessProgressVo">
|
|
|
|
|
<!-- (已清理)订单维度的工序进度查询已移除,统一按 plan_code 维度处理 -->
|
|
|
|
|
|
|
|
|
|
<!-- 获取计划的工序进度详情(按planCode单条) -->
|
|
|
|
|
<select id="getPlanProcessProgress" resultType="org.dromara.mes.domain.vo.ProcessProgressVo">
|
|
|
|
|
SELECT
|
|
|
|
|
p.plan_code AS planCode,
|
|
|
|
|
p.process_id AS processId,
|
|
|
|
|
ISNULL(pr.process_name, '未知工序') AS processName,
|
|
|
|
|
ISNULL(p.process_order, 0) AS processOrder,
|
|
|
|
|
@ -491,34 +576,29 @@
|
|
|
|
|
CAST(ISNULL(p.plan_amount, 0) AS DECIMAL(18,2)) AS planAmount,
|
|
|
|
|
CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,2)) AS completeAmount,
|
|
|
|
|
CAST(ISNULL(p.plan_amount, 0) - ISNULL(p.complete_amount, 0) AS DECIMAL(18,2)) AS remainingAmount,
|
|
|
|
|
-- 工序进度百分比
|
|
|
|
|
CAST(
|
|
|
|
|
CASE
|
|
|
|
|
WHEN ISNULL(p.plan_amount, 0) > 0
|
|
|
|
|
THEN (CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,6)) / CAST(p.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
CASE WHEN ISNULL(p.plan_amount, 0) > 0
|
|
|
|
|
THEN (CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,6)) / CAST(p.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
END
|
|
|
|
|
AS DECIMAL(10,2)) AS processProgress,
|
|
|
|
|
-- 计划开始时间和结束时间
|
|
|
|
|
p.plan_begin_time AS planBeginTime,
|
|
|
|
|
p.plan_end_time AS planEndTime,
|
|
|
|
|
p.real_begin_time AS realBeginTime,
|
|
|
|
|
p.real_end_time AS realEndTime
|
|
|
|
|
p.real_end_time AS realEndTime,
|
|
|
|
|
bmi.material_name AS materialName,
|
|
|
|
|
bmi.material_code AS materialCode
|
|
|
|
|
FROM ${planTableName} p
|
|
|
|
|
LEFT JOIN prod_base_process_info pr ON pr.process_id = p.process_id
|
|
|
|
|
WHERE p.product_order_id = #{productOrderId}
|
|
|
|
|
LEFT JOIN base_material_info bmi ON bmi.material_id = p.material_id
|
|
|
|
|
WHERE p.plan_code = #{planCode}
|
|
|
|
|
ORDER BY p.process_order
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 批量获取订单的工序进度详情(避免N+1,一次查询一个工序表) -->
|
|
|
|
|
<!-- 说明:
|
|
|
|
|
1. 通过 IN 子句一次性查询多个订单的工序进度,显著减少数据库往返,提高性能;
|
|
|
|
|
2. 返回 product_order_id 字段用于在服务层进行分组映射;
|
|
|
|
|
3. 该SQL按订单ID与工序顺序排序,便于后续按工序顺序展示;
|
|
|
|
|
-->
|
|
|
|
|
<select id="getOrdersProcessProgressBatch" resultType="org.dromara.mes.domain.vo.ProcessProgressVo">
|
|
|
|
|
<!-- 批量获取计划的工序进度详情(按planCode批量) -->
|
|
|
|
|
<select id="getPlansProcessProgressBatch" resultType="org.dromara.mes.domain.vo.ProcessProgressVo">
|
|
|
|
|
SELECT
|
|
|
|
|
p.product_order_id AS productOrderId,
|
|
|
|
|
p.plan_code AS planCode,
|
|
|
|
|
p.process_id AS processId,
|
|
|
|
|
ISNULL(pr.process_name, '未知工序') AS processName,
|
|
|
|
|
ISNULL(p.process_order, 0) AS processOrder,
|
|
|
|
|
@ -536,24 +616,49 @@
|
|
|
|
|
CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,2)) AS completeAmount,
|
|
|
|
|
CAST(ISNULL(p.plan_amount, 0) - ISNULL(p.complete_amount, 0) AS DECIMAL(18,2)) AS remainingAmount,
|
|
|
|
|
CAST(
|
|
|
|
|
CASE
|
|
|
|
|
WHEN ISNULL(p.plan_amount, 0) > 0
|
|
|
|
|
THEN (CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,6)) / CAST(p.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
CASE WHEN ISNULL(p.plan_amount, 0) > 0
|
|
|
|
|
THEN (CAST(ISNULL(p.complete_amount, 0) AS DECIMAL(18,6)) / CAST(p.plan_amount AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0
|
|
|
|
|
END
|
|
|
|
|
AS DECIMAL(10,2)) AS processProgress,
|
|
|
|
|
p.plan_begin_time AS planBeginTime,
|
|
|
|
|
p.plan_end_time AS planEndTime,
|
|
|
|
|
p.real_begin_time AS realBeginTime,
|
|
|
|
|
p.real_end_time AS realEndTime
|
|
|
|
|
p.real_end_time AS realEndTime,
|
|
|
|
|
bmi.material_name AS materialName,
|
|
|
|
|
bmi.material_code AS materialCode
|
|
|
|
|
FROM ${planTableName} p
|
|
|
|
|
LEFT JOIN prod_base_process_info pr ON pr.process_id = p.process_id
|
|
|
|
|
WHERE p.product_order_id IN
|
|
|
|
|
<foreach collection="productOrderIds" item="id" open="(" separator="," close=")">
|
|
|
|
|
#{id}
|
|
|
|
|
LEFT JOIN base_material_info bmi ON bmi.material_id = p.material_id
|
|
|
|
|
WHERE p.plan_code IN
|
|
|
|
|
<foreach collection="planCodes" item="code" open="(" separator="," close=")">
|
|
|
|
|
#{code}
|
|
|
|
|
</foreach>
|
|
|
|
|
<if test="tenantId != null"> AND p.tenant_id = #{tenantId} </if>
|
|
|
|
|
ORDER BY p.product_order_id, p.process_order
|
|
|
|
|
ORDER BY p.plan_code, p.process_order
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 工序下的计划子节点查询:按 plan_code + process_id 过滤,计划级视图(不关联明细表) -->
|
|
|
|
|
<select id="getPlanProcessDetailChildren" resultType="java.util.HashMap">
|
|
|
|
|
SELECT
|
|
|
|
|
ppi.plan_id AS planId,
|
|
|
|
|
ppi.plan_code AS planCode,
|
|
|
|
|
ppi.process_id AS processId,
|
|
|
|
|
ppi.process_order AS processOrder,
|
|
|
|
|
ISNULL(ppi.plan_amount, 0) AS planAmount,
|
|
|
|
|
ISNULL(ppi.complete_amount, 0) AS completeAmount,
|
|
|
|
|
ppi.real_begin_time AS realBeginTime,
|
|
|
|
|
ppi.real_end_time AS realEndTime,
|
|
|
|
|
ISNULL(bct.team_name, '') AS teamName,
|
|
|
|
|
ISNULL(pbsi.station_name, '') AS stationName,
|
|
|
|
|
ISNULL(ppi.plan_status, '0') AS planStatus
|
|
|
|
|
FROM ${planTableName} ppi
|
|
|
|
|
LEFT JOIN base_class_team_info bct ON bct.class_team_id = ppi.class_team_id
|
|
|
|
|
LEFT JOIN prod_base_station_info pbsi ON pbsi.station_id = bct.station_id
|
|
|
|
|
WHERE ppi.plan_code = #{planCode}
|
|
|
|
|
<if test="processId != null"> AND ppi.process_id = #{processId} </if>
|
|
|
|
|
<if test="tenantId != null"> AND ppi.tenant_id = #{tenantId} </if>
|
|
|
|
|
ORDER BY ppi.real_begin_time, ppi.plan_id
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -597,4 +702,59 @@
|
|
|
|
|
ORDER BY productionDate, DATEPART(HOUR, t.create_time)
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<!-- 工序生产统计(按工序聚合):完成数量、未完成数量与完成率 -->
|
|
|
|
|
<select id="processWorkOrderStats" resultType="java.util.HashMap">
|
|
|
|
|
<![CDATA[
|
|
|
|
|
SELECT
|
|
|
|
|
ISNULL(pproc.process_name, N'未知工序') AS processName,
|
|
|
|
|
-- 汇总计划与完成数量
|
|
|
|
|
CAST(SUM(ISNULL(p.plan_amount, 0)) AS DECIMAL(18,4)) AS planQty,
|
|
|
|
|
CAST(SUM(ISNULL(p.complete_amount, 0)) AS DECIMAL(18,4)) AS completedQty,
|
|
|
|
|
CAST(SUM(ISNULL(p.plan_amount, 0) - ISNULL(p.complete_amount, 0)) AS DECIMAL(18,4)) AS uncompletedQty,
|
|
|
|
|
-- 完成率(数值 & 展示)
|
|
|
|
|
CAST(
|
|
|
|
|
CASE WHEN SUM(ISNULL(p.plan_amount, 0)) > 0
|
|
|
|
|
THEN (CAST(SUM(ISNULL(p.complete_amount, 0)) AS DECIMAL(18,6)) / CAST(SUM(ISNULL(p.plan_amount, 0)) AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0 END
|
|
|
|
|
AS DECIMAL(10,2)) AS completionRateNum,
|
|
|
|
|
CONCAT(
|
|
|
|
|
CAST(
|
|
|
|
|
CASE WHEN SUM(ISNULL(p.plan_amount, 0)) > 0
|
|
|
|
|
THEN (CAST(SUM(ISNULL(p.complete_amount, 0)) AS DECIMAL(18,6)) / CAST(SUM(ISNULL(p.plan_amount, 0)) AS DECIMAL(18,6))) * 100
|
|
|
|
|
ELSE 0 END
|
|
|
|
|
AS DECIMAL(10,2)
|
|
|
|
|
), '%') AS completionRate
|
|
|
|
|
FROM ${planTableName} AS p
|
|
|
|
|
LEFT JOIN prod_base_process_info AS pproc ON pproc.process_id = p.process_id
|
|
|
|
|
LEFT JOIN base_material_info AS bmi ON bmi.material_id = p.material_id
|
|
|
|
|
]]>
|
|
|
|
|
<where>
|
|
|
|
|
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
|
|
|
|
|
AND FORMAT(p.plan_begin_time, 'yyyy-MM-dd') BETWEEN #{map.beginDate} AND #{map.endDate}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.processId != null and map.processId != ''">
|
|
|
|
|
AND p.process_id = #{map.processId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.machineId != null and map.machineId != ''">
|
|
|
|
|
AND p.release_id = #{map.machineId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.shiftId != null and map.shiftId != ''">
|
|
|
|
|
AND p.shift_id = #{map.shiftId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.classTeamId != null and map.classTeamId != ''">
|
|
|
|
|
AND p.class_team_id = #{map.classTeamId}
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.planCode != null and map.planCode != ''">
|
|
|
|
|
AND p.plan_code LIKE CONCAT('%', #{map.planCode}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
<if test="map.materialName != null and map.materialName != ''">
|
|
|
|
|
AND bmi.material_name LIKE CONCAT('%', #{map.materialName}, '%')
|
|
|
|
|
</if>
|
|
|
|
|
</where>
|
|
|
|
|
<![CDATA[
|
|
|
|
|
GROUP BY ISNULL(pproc.process_name, N'未知工序')
|
|
|
|
|
ORDER BY completionRateNum DESC, processName
|
|
|
|
|
]]>
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
</mapper>
|
|
|
|
|
|