<?php

namespace admin\action;

use model\alioss;
use model\aiImage;
use model\element;
use model\import\uploadProPicZip;
use model\oe;
use model\pro\packing;
use \model\pro\pro;
use \model\pro\photo;
use \model\pro\master;
use model\pro\picTpl;
use model\pro\param;
use model\pro\synProPic;
use model\rcaApi;
use model\ypApi;
use model\ypRcaApi;


class proAction  extends \action
{
	public $pro = null;

	public function __construct()
	{
		$this->pro = new pro();
	}


	function getSetstate()
	{
		foreach (\mvc::$cfg['PROSTATUS'] as $k => $v) {
			$data[] = ['key' => $k, 'value' => $v];
		}
		$this->successJson($data);
	}


	function total()
	{
		$this->successJson($this->pro->total());
	}

	function totalCommon($states)
	{
		$this->successJson($this->pro->totalCommon($states));
	}

	public function listView()
	{
		// dd('开发中');
		$req = \mvc::$req;
		if (!isset($req['from']))  $req['from'] = 'pro';
		$carmodel = new \model\carmodel();
		$pack = new \model\pro\packing();
		\view::set('proExpModelfields', $carmodel->proExpModelfields);
		\view::set('packFileds', []);
		\view::set('from', $req['from']);
		\view::put('pro/list');
	}

	public function list()
	{
		$req = \mvc::$req;
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		if (isset($req['keys'])) {
			$rules['keys'] = explode(',', $req['keys']);
		}
		if (isset($rules['findNulls']) && $rules['findNulls']) {
			$rules['findNulls'] = json_decode(base64_decode($rules['findNulls']), true);
		}
		if (isset($req['coutype'])) $rules['coutype'] = $req['coutype'];
		$data = $this->pro->list($rules, $req['filters'], $req['page'], $req['rows'], $req['sidx'], $req['sord'], 'p_comnum');
		$this->successJson($data);
	}

	//
	public function exportMQ()
	{
		error_reporting(E_ALL & ~E_NOTICE);
		set_time_limit(0);
		$mq = makeOne(\lib\mqRabbitMQ::class, 'exportMQ', \mvc::$cfg['exportMQ']);
		echo "exportMQ runing.\r\n";
		$mq->receive(function ($talk, $queue) {
			sleep(1);
			$data = json_decode($talk->getBody(), true);
			$export = new \model\pro\export2();
			try {
				$queue->ack($talk->getDeliveryTag());
				if ($export->export($data['msgId'], $data['count'], $data['filename'], $data['username'], $data['lgtag'], $data['type'], $data['options'], $data['rules'], $data['sql'], $data['pagesize'])) {
					//$queue->ack($talk->getDeliveryTag());
				}
			} catch (\Exception $e) {
				makeOne(\model\message::class)->update($data['msgId'], ['amsg_body' => lg('失败') . ': ' . $e->getMessage()]);
				//$queue->ack($talk->getDeliveryTag());
			}
			unset($export);
			return true;
		});
		echo "exportMQ exit.\r\n";
	}
	//监听队列
	public function export2($type, $options, $req)
	{
		ignore_user_abort(true);
		ini_set('memory_limit', \mvc::$cfg['export_memory_limit']);
		set_time_limit(\mvc::$cfg['export_time_limit']);
		//type:xlsx|xlsxzip|imgxlsx|imgzip
		$options = json_decode(base64_decode($options), true);
		parse_str(html_entity_decode($req), $req);
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
			$options['numbers'] = $req['numbers'];
		}
		if (isset($req['keys'])) {
			$rules['keys'] = explode(',', $req['keys']);
		}
		$pagesize = \p::fieldval('1100', 'export_limit');
		if (\p::isAdmin()) $pagesize = 2147483647;
		if ($options['model']['hasmodel']) {
			if ($options['model']['modelCel'] == 'one') {
				$rules['modelsOne'] = 1;
			} else if ($options['model']['modelCel'] == 'more') {
				$rules['modelsAll'] = 1;
			} else {
				$rules['modelsRows'] = 1;
			}
		}
		if (empty($pagesize)) $pagesize = \mvc::$cfg['export_record_limit'];
		if ($options['oe']['qty'] > 200) $options['oe']['qty'] = 200;
		$options['fac'] = ($options['fac'] != '') ? explode(',', $options['fac']) : [];

		$rules['getSQL'] = true;
		$sql = $this->pro->list($rules, $req['filters'], 1, $pagesize, '', '', 'p_cate,p_comnum');
		$sql = preg_replace('/ORDER(.*)/', '', $sql);
		$sql = preg_replace('/SELECT(.*)FROM/', 'SELECT p.p_id,p_cate,p_pic,p_innum,p_comnum,p_state_main,p_sales_qty,p_vio FROM', $sql);
		$sql = str_replace('"', '`', $sql);
		$sql = "SELECT * FROM (" . $sql . ") proAction GROUP BY p_id";

		$filename = date('ymdHis');
		$msg = [
			'amsg_title' => lg('自由导出') . ',' . lg('序号') . ': ' . $filename,
			'amsg_body' => lg('排队中'),
			'amsg_send_mail' => 0,
			'amsg_send_sms' => 0
		];
		$msgId = makeOne(\model\message::class)->send([getOpuser()], $msg);
		$export = makeOne(\model\pro\export2::class);
		$count = $export->count($sql);
		$backJson = ['mq' => false];
		$newRules['models'] = $rules['models'];
		$newRules['modelFields'] = $rules['modelFields'];
		$newRules['modelDisplayFields'] = $rules['modelDisplayFields'];
		$newRules['modelPos'] = $options['modelPos'];
		if ($count > 2000) {
			//加入队列
			if ($msgId) {
				$mq = makeOne(\lib\mqRabbitMQ::class, 'exportMQ', \mvc::$cfg['exportMQ']);
				$mq->send(json_encode([
					'msgId' => $msgId,
					'count' => $count,
					'filename' => $filename,
					'username' => getOpuser(),
					'lgtag' => cateName(),
					'type' => $type,
					'options' => $options,
					'rules' => $newRules,
					'sql' => $sql,
					'pagesize' => $pagesize
				]));
			}
			$mq->close();
			$backJson = ['mq' => true];
			(new \model\user)->toLog('导出', '自由导出(队列)' . ', 共 ' . $count . '条, ' . $sql, $count);
		} else {
			$export->export($msgId, $count, $filename, getOpuser(), cateName(), $type, $options, $newRules, $sql, $pagesize);
			(new \model\user)->toLog('导出', '自由导出' . ', 共 ' . $count . '条, ' . $sql, $count);
		}
		$this->successJson($backJson);
	}

	public function export($type, $options, $req)
	{
		ini_set('memory_limit', \mvc::$cfg['export_memory_limit']);
		set_time_limit(\mvc::$cfg['export_time_limit']);
		//type:xlsx|xlsxzip|imgxlsx|imgzip
		$options = json_decode(base64_decode($options), true);
		parse_str(html_entity_decode($req), $req);
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
			$options['numbers'] = $req['numbers'];
		}
		if (isset($req['keys'])) {
			$rules['keys'] = explode(',', $req['keys']);
		}
		$pagesize = \p::fieldval('1100', 'export_limit');
		if (\p::isAdmin()) $pagesize = 2147483647;
		if ($options['model']['hasmodel']) {
			if ($options['model']['modelCel'] == 'one') {
				$rules['modelsOne'] = 1;
			} else if ($options['model']['modelCel'] == 'more') {
				$rules['modelsAll'] = 1;
			} else {
				$rules['modelsRows'] = 1;
			}
		}
		//dd($rules);
		if (empty($pagesize)) $pagesize = \mvc::$cfg['export_record_limit'];
		$data = $this->pro->list($rules, $req['filters'], 1, $pagesize, '', '', 'p_cate,p_comnum');
		//dd($data);
		if (empty($data['rows'])) exit(lg('无数据'));

		if ($options['oe']['qty'] > 200) $options['oe']['qty'] = 200;
		$options['fac'] = ($options['fac'] != '') ? explode(',', $options['fac']) : [];
		(new \model\user)->toLog('导出', '自由导出(1)' . ', 共 ' . count($data['rows']) . '条, ');
		$export = makeOne(\model\pro\export::class, $options, $data['rows']);
		if ($type == 'xlsx') {
			$export->imgxlsx($options, false);
		} else if ($type == 'xlsxzip') {
			$export->zip($options);
		} else if ($type == 'imgxlsx') {
			$export->imgxlsx($options, true);
		} else if ($type == 'imgzip') {
			$export->imgzip($options);
		}
	}


	/**
	 * @method 编码库
	 * @author soul
	 */
	public function exportState($url, $query, $fields, $keyField, $keys, $searchoptions, $pwcode = '', $page = 1, $pagesize = 2147483647, $callback = null)
	{
		ini_set('memory_limit', \mvc::$cfg['export_memory_limit']);
		set_time_limit(\mvc::$cfg['export_time_limit']);
		$bigDataPageSize = 65535;
		$excelType = 'binary'; //binary | xml ,默认 binary

		$dir = str_replace('\\', '/', __DIR__);
		preg_match('/(\w+)\/action/i', str_replace('\\', '/', __DIR__), $m);
		$path_info = '/' . explode($m[1] . '/', $url)[1];

		$fields = html_entity_decode($fields);
		$arr1 = explode(',', $fields);
		$fields = [];
		foreach ($arr1 as $k => $v) {
			$arr2 = explode('=>', $v);
			$fields[$arr2[0]] = $arr2[1];
		}
		parse_str(html_entity_decode($query), $post);
		/*
        if(!\p::isAdmin() && !in_array($url,\mvc::$cfg['export_record_max_urls'])){
           $pagesize = \mvc::$cfg['export_record_limit'];
            if($pwcode!=''){
                $pagesize = \p::fieldval($pwcode,'export_limit');
            }
        }
        if(empty($pagesize)) $pagesize = \mvc::$cfg['export_record_limit'];*/
		$post['page'] = 1;
		$post['rows'] = $pagesize;
		list($class, $method, $uri_params, $req, $reqUriValues) = \mvc::parseurl($path_info);
		if ($req) {
			foreach ($req as $k => $v) {
				$post[$k] = $v;
			}
		}
		\mvc::$req = [];
		if (strpos($url, '?')) {
			parse_str(html_entity_decode(explode('?', $url)[1]), \mvc::$req);
		}
		$_hasJsonFields = [];
		if (!empty($post['_hasJsonFields'])) {
			$_hasJsonFields = explode(',', $post['_hasJsonFields']);
		}
		foreach ($post as $k => $v) {
			if (in_array($k, $_hasJsonFields)) $v = json_decode(urldecode(base64_decode($v)), true);
			\mvc::$req[$k] = $v;
		}

		$req = \mvc::$req;
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		if (isset($req['keys'])) {
			$rules['keys'] = explode(',', $req['keys']);
		}
		if (isset($rules['findNulls']) && $rules['findNulls']) {
			$rules['findNulls'] = json_decode(base64_decode($rules['findNulls']), true);
		}
		$rules['getDoneSQL'] = true;
		$sql = $this->pro->list($rules, $req['filters'], $req['page'], $req['rows'], $req['sidx'], $req['sord'], 'p_comnum');
		$fields = "p.*";
		/*
        $fields .= ",   (
                        select 
                          mpro.`p_comnum` 
                        from 
                          p_code 
                          JOIN pro mpro ON pc_merge_p_id = mpro.`p_id` 
                        where 
                          pc_p_id = p.p_id 
                        limit 
                          1
                      ) AS `merge_outnum`";
        $fields .= ",   (
                        select 
                          mpro.`p_innum` 
                        from 
                          p_code 
                          JOIN pro mpro ON pc_merge_p_id = mpro.`p_id` 
                        where 
                          pc_p_id = p.p_id 
                        limit 
                          1
                      ) AS `merge_innum`";
        */
		$join = "\r\n ";
		$sql = preg_replace('/SELECT\s.*\s+FROM/is', "SELECT " . $fields . " FROM", $sql);
		//$sql = preg_replace('/\sAS\s`p`(.*)\sWHERE/is','AS `p` "\\1"'.$join." WHERE",$sql);
		$pro = new \model\pro\pro();
		$db = $pro->getDb();
		//$rows  = $db->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
		$data = [];

		$cateRows = $db->select('pro_cate', ['id' => ['parent_id', cateName()]]);
		$tRows = $db->query("SELECT from_id,pc_p_id to_id,pc_outnum,pc_innum FROM p_code
JOIN (SELECT pc_p_id from_id,pc_merge_p_id FROM p_code WHERE pc_merge_p_id>0) t1 ON t1.pc_merge_p_id = pc_p_id
WHERE pc_p_id>0")->fetchAll(\PDO::FETCH_ASSOC);
		$mergeRows = [];
		foreach ($tRows as $tRow) {
			$mergeRows[$tRow['from_id']] = $tRow;
		}
		unset($tRows);
		$header = [
			lg('主状态'),
			lg('产品线'),
			lg('小类')
		];

		if (\p::fieldhas('1D00', 'outnum')) $header[] = lg('FREAY型号');
		if (\p::fieldhas('1D00', 'innum')) $header[] = lg('内部编码');
		if (\p::fieldhas('1D00', 'merge_outnum')) $header[] = lg('合并后型号');
		if (\p::fieldhas('1D00', 'merge_innum')) $header[] = lg('合并后内部编码');

		$cacheDir = \mvc::$cfg['dir']['cache'] . '/' . date('Ym');
		mkdirs($cacheDir);
		$tempfile = $cacheDir . '/' . getOpuser() . guid() . '.xlsx';
		include(\mvc::$cfg['mvcDir'] . '/lib/excel/excelInterface.php');
		include(\mvc::$cfg['mvcDir'] . '/lib/excel/excel.php');
		include(\mvc::$cfg['mvcDir'] . '/lib/excel/excelBase.php');
		include(\mvc::$cfg['mvcDir'] . '/lib/excel/excelXlsx.php');

		$excel = new \lib\excel\excel('xlsx');
		$excel->setDirFile($tempfile);
		//$excel = new \lib\exportXlsxDll($cacheDir,$tempfile);
		$excel->header();
		$excel->bookBegin();
		$excel->sheetBegin(lg('基本资料'), $header);

		//foreach($rows as $k=>$row){

		$db->useBuff(false);
		$res = $db->query($sql);
		while ($row = $res->fetch(\PDO::FETCH_ASSOC)) {
			//$row = $pro->formatRow($row);
			$pid = $row['p_id'];
			if (isset($cateRows[$row['p_cate']])) {
				$cateName = $cateRows[$row['p_cate']][cateName()];
				$bigCateName = $cateRows[$cateRows[$row['p_cate']]['parent_id']][cateName()];
			} else {
				$cateName = '';
				$bigCateName = '';
			}
			if ($mergeRows[$pid]) {
				$row['merge_outnum'] = $mergeRows[$pid]['pc_outnum'];
				$row['merge_innum'] = $mergeRows[$pid]['pc_innum'];
			}
			$item = [
				'p_state_main' => $row['p_state_main'],
				//'p_bigcate'=>$row['langs']['p_bigcate'][LG],
				//'p_cate'=>$row['langs']['p_cate'][LG],
				'p_bigcate' => $bigCateName,
				'p_cate' => $cateName
			];
			if (\p::fieldhas('1D00', 'outnum')) $item['p_comnum'] = $row['p_comnum'];
			if (\p::fieldhas('1D00', 'innum')) $item['p_innum'] = $row['p_innum'];
			if (\p::fieldhas('1D00', 'merge_outnum')) $item['merge_outnum'] = $row['merge_outnum'];
			if (\p::fieldhas('1D00', 'merge_innum')) $item['merge_innum'] = $row['merge_innum'];

			$excel->append($item);
			unset($rows[$k]);
		}
		$excel->sheetEnd();
		$excel->bookEnd();
		//readfile($tempfile);
		//ob_end_flush();
		//unlink($tempfile);
		//exit();
	}

	public function codeList()
	{
		$req = \mvc::$req;
		\view::set('allPos', $this->pro->allPos);
		\view::put();
	}
	/**
	 * @method 编码库
	 * @author soul
	 */
	public function getCodeList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if ($req['coutype']) $rules['coutype'] = $req['coutype'];
		if (isset($req['numbers'])) {
			$rules['numbers'] = arryNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		if (isset($rules['findNulls']) && $rules['findNulls']) {
			$rules['findNulls'] = json_decode(base64_decode($rules['findNulls']), true);
		}
		$data = $this->pro->getCodeList($req, $rules);
		$this->successJson($data);
	}

	/**
	 * @method 编辑编码库
	 * @param  id  int  [必填] pn_id
	 * @param  field  string  [必填] 字段
	 * @author soul
	 */
	public function setCodeCell()
	{
		$req = \mvc::$req;
		$result = '';
		if (!empty($req['id']) && preg_match('/^\d+$/', $req['id'])) {
			$setArr = [
				$req['field'] => $req[$req['field']]
			];
			$result = $this->pro->setCodeCell($req['id'], $setArr);
		}
		echo $result;
	}

	public function setCnNosale()
	{
		$req = \mvc::$req;
		$data = $this->pro->setCnNosale($req['ids'], $req['val']);
		$this->successJson($data);
	}

	public function setCodeCate()
	{
		$req = \mvc::$req;
		$data = $this->pro->setCodeCate($req['ids'], $req['pc_cate']);
		$this->successJson($data);
	}

	/**
	 * @method 删除编码库
	 * @param  ids  string  [必填] pc_id  多个逗号分隔
	 * @author soul
	 */
	public function delCode()
	{
		$req = \mvc::$req;
		$data = $this->pro->delCode(explode(',', $req['ids']));
		$this->successJson($data);
	}

	/**
	 * @method 变更主状态
	 * @param  ids  string  [必填] pc_id  多个逗号分隔
	 * @author soul
	 */
	public function changeStateMain()
	{
		$req = \mvc::$req;
		$data = $this->pro->changeStateMain(explode(',', $req['ids']), $req);
		$this->successJson($data);
	}


	/**
	 * @method 生成编码
	 * @param  ids  string  [必填] pc_id  多个逗号分隔
	 * @author soul
	 */
	public function buildCode()
	{
		$req = \mvc::$req;
		$data = $this->pro->buildCode(explode(',', $req['ids']), $req['auto'], $req['pcr_id']);
		$this->successJson($data);
	}


	/**
	 * @method 审核编码
	 * @param  ids  string  [必填] pc_id  多个逗号分隔
	 * @author soul
	 */
	public function checkCode()
	{
		$req = \mvc::$req;
		$data = $this->pro->checkCode(explode(',', $req['ids']));
		$this->successJson($data);
	}

	//取附件
	public function attaqtyList()
	{
		$req = \mvc::$req;
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->list($rules, $req['filters'], $req['page'], $req['rows'], $req['sidx'], $req['sord'], 'p_comnum');
		if (!empty($data)) {
			foreach ($data['rows'] as &$row) {
				$attaRow = $this->pro->getAttaqtyByPid($row['p_id']);
				if (!empty($attaRow)) {
					foreach ($attaRow as $field => $value) {
						$regi = substr($field, strrpos($field, '_') + 1);
						if ($regi != '' && is_numeric($regi)) {
							$row['pa_' . $regi] = $value;
						}
					}
				} //$data['rows']
			}
		}
		$this->successJson($data);
	}

	public function detail($p_id, $outnum = '')
	{
		$req = \mvc::$req;
		if ($p_id) {
			$item = $this->pro->getRowByKey($p_id);
		} else if ($outnum) {
			$item = $this->pro->getRowByFieldValue('p_comnum_format', formatNum($outnum));
			$p_id = $item['p_id'];
		}
		$packInfo = ['p_lnk_p_id' => $req['p_lnk_p_id'] ?: '', 'ppm_pp_id' => $req['ppm_pp_id'] ?: ''];

		\view::set('packInfo', $packInfo);
		\view::set('item', $item);
		\view::put('pro/detail');
	}

	public function getNumberByPid($num)
	{
		$num = $this->pro->getPidByNumber($num);
		$this->successJson($num);
	}

	public function getPidByNumber($num)
	{
		$pid = $this->pro->getPidByNumber($num);
		$this->successJson(['pid' => $pid]);
	}

	public function getRowByNumber($num)
	{
		$pid = $this->pro->getPidByNumber($num);
		if ($pid) {
			$data = $this->pro->getRowByKey($pid);
			if (!empty($data))
				$this->successJson($this->pro->formatRow($data));
		}
		$this->successJson(0);
	}

	public function chkProIdByAny()
	{
		$this->successJson($this->pro->chkProIdByAny(\mvc::$req));
	}

	public function base($p_id)
	{
		$req = \mvc::$req;
		$item = $this->pro->getDetail($p_id);
		$keyToName = [
			'p_standard_name'=>'事业部名称',
			'p_cn_name'=>'中文名称',
			'p_en_name'=>'英文名称',
			'p_py_name'=>'俄文名称',
			'p_sp_name'=>'西语名称',
			'p_al_name'=>'阿拉伯名称',
			'p_state_main'=>'主状态',
			'p_state_remark'=>'状态备注',
			'p_iskit'=>'套件',
			'p_unit'=>'基本单位',
			'p_model_cn_name'=>'中文车型',
			'p_model_en_name'=>'英文车型',
			'p_model_py_name'=>'俄文车型',
			'p_model_sp_name'=>'西语车型',
			'p_model_al_name'=>'阿拉伯车型',
			'p_chassis'=>'底盘',
			'p_model_year'=>'年限',
			'p_engine'=>'发动机',
			'p_cc'=>'排量',
			'p_fuel_type'=>'燃油类型',
			'p_des_cn_name'=>'中文描述',
			'p_des_en_name'=>'英文描述',
			'p_des_py_name'=>'俄文描述',
			'p_des_sp_name'=>'西语描述',
			'p_des_al_name'=>'阿拉伯描述',
			'plc_p_cn_name'=>'中文名称',
			'plc_p_en_name'=>'英文名称',
			'plc_p_py_name'=>'俄文名称',
			'plc_p_sp_name'=>'西语名称',
			'plc_p_al_name'=>'阿拉伯名称',
			'plc_p_state_main'=>'产品状态',
			'plc_p_model_cn_name'=>'中文车型',
			'plc_p_model_en_name'=>'英文车型',
			'plc_p_model_py_name'=>'俄文车型',
			'plc_p_model_sp_name'=>'西语车型',
			'plc_p_model_al_name'=>'阿拉伯车型',
			'plc_p_chassis'=>'底盘',
			'plc_p_model_year'=>'年限',
			'plc_p_engine'=>'发动机',
			'plc_p_cc'=>'排量',
		];

		\view::set('keyToName', $keyToName);
		\view::set('item', $item);
		\view::set('allPos', $this->pro->allPos);
		\view::set('req', $req);
		\view::put('pro/base/form');
	}

	public function pic($p_id)
	{
		$item = $this->pro->formatRow($p_id);
		\view::set('item', $item);
		\view::put('pro/pic');
	}

	public function pack()
	{
		$req = \mvc::$req;
		$p_id = $req['p_id'];

		$pack = new packing();

		$item = $pack->getProPack($p_id);

		\view::set('item', $item);
		\view::set('p_id', $p_id);

		\view::put('pro/pack');
	}

	public function getPackFiledAndArea()
	{
		$req = \mvc::$req;
		$pack = new packing();
		$data = ['packFileds' => $pack->packFileds, 'packArea' => $pack->packArea];
		$this->successJson($data);
	}

	public function bom($p_id)
	{
		$proRow = $this->pro->getRowByKey($p_id);
		\view::set('proRow', $proRow);
		\view::put('pro/bom');
	}

	public function order()
	{
		\view::put();
	}

	public function base_order($p_id)
	{
		$proRow = $this->pro->getRowByKey($p_id);
		\view::set('proRow', $proRow);
		\view::put();
	}

	public function base_sample($p_id)
	{
		if (empty($p_id)) {
			exitJson(lg('参数错误'));
		} else {
			$proRow = $this->pro->getRowByKey($p_id);
			\view::set('proRow', $proRow);
			\view::put();
		}
	}

	public function getOrder()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$data = (makeOne(\model\bi\bi::class))->getOrder($rules, $req['filters'], $req['page'], $req['rows'], $req['sidx'], $req['sord']);
		$this->successJson($data);
	}

	public function saveBase()
	{
		$req = \mvc::$req;
		$key = $req['p_id'];
		$result = $this->pro->saveCodeBase($key, $req);
		$this->successJson($result);
	}

	public function baseEdit()
	{
		$req = \mvc::$req;
		$key = $req['p_id'];
		$link_tags = $req['link_tags'];
		unset($req['link_tags']);
		if ($key == 0) {
			$result = $this->pro->baseAdd($req, $link_tags);
		} else {
			$result = $this->pro->baseEdit($key, $req, $link_tags);
		}
		$this->successJson($result);
	}

	//取父零件
	public function getFather($p_id)
	{
		$data = $this->pro->getFather($p_id);
		$this->successJson($data);
	}

	//取子零件
	public function getSon($p_id)
	{
		$data = $this->pro->getSon($p_id);
		$this->successJson($data);
	}

	//添加父零件
	public function addFather($p_id, $father_p_id)
	{
		if ($p_id == $father_p_id) {
			$this->msgJson(lg('自己不能添加自己'));
		}
		if ($this->pro->hasSon($p_id, $father_p_id)) {
			$this->msgJson(lg('执行失败, 此型号已存在于子零件中'));
		}
		$data = [
			'pf_father_pid' => $father_p_id,
			'pf_son_pid' => $p_id,
		];
		$this->pro->addFatherSon($data);
		$this->successJson(lg('执行成功'));
	}

	//添加子零件
	public function addSon($p_id, $son_p_id)
	{
		if ($p_id == $son_p_id) {
			$this->msgJson(lg('自己不能添加自己'));
		}
		if ($this->pro->hasFather($p_id, $son_p_id)) {
			$this->msgJson(lg('执行失败, 此型号已存在于父零件中'));
		}
		$data = [
			'pf_father_pid' => $p_id,
			'pf_son_pid' => $son_p_id,
		];
		$this->pro->addFatherSon($data);
		$this->successJson(lg('执行成功'));
	}

	//删父或子零件
	public function deleteSon($p_id)
	{
		$data = $this->pro->deleteSon($p_id, \mvc::$req['ids']);
		$this->successJson($data);
	}

	//编码测试
	public function testProCodeCreate($plmseq, $innum)
	{
		$codeRule = new \model\pro\codeRule();
		$data = $codeRule->createCode($plmseq, $innum);
		$this->successJson($data);
	}



	/**
	 * 通过属性集合住创建产品CODE
	 * @param  s_cate  int  [必填] 小类
	 * @param  s_procode_ext  string  [必填] 扩展类型
	 * @param  s_usa_make  string  [选填] 大品牌
	 * @param  s_procode_a  string  [选填]
	 * @param  s_procode_b  string  [选填]
	 * @param  s_procode_c  string  [选填]
	 * @param  innum string [必填] 内部编码
	 * @author soul
	 */
	public function createCodeByValues()
	{
		$req = \mvc::$req;
		$codeRule = new \model\pro\codeRule();
		$data = $codeRule->createCodeByValues($req, $req['innum']);
		$this->successJson($data);
	}



	public function editCell()
	{
		$req = \mvc::$req;
		$id = $req['id'];
		$oper = $req['oper'];
		$field = $req['field'];
		if (isset($req['value']))
			$value = $req['value'];
		else
			$value = $req[$field];
		if ($oper == 'edit') {
			$result = $this->pro->setValue($id, $field, $value);
		}
	}

	public function editCellAttaqty()
	{
		$req = \mvc::$req;
		$id = $req['id'];
		$oper = $req['oper'];
		$field = $req['field'];
		if (isset($req['value']))
			$value = $req['value'];
		else
			$value = $req[$field];
		if ($oper == 'edit') {
			$result = $this->pro->setAttaqty($id, $field, $value);
		}
	}



	/**
	 * @method 新增产品
	 * @param  p_cate  int  [必填] 小类
	 * @param  p_innum  string  [必填] 内部编码
	 * @param  nums  array  [必填] 自动生成的编码
	 * @author soul
	 */
	public function addNewProduct()
	{
		$req = \mvc::$req;
		$autonums = [];
		foreach ($req['nums'] as $fac => $nv) {
			if ($fac == 'OUTNUM') {
				$row = json_decode($nv['old'], true);
				$row['num'] = $nv['num'];
				$autonums[$fac] = $row;
			} else {
				foreach ($nv as $nkk => $nvv) {
					$row = json_decode($nvv['old'], true);
					$row['num'] = $nvv['num'];
					$autonums[$fac][] = $row;
				}
			}
		}
		$baseArr = [
			'p_cate' => $req['p_cate'],
			'p_innum' => $req['p_innum']
		];
		$othArr = [
			'autonums' => $autonums
		];
		$data = $this->pro->addProductBySelf($baseArr, $othArr);
		$this->successJson($data);
	}

	/**
	 * @method 号码自动完成
	 * @param  type string  [选填] outnum[默认] innum  oth:非gsp品牌号  all:不限制
	 * @param  num string  [必填] 号码
	 * @author soul
	 */
	public function autocomNum()
	{
		$req = \mvc::$req;
		$data = $this->pro->autocomNum($req);
		$this->successJson($data);
	}


	public function autoCate()
	{
		$req = \mvc::$req;
		$data = $this->pro->autoCate($req);
		$this->successJson($data);
	}


	/**
	 * @method 导入中心
	 */
	public function import()
	{
		\view::put();
	}


	/**
	 * @method 产品比较
	 * @param  pids string  [选填] 产品ID，逗号分隔
	 * @param  nums string  [选填] FREAY型号，逗号分隔
	 * @author soul
	 */
	public function compare()
	{
		$req = \mvc::$req;
		$maxItem = 20;
		$req['maxItem'] = $maxItem;
		if (!empty($req['pids'])) {
			$pids = [];
			foreach (explode(',', $req['pids']) as $k => $v) {
				$t = explode('-', $v);
				$pids[] = (int) $t[0];
			}
			$req['pids'] = implode(',', $pids);
		}
		$dataArr = $this->pro->getCompare($req);

		list($numUnikeyArr, $numCount) = $this->compareData($dataArr['items'], 'nums');
		list($cnModelsUnikeyArr, $cnModelsCount) = $this->compareData($dataArr['items'], 'cnmodels');
		list($modelsUnikeyArr, $modelsCount)  = $this->compareData($dataArr['items'], 'models');
		list($paraUnikeyArr, $paraCount)  = $this->compareData($dataArr['items'], 'paras');
		\view::set('paraCount', $paraCount);
		\view::set('paraUnikeyArr', $paraUnikeyArr);
		\view::set('itemCount', count($dataArr['items']));
		\view::set('numCount', $numCount);
		\view::set('cnModelsCount', $cnModelsCount);
		\view::set('modelsCount', $modelsCount);
		\view::set('numUnikeyArr', $numUnikeyArr);
		\view::set('cnModelsUnikeyArr', $cnModelsUnikeyArr);
		\view::set('modelsUnikeyArr', $modelsUnikeyArr);
		\view::set('ip_test_edi_runtime', gethostbyname("test.edi-runtime.jdl.cn")); //test.edi-runtime.jdl.cn
		\view::set('ip_edi_runtime', gethostbyname("edi-runtime.jdl.cn")); //test.edi-runtime.jdl.cn
		\view::set('maxItem', $maxItem);
		\view::set('maxInput', 6);
		\view::set('nums', $req['nums']);
		\view::set('itemArr', $dataArr['items']);
		\view::set('paraArr', $dataArr['para']);
		\view::set('dataArr', $dataArr);
		\view::set('req', $req);
		\view::put();
	}

	protected function compareData($dataArr, $type)
	{
		if (!in_array($type, ['nums', 'models', 'cnmodels', 'paras'])) return [];
		$hasCount = 0;
		$unikeyArr = [];
		foreach ($dataArr as $k => $v) {
			if (!empty($v[$type])) {
				$hasCount++;
				foreach ($v[$type] as $kk => $vv) {
					$unikeyArr[$vv['unikey']]['keys'][$k] = $kk;
					$unikeyArr[$vv['unikey']]['count']++;
					$unikeyArr[$vv['unikey']]['unikey'] = $vv['unikey'];
				}
				unset($vv);
			}
		}
		if ($unikeyArr) {
			$sort = [];
			foreach ($unikeyArr as $k => $v) {
				$sort['count'][$k] = $v['count'];
				$sort['unikey'][$k] = $v['unikey'];
			}
			array_multisort($sort['count'], SORT_DESC, $sort['unikey'], SORT_ASC, $unikeyArr);
		}

		return [array_values($unikeyArr), $hasCount];
	}

	public function addMerge()
	{
		$req = \mvc::$req;
		$data = $this->pro->addMerge($req['pch_p_id_from'], $req['pch_p_id_to']);
		$this->successJson($data);
	}

	public function getMergeList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->getMergeList($req, $rules);
		$this->successJson($data);
	}

	public function getMergeEndList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->getMergeEndList($req, $rules);
		$this->successJson($data);
	}

	public function getExchageAllList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->getExchageAllList($req, $rules);
		$this->successJson($data);
	}

	public function delMerge()
	{
		$req = \mvc::$req;
		$data = $this->pro->delMerge(explode(',', $req['ids']));
		$this->successJson($data);
	}

	public function checkMerge()
	{
		$req = \mvc::$req;
		$data = $this->pro->checkMerge(explode(',', $req['ids']), $req);
		$this->successJson($data);
	}

	public function rollbackMerge()
	{
		$req = \mvc::$req;
		$data = $this->pro->rollbackMerge($req['id'], $req);
		$this->successJson($data);
	}


	/**
	 * @method 选择器
	 * @param  sql    string  [sql+db] base64:xxxxxx select brand_name name, brand_id id, brand_initial letter from m_cn_model group by brand_id order by brand_initial
	 * @param  db    string  [sql+db] 选择sql时必填
	 * @param  table  string  [选填] factory | make
	 * @param  style  string  [选填] 选择模式 anychk:多选  空(默认):单选
	 * @param  letter  int  [选填] 是否启用字母选择  1(默认)|-1
	 * @param  liwidth  int  [选填] 每个名称宽度 默认 150
	 * @param  data  string  [选填] base64:W3sibmFtZSI6Ilx1NTAzYyIsImlkIjoiMTIzIn0seyJuYW1lIjoiXHU1MDNjMiIsImlkIjoiNDU2In1d  base64_encode(json_encode([["name"=>"值", "id"=>"123"], ["name"=>"值2", "id"=>"456"]]))
	 * @author soul
		传sql   pro/select?db=main&sql=select+brand_name+name%2C+brand_id+id%2C+brand_initial+letter+from+m_cn_model+group+by+brand_id+order+by+brand_initial&style=anychk&callback=onSelectUser&letter=1
        传sql base64 /pro/select?sql=base64:xxxxxx
		model/pro/pro/getSelect配置  pro/select?table=cnmakesql&callback=onSelectUser&letter=1
	 */
	public function select()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$style = !empty($req['style']) && $req['style'] == 'anychk' ? 'anychk' : '';
		if (substr($req['sql'], 0, 7) == 'base64:') {
			$req['sql'] = base64_decode(substr($req['sql'], 7));
		}
		if (!empty($req['sql']) && stripos($req['sql'], 'select') === 0 && !empty(\mvc::$cfg['db'][$req['db']])) {
			$req['sql'] = strtr($req['sql'], ['insert' => '###', 'update' => '###', 'delete' => '###', 'drop' => '###', 'truncate' => '###', 'alert' => '###']);
			$this->sdb = new \lib\db(\mvc::$cfg['db'][$req['db']]);
			$dataArr = $this->sdb->query($req['sql'])->fetchAll(\PDO::FETCH_ASSOC);
		} else if (!empty($req['data'])) {
			$dataArr = json_decode(base64_decode(substr($req['data'], 7)), true);
		} else {
			if ($req['table'] == 'brand' && $req['pwcode']) {
				$proBrands = \p::areas($req['pwcode']);
				if (!\p::isAdmin() && $proBrands) {
					if (!isset($rules['pb_id'])) {
						$rules['pb_id'] = explode(',', $proBrands);
					}
				}
			}

			if ($req['table'] == 'tagbrand' && $req['pwcode']) {
				$tagbrands = \p::tagbrands($req['pwcode']);
				if (!\p::isAdmin() && $tagbrands) {
					if (!isset($rules['tb_id'])) {
						$rules['tb_id'] = explode(',', $tagbrands);
					}
				}
			}

			if ($req['table'] == 'supplier' && $req['pwcode']) {
				$cates = \p::cates($req['pwcode']);
				if (!\p::isAdmin() && $cates) {
					$rules['RAW #sup_id'] = raw(sprintf(" sup_id in (select DISTINCT sc_sup_id from supplier_cate where sc_cat_id in (%s))", $cates));
				}
			}

			$dataArr = $this->pro->getSelect($req['table'], $rules);
		}
		$letterArr = [];
		if ($req['letter'] != -1) {
			$sort = ['seq' => [], 'letter' => [], 'name' => []];
			$cnInitialLetter = include(\mvc::$cfg['mvcDir'] . '/lib/cnInitialLetter.php');
			foreach ($dataArr as &$v) {
				if (isset($v['letter'])) {
					$v['letter'] = substr($v['letter'], 0, 1);
				} else if (preg_match('/^[0-9a-zA-Z]/', $v['name'], $match)) {
					$v['letter'] = $match[0];
				} else {
					$first = mb_substr($v['name'], 0, 1);
					if (!empty($cnInitialLetter[$first])) {
						$py = $cnInitialLetter[$first];
					} else {
						$py = pinyinFirst($first);
					}
					$v['letter'] = substr($py, 0, 1);
				}
				$v['letter'] = strtoupper($v['letter']);
				$sort['seq'][] = isset($v['seq']) ? $v['seq'] : 0;
				$sort['letter'][] = $v['letter'];
				$sort['name'][] = $v['name'];
				$letterArr[] = $v['letter'];
			}
			array_multisort($sort['seq'], SORT_DESC, $sort['letter'], SORT_ASC, $sort['name'], SORT_ASC, $dataArr);
			$letterArr = array_unique($letterArr);
			sort($letterArr);
		}
		\view::set('letterArr', $letterArr);
		\view::set('dataArr', $dataArr);
		\view::set('style', $style);
		\view::set('req', $req);
		\view::set('id', $id);
		\view::put();
	}

	/**
	 * @method 区域&本地码 审核
	 * @param string $ids 
	 */
	public function codeAreaNumberCheck2($ids)
	{
		if ($ids != '') {
			$res = (new \model\pro\codeRule())->codeAreaNumberCheck2($ids, true);
			$this->successJson($res);
		}
		$this->msgJson(lg('未知错误'));
	}

	/**
	 * @method 区域&本地码 删除
	 * @param string $ids 
	 */
	public function codeAreaNumberDeleteRows($ids)
	{
		if ($ids != '') {
			$res = (new \model\pro\codeRule())->codeAreaNumberDeleteRows($ids);
			$this->successJson();
		}
		$this->msgJson(lg('未知错误'));
	}



	/**
	 * @method 生成条码
	 * @param string $ids 
	 */
	public function buildBarCode($ids)
	{
		if ($ids != '') {
			$res = (new \model\pro\codeRule())->buildBarCode($ids);
			if ($res) {
				$this->successJson([$res]);
			}
		}
		$this->msgJson(lg('生成条码出现错误,请检测企业编码可使用次数'));
	}


	public function getPlmParamByInnum($innum)
	{
		$io = new \model\io();
		$data = $io->plmParam($innum);
		$this->successJson($data);
	}

	public function getBomByInnum()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if (empty($rules['innum']) || empty($rules['cid']))
			return $this->successJson([]);;
		$cate = makeOne(\model\pro\cate::class)->getRowByKey($rules['cid']);
		$io = new \model\io();
		$ioPost = [
			"IV_VALUE" => $cate['iv_value'],
			"IV_MAKTX" => $rules['innum'],
			"IV_WERKS" => $cate['iv_werks']
		];
		$data = $io->bom('sap/bom', $ioPost);
		$data = $data['ET_BOM_ITEM'];
		if (!empty($data)) {
			$sort = [];
			foreach ($data as $k => &$v) {
				$v['IMAKT_zh_cn'] = $v['IMAKT'];
				$v['IMAKT_en'] = $v['IMAKT_zh_cn'];
				preg_match_all("/[\x{4e00}-\x{9fa5}]+/u", $v['IMAKT_zh_cn'], $m);
				if ($m) {
					foreach ($m[0] as $mv) {
						$en = $this->pro->getBomEnTxt($mv);
						if (empty($en)) {
							preg_match("/[a-z0-9]+" . $mv . "/i", $v['IMAKT_en'], $m2);
							if ($m2) {
								$en = $this->pro->getBomEnTxt($m2);
								$mv = $m2;
							}
						}
						if ($en) {
							$v['IMAKT_en'] = str_replace($mv, ' ' . ucfirst($en) . ' ', $v['IMAKT_en']);
						}
					}
				}
				$sort[$k] = $v['deliverydate'];
			}
			array_multisort($sort, SORT_DESC, $data);
		}
		$this->successJson($data);
	}


	//报表
	public function master()
	{
		$req = \mvc::$req;
		$master = new master();
		$mainkey = $req['mainkey'];
		$scof = [];
		$selftscof = [];
		if ($mainkey == 'self') {
			$selftscof = $master->getSelfReport();
			\view::set('selftscof', $selftscof);
		} else {
			$scof = \mvc::$cfg['master'][$mainkey];
			\view::set('scof', $scof);
		}
		\view::set('mainkey', $mainkey);
		\view::put();
	}

	public function exeMaster()
	{
		$req = \mvc::$req;
		$master = new master();
		$master->export($req['mainkey'], explode(',', $req['skey']), $req);
		$this->successJson([]);
	}

	function delMasterTpl()
	{
		$req = \mvc::$req;
		$master = new master();
		$master->delMasterTpl(explode(',', $req['ids']));
		$this->successJson([]);
	}

	//监听队列
	public function exeMasterSelf($options, $req)
	{
		ignore_user_abort(true);
		ini_set('memory_limit', \mvc::$cfg['export_memory_limit']);
		set_time_limit(\mvc::$cfg['export_time_limit']);
		//type:xlsx|xlsxzip|imgxlsx|imgzip
		$options = json_decode(base64_decode($options), true);
		parse_str(html_entity_decode($req), $req);
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
			$options['numbers'] = $req['numbers'];
		}
		if (isset($req['keys'])) {
			$rules['keys'] = explode(',', $req['keys']);
		}
		$pagesize = 2147483647;
		if ($options['model']['hasmodel']) {
			if ($options['model']['modelCel'] == 'one') {
				$rules['modelsOne'] = 1;
			} else if ($options['model']['modelCel'] == 'more') {
				$rules['modelsAll'] = 1;
			} else {
				$rules['modelsRows'] = 1;
			}
		}
		if ($options['oe']['qty'] > 200) $options['oe']['qty'] = 200;
		$options['fac'] = ($options['fac'] != '') ? explode(',', $options['fac']) : [];
		$rules['getSQL'] = true;
		$sql = $this->pro->list($rules, $req['filters'], 1, $pagesize, '', '', '');
		$fields = "p.p_id";
		$join = "\r\n ";
		$sql = preg_replace('/SELECT\s.*\s+FROM/is', "SELECT " . $fields . " FROM", $sql);
		$master = new master();
		if ($options['act'] == 'reporttpl') {
			$data = ['mr_name' => $options['mr_name'], 'mr_mt_id' => (int)$options['mtids'], 'mr_sql' => $sql];
			$master->setReportTpl($data);
			$this->successJson([]);
		} else if ($options['act'] == 'export') {
			$master = new master();
			$master->export('self', '', ['sql' => $sql, 'mtids' => $options['mtids']]);
			$this->successJson([]);
		}
	}

	public function masAttaqtyList()
	{
		$req = \mvc::$req;
		//前置条件
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = formatNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->list($rules, $req['filters'], $req['page'], $req['rows'], $req['sidx'], $req['sord'], 'p_comnum');
		if (!empty($data)) {
			foreach ($data['rows'] as &$row) {
				$attaRow = $this->pro->getMasAttaqtyByPid($row['p_id']);
				if (!empty($attaRow)) {
					foreach ($attaRow as $field => $value) {
						$regi = substr($field, strrpos($field, '_') + 1);
						if ($regi != '' && is_numeric($regi)) {
							$row['pa_' . $regi] = $value;
						}
					}
				} //$data['rows']
			}
		}
		$this->successJson($data);
	}

	public function editCellMasAttaqty()
	{
		$req = \mvc::$req;
		$id = $req['id'];
		$oper = $req['oper'];
		$field = $req['field'];
		if (isset($req['value']))
			$value = $req['value'];
		else
			$value = $req[$field];
		if ($oper == 'edit') {
			$result = $this->pro->setMasAttaqty($id, $field, $value);
		}
	}

	//审核零件库到商品库
	public function chkPoeToPro()
	{
		$req = \mvc::$req;
		$data = $this->pro->getBuildProByOeInfo($req['oe_id']);
		\view::set('data', $data);
		\view::put();
	}


	public function getBatchBuildProByOeInfo()
	{
		$req = \mvc::$req;
		$data = $this->pro->getBatchBuildProByOeInfo($req['oe_id']);
		$this->successJson($data);
	}

	public function buildProByOe()
	{
		$req = \mvc::$req;
		$data = $this->pro->buildProByOe($req['oe_id'], $req, $req['p_id'], true);
		$this->successJson($data);
	}

	public function getProRelOe()
	{
		$req = \mvc::$req;
		$data = [];
		$data = $this->pro->getProRelOe($req['pid'], $req);
		$this->successJson($data);
	}

	/**
	 * @method 关联产品
	 * @author zhengweihua 
	 * @copyright 2024-12-04
	 */
	public function relpro()
	{
		$req = \mvc::$req;
		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 保存产品包装
	 * @author zhengweihua 
	 * @copyright 2024-12-05
	 */
	public function saveProPack()
	{
		$req = \mvc::$req;
		$key = $req['pp_p_id'];
		$result = $this->pro->saveProPack($key, $req);
		$this->successJson($result);
	}


	public function getPackList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = arryNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$data = $this->pro->getPackList($req, $rules);
		$this->successJson($data);
	}


	public function delPack()
	{
		$req = \mvc::$req;
		$data = $this->pro->delPack(\mvc::$req['ids']);
		$this->successJson($data);
	}

	/**
	 * @param  string $elename
	 * @method 产品相关属性的删除
	 * @author zhengweihua 
	 * @copyright 2024-12-10
	 */
	public function deleteElementRows($elename = '')
	{
		$req = \mvc::$req;
		$elename = ($elename != '') ? $elename : \mvc::$req['elename'];
		$elecfg = require(\mvc::$cfg['projectDir'] . '/element/' . $elename . '.php');
		$pro =  new pro();
		if ($pro->deleteElementRows($elecfg, $req['ids'])) {
			$this->successJson(lg('删除完成'));
		}
	}

	/**
	 * @param  string $elename
	 * @method 产品相关属性的编辑
	 * @author zhengweihua 
	 * @copyright 2024-12-11
	 */
	public function editElementCell($elename = '')
	{
		$req = \mvc::$req;
		$id = $req['id'];
		$oper = $req['oper'];
		$field = $req['field'];
		if (isset($req['value']))
			$value = $req['value'];
		else
			$value = $req[$field];

		$elename = ($elename != '') ? $elename : \mvc::$req['elename'];
		$elecfg = require(\mvc::$cfg['projectDir'] . '/element/' . $elename . '.php');
		$elementModel = new element($elecfg);

		$pro =  new pro();

		if ($oper == 'edit' && !empty($field)) {
			if (isset($elecfg['uniqueFields']) && !empty($elecfg['uniqueFields']) && in_array($field,  $elecfg['uniqueFields'])) {
				if ($elementModel->hasUnique($id, $field, $value)) {
					exit(lg("重复的记录,保存失败"));
				}
			}
			if ($value != '' && $elecfg['fields'][$field]['unique'] && !$elecfg['fields'][$field]['key']) {
				if ($elementModel->hasWithOut($field, $value, $id)) {
					exit(sprintf("重复的 [ %s ] 在 [ %s ] 中", $value, $elecfg['fields'][$field][LG_NAME]));
				}
			}
			$pro->editElementCell($elecfg, $id, $field, $value);
		} else {
			$this->errorJson(500);
		}
	}

	/**
	 * @method 根据号码获取对应配件分类
	 * @author zhengweihua 
	 * @copyright 2024-12-17
	 */
	public function getNumParts()
	{
		$req = \mvc::$req;
		if (!$req['number']) exitJson(-1, '参数错误');
		$ypApi = new ypApi();
		$chkres = $ypApi->Get('tcd/getNumParts', $req);
		$data = $chkres['status'] ? $chkres['data'] : [];
		\view::set('data', $data);
		\view::put();
	}

	/**
	 * 格式化参考参数
	 */
	public function formatPara()
	{
		$req = \mvc::$req;
		$p_id = $req['p_id'];

		$pro = new pro();
		$detail = $this->pro->getDetail($p_id);

		if ($detail['p_para']) {
			$ret = $pro->formatParaFromTcd($detail['p_cate'], $detail['p_para'], $p_id);

			$pro->setProParaAndPos($p_id, $ret);
		}

		$this->successJson("操作成功");
	}

	/**
	 * 检测状态并删除选项
	 */
	public function deleteRowsByChk($elename = '')
	{
		$req = \mvc::$req;
		$elename = ($elename != '') ? $elename : \mvc::$req['elename'];
		$pro = new pro();
		$data = $pro->deleteRowsByChk($elename, $req['ids']);
		$this->successJson($data);
	}

	public function seachAllNum()
	{
		$req = \mvc::$req;
		$nums = splitNums($req['num'], $req['splitval']);
		$datas = [];
		if ($req['showtype'] == 'merge') {
			//合并模式
			foreach ($nums as $numstr) {
				$tnum = explode(':', $numstr);
				if (count($tnum) == 1) $tnum = ['', $tnum[0]];
				$number = $tnum[1];
				$factory = $tnum[0];
				$pro = new pro();
				$chkres = $pro->seachAllNum($number, $factory, $req);
				$unikey = md5(serialize(['oe_ids' => array_column($chkres['poe'], 'oe_id')]));
				$typeArr = ['pro' => 'p_id', 'super' => 'sup_id', 'work' => 'wdlist_id', 'poe' => 'oe_id', 'tb_brands' => 'tb_id', 'oe_nums' => '', 'company' => '', 'resource' => '', 'ypresource' => ''];
				foreach ($typeArr as $type => $unifield) {
					if (empty($chkres[$type])) {
						$datas[$unikey][$type] = [];
						continue;
					}
					foreach ($chkres[$type] as $vv) {
						if ($type == 'poe') {
							$datas[$unikey]['num_by'][] = ['number' => $vv['on_number'], 'factory' => $vv['pf_name_s']];
						}
						if ($unifield) {
							$datas[$unikey][$type][$vv[$unifield]] = $vv;
						} else {
							$datas[$unikey][$type][] = $vv;
						}
					}
					if (empty($unifield) && $datas[$unikey][$type]) $datas[$unikey][$type] = multiArrayUnique($datas[$unikey][$type]);
				}
				$datas[$unikey]['num_org'][] = ['number' => $number, 'factory' => $factory];
			}
			$datas = array_values($datas);
		} else {
			foreach ($nums as $numstr) {
				$tnum = explode(':', $numstr);
				if (count($tnum) == 1) $tnum = ['', $tnum[0]];
				$number = $tnum[1];
				$factory = $tnum[0];
				$pro = new pro();
				$chkres = $pro->seachAllNum($number, $factory);
				$chkres['num_org'] = [['number' => $number, 'factory' => $factory]];
				$chkres['num_by'] = [];
				if ($chkres['poe']) {
					foreach ($chkres['poe'] as $vv) {
						$chkres['num_by'][] = ['number' => $vv['on_number'], 'factory' => $vv['pf_name_s']];
					}
				}
				$datas[] = $chkres;
			}
		}

		\view::set('datas', $datas);
		\view::set('rownum', $req['rownum']);
		$html = \view::fetch();

		$this->successJson(['html' => $html]);
	}


	public function seachEpcNum()
	{
		$req = \mvc::$req;
		$nums = splitNums($req['num'], $req['splitval']);
		$datas = [];
		foreach ($nums as $numstr) {
			$tnum = explode(':', $numstr);
			if (count($tnum) == 1) $tnum = ['', $tnum[0]];
			$number = $tnum[1];
			$factory = $tnum[0];
			$pro = new pro();
			$chkres = $pro->seachEpcNum($number);
			$chkres['num_org'] = [['number' => $number, 'factory' => $factory]];
			$datas[] = $chkres;
		}
		\view::set('datas', $datas);
		\view::set('rownum', $req['rownum']);
		$html = \view::fetch();

		$this->successJson(['html' => $html]);
	}

	/**
	 * @method 获取品牌标签key value
	 * @author zhengweihua 
	 * @copyright 2025-01-09
	 */
	public function getTagBrandAllKv()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$rows = $pro->getDb()->select('tag_brand', ['tb_id', 'tb_' . LG_NAME], ['ORDER' => raw('tb_seq,CONVERT(tb_' . LG_NAME . ' USING gbk)')]);
		$data = [];
		$regi = 0;
		
		$firstkey = isset($req['firstkey']) ? $req['firstkey'] : 0;
		if (isset($req['hasFirst']) && $req['hasFirst']) {
			$data[$regi] = ['key' => $firstkey, 'value' => ''];
			$regi++;
		}
		$emptykey = isset($req['emptyKey'])? $req['emptyKey']: -1;
        if(isset($req['hasEmpty']) && $req['hasEmpty']){
            $data[$regi] = ['key'=>$emptykey, 'value'=>lg('不存在')];
			$regi++;
        }
		foreach ($rows as $k => $v) {
			$data[$k + $regi] = ['key' => $v['tb_id'], 'value' => $v['tb_' . LG_NAME]];
		}
		$this->successJson($data);
	}

	/**
	 * @method 产品供应商
	 * @author zhengweihua 
	 * @copyright 2025-01-09
	 */
	public function listSupplier()
	{
		$req = \mvc::$req;
		\view::set('req', $req);
		\view::put();
	}
	/**
	 * @method OE供应商列表
	 */
	public function getListSupplier()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$pro = new pro();
		$data = $pro->getListSupplier($req, $rules);
		$this->successJson($data);
	}


	function itemImg()
	{
		$req = \mvc::$req;
		$pro = new pro();
		//$pro->getItemImg();
		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 图片相关
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function listPic()
	{
		$req = \mvc::$req;

		$pro = new pro();
		$data = $pro->getDetail($req['p_id']);
		\view::set('data', $data);
		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 获取图片列表
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function getListPic()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$pro = new pro();
		$data = $pro->getListPic($req, $rules);
		$this->successJson($data);
	}

	/**
	 * @method 单元格编辑
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function setOePicCell()
	{
		$req = \mvc::$req;

		$pro = new pro();
		$data = $pro->setOePicCell($req);
	}

	public function searchPic()
	{
		$req = \mvc::$req;
		$data = [];
		$searchArr = [];
		if ($req['p_id']) {
			$pro = new pro();
			$res = $pro->getListPic(['pid' => $req['p_id'], 'type' => 'img']);
			$data = $res['rows'];
		}
		\view::set('data', $data);
		if ($req['number']) {
			$oe = new oe();
			$res = $oe->searchPic($req['number']);
			$searchArr = $res['data'];
		}
		\view::set('searchArr', $searchArr);

		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 设置主图
	 * @author zhengweihua 
	 * @copyright 2025-01-14
	 */
	public function setProMainPic()
	{
		$req = \mvc::$req;
		if (!$req['fileid'] || !$req['pid'] || !$req['type']) return $this->exitJson(-1, lg('参数错误'));
		$pro = new pro();
		$data = $pro->setProMainPic($req['fileid'], $req['pid'], $req['type']);
		$this->successJson($data);
	}

	public function setPicSup()
	{
		$req = \mvc::$req;
		if (!$req['fileid'] || !$req['pid'] || !$req['sup_id']) return $this->exitJson(-1, lg('参数错误'));
		$pro = new pro();
		$fileids = array_values(explode(',', $req['fileid']));
		$data = $pro->setPicLineSup($req['pid'], $req['sup_id'], $fileids);
		$this->successJson($data);
	}

	public function delProPic()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->delProPic($req);
		$this->successJson($data);
	}

	/**
	 * @method 将选择的图片设置为零件图
	 * @author zhengweihua 
	 * @copyright 2025-01-15
	 */
	public function setProPicByFile()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->setProPicByFile($req);
		$this->successJson($data);
	}

	/**
	 * @method 设置零件图为主图
	 * @author zhengweihua 
	 * @copyright 2025-01-15
	 */
	public function setImgToMain()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->setImgToMain($req);
		$this->successJson($data);
	}

	public function getNumParams()
	{
		$req = \mvc::$req;
		if (!$req['number']) exitJson(-1, '参数错误');
		$ypApi = new ypApi();
		$postData = ['number' => $req['number'], 'factory' => $req['factory'], 'ganame' => $req['ganame']];
		$chkres = $ypApi->Get('tcd/chkOneNumBase', [], $postData);
		$data = $chkres['status'] ? $chkres['data'] : [];
		$this->successJson($data);
	}

	/**
	 * @method 设置主OE
	 * @author zhengweihua 
	 * @copyright 2025-03-06
	 */
	public function setOeMain()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->setOeMain($req['pn_id'],$req['p_id'],$req['p_lnk_p_id']);
		$this->successJson($data);
	}

	public function setDevelopNo()
	{
		$req = \mvc::$req;
		\view::set('req', $req);
		\view::put();
	}

	public function proLink()
	{
		$req = \mvc::$req;
		\view::set('req', $req);
		\view::put();
	}

	public function getListProLink()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = explode(',', $req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		$pro = new pro();
		$data = $pro->getListProLink($req['p_id'], $req, $rules);
		$this->successJson($data);
	}

	public function syncProPic()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$p_id = explode(',', $req['p_id']);
		$data = $pro->synPic($p_id);
		$this->successJson($data);
	}

	public function getInnum()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->getAllInnum($req);
		$this->successJson($data);
	}

	public function doExcel()
	{
		set_time_limit(0);
		set_time_limit(\mvc::$cfg['bigtable_memory_limit']);
		$req = \mvc::$req;
		$synProPic = new synProPic();
		//excle文件目录
		if ($req['path']) {
			$path = $req['path'];
		} else {
			$path = \mvc::$cfg['dir']['files'] . '/pro.xlsx';
		}

		$data = $synProPic->savePicToExcel($path);
		$this->successJson($data);
	}


	/**
	 * @method 品牌商品
	 * @author zhengweihua 
	 * @copyright 2025-06-18
	 */
	public function pbProExt()
	{
		$req = \mvc::$req;

		$pro = new pro();
		$list = $pro->getProPbList();
		foreach ($list as $key => $val) {
			$arr[] = [
				'name' => $val['pb_name'],
				'src' =>  \mvc::$cfg['domain'] . '/pro/pbProList?pb_id=' . $val['pb_id']
			];
		}
		\view::set('arr', $arr);
		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 品牌商品页面
	 * @author zhengweihua 
	 * @copyright 2025-06-19
	 */
	public function pbProList()
	{
		$req = \mvc::$req;
		\view::set('req', $req);
		\view::set('allPos', $this->pro->allPos);
		\view::put();
	}

	public function getPbProList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = arryNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		if (isset($rules['findNulls']) && $rules['findNulls']) {
			$rules['findNulls'] = json_decode(base64_decode($rules['findNulls']), true);
		}
		if (isset($req['pb_id']) && $req['pb_id']) {
			$rules['proBrand'] = $req['pb_id'];
		}

		$pro = new pro();
		$data = $pro->getCodeList($req, $rules);
		$this->successJson($data);
	}

	/**
	 * @method 事业部商品列表
	 * @author zhengweihua 
	 * @copyright 2025-06-19
	 */
	public function compProExt()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$list = $pro->getPlcComList();
		foreach ($list as $key => $val) {
			$arr[] = [
				'name' => $val['com_name'],
				'src' =>  \mvc::$cfg['domain'] . '/pro/compProList?com_id=' . $val['com_id']
			];
		}
		\view::set('arr', $arr);
		\view::set('req', $req);
		\view::put();
	}
	/**
	 * @method 事业部商品
	 * @author zhengweihua 
	 * @copyright 2025-06-18
	 */
	public function compProList()
	{
		$req = \mvc::$req;

		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 获取事业部商品
	 * @author zhengweihua 
	 * @copyright 2025-06-19
	 */
	public function getCompProList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		if (isset($req['numbers'])) {
			$rules['numbers'] = arryNums($req['numbers']);
			$rules['numlike'] = empty($req['numlike']) ? 0 : $req['numlike'];
		}
		if (isset($rules['findNulls']) && $rules['findNulls']) {
			$rules['findNulls'] = json_decode(base64_decode($rules['findNulls']), true);
		}
		$pro = new pro();
		$data = $pro->compProList($req, $rules);
		$this->successJson($data);
	}

	public function linkcomp()
	{
		$req = \mvc::$req;

		\view::set('req', $req);
		\view::put();
	}

	/**
	 * @method 事业部相关信息
	 */
	public function getLinkcompList()
	{
		$req = \mvc::$req;
		$rules = $this->urlRulesToWhere($req);
		$pro = new pro();
		$data = $pro->compProList($req, $rules);
		$this->successJson($data);
	}

	/**
	 * @method 关联事业部信息详情
	 * @author zhengweihua 
	 * @copyright 2025-06-21
	 */
	public function compLinkDetail()
	{
		$req = \mvc::$req;
		$pro = new pro();
		// 主号列表
		$pnList = $pro->getCompProPnList($req['plc_id']);
		$showPnList = [];
		foreach ($pnList as $item) {
			$showPnList[] = $item['pn_id'].':'.$item['pf_name'].'：'.$item['pn_number'];
		}
		$showPnListString = implode(",",$showPnList);
		$data = $pro->compLinkDetail($req['plc_id']);
		\view::set('req', $req);
		\view::set('pnList',array_column($pnList,null,'pn_id'));
		\view::set('showPnListString',$showPnListString);
		\view::set('item', $data);
		\view::put();
	}

	/**
	 * 同步产品
	 */
	public function synPro()
	{
		$req = \mvc::$req;
		$start_date = $req['start_date'] ?? '2025-01-01';
		$pro = 	new pro();
		$pro->synPro($start_date);
	}

	/**
	 * @method 初始化产品关联事业部
	 * @author zhengweihua 
	 * @copyright 2025-06-23
	 */
	public function initProLinkCompany()
	{
		set_time_limit(0);
		$req = \mvc::$req;
		$productIds = [];
		if ($req['productIds'] && !is_array($req['productIds'])) {
			$productIds = explode(',', $req['productIds']);
		}
		$pro = 	new pro();
		$data = $pro->initProLinkCompany($productIds);
		$this->successJson($data);
	}

	/**
	 * @method 资源库
	 * @author zhengweihua 
	 * @copyright 2025-06-27
	 */
	public function sourceSearch()
	{
		$req = \mvc::$req;
		if ($req['nums'] && !is_array($req['nums'])) {
			$req['nums'] = explode("\r\n", strtr($req['nums'], [',' => "\r\n"]));
		}
		\view::set('req', $req);
		\view::put();
	}


	public function sourceSearchList()
	{
		$req = \mvc::$req;
		if (!$req['num'] && !$req['keyword']) $this->successJson([]);
		$rcaApi = new rcaApi();

		if ($req['type'] == 'num') {
			$numArr = splitNums($req['num'], $req['splitval']);
			$dataArr  = array_unique($numArr);
			$data = $rcaApi->getSourceSearch($dataArr);
			\view::set('datas', $data);
			$html = \view::fetch();
		} elseif ($req['type'] == 'keyword') {
			$data = $rcaApi->getFactorySearch($req['keyword']);
			\view::set('datas', $data);
			\view::set('from', 'rca');
			$html = \view::fetch('pro.factorySearchList');
		}

		\view::set('rownum', $req['rownum']);
		$this->successJson(['html' => $html]);
	}

	public function getResourcesUrlById()
	{
		$req = \mvc::$req;
		if (!$req['id']) $this->successJson([]);
		$rcaApi = new rcaApi();
		$data = $rcaApi->getResourcesUrlById($req['id']);
		$this->successJson($data);
	}


	/**
	 * @method 同步事业部商品图片
	 * @author zhengweihua 
	 * @copyright 2025-07-17
	 */
	public function synCompanyPic()
	{
		$req = \mvc::$req;
		if (!$req['p_id'] && !$req['p_innum']) $this->successJson([]);

		$pro = new pro();
		if ($req['p_id']) {

			$p_id = explode(',', $req['p_id']);
			$data = $pro->synCompanyPic($p_id);
		} elseif ($req['p_innum']) {

			$p_innum = explode(',', $req['p_innum']);
			$data = $pro->synCompanyPic([], $p_innum);
		}
		$this->successJson($data);
	}

	/**
	 * @method 资源库
	 * @author zhengweihua 
	 * @copyright 2025-06-27
	 */
	public function sourceSearchYp()
	{
		$req = \mvc::$req;
		if ($req['nums'] && !is_array($req['nums'])) {
			$req['nums'] = explode("\r\n", strtr($req['nums'], [',' => "\r\n"]));
		}
		\view::set('req', $req);
		\view::put();
	}


	/**
	 * @method
	 * @author zhengweihua 
	 * @copyright 2025-07-21
	 */
	public function sourceSearchYpList()
	{
		$req = \mvc::$req;
		if (!$req['num'] && !$req['keyword']) $this->successJson([]);

		$ypRcaApi = new ypRcaApi();
		if ($req['type'] == 'num') {
			$numArr = splitNums($req['num'], $req['splitval']);
			$dataArr  = array_unique($numArr);
			$data = $ypRcaApi->getSourceSearch($dataArr);
			\view::set('datas', $data);
			$html = \view::fetch();
		} elseif ($req['type'] == 'keyword') {
			$data = $ypRcaApi->getFactorySearch($req['keyword']);
			\view::set('datas', $data);
			\view::set('from', 'yp');
			$html = \view::fetch('pro.factorySearchList');
		}
		\view::set('rownum', $req['rownum']);
		$this->successJson(['html' => $html]);
	}

	/**
	 * @method 工厂详情(宜配)
	 * @author zhengweihua 
	 * @copyright 2025-07-21
	 */
	public function factoryYpDetail()
	{
		$req = \mvc::$req;
		if (!$req['id']) $this->exitJson(-1, '参数错误');

		$ypRcaApi = new ypRcaApi();
		$res = $ypRcaApi->Get('resourcefactory/get', [], ['id' => $req['id']]);

		\view::set('dataArr', $res['data']);
		\view::put();
	}

	/**
	 * @method 删除发动机字段的重复数据
	 * @author zhengweihua 
	 * @copyright 2025-07-21
	 */
	public function removeEngineDuplicates()
	{
		set_time_limit(0);
		ini_set('memory_limit', \mvc::$cfg['bigtable_memory_limit']);
		$pro = new pro();
		$data = $pro->removeEngineDuplicates();
		$this->successJson($data);
	}

	public function checkIsFgioBrand()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->checkIsFgioBrand($req['p_id']);
		$this->successJson($data);
	}

	public function getOeItem()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->getOeItemByPid($req);
		$this->successJson($data);
	}

	/**
	 * @method 变更所属零件
	 * @author zhengweihua 
	 * @copyright 2025-10-20
	 */
	public function changeProOe()
	{
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->changeProOe($req);
		$this->successJson($data);
	}

	public function getRowByPid($pid)
	{
		if ($pid) {
			$data = $this->pro->getDetail($pid);
			if (!empty($data)) {
				$returnData = [
					'p_comnum' => $data['p_comnum'],
					'p_innum' => $data['p_innum'],
					'p_cate' => $data['cat_name'],
					'p_id' => $data['p_id'],
					'main_pic' => $data['imgs']['img'][0]['smallImg'] ?? '',
					'p_oe' => $data['p_oe'],
					'p_name' => $data['p_' . LG_NAME],
					'pb_name' => $data['pb_name'],
					'pb_id' => $data['p_pb_id'],
				];
				$this->successJson($returnData);
			}
		}
		$this->successJson(0);
	}

	/**
	 * @method 批量上传图片
	 * @author zhengweihua 
	 * @copyright 2026-02-10
	 */
	public function batchUploadPic()
	{
		\view::put();
	}

	/**
	 * @method 处理批量上传图片
	 * @author zhengweihua 
	 * @copyright 2026-02-10
	 */
	public function batchUploadProPic()
	{
		$req = \mvc::$req;
		$filesArray = $req['filesArray'] ?? [];
		$pid = $req['pid'] ?? 0;

		if (empty($filesArray)) {
			$this->msgJson(lg('没有待处理的文件'));
		}

		$successCount = 0;
		$errorCount = 0;
		$results = [];

		foreach ($filesArray as $file) {
			$uploadProPicZip = new uploadProPicZip();
			$result = $uploadProPicZip->uploadSingleFileToOSS(
				$file['temp_path'],
				$file['original_name'],
				$file['pic_style'],
				$file['p_id']
			);

			if ($result['success']) {
				$successCount++;
				$results[] = [
					'filename' => $file['original_name'],
					'status' => 'success',
					'fileid' => $result['data']['fileid']
				];
			} else {
				$errorCount++;
				$results[] = [
					'filename' => $file['original_name'],
					'status' => 'error',
					'error' => $result['error']
				];
			}
		}
		$this->successJson([
			'total' => count($filesArray),
			'success' => $successCount,
			'error' => $errorCount,
			'results' => $results
		]);
	}

	/**
	 * 清理临时目录
	 */
	public function cleanupTempDir()
	{
		$req = \mvc::$req;
		$tempDir = $req['temp_dir'] ?? '';

		if (empty($tempDir) || !is_dir($tempDir)) {
			$this->successJson(['success' => true]);
		}

		try {
		
			//清理临时目录
			$uploadModel = make(\model\import\uploadProPicZip::class);
			$uploadModel->removeDir($tempDir);

			$this->successJson(['success' => true]);
		} catch (Exception $e) {
			$this->errorJson(500, $e->getMessage());
		}
	}

	/**
	 * @method 海报模板
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function picTpl()
	{
		$req = \mvc::$req;
		\view::put('pro/pic/picTpl');
	}
	/**
	 * @method 获取模板列表
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function getPicTplList()
	{
		$req = \mvc::$req;
		$picTpl = new picTpl();
		$data = $picTpl->getList($req);
		$this->successJson($data);
	}
	/**
	 * @method 新增模板界面
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function addPicTpl()
	{
		$req = \mvc::$req;
		$ptl_id = $req['id']??'';
		// 判断是更新还是新增
		$update = $req['update']??'';
		$text_cfg = [];
		$logo_cfg = [];
		$watermark_cfg = [];
		$qrcode_cfg = [];
		$background_cfg = [];
		$template_cfg = [];
		$ptl_lang = '';
		$ptl_name = '';
		$ptl_pb_id = '';
		$ptl_test_info = [];
		$hasTestProInfo = false;
		$picTpl = new picTpl();
		// 获取模板详情
		if($ptl_id){
			$detail = $picTpl->getTplCfg($ptl_id);
			$ptl_lang = $detail['ptl_lang'];
			$ptl_name = $detail['ptl_name'];
			$ptl_pb_id = $detail['ptl_pb_id'];
			$ptl_cfg = $detail['ptl_cfg'];
			$ptl_cfg = json_decode($ptl_cfg,true);
			foreach($ptl_cfg as $item){
				if($item['type']=='text'){
					$text_cfg[] = $item;
				}elseif($item['type']=='logo'){
					$logo_cfg = $item;
					$logo_cfg['val'] = \mvc::$cfg['path']['files'].'/pictpl/logo/'.$logo_cfg['val'];
				}elseif($item['type']=='watermark'){
					$watermark_cfg = $item;
					$watermark_cfg['val'] = \mvc::$cfg['path']['files'].'/pictpl/watermark/'.$watermark_cfg['val'];
				}elseif($item['type']=='qrcode'){
					$qrcode_cfg = $item;
					$qrcode_cfg['val'] = $qrcode_cfg['val'];
				}elseif($item['type']=='background'){
					$background_cfg = $item;
					if($background_cfg['mode']=='image' && !empty($background_cfg['val'])){
						$background_cfg['val'] = \mvc::$cfg['path']['files'].'/pictpl/bg/'.$background_cfg['val'];
					}
				}elseif($item['type']=='template'){
					$template_cfg = $item;
				}elseif($item['type']=='testProInfo'){
					$hasTestProInfo = true;
					$testProOInfo = $item;
				}
			}
			\view::set('ptl_id',$ptl_id);

			if($hasTestProInfo){
				$ptl_test_info = $picTpl->getProInfoByBrand($ptl_pb_id,$ptl_lang,$testProOInfo['p_id']);
			}else{
				$ptl_test_info = $picTpl->getProInfoByBrand($ptl_pb_id,$ptl_lang);
			}
		}else{
			$ptl_test_info = $picTpl->getProInfoByBrand();
		}
		\view::set('update',$update);
		\view::set('text_cfg',$text_cfg);
		\view::set('logo_cfg',$logo_cfg);
		\view::set('watermark_cfg',$watermark_cfg);
		\view::set('qrcode_cfg',$qrcode_cfg);
		\view::set('background_cfg',$background_cfg);
		\view::set('template_cfg',$template_cfg);
		\view::set('ptl_lang',$ptl_lang);
		\view::set('ptl_name',$ptl_name);
		\view::set('ptl_pb_id',$ptl_pb_id);
		\view::set('ptl_test_info',$ptl_test_info);
		$logoList = [];
		$watermarkList = [];
		$bgList = [];
		$logoDir = \mvc::$cfg['dir']['files'].'/pictpl/logo';
		$watermarkDir = \mvc::$cfg['dir']['files'].'/pictpl/watermark';
		$bgDir = \mvc::$cfg['dir']['files'].'/pictpl/bg';
		$logoBaseUrl = \mvc::$cfg['path']['files'].'/pictpl/logo';
		$watermarkBaseUrl = \mvc::$cfg['path']['files'].'/pictpl/watermark';
		$bgBaseUrl = \mvc::$cfg['path']['files'].'/pictpl/bg';
		$allowExt = ['jpg','jpeg','png','gif','bmp','webp'];
		// 获取语言列表
		$langList = \mvc::$cfg['LANGS'];
		// 获取pro_brand表中的品牌列表
		$proBrand = new picTpl();
		$brandList = $proBrand->getProBrandList('G500');
		// 读取logo目录下的文件
		if (is_dir($logoDir)) {
			$files = scandir($logoDir);
			foreach ($files as $file) {
				if ($file === '.' || $file === '..') {
					continue;
				}
				$full = $logoDir.'/'.$file;
				if (!is_file($full)) {
					continue;
				}
				$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
				if (!in_array($ext, $allowExt, true)) {
					continue;
				}
				$logoList[] = ['name'=>$file,'url'=>$logoBaseUrl.'/'.$file];
			}
		}
		// 读取水印目录下的文件
		if (is_dir($watermarkDir)) {
			$files = scandir($watermarkDir);
			foreach ($files as $file) {
				if ($file === '.' || $file === '..') {
					continue;
				}
				$full = $watermarkDir.'/'.$file;
				if (!is_file($full)) {
					continue;
				}
				$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
				if (!in_array($ext, $allowExt, true)) {
					continue;
				}
				$watermarkList[] = ['name'=>$file,'url'=>$watermarkBaseUrl.'/'.$file];
			}
		}

		// 读取背景图目录下的文件
		if (is_dir($bgDir)) {
			$files = scandir($bgDir);
			foreach ($files as $file) {
				if ($file === '.' || $file === '..') {
					continue;
				}
				$full = $bgDir.'/'.$file;
				if (!is_file($full)) {
					continue;
				}
				$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
				if (!in_array($ext, $allowExt, true)) {
					continue;
				}
				$bgList[] = ['name'=>$file,'url'=>$bgBaseUrl.'/'.$file];
			}
		}
		\view::set('langList',$langList);
		\view::set('pbList',$brandList);
		\view::set('logoList',$logoList);
		\view::set('watermarkList',$watermarkList);
		\view::set('bgList',$bgList);
		\view::put('pro/pic/addPicTpl');
	}
	/**
	 * @method 海报模板选择不同品牌时随机给一个商品信息
	 * @author hongzhang
	 * @copyright 2026-02-25
	 */
	public function getProInfoByBrand()
	{
		$req = \mvc::$req;
		$pb_id = $req['pb_id'];
		$lang = $req['langue'];
		// 改变语言的情况下，不改变现有的testProOInfo的其他值
		$p_id = $req['p_id'];
		$p_innum = $req['p_innum'];
		if(!$pb_id){
			$this->errorJson('未知品牌');
		}
		$proBrand = new picTpl();
		$proInfo = $proBrand->getProInfoByBrand($pb_id,$lang,$p_id,$p_innum);
		if(!$proInfo){
			$this->errorJson('该品牌下暂无商品');
		}
		$this->successJson($proInfo);
	}

	/**
	 * @method 海报模板预览图AI抠图
	 * @author hongzhang
	 * @copyright 2026-04-14
	 */
	public function getTplMattingImage()
	{
		$req = \mvc::$req;
		$source = $req['source'] ?? '';
		if (!$source) {
			$this->errorJson(-1, '图片地址不能为空');
		}
		if (empty(\mvc::$cfg['aiimg']['automatting'])) {
			$this->successJson(['image' => $source]);
		}
		// 图可丽的 mattingByUrl 需要公网可访问地址，模板图常为内网地址；
		// 这里统一先转为 base64，强制走上传文件通道(matting2)以避免回源失败。
		$sourceForMatting = $source;
		if (stripos($source, 'http') === 0) {
			$imgData = false;
			// 优先把 outfiles URL 映射到本地 files 目录读取，避免网络回源失败
			$outfilesUrl = rtrim(\mvc::$cfg['urls']['outfiles'] ?? '', '/');
			if ($outfilesUrl && stripos($source, $outfilesUrl . '/') === 0) {
				$relativePath = ltrim(substr($source, strlen($outfilesUrl)), '/');
				$relativePath = str_replace('/', DIRECTORY_SEPARATOR, $relativePath);
				$localPath = rtrim(\mvc::$cfg['dir']['files'], '\\/') . DIRECTORY_SEPARATOR . $relativePath;
				if (is_file($localPath)) {
					$imgData = @file_get_contents($localPath);
				}
			}
			if ($imgData !== false && strlen($imgData) > 0) {
				$mimeType = 'image/jpeg';
				$finfo = @finfo_open(FILEINFO_MIME_TYPE);
				if ($finfo) {
					$detectedType = @finfo_buffer($finfo, $imgData);
					@finfo_close($finfo);
					if ($detectedType && stripos($detectedType, 'image/') === 0) {
						$mimeType = $detectedType;
					}
				}
				$sourceForMatting = 'data:' . $mimeType . ';base64,' . base64_encode($imgData);
			} else {
				// 无法映射本地文件时直接回退原图，避免继续触发 mattingByUrl 报错
				$this->successJson(['image' => $source]);
			}
		}
		$aiImage = new aiImage();
		$imageData = $aiImage->matting([
			'source' => $sourceForMatting
		]);
		if (!$imageData) {
			$this->errorJson(-1, 'AI抠图处理失败');
		}
		$this->successJson(['image' => $imageData]);
	}
	/**
	 * @method 新模板入库
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function savePicTpl()
	{
		$req = \mvc::$req;
		$picTpl = new picTpl();
		$data = $picTpl->add($req);
		if(!$data['status']){
			$this->errorJson(-1,$data['msg']);
		}
		$this->successJson($data);
	}
	/**
	 * @method 更新模板
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function updatePicTpl()
	{
		$req = \mvc::$req;
		$id = $req['id'];
		$data = $req['data'];
		if(!$id){
			$this->errorJson('未知模板');
		}
		$picTpl = new picTpl();
		$data = $picTpl->update($id,$req);
		$this->successJson($data);
	}

	/**
	 * @method 删除模板
	 * @author hongzhang
	 * @copyright 2026-02-10
	 */
	public function delPicTpl()
	{
		$req = \mvc::$req;
		$idArr = [];
		if($req['ids']){
			$idArr = explode(',',$req['ids']);
		}
		$picTpl = new picTpl();
		$data = $picTpl->del($idArr);
		$this->successJson($data);
	}

	/**
	 * @method 应用模板界面
	 * @author hongzhang
	 * @copyright 2026-02-11
	 */
	public function setPicTpl()
	{
		$req = \mvc::$req;
		$pic_fileid = $req['id'];
		// 获取商品信息
		$picTpl = new picTpl();
		$tplShowInfo = $picTpl->getTplInfo($pic_fileid);
		\view::set('tplShowInfo',$tplShowInfo);
		// 获取模板信息
		$tplList = $picTpl->getListSimple();
		\view::set('tplList',$tplList);
		\view::set('pic_fileid',$pic_fileid);
		\view::put('pro/pic/setPicTpl');
	}

	/**
	 * @method 图片绑定模板
	 * @author hongzhang
	 * @copyright 2026-02-11
	 */
	public function bindPicTpl()
	{
		$req = \mvc::$req;
		$p_id = $req['p_id'];
		$pic_fileid = $req['pic_fileid'];
		$tpl_id = $req['tpl_id'];
		// 绑定模板
		$picTpl = new picTpl();
		$data = $picTpl->bindTpl($p_id,$pic_fileid,$tpl_id);
		$this->successJson($data);
	}

	/**
	 * @method 图片模板单元格编辑
	 * @author hongzhang
	 * @copyright 2026-02-11
	 */
	public function editPicTplCell()
	{
		$req = \mvc::$req;
		$picTpl = new picTpl();
		$picTpl->updateCell($req);
		echo json_encode(['msg'=>'']);
		exit;
	}
	/**
	 * @method 获取品牌列表(除集团品牌)
	 * @author hongzhang
	 * @copyright 2026-02-28
	 */
	public function getProPbList(){
		$pro = new pro();
		$list = $pro->getProPbList();
		$data = [];
		foreach($list as $item){
			$data[] = ['key'=>$item['pb_id'],'value'=>$item['pb_name']];
		}
		$this->successJson($data);
	}
	/**
	 * @method 根据产品id获取其汽车品牌
	 * @author hongzhang
	 * @copyright 2026-02-28
	 */
	public function getComnumTbList(){
		$req = \mvc::$req;
		$p_id = $req['p_id'];
		$pro = new pro();
		// 先根据产品id回溯到集团一级的层面
 		$list = $pro->getProTbList($p_id);
		$data = [];
		foreach($list as $item){
			$data[] = ['key'=>$item['tb_id'],'value'=>$item['tb_name']];
		}
		$this->successJson($data);
	}
	/**
	 * @method 获取事业部列表
	 * @author hongzhang
	 * @copyright 2026-02-28
	 */
	public function getCompanyList(){
		$pro = new pro();
		$list = $pro->getCompanyList();
		$data = [];
		foreach($list as $item){
			$data[] = ['key'=>$item['com_id'],'value'=>$item['com_name']];
		}
		$this->successJson($data);
	}

	/**
	 * @method 创建品牌物料
	 * @author hongzhang
	 * @copyright 2026-02-28
	 */
	public function createBrandPro(){
		$req = \mvc::$req;
		$p_id = $req['p_id'];
		$p_pb_id = $req['p_pb_id'];
		$p_tb_id = $req['p_tb_id'];
		$com_id = $req['com_id'];
		$pro = new pro();
		$data = $pro->createBrandPro($p_id,$p_pb_id,$p_tb_id,$com_id);
		$this->successJson($data);
	}

	/**
	 * @method 品牌物料添加事业部
	 * @author hongzhang
	 * @copyright 2026-03-02
	 */
	public function addCompanyToPro(){
		$req = \mvc::$req;
		$p_id = $req['p_id'];
		$com_ids = explode(',',$req['com_id']);
		if(!$com_ids){
			$this->errorJson('请选择事业部');
		}
		$pro = new pro();
		$data = $pro->addCompanyToPro($p_id,$com_ids);
		$this->successJson($data);
	}

	/**
	 * @method 批量添加事业部
	 * @author hongzhang
	 * @copyright 2026-07-16
	 */
	public function batchAddCompanyToPro(){
		$req = \mvc::$req;
		// 权限验证
		if(!\p::isAdmin() && !\p::has('B100', 'edit')){
			$this->errorJson('无权限执行此操作');
		}
		$p_ids = $req['p_ids'];
		if(!$p_ids){
			$this->errorJson('请选择商品');
		}
		$p_ids = explode(',', $p_ids);
		$com_ids = explode(',', $req['com_id']);
		if(empty($com_ids)){
			$this->errorJson('请选择事业部');
		}
		$pro = new pro();
		$data = $pro->batchAddCompanyToPro($p_ids, $com_ids);
		if(isset($data['code']) && $data['code'] < 0){
			$this->errorJson($data['msg']);
		}
		$this->successJson($data);
	}

	/**
	 * @method 更新事业部商品
	 * @author hongzhang
	 * @copyright 2026-03-03
	 */
	public function saveCompPro(){
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->updateCompPro($req);
		$this->successJson($data);
	}

	/**
	 * @method 按物料编码查含此商品的事业部列表
	 * @author hongzhang
	 * @copyright 2026-07-28
	 */
	public function getCompProComListByInnum(){
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->getCompProComListByInnum($req['innum']);
		$this->successJson($data);
	}

	/**
	 * @method 按物料编码取主号列表
	 * @author hongzhang
	 * @copyright 2026-07-28
	 */
	public function getCompProPnListByInnum(){
		$req = \mvc::$req;
		$pro = new pro();
		$data = $pro->getCompProPnListByInnum($req['innum']);
		$this->successJson($data);
	}

	/**
	 * @method 批量更新事业部商品
	 * @author hongzhang
	 * @copyright 2026-07-28
	 */
	public function batchUpdateCompPro(){
		$req = \mvc::$req;
		$pro = new pro();
		$fields = isset($req['fields']) ? json_decode($req['fields'], true) : [];
		if(!$fields) $fields = [];
		$data = $pro->batchUpdateCompPro($req['plc_ids'], $fields);
		$this->successJson($data);
	}

	/**
	 * @method 删除事业部商品
	 * @author hongzhang
	 * @copyright 2026-03-03
	 */
	public function deleteCompanyToPro(){
		$req = \mvc::$req;
		$ids = $req['ids'];
		if(!$ids){
			$this->errorJson('请选择事业部');
		}
		$pro = new pro();
		$data = $pro->deleteCompanyToPro($ids);
		$this->successJson($data);
	}

	/**
	 * @method 比较修改值，返回需要同步的字段
	 * @author hongzhang
	 * @copyright 2026-03-03
	 */
	public function compareAsync(){
		$req = \mvc::$req;
		// 需要同步到事业部物料的字段
		$asyncToCompPro = ['p_state_main','p_chassis','p_model_year','p_engine','p_cc'];
		// 需要同步到商品物料的字段
		$asyncToPro = ['p_state_main','p_chassis','p_model_year','p_engine','p_cc','p_standard_name','p_unit','p_state_remark','p_iskit','p_fuel_type'];
		foreach(\mvc::$cfg['LANGS'] as $lk=>$lv){
			$asyncToCompPro[] = 'p_'.$lv['field'];
			$asyncToCompPro[] = 'p_model_'.$lv['field'];
			$asyncToPro[] = 'p_'.$lv['field'];
			$asyncToPro[] = 'p_model_'.$lv['field'];
			$asyncToPro[] = 'p_des_'.$lv['field'];
		}
		$pro = new pro();
		$data = $pro->compareAsync($req,$asyncToCompPro,$asyncToPro);
		$this->successJson($data);
	}

	public function syncPosFromLinkParent()
	{
		$data = $this->pro->syncPosFromLinkParent();
		$this->successJson($data);
	}

}
