<?php
namespace model;
use \model;
use \model\check;
use \model\collocation;
use \model\carmodel;
use \model\country;
use model\pro\cate;
use model\pro\factory;
use model\pro\pro;
use model\pro\synProPic;

class oe extends model
{
	public $table = 'oe_item';
    public $key = 'oe_id';

	public $cate;
    public $factory;

	public function __construct ()
    {
		parent::__construct();
		$this->cate = new cate();
        $this->factory = new factory();
	}

	public function getDetail($oe_id)
	{
		$data = $this->getListSup(['oe_id'=>$oe_id]);
		if(empty($data['rows'])) exitJson('记录不存在');
		
		$arr =$data['rows'][0];
		$arr['imgs'] = [];
		$join = ["[><]files"=>["pic_fileid"=>'fileid'],"[>]supplier"=>["pic_sup_id"=>"sup_id"]];
		$picrows = $this->db->select('oe_pic',$join,'*',['pic_oe_id'=>$oe_id,'ORDER'=>['pic_ismain'=>'DESC', 'pic_sort'=>'ASC']]);
		foreach ($picrows as  $pic) {
			if($pic['pic_type']=='img' && $pic['filetype']=='image'){
				$pic['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
				$pic['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
			}
			$arr['imgs'][$pic['pic_type']][] = $pic;
		}
		list($arr['pairList'],$arr['fatherList'],$arr['sonList']) = $this->getOePairList($oe_id);
		// dd($arr['imgs']);
		$arr['oe_para'] = empty($arr['oe_para'])? []:json_decode($arr['oe_para'], true);
		$arr['oe_chkpro_info'] = empty($arr['oe_chkpro_info'])? []:json_decode($arr['oe_chkpro_info'], true);
		$arr['oe_etk_info'] = empty($arr['oe_etk_info'])? []:json_decode($arr['oe_etk_info'], true);
		$arr['oe_etk_partitem'] = [];
		if($arr['oe_etk_epa_id']){
			$epainfo = $this->db->get('etk_partitem','*', ['epa_id'=>$arr['oe_etk_epa_id']]);
			$arr['oe_etk_partitem'] = empty($epainfo['epa_partitem'])? []:json_decode($epainfo['epa_partitem'], true);
		}

		$tb_name = $this->db->get('oe_tag_brand',['[><]tag_brand'=>['otb_tb_id'=>'tb_id']],['tb_ids'=>raw('GROUP_CONCAT(tb_id)'),'tb_names'=>raw('GROUP_CONCAT(tb_cn_name ORDER BY CONVERT(tb_cn_name USING gbk))')],['otb_oe_id'=>$oe_id]);
		$arr['captions']['oe_tb_id'] = $tb_name['tb_names'];
		$arr['tb_ids'] = $tb_name['tb_ids'];
		//数据标签
		$tags = new tags();
		$verArr = $tags->getTypeValTags('poe', [$oe_id]);
		$verArr = array_column($verArr, 'tags', 'tl_value_id');
		$arr['tags'] = $verArr[$oe_id]?implode(',', array_column($verArr[$oe_id], LG_NAME)):'';
		//获取sale_coun
		$country = new \model\country();
		$tItem = $country->getDataCountryId([$arr], 'poe');
		$tItem = $country->formatDataCountry($tItem, 1);
		$arr = $tItem[0];

		$arr['editTagBrand'] = false;
		
		$sql = sprintf('SELECT oml_id FROM oe_model_cn_link WHERE oml_oe_id = %d 
		UNION SELECT oml_id FROM oe_model_link WHERE oml_oe_id = %d',$arr['oe_id'],$arr['oe_id']);
		$hasModel = $this->db->query($sql)->fetch();

		if(!$hasModel){
			$arr['editTagBrand'] = true;
		}
		//关联商品
		$arr['relProducts'] = $this->db->select('pro',['[><]pro_brand'=>['p_pb_id'=>'pb_id']],['p_id','pb_'.LG_NAME.'(pb_name)','p_innum'],['p_oe_id'=>$arr['oe_id'],'ORDER'=>'p_pb_id']);

		// $arr['tb_id'] = $res['tb_ids']?:'';
		return $arr;
	}

	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'];
		$this->joinWhere = [];
		$refiled = [
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName(),
			'mk_name'=>'mk.mk_'.LG_NAME,
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'oe_item(oi)';
		$join = [
			"[><]pro_cate(cat)" => ["oi.oe_cate_id" => "id"],
			"[><]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[><]oe_numidx(oen)" => ["oi.oe_id" => "on_oe_id"],
			"[><]pro_factory(pf)" => ["oi.oe_pf_id" => "pf_id"],
		];
		
		$this->set('pnumwhere', []);
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			switch ($field) {
				case 'devNoList':
					$op = 'RAW_'.$field;
					$data = raw(sprintf("oe_id IN (select distinct oid_oe_id 
					from oe_item_developno left join supplier on oid_sup_id=sup_id where sup_name like '%%%s%%' or oid_format like '%%%s%%')",$data,formatNum($data)));
					break;
			}
        });
		
		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'p_cate': $where['oe_cate_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['on_formart'.($rules['numlike']? '[~]': '')] = $tnums;
				break;	
			}
		}

		if(!empty($params['keys'])) $where['oe_id'] = explode(',', $params['keys']);
		if(!empty($params['oe_id'])) $where['oe_id'] = $params['oe_id'];
		//if(!\p::isAdmin()) $where['oe_opuser'] = getOpuser();

		//查非
		if(!empty($rules['findNulls'])){
			$this->findNullsSearch($rules['findNulls'], $join, $this->joinWhere);
		}
		$where['GROUP'] ='oe_id';
		
		if(!empty($this->joinWhere)){
			$where = array_merge($where, $this->joinWhere);
		}
        $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)', 'cat.cat_pos1','cat.cat_pos2','cat.cat_pos3','cat.cat_pos4','cat.cat_pos5', 'pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'cat.is_engine', 'pf_name','oi.*'];
        $arr = $this->db->select($table,$join,$fields,$where);
		$collocation = new collocation();
		$collArr = $collocation->getCollItems('work');

		//查devlopno
		$devNoList = [];
		$oeIdArr = array_column($arr,'oe_id');
		if($oeIdArr)
		{
			$devNoRes = $this->db->select('oe_item_developno',["[>]supplier"=>["oid_sup_id"=>"sup_id"]],['oe_item_developno.*','sup_name'],['oid_oe_id'=>$oeIdArr]);
			foreach ($devNoRes as $key => $val) {
				$devNoList[$val['oid_oe_id']][] = $val;
			}
		}
			
		foreach($arr as &$v){
		
			$v['devNoList'] = $devNoList[$v['oe_id']]?$devNoList[$v['oe_id']]:[];
			$v['cate_posArr'] = [
				'cat_pos1'=>$v['cat_pos1']?explode(',',$v['cat_pos1']):[],
				'cat_pos2'=>$v['cat_pos2']?explode(',',$v['cat_pos2']):[],
				'cat_pos3'=>$v['cat_pos3']?explode(',',$v['cat_pos3']):[],
				'cat_pos4'=>$v['cat_pos4']?explode(',',$v['cat_pos4']):[],
				'cat_pos5'=>$v['cat_pos5']?explode(',',$v['cat_pos5']):[],
			];

			$v['captions'] = [
				'oe_oe'=>$v['pf_name'].': '.$v['oe_oe'],
				'oe_unit'=>!empty($collArr[$v['oe_unit']])? $collArr[$v['oe_unit']]: '',
				'oe_fuel'=>!empty($collArr[$v['oe_fuel']])? $collArr[$v['oe_fuel']]: '',
				'oe_progroup'=>!empty($collArr[$v['oe_progroup']])? $collArr[$v['oe_progroup']]: '',
				'oe_clean'=>$this->cleanStatus[$v['oe_clean']],
				'oe_develop_status'=>!empty($collArr[$v['oe_develop_status']])? $collArr[$v['oe_develop_status']]: '',
			];
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}


	public function delData($idArr)
	{
		if(!empty($idArr)){

			$exits = $this->db->select('pro','p_id',['p_oe_id'=>$idArr]);
			if($exits) exitJson('零件已被商品引用，不能删除');
			$this->db->Begin();

			$this->db->delete('oe_item', ['oe_id'=>$idArr]);
			//删除关联车型
			$this->db->delete('oe_model_link',['oml_oe_id'=>$idArr]);
			//删除关联参考号
			$this->db->delete('oe_numidx',['on_oe_id'=>$idArr]);
			$this->db->delete('oe_numidx_tag_brand',['ontb_oe_id'=>$idArr]);
			//删除关联的中国车型
			$this->db->delete('oe_model_cn_link',['oml_oe_id'=>$idArr]);
			$this->db->delete('oe_param_val',['ppv_oe_id'=>$idArr]);
			$this->db->delete('oe_pic',['pic_oe_id'=>$idArr]);
			$this->db->delete('oe_tag_brand',['otb_oe_id'=>$idArr]);
			$this->db->delete('oe_item_developno',['oid_oe_id'=>$idArr]);
			$this->db->delete('oe_link',['OR'=>['ol_oe_id1'=>$idArr, 'ol_oe_id2'=>$idArr]]);
			$this->db->delete('project_recommend',['prr_oe_id'=>$idArr]);
			$this->db->update('project_item', ['pi_p_id'=>0, 'pi_oe_id'=>0],['pi_oe_id'=>$idArr]);
			$this->db->End();
		}
		return [];
	}
	
	public function setCell($kid, $setArr)
	{
		if(!empty($kid) && !empty($setArr))
		{
			$ignoreFileds = ['oe_list_id', 'oe_oe','oe_create_time'];
			$old = $this->db->get('oe_item', '*', ['oe_id'=>$kid]);
			if(empty($old)) exitJson('记录不存在');

			$this->db->Begin();
			foreach($setArr as $filed=>$val){
				if(in_array($filed, $ignoreFileds) || stripos($filed, 'oe_') !== 0){
					unset($setArr[$filed]);
					continue;
				}
				if(stripos($filed, 'oe_pos')!==false && is_array($setArr[$filed]))
				{
					$setArr[$filed] = implode('/',$setArr[$filed]);
				} 
			}
			if(!empty($setArr)){
				$opuser = getOpuser();
				$datetime = getNowTime();
				$setArr['oe_opuser'] = $opuser;
				$setArr['oe_update_time'] = $datetime;
				$this->db->update('oe_item', $setArr, ['oe_id'=>$kid]);
			}
			//更新下供应商价格
			if(isset($setArr['oe_cate_id'])){
				$this->db->update('supplier_pro',['spr_cat_id'=>$setArr['oe_cate_id']],['spr_oe_id'=>$kid]);
			}
			
			$this->db->End();
		}
		return [];
	}

	public function saveDetail($kid, $dataArr)
	{
		$this->db->Begin();
		$setArr = [];
		if(!empty($dataArr)) $setArr = $dataArr;
		if(!empty($dataArr['para'])){
			$paramArr = json_decode($dataArr['para'],true);
	
			$this->setParam($paramArr,$kid);
		}
		
		$devArr = $setArr['devNo']?json_decode($setArr['devNo'],true):[];
		$this->saveDevelopNo($kid,$devArr);
		
		if($setArr['oePair']){
			$oePairArr = json_decode($setArr['oePair'],true);
			$this->saveOeLinkData($kid,$oePairArr);
		}
		if($setArr['oeFather']){
			$oeFatherArr = json_decode($setArr['oeFather'],true);
			$this->saveOeLinkData($kid,$oeFatherArr,'father');
		}
		if($setArr['oeSon']){
			$oeSonArr = json_decode($setArr['oeSon'],true);
			$this->saveOeLinkData($kid,$oeSonArr,'son');
		}
		if(!empty($setArr)){
			$this->setCell($kid, $setArr);
		}

		//汽车品牌
		if(isset($dataArr['tb_ids'])){
			$tb_ids = array_unique(explode(',',$dataArr['tb_ids']));
			$curtbArr = $this->db->select('oe_tag_brand','otb_tb_id',['otb_oe_id'=>$kid]);
			if(!empty($tb_ids)){
				//删除不存在的品牌
				$delArr = array_diff($curtbArr, $tb_ids);
				if($delArr)
				{
					$this->db->delete('oe_tag_brand',['otb_oe_id'=>$kid,'otb_tb_id'=>$delArr]);
				}
				foreach($tb_ids as $tb_id){
					if(!empty($tb_id) && !in_array($tb_id, $curtbArr)){
						$this->db->insert('oe_tag_brand',['otb_oe_id'=>$kid,'otb_tb_id'=>$tb_id]);
					}
				}
			}
		}

		//联动商品库
		$pro = new pro();
		$pro->synProByOe($kid, ['base', 'params'],$setArr['syncFgio']?true:false,['syncChassis'=>$setArr['syncChassis']?true:false]);
		$this->db->End();
		return [];
	}

	
    public function getPidByNumber($number)
    {
		if(stripos($number,":")!==false){
			$arr = explode(":",$number);
			$number = $arr[1];
		}
		$where = ['oe_oe_format'=>formatNum($number)];
		$pid = 0;
		$pid = $this->db->get('oe_item','oe_id', $where);
		return $pid;
    }

	/**修正要显示的数据
     * @param int|array $row
     * @return array
     */
    public function formatRow($row,$rules=null){
        if(!is_array($row)){
            $row = $this->getRowByKey($row);
        }
		
        //产品线与小类
        if(!empty($row['oe_cate_id'])){
			if(empty($this->formatRowCache['cate'][$row['oe_cate_id']])){
				 $cateRow = $this->cate->getRowByKey($row['oe_cate_id']);
				 $this->formatRowCache['cate'][$row['oe_cate_id']] = $cateRow;
			}else{
				 $cateRow = $this->formatRowCache['cate'][$row['oe_cate_id']];
			}

			if(empty($this->formatRowCache['cate'][$cateRow['parent_id']])){
				 $bigCateRow = $this->cate->getRowByKey($cateRow['parent_id']);
				 $this->formatRowCache['cate'][$cateRow['parent_id']] = $bigCateRow;
			}else{
				 $bigCateRow = $this->formatRowCache['cate'][$cateRow['parent_id']];
			}
            $row['captions']['p_bigcate'] = $bigCateRow[cateName()];
            $row['captions']['p_cate'] = $cateRow[cateName()];
            $row['captions']['p_cateas'] = $cateRow['as'];
            $row['langs']['p_cate']['en'] = $cateRow['en_name'];
            $row['langs']['p_cate']['cn'] = $cateRow['cn_name'];
            $row['langs']['p_bigcate']['en'] = $bigCateRow['en_name'];
            $row['langs']['p_bigcate']['cn'] = $bigCateRow['cn_name'];
        }

		if(!empty($row['pf_alias'])){
			$row['pf_name'] = $row['pf_alias'];
		}
		//燃油方式
		if(isset($row['mm_fuel']) && $row['mm_fuel']!=''){
			$row['mm_fuel'] = (new \model\collocation())->getRowByKey($row['mm_fuel'])[cateName()];
		}
		//Aspiration增压方式
		if(isset($row['mm_turbo']) && $row['mm_turbo']!=''){
			$row['mm_turbo'] = (new \model\collocation())->getRowByKey($row['mm_turbo'])[cateName()];
		}
		//Cyl发动机汽缸排列方式
		if(isset($row['mm_cylinders']) && $row['mm_cylinders']!=''){
			$row['mm_cylinders'] = (new \model\collocation())->getRowByKey($row['mm_cylinders'])[cateName()];
		}
		//Drive驱动方式
		if(isset($row['mm_drive_type']) && $row['mm_drive_type']!=''){
			$row['mm_drive_type'] = (new \model\collocation())->getRowByKey($row['mm_drive_type'])[cateName()];
		}
		$row['cktime3'] = shortDate($row['cktime3']);
		$row['create_time'] = shortDate($row['create_time']);
		$row['update_time'] = shortDate($row['update_time']);
		//参数翻译
		// foreach($row as $field => $value){
	    //     $row[$field] = $this->getParamLangText(substr($field,6),$value);
		// }
        return $row;
    }


	/**
	  * @method 号码自动完成
	  * @param  $params [
					num|query string  [必填] 号码
				]
	  * @author soul
	  */
	  public function autoComNum($params)
	  {
		  $params['num'] = empty($params['num'])? $params['query']: $params['num'];
		  $where = ['oe_oe_format[=~]'=>formatNum($params['num'])];
		  
		  $where['LIMIT'] = empty($params['limit'])? 20: (int) $params['limit'];
		  $where['ORDER'] = 'oe_oe';

		  $rows = $this->db->select('oe_item(oi)',['oe_oe'], $where);
		  $data = [];
		  foreach($rows as $k=>$v){
			  $data[$k]=['key'=>$v['oe_oe'], 'value'=>$v['oe_oe']];
		  }
		  return $data;
	  }

	
	public function getAllOeNum($params)
	{
		$params['num'] = empty($params['num'])? $params['query']: $params['num'];
		$params['num'] = strtr($params['num'],[':'=>':','：'=>':']);
		if(stripos($params['num'],":")!==false){
			$arr = explode(":",$params['num']);
			$where['pf_name'] = $arr[0];
			$where['on_formart[~]'] = formatNum($arr[1]).'%';
		}else{
			$num = formatNum($params['num']);
			$where['on_formart[~]'] = $num.'%';
		}
	
		$where['LIMIT'] = empty($params['limit'])? 20: (int) $params['limit'];
		$where['ORDER'] = 'on_formart';
		if($params['noid']){
			$where['oe_id[!]'] = $params['noid'];
		}
		if($params['type']=='oe'){
			$where['on_pf_id'] = 1;
		}
		$join = [
			'[><]oe_numidx(on)'=>['oi.oe_id'=>'on_oe_id'],
			'[><]pro_factory'=>['on.on_pf_id'=>'pf_id'],
			'[><]pro_cate'=>['oi.oe_cate_id'=>'id'],
		];
		$rows = $this->db->select('oe_item(oi)',$join,['oe_id','on_number','pf_id','pf_name',cateName().'(cat_name)'], $where);
		$data = [];
		foreach($rows as $k=>$v){
			if($params['type']=='oe'){
				$key = $v['oe_id'];
			}else{
				$key = $v['pf_id'].":".$v['pf_name'].":".$v['on_number'];
			}
			$data[$k]=['key'=>$key, 'value'=>$v['pf_name'].":".$v['on_number']." (".$v['cat_name'].")"];
		}
		return $data;
	}


	  /**
	  * @method 审核OE库
	  * @param  $idArr array [必填] [1,2,3,...]
	  * @param  $setArr array [必填] ['act'=>'nopass', 'ckremark1'=>'核对备注'] 
	  * @author soul
	  */
	public function check1($idArr, $setArr)
	{
		if(!empty($idArr))
		{
			$tempArr = $this->db->select('oe_item', '*', ['oe_id'=>$idArr]);
			if(empty($tempArr)) exitJson('记录不存在');
			$opuser = getOpuser();
			$datetime = getNowTime();
			$set = [
				'ckuser1'=>$opuser,
				'cktime1'=>$datetime,
				'ckremark1'=>$setArr['ckremark1'],
				'oe_update_time'=>$datetime,
				'oe_opuser'=>$opuser
			];
			if($setArr['act'] && $setArr['act'] == 'nopass'){
				$set['ck1'] = -1;
			}
			$this->db->update('oe_item', $set, ['oe_id'=>$idArr]);
		}
		return [];
	}


	/**
	  * @method 根据号码查询查询对应的OEID 
	  * @param  $params array [必填] ['oenum'=>'']
	*/
	public function chkOeIdByAny($params)
	{
		$oeidArr = [];
		if(empty($oeidArr) && !empty($params['oenum']))
		{
			$rows = $this->db->select('oe_numidx', ['on_oe_id'], ['on_pf_id'=>1, 'on_formart'=>formatNum($params['oenum'])]);
			if(!empty($rows)) $oeidArr = array_column($rows, 'on_oe_id');
		}
		
		return array_unique($oeidArr);
	}


	/**
     * 根据产品ID获取产品参数
     * @param int $oeId
     * @param array $param ptpa_in_showlist是否再列表显示
     * ptpa_in_showpage int是否再详情页显示
     * ptpa_is_website int 是否对外网显示
     * ptpa_is_edit int 是否允许编辑
     * ptpa_is_show int 是否全部显示
     *
     * @param int $isScan 是否需要返回全部附表
     * @return array
     */
    public function getOeParamByOeid(int $oeId, $param = [], $isScan = 1): array
    {
        $paramValue = $this->db->select('oe_item',['[>]oe_param_val' => ['oe_id' => 'ppv_oe_id']],['ppv_val_smalltxt','ppv_val_string','ppv_val_double','ppv_val_int','ppv_ptpa_id','oe_cate_id','ppv_oe_id','ppv_pc_id'],['oe_id' => $oeId]);
        if (isset($paramValue['0'])) {
            $ptIds = $paramValue['0']['oe_cate_id'];
        } else {
            return [];
        }
        if(empty($paramValue['0']['ppv_ptpa_id'])){
            $paramValue = [];
        }else{
            $paramValue = array_column($paramValue,null,'ppv_ptpa_id');
        }

        $where = [];
        if(!empty($param))
        {
            foreach ($param as $k => $v)
            {
                $where[$k] = (int) $v;
            }
        }
        $where['ptpa_cate_id'] = $ptIds;
        $where['ptpa_is_show'] = 1;
        $where['ORDER'] = ['ptpa_col_order'=>'ASC'];
        $field = [
            'ptpa_pid','ptpa_cate_id','ptpa_is_edit', 'ptpa_unit','ptpa_syn_field','ptpa_decimal','ptpa_type','ptpa_length','ptpa_id'
        ];
		$field = langFields($field,'');

        $paramName = $this->db->select('part_param',$field,$where);
		$ptpaId = [];
		foreach ($paramName as $item) {
			
			if($item['ptpa_pid']>0){
				$ptpaId[] = $item['ptpa_pid'];
			}else{
				$ptpaId[] = $item['ptpa_id'];
			}
		}
		$ptpaId = array_unique($ptpaId);
		if($ptpaId)
		{
			$canList = $this->db->select('part_param_sche','*',['pps_ptpa_id' => $ptpaId,'ORDER' => ['pps_order' => 'ASC']]);
			if(!empty($canList)){
				$canList = array_column($canList,null,'pps_id');
			}
		}

        if($isScan == 1 && !empty($canList)){
            $canLists = [];
            foreach ($canList as $va)
            {	
				$temp = [
                    'key' => $va['pps_id'],
                    'value' => $va[LG_NAME]
                ];
				$temp = langGetVals($temp,$va,[''=>'']);
                $canLists[$va['pps_ptpa_id']][] = $temp;
            }
        }
        foreach ($paramName as &$value)
        {	
			$searchKey = $value['ptpa_id'];
			if($value['ptpa_pid']>0){
				$value['ptpa_type'] = 'list';
				$searchKey = $value['ptpa_pid'];
			}
            $value['name'] = $value[LG_NAME];
            if(!empty($value['ptpa_syn_field'])){
                $value['is_edit'] = 0;
            }else{
                $value['is_edit'] = 1;
            }
            $value['parameter_value'] = '';
            $value['parameter_text'] = '';
            if($isScan == 1 && isset($canLists) && isset($canLists[$searchKey])){
                $value['has_many_scan'] = $canLists[$searchKey];
            }
			if($value['ptpa_pid']>0){
				$value['ptpa_type'] = 'list';
			}
            if(!empty($paramValue)){
                if(isset($paramValue[$value['ptpa_id']])){
                    switch ($value['ptpa_type']) {
                        case 'int':
                            $value['parameter_value'] = $paramValue[$value['ptpa_id']]['ppv_val_int'];
                            $value['parameter_text'] = $paramValue[$value['ptpa_id']]['ppv_val_int'];
                            break;
                        case 'double':
                            $value['parameter_value'] = floatval(number_format($paramValue[$value['ptpa_id']]['ppv_val_double'], $value['ptpa_decimal'],".",""));
                            $value['parameter_text'] = floatval(number_format($paramValue[$value['ptpa_id']]['ppv_val_double'], $value['ptpa_decimal'],".",""));

                            break;
                        case 'bigtxt':
                        case 'smalltxt':
                            $value['parameter_value'] = $paramValue[$value['ptpa_id']]['ppv_val_smalltxt'];
                            $value['parameter_text'] = $paramValue[$value['ptpa_id']]['ppv_val_string'];
                            break;
                        case 'checkbox':
                            $value['parameter_value'] = explode(',', $paramValue[$value['ptpa_id']]['ppv_val_string']);
                            if(!empty($value['parameter_value'])){
                                unset($value['parameter_text']);
                                foreach ($value['parameter_value'] as $v)
                                {
                                    $value['parameter_text'][] = $canList[$v][LG_NAME];
                                }
                            }
                            break;
                        case 'list':
                        case 'radio':
                            $value['parameter_value'] = $paramValue[$value['ptpa_id']]['ppv_val_int'];
                            $value['parameter_text'] = $canList[$value['parameter_value']][LG_NAME]??$canList[$value['parameter_value']]['cn_name'];
                            break;
                        case 'string':
                            $value['parameter_value'] = $paramValue[$value['ptpa_id']]['ppv_val_string'];
                            $value['parameter_text'] = $paramValue[$value['ptpa_id']]['ppv_val_string'];
                            break;
                    }
                }
            }
            if($value['parameter_value']==null) $value['parameter_value'] = '';
        }
		unset($value);
       
        return $paramName ?: [];
    }

	public function setParam($data,$oeId)
    {     	

		$oeitem = $this->db->get('oe_item',['oe_cate_id','oe_para','oe_chkpro_info'],['oe_id'=>$oeId]);
		$para = json_decode($oeitem['oe_para'],true);
		$chkinfo = json_decode($oeitem['oe_chkpro_info'],true);
		//当前分类的所有参数
		$partinfo = $this->db->select('part_param','*',['ptpa_cate_id'=>$oeitem['oe_cate_id']]);
		$partinfo = array_column($partinfo,null,'ptpa_id');
		$allPartName = array_column($partinfo,'cn_name');

		//当前零件已设置的参数
		$list = $this->db->select('oe_param_val','ppv_ptpa_id',['ppv_oe_id' => $oeId]);
        $this->db->begin();
       
		foreach ($data as $value)
		{	
			$curpart = $partinfo[$value['ppv_ptpa_id']];
			
			foreach ($para as $val) {
				if($value['ppv_val_'.$curpart['ptpa_type']] == $val['val'] && !in_array($val['cn_name'],$allPartName)){
					$tcdname =  explode(';',strtr(strtoupper($curpart['tcd_name'] ), ['；'=>';', '，'=>';']));
					$tcdnameArr = [];
					foreach ($tcdname as $tcdval) {
						$arr = explode(":",$tcdval);
						$tcdnameArr[$arr[0]] = explode(',',$arr[1]);
					}
					if(!isset($tcdnameArr[$val['cn_name']]) || $tcdnameArr[$val['cn_name']] && !in_array($chkinfo['pro_factory'],$tcdnameArr[$val['cn_name']]))
					{	
						$tcdnameArr[$val['cn_name']][] = $chkinfo['pro_factory'];
						$newtcdName = $val['cn_name'].':'.implode(',',$tcdnameArr[$val['cn_name']]);
						$tcdname[] = $newtcdName;
						$curpart['tcd_name'] =  implode(';',$tcdname);
						$this->db->update('part_param',$curpart,['ptpa_id'=>$value['ppv_ptpa_id']]);
					}
				}
			}
			//存在的
			if(in_array($value['ppv_ptpa_id'],$list)){
				$ptpaId = $value['ppv_ptpa_id'];
				unset($value['ppv_ptpa_id'],$value['ppv_oe_id']);
				if(!$value['ppv_val_int']&& !$value['ppv_val_double'] && !$value['ppv_val_string'] && !$value['ppv_val_smalltxt']){
					$this->db->delete('oe_param_val',['ppv_oe_id' => $oeId,'ppv_ptpa_id' => $ptpaId]);
				}else{
					$this->db->update('oe_param_val',$value,['ppv_oe_id' => $oeId,'ppv_ptpa_id' => $ptpaId]);
				}
			}else{
				if(!$value['ppv_val_int']&& !$value['ppv_val_double'] && !$value['ppv_val_string'] && !$value['ppv_val_smalltxt']){
					continue;
				}
				$this->db->insert('oe_param_val',$value);
			}
			if($value['ppv_val_string']){
                $sche = $this->db->get('part_param_sche','*',['cn_name'=>$value['ppv_val_string'],'pps_ptpa_id'=>$ptpaId]);
                if(!$sche){
                    $this->db->insert('part_param_sche',['cn_name'=>$value['ppv_val_string'],'pps_ptpa_id'=>$ptpaId]);
                }
            }
		}
        return $this->db->end();
    }


	//从宜配数据参数中格式化系统参数值
	function formatParaFromTcd($cat_id, $pvals, $oe_id = 0,$factory='')
	{
		$rows = $this->db->select('part_param', ['ptpa_id','tcd_name', 'ptpa_type', 'ptpa_decimal'], ['ptpa_cate_id'=>$cat_id, 'tcd_name[!]'=>'']);

		$labels = [];
		$tcdNameskeyVal = []; 
		foreach($rows as $rv){
			$rv['tcd_names'] = [];
			foreach(explode(';', strtr(strtoupper($rv['tcd_name']), ['；'=>';', '，'=>';'])) as $nv){
				$arr = explode(':', $nv);
				$name = trim($arr[0]);
				$rv['tcd_names'][] = $name;
				$tcdNameskeyVal[$name] = $arr[1]? array_filter(explode(',',$arr[1])):[];
			}
			$labels[$rv['ptpa_id']] = $rv;
		}
		$paras = [];
		
		//获取当前分类限定的位置
		$catinfo = $this->db->get('pro_cate','*',['id'=>$cat_id]);
		
		$pos = [];
		$posArr = $this->formatPosFromTcd($catinfo, $pvals);
		foreach($posArr as $posk=>$posvs){
			$pos['oe_'.$posk] = $posvs;
		}
		
		foreach($pvals as $pv){
			$existFirst = 0; //用于判断存在多个指定品牌的参数只匹配第一个
			foreach($labels as $lk=>$lv){
				if(($pv['name'] && in_array(strtoupper($pv['name']), $lv['tcd_names'])) || ($pv['cn_name'] && in_array(strtoupper($pv['cn_name']), $lv['tcd_names']))){
					
					if($lv['ptpa_type'] == 'double' && $lv['ptpa_decimal']){
						$pv['val'] = number_format($pv['val'], $lv['ptpa_decimal']);
					}
					//指定品牌
					if(!$existFirst && !empty($factory) && ($tcdNameskeyVal[$pv['cn_name']] && in_array($factory,$tcdNameskeyVal[$pv['cn_name']]) || $tcdNameskeyVal[$pv['name']] && in_array($factory,$tcdNameskeyVal[$pv['name']])))
					{
						$existFirst = $lk; 
						$paras[$lk] = [
							'ppv_oe_id'=>$oe_id,
							'ppv_pc_id'=>$cat_id,
							'ppv_ptpa_id'=>$lk,
							'ppv_val_'.$lv['ptpa_type']=>$pv['val']
						];
						
					}else{
						if(!$paras[$lk]){
							$paras[$lk] = [
								'ppv_oe_id'=>$oe_id,
								'ppv_pc_id'=>$cat_id,
								'ppv_ptpa_id'=>$lk,
								'ppv_val_'.$lv['ptpa_type']=>$pv['val']
							];
						}
					}
					break;
				}
			}
		}
		return ['paras'=>array_values($paras),'pos'=>$pos];
	}

	function formatPosFromTcd($catinfo, $pvals){
		//分类已定义的位置
		$hasPoskey = [];
		$pos = [];
		foreach(\mvc::$cfg['PosKeyVal'] as $poskey=>$posv){
			if(empty($catinfo['cat_'.$poskey])) continue;
			$hasPoskey[$poskey] = [];
			foreach(explode(',', $catinfo['cat_'.$poskey]) as $tv){
				if(\mvc::$cfg['PosKeyVal'][$poskey][$tv]) $hasPoskey[$poskey][$tv] = \mvc::$cfg['PosKeyVal'][$poskey][$tv];
			}
		}
		if($hasPoskey){
			foreach($pvals as $pv){
				$fullname = $pv['cn_name'].':'.$pv['cn_name'];
				if(stripos($fullname, '位置') === false && stripos($fullname, 'Position') === false) continue;
				$posval = trim($pv['val']);
				$poskeys = [];
				if(stripos($posval, '轴') !== false || stripos($posval, 'Axle') !== false || stripos($posval, '桥') !== false){
					if($hasPoskey['pos1']) $poskeys[] = 'pos1';
				}else{
					if($hasPoskey['pos2']) $poskeys[] = 'pos2';
				}
				if($hasPoskey['pos3']) $poskeys[] = 'pos3';
				if($hasPoskey['pos4']) $poskeys[] = 'pos4';
				if($hasPoskey['pos5']) $poskeys[] = 'pos5';
				foreach($poskeys as $poskey){
					//遍历零件已定义的
					foreach($hasPoskey[$poskey] as $pvk=>$pvvs){
						foreach($pvvs as $pvvv){
							if(stripos($posval, $pvvv) !== false) $pos[$poskey][] = $pvk;
						}
					}
				}
			}
		}
		return $pos;
	}


	/**
	 * @param  [type] $oe_id
	 * @param  [type] $data
	 * @method 更新零件库参数、位置信息
	 * @author zhengweihua 
	 * @copyright 2025-01-10
	 */
	function setOeParaAndPos($oe_id,$data,$syncFgio=false)
	{
		if(!$data['paras'] && !$data['pos']) return [];

		$this->db->Begin();
		if($data['paras']) $this->setParam($data['paras'],$oe_id);
		if($data['pos']){
			$updateArr = [];
			foreach ($data['pos'] as $key => $val) 
			{
				$updateArr[$key] = implode('/',$val);
			}
			$this->db->update('oe_item',$updateArr,['oe_id'=>$oe_id]);
		}
		$pro = new pro();
		$pro->synProByOe($oe_id, ['base', 'params'],$syncFgio);
		$this->db->End();
		return [];
		
	}

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

		$refiled = [
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName(),
			'oe_oe'=>'oe_oe_format',
			'on_pf_name'=>'fac.pf_name'
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);
		$this->joinWhere = [];
		$table = 'oe_item(oi)';
		$join = [
			"[><]pro_factory(pf)" => ["oi.oe_pf_id" => "pf_id"],
			"[><]pro_cate(cat)" => ["oi.oe_cate_id" => "id"],
			"[><]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[><]oe_numidx(oen)" => ["oi.oe_id" => "on_oe_id"],
		];
		
		$fields = ['cat.id(cat_id)', 'cat.is_engine', 'cat.cat_pos1','cat.cat_pos2','cat.cat_pos3','cat.cat_pos4','cat.cat_pos5','pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'pf.pf_name', 'oi.*'];
		$this->set('pnumwhere', []);
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));
			if($field == 'chk_pcs'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" oe_id not in (
					SELECT distinct oe_id FROM oe_numidx
					JOIN oe_item ON oe_id = on_oe_id
					JOIN pro_numidx ON on_pf_id=pn_pf_id AND on_formart=pn_formart
					JOIN pro ON p_id=pn_p_id and p_pb_id = 1 where oe_cate_id = p_cate
					)");
				}else{
					$data = raw(" oe_id in (
					SELECT distinct oe_id FROM oe_numidx
					JOIN oe_item ON oe_id = on_oe_id
					JOIN pro_numidx ON on_pf_id=pn_pf_id AND on_formart=pn_formart
					JOIN pro ON p_id=pn_p_id and p_pb_id = 1 where oe_cate_id = p_cate
					)");
				}
			}else if($field == 'chk_sups'){
				$op = 'RAW_'.$field;
				if($data == '-1'){
					$data = raw(" oe_id not in (
					SELECT DISTINCT oe_id FROM oe_numidx
					JOIN oe_item ON oe_id = on_oe_id
					JOIN supplier_pro ON on_pf_id=spr_pf_id AND on_formart=spr_format AND oe_cate_id= spr_cat_id
					)");
				}else{
					$data = raw(" oe_id in (
					SELECT DISTINCT oe_id FROM oe_numidx
					JOIN oe_item ON oe_id = on_oe_id
					JOIN supplier_pro ON on_pf_id=spr_pf_id AND on_formart=spr_format AND oe_cate_id= spr_cat_id)");
				}
			}else if($field == 'tb_names'){
				$op = 'RAW_'.$field;
				$data = raw(sprintf(" oe_id in (select distinct otb_oe_id from oe_tag_brand join tag_brand on otb_tb_id=tb_id where tb_id=%d)",$data));
			}else if($field == 'pic'){
				$op = 'RAW_'.$field;
				if($data==1){
					$data = raw(" oe_id in (select distinct pic_oe_id from oe_pic join files on pic_fileid=fileid where pic_type='img')");
				}else{
					$data = raw(" oe_id not in (select distinct pic_oe_id from oe_pic join files on pic_fileid=fileid where pic_type='img')");
				}
			}else if($field == 'devNoList'){
				$op = 'RAW_'.$field;
				$data = raw(sprintf("oe_id IN (select distinct oid_oe_id 
				from oe_item_developno left join supplier on oid_sup_id=sup_id where sup_name like '%%%s%%' or oid_format like '%%%s%%')",$data,formatNum($data)));
			}else if($field == 'ck1'){
				$op = 'eq';
				if($data == 0){
					$op = 'RAW_'.$field;
					$data = raw("ck1 is null or ck1=0");
				}
			}else if($field == 'oe_oe_format'){
				$data = formatNum($data);
			}else if($field == 'tags'){
				if(!empty($data)){
					if($op == 'ne'){
						$data= raw(sprintf("oe_id not in (select tl_value_id from tags_link where tl_type='poe' and tl_t_id > tl_t_id ^ %d)", $data));
					}else{
						$data= raw(sprintf("oe_id in (select tl_value_id from tags_link where tl_type='poe' and tl_t_id > tl_t_id ^ %d)", $data));
					}
				}else{
					if($op == 'ne'){
						$data= raw(sprintf("oe_id in (select tl_value_id from tags_link where tl_type='poe')"));
					}else{
						$data= raw(sprintf("oe_id not in (select tl_value_id from tags_link where tl_type='poe')"));
					}
				}
				$op = 'RAW_'.$field.$op.$orgdata;	
			}
        });
		
		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'p_cate': $where['oe_cate_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['on_formart'.($rules['numlike']? '[~]': '')] = $tnums;
					$fields[] = 'oen.on_number';
					$fields[] = 'fac.pf_name(on_pf_name)';
					$join['[><]pro_factory(fac)'] = ['oen.on_pf_id'=>'pf_id'];
				break;
				case 'mk_id':
					$where['RAW_'.$filed] = raw(sprintf("oe_id in (select distinct oml_oe_id from oe_model_link join m_model on oml_mm_id =mm_id where mm_mk_id in (%s))",$val));
					break;
				case 'ms_id':
					$where['RAW_'.$filed] = raw(sprintf("oe_id in (select distinct oml_oe_id from oe_model_link join m_model on oml_mm_id =mm_id where mm_ms_id in (%s))",$val));
					break;
				case 'brand_id':
					$where['RAW_'.$filed] = raw(sprintf("oe_id in (select distinct oml_oe_id from oe_model_cn_link join m_cn_model on oml_mod3_id =mod3_id where brand_id in (%s))",$val));
					break;
				case 'make_id':
					$where['RAW_'.$filed] = raw(sprintf("oe_id in (select distinct oml_oe_id from oe_model_cn_link join m_cn_model on oml_mod3_id =mod3_id where make_id in (%s))",$val));
					break;
				case 'mod2_id':
					$where['RAW_'.$filed] = raw(sprintf("oe_id in (select distinct oml_oe_id from oe_model_cn_link join m_cn_model on oml_mod3_id =mod3_id where mod2_id in (%s))",$val));
					break;
				case 'model_engine':
					$sql1 = sprintf("select distinct oml_oe_id from oe_model_cn_link
					join m_cn_model on oml_mod3_id =mod3_id where FIND_IN_SET('%s', mod3_engine) > 0 ",$val);
					$sql2 = sprintf("select distinct oml_oe_id from oe_model_link 
					join m_model on oml_mm_id =mm_id where FIND_IN_SET('%s', mm_engine) > 0",$val);
					$where['RAW_'.$filed] = raw(sprintf("oe_engine like '%%%s%%' or oe_id in (%s) or oe_id in (%s)",$val,$sql1,$sql2));
					break;
				case 'model_keyword':
					$sql = sprintf("select distinct oml_oe_id from oe_model_link 
					join m_model on oml_mm_id =mm_id
					join m_make on mm_mk_id=mk_id
					join m_series on mm_ms_id=ms_id
					where mm_name like '%%%s%%' or mk_cn_name like '%%%s%%' or mk_en_name like '%%%s%%' or mk_py_name like '%%%s%%' or ms_name like '%%%s%%'",$val,$val,$val,$val,$val);
					$where['RAW_'.$filed] = raw(sprintf("(oe_id in (select distinct oml_oe_id from oe_model_cn_link
					join m_cn_model on oml_mod3_id =mod3_id where mod3_name like '%%%s%%' or mod2_name like '%%%s%%')
					or oe_id in (%s))",$val,$val,$sql));
					break;
				case 'ver': 
					$join["[><]tags_link(tl)"] = ["oi.oe_id" => "tl_value_id"];
					$where['tl_type'] = 'poe';
					$where['tl_t_id[>]'] = raw(sprintf("tl_t_id ^ %d",$rules['ver']));
				break;
				
			}
		}

		if(!empty($params['supplier'])){
			$tids = [];
			foreach(explode(',', $params['supplier']) as $tid){
				$tids[] = (int) $tid;
			}
			$where['RAW_'.$filed] = raw(sprintf(" oe_id in (
			SELECT DISTINCT oe_id FROM oe_numidx
			JOIN oe_item ON oe_id = on_oe_id
			JOIN supplier_pro ON on_pf_id=spr_pf_id AND on_formart=spr_format AND oe_cate_id= spr_cat_id and spr_sup_id in (%s)
			)", implode(',', array_unique($tids))));
		}

		//查非
		if(!empty($rules['findNulls'])){
			$this->findNullsSearch($rules['findNulls'], $join, $this->joinWhere);
		}

		//汽车品牌查询
		if(isset($rules['tagBrand'])){
			$join['[><]oe_tag_brand(otb)'] = [
				"oi.oe_id" => "otb_oe_id"
			];
			if(!is_array($rules['tagBrand'])){
				$rules['tagBrand'] = explode(',', $rules['tagBrand']);
			}
			$this->joinWhere['otb_tb_id'] = $rules['tagBrand'];
		}
		
		//权限 - 小类
        $cates = \p::cates('A300');
        if(!\p::isAdmin() && $cates){
			$where['AND #rule_cate'] = ['oe_cate_id'=>explode(',',$cates)];
        }

		//权限 - 用户数据
		$viewUser = $this->getPowerViewUser();
		if($viewUser){
			$where['AND #rule_user'] = ['oe_opuser'=>$viewUser];	
		}

		if(!empty($params['coutype'])){
			$country = new \model\country();
			$couwhere = $country->formatSearchWhere('poe', $rules, $params);
			if(!empty($couwhere)) $where = array_merge($where, $couwhere);
		}

		if(!empty($params['keys'])) $where['oe_id'] = explode(',', $params['keys']);
		if(!empty($params['oe_id'])) $where['oe_id'] = $params['oe_id'];
		if($rules['show_rowsup']){
			$fields[] = 'sup.*';
			$fields[] = 'spr.*';
			$join['[>]supplier_pro(spr)'] = ['oen.on_pf_id'=>'spr_pf_id', 'oen.on_formart'=>'spr_format', 'oi.oe_cate_id'=>'spr_cat_id'];
			$join['[>]supplier(sup)'] = ['spr.spr_sup_id'=>'sup_id'];
			$where['GROUP'] = ['oe_id', 'sup_id'];
		}else{
			$where['GROUP'] ='oe_id';
		}
		
		if(!empty($this->joinWhere)){
			$where = array_merge($where, $this->joinWhere);
		}
        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);
	
		if($page>0 && $pagesize>0){
			$pages = $this->paging($table,$join, '*',$where,$page,$pagesize);
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
        $arr = $this->db->select($table,$join,$fields,$where);
		if(!empty($arr)){
			$oeIds = array_column($arr, 'oe_id');

			$join = ["[><]pro_factory(fac)" => ["on_pf_id" =>"pf_id"]];
			$rows = $this->db->select('oe_numidx', $join, ['on_oe_id', 'pf_name', 'on_number'], ['on_from'=>99, 'on_oe_id'=>$oeIds, 'ORDER'=>['pf_name', 'on_formart']]);
			$nums = [];
			foreach($rows as $rv){
				$nums[$rv['on_oe_id']][] = ['factory'=>$rv['pf_name'], 'number'=>$rv['on_number']];  
			}

			//存在的供应商
			$sups = [];
			$sql = sprintf("SELECT oe_id,sup_id, sup_name FROM oe_numidx
				JOIN oe_item ON oe_id = on_oe_id
				JOIN supplier_pro ON on_pf_id=spr_pf_id AND on_formart=spr_format
				JOIN supplier ON spr_sup_id=sup_id
				LEFT JOIN object ON sup_level=o_id WHERE oe_cate_id = spr_cat_id and oe_id IN (%s) group by oe_id, sup_id ORDER BY o_sort,sup_name", implode(',', $oeIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$sups[$rv['oe_id']][] = $rv;
				}
			}
			
			//存在商品库
			$pcs = [];
			$sql = sprintf("SELECT oe_id, p_id, p_innum FROM oe_numidx
				JOIN oe_item ON oe_id = on_oe_id
				JOIN pro_numidx ON on_pf_id=pn_pf_id AND on_formart=pn_formart 
				JOIN pro ON p_id=pn_p_id and p_pb_id = 1
				WHERE oe_cate_id = p_cate AND oe_id IN (%s) group by oe_id, p_id order by p_innum", implode(',', $oeIds));
			$rows = $this->db->query($sql)->fetchAll();
			if(!empty($rows)){
				foreach($rows as $rv){
					$pcs[$rv['oe_id']][] = $rv;
				}
			}

			//oe汽车品牌
			$oeTagRes = $this->db->select('oe_tag_brand(otb)',['[><]tag_brand(tb)'=>['otb.otb_tb_id'=>'tb_id']],['otb_oe_id','tb_names'=>raw('GROUP_CONCAT(tb_'.LG_NAME.' ORDER BY CONVERT(tb_'.LG_NAME.' USING gbk))')],['otb_oe_id'=>$oeIds,'GROUP'=>'otb_oe_id']);

			$oeTagBrand = array_column($oeTagRes,'tb_names','otb_oe_id');

			//主图
			$picRes = $this->db->select('oe_pic',['[><]files'=>['pic_fileid'=>'fileid']],'*',['pic_oe_id'=>$oeIds,'pic_type'=>'img','pic_ismain'=>1]);
			$picArr = [];
			foreach ($picRes as $pic) {
				if($pic['pic_type']=='img' && $pic['filetype']=='image'){
					$picArr[$pic['pic_oe_id']]['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
					$picArr[$pic['pic_oe_id']]['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
					if($params['isExport'])
					{
						$picArr[$pic['pic_oe_id']]['type'] = 'image';
						$picArr[$pic['pic_oe_id']]['filename'] = \mvc::$cfg['dir']['files'].'/'.$picArr[$pic['pic_oe_id']]['smallImg'];

						list($width, $height, $type, $attr) = getimagesize($picArr[$pic['pic_oe_id']]['filename']);
						$picArr[$pic['pic_oe_id']]['widthScale'] = 1;
						$picArr[$pic['pic_oe_id']]['heightScale'] = 1;
						$picArr[$pic['pic_oe_id']]['rowHeight'] = $height;
					}
				}
			}
			//查参数
			$fields = ['ppv_oe_id', 'ptpa_id', 'ptpa_type', 'ptpa_unit', 'ptpa_decimal', 'ppv_val_int', 'ppv_val_double', 'ppv_val_string', 'ptpa_col_order'];
			$fields = langSqlFields($fields, 'pa.', 'ptpa_', true);
			$fields = langSqlFields($fields, 'pps.', 'ppv_val_', true);
			$fields = langSqlFields($fields, 'ppsu.', 'ptpa_unit_', true);
			$sqltpl =sprintf("SELECT ".implode(',', $fields)."  FROM `oe_param_val` ov
			JOIN part_param pa ON ptpa_id = ppv_ptpa_id
			LEFT JOIN part_param_sche pps ON ((pps.pps_ptpa_id = ptpa_id AND ppv_val_string = pps.cn_name) or (pps.pps_ptpa_id = ptpa_pid and pps_id = ppv_val_int))
			LEFT JOIN part_param_sche ppsu ON ppsu.pps_ptpa_id = 0 and ptpa_unit = ppsu.cn_name
			WHERE ppv_oe_id in (%s) ORDER BY ptpa_pid DESC,ptpa_id ASC",implode(',',$oeIds));
			$rows = $this->db->query($sqltpl)->fetchAll();
			foreach($rows as $row){
				if($row['ppv_val_int']){
					$row['ppv_val'] = $row['ppv_val_'.LG_NAME].($row['ptpa_unit_'.LG_NAME]?:$row['ptpa_unit']);
					$paramArr[$row['ppv_oe_id']][] = ['name'=>$row['ptpa_'.LG_NAME],'value'=>$row['ppv_val']];
					continue;
				}
				if($row['ptpa_type']=='string'){
					$row['ppv_val'] = $row['ppv_val_'.LG_NAME];
				}elseif($row['ptpa_type']=='double'){
					$row['ppv_val'] = floatval(number_format($row['ppv_val_double'], $row['ptpa_decimal'],".",""));
				}
				$paramArr[$row['ppv_oe_id']][] = ['name'=>$row['ptpa_'.LG_NAME],'value'=>$row['ppv_val'].($row['ptpa_unit_'.LG_NAME]?:$row['ptpa_unit'])];
			}
			//查devlopno
			$devNoList = [];
			$devNoCapList = [];
			if($oeIds)
			{
				$devNoRes = $this->db->select('oe_item_developno',["[>]supplier"=>["oid_sup_id"=>"sup_id"]],['oe_item_developno.*','sup_name'],['oid_oe_id'=>$oeIds]);
				foreach ($devNoRes as $key => $val) {
					$devNoList[$val['oid_oe_id']][] = $val;
					$devNoCapList[$val['oid_oe_id']][] = $val['oid_number'].($val['sup_name']?'('.$val['sup_name'].')':'');
				}
			}
			//查用户
			$opuser = array_unique(array_filter(array_column($arr, 'oe_opuser')));
			if($opuser){
				$nameRes = $this->db->select('adm_user',['au_name','au_id'],['au_id'=>$opuser]);
				$aunameArr = array_column($nameRes,'au_name','au_id');
			}

			$allPos = (new pro())->allPos;
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('work');

			$tags = new tags();
			$verArr = $tags->getTypeValTags('poe', array_column($arr, 'oe_id'));
			$verArr = array_column($verArr, 'tags', 'tl_value_id');
			foreach($arr as &$v){
				$v['oe_amount'] = $v['oe_amount']?:'';
				$v['devNoList'] = $devNoList[$v['oe_id']]?$devNoList[$v['oe_id']]:[];
				$v['tb_names'] = $oeTagBrand[$v['oe_id']]??'';
				$v['nums'] = $nums[$v['oe_id']]? $nums[$v['oe_id']]: [];
				$v['sups'] = $sups[$v['oe_id']]? array_values($sups[$v['oe_id']]): [];
				$v['pcs'] = $pcs[$v['oe_id']]? array_values($pcs[$v['oe_id']]): [];
				$v['pic'] = $picArr[$v['oe_id']]??[];
				$v['tags'] = empty($verArr[$v['oe_id']]) ? '': implode(',', array_column($verArr[$v['oe_id']], 't_id'));
				$v['cate_posArr'] = [
					'cat_pos1'=>$v['cat_pos1']?explode(',',$v['cat_pos1']):[],
					'cat_pos2'=>$v['cat_pos2']?explode(',',$v['cat_pos2']):[],
					'cat_pos3'=>$v['cat_pos3']?explode(',',$v['cat_pos3']):[],
					'cat_pos4'=>$v['cat_pos4']?explode(',',$v['cat_pos4']):[],
					'cat_pos5'=>$v['cat_pos5']?explode(',',$v['cat_pos5']):[],
				];

				$numsopt = [];
				foreach($v['nums'] as $tk=>$tv){
					$numsopt[] = $tv['factory'].': '.$tv['number'];
				}

				if(!empty($v['sups'])){
					$v['chk_sups'] .= '<ul class="sup-list">';
					foreach($v['sups'] as $tpk=>$tpv){
						$v['chk_sups'] .= '<li> '.$tpv['sup_name'].($tpk === 0? ' <a href="javascript:openOeSupList('.$v['oe_id'].',\''.$v['oe_oe'].'\');"><i class="fa fa-list-alt"></i></a>': '').'</li>';
					}
					$v['chk_sups'] .= '</ul>';
				}
				$paramArr2 = [];
				foreach ($allPos as $pos => $val) {
					if($v['cat_'.$pos] && $v['oe_'.$pos]) {
						$pos = array_intersect(explode('/',$v['oe_'.$pos]),explode(',',$v['cat_'.$pos]));
						if($pos) $paramArr2[] = ['name'=>$val['name'],'value'=>implode('/',$pos)];
					}
				}
				
				$paramArr[$v['oe_id']]  = array_merge($paramArr2,$paramArr[$v['oe_id']]??[]);
				$v['param'] = $paramArr[$v['oe_id']]?$paramArr[$v['oe_id']]: [];
				$paramsopt = [];
				foreach ($v['param'] as $value) {
					$paramsopt[] = $value['name'].': '.$value['value'];
				}
				//检测产品库
				$v['chk_pcs'] = '';
				if(!empty($v['pcs'])){
					$v['chk_pcs'] .= '<ul class="pro-list-self">';
					foreach($v['pcs'] as $tpk=>$tpv){
						$tpv['pro_url'] = \mvc::$cfg['sitePath'].'/pro/detail?tab=base&p_id='.$tpv['p_id'];
						$v['chk_pcs'] .= '<li><a href="'.$tpv['pro_url'].'" tab>'.$tpv['p_innum'].'</a></li>';
					}
					$v['chk_pcs'] .= '</ul>';
				}

				$v['captions'] = [
					'oe_pic'=>$v['filepath']? \mvc::$cfg['urls']['outfiles'].'/'.$v['filepath'].'/'.$v['filebasename'].'small.'.$v['fileextname'] : '',
					'oe_oe'=>$v['pf_name'].': '.$v['oe_oe'],
					'nums'=>implode('<br>', $numsopt),
					'oe_unit'=>!empty($collArr[$v['oe_unit']])? $collArr[$v['oe_unit']]: '',
					'oe_fuel'=>!empty($collArr[$v['oe_fuel']])? $collArr[$v['oe_fuel']]: '',
					'oe_progroup'=>!empty($collArr[$v['oe_progroup']])? $collArr[$v['oe_progroup']]: '',
					'spr_material'=>!empty($collArr[$v['spr_material']])? $collArr[$v['spr_material']]: '',
					'param'=>implode('<br>', $paramsopt),
					'oe_develop_status'=>!empty($collArr[$v['oe_develop_status']])? $collArr[$v['oe_develop_status']]: '',
					'oe_opuser'=>$aunameArr[$v['oe_opuser']]??'',
					'devNoList'=>$devNoCapList[$v['oe_id']]?implode("\r\n",$devNoCapList[$v['oe_id']]):'',
					'tags'=> empty($verArr[$v['oe_id']]) ? '': implode(',', array_column($verArr[$v['oe_id']], LG_NAME)),
				];
			}
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	 /**查非
     * @return 
     */
    public function findNullsSearch($findNulls,&$join,&$where)
    {
        if(is_string($findNulls)) return;
        foreach($findNulls as $item){
            $name = $item['name'];
            $value = $item['value'];
			$op = $value ? ' EXISTS ' : ' NOT EXISTS ';
            switch($name){
                case 'null_param':
                    $tsql = $op.sprintf("(SELECT 1 FROM oe_param_val WHERE ppv_oe_id = oi.oe_id LIMIT 1)");
                    break;
                case 'null_cnmodel':
                    $tsql = $op.sprintf("(SELECT 1 FROM oe_model_cn_link WHERE oml_oe_id = oi.oe_id LIMIT 1)");
                    break;
				case 'null_model':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_model_link WHERE oml_oe_id = oi.oe_id LIMIT 1)");
					break;
				case 'null_numidx':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_numidx WHERE on_oe_id = oi.oe_id LIMIT 1)");
					break;
				case 'null_oe':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_numidx WHERE on_oe_id = oi.oe_id and on_pf_id = 1 LIMIT 1)");
					break;
				case 'null_name':
					$tsql = $value? " oe_cn_name != '' and oe_en_name != '' and oe_py_name != ''": " (oe_cn_name = '' or oe_en_name = '' or oe_py_name = '')";
					break;
				case 'null_img':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_pic WHERE pic_oe_id = oi.oe_id and pic_type = 'img' LIMIT 1)");
					break;
				case 'null_line':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_pic WHERE pic_oe_id = oi.oe_id and pic_type = 'line' LIMIT 1)");
					break;
				case 'null_other':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_pic WHERE pic_oe_id = oi.oe_id and pic_type = 'other' LIMIT 1)");
					break;
				case 'null_competitor':
					$tsql = $op.sprintf("(SELECT 1 FROM competitor_price WHERE cop_oe_id = oi.oe_id LIMIT 1)");
					break;
				case 'null_link':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_link WHERE ol_type = 'link' and  ol_oe_id1 = oi.oe_id LIMIT 1)");
					break;
				case 'null_pair':
					$tsql = $op.sprintf("(SELECT 1 FROM oe_link WHERE ol_type = 'pair' and  ol_oe_id1 = oi.oe_id LIMIT 1)");
					break;
				case 'null_supplier':
					$tsql = $op.sprintf("(SELECT 1 FROM supplier_pro WHERE spr_oe_id = oi.oe_id LIMIT 1)");
					break;
				case 'null_pro':
					if($value=='one'){
						$tsql = sprintf("oi.oe_id in (SELECT oe_id FROM oe_item JOIN pro ON oe_id = p_oe_id AND p_pb_id=1 GROUP BY oe_id HAVING COUNT(p_id) =1)");
					}elseif ($value=='any') {
						$tsql = sprintf("oi.oe_id in (SELECT oe_id FROM oe_item JOIN pro ON oe_id = p_oe_id AND p_pb_id=1 GROUP BY oe_id HAVING COUNT(p_id) > 1)");
					}
					break;
            }
            $where['RAW #'.$name] = raw($tsql);
        }
    }


	
	public function getListSupplier($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'];

		$table = 'oe_item(oi)';
		$join = [
			"[><]oe_numidx(oen)" => ["oi.oe_id" => "on_oe_id"],
			"[><]supplier_pro(spr)" => ["oi.oe_cate_id"=>"spr_cat_id","oi.oe_id"=>"spr_oe_id"],
			"[><]supplier(sup)" => ["spr.spr_sup_id" => "sup_id"],
		];
		
		
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			// $field = strtr( $field, $this->get('refiled'));
        });
		
		if(!empty($params['keys'])) $where['oe_id'] = explode(',', $params['keys']);
		if(!empty($params['oe_id'])) $where['oe_id'] = $params['oe_id'];
		//if(!\p::isAdmin()) $where['oe_opuser'] = getOpuser();

		$where['GROUP'] = 'spr_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 = ['spr.*','sup.sup_name','sup.sup_code'];
        $arr = $this->db->select($table,$join,$fields,$where);

		$collocation = new collocation();
		foreach($arr as &$v){

			$v['captions'] = [
				'spr_price_status'=>$v['spr_price_status']=='Y'	? '有效': '无效',
				'spr_has'=>$v['spr_has']=='Y'	? '是': '否',
				'spr_hasample'=>$v['spr_hasample']=='Y'	? '是': '否',
			];

			$v['captions']['spr_material'] = '';
			$v['captions']['spr_material'] = '';
			if($v['spr_material']){
				$v['captions']['spr_material'] = $collocation->getRowByKey($v['spr_material'])[cateName()];
			}	
			
			
		}
		unset($v);
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}
	

	/**
	 * @method  初始化零件库的品牌标签
	 * @param  $ids [int/array] 为空则整库
	 * @copyright
	 */
	function initTagBrand($ids = [])
	{
		$isall = false;
		if(!empty($ids)){
			if(!is_array($ids)) $ids = [$ids];
			$ids = array_map(function($id) {return (int) $id; }, $ids);
		}else{
			$isall = true;
			$ids = $this->db->select('oe_item', 'oe_id');
		}
		$chus = array_chunk($ids, 20);
		$this->db->Begin();
		foreach($chus as $idArr){
			$hasArr = [];
			//已有的
			$rows = $this->db->select('oe_tag_brand', ['otb_oe_id(oe_id)', 'otb_tb_id(tb_id)'], ['otb_oe_id'=>$idArr]);
			foreach($rows as $v){
				$hasArr[$v['oe_id']][$v['tb_id']] = $v['tb_id'];
			}

			//车型关联的
			$newArr = [];

			//中国车型
			$join =[
				'[><]m_cn_model(cm)'=>['ol.oml_mod3_id'=>'mod3_id'],
				'[><]tag_brand_cnbrand(tb)'=>['cm.brand_id'=>'tbm_brand_id'],
			];
			$rows = $this->db->select('oe_model_cn_link(ol)', $join, ['oml_oe_id(oe_id)', 'tbm_tb_id(tb_id)'], ['oml_oe_id'=>$idArr, 'GROUP'=>['oml_oe_id', 'tbm_tb_id']]);
			foreach($rows as $v){
				$newArr[$v['oe_id']][$v['tb_id']] = $v['tb_id'];
			}

			//国际车型库
			$join =[
				'[><]m_model(cm)'=>['ol.oml_mm_id'=>'mm_id'],
				'[><]tag_brand_make(tb)'=>['cm.mm_mk_id'=>'tbm_mk_id'],
			];
			$rows = $this->db->select('oe_model_link(ol)', $join, ['oml_oe_id(oe_id)', 'tbm_tb_id(tb_id)'], ['oml_oe_id'=>$idArr, 'GROUP'=>['oml_oe_id', 'tbm_tb_id']]);
			foreach($rows as $v){
				$newArr[$v['oe_id']][$v['tb_id']] = $v['tb_id'];
			}

			foreach($idArr as $id){
				//车型匹配为空的跳过，人工加入
				if(empty($newArr[$id])) continue;
				$old = $hasArr[$id] ? $hasArr[$id]: [];
				$add = []; $del = [];
				foreach($newArr[$id] as $tbid){
					if(!$old[$tbid]) $add[$tbid] = ['otb_oe_id'=>$id, 'otb_tb_id'=>$tbid];
				}
				$del = array_diff($old, $newArr[$id]);
				if($add) $this->db->insert('oe_tag_brand', array_values($add));
				if($del) $this->db->delete('oe_tag_brand', ['otb_oe_id'=>$id, 'otb_tb_id'=>$del]);
			}

			//自动初始化零件适用国家
			if(!$isall) $this->initCountryLink($idArr);
		}
		$this->db->End();
		return [];
	}


	/**
	 * @method  自动初始化零件适用国家
	 * @param  $ids [int/array] 为空则整库
	 * @copyright
	 */
	function initCountryLink($ids = [])
	{
		if(!empty($ids)){
			if(!is_array($ids)) $ids = [$ids];
			$ids = array_map(function($id) {return (int) $id; }, $ids);
		}else{
			$ids = $this->db->select('oe_item', 'oe_id', ['ORDER'=>'oe_id']);
		}

		$chus = array_chunk($ids, 20);
		$country = new country();
		foreach($chus as $tids){
			$hasArr = [];
			//国际车型
			$sql = sprintf("SELECT oml_oe_id, cl_cc_id FROM oe_model_link 
			JOIN crm_country_link ON cl_value_id = oml_mm_id AND cl_type = 'model'
			WHERE oml_oe_id in (%s) GROUP BY oml_oe_id, cl_cc_id", implode(',', $tids));
			$rows = $this->db->query($sql)->fetchAll();
			if($rows){
				foreach($rows as $row){
					$hasArr[$row['oml_oe_id']][] = $row['cl_cc_id'];
				}
			}
			//中国车型
			$pids = $this->db->select('oe_model_cn_link', 'oml_oe_id', ['oml_oe_id'=>$tids, 'GROUP'=>'oml_oe_id']);
			if($pids){
				foreach($pids as $id){
					$hasArr[$id][] = \mvc::$cfg['CNID'];
				}
			}
			$this->db->Begin();
			foreach($hasArr as $valid=>$ccids){
				$ccids = array_unique($ccids);
				$country->changeLink('poe', 'replace', [$valid], $ccids);
			}
			$delids = array_diff($tids, array_keys($hasArr));
			if($delids) $this->db->delete('crm_country_link', ['cl_type'=>'poe', 'cl_value_id'=>$delids]);
			$this->db->End();
		}
		return [];
	}

	public function setOePicCell($param)
	{	
		return $this->db->update('oe_pic',[$param['field']=>$param[$param['field']]],['pic_oe_id'=>$param['oeid'],'pic_fileid'=>$param['fileid'],'pic_type'=>$param['type']]);
	}


	/**
	 * @method 根据on_id设置零件库主号码
	 * @author zhengweihua 
	 * @copyright 2025-01-11
	 */
	public function setOeMain($on_id,$syncFgio=false)
	{
		$this->db->Begin();
		$row = $this->db->get('oe_numidx','*',['on_id'=>$on_id]);
		if(!$row) return [];
		$updata = [
			'oe_pf_id'=>$row['on_pf_id'],
			'oe_oe'=>$row['on_number'],
			'oe_oe_format'=>$row['on_formart'],
			'oe_update_time'=>getNowTime()
		];
		$this->db->update('oe_numidx', ['on_ismain'=>'N'], ['on_oe_id'=>$row['on_oe_id'], 'on_ismain'=>'Y', 'on_id[!]'=>$on_id]);
		$this->db->update('oe_numidx', ['on_ismain'=>'Y'], ['on_oe_id'=>$row['on_oe_id'], 'on_ismain'=>'N', 'on_id'=>$on_id]);
		$this->db->update('oe_item',$updata,['oe_id'=>$row['on_oe_id']]);
		$pro = new pro();
		$pro->synProByOe($row['on_oe_id'],['nums'],$syncFgio);
		$this->db->end();
		return [];
	}

	/**
	 * @method 根据选中的on_id设置借用
	 * @author hongzhang
	 * @copyright 2025-08-29
	 */
	public function setBorrowNums($ids,$borrow){
		// dump($on_ids);
		$on_ids = explode(',', $ids);
		// 获取选中的号码的oe_id（实际上都为同一个）
		$oeId = $this->db->get('oe_numidx',['[><]oe_item'=>['on_oe_id'=>'oe_id']],'oe_id,oe_name', ['on_id'=>$on_ids,'GROUP'=>'oe_id']);
		$on_list = $this->db->select('oe_numidx',[],['on_pf_id'],['on_id'=>$on_ids,'on_pf_id[!]'=>1]);
		if($on_list){
			exitJson(lg('只能选择OE厂商的号码借用'));
		}else{
			$updateTime = getNowTime();
			$this->db->Begin();
			$this->db->update('oe_numidx',['on_isborrow'=>$borrow,'on_update_time'=>$updateTime],['on_id'=>$on_ids]);
			$pro = new pro();
			$pro->synProByOe($oeId,['nums']);
			$this->db->End();
		}
		return [];
	}

	/**检测上传
     * @param 
     * @return
     */
	public function uploadCheck($filecount,$reqfilename,$reqfilesize,$uploadID,$extname,$category,$item,$params)
	{
		$oeid = $params['oeid'];
		if(empty($oeid)) {
			throw new \Exception ( '上传图片时，零件库ID丢失' );
		}
		$cfg = \mvc::$cfg['upload']['category'][$category]['items'][$item];
		
		$count = 0;
		$oe_photos = $this->db->select('oe_pic','pic_fileid',['pic_oe_id'=>$oeid]);
		if($oe_photos){
		   
			$count = count($oe_photos);
		}
		if( ($count+1) > $cfg['maxfile']){
			return lg('超出此项的最大允许的文件数量') .','. lg('最大允许').' '.$cfg['maxfile'].' '.lg('个文件');
		}else{
			return true;
		}
	}


    /**接收上传的图片处理
     * @param 
     * @return
     */
	public function uploadGet($fileid,$filename,$dir,$filebase,$extname,$category,$item,$params)
	{
		$oeid = $params['oeid'];

		if(empty($oeid)) {
			throw new \Exception ( '上传图片时，零件库ID丢失' );
		}	
		$join =[
			'[>]oe_pic(pic1)'=>['oi.oe_pic'=>'pic_fileid'],
			'[>]oe_pic(pic2)'=>['oi.oe_linepic'=>'pic_fileid'],
		];
		$oeinfo = $this->db->get('oe_item(oi)',$join,['oe_pic','oe_linepic','oe_id','pic1.pic_fileid(oe_pic_fileid)','pic2.pic_fileid(oe_linepic_fileid)'],['oe_id'=>$oeid]);
		//图片
		$flag = false;
		if(!$oeinfo['oe_pic_fileid'] && $item =='img')
		{
			$flag  = true;
			$this->db->update('oe_item',['oe_pic'=>$fileid],['oe_id'=>$oeid]);
		}
		//图纸
		if(!$oeinfo['oe_linepic_fileid'] && $item =='line')
		{
			$flag = true;
			$this->db->update('oe_item',['oe_linepic'=>$fileid],['oe_id'=>$oeid]);
		}

		//同零件同类型下是否已存在
		$has  = $this->db->get('oe_pic','*',['pic_oe_id'=>$oeid,'pic_type'=>$item,'pic_fileid'=>$fileid]);
		if(!$has)
		{
			$fileinfo = $this->db->get('files', '*', ['fileid' => $fileid]);
			$data = [
				'pic_oe_id'=>$oeid,
				'pic_fileid'=>$fileid,
				'pic_type'=>$item,
				'pic_filebase'=>$fileinfo['fileremark'],
				'pic_opuser'=>getOpuser(),
				'pic_create_time'=>getNowTime(),
				'pic_update_time'=>getNowTime(),
				'pic_ismain'=>$flag?1:0
			];
			$this->db->insert('oe_pic',$data);
		}
		
	}

	/**
	 * @param  int $fileid
	 * @param int  $oeid
	 * @method 设置主图
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function setOeMainPic($fileid,$oeid,$type)
	{
		//无需文件ID,支持自动设置
		if(empty($fileid)){
			$main = $this->db->get('oe_pic', 'pic_fileid', ['pic_oe_id'=>$oeid, 'pic_type'=>$type, 'pic_ismain'=>1]);
			if($main) return [];
			$fileid = $this->db->get('oe_pic', 'pic_fileid', ['pic_oe_id'=>$oeid, 'pic_type'=>$type, 'ORDER'=>['pic_fileid']]);
		}
		$fileid = (int) $fileid;
		$this->db->Begin();
		if($type=='img')
		{
			$this->db->update('oe_item',['oe_pic'=>$fileid],['oe_id'=>$oeid]);
		}
		if($type=='line')
		{
			$this->db->update('oe_item',['oe_linepic'=>$fileid],['oe_id'=>$oeid]);
		}
		$this->db->update('oe_pic',['pic_ismain'=>0],['pic_fileid[!]'=>$fileid,'pic_oe_id'=>$oeid,'pic_type'=>$type]);
		$this->db->update('oe_pic',['pic_ismain'=>1],['pic_fileid'=>$fileid,'pic_oe_id'=>$oeid,'pic_type'=>$type]);
		//零件主图保存到商品
		$arr = $this->db->get('oe_pic',['[><]files'=>['oe_pic.pic_fileid'=>'fileid']],'*',['pic_ismain'=>1,'pic_fileid'=>$fileid,'pic_oe_id'=>$oeid,'pic_type'=>$type]);
		if($arr){
			$p_id = $this->db->get('pro','p_id',['p_oe_id'=>$oeid,'p_pb_id'=>1]);
			$join = [
				'[><]files'=>['pic.pic_fileid'=>'fileid'],
			];
			$parr = $this->db->get('pro_pic(pic)',$join,['pic.*'],['pic_p_id'=>$p_id,'file_category'=>'pro','file_crc32'=>$arr['file_crc32'],'pic_type'=>$type]);
			if($p_id && $parr['pic_fileid']){
				$pro = new pro();
				$pro->setProMainPic($parr['pic_fileid'],$p_id,$parr['pic_type']);
			}elseif ($p_id && !$parr['pic_fileid']) {
				//将零件主图
				$synProPic = new synProPic();
				$data = file_get_contents(\mvc::$cfg['urls']['outfiles'].'/'.$arr['filename']);
				$synProPic->saveProPic($p_id,$data,$arr['filename'],$arr['fileextname'],['is_main'=>1]);
			}
		}
		
		$this->db->End();
		return [];
	}

	/**
	 * @param  [type] $sup_id
	 * @param  [type] $fileid
	 * @param  [type] $oeid
	 * @method 变更图片供应商
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function setPicLineSup($oeid,$sup_id,$fileid = [])
	{
		$this->db->update('oe_pic',['pic_sup_id'=>$sup_id],['pic_fileid'=>$fileid,'pic_oe_id'=>$oeid]);
		return [];
	}

	/**
	 * @param  [type] $params
	 * @param  array  $rules
	 * @method 获取零件图片列表
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function getListPic($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? 'pic_ismain': $params['sidx'];
		$sord = empty($params['sord'])? 'desc': $params['sord'];
		$orderby = $params['orderby'];

		$table = 'oe_pic(pic)';
		$join = [
			"[><]oe_item(oi)" => ["pic.pic_oe_id" => "oe_id"],
			"[><]files(file)"=>["pic.pic_fileid"=>"fileid"],
			"[>]supplier(sup)"=>['pic.pic_sup_id'=>'sup_id'],
			"[>]adm_user(au)"=>['pic.pic_opuser'=>'au_id'],
		];
		
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			if($field == 'main_pic'){
				$op = 'RAW_'.$field;
				if($data =='Y'){
					$data = raw("pic_fileid in (select oe_pic from oe_item where oe_id = pic_oe_id)");
				}else{
					$data = raw("pic_fileid not in (select oe_pic from oe_item where oe_id = pic_oe_id)");
				}
			}

			if($field == 'main_linepic'){
				$op = 'RAW_'.$field;
				if($data =='Y'){
					$data = raw("pic_fileid in (select oe_linepic from oe_item where oe_id = pic_oe_id)");
				}else{
					$data = raw("pic_fileid not in (select oe_linepic from oe_item where oe_id = pic_oe_id)");
				}
				
			}
        });
		if(!empty($params['type'])) $where['pic_type'] = $params['type'];
		if(!empty($params['keys'])) $where['pic_fileid'] = explode(',', $params['keys']);
		if(!empty($params['oe_id'])) $where['pic_oe_id'] = $params['oe_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];
		}
		$where['ORDER'] = raw("CASE WHEN pic_from=99 THEN -1 WHEN pic_from=1116 THEN 0 ELSE 1 END ASC,pic_ismain DESC,pic_sort ASC");
		$fields = ['pic.*','sup_name','file.*','au_name'];
        $arr = $this->db->select($table,$join,$fields,$where);
		// dd($this->db->last());
		$oeArr = [];
		if($arr){
			$oeidArr = array_column($arr,'pic_oe_id');
			$oeArr = $this->db->select('oe_item',['oe_pic','oe_linepic','oe_id'],['oe_id'=>$oeidArr]);
			$oeArr = array_column($oeArr,null,'oe_id');
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('other');
			foreach ($arr as $key => &$val) {
				if($val['filetype']=='image' && $val['pic_type']=='img'){
					$val['bigImg'] = $val['filepath'].'/'.$val['filebasename'].'big.'.$val['fileextname'];
					$val['smallImg'] = $val['filepath'].'/'.$val['filebasename'].'small.'.$val['fileextname'];
				}
				
				$val['main_pic'] = '';
				$val['main_linepic'] = '';
				if($oeArr[$val['pic_oe_id']]['oe_pic']==$val['pic_fileid']){
					$val['main_pic'] = 'Y';
				}

				if($oeArr[$val['pic_oe_id']]['oe_linepic']==$val['pic_fileid']){
					$val['main_linepic'] = 'Y';
				}
				$val['captions'] = [
					'pic_opuser'=>$val['au_name'],
					'pic_from'=>$collArr[$val['pic_from']]
				];
			}
			unset($val);
		}
		
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	public function autoSup($params)
	{
		$params['name'] = empty($params['name'])? $params['query']: $params['name'];
		$where = ['sup_name[=~]'=>$params['name']];
		
		$where['LIMIT'] = empty($params['limit'])? 20: (int) $params['limit'];
		$where['ORDER'] = 'sup_id';

		$rows = $this->db->select('supplier',['sup_id','sup_name'], $where);
		$data = [];
		foreach($rows as $k=>$v){
			$data[$k]=['key'=>$v['sup_id'], 'value'=>$v['sup_name']];
		}
		return $data;
	}

	public function chkSup($param)
	{
		$idArr =[];
		if(!empty($param['sup_id']))
		{
			$rows = $this->db->select('supplier', ['sup_id'], ['sup_name'=>$param['sup_id']]);
			if(!empty($rows)) $idArr = array_column($rows, 'sup_id');
		}
		
		return array_unique($idArr);
	}

	public function delOePic($param)
	{	
		if($param['ids'] && $param['oeid'] && $param['type']){
			$ids = explode(',',$param['ids']);
			$this->db->delete('oe_pic',['pic_oe_id'=>$param['oeid'],'pic_fileid'=>$ids,'pic_type'=>$param['type']]);
			$this->setOeMainPic(0, $param['oeid'], $param['type']);
		}
		return [];
	}

	function getPicByNum($number)
	{	
		if(!$number) [];
		$arr = [];
		$arr = $this->db->get('oe_item',['oe_oe','oe_oe_format','oe_id'],['oe_oe_format'=>formatNum($number)]);
		if($arr)
		{
			$pic = $this->db->select('oe_pic(pic)',['[><]files'=>['pic.pic_fileid'=>'fileid']],'*',['pic_oe_id'=>$arr['oe_id'],'pic_type'=>'img']);
			$arr['img'] = $pic;
		}
		return $arr;
	
	}

	public function searchPic($number,$post_arr=[])
	{	
		
		if(!$number) return [];
		$url = sprintf('http://pic.amozi.com/robot/index.php?from=g&search=%s&first=0',formatNum($number));
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
		if(!empty($post_arr))
		{
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, ['data'=>json_encode($post_arr)]);
		}
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$ssl = substr($url, 0, 8) == "https://" ? true : false;
        if($ssl)
		{
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
		$html = curl_exec($ch);
		curl_close($ch);
		
		//处理错误提示
		$return = json_decode($html, true);
		if(is_array($return)){
			return $return;
		}
	}

	//重新获取零件爆炸图信息 $on_id=0随机取OE
	function reGetEpcInfo($oe_id, $on_id = 0){
		$oes = [];
		$where = ['on_pf_id'=>1, 'on_oe_id'=>$oe_id];
		$apiParam = [];
		if(empty($on_id)){
			//优先清洗源
			$row = $this->db->get('oe_item', ['oe_oe_format', 'oe_pf_id', 'oe_chkpro_from', 'oe_chkpro_info', 'oe_etk_info'], ['oe_id'=>$oe_id]);
			if($row){
				if($row['oe_chkpro_from'] == 'etk'){
					$chkinfo = json_decode($arr['oe_chkpro_info'], true);
					$apiParam = [
						'etk_id'=>$chkinfo['etk_id'],
						'pro_id'=>$chkinfo['pro_id'],
						'grp2_id'=>$chkinfo['grp2_id']
					];
				}
				if($row['oe_pf_id'] == 1) $oes[] = $row['oe_oe_format'];
			}
		}else{
			$where['on_id'] = $on_id;
		}
		$where['LIMIT'] = 20;
		$rows = $this->db->select('oe_numidx', 'on_formart', $where);
		$oes = array_unique(array_merge($oes, $rows));
		$apiParam['number'] = implode(',', $oes);

		$ypApi = new ypApi();
		$chkres = $ypApi->Get('client/epcItemGroupInfo', $apiParam);
		if($chkres['status'] && $chkres['data']['base']){
			$partitem = $chkres['data']['partitem'];
			$probase = $chkres['data']['base'];

			//OE借用
			$isborrow = $this->db->get('oe_numidx', 'on_isborrow', ['on_oe_id'=>$oe_id, 'on_isborrow'=>1]);
			if($isborrow) $probase = [];
			
			//加入关联表
			$opuser = getOpuser();
			$datetime = getNowTime();
			$this->db->Begin();
			$ektAdd = [
				'epa_param'=>json_encode($apiParam, JSON_UNESCAPED_UNICODE),
				'epa_param_unikey'=>md5(serialize($apiParam)),	
				'epa_partitem'=>json_encode($partitem, JSON_UNESCAPED_UNICODE),	
				'epa_create_time'=>$datetime
			];
			$epa_id = $this->db->get('etk_partitem', 'epa_id', ['epa_param_unikey'=>$ektAdd['epa_param_unikey']]);
			if(empty($epa_id)){
				$this->db->insert('etk_partitem', $ektAdd);
				$epa_id = $this->db->id();
			}
			$set = [
				'oe_etk_info'=>json_encode($probase, JSON_UNESCAPED_UNICODE),
				'oe_etk_epa_id'=>$epa_id
			];
			//取用量
			if($probase['para']){
				foreach ($probase['para'] as $pvals) {
					if($pvals['name']=='用量'){
						$set['oe_amount'] = $pvals['val'];
						break;
					}
				}
			}
			$this->db->update('oe_item', $set, ['oe_id'=>$oe_id]);
			if(!$isborrow){
				if(!empty($partitem['item'])){
					foreach($partitem['item'] as $ptv){
						if(!$ptv['pro_realoem']) continue;
						$number2 = $ptv['pro_realoem'];
						$format2 = formatNum($number2);
						if(strlen($format2) < 3) continue;
						$pf_id2 = 1;

						$snums = reSearchNum($format2);
						$oe_id2 = $this->db->get('oe_numidx', 'on_oe_id', ['on_pf_id'=>$pf_id2, 'on_formart'=>$snums]);
						if($oe_id2 && $oe_id2 == $oe_id) continue;
						$chk = null;
						if($oe_id2) $chk = $this->db->get('oe_link', 'ol_id', ['ol_type'=>'link', 'ol_oe_id1'=>$oe_id, 'ol_oe_id2'=>$oe_id2]);
						if(!$chk) $chk = $this->db->get('oe_link', 'ol_id', ['ol_type'=>'link', 'ol_oe_id1'=>$oe_id, 'ol_pf_id2'=>$pf_id2, 'ol_format2'=>$format2]);
						if($chk) continue;
						$link = [
							'ol_type'=>'link',	
							'ol_oe_id1'=>$oe_id,
							'ol_oe_id2'=>$oe_id2,
							'ol_pf_id2'=>$pf_id2,	
							'ol_number2'=>$number2,	
							'ol_format2'=>$format2,	
							'ol_from'=>1070,	
							'ol_opuser'=>$opuser,
							'ol_create_time'=>$datetime,
							'ol_update_time'=>$datetime,
						];
						$this->db->insert('oe_link', $link);
					}
				}

				if($probase['pic']){
					$imgdir = $this->drawEpcWz($probase['pic'], $probase['wz'], $partitem['part']['width'], $partitem['part']['rate']);
					if($imgdir) $this->downloadAndSaveImage($oe_id, $imgdir, 'img', ['text'=>'EPC', 'pic_from'=>1070]);
					@unlink($imgdir);
				}
			}
			$this->db->End();
			return ['epc'=>1];
		}
		return ['epc'=>0];
	}

	//EPC图绘画坐标
	function drawEpcWz($url, $wzs, $width = 0, $rate = 1){
		$imgdir = '';
		$html = _iohtml($url);
		if(strlen($html) > 10240){
			$tdir = \mvc::$cfg['dir']['files'].'/temp';
			mkdirs($tdir);
			$crc32 = strtoupper(dechex(crc32($html)));
			$ext = 'jpg';
			if(stripos($url, '.png') !== false){
				$ext = 'png';
			}
			$tpic = $tdir.'/'.$crc32.'.'.$ext;
			file_put_contents($tpic, $html);
			$image = make(\lib\image::class,100);
			if($ext == 'png'){
				//由于可能会失败获取真实的后缀,
				$ext = $this->getExtensionFromMime($tpic);
				$tpic = $tdir.'/'.$crc32.'.'.$ext;
				$new = $tdir.'/'.$crc32.'.jpg';
				$image->ToJPG($tpic, $new, true);
				$tpic = $new;
			}
			
			$width = (int) $width;
			$rate = (int) $rate;
			if(empty($rate)) $rate = 1;
			if($width > 0){
				$sizeInfo = getimagesize($tpic);
				$rate = $sizeInfo[0]/$width*$rate;
			}
			$image = imagecreatefromjpeg($tpic);
			$red = imagecolorallocate($image, 255, 0, 0); // 红色背景
			$text_color = imagecolorallocate($image, 255, 255, 255); // 白色文字
			$font_path = \mvc::$cfg['dir']['static'].'/fonts/arial.ttf'; // 字体文件路径
			foreach($wzs as $wz){
				$xyArr = explode(',', $wz[1]);
				foreach($xyArr as $k=>$v){
					$xyArr[$k] = $v*$rate;
				}
				$xyArr[0] -= 3;
				$xyArr[1] -= 3;
				$xyArr[2] += 3;
				$xyArr[3] += 3;
				$h = $xyArr[3]-$xyArr[1];
				$w = $xyArr[2]-$xyArr[0];
				$text = $wz[0];
				$rect_x = $xyArr[0];
				$rect_y = $xyArr[1];
				$rect_width = $w;
				$rect_height = $h;
				$font_size = (int) $w/strlen($text);
				if($font_size < 14) $font_size = 14;

				imagefilledrectangle($image, $rect_x, $rect_y, $rect_x + $rect_width, $rect_y + $rect_height, $red);
				$bbox = imagettfbbox($font_size, 0, $font_path, $text);
				$text_width = $bbox[2] - $bbox[0];
				$text_height = $bbox[1] - $bbox[7];
				$text_x = $rect_x + ($rect_width - $text_width) / 2;
				$text_y = $rect_y + ($rect_height + $text_height) / 2;
				imagettftext($image, $font_size, 0, $text_x, $text_y, $text_color, $font_path, $text);
			}
			imagejpeg($image, $tpic, 100);
			imagedestroy($image);
			$imgdir = $tpic;
		}
		return $imgdir;
	}

	function setOePicByFile($param){
		if(!$param['oe_id']||!$param['imgs']) return exitJson(-1,'参数错误');
		$oeId = $this->db->get('oe_item', 'oe_id',['oe_id'=>$param['oe_id']]);
		if(!$oeId) return exitJson(-1,'零件不存在');
		$result = [];
		foreach ($param['imgs'] as $key => $val) 
		{
			$val = json_decode(base64_decode($val),true);
			$res = $this->downloadAndSaveImage($oeId,$val['big'],'search',$val);
			if($res['code']==-1){
				$result[] = $val['text'].$res['msg'];
			}
		}
		if($result){
			return exitJson(-1,implode('<br>',$result));
		}
		return  [];
	}

	/**
	 * @param  int $oe_id
	 * @param  string $url 图片网址或者本地图片路径
	 * @param  string $type 默认为空， search:搜图模式
	 * @param  Array $options 搜图模式可提供额外参数
	 * @method 下载并保存图片
	 * @author zhengweihua 
	 * @copyright 2025-01-15
	 */
	function downloadAndSaveImage($oe_id,$url,$type='',$options = [])
	{	
		if(!$oe_id ||!$url) return ['code'=>-1,'msg'=>'参数错误']; 
		$path = parse_url($url, PHP_URL_PATH);
		// 获取路径中的文件名
		$filename = basename($path);
		$validImageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
		// 获取文件扩展名
		$extname = pathinfo($filename, PATHINFO_EXTENSION);
		//  如果文件名不是图片扩展名，则使用默认名称
		if (!in_array(strtolower($extname), $validImageExtensions)) {
			$filename = 'image_'.time().'_'.rand(1000,9999).'.jpg'; // 默认使用jpg扩展名
			$extname = 'jpg';
		}

		// 将 MIME 类型转换为文件扩展名
		$mimeMap = [
			'image/jpeg' => 'jpg',
			'image/png' => 'png',
			'image/gif' => 'gif',
			'image/bmp' => 'bmp',
			'image/webp' => 'webp'
		];
		$params = ['oe_id'=>$oe_id];

		//是否是有效网址
		if(filter_var($url, FILTER_VALIDATE_URL))
		{
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时时间为5秒
			$data = curl_exec($ch);

			//如果不是图片，则二次请求 
			$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

			if($type=='search' && strpos($contentType, 'image/') !== 0)
			{
				$url = sprintf("http://pic.amozi.com/robot/index.php?from=big&search=%s",$url);
				$ch = curl_init($url);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
				curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时时间为5秒
				$data = curl_exec($ch);
				$arr = json_decode($data,true);
				if($arr['data']['img']!=-1){
					$base64String = $arr['data']['img'];
					$oribase64 = $base64String;
					// 去掉base64头部信息
					$base64String = preg_replace('/^data:image\/\w+;base64,/', '', $base64String);
					$base64String = str_replace(' ', '+', $base64String);
					// 解码base64数据
					$data = base64_decode($base64String);
				}else{
					$data = false;
				}
			}else{
				if(!$extname) $extname = $mimeMap[$contentType]??'';
			}
			curl_close($ch);
		}else{
			$data = file_get_contents($url);
			if(!$extname) {
				// 获取文件的 MIME 类型
				$finfo = finfo_open(FILEINFO_MIME_TYPE);
				$mimeType = finfo_file($finfo, $url);
				finfo_close($finfo);
				$extname = $mimeMap[$mimeType]??'';
			}
		}
		//小图
		if(!$data && $type=='search' && $options['img'])
		{
			$oribase64 = $options['img'];
			// 去掉base64头部信息
			$base64String = preg_replace('/^data:image\/\w+;base64,/', '', $options['img']);
			$base64String = str_replace(' ', '+', $base64String);
			// 解码base64数据
			$data = base64_decode($base64String);
		}
		
		//后缀不存在就从base64中获取
		if (!$extname && $oribase64 && preg_match('/^data:(\w+\/\w+);base64,/', $oribase64, $matches)) {
			$mimeType = $matches[1];
			$extname = $mimeMap[$mimeType]?$mimeMap[$mimeType] : 'jpg';
		}
		if(!$data) return ['code'=>-1,'ms'=>'获取图片失败'];
		//已存在直接跳过
		$crc32 = strtoupper(dechex(crc32($data)));
		$has = $this->db->get('oe_pic',['[><]files'=>['pic_fileid'=>'fileid']],'*',['file_crc32'=>$crc32,'file_category'=>'poe','pic_oe_id'=>$oe_id,'pic_type'=>'img']);
		if($has){
			$file_exists = \mvc::$cfg['dir']['files'].'/'.$has['filename'];
            if(file_exists($file_exists)){
                return ['fileid'=>$has['fileid']];
            }
		}
		//保存到files里
		$category = 'poe';
		$item = 'img';
		$uploadID =  guid();
		$cfg = \mvc::$cfg['upload']['category'][$category]['items'][$item];

		if($has['fileid'])
		{	
			$dir = $has['filepath'];
			$filebase = $has['filebasename'];
		}
		else
		{
			if(isset($cfg['path'])){
				$dir = call_user_func_array($cfg['path'], [$uploadID,$item,$extname,$params,$filename]);
			}else{
				$dir = call_user_func_array(\mvc::$cfg['upload']['category'][$category]['path'],[$uploadID,$item,$extname,$params,$filename]);
			}
			if(isset($cfg['filebase'])){
				$filebase = call_user_func_array($cfg['filebase'],[$uploadID,$item,$extname,$params,$filename]);
			}else{
				$filebase = call_user_func_array(\mvc::$cfg['upload']['category'][$category]['filebase'], [$uploadID,$item,$extname,$params,$filename]);
			}
		}

		$absdir = \mvc::$cfg['dir']['files'].'/'.$dir;

		mkdirs($absdir);
		if(isset($cfg['tojpeg']) && $cfg['tojpeg'] && $extname!='jpg'){
			$extname = 'jpg';
		}
		file_put_contents($absdir.'/'.$filebase.'.'.$extname, $data);
		$fileType = $cfg['filetype'];
		$remark = str_replace('.'.strtolower($extname),'',strtolower(basename($filename)));
		if($options['text']) $remark = $options['text'];
		$this->db->Begin();

		if(!$has['fileid'])
		{
			$fileData = [
				'filename' => $dir.'/'.$filebase.'.'.$extname,
				'fileextname'=>$extname,
				'fileremark' => $remark,
				'filetype' => $fileType,
				'file_category' => $category,
				'file_item' => $item,
				'file_time' => getNowTime(),
				'file_crc32'=>$crc32,
				'filepath'=>$dir,
				'filebasename'=>$filebase
			];
			$this->db->insert('files',$fileData);
			$fileid = $this->db->id();
		}else{
			$fileid = $has['fileid'];
		}
		
		$files = new files();
		if($fileType=='image'){
			$image = make(\lib\image::class,100);
			if(isset($cfg['tojpeg']) && $cfg['tojpeg'] && $extname!='jpg'){
				$dist = $dir.'/'.$filebase.'.jpg';
				$image->ToJPG($filename,\mvc::$cfg['dir']['files'].'/'.$dist,false);
				$files->updateFilename($dist,$fileid);
				$filename = \mvc::$cfg['dir']['files'].'/'.$dist;
			}
			if(isset($cfg['size'])){
			    //由大到小生成缩略图
			    $arrSize = $cfg['size'];
                uksort($arrSize,function($a,$b)use($arrSize){
                   return $arrSize[$b][0] - $arrSize[$a][0];
                });
			    $sizefilename = $absdir.'/'.$filebase.'.'.$extname;
				$orisizefilename =  $absdir.'/'.$filebase.'.'.$extname;
				foreach($arrSize as $key=>$size){
					if($key=='small'){
						$sizefilename = $orisizefilename;
					}
					$dist = $dir.'/'.$filebase.$key.'.jpg';
					$watermark = \mvc::$cfg['dir']['static'].'/images/watermark/'.$category.'/'.$item.'.png';
					if(file_exists($watermark)){
					    try {
    						$image->ResizeWatermark($sizefilename,\mvc::$cfg['dir']['files'].'/'.$dist,$size[0],$size[1],$watermark);
					    } catch (\Exception $e) {
					        $newid=0;
					    }
					}else{
					    try {
    						$image->Resize($sizefilename,\mvc::$cfg['dir']['files'].'/'.$dist,$size[0],$size[1]);
					    } catch (\Exception $e) {
					        $newid=0;
					    }
						$sizefilename = \mvc::$cfg['dir']['files'].'/'.$dist;
					}
				}
			}
    		if($newid==0){
    		    @unlink($filename);
    		}
		}
		
		if(!$has['pic_fileid'])
		{
			$data = [
				'pic_oe_id'=>$oe_id,
				'pic_fileid'=>$fileid,
				'pic_type'=>$item,
				'pic_filebase'=>$remark,
				'pic_opuser'=>getOpuser(),
				'pic_create_time'=>getNowTime(),
				'pic_update_time'=>getNowTime(),
			];
			if($options['pic_remark']); $data['pic_remark'] = $options['pic_remark'];
			if($options['pic_from']); $data['pic_from'] = $options['pic_from'];
			$this->db->insert('oe_pic',$data);
		}
		$mainpic = $this->db->get('oe_pic', 'pic_fileid', ['pic_oe_id'=>$oe_id, 'pic_type'=>$item, 'pic_ismain'=>1]);
		if(!$mainpic) $this->setOeMainPic($fileid,$oe_id,$item);
		$this->db->End();
		return ['fileid'=>$fileid];
	}

	/**
	 * @param  [type] $param
	 * @method 编辑开发号
	 * @author zhengweihua 
	 * @copyright 2025-01-16
	 */
	public function saveDevelopNo($oe_id,$numArr)
	{
		if(!$oe_id) return [];
		$oldIds = $this->db->select('oe_item_developno','oid_id',['oid_oe_id'=>$oe_id]);

		$this->db->Begin();
		
		foreach ($numArr as $val) {
			unset($val['sup_name']);
			$val['oid_format'] = formatNum($val['oid_number']);
			$val['oid_oe_id'] = $oe_id;
			if(in_array($val['oid_id'],$oldIds)){
				$this->db->update('oe_item_developno',$val,['oid_id'=>$val['oid_id']]);
			}else{
				unset($val['oid_id']);
				$this->db->insert('oe_item_developno',$val);
			}
		}
		$newIds = array_column($numArr,'oid_id');
		$delArr = array_diff($oldIds,$newIds);
		if($delArr){
			$this->db->delete('oe_item_developno',['oid_id'=>$delArr]);
		}
		$this->db->End();
		
		return [];
	}

	public function saveCompetitor($param)
	{	
		$data = [
			'cop_cor_id'=>$param['cop_cor_id'],
			'cop_cop_num'=>$param['cop_cop_num'],
			'cop_price'=>$param['cop_price'],
			'cop_price_time'=>$param['cop_price_time']?:getNowTime(),
			'cop_remark'=>$param['cop_remark'],
			'cop_opuser'=>getOpuser(),
			'cop_update_time'=>getNowTime(),
			'cop_cat_id'=>$param['cop_cat_id'],
		];
		$number = strtr($param['con_number'],['/'=>';','；'=>';',','=>';','，'=>';']);
		if($param['cop_oe_id']){
			$data['cop_cat_id'] = $this->db->get('oe_item','oe_cate_id',['oe_id'=>$param['cop_oe_id']]);
			$data['cop_oe_id'] = $param['cop_oe_id'];
		}else{
			if($number)
			{
				if($data['cop_cat_id'])
				{
					$arr = $this->db->get('oe_item',['[><]oe_numidx'=>['oe_id'=>'on_oe_id']],['oe_id','oe_cate_id'],['oe_cate_id'=>$data['cop_cat_id'],'on_pf_id'=>1,'on_formart'=>formatNums($number)]);
					$data['cop_oe_id'] = $arr['oe_id']??0;
				}else{
					$arr = $this->db->select('oe_item',['[><]oe_numidx'=>['oe_id'=>'on_oe_id']],['oe_id','oe_cate_id'],['on_pf_id'=>1,'on_formart'=>formatNums($number),'GROUP'=>'oe_id']);
					if(count($arr)==1){
						$data['cop_oe_id'] = $arr[0]['oe_id'];
						$data['cop_cat_id'] = $arr[0]['oe_cate_id'];
					}
				}
			}
		}
		
		
		if($param['cop_id']){
			$this->db->update('competitor_price',$data,['cop_id'=>$param['cop_id']]);
			$cop_id = $param['cop_id'];
		}else{
			$data['cop_create_time'] = getNowTime();
			$this->db->insert('competitor_price',$data);
			$cop_id = $this->db->id();
		}
		$oldnum = $this->db->select('cop_numidx','con_formart',['con_cop_id'=>$cop_id]);
		$number = formatNums($number);
		$newArr = [];
		foreach ($number as $k=> $num){
			
			if(in_array($num,$oldnum)){
				$set = [
					'con_ismain'=> $k==0?'Y':'N',
					'con_opuser'=> getOpuser(),
					'con_update_time'=> getNowTime(),
				];
				$this->db->update('cop_numidx',$set,['con_cop_id'=>$cop_id,'con_formart'=>$num]);
			}else{
				$newArr[] = [
					'con_ismain'=> $k==0?'Y':'N',
					'con_pf_id'=>1,
					'con_cop_id'=>$cop_id,
					'con_number'=>$num,
					'con_formart'=>formatNum($num),
					'con_opuser'=> getOpuser(),
					'con_create_time'=> getNowTime(),
					'con_update_time'=> getNowTime(),
				];
			}
		}
		if($newArr){
			$this->db->insert('cop_numidx',$newArr);
		}
		$delArr = array_diff($oldnum,$number);
		if($delArr){
			$this->db->delete('cop_numidx',['con_cop_id'=>$cop_id,'con_formart'=>formatNums(implode(';', $delArr))]);
		}
		return [];
	}

	/**
	 * @method 获取没用绑定零件的竞品价格数据
	 * @author zhengweihua 
	 * @copyright 2025-04-25
	 */
	public function getCopPriceNoOe()
	{
		$where = [
			'OR'=>[
				'cop_oe_id[=]' => 0,
				'cop_oe_id' => null
			],
			'GROUP'=>'cop_id'
		];
		$arr = $this->db->select('competitor_price(cop)',['[><]cop_numidx(con)'=>['cop.cop_id'=>'con_cop_id']],'cop_id',$where);
		return $arr;
	}
	/**
	 * @param  array $copIds
	 * @method 竞品价格自动绑定OE
	 * @author zhengweihua 
	 * @copyright 2025-04-25
	 */
	public function autoBindOeItem($copIds = [])
	{	
		if($copIds)
		{
			if(!is_array($copIds)){
				$copIds = array_filter(explode(',',$copIds));
			}
			$where['con_cop_id']=$copIds;
		}
		$chkjoin = [
			'[><]oe_numidx'=>['oe_id'=>'on_oe_id'],
			'[><]pro_factory'=>['oe_pf_id'=>'pf_id']
		];
		$this->db->Begin();
		$join = [
			'[><]competitor_price(cop)'=>['con_cop_id'=>'cop_id'],
			'[><]pro_factory'=>['con_pf_id'=>'pf_id']
		];
		$rows = $this->db->select('cop_numidx',$join,['con_cop_id','con_pf_id','con_formart','con_number','pf_name','cop_cat_id'],$where);
		$arr = [];
		foreach ($rows as $val) {
			$arr[$val['con_cop_id']][] = $val;
		}	
		$data = [];
		foreach ($arr as $cop_id=> $cval) 
		{			
			foreach ($cval as $val) 
			{
				$cur = $val['pf_name'].':'.$val['con_number'];
				$snums = $val['con_pf_id'] == 1? reSearchNum($val['con_formart']): $val['con_formart'];
				//加上小类去匹配
				$swhere = ['on_pf_id'=>$val['con_pf_id'],'on_formart'=>$snums,'GROUP'=>'oe_id'];
				if($val['cop_cat_id']){
					$swhere['oe_cate_id']=$val['cop_cat_id'];
				}
				$chkoe = $this->db->select('oe_item',$chkjoin,['oe_id','oe_oe','pf_name','oe_cate_id'],$swhere);
				// $cntOe = array_unique(array_column($chkoe,'oe_id'));
				if(count($chkoe)==1)
				{
					$chkoe =$chkoe[0];
					$this->db->update('competitor_price',['cop_oe_id'=>$chkoe['oe_id'],'cop_cat_id'=>$chkoe['oe_cate_id']],['cop_id'=>$cop_id]);
					//OE：LR1133051 关联到零件 OE:008 420 06 20
					$data[] = '<p>'.$cur.' 关联到零件 <a href="javascript:qg.page.open(\''.$chkoe['oe_oe'].'\',\''.HOST.'/oe/detail?oe_id='.$chkoe['oe_id'].'\')" title="查看详情">'.$chkoe['pf_name'].':'.$chkoe['oe_oe'].'</a></p>';
					break;
				}
			}
		}
		$this->db->End();

		return $data;
	}

	/**
	 * @param  array $params
	 * @param  array  $rules
	 * @method 获取OE关联列表
	 * @author zhengweihua 
	 * @copyright 2025-01-18
	 */
	public function getListOELink($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'];

		$table = 'oe_link(ol)';
		$join = [
			"[><]oe_item(oe1)" => ["ol.ol_oe_id1" => "oe_id"],
			"[>]oe_item(oe2)" => ["ol.ol_oe_id2" => "oe_id"],
			"[>]pro_factory(fac1)" => ["ol.ol_pf_id1" => "pf_id"],
			"[>]pro_factory(fac2)" => ["ol.ol_pf_id2" => "pf_id"],
			"[>]adm_user(au)" => ["ol.ol_opuser" => "au_id"],
			
		];
		$refiled = [
			'pf_name1'=>'fac1.pf_name',
			'pf_name2'=>'fac2.pf_name',
			'ol_oe_id1'=>'oe1.oe_oe',
			'ol_oe_id2'=>'oe2.oe_oe',
			'oe_name1'=>'oe1.oe_'.LG_NAME,
			'oe_name2'=>'oe2.oe_'.LG_NAME,
		];
		$this->set('refiled',$refiled);

		$sidx =  strtr($sidx,$refiled);
		
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr($field, $this->get('refiled'));
			if($field=='rel_oe_id'){
				$op = 'RAW_'.$field;
				$data = raw(sprintf("oe1.oe_oe like '%%%s%%' or oe2.oe_oe like '%%%s%%'",$data,$data));
			}
			if($field=='rel_pf_name'){
				$op = 'RAW_'.$field;
				$data = raw(sprintf("fac1.pf_name = '%s' or fac2.pf_name = '%s'",$data,$data));
			}
			if($field=='rel_number'){
				$op = 'RAW_'.$field;
				$data = raw(sprintf("ol.ol_format1 like '%s%%' or ol.ol_format2 like '%s%%'",formatNum($data),formatNum($data)));
			}
        });

		foreach($rules as $filed=>$val){
			if(empty($val)) continue;
			switch($filed){
				case 'numbers':
					if(!isset($join['[>]oe_numidx(on1)'])){
						$join['[>]oe_numidx(on1)'] = ['ol.ol_oe_id1'=>'on_oe_id'];
						$where['GROUP'] = 'ol.ol_oe_id1';
					}
					if(!isset($join['[>]oe_numidx(on2)'])){
						$join['[>]oe_numidx(on2)'] = ['ol.ol_oe_id2'=>'on_oe_id'];
						$where['GROUP'] = 'ol.ol_oe_id2';
					}
	
					$where['OR'] = [
							
						"ol_format1".($rules['numlike']? '[~]': '') => formatNums(implode(',',$val)),

						"ol_format2".($rules['numlike']? '[~]': '') => formatNums(implode(',',$val)),		

						"on1.on_formart".($rules['numlike']? '[~]': '') => formatNums(implode(',',$val)),

						"on2.on_formart".($rules['numlike']? '[~]': '') => formatNums(implode(',',$val)),		
					];
	
					unset($rules['numlike']);
					unset($rules['numbers']);
					unset($rules['numberFormats']);
					
				break;
			}
		}

		if(!empty($params['oe_id'])) {
			$where['OR']['ol_oe_id1'] = $params['oe_id'];
			$where['OR']['ol_oe_id2'] = $params['oe_id'];
		}
		
		if(!empty($params['type'])) $where['ol_type'] = $params['type'];
		
        $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 = ['ol.*','oe1.oe_id(oe_id1)','oe1.oe_'.LG_NAME.'(oe_name1)','oe2.oe_id(oe_id2)','oe2.oe_'.LG_NAME.'(oe_name2)','fac1.pf_name(pf_name1)','fac2.pf_name(pf_name2)','au_name'];
        $arr = $this->db->select($table,$join,$fields,$where);
		if($arr){
			$collocation = new collocation();
			$oeidArr = array_filter(array_unique(array_merge(array_column($arr,'ol_oe_id1'),array_column($arr,'ol_oe_id2'))));
			$join = [
				'[><]pro_factory'=>['oe_pf_id'=>'pf_id'],
				"[><]pro_cate(cat)" => ["oe_cate_id" => "id"],
			];
			$oeArr = $this->db->select('oe_item',$join,['oe_id','oe_'.LG_NAME.'(oe_name)',LG_NAME.'(cate_name)','oe_oe','pf_name'],['oe_id'=>$oeidArr]);
			$oeArr = array_column($oeArr,null,'oe_id');
			//获取主图
			$picArr = [];
			$join = ["[><]files"=>["pic_fileid"=>'fileid']];
			$picrows = $this->db->select('oe_pic',$join,'*',['pic_oe_id'=>$oeidArr,'pic_type'=>'img','pic_ismain'=>1]);
			foreach ($picrows as  $pic) {
				if($pic['pic_type']=='img' && $pic['filetype']=='image'){
					$pic['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
					$pic['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
				}
				$picArr[$pic['pic_oe_id']] = $pic;
			}
			foreach ($arr as $k => &$v) {

				$v['main_pic1'] = $picArr[$v['ol_oe_id1']]??[];
				$v['main_pic2'] = $picArr[$v['ol_oe_id2']]??[];
				$v['ol_number1'] = $v['ol_oe_id1']?$oeArr[$v['ol_oe_id1']]['oe_oe']:$v['ol_number1'];
				$v['pf_name1'] = $v['ol_oe_id1']?$oeArr[$v['ol_oe_id1']]['pf_name']:$v['pf_name1'];
				$v['ol_number2'] = $v['ol_oe_id2']?$oeArr[$v['ol_oe_id2']]['oe_oe']:$v['ol_number2'];
				$v['pf_name2'] = $v['ol_oe_id2']?$oeArr[$v['ol_oe_id2']]['pf_name']:$v['pf_name2'];
				//如果请求存在oe_id,则只显示关联的数据
				if($params['oe_id']){
					$v['rel_oe_id'] = '';
					$v['rel_pf_name'] = '';
					$v['rel_number'] = '';

					if($v['ol_oe_id1']==$params['oe_id']){
						$v['rel_oe_id'] = $v['ol_oe_id2'];
						$v['rel_pf_name'] = $v['pf_name2'];
						$v['rel_number'] = $v['ol_number2'];
						$v['rel_mainpic'] = $v['main_pic2'];
						$v['rel_oe_oe'] = $oeArr[$v['ol_oe_id2']]['oe_oe'];
						$v['rel_oe_name'] = $oeArr[$v['ol_oe_id2']]['oe_name'];
						$v['rel_cate_name'] = $oeArr[$v['ol_oe_id2']]['cate_name'];
					}else if($v['ol_oe_id2']==$params['oe_id']){
						$v['rel_oe_id'] = $v['ol_oe_id1'];
						$v['rel_pf_name'] =$v['pf_name1'];
						$v['rel_number'] = $v['ol_number1'];
						$v['rel_mainpic'] = $v['main_pic1'];
						$v['rel_oe_oe'] = $oeArr[$v['ol_oe_id1']]['oe_oe'];
						$v['rel_oe_name'] = $oeArr[$v['ol_oe_id1']]['oe_name'];
						$v['rel_cate_name'] = $oeArr[$v['ol_oe_id1']]['cate_name'];
					}
				}
				if(isset($params['onlyExits']) && !empty($params['onlyExits']) && !$v['rel_oe_id']){
					unset($arr[$k]);
				}

				$v['captions']['ol_from'] = $collocation->getRowByKey($v['ol_from'])[cateName()];
				$v['captions']['ol_opuser'] = $v['au_name'];
			}
			unset($v);
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	/**
	 * @param  [type] $param
	 * @method 删除数据
	 * @author zhengweihua 
	 * @copyright 2025-02-12
	 */
	public function delOeLink($param)
	{	
		if($param['ids'] && $param['type']){
			$ids = explode(',',$param['ids']);
			$this->db->delete('oe_link',['ol_id'=>$ids,'ol_type'=>$param['type']]);
		}
		return [];
	}

	/**
	 * @param  Array $param
	 * @method 设置零件图为主图
	 * @author zhengweihua 
	 * @copyright 2025-01-20
	 */
	public function setImgToMain($param)
	{
		if(!$param['oe_id']||!$param['imgs']) return exitJson(-1,'参数错误');
		$oeId = $this->db->get('oe_item', 'oe_id',['oe_id'=>$param['oe_id']]);
		if(!$oeId) return exitJson(-1,'零件不存在');

		$imgs = json_decode(base64_decode($param['imgs']),true);
		$this->db->Begin();
		$res = $this->downloadAndSaveImage($oeId,$imgs['big'],'search',$imgs);
		if($res['code']==-1){
			return exitJson(-1,$res['msg']);
		}
		if($res['fileid']){
			$this->setOeMainPic($res['fileid'],$param['oe_id'],'img');
		}
		$this->db->End();
		return  [];
	}

	/**
	 * @param  [type] $data
	 * @method 获取需要绑定的OE零件
	 * @method getAutoBindOe
	 * @author zhengweihua 
	 * @copyright 2025-04-23
	 */
	public function getAutoBindOe($data)
	{
		if($data['oe_id']){
			$sql = sprintf("SELECT `ol`.`ol_id` FROM `oe_link` AS `ol` 
			WHERE  ol_oe_id1 =%d  AND (`ol_oe_id2` = 0 OR `ol_oe_id2` IS NULL) AND `ol_type` = 'link'",$data['oe_id']);
		}else{
			$sql = "SELECT `ol`.`ol_id` FROM `oe_link` AS `ol` 
			WHERE (`ol_oe_id2` = 0 OR `ol_oe_id2` IS NULL OR `ol_oe_id1` = 0 OR `ol_oe_id1` IS NULL) AND `ol_type` = 'link'";
		}
		$rows = $this->db->query($sql)->fetchAll();
		return $rows;
	}

	/**
	 * @method oelink自动绑定零件
	 * @author zhengweihua 
	 * @copyright 2025-01-21
	 */
	public function oeLinkAutoBind($param)
	{	
		$ids = $param['ids']?implode(',',array_column($param['ids'],'ol_id')):[];
		if(!$ids) return [];
		$sql = sprintf("SELECT 
		`ol`.`ol_id`,`ol`.`ol_oe_id1`,`ol`.`ol_pf_id1`,`ol`.`ol_number1`,`ol`.`ol_format1`,`ol`.`ol_oe_id2`,`ol`.`ol_pf_id2`,`ol`.`ol_number2`,`ol`.`ol_format2`,`oe1`.`oe_id` AS `oe_id1`,`oe2`.`oe_id` AS `oe_id2`,`fac1`.`pf_name` AS `pf_name1`,`fac2`.`pf_name` AS `pf_name2` 
		FROM `oe_link` AS `ol` 
		LEFT JOIN `oe_item` AS `oe1` ON `ol`.`ol_oe_id1` = `oe1`.`oe_id` 
		LEFT JOIN `oe_item` AS `oe2` ON `ol`.`ol_oe_id2` = `oe2`.`oe_id` 
		LEFT JOIN `pro_factory` AS `fac1` ON `ol`.`ol_pf_id1` = `fac1`.`pf_id` 
		LEFT JOIN `pro_factory` AS `fac2` ON `ol`.`ol_pf_id2` = `fac2`.`pf_id` 
		WHERE ol_id IN (%s)",$ids);	
		$rows = $this->db->query($sql)->fetchAll();
		$chkjoin = [
			'[><]oe_numidx'=>['oe_id'=>'on_oe_id'],
			'[><]pro_factory'=>['oe_pf_id'=>'pf_id']
		];
		
		$this->db->Begin();

		$data = [];
		foreach ($rows as $val) 
		{	
			if(!$val['ol_oe_id1'])
			{
				$cur = $val['pf_name1'].':'.$val['ol_number1'];
				$snums = $val['ol_pf_id1'] == 1? reSearchNum($val['ol_format1']): $val['ol_format1'];
				$chkoe1 = $this->db->get('oe_item',$chkjoin,['oe_id','oe_oe','pf_name'],['on_pf_id'=>$val['ol_pf_id1'],'on_formart'=>$snums]);
				if($chkoe1){
					$data[] = '<div>'.$cur.' 关联到零件 <a href="javascript:qg.page.open(\''.$chkoe1['oe_oe'].'\',\''.HOST.'/oe/detail?oe_id='.$chkoe1['oe_id'].'\')" title="查看详情">'.$chkoe1['pf_name'].':'.$chkoe1['oe_oe'].'</a></div>';
					$this->db->update('oe_link',['ol_oe_id1'=>$chkoe1['oe_id']],['ol_id'=>$val['ol_id']]);
				}
			}

			if(!$val['ol_oe_id2'])
			{
				$cur = $val['pf_name2'].':'.$val['ol_number2'];
				$snums = $val['ol_pf_id2'] == 1? reSearchNum($val['ol_format2']): $val['ol_format2'];
				$chkoe2 = $this->db->get('oe_item',$chkjoin,['oe_id','oe_oe','pf_name'],['on_pf_id'=>$val['ol_pf_id2'],'on_formart'=>$snums]);
				if($chkoe2){
					$data[] = '<div>'.$cur.' 关联到零件 <a href="javascript:qg.page.open(\''.$chkoe2['oe_oe'].'\',\''.HOST.'/oe/detail?oe_id='.$chkoe2['oe_id'].'\')" title="查看详情">'.$chkoe2['pf_name'].':'.$chkoe2['oe_oe'].'</a></div>';
					$this->db->update('oe_link',['ol_oe_id2'=>$chkoe2['oe_id']],['ol_id'=>$val['ol_id']]);
				}
			}
			
		}
		$this->db->End();

		return $data;
	}

	/**
	 * @param  array $ids
	 * @method 智能配对
	 * @author zhengweihua 
	 * @copyright 2025-01-22
	 */
	public function oeLinkAutoPair($ids)
	{	
		$data = [];
		foreach ($ids as  $rows2) {
			$oeid1 = $rows2['oe_id1'];
			$oeid2 = $rows2['oe_id2'];
			if ($oeid1 == $oeid2) return [];
			$pairExist = $this->db->get('oe_link', 'ol_id', ['ol_oe_id1' => $oeid1, 'ol_oe_id2' => $oeid2,'ol_type'=>'pair']);
			if ($pairExist) return [];
		
			$oe1info = $this->db->get('oe_item',['[><]pro_factory'=>['oe_pf_id'=>'pf_id']],['oe_id','pf_name','oe_oe'],['oe_id'=>$oeid1]);
			$oe2info = $this->db->get('oe_item',['[><]pro_factory'=>['oe_pf_id'=>'pf_id']],['oe_id','pf_name','oe_oe'],['oe_id'=>$oeid2]);	
			$this->db->insert('oe_link', [
				'ol_type' => 'pair',
				'ol_oe_id1' => $oeid1,
				'ol_oe_id2' => $oeid2,
				'ol_opuser' => getOpuser(),
				'ol_create_time' => getNowTime(),
				'ol_update_time' => getNowTime(),
			]);

			$data[] = '<div><a href="javascript:qg.page.open(\''.$oe1info['oe_oe'].'\',\''.HOST.'/oe/detail?oe_id='.$oe1info['oe_id'].'\')" title="查看详情">'.$oe1info['pf_name'].':'.$oe1info['oe_oe'].'</a> 配对到零件 <a href="javascript:qg.page.open(\''.$oe2info['oe_oe'].'\',\''.HOST.'/oe/detail?oe_id='.$oe2info['oe_id'].'\')" title="查看详情">'.$oe2info['pf_name'].':'.$oe2info['oe_oe'].'</a></div>';
			
		}
		
		return $data;
	}

	/**
	 * @method 获取可配对的零件号码
	 * @author zhengweihua 
	 * @copyright 2025-02-07
	 */
	public function getAutoOeIds()
	{
		//查询找出未配对的记录
		$sql = 'SELECT DISTINCT
			oe1.on_oe_id AS oe_id1,
			oe2.on_oe_id AS oe_id2
		FROM
			link_pair as lp
		LEFT JOIN pro_factory as pf1 ON lp.lp_factory1 = pf1.pf_name
		LEFT JOIN oe_numidx as oe1 ON pf1.pf_id = oe1.on_pf_id AND lp.lp_format1 = oe1.on_formart
		LEFT JOIN pro_factory as pf2 ON lp.lp_factory2 = pf2.pf_name
		LEFT JOIN oe_numidx as oe2 ON pf2.pf_id = oe2.on_pf_id AND lp.lp_format2 = oe2.on_formart
		WHERE oe1.on_oe_id IS NOT NULL AND oe2.on_oe_id IS NOT NULL AND oe1.on_oe_id != oe2.on_oe_id	
		AND NOT EXISTS (
			SELECT 1 FROM oe_link AS ol WHERE ol.ol_oe_id1 = oe1.on_oe_id AND ol.ol_oe_id2 = oe2.on_oe_id AND ol.ol_type = \'pair\'
    	)';
		$unpairedRecords = $this->db->query($sql)->fetchAll();
		
		return $unpairedRecords;
	}

	/**
	 * @param  [type] $oe_id
	 * @param  array  $type
	 * @method 获取某oeid的关联关系
	 * @author zhengweihua 
	 * @copyright 2025-08-26
	 */
	public function getOePairList($oe_id,$type=['father','son','pair'])
	{
		$join = [
			'[><]oe_item'=>['ol_oe_id2'=>'oe_id'],
			'[><]pro_factory'=>['oe_item.oe_pf_id'=>'pf_id']
		];
		$rows = $this->db->select('oe_link',$join,['ol_type','ol_id','ol_oe_id2','ol_pf_id2','ol_number2','oe_'.LG_NAME.'(oe_name)','ol_format2','pf_name','oe_oe','oe_oe_format','oe_pf_id'],['ol_type'=>$type, 'ol_oe_id1'=>$oe_id]);
	
		if($rows){
			$oeIds = array_column($rows,'ol_oe_id2');
			$picRes = $this->db->select('oe_pic',['[><]files'=>['pic_fileid'=>'fileid']],'*',['pic_oe_id'=>$oeIds,'pic_type'=>'img','pic_ismain'=>1]);
			$picArr = [];
			foreach ($picRes as $pic) {
				if($pic['pic_type']=='img' && $pic['filetype']=='image'){
					$picArr[$pic['pic_oe_id']]['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
					$picArr[$pic['pic_oe_id']]['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
				}
			}
			$arr = [];
			foreach ($rows as $key => &$val) {
				
				$val['bigImg'] = $picArr[$val['ol_oe_id2']]['bigImg']??'';
				$val['smallImg'] = $picArr[$val['ol_oe_id2']]['smallImg']??'';
				$val['ol_pf_id2'] = $val['oe_pf_id'];
				$val['ol_number2'] = $val['oe_oe'];
				$val['ol_format2'] = $val['oe_oe_format'];
				unset($val['oe_pf_id'],$val['oe_oe'],$val['oe_oe_format']);

				$arr[$val['ol_type']][] = $val;
			}
			unset($val);
		}
		return [$arr['pair'],$arr['father'],$arr['son']];
	}

	//智能匹配零件或者商品的中国车型 $type=poe|pro
	public function autoMatchCnModel($type, $id)
	{
		$arr = [];
		$has = [];
		if($type == 'poe'){
			$nums = $this->db->select('oe_numidx', 'on_formart', ['on_pf_id'=>1, 'on_oe_id'=>$id]);
			$has = $this->db->select('oe_model_cn_link', 'oml_mod3_id', ['oml_oe_id'=>$id]);
		}else if($type == 'pro'){
			$nums = $this->db->select('pro_numidx', 'pn_formart', ['pn_pf_id'=>1, 'pn_p_id'=>$id]);
			$has = $this->db->select('pro_model_cn_link', 'pml_mod3_id', ['pml_p_id'=>$id]);
		}
		if($nums){
			if(!is_array($has)) $has = [];
			$ypApi = new ypApi();
			$res = $ypApi->Get('number/getModelByNumber', ['number'=>implode(',', $nums)]);
			if(!empty($res['data'])){
				$carmodelcn = new carmodelcn();
				$res = $carmodelcn->getModelList(['keys'=>$res['data']]);
				foreach($res['rows'] as $row){
					$row['checked'] = in_array($row['mod3_id'], $has);
					$arr[] = $row;
				}
			}
		}
		return $arr;
	}

	public function saveAddCnModel($type, $id, $modids)
	{
		$opuser = getOpuser();
		$datetime = getNowTime();
		$check = new check();
		$this->db->Begin();
		if($type == 'poe'){
			foreach($modids as $mod3_id){
				$add = [
					'oml_oe_id'=>$id,
					'oml_mod3_id'=>$mod3_id,
					'oml_opuser'=>$opuser,
					'oml_from'=>100,
					'oml_create_time'=>$datetime,
					'oml_update_time'=>$datetime,
				];
				$exists = $check->checkExist('oe_model_cn_link', $add);
				if(empty($exists)) $this->db->insert('oe_model_cn_link', $add);	
			}
			$this->initTagBrand([$id]);
		}else if($type == 'pro'){
			foreach($modids as $mod3_id){
				$add = [
					'pml_p_id'=>$id,
					'pml_mod3_id'=>$mod3_id,
					'opuser'=>$opuser,
					'pml_from'=>100,
					'create_time'=>$datetime,
					'update_time'=>$datetime,
				];
				$exists = $check->checkExist('pro_model_cn_link', $add);
				if(empty($exists)) $this->db->insert('pro_model_cn_link', $add);	
			}
			$pro = new pro();
			$pro->initTagBrand([$id]);
		}
		$this->db->End();
		return [];
	}

	public function getOeItemInfo($param)
	{
		$join = [
			'[><]oe_item(oe)'=>['on.on_oe_id'=>'oe_id'],
		];
		$where = [
			'on.on_pf_id'=>$param['pf_id'],
			'on.on_formart'=>formatNum($param['number']),
			'GROUP'=>'oe_id'
		];
		$item = $this->db->get('oe_numidx(on)',$join,['oe_id','oe.oe_'.LG_NAME.'(oe_name)'],$where);
		if($item){
			$item['bigImg'] ='';
			$item['smallImg'] = '';
			$picRes = $this->db->get('oe_pic',['[><]files'=>['pic_fileid'=>'fileid']],'*',['pic_oe_id'=>$item['oe_id'],'pic_type'=>'img','pic_ismain'=>1]);
			if($picRes){
				$item['bigImg'] = $picRes['filepath'].'/'.$picRes['filebasename'].'big.'.$picRes['fileextname'];
				$item['smallImg'] = $picRes['filepath'].'/'.$picRes['filebasename'].'small.'.$picRes['fileextname'];
			}
			return $item;
		}
		return [];
	}

	public function setEpcNumLink($oe_id,$numArr = [])
	{	
		$arr = $this->getListOELink(['oe_id'=>$oe_id,'type'=>'link','ol_from'=>1070]);
		$linkarr = [];
		$linkKeyVal =[];
		if($arr['rows']){
			foreach ($arr['rows'] as $val) {
				$format = formatNum($val['rel_number']);
				$linkKeyVal[$format] = $val['ol_id'];
				$linkarr[] = $format;
			}
		}
		$numArr = array_unique($numArr);
		//格式化后的
		$arr1 = [];
		foreach ($numArr as $val) {
			$arr1[$val] = formatNum($val);
		}
		$add = array_diff($arr1,$linkarr);
		if($add){
			foreach ($add as $key=> $val) {
				$item = [
					'ol_oe_id1'=>$oe_id,
					'ol_pf_id2'=>1,
					'ol_number2'=>$key,
					'ol_format2'=>$val,
					'ol_type'=>'link',
					'ol_from'=>1070,
					'ol_opuser'=>getOpuser(),
					'ol_create_time'=>getNowTime(),
					'ol_update_time'=>getNowTime()
				];
				$this->db->insert('oe_link',$item);
			}
		}

		$del = array_diff($linkarr,$arr1);
		if($del){
			foreach ($del as $val) {
				$ol_ids[] = $linkKeyVal[$val];
			}
			$this->db->delete('oe_link',['ol_id'=>$ol_ids]);
		}
		return [];
	}

	/**
	 * @method 获取用户数据权限下可查看的用户
	 * @author zhengweihua 
	 * @copyright 2025-02-24
	 */
	public function getPowerViewUser()
	{	
		$search_user = [];
		$viewall = \p::getIds('A300','prl_view_all');
		if(!\p::isAdmin() && !$viewall){
			//部门
			$viewdepa = \p::getIds('A300','prl_view_depa');
			if($viewdepa){
				$au_depa = $this->db->get('adm_user','au_depa',['au_id'=>getOpuser()]);
				if($au_depa){
					$depa_user  = $this->db->select('adm_user','au_id',['au_depa'=>$au_depa]);
					$search_user = array_merge($search_user,$depa_user);
				}
			}
			//自身
			$viewself = \p::getIds('A300','prl_view_self');
			if($viewself){
				$search_user[] = getOpuser();
			}
			//特定用户
			$users = \p::getIds('A300','prl_users');
			if($users){
				$search_user = array_merge($search_user,explode(',',$users));
			}
		}
		return array_unique($search_user);
	}

	/**
	 * @param  [type] $idArr
	 * @param  [type] $cate_id
	 * @method 修改竞争对手价格的分类
	 * @author zhengweihua 
	 * @copyright 2025-04-25
	 */
	public function setCopPriceCate($idArr,$cate_id)
	{
		if(empty($idArr) || !is_array($idArr)) return [];

		$arr = $this->db->select('competitor_price','cop_id',['cop_id'=>$idArr,'cop_cat_id'=>0]);
		if($arr){
			$this->db->update('competitor_price', ['cop_cat_id'=>$cate_id], ['cop_id'=>$arr]);
		}
		return [];
	}

	
	/**
	 * @method 从车型中提取文本
	 */
	public function getPoeModelTxt($oe_id)
	{
		$arr = [];
		$carmodel = new carmodel();
		$mm_ids = $this->db->select('oe_model_link', 'oml_mm_id', ['oml_oe_id'=>$oe_id]);
		$mod3_ids = $this->db->select('oe_model_cn_link', 'oml_mod3_id', ['oml_oe_id'=>$oe_id]);
		$vals = $carmodel->formatValsFromModel($mm_ids, $mod3_ids);
		if($vals['chassis']) $arr['oe_chassis'] = $vals['chassis'];
		if($vals['cc']) $arr['oe_cc'] = $vals['cc'];
		if($vals['engine']) $arr['oe_engine'] = $vals['engine'];
		if($vals['model_year']) $arr['oe_model_year'] = $vals['model_year'];
		if($vals['minname']){
			foreach(\mvc::$cfg['LANGS'] as $lk=>$lv){
				$arr['oe_model_'.$lv['field']] = $vals['minname'];
			}
		}
		return $arr;
	}

	/**
	 * @param  int $oe_id
	 * @param  Array $dataArr
	 * @param  string $type
	 * @method 根据type类型保存oe_link关系
	 * @author zhengweihua 
	 * @copyright 2025-08-26
	 */
	public function saveOeLinkData($oe_id,$dataArr,$type = 'pair')
	{	
		// 获取当前OE已有的配对关系
		$oldArr = $this->db->select('oe_link',['ol_id','ol_oe_id2'],['ol_oe_id1'=>$oe_id,'ol_type'=>$type]);
		$oldIds = array_column($oldArr,'ol_id');
		$olOeIds = array_column($oldArr,null,'ol_id');
		//获取当前类型的反向类型
		$reverseType = $this->getReverseLinkType($type);
		// 记录已处理的配对，避免重复处理
		$processedPairs = [];
		foreach ($dataArr as $val) 
		{
			$temppfname = $val['pf_name'];
			unset($val['pf_name'],$val['oe_name'],$val['bigImg'],$val['smallImg']);
			$val['ol_type'] = $type;
			$val['ol_format2'] = formatNum($val['ol_number2']);
			//查找是否存在零件
			$val['ol_oe_id2'] = $this->db->get('oe_item',['[><]oe_numidx'=>['oe_id'=>'on_oe_id']],'oe_id',['on_pf_id'=>$val['ol_pf_id2'],'on_formart'=>$val['ol_format2']]);
			if(!$val['ol_oe_id2']){
				return exitJson(-1,"【{$temppfname}{$val['ol_number2']}】配对零件不存在");
			}
			$val['ol_opuser'] = getOpuser();
			$val['ol_update_time'] = getNowTime();

			// 构建配对键，用于避免重复处理
			$pairKey = $oe_id < $val['ol_oe_id2'] 
				? $oe_id . '_' . $val['ol_oe_id2'] 
				: $val['ol_oe_id2'] . '_' . $oe_id;
				
			if (in_array($pairKey, $processedPairs)) {
				continue; // 已处理过这个配对关系
			}
			$processedPairs[] = $pairKey;

			if(in_array($val['ol_id'],$oldIds))
			{	
				// 更新现有记录
				if($olOeIds[$val['ol_id']]['ol_oe_id2']!=$val['ol_oe_id2'])
				{
					$this->db->update('oe_link',$val,['ol_id'=>$val['ol_id']]);
					// 删除反向的旧配对关系
					$this->db->delete('oe_link',['ol_oe_id1'=>$val['ol_oe_id2'],'ol_oe_id2'=>$oe_id,'ol_type'=>$reverseType]);
				}
				
			}
			else
			{
				// 插入新记录
				unset($val['ol_id']);
				$val['ol_oe_id1'] = $oe_id;
				$val['ol_create_time'] = getNowTime();
				$this->db->insert('oe_link',$val);
			}
			// 确保双向配对关系存在
			$exist = $this->db->get('oe_link','ol_id',['ol_oe_id1'=>$val['ol_oe_id2'],'ol_oe_id2'=>$oe_id,'ol_type'=>$reverseType]);
			if(!$exist){
				// 创建反向配对关系
				$reverseLink = [
					'ol_type' => $reverseType,
					'ol_oe_id1' => $val['ol_oe_id2'],
					'ol_oe_id2' => $oe_id,
					'ol_pf_id1' => $val['ol_pf_id2'],
					'ol_number1' => $val['ol_number2'],
					'ol_format1' => $val['ol_format2'],
					'ol_opuser' => getOpuser(),
					'ol_create_time' => getNowTime(),
					'ol_update_time' => getNowTime()
				];
				$this->db->insert('oe_link', $reverseLink);
			}
		}
		 // 删除不再需要的配对关系
		$newIds = array_column($dataArr,'ol_id');
		$delArr = array_diff($oldIds,$newIds);
		if($delArr)
		{	
			// 删除对应的反向配对关系
			$temp = $this->db->select('oe_link',['ol_oe_id1','ol_oe_id2'],['ol_id'=>$delArr]);
			
			foreach ($temp as $tval) {
				$this->db->delete('oe_link',['ol_oe_id1'=>$tval['ol_oe_id2'],'ol_oe_id2'=>$tval['ol_oe_id1'],'ol_type'=>$reverseType]);
			}
			// 删除正向配对关系
			$this->db->delete('oe_link',['ol_id'=>$delArr]);
		}
	}

	/**
	 * 获取链接类型的反向类型
	 * @param string $type 当前类型
	 * @return string 反向类型
	 * @author zhengweihua 
	 * @copyright 2025-08-26
	 */
	private function getReverseLinkType($type)
	{
		switch ($type) {
			case 'father':
				return 'son';
			case 'son':
				return 'father';
			default: // pair类型保持不变
				return $type;
		}
	}

	/**
     * @param  int $oe_id
     * @method 检查零件是否符合零件库唯一性
     * @author hongzhang
     * @copyright 2025-08-26
     */
	public function checkOeUnique($oe_id)
	{
		// 检查是否存在相同on_formart和oe_cate_id的重复组合
		$sql = sprintf("
			SELECT GROUP_CONCAT(DISTINCT on_number) nums
			FROM oe_numidx n1 
			INNER JOIN oe_item i1 ON n1.on_oe_id = i1.oe_id 
			WHERE n1.on_oe_id = %d AND n1.on_pf_id = 1
			AND EXISTS (
				SELECT 1 
				FROM oe_numidx n2 
				INNER JOIN oe_item i2 ON n2.on_oe_id = i2.oe_id 
				WHERE n2.on_formart = n1.on_formart AND n1.on_pf_id = 1 AND n2.on_pf_id = 1
				AND i2.oe_cate_id = i1.oe_cate_id 
				AND n2.on_id <> n1.on_id
			)
			GROUP BY on_formart
		", $oe_id);
		
		return $this->db->query($sql)->fetchAll();
		// 如果查询结果为空，说明没有重复，返回true（唯一）
	}

	/**
	 * @param  [type] $filePath
	 * @method 获取图片的扩展名
	 * @author zhengweihua 
	 * @copyright 2025-10-27
	 */
	protected function getExtensionFromMime($filePath) 
	{
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		$mimeType = finfo_file($finfo, $filePath);
		finfo_close($finfo);
		
		$mimeMap = [
			'image/jpeg' => 'jpg',
			'image/png' => 'png',
			'image/gif' => 'gif',
			'image/bmp' => 'bmp',
			'image/webp' => 'webp',
			'image/x-ms-bmp' => 'bmp'
		];
		
		return $mimeMap[$mimeType] ?? 'jpg';
	}
}