批量导入解决方案

效果预览:
批量导入解决方案_第1张图片批量导入解决方案_第2张图片
优势:

个人感觉这样做法的优势:
1、文件内数据可视化,体验好。
2、后台无需专门做文件上传,专注解析数据即可。

使用到的扩展:

1、X-admin 后台模板
2、前端操作 Excel 插件

前端HTML代码:

仅支持excel文件,数据最大支持1M
文件表头格式为:分类标题、网址、网站标题


        

前端 Js 代码:






服务端代码如下:

public function webBatchPost(Request $request){
        set_time_limit(0);
        ///获取数据
        $request->filter('');
        $client_batch_data_json = $request->param('batch_data',array());///json化的文件内容
        $client_batch_data_arr = json_decode($client_batch_data_json,true);///将json转换为数组
        $client_batch_data_len = count($client_batch_data_arr);///

		///已脱敏,故效验忽略...
    
        ///数据归类
        $sort_arr = array();
        for($i=0;$i<$client_batch_data_len;$i++){
            $i_data = $client_batch_data_arr[$i];
            $index = $i_data ['分类标题'] ?? 'default';
            $sort_arr[$index][] = array_values($i_data);
        }

        ///获取文件指定的所有分类
        $class_title_arr = array_keys($sort_arr);

        ///获取数据库已经存在的分类标题{结果集为:class_title=>class_id}
        $db_class_data_arr = Db::table('web_class')->where('class_title','in',$class_title_arr)->column('class_id,class_title','class_title');
        $db_class_title_data = array_keys($db_class_data_arr);


        ///获得数据库不存在的分类标题
        $diff_arr = array_diff($class_title_arr,$db_class_title_data);
        try{
            if($diff_arr){
                ///将不存在分类入库
                $a = array();
                foreach($diff_arr as $v2){
                    $a[] = ['class_title'=>$v2,'class_description'=>$v2];
                }
                Db::table('dh_class')->insertAll($a);
                ///重新获取分类标题的class_id
                $db_class_data_arr = Db::table('web_class')->where('class_title','in',$class_title_arr)->column('class_id,class_title','class_title');
            }
        }catch(\Exception $e){
            trace($e->getMessage(),'error');
            return json_encode(['status'=>2,'msg'=>'出现异常,请检查啊!'],JSON_UNESCAPED_UNICODE);
        }


        try{
            $error_data_limit = 0;///不合格数据条数
            $success_data_limit = 0;///合格数据条数
            $unique_data_limit = 0;///重复数据条数
            foreach($sort_arr as $v3){
                $dt = array();
                $web_url = array();
                foreach($v3 as $v4){
                    $v4_0 = $v4[0] ?? '';///分类标题
                    $v4_1 = $v4[1] ?? '';///网站url
                    $v4_2 = $v4[2] ?? '';///网站标题
                    $class_id = $db_class_data_arr[$v4_0] ?? '';///分类id
                    if(empty($v4_0) || empty($v4_1) || empty($v4_2) || empty($class_id)){$error_data_limit += 1;continue;}

                    $dt[] = array('class_id'=>$class_id,'web_url'=>$v4_1,'web_title'=>$v4_2,'web_description'=>$v4_2);
                    $web_url[] = $v4_1;
                }

                ///获取数据库内对应网站的数据
                $web_url_get_data =  Db::table('web_info')->where('web_url','in',$web_url)->field('class_id,web_url,web_title,web_description')->select();;
                ///去重前
                $be = count($dt);
                ///获得上传的数据在数据库内没有的数据
                $dt = array_udiff($dt,$web_url_get_data,"myfunction");
                ///去重后
                $af = count($dt);

                $unique_data_limit = $unique_data_limit + ($be - $af);

                ///入库操作
                if($dt){$res = Db::table('web_info')->insertAll($dt);$success_data_limit = $success_data_limit+$res;}
            }

            return json_encode(['status'=>0,'msg'=>'上传成功:共上传'.$client_batch_data_len.'条数据;检测重复'.$unique_data_limit.'条数据;入库成功'.$success_data_limit.'条数据;不合格'.$error_data_limit.'条数据','url'=>'/admin/web-batch'],JSON_UNESCAPED_UNICODE);
        }catch(\Exception $e){
            trace($e->getMessage(),'error');
            return json_encode(['status'=>2,'msg'=>'出现异常,请检查啊!'],JSON_UNESCAPED_UNICODE);
        }
    }

服务端用到的助手函数:

///比较差集回调函数,返回参数1对照参数2中不同的数据{白话来说结果是参数1内的数据}
function myfunction($a,$b)
{
    if ($a===$b)
    {
        return 0;
    }
    return ($a>$b)?1:-1;
}

代码到此结束.

服务端还可以优化的点:
1、业务实现在model 层,controller 更简洁。
2、服务层数据入库可以分批处理,当数据量达 500 或者某个阈值则入库一次(批量),最终入库剩余数据 。

你可能感兴趣的:(PHP,ThinKPHP,5,JavaScript)