<?php
namespace model\homecn;
use \model;
use \model\work;
use \model\pro\cate;
/**
 * Class userpowerMod
 * @author
 * @copyright
 */
class trade extends \model
{

	function getTradeComBase()
	{
		$companys = $this->db->select('company',['com_id', 'com_'.LG_NAME.'(com_name)'], ['ORDER'=>'com_'.LG_NAME]);
		return ['company'=>$companys];
	}

	//通过客户代码查询上一次询单的客户基本信息
	public function getUcodeInfo($ucode)
	{
		$row = [];
		if($ucode)
			$row = $this->db->get('work_ask',['was_uname', 'was_utel', 'was_com_id'], ['was_u_code'=>$ucode, 'ORDER'=>['was_id'=>'DESC']]);
		return $row?:[];
	}

    /**
     * @param  用户 $uid
     * @param  Array $dataArr
     * @method 新增询单
     * @author zhengweihua 
     * @copyright 2025-02-25
     */
    public function addTrade($uid, $dataArr)
    {
		$datetime = getNowTime();
		$add = [];
		foreach($dataArr['ask'] as $k=>$v){
			if(stripos($k, 'was_') === 0) $add[$k] = $v;
		}
		if(!$add['was_title']) exitJson(0,'标题必填');
		if(!$add['was_u_code']) exitJson(0,'客户编码必填');
		if(!$add['was_com_id']) exitJson(0,'事业部必填');
		if(!$add['was_uname']) exitJson(0,'联系人必填');
		if(!$add['was_utel']) exitJson(0,'联系电话必填');

		$add['was_u_id'] = $uid;
		$add['was_create_time'] = $datetime;
		$add['was_update_time'] = $datetime;
		if(!empty($dataArr['exceldata'])){
			$coltyp = []; $colArr = [];
			foreach($dataArr['colcfg'] as $type=>$cvs){
				foreach($cvs as $cv){
					$coltyp[$cv]  = $type;
				}
			}
			foreach($dataArr['exceldata'][0] as $colk=>$colname){
				$colArr[$colk] = ['colnum'=>$colk, 'name'=>$colname, 'type'=>$coltyp[$colk]? : 'Oth'];
			}
			$add['was_cols'] = json_encode($colArr, JSON_UNESCAPED_UNICODE);
		}


        $this->db->Begin();
        $this->db->insert('work_ask', $add);
        $was_id = $this->db->id();
		if(!empty($dataArr['exceldata'])){
			foreach($dataArr['exceldata'] as $line=>$dv){
				if($line === 0) continue;
				$orgData = $dv;
				$item = [];
				foreach($colArr as $ck=>$cv){
					if($cv['type'] == 'Number'){
						$tnums = $this->formatTradeNum($orgData[$ck]);
						$item['nums'] = $item['nums']? array_merge($item['nums'], $tnums): $tnums;
					}else if($cv['type'] == 'ProName'){
						$item['wai_name'] = $orgData[$ck];
					}else if($cv['type'] == 'Uprice'){
						$item['wai_uprice'] = sprintf("%.2f", $orgData[$ck]);
					}else if($cv['type'] == 'ProCount'){
						$item['wai_count'] = (int) $orgData[$ck];
					}else if($cv['type'] == 'Image'){
						$imgInfo = $dv[$ck];
						if(isset($imgInfo['path']) && $imgInfo['path'] && $imgInfo['ext']){
							$imagname = substr(md5($imgInfo['path']), 8, 16).'.'.$imgInfo['ext'];
							$imgPath = 'workask/'.date('Ym');
							$imagefile = \mvc::$cfg['dir']['files'].'/'.$imgPath.'/'.$imagname;
							mkdirs(\mvc::$cfg['dir']['files'].'/'.$imgPath);
							if(!file_exists($imagefile)){
								switch ($imgInfo['ext']) {
									case 'jpg':
									case 'jpeg':
										$source = imagecreatefromjpeg($imgInfo['path']);
										imagejpeg($source, $imagefile);
										break;
									case 'gif':
										$source = imagecreatefromgif($imgInfo['path']);
										imagegif($source, $imagefile);
										break;
									case 'png':
										$source = imagecreatefrompng($imgInfo['path']);
										imagepng($source, $imagefile);
										break;
								}
							}
							$orgData[$ck] = $imgPath.'/'.$imagname;
						}else{
							$orgData[$ck] = '';
						}
					}
				}
				$item['wai_data'] = json_encode($orgData, JSON_UNESCAPED_UNICODE);
				$this->addAskItem($was_id, $item);
			}
		}else{
			//手工添加
			foreach ($dataArr['item'] as $item) {
				$item['nums'] = $this->formatTradeNum($item['nums']);
				$this->addAskItem($was_id, $item);
			}
		}

		//匹配分类
		$this->autoChkAsk([$was_id]);
		
		//自动填充价格
		$this->autoAskItemPrice([$was_id]);
		
		//无零件的自动转数据单
		$wai_ids = $this->db->select('work_ask_item', 'wai_id', ['wai_was_id'=>$was_id, 'wai_oe_id'=>0]);
		if($wai_ids){
			$work = new work();
			$work->askItemToWorkOrder($wai_ids);
		}

		$this->resetAskTotal($was_id);
        $this->db->End();
        return ['was_id'=>$was_id];
    }
	
	//数量或者价格发生变化重新汇总
	public function resetAskTotal($was_id)
	{
		//更新总数
		$sql = sprintf("UPDATE work_ask wa
			JOIN (SELECT wai_was_id, SUM(wai_count) AS total_count, COUNT(*) AS item_count, SUM(wai_money_total) AS total_money FROM work_ask_item WHERE wai_was_id = %d GROUP BY wai_was_id) AS items ON wa.was_id = items.wai_was_id 
			SET wa.was_count_total = items.total_count, wa.was_item_total = items.item_count, wa.was_money_total = items.total_money WHERE wa.was_id = %d", $was_id, $was_id);
		$this->db->query($sql);
	}


	//添加询单明细
	public function addAskItem($was_id, $item)
	{
		$datetime = getNowTime();
		$wai_id = 0;
		if($item['nums']){
			$this->db->Begin();
			$wdli = [
				'wai_was_id'=>$was_id,
				'wai_name'=>$item['wai_name'],
				'wai_uprice'=>$item['wai_uprice'],
				'wai_count'=>$item['wai_count'] > 0 ? $item['wai_count']: 1,
				'wai_data'=>$item['wai_data']? $item['wai_data']: '{}',
				'wai_create_time'=>$datetime,
				'wai_update_time'=>$datetime
			];
			$this->db->insert('work_ask_item', $wdli);
			$wai_id = $this->db->id();
			$addnums = [];
			foreach($item['nums'] as $tnumArr){
				$uniwhere = [
					'wain_wai_id'=>$was_id,
					'wai_name'=>$wdli['wai_name'],
					'wain_format'=>$tnumArr['wain_format'],
					'wain_pf_name'=>$tnumArr['wain_pf_name']
				];
				$chk = $this->db->get('work_ask_item_num(wdif)', ["[><]work_ask_item(wdi)"=>["wdif.wain_wai_id" =>"wai_id"]], ['wain_id'], $uniwhere);
				if(empty($chk)){
					$tnumArr['wain_was_id'] = $was_id;
					$tnumArr['wain_wai_id'] = $wai_id;
					$addnums[$tnumArr['wain_format'].$tnumArr['wain_pf_name']] = $tnumArr;
				}
			}
			if($addnums) $this->db->insert('work_ask_item_num', array_values($addnums));
			$this->db->End();
		}
		return $wai_id;
	}
	
	//字符串格式化号码
	public function formatTradeNum($strNums)
	{
		$arr = [];
		$tnums = strtr($strNums, ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
		foreach(explode(',', $tnums) as $tnum){
			if(empty($tnum)) continue;
			$fac = '';
			$tvs = explode(':', $tnum);
			if(count($tvs) >= 2){
				$fac = $tvs[0];
				$tnum = $tvs[1];
			}else{
				$tnum = $tvs[0];
			}
			$tnumArr = [
				'wain_pf_name'=>$fac,
				'wain_number'=>$tnum,
				'wain_format'=>formatNum($tnum)
			];
			if($tnumArr['wain_format']) $arr[] = $tnumArr;
		}
		//数组本身去重
		$arr = array_map('unserialize', array_unique(array_map('serialize', $arr)));
		return $arr;
	}


	/**
	 * 自动匹配询单的零件
	 * @return string
	 */
	public function autoChkAsk($was_ids = [], $wai_ids = [])
	{
		$where = ['wai_oe_id'=>0];
		if(!empty($wai_ids)){
			$where['wai_id'] = $wai_ids;
		}else if(!empty($was_ids)){
			$where['wai_was_id'] = $was_ids;
		}
		$items = $this->db->select('work_ask_item', ['wai_id', 'wai_name', 'wai_oe_id', 'wai_cat_id'], $where);
		if($items){
			$sql = sprintf("SELECT wai_id, wai_name, oe_id, oe_cate_id FROM work_ask_item_num
			JOIN work_ask_item ON wai_id = wain_wai_id
			JOIN oe_numidx ON wain_format=on_formart 
			JOIN oe_item ON on_oe_id=oe_id
			JOIN pro_factory ON pf_id = oe_pf_id AND (pf_name = wain_pf_name OR wain_pf_name = '')
			WHERE wai_oe_id = 0 and wai_id in (%s) GROUP BY wai_id", implode(',', array_column($items, 'wai_id')));
			$rows = $this->db->query($sql)->fetchAll();
			$has = $rows? array_column($rows, null, 'wai_id') : [];
			$cate = new cate();
			$this->db->Begin();
			foreach($items as $v){
				$setArr = [];
				if(empty($v['wai_oe_id']) && !empty($has[$v['wai_id']])){
					$setArr['wai_cat_id'] = $has[$v['wai_id']]['oe_cate_id'];
					$setArr['wai_oe_id'] = $has[$v['wai_id']]['oe_id'];
					$setArr['wai_oebind_time'] = getNowTime();
				}else if(empty($v['wai_cat_id']) && $v['wai_name']){
					$tid = $cate->eqname($v['wai_name']);
					if(!empty($tid)) $setArr['wai_cat_id'] = $tid;
				}
				if($setArr) $this->db->update('work_ask_item', $setArr, ['wai_id'=>$v['wai_id']]);
			}
			$this->db->End();
		}
		return [];
	}


	/**
	 * 零件号码变更触发自动匹配询单的零件
	 * @return 变更的询单明细ID
	 */
	public function autoChkAskByPoeChange($oeIds = [])
	{
		$change_ids = [];
		$sql = "SELECT wai_id, wai_name, oe_id, oe_cate_id FROM work_ask_item_num
		JOIN work_ask_item ON wai_id = wain_wai_id
		JOIN oe_numidx ON wain_format=on_formart 
		JOIN oe_item ON on_oe_id=oe_id
		JOIN pro_factory ON pf_id = oe_pf_id AND (pf_name = wain_pf_name OR wain_pf_name = '')
		WHERE wai_oe_id = 0";
		if($oeIds) $sql .= sprintf(" and oe_id in (%s)", implode(',', $oeIds));
		$items = $this->db->query($sql)->fetchAll();
		$has = $items? array_column($items, null, 'wai_id') : [];
		$cate = new cate();
		$this->db->Begin();
		foreach($items as $v){
			$setArr = [];
			$setArr['wai_cat_id'] = $has[$v['wai_id']]['oe_cate_id'];
			$setArr['wai_oe_id'] = $has[$v['wai_id']]['oe_id'];
			$setArr['wai_oebind_time'] = getNowTime();
			$change_ids[] = $v['wai_id'];
			$this->db->update('work_ask_item', $setArr, ['wai_id'=>$v['wai_id']]);
		}
		$this->db->End();
		return $change_ids;
	}

	/**
	 * 自动填充价格
	 */
	public function autoAskItemPrice($was_ids = [], $wai_ids = [], $oe_ids = [])
	{
		$where = ['wai_status'=>0, 'wai_cost_price'=>0, 'wai_price'=>0];
		if(!empty($wai_ids)){
			$where['wai_id'] = $wai_ids;
		}else if(!empty($was_ids)){
			$where['wai_was_id'] = $was_ids;
		}else if(!empty($oe_ids)){
			$where['wai_oe_id'] = $oe_ids;
		}
		$items = $this->db->select('work_ask_item(wai)', ["[><]work_ask(was)" => ["wai.wai_was_id" => "was_id"]], '*', $where);
		if($items){
			$work = new work();
			$opuser = getOpuser();
			$datetime = getNowTime();
			$this->db->Begin();
			$change_was_ids = [];
			$priceAllRes = $work->getAskItemRefPrice(array_column($items, 'wai_id'), 'autoPrice');
			foreach($items as $v){
				if(!$priceAllRes[$v['wai_id']]) continue;
				$flag = false;
				$priceRes = $priceAllRes[$v['wai_id']];
				foreach(['old_ask', 'sup_pro'] as $type){
					if(empty($priceRes[$type])) continue;
					foreach($priceRes[$type] as $refprice){
						$setArr = [];
						$setArr['wai_refprice'] = json_encode($refprice, JSON_UNESCAPED_UNICODE);
						if(isset($refprice['wai_cost_price'])){
							//非询价加点
							if($refprice['from_type'] != 'old_ask'){
								$refprice['wai_cost_price'] *= \mvc::$cfg['askSupProPriceRate'];
								$refprice['wai_price'] *= \mvc::$cfg['askSupProPriceRate'];
							}
							$setArr['wai_cost_price'] = $refprice['wai_cost_price'];
							$setArr['wai_price'] = $refprice['wai_price']/$v['was_money_rate'];
							$setArr['wai_cost_status'] = 1;
							if($refprice['was_money_rate']) $setArr['wai_price'] = $setArr['wai_price']*$refprice['was_money_rate'];//转CNY
						}else if($refprice['from_type'] == 'pro_api' && isset($refprice['wai_price'])){
							$setArr['wai_price'] = $refprice['wai_price']/$old['was_money_rate'];
							if($refprice['was_money_rate']) $setArr['wai_price'] = $setArr['wai_price']*$refprice['was_money_rate'];//转CNY
						}
						//同步其他字段
						foreach(['wai_sup_id', 'wai_pb_id', 'wai_hasshui', 'wai_tuishui', 'wai_haspack', 'wai_delivery', 'wai_minbuy'] as $field){
							if(isset($refprice[$field])) $setArr[$field] = $refprice[$field];
						}
						if(empty($setArr['wai_sup_id']) && !empty($refprice['sup_id'])) $setArr['wai_sup_id'] = (int) $refprice['sup_id'];
						if(empty($setArr['wai_pb_id']) && !empty($refprice['pb_id'])) $setArr['wai_pb_id'] = (int) $refprice['pb_id'];
						if($setArr['wai_price'] > 0) $setArr['wai_status'] = 1;
						$setArr['wai_money_total'] = raw("wai_price*wai_count");
						if($setArr['wai_cost_price'] || $setArr['wai_price']){
							$setArr['wai_opuser'] = $opuser;
							$setArr['wai_update_time'] = $datetime;
							$this->db->update('work_ask_item', $setArr, ['wai_id'=>$v['wai_id']]);
							$change_was_ids[] = $v['was_id'];
							$flag = true;
							break;
						}
					}
					if($flag) break;
				}
			}
			$change_was_ids = array_unique($change_was_ids);
			foreach($change_was_ids as $was_id){
				$this->resetAskTotal($was_id);
			}
			$this->db->End();
		}
		return [];
	}

    public function detail($was_id)
    {   	

        $data = [];
        $oeArr = [];
        $data['total_pro'] = 0;
        $data['total_money'] = 0;
		$join = ["[>]user(wdl)" => ["was.was_u_id" => "u_id"]];
        $data = $this->db->get('work_ask(was)', $join,['was.*','wdl.u_name'],['was_id'=>$was_id]);
        if($data){
			$join = [
				"[>]pro_brand(pb)" => ["wai_pb_id" => "pb_id"]
			];
            $rows = $this->db->select('work_ask_item',$join,'*',['wai_was_id'=>$was_id]);
			$data['itemArr'] = array_column($rows, null, 'wai_id');
            if($data['itemArr']){
				$rows = $this->db->select('work_ask_item_num','*',['wain_was_id'=>$was_id]);
				foreach($rows as $row){
					$data['itemArr'][$row['wain_wai_id']]['nums'][] = $row['wain_pf_name']? $row['wain_pf_name'].':'.$row['wain_number']: $row['wain_number'];
				}
                $oeIdArr = array_unique(array_filter(array_column($data['itemArr'],'wai_oe_id')));
                if($oeIdArr){
                    $join = [
						'[><]pro_factory'=>['oe_pf_id'=>'pf_id'],
                        '[><]oe_pic(pic)'=>['oe_pic'=>'pic_fileid'],
                        '[><]files'=>['pic.pic_fileid'=>'fileid']
                    ];
                    $res = $this->db->select('oe_item',$join,['oe_id','oe_oe','oe_model_cn_name','oe_model_en_name','pf_name','oe_'.LG_NAME.'(oe_name)','files.*'],['oe_id'=>$oeIdArr]);
                    foreach ($res as $pic) {
						$oeArr[$pic['oe_id']]['oe_num'] = $pic['pf_name']? $pic['pf_name'].':'.$pic['oe_oe'] : $pic['oe_oe'];
                        $oeArr[$pic['oe_id']]['oe_name'] = $pic['oe_name'];
                        $oeArr[$pic['oe_id']]['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
					    $oeArr[$pic['oe_id']]['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
                    }
                }
                $collArr = $this->db->select('object', ['o_parent_id', 'o_id', LG_NAME], ['o_parent_id'=>16]);
		        $collArr = array_column($collArr, LG_NAME, 'o_id');
                foreach ($data['itemArr'] as $key => &$val) {
					$val['wai_data'] = empty($val['wai_data']) ? []: json_decode($val['wai_data'], true);
                    $val['oe_name'] = '';
                    $val['bigImg'] = '';
                    $val['smallImg'] = '';
                    $val = array_merge($val,$oeArr[$val['wai_oe_id']]??[]);

                    $val['wai_material_name'] =  $collArr[$val['wai_material']];
                    $data['total_pro'] += $val['wai_count'];
                    if($val['wai_price'] > 0){
                        //如果是外币
                        // if($data['was_money_type'] && $data['was_money_rate']>0){
                        //     $val['wai_price'] = sprintf('%.2f',$val['wai_price']/$data['was_money_rate']);
                        // }
                        $data['total_money'] += sprintf('%.2f',$val['wai_count']*$val['wai_price']);
                    }
					$val['captions'] = [
						'wai_pb_id'=> $val['pb_'.LG_NAME]?:$val['pb_cn_name']
					];
                }
                unset($val);
            }
        }
		// dd($data);die;
        return $data;
    }

    public function getLists($uid,$params)
    {
        $page = $params['page']?:1;
        $pagesize = $_COOKIE['pagesize']?:10;

        $where = ['was_u_id'=>$uid];
        $total = $this->db->count('work_ask',$where);
        if($total>0){
            $where["LIMIT"] = [($page-1)*$pagesize,$pagesize];
            $where["ORDER"] = ['was_id'=>'DESC'];
            $data = $this->db->select('work_ask','*',$where);
            if(!$data){
                return  [
                    'page'=>$page,
                    'pagesize'=>$pagesize,
                    'recordCount'=>$total?:0,
                    'list'=>[]
                ]; 
            }
            $wasIdArr = array_column($data,'was_id');
            //子项
            $itemArr = $this->db->select('work_ask_item',['[><]work_ask'=>['wai_was_id'=>'was_id']],['work_ask.*','wai_id','wai_was_id','wai_name','wai_price','wai_count'],['wai_was_id'=>$wasIdArr]);
            $arr = [];
            $cntArr = [];
            $priceArr = [];
            foreach ($itemArr as $key => $item) 
            {
                $arr[$item['wai_was_id']][] = $item;
                if($item['wai_price']){
                    // if($item['was_money_type'] && $item['was_money_rate']>0){
                    //     $item['wai_price'] = sprintf('%.2f',$item['wai_price']/$item['was_money_rate']);
                    // }
                    $priceArr[$item['wai_was_id']] += sprintf('%.2f',$item['wai_count'] * $item['wai_price']);
                }
                $cntArr[$item['wai_was_id']] += $item['wai_count'];
            }

            foreach ($data as $key => $val) {
                $data[$key]['itemArr'] = $arr[$val['was_id']]?:[];
                $data[$key]['count'] = $cntArr[$val['was_id']]?:'';
                $data[$key]['price'] = $priceArr[$val['was_id']]?:'';
            }
        }
        return  [
            'page'=>$page,
            'pagesize'=>$pagesize,
            'recordCount'=>$total?:0,
            'list'=>$data?:[]
        ];
    }

    public function delData($uid,$id)
    {
        if(!is_array($id)){
            $id = explode(',',$id);
        }
        $idArr = $this->db->select('work_ask','was_id',['was_id'=>$id,'was_u_id'=>$uid]);
		$work = new work();
		$work->delData('work_ask', $idArr);
        return [];
    }

	/**
	 * @param  int $was_id
	 * @method 导出询价单
	 * @author zhengweihua 
	 * @copyright 2025-07-07
	 */
	public function exportTrade($was_id, $uid)
	{	
		$detail = $this->detail($was_id);
		if(!$detail['was_status']) exitJson(-1,'未完成，不可导出');
		$was_money_type = ($detail['was_money_type']?'（'.$detail['was_money_type'].'）':'');
		function processBatchData($data,$fields,&$drawImgRanges, &$wrapTextRanges, &$brow){
			foreach ($data as $v) {
				$row = [];
				$col = 0;
				$bcol = 'A';
				// 写入主数据
				foreach ($fields as $fk => $fv) {
					
					if($fk=='wai_total_price'){
						// 小计
						$v['wai_total_price'] = isset($v['wai_price']) && !empty($v['wai_price'])? sprintf('%.2f', $v['wai_price'] * $v['wai_count']) : '';
					}
					//不显示0.00
					if(in_array($fk,['wai_cost_price','wai_price'])){
						$v[$fk] = $v[$fk] != 0?$v[$fk]:'';
					}
					if(stripos($fk, 'wai_data')!==false && $fv['colnum']){
						$val = $v['wai_data'][$fv['colnum']]?:'';
					}else{
						$val = isset($v['captions'][$fk]) ?$v['captions'][$fk]: (isset($v[$fk]) && !empty($v[$fk])  ? $v[$fk]: '');
						if($val===0) $val = '';
					}

					$val = is_array($val) ? implode("\n", $val) : $val;
					$row[$col] = $val;

					// 如果值中包含 \n，记录单元格范围
					if (stripos($val, "\n") !== false) {
						$wrapTextRanges[] = $bcol . $brow;
					}
					if($fv['type']=='Image' && $val){
						$sss = $fv;
					}
					if(($fk=='smallImg'||$fv['type']=='Image') && $val){
						$imgPath = tempnam(sys_get_temp_dir(), 'excel_img_'.md5($val));
						$filePath = \mvc::$cfg['urls']['outfiles'].'/'.str_replace('small','',$val);
						$contents = file_get_contents($filePath);
						if($imgPath && file_exists($imgPath) && $contents){
							file_put_contents($imgPath,$contents);
							$drawImgRanges[$bcol . $brow] = $imgPath;
						}
						$row[$col] = '';
					}
					

					$bcol++;
					$col++;
				}

				$brow++; // 更新行号
				yield $row; // 使用 yield 返回当前行
			}
		}
        // 创建一个新的 Spreadsheet 对象
		$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
		$sheet = $spreadsheet->getActiveSheet();		//先设置表头

		$work = new work();
		$askList = $work->getAskList(['was_id'=>$was_id, 'was_u_id'=>$uid], []);
		$info = $askList['rows'][0];

		$columnD = [
			'wai_id'=>['title'=>'序号',  'bold'=>true,'color'=>'ff7cded7'],
			'nums'=>[ 'title'=>'询价号码', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_name'=>[ 'title'=>'询价名称',  'bold'=>true,'color'=>'ff7cded7'],
			'oe_num'=>['title'=>'产品号码', 'bold'=>true, 'color'=>'ff7cded7'],
			'oe_name'=>[ 'title'=>'产品名称', 'bold'=>true, 'color'=>'ff7cded7'],
			'smallImg'=>['title'=>'产品图片', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_pb_id'=>['title'=>'产品品牌', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_count'=>['title'=>'数量', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_price'=>['title'=>'单价'.$was_money_type, 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_total_price'=>['title'=>'小计'.$was_money_type, 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_minbuy'=>['title'=>'最小起订量', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_delivery'=>['title'=>'交期(天)', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_uprice'=>['title'=>'客户意向价', 'bold'=>true, 'color'=>'ff7cded7'],
			'wai_remark_user'=>['title'=>'备注', 'bold'=>true, 'color'=>'ff7cded7'],
			'oe_model_en_name'=>['title'=>'适用车型', 'width'=>20,'bold'=>true, 'color'=>'ff7cded7'],
		];
		foreach($info['cols'] as $col){ 
			if($col['type'] == 'Image' || !in_array($col['type'], array_column(\mvc::$cfg['workAskType'], 'type'))){
				$columnD['wai_data'.$col['colnum']] = [
					'title'=>$col['name'],
					'width'=>20,
					'bold'=>true,
					'color'=>'fff1eed1',
					'colnum'=>$col['colnum'],
					'type'=>$col['type'],
				];
			}
		}

		//最大列
		$maxColumn = $this->numberToExcelColumn(count($columnD));

		$fieldsArr = [
			[
				['title'=>'宜配产品报价单','height'=>80,'scell'=>'A1','ecell'=>($maxColumn).'1','isMerge'=>true,'color'=>'ff248e87','fontColor'=>'FFFFFFFF','bold'=>true,'fontSize'=>20,'align'=>'center'],
			],
			[
				['title'=>'客户编码','scell'=>'A2','ecell'=>'B2','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['was_u_code'].'('.$info['com_name'].')','scell'=>'C2','ecell'=>'D2','isMerge'=>true,'align'=>'left'],
				['title'=>'总金额','scell'=>'E2','ecell'=>'F2','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['total_money'].$was_money_type,'scell'=>'G2','ecell'=>($maxColumn).'2','isMerge'=>true,'align'=>'left']
			],
			[
				['title'=>'联系人','scell'=>'A3','ecell'=>'B3','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['was_uname'],'scell'=>'C3','ecell'=>'D3','isMerge'=>true,'align'=>'left'],
				['title'=>'联系电话','scell'=>'E3','ecell'=>'F3','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['was_utel'],'scell'=>'G3','ecell'=>($maxColumn).'3','isMerge'=>true,'align'=>'left']
			],
			[
				['title'=>'询价日期','scell'=>'A4','ecell'=>'B4','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['was_create_time']?:'','scell'=>'C4','ecell'=>'D4','isMerge'=>true,'align'=>'left'],
				['title'=>'报价日期','scell'=>'E4','ecell'=>'F4','isMerge'=>true,'bold'=>true,'align'=>'right'],
				['title'=>$detail['was_ok_time']?:'','scell'=>'G4','ecell'=>($maxColumn).'4','isMerge'=>true,'align'=>'left'],
			],
			$columnD
		];
		
		// 设置标题
		$row = 1;
      
		$defaultColumnWidth = 15;
		
		$this->formatFields($fieldsArr,$defaultColumnWidth,$sheet,$row);
	

		$batchSize = 1000; // 每次处理 1000 条数据
		$totalRows = count($detail['itemArr']);

		for ($i = 0; $i < $totalRows; $i += $batchSize) {
			$batchData = array_slice($detail['itemArr'], $i, $batchSize); // 获取当前批次数据
			$data = [];
			$wrapTextRanges = [];
			$startRow = $row; // 记录当前批次的起始行号
			$drawImgRanges = [];
			$borderRanges = [];
			$borderRanges[] = 'A' . $row . ':'.$maxColumn . $row ; // 设置边框范围
			// 使用生成器逐行处理数据
			foreach (processBatchData($batchData,$fieldsArr[4],$drawImgRanges, $wrapTextRanges, $row) as $item) {
				$data[] = $item;
				$borderRanges[] = 'A' . $row . ':'.$maxColumn . $row ; // 设置边框范围
			}

			// 批量写入数据到表格
			if (!empty($data)) {
				$sheet->fromArray($data, null, 'A' . $startRow);
			}

			// 批量设置边框样式
			if (!empty($borderRanges)) {
				foreach ($borderRanges as $cnt=> $range) {
					$fromArray = [
						'borders' => [
							'allBorders' => [
								'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
								'color' => ['argb' => 'FF000000'], // 黑色边框
							],
						],
					];
					if ($cnt % 2 != 0 && count($borderRanges)!= $cnt + 1) { 
						$fromArray['fill'] = [
							'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
							'startColor' => ['argb' => 'FFD2F4F2'], // 浅绿色
						];
					}

					$sheet->getStyle($range)->applyFromArray($fromArray);
				}
			}

			// 批量设置换行样式
			if (!empty($wrapTextRanges)) {
				foreach ($wrapTextRanges as $cell) {
					$sheet->getStyle($cell)->getAlignment()->setWrapText(true);
				}
			}

			//批量插入图片
			if(!empty($drawImgRanges)){
				foreach ($drawImgRanges as $cell => $img) {
					// 插入图片
					$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
					$drawing->setPath($img); // 图片路径
					$drawing->setHeight(50); // 设置图片高度
					$drawing->setCoordinates($cell); // 设置图片插入的单元格
					$drawing->setWorksheet($sheet);

					// 设置图片所在行的高度
					$rowIndex = preg_replace('/[^0-9]/', '', $cell); // 提取行号
					$sheet->getRowDimension($rowIndex)->setRowHeight(40); // 设置行高为 80，可根据需求调整
				}
			}

		}
		//底部
		$fieldsArr = [
			[
				['title'=>''],['title'=>''],['title'=>''],['title'=>''],['title'=>''],['title'=>''],
				['title'=>'总计','bold'=>true],
				['title'=>$detail['total_pro'],'bold'=>true],
				['title'=>''],
				['title'=>$detail['total_money'],'bold'=>true],
			],
		];
		$this->formatFields($fieldsArr,$defaultColumnWidth,$sheet,$row);
		// 输出文件
		ob_clean();
		if (empty($filename)) {
			$filename = sprintf('%d.xlsx', time());
		}
		header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
		header('Content-Disposition: attachment;filename="' . $filename . '"');
		header('Cache-Control: max-age=0');
		$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
		$writer->save('php://output');

		// 释放内存
		$spreadsheet->disconnectWorksheets();
		unset($spreadsheet);

	}

	/**
	 * @param  Array $fieldsArr 表头数组
	 * @param  int $defaultColumnWidth 默认列宽
	 * @param object $sheet phpspreadsheet对象
	 * @param  int $row 行
	 * @method 设置表格头、尾
	 * @author zhengweihua 
	 * @copyright 2025-07-07
	 */
	public function formatFields($fieldsArr,$defaultColumnWidth,&$sheet,&$row)
	{
		foreach ($fieldsArr as $key => $fields) 
		{	
			$col = 'A';
			foreach ($fields as $vv) 
			{
				if(!$vv){
					$col++;
					continue;
				} 
				 // 设置列宽（如果未单独指定宽度，则使用默认宽度）
				if (is_array($vv) && !empty($vv['width'])) {
					$sheet->getColumnDimension($col)->setWidth($vv['width']);
				} else {
					$sheet->getColumnDimension($col)->setWidth($defaultColumnWidth);
				}
				if(is_array($vv)){
					if($vv['isMerge']){
						$sheet->mergeCells(sprintf("%s:%s",$vv['scell'],$vv['ecell'])); // 合并单元格
					}
	
					$sheet->setCellValue($vv['scell']??$col.$row, $vv['title']); 
	
					$cell = $vv['isMerge']?sprintf("%s:%s",$vv['scell'],$vv['ecell']):$col.$row;
					$style = $sheet->getStyle($cell);
	
					if($vv['color']){
						$style->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB($vv['color']);
					} 
					// 设置字体颜色和加粗
					if (!empty($vv['fontColor']) || !empty($vv['bold'])) {
						$font = $style->getFont();
						if (!empty($vv['fontColor'])) {
							$font->getColor()->setARGB($vv['fontColor']); // 设置字体颜色
						}
						if (!empty($vv['bold'])) {
							$font->setBold(true); // 设置加粗
						}
					}
					// 设置字体大小
					if (!empty($vv['fontSize'])) {
						$style->getFont()->setSize($vv['fontSize']); // 设置字体大小
					}
					//设置行高
					if($vv['height']){
						$sheet->getRowDimension($row)->setRowHeight($vv['height']); // 设置行高为 80，可根据需求调整
					}
					
				}else{
					$sheet->setCellValue($col.$row, $vv);
					$style = $sheet->getStyle($col.$row);  
				}

				$styleArray = [
					'borders' => [
						'allBorders' => [
							'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
							'color' => ['argb' => 'FF000000'], // 黑色边框
						],
					],
				];
				$style->applyFromArray($styleArray);
				if($vv['align']){
					$style->getAlignment()->setHorizontal($vv['align']);  
					$style->getAlignment()->setVertical($vv['align']);
				}
				$col++;
			}
			$row++;
		}
	}

	function numberToExcelColumn($number) {
		$column = '';
		while ($number > 0) {
			$number--;
			$remainder = $number % 26;
			$column = chr(65 + $remainder) . $column;
			$number = (int)($number / 26); // 从 1 开始，调整进位
		}
		return $column;
	}
}