<?php
namespace model\pro;
use \model;
use \model\check;
use \model\collocation;
use \model\carmodel;
use \model\carmodelcn;
use \model\pro\numidx;
use \model\pro\promodel;
use \model\pro\promodelcn;
use \model\pro\cate;
use \model\ypApi;
use \model\user;
use \model\oe;
use \model\pro\pro;
use \model\pro\factory;
use \model\homecn\trade;
use \model\rcaApi;
use \model\wdzy\resource;

class prodevelop extends model
{
	
	public function __construct ()
    {
		parent::__construct();
		$this->proFrom = [
			'self'=>'产品库',
			'tcd'=>'TCD',
			'etk'=>'EPC',
		];
		$this->proFromSelect = ':;self:产品库;tcd:TCD;etk:EPC';
	}

	public function getDevelopList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? 'pdlist_id': $params['sidx'];
		$sord = empty($params['sord']) || empty($params['sidx'])? 'desc': $params['sord'];
		$orderby = $params['orderby'];

		$table = 'pro_develop_list(pdl)';
		$join = [
			"[>]adm_user(au)" => ["pdl.pdlist_from_opuser" => "au_id"],
			"[>]adm_user(au2)" => ["pdl.pdlist_opuser" => "au_id"],
		];
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			
        });
		
		if(!empty($params['keys'])) $where['pdlist_id'] = explode(',', $params['keys']);
		if(!empty($params['pdlist_id'])) $where['pdlist_id'] = explode(',', $params['pdlist_id']);
		
	
		$where['GROUP'] = 'pdlist_id';

        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);
		if($page>0 && $pagesize>0){
			$fields = '*';
			$pages = $this->paging($table,$join,$fields,$where,$page,$pagesize);
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}

		$fields = ['au.au_name(au_name_from)', 'au2.au_name', 'pdl.*'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if($arr){
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('work');

			$wdlIds = array_column($arr, 'pdlist_id');
			//清洗
			$rows = $this->db->select('pro_develop_item', ['pdi_pdlist_id', 'item_count'=>raw('count(*)')], ['pdi_pdlist_id'=>$wdlIds, 'GROUP'=>'pdi_pdlist_id']);
			$tj1 = array_column($rows, null, 'pdi_pdlist_id');
			
			//存在的样品库
			$sql = sprintf("SELECT pdi_pdlist_id, count(distinct pdi_id) sample_has_count FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN sample_numidx ON pdif_pf_id=sn_pro_factory AND pdif_search=sn_numfomart 
				JOIN sample ON sn_s_id=s_id
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = s_cate) AND pdi_pdlist_id IN (%s) GROUP BY pdi_pdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj5 = array_column($rows, null, 'pdi_pdlist_id');


			//存在的零件库
			$sql = sprintf("SELECT pdi_pdlist_id, count(distinct pdi_id) poe_has_count FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = oe_cate_id) AND pdi_pdlist_id IN (%s) GROUP BY pdi_pdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj2 = array_column($rows, null, 'pdi_pdlist_id');

			// //存在的供应商
			$sql = sprintf("SELECT pdi_pdlist_id, count(distinct pdi_id) sup_has_count FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
				JOIN supplier_pro ON spr_oe_id=on_oe_id 
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = spr_cat_id) AND pdi_pdlist_id IN (%s) group by pdi_pdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj3 = array_column($rows, null, 'pdi_pdlist_id');

			// //存在的商品库
			$sql = sprintf("SELECT pdi_pdlist_id, count(distinct pdi_id) pro_has_count FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN pro_numidx ON pdif_pf_id=pn_pf_id AND pdif_search=pn_formart 
				JOIN pro ON p_id=pn_p_id and p_pb_id = 1
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = p_cate) AND pdi_pdlist_id IN (%s) group by pdi_pdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj4 = array_column($rows, null, 'pdi_pdlist_id');

			
			// $roleArr = $this->db->select('pro_develop_item',['[><]adm_role'=>['pdi_ar_id'=>'ar_id']],['pdi_pdlist_id','ar_name'=>raw('GROUP_CONCAT(DISTINCT ar_name)')],['pdi_pdlist_id'=>$wdlIds,'GROUP'=>'pdi_pdlist_id']);
			// $roleArr = array_column($roleArr,null,'pdi_pdlist_id');
			foreach($arr as &$v){
				if($tj1[$v['pdlist_id']]) $v = array_merge($v, $tj1[$v['pdlist_id']]);
				if($tj2[$v['pdlist_id']]) $v = array_merge($v, $tj2[$v['pdlist_id']]);
				if($tj3[$v['pdlist_id']]) $v = array_merge($v, $tj3[$v['pdlist_id']]);
				if($tj4[$v['pdlist_id']]) $v = array_merge($v, $tj4[$v['pdlist_id']]);
				if($tj5[$v['pdlist_id']]) $v = array_merge($v, $tj5[$v['pdlist_id']]);
				$v['captions']['pdlist_from_opuser'] = $v['au_name_from'];
				$v['captions']['pdlist_opuser'] = $v['au_name'];
				$v['captions']['pdlist_type'] = !empty($collArr[$v['pdlist_type']])? $collArr[$v['pdlist_type']]: '';

				$v['ar_name'] = $roleArr[$v['pdlist_id']]['ar_name']??'';
			}
			unset($v);
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	//开发单的明细
	public function getDevelopItemList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		if(empty($params['sidx'])){
			$sidx = 'pdi_id';
			$sord = 'desc';
		}else{
			$sidx = $params['sidx'];
			$sord = $params['sord'];
		}
		$orderby = $params['orderby'];

		$refiled = [
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName()
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'pro_develop_item(pdi)';
		$join = [
			"[><]pro_develop_list(pdl)" => ["pdi.pdi_pdlist_id" => "pdlist_id"],
			"[>]pro_cate(cat)" => ["pdi.pdi_cat_id" => "id"],
			"[>]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]adm_user(au)" => ["pdi.pdi_opuser" => "au_id"]
		];
		
		$this->set('pnumwhere', []);
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'chknums'){
				if($op == 'eq'){
					$where = "pdif_search = '".formatNum($data)."'";
				}else if($op == 'bw'){
					$where = "pdif_search like '%".formatNum($data)."%'";
				}else{
					$where = "pdif_search like '".formatNum($data)."%'";
				}
				$op = 'RAW_'.$field;
				$data = raw(" pdi_id in (select pdif_pdi_id from pro_develop_item_format where pdif_type='Number' and ".$where.")");
			}else if($field == 'chk_poes'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" pdi_id not in (SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = oe_cate_id)
					)");
				}else{
					$data = raw(" pdi_id in (SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = oe_cate_id)
					)");
				}
			}else if($field == 'chk_pcs'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" pdi_id not in (
						SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN pro_numidx ON pdif_pf_id=pn_pf_id AND pdif_search=pn_formart 
						JOIN pro ON p_id=pn_p_id and p_pb_id = 1
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = p_cate)
					)");
				}else{
					$data = raw(" pdi_id in (
						SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN pro_numidx ON pdif_pf_id=pn_pf_id AND pdif_search=pn_formart 
						JOIN pro ON p_id=pn_p_id and p_pb_id = 1
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = p_cate)
					)");
				}
			}else if($field == 'chk_sups'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" pdi_id not in (
					SELECT DISTINCT pdif_pdi_id FROM pro_develop_item_format
					JOIN pro_develop_item ON pdi_id = pdif_pdi_id
					JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
					JOIN supplier_pro ON spr_oe_id=on_oe_id 
					WHERE pdif_type='Number' AND (pdi_cat_id = 0 OR pdi_cat_id = spr_cat_id)
					)");
				}else{
					$data = raw(" pdi_id in (SELECT DISTINCT pdif_pdi_id FROM pro_develop_item_format
					JOIN pro_develop_item ON pdi_id = pdif_pdi_id
					JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
					JOIN supplier_pro ON spr_oe_id=on_oe_id WHERE pdif_type='Number' AND (pdi_cat_id = 0 OR pdi_cat_id = spr_cat_id))");
				}
			}else if($field == 'cat.'.cateName()){
				if($data == 'Y'){
					$op = 'RAW_'.$field;
					$data = raw(" pdi_cat_id > 0");
				}else if($data == 'N'){
					$op = 'RAW_'.$field;
					$data = raw(" pdi_cat_id = 0");
				}
			}else if($field == 'chk_sam'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" pdi_id not in (
						SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN sample_numidx ON pdif_pf_id=sn_pro_factory AND pdif_search=sn_numfomart 
						JOIN sample ON s_id=sn_s_id
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = s_cate)
					)");
				}else{
					$data = raw(" pdi_id in (
						SELECT distinct pdif_pdi_id FROM pro_develop_item_format
						JOIN pro_develop_item ON pdi_id = pdif_pdi_id
						JOIN sample_numidx ON pdif_pf_id=sn_pro_factory AND pdif_search=sn_numfomart 
						JOIN sample ON s_id=sn_s_id
						WHERE (pdi_cat_id = 0 OR pdi_cat_id = s_cate)
					)");
				}
			}
			
        });
		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'p_cate': $where['pdi_cat_id'] = explode(',', $rules['p_cate']); break;
				case 'numbers':
					$tnums = [];
					foreach($val as $tk=>$tv){
						$tnums = array_merge($tnums, reSearchNum($tv));
					}
					$tnums = array_unique($tnums);
					$where['pdif_search'.($rules['numlike']? '[~]': '')] = $tnums;
					$join['[><]pro_develop_item_format(pdif)'] = ['pdi.pdi_id'=>'pdif_pdi_id'];
				break;
			}
		}
		
		if($params['pdlist_id']) $where['pdlist_id'] = $params['pdlist_id'];
		if(!empty($params['keys'])) $where['pdi_id'] = explode(',', $params['keys']);
		

		//无分配权限的，展示分配给自己的
		if(!\p::isAdmin() && !\p::has('A200','check1') ){
			$user = new user();
			$arids = $user->getMyPowerRole('A200', ['check2']);
			$where['pdi_ar_id'] = $arids? $arids: -1;
		}
		$cates = \p::cates('A200');
		if(!\p::isAdmin() && $cates){
			$where['AND #rule_cate']['pdi_cat_id'] = explode(',',$cates);
		}

        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);
		if($page>0 && $pagesize>0){
			$fields = '*';
			$pages = $this->paging($table,$join,$fields,$where,$page,$pagesize);
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}

		$fields = ['cat.id(cat_id)', 'pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'pdl.pdlist_id', 'pdl.pdlist_title', 'pdi.*', 'au.au_name'];
        $arr = $this->db->select($table,$join,$fields,$where);

		if(!empty($arr)){
			$pdiIds = array_column($arr, 'pdi_id');
			$join = [
				"[>]pro_factory(fac)" => ["pdif_pf_id" =>"pf_id"]
			];
			
			$rows = $this->db->select('pro_develop_item_format', $join, '*', ['pdif_type'=>'Number', 'pdif_pdi_id'=>$pdiIds]);
			$nums = [];
			$tnums = [];
			foreach($rows as $rv){
				$nums[$rv['pdif_pdi_id']][] = ['pdif_id'=>$rv['pdif_id'], 'factory'=>$rv['pf_name'], 'number'=>$rv['pdif_val'], 'format'=>$rv['pdif_search'], 'ok'=>1, 'pf_id'=>$rv['pf_id'], 'pdif_isborrow'=>$rv['pdif_isborrow']];
				$tnums[] = $rv['pdif_search'];
			}
			
		
			//存在的零件库
			$poes = [];
			$pdipoes = [];
			$sql = sprintf("SELECT pdif_id, pdif_pdi_id, oe_id, pf_name, oe_oe FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				JOIN pro_factory on pf_id = oe_pf_id
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = oe_cate_id) AND pdif_pdi_id IN (%s)", implode(',', $pdiIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$poes[$rv['pdif_pdi_id']][$rv['oe_id']] = $rv;
					$pdipoes[$rv['pdif_id']] = $rv;
				}
			}
			
			//存在的供应商
			$sups = [];
			$pdisups = [];
			$supnameField = \p::has('C500','view')? 'sup_name': 'sup_code as sup_name';
			$supnameField2 = \p::has('C500','view')? 'sup_name': 'sup_code';
			$sql = sprintf("SELECT pdif_id, pdif_pdi_id,sup_id, %s,spr_id FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
				JOIN supplier_pro ON spr_oe_id=on_oe_id 
				JOIN supplier ON spr_sup_id=sup_id
				LEFT JOIN object ON sup_level=o_id WHERE pdif_type='Number' AND (pdi_cat_id = 0 OR pdi_cat_id = spr_cat_id) AND pdif_pdi_id IN (%s) group by pdif_id, sup_id ORDER BY o_sort,%s", $supnameField, implode(',', $pdiIds), $supnameField2);
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$sups[$rv['pdif_pdi_id']][$rv['sup_id']] = $rv;
					$pdisups[$rv['pdif_id']][] = $rv;
				}
			}


			//存在的商品库
			$pcs = [];
			$pdipcs = [];
			$sql = sprintf("SELECT pdif_id, pdif_pdi_id, p_id, p_innum p_innum FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN pro_numidx ON pdif_pf_id=pn_pf_id AND pdif_search=pn_formart 
				JOIN pro ON p_id=pn_p_id and p_pb_id = 1
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = p_cate) AND pdif_pdi_id IN (%s) group by pdif_id, p_id order by p_innum", implode(',', $pdiIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$pcs[$rv['pdif_pdi_id']][$rv['p_id']] = $rv;
					$pdipcs[$rv['pdif_id']][$rv['p_id']] = $rv;
				}
			}

			//存在的样品库
			$sam = [];
			$pdisam = [];
			$sql = sprintf("SELECT pdif_id, pdif_pdi_id, s_id, sn_number FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN sample_numidx ON pdif_pf_id=sn_pro_factory AND pdif_search=sn_numfomart 
				JOIN sample ON s_id=sn_s_id
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = s_cate) AND pdif_pdi_id IN (%s) group by pdif_id, s_id order by sn_numfomart", implode(',', $pdiIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$sam[$rv['pdif_pdi_id']][$rv['s_id']] = $rv;
					$pdisam[$rv['pdif_id']][$rv['s_id']] = $rv;
				}
			}
		
			foreach($arr as &$v){
				$v['nums'] = $nums[$v['pdi_id']]? $nums[$v['pdi_id']]: [];
				$v['poes'] = $poes[$v['pdi_id']]? $poes[$v['pdi_id']]: [];
				$v['sups'] = $sups[$v['pdi_id']]? array_values($sups[$v['pdi_id']]): [];
				$v['pcs'] = $pcs[$v['pdi_id']]? array_values($pcs[$v['pdi_id']]): [];
				$v['sam'] = $sam[$v['pdi_id']]? array_values($sam[$v['pdi_id']]): [];
	
				//号码检测
				$v['chknums'] = '<div class="table table-bordered YpTable chknums supplier-grid-container" style="display: table;">
					<div class="thead Filter Sortable supplier-grid-header" style="display: table-header-group;">
						<div class="tr" style="display: table-row;">
							<div class="th supplier-grid-cell" style="display: table-cell;width:150px"><span><lg>号码</lg></span>&nbsp;&nbsp;&nbsp;</div>
							<div class="th supplier-grid-cell" style="display: table-cell;"><span><lg>样品</lg></span></div>
							<div class="th supplier-grid-cell" style="display: table-cell;"><span><lg>零件</lg></span></div>
							<div class="th supplier-grid-cell" style="display: table-cell;"><span><lg>供应</lg></span></div>
							<div class="th supplier-grid-cell" style="display: table-cell;"><span><lg>商品</lg></span></div>
						</div>
					</div>
					<div class="tbody supplier-grid-body" style="display: table-row-group;">';
				foreach($v['nums'] as $tk=> $tv){
					$v['chknums'] .= '<div class="tr supplier-grid-row" style="display: table-row;">
						<div class="td supplier-grid-cell" style="display: table-cell;" pdif-id="'.$tv['pdif_id'].'"><span class="num">'.($tv['factory']? $tv['factory'].': ' : '').$tv['number'].'</span>'.($tv['err']? ' <span class="red">[异常]</span>': '').'</div>
						<div class="td supplier-grid-cell" style="display: table-cell;">'.($pdisam[$tv['pdif_id']]? 'Y': '').'</div>
						<div class="td supplier-grid-cell" style="display: table-cell;">'.($pdipoes[$tv['pdif_id']]? 'Y': '').'</div>
						<div class="td supplier-grid-cell" style="display: table-cell;">'.($pdisups[$tv['pdif_id']]? count($pdisups[$tv['pdif_id']]): '').'</div>
						<div class="td supplier-grid-cell" style="display: table-cell;">'.($pdipcs[$tv['pdif_id']]? count($pdipcs[$tv['pdif_id']]): '').'</div>
					</div>';
				}
		
				$v['chknums'] .= '</div></div>';


				$v['chkok_para'] = '';
				if(!empty($chkproArr['para'])){
					foreach($chkproArr['para'] as $tv){
						$v['chkok_para'] .= '<div>'.($tv['cn_name']? $tv['cn_name']: $tv['name']).' : '.$tv['val'].$tv['unit'].'</div>';
					}
				}
				
				$v['chk_poes'] = '';
				if(!empty($v['poes'])){
					$v['chk_poes'] .= '<ul class="pro-list-self poes">';
					foreach($v['poes'] as $tpk=>$tpv){
						$v['chk_poes'] .= '<li><a href="'.\mvc::$cfg['sitePath'].'/oe/detail?tab=base&oe_id='.$tpv['oe_id'].'" title="零件库['.$tpv['oe_oe'].']" tab>'.$tpv['pf_name'].': '.$tpv['oe_oe'].'</a></li>';
					}
					$v['chk_poes'] .= '</ul>';
				}

				$v['chk_sups'] = '';
				if(!empty($v['sups'])){
					$v['chk_sups'] .= '<ul class="sup-list">';
					foreach($v['sups'] as $tpk=>$tpv){
						$v['chk_sups'] .= '<li> '.$tpv['sup_name'].'</li>';
					}
					$v['chk_sups'] .= '</ul>';
				}

				//检测产品库
				$v['chk_pcs'] = '';
				$v['chkpro_url'] = '';

				if(!empty($v['pcs'])){
					$v['chk_pcs'] .= '<ul class="pro-list-self">';
					foreach($v['pcs'] as $tpk=>$tpv){
						$tpv['pro_url'] = \mvc::$cfg['sitePath'].'/pro/detail?tab=base&p_id='.$tpv['p_id'];
						$v['chk_pcs'] .= '<li><a href="'.$tpv['pro_url'].'" tab>'.$tpv['p_innum'].'</a></li>';
					}
					$v['chk_pcs'] .= '</ul>';
				}	
				
				//检测样品库库
				$v['chk_sam'] = '';
				$v['chksam_url'] = '';

				if(!empty($v['sam'])){

					$v['chk_sam'] .= '<ul class="pro-list-self">';
					foreach($v['sam'] as $tpk=>$tpv){
						$tpv['sam_url'] = \mvc::$cfg['sitePath'].'/sample/process/detail?id='.$tpv['s_id'];
						$v['chk_sam'] .= '<li><a href="'.$tpv['sam_url'].'" tab>'.$tpv['sn_number'].'</a></li>';
					}
					$v['chk_sam'] .= '</ul>';
				}	
		
				$v['captions']['pdi_opuser'] = $v['au_name'];

				if($params['isExport'])
				{	
					
					//零件库检测
					$v['chk_poes'] = [];
					if(!empty($v['poes'])){
						foreach($v['poes'] as $tpk=>$tpv){
							$v['chk_poes'][] = $tpv['pf_name'].': '.$tpv['oe_oe'];
						}
						$v['chk_poes'] =implode("\n", $v['chk_poes']);
					}
					
					//供应商检测
					$v['chk_sups'] = [];
					if(!empty($v['sups'])){
						foreach($v['sups'] as $tpk=>$tpv){
							$v['chk_sups'][] = $tpv['sup_name'];
						}
						$v['chk_sups'] =implode("\n", $v['chk_sups']);
					}
					
					//商品库检测
					$v['chk_pcs'] = [];
					if(!empty($v['pcs'])){
						foreach($v['pcs'] as $tpk=>$tpv){
							$v['chk_pcs'][] = $tpv['p_innum'];
						}
						$v['chk_pcs'] =implode("\n", $v['chk_pcs']);
					}

					//样品库检测
					$v['chk_sam'] = [];
					if(!empty($v['sam'])){
						foreach($v['sam'] as $tpk=>$tpv){
							$v['chk_sam'][] = $tpv['sn_number'];
						}
						$v['chk_sam'] =implode("\n", $v['chk_sam']);
					}
			
					$v['chknums'] = [];
					if(!empty($v['nums'])){
						foreach($v['nums'] as $tk=>$tv){
							$v['chknums'][] = ($tv['factory']? $tv['factory'].': ' : '').$tv['number'].($tv['err']? ' [异常]': '');
						}
						$v['chknums'] =implode("\n", $v['chknums']);
					}

				
					
				}

				unset($v['pdi_data']);
			}
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	//获取清单对应的零件库ID
	function getPdiOeIds($pdiIds)
	{
		$sql = sprintf("SELECT pdi_id, oe_id, oe_oe FROM pro_develop_item_format
				JOIN pro_develop_item ON pdi_id = pdif_pdi_id
				JOIN oe_numidx ON pdif_pf_id=on_pf_id AND pdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				WHERE (pdi_cat_id = 0 OR pdi_cat_id = oe_cate_id) AND pdi_id IN (%s) group by pdi_id, oe_id", implode(',', $pdiIds));
		return $this->db->query($sql)->fetchAll();
	}
	

	public function setCate($table, $idArr, $cate_id)
	{
		if(empty($idArr) || !is_array($idArr)) return [];
		if($table == 'pro_develop_item'){
			$this->db->update('pro_develop_item', ['pdi_cat_id'=>$cate_id], ['pdi_id'=>$idArr]);
		}
		return [];
	}


	function setPdiStatus($req)
	{
		if(!empty($req['pdi_dstatus'])){
			$setArr = [
				'pdi_dstatus'=>$req['pdi_dstatus'],
				'pdi_dstatus_user'=>getOpuser(),
				'pdi_dstatus_time'=>getNowTime()
			];
			$this->db->update('pro_develop_item', $setArr, ['pdi_id'=>explode(',', $req['ids'])]);
		}
		return [];
	}

	function getpdiIds($req){
		return $this->db->select('pro_develop_item','pdi_id',['pdi_pdlist_id'=>$req['pdlist_id']]);
	}

	

	//修改
	public function setCell($table, $kid, $setArr)
	{
		$opuser = getOpuser();
		$datetime = getNowTime();
		
		if($table == 'pro_develop_list'){
			$setArr['pdlist_opuser'] = $opuser;
			$setArr['pdlist_update_time'] = $datetime;
			$this->db->update('pro_develop_list', $setArr, ['pdlist_id'=>$kid]);
		}else if($table == 'pro_develop_item'){
			$setArr['pdi_opuser'] = $opuser;
			$setArr['pdi_update_time'] = $datetime;
			$this->db->update('pro_develop_item', $setArr, ['pdi_id'=>$kid]);
		}else if($table == 'pro_develop_item_format'){
			$this->db->update('pro_develop_item_format', $setArr, ['pdif_id'=>$kid]);
		}
		return [];
	}


	//删除
	public function delData($table, $idArr)
	{
		if(empty($idArr) || !is_array($idArr)) return [];

		$this->db->Begin();
		if($table == 'pro_develop_list'){
			//删除开发单
			$sonids = $this->db->select('pro_develop_item', 'pdi_id', ['pdi_pdlist_id'=>$idArr]);
			if($sonids){
				
				$this->db->delete('pro_develop_item_format', ['pdif_pdi_id'=>$sonids]);	
			}
			$this->db->delete('pro_develop_item', ['pdi_pdlist_id'=>$idArr]);
			$this->db->delete('pro_develop_list', ['pdlist_id'=>$idArr]);

		}else if($table == 'pro_develop_item'){

			$this->db->delete('pro_develop_item_format', ['pdif_pdi_id'=>$idArr]);
			$this->db->delete('pro_develop_item', ['pdi_id'=>$idArr]);
		}else if($table == 'pro_develop_item_format'){
			$this->db->delete('pro_develop_item_format', ['pdif_id'=>$idArr]);
		}
		$this->db->End();
		
		return [];
	}


	//开发单流水
	function getWorkSeqNext(){
        $fix = date('Ymd');
        return $this->getSeqNext('pro_develop_list', $fix,'pdlist_seq',4);
	}


	/**
	 * 取下一个序列号
     * @param string $fix 前缀
     * @param string $field 字段
     * @param string $lengh 流水号长度
	 * @return string
	 */
	function getSeqNext($table, $fix,$field,$lengh=4){
        $where[$field.'[=~]'] = $fix;
        $where['ORDER'][$field] ='DESC';
        $value = $this->db->get($table,$field,$where);
        if(!empty($value)){
            $value = ltrim(substr($value,-$lengh),'0') + 1;
            $value = $fix.str_pad($value,$lengh,'0',STR_PAD_LEFT);
        }else{
            $value = $fix.str_pad('1',$lengh,'0',STR_PAD_LEFT);
        }
        return $value;
	}
	
	

	public function dataItemExport($fields,$data)
	{
		function processBatchData($data,$fields,&$drawImgRanges, &$wrapTextRanges, &$brow){
			foreach ($data as $v) {
				$row = [];
				$col = 0;
				$bcol = 'A';
				// 写入主
				foreach ($fields as $fk => $fv) {
					if($fk=='pdi_dstatus'){
						$v['pdi_dstatus'] = $v['pdi_dstatus'] == 1 ? 'Y' : 'N';
					}
					if($fk=='pdi_clean'){
						$v['pdi_clean'] = $v['pdi_clean'] == 1 ? 'Y' : 'N';
					}
					//零件库检测
					if($fk=='chk_poes')
					{
						$v['chk_poes'] = [];
						if(!empty($v['poes'])){
							foreach($v['poes'] as $tpk=>$tpv){
								$v['chk_poes'][] = $tpv['pf_name'].': '.$tpv['oe_oe'];
							}
						}
					}
					//供应商检测
					if($fk=='chk_sups')
					{
						$v['chk_sups'] = [];
						if(!empty($v['sups'])){
							foreach($v['sups'] as $tpk=>$tpv){
								$v['chk_sups'][] = $tpv['sup_name'];
							}
						}
					}
					//商品库检测
					if($fk=='chk_pcs'){
						$v['chk_pcs'] = [];
						if(!empty($v['pcs'])){
							foreach($v['pcs'] as $tpk=>$tpv){
								$v['chk_pcs'][] = $tpv['p_innum'];
							}
						}
					}
					if($fk=='chknums'){
						$v['chknums'] = [];
						foreach($v['nums'] as $tk=>$tv){
							$v['chknums'][] = ($tv['factory']? $tv['factory'].': ' : '').$tv['number'].($tv['err']? ' [异常]': '');
						}
					}
					if($fk=='chkok'){
						
						$v['chkok'] = strip_tags(str_replace($v['chkok_para'],'',$v['captions']['chkok']));
				
						$v['captions']['chkok'] = [];
						if($v['chkok']){
							$v['captions']['chkok'][] = trim($v['chkok'],'&nbsp;');
						}
						$chkproArr = empty($v['pdi_chkpro_clean_result']) ? []: json_decode($v['pdi_chkpro_clean_result'], true);
						if(!empty($chkproArr['para'])){
							foreach($chkproArr['para'] as $tv){
								$v['captions']['chkok'][] = ($tv['cn_name']? $tv['cn_name']: $tv['name']).' : '.$tv['val'].$tv['unit'];
							}
						}
					}
					
					$val = isset($v['captions'][$fk]) ?$v['captions'][$fk]: (isset($v[$fk]) ? $v[$fk]: '');
				
					$val = is_array($val) ? implode("\n", $val) : $val;
					$row[$col] = $val;

					// 如果值中包含 \n，记录单元格范围
					if (stripos($val, "\n") !== false) {
						$wrapTextRanges[] = $bcol . $brow;
					}
					if($fk=='img' && $val){
						$imgPath = tempnam(sys_get_temp_dir(), 'excel_img_'.md5($val));
				
						// 检查文件是否存在且可访问
						$headers = @get_headers($val);
						if($headers && strpos($headers[0], '200') !== false) {

							$contents = file_get_contents($val);
							if($imgPath && file_exists($imgPath) && $contents){
								file_put_contents($imgPath,$contents);
								$drawImgRanges[$bcol . $brow] = $imgPath;
							}
							$row[$col] = '';
						}
					}
					$bcol++;
					$col++;
				}

				$brow++; // 更新行号
				yield $row; // 使用 yield 返回当前行
			}
		}
        // 创建一个新的 Spreadsheet 对象
		$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
		$sheet = $spreadsheet->getActiveSheet();

		// 设置标题
		$row = 1;
        $col = 'A';
		$defaultColumnWidth = 20;
		foreach ($fields as $vv) {
            if(!$vv){
                $col++;
                continue;
            } 
			 // 设置列宽（如果未单独指定宽度，则使用默认宽度）
			if (is_array($vv) && !empty($vv['width'])) {
				$sheet->getColumnDimension($col)->setWidth($vv['width']);
			} else {
				$sheet->getColumnDimension($col)->setWidth($defaultColumnWidth);
			}
            if(is_array($vv)){
                if($vv['isMerge']){
                    $sheet->mergeCells(sprintf("%s:%s",$vv['scell'],$vv['ecell'])); // 合并单元格
                }

                $sheet->setCellValue($vv['scell']??$col.$row, $vv['title']); 

                $cell = $vv['isMerge']?sprintf("%s:%s",$vv['scell'],$vv['ecell']):$col.$row;
                $style = $sheet->getStyle($cell);

                if($vv['color']){
                    $style->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB($vv['color']);
                    $styleArray = [
                        'borders' => [
                            'allBorders' => [
                                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                                'color' => ['argb' => 'FF000000'], // 黑色边框
                            ],
                        ],
                    ];
                    $style->applyFromArray($styleArray);
                } 
            }else{
                $sheet->setCellValue($col.$row, $vv);
                $style = $sheet->getStyle($col.$row);  
            }
            $style->getAlignment()->setHorizontal('center');  
            $style->getAlignment()->setVertical('center');  
            $col++;
		}
        $row++;

		$batchSize = 1000; // 每次处理 1000 条
		$totalRows = count($data);

		for ($i = 0; $i < $totalRows; $i += $batchSize) {
			$batchData = array_slice($data, $i, $batchSize); // 获取当前批次
			$data = [];
			$wrapTextRanges = [];
			$startRow = $row; // 记录当前批次的起始行号
			$drawImgRanges = [];
			// 使用生成器逐行处理
			foreach (processBatchData($batchData,$fields,$drawImgRanges, $wrapTextRanges, $row) as $item) {
				$data[] = $item;
			}

			// 批量写入到表格
			if (!empty($data)) {
				$sheet->fromArray($data, null, 'A' . $startRow);
			}
			// 批量设置换行样式
			if (!empty($wrapTextRanges)) {
				foreach ($wrapTextRanges as $cell) {
					$sheet->getStyle($cell)->getAlignment()->setWrapText(true);
				}
			}

			//批量插入图片
			if(!empty($drawImgRanges)){
				foreach ($drawImgRanges as $cell => $img) {
					// 插入图片
					$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
					$drawing->setPath($img); // 图片路径
					$drawing->setHeight(50); // 设置图片高度
					$drawing->setCoordinates($cell); // 设置图片插入的单元格
					$drawing->setWorksheet($sheet);

					 // 设置图片所在行的高度
					$rowIndex = preg_replace('/[^0-9]/', '', $cell); // 提取行号
					$sheet->getRopDimension($rowIndex)->setRowHeight(40); // 设置行高为 80，可根据需求调整
				}
			}
		}

		// 输出文件
		ob_clean();
		if (empty($filename)) {
			$filename = sprintf('%d.xlsx', time());
		}
		header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
		header('Content-Disposition: attachment;filename="' . $filename . '"');
		header('Cache-Control: max-age=0');
		$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
		$writer->save('php://output');

		// 释放内存
		$spreadsheet->disconnectWorksheets();
		unset($spreadsheet);

	}

	//通过小类匹配清洗数据的分类ID
	public function autoCleanCat($req)
	{
		set_time_limit(0);
		$where = ['pdi_cat_id'=>0];
		if(!empty($req['ids'])){
			$where['pdi_id'] = is_array($req['ids'])? $req['ids']: explode(',', $req['ids']);
		}else if(!empty($req['wplist_id'])){
			$where['pdi_wplist_id'] = explode(',', $req['wplist_id']);
		}
		$items = $this->db->select('pro_develop_item', ['pdi_id', 'pdi_cat_id'], $where);

		foreach($items as $pdiArr){
			$setArr = [];

			//检测产品库
			$join = [
				"[><]pro_numidx(pn)" => ["pdif.pdif_pf_id"=>"pn_pf_id", "pdif.pdif_search"=>'pn_formart'],
				"[><]pro(p)" => ["pn.pn_p_id"=>"p_id"],
			];
			$hasPro = $this->db->get('pro_develop_item_format(pdif)', $join, ['p_cate'], ['p_pb_id'=>1, 'pdif_pdi_id'=>$pdiArr['pdi_id']]);
			if(!empty($hasPro)){
				$setArr['pdi_cat_id'] = $hasPro['p_cate'];
			}

			//零件库本身
			if(empty($setArr['pdi_cat_id'])){
				$join = [
					"[><]oe_numidx(pn)" => ["pdif.pdif_pf_id"=>"on_pf_id", "pdif.pdif_search"=>'on_formart'],
					"[><]oe_item(pro)" => ["pn.on_oe_id"=>"oe_id"],
				];
				$hasPro = $this->db->get('pro_develop_item_format(pdif)', $join, ['oe_cate_id(p_cate)'], ['pdif_pdi_id'=>$pdiArr['pdi_id']]);
				if(!empty($hasPro)){
					$setArr['pdi_cat_id'] = $hasPro['p_cate'];
				}
			}

			if($setArr){
				$this->db->update('pro_develop_item', $setArr, ['pdi_id'=>$pdiArr['pdi_id']]);
			}
		}
		return [];
	}

}