453 lines
18 KiB
PHP
453 lines
18 KiB
PHP
<?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;
|
||
}
|
||
}
|