SCTMES_V5/mes_in_sct/app/event/SetTrayProcessResultEvent.php
2025-06-14 18:55:09 +08:00

453 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\event;
use libs\db\Db;
use libs\listener\Event;
use Exception;
class SetTrayProcessResultEvent extends Event
{
/**
* 计算温度补偿值并返回
* @param $data
* @return string[]
* @throws \Exception
*/
public function getTemperatureSupp($data)
{
list($param, $flow_id, $process_id) = [$data['param'], $data['flow_id'], $data['process_id']];
// 判断是否存在温度数组TEMPERATURE
if (isset($param['TEMPERATURE'])) {
// 查询是否配置了温度补偿数据
$sql = sprintf(
"SELECT result_param_code
FROM hf_mes_technology_process_temperature
WHERE process_id=%s GROUP BY result_param_code;",
$process_id
);
$ret = Db::query($sql);
if (!empty($ret)) {
// 保留充放电原始容量参数
foreach ($param as $k => $v) {
$string = $k;
$pattern = '/ENDC(\d)(\d)/';
$replacement = 'ORCA$1$2';
$replace_string = preg_replace($pattern, $replacement, $string);
if ($replace_string != NULL && $replace_string != $k) {
$param[$replace_string] = $v;
}
}
// 查找对应的温度补偿result_param
foreach ($param as $k => $v) {
foreach ($ret as $v1) {
// 查找配置的工步key等于结果参数的工步key
if ($v1['result_param_code'] == $k) {
// 判断工步数组与TEMPERATURE的长度是否一致
if (count($v) == count($param['TEMPERATURE'])) {
// 获取对应的工序key的温度补偿配置数据
$sql = sprintf(
"SELECT result_param_code,temperature,compensation_value
FROM hf_mes_technology_process_temperature
WHERE process_id=%s AND result_param_code='%s' ORDER BY temperature ASC;",
$process_id,
$k
);
$temp_ret = Db::query($sql);
for ($j = 0; $j < count($v); $j++) {
// 进行温度补偿修正
$value = floatval($v[$j]);
$temperature = floatval($param['TEMPERATURE'][$j]);
$closest = null;
foreach ($temp_ret as $item) {
if ($closest === null || abs($temperature - floatval($closest['temperature'])) > abs(floatval($item['temperature']) - $temperature)) {
$closest = $item;
}
}
$param[$k][$j] = $value * floatval($closest['compensation_value']);
}
}
}
}
}
}
}
return $param;
}
/**
* 验证pin_check数据
* @param $data
* @return bool
* @throws Exception
*/
public function verifyPinCheck($data)
{
list($param, $battery_ids) = [$data['param'], $data['battery_ids']];
if (!isset($param['pin_check'])) {
throw new Exception('上传的结果参数中不存在[pin_check]结果数据,请检查![pin_check]');
}
if (!is_array($param['pin_check'])) {
throw new Exception('上传的结果参数[pin_check]不是数组类型,请检查![pin_check]');
}
if (count($param['pin_check']) != count($battery_ids)) {
$count = count($battery_ids);
throw new Exception("上传的结果参数[pin_check]的数组长度与电池数量不相等,电池数量为:[{$count}],请检查![pin_check]");
}
if (!is_array($param['NG'])) {
throw new Exception('上传的结果参数中不存在[NG]结果数据,请检查![pin_check]');
}
if (!is_array($param['NG'])) {
throw new Exception('上传的结果参数[NG]不是数组类型,请检查![pin_check]');
}
if (count($param['NG']) != count($battery_ids)) {
$count = count($battery_ids);
throw new Exception("上传的结果参数[NG]的数组长度与电池数量不相等,电池数量为:[{$count}],请检查![pin_check]");
}
$pin_ckeck_arr = $param['pin_check'];
foreach ($pin_ckeck_arr as $index => $item) {
if (!is_int($item)) {
$index = $index + 1;
throw new Exception("上传的结果参数[pin_check]的数组位置[{$index}]的数值不是整数类型,类型要求例子:[0,1]");
}
if (!in_array($item, [0, 1])) {
$index = $index + 1;
throw new Exception("上传的结果参数[pin_check]的数组位置[{$index}]的数值不是整数0或者1类型要求例子:[0]或者[1]");
}
// 验证NG数据
if (!is_numeric($param['NG'][$index])) {
$index = $index + 1;
throw new Exception("上传的结果参数[NG]的数组位置[{$index}]的数值整型的字符串类型,类型要求例子:['0','1'],其中如果没有异常码,默认值为['0']");
}
// 验证pin_check等于1时对应的NG位置必须上传异常码
if ($item == 1) {
if (empty($param['NG'][$index])) {
throw new Exception("当[pin_check]结果参数数组位置[{$index}]的值为[1]时,对应上传的结果参数[NG]的数组位置[{$index}]必须上传通道异常码");
}
}
}
return true;
}
/**
* 写入pin_ckeck队列缓存数据
* @param $data
* @return bool
* @throws Exception
*/
public function setPincheckQueue($data)
{
list($param, $device_code, $batch, $subbatch, $tray, $lot) = [
$data['param'],
$data['device_code'],
$data['batch'],
$data['subbatch'],
$data['tray'],
$data['lot'],
];
// 判断是否存在pin_ckeck的数据
$pin_ckeck = $param['pin_check'];
// 判断pin_ckeck是否存在等于1数据
$filteredArray = array_filter($pin_ckeck, function ($value) {
return $value === 1;
});
if (!empty($filteredArray)) {
// 写入队列缓存数据(status=0为未处理数据)
$row = Db::insert('hf_mes_queue_pincheck', [
'device_code' => $device_code,
'batch' => $batch,
'subbatch' => $subbatch,
'tray' => $tray,
'lot' => $lot,
'param' => json_encode($param, JSON_UNESCAPED_UNICODE),
'status' => 0,
'create_time' => date('Y-m-d H:i:s')
]);
if ($row === NULL) {
throw new Exception('写入[pin_check]队列数据失败');
}
}
return true;
}
/**
* 写入曲线队列缓存数据
* @param $data
* @return bool
* @throws Exception
*/
public function setCurveQueue($data)
{
list($param, $device_code, $batch, $subbatch, $tray, $lot, $process_code, $battery_ids) = [
$data['param'],
$data['device_code'],
$data['batch'],
$data['subbatch'],
$data['tray'],
$data['lot'],
$data['process_code'],
$data['battery_ids']
];
$end_time = $param['end_time'];
$workingsubclass = $param['workingsubclass'];
try {
// 写入队列缓存数据(status=0为未处理数据)
$row = Db::insert('hf_mes_queue_curve', [
'device_code' => $device_code,
'batch' => $batch,
'subbatch' => $subbatch,
'tray' => $tray,
'lot' => $lot,
'param' => json_encode($param, JSON_UNESCAPED_UNICODE),
'status' => 0,
'end_time' => $end_time,
'create_time' => date(format: 'Y-m-d H:i:s')
]);
if ($row === NULL) {
throw new Exception('写入曲线队列数据失败!');
}
// 获取batch和电池ID
if (in_array($workingsubclass, ['IC', 'YC', 'PRESSURE_FORMATION', 'HC'])) {
$insert_curve_data = [];
$insert_curve_key = sprintf("INSERT INTO hf_mes_production_curve_data_path (batch,subbatch,workingsubclass,process_code,channel,battery_id,device_code,end_time,tray,lot,create_time,curve_path) VALUES ");
foreach ($battery_ids as $index => $val) {
// 跳过无效条码
if (in_array($val, ["0", 0, "", null], true)) {
continue;
}
$channel = $index + 1;
$insert_curve_data[] = sprintf(
"('%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s')",
$batch,
$subbatch,
$workingsubclass,
$process_code,
$channel,
$val,
$device_code,
$end_time,
$tray,
$lot,
date("Y-m-d H:i:s"),
"/hf-data/" . $subbatch . '/' . $process_code . '/' . $device_code . '/' . $end_time
);
}
if (!empty($insert_curve_data)) {
//插入曲线表
$sql = $insert_curve_key . implode(',', $insert_curve_data);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("电池曲线信息写入失败!");
}
} else {
throw new Exception("构造插入hf_mes_production_curve_data_path表数据库语句失败");
}
}
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
return true;
}
/**
* 直接写入分档信息
* @param $data
* @return bool
* @throws Exception
*/
public function setGradingQueue($data)
{
list($param, $batch, $subbatch, $tray, $lot, $process_code) = [
$data['param'],
$data['batch'],
$data['subbatch'],
$data['tray'],
$data['lot'],
$data['process_code']
];
try {
//直接更新bkv 表的分档信息
$sql = "SELECT
a.id AS id,
a.tray AS tray,
a.batch AS batch,
a.lot AS lot,
a.process_idx AS process_idx,
a.next_process_code AS next_process_code,
b.flow_id AS flow_id,
b2.setting AS setting,
json_agg(
json_build_object(
'param', d.code,
'name', d.name,
'note', d.remark,
'ng', d.remark,
'class', d.field_type,
'is_need', d.is_upload
)
) AS result_param
FROM hf_mes_production_tray_map a
INNER JOIN hf_mes_technology_process b ON a.next_process_code = b.code
INNER JOIN hf_mes_process_workingsubclass c ON b.workingsubclass_id = c.id
LEFT JOIN hf_mes_technology_process_result_param d ON d.process_id = b.id
LEFT JOIN hf_mes_technology_process b2 ON b2.code = (b.flow_id || '_SELECTION')
WHERE
a.active = 1
AND a.next_process_code != '-1'
AND a.next_process_code IS NOT NULL
AND a.tray = '$tray'
AND a.lot = '$lot'
AND a.subbatch = '$subbatch'
AND a.batch = '$batch'
GROUP BY
a.id, a.tray, a.batch, a.lot, a.process_idx, a.next_process_code,
b.flow_id, b2.setting;";
$ret = Db::query($sql);
if (count($ret) > 0) {
//进行分选和NG逻辑处理
for ($i = 0; $i < count($ret); $i++) {
//单个托盘处理
$process_code = $ret[$i]['next_process_code'];
$setting = json_decode($ret[$i]['setting']);
if (!isset($setting->process)) {
break;
}
$o = $setting->process;
$o_result_param = $setting->result_param;
foreach ($o as $item) {
// 将对象转为数组以获取 key 和 value
$arr = (array) $item;
foreach ($arr as $key => $val) {
// 替换 ' :' 为 '.'(注意:这里只是你可能用于 WHERE 子句的字段名或条件的一部分)
$val = str_replace(' :', '.', $val);
// 判断值非空
if (!empty($val)) {
$class = '';
// 查找匹配 param 的 ng 值
foreach ($o_result_param as $result_elem) {
if ($result_elem->param == $key) {
$class = $result_elem->ng;
break;
}
}
try {
if (!empty($class)) {
// SQL 条件安全性未验证,假设 $val 是类似 "some_field = 'some_value'" 的条件语句
$sql = "UPDATE \"hf_mes_tmp_bkv_{$subbatch}\"
SET classname = '{$key}',
class = '{$class}'
WHERE ({$val})
AND lot = '{$lot}'
AND tray = '{$tray}'
AND active = 1
AND (class IS NULL OR class = '' OR class = 'GOOD');";
$ret_bkv_update = Db::query($sql);
if ($ret_bkv_update === NULL) {
throw new Exception("更新分档数据失败!");
}
}
} catch (Exception $e) {
throw new Exception("更新分档数据失败!" . $e->getMessage());
}
}
}
}
}
}
return true;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
/**
* 写入K值队列缓存数据
* @param $data
* @return bool
* @throws Exception
*/
public function setKQueue($data)
{
list($param, $batch, $subbatch, $tray, $lot, $flow_id) = [
$data['param'],
$data['batch'],
$data['subbatch'],
$data['tray'],
$data['lot'],
$data['flow_id']
];
// 写入队列缓存数据(status=0为未处理数据)
$row = Db::insert('hf_mes_queue_k', [
'flow_id' => $flow_id,
'batch' => $batch,
'subbatch' => $subbatch,
'tray' => $tray,
'lot' => $lot,
'param' => json_encode($param, JSON_UNESCAPED_UNICODE),
'status' => 0,
'create_time' => date('Y-m-d H:i:s')
]);
if ($row === NULL) {
throw new Exception('写入K值队列数据失败');
}
return true;
}
/**
* 写入容量预测队列缓存数据
* @param $data
* @return bool
* @throws Exception
*/
public function setKunQueue($data)
{
list($param, $batch, $subbatch, $tray, $lot, $workingsubclass) = [
$data['param'],
$data['batch'],
$data['subbatch'],
$data['tray'],
$data['lot'],
$data['workingsubclass']
];
// 写入队列缓存数据(status=0为未处理数据)
$row = Db::insert('hf_mes_queue_kun', [
'workingsubclass' => $workingsubclass,
'batch' => $batch,
'subbatch' => $subbatch,
'tray' => $tray,
'lot' => $lot,
'param' => json_encode($param, JSON_UNESCAPED_UNICODE),
'status' => 0,
'create_time' => date('Y-m-d H:i:s')
]);
if ($row === NULL) {
throw new Exception('写入容量预测队列数据失败');
}
return true;
}
}