<?php
namespace model;
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 work extends model
{
	
	public function __construct ()
    {
		parent::__construct();
		$this->proFrom = [
			'self'=>'产品库',
			'tcd'=>'TCD',
			'etk'=>'EPC',
		];
		$this->proFromSelect = ':;self:产品库;tcd:TCD;etk:EPC';
	}

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

		$table = 'work_data_list(wdl)';
		$join = [
			"[>]supplier(sup)" => ["wdl.wdlist_sup_id" => "sup_id"],
			"[>]adm_user(au)" => ["wdl.wdlist_from_opuser" => "au_id"],
			"[>]adm_user(au2)" => ["wdl.wdlist_opuser" => "au_id"],
		];
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			
        });
		
		if(!empty($params['keys'])) $where['wdlist_id'] = explode(',', $params['keys']);
		if(!empty($params['wdlist_id'])) $where['wdlist_id'] = explode(',', $params['wdlist_id']);
		if(!empty($params['wdlist_seq'])) $where['wdlist_seq'] = explode(',', $params['wdlist_seq']);
		
		//无分配权限的，展示分配给自己的数据
		if(!\p::isAdmin() && !\p::has('A200','check1') ){
			$user = new user();
			$arids = $user->getMyPowerRole('A200', ['check2']);
			$where['wdi_ar_id'] = $arids? $arids: -1;
			$join["[><]work_data_item(wdi)"] = ["wdl.wdlist_id" => "wdi_wdlist_id"];
		}
		$where['GROUP'] = 'wdlist_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 = ['sup_name', 'sup_code', 'au.au_name(au_name_from)', 'au2.au_name', 'wdl.*'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if($arr){
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('work');

			$wdlIds = array_column($arr, 'wdlist_id');
			//清洗
			$rows = $this->db->select('work_data_item', ['wdi_wdlist_id', 'item_count'=>raw('count(*)'), 'clean_count'=>raw('(sum(case when wdi_clean = 1 then 1 else 0 end))'), 'clean_has_count'=>raw('(sum(case when wdi_clean_has = 1 then 1 else 0 end))'), 'dstatusok_count'=>raw('(sum(case when wdi_dstatus > 0 then 1 else 0 end))')], ['wdi_wdlist_id'=>$wdlIds, 'GROUP'=>'wdi_wdlist_id']);
			$tj1 = array_column($rows, null, 'wdi_wdlist_id');
			

			//存在的零件库
			$sql = sprintf("SELECT wdi_wdlist_id, count(distinct wdi_id) poe_has_count FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id) AND wdi_wdlist_id IN (%s) GROUP BY wdi_wdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj2 = array_column($rows, null, 'wdi_wdlist_id');

			//存在的供应商
			$sql = sprintf("SELECT wdi_wdlist_id, count(distinct wdi_id) sup_has_count FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
				JOIN supplier_pro ON spr_oe_id=on_oe_id 
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = spr_cat_id) AND wdi_wdlist_id IN (%s) group by wdi_wdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj3 = array_column($rows, null, 'wdi_wdlist_id');

			//存在的商品库
			$sql = sprintf("SELECT wdi_wdlist_id, count(distinct wdi_id) pro_has_count FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN pro_numidx ON wdif_pf_id=pn_pf_id AND wdif_search=pn_formart 
				JOIN pro ON p_id=pn_p_id and p_pb_id = 1
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = p_cate) AND wdi_wdlist_id IN (%s) group by wdi_wdlist_id", implode(',', $wdlIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)) $tj4 = array_column($rows, null, 'wdi_wdlist_id');

			
			$roleArr = $this->db->select('work_data_item',['[><]adm_role'=>['wdi_ar_id'=>'ar_id']],['wdi_wdlist_id','ar_name'=>raw('GROUP_CONCAT(DISTINCT ar_name)')],['wdi_wdlist_id'=>$wdlIds,'GROUP'=>'wdi_wdlist_id']);
			$roleArr = array_column($roleArr,null,'wdi_wdlist_id');
			foreach($arr as &$v){
				if($tj1[$v['wdlist_id']]) $v = array_merge($v, $tj1[$v['wdlist_id']]);
				if($tj2[$v['wdlist_id']]) $v = array_merge($v, $tj2[$v['wdlist_id']]);
				if($tj3[$v['wdlist_id']]) $v = array_merge($v, $tj3[$v['wdlist_id']]);
				if($tj4[$v['wdlist_id']]) $v = array_merge($v, $tj4[$v['wdlist_id']]);
				$v['captions']['wdlist_from_opuser'] = $v['au_name_from'];
				$v['captions']['wdlist_opuser'] = $v['au_name'];
				$v['captions']['wdlist_type'] = !empty($collArr[$v['wdlist_type']])? $collArr[$v['wdlist_type']]: '';

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

	public function formatWordDataCols($wdlist_id)
	{
		$row = $this->db->get('work_data_list', '*', ['wdlist_id'=>$wdlist_id]);
		$row['cols'] = json_decode($row['wdlist_cols'], true);
		return $row;
	}

	//数据工单的明细
	public function getDataItemList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		if(empty($params['sidx'])){
			$sidx = 'wdi_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 = 'work_data_item(wdi)';
		$join = [
			"[><]work_data_list(wdl)" => ["wdi.wdi_wdlist_id" => "wdlist_id"],
			"[>]pro_cate(cat)" => ["wdi.wdi_cat_id" => "id"],
			"[>]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]adm_role(ar)" => ["wdi.wdi_ar_id" => "ar_id"],
			"[>]adm_user(au)" => ["wdi.wdi_opuser" => "au_id"],
			"[>]adm_user(au2)" => ["wdi.wdi_from_opuser" => "au_id"],
		];
		
		$this->set('pnumwhere', []);
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'chkok'){
				$op = 'RAW_'.$field;
				if($data == 1){
					$data = raw(" wdi_chkpro_id!=0");
				}else{
					$data = raw(" wdi_chkpro_id=0");
				}
			}else if($field == 'wdi_chkpro_from'){
				if($data == 'oth'){
					$op = 'RAW_'.$field;
					$data = raw(" wdi_chkpro_from not in ('', 'selft')");
				}
			}else if($field == 'chknums'){
				if($op == 'eq'){
					$where = "wdif_search = '".formatNum($data)."'";
				}else if($op == 'bw'){
					$where = "wdif_search like '%".formatNum($data)."%'";
				}else{
					$where = "wdif_search like '".formatNum($data)."%'";
				}
				$op = 'RAW_'.$field;
				$data = raw(" wdi_id in (select wdif_wdi_id from work_data_item_format where wdif_type='Number' and ".$where.")");
			}else if($field == 'chk_poes'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" wdi_id not in (SELECT distinct wdif_wdi_id FROM work_data_item_format
						JOIN work_data_item ON wdi_id = wdif_wdi_id
						JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id)
					)");
				}else{
					$data = raw(" wdi_id in (SELECT distinct wdif_wdi_id FROM work_data_item_format
						JOIN work_data_item ON wdi_id = wdif_wdi_id
						JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id)
					)");
				}
			}else if($field == 'chk_pcs'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" wdi_id not in (
						SELECT distinct wdif_wdi_id FROM work_data_item_format
						JOIN work_data_item ON wdi_id = wdif_wdi_id
						JOIN pro_numidx ON wdif_pf_id=pn_pf_id AND wdif_search=pn_formart 
						JOIN pro ON p_id=pn_p_id and p_pb_id = 1
						WHERE (wdi_cat_id = 0 OR wdi_cat_id = p_cate)
					)");
				}else{
					$data = raw(" wdi_id in (
						SELECT distinct wdif_wdi_id FROM work_data_item_format
						JOIN work_data_item ON wdi_id = wdif_wdi_id
						JOIN pro_numidx ON wdif_pf_id=pn_pf_id AND wdif_search=pn_formart 
						JOIN pro ON p_id=pn_p_id and p_pb_id = 1
						WHERE (wdi_cat_id = 0 OR wdi_cat_id = p_cate)
					)");
				}
			}else if($field == 'chk_sups'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" wdi_id not in (
					SELECT DISTINCT wdif_wdi_id FROM work_data_item_format
					JOIN work_data_item ON wdi_id = wdif_wdi_id
					JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
					JOIN supplier_pro ON spr_oe_id=on_oe_id 
					WHERE wdif_type='Number' AND (wdi_cat_id = 0 OR wdi_cat_id = spr_cat_id)
					)");
				}else{
					$data = raw(" wdi_id in (SELECT DISTINCT wdif_wdi_id FROM work_data_item_format
					JOIN work_data_item ON wdi_id = wdif_wdi_id
					JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
					JOIN supplier_pro ON spr_oe_id=on_oe_id WHERE wdif_type='Number' AND (wdi_cat_id = 0 OR wdi_cat_id = spr_cat_id))");
				}
			}else if($field == 'cleandes_tcd'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw("JSON_CONTAINS_PATH(wdi_clean_result, 'one', '$.data.tcd') != 1");
				}else{
					$data = raw("JSON_CONTAINS_PATH(wdi_clean_result, 'one', '$.data.tcd') = 1");
				}
			}else if($field == 'cleandes_etk'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw("JSON_CONTAINS_PATH(wdi_clean_result, 'one', '$.data.etk') != 1");
				}else{
					$data = raw("JSON_CONTAINS_PATH(wdi_clean_result, 'one', '$.data.etk') = 1");
				}
			}else if($field == 'ar_name'){
				$field = 'RAW #ar_name';
				$data = raw(sprintf(" wdi_wdlist_id IN (select distinct wdi_wdlist_id from work_data_item join adm_role on wdi_ar_id=ar_id where ar_name like '%%%s%%')",$data));
			}else if($field == 'cat.'.cateName()){
				if($data == 'Y'){
					$op = 'RAW_'.$field;
					$data = raw(" wdi_cat_id > 0");
				}else if($data == 'N'){
					$op = 'RAW_'.$field;
					$data = raw(" wdi_cat_id = 0");
				}
			}
			
        });
		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'p_cate': $where['wdi_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['wdif_search'.($rules['numlike']? '[~]': '')] = $tnums;
					$join['[><]work_data_item_format(wdif)'] = ['wdi.wdi_id'=>'wdif_wdi_id'];
				break;
			}
		}
		
		if($params['wdlist_id']) $where['wdlist_id'] = $params['wdlist_id'];
		if(!empty($params['keys'])) $where['wdi_id'] = explode(',', $params['keys']);
		

		//无分配权限的，展示分配给自己的数据
		if(!\p::isAdmin() && !\p::has('A200','check1') ){
			$user = new user();
			$arids = $user->getMyPowerRole('A200', ['check2']);
			$where['wdi_ar_id'] = $arids? $arids: -1;
		}
		$cates = \p::cates('A200');
		if(!\p::isAdmin() && $cates){
			$where['AND #rule_cate']['wdi_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)', 'wdl.wdlist_id', 'wdl.wdlist_seq', 'wdi.*','ar_name', 'au.au_name', 'au2.au_name(au_name_from)'];
        $arr = $this->db->select($table,$join,$fields,$where);
		$wdlCols = $this->formatWordDataCols($wdlist_id);

		if(!empty($arr)){
			$wdiIds = array_column($arr, 'wdi_id');
			$join = [
				"[>]pro_factory(fac)" => ["wdif_pf_id" =>"pf_id"]
			];
			//$rows = $this->db->select('work_data_item_format', $join, ['wdif_wdi_id', 'wdif_id', 'pf_name', 'wdif_val', 'wdif_search'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdiIds, 'ORDER'=>['pf_name', 'wdif_search']]);
			$rows = $this->db->select('work_data_item_format', $join, '*', ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdiIds]);
			$nums = [];
			$tnums = [];
			foreach($rows as $rv){
				$nums[$rv['wdif_wdi_id']][] = ['wdif_id'=>$rv['wdif_id'], 'factory'=>$rv['pf_name'], 'number'=>$rv['wdif_val'], 'format'=>$rv['wdif_search'], 'ok'=>1, 'pf_id'=>$rv['pf_id'], 'wdif_isborrow'=>$rv['wdif_isborrow']];
				$tnums[] = $rv['wdif_search'];
			}
			
			//EDC
			$wdzyArr = [];
			if($tnums){
				$resource = new resource();
				$rows = $resource->getResourcesByNum(array_unique($tnums));
				//每个号码每个工厂只取一条
				foreach($rows as $row){
					$row['num_format'] = formatNum($row['rnumber']);
					if(empty($wdzyArr[$row['num_format']][$row['resourceFactoryId']]))
						$wdzyArr[$row['num_format']][$row['resourceFactoryId']] = $row;
				}
			}

			//存在的零件库
			$poes = [];
			$wdipoes = [];
			$sql = sprintf("SELECT wdif_id, wdif_wdi_id, oe_id, pf_name, oe_oe FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				JOIN pro_factory on pf_id = oe_pf_id
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id) AND wdif_wdi_id IN (%s)", implode(',', $wdiIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$poes[$rv['wdif_wdi_id']][$rv['oe_id']] = $rv;
					$wdipoes[$rv['wdif_id']] = $rv;
				}
			}
			
			//存在的供应商
			$sups = [];
			$wdisups = [];
			$supnameField = \p::has('C500','view')? 'sup_name': 'sup_code as sup_name';
			$supnameField2 = \p::has('C500','view')? 'sup_name': 'sup_code';
			$sql = sprintf("SELECT wdif_id, wdif_wdi_id,sup_id, %s,spr_id FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_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 wdif_type='Number' AND (wdi_cat_id = 0 OR wdi_cat_id = spr_cat_id) AND wdif_wdi_id IN (%s) group by wdif_id, sup_id ORDER BY o_sort,%s", $supnameField, implode(',', $wdiIds), $supnameField2);
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$sups[$rv['wdif_wdi_id']][$rv['sup_id']] = $rv;
					$wdisups[$rv['wdif_id']][] = $rv;
				}
			}


			//存在的商品库
			$pcs = [];
			$wdipcs = [];
			$sql = sprintf("SELECT wdif_id, wdif_wdi_id, p_id, p_innum p_innum FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN pro_numidx ON wdif_pf_id=pn_pf_id AND wdif_search=pn_formart 
				JOIN pro ON p_id=pn_p_id and p_pb_id = 1
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = p_cate) AND wdif_wdi_id IN (%s) group by wdif_id, p_id order by p_innum", implode(',', $wdiIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$pcs[$rv['wdif_wdi_id']][$rv['p_id']] = $rv;
					$wdipcs[$rv['wdif_id']][$rv['p_id']] = $rv;
				}
			}
		
			foreach($arr as &$v){
				$v['nums'] = $nums[$v['wdi_id']]? $nums[$v['wdi_id']]: [];
				$v['poes'] = $poes[$v['wdi_id']]? $poes[$v['wdi_id']]: [];
				$v['sups'] = $sups[$v['wdi_id']]? array_values($sups[$v['wdi_id']]): [];
				$v['pcs'] = $pcs[$v['wdi_id']]? array_values($pcs[$v['wdi_id']]): [];

				//文档资源
				$v['wdzy'] = [];
				foreach($v['nums'] as $nv){
					$numf = $nv['format'];
					if(empty($wdzyArr[$numf])) continue;
					foreach($wdzyArr[$numf] as $fac=>$row){
						if(!$v['wdzy'][$fac]){
							$v['wdzy'][$fac] = [
								'fac_resource_facid'=>$row['resourceFactoryName'], 
								'fac_name'=>$row['resourceFactoryName'], 
								'pro_name'=>$row['partName'], 
								'pro_number'=>$row['number'],
								'from_time'=>date('Y-m-d', strtotime($row['resourceProvideTime'])), 
							];
						}
					}
				}
				$v['wdzy'] = array_values($v['wdzy']);


				if(empty($v['wdi_chkpro_id'])) $v['wdi_chkpro_id'] = '';
				$v['chkok'] = $v['wdi_chkpro_from'] && $v['wdi_chkpro_id'] ? $v['wdi_chkpro_from'].'@'.$v['wdi_chkpro_id']: '';
				$cleanArr = empty($v['wdi_clean_result']) ? []: json_decode($v['wdi_clean_result'], true);
				$chkproArr = empty($v['wdi_chkpro_clean_result']) ? []: json_decode($v['wdi_chkpro_clean_result'], true);

				//哪些号码是异常的
				if($cleanArr['errnum'] && $v['nums']){
					foreach($v['nums'] as $tk=>$tv){
						foreach($cleanArr['errnum'] as $tvv){
							if($tvv['format'] == formatNum($tv['number'])){
								$v['nums'][$tk]['err'] = 1;
							}
						}
					}
				}

				//号码检测
				$combtn = count($v['nums']) > 1? '<a href="javascript:" class="blue" onclick="compareByYiparts(\'wdi_id='.$v['wdi_id'].'\')">比较</a>': '';
				$v['chknums'] = '<table class="table table-bordered YpTable chknums">
					<thead class="Filter Sortable">
						<tr>
							<th width="" class="Sort"><span>号码</span>&nbsp;&nbsp;&nbsp;'.$combtn.'</th>
							<th width="35px" class="Sort"><span>零件</span></th>
							<th width="35px" class="Sort"><span>供应</span></th>
							<th width="35px" class="Sort"><span>商品</span></th>
							<th width="35px" class="Sort" title="OE借用"><span>借用</span></th>
						</tr>
					</thead>
					<tbody>';
				foreach($v['nums'] as $tk=> $tv){
					
					$v['chknums'] .= '<tr>
						<td wdif-id="'.$tv['wdif_id'].'"><span class="num">'.($tv['factory']? $tv['factory'].': ' : '').$tv['number'].'</span>'.($tv['err']? ' <span class="red">[异常]</span>': '').'</td>
						<td>'.($wdipoes[$tv['wdif_id']]? 'Y': '').'</td>
						<td>'.($wdisups[$tv['wdif_id']]? count($wdisups[$tv['wdif_id']]): '').'</td>
						<td>'.($wdipcs[$tv['wdif_id']]? count($wdipcs[$tv['wdif_id']]): '').'</td>
						<td>'.($tv['pf_id'] == 1? '<input type="checkbox" class="isborrow" value="'.$tv['wdif_id'].'" '.($tv['wdif_isborrow']? ' checked': '').'/>': '').'</td>
					</tr>';
				}
		
				$v['chknums'] .= '</tbody></table>';

				$wdi_chkpro_info = empty($v['wdi_chkpro_info']) ? []: json_decode($v['wdi_chkpro_info'], true);
				$v['img'] = $wdi_chkpro_info['pro_img']? $wdi_chkpro_info['pro_img']: '';

				$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>';
				}

				$chkok_org = $chkproArr['pro']['art_show'] == 'org'? ' <span class="red">[人工]</span>': '';
				
				//数据清洗
				$v['cleandes_tcd'] = '';
				$v['captions']['wdi_chkpro_from'] = $this->proFrom[$v['wdi_chkpro_from']]? $this->proFrom[$v['wdi_chkpro_from']] : ($v['wdi_chkpro_from']? $this->proFrom['oth']: ''); 
				if(!empty($cleanArr['data'])){
					foreach(['tcd', 'etk'] as $type){
						if(empty($cleanArr['data'][$type])) continue;
						$tdata = $cleanArr['data'][$type];
						$v['cleandes_'.$type] = '<div class="cleandes cleandes-'.$type.'">';
						if($tdata['from'] == 'tcd'){//tcd源
							$v['cleandes_'.$type] .= '<ul class="ga-list">';
							foreach($tdata['ga_chk'] as $ctk=>$ctv){
								$prostpl = '';
								foreach($ctv['pros'] as $tpk=>$tpv){
									$valkey = $tdata['from'].'@'.$tpv['pro_id'];
									$prochk = $v['chkok'] == $valkey? ' checked': '';
									if($v['chkok'] == $valkey){
										$v['chkpro_url'] = $tpv['pro_url'];
										$v['captions']['chkok'] = '<div class="chkpro"><a href="'.$tpv['pro_url'].'" target="blank"><i class="fa fa-list-alt"></i></a>&nbsp;&nbsp;<a href="'.\mvc::$cfg['sitePath'].'/work/wdiDetail?wdi_id='.$v['wdi_id'].'" title="清洗详情" tab class="resetChkPro" data-id="'.$v['wdi_id'].'">'.$tpv['pro_factory'].': '.$tpv['pro_number'].'</a>'.$chkok_org.'</div>';
										$prochk .= ' haschkok="1"';
									}
									$prostpl .= '<li><label><input type="radio" name="pro['.$v['wdi_id'].']" value="'.$valkey.'"'.$prochk.'> <span>'.$tpv['pro_factory'].'</span></label>: <a href="'.$tpv['pro_url'].'" target="blank">'.$tpv['pro_number'].'</a></li>';
								}
								$v['cleandes_'.$type] .= '<li class="ga-item"><div class="ga-name"><i class="fa fa-search" aria-hidden="true" /></i> '.($ctv['ga_name_cn']? $ctv['ga_name_cn']: $ctv['ga_name']).'<b title="'.$tdata['from'].'产品数据">['.$ctv['pro_count'].'个]</b></div><ul class="ga-items">'.$prostpl.'</ul><div class="clear"></div></li>';
							}
							$v['cleandes_'.$type] .= '</ul>';
						}else{//其他数据源
							$v['cleandes_'.$type] .= '<ul class="pro-list">';
							$comnums = [];
							foreach($tdata['pros'] as $tpk=>$tpv){
								$valkey = $tdata['from'].'@'.$tpv['pro_id'];
								$prochk = $v['chkok'] == $valkey? ' checked': '';
								if($v['chkok'] == $valkey){
									$v['chkpro_url'] = $tpv['pro_url'];
									$v['captions']['chkok'] = '<div class="chkpro"><a href="'.$tpv['pro_url'].'" target="blank"><i class="fa fa-list-alt"></i></a>&nbsp;&nbsp;<a href="'.\mvc::$cfg['sitePath'].'/work/wdiDetail?wdi_id='.$v['wdi_id'].'" title="清洗详情" tab class="resetChkPro" data-id="'.$v['wdi_id'].'">'.$tpv['num'][0]['factory'].': '.$tpv['num'][0]['display'].'</a></div>';
									$prochk .= ' haschkok="1"';
								}
								$isnew = '';
								if($tdata['from'] == 'etk'){
									$tpv['pro_name'] = trim($tpv['grp1_name']).'<br>'.$tpv['grp2_name'].'<br>'.$tpv['pro_name'];
									if($tpv['isnew'] == -1) $isnew = '<span class="orange">【旧】</span>';
								}
								$v['cleandes_'.$type] .= '<li><div>'.$tpv['pro_name'].'</div><label><input type="radio" name="pro['.$v['wdi_id'].']" value="'.$valkey.'"'.$prochk.'> <span>'.$tpv['num'][0]['factory'].'</span></label>: <a href="'.$tpv['pro_url'].'" target="blank">'.$tpv['num'][0]['display'].'</a>'.$isnew;
								$comnums[] = 'OE:'.$tpv['num'][0]['display'];
								if($tdata['from'] == 'etk' && !empty($tpv['renum'])){
									$v['cleandes_'.$type] .= '<div>替换号<br>';
									foreach($tpv['renum'] as $tpk=>$tpv){
										$v['cleandes_'.$type] .= '<div>'.$tpv.($tpk === 0? '<span class="green">【新】</span>': '').'</div>';
										$comnums[] = 'OE:'.$tpv;
									}
									$v['cleandes_'.$type] .= '</div>';
								}
								$v['cleandes_'.$type] .= '</li>';
							}
							
							$v['cleandes_'.$type] .= '</ul>';
							$comnums = array_unique($comnums);
							if(count($comnums) > 1) $v['cleandes_'.$type] .= '<a <a href="javascript:" onclick="compareByYiparts(\'type=out&nums='.implode(',', $comnums).'\')">比较</a>';
						}
						$v['cleandes_'.$type] .= '</div>';
					}
					if($v['chkok_para']) $v['captions']['chkok'] .= $v['chkok_para'];
				}

				$v['captions']['wdzy'] = '';
				if($v['wdzy']){
					$turl = "javascript:qg.page.open('EDC', '".\mvc::$cfg['sitePath']."pro/sourceSearch?nums=".implode(',', array_column($v['nums'], 'number'))."&type=num')";
					$v['captions']['wdzy'] .= '<div><a href="'.$turl.'">查询明细</a></div>
					<ul class="wdzylist">';
					foreach($v['wdzy'] as $tpv){	
						$v['captions']['wdzy'] .= '<li><div>'.$tpv['fac_name'].'</div>';
						if($tpv['pro_name']) $v['captions']['wdzy'] .= '<div>名称: '.$tpv['pro_name'].'</div>';
						//if($tpv['pro_number']) $v['captions']['wdzy'] .= '<div>号码: '.$tpv['pro_number'].'</div>';
						$v['captions']['wdzy'] .= '</li>';
					}
					$v['captions']['wdzy'] .= '</ul>';
				}
				$v['captions']['wdi_from_opuser'] = $v['au_name_from'];
				$v['captions']['wdi_opuser'] = $v['au_name'];

				if($params['isExport'])
				{	
					//跳过图片列
					if(!$params['skipImageColumn'])
					{
						$temp = $v['img'];
						unset($v['img']);

						$imgPath = tempnam(sys_get_temp_dir(), 'excel_img_'.md5($temp));
						// 检查文件是否存在且可访问
						$headers = @get_headers($temp);
						if($headers && strpos($headers[0], '200') !== false) {
							$contents = file_get_contents($temp);
							if($imgPath && file_exists($imgPath) && $contents){
								file_put_contents($imgPath,$contents);
								
							}
						}
						$v['img'] = [];
						$v['img']['type'] = 'image';
						$v['img']['filename'] = $imgPath;
						list($width, $height, $type, $attr) = getimagesize($v['img']['filename']);
						$v['img']['rowHeight'] = 80;
						$v['img']['widthScale'] = 1;
						$v['img']['heightScale'] = 1;
						if($height>80){
							// 保持图片在合理范围内 (60-100像素高度)
							$maxHeight = 100;
							$minHeight = 60;
							
							// 根据宽高比调整目标高度
							$aspectRatio = $width / $height;
							
							// 竖图使用较高值，横图使用较低值
							if($aspectRatio < 1) {  // 竖图
								$targetHeight = min($maxHeight, max($minHeight, 90));
							} else if($aspectRatio > 2) {  // 很宽的横图
								$targetHeight = min($maxHeight, max($minHeight, 65));
							} else {  // 普通比例
								$targetHeight = min($maxHeight, max($minHeight, 80));
							}
							
							// 计算统一的缩放比例
							$scale = $targetHeight / $height;
							
							$v['img']['widthScale'] = $scale;
							$v['img']['heightScale'] = $scale;
							$v['img']['rowHeight'] = $targetHeight;
						}
					}
					
					
					//零件库检测
					$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['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']);
					}

					$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['wdi_chkpro_clean_result']) ? []: json_decode($v['wdi_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'];
						}
						
					}
					$v['captions']['chkok'] =implode("\n", $v['captions']['chkok']);
					
					
				}

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


	//数据工单详情
	public function getWdiDetail($wdi_id)
	{
		$join = ["[>]pro_cate(cat)" => ["wdi.wdi_cat_id"=>"id"]];
		$arr = $this->db->get('work_data_item(wdi)', $join, ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model', 'wdi.*'], ['wdi_id'=>$wdi_id]);
		if(empty($arr)) exitJson('记录不存在');
		$join = [
				"[>]pro_factory(fac)" => ["wdif_pf_id" =>"pf_id"]
		];
		$arr['isborrow'] = 0;
		$rows = $this->db->select('work_data_item_format', $join, '*', ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdi_id]);
		foreach($rows as $rv){
			$arr['wdi_nums'] = ['factory'=>$rv['pf_name'], 'number'=>$rv['wdif_val'], 'format'=>$rv['wdif_search'], 'wdif_isborrow'=>$rv['wdif_isborrow']];
			if($rv['wdif_isborrow']) $arr['isborrow'] = 1;
		}
		
		$arr['cleans'] = empty($arr['wdi_chkpro_clean_result'])? []:json_decode($arr['wdi_chkpro_clean_result'], true);
		$arr['chkpro'] = empty($arr['wdi_chkpro_info'])? []:json_decode($arr['wdi_chkpro_info'], true);
		$arr['cleans_chk'] = empty($arr['wdi_chkpro_clean_chk'])? []:json_decode($arr['wdi_chkpro_clean_chk'], true);
		$arr['clean_by'] = empty($arr['wdi_chkpro_clean_by'])? []:json_decode($arr['wdi_chkpro_clean_by'], true);
		$carmodel = new carmodel();
		foreach(['model', 'model_oknum'] as $type){
			if(!empty($arr['cleans'][$type])){
				$has = array_column($arr['cleans'][$type], null, 'mm_id');
				$res = $carmodel->getModel(['mm_ids'=>array_unique(array_column($arr['cleans'][$type], 'mm_id'))]);
				$merge = [];
				foreach($res['models'] as $k=>$v){
					if($has[$v['mm_id']]){
						$v = array_merge($v, $has[$v['mm_id']]);
					}
					$merge[] = $v;
				}
				$arr['cleans'][$type] = $merge;
			}
		}

		//参考号
		$arr['matchOes'] = [];
		foreach(['num', 'othnum'] as $type){
			if(empty($arr['cleans'][$type])) continue;
			foreach($arr['cleans'][$type] as $key=>$row){
				$twhere = $arr['wdi_cat_id'] > 0? ' and oe_cate_id='.$arr['wdi_cat_id']: '';
				$sql = sprintf("SELECT oe_id, fac.pf_name, oe_oe, oe_cate_id FROM oe_numidx
				JOIN oe_item ON on_oe_id=oe_id 
				JOIN pro_factory fac on fac.pf_id = oe_pf_id
				JOIN pro_factory fac2 on fac2.pf_id = on_pf_id
				WHERE on_formart = '%s' and fac2.pf_name = '%s' %s group by oe_id", $row['format'], ($row['oe']? 'OE': $row['brand']), $twhere);
				$row['poes'] = $this->db->query($sql)->fetchAll();
				if($row['poes']){
					$arr['matchOes'] = array_merge($arr['matchOes'], $row['poes']);
				}
				$arr['cleans'][$type][$key] = $row;
			}
		}

		$sql = sprintf("SELECT oe_id, fac.pf_name, oe_oe, oe_cate_id FROM work_data_item_format
			JOIN work_data_item ON wdi_id = wdif_wdi_id
			JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
			JOIN oe_item ON on_oe_id=oe_id
			JOIN pro_factory fac on fac.pf_id = oe_pf_id
			WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id) AND wdi_id=%d group by oe_id", $wdi_id);
		$rows = $this->db->query($sql)->fetchAll();
		if($rows){
			$arr['matchOes'] = array_merge($arr['matchOes'], $rows);
		}
		$arr['matchOes'] = array_values(array_column($arr['matchOes'], null, 'oe_id'));
		
		
		//替换号
		$oes = $this->getWorkItemOes($arr);
		if(!empty($oes)){
			$ypApi = new ypApi();
			$res = $ypApi->Get('etk/getReplaceNumber', ['number'=>implode(',', $oes)]);
			$arr['cleans']['replace'] = $res['data'];
		}
		
		if(!empty($arr['cleans']['cnmodelids'])){
			$cnmodelchk = [];
			if($arr['cleans_chk']['cnmodelids']){
				$cnmodelchk = $arr['cleans_chk']['cnmodelids'];
			}else{
				$cnmodelchk = $arr['cleans']['cnmodelids'];
			}

			$carmodelcn = new carmodelcn();
			$res = $carmodelcn->getModelList(['keys'=>$arr['cleans']['cnmodelids']]);
			foreach($res['rows'] as $row){
				$row['checked'] = in_array($row['mod3_id'], $cnmodelchk);
				$arr['cleans']['cnmodel'][] = $row;
			}
		}
		return $arr;
	}
	
	//保存数据工单详情
	public function saveWdiDetail($wdi_id, $dataArr)
	{
		$setArr = [];
		if(isset($dataArr['base'])) $setArr['wdi_oeitem'] = json_encode($dataArr['base'], JSON_UNESCAPED_UNICODE);
		if(isset($dataArr['base']['wdi_cat_id'])) $setArr['wdi_cat_id'] = $dataArr['base']['wdi_cat_id'];
		if(isset($dataArr['qingxi'])){
			if(!isset($dataArr['qingxi']['num_ok_chk'])) $dataArr['qingxi']['num_ok_chk'] = [];
			if(!isset($dataArr['qingxi']['num_no_chk'])) $dataArr['qingxi']['num_no_chk'] = [];
			if(!isset($dataArr['qingxi']['othnum_ok_chk'])) $dataArr['qingxi']['othnum_ok_chk'] = [];
			if(!isset($dataArr['qingxi']['model_chk'])) $dataArr['qingxi']['model_chk'] = [];
			if(!isset($dataArr['qingxi']['model_oknum_chk'])) $dataArr['qingxi']['model_oknum_chk'] = [];
			$setArr['wdi_chkpro_clean_chk'] = json_encode($dataArr['qingxi'], JSON_UNESCAPED_UNICODE);
		}
		if(!empty($setArr)){
			$opuser = getOpuser();
			$datetime = getNowTime();
			$setArr['wdi_opuser'] = $opuser;
			$setArr['wdi_update_time'] = $datetime;
			$this->db->update('work_data_item', $setArr, ['wdi_id'=>$wdi_id]);
		}
		return $this->workItemToPoeItem(['ids'=>$wdi_id, 'oe_id'=>$dataArr['oe_id']]);
	}

	//批量清洗检测
	public function cleanWorkData($req)
	{
		set_time_limit(0);
		$where = [];
		if(!empty($req['ids'])){
			$where = ['wdi_id'=>explode(',', $req['ids'])];
		}else if(!empty($req['wdlist_id'])){
			$where = ['wdi_wdlist_id'=>explode(',', $req['wdlist_id'])];
		}
		if($req['cleantype'] == 'no') $where['wdi_clean[!]'] = 1;
		$wdiIds = $this->db->select('work_data_item', 'wdi_id', $where);
		if(!empty($wdiIds)){
			foreach($wdiIds as $wdi_id){
				$this->cleanDataItem($wdi_id);
			}
		}
		$this->cleanWorkChkOkPro($wdiIds);
		return [];
	}


	//清洗单条数据
	public function cleanDataItem($wdi_id)
	{
		set_time_limit(0);
		$arr = [];
		$join = [
			"[>]pro_cate(cat)" => ["wdi.wdi_cat_id"=>"id"]
		];
		$wdiArr = $this->db->get('work_data_item(wdi)', $join, ['wdi.*', 'cat.cn_name(cat_cn_name)', 'cat.en_name(cat_en_name)', 'tcd_name', 'cat_tcdfac'], ['wdi_id'=>$wdi_id]);
		if(empty($wdiArr)) return $arr;
		
		//已有号码
		$join = ["[>]pro_factory(fac)" => ["wdif_pf_id" =>"pf_id"]];
		$nums = $this->db->select('work_data_item_format', $join, ['pf_name(factory)', 'wdif_search(number)'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdi_id]);	

		//宜配检测
		$apiPost = [
			'number'=>json_encode($nums, JSON_UNESCAPED_UNICODE),
			'facseq'=>$wdiArr['cat_tcdfac'],
			'ganame'=>$wdiArr['tcd_name']
		];
		
		$ypApi = new ypApi();
		$chkres = $ypApi->Get('tcd/checkNumberData', [], $apiPost);
		$chkdata = $chkres['status']? $chkres['data']: [];

		$setArr = [
			'wdi_clean'=>1,	
			'wdi_clean_has'=>empty($chkdata['data'])? -1: 1,	
			'wdi_clean_result'=>json_encode($chkdata, JSON_UNESCAPED_UNICODE),
			'wdi_clean_time'=>getNowTime()
		];

		//确认的参考数据是否在清洗数据中
		if(!empty($wdiArr['wdi_chkpro_id'])){
			$exists = false;
			if(!empty($chkdata['data'][$wdiArr['wdi_chkpro_from']])){
				$tdata = $chkdata['data'][$wdiArr['wdi_chkpro_from']];
				if($tdata['from'] == 'tcd'){
					foreach($tdata['ga_chk'] as $ctk=>$ctv){	
						foreach($ctv['pros'] as $tpk=>$tpv){
							if($tpv['pro_id'] == $wdiArr['wdi_chkpro_id']){
								$tpv['from'] = $tdata['from'];
								$tpv['ga_name'] = $ctv['ga_name'];
								$tpv['ga_name_cn'] = $ctv['ga_name_cn'];
								$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
								$exists = true;
								break;
							}
						}
						if($exists) break;
					}
				}else if(!empty($tdata['pros'])){
					foreach($tdata['pros'] as $tpk=>$tpv){
						if($tpv['pro_id'] == $wdiArr['wdi_chkpro_id']){
							$tpv['from'] = $tdata['from'];
							$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
							$exists = true;
							break;
						}
					}
				}
			}
			if(!$exists){
				$setArr['wdi_chkpro_from'] = '';
				$setArr['wdi_chkpro_id'] = 0;
				$setArr['wdi_chkpro_info'] = '[]';
				$setArr['wdi_chkpro_clean'] = -1;
				$setArr['wdi_chkpro_clean_has'] = -1;
				$setArr['wdi_chkpro_clean_result'] = '[]';
				$setArr['wdi_chkpro_clean_chk'] = '[]';
				$setArr['wdi_chkpro_clean_time'] = null;
				$wdiArr = array_merge($wdiArr, $setArr);
			}
		}
		
		if(!empty($chkdata['data']) && empty($wdiArr['wdi_chkpro_id'])){
			foreach(['tcd', 'etk'] as $type){
				if(empty($chkdata['data'][$type])) continue;
				$tdata = $chkdata['data'][$type];
				$setArr['wdi_chkpro_from'] = $tdata['from'];
				if($tdata['from'] == 'tcd'){
					$ctv = $tdata['ga_chk'][0];
					$tpv = $ctv['pros'][0];
					$tpv['from'] = 'tcd';
					$tpv['ga_name'] = $ctv['ga_name'];
					$tpv['ga_name_cn'] = $ctv['ga_name_cn'];
					$setArr['wdi_chkpro_id'] = $tpv['pro_id'];
					$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
				}else{
					$tpv = $tdata['pros'][0];
					$tpv['from'] = $tdata['from'];
					$setArr['wdi_chkpro_id'] = $tpv['pro_id'];
					$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
				}
				$wdiArr = array_merge($wdiArr, $setArr);
				break;
			}
		}
		$this->db->update('work_data_item', $setArr, ['wdi_id'=>$wdiArr['wdi_id']]);

		if(empty($wdiArr['wdi_cat_id'])) $this->autoCleanCat(['ids'=>$wdi_id]);

		return [];
	}

	//通过小类匹配清洗数据的分类ID
	public function autoCleanCat($req)
	{
		set_time_limit(0);
		$where = ['wdi_cat_id'=>0];
		if(!empty($req['ids'])){
			$where['wdi_id'] = is_array($req['ids'])? $req['ids']: explode(',', $req['ids']);
		}else if(!empty($req['wdlist_id'])){
			$where['wdi_wdlist_id'] = explode(',', $req['wdlist_id']);
		}
		$items = $this->db->select('work_data_item', ['wdi_id', 'wdi_chkpro_info', 'wdi_cat_id'], $where);
		$cate = new cate();
		foreach($items as $wdiArr){
			$setArr = [];

			//检测产品库
			$join = [
				"[><]pro_numidx(pn)" => ["wdif.wdif_pf_id"=>"pn_pf_id", "wdif.wdif_search"=>'pn_formart'],
				"[><]pro(p)" => ["pn.pn_p_id"=>"p_id"],
			];
			$hasPro = $this->db->get('work_data_item_format(wdif)', $join, ['p_cate'], ['p_pb_id'=>1, 'wdif_wdi_id'=>$wdiArr['wdi_id']]);
			if(!empty($hasPro)){
				$setArr['wdi_cat_id'] = $hasPro['p_cate'];
			}

			//零件库本身
			if(empty($setArr['wdi_cat_id'])){
				$join = [
					"[><]oe_numidx(pn)" => ["wdif.wdif_pf_id"=>"on_pf_id", "wdif.wdif_search"=>'on_formart'],
					"[><]oe_item(pro)" => ["pn.on_oe_id"=>"oe_id"],
				];
				$hasPro = $this->db->get('work_data_item_format(wdif)', $join, ['oe_cate_id(p_cate)'], ['wdif_wdi_id'=>$wdiArr['wdi_id']]);
				if(!empty($hasPro)){
					$setArr['wdi_cat_id'] = $hasPro['p_cate'];
				}
			}

			if(empty($setArr['wdi_cat_id']) && $wdiArr['wdi_chkpro_info']){
				$chkpro = $wdiArr['wdi_chkpro_info']? json_decode($wdiArr['wdi_chkpro_info'], true) : [];
				if($chkpro['from'] == 'tcd'){
					$catenames = $chkpro['ga_name'] ? [$chkpro['ga_name'], $chkpro['ga_name_cn']]: [$chkpro['pro_name']];
				}else{
					$catenames = [$chkpro['pro_name']];
				}
				foreach($catenames as $catename){
					if(empty($catename)) continue;
					$tid = $cate->eqname($catename);
					if(!empty($tid)){
						$setArr['wdi_cat_id'] = $tid;
						break;
					}else{
						$tids = $cate->eqnameByTcd($catename);
						if($tids && count($tids) == 1){
							$setArr['wdi_cat_id'] = $tids[0];
							break;
						}
					}
				}
			}
			if($setArr){
				$this->db->update('work_data_item', $setArr, ['wdi_id'=>$wdiArr['wdi_id']]);
			}
		}
		return [];
	}


	//清洗数据单明细确认的产品数据
	public function cleanWorkChkOkPro($idArr)
	{
		set_time_limit(0);
		if(empty($idArr)) return [];
		$join = [
			"[>]pro_cate(cat)" => ["wdi_cat_id" => "id"]
		];
		$items = $this->db->select('work_data_item', $join, '*', ['wdi_id'=>$idArr, 'wdi_chkpro_from'=>['tcd', 'etk']]);
		if(empty($items)) return [];
			
		$ypApi = new ypApi();
		$carmodel = new carmodel();
		$collocation = new collocation();
		foreach($items as $row){
			$chkCleanArr = $row['wdi_clean_result'] ? json_decode($row['wdi_clean_result'], true): [];
			$oeitemArr = $row['wdi_oeitem'] ? json_decode($row['wdi_oeitem'], true): [];
			$row['wdi_chkpro_clean_chk'] = $row['wdi_chkpro_clean_chk'] ? json_decode($row['wdi_chkpro_clean_chk'], true): [];
			$chkdata = [];
			$apiPost = [];
			if($row['wdi_chkpro_from'] == 'tcd'){
				$apiPost = [
					'art_id'=>$row['wdi_chkpro_id'],
					'rate_number'=>$row['cat_rate_number'],
					'rate_model'=>$row['cat_rate_model'],
				];
				$chkres = $ypApi->Get('tcd/cleanData', [], $apiPost);
				$chkdata = $chkres['status']? $chkres['data']: [];
				
				//typ_id 转 mm_id
				foreach(['model', 'model_oknum'] as $type){
					if(empty($chkdata[$type])) continue;
					$typids = array_column($chkdata[$type], 'typ_id');
					$tvals = $this->db->select('m_model', ['mm_yptyp_id', 'mm_id'], ['mm_yptyp_id'=>$typids]);
					$typTomm = array_column($tvals, 'mm_id', 'mm_yptyp_id');
					foreach($chkdata[$type] as $tk=>$tv){
						$chkdata[$type][$tk]['mm_id'] = (int) $typTomm[$tv['typ_id']];
					}
				}
			}else if($row['wdi_chkpro_from'] == 'etk'){
				if(!empty($chkCleanArr['data']['etk'])){
					foreach($chkCleanArr['data']['etk']['pros'] as $tpk=>$tpv){
						if($row['wdi_chkpro_id'] != $tpv['pro_id']) continue;
						$chkres = $ypApi->Get('etk/cleanData', ['etk_id'=>$tpv['etk_id'], 'pro_id'=>$tpv['pro_id'], 'grp2_id'=>$tpv['grp2_id']]);
						if(!empty($chkres['data'])){
							$chkdata = $chkres['data'];
							$chkdata = array_merge($chkdata, $tpv);
						}
					}
				}
			}

			$setArr = [
				'wdi_chkpro_clean'=>1,
				'wdi_chkpro_clean_by'=>json_encode($apiPost, JSON_UNESCAPED_UNICODE),
				'wdi_chkpro_clean_result'=>json_encode($chkdata, JSON_UNESCAPED_UNICODE),
				'wdi_chkpro_clean_time'=>getNowTime()
			];

			$makeNames = [];

			//填充简单清晰的缺失数据
			if(!empty($chkdata['pro'])){
				if($row['wdi_chkpro_clean_chk']['art_id'] != $chkdata['pro']['art_id']){
					$setArr['wdi_chkpro_clean_chk'] = '[]'; 
				}
				if(empty($oeitemArr['oe_cn_name']) && !empty($chkdata['pro']['ga_name_cn'])) $oeitemArr['oe_cn_name'] = $chkdata['pro']['ga_name_cn'];
				if(empty($oeitemArr['oe_en_name']) && !empty($chkdata['pro']['ga_name'])) $oeitemArr['oe_en_name'] = $chkdata['pro']['ga_name'];
				//汽车生产商
				if(!empty($chkdata['ok_typids'])){
					$join = ["[><]m_make(mk)" => ["mm.mm_mk_id" => "mk_id"]];
					$rows = $this->db->select('m_model(mm)',$join, 'mk_'.LG_NAME, ['mm_yptyp_id'=>$chkdata['ok_typids'], 'GROUP'=>['mk_id']]);
					if($rows) $makeNames = $rows;
				}
			}
			$setArr['wdi_oeitem'] = json_encode($oeitemArr, JSON_UNESCAPED_UNICODE); 
			
			//提取号码获取中国车型
			$wdiArr = array_merge($row, $setArr);
			$res = $this->getWorkItemOes($wdiArr, $chkdata['pro']['art_show'] == 'org', false);
			$oenums = [];
			foreach($res as $tv){
				$oenums[] = ['factory'=>'OE', 'number'=>$tv];
			}

			$setEtkNull = false;
			if($oenums){
				$ypApi = new ypApi();
				$res = $ypApi->Get('number/getModelByNumber', ['number'=>implode(',', array_column($oenums, 'number'))]);
				if(!empty($res['data'])){
					$chkdata['cnmodelids'] = $res['data'];
					$rows = $this->db->select('m_cn_model', 'make_name', ['mod3_id'=>$chkdata['cnmodelids'], 'GROUP'=>'make_id']);
					if($rows) $makeNames = array_merge($makeNames, $rows);
				}
				
				//如果当前确认数据是TCD，没有EPC数据，重新清洗
				if($row['wdi_chkpro_from'] == 'tcd' && (empty($chkCleanArr['data']['etk']) || $chkCleanArr['data']['etkby'] == 'tcdoe')){
					$apiPost = ['type'=>'etk', 'number'=>json_encode($oenums, JSON_UNESCAPED_UNICODE)];
					$ypApi = new ypApi();
					$res = $ypApi->Get('tcd/checkNumberData', [], $apiPost);
					if($res['data']['data']['etk']){
						$chkCleanArr['data']['etk'] = $res['data']['data']['etk'];
						$chkCleanArr['data']['etkby'] = 'tcdoe';
						$setArr['wdi_clean_result'] = json_encode($chkCleanArr, JSON_UNESCAPED_UNICODE);
					}else{
						$setEtkNull = true;
					}
				}
			}else if($chkCleanArr['data']['etkby'] == 'tcdoe'){
				$setEtkNull = true;
			}
			if($setEtkNull){
				unset($chkCleanArr['data']['etk']);
				unset($chkCleanArr['data']['etkby']);
				$setArr['wdi_clean_result'] = json_encode($chkCleanArr, JSON_UNESCAPED_UNICODE);
			}

			$makeNames = array_unique($makeNames);
			sort($makeNames);
			$setArr['wdi_modmake'] = implode(',', $makeNames);

			$setArr['wdi_chkpro_clean_has'] = empty($chkdata)? -1: 1;
			$setArr['wdi_chkpro_clean_result'] = json_encode($chkdata, JSON_UNESCAPED_UNICODE);
			
			$this->db->update('work_data_item', $setArr, ['wdi_id'=>$row['wdi_id']]);
		}
		return [];
	}
	
	//仅仅获取确认产品单的OE号码
	public function getWorkItemOes($wdiArr, $all = false, $cleanetk = true){
		if(isset($wdiArr['wdi_chkpro_clean_result'])){
			$cleanArr = json_decode($wdiArr['wdi_chkpro_clean_result'], true);
			if(is_array($wdiArr['wdi_chkpro_clean_chk'])){
				$cleanChkArr = $wdiArr['wdi_chkpro_clean_chk'];
			}else{
				$cleanChkArr = empty($wdiArr['wdi_chkpro_clean_chk'])? []:json_decode($wdiArr['wdi_chkpro_clean_chk'], true);
			}
			$chkproInfoArr = empty($wdiArr['wdi_chkpro_info'])? []:json_decode($wdiArr['wdi_chkpro_info'], true);
		}else if(is_array($wdiArr['cleans'])){
			$cleanArr = $wdiArr['cleans'];
		}
		$oes = [];
		//导入的号码
		$rows = $this->db->select('work_data_item_format', ['wdif_val'], ['wdif_type'=>'Number', 'wdif_pf_id'=>1, 'wdif_wdi_id'=>$wdiArr['wdi_id']]);
		foreach($rows as $tv){
			$oes[] = $tv['wdif_val'];
		}

		//是否包含清洗结果的EPC的第一个号码
		if($cleanetk){
			$cleanResArr = empty($wdiArr['wdi_clean_result'])? []:json_decode($wdiArr['wdi_clean_result'], true);
			if($cleanResArr['data']['etk']['pros'][0]['num']){
				$oes[] = $cleanResArr['data']['etk']['pros'][0]['num'][0]['display'];
			}
		}
	
		//替换号
		$strNumArr = [];
		if(isset($cleanChkArr['replace'])){
			$strNumArr['replace'] = $cleanChkArr['replace'];
		}else if(!empty($chkproInfoArr['renum'])){
			$strNumArr['replace'] = implode(',', $chkproInfoArr['renum']);
		}else if(!empty($cleanArr['replace'])){
			$strNumArr['replace'] = implode(',', array_column($cleanArr['replace'], 'display'));
		}
		foreach($strNumArr as $type=>$strNums){
			$tnums = strtr($strNums, ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
			foreach(explode(',', $tnums) as $tv){
				if(empty($tv)) continue;
				$tvs = explode(':', $tv);
				if(count($tvs) == 1){
					$oes[] = $tvs[0];
				}else if(count($tvs) >= 2){
					if($tvs[0] == 'OE') $oes[] = $tvs[1];
				}
			}
		}
		
		//参考号
		foreach(['num', 'othnum'] as $type){
			if(empty($cleanArr[$type])) continue;
			foreach($cleanArr[$type] as $row){
				if($all){
					if($row['oe'] == 'OE') $oes[] = $row['display'];
				}else{
					if(
						(isset($cleanChkArr[$type.'_ok_chk']) && in_array($row['unikey'], $cleanChkArr[$type.'_ok_chk'])) || 
						($cleanArr['pro']['art_show'] != 'org' && !isset($cleanChkArr[$type.'_ok_chk']) && $row['ok']) || 
						(isset($cleanChkArr[$type.'_no_chk']) && in_array($row['unikey'], $cleanChkArr[$type.'_no_chk']))
					){
						if($row['oe'] == 'OE') $oes[] = $row['display'];
					}
				}
			}
		}
		return array_unique($oes);

	}


	//结合确认参考的清洗数据 提取号码车型信息
	public function getWorkOeFormat($wdiArr)
	{
		$cleanArr = empty($wdiArr['wdi_chkpro_clean_result'])? []:json_decode($wdiArr['wdi_chkpro_clean_result'], true);
		if(is_array($wdiArr['wdi_chkpro_clean_chk'])){
			$cleanChkArr = $wdiArr['wdi_chkpro_clean_chk'];
		}else{
			$cleanChkArr = empty($wdiArr['wdi_chkpro_clean_chk'])? []:json_decode($wdiArr['wdi_chkpro_clean_chk'], true);
		}
		$chkproInfoArr = empty($wdiArr['wdi_chkpro_info'])? []:json_decode($wdiArr['wdi_chkpro_info'], true);
		$factory = new factory();
		$carmodel = new carmodel();
		$addNums = [];
		
		//导入的号码
		$numBorrow = 0; //有一个借用则清洗出来的OE全部是借用
		$rows = $this->db->select('work_data_item_format', ['wdif_pf_id', 'wdif_val', 'wdif_isborrow'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdiArr['wdi_id']]);
		foreach($rows as $tv){
			$addNums[] = [
				'on_pf_id'=>$tv['wdif_pf_id'],
				'on_number'=>$tv['wdif_val'],
				'on_isborrow'=>$tv['wdif_isborrow'],
				'on_mk_id'=>[],
				'on_from'=>99
			];
			if($tv['wdif_isborrow']) $numBorrow = 1;
		}

		$strNumArr = [];
		if($cleanArr['pro']['art_show'] != 'org' && $chkproInfoArr['pro_number']){
			//$strNumArr['chkpro'] = $chkproInfoArr['pro_factory'].':'.$chkproInfoArr['pro_number'];
		}

		//替换号
		if(isset($cleanChkArr['replace'])){
			$strNumArr['replace'] = $cleanChkArr['replace'];
		}else{
			$oes = $this->getWorkItemOes($wdiArr);
			if(!empty($oes)){
				$ypApi = new ypApi();
				$res = $ypApi->Get('etk/getReplaceNumber', ['number'=>implode(',', $oes)]);
				$strNumArr['replace'] = implode(',', array_column($res['data'], 'display'));
			}
		}

		//EPC的第一个号码
		$cleanResArr = empty($wdiArr['wdi_clean_result'])? []:json_decode($wdiArr['wdi_clean_result'], true);
		if($cleanResArr['data']['etk']['pros'][0]['num']){
			$strNumArr['replace'] .= ','.$cleanResArr['data']['etk']['pros'][0]['num'][0]['display'];
		}
		
		foreach($strNumArr as $type=>$strNums){
			$tnums = strtr($strNums, ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
			foreach(explode(',', $tnums) as $tv){
				if(empty($tv)) continue;
				$tvs = explode(':', $tv);
				if(count($tvs) == 1){
					$addNums[] = [
						'on_pf_id'=>1,
						'on_number'=>$tvs[0],
						'on_mk_id'=>[],
						'on_from'=>in_array($type, ['chkpro', 'replace'])? 100: 99
					];
				}else if(count($tvs) >= 2){
					$pfid = $tvs[0] == 'OE'? 1: $factory->getFacId($tvs[0], 'add');
					$mkid = $tvs[2]? $carmodel->getOeMakeIds($tvs[2]): '';
					$addNums[] = [
						'on_pf_id'=>$pfid,
						'on_number'=>$tvs[1],
						'on_mk_id'=>$mkid? explode(',',$mkid): [],
						'on_from'=>in_array($type, ['chkpro', 'replace'])? 100: 99
					];
				}
			}
		}

		foreach(['num', 'othnum'] as $type){
			if(empty($cleanArr[$type])) continue;
			foreach($cleanArr[$type] as $row){
				if(
					(isset($cleanChkArr[$type.'_ok_chk']) && in_array($row['unikey'], $cleanChkArr[$type.'_ok_chk'])) || 
					($cleanArr['pro']['art_show'] != 'org' && !isset($cleanChkArr[$type.'_ok_chk']) && $row['ok']) || 
					(isset($cleanChkArr[$type.'_no_chk']) && in_array($row['unikey'], $cleanChkArr[$type.'_no_chk']))
				){
					$pfid = $row['oe'] == 'OE'? 1: $factory->getFacId($row['brand'], 'add');
					$mkid = $row['oe'] == 'OE'? $carmodel->getOeMakeIds($row['brand']): '';
					$addNums[] = [
						'on_pf_id'=>$pfid,
						'on_number'=>$row['display'],
						'on_mk_id'=>$mkid? explode(',',$mkid): [],
						'on_from'=>100
					];
				}
			}
		}
		
		//本身去重
		$uniTempNumArr = [];
		foreach($addNums as $add){
			$add['on_formart'] = formatNum($add['on_number']);
			if(empty($add['on_pf_id']) || empty($add['on_number'])) continue;
			$unikey = $add['on_pf_id'].'@'.$add['on_formart'];
			if(!$uniTempNumArr[$unikey]) $uniTempNumArr[$unikey] = $add;
			if(!empty($add['on_mk_id'])){
				$uniTempNumArr[$add['on_pf_id'].'@'.$add['on_formart']]['on_mk_id'] = array_unique(array_merge($uniTempNumArr[$add['on_pf_id'].'@'.$add['on_formart']]['on_mk_id'], $add['on_mk_id']));
			}
		}

		foreach($uniTempNumArr as $k=>$v){
			if(!isset($v['on_isborrow'])){
				$uniTempNumArr[$k]['on_isborrow'] = $numBorrow && $v['on_pf_id'] == 1? 1: 0;
			}
			$uniTempNumArr[$k]['on_number'] = trim($v['on_number']);
			$uniTempNumArr[$k]['on_mk_id'] = trim(implode(',', $v['on_mk_id']), ',');
		}

		//车型
		$modArr = [];
		if($cleanArr['pro']['art_show'] == 'org'){
			$type = 'model';
			if($cleanArr[$type]){
				foreach($cleanArr[$type] as $row){
					if(!empty($modArr[$row['mm_id']])) continue;
					if((isset($cleanChkArr[$type.'_chk']) && in_array($row['mm_id'], $cleanChkArr[$type.'_chk']))){
						$modArr[$row['mm_id']] = [
							'oml_mm_id'=>$row['mm_id'],	
							'oml_para'=>is_array($row['para'])? json_encode($row['para'], JSON_UNESCAPED_UNICODE): '[]',
							'oml_from'=>100
						];
					}
				}
			}
		}else{
			foreach(['model', 'model_oknum'] as $type){
				if(empty($cleanArr[$type])) continue;
				foreach($cleanArr[$type] as $row){
					if(!empty($modArr[$row['mm_id']])) continue;
					if((
						isset($cleanChkArr[$type.'_chk']) && in_array($row['mm_id'], $cleanChkArr[$type.'_chk'])) || 
						($cleanArr['pro']['art_show'] != 'org' && !isset($cleanChkArr[$type.'_chk']) && $row['ok'])
					){
						$modArr[$row['mm_id']] = [
							'oml_mm_id'=>$row['mm_id'],	
							'oml_para'=>is_array($row['para'])? json_encode($row['para'], JSON_UNESCAPED_UNICODE): '[]',
							'oml_from'=>100
						];
					}
				}
			}
		}

		$modArr = array_values($modArr);
		$cnmodArr = [];
		//中国车型不需要判断人工ORG
		if(isset($cleanChkArr['cnmodelids'])){
			$cnmodArr = $cleanChkArr['cnmodelids'];
		}else{
			$cnmodArr = $cleanArr['cnmodelids'];
		}
		return ['uninums'=>$uniTempNumArr, 'unimodel'=>$modArr, 'unicnmodel'=>$cnmodArr];
	}

	
	//数据单明细审核到零件库
	public function workItemToPoeItem($req)
	{
		if($req['ids']){
			$where = ['wdi_id'=>explode(',', $req['ids'])];
		}else{
			$where = ['wdi_wdlist_id'=>explode(',', $req['wdlist_id'])];
		}
		//小类是否已填
		//OE、小类是否存在
		$join = [
			"[><]work_data_list(wdl)" => ["wdi.wdi_wdlist_id" => "wdlist_id"],
			"[>]pro_cate(cat)" => ["wdi.wdi_cat_id"=>"id"]
		];
		$fields = ['cat.is_engine', 'cat.cat_pos1','cat.cat_pos2','cat.cat_pos3','cat.cat_pos4','cat.cat_pos5','wdi.*', 'wdlist_seq'];
		$fields = langSqlFields($fields, 'cat_', 'cat.');
		$items = $this->db->select('work_data_item(wdi)', $join, $fields, $where);
		if(empty($items)) return [];
		foreach($items as $v){
			if(empty($v['wdi_cat_id'])) exitJson('请先完善号码小类');
		}

		$opuser = getOpuser();
		$datetime = getNowTime();
		
		$check = new check();
		$carmodel = new carmodel();
		$oe = new oe();
		$tags = new tags();
		$pro = new pro();
		$oeNumidx = new \model\oeNumidx();
		$trade = new trade();
		$projectItem = new \model\projectItem();
		$oeids = [];
		foreach($items as $v){
			$cleanArr = empty($v['wdi_chkpro_clean_result'])? []:json_decode($v['wdi_chkpro_clean_result'], true);
			$changeChkPro = false; //是否变更参考数据
			$isNew = false;
			$res = $this->getWorkOeFormat($v);
			$uninums = $res['uninums'];
			$unimodel = $res['unimodel'];
			$unicnmodel = $res['unicnmodel'];
			if($req['oe_id'] == -1){
				//指定新建
				$isNew = true;
			}else{
				$hasPoe = $this->getWdiOeIds([$v['wdi_id']]);
				if($uninums){
					foreach($uninums as $row){
						$sql = sprintf("SELECT oe_id, oe_oe FROM oe_numidx
						JOIN oe_item ON on_oe_id=oe_id 
						WHERE on_formart='%s' and on_pf_id=%d and oe_cate_id=%d group by oe_id", $row['on_formart'], $row['on_pf_id'], $v['wdi_cat_id']);
						$row['poes'] = $this->db->query($sql)->fetchAll();
						if($row['poes']){
							$hasPoe = array_merge($hasPoe, $row['poes']);
						}
					}
				}
				$hasPoe = array_values(array_column($hasPoe, null, 'oe_id'));
				if(empty($hasPoe)) $isNew = true;
				if($req['oe_id']){
					if(!in_array($req['oe_id'], array_column($hasPoe, 'oe_id'))){
						exitJson('零件ID：'.$req['oe_id'].'不存在于检测零件中，请核查');
					}else{
						$oe_id = (int) $req['oe_id'];
					}
				}
				if(!$oe_id && count($hasPoe) > 1) exitJson('数据单：'.$v['wdlist_seq'].' 明细ID: '.$v['wdi_id'].'=>存在多个零件，请到已确认数据的清洗详情审核');
			}
			$addbase = [
				'oe_wdi_id'=>$v['wdi_id'],
				'oe_cate_id'=>$v['wdi_cat_id'],
				'oe_chkpro_from'=>$v['wdi_chkpro_from'],
				'oe_chkpro_id'=>$v['wdi_chkpro_id'],
				'oe_chkpro_info'=>$v['wdi_chkpro_info'],
				'oe_para' => $cleanArr['para']? json_encode($cleanArr['para'], JSON_UNESCAPED_UNICODE): '[]',
				'oe_opuser'=>$opuser,
				'oe_update_time'=>$datetime,
			];
			$this->db->Begin();
			$oldOeInfo = [];
			if($isNew){
				$addbase['oe_create_time'] = $datetime;
				$oeInfoArr = empty($v['wdi_oeitem'])? []:json_decode($v['wdi_oeitem'], true);
				$tfields = langFields(['oe_chassis', 'oe_model_year', 'oe_engine', 'oe_cc'], 'oe_model_');
				foreach($oeInfoArr as $tk=>$tv){
					if(!$v['is_engine'] && in_array($tk, ['oe_cc', 'oe_engine'])) continue;
					if(in_array($tk, $tfields)){
						$addbase[$tk] = $tv;
					}
				}
				//名称引用分类
				$addbase = langGetVals($addbase, $v, ['oe_'=>'cat_']);
				$this->db->insert('oe_item', $addbase);
				$oe_id = $this->db->id();
				$changeChkPro = true;
			}else{
				$oe_id = $oe_id? $oe_id: $hasPoe[0]['oe_id'];
				$oldOeInfo = $this->db->get('oe_item', '*', ['oe_id'=>$oe_id]);
				//取用量
				if($oldOeInfo['oe_etk_info']){
					$oe_etk_info = json_decode($oldOeInfo['oe_etk_info'], true);
					if($oe_etk_info['para']){
						foreach ($oe_etk_info['para'] as $pvlas) {
							if($pvlas['name']=='用量'){
								$addbase['oe_amount'] = $pvlas['val'];
								break;
							}
						}
					}
				}
				$this->db->update('oe_item', $addbase, ['oe_id'=>$oe_id]);
				$changeChkPro = true;
			}

			if($cleanArr['para'])
			{
				//处理下位置参数 start
				$chkpro = json_decode($v['wdi_chkpro_info'],true);
				$factory = $chkpro['pro_factory'];
				$ret = $oe->formatParaFromTcd($v['wdi_cat_id'],$cleanArr['para'],$oe_id,$factory);
				$oe->setOeParaAndPos($oe_id,$ret);
				//end
			}

			
			if($uninums){
				$addArr = [];
				foreach($uninums as $add){
					if($add['on_isborrow']){
						$chk = $this->db->get('oe_numidx(oen)', ["[>]oe_item(poe)" => ["oen.on_oe_id" =>"oe_id"]], ['on_id', 'on_mk_id', 'oe_id'], ['oe_id'=>$oe_id, 'oe_cate_id'=>$v['wdi_cat_id'], 'on_pf_id'=>$add['on_pf_id'], 'on_formart'=>$add['on_formart']]);
					}else{
						$chk = $this->db->get('oe_numidx(oen)', ["[>]oe_item(poe)" => ["oen.on_oe_id" =>"oe_id"]], ['on_id', 'on_mk_id', 'oe_id'], ['on_isborrow'=>0, 'oe_cate_id'=>$v['wdi_cat_id'], 'on_pf_id'=>$add['on_pf_id'], 'on_formart'=>$add['on_formart']]);
						if($chk['oe_id'] && $chk['oe_id'] !== $oe_id) exitJson('号码重复，零件ID：'.$chk['oe_id'].'已经存在号码'.$add['on_number']);
					}
					if(empty($chk)){
						$add['on_oe_id'] = $oe_id;
						$add['on_opuser'] = $opuser;
						$add['on_create_time'] = $datetime;
						$add['on_update_time'] = $datetime;
						$this->db->insert('oe_numidx', $add);
						$on_id = $this->db->id();
					}else{
						$on_id = $chk['on_id'];
						if(isset($add['on_mk_id']) && $add['on_mk_id'] != $chk['on_mk_id']){
							$add['on_mk_id'] = implode(',', array_unique(array_merge(explode(',', $add['on_mk_id']), explode(',', $chk['on_mk_id']))));
							$this->db->update('oe_numidx', ['on_mk_id'=>$add['on_mk_id'], 'on_opuser'=>$opuser, 'on_update_time'=>$datetime], ['on_id'=>$on_id]);
						}
					}

					if($add['on_pf_id'] == 1){
						$tbIds = [];
						$add['on_mk_id'] = trim($add['on_mk_id'], ',');
						if(!empty($add['on_mk_id'])){
							$ids = $this->db->select('tag_brand_make', 'tbm_tb_id', ['tbm_mk_id'=>explode(',', $add['on_mk_id'])]);
							if($ids) $tbIds = $ids;
						}else{
							$ypApi = new ypApi();
							$res = $ypApi->Get('etk/getNumberBrand', ['number'=>$add['on_formart']]);
							if($res['data']){
								$names = $res['data'];
								$namesstr = implode("','", $names);
								$sql = "SELECT DISTINCT tb_id FROM `tag_brand` WHERE tb_cn_name IN ('{$namesstr}') OR tb_en_name IN ('{$namesstr}') 
								OR tb_id IN (SELECT DISTINCT tbm_tb_id FROM tag_brand_cnbrand JOIN m_cn_model ON brand_id = tbm_brand_id WHERE brand_name IN ('{$namesstr}'))
								OR tb_id IN (SELECT DISTINCT tbm_tb_id FROM tag_brand_make JOIN m_make ON mk_id = tbm_mk_id WHERE mk_cn_name IN ('{$namesstr}') OR mk_en_name IN ('{$namesstr}'))";
								$vals = $this->db->query($sql)->fetchAll();
								if($vals) $tbIds = array_column($vals, 'tb_id');
							}
						}
						$oeNumidx->saveOeNumTb($oe_id, $on_id,$tbIds);
					}
				}
			}
			
			if($unimodel){
				$addArr = [];
				$has = $this->db->select('oe_model_link', 'oml_mm_id', ['oml_oe_id'=>$oe_id]);
				foreach($unimodel as $add){
					if(in_array($add['oml_mm_id'], $has)) continue;
					$add['oml_oe_id'] = $oe_id;
					$add['oml_opuser'] = $opuser;
					$add['oml_create_time'] = $datetime;
					$add['oml_update_time'] = $datetime;
					$addArr[$add['oml_mm_id']] = $add;
				}
				if($addArr) $this->db->insert('oe_model_link', array_values($addArr));
			}
			
			//入中国车型库
			if($unicnmodel)
			{
				$addArr = [];
				$has = $this->db->select('oe_model_cn_link', 'oml_mod3_id', ['oml_oe_id'=>$oe_id]);
				foreach($unicnmodel as $mod3_id){
					if($has && in_array($mod3_id, $has)) continue;
					$addArr[$mod3_id] = [
						'oml_oe_id' => $oe_id,
						'oml_mod3_id' => $mod3_id,
						'oml_opuser' => $opuser,
						'oml_from' => 100,
						'oml_create_time' => $datetime,
						'oml_update_time' => $datetime	
					];
				}
				if($addArr) $this->db->insert('oe_model_cn_link', array_values($addArr));	
			}
			
			if($isNew){
				$mainNum = $this->db->get('work_data_item_format', ['wdif_pf_id', 'wdif_val', 'wdif_search'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$v['wdi_id'], 'ORDER'=>['wdif_pf_id','wdif_id']]);
				//新增零件，主号码非OE，尝试号码库找OE
				if(isset($mainNum['wdif_pf_id']) && $mainNum['wdif_pf_id'] != 1){
					$main_on_id = $this->db->get('oe_numidx', 'on_id', ['on_pf_id'=>1, 'on_oe_id'=>$oe_id, 'ORDER'=>['on_id']]);
				}else{
					$main_on_id = $this->db->get('oe_numidx', 'on_id', ['on_pf_id'=>$mainNum['wdif_pf_id'], 'on_oe_id'=>$oe_id, 'on_formart'=>$mainNum['wdif_search']]);
				}
				$oe->setOeMain($main_on_id);
			}
				
			//初始化车型相关字段
			$mm_ids = array_column($unimodel, 'oml_mm_id');
			$mod3_ids = $unicnmodel;
			$vals = $carmodel->formatValsFromModel($mm_ids, $mod3_ids);
			$set = [];
			if($vals['chassis'] && empty($oldOeInfo['oe_chassis'])) $set['oe_chassis'] = $vals['chassis'];
			if($v['is_engine'] && $vals['cc'] && empty($oldOeInfo['oe_cc'])) $set['oe_cc'] = $vals['cc'];
			if($v['is_engine'] && $vals['engine'] && empty($oldOeInfo['oe_engine'])) $set['oe_engine'] = $vals['engine'];
			if($vals['model_year'] && empty($oldOeInfo['oe_model_year'])) $set['oe_model_year'] = $vals['model_year'];
			if($vals['minname'] && empty($oldOeInfo['oe_model_cn'])){
				foreach(\mvc::$cfg['LANGS'] as $lk=>$lv){
					$set['oe_model_'.$lv['field']] = $vals['minname'];
				}
			}
			if($set) $this->db->update('oe_item', $set, ['oe_id'=>$oe_id]);
			$setwdi = [
				'wdi_dstatus_user' => $opuser,
				'wdi_dstatus' => 1,
				'wdi_dstatus_time' => $datetime,
			];
			$this->db->update('work_data_item', $setwdi, ['wdi_id'=>$v['wdi_id'], 'wdi_dstatus'=>0]);

			$oe->initTagBrand($oe_id);
			

			//补充EPC爆炸图
			if(empty($oldOeInfo['oe_etk_info'])){
				$oe->reGetEpcInfo($oe_id);
			}
			
			$setArr[] = ['t_id'=>$req['tids'], 'value_id'=>$oe_id];
			$tags->changeTagsLink('poe', 'add', $setArr);
			
			if($changeChkPro){
				if($v['wdi_chkpro_from'] == 'tcd'){
					if(!empty($cleanArr['pro']['art_pic'][0]['big'])){
						$oe->downloadAndSaveImage($oe_id, $cleanArr['pro']['art_pic'][0]['big'], 'img', ['text'=>'TCD', 'pic_from'=>1069]);
					}
				}
			}
			$pro->synProByOe($oe_id, ['params', 'nums', 'model', 'cnmodel', 'link']);
			$oeids[] = $oe_id;
			$trade->autoChkAskByPoeChange([$oe_id]);
			$projectItem->autoChkProjectPoe(0, [$oe_id]);
			$this->db->End();
		}
		return $oeids;
	}
	
	//不依赖工单零件直接清洗
	public function cleanDetail($req)
	{
		$arr = [
			'cat_rate_number'=>70,	
			'cat_rate_model'=>50,	
			'cat_id'=>0,
		];

		//来源零件ID
		if($req['oe_id']){
			$join = ["[>]pro_cate(cat)" => ["oi.oe_cate_id"=>"id"]];
			$arr = $this->db->get('oe_item(oi)', $join, ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model', 'oi.*'], ['oe_id'=>$req['oe_id']]);
			if(empty($arr)) exitJson('零件ID记录不存在');
		}else if($req['cat_id']){
			$arr = $this->db->get('pro_cate(cat)', ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model'], ['id'=>$req['cat_id']]);
			if(empty($arr)) exitJson('小类ID'.$req['cat_id'].'不存在');
		}
		
		$apiPost = [
			'art_id'=>$req['from_id'],
			'rate_number'=>$arr['cat_rate_number'],
			'rate_model'=>$arr['cat_rate_model'],
		];
		$ypApi = new ypApi();
		$chkres = $ypApi->Get('tcd/cleanData', [], $apiPost);
		$chkdata = $chkres['status']? $chkres['data']: [];
		if(empty($chkdata['pro'])) exitJson('清洗数据不存在');
		//typ_id 转 mm_id
		foreach(['model', 'model_oknum'] as $type){
			if(empty($chkdata[$type])) continue;
			$typids = array_column($chkdata[$type], 'typ_id');
			$tvals = $this->db->select('m_model', ['mm_yptyp_id', 'mm_id'], ['mm_yptyp_id'=>$typids]);
			$typTomm = array_column($tvals, 'mm_id', 'mm_yptyp_id');
			foreach($chkdata[$type] as $tk=>$tv){
				$chkdata[$type][$tk]['mm_id'] = (int) $typTomm[$tv['typ_id']];
			}
		}
		$arr['cleans'] = $chkdata;
		$arr['cleans_chk'] = [];

		$arr['matchOes'] = [];
		
		//尝试通过分类名称确认小类
		$cate = new cate();
		if(empty($arr['cat_id'])){
			$catenames = [$chkdata['pro']['ga_name'], $chkdata['pro']['ga_name_cn']];
			foreach($catenames as $catename){
				if(empty($catename)) continue;
				$tid = $cate->eqname($catename);
				if(!empty($tid)){
					$arr['cat_id'] = $tid;
					break;
				}else{
					$tids = $cate->eqnameByTcd($catename);
					if($tids && count($tids) == 1){
						$arr['cat_id'] = $tids[0];
						break;
					}
				}
			}
			if($arr['cat_id']){
				$catArr = $this->db->get('pro_cate(cat)', ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model'], ['id'=>$arr['cat_id']]);
				//清洗参数不一致，重新清洗
				if($catArr['rate_number'] != $arr['rate_number'] || $catArr['rate_model'] != $arr['rate_model']){
					$req['cat_id'] = $arr['cat_id'];
					return $this->cleanDetail($req);
				}
				$arr = array_merge($arr, $catArr);
			}
		}
		
		//参考号
		foreach(['num', 'othnum'] as $type){
			if(empty($arr['cleans'][$type])) continue;
			foreach($arr['cleans'][$type] as $key=>$row){
				$twhere = $arr['cat_id'] > 0? ' and oe_cate_id='.$arr['cat_id']: '';
				$sql = sprintf("SELECT oe_id, fac.pf_name, oe_oe, oe_cate_id FROM oe_numidx
				JOIN oe_item ON on_oe_id=oe_id 
				JOIN pro_factory fac on fac.pf_id = oe_pf_id
				JOIN pro_factory fac2 on fac2.pf_id = on_pf_id
				WHERE on_formart = '%s' and fac2.pf_name = '%s' %s group by oe_id", $row['format'], ($row['oe']? 'OE': escape($row['brand'])), $twhere);
				$row['poes'] = $this->db->query($sql)->fetchAll();
				if($row['poes']){
					foreach($row['poes'] as $rv){
						if(empty($arr['matchOes'][$rv['oe_id']])){
							$rv['poe_count'] = 1;
							$arr['matchOes'][$rv['oe_id']] = $rv;
						}else{
							$arr['matchOes'][$rv['oe_id']]['poe_count']++;
						}
					}
				}
				$arr['cleans'][$type][$key] = $row;
			}
		}
		$arr['matchOes'] = array_values($arr['matchOes']);
		array_multisort(array_column($arr['matchOes'], 'poe_count'), SORT_DESC, $arr['matchOes']);

		
		//分类未确定，零件唯一，自动赋值零件
		if(empty($arr['cat_id']) && count($arr['matchOes']) == 1){
			$arr['cat_id'] = $arr['matchOes'][0]['oe_cate_id'];
			$catArr = $this->db->get('pro_cate(cat)', ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model'], ['id'=>$arr['cat_id']]);
			//清洗参数不一致，重新清洗
			if($catArr['rate_number'] != $arr['rate_number'] || $catArr['rate_model'] != $arr['rate_model']){
				$req['cat_id'] = $arr['cat_id'];
				return $this->cleanDetail($req);
			}
			$arr = array_merge($arr, $catArr);
		}

		$carmodel = new carmodel();
		foreach(['model', 'model_oknum'] as $type){
			if(!empty($arr['cleans'][$type])){
				$has = array_column($arr['cleans'][$type], null, 'mm_id');
				$res = $carmodel->getModel(['mm_ids'=>array_unique(array_column($arr['cleans'][$type], 'mm_id'))]);
				$merge = [];
				foreach($res['models'] as $k=>$v){
					if($has[$v['mm_id']]){
						$v = array_merge($v, $has[$v['mm_id']]);
					}
					$merge[] = $v;
				}
				$arr['cleans'][$type] = $merge;
			}
		}
		
		//替换号
		$oes = $this->getWorkItemOes($arr);
		if(!empty($oes)){
			$ypApi = new ypApi();
			$res = $ypApi->Get('etk/getReplaceNumber', ['number'=>implode(',', $oes)]);
			$arr['cleans']['replace'] = $res['data'];

			$res = $ypApi->Get('number/getModelByNumber', ['number'=>implode(',', $oes)]);
			$arr['cleans']['cnmodelids'] = $res['data'];
		}
		
		if(!empty($arr['cleans']['cnmodelids'])){
			$cnmodelchk = $arr['cleans']['cnmodelids'];
			$carmodelcn = new carmodelcn();
			$res = $carmodelcn->getModelList(['keys'=>$arr['cleans']['cnmodelids']]);
			foreach($res['rows'] as $row){
				$row['checked'] = in_array($row['mod3_id'], $cnmodelchk);
				$arr['cleans']['cnmodel'][] = $row;
			}
		}
		return $arr;
	}


	//保存清洗数据到零件库
	public function saveCleanToPoe($oe_id, $dataArr)
	{
		$opuser = getOpuser();
		$datetime = getNowTime();
		$cat_id = 0;
		if($oe_id){//指定零件ID
			$join = ["[>]pro_cate(cat)" => ["oi.oe_cate_id"=>"id"]];
			$oldOeInfo = $this->db->get('oe_item(oi)', $join, ['cat.id(cat_id)', 'cat.'.cateName().'(cat_name)','cat_rate_number', 'cat_rate_model', 'oi.*'], ['oe_id'=>$oe_id]);
			if(empty($oldOeInfo)) exitJson('零件ID记录不存在');
			$cat_id = $oldOeInfo['oe_cate_id'];
		}else if(empty($dataArr['cat_id'])){
			exitJson('请先完善号码小类');
		}else{
			$cat_id = (int) $dataArr['cat_id'];
		}
		$catArr = $this->db->get('pro_cate(cat)', '*', ['id'=>$cat_id]);
		if(empty($catArr)) exitJson('小类不存在');

		$addNums = [];
		//组装需要处理的号码
		$factory = new factory();
		$carmodel = new carmodel();
		if(!empty($dataArr['replace'])){
			$strNums = $dataArr['replace'];
			$tnums = strtr($strNums, ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
			foreach(explode(',', $tnums) as $tv){
				if(empty($tv)) continue;
				$tvs = explode(':', $tv);
				if(count($tvs) == 1){
					$addNums[] = [
						'on_pf_id'=>1,
						'on_number'=>$tvs[0],
						'on_mk_id'=>[],
						'on_from'=>in_array($type, ['chkpro', 'replace'])? 100: 99
					];
				}else if(count($tvs) >= 2){
					$pfid = $tvs[0] == 'OE'? 1: $factory->getFacId($tvs[0], 'add');
					$mkid = $tvs[2]? $carmodel->getOeMakeIds($tvs[2]): '';
					$addNums[] = [
						'on_pf_id'=>$pfid,
						'on_number'=>$tvs[1],
						'on_mk_id'=>$mkid? explode(',',$mkid): [],
						'on_from'=>in_array($type, ['chkpro', 'replace'])? 100: 99
					];
				}
			}
		}

		foreach(['num_ok_chk', 'num_no_chk', 'othnum_ok_chk', 'othnum_no_chk'] as $type){
			if(!is_array($dataArr[$type])) continue;
			foreach($dataArr[$type] as $unikey){
				if(!empty($dataArr['num'][$unikey])){
					$row = $dataArr['num'][$unikey];
					$pfid = $row['oe'] == 'OE'? 1: $factory->getFacId($row['brand'], 'add');
					$mkid = $row['oe'] == 'OE'? $carmodel->getOeMakeIds($row['brand']): '';
					$addNums[] = [
						'on_pf_id'=>$pfid,
						'on_number'=>$row['display'],
						'on_mk_id'=>$mkid? explode(',',$mkid): [],
						'on_from'=>100
					];
				}
			}
		}
		//本身去重
		$uniTempNumArr = [];
		foreach($addNums as $add){
			$add['on_formart'] = formatNum($add['on_number']);
			if(empty($add['on_pf_id']) || empty($add['on_number'])) continue;
			$uniTempNumArr[$add['on_pf_id'].'@'.$add['on_formart']] = $add;
			if(!empty($add['on_mk_id'])){
				$uniTempNumArr[$add['on_pf_id'].'@'.$add['on_formart']]['on_mk_id'] = array_unique(array_merge($uniTempNumArr[$add['on_pf_id'].'@'.$add['on_formart']]['on_mk_id'], $add['on_mk_id']));
			}
		}

		foreach($uniTempNumArr as $k=>$v){
			$uniTempNumArr[$k]['on_mk_id'] = trim(implode(',', $v['on_mk_id']), ',');
		}
		
		$oe = new oe();
		$chkpro = json_decode($dataArr['pro'],true);
		//转换和数据单一样格式
		$chkpro['from'] = 'tcd';
		$chkpro['pro_id'] = $chkpro['art_id'];
		$chkpro['pro_name'] = $chkpro['ga_name'];
		$chkpro['pro_number'] = $chkpro['art_number'];
		$chkpro['pro_factory'] = $chkpro['sup_brand'];
		$chkpro['pro_img'] = $chkpro['art_pic']? $chkpro['art_pic'][0]['small']: '';

		$proPara = $dataArr['para']? json_decode($dataArr['para'],true) : [];

		$isNew = false;
		if(empty($oe_id)){//新增
			$matchOeIds = [];
			//检测号码的唯一性
			foreach($uniTempNumArr as $add){
				$rows = $this->db->select('oe_numidx(oen)', ["[>]oe_item(poe)" => ["oen.on_oe_id" =>"oe_id"]], ['oe_id', 'oe_oe'], ['oe_cate_id'=>$cat_id, 'on_pf_id'=>$add['on_pf_id'], 'on_formart'=>$add['on_formart']]);
				if($rows){
					foreach($rows as $rv){
						$matchOeIds[$rv['oe_id']] = $rv;
					}
				}
			}
			$matchOeIds = array_values($matchOeIds);
			if($matchOeIds){
				exitJson('所选的号码存在零件'.implode(', ', array_column($matchOeIds, 'oe_oe')).'中，请核对号码');
			}else{
				$isNew = true;
				$addbase = [
					'oe_cate_id'=>$cat_id,
					'oe_chkpro_from'=>'tcd',
					'oe_chkpro_id'=>$dataArr['art_id'],
					'oe_chkpro_info'=>json_encode($chkpro, JSON_UNESCAPED_UNICODE),
					'oe_para' =>json_encode($proPara, JSON_UNESCAPED_UNICODE),
					'oe_opuser'=>$opuser,
					'oe_update_time'=>$datetime,
					'oe_create_time'=>$datetime
				];

				//名称引用分类
				$addbase = langGetVals($addbase, $catArr, ['oe_'=>'']);
				$this->db->insert('oe_item', $addbase);
				$oe_id = $this->db->id();

				if($proPara){
					$ret = $oe->formatParaFromTcd($cat_id, $proPara, $oe_id, $chkpro['pro_factory']);
					$oe->setOeParaAndPos($oe_id,$ret);
				}
			}
		}

		if($uniTempNumArr){
			$oeNumidx = new \model\oeNumidx();
			foreach($uniTempNumArr as $add){
				$chk = $this->db->get('oe_numidx(oen)', ["[>]oe_item(poe)" => ["oen.on_oe_id" =>"oe_id"]], ['on_id', 'on_mk_id'], ['oe_id'=>$oe_id,'oe_cate_id'=>$cat_id, 'on_pf_id'=>$add['on_pf_id'], 'on_formart'=>$add['on_formart']]);
				if(empty($chk)){
					$add['on_oe_id'] = $oe_id;
					$add['on_opuser'] = $opuser;
					$add['on_create_time'] = $datetime;
					$add['on_update_time'] = $datetime;
					$this->db->insert('oe_numidx', $add);
					$on_id = $this->db->id();
				}else{
					$on_id = $chk['on_id'];
					if(isset($add['on_mk_id']) && $add['on_mk_id'] != $chk['on_mk_id']){
						$add['on_mk_id'] = implode(',', array_unique(array_merge(explode(',', $add['on_mk_id']), explode(',', $chk['on_mk_id']))));
						$this->db->update('oe_numidx', ['on_mk_id'=>$add['on_mk_id'], 'on_opuser'=>$opuser, 'on_update_time'=>$datetime], ['on_id'=>$on_id]);
					}
				}
				
				if($add['on_pf_id'] == 1){
					$tbIds = [];
					$add['on_mk_id'] = trim($add['on_mk_id'], ',');
					if(!empty($add['on_mk_id'])){
						$ids = $this->db->select('tag_brand_make', 'tbm_tb_id', ['tbm_mk_id'=>explode(',', $add['on_mk_id'])]);
						if($ids) $tbIds = $ids;
					}else{
						$ypApi = new ypApi();
						$res = $ypApi->Get('etk/getNumberBrand', ['number'=>$add['on_formart']]);
						if($res['data']){
							$names = $res['data'];
							$namesstr = implode("','", $names);
							$sql = "SELECT DISTINCT tb_id FROM `tag_brand` WHERE tb_cn_name IN ('{$namesstr}') OR tb_en_name IN ('{$namesstr}') 
							OR tb_id IN (SELECT DISTINCT tbm_tb_id FROM tag_brand_cnbrand JOIN m_cn_model ON brand_id = tbm_brand_id WHERE brand_name IN ('{$namesstr}'))
							OR tb_id IN (SELECT DISTINCT tbm_tb_id FROM tag_brand_make JOIN m_make ON mk_id = tbm_mk_id WHERE mk_cn_name IN ('{$namesstr}') OR mk_en_name IN ('{$namesstr}'))";
							$vals = $this->db->query($sql)->fetchAll();
							if($vals) $tbIds = array_column($vals, 'tb_id');
						}
					}
					$oeNumidx->saveOeNumTb($oe_id, $on_id,$tbIds);
				}
			}
		}

		//国际车型
		$modArr = [];
		foreach(['model_chk', 'model_oknum_chk'] as $type){
			if(!is_array($dataArr[$type])) continue;
			foreach($dataArr[$type] as $mm_id){
				$modArr[$mm_id] = [
					'oml_mm_id'=>$mm_id,	
					'oml_para'=>!empty($dataArr['enmod'][$mm_id])? $dataArr['enmod'][$mm_id]: '[]',
					'oml_from'=>100
				];
			}
		}
		$unimodel = array_values($modArr);
		if($unimodel){
			$addArr = [];
			$has = $this->db->select('oe_model_link', 'oml_mm_id', ['oml_oe_id'=>$oe_id]);
			foreach($unimodel as $add){
				if(in_array($add['oml_mm_id'], $has)) continue;
				$add['oml_oe_id'] = $oe_id;
				$add['oml_opuser'] = $opuser;
				$add['oml_create_time'] = $datetime;
				$add['oml_update_time'] = $datetime;
				$addArr[$add['oml_mm_id']] = $add;
			}
			if($addArr) $this->db->insert('oe_model_link', array_values($addArr));
		}
	
		//入中国车型库
		if($dataArr['cnmodelids'])
		{
			$addArr = [];
			$has = $this->db->select('oe_model_cn_link', 'oml_mod3_id', ['oml_oe_id'=>$oe_id]);
			foreach($dataArr['cnmodelids'] as $mod3_id){
				if($has && in_array($mod3_id, $has)) continue;
				$addArr[$mod3_id] = [
					'oml_oe_id' => $oe_id,
					'oml_mod3_id' => $mod3_id,
					'oml_opuser' => $opuser,
					'oml_from' => 100,
					'oml_create_time' => $datetime,
					'oml_update_time' => $datetime	
				];
			}
			if($addArr) $this->db->insert('oe_model_cn_link', array_values($addArr));	
		}
		
		if($isNew){
			$main_on_id = $this->db->get('oe_numidx', 'on_id', ['on_oe_id'=>$oe_id, 'ORDER'=>['on_pf_id', 'on_id']]);
			$oe->setOeMain($main_on_id);
		}
			
		//初始化车型相关字段
		$mm_ids = array_column($unimodel, 'oml_mm_id');
		$mod3_ids = $unicnmodel;
		$vals = $carmodel->formatValsFromModel($mm_ids, $mod3_ids);
		$set = [];
		if($vals['chassis'] && empty($oldOeInfo['oe_chassis'])) $set['oe_chassis'] = $vals['chassis'];
		if($v['is_engine'] && $vals['cc'] && empty($oldOeInfo['oe_cc'])) $set['oe_cc'] = $vals['cc'];
		if($v['is_engine'] && $vals['engine'] && empty($oldOeInfo['oe_engine'])) $set['oe_engine'] = $vals['engine'];
		if($vals['model_year'] && empty($oldOeInfo['oe_model_year'])) $set['oe_model_year'] = $vals['model_year'];
		if($vals['minname'] && empty($oldOeInfo['oe_model_cn'])){
			foreach(\mvc::$cfg['LANGS'] as $lk=>$lv){
				$set['oe_model_'.$lv['field']] = $vals['minname'];
			}
		}
		if($set) $this->db->update('oe_item', $set, ['oe_id'=>$oe_id]);

		$oe->initTagBrand($oe_id);

		//补充EPC爆炸图
		if(empty($oldOeInfo['oe_etk_info'])){
			$oe->reGetEpcInfo($oe_id);
		}
		
		if(!empty($chkpro['art_pic'][0]['big'])){
			$oe->downloadAndSaveImage($oe_id, $chkpro['art_pic'][0]['big'], 'img', ['text'=>'TCD', 'pic_from'=>1069]);
		}
		$pro = new pro();
		$pro->synProByOe($oe_id, ['params', 'nums', 'model', 'cnmodel', 'link']);
		$trade = new trade();
		$trade->autoChkAskByPoeChange([$oe_id]);
		$projectItem = new \model\projectItem();
		$projectItem->autoChkProjectPoe(0, [$oe_id]);
		return [$oe_id];
	}


	//获取数据清单对应的零件库ID
	function getWdiOeIds($wdiIds)
	{
		$sql = sprintf("SELECT wdi_id, oe_id, oe_oe FROM work_data_item_format
				JOIN work_data_item ON wdi_id = wdif_wdi_id
				JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
				JOIN oe_item ON on_oe_id=oe_id
				WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id) AND wdi_id IN (%s) group by wdi_id, oe_id", implode(',', $wdiIds));
		return $this->db->query($sql)->fetchAll();
	}
	

	public function setCate($table, $idArr, $cate_id)
	{
		if(empty($idArr) || !is_array($idArr)) return [];
		if($table == 'work_data_item'){
			$this->db->update('work_data_item', ['wdi_cat_id'=>$cate_id], ['wdi_id'=>$idArr]);
		}else if($table == 'work_ask_item'){
			$arr = $this->db->select('work_ask_item','wai_id',['wai_id'=>$idArr]);
			if($arr){
				$this->db->update('work_ask_item', ['wai_cate_id'=>$cate_id], ['wai_id'=>$arr]);
			}
			
		}
		return [];
	}


	function setWdiStatus($req)
	{
		if(!empty($req['wdi_dstatus'])){
			$setArr = [
				'wdi_dstatus'=>$req['wdi_dstatus'],
				'wdi_dstatus_user'=>getOpuser(),
				'wdi_dstatus_time'=>getNowTime()
			];
			$this->db->update('work_data_item', $setArr, ['wdi_id'=>explode(',', $req['ids'])]);
		}
		return [];
	}

	function getWdiIds($req){
		return $this->db->select('work_data_item','wdi_id',['wdi_wdlist_id'=>$req['wdlist_id']]);
	}

	function chkProOeByWdi($wdi_id)
	{
		$sql = sprintf("SELECT oe_id, pf_name, oe_oe FROM work_data_item_format
			JOIN work_data_item ON wdi_id = wdif_wdi_id
			JOIN oe_numidx ON wdif_pf_id=on_pf_id AND wdif_search=on_formart 
			JOIN oe_item ON on_oe_id=oe_id
			JOIN pro_factory on pf_id = oe_pf_id
			WHERE (wdi_cat_id = 0 OR wdi_cat_id = oe_cate_id) AND wdif_wdi_id =%d group by oe_id", $wdi_id);
		$rows = $this->db->query($sql)->fetchAll();
		return $rows? $rows: [];
	}

	//修改
	public function setCell($table, $kid, $setArr)
	{
		$opuser = getOpuser();
		$datetime = getNowTime();
		
		if($table == 'work_data_list'){
			$setArr['wdlist_opuser'] = $opuser;
			$setArr['wdlist_update_time'] = $datetime;
			$this->db->update('work_data_list', $setArr, ['wdlist_id'=>$kid]);
		}else if($table == 'work_data_item'){
			$setArr['wdi_opuser'] = $opuser;
			$setArr['wdi_update_time'] = $datetime;
			$this->db->update('work_data_item', $setArr, ['wdi_id'=>$kid]);
		}else if($table == 'work_ask_item'){
			$old = $this->db->get('work_ask_item(wai)', ["[><]work_ask(was)" => ["wai.wai_was_id" => "was_id"]], '*', ['wai_id'=>$kid]);
			if($old['was_status'] == 1) exitJson('询单已处理，禁止修改');

			if(isset($setArr['wai_status']) && $setArr['wai_status'] == -1 && $old['wai_cost_status'] = 0){
				$setArr['wai_cost_status'] = -1;
			}else if(isset($setArr['wai_cost_status']) && $setArr['wai_cost_status'] == -1 && $old['wai_status'] = 0){
				$setArr['wai_status'] = -1;
			}

			//引用价格
			if(isset($setArr['refprice'])){
				$refprice = is_array($setArr['refprice'])? $setArr['refprice'] : json_decode(base64_decode($setArr['refprice']), true);
				$setArr['wai_refprice'] = json_encode($refprice, JSON_UNESCAPED_UNICODE);
				unset($setArr['refprice']);
				if(isset($refprice['wai_cost_price'])){
					//非询价加点
					if($refprice['from_type'] != 'old_ask'){
						$refprice['wai_cost_price'] *= \mvc::$cfg['askSupProPriceRate'];
						$refprice['wai_price'] *= \mvc::$cfg['askSupProPriceRate'];
					}
					$setArr['wai_cost_price'] = $refprice['wai_cost_price'];
					$setArr['wai_price'] = $refprice['wai_price']/$old['was_money_rate'];
					if($refprice['was_money_rate']) $setArr['wai_price'] = $setArr['wai_price']*$refprice['was_money_rate'];//转CNY
				}else if($refprice['from_type'] == 'pro_api' && isset($refprice['wai_price'])){
					$setArr['wai_price'] = $refprice['wai_price']/$old['was_money_rate'];
					if($refprice['was_money_rate']) $setArr['wai_price'] = $setArr['wai_price']*$refprice['was_money_rate'];//转CNY
				}
				//同步其他字段
				foreach(['wai_sup_id', 'wai_pb_id', 'wai_hasshui', 'wai_tuishui', 'wai_haspack', 'wai_delivery', 'wai_minbuy'] as $field){
					if(isset($refprice[$field])) $setArr[$field] = $refprice[$field];
				}
				if(empty($setArr['wai_sup_id']) && !empty($refprice['sup_id'])) $setArr['wai_sup_id'] = (int) $refprice['sup_id'];
				if(empty($setArr['wai_pb_id']) && !empty($refprice['pb_id'])) $setArr['wai_pb_id'] = (int) $refprice['pb_id'];
			}
			
			//成本价录入
			if(isset($setArr['wai_cost_price']) || isset($setArr['wai_sup_id'])){
				if(\p::has('M200','check2')){//权限
					if($setArr['wai_cost_price'] > 0){//有价格
						$setArr['wai_cost_status'] = 1;
						if($old['wai_status'] === -1) $setArr['wai_status'] = 0;
					}else if(isset($setArr['wai_cost_price']) && $old['wai_cost_status'] == 1){//无价格充值状态
						$setArr['wai_cost_status'] = 0;
						$setArr['wai_status'] = 0;
					}
					$setArr['wai_cost_opuser'] = $opuser;
					$setArr['wai_cost_time'] = $datetime;
				}else{
					exitJson('无修改权限');
					/*unset($setArr['wai_status']);
					unset($setArr['wai_cost_price']);
					unset($setArr['wai_sup_id']);
					unset($setArr['wai_cost_opuser']);
					unset($setArr['wai_cost_time']);*/
				}
			}
		
			//销售价格变化控制状态
			$flag = false;
			if(isset($setArr['wai_price']) || isset($setArr['wai_count'])){
				if(\p::has('M200','check3')){//权限
					$flag = true;
					$setArr['wai_money_total'] = raw("wai_price*wai_count");
					if($setArr['wai_price'] > 0){
						$setArr['wai_status'] = 1;
					}else if(isset($setArr['wai_price']) && $old['wai_status'] == 1){//无价格充值状态
						$setArr['wai_status'] = 0;
					}
					$setArr['wai_price_opuser'] = $opuser;
					$setArr['wai_price_time'] = $datetime;
				}else{
					exitJson('无修改权限');
					/*unset($setArr['wai_price']);
					unset($setArr['wai_price_opuser']);
					unset($setArr['wai_price_time']);*/
				}
			}

			$setArr['wai_opuser'] = $opuser;
			$setArr['wai_update_time'] = $datetime;
			$this->db->Begin();
			$this->db->update('work_ask_item', $setArr, ['wai_id'=>$kid]);
			if($flag){
				$trade = new trade();
				$trade->resetAskTotal($old['wai_was_id']);
			}
			$this->db->End();
			
		}elseif ($table == 'work_ask') {
			if(!\p::has('M200','check1') && isset($setArr['was_status'])){
				exitJson('无修改权限');
			}
			$old = $this->db->get('work_ask', '*', ['was_id'=>$kid]);
			if(!isset($setArr['was_status']) && $old['was_status'] == 1) exitJson('询单已处理，禁止修改');
			
			$this->db->Begin();
			if(isset($setArr['was_money_rate']) && $setArr['was_money_rate'] != $old['was_money_rate']){//汇率改变
				$itemSet = [
					'wai_price'=> raw("wai_price*".$old['was_money_rate'].'/'.$setArr['was_money_rate']),
					'wai_money_total' => raw("wai_price*wai_count"),
					'wai_opuser' => $opuser,
					'wai_update_time' => $datetime
				];
				$this->db->update('work_ask_item', $itemSet, ['wai_was_id'=>$kid]);
				$trade = new trade();
				$trade->resetAskTotal($old['was_id']);
			}
			if(isset($setArr['was_status'])) $setArr['was_ok_time'] = $setArr['was_status'] == 1? $datetime: null;
			$setArr['was_opuser'] = $opuser;
			$setArr['was_update_time'] = $datetime;
			$this->db->update('work_ask', $setArr, ['was_id'=>$kid]);
			$this->db->End();
		}else if($table == 'work_data_item_format'){
			$this->db->update('work_data_item_format', $setArr, ['wdif_id'=>$kid]);
		}
		return [];
	}


	//删除
	public function delData($table, $idArr)
	{
		if(empty($idArr) || !is_array($idArr)) return [];
		$delfiles = [];
		$this->db->Begin();
		if($table == 'work_data_list'){
			//删除工单
			$sonids = $this->db->select('work_data_item', 'wdi_id', ['wdi_wdlist_id'=>$idArr]);
			if($sonids){
				$rows = $this->db->select('work_data_item_format', 'wdif_val', ['wdif_wdi_id'=>$sonids,'wdif_type'=>['Image', 'Image2']]);
				foreach($rows as $img){
					$delfiles[] = \mvc::$cfg['dir']['files'].'/'.$img;
				}
				$this->db->delete('work_data_item_format', ['wdif_wdi_id'=>$sonids]);	
			}
			$this->db->delete('work_data_item', ['wdi_wdlist_id'=>$idArr]);
			$this->db->delete('work_data_list', ['wdlist_id'=>$idArr]);

		}else if($table == 'work_data_item'){
			//工单数据项
			$rows = $this->db->select('work_data_item_format', 'wdif_val', ['wdif_wdi_id'=>$idArr,'wdif_type'=>['Image', 'Image2']]);
			foreach($rows as $img){
				$delfiles[] = \mvc::$cfg['dir']['files'].'/'.$img;
			}
			$this->db->delete('work_data_item_format', ['wdif_wdi_id'=>$idArr]);
			$this->db->delete('work_data_item', ['wdi_id'=>$idArr]);
		}else if($table == 'work_data_item_format'){
			$this->db->delete('work_data_item_format', ['wdif_id'=>$idArr]);
		}else if($table == 'work_ask'){
			$join = [
				"[>]work_data_list(wdl)" => ["was.was_id" => "wdlist_from_id", '1'=>'@wdlist_from=1123']
			];
			$rows = $this->db->select('work_ask(was)', $join, ['was_id', 'wdlist_id', 'was_status'], ['was_id'=>$idArr]);
			foreach($rows as $row){
				if($row['was_status'] == 1) exitJson('已处理询单禁止删除');
				$this->db->delete('work_ask', ['was_id'=>$row['was_id']]);
				$this->db->delete('work_ask_item', ['wai_was_id'=>$row['was_id']]);
				$this->db->delete('work_ask_item_num', ['wain_was_id'=>$row['was_id']]);
				if($row['wdlist_id']){
					$this->delData('work_data_list', [$row['wdlist_id']]);
				}
			}
		}else if($table == 'work_ask_item'){
			//询单数据项
			$was_ids = $this->db->select('work_ask_item', 'wai_was_id', ['wai_id'=>$idArr, 'GROUP'=>'wai_was_id']);
			$this->db->delete('work_ask_item', ['wai_id'=>$idArr]);
			$this->db->delete('work_ask_item_num', ['wain_wai_id'=>$idArr]);
			$wdi_ids = $this->db->select('work_data_item', 'wdi_id', ['wdi_from'=>1123, 'wdi_from_id'=>$idArr]);
			if($wdi_ids){
				$this->delData('work_data_item', $wdi_ids);
			}
			foreach($was_ids as $was_id){
				$trade = new trade();
				$trade->resetAskTotal($was_id);
			}
		}
		$this->db->End();
		foreach($delfiles as $del){
			@unlink($del);
		}
		return [];
	}


	function saveDataItemChkPro($dataArr)
	{
		$this->db->Begin();
		foreach($dataArr as $row){
			$t = explode('@', $row['value']);
			$setArr = [
				'wdi_chkpro_from'=>$t[0]? $t[0]: '',
				'wdi_chkpro_id'=>$t[0] && $t[1]? $t[1]: '',
				'wdi_chkpro_info'=>'[]',
				'wdi_chkpro_clean' => -1,
				'wdi_chkpro_clean_has' => -1,
				'wdi_chkpro_clean_result' => '[]',
				'wdi_chkpro_clean_chk' => '[]',
				'wdi_chkpro_clean_by' => '[]',
				'wdi_opuser'=>getOpuser(),
				'wdi_update_time'=>getNowTime(),
			];
			if($setArr['wdi_chkpro_from'] != 'self'){
				//第三方确认数据的信息
				$clean_result = $this->db->get('work_data_item', 'wdi_clean_result', ['wdi_id'=>$row['kid']]);
				$cleanArr = empty($clean_result) ? []: json_decode($clean_result, true);
				if(!empty($cleanArr['data'][$setArr['wdi_chkpro_from']])){
					$tdata = $cleanArr['data'][$setArr['wdi_chkpro_from']];
					if($setArr['wdi_chkpro_from'] == 'tcd'){
						foreach($tdata['ga_chk'] as $ctk=>$ctv){
							foreach($ctv['pros'] as $tpk=>$tpv){
								if($tpv['pro_id'] == $setArr['wdi_chkpro_id']){
									$tpv['ga_name'] = $ctv['ga_name'];
									$tpv['ga_name_cn'] = $ctv['ga_name_cn'];
									$tpv['from'] = $setArr['wdi_chkpro_from'];
									$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
									break;
								}
							}
						}
					}else{
						foreach($tdata['pros'] as $tpk=>$tpv){
							if($tdata['from'] == $setArr['wdi_chkpro_from'] && $tpv['pro_id'] == $setArr['wdi_chkpro_id']){
								$tpv['from'] = $setArr['wdi_chkpro_from'];
								$setArr['wdi_chkpro_info'] = json_encode($tpv, JSON_UNESCAPED_UNICODE);
								break;
							}
						}
					}
				}
			}
			
			$this->db->update('work_data_item', $setArr, ['wdi_id'=>$row['kid']]);
			$this->cleanWorkChkOkPro($row['kid']);
		}
		$this->db->End();
		return [];
	}



	//数据工单流水
	function getWorkSeqNext(){
        $fix = date('Ymd');
        return $this->getSeqNext('work_data_list', $fix,'wdlist_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 getOeDetail($woi_id)
	{
		$data = $this->getOeItemList(['woi_id'=>$woi_id]);
		if(empty($data['rows'])) exitJson('记录不存在');
		$arr =$data['rows'][0];
		$arr['cleans'] = empty($arr['woi_clean_result'])? []:json_decode($arr['woi_clean_result'], true);
		$arr['woi_clean_by'] = empty($arr['woi_clean_by'])? []:json_decode($arr['woi_clean_by'], true);
		$arr['cleans_chk'] = empty($arr['woi_clean_chk'])? []:json_decode($arr['woi_clean_chk'], true);
		$carmodel = new carmodel();
		foreach(['model', 'model_oknum'] as $type){
			if(!empty($arr['cleans'][$type])){
				$has = array_column($arr['cleans'][$type], null, 'mm_id');
				$res = $carmodel->getModel(['mm_ids'=>array_unique(array_column($arr['cleans'][$type], 'mm_id'))]);
				$merge = [];
				foreach($res['models'] as $k=>$v){
					if($has[$v['mm_id']]){
						$v = array_merge($v, $has[$v['mm_id']]);
					}
					$merge[] = $v;
				}
				$arr['cleans'][$type] = $merge;
			}
		}
		return $arr;
	}
	
	
	public function saveOeDetail($woi_id, $dataArr)
	{
		$arr = [];
		$this->db->Begin();
		$setArr = [];
		if(!empty($dataArr['base'])) $setArr = $dataArr['base'];
		if(!empty($dataArr['qingxi'])) $setArr['woi_clean_chk'] = json_encode($dataArr['qingxi'], JSON_UNESCAPED_UNICODE);
		if(!empty($setArr)){
			$this->setOeCell($woi_id, $setArr);
		}
		
		$chkArr = [];
		if($dataArr['act'] == 'topro' && $dataArr['to_pid']){
			//追加到产品库
			$arr = $this->checkWorkOeToPro($woi_id, $chkArr, $dataArr['to_pid']);
		}else if($dataArr['act'] == 'oepro'){
			//新增到新增待进入库
			$arr = $this->checkWorkOeToOe($woi_id, $chkArr);
		}
		$this->db->End();
		return $arr;
	}


	//询源单
	public function getAskList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? 'was_id': $params['sidx'];
		$sord = empty($params['sord']) || empty($params['sidx'])? 'desc': $params['sord'];
		$orderby = $params['orderby'];

		$refiled = [
			'com_name'=>'com_'.LG_NAME,
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'work_ask(was)';
		$join = [
			"[>]user(wdl)" => ["was.was_u_id" => "u_id"],
			"[>]adm_user(au)" => ["was.was_opuser" => "au_id"],
			"[>]company(com)" => ["was.was_com_id" => "com_id"],
		];
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			switch ($field) {
				case 'ar_name':
					$field = 'RAW #ar_name';
					$data = raw(sprintf(" was_id IN (select distinct wai_was_id from work_ask_item join adm_role on wai_ar_id=ar_id where ar_name like '%%%s%%')",$data));
					break;
			}
        });
		if(!empty($params['keys'])) $where['was_id'] = explode(',', $params['keys']);
		if(!empty($params['was_id'])) $where['was_id'] = explode(',', $params['was_id']);
		//权限 - 小类
        $cates = \p::cates('M200');
        if(!\p::isAdmin() && $cates){
			$where['RAW #rule_cate'] = raw(sprintf(" was_id IN (select distinct wai_was_id from work_ask_item where wai_cat_id in (%s))", $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 = ['was.*', 'u_mb', 'u_name', 'u_company', 'au.au_name', 'com_'.LG_NAME.'(com_name)'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if($arr){
			$ids = array_column($arr, 'was_id');
			$twhere = ['wai_was_id'=>$ids, 'GROUP'=>'wai_was_id'];
			if($cates) $twhere['AND #rule_cate'] = ['wai_cat_id'=>explode(',',$cates)];
			$rows = $this->db->select('work_ask_item', ['wai_was_id', 'item_count'=>raw('count(*)'), 'wait_count'=>raw('(sum(case when wai_status = 0 then 1 else 0 end))'), 'wait_cost_count'=>raw('(sum(case when wai_cost_status = 0 then 1 else 0 end))'), 'ok_count'=>raw('(sum(case when wai_status != 0 then 1 else 0 end))'), 'poe_count'=>raw('(sum(case when wai_oe_id > 0 then 1 else 0 end))'), 'cost_ok_count'=>raw('(sum(case when wai_cost_status != 0 then 1 else 0 end))')], $twhere);
			$tj = array_column($rows, null, 'wai_was_id');

			foreach($arr as &$v){
				$v['cols'] = $v['was_cols']? json_decode($v['was_cols'], true): [];
				if($tj[$v['was_id']]) $v = array_merge($v, $tj[$v['was_id']]);
				$v['captions']['was_opuser'] = $v['au_name'];
			}
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	
	//询单详情
	public function getAskDes($was_id)
	{
		$table = 'work_ask(was)';
		$join = [
			"[>]user(wdl)" => ["was.was_u_id" => "u_id"],
			"[>]adm_user(au)" => ["was.was_opuser" => "au_id"],
		];
		$data = $this->db->get($table, $join, '*', ['was_id'=>$was_id]);
		if(empty($data))  exitJson('记录不存在');
		
		$factory = new factory();
		$table = 'work_ask_item(wai)';
		$join = [
			"[>]supplier(sup)" => ["wai.wai_sup_id" => "sup_id"],
			"[>]adm_user(au)" => ["wai.wai_opuser" => "au_id"],
		];
		$data['ok_count'] = 0;
		$data['total_pro'] = 0;
		$data['total_money'] = 0.00;
		$items = $this->db->select($table, $join, '*', ['wai_was_id'=>$was_id, 'ORDER'=>['wai_factory', 'wai_formart']]);
		
		foreach($items as $k=>$v){
			$format = reSearchNum($v['wai_formart']);
			
			//上次报价
			$sql = sprintf("SELECT wai_oe_id oe_id,oe_oe, oe_".LG_NAME." oe_name,pf_name,oe_pic,fileid,filepath,filebasename,fileextname, sup_id, o.%s material, wai_material spr_material, sup_name, sup_code, wai_price spr_price, wai_update_time,wai_id wai_from_wai_id FROM work_ask_item
			JOIN supplier ON wai_sup_id = sup_id
			JOIN object o ON wai_material = o.o_id
			LEFT JOIN oe_item ON wai_oe_id = oe_id
			LEFT JOIN pro_factory ON oe_pf_id = pf_id
			LEFT JOIN files ON oe_pic = fileid
			where wai_factory in ('%s', '') and wai_formart in ('%s') ORDER BY wai_update_time DESC limit 1", LG_NAME, $v['wai_factory'], implode("','", $format));
			$rows = $this->db->query($sql)->fetchAll();
			if($rows){
				foreach ($rows as $key => $val) {
					$rows[$key]['bigImg'] = '';
					$rows[$key]['smallImg'] = '';
					if($val['fileid']){
						$rows[$key]['bigImg'] = $val['filepath'].'/'.$val['filebasename'].'big.'.$val['fileextname'];
						$rows[$key]['smallImg'] = $val['filepath'].'/'.$val['filebasename'].'small.'.$val['fileextname'];
					}
				}
			}
			$v['lastprice'] = $rows;

			$pfid = 0;
			if($fac) $pfid = $factory->getFacId($fac);
			
			$where = sprintf(" on_formart in ('%s')", implode("','", $format));
			if($pfid) $where .= sprintf(" and on_pf_id=%d", $pfid);
			$sql = sprintf("SELECT oe_id, pf_name, oe_oe,oe_pic,files.*, oe_%s oe_name, spr_id, sup_id, o2.%s spr_area, o3.%s material, spr_material, sup_name, sup_code, spr_price FROM oe_numidx
			JOIN oe_item ON oe_id = on_oe_id
			JOIN pro_factory ON on_pf_id = pf_id
			LEFT JOIN supplier_pro ON spr_oe_id = oe_id
			LEFT JOIN supplier ON spr_sup_id = sup_id
			LEFT JOIN object o ON sup_level = o.o_id
			LEFT JOIN object o2 ON spr_area = o2.o_id
			LEFT JOIN object o3 ON spr_material = o3.o_id
			LEFT JOIN oe_pic pic ON oe_pic = pic_fileid
			LEFT JOIN files ON pic_fileid = fileid
			where %s GROUP BY oe_id, spr_id order by o.o_sort,sup_name", LG_NAME, LG_NAME, LG_NAME, $where);
			$rows = $this->db->query($sql)->fetchAll();
			$v['super'] = [];
			if(!empty($rows)){
				foreach($rows as $rv){
					$rv['bigImg'] = '';
					$rv['smallImg'] = '';
					if($rv['oe_pic']){
						$rv['bigImg'] = $rv['filepath'].'/'.$rv['filebasename'].'big.'.$rv['fileextname'];
						$rv['smallImg'] = $rv['filepath'].'/'.$rv['filebasename'].'small.'.$rv['fileextname'];
					}
					$v['super'][$rv['oe_id']]['base'] = $rv;
					$v['super'][$rv['oe_id']]['price'][$rv['spr_id']] = $rv;
				}
			}
			$items[$k] = $v;
			$data['total_pro'] += $v['wai_count'];
			if($v['wai_price'] > 0){
				$data['total_money'] += $v['wai_count']*$v['wai_price'];
				$data['ok_count']++;
			}
		}
		
		$data['total_money'] = sprintf("%.2f", $data['total_money']);
		$data['items'] = $items;
		$data['ok_rate'] = sprintf('%.1f', $data['ok_count']/count($data['items'])*100);
		return $data;
	}
	

	//询源单明细
	public function getAskItemList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		if(empty($params['sidx'])){
			//$sidx = 'wai_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 = 'work_ask_item(wai)';
		$join = [
			"[><]work_ask(was)" => ["wai.wai_was_id" => "was_id"],
			"[>]pro_brand(pb)" => ["wai.wai_pb_id" => "pb_id"],
			"[>]user(usr)" => ["was.was_u_id" => "u_id"],
			"[>]oe_item(poe)" => ["wai.wai_oe_id" => "oe_id"],
			"[>]files(fi)" => ["poe.oe_pic" => "fileid"],
			"[>]pro_factory(pf)" => ["poe.oe_pf_id" => "pf_id"],
			"[>]pro_cate(cat)" => ["wai.wai_cat_id" => "id"],
			"[>]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]work_data_item(wdi)" => ["wai.wai_id" => "wdi_from_id", '1'=>'@wdi_from=1123'],
			"[>]work_data_list(wdl)" => ["wdi.wdi_wdlist_id" => "wdlist_id"],
			"[>]supplier(sup)" => ["wai.wai_sup_id" => "sup_id"],
			"[>]adm_user(au)" => ["wai.wai_opuser" => "au_id"],
			"[>]adm_user(au2)" => ["wai.wai_cost_opuser" => "au_id"],
			"[>]adm_user(au3)" => ["wai.wai_price_opuser" => "au_id"],
		];

		$this->set('pnumwhere', []);
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'wai_oe_id'){
				$op = 'RAW_'.$field;
				if($data == 1){
					$data = raw(" wai_oe_id > 0");
				}else{
					$data = raw(" wai_oe_id = 0");
				}
			}else if($field == 'cat.'.cateName()){
				if($data == 'Y'){
					$op = 'RAW_'.$field;
					$data = raw(" wai_cat_id > 0");
				}else if($data == 'N'){
					$op = 'RAW_'.$field;
					$data = raw(" wai_cat_id = 0");
				}
			}else if($field == 'poe_img_small'){
				$op = 'RAW_'.$field;
				if($data == 1){
					$data = raw(" oe_pic > 0");
				}else{
					$data = raw(" (oe_pic is null or oe_pic = 0)");
				}
			}else if($field == 'wdlist_id'){
				$op = 'RAW_'.$field;
				if($data == 1){
					$data = raw(" wdlist_id > 0");
				}else{
					$data = raw(" (wdlist_id is null or wdlist_id = 0)");
				}
			}else if(in_array($field, ['wai_cost_price', 'wai_price'])){
				$op = 'RAW_'.$field;
				if($data == 1){
					$data = raw(" {$field} > 0");
				}else{
					$data = raw(" {$field} <= 0");
				}
			}else if($field == 'chknums'){
				if($op == 'eq'){
					$where = "wain_format = '".formatNum($data)."'";
				}else if($op == 'bw'){
					$where = "wain_format like '%".formatNum($data)."%'";
				}else{
					$where = "wain_format like '".formatNum($data)."%'";
				}
				$op = 'RAW_'.$field;
				$data = raw(" wai_id in (select wain_wai_id from work_ask_item_num where ".$where.")");
			}else if($field == 'chk_poes'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" wai_id not in (SELECT distinct wain_wai_id FROM work_ask_item_num
						JOIN work_ask_item ON wai_id = wain_wai_id
						JOIN oe_numidx ON wain_format=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						JOIN pro_factory on pf_id = oe_pf_id and (pf_name = wain_pf_name or wain_pf_name = '')
						WHERE (wai_cat_id = 0 OR wai_cat_id = oe_cate_id)
					)");
				}else{
					$data = raw(" wai_id in (SELECT distinct wain_wai_id FROM work_ask_item_num
						JOIN work_ask_item ON wai_id = wain_wai_id
						JOIN oe_numidx ON wain_format=on_formart 
						JOIN oe_item ON on_oe_id=oe_id
						JOIN pro_factory on pf_id = oe_pf_id and (pf_name = wain_pf_name or wain_pf_name = '')
						WHERE (wai_cat_id = 0 OR wai_cat_id = oe_cate_id)
					)");
				}

			}
        });
		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'p_cate': $where['wai_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['wain_format'.($rules['numlike']? '[~]': '')] = $tnums;
					$join['[><]work_ask_item_num(wain)'] = ['wai.wai_id'=>'wain_wai_id'];
				break;
			}
		}
		
		if($params['was_id']) $where['was_id'] = $params['was_id'];
		if(isset($params['wai_status'])) $where['wai_status'] = $params['wai_status'];
		if(isset($params['wai_cost_status'])) $where['wai_cost_status'] = $params['wai_cost_status'];
		if(!empty($params['keys'])) $where['wai_id'] = explode(',', $params['keys']);
		
		//权限 - 小类
        $cates = \p::cates('M200');
        if(!\p::isAdmin() && $cates){
			$where['AND #rule_cate'] = ['wai_cat_id'=>explode(',',$cates)];
        }

		$where['GROUP'] = ['wai_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];
		}
		
		$supnameField = \p::has('C500','view')? 'sup_name': 'sup_code(sup_name)';
		$fields = ['u_code', 'u_level', 'oe_id', 'pf_name', 'oe_oe', 'oe_'.LG_NAME.'(oe_name)', 'oe_model_'.LG_NAME.'(oe_model_name)', 'pb_'.LG_NAME.'(pb_name)', 'filepath', 'filebasename', 'fileextname', 'cat.id(cat_id)', 'pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'wdlist_id', 'wdlist_seq', 'wdi_id', 'wdi_dstatus', 'was.*', 'wai.*', $supnameField, 'au.au_name', 'au2.au_name(au_cost_name)', 'au3.au_name(au_price_name)'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if(!empty($arr)){
			$waiIds = array_column($arr, 'wai_id');
			$rows = $this->db->select('work_ask_item_num', ['wain_wai_id', 'wain_id', 'wain_pf_name(pf_name)', 'wain_number'], ['wain_wai_id'=>$waiIds, 'ORDER'=>['wain_pf_name', 'wain_format']]);
			$nums = [];
			foreach($rows as $rv){
				$nums[$rv['wain_wai_id']][] = ['wain_id'=>$rv['wain_id'], 'factory'=>$rv['wain_pf_name'], 'number'=>$rv['wain_number']];  
			}
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('ask');

			$ref_prices = $this->getAskItemRefPrice($waiIds);
		
			foreach($arr as &$v){
				$v['ref_price'] = $ref_prices[$v['wai_id']]? $ref_prices[$v['wai_id']]: [];
				$v['nums'] = $nums[$v['wai_id']]? $nums[$v['wai_id']]: [];
				$v['chknums'] = '';
				foreach($v['nums'] as $tk=> $tv){
					$v['chknums'] .= '<div>'.($tv['factory']? $tv['factory'].': ' : '').$tv['number'].'</div>';
				}
				
				$v['captions']['wai_oe_id'] = $v['oe_id']? '<a href="'.\mvc::$cfg['sitePath'].'/oe/detail?tab=base&oe_id='.$v['oe_id'].'" title="零件库['.$v['oe_oe'].']" tab>'.$v['pf_name'].': '.$v['oe_oe'].'</a>': '';
				$v['poe_img_big'] = $v['filepath']? $v['filepath'].'/'.$v['filebasename'].'big.'.$v['fileextname']: '';
				$v['poe_img_small'] = $v['filepath']? $v['filepath'].'/'.$v['filebasename'].'small.'.$v['fileextname']: '';
				
				$v['captions']['ref_price'] = '';
				if(!empty($v['ref_price'])){
					foreach($v['ref_price'] as $type=>$tpvs){
						$v['captions']['ref_price'] .= '<ul class="ref_price ref_price_'.$type.'">';
						foreach($tpvs as $tpv){
							$btns = '';
							if($v['was_status'] != 1)
								$btns = '<button type="button" data-wai_id="'.$v['wai_id'].'" data-info="'.base64_encode(json_encode($tpv, JSON_UNESCAPED_UNICODE)).'" class="btn btn-outline-primary btn-sm fa pirce-init"> 使用</button>';
							if($tpv['from_type'] == 'pro_api'){
								$tpv['pro_url'] = \mvc::$cfg['sitePath'].'/pro/detail?p_id='.$tpv['p_id'];
								$v['captions']['ref_price'] .= '<li>
									<div>'.$btns.'<b class="green">【'.$tpv['from_name'].'】</b></div>
									<div><a href="'.$tpv['pro_url'].'" tab>'.$tpv['pb_name'].':'.$tpv['p_innum'].'</a> </div>
									<div><span class="marr10">最小起订量: '.$tpv['wai_minbuy'].'</span><span class="marr10">'.$tpv['wai_price_name'].'('.$tpv['was_money_type'].'): '.$tpv['wai_price'].'</span></div>
								</li>';
							}else if($tpv['from_type'] == 'old_ask'){
								$tpv['pro_url'] = \mvc::$cfg['sitePath'].'/work/askItemList?keys='.$tpv['wai_id'];
								$v['captions']['ref_price'] .= '<li>
									<div>'.$btns.'<b class="green">【'.$tpv['from_name'].'】</b>'.date('Y-m-d', strtotime($tpv['from_time'])).'</div>
									<div><a href="'.$tpv['pro_url'].'" tab>'.$tpv['was_u_code'].' 数量: '.$tpv['wai_count'].'</a> </div>
									<div>供应商: '.$tpv['sup_name'].'</div>
									<div><span class="marr10">成本价: '.$tpv['wai_cost_price'].'</span><span class="marr10">销售价('.$tpv['was_money_type'].'): '.$tpv['wai_price'].'</span></div>
								</li>';
							}else if($tpv['from_type'] == 'sup_pro'){
								$tpv['pro_url'] = \mvc::$cfg['sitePath'].'/element/listView?elename=supplier_pro&rules=spr_id:'.$tpv['spr_id'];
								$v['captions']['ref_price'] .= '<li>
									<div>'.$btns.'<b class="orange">【'.$tpv['from_name'].'】</b>'.date('Y-m-d', strtotime($tpv['from_time'])).'</div>
									<div><a href="'.$tpv['pro_url'].'" tab>'.$tpv['sup_name'].'</a></div>
									<div><span class="marr10">含税价: '.$tpv['wai_cost_price'].'</span><span class="marr10">指导价: '.$tpv['wai_price'].'</span></div>
								</li>';
							}else if($tpv['from_type'] == 'resource'){
								$tpv['pro_url'] = "javascript:qg.page.open('EDC', '".\mvc::$cfg['sitePath']."/pro/sourceSearch?nums=".$tpv['nums']."&type=num')";
								$v['captions']['ref_price'] .= '<li>
									<div><b class="orange">【'.$tpv['from_name'].'】</b>'.date('Y-m-d', strtotime($tpv['from_time'])).'</div>
									<div><a href="'.$tpv['pro_url'].'">'.$tpv['fac_name'].'</a></div>';
								if($tpv['pro_name']) $v['captions']['ref_price'] .= '<div>名称: '.$tpv['pro_name'].'</div>';
								if($tpv['pro_price']) $v['captions']['ref_price'] .= '<div>价格: '.$tpv['pro_price'].'</div>';
								$v['captions']['ref_price'] .= '</li>';
							}
						}
						$v['captions']['ref_price'] .= '</ul>';
					}
				}
				$v['captions']['wai_sup_id'] = $v['sup_name'];
				$v['captions']['wai_pb_id'] = $v['pb_name'];
				$v['captions']['u_level'] = !empty($collArr[$v['u_level']])? $collArr[$v['u_level']]: '';
				$v['captions']['wai_opuser'] = $v['au_name'];
				$v['captions']['wai_cost_opuser'] = $v['au_cost_name'];
				$v['captions']['wai_price_opuser'] = $v['au_price_name'];

				$v['wai_data'] = empty($v['wai_data']) ? []: json_decode($v['wai_data'], true);
				foreach($v['wai_data'] as $kk=>$vv){
					$v['col_'.$kk] = $vv;
				}
				unset($v['wai_data']);
			}
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	//获取询单项有哪些参考价格 $type = autoPrice时只处理能用于自动填充价格的
	public function getAskItemRefPrice($waiIdArr, $type = '')
	{
		$arr = [];
		$join = [
			"[><]work_ask(was)" => ["wai.wai_was_id" => "was_id"],
			"[>]company(com)" => ["was.was_com_id" => "com_id"]
		];
		$rows = $this->db->select('work_ask_item(wai)', $join, '*', ['wai_id'=>$waiIdArr]);
		if(empty($rows)) return $arr;
		$waiArr = [];//明细项角度
		$wasArr = [];//询单角度
		foreach($rows as $row){
			$row['wai_refprice_cache'] = $row['wai_refprice_cache']? json_decode($row['wai_refprice_cache'], true): [];
			$waiArr[$row['wai_id']] = $row;
			$wasArr[$row['was_id']][] = $row;
		}
		
		//事业部对应的商品
		foreach($wasArr as $items){
			//询单明细零件ID=>集团ID=>事业部
			$sql = sprintf("SELECT wai_id, p.p_id, p.p_innum, pb_id, pb_%s pb_name, wai_count FROM pro p
			JOIN pro_brand ON pb_id = p.p_pb_id
			JOIN pro p1 ON p.p_lnk_p_id = p1.p_id
			JOIN work_ask_item ON p1.p_oe_id = wai_oe_id
			JOIN pro_link_company ON p.p_id = plc_p_id and plc_com_id = %d
			WHERE wai_id IN (%s) GROUP BY wai_id, p.p_id ORDER BY pb_cn_name, p.p_innum_format", LG_NAME, $items[0]['was_com_id'], implode(',', array_column($items, 'wai_id')));
			$rows = $this->db->query($sql)->fetchAll();
			if($rows){
				$link = []; $allnums = [];
				foreach($rows as $row){
					$link[$row['wai_id']][] = $row;
					$allnums[] = $row['p_innum'];
				}
				$allnums = array_unique($allnums);

				$freyApi = new \model\freyApi();
				$numPrices = [];
				foreach(array_chunk($allnums, 500) as $nums){
					$post = [
						'company_sap_no'=>$items[0]['com_code'],	
						'partner_sap_no'=>$items[0]['was_u_code'],	
						'frey_nos'=>implode(',', $nums)
					];
					//物料编码对应的价格
					$post = json_encode($post, JSON_UNESCAPED_UNICODE);
					$fres = $freyApi->httpCurl('/Pic.Pic/GetCompanyProductPrices', 'POST', $post, ["Content-Type:application/json"]);
					if(isset($fres['data']['price_list']) && $fres['data']['price_list']){
						foreach($fres['data']['price_list'] as $v){
							if(empty($v['price'])) continue;
							$numPrices[$v['frey_no']][] = $v;
						}
					}
				}
				//汇总到明细
				foreach($link as $wai_id=>$ivs){
					foreach($ivs as $iv){
						if(empty($numPrices[$iv['p_innum']])) continue;
						$row = $iv;
						$priceInfo = $numPrices[$iv['p_innum']][0];
						$row['from_type'] = 'pro_api';
						$row['from_name'] = '商品接口';
						$row['was_money_type'] = 'CNY';
						$row['was_money_rate'] = 1;
						$row['wai_minbuy'] = $priceInfo['min_quantity']; 
						$row['wai_price'] = $priceInfo['price']; 
						$row['wai_price_name'] = $priceInfo['price_name']; 
						$arr[$wai_id]['pro_api'][] = $row;
					}
				}
			}
		}
		
		//历史询单
		$sql = sprintf("SELECT *
		FROM (
			SELECT 
				sorted.*,
				@row_number := IF(@prev_id = sorted.my_wai_id, @row_number + 1, 1) AS rn,
				@prev_id := sorted.my_wai_id
			FROM (
				SELECT myin.wain_wai_id my_wai_id, 'old_ask' from_type, '询单' from_name, oa.was_id, oa.was_u_code, oi.wai_id, sup_id, sup_name, sup_code, wai_count, wai_cost_price, wai_cost_opuser, wai_cost_time, oa.was_money_type, oa.was_money_rate, wai_price, oa.was_create_time from_time,wai_pb_id pb_id, wai_hasshui, wai_tuishui, wai_haspack, wai_delivery, wai_minbuy 
				FROM work_ask_item_num oin
				JOIN work_ask_item_num myin ON oin.wain_format = myin.wain_format AND oin.wain_wai_id != myin.wain_wai_id AND (oin.wain_pf_name = myin.wain_pf_name OR myin.wain_pf_name = '' AND oin.wain_pf_name != '')
				JOIN work_ask mya ON myin.wain_was_id = mya.was_id
				JOIN work_ask_item oi ON oi.wai_id = oin.wain_wai_id
				LEFT JOIN supplier ON sup_id = oi.wai_sup_id
				JOIN work_ask oa ON oa.was_id = oin.wain_was_id
				WHERE myin.wain_wai_id IN (%s) AND wai_status = 1 ORDER BY myin.wain_wai_id, FIND_IN_SET(oa.was_u_code, mya.was_u_code) DESC, wai_id DESC
			
		) AS sorted,
		(SELECT @row_number := 0, @prev_id := NULL) AS vars
	) AS ranked
	WHERE ranked.rn = 1
	ORDER BY ranked.my_wai_id", implode(',', array_keys($waiArr)));
		$rows = $this->db->query($sql)->fetchAll();
		if($rows){
			foreach($rows as $row){
				$arr[$row['my_wai_id']]['old_ask'][] = $row;
			}
		}
		
		//零件供应商
		$oeids = array_unique(array_column($waiArr, 'wai_oe_id'));
		$supnameField = \p::has('C500','view')? 'sup_name': 'sup_code sup_name';
		$sql = sprintf("SELECT spr_oe_id oe_id,'sup_pro' from_type, '零件供应商' from_name, sup_id, %s, sup_code, spr_id, oa.%s price_area, spr_price wai_cost_price, 'CNY' was_money_type, 1 was_money_rate, spr_price4 wai_price, spr_update_time from_time, spr_delivery wai_delivery, spr_minbuy wai_minbuy
		FROM `supplier_pro` JOIN `supplier` ON  sup_id = spr_sup_id
		LEFT JOIN object oa ON o_id = spr_area
		WHERE spr_oe_id in (%s)", $supnameField, LG_NAME, implode(',', $oeids));
		$rows = $this->db->query($sql)->fetchAll();
		if($rows){
			$poePrice = [];
			foreach($rows as $row){
				$poePrice[$row['oe_id']][] = $row;
			}
			foreach($waiArr as $wai){
				if($poePrice[$wai['wai_oe_id']]) $arr[$wai['wai_id']]['sup_pro'] = $poePrice[$wai['wai_oe_id']];
			}
		}

		if($type != 'autoPrice'){
			//无价格的找资源库
			$nullIds = [];
			$resource = new resource();
			foreach($waiArr as $wai_id=>$wai){
				if(empty($arr[$wai_id])){
					$nullIds[] = $wai_id;
				}
			}
			if($nullIds){
				$nums = $this->db->select('work_ask_item_num', ['wain_wai_id', 'wain_number', 'wain_format'], ['wain_wai_id'=>$nullIds]);
				if($nums){
					$waiNums = [];
					foreach($nums as $row){
						$waiNums[$row['wain_wai_id']][$row['wain_format']] = $row['wain_number'];
					}
					$rows = $resource->getResourcesByNum(array_column($nums, 'wain_format'));
					$mergeArr = [];//每个号码每个工厂只取一条
					foreach($rows as $row){
						$row['num_format'] = formatNum($row['rnumber']);
						if(empty($mergeArr[$row['num_format']][$row['resourceFactoryId']]))
							$mergeArr[$row['num_format']][$row['resourceFactoryId']] = $row;
					}
					
					foreach($waiNums as $wai_id=>$nvs){
						$match = [];
						foreach($nvs as $numf=>$nv){
							if(empty($mergeArr[$numf])) continue;
							foreach($mergeArr[$numf] as $fac=>$row){
								if(!$match[$fac]){
									$match[$fac] = [
										'from_type'=>'resource', 
										'from_name'=>'EDC', 
										'fac_resource_facid'=>$row['resourceFactoryName'], 
										'fac_name'=>$row['resourceFactoryName'], 
										'pro_name'=>$row['partName'], 
										'pro_price'=>$row['price'],
										'nums'=>implode(',', $nvs),
										'from_time'=>date('Y-m-d', strtotime($row['resourceProvideTime'])), 
									];
								}
							}
						}
						if($match) $arr[$wai_id]['resource'] = array_values($match);
					}
				}
			}
		}
		return $arr;
	}


	//批量改价
	function changeAnyAskPrice($wai_ids, $req)
	{
		$waiArr = $this->db->select('work_ask_item(wai)', ["[><]work_ask(was)" => ["wai.wai_was_id" => "was_id"]], '*', ['wai_id'=>$wai_ids]);
		$this->db->Begin();
		foreach($waiArr as $wai){
			$setArr = [];
			foreach(['wai_cost_price', 'wai_price'] as $field){
				if($req[$field]['opeval']){
					$opv = $req[$field];
					if($opv['byprice'] == 'new'){
						$setArr[$field] = $opv['opeval'];
					}else{
						 if($opv['byprice'] == 'wai_cost_price'){
							//销售价使用成本价，两价是否同时改
							$setArr[$field] = $setArr['wai_cost_price']? $setArr['wai_cost_price']: $wai['wai_cost_price'];
						 }else{
							$setArr[$field] = $wai[$field];
						 }
						if($opv['ope'] == '*'){
							$setArr[$field] *= $opv['opeval'];
						}else if($opv['ope'] == '+'){
							$setArr[$field] += $opv['opeval'];
						}else if($opv['ope'] == '-'){
							$setArr[$field] -= $opv['opeval'];
						}
					}
				}
			}
			foreach(['wai_pb_id', 'wai_sup_id', 'wai_delivery', 'wai_minbuy'] as $field){
				if($req[$field]) $setArr[$field] = $req[$field];
			}
			if($setArr) $this->setCell('work_ask_item', $wai['wai_id'], $setArr);
		}
		$this->db->End();
		
		return [];
	}

	
	//宜配号码比较['wdi_id'=>xxx]
	public function compareNumByYiparts($params){
		$arr = [];
		if(!empty($params['wdi_id'])){
			$join = [
				"[>]pro_factory(fac)" => ["wdif_pf_id" =>"pf_id"]
			];
			$numsTemp = $this->db->select('work_data_item_format', $join, ['pf_name(factory)', 'wdif_val(number)'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$params['wdi_id']]);
			//去重
			$nums = [];
			foreach ($numsTemp as $val) 
			{	
				$unikey = $val['factory'].formatNum($val['number']);
				$nums[$unikey] = $val;
			}
			$nums = array_values($nums);
			$apiPost = [
				'number'=>json_encode($nums, JSON_UNESCAPED_UNICODE)
			];
		}else if($params['type']){
			$nums = [];
			foreach(explode(',', $params['nums']) as $v){
				$tt = explode(':', $v);
				$unikey = $tt[0].formatNum($tt[1]);
				$nums[$unikey] = ['factory'=>$tt[0], 'number'=>$tt[1]];
			}
			$nums = array_values($nums);
			if(!empty($params['artids']) || !empty($nums)){
				$apiPost = [
					'artids'=>$params['artids'],
					'number'=>json_encode($nums, JSON_UNESCAPED_UNICODE)
				];
			}
		}
		if($apiPost){
			$ypApi = new ypApi();
			$res = $ypApi->Get('tcd/compareNum', [], $apiPost);
			$arr = $res['status']? $res['data']: [];
		}
		return $arr;
	}

	//宜配号码检测['oe_id'=>xxx]
	public function chkNumByYiparts($params){
		$arr = [];
		if(!empty($params['oe_id'])){
			$join = [
				"[><]pro_cate(cate)" => ["oi.oe_cate_id" =>"id"]
			];
			$oeInfo = $this->db->get('oe_item(oi)', $join, ['cat_tcdfacmain'], ['oe_id'=>$params['oe_id']]);

			$join = [
				"[>]pro_factory(fac)" => ["on_pf_id" =>"pf_id"]
			];
			$numsTemp = $this->db->select('oe_numidx', $join, ['pf_name(factory)', 'on_number(number)'], ['on_oe_id'=>$params['oe_id'], 'ORDER'=>['pf_name', 'on_number']]);
			$nums = [];
			foreach ($numsTemp as $val) {	
				$unikey = $val['factory'].formatNum($val['number']);
				$nums[$unikey] = $val;
			}
			$nums = array_values($nums);
			$apiPost = [
				'number'=>json_encode($nums, JSON_UNESCAPED_UNICODE),
				'mainfac'=>$oeInfo['cat_tcdfacmain']
			];
		
			$ypApi = new ypApi();
			$res = $ypApi->Get('tcd/chkNumBase', [], $apiPost);
			$arr = $res['status']? $res['data']: [];
		}
		return $arr;
	}


	public function checkAskItem($idArr,$setArr)
	{
		if(!empty($idArr))
		{
			$tempArr = $this->db->select('work_ask_item', '*', ['wai_id'=>$idArr]);
			if(empty($tempArr)) exitJson('记录不存在');

			$opuser = getOpuser();
			$datetime = getNowTime();
			$set = [
				'ckuser1'=>$opuser,
				'cktime1'=>$datetime,
				'ck1'=>$setArr['ck1'],
				'ckremark1'=>$setArr['ckremark1'],
			];
			$this->db->update('work_ask_item', $set, ['wai_id'=>$idArr]);
			//审核通过->供应商产品目录
			if($setArr['ck1']==1 && $idArr)
			{
				$askItem = $this->db->select('work_ask_item','*',['wai_id'=>$idArr]);

				$emptySup = [];
				foreach ($askItem as $item) {
					if(!$item['wai_sup_id']){
						$emptySup[] = $item['wai_oe'];	
					}
				}
				if(!empty($emptySup))  exitJson("OE号：".implode(',',$emptySup).'所属记录未填写供应商');

				$wdiIds = array_column($askItem,'wai_wdi_id');
				//存在的号码
				$join = [
					"[>]pro_factory(fac)" => ["wdif_pf_id" =>"pf_id"]
				];
				$rows = $this->db->select('work_data_item_format', $join, ['wdif_wdi_id', 'wdif_id', 'pf_id', 'wdif_val'], ['wdif_type'=>'Number', 'wdif_wdi_id'=>$wdiIds]);
				$nums = [];
				foreach($rows as $rv){
					$nums[$rv['wdif_wdi_id']][] = ['wdif_id'=>$rv['wdif_id'], 'pf_id'=>$rv['pf_id'], 'number'=>$rv['wdif_val']];  
				}

				if(!$nums) return [];
			
				$anyAdd = [];
				foreach ($askItem as $key => $val) 
				{	
					$dataArr = [
						'spr_sup_id' => $val['wai_sup_id'],
						'spr_brand' => $val['wai_brand'],
						'spr_material' => $val['wai_material'],
						'spr_price' => $val['wai_price'],
						'spr_minbuy' => $val['wai_minbuy'],
						'spr_delivery' => $val['wai_delivery'],
						'spr_price_btime' => $val['wai_price_btime'],
						'spr_price_etime' => $val['wai_price_etime'],
						'spr_purin_time' => $val['wai_purin_time'],
						'spr_price_status' => $val['wai_price_status'],
						'spr_has' => $val['wai_has'],
						'spr_hasample' => $val['wai_hasample'],
						'spr_from' => $val['wai_form'],
						'spr_remark' => $val['wai_remark'],
						'spr_opuser' => getOpuser(),
						'spr_update_time'=>getNowTime()
					];

					foreach ($nums[$val['wai_wdi_id']] as $nval) 
					{	
						// $dataArr['spr_number'] = $nval['number'];
						// $dataArr['spr_format'] = formatNum($nval['number']);
						// $dataArr['spr_pf_id'] = $nval['pf_id'];

						$exists = $this->db->get('supplier_pro','spr_id',['spr_sup_id'=>$dataArr['spr_sup_id'],'spr_pf_id'=>$nval['pf_id'],'spr_format'=>formatNum($nval['number'])]);
						if($exists){
							$this->db->update('supplier_pro',$dataArr,['spr_id'=>$exists]);
						}else{

							$dataArr['spr_number'] = $nval['number'];
							$dataArr['spr_format'] = formatNum($nval['number']);
							$dataArr['spr_pf_id'] = $nval['pf_id'];

							$dataArr['spr_create_time'] = getNowTime();
							$anyAdd[] = $dataArr; 
						}
					}
				}
				if($anyAdd) $this->db->insert('supplier_pro',$anyAdd);
			}

		}
		return [];
	}


	function saveAskSup($dataArr)
	{
		$this->db->Begin();
		foreach($dataArr as $row){
			$spr_ids = explode(',', $row['value']);
			
			$setArr = [];
			if($spr_ids[0]){
				$info = $this->db->get('supplier_pro', '*', ['spr_id'=>$spr_ids[0]]);
				if($info){
					$setArr['wai_sup_id'] = $info['spr_sup_id'];
					$setArr['wai_material'] = $info['spr_material'];
					$setArr['wai_has'] = $info['spr_has'];
					$setArr['wai_minbuy'] = $info['spr_minbuy'];
					$setArr['wai_delivery'] = $info['spr_delivery'];
					$setArr['wai_price_btime'] = $info['spr_price_btime'];
					$setArr['wai_price_etime'] = $info['spr_price_etime'];
					$setArr['wai_purin_time'] = $info['spr_purin_time'];
					$setArr['wai_purin_level'] = '主供应商';
					$setArr['wai_from'] = $info['spr_from'];
				}
			}

			if($spr_ids[1]){
				$info = $this->db->get('supplier_pro', '*', ['spr_id'=>$spr_ids[1]]);
				if($info){
					$setArr['wai_bsup_id'] = $info['spr_sup_id'];
					$setArr['wai_bhas'] = $info['spr_has'];
					$setArr['wai_bdelivery'] = $info['spr_delivery'];
					$setArr['wai_bprice_btime'] = $info['spr_price_btime'];
					$setArr['wai_bprice_etime'] = $info['spr_price_etime'];
					$setArr['wai_bpurin_time'] = $info['spr_purin_time'];
					$setArr['wai_bpurin_level'] = '潜在供应商';
					$setArr['wai_bfrom'] = $info['spr_from'];
				}
			}
			if($setArr){
				$setArr['wai_opuser'] = getOpuser();
				$setArr['wai_update_time'] = getNowTime();
				$this->db->update('work_ask_item', $setArr, ['wai_id'=>$row['kid']]);
			}
		}
		$this->db->End();
		return [];
	}
	//基本统计
	function getBaseTj()
	{
		$arr = ['ask'=>[], 'oe'=>[]];
		$user = new user();
		$arr['ask']['role'] = $user->getPowerRole('A300');
		//询源单
		$sql = "SELECT COUNT(*) total, SUM(CASE WHEN was_status = 1 THEN 1 ELSE 0 END) ok_count, SUM(CASE WHEN was_status != 1 THEN 1 ELSE 0 END) wait_count FROM work_ask";
		$row = $this->db->query($sql)->fetch();
		$arr['ask'] = array_merge($arr['ask'], $row);
		$sql = "SELECT wai_ar_id ar_id, COUNT(*) total, SUM(CASE WHEN was_status = 1 THEN 1 ELSE 0 END) ok_count, SUM(CASE WHEN was_status != 1 THEN 1 ELSE 0 END) wait_count FROM (
		SELECT * 
		FROM work_ask JOIN work_ask_item ON was_id = wai_was_id GROUP BY was_id,wai_ar_id
		) t GROUP BY wai_ar_id";
		$rows = $this->db->query($sql)->fetchAll();
		if(!empty($rows)){
			foreach($rows as $v){
				$arr['ask']['role'.$v['ar_id']] = $v;
			}
		}
		
		//询源单明细
		$sql = "SELECT COUNT(*) total, SUM(CASE WHEN ck1 = 1 THEN 1 ELSE 0 END) ok_count, SUM(CASE WHEN ck1 != 1 THEN 1 ELSE 0 END) wait_count FROM work_ask_item";
		$arr['ask_item'] = $this->db->query($sql)->fetch();

		$sql = "SELECT wai_ar_id ar_id, COUNT(*) total, SUM(CASE WHEN ck1 = 1 THEN 1 ELSE 0 END) ok_count, SUM(CASE WHEN ck1 != 1 THEN 1 ELSE 0 END) wait_count FROM work_ask_item GROUP BY wai_ar_id";
		$rows = $this->db->query($sql)->fetchAll();
		if(!empty($rows)){
			foreach($rows as $v){
				$arr['ask_item']['role'.$v['ar_id']] = $v;
			}
		}

		return $arr;
	}

	/**
	 * @param  [type] $req
	 * @param  [type] $rules
	 * @method 导出解决方案
	 * @author zhengweihua 
	 * @copyright 2024-12-13
	 */
	public function exportSolution($req, $rules)
	{
		
		$data = $this->getAskItemList($req, $rules);

		if(!$data['rows']) return exitJson(-1,'没有数据');

		$header = [
            [
                ['title'=>'序号','scell'=>'A1','ecell'=>'A2','isMerge'=>true,'width'=>'8'],
                ['title'=>'物料编码','scell'=>'B1','ecell'=>'B2','isMerge'=>true,'width'=>'14'],
                ['title'=>'OE号','scell'=>'C1','ecell'=>'C2','isMerge'=>true,'width'=>'14'],
                ['title'=>'替换号','scell'=>'D1','ecell'=>'D2','isMerge'=>true,'width'=>'40'],
                ['title'=>'搜索号','scell'=>'E1','ecell'=>'E2','isMerge'=>true,'width'=>'14'],
                ['title'=>'图片','scell'=>'F1','ecell'=>'F2','isMerge'=>true,'width'=>'14'],
				['title'=>'产品名称','scell'=>'G1','ecell'=>'G2','isMerge'=>true,'width'=>'20'],
				['title'=>'产小类型','scell'=>'H1','ecell'=>'H2','isMerge'=>true,'width'=>'20'],
				['title'=>'小类','scell'=>'I1','ecell'=>'I2','isMerge'=>true],
				['title'=>'项目负责人','scell'=>'J1','ecell'=>'J2','isMerge'=>true,'width'=>'14'],
				['title'=>'属性','scell'=>'K1','ecell'=>'K2','isMerge'=>true],
				['title'=>'车型/发动机','scell'=>'L1','ecell'=>'L2','isMerge'=>true,'width'=>'16'],
				['title'=>'所属项目','scell'=>'M1','ecell'=>'M2','isMerge'=>true],
				['title'=>'品牌','scell'=>'N1','ecell'=>'N2','isMerge'=>true],
				['title'=>'事业部','scell'=>'O1','ecell'=>'O2','isMerge'=>true,'width'=>'30'],
				['title'=>'合作供应商','scell'=>'P1','ecell'=>'AA1','color'=>'FF80FFFF','isMerge'=>true],
				['title'=>'潜在供应商','scell'=>'AB1','ecell'=>'AL1','color'=>'FFFACD91','isMerge'=>true],
            ],
            [
				'','','','','','','','','','','','','','','',
				['title'=>'供应商编码','color'=>'FF80FFFF','width'=>'20'],['title'=>'供应商名称','color'=>'FF80FFFF','width'=>'25'],['title'=>'含税单价','color'=>'FF80FFFF'],['title'=>'是否备货','color'=>'FF80FFFF'],
				['title'=>'交期','color'=>'FF80FFFF'],['title'=>'起订量','color'=>'FF80FFFF'],['title'=>'工厂报价时间','color'=>'FF80FFFF','width'=>'30'],['title'=>'价格失效时间','color'=>'FF80FFFF','width'=>'30'],
				['title'=>'采购入库时间','color'=>'FF80FFFF','width'=>'30'],['title'=>'采购优先级','color'=>'FF80FFFF','width'=>'25'],['title'=>'采购类型','color'=>'FF80FFFF'],['title'=>'数据类型','color'=>'FF80FFFF'],
				
				['title'=>'供应商编码','color'=>'FFFACD91','width'=>'20'],['title'=>'供应商名称','color'=>'FFFACD91','width'=>'25'],['title'=>'含税单价','color'=>'FFFACD91'],['title'=>'是否验厂','color'=>'FFFACD91'],
				['title'=>'初步评级','color'=>'FFFACD91'],['title'=>'是否备货','color'=>'FFFACD91'],['title'=>'交期','color'=>'FFFACD91'],['title'=>'工厂报价时间','color'=>'FFFACD91','width'=>'30'],['title'=>'价格失效时间','color'=>'FFFACD91','width'=>'30'],
				['title'=>'采购优先级','color'=>'FFFACD91','width'=>'25'],['title'=>'数据类型','color'=>'FFFACD91']
			]
        ];

		$fields = ['wai_id','p_innum','wai_oe','nums','','','wai_item_name','wai_item_type','cat_name','wai_manager','wai_material',
			['name'=>['wai_model','wai_engine'],'separator'=>'/'],'wai_project','pb_name','user_area',['name'=>'sup_code','color'=>'FF80FFFF'],['name'=>'sup_name','color'=>'FF80FFFF'],
			
			['name'=>'wai_price','color'=>'FF80FFFF'],['name'=>'wai_has','color'=>'FF80FFFF'],['name'=>'wai_delivery','color'=>'FF80FFFF'],['name'=>'wai_minbuy','color'=>'FF80FFFF'],
			['name'=>'wai_price_btime','color'=>'FF80FFFF'],['name'=>'wai_price_etime','color'=>'FF80FFFF'],['name'=>'wai_purin_time','color'=>'FF80FFFF'],['name'=>'wai_purin_level','color'=>'FF80FFFF'],
			['name'=>'wai_purin_type','color'=>'FF80FFFF'],['name'=>'wai_from','color'=>'FF80FFFF'],

			['name'=>'sup_code2','color'=>'FFFACD91'],['name'=>'sup_name2','color'=>'FFFACD91'],['name'=>'wai_bprice','color'=>'FFFACD91'],['name'=>'wai_bchkfac','color'=>'FFFACD91'],['name'=>'wai_bchklevel','color'=>'FFFACD91'],['name'=>'wai_has','color'=>'FFFACD91'],['name'=>'wai_bdelivery','color'=>'FFFACD91'],
			['name'=>'wai_bprice_btime','color'=>'FFFACD91'],['name'=>'wai_bprice_etime','color'=>'FFFACD91'],['name'=>'wai_bpurin_level','color'=>'FFFACD91'],['name'=>'wai_bfrom','color'=>'FFFACD91'],
		];

		// 创建一个新的 Spreadsheet 对象
		$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
		$sheet = $spreadsheet->getActiveSheet();

		// 设置标题
		$row = 1;
		foreach ($header as $val) {
			$col = 'A';
			foreach ($val as $vv) {
				
				if(!$vv){
					$col++;
					continue;
				} 
				if(is_array($vv)){
					if($vv['isMerge']){
						$sheet->mergeCells(sprintf("%s:%s",$vv['scell'],$vv['ecell'])); // 合并单元格
					}
					if(!empty($vv['width']))
						$sheet->getColumnDimension($col)->setWidth($vv['width']);

					$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++;
		}
		 
		 foreach ($data['rows'] as $val) 
		 {
			$col = 'A';
			foreach ($fields as $field) {
				if(!is_array($field)){
					$val[$field] = $val['captions'][$field]?:$val[$field];
					if($field=='nums'){
						$val['nums'] =$val['nums']? implode(',',explode("\r\n",$val['nums'])):''; 
					}
					$sheet->setCellValue($col.$row, $val[$field]); 
					$style = $sheet->getStyle($col.$row); 
				}else{
					$fieldsVal = '';
					$nameArr = [];
					if(is_array($field['name'])){
						foreach ($field['name'] as $name) {
							if($val[$name]) $nameArr[] = $val['captions'][$name]?:$val[$name];
						}
						$fieldsVal = $nameArr ? implode($field['separator']?:',',$nameArr):'';
					}else{
						$fieldsVal =  $val['captions'][$field['name']]?:$val[$field['name']];
					}
					if(!$fieldsVal||in_Array($fieldsVal,['0','0000-00-00'])) $fieldsVal = '';
					$sheet->setCellValue($col.$row, $fieldsVal); 
					$style = $sheet->getStyle($col.$row); 
					if($field['color']){
						$style->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB($field['color']);
						$styleArray = [
							'borders' => [
								'allBorders' => [
									'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
									'color' => ['argb' => 'FF000000'], // 黑色边框
								],
							],
						];
						$style->applyFromArray($styleArray);
					}
				}
				if($field=='nums'){
					$style->getAlignment()->setWrapText(true);
				}
				$style->getAlignment()->setHorizontal('center');  
				$style->getAlignment()->setVertical('center');
				
				$col++;
			}
			$row++;
		 }
		 $dateTime = getNowTime();
		 $filename = sprintf('解决方案%s',$dateTime).'.xlsx';
		 $objWriter = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
		 ob_clean();
		 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
		 header('Content-Disposition: attachment;filename="'.$filename.'"');
		 header('Cache-Control: max-age=0');
		 $objWriter->save("php://output"); 

	}

	public function chkDataToOth($req)
	{	
		$data = [
			'role'=>[],
			'user'=>[]
		];
		//角色
		$arr = $this->db->select('power_role_link(pw)',['[><]adm_role(ro)'=>['pw.prl_ar_id'=>'ar_id']],'*',['prl_power_code'=>$req['pwcode']]);
		if($arr){
			//判断是否有check2权限
			foreach ($arr as $key => $val) {
				if(!\p::checkXor($val['prl_value'],['check2'])){
					unset($arr[$key]);
				}
			}
		}
		$data['role'] = array_values($arr);
		//用户
		$where = [
			'au_id[!]' => ['frey.admin','admin','admin888']
		];
		$data['user'] = $this->db->select('adm_user',['au_id','au_name'],$where);

		return $data;
	}

	public function workPoesTask($params)
	{
		$data = ['wdi_ar_id'=>$params['ar_id'],'wdi_from_opuser'=>$params['from_opuser'],'wdi_from_time'=>getNowTime()];
		$this->db->update('work_data_item',$data,['wdi_id'=>explode(',',$params['ids'])]);
		return [];
	}

	
	//保存询单
	public function saveAskDetail($was_id, $dataArr)
	{
		$this->db->Begin();
		foreach($dataArr['wai'] as $wai_id=>$v){
			$set = [];
			foreach($v as $kk=>$vv){
				if(stripos($kk, 'wai_') === 0){
					if(in_array($kk, ['wai_spr_id', 'wai_oe_id'])) $vv = (int) $vv;
					$set[$kk] = $vv;
				}
			}
			if($set){
				if($set['wai_spr_id']){
					$oe_id = $this->db->get('supplier_pro', 'spr_oe_id', ['spr_id'=>$set['wai_spr_id']]);
					if($oe_id) $set['wai_oe_id'] = $oe_id;
				}
				$set['wai_opuser']  = getOpuser();
				$set['wai_update_time'] = getNowTime();
				$this->db->update('work_ask_item', $set,['wai_was_id'=>$was_id, 'wai_id'=>$wai_id]);
			}
		}

		$set = [];
		foreach($dataArr as $kk=>$vv){
			if(stripos($kk, 'was_') === 0){
				if(in_array($kk, ['was_money_rate'])) $vv = (float) $vv;
				$set[$kk] = $vv;
			}
		}
		if($set){
			$set['was_opuser']  = getOpuser();
			$set['was_update_time'] = getNowTime();
			$this->db->update('work_ask', $set,['was_id'=>$was_id]);
		}
		$this->db->End();
		return [];
	}



	//转数据单
    public function numToWorkOrder($req)
    {
		$wdlInfo = [];
		$factory = new factory();
		$wdiNumArr = [];
		foreach($req['nums'] as $tnums){
			if(empty($tnums)) continue;
			$nums = [];
			foreach($tnums as $tnum){
				$tarr = unserialize(base64_decode($tnum));
				foreach($tarr as $tv){
					$pfid = empty($tv['factory']) || $tv['factory'] == 'OE'? 1: $factory->getFacId($tv['factory'], 'add');
					$format = formatNum($tv['number']);
					if($format){
						$nums[$pfid.$format] = [
							'wdif_type'=>'Number',
							'wdif_val'=>$tv['number'],
							'wdif_search'=>$format,
							'wdif_pf_id'=>$pfid? $pfid: 1
						];
					}
				}
			}
			if($nums) $wdiNumArr[] = $nums;
		}
		
		if(empty($wdiNumArr)) exitJson('号码必填');
		if($req['wdlist_id']){
			$wdlArr = $this->db->get('work_data_list', ['wdlist_id', 'wdlist_seq'], ['wdlist_id'=>$req['wdlist_id']]);
			$wdlist_seq = $wdlArr['wdlist_seq'];
			$wdlist_id = $req['wdlist_id'];
		}

		$work = new work();
		$opuser = getOpuser();
		$datetime = getNowTime();

		$this->db->Begin();
		$check = new check();
		
		if(empty($wdlist_id)){
			$exists = $check->checkExist('wdlist_title', ['wdlist_title'=>$req['wdlist_title']]);
			if($exists) exitJson('标题已存在');
			$wdl = [
				'wdlist_seq'=>$work->getWorkSeqNext(),
				'wdlist_from_opuser'=>$req['wdlist_from_opuser']? $req['wdlist_from_opuser'] : '',
				'wdlist_title'=>$req['wdlist_title'],
				'wdlist_remark'=>$req['wdlist_remark']? $req['wdlist_remark'] : '',
				'wdlist_opuser'=>$opuser,
				'wdlist_create_time'=>$datetime,
				'wdlist_update_time'=>$datetime
			];
			$wdlist_seq = $wdl['wdlist_seq'];
			$this->db->insert('work_data_list', $wdl);
			$wdlist_id = $this->db->id();
		}
		$noCatids = [];
		foreach($wdiNumArr as $nums){
			$toFormat = ['Number'=>[]];
			foreach($nums as $dv){
				$uniwhere = [
					'wdi_wdlist_id'=>$wdlist_id,
					'wdif_type'=>'Number',
					'wdif_search'=>$dv['wdif_search'],
					'wdif_pf_id'=>$dv['wdif_pf_id']
				];
				$chk = $this->db->get('work_data_item_format(wdif)', ["[><]work_data_item(wdi)"=>["wdif.wdif_wdi_id" =>"wdi_id"]], ['wdif_id'], $uniwhere);
				if(!empty($chk)) continue;
				$toFormat['Number'][] = $dv;
			}
			if(empty($toFormat['Number'])) continue;
			
			$wdli = [
				'wdi_wdlist_id'=>$wdlist_id,	
				'wdi_data'=>'{}',
				'wdi_opuser'=>$opuser,
				'wdi_create_time'=>$datetime,
				'wdi_update_time'=>$datetime
			];
			$this->db->insert('work_data_item', $wdli);
			$wdi_id = $this->db->id();
			$noCatids[] = $wdi_id;
			//格式化数据
			foreach($toFormat as $type=>$vals){
				//数组本身去重
				$vals = array_map('unserialize', array_unique(array_map('serialize', $vals)));
				foreach($vals as $vk=>$wdif){
					$vals[$vk]['wdif_wdi_id'] = $wdi_id;
				}
				$this->db->insert('work_data_item_format', $vals);
			}
		}
		if($noCatids) $this->autoCleanCat(['ids'=>$noCatids]);
		$this->db->End();
		$wdlInfo = ['wdlist_id'=>$wdlist_id, 'wdlist_seq'=>$wdlist_seq];
        return $wdlInfo;
	}


	/**
	 * 询源明细自动转数据单
	 * @return string
	 */
	public function askItemToWorkOrder($wai_ids)
	{
		$where = [
			'wai_id'=>$wai_ids,
			'RAW_NOT'=>raw(" wai_id not in (SELECT distinct wdi_from_id FROM work_data_item where wdi_from=1123)")
		];
		$items = $this->db->select('work_ask_item', ['wai_id', 'wai_was_id', 'wai_cat_id'], $where);
		if($items){
			$linkArr = [];
			foreach($items as $v){
				$linkArr[$v['wai_was_id']][] = $v;
			}
			$nums = [];
			$factory = new factory();
			$rows = $this->db->select('work_ask_item_num', ['wain_wai_id', 'wain_pf_name(factory)', 'wain_number(number)', 'wain_format'], ['wain_wai_id'=>array_column($items, 'wai_id')]);
			foreach($rows as $tv){
				$pfid = empty($tv['factory']) || $tv['factory'] == 'OE'? 1: $factory->getFacId($tv['factory'], 'add');
				$format = $tv['wain_format'];
				if($format){
					$nums[$tv['wain_wai_id']][] = [
						'wdif_type'=>'Number',
						'wdif_val'=>$tv['number'],
						'wdif_search'=>$format,
						'wdif_pf_id'=>$pfid? $pfid: 1
					];
				}
			}

			$opuser = getOpuser();
			$datetime = getNowTime();
			$this->db->Begin();
			$noCatids = [];
			foreach($linkArr as $wasid=>$wais){
				$wdlist_id = $this->db->get('work_data_list', 'wdlist_id', ['wdlist_from'=>1123, 'wdlist_from_id'=>$wasid]);
				if(!$wdlist_id){
					$wdl = [
						'wdlist_seq'=>$this->getWorkSeqNext(),
						'wdlist_from_opuser'=>'',
						'wdlist_title'=>'询单ID:'.$wasid,
						'wdlist_remark'=>'',
						'wdlist_from'=>1123,
						'wdlist_from_id'=>$wasid,
						'wdlist_opuser'=>$opuser,
						'wdlist_create_time'=>$datetime,
						'wdlist_update_time'=>$datetime
					];
					$wdlist_seq = $wdl['wdlist_seq'];
					$this->db->insert('work_data_list', $wdl);
					$wdlist_id = $this->db->id();
				}
				foreach($wais as $wai){
					$toFormat = ['Number'=>$nums[$wai['wai_id']]];
					$wdli = [
						'wdi_wdlist_id'=>$wdlist_id,	
						'wdi_cat_id'=>$wai['wai_cat_id'],
						'wdi_data'=>'{}',
						'wdi_from'=>1123,
						'wdi_from_id'=>$wai['wai_id'],
						'wdi_opuser'=>$opuser,
						'wdi_create_time'=>$datetime,
						'wdi_update_time'=>$datetime
					];
					if($wai['wai_cat_id']) $wdli['wdi_cat_id'] = $wai['wai_cat_id'];
					$this->db->insert('work_data_item', $wdli);
					$wdi_id = $this->db->id();
					if(!$wai['wai_cat_id']) $noCatids[] = $wdi_id;
					//格式化数据
					foreach($toFormat as $type=>$vals){
						//数组本身去重
						$vals = array_map('unserialize', array_unique(array_map('serialize', $vals)));
						foreach($vals as $vk=>$wdif){
							$vals[$vk]['wdif_wdi_id'] = $wdi_id;
						}
						$this->db->insert('work_data_item_format', $vals);
					}
				}
			}
			if($noCatids) $this->autoCleanCat(['ids'=>$noCatids]);
			$this->db->End();
		}
		return [];
	}
	

	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=='wdi_dstatus'){
						$v['wdi_dstatus'] = $v['wdi_dstatus'] == 1 ? 'Y' : 'N';
					}
					if($fk=='wdi_clean'){
						$v['wdi_clean'] = $v['wdi_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['wdi_chkpro_clean_result']) ? []: json_decode($v['wdi_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->getRowDimension($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);

	}


	//tcd汽车品牌
	function tcdMfaList($req)
	{
		$ypApi = new ypApi();
		$req['lang'] = LG;
		$hotids = [];
		$ckv = new \model\ckv();
		$hids = $ckv->getKV('hot_brands');
		if($hids){
			$hotids = $this->db->select('m_make', 'mk_ypmfa_id', ['mk_id'=>$hids]);
			if(!$hotids) $hotids = [];
		}
		$res = $ypApi->Get('tcd/tcdMfaList', $req);
		$arr = $res['data'];
		foreach($arr as $k=>$v){
			$arr[$k]['ishot'] = in_array($v['mfa_id'], $hotids)? 1: 0;
		}
		return $arr;
	}

	//tcd某些汽车生产商的竞品和分类
	function tcdSupGaByMfa($req)
	{
		$ypApi = new ypApi();
		$req['lang'] = LG;
		$res = $ypApi->Get('tcd/tcdSupGaByMfa', [], $req);
		$arr = $res['data'];
		return $arr;
	}

	//tcd产品统计
	function tcdGaSupTj($req)
	{
		$ypApi = new ypApi();
		$req['lang'] = LG;
		$res = $ypApi->Get('tcd/tcdGaSupTj', [], $req);
		$arr = $res['data'];
		return $arr;
	}

	//tcd产品统计
	function tcdGaSupArtList($req)
	{
		$ypApi = new ypApi();
		$req['lang'] = LG;
		$res = $ypApi->Get('tcd/tcdGaSupArtList', [], $req);
		$arr = $res['data'];
		$supname = $req['supname'];
		$factory = new factory();
		$pfid = $factory->getFacId($supname);

		$ganame = $req['ganame'];
		$cate = new cate();
		$catIds = [];
		$tid = $cate->eqname($ganame);
		if(!empty($tid)){
			$catIds = [$tid];
		}else{
			$tids = $cate->eqnameByTcd($ganame);
			$catIds = $tids;
		}

		$tnums = [];
		$numToPoe = [];
		foreach($arr as $k=>$v){
			$tnums[] = $v['art_format'];
			if($k % 1000 == 999 || $k+1 == count($arr)){
				
				$join = [
					'[><]oe_item(woe)'=>['woi.on_oe_id'=>'oe_id'],
					"[><]pro_factory(pf)" => ["woe.oe_pf_id" => "pf_id"],
					"[<]pro_factory(pf2)" => ["woi.on_pf_id" => "pf_id"],
				];
				$where = ['on_pf_id'=>$pfid, 'on_formart'=>$tnums, 'GROUP'=>['oe_id'], 'ORDER'=>['oe_id'=>'DESC']];
				if($catIds) $where['oe_cate_id'] = $catIds;
				$rows = $this->db->select('oe_numidx(woi)', $join, ['oe_id', 'pf.pf_name', 'oe_oe', 'on_formart'], $where);
				foreach($rows as $vv){
					$numToPoe[$vv['on_formart']][] = $vv;
				}
				$tnums = [];
			}
		}

		foreach($arr as $k=>$v){
			$v['poe'] = $numToPoe[$v['art_format']]? $numToPoe[$v['art_format']]: [];
			$arr[$k] = $v;
		}
		return $arr;
	}
}