<?php

namespace model\pack;

use \model;

class proPack extends model
{
    public $table = 'pro_pack_material';
    public $key = 'ppm_id';

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @method 获取所有的关联属性
     * @author hongzhang
     * @copyright 2025-12-19
     */
    public function getList($params, $rules = [])
    {
        $filters = $params['filters'];
        $page = $params['page'];
        $pagesize = $params['rows'];
        $isExport = !empty($params['isExport']);
        $sidx = empty($params['sidx']) ? '' : $params['sidx'];
        $sord = empty($params['sord']) ? 'asc' : $params['sord'];
        $orderby = $params['orderby'];
        $this->joinWhere = [];

        $table = 'pro_pack_material(ppm)';
        $join = [
            // 商品包装相关
            '[>]pro_pack(pp)' => ['ppm.ppm_pp_id' => 'pp_id'],
            '[><]company(com)' => ['pp.pp_com_id' => 'com_id'],
            '[>]object(o1170)' => ['pp.pp_craft' => 'o_id'],
            '[><]pro(p)'=>['pp.pp_p_id'=>'p_id'],
            // 包材物料相关
            '[>]pack_material_brand(pmb)' => ['ppm.ppm_pmb_id' => 'pmb_id'],
            '[><]pro_brand(pb)' => ['pmb.pmb_pb_id' => 'pb_id'],
            '[><]pack_material(pam)' => ['pmb.pmb_pam_id' => 'pam_id'],
            '[><]pack_type(pat)' => ['pam.pam_pat_id' => 'pat_id'],
            // 用于过滤包材物料属性
            '[>]pack_material_attributes(pma)' => ['pam.pam_id' => 'pma_pam_id'],
            '[>]pack_attributes(paa)' => ['pma.pma_paa_id' => 'paa_id'],
            '[>]adm_user'=>['ppm.ppm_opuser'=>'au_id']
        ];

        

        $where = $this->filter2medoo($filters, function (&$field, &$op, &$data) use (&$join) {
            // 过滤包材物料的属性
            if (preg_match('/^attcat(\d+)$/', $field, $m)) {
                // 如果只需要区分这是一个“属性类别字段”，可以直接统一成 attcat
                // $m[1] 是数字部分（属性类别 ID），后面要用也可以拿出来
                $field = 'pma_paa_id';
                return;
            }
            switch ($field) {
                // 商品品牌筛选
                case 'pb_name':
                    $field = 'pb.pb_' . LG_NAME;
                    break;   
                case 'p_innum_format':
                    $field = 'p.p_innum_format';
                    break;
                case 'p_comnum_format':
                    $field = 'p.p_comnum_format';
                    break;
                // 套装子零件筛选
                case 'pmIdsArr':
                    // 用于过滤套装子零件
                    $join['[>]pro_pack_sonpro(pps)'] = ['ppm.ppm_pp_id' => 'pps_pp_id'];
                    $join['[>]pro(p2)'] = ['pps.pps_p_id'=>'p_id'];
                    $field = 'p2.p_innum';
                    break;
                // 包材物料图片筛选
                case 'ppm_imgs':
                    $op = 'RAW_'.$field;
                    if($data==1){
                        $data = raw("JSON_VALID(ppm_imgs) = 1 AND JSON_LENGTH(ppm_imgs) > 0");
                    }else{
                        $data = raw("(ppm_imgs = '[]' OR ppm_imgs IS NULL OR JSON_VALID(ppm_imgs) = 0 OR JSON_LENGTH(ppm_imgs) = 0)");
                    }
                    break;
                // 刻字图片筛选
                case 'pp_lettering_imgs':
                    $op = 'RAW_'.$field;
                    if($data==1){
                        $data = raw("JSON_VALID(pp_lettering_imgs) = 1 AND JSON_LENGTH(pp_lettering_imgs) > 0");
                    }else{
                        $data = raw("(pp_lettering_imgs = '[]' OR pp_lettering_imgs IS NULL OR JSON_VALID(pp_lettering_imgs) = 0 OR JSON_LENGTH(pp_lettering_imgs) = 0)");
                    }
                    break;
                // 事业部名称筛选
                case 'com_name':
                    $dataArr = explode(' ',$data);
                    $data = count($dataArr)>1?$dataArr[1]:$dataArr[0];
                    $field = 'com.com_'.LG_NAME;
                    break;
                // 产品净重
                case 'p_weight':
                    $field = 'p.p_weight';
                    break;
                case 'p_oe':
                    $field = 'p.p_oe_format';
                    $data = formatNum($data);
                    break;
                case 'p_name':
                     $field = 'p.p_'.LG_NAME;
                    break;
                case 'per_pro_net_weight':
                    // 单个产品毛重：关联方案判断（一个方案有多个包材子件）
                    // 方案下有“盒”取每盒毛重，否则有“袋”取每袋毛重，盒优先
                    $keyword = escape(trim($data));
                    $op = 'RAW_'.$field;
                    $data = raw(
                        "exists (
                            select 1
                            from pro_pack_material ppm2
                            join pack_material_brand pmb2 on ppm2.ppm_pmb_id = pmb2.pmb_id
                            join pack_material pam2 on pmb2.pmb_pam_id = pam2.pam_id
                            join pack_type pat2 on pam2.pam_pat_id = pat2.pat_id
                            where ppm2.ppm_pp_id = ppm.ppm_pp_id
                            and (
                                (pat2.pat_" . LG_NAME . " like '%盒%' and cast(pp.pp_weight_carton as char) like '%$keyword%')
                                or
                                (pat2.pat_" . LG_NAME . " not like '%盒%' and pat2.pat_" . LG_NAME . " like '%袋%' and cast(pp.pp_weight_bag as char) like '%$keyword%')
                            )
                            limit 1
                        )"
                    );
                    return;
                    
            }
        });
        // 权限控制
        // 品牌
        $proBrandPower = \p::areas('D400');
        if(!\p::isAdmin()&& !empty($proBrandPower)){
            $where['pmb_pb_id'] = explode(',',$proBrandPower) ;
        }
        // 公司
        $companyPower = \p::company('D400');
        if(!\p::isAdmin()&& !empty($companyPower)){
            $where['pp.pp_com_id'] = explode(',',$companyPower) ;
        }          
        foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
                case 'numbers':
                    $tnums = [];
                    foreach($val as $tk=>$tv){
                        $tnums = array_merge($tnums, reSearchNum($tv));
                    }
                    $tnums = array_unique($tnums);
                    $op = $rules['numlike'] ? '[~]' : '';
                    $where['OR']['pmb_incode'.$op] = $tnums;
                    $where['OR']['p.p_innum_format'.$op] = $tnums;
                break;

				case 'proBrand': $where['pmb_pb_id'] = explode(',', $rules['proBrand']); break;		
			}
		}
        $where['GROUP'] = ['ppm_id'];
        $where = $this->listWhere($where, $page, $pagesize, $sidx, $sord, $orderby);
        if ($page > 0 && $pagesize > 0) {
            $fields = '*';
            $pages = $this->paging($table, $join, $fields, $where, $page, $pagesize);
            $where["LIMIT"] = [$pages['limit'], $pagesize];
        }
        $fields = ['ppm.*', 'pmb.*', 'pam.*','pp.*', 'pam_' . LG_NAME . '(pam_name)', 'pb_' . LG_NAME . '(pb_name)', 'pat_' . LG_NAME . '(pat_name)', 'pat_code','com.com_'.LG_NAME.'(com_name)','o1170.'.LG_NAME.'(pp_craft_name)','p.p_weight','p.p_id','p.p_lnk_p_id','p.p_comnum_format','p.p_innum_format','p.p_oe','p.p_'.LG_NAME.'(p_name)','au_name'];
        $arr = $this->db->select($table, $join, $fields, $where);
        if ($arr) {
            $pamids = array_column($arr, 'pam_id');
            // 获取关联的属性
            $attrArr = $this->db->select(
                'pack_material_attributes(pma)',
                [
                    '[><]pack_attributes(paa)' => ['pma.pma_paa_id' => 'paa_id'],
                    '[><]object(o)' => ['paa.paa_attcat' => 'o_id']
                ],
                ['pma_id', 'pma_paa_id', 'pma_pam_id', 'paa_cn_name(paa_name)', 'paa_attcat', 'o.' . LG_NAME . '(o_name)'],
                ['pma_pam_id' => $pamids]
            );
            $attrObjectArr = [];
            if ($attrArr) {
                foreach ($attrArr as $key => $val) {
                    $attrObjectArr[$val['pma_pam_id']][] = $val;
                }
            }

            $objectArr = [];
            $oArr = $this->db->select('object', ['o_id', 'o_parent_id', LG_NAME . '(o_name)'], ['o_parent_id' => [7, 2, 1168]]);
            if ($oArr) {
                foreach ($oArr as $key => $val) {
                    $objectArr[$val['o_id']] = $val;
                }
            }

            // 获取对应套装子零件的商品物料编码
            $ppmids = array_column($arr, 'ppm_id');
            $ppspids = $this->db->select('pro_pack_material(ppm)',[
                '[><]pro_pack_sonpro(pps)' => ['ppm.ppm_pp_id' => 'pps_pp_id'],
                '[><]pro(p)'=>['pps.pps_p_id'=>'p_id'],
            ], ['ppm_id', 'p_innum','p_id'], ['ppm_id' => $ppmids]);
            $pmIdsArr = [];
            if($ppspids){
                foreach($ppspids as $key=>$val){
                    $pmIdsArr[$val['ppm_id']][] = ['p_innum'=>$val['p_innum'],'p_id'=>$val['p_id']];
                }
            }

            //图片
            $fileIds = array_filter(array_merge(array_column($arr, 'ppm_imgs'),array_column($arr, 'pp_lettering_imgs')));
            $fileInfoArr = [];

            if (!empty($fileIds)) {
                // 展开所有JSON格式的文件ID数组
                $allFileIds = [];
                foreach ($fileIds as $fileIdJson) {
                    $ids = json_decode($fileIdJson, true);
                    if (is_array($ids) && !empty($ids)) {
                        $allFileIds = array_merge($allFileIds, $ids);
                    }
                }
                $allFileIds = array_unique($allFileIds);

                if (!empty($allFileIds)) {
                    // 一次性获取所有文件信息
                    $files = $this->db->select(
                        'files',
                        ['fileid', 'filename', 'fileextname', 'filetype'],
                        ['fileid' => $allFileIds]
                    );
                    $fileInfoArr = array_column($files, null, 'fileid');
                }
            }
            $typeArr = ['share'=>'共享','self'=>'定制'];
            $packStatusArr = ['outpack'=>'外包','inpack'=>'内包'];

            // 单个产品毛重：按方案聚合判断（一个方案有多个包材子件）
            // 方案下有“盒”取每盒毛重，否则有“袋”取每袋毛重，盒优先
            //优化下查询sql
            $ppIdsOnPage = array_values(array_unique(array_filter(array_column($arr, 'ppm_pp_id'))));
            $proNetWeightByPp = [];
            if($ppIdsOnPage){
                $schemeWeightFlags = $this->db->select(
                    'pro_pack_material(ppm)',
                    [
                        '[><]pack_material_brand(pmb)'=>['ppm.ppm_pmb_id'=>'pmb_id'],
                        '[><]pack_material(pam)'=>['pmb.pmb_pam_id'=>'pam_id'],
                        '[><]pack_type(pat)'=>['pam.pam_pat_id'=>'pat_id']
                    ],
                    [
                        'ppm.ppm_pp_id',
                        'has_box'=>raw("MAX(CASE WHEN pat_" . LG_NAME . " LIKE '%盒%' THEN 1 ELSE 0 END)"),
                        'has_bag'=>raw("MAX(CASE WHEN pat_" . LG_NAME . " LIKE '%袋%' THEN 1 ELSE 0 END)")
                    ],
                    [
                        'ppm.ppm_pp_id'=>$ppIdsOnPage,
                        'GROUP'=>'ppm.ppm_pp_id'
                    ]
                );
                if($schemeWeightFlags){
                    foreach ($schemeWeightFlags as $swf) {
                        $ppid = $swf['ppm_pp_id'] ?? 0;
                        if(!$ppid) continue;
                        $proNetWeightByPp[$ppid] = [
                            'box'=>!empty($swf['has_box']),
                            'bag'=>!empty($swf['has_bag'])
                        ];
                    }
                }
            }

            foreach ($arr as &$v) {
                $decimalFields = ['pam_length', 'pam_width', 'pam_height','pp_per_pallet_volume','p_weight','pp_weight_carton','pp_weight_bag','pp_weight_box'];
                foreach ($decimalFields as $field) {
                    if (isset($v[$field]) && is_numeric($v[$field])) {
                        // 如果是浮点数且小数部分为0，则转换为整数
                        if (strpos($v[$field], '.') !== false) {
                            $v[$field] = rtrim(rtrim($v[$field], '0'), '.');
                        }
                    }
                }
                // 单个产品毛重：关联方案，方案下有“盒”取每盒毛重，否则有“袋”取每袋毛重，盒优先
                $ppWeightInfo = $proNetWeightByPp[$v['ppm_pp_id']] ?? [];
                if(!empty($ppWeightInfo['box'])){
                    $v['per_pro_net_weight'] = $v['pp_weight_carton'] ?? '';
                } elseif(!empty($ppWeightInfo['bag'])){
                    $v['per_pro_net_weight'] = $v['pp_weight_bag'] ?? '';
                } else {
                    $v['per_pro_net_weight'] = '';
                }
                $fileinfo = [];
                if (!empty($v['ppm_imgs'])) {
                    $fileIds = json_decode($v['ppm_imgs'], true);
                    if (is_array($fileIds) && !empty($fileIds)) {
                        foreach ($fileIds as $fileId) {
                            if (isset($fileInfoArr[$fileId])) {
                                $fileinfo[] = $fileInfoArr[$fileId];
                            }
                        }
                    }
                }
                $craftfileinfo = [];
                if (!empty($v['pp_lettering_imgs'])) {
                    $fileIds = json_decode($v['pp_lettering_imgs'], true);
                    if (is_array($fileIds) && !empty($fileIds)) {
                        foreach ($fileIds as $fileId) {
                            if (isset($fileInfoArr[$fileId])) {
                                $craftfileinfo[] = $fileInfoArr[$fileId];
                            }
                        }
                    }
                }
                $attcat = $attrObjectArr[$v['pam_id']] ?? [];
                if($attcat){
                    foreach($attcat as $key=>$val){
                        $v['attcat'.$val['paa_attcat']] = $val['paa_name'] ?? '';
                    }
                }

                $v['pmb_name'] = $v['pam_' . LG_NAME] . '(' . $v['pmb_incode'] . ')';
                $v['ppm_imgs'] = $fileinfo;
                $v['pp_lettering_imgs'] = $craftfileinfo;
                $v['pmIdsArr'] = $pmIdsArr[$v['ppm_id']] ?? [];
                if ($isExport) {
                    $nums = array_column($v['pmIdsArr'], 'p_innum');
                    $v['pmIdsArr'] = $nums ? implode("\r\n", $nums) : '';
                    $v['ppm_imgs'] = $fileinfo ? 'Y' : '';
                    $v['pp_lettering_imgs'] = $craftfileinfo ? 'Y' : '';
                }
                $v['captions']['pam_material_type'] =  $objectArr[$v['pam_material_type']]['o_name'] ?? '';
                $v['captions']['pam_weight_unit'] =  $objectArr[$v['pam_weight_unit']]['o_name'] ?? '';
                $v['captions']['pam_invoice_unit'] =  $objectArr[$v['pam_invoice_unit']]['o_name'] ?? '';
                $v['captions']['pmb_pb_id'] =  $v['pb_name'] ?? '';
                $v['captions']['pam_pat_id'] =  $v['pat_name'] ?? '';
                $v['captions']['pp_type'] =  $typeArr[$v['pp_type']] ?? '';
                $v['captions']['pp_pack_status'] =  $packStatusArr[$v['pp_pack_status']] ?? '';
                $v['captions']['pp_craft'] =  $v['pp_craft_name'] ?? '';
                $v['captions']['ppm_opuser'] = $v['au_name']??'';
            }
        }
        $data = [
            'page'=> $page,
            'total'=> $pages['total'],
            'records' => $pages['records'],
            'rows' => $arr
        ];
        return $data;
    }

    /**
     * @method 获取所有的关联属性
     * @author hongzhang
     * @copyright 2025-12-20
     */
    public function getAllMaterialAttributes()
    {
        $arr = [];
        $table = 'pack_material_attributes(pma)';
        $join = [
            '[><]pack_attributes(paa)'=>['pma.pma_paa_id'=>'paa_id'],
            '[><]object(o)'=>['paa.paa_attcat'=>'o_id']
        ];
        $fields = ['o.'.LG_NAME.'(o_name)','o.o_id'];
        $where = ['ORDER'=>['o.o_sort'=>'ASC'],'GROUP'=>'o.o_id'];
        $result = $this->db->select($table,$join,$fields,$where);
        foreach ($result as $val) {
            $arr[] = [
                'field'=>'attcat'.$val['o_id'],
                'o_name'=>$val['o_name'],
                'o_id'=>$val['o_id']
            ];
        }
        return $arr;
    }

    public function getPackMaterialTypes()
    {
        $arr = [];
        $rows = $this->db->select(
            'pro_pack_material(ppm)',
            [
                '[><]pack_material_brand(pmb)'=>['ppm.ppm_pmb_id'=>'pmb_id'],
                '[><]pack_material(pam)'=>['pmb.pmb_pam_id'=>'pam_id'],
                '[><]pack_type(pat)'=>['pam.pam_pat_id'=>'pat_id']
            ],
            ['pat_id','pat_'.LG_NAME.'(pat_name)'],
            ['GROUP'=>'pat_id','ORDER'=>['pat_code'=>'ASC','pat_'.LG_NAME=>'ASC']]
        );
        foreach ($rows as $row) {
            $arr[] = [
                'field'=>'pat'.$row['pat_id'],
                'pat_name'=>$row['pat_name'],
                'pat_id'=>$row['pat_id']
            ];
        }
        return $arr;
    }

    /**
     * @method 删除商品的方案包材数据
     * @author zhengweihua 
     * @copyright 2026-04-29
     */
    public function delData($idArr)
    {   
        if(!$idArr) return [];
        $where = ['ppm_id'=>$idArr];
        
        $ppmIds = $this->db->select('pro_pack_material','ppm_id',$where);
        if(!$ppmIds) return true;
        $this->db->Begin();
		$this->db->delete('pro_pack_material',['ppm_id'=>$ppmIds]);
		$this->db->End();
        
    }

    /**
     * @method 获取商品子件列表
     * @author zhengweihua 
     * @copyright 2026-04-29
     */
    public function getSonProlist($params, $rules = [])
    {
        $filters = $params['filters'];
        $page = $params['page'];
        $pagesize = $params['rows'];
        $isExport = !empty($params['isExport']);
        $sidx = empty($params['sidx']) ? '' : $params['sidx'];
        $sord = empty($params['sord']) ? 'asc' : $params['sord'];
        $orderby = $params['orderby'];
        $this->joinWhere = [];

        $table = 'pro_pack_sonpro(pps)';
        $join = [
            // 商品包装相关
            '[>]pro_pack(pp)' => ['pps.pps_pp_id' => 'pp_id'],
            '[><]company(com)' => ['pp.pp_com_id' => 'com_id'],
            '[>]object(o1170)' => ['pp.pp_craft' => 'o_id'],
            '[><]pro(p)'=>['pp.pp_p_id'=>'p_id'],
            // 子零件相关
      
            '[><]pro(p2)' => ['pps.pps_p_id' => 'p_id'],
            '[><]pro_brand(pb)' => ['p2.p_pb_id' => 'pb_id'],
            '[><]pro_cate(cate)'=>['p2.p_cate'=>'id'],
            '[>]adm_user'=>['pps.pps_opuser'=>'au_id']

        ];

        

        $where = $this->filter2medoo($filters, function (&$field, &$op, &$data) use (&$join) {
           
            switch ($field) {
                // 商品品牌筛选
                case 'pb_name':
                    $field = 'pb.pb_' . LG_NAME;
                    break;   
                case 'p_innum':
                    $field = 'p.p_innum_format';
                    $data = formatNum($data);
                    break;
                case 'p_comnum':
                    $field = 'p.p_comnum_format';
                    $data = formatNum($data);
                    break;
               
                // 子零件图片筛选
                case 'pic':
                    $op = 'RAW_'.$field;
                    if($data==1){
                         $data = raw("
                            EXISTS (                      
                                SELECT 1
                                FROM pro_pic pic
                                JOIN files f ON f.fileid = pic.pic_fileid
                                WHERE pic.pic_p_id = pps.pps_p_id
                                AND pic.pic_type = 'img'
                                LIMIT 1
                            )
                        ");
                    }else{
                       $data = raw("
                            NOT EXISTS (
                                SELECT 1
                                FROM pro_pic pic
                                JOIN files f ON f.fileid = pic.pic_fileid
                                WHERE pic.pic_p_id = pps.pps_p_id
                                AND pic.pic_type = 'img'
                                LIMIT 1
                            )
                        ");
                    }
                    break;
               
                // 事业部名称筛选
                case 'com_name':
                    $dataArr = explode(' ',$data);
                    $data = count($dataArr)>1?$dataArr[1]:$dataArr[0];
                    $field = 'com.com_'.LG_NAME;
                    break;
               
                case 'p_oe':
                    $field = 'p.p_oe_format';
                    $data = formatNum($data);
                    break;
                case 'p_name':
                    $field = 'p.p_'.LG_NAME;
                    break;
                case 'pps_p_name':
                    $field = 'p2.p_'.LG_NAME;
                    break;
                case 'pps_p_innum':
                    $field = 'p2.p_innum_format';
                    $data = formatNum($data);
                    break;
                case 'pps_p_comnum':
                    $field = 'p2.p_comnum_format';
                    $data = formatNum($data);
                    break;
                case 'pps_p_oe':
                    $field = 'p2.p_oe_format';
                    $data = formatNum($data);
                    break;
                case 'pps_p_pb_id':
                    $field = 'p2.p_pb_id';
                    break;
                case 'pps_p_cate_name':
                    $field = 'cate.'.cateName();
                    break;
            }
        });
        // 权限控制
        // 品牌
        $proBrandPower = \p::areas('D500');
        if(!\p::isAdmin()&& !empty($proBrandPower)){
            $where['p2.p_pb_id'] = explode(',',$proBrandPower) ;
        }
        // 公司
        $companyPower = \p::company('D500');
        if(!\p::isAdmin()&& !empty($companyPower)){
            $where['pp.pp_com_id'] = explode(',',$companyPower) ;
        }          
        foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
                case 'numbers':
                    $tnums = [];
                    foreach($val as $tk=>$tv){
                        $tnums = array_merge($tnums, reSearchNum($tv));
                    }
                    $tnums = array_unique($tnums);
                    $op = $rules['numlike'] ? '[~]' : '';
                    $where['OR']['p.p_innum_format'.$op] = $tnums;
                break;

				case 'proBrand': $where['p2.p_pb_id'] = explode(',', $rules['proBrand']); break;		
			}
		}
        // $where['GROUP'] = ['ppm_id'];
        $where = $this->listWhere($where, $page, $pagesize, $sidx, $sord, $orderby);
        if ($page > 0 && $pagesize > 0) {
            $fields = '*';
            $pages = $this->paging($table, $join, $fields, $where, $page, $pagesize);
            $where["LIMIT"] = [$pages['limit'], $pagesize];
        }
        $fields = [
            'pps.*', 'pp.*', 'pb_' . LG_NAME . '(pb_name)', 'com.com_'.LG_NAME.'(com_name)',
            'o1170.'.LG_NAME.'(pp_craft_name)',
            'p.p_id','p.p_lnk_p_id','p.p_comnum',
            'p.p_innum','p.p_oe','p.p_'.LG_NAME.'(p_name)',
            'p2.p_comnum(pps_p_comnum)','p2.p_innum(pps_p_innum)','p2.p_oe(pps_p_oe)','p2.p_'.LG_NAME.'(pps_p_name)',
            'p2.p_pb_id(pps_p_pb_id)','cate.'.cateName().'(pps_p_cate_name)','au_name'
        ];
        $arr = $this->db->select($table, $join, $fields, $where);
        if ($arr) {
            $ppspidArr = array_column($arr, 'pps_p_id');
            //主图
            $picRes = $this->db->select('pro_pic',['[><]files'=>['pic_fileid'=>'fileid']],'*',['pic_p_id'=>$ppspidArr,'pic_type'=>'img','pic_ismain'=>1]);
            $picArr = [];
            foreach ($picRes as $pic) {
                if($pic['pic_type']=='img' && $pic['filetype']=='image'){
                    $picArr[$pic['pic_p_id']]['bigImg'] = $pic['filepath'].'/'.$pic['filebasename'].'big.'.$pic['fileextname'];
                    $picArr[$pic['pic_p_id']]['smallImg'] = $pic['filepath'].'/'.$pic['filebasename'].'small.'.$pic['fileextname'];
                    if($params['isExport'])
                    {
                        $picArr[$pic['pic_p_id']]['type'] = 'image';
                        $picArr[$pic['pic_p_id']]['filename'] = \mvc::$cfg['dir']['files'].'/'.$picArr[$pic['pic_p_id']]['smallImg'];
                        if(file_exists($picArr[$pic['pic_p_id']]['filename'])){
                            list($width, $height, $type, $attr) = getimagesize($picArr[$pic['pic_p_id']]['filename']);
                            $picArr[$pic['pic_p_id']]['widthScale'] = 1;
                            $picArr[$pic['pic_p_id']]['heightScale'] = 1;
                            $picArr[$pic['pic_p_id']]['rowHeight'] = $height;
                        }else{
                            unset($picArr[$pic['pic_p_id']]);
                        }
                    }
                    
                }
            }

            $typeArr = ['share'=>'共享','self'=>'定制'];
            $packStatusArr = ['outpack'=>'外包','inpack'=>'内包'];
            foreach ($arr as &$v) {
                $v['pic'] = $picArr[$v['pps_p_id']]??[];
                $v['captions']['pps_p_pb_id'] =  $v['pb_name'] ?? '';
                $v['captions']['pp_type'] =  $typeArr[$v['pp_type']] ?? '';
                $v['captions']['pp_pack_status'] =  $packStatusArr[$v['pp_pack_status']] ?? '';
                $v['captions']['pp_craft'] =  $v['pp_craft_name'] ?? '';
                $v['captions']['pps_opuser']=$v['au_name'];
            }
            unset($v);
        }
        $data = [
            'page'=> $page,
            'total'=> $pages['total'],
            'records' => $pages['records'],
            'rows' => $arr
        ];
        return $data;           
    }

    /**
     * @method 删除子商品数据
     * @author zhengweihua 
     * @copyright 2026-07-03
     */
    public function delSonProData($idArr)
    {
       if(!$idArr) return [];
        $where = ['pps_id'=>$idArr];
        
        $ppsIds = $this->db->select('pro_pack_sonpro','pps_id',$where);
        if(!$ppsIds) return true;
		$this->db->delete('pro_pack_sonpro',['pps_id'=>$ppsIds]);
    }

    /**
     * @method 获取包装列表
     * @author zhengweihua 
     * @copyright 2026-07-11
     */
    public function getPackList($params,$rules)
    {
        $filters = $params['filters'];
        $page = $params['page'];
        $pagesize = $params['rows'];
        $isExport = !empty($params['isExport']);
        $sidx = empty($params['sidx']) ? '' : $params['sidx'];
        $sord = empty($params['sord']) ? 'asc' : $params['sord'];
        $orderby = $params['orderby'];
        $this->joinWhere = [];

        $table = 'pro_pack(pp)';
        $join = [
            '[><]pro(p)'=>['pp.pp_p_id'=>'p_id'],
            '[><]company(com)' => ['pp.pp_com_id' => 'com_id'],
            '[>]object(o1170)' => ['pp.pp_craft' => 'o_id'],
            '[>]adm_user'=>['pp.pp_opuser'=>'au_id']
        ];

        $where = $this->filter2medoo($filters, function (&$field, &$op, &$data) use (&$join) {
            // 过滤包材物料的属性
            if(preg_match('/^pat(\d+)$/', $field, $m)){
                $patId = (int)$m[1];
                $keyword = escape(trim($data));
                $op = 'RAW_'.$field;
                $searchSql = '';
                if($keyword !== ''){
                    $searchSql = sprintf(
                        " and (
                            pmb2.pmb_incode like '%%%s%%'
                            or pam2.pam_%s like '%%%s%%'
                            or concat_ws('*', pam2.pam_length, pam2.pam_width, pam2.pam_height) like '%%%s%%'
                        )",
                        $keyword,
                        LG_NAME,
                        $keyword,
                        $keyword
                    );
                }
                $data = raw(
                    sprintf("EXISTS (
                        select 1
                        from pro_pack_material ppm2
                        join pack_material_brand pmb2 on ppm2.ppm_pmb_id = pmb2.pmb_id
                        join pack_material pam2 on pmb2.pmb_pam_id = pam2.pam_id
                        where pam2.pam_pat_id = %d
                        and ppm2.ppm_pp_id = pp.pp_id
                        %s
                    )", $patId, $searchSql)
                );
                return;
            }
            switch ($field) {
                // 商品品牌筛选
                case 'pb_name':
                    $field = 'pb.pb_' . LG_NAME;
                    break;   
                case 'p_innum':
                    $field = 'p.p_innum_format';
                    $data = formatNum($data);
                    break;
                case 'p_comnum':
                    $field = 'p.p_comnum_format';
                    $data = formatNum($data);
                    break;
               
                // 子零件图片筛选
                case 'pic':
                    $op = 'RAW_'.$field;
                    if($data==1){
                         $data = raw("
                            EXISTS (                      
                                SELECT 1
                                FROM pro_pic pic
                                JOIN files f ON f.fileid = pic.pic_fileid
                                WHERE pic.pic_p_id = pps.pps_p_id
                                AND pic.pic_type = 'img'
                                LIMIT 1
                            )
                        ");
                    }else{
                       $data = raw("
                            NOT EXISTS (
                                SELECT 1
                                FROM pro_pic pic
                                JOIN files f ON f.fileid = pic.pic_fileid
                                WHERE pic.pic_p_id = pps.pps_p_id
                                AND pic.pic_type = 'img'
                                LIMIT 1
                            )
                        ");
                    }
                    break;
               
                // 事业部名称筛选
                case 'com_name':
                    $dataArr = explode(' ',$data);
                    $data = count($dataArr)>1?$dataArr[1]:$dataArr[0];
                    $field = 'com.com_'.LG_NAME;
                    break;
               
                case 'p_oe':
                    $field = 'p.p_oe_format';
                    $data = formatNum($data);
                    break;
                case 'p_name':
                    $field = 'p.p_'.LG_NAME;
                    break;
                case 'per_pro_net_weight':
                    // 单个产品净重：根据方案包材子件的包材类型判断
                    // 有“盒”取每盒毛重，否则有“袋”取每袋毛重，盒优先
                    $keyword = escape(trim($data));
                    $op = 'RAW_'.$field;
                    $data = raw(
                        "exists (
                            select 1
                            from pro_pack_material ppm3
                            join pack_material_brand pmb3 on ppm3.ppm_pmb_id = pmb3.pmb_id
                            join pack_material pam3 on pmb3.pmb_pam_id = pam3.pam_id
                            join pack_type pat3 on pam3.pam_pat_id = pat3.pat_id
                            where ppm3.ppm_pp_id = pp.pp_id
                            and (
                                (pat3.pat_" . LG_NAME . " like '%盒%' and cast(pp.pp_weight_carton as char) like '%$keyword%')
                                or
                                (pat3.pat_" . LG_NAME . " like '%盒%' = 0 and pat3.pat_" . LG_NAME . " like '%袋%' and cast(pp.pp_weight_bag as char) like '%$keyword%')
                            )
                            limit 1
                        )"
                    );
                    return;
                case 'has_material':
                    $op = 'RAW_'.$field;
                    if($data==1){
                         $data = raw("
                            EXISTS (                      
                                SELECT 1
                                FROM pro_pack_material ppm
                                WHERE ppm.ppm_pp_id = pp.pp_id 
                            LIMIT 1)"
                         );
                    }else{
                       $data = raw("
                        NOT EXISTS (                      
                                SELECT 1
                                FROM pro_pack_material ppm
                                WHERE ppm.ppm_pp_id = pp.pp_id 
                            LIMIT 1)"
                        );
                    }
                    break;
                case 'has_sonpro': 
                    $op = 'RAW_'.$field;
                    if($data==1){
                         $data = raw("
                            EXISTS (                      
                                SELECT 1
                                FROM pro_pack_sonpro pps
                                WHERE pps.pps_pp_id = pp.pp_id 
                            LIMIT 1)"
                         );
                    }else{
                       $data = raw("
                        NOT EXISTS (
                            SELECT 1
                            FROM pro_pack_sonpro pps
                            WHERE pps.pps_pp_id = pp.pp_id 
                        )
                        "
                       );
                    }
                    break;
            }
        });

        // 权限控制
        
        // 公司
        $companyPower = \p::company('D600');
        if(!\p::isAdmin()&& !empty($companyPower)){
            $where['pp.pp_com_id'] = explode(',',$companyPower) ;
        }          
        foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
                case 'numbers':
                    $tnums = [];
                    foreach($val as $tk=>$tv){
                        $tnums = array_merge($tnums, reSearchNum($tv));
                    }
                    $tnums = array_unique($tnums);
                    $op = $rules['numlike'] ? '[~]' : '';
                    $where['p.p_innum_format'.$op] = $tnums;
                break;	
			}
		}
        $where = $this->listWhere($where, $page, $pagesize, $sidx, $sord, $orderby);
        if ($page > 0 && $pagesize > 0) {
            $fields = '*';
            $pages = $this->paging($table, $join, $fields, $where, $page, $pagesize);
            $where["LIMIT"] = [$pages['limit'], $pagesize];
        }
        $fields = [
            'pp.*',
            'com.com_'.LG_NAME.'(com_name)',
            'o1170.'.LG_NAME.'(pp_craft_name)',
            'p.p_weight','p.p_id','p.p_lnk_p_id',
            'p.p_comnum_format','p.p_innum_format','p.p_oe',
            'p.p_'.LG_NAME.'(p_name)',
            'au_name'
           
        ];
        $arr = $this->db->select($table, $join, $fields, $where);
        // dd($this->db->last());
        if ($arr) {
            
            $objectArr = [];
            $oArr = $this->db->select('object', ['o_id', 'o_parent_id', LG_NAME . '(o_name)'], ['o_parent_id' => [7, 2, 1168]]);
            if ($oArr) {
                foreach ($oArr as $key => $val) {
                    $objectArr[$val['o_id']] = $val;
                }
            }
            $ppIds = array_column($arr,'pp_id');
            //获取具体的商品包材和子件
            $materialArr = $this->db->select('pro_pack_material(ppm)',
            [
                '[><]pack_material_brand(pmb)'=>['ppm.ppm_pmb_id'=>'pmb_id'],
                '[><]pack_material(pam)'=>['pmb.pmb_pam_id'=>'pam_id'],
                '[><]pack_type(pat)'=>['pam.pam_pat_id'=>'pat_id']
            ],
            ['pmb_incode','ppm_remark','ppm_count','ppm_pp_id','pam.pam_pat_id','pam_'.LG_NAME.'(pam_name)','pam_length','pam_width','pam_height','pat_spec','pat_'.LG_NAME.'(pat_name)'],['ppm_pp_id'=>$ppIds]);
            $hasMaterialArr = [];
            $materialTypeArr = [];
            $perProNetWeightArr = [];
            if($materialArr){
                foreach ($materialArr as $val) {
                    $hasMaterialArr[$val['ppm_pp_id']][] = implode('@',array_filter([$val['pmb_incode'],$val['ppm_count'],$val['ppm_remark']])); 
                    if(!empty($val['pam_pat_id'])){
                        $sizeArr = $this->buildMaterialSizeArrByPatSpec($val);
                        $field = 'pat'.$val['pam_pat_id'];
                        $materialTypeArr[$val['ppm_pp_id']][$field][] = implode(' ', array_filter([
                            $sizeArr ? implode('*', $sizeArr) : '',
                            $val['pam_name'] ?? '',
                            $val['pmb_incode'] ?? ''
                        ]));
                    }
                    // 记录每个方案是否含“盒”/“袋”包材，用于“单个产品净重”判断
                    if(!empty($val['pat_name'])){
                        $pName = $val['pat_name'];
                        if(mb_strpos($pName, '盒') !== false){
                            $perProNetWeightArr[$val['ppm_pp_id']]['box'] = true;
                        } elseif(mb_strpos($pName, '袋') !== false){
                            $perProNetWeightArr[$val['ppm_pp_id']]['bag'] = true;
                        }
                    }
                }
            }
            //获取具体的商品子件       
            $sonProArr = $this->db->select('pro_pack_sonpro(pps)',
            ['[><]pro(p)'=>['pps.pps_p_id'=>'p_id']],
            ['p_innum','pps_remark','pps_count','pps_pp_id'],['pps_pp_id'=>$ppIds]);
            $hassonProArr = [];
            if($sonProArr){
                foreach ($sonProArr as $val) {
                    $hassonProArr[$val['pps_pp_id']][] = implode('@',array_filter([$val['p_innum'],$val['pps_count'],$val['pps_remark']])); 
                }
            }
         

            $typeArr = ['share'=>'共享','self'=>'定制'];
            $packStatusArr = ['outpack'=>'外包','inpack'=>'内包'];
            foreach ($arr as &$v) {
                $decimalFields = ['pp_per_pallet_volume','p_weight','pp_weight_carton','pp_weight_bag','pp_weight_box','pp_per_pro_volume'];
                foreach ($decimalFields as $field) {
                    if (isset($v[$field]) && is_numeric($v[$field])) {
                        // 如果是浮点数且小数部分为0，则转换为整数
                        if (strpos($v[$field], '.') !== false) {
                            $v[$field] = rtrim(rtrim($v[$field], '0'), '.');
                        }
                    }
                }
                $v['captions']['has_material'] = $hasMaterialArr[$v['pp_id']]?implode($isExport?"\n":"<br/>",$hasMaterialArr[$v['pp_id']]):'';
                $v['captions']['has_sonpro'] = $hassonProArr[$v['pp_id']]?implode($isExport?"\n":"<br/>",$hassonProArr[$v['pp_id']]):'';
                if(!empty($materialTypeArr[$v['pp_id']])){
                    foreach ($materialTypeArr[$v['pp_id']] as $field=>$names) {
                        $v[$field] = implode(',', array_unique(array_filter($names)));
                    }
                }
                // 单个产品净重：有“盒”取每盒毛重，否则有“袋”取每袋毛重，盒优先
                $netInfo = $perProNetWeightArr[$v['pp_id']] ?? [];
                if(!empty($netInfo['box'])){
                    $v['per_pro_net_weight'] = $v['pp_weight_carton'] ?? '';
                } elseif(!empty($netInfo['bag'])){
                    $v['per_pro_net_weight'] = $v['pp_weight_bag'] ?? '';
                } else {
                    $v['per_pro_net_weight'] = '';
                }
                $v['captions']['pp_type'] =  $typeArr[$v['pp_type']] ?? '';
                $v['captions']['pp_pack_status'] =  $packStatusArr[$v['pp_pack_status']] ?? '';
                $v['captions']['pp_craft'] =  $v['pp_craft_name'] ?? '';
                $v['captions']['pp_opuser'] = $v['au_name']??'';
            }
        }
        $data = [
            'page'=> $page,
            'total'=> $pages['total'],
            'records' => $pages['records'],
            'rows' => $arr
        ];
        return $data;
    }
    
    /**
     * @param  Array $material
     * @method 根据物料类型的拼接规则处理方案子材的规格
     * @author zhengweihua 
     * @copyright 2026-07-30
     */
    private function buildMaterialSizeArrByPatSpec($material)
    {
        $paramMap = [
            'L' => 'pam_length',
            'W' => 'pam_width',
            'H' => 'pam_height'
        ];

        if(empty($material['pat_spec'])){
            $sizeArr = [];
            foreach ($paramMap as $sizeField) {
                if(isset($material[$sizeField]) && $material[$sizeField] !== '' && $material[$sizeField] !== null){
                    $sizeArr[] = $this->formatMaterialSpecValue($material[$sizeField]);
                }
            }
            return $sizeArr;
        }

        $sizeArr = [];
        $specArr = explode('@', $material['pat_spec']);
        foreach ($specArr as $part) {
            if($part === '') continue;
            if(isset($paramMap[$part])){
                $field = $paramMap[$part];
                if(isset($material[$field]) && $material[$field] !== '' && $material[$field] !== null){
                    $sizeArr[] = $this->formatMaterialSpecValue($material[$field]);
                }
            }
        }

        return $sizeArr;
    }

    private function formatMaterialSpecValue($value)
    {
        if(is_numeric($value) && strpos((string)$value, '.') !== false){
            return rtrim(rtrim($value, '0'), '.');
        }
        return $value;
    }

    public function delPackData($idArr)
    { 
         if(!$idArr) return [];
        $where = ['pp_id'=>$idArr];
        
        $ppIds = $this->db->select('pro_pack','pp_id',$where);
        if(!$ppIds) return true;
        $this->db->Begin();
		$this->db->delete('pro_pack',['pp_id'=>$ppIds]);
        $this->db->delete('pro_pack_material',['ppm_id'=>$ppIds]);
        $this->db->delete('pro_pack_sonpro',['pps_id'=>$ppIds]);
		$this->db->End();
    }
}
