feat(mixTrace): 优化混料追溯报表数据查询逻辑

- 简化实际重量计算逻辑,移除复杂的CASE WHEN条件判断
- 新增时间段内所有工步列表查询功能,支持曲线生成需求
- 实现混料步骤数据的完整时间线展示
- 添加设备、材料、配方等相关信息的关联查询
- 优化SQL性能,减少不必要的子查询和条件判断
- 支持按多种条件筛选混料步骤数据
master
zangch@mesnac.com 2 days ago
parent 534cc43806
commit 7ef0866057

@ -86,6 +86,12 @@ public class ProdMixTraceReportController extends BaseController {
return R.ok(mixTraceReportService.calculateSpcXbarR(normalizeParams(params)));
}
/** 按时间段获取最新一条曲线(仅曲线数据) */
@GetMapping("/curve/latest")
public R<MixTraceDetailVo> latestCurve(@RequestParam(required = false) Map<String, Object> params) {
return R.ok(mixTraceReportService.queryLatestCurve(normalizeParams(params)));
}
private Map<String, Object> normalizeParams(Map<String, Object> params) {
return params == null ? Collections.emptyMap() : params;
}

@ -79,4 +79,6 @@ public interface ProdMixTraceReportMapper {
*/
List<MixTraceSpcSampleVo> selectSpcSamples(@Param("map") Map<String, Object> params);
/** 按时间段获取最新一条记录的工步列表(用于曲线) */
List<MixTraceStepVo> selectLatestStepList(@Param("map") Map<String, Object> params);
}

@ -52,4 +52,9 @@ public interface IProdMixTraceReportService {
* SPC - 10Xbar-R
*/
MixTraceSpcResultVo calculateSpcXbarR(Map<String, Object> params);
/**
* 线线
*/
MixTraceDetailVo queryLatestCurve(Map<String, Object> params);
}

@ -720,4 +720,19 @@ public class ProdMixTraceReportServiceImpl implements IProdMixTraceReportService
tree.add(root);
return tree;
}
@Override
public MixTraceDetailVo queryLatestCurve(Map<String, Object> params) {
// 只关注曲线所需的工步数据,其他列表返回空集合以避免前端 NPE
List<MixTraceStepVo> steps = mixTraceReportMapper.selectLatestStepList(params);
MixTraceDetailVo detail = new MixTraceDetailVo();
detail.setMixingStepList(steps == null ? new ArrayList<>() : steps);
detail.setCurveSeries(buildCurveSeries(steps));
detail.setUsageList(new ArrayList<>());
detail.setBatchList(new ArrayList<>());
detail.setMaterialTraceTree(new ArrayList<>());
detail.setMixingList(new ArrayList<>());
detail.setWeightList(new ArrayList<>());
return detail;
}
}

@ -618,27 +618,7 @@
SELECT
CAST(9 AS INT) AS matchPriority,
CAST(
CASE
WHEN ISNULL(SUM(CASE WHEN t.materiel_id = w.child_code THEN 1 ELSE 0 END), 0) = 0
AND ISNULL(SUM(CASE
WHEN w.father_code IS NOT NULL
AND w.father_code &lt;&gt; w.child_code
AND t.materiel_id = w.father_code THEN 1
ELSE 0
END), 0) = 0
THEN NULL
ELSE
ISNULL(SUM(CASE WHEN t.materiel_id = w.child_code THEN ISNULL(t.used_amount, 0) ELSE 0 END), 0)
+ ISNULL(SUM(CASE
WHEN w.father_code IS NOT NULL
AND w.father_code &lt;&gt; w.child_code
AND t.materiel_id = w.father_code
THEN ISNULL(t.used_amount, 0)
ELSE 0
END), 0)
END
AS DECIMAL(18, 4)) AS actualWeight,
CAST(CASE WHEN COUNT(1) = 0 THEN NULL ELSE SUM(ISNULL(t.used_amount, 0)) END AS DECIMAL(18, 4)) AS actualWeight,
MAX(t.plan_detail_id) AS tracePlanDetailId,
MAX(t.recipe_id) AS traceRecipeId,
MAX(t.weight_seq) AS traceWeightSeq,
@ -755,6 +735,110 @@
ORDER BY m.mix_id ASC
</select>
<!-- 时间段内所有工步列表,用于生成曲线(不再只取最新一条) -->
<select id="selectLatestStepList" resultType="org.dromara.mes.domain.vo.MixTraceStepVo">
<include refid="routerMasterDataCte"/>
SELECT
ri.recipe_id AS recipeId,
ri.recipe_code AS recipeCode,
ri.machine_id AS machineId,
bm.machine_name AS machineName,
ri.material_id AS materialId,
bmi.material_name AS materialName,
tp.trainNumber AS trainNumber,
COALESCE(tp.planRealBeginTime, tp.detailRealBeginTime, ri.create_time) AS realBeginTime,
COALESCE(tp.planRealEndTime, tp.detailRealEndTime, ri.create_time) AS realEndTime,
m.mixing_id AS mixingId,
m.mix_id AS mixId,
SUM(ISNULL(m.mixing_time, 0)) OVER (PARTITION BY ri.recipe_id ORDER BY m.mix_id ROWS UNBOUNDED PRECEDING) AS timelineSecond,
RTRIM(LTRIM(COALESCE(m.term_code, ''))) AS termCode,
CASE
WHEN term_detail.data_detail_name IS NULL OR LTRIM(RTRIM(term_detail.data_detail_name)) = '' THEN RTRIM(LTRIM(COALESCE(m.term_code, '')))
ELSE RTRIM(LTRIM(term_detail.data_detail_name))
END AS termName,
RTRIM(LTRIM(COALESCE(m.cond_code, ''))) AS condCode,
CASE
WHEN cond_detail.data_detail_name IS NULL OR LTRIM(RTRIM(cond_detail.data_detail_name)) = '' THEN RTRIM(LTRIM(COALESCE(m.cond_code, '')))
ELSE RTRIM(LTRIM(cond_detail.data_detail_name))
END AS condName,
RTRIM(LTRIM(COALESCE(m.act_code, ''))) AS actCode,
CASE
WHEN act_detail.data_detail_name IS NULL OR LTRIM(RTRIM(act_detail.data_detail_name)) = '' THEN RTRIM(LTRIM(COALESCE(m.act_code, '')))
ELSE RTRIM(LTRIM(act_detail.data_detail_name))
END AS actName,
m.mixing_time AS mixingTime,
m.mixing_temp AS mixingTemp,
m.mixing_energy AS mixingEnergy,
m.mixing_power AS mixingPower,
m.mixing_press AS mixingPress,
m.mixing_speed AS mixingSpeed,
m.set_time AS setTime,
m.set_temp AS setTemp,
m.set_energy AS setEnergy,
m.set_power AS setPower,
m.set_pres AS setPres,
m.set_rota AS setRota
FROM prod_recipe_info ri
LEFT JOIN prod_base_machine_info bm ON bm.machine_id = ri.machine_id
LEFT JOIN base_material_info bmi ON bmi.material_id = ri.material_id
OUTER APPLY (
<include refid="tracePickApply"/>
) tp
JOIN prod_recipe_mixing m ON m.recipe_id = ri.recipe_id AND m.del_flag = '0'
CROSS JOIN router_master_data rmd
OUTER APPLY (
SELECT TOP 1 d.data_detail_name
FROM sys_master_data_detail d
WHERE d.del_flag = '0'
AND d.active_flag = '1'
AND d.master_data_id = rmd.term_master_data_id
AND RTRIM(LTRIM(COALESCE(d.data_detail_code, ''))) = RTRIM(LTRIM(COALESCE(m.term_code, '')))
ORDER BY d.master_data_detail_id DESC
) term_detail
OUTER APPLY (
SELECT TOP 1 d.data_detail_name
FROM sys_master_data_detail d
WHERE d.del_flag = '0'
AND d.active_flag = '1'
AND d.master_data_id = rmd.term_master_data_id
AND RTRIM(LTRIM(COALESCE(d.data_detail_code, ''))) = RTRIM(LTRIM(COALESCE(m.cond_code, '')))
ORDER BY d.master_data_detail_id DESC
) cond_detail
OUTER APPLY (
SELECT TOP 1 d.data_detail_name
FROM sys_master_data_detail d
WHERE d.del_flag = '0'
AND d.active_flag = '1'
AND d.master_data_id = rmd.act_master_data_id
AND RTRIM(LTRIM(COALESCE(d.data_detail_code, ''))) = RTRIM(LTRIM(COALESCE(m.act_code, '')))
ORDER BY d.master_data_detail_id DESC
) act_detail
WHERE ri.del_flag = '0'
<if test="map.machineId != null and map.machineId != ''">
AND ri.machine_id = #{map.machineId}
</if>
<if test="map.machineName != null and map.machineName != ''">
AND bm.machine_name LIKE CONCAT('%', #{map.machineName}, '%')
</if>
<if test="map.recipeId != null and map.recipeId != ''">
AND ri.recipe_id = #{map.recipeId}
</if>
<if test="map.recipeCode != null and map.recipeCode != ''">
AND ri.recipe_code LIKE CONCAT('%', #{map.recipeCode}, '%')
</if>
<if test="map.materialId != null and map.materialId != ''">
AND ri.material_id = #{map.materialId}
</if>
<if test="map.materialName != null and map.materialName != ''">
AND bmi.material_name LIKE CONCAT('%', #{map.materialName}, '%')
</if>
<if test="map.beginDate != null and map.beginDate != '' and map.endDate != null and map.endDate != ''">
AND ri.create_time &gt;= CAST(CONCAT(#{map.beginDate}, ' 00:00:00') AS DATETIME)
AND ri.create_time &lt; DATEADD(DAY, 1, CAST(#{map.endDate} AS DATE))
</if>
ORDER BY COALESCE(tp.planRealBeginTime, tp.detailRealBeginTime, ri.create_time) DESC, ri.create_time DESC, m.mix_id ASC
</select>
<!-- trace detail step list -->
<select id="selectTraceStepList" resultType="org.dromara.mes.domain.vo.MixTraceStepVo">
<include refid="routerMasterDataCte"/>

Loading…
Cancel
Save