<?php
namespace model\pro;
use \model;
use \model\tags;
use \model\pro\pro;
use \model\pro\factory;
use \model\carmodel;
use \model\check;
use \model\collocation;

/**
 * Class 产品号码关系
 * @package Numidx
 */
class numidx extends model
{
	public function __construct ()
    {
		parent::__construct();
		$this->factory = new factory();
	}
	/**
	  * @method 待进入交叉库 数据  
	  * @method ['next'=>1表示取下一条]
	  * @author soul
	  */
	public function getListTemp($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? '': $params['sidx'];
		$sord = empty($params['sord'])? 'asc': $params['sord'];
		$orderby = $params['orderby'];

		if(!empty($params['next']) && !empty($params['ckact']))
		{
			$page = 1;
			$pagesize = 1;
			if($params['ckact'] == 'ck1')
			{
				$params['ck1'] = 0;
			}
			else if($params['ckact'] == 'ck2')
			{
				$params['ck2'] = 0;
			}
		}
		
		$refiled = [
			'pb_name'=>'pb.pb_'.LG_NAME,
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName(),
			'pnt_number'=>'pnt_formart',
			'opuser'=>'num.opuser',
			'create_time'=>'num.update_time',
			'update_time'=>'num.update_time'
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'pro_numidx_temp(num)';
		$join = [
			"[><]pro(pro)" => ["num.pnt_p_id" => "p_id"],
			"[>]pro_brand(pb)" => ["pro.p_pb_id" => "pb_id"],
			"[><]pro_cate(cat)" => ["pro.p_cate" => "id"],
			"[><]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]pro_factory(fac)" => ["num.pnt_pf_id" => "pf_id"],
			//"[>]m_make(mk)" => ["num.pnt_mk_id" => "mk_id"],
		];
		$this->set('sTags', false);
		$this->set('pnumwhere', []);
		$this->set('carmodel', new carmodel());
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'pnt_pf_id') $data = $this->factory->like($data);
			if($field == 'tags')
			{
				$res = $this->get('carmodel')->medooAnyLink($field, 'pnt_id', $op, $data, ['tl_type'=>'_number']);
				$data = $res['data'];
				$op = $res['op'];
			}
			
			if($field == 'pnt_formart') $data = formatNum($data);
			if($field == 'p_comnum')
			{
				$res = $this->fiterProByNum('p_comnum', ['p_fined'=>'num.pnt_p_id', 'op'=>$op, 'val'=>$data, 'pnumwhere'=>$this->get('pnumwhere')]);
				$op = $res['op'];
				$data = $res['data'];
				$this->set('pnumwhere', $res['pnumwhere']);
			}
			if($field == 'pnt_cn_remark') $op = 'bw';
			if($field == 'pnt_mk_id'){
			    if(in_array($op,['cn','bw','eq'])){
			        $data = $this->db->select('m_make','mk_id',['name['.$this->getMedooOp($op).']'=>$data]);
			        if(!$data) $data = [-1];
			        $op = 'eq';
			    }
			}
        });
		
		foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
				case 'numbers':
					if(!empty($rules['numfac']) && $rules['numfac'] == 2)
					{
						$res = $this->fiterProByNum('numbers', ['p_fined'=>'num.pnt_p_id', 'numlike'=>$rules['numlike'], 'val'=>$val, 'pnumwhere'=>$this->get('pnumwhere')]);
						$where = array_merge($where, $res['sqlwhere']);
						$this->set('pnumwhere', $res['pnumwhere']);
					}
					else
					{
						foreach($val as $tk=>$tv)
						{
							$val[$tk] = formatNum($tv);
						}
						if($rules['numfac'] == 3)
						{
							$where['p_innum_format'.($rules['numlike']? '[~]': '')] = $val;
						}
						else if($rules['numfac'] == 1)
						{
							$where['pnt_formart'.($rules['numlike']? '[~]': '')] = $val;
						}
						else
						{
							$where["AND #num"] = [
								"OR" => [
									'pnt_formart'.($rules['numlike']? '[~]': '') => $val,
									'p_comnum_format'.($rules['numlike']? '[~]': '') => $val,
									'p_innum_format'.($rules['numlike']? '[~]': '') => $val
								]
							];
						}
						if(!empty($rules['numfac']) && !in_array($rules['numfac'], [2,3]))
						{
							$where['num.pnt_pf_id'] = $rules['numfac'];
						}
					}
				break;
				case 'p_cate': $where['p_cate'] = explode(',', $rules['p_cate']); break;
				case 'ver': 
					$join["[><]tags_link(tl)"] = ["num.pnt_id" => "tl_value_id"];
					$where['tl_type'] = '_number';
					$where['tl_t_id[>]'] = raw(sprintf("tl_t_id ^ %d",$rules['ver']));
				break;
			}
		}

		//状态
		$where['p_pb_id'] = 1;
		$where["pnt_status"] = empty($params['pnt_status']) || $params['pnt_status'] != -1 ? 1: -1;
		$check = new \model\check();
		$ruleWhere = $check->getPowerWhere('pro_numidx_temp', $where["pnt_status"] == 1? 'E100':'E300');
		$where = array_merge($where, $ruleWhere);
		
		if(!empty($params['keys'])) $where['pnt_id'] = explode(',', $params['keys']);
		if(!empty($params['pnt_id'])) $where['pnt_id'] = $params['pnt_id'];
		$orgPid = 0;
		if(!empty($params['p_lnk_p_id'])){
			$where['p_id'] = $params['p_lnk_p_id'];
			$orgPid = $params['p_id'];
		}else if(!empty($params['p_id'])){
			$where['p_id'] = $params['p_id'];
		}
		
		if(isset($params['ck1'])) $where['ck1'] = $params['ck1'];
		if(isset($params['ck2'])) $where['ck2'] = $params['ck2'];
		if(empty($where['ORDER']))$where['ORDER'] = ['pcat.'.cateName(), 'cat.'.cateName(), 'p_comnum', 'pf_name', 'pnt_formart'];

        $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)', 'p_id', 'p_innum', 'p_comnum', 'p_state_main', 'fac.pf_id', 'fac.pf_name', 'pb_'.LG_NAME.'(pb_name)', 'num.*'];

        $arr = $this->db->select($table,$join,$fields,$where);
		//dd($this->db->last());
		if(!empty($this->get('pnumwhere'))) $arr = $this->getSearchOutnum($arr, $this->get('pnumwhere'));
		if(!empty($arr)){
			$arr = $this->fillProNumidxTemp($arr);
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}


	public function fillProNumidxTemp($arr)
	{
		if(!empty($arr))
		{
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('number');

			$carmodel = new carmodel();
			$tags = new tags();
			$verArr = $tags->getTypeValTags('_number', array_column($arr, 'pnt_id'));
			$verArr = array_column($verArr, 'tags', 'tl_value_id');
			foreach($arr as &$v)
			{
				$oemake = [];
				if(!empty($v['pnt_mk_id'])) $oemake = $carmodel->getMakes(explode(',', $v['pnt_mk_id']));
				$v['tags'] = empty($verArr[$v['pnt_id']]) ? '': implode(',', array_column($verArr[$v['pnt_id']], 't_id'));
				$v['captions'] = [
					'pnt_pf_id'=>$v['pf_name'],
					'pnt_mk_id'=>implode(',', array_column($oemake, 'mk_'.LG_NAME)),
					'tags'=> empty($verArr[$v['pnt_id']]) ? '': implode(',', array_column($verArr[$v['pnt_id']], LG_NAME)),
					'pnt_src'=>!empty($collArr[$v['pnt_src']])? $collArr[$v['pnt_src']]: '',
					'ckresult1'=>!empty($collArr[$v['ckresult1']])? $collArr[$v['ckresult1']]: '',
					'ckresult2'=>!empty($collArr[$v['ckresult2']])? $collArr[$v['ckresult2']]: ''
				];
			}
		}
		return $arr;
	}
	

	/**
	  * @method 添加 待进入交叉库
	  * @param  $dataArr  array  [必填] ['pnt_outnum'=>'', 'pnt_pf_id'=>'',....,'tags'=>[1,2...]]
	  * @author soul
	  */
	public function adNumidxTemp($dataArr)
	{
		$fileds = ['pnt_src', 'pnt_sign_type', 'pnt_innum', 'pnt_pf_id', 'pnt_number', 'pnt_mk_id', 'pnt_cn_remark', 'pnt_en_remark', 'pnt_ref', 'ckresult1', 'ckremark1'];
		$baseArr = [];
		$othArr = [];
		foreach($dataArr as $filed=>$v)
		{
			if(in_array($filed, $fileds))
			{
				$baseArr[$filed] = $v;
			}
			else
			{
				$othArr[$filed] = $v;
			}
		}

		//确认产品ID
		if(empty($baseArr['pnt_p_id']))
		{
			$pro = new pro();
			$pid = $pro->getLinkPidByInnum($baseArr['pnt_innum']);
			if(empty($pid)) exitJson('', '物料编码不存在');
			$baseArr['pnt_p_id'] = $pid;
		}
		unset($baseArr['pnt_innum']);

		$row = $this->db->get('pro', ['p_cate', 'p_innum'], ['p_id'=>$baseArr['pnt_p_id'], 'p_pb_id'=>1]);
		if(!\p::catesAdd('E100', $row['p_cate'])) exitJson('无此品名权限');

		$baseArr['pnt_formart'] = formatNum($baseArr['pnt_number']);
		if(empty($baseArr['pnt_pf_id'])) exitJson('号码品牌必填');
		if(empty($baseArr['pnt_formart'])) exitJson('号码必填');
		
		$exists = $this->checkExistTemp($baseArr);
		if(!empty($exists)) exitJson($exists['msg']);

		$opuser = getOpuser();
		$datetime = getNowTime();
		$baseArr['opuser'] = $opuser;
		$baseArr['create_time'] = $datetime;
		$baseArr['update_time'] = $datetime;
		
		//初审人
		if(!empty($baseArr['ckresult1']) || !empty($baseArr['ckremark1']))
		{
			$baseArr['ck1'] = 1;
			$baseArr['ckuser1'] = $opuser;
			$baseArr['cktime1'] = $datetime;
		}
		$this->db->Begin();
		$this->db->insert('pro_numidx_temp', $baseArr);
		$pnt_id = $this->db->id();

		/*if(isset($othArr['tags'])){
			$tagsLinkArr = [['t_id'=>$othArr['tags'], 'value_id'=>$pnt_id]];
			$tags = new tags();
			$tags->changeTagsLink('_number', 'replace', $tagsLinkArr);
		}*/

		$this->db->End();
		return ['pnt_id'=>$pnt_id];
	}


	/**
	  * @method 虚删除待进入交叉号
	  * @param  $idArr array [必填] pnt_id [1,2,3,...]
	  * @author soul
	  */
	public function xudelNumidxTemp($idArr)
	{
		if(!empty($idArr))
		{
			$opuser = getOpuser();
			$datetime = getNowTime();
			$setArr = [
				'pnt_status'=>-1,
				'update_time'=>$datetime,
				'opuser'=>$opuser
			];
			$this->db->update('pro_numidx_temp', $setArr, ['pnt_id'=>$idArr]);
		}
		return [];
	}


	/**
	  * @method 删除待进入交叉号
	  * @param  $idArr array [必填] pnt_id [1,2,3,...]
	  * @author soul
	  */
	public function delNumidxTemp($idArr)
	{
		if(!empty($idArr))
		{
			$rows = $this->db->select('pro_numidx_temp', 'pnt_p_id', ['pnt_id'=>$idArr]);
			$check = new check();
			$proCateRule = $check->checkProRuleCate($rows, 'E300', 'delete');
			if(!empty($proCateRule['no'])) exitJson('无此品名权限');

			$this->db->delete('pro_numidx_temp', ['pnt_status'=>-1, 'pnt_id'=>$idArr]);
		}
		return [];
	}


	/**
	  * @method 编辑待进入交叉号单字段
	  * @param  $pnt_id  int  [必填] pnt_id
	  * @param  $setArr  array  [必填] ['pnt_pf_id'=>'',....]
	  * @author soul
	  */
	public function setNumidxCellTemp($pnt_id, $setArr)
	{
		$canSetFiled = ['pnt_src', 'pnt_sign_type',  'pnt_pf_id', 'pnt_number', 'pnt_mk_id', 'pnt_cn_remark', 'pnt_en_remark', 'pnt_ref', 'tags','sale_coun'];
		if(!empty($pnt_id) && !empty($setArr))
		{
			$old = $this->db->get('pro_numidx_temp', '*', ['pnt_id'=>$pnt_id]);
			if(empty($old)) exitJson('记录不存在');

			$row = $this->db->get('pro', ['p_cate', 'p_innum', 'p_comnum'], ['p_id'=>$old['pnt_p_id']]);
			if(!\p::catesEdit('E100', $row['p_cate'])) exitJson('无此品名权限');
			
			$this->db->Begin();
			foreach($setArr as $filed=>$val)
			{
				if(!in_array($filed, $canSetFiled)) 
				{
					unset($setArr[$filed]);
					continue;
				}
				if($filed == 'tags')
				{
					$tagsLinkArr = [['t_id'=>$val, 'value_id'=>$pnt_id]];
					$tags = new tags();
					$tags->changeTagsLink('_number', 'replace', $tagsLinkArr);
					unset($setArr[$filed]);
				}
			}
			if(isset($setArr['pnt_number']))
			{
				$setArr['pnt_formart'] = formatNum($setArr['pnt_number']);
			}
			
			$opuser = getOpuser();
			$datetime = getNowTime();
			if(!empty($setArr['ckresult1']) || !empty($setArr['ckremark1']))
			{
				$setArr['ck1'] = 1;
				$setArr['ckuser1'] = $opuser;
				$setArr['cktime1'] = $datetime;
			}

			if(!empty($setArr['ckresult2']) || !empty($setArr['ckremark2']))
			{
				$setArr['ck2'] = 1;
				$setArr['ckuser2'] = $opuser;
				$setArr['cktime2'] = $datetime;
			}
			
			if(!empty($setArr))
			{
				$setArr = array_merge($old, $setArr);
				if(empty($setArr['pnt_pf_id'])) exitJson('号码品牌必填');
				if(empty($setArr['pnt_formart'])) exitJson('号码必填');
				if($setArr['pnt_pf_id'] == 1 && empty($setArr['pnt_mk_id'])) exitJson('OE品牌必填');

				$setArr['opuser'] = $opuser;
				$setArr['update_time'] = $datetime;
				
				$exists = $this->checkExistTemp($setArr, $pnt_id);
				if(!empty($exists)) exitJson($exists['msg']);

				$this->db->update('pro_numidx_temp', $setArr, ['pnt_id'=>$pnt_id]);
			}
			$this->db->End();
		}
		return [];
	}

	/**
     * 加入待进入检测是交叉号否存在
	 * @param  $dataArr  array  [必填] ['pnt_p_id'=>'', 'pnt_pf_id'=>'', 'pnt_formart'=>'']
     */
	public function checkExistTemp($dataArr, $pnt_id = 0)
	{
		//正式交叉号库
		$uniwhere = [
			//'p_state_main[!]'=>'Y5',
			'pn_type'=>'none',
			'pn_is_sys'=>0,
			'pn_p_id'=>$dataArr['pnt_p_id'],
			'pn_pf_id'=>$dataArr['pnt_pf_id'],
			'pn_formart'=>$dataArr['pnt_formart']
		];

		$table = 'pro_numidx(num)';
		$join = ["[><]pro(pro)" => ["num.pn_p_id" => "p_id"]];
		$exists = $this->db->get($table, $join, ['pn_id'], $uniwhere);
		if(!empty($exists)) return ['code'=>0, 'table'=>'pro_numidx', 'msg'=>$dataArr['pnt_formart'].'正式交叉号库已有记录，禁止添加'];

		//变更库
		/*$uniwhere = [
			'pnc_act'=>'del',
			'pn_p_id'=>$dataArr['pnt_p_id'],
			'pn_pf_id'=>$dataArr['pnt_pf_id'],
			'pn_formart'=>$dataArr['pnt_formart']
		];
		$chk = $this->db->get('pro_numidx_change', ['delremark', 'pnc_opuser', 'pnc_create_time'], $uniwhere);
		if(!empty($chk)){
			$msg = $dataArr['pnt_formart'].'变更交叉号库已有记录，禁止添加';
			$msg .= '<br>'.$chk['delremark'].' '.$chk['pnc_opuser'].' '.$chk['pnc_create_time'];
			return ['code'=>0, 'table'=>'pro_numidx_change', 'msg'=>$msg];
		}*/

		$uniwhere = [
			'pnt_id[!]'=>$pnt_id,
			'pnt_p_id'=>$dataArr['pnt_p_id'],
			'pnt_pf_id'=>$dataArr['pnt_pf_id'],
			'pnt_formart'=>$dataArr['pnt_formart']
		];
		$chk = $this->db->get('pro_numidx_temp', ['pnt_id', 'pnt_status', 'ckuser1', 'ckremark1', 'cktime1', 'ckuser2', 'ckremark2', 'cktime2'], $uniwhere);
		if(!empty($chk)){
			return ['code'=>0, 'table'=>'pro_numidx_temp', 'msg'=>'待进入交叉号库已有记录，禁止添加'];
			/*
			if($chk['pnt_status'] == -1){
				$msg = $dataArr['pnt_formart'].'虚删除交叉号库已有记录，禁止添加';
				if(!empty($chk['ckremark2'])){
					$msg .= '<br>'.$chk['ckremark2'].' '.$chk['ckuser2'].' '.$chk['cktime2'];
				}else{
					$msg .= '<br>'.$chk['ckremark1'].' '.$chk['ckuser1'].' '.$chk['cktime1'];
				}
				return ['code'=>0, 'table'=>'pro_numidx_temp_del', 'msg'=>$msg];
			}else{
				return ['code'=>0, 'table'=>'pro_numidx_temp', 'msg'=>'待进入交叉号库已有记录，禁止添加'];
			}*/
		}

		return [];
	}


	/**
     * 加入正式库检测是交叉号否存在
	 * @param  $dataArr  array  [必填] ['pn_p_id'=>'', 'pn_pf_id'=>'', 'pn_formart'=>'']
     */
	public function checkExist($dataArr, $pn_id = 0)
	{
		//正式交叉号库
		$uniwhere = [
			//'p_state_main[!]'=>'Y5',
			'pn_type'=>'none',
			'pn_is_sys'=>0,
			//'pn_id[!]'=>$pn_id,
			'pn_p_id'=>$dataArr['pn_p_id'],
			'pn_pf_id'=>$dataArr['pn_pf_id'],
			'pn_formart'=>$dataArr['pn_formart']
		];
		$table = 'pro_numidx(num)';
		$join = ["[><]pro(pro)" => ["num.pn_p_id" => "p_id"]];
		$exists = $this->db->get($table, $join, ['pn_id'], $uniwhere);
		if(!empty($exists)) return ['code'=>0, 'table'=>'pro_numidx', 'msg'=>$dataArr['pn_formart'].'已存在，禁止添加'];


		/*$uniwhere = [
			'p_state_main[!]'=>'Y5',
			'pn_type'=>'none',
			'pn_is_sys'=>0,
			'pn_id[!]'=>$pn_id,
			'pn_pf_id'=>$dataArr['pn_pf_id'],
			'pn_formart'=>$dataArr['pn_formart']
		];
		$table = 'pro_numidx(num)';
		$join = ["[><]pro(pro)" => ["num.pn_p_id" => "p_id"]];
		$rows = $this->db->select($table, $join, ['pn_id', 'pn_cn_remark'], $uniwhere);
		if(!empty($rows))
		{
			$hasremark = array_unique(array_column($rows, 'pn_cn_remark'));
			if(empty($dataArr['pn_cn_remark']) || count($hasremark) > 1 || $hasremark[0] != $dataArr['pn_cn_remark'])
				return ['code'=>0, 'table'=>'pro_numidx', 'msg'=>$dataArr['pn_formart'].'号码一对多，中文描述需不能为空且相同'];
		}*/

		//变更库
		/*$uniwhere = [
			'pnc_act'=>'del',
			'pn_p_id'=>$dataArr['pn_p_id'],
			'pn_pf_id'=>$dataArr['pn_pf_id'],
			'pn_formart'=>$dataArr['pn_formart']
		];
		$chk = $this->db->get('pro_numidx_change', ['delremark', 'pnc_opuser', 'pnc_create_time'], $uniwhere);
		if(!empty($chk)){
			$msg = $dataArr['pn_formart'].'变更交叉号库已有记录，禁止添加';
			$msg .= '<br>'.$chk['delremark'].' '.$chk['pnc_opuser'].' '.$chk['pnc_create_time'];
			return ['code'=>0, 'table'=>'pro_numidx_change', 'msg'=>$msg];
		}*/
		return [];
	}



	/**
	  * @method 初审待进入产品交叉号
	  * @param  $idArr array [必填] [1,2,3,...]
	  * @param  $setArr array [必填] ['act'=>'ok|del','ckresult1'=>'结论', 'ckremark1'=>'核对备注'] 
	  * @author soul
	  */
	public function check1Temp($idArr, $setArr)
	{
		if(!empty($idArr))
		{
			$tempArr = $this->db->select('pro_numidx_temp', '*', ['pnt_id'=>$idArr]);
			if(empty($tempArr)) exitJson('记录不存在');

			$check = new check();
			$proCateRule = $check->checkProRuleCate(array_column($tempArr, 'pnt_p_id'), 'E100', 'check1');
			if(!empty($proCateRule['no'])) exitJson('无此品名权限');

			$opuser = getOpuser();
			$datetime = getNowTime();
			$set = [
				'ckuser1'=>$opuser,
				'cktime1'=>$datetime,
				'ckresult1'=>$setArr['ckresult1'],
				'ckremark1'=>$setArr['ckremark1'],
				'update_time'=>$datetime,
				'opuser'=>$opuser
			];

			/*if(isset($setArr['pnt_mk_id']))
			{
				foreach($idArr as $pnt_id)
				{
					$this->setNumidxCellTemp($pnt_id, $setArr);
				}
			}*/
			if($setArr['act'] && $setArr['act'] == 'ok')
			{
				$set['ck1'] = 1;
				$this->db->update('pro_numidx_temp', $set, ['pnt_id'=>$idArr]);
			}
			else if($setArr['act'] && $setArr['act'] == 'del')
			{
				$set['ck1'] = 1;
				$set['pnt_status'] = -1;
				//$this->db->update('pro_numidx_temp', $set, ['pnt_id'=>$idArr]);
				$this->db->delete('pro_numidx_temp', ['pnt_id'=>$idArr]);
			}
		}
		return [];
	}
	

	/**
	  * @method 复审待进入产品交叉号
	  * @param  $idArr array [必填] [1,2,3,...]
	  * @param  $setArr array [必填] ['act'=>'ok|del','ckresult2'=>'结论', 'ckremark2'=>'核对备注'] 
	  * @author soul
	  */
	public function check2Temp($idArr, $setArr)
	{
		if(!empty($idArr))
		{
			//转正式，并删除待进入
			$join = [
				"[><]pro(pro)" => ["num.pnt_p_id" => "p_id"],
			];
			$tempArr = $this->db->select('pro_numidx_temp(num)', $join, '*', ['pnt_id'=>$idArr]);
			if(empty($tempArr)) exitJson('记录不存在');

			$check = new check();
			$proCateRule = $check->checkProRuleCate(array_column($tempArr, 'pnt_p_id'), 'E100', 'check2');
			if(!empty($proCateRule['no'])) exitJson('无此品名权限');

			$opuser = getOpuser();
			$datetime = getNowTime();
			
			if($setArr['act'] && $setArr['act'] == 'ok')
			{
				/*$tags = new tags();
				$tagsArr = $tags->getTypeValTags('_number', array_column($tempArr, 'pnt_id'));
				$tagsArr = array_column($tagsArr, 'tags', 'tl_value_id');*/

				$this->db->Begin();
				$pro = new pro();
				foreach($tempArr as $mt)
				{
					//此产品是否有合并后产品
					$mergePid = $this->db->get('p_code', 'pc_merge_p_id', ['pc_p_id'=>$mt['pnt_p_id']]);
					if(!empty($mergePid)) $mt['pnt_p_id'] = $mergePid;

					$chk = $pro->canSetPro($mt['pnt_p_id']);
					if(!empty($chk['msg'])) exitJson($chk['msg']);

					$set = [
						'pn_type'=>'none',
						'pn_is_sys'=>0,
						'pn_p_id'=>$mt['pnt_p_id'],
						'pn_pf_id'=>$mt['pnt_pf_id'],
						'pn_number'=>$mt['pnt_number'],
						'pn_formart'=>formatNum($mt['pnt_number']),
						'pn_mk_id'=>$mt['pnt_mk_id'],
						/*'pn_src'=>$mt['pnt_src'],
						'pn_sample'=>$mt['pnt_sample'],
						'pn_sign_type'=>$mt['pnt_sign_type'],
						'pn_cn_remark'=>$mt['pnt_cn_remark'],
						'pn_en_remark'=>$mt['pnt_en_remark'],
						'pn_ref'=>$mt['pnt_ref'],
						'ckuser1'=>$mt['ckuser1'],
						'cktime1'=>$mt['cktime1'],*/
						'ckuser2'=>$opuser,
						'ckresult2'=>$setArr['ckresult2'],
						'ckremark2'=>empty($setArr['ckremark2'])? $mt['ckremark1']: $setArr['ckremark2'],
						'cktime2'=>$datetime,
						'create_time'=>$datetime,
						'update_time'=>$datetime,
						'opuser'=>$opuser
					];

					//合并历史
					if(!empty($mergePid)) $set['pn_merge_remark'] = $mt['p_innum'];

					if($set['pn_pf_id'] == 1 && empty($set['pn_mk_id']))  exitJson('OE品牌必填');

					$exists = $this->checkExist($set);
					if(!empty($exists)) exitJson($exists['msg']);
					$this->db->insert('pro_numidx', $set);
					$pn_id = $this->db->id();
					//数据版本
					/*if(!empty($tagsArr[$mt['pnt_id']])){
						$tags->changeTagsLink('number', 'replace', ['t_id'=>array_column($tagsArr[$mt['pnt_id']], 't_id'), 'value_id'=>$pn_id]);
					}*/
				}
				$this->db->delete('pro_numidx_temp', ['pnt_id'=>$idArr]);
				$this->db->End();
			}
			else if($setArr['act'] && $setArr['act'] == 'notpass')
			{
				$set = [
					'ck2'=>1,	
					//'pnt_status'=>-1,
					'ckuser2'=>$opuser,
					'cktime2'=>$datetime,
					'ckresult2'=>$setArr['ckresult2'],
					'ckremark2'=>$setArr['ckremark2'],
					'update_time'=>$datetime,
					'opuser'=>$opuser
				];
				$this->db->update('pro_numidx_temp', $set, ['pnt_id'=>$idArr]);
			}
		}
		return [];
	}

	
	/**
	  * @method 正式交叉库 数据 pro_numidx
	  * @author soul
	  */
	public function getList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? '': $params['sidx'];
		$sord = empty($params['sord'])? 'asc': $params['sord'];
		$orderby = $params['orderby'];
		
		$refiled = [
			'pb_name'=>'pb.pb_'.LG_NAME,
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName(),
			'pn_number'=>'pn_formart',
			'opuser'=>'num.opuser',
			'create_time'=>'num.update_time',
			'update_time'=>'num.update_time'
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'pro_numidx(num)';
		$join = [
			"[>]pro(pro)" => ["num.pn_p_id" => "p_id"],
			"[>]pro_brand(pb)" => ["pro.p_pb_id" => "pb_id"],
			"[>]pro_cate(cat)" => ["pro.p_cate" => "id"],
			"[>]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]pro_factory(fac)" => ["num.pn_pf_id" => "pf_id"]
		];
		
		$this->set('pnumwhere', []);
		$this->set('carmodel', new carmodel());
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));

			if($field == 'pn_pf_id') $data = $this->factory->like($data);

			if($field == 'tags')
			{
				$res = $this->get('carmodel')->medooAnyLink($field, 'pn_id', $op, $data, ['tl_type'=>'number']);
				$data = $res['data'];
				$op = $res['op'];
			}
			if($field == 'pn_formart') $data = formatNum($data);
			if($field == 'p_comnum')
			{
				$res = $this->fiterProByNum('p_comnum', ['p_fined'=>'num.pn_p_id', 'op'=>$op, 'val'=>$data, 'pnumwhere'=>$this->get('pnumwhere')]);
				$op = $res['op'];
				$data = $res['data'];
				$this->set('pnumwhere', $res['pnumwhere']);
			}
			if($field == 'pn_cn_remark') $op = 'bw';
			if($field == 'pn_mk_id'){
			    if(in_array($op,['cn','bw','eq'])){
			        $data = $this->db->select('m_make','mk_id',['name['.$this->getMedooOp($op).']'=>$data]);
			        if(!$data) $data = [-1];
			        $op = 'eq';
			    }
			}
			if($field == 'pn_id') $data = explode(',', $data);
        });
		
		$where['pn_is_sys'] = 0;
		foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
				case 'numbers':
					if(!empty($rules['numfac']) && $rules['numfac'] == 2)
					{
						$res = $this->fiterProByNum('numbers', ['p_fined'=>'num.pn_p_id', 'numlike'=>$rules['numlike'], 'val'=>$val, 'pnumwhere'=>$this->get('pnumwhere')]);
						$where = array_merge($where, $res['sqlwhere']);
						$this->set('pnumwhere', $res['pnumwhere']);
					}
					else
					{
						foreach($val as $tk=>$tv)
						{
							$val[$tk] = formatNum($tv);
						}
						if($rules['numfac'] == 3)
						{
							$where['p_innum_format'.($rules['numlike']? '[~]': '')] = $val;
						}
						else if($rules['numfac'] == 1)
						{
							$where['pn_formart'.($rules['numlike']? '[~]': '')] = $val;
						}
						else
						{
							$where["AND #num"] = [
								"OR" => [
									'pn_formart'.($rules['numlike']? '[~]': '') => $val,
									'p_comnum_format'.($rules['numlike']? '[~]': '') => $val,
									'p_innum_format'.($rules['numlike']? '[~]': '') => $val
								]
							];
						}
						if(!empty($rules['numfac']))
						{
							if(!in_array($rules['numfac'], [2,3]))
							{
								$where['num.pn_pf_id'] = $rules['numfac'];
							}
						}
					}
				break;
				case 'p_cate': $where['p_cate'] = explode(',', $rules['p_cate']); break;
				case 'ver': 
					$join["[><]tags_link(tl)"] = ["num.pn_id" => "tl_value_id"];
					$where['tl_type'] = 'number';
					$where['tl_t_id[>]'] = raw(sprintf("tl_t_id ^ %d",$rules['ver']));
				break;
			}
		}
		
		$where['p_pb_id'] = 1;
		$where['pn_type'] = 'none';
		if(!empty($params['keys'])) $where['pn_id'] = explode(',', $params['keys']);
		if(!empty($params['pn_id'])) $where['pn_id'] = $params['pn_id'];
		
		//if(!empty($rules['noy5'])) $where['p_state_main[!]'] = 'Y5';
		$orgPid = 0;
		if(!empty($params['p_lnk_p_id'])){
			$where['p_id'] = $params['p_lnk_p_id'];
			$orgPid = $params['p_id'];
		}else if(!empty($params['p_id'])){
			$where['p_id'] = $params['p_id'];
		}

		//综合
		if(!empty($params['p_id']) && !empty($params['pwcode']))
		{
			if(\p::fieldhas($params['pwcode'], 'oe') && \p::fieldhas($params['pwcode'], 'numidx'))
			{}else if(\p::fieldhas($params['pwcode'], 'oe')){
				$where['AND #rulefac']['num.pn_pf_id'] = 1;
			}else if(\p::fieldhas($params['pwcode'], 'numidx')){
				$where['AND #rulefac']['num.pn_pf_id[!]'] = 1;
			}else{
				$where['AND #rulefac']['num.pn_pf_id'] = -1;
			}
		}
		else
		{//正式库
			$check = new \model\check();
			$ruleWhere = $check->getPowerWhere('pro_numidx', 'E200');
			$where = array_merge($where, $ruleWhere);
		}

        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);
		if($page>0 && $pagesize>0){
			$fields = '*';
			$pages = $this->paging($table,$join,$fields,$where,$page,$pagesize, 15*60); // 15分钟缓存
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
		$fields = ['cat.id(cat_id)', 'pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'p_id', 'p_innum', 'p_comnum', 'p_state_main', 'fac.pf_id', 'fac.pf_name', 'pb_'.LG_NAME.'(pb_name)', 'num.*'];

        $arr = $this->db->select($table,$join,$fields,$where);
		if(!empty($this->get('pnumwhere'))) $arr = $this->getSearchOutnum($arr, $this->get('pnumwhere'));
		if(!empty($arr)){
			$arr = $this->fillProNumidx($arr);
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	public function fillProNumidx($arr)
	{
		if(!empty($arr))
		{
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('number');
			$carmodel = new carmodel();
			$tags = new tags();
			$verArr = $tags->getTypeValTags('number', array_column($arr, 'pn_id'));
			$verArr = array_column($verArr, 'tags', 'tl_value_id');

			$coll13Arr = $collocation->lrtree->getChilds(13);
			$coll13Arr = array_column($coll13Arr, LG_NAME, 'o_id');
			foreach($arr as &$v)
			{
				$oemake = [];
				if(!empty($v['pn_mk_id'])) $oemake = $carmodel->getMakes(explode(',', $v['pn_mk_id']));
				$v['tags'] = empty($verArr[$v['pn_id']]) ? '': implode(',', array_column($verArr[$v['pn_id']], 't_id'));
				$v['captions'] = [
					'pn_pf_id'=>$v['pf_name'],
					'pn_mk_id'=>implode(',', array_column($oemake, 'mk_'.LG_NAME)),
					'tags'=> empty($verArr[$v['pn_id']]) ? '': implode(',', array_column($verArr[$v['pn_id']], LG_NAME)),
					'pn_src'=>!empty($collArr[$v['pn_src']])? $collArr[$v['pn_src']]: '',
					'ckresult2'=>!empty($collArr[$v['ckresult2']])? $collArr[$v['ckresult2']]: '',
					'pn_from'=>!empty($coll13Arr[$v['pn_from']])? $coll13Arr[$v['pn_from']]: '',
				];
			}
		}
		return $arr;
	}

	
	/**
	$type = 'p_comnum'  ['p_fined'=>'num.pn_p_id', 'pnumwhere'=>$pnumwhere,'op'=>'eq', 'val'=>'NTK']
	$type = 'numbers'   ['p_fined'=>'num.pn_p_id', 'numlike'=>$rules['numlike'], 'val'=>$val, 'pnumwhere'=>$this->get('pnumwhere')]
	**/
	public function fiterProByNum($type, $params)
	{
		if($type == 'p_comnum')
		{
			$pnumwhere['pn_pf_id'] = [2,5];
			$data = formatNum($params['val']);
			if($params['op'] == 'eq')
			{
				$pnumwhere['pn_formart'] =$data;
				$data= raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart = '%s')", $params['p_fined'], $data));
			}
			else
			{
				$pnumwhere['pn_formart[=~]'] =$data;
				$data= raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart like '%s%%')", $params['p_fined'], $data));
			}
			$this->set('pnumwhere', $pnumwhere);
			return ['pnumwhere'=>$pnumwhere, 'data'=>$data, 'op'=>'RAW'];
		}
		else if($type == 'numbers')
		{
			$nums = [];
			foreach($params['val'] as $tnum)
			{
				$nums[] = formatNum($tnum);
			}
			$nums = array_unique($nums);
			$sqlwhere = [];
			if($params['numlike'])
			{
				$twhere = [];
				foreach($nums as $tnum)
				{
					$twhere[] = sprintf(" pn_formart like '%s%%'", $tnum);
				}
				$sqlwhere["RAW_PNUM"] = raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and (%s))", $params['p_fined'], implode(" or ", $twhere)));
				$pnumwhere['pn_formart[=~]'] =$nums;
			}
			else
			{
				$sqlwhere["RAW_PNUM"] = raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart in ('%s'))", $params['p_fined'], implode("','", $nums)));
				$pnumwhere['pn_formart'] =$nums;
			}
			return ['pnumwhere'=>$pnumwhere, 'sqlwhere'=>$sqlwhere];
		}
		return ['pnumwhere'=>$pnumwhere];
	}

	//号码查询，p_comnum 显示查询条件的号码
	public function getSearchOutnum($dataArr, $pnumwhere)
	{
		if(!empty($pnumwhere) && !empty($dataArr))
		{
			$pnumwhere['pn_pf_id'] = 5;
			$rows = $this->db->select('pro_numidx', ['pn_p_id', 'pn_number'], $pnumwhere);
			$rows = array_column($rows, 'pn_number', 'pn_p_id');
			foreach($dataArr as &$pv)
			{
				if(!empty($rows[$pv['p_id']]))
					$pv['p_comnum'] = $rows[$pv['p_id']];
			}
		}
		return $dataArr;
	}


	
	/**
	  * @method 变更某源的标签
	  * @param  $actType string [必填] add:只增加  del:只删除 replace:替换
	  * @param  $dataArr array [必填] 
				单个 ['t_id'=>[1,2,3,4]（string|array actType=replace空表示删除）, 'value_id'=>11]
				批量 [['t_id'=>[1,2,3,4]（string|array actType=replace空表示删除）, 'value_id'=>11],...]
	  * @author soul
	  */
	public function changeTagsLinkNumber($actType, $dataArr)
	{
		if(is_array($dataArr) && !empty($dataArr))
		{
			if(!empty($dataArr['value_id'])) $dataArr = [$dataArr];
			
			$where = [
				'tl_type'=>'number',
				'tl_value_id'=>array_unique(array_column($dataArr, 'value_id')),
			];
			
			$hasArr = [];
			$rows = $this->db->select('tags_link', ['tl_t_id', 'tl_value_id'], $where);
			$hasArr = array_column($rows, 'tl_t_id', 'tl_value_id');
			
			$newArr = [];
			foreach($dataArr as $v)
			{
				if(!is_array($v['t_id'])) $v['t_id'] = explode(',', $v['t_id']);
				$newArr[$v['value_id']] = [];
				foreach($v['t_id'] as $tid)
				{
					if($tid > 0)
						$newArr[$v['value_id']][] = $tid;
				}
			}
			//标签合并处理
			switch($actType)
			{
				case 'add':
					foreach($newArr as $valid=>$tidArr)
					{
						if(!empty($hasArr[$valid]))
						{
							$tl_t_id = addXor($tidArr, $hasArr[$valid]);
							$newArr[$valid] = explodeXor($tl_t_id);
						}
					}
				break;
				case 'del':
					foreach($newArr as $valid=>$tidArr)
					{
						if(!empty($hasArr[$valid]))
						{
							$tl_t_id = deleteXor($tidArr, $hasArr[$valid]);
							$newArr[$valid] = explodeXor($tl_t_id);
						}
						else
						{
							unset($newArr[$valid]);
						}
					}
				break;
				case 'replace': break;
			}
			$this->db->Begin();
			foreach($newArr as $pn_id=>$tidArr)
			{
				$this->setNumidxCell($pn_id, ['tags'=>implode(',', $tidArr)]);
			}
			$this->db->End();
		}
		return [];
	}




	/**
	  * @method 编辑正式交叉号单字段
	  * @param  $pn_id  int  [必填] pn_id
	  * @param  $setArr  array  [必填] ['pn_cn_remark'=>'',....]
	  * @author soul
	  */
	public function setNumidxCell($pn_id, $setArr, $chkExists = true)
	{
		$canSetFiled = ['pn_mk_id'=>'OE品牌', 'pn_src'=>'数据来源', 'pn_cn_remark'=>'中文描述', 'pn_en_remark'=>'英文描述', 'pn_ref'=>'参考来源', 'tags'=>'数据版本', 'ckresult2'=>'复审结论','sale_coun'=>'适用国家'];
		if(!empty($pn_id) && !empty($setArr))
		{
			$list = $this->getList(['all'=>1,'pn_is_sys'=>0,'pn_type'=>'none','pn_id'=>$pn_id]);
			$old = $list['rows'][0];
			if(empty($old)) exitJson($pn_id.'记录不存在');

			$row = $this->db->get('pro', ['p_cate', 'p_innum', 'p_comnum'], ['p_id'=>$old['pn_p_id']]);
			if(!\p::catesEdit('E200', $row['p_cate'])) exitJson('无此品名权限');

			$pro = new pro();
			$chk = $pro->canSetPro($old['pn_p_id']);
			if(!empty($chk['msg'])) exitJson($chk['msg']);

			$this->db->Begin();
			$chageceilArr = [];
			
			foreach($setArr as $filed=>$val)
			{
				if(empty($canSetFiled[$filed]) || $val == $old[$filed] || (isset($old['captions'][$filed]) && $val == $old['captions'][$filed])) 
				{
					unset($setArr[$filed]);
					continue;
				}
				
				/*if($filed == 'tags')
				{
					$newVal = [];
					$tags = new tags();
					if(!empty($val))
					{
						$newVal = $tags->getTags(explode(',', $val));
					}
					$tagsLinkArr = [['t_id'=>$val, 'value_id'=>$pn_id]];
					$tags->changeTagsLink('number', 'replace', $tagsLinkArr);
					$chageceilArr[$filed] = ['filed'=>$filed, 'name'=>$canSetFiled[$filed], 'old'=>$old['captions'][$filed], 'new'=>implode(',', array_column($newVal, LG_NAME))];
					unset($setArr[$filed]);
				}
				else if(in_array($filed, ['pn_src', 'ckresult2']))
				{
					$newShow = '';
					if(!empty($val))
					{
						$collocation = new collocation();
						$collArr = $collocation->getCollItems('number');
						$newShow = $collArr[$val];
					}
					$chageceilArr[$filed] = ['filed'=>$filed, 'name'=>$canSetFiled[$filed], 'old'=>$old['captions'][$filed], 'new'=>$newShow];
				}
				else if($filed == 'sale_coun')
				{
					$newShow = '';
					if(!empty($val))
					{
						$carmodel = new carmodel();
						$row = $carmodel->getSalecounInfo($val);
						$newShow = $row[LG_NAME];
					}
					$chageceilArr[$filed] = ['filed'=>$filed, 'name'=>$canSetFiled[$filed], 'old'=>$old['captions'][$filed], 'new'=>$newShow];
				}
				else if(in_array($filed, ['pn_src', 'ckresult2']))
				{
					$newShow = '';
					if(!empty($val))
					{
						$collocation = new collocation();
						$collArr = $collocation->getCollItems('number');
						$newShow = $collArr[$val];
					}
					$chageceilArr[$filed] = ['filed'=>$filed, 'name'=>$canSetFiled[$filed], 'old'=>$old['captions'][$filed], 'new'=>$newShow];
				}
				else
				{
					$chageceilArr[$filed] = ['filed'=>$filed, 'name'=>$canSetFiled[$filed], 'old'=>$old[$filed], 'new'=>$val];
				}*/
			}

			$opuser = getOpuser();
			$datetime = getNowTime();
			if(!empty($setArr))
			{
				if(isset($setArr['pn_number']))
					$setArr['pn_formart'] = formatNum($setArr['pn_number']);
				if(isset($setArr['ckresult2']))
				{
					$setArr['ckuser2'] = $opuser;
					$setArr['cktime2'] = $datetime;
				}
				if($chkExists)
				{
					$chkdata = array_merge($old, $setArr);
					$exists = $this->checkExist($chkdata, $pn_id);
					if(!empty($exists)) exitJson($exists['msg']);
				}
				$setArr['opuser'] = $opuser;
				$setArr['update_time'] = $datetime;
				$this->db->update('pro_numidx', $setArr, ['pn_id'=>$pn_id]);
			}

			//变更库
			/*if(!empty($chageceilArr))
			{
				$this->saveChangeLog('set', $old, $chageceilArr);
			}*/
			$this->db->End();
		}
		return [];
	}

	
	private function saveChangeLog($act, $old, $chageceilArr)
	{
		$opuser = getOpuser();
		$datetime = getNowTime();
		$addChange = [
			'pnc_act'=>$act,
			'pnc_change'=>$act == 'del'? '[]':[
				[
					'opuser'=>$opuser,	
					'create_time'=>$datetime,
					'change'=>$chageceilArr
				]
			],
			'pnc_opuser'=>$opuser,
			'pnc_create_time'=>$datetime,
		];
		//快速字段
		$fashfileds = ['pcat_name','cat_name','p_innum','p_comnum','pn_id','pn_p_id','pn_pf_id','pn_pf_id_opt','pn_number','pn_formart','pn_mk_id','pn_mk_id_opt','pn_src','pn_sample','pn_sign_type','pn_cn_remark','pn_en_remark','pn_ref','ckuser2','ckresult2','ckremark2','cktime2','opuser','create_time','update_time', 'tags', 'sale_coun', 'sale_coun_opt'];
		foreach($fashfileds as $filed)
		{
			$optfiled = substr($filed, -4) == '_opt' && strlen($filed) > 4? substr($filed, 0, -4): null;
			if($optfiled && isset($old['captions'][$optfiled]))
			{
				$addChange[$filed] = $old['captions'][$optfiled];
			}
			else if(isset($old['captions'][$filed]) && !in_array($filed.'_opt', $fashfileds))
			{
				$addChange[$filed] = $old['captions'][$filed];
			}
			else if(isset($old[$filed]))
			{
				$addChange[$filed] = $old[$filed];
			}
		}
		if($act == 'del')
		{
			if(empty($chageceilArr['delremark'])) exitJson('删除原因必填');
			$addChange['delremark'] = $chageceilArr['delremark'];
			$this->db->insert('pro_numidx_change', $addChange);
			$pnc_id = $this->db->id();
		}
		else
		{
			//追加旧的变更历史
			$lastChange = $this->db->get('pro_numidx_change', ['pnc_id', 'pnc_change'], ['pn_id' =>$old['pn_id'], 'pnc_act' =>'set', 'ORDER'=>['pnc_id'=>'DESC']]);
			if(!empty($lastChange))
			{
				$lastChange['pnc_change'] = json_decode($lastChange['pnc_change'], true);
				foreach($lastChange['pnc_change'] as $cv)
				{
					$addChange['pnc_change'][] = $cv;
				}
			}
			$addChange['pnc_change'] = json_encode($addChange['pnc_change']);
			if(!empty($lastChange))
			{
				$pnc_id = $lastChange['pnc_id'];
				$this->db->update('pro_numidx_change', $addChange, ['pnc_id'=>$lastChange['pnc_id']]);
			}
			else
			{
				$this->db->insert('pro_numidx_change', $addChange);
				$pnc_id = $this->db->id();
			}
		}
		return ['id'=>$pnc_id];
	}


	/**
	  * @method 删除产品的交叉号
	  * @param  $idArr array  [必填] pn_id
	  * @param  $delremark string  [必填] 变更原因
	  * @author soul
	  */
	public function delNumidx($idArr, $delremark)
	{
		$list = $this->getList(['all'=>1,'pn_type'=>'none', 'pn_id'=>$idArr]);
		$numArr = $list['rows'];
		if(empty($numArr)) exitJson('记录不存在');
		//if(empty($delremark)) exitJson('删除原因必填');

		$check = new check();
		$proCateRule = $check->checkProRuleCate(array_column($numArr, 'pn_p_id'), 'E200', 'delete');
		if(!empty($proCateRule['no'])) exitJson('无此品名权限');
		
		//检测OE是否被使用为主OE
		$rows = $this->db->select('pro_numidx', ['pn_p_id', 'pn_formart'], ['pn_type'=>'none', 'pn_pf_id'=>1, 'pn_id'=>$idArr]);
		foreach($rows as $v){
			$has = $this->db->get('pro_numidx', ["[><]pro" => ["pn_p_id"=>"p_id"]], ['p_innum', 'pn_number'], ['pn_mainoe'=>1, 'p_lnk_p_id'=>$v['pn_p_id'], 'pn_formart'=>$v['pn_formart']]);
			if($has['pn_number']) exitJson($has['pn_number'].'已被'.$has['p_innum'].'使用为主OE，禁止删除');
		}

		$oldArr = $this->db->select('pro_numidx','*' ,['pn_type'=>'none', 'pn_id'=>$idArr]);
		$this->db->Begin();
		/*$opuser = getOpuser();
		$datetime = getNowTime();
		foreach($numArr as $old)
		{
			$this->saveChangeLog('del', $old, ['delremark'=>$delremark]);
		}*/
		$this->db->delete('pro_numidx', ['pn_type'=>'none', 'pn_id'=>$idArr]);

		//日志记录
		$logdata = [];
		foreach ($oldArr as $item) {
			$changeArr[$item['pn_p_id']][] = $item; 
		}
		foreach ($changeArr as $pid => $changeItem) {
			$arr['num'] = $changeItem;
			$logdata[] = [
				'cl_type'=>'pro',
				'cl_act'=>'del',
				'cl_dataid'=>$pid,
				'cl_change'=>json_encode($arr, JSON_UNESCAPED_UNICODE),
				'cl_opuser'=>getOpuser(),
				'cl_create_time'=>getNowTime(),
			];
		}
		
		if($logdata) $this->db->insert('change_log',$logdata);
		$this->db->End();
		return [];
	}


	/**
	  * @method 变更交叉库 数据
	  * @author soul
	  */
	public function getListChange($params)
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? '': $params['sidx'];
		$sord = empty($params['sord'])? 'asc': $params['sord'];
		$orderby = $params['orderby'];
		$table = 'pro_numidx_change(num)';
		$join = ["[><]p_code(pc)" => ["num.pn_p_id" => "pc_p_id"]];

		$refiled = [
			'pn_number'=>'pn_formart',
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'pn_formart') $data = formatNum($data);
			if($field == 'pn_cn_remark') $op = 'bw';
        });
		if(!empty($params['keys'])) $where['pnc_id'] = explode(',', $params['keys']);
		if(isset($params['pnc_id'])) $where['pnc_id'] = $params['pnc_id'];
        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);

		if(empty($where['ORDER'])) $where['ORDER'] = ['pnc_create_time' => "DESC"];
	
		if($page>0 && $pagesize>0){
			$fields = '*';
			$pages = $this->paging($table,$join,$fields,$where,$page,$pagesize);
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
		$fields = ['pc_state_main', 'num.*'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if(!empty($arr))
		{
			$actArr = ['set'=>lg('变更'), 'del'=>lg('删除')];
			foreach($arr as &$v)
			{
				$v['captions'] = ['pnc_act'=>$actArr[$v['pnc_act']]];
				$v['pnc_change'] = json_decode($v['pnc_change'], true);
				$drows = [];
				foreach($v['pnc_change'] as $drow)
				{
					$tc = [];
					foreach($drow['change'] as $f=>$da)
					{
						if(!empty($da['name'])){
							$tc[] = $da['name'].':"'.$da['old'].'"=>"<span class="green">'.$da['new'].'</span>"';
						}
					}
					$drows[] = substr($drow['create_time'], 0, 10).' '.$drow['opuser'].' '.lg('变更').' '.implode(',', $tc);
				}
				$v['pnc_change'] = implode("\r\n", $drows);
			}
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}


	/**
	  * @method 删除产品的变更交叉号
	  * @param  $idArr array  [必填] pnc_id
	  * @author soul
	  */
	public function delNumidxChange($idArr)
	{
		$rows = $this->db->select('pro_numidx_change', 'pn_p_id', ['pnc_id'=>$idArr]);
		$check = new check();
		$proCateRule = $check->checkProRuleCate($rows, 'E400', 'delete');
		if(!empty($proCateRule['no'])) exitJson('无此品名权限');

		$this->db->delete('pro_numidx_change', ['pnc_id'=>$idArr]);
		return [];
	}

	


	/**
	  * @method 重置交叉索引正式库的！提醒
	  * @author soul
	  */
	public function resetNumidxWarn()
	{
		ini_set('memory_limit', \mvc::$cfg['upload']['memory_limit']);
		set_time_limit(0);
		ignore_user_abort(true);
		$sqlArr = [
			[//需要设置的ID
				'warn'=>1,
				'sql'=>"select ids from (
						SELECT GROUP_CONCAT(pn_id) as ids, COUNT(DISTINCT pn_cn_remark) as remark_count, pn_cn_remark, COUNT(DISTINCT warn) as warn_count, warn 
						FROM `pro_numidx` WHERE pn_is_sys = 0 and pn_type='none' GROUP BY pn_pf_id, pn_formart HAVING COUNT(*) > 1
					) a where (remark_count > 1 or (remark_count = 1 and pn_cn_remark = '')) OR (warn_count > 1 or (warn_count = 1 and warn = 0))"
			],
			[
				'warn'=>0,
				'sql'=>"select ids from (
				SELECT GROUP_CONCAT(pn_id) AS ids, COUNT(DISTINCT pn_cn_remark) AS remark_count, pn_cn_remark, COUNT(DISTINCT warn) AS warn_count, warn, pn_formart, COUNT(*) co 
				FROM `pro_numidx` WHERE pn_is_sys = 0 and pn_type='none' GROUP BY pn_pf_id, pn_formart
				) a where ((remark_count = 1 AND pn_cn_remark != '') or co = 1) AND warn = 1"
			]
		];
		$this->db->Begin();
		foreach($sqlArr as $tw)
		{
			$rows = $this->db->query($tw['sql'])->fetchAll(\PDO::FETCH_ASSOC);
			$idArr = [];
			foreach($rows as $v)
			{
				$idArr = array_merge($idArr, explode(',', $v['ids']));
			}
			$idArr = array_unique($idArr);
			$warnCount = count($idArr);
			if($warnCount > 0)
			{
				$setIds = [];
				foreach($idArr as $k=>$v)
				{
					$setIds[] = $v;
					if(count($setIds) == 500 || ($k+1) == $warnCount)
					{//500一次
						$this->db->update('pro_numidx', ['warn'=>$tw['warn']], ['pn_id'=>$setIds]);
						$setIds = [];
					}
				}
			}
		}
		$this->db->End();
		//消息记录与在线提醒
		$msg = [
			'amsg_title'=> '正式交叉号库重置 ! 提醒完成',
			'amsg_body'=> '正式交叉号库重置 ! 提醒完成',
			'amsg_url'=> '',
			'amsg_urltitle'=>'',
		];
		makeOne(\model\message::class)->send([getOpuser()],$msg);
		socketSendMsg([getOpuser()],$msg);
		return [];
	}


    /**
     * 根据pid和号码品牌ID 获取当前PID下gsp品牌的列表
     * @param array $factory 号码品牌
     * @param int $pId 产品ID
	 *yang
     */
    public function gspFactory($factory = [],$pId)
    {
        if($pId <= 0){
            return false;
        }
        if(empty($factory)){
            $factory = $this->db->select('pro_numidx','pf_id',['pf_is_sys' => 1]);
        }
        return $this->db->select('pro_numidx','*',['pn_type'=>'none','pn_pf_id' => $factory,'pn_p_id' => $pId]);
    }

    /**
     * 根据pid得到GSP集团品牌的号码
     * @return array
     */
    public function getGspNumbersByPID($pid)
    {
        if(empty($pid)){
			return [];
		}
		$join['[>]pro_factory(f)'] = ['n.pn_pf_id'=>'pf_id'];
		$join['[>]m_area(a)'] = ['n.pn_ma_id'=>'ma_id'];
		$where['pn_is_sys'] = 1;
		$where['pn_p_id'] = $pid;
		$where['pn_type'] = 'none';
		$where['RAW'] = raw(' 1=1 ORDER BY FIELD(pn_pf_id,3,2,4,5), pn_ma_id');
		//$where['ORDER'] = ['pn_pf_id'=>'ASC','pn_ma_id'=>'ASC'];
		$fields = ['n.*','f.pf_id','f.pf_name','f.cn_name','f.en_name','f.pf_hasbar','a.'.LG_NAME.'(areaname)'];
		$rows = $this->db->select('pro_numidx(n)',$join,$fields,$where);
		foreach($rows as &$row){
		    $row['factory'] = $row[LG_NAME];
		}
		return $rows;
    }

    /**
     * GSP 号码添加或者修改
     * @param $data
     * @return false|\PDOStatement
	 *yang
     */
    public function gspAdd($data)
    {
        $pnId = $this->db->get('pro_numidx','pn_id',['pn_p_id' => $data['pn_p_id'],'pn_pf_id' => $data['pn_pf_id']]);
        $data['pn_formart'] = formatNum($data['pn_number']);
        $data['opuser'] = $this->getOpuser();
        $data['pn_ma_id'] = $data['pn_ma_id'];
        $data['update_time'] = $this->getDateTime();
        $data['pn_is_sys'] = 1;
        if($pnId > 0){
            //更新
            $result = $this->db->update('pro_numidx',$data,['pn_id' => $pnId]);
        }else{
            $data['create_time'] = $this->getDateTime();
            $result = $this->db->insert('pro_numidx',$data);
            //添加
        }
		if($data['pn_pf_id']=='2' && $data['pn_formart']!=''){
			(new model\pro\pro())->setValue($data['pn_p_id'],'p_comnum',trim($data['pn_number']));
		}else if($data['pn_pf_id']=='3' && $data['pn_formart']!=''){
			(new model\pro\pro())->setValue($data['pn_p_id'],'p_innum',trim($data['pn_number']));
		}
        return $result;
    }

    /**
     * 设置产品号码的条码
     * @param $param
     * @return false|\PDOStatement
     */
    public function setBarcode($param)
    {
        $update = ['pn_barcode' => $param['pn_barcode'],'pn_ma_id' => $param['pn_ma_id'],'update_time' => $this->getDateTime()];
        $where = ['pn_pf_id' => $param['pn_pf_id'],'pn_p_id' => $param['pn_p_id']];
        return $this->db->update('pro_numidx',$update,$where);
    }
    
    function setTempValue($key,$field,$value,$remark=''){ 
        $this->db->update('pro_numidx_temp',[$field=>$value],['pnt_id'=>$key]);
    }

	/**
	 * @method 添加 交叉库
	* @param  $dataArr  array  [必填] ['pn_number'=>'', 'pn_mk_id'=>'',....]
	* @author soul
	*/
	public function addNumidx($dataArr)
	{
		$fileds = ['pn_p_id','pn_innum', 'pn_pf_id', 'pn_number', 'pn_mk_id'];
		$baseArr = [];
		$othArr = [];
		foreach($dataArr as $filed=>$v)
		{
			if(in_array($filed, $fileds))
			{
				$baseArr[$filed] = $v;
			}
			else
			{
				$othArr[$filed] = $v;
			}
		}

		//确认产品ID
		if(empty($baseArr['pn_p_id']))
		{
			$pro = new pro();
			$pid = $pro->getLinkPidByInnum($baseArr['pn_innum']);
			if(empty($pid)) exitJson('', '物料编码不存在');
			$baseArr['pn_p_id'] = $pid;
		}
		unset($baseArr['pn_innum']);
		
		$baseArr['pn_formart'] = formatNum($baseArr['pn_number']);
		if(empty($baseArr['pn_pf_id'])) exitJson('号码品牌必填');
		if(empty($baseArr['pn_formart'])) exitJson('号码必填');
		
		$exists = $this->checkExist($baseArr);
		if(!empty($exists)) exitJson($exists['msg']);

		$opuser = getOpuser();
		$datetime = getNowTime();
		$baseArr['opuser'] = $opuser;
		$baseArr['create_time'] = $datetime;
		$baseArr['update_time'] = $datetime;
		
		//初审人
		if(!empty($baseArr['ckresult1']) || !empty($baseArr['ckremark1']))
		{
			$baseArr['ck1'] = 1;
			$baseArr['ckuser1'] = $opuser;
			$baseArr['cktime1'] = $datetime;
		}
		$this->db->Begin();
		$this->db->insert('pro_numidx', $baseArr);
		$pn_id = $this->db->id();

	
		$this->db->End();
		return ['pn_id'=>$pn_id];
	}
  
}