SCTMES_V5/mes_in_sct/app/action/SetTrayRebatch.php

419 lines
18 KiB
PHP
Raw Permalink Normal View History

2025-06-14 18:55:09 +08:00
<?php
namespace app\action;
use libs\listener\Event;
use libs\db\Db;
use Exception;
class SetTrayRebatch
{
/*
{
"action":"set_tray_rebatch",
"param":{
"tray":"",
"workingsubclass":""
}
}
1、判断托盘是否存在tray_map表
2、判断托盘内电池是否存在NG,需要判断托盘next_process_code和电池next_process_code一致不一致电池默认已被其他工序取出不存NG电池则不允许再投
3、copy再投工序之前工序所有数据
4、之前工序所有数据新增到bkv表、battery_map表、process_log表
5、更改之前tray_map表托盘、bkv表电池状态为未激活process_log表last_status=0
*/
public function execute($post)
{
// 验证数据
$param = check_valid($post['action'], [
['tray', 'string', '托盘号'],
['workingsubclass', 'string', '工序单元']
], $post['param']);
try {
// 1、判断托盘是否存在tray_map表
$sql = sprintf(
"SELECT a.tray,a.lot,a.batch,a.subbatch,a.active,a.next_process_code,a.date_log,b.flow_id,c.process
FROM hf_mes_production_tray_map AS a
INNER JOIN hf_mes_production_planning_management_batch AS b ON b.batch = a.batch
INNER JOIN hf_mes_technology_flow AS c ON b.flow_id=c.id
WHERE a.tray='%s' ORDER BY a.id DESC LIMIT 1;",
$param['tray']
);
$ret = Db::fetch($sql);
if (empty($ret)) {
throw new Exception("托盘[{$param['tray']}]不存在");
}
list($tray, $lot, $batch, $subbatch, $active, $next_process_code, $flow_id, $date_log, $workingsubclass, $process) = [
$ret['tray'],
$ret['lot'],
$ret['batch'],
$ret['subbatch'],
$ret['active'],
$ret['next_process_code'],
$ret['flow_id'],
json_decode($ret['date_log'], true),
$param['workingsubclass'],
json_decode($ret['process'],true)
];
// 2、判断托盘内电池是否存在NG,需要判断托盘next_process_code和电池next_process_code一致不一致电池默认已被其他工序取出不存NG电池则不允许再投
$sql = sprintf(
"SELECT battery_id,class
FROM \"%s\"
WHERE tray='%s' AND lot='%s' AND next_process_code='%s' ORDER BY id ASC;",
config('app.bkv_prefix') . $subbatch,
$tray,
$lot,
$next_process_code
);
$bkv_ret = Db::fetchAll($sql);
if (empty($bkv_ret)) {
throw new Exception("托盘[{$tray}]内不存在电池数据,不允许再投");
}
if(!in_array("NG",array_column($bkv_ret, 'class'))){
throw new Exception("托盘[{$tray}]内不存在NG电池不允许再投");
}
// 筛选出应该再投的电池ID
$rebatch_battery_ids = array_column($bkv_ret, 'battery_id');
// 3、copy再投工序之前工序所有数据
$is_workingsubclass_exist = 0;
foreach ($process as $process_data) {
if ($process_data[4] == $workingsubclass) {
$is_workingsubclass_exist = 1;
}
}
if($is_workingsubclass_exist == 0){
throw new Exception("需要再投工序单元[{$workingsubclass}]不存在托盘工艺流程内");
}
$new_process_code = "";
$new_process_idx = -1;
$new_next_process_code = "";
//获取除当前工序所有process_id的参数
$process_param = [];
foreach($process as $key=>$val){
if($workingsubclass == $val[4]){
$new_process_code = $process[$key-1][2];
$new_process_idx = $process[$key-1][0];
$new_next_process_code = $val[2];
break;
}
$sql = "SELECT code FROM hf_mes_technology_process_result_param
WHERE process_id=".$val[1];
$ret = Db::fetchAll($sql);
if(empty($ret)){
continue;
}
foreach($ret as $k => $v){
$process_param[] = '"'.$val[2].'.'.$v['code'].'"';
}
}
// 修改tray_map表的date_log
foreach ($date_log as $k => $v) {
if ($k > $new_process_idx) {
$date_log[$k]['beginTime'] = "";
$date_log[$k]['endTime'] = "";
$date_log[$k]['device_code'] = "";
}
}
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
// 开启事务
Db::beginTrans();
try {
// 4、之前工序所有数据新增到bkv表、battery_map表、tray_map表、process_log表
// 4.1、针对tray_map表拿之前的数据除lot、active、process_code、process_idx、next_process_code、date_log、tray_unique_value、create_time其他沿用原来的
$sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = 'hf_mes_production_tray_map' AND column_name <> 'id' ORDER BY ordinal_position";
$ret = Db::fetchAll($sql);
$key_str = implode(",",array_column($ret, 'column_name'));
$sql = "SELECT $key_str FROM hf_mes_production_tray_map WHERE tray='$tray' AND lot='$lot' AND batch='$batch' LIMIT 1";
$ret = Db::fetch($sql);
if(empty($ret)){
throw new Exception("查找tray_map数据失败");
}
$new_log = time();
$ret['lot'] = $new_log;
$ret['active'] = 1;
$ret['process_code'] = $new_process_code;
$ret['process_idx'] = $new_process_idx;
$ret['next_process_code'] = $new_next_process_code;
$ret['date_log'] = json_encode($date_log, JSON_UNESCAPED_UNICODE);
$ret['tray_unique_value'] = "{$batch}_{$subbatch}_{$tray}_{$new_log}";
$ret['create_time'] = date("Y-m-d H:i:s");
$k_str = "";
$v_str = "";
foreach($ret as $k => $v){
$k_str .= "$k,";
if($v === '' || $v === NULL){
$v_str .= "Null,";
}else{
$v_str .= "'$v',";
}
}
$k_str = rtrim($k_str, ",");
$v_str = rtrim($v_str, ",");
// 写入tray_map数据
$sql = sprintf(
"INSERT INTO \"%s\" %s VALUES %s;",
'hf_mes_production_tray_map',
"({$k_str})",
"({$v_str})"
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("写入tray_map数据失败");
}
// 4.2、针对battery_map表拿之前的数据除lot、battery_unique_value、workingsubclass其他沿用原来的
$sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = 'hf_mes_production_battery_map' AND column_name <> 'id' ORDER BY ordinal_position";
$ret = Db::fetchAll($sql);
$key_str = implode(",",array_column($ret, 'column_name'));
$sql = "SELECT $key_str FROM hf_mes_production_battery_map WHERE tray='$tray' AND lot='$lot' AND batch='$batch' ORDER BY id ASC";
$ret = Db::fetchAll($sql);
if(empty($ret)){
throw new Exception("查找battery_map数据失败");
}
$batterys_v_str = "";
foreach($ret as $val){
$v_str = "";
// 如果电池ID在再投电池内则复制原来的数据
if(in_array($val['battery_id'],$rebatch_battery_ids)){
foreach($val as $k => $v){
if($k == 'battery_unique_value'){
$v_str .= "'{$batch}_{$subbatch}_{$tray}_{$new_log}_{$val['battery_id']}',";
}else if($k == 'lot'){
$v_str .= "'$new_log',";
}else if($k == 'workingsubclass'){
$v_str .= "'$workingsubclass',";
}else{
if($v === '' || $v === NULL){
$v_str .= "Null,";
}else{
$v_str .= "'$v',";
}
}
}
}
// else{
// // 电池不需要再投默认是0
// foreach($val as $k => $v){
// if($k == 'battery_id'){
// $v_str .= "'0',";
// }else if($k == 'battery_unique_value'){
// $v_str .= "'{$batch}_{$subbatch}_{$tray}_{$new_log}_0',";
// }else if($k == 'lot'){
// $v_str .= "'$new_log',";
// }else if($k == 'workingsubclass'){
// $v_str .= "'$workingsubclass',";
// }else if($k == 'batch' || $k == 'subbatch' || $k == 'tray'){
// $v_str .= "'$v',";
// }else{
// $v_str .= "Null,";
// }
// }
// }
if($v_str != ""){
$v_str = rtrim($v_str, ",");
$batterys_v_str .= "({$v_str}),";
}
}
$batterys_v_str = rtrim($batterys_v_str, ",");
// 写入battery_map数据
$sql = sprintf(
"INSERT INTO \"%s\" %s VALUES %s;",
'hf_mes_production_battery_map',
"({$key_str})",
"{$batterys_v_str}"
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("写入battery_map数据失败");
}
// 4.3、针对bkv表拿之前的数据除lot、class、classname、process_code、process_idx、next_process_code、工序NG其他沿用原来的
$sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = 'hf_mes_tmp_bkv_".$subbatch."' AND column_name <> 'id' AND column_name NOT LIKE '%.%' ORDER BY ordinal_position";
$ret = Db::fetchAll($sql);
// 合并再投工序之前工序结果参数字段
$key_str = implode(",",array_merge(array_column($ret, 'column_name'),$process_param));
$sql = "SELECT $key_str FROM \"hf_mes_tmp_bkv_".$subbatch."\" WHERE tray='$tray' AND lot='$lot' ORDER BY id ASC";
$ret = Db::fetchAll($sql);
if(empty($ret)){
throw new Exception("查找bkv表数据失败");
}
$batterys_v_str = "";
foreach($ret as $val){
$v_str = "";
// 如果电池ID在再投电池内则复制原来的数据
if(in_array($val['battery_id'],$rebatch_battery_ids)){
foreach($val as $k => $v){
if($k == 'lot'){
$v_str .= "'$new_log',";
}else if($k == 'process_code'){
$v_str .= "'$new_process_code',";
}else if($k == 'process_idx'){
$v_str .= "'$new_process_idx',";
}else if($k == 'next_process_code'){
$v_str .= "'$new_next_process_code',";
}else if($k == 'class' || $k == 'classname' || strpos($k, '.NG') !== false){
// 清掉class、classname、工序NG
$v_str .= "Null,";
}else{
if($v === '' || $v === NULL){
$v_str .= "Null,";
}else{
$v_str .= "'$v',";
}
}
}
}else{
// 电池不需要再投默认是0
foreach($val as $k => $v){
if($k == 'battery_id'){
$v_str .= "'0',";
}else if($k == 'lot'){
$v_str .= "'$new_log',";
}else if($k == 'tray'){
$v_str .= "'$v',";
}else{
$v_str .= "Null,";
}
}
}
$v_str = rtrim($v_str, ",");
$batterys_v_str .= "({$v_str}),";
}
$batterys_v_str = rtrim($batterys_v_str, ",");
// 写入bkv表数据
$sql = sprintf(
"INSERT INTO \"%s\" %s VALUES %s;",
config('app.bkv_prefix') . $subbatch,
"({$key_str})",
"{$batterys_v_str}"
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("写入bkv表数据失败");
}
// 4.4、针对process_log表拿之前的数据除lot、class、classname、ng_code、last_status其他沿用原来的
$sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = 'hf_mes_bkv_batch_process_log' AND column_name <> 'id' ORDER BY ordinal_position";
$ret = Db::fetchAll($sql);
$key_str = implode(",",array_column($ret, 'column_name'));
// 在再投电池内找出电池最后一条process_log数据兼容是跳工序做的电池场景
$batterys_v_str = "";
foreach($rebatch_battery_ids as $battery_id){
$sql = "SELECT $key_str FROM hf_mes_bkv_batch_process_log WHERE item_id='$battery_id' ORDER BY id DESC LIMIT 1";
$ret = Db::fetch($sql);
if(empty($ret)){
throw new Exception("查找process_log表数据失败");
}
$v_str = "";
foreach($ret as $k => $v){
if($k == 'lot'){
$v_str .= "'$new_log',";
}else if($k == 'class' || $k == 'classname'){
// 清掉工序NG
$v_str .= "Null,";
}else if($k == 'ng_code'){
// 清掉工序NG
$v_str .= "0,";
}else if($k == 'last_status'){
$v_str .= "1,";
}else{
if($v === '' || $v === NULL){
$v_str .= "Null,";
}else{
$v_str .= "'$v',";
}
}
}
$v_str = rtrim($v_str, ",");
$batterys_v_str .= "({$v_str}),";
}
$batterys_v_str = rtrim($batterys_v_str, ",");
// 写入process_log表数据
$sql = sprintf(
"INSERT INTO \"%s\" %s VALUES %s;",
'hf_mes_bkv_batch_process_log',
"({$key_str})",
"{$batterys_v_str}"
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("写入process_log表数据失败");
}
// 5、更改之前tray_map表托盘、bkv表电池状态为未激活process_log表last_status=0
// 5.1、更改之前tray_map表托盘状态为未激活
$sql = sprintf(
"UPDATE \"%s\" SET active=0 WHERE batch='%s' AND tray='%s' AND lot='%s'",
'hf_mes_production_tray_map',
$batch,
$tray,
$lot
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("更新tray_map表数据失败");
}
// 5.2、更改之前bkv表电池状态为未激活
$sql = sprintf(
"UPDATE \"%s\" SET active=0 WHERE tray='%s' AND lot='%s'",
config('app.bkv_prefix') . $subbatch,
$tray,
$lot
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("更新bkv表数据失败");
}
// 5.3、更改之前process_log表last_status=0
foreach($rebatch_battery_ids as $battery_id){
$sql = sprintf(
"UPDATE \"%s\" SET last_status=0 WHERE item_id='%s' AND tray='%s' AND lot='%s'",
'hf_mes_bkv_batch_process_log',
$battery_id,
$tray,
$lot
);
$row = Db::query($sql);
if ($row === NULL) {
throw new Exception("更新process_log表数据失败");
}
}
} catch (Exception $e) {
Db::rollBackTrans();
throw new Exception($e->getMessage());
}
Db::commitTrans();
return '';
}
}