$userinfo['company_name'], 'postcode' => $userinfo['postcode'], 'mobile' => $userinfo['mobile'], 'printer_code' => $userinfo['printer_code'], 'company_address' => $userinfo['company_address'] ]; //创建公司唯一id,进行创建公司对用表名 $user_company_value = Db::name('admin')->where('id', $userinfo['id'])->value('company'); if (empty($user_company_value)) { $max_company = Db::name('admin')->max('company'); $new_company_value = $max_company ? ($max_company + 1) : 1; Db::name('admin')->where('id', $userinfo['id'])->update(['company' => $new_company_value]); } else { $new_company_value = $user_company_value; } $tableNames = [ $new_company_value . '_qcode_bach', $new_company_value . '_qcode_company', $new_company_value . '_qcode_large', $new_company_value . '_qcode_liushui', $new_company_value . '_qcode_small', $new_company_value . '_reset_flow', ]; foreach ($tableNames as $tableName) { try { Db::connect('mongodb')->name($tableName)->insert(['init' => 1]); // 删除测试数据(可选,如果不想保留这个测试数据) Db::connect('mongodb')->name($tableName)->where('init', 1)->delete(); } catch (\Exception $e) { echo "创建集合 {$tableName} 失败:" . $e->getMessage(); } } // $product_id = $company->name((int)$userinfo['company'].'_'.'qcode_company')->where('delete_time','')->column('product_id'); // echo "
";
//        print_r($product_id);
//        echo "
";
//        $product_name = [];
//        foreach ($product_id as $v){
//            $list = $product->where('_id',$v)->where('delete_time','')->find();
//            $product_name[$list['product_code']] =  $list['product_name'];
//        }
//        echo "
";
//        print_r($product_name);
//        echo "
";
//        $this->view->assign('product', $product_name);

        // 1. 获取所有产品的 ID
        $product_id = $company
            ->name((int)$userinfo['company'] . '_' . 'qcode_company')
            ->where('delete_time', '')
            ->column('product_id');

        // 2. 查找产品信息:构建 product_code => 全部信息数组
        $product_info = [];
        foreach ($product_id as $v) {
            $list = $product
                ->where('_id', $v)
                ->where('delete_time', '')
                ->find();
            if ($list) {
                // 记录完整产品信息
                $product_info[$list['product_code']] = [
                    'jjcp_cpmc' => $list['product_name'], // 产品名称
                    'jjcp_cpdh' => $list['product_code'], // 产品代码
                ];
            }
        }

        // 3. 从 Mongo 查询 jjcp_cpmc 名称
        $mongo = \think\Db::connect('mongodb');
        $mongo_products = $mongo
            ->name('finished_products')
            ->field('jjcp_cpmc, jjcp_cpdh, order_ddbh, jjcp_gdbh, jjcp_sl')
            ->select();

        // 4. 比对名称,匹配成功的组装完整 vo 结构
        $matched_products = [];
        foreach ($product_info as $code => $item) {
            foreach ($mongo_products as $mp) {
                if (trim($item['jjcp_cpmc']) === trim($mp['jjcp_cpmc'])) {
                    $matched_products[] = [
                        'jjcp_cpmc' => $item['jjcp_cpmc'],
                        'jjcp_cpdh' => $item['jjcp_cpdh'],
                        'order_ddbh' => $mp['order_ddbh'], // 从 MongoDB 查找
                        'jjcp_gdbh' => $mp['jjcp_gdbh'],   // 从 MongoDB 查找
                        'jjcp_sl' => $mp['jjcp_sl'],       // 从 MongoDB 查找
                        'product_code' => $code,
                    ];
                }
            }
        }
        $this->view->assign('product', $matched_products);
        $this->view->assign('row',$data);
        return $this->view->fetch();
    }

    /**
     * 获取产品信息
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function product(){
        $QcodeProduct = new QcodeProduct();
        $ResetFlow = new ResetFlow();
        $userinfo = Session::get('admin');
        if ($this->request->isAjax() === false){
            $this->error('请求错误');
        }

        $product_code = input('product_code');

        if (empty($product_code)){
            $this->error('参数错误');
        }
        $product = $QcodeProduct->where('product_code',$product_code)->find();
        if (empty($product)){
            $this->error('未找到该产品信息');
        }

        $flow = $ResetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',substr(json_encode($product['_id']),9,-2))->find();
        $row = [
            'temple' => $product['temple'],
            'flow' => isset($flow['l_flow'])?(int)$flow['l_flow']+1:'',
            'bach' => isset($flow['bach_num'])?(int)$flow['bach_num']+1:'',
        ];
        if (!empty($flow)){
            $row['flow'] = $flow['l_flow']+1;
            $row['bach'] = $flow['bach_num']+1;
        }

        return json(['code'=>1,'data'=>$row]);
    }

    /**
     * 增加新批次
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function add()
    {
        $product = new QcodeProduct();
        $bach = new QcodeBach();
        $large = new QcodeLarge();
        $small = new QcodeSmall();
        $liushui = new QcodeLiushui();
        $resetFlow = new ResetFlow();
        $QcodeCompany = new QcodeCompany();
        if ($this->request->isAjax() === false){
            $this->error('请求错误');
        }
        $rows = input('row');
        if (empty($rows)){
            $this->error('参数错误');
        }
        $rows = json_decode($rows);
        $data = [];
        foreach ($rows as $value){
           foreach ($value as $k=>$v){
               $data[$k] = $v;
           }
        }
        if ($data['danwei'] == 1){
            $num = $data['number'];
            $tray_num = $data['tray_num'];
            $tray_num1 = $data['tray_num'];
            $box_number = $data['box_number'];
            //$small_num = (int)ceil((int)总数量(张/个)/(int)张数);
            $small_num = (int)ceil((int)$data['number']/(int)$data['box_number']);
            $large_num = (int)ceil($small_num/$tray_num);
        }else{
            $num = 0;
            $tray_num = $data['volume_num'];
            $small_num = $data['small_num'];
            $large_num = (int)ceil($small_num/$tray_num);
            $box_number = 1;
            $tray_num1 = 1;
        }
        $userinfo = Session::get('admin');
        $productList = $product->where('product_code',$data['product_code'])->find();
        $arr = [
            'product_id' => $productList['_id'],
            'create_time' => time(),
            'delect_time' => '',
            'sync_flag' => 0,
            ];
        $productres = $QcodeCompany->save($arr);
        if ($productres === 0){
            $this->error('添加失败');
        }

        if (empty($productList)){
            $this->error('未找到该产品数据');
        }

        $batchList = [
            'supplier_name' => $data['company_name'],
            'supplier_code' => $userinfo['printer_code'],
            'supplier_id' => $userinfo['id'],
            'matter_name' => $productList['product_name'],
            'matter_no' => $productList['product_code'],//生产批次号
            'order_ddbh' => $data['order_ddbh'],//销售订单号
            'matter_id' => substr(json_encode($productList['_id']),9,-2),
            'matter_type' => $productList['temple'],
            'manufacture_date' => (int)date('ymd',strtotime($data['manufacture_date'])),
            'print_date' => (int)date('ymd',strtotime($data['print_date'])),

            'danwei' => $data['danwei'],//单位
            'num' => $num,//总数量(张/个)
            'tray_num' => $tray_num1,//每层箱数
            'box_num' => $box_number,//每托层数
            'total_boxes' => $data['total_boxes'],//每托盘箱数
            'small_num' => $small_num,//每托盘箱数
            'pallet_height' => $data['pallet_height'],//每托高度
            'pallet_length' => $data['pallet_length'],//托盘规格
            'pallet_width' => $data['pallet_width'],//托盘规格
            'larger_num' => $large_num,//大件(总托数)

            'l_reservation' => '',
            'l_flow' => $data['big_liushui'],
            'l_weight' => $data['big_weight'],
            's_flow' => $data['small_start_liushui'],
            's_weight' => $data['small_weight'],
            's_reservation' => '',
            'bach_status' => 0,
            'userid' => $userinfo['id'],
            'bach_num' => $data['batch'],
            'large_endnum' => $data['big_liushui'] + $data['box_num'] -1,
            'create_time' => time(),//新增时间
        ];

        $res = $bach->save($batchList);
        if ($res === 0){
            $this->error('添加失败');
        }
        $flow = [
            'l_flow' => (int)$batchList['large_endnum'],
            'bach_num' => $batchList['bach_num'],
        ];
        if ($resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_id'])->find()){
            $resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_id'])->update($flow);
        }else{
            $flow['product_id'] = $batchList['matter_id'];
            $resetFlow->save($flow);
        }
        $last_id = $bach->getLastInsID();
        if ($last_id){
            //插入大小二维码数据
            //二维码数据不变区域
//            echo "
";
//            print_r($batchList['matter_type']);
//            echo "
";
//            echo "
";
//            print_r($batchList['supplier_code']);
//            echo "
";
//            echo "
";
//            print_r('9');
//            echo "
";
//            echo "
";
//            print_r($batchList['matter_no']);
//            echo "
";
//            echo "
";
//            print_r($batchList['manufacture_date']);
//            echo "
";
//            echo "
";
//            print_r($batchList['print_date']);
//            echo "
";
            $fixed_code = '';
            $fixed_code.=$this->intTochar($batchList['matter_type'],2);//2位  辅料种类编码
//            $fixed_code .= substr($this->intTochar($batchList['supplier_code'], 12), 1);//12位  供应商编码 // 去掉第一位0
            $fixed_code .= $this->intTochar($batchList['supplier_code'], 21);//21位  供应商编码
            $fixed_code .= '9'; // 补0一位
            $fixed_code.=$this->intTochar($batchList['matter_no'],10);//10位  辅料编码
            $fixed_code.=$batchList['manufacture_date'];//6位  生产日期
            $print_code=$batchList['print_date'];//6位  打码日期

//            echo "
";
//            print_r($fixed_code);
//            echo "
";
//            echo "
";
//            print_r($print_code);
//            echo "
";
            $small_liushui = [
                'onlycode' => 'AB92'.$fixed_code.$print_code,
                'last_num' => 0,
                'user_id' => $userinfo['company'],
                'stype' => 2,
                'dateTime' => time(),
            ];

            $whereSmall = [
                'onlycode' => $small_liushui['onlycode'],
                'user_id' => $userinfo['company'],
            ];

            if ($liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find()){
                //小件二维码存在,更新小件二维码最后流水号
                $lastNum = $liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find();
            }else{
                //小件二维码不存在,新增记录
                $liushui->save($small_liushui);
                $lastNum['last_num'] = 0;
            }

            //循环插入大件二维码数据
            for ($i=0;$i<$batchList['larger_num'];$i++){
                $large = new QcodeLarge();
                $l_flow = $this->intTochar($batchList['l_flow']+$i,6);
                $l_weight = $this->intTochar($batchList['l_weight']*100,6);
                $l_reservation = $this->intTochar($batchList['bach_num'],10);
                $l_reservation = $l_reservation.'0000000000';
                $remainder = $batchList['small_num'] - $batchList['tray_num'] * $i;//最后一托盘小件数量
                if ($remainder < $batchList['tray_num']){
                    $small_n = $this->intTochar($remainder,3);//3位小件数量,不足补0
                }else{
                    $small_n = $this->intTochar($batchList['tray_num'],3);
                }
                $l_num = 0;
                if ($data['danwei'] == 1){
                    //以箱为单位时
                    $l_num = $small_n * $batchList['box_num'];
                }
                //大件二维码数据
                $code_data = $this->CodeData('AB92',$fixed_code,$small_n,$print_code,$l_flow,$l_weight,'2',$l_reservation);
                //大码数据信息
                $l_data = [
                    'bach_id' => $last_id,
                    'code' => $code_data['code'],
                    'code_cp1' => $code_data['code_cp1'],
                    'code_cp2' => $code_data['code_cp2'],
                    'print_date' => $print_code,
                    'create_time' => time(),
                    'p_nums' => 0,
                    'userid' =>$userinfo['id'],
                    'l_weight' =>$batchList['l_weight']*100,
                    'l_num' =>$l_num,
                    'l_status' => 0,
                    'l_print' => 0
                ];
                $l_res = $large->save($l_data);
                if ($l_res === 0){
                    $this->error('大件码插入失败');
                }
                $large_id = $large->getLastInsID();
                if ($large_id){
//                    //小件码循环插入
                    for ($j=0;$j<$tray_num and ($j+$i*$tray_num)<$batchList['small_num'];$j++){
                        $small = new QcodeSmall();
                        $s_flow = $this->intTochar($batchList['s_flow']+$j+$i*$tray_num+$lastNum['last_num'],6);//小件码序号从1开始
                        $s_weight = $this->intTochar($batchList['s_weight'],6);
                        $small_sign = '000';
                        $s_reservation = $this->intTochar($batchList['bach_num'],10);
                        $s_reservation = $s_reservation . '0000000000';
                        //生成小件码
                        $small_code_data = $this->CodeData('AB92',$fixed_code,$small_sign,$print_code,$s_flow,$s_weight,'1',$s_reservation);
                        //小码数据
                        $s_data = [
                            'large_id'=>$large_id,
                            'bach_id'=>$last_id,
                            'code'=>$small_code_data['code'],
                            'code_cp1'=>$small_code_data['code_cp1'],
                            'code_cp2'=>$small_code_data['code_cp2'],
                            'l_flow'=>$j+1,
                            'print_date'=>$print_code,
                            'create_time'=>time(),
                            'p_nums'=>0,
                            'userid'=>$userinfo['id'],//小码绑定用户id
                            's_weight'=>$batchList['s_weight'],//单个小件重量
                            'status' => 0,
                        ];
                        $s_res = $small->save($s_data);
                        if ($s_res === 0){
                            $this->error('小件码插入失败');
                        }
                    }
                }else{
                    $this->error('添加失败');
                }

            }
        }
        $liushui_res = $liushui->name($userinfo['id'].'_'.'qcode_liushui')->where($whereSmall)->update(['last_num'=>$batchList['small_num']]);
        if ($liushui_res === false){
            $this->error('添加失败');
        }
        $this->success('成功');
    }

    /**
     * 编码补位
     * @param $num
     * @param $len
     * @return string
     */
    function intTochar($num=0,$len){
        //规定的不足的时候自动补足零
        $code=(string)$num;
        $buwei='';
        if(strlen($code)<$len){
            for($i=strlen($code);$i<$len;$i++){
                $buwei.='0';
            }
        }
        return $buwei.$code;
    }

    /**
     * 二维码编码生成
     * @param $sign
     * @param $fixed_code
     * @param $small_num
     * @param $print_date
     * @param $flow
     * @param $weight
     * @param $large_sign
     * @param $reservation
     * @return array
     */
     function CodeData($sign,$fixed_code,$small_num,$print_date,$flow,$weight,$large_sign,$reservation){
         $code=$sign;//4 位固定标志位
         $code.=$fixed_code; // 固定字符串
         $code.=$small_num;//3位 小件数量
         $code.=$print_date;//6 位 日期
         $code.=$flow;//6位打印流水号
         $code.=$weight;//6位辅料重量
         $code.=$large_sign;//大小件标示位

         $code.=$reservation;//20 位 预留号

         //大码数据信息
         $data=[
             'code'=>str_replace(" ","",$code),
             'code_cp1'=>$print_date.$flow,
             'code_cp2'=>$weight.$reservation,//20位补充
             'print_date'=>time(),
             'p_nums'=>0,
         ];
         return $data;
     }
}