From 31294caced1401ea92a615a665d6cc97b0c7940e Mon Sep 17 00:00:00 2001 From: heibai Date: Mon, 20 Jun 2022 17:34:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=AF=BC=E5=85=A5=E7=95=8C?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/user4s/Import.php | 513 ++++++++++++++++++ .../admin/view/user4s/import/index.html | 113 ++++ public/assets/js/backend/user4s/import.js | 208 +++++++ 3 files changed, 834 insertions(+) create mode 100644 application/admin/controller/user4s/Import.php create mode 100644 application/admin/view/user4s/import/index.html create mode 100644 public/assets/js/backend/user4s/import.js diff --git a/application/admin/controller/user4s/Import.php b/application/admin/controller/user4s/Import.php new file mode 100644 index 0000000..88e3bae --- /dev/null +++ b/application/admin/controller/user4s/Import.php @@ -0,0 +1,513 @@ +level_model = new \app\common\model\user4s\Level; + $this->all_levels = $this->level_model->where('status', 1)->column('id,name'); + $this->all_levels_name = array_flip($this->all_levels); + + $this->cate_model = new \app\common\model\user4s\Category; + $this->all_cates = $this->cate_model->where('status', 1)->column('id,name'); + $this->all_cates_name = array_flip($this->all_cates); + + //var_dump(in_array('本店购车',$this->all_cates)); + } + + /** + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 + * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 + */ + + /** + * 导入 + */ + public function index() + { + if ($this->request->isPost()) { + $params = $this->request->post("row/a"); + $step = $params['step']; + if ($params) { + $params = $this->preExcludeFields($params); + if ($this->dataLimit && $this->dataLimitFieldAutoFill) { + $params[$this->dataLimitField] = $this->auth->id; + } + $result = false; + Db::startTrans(); + try { + //是否采用模型验证 + // if ($this->modelValidate) { + // $name = str_replace("\\model\\", "\\validate\\", get_class($this->model)); + // $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; + // $this->model->validateFailException(true)->validate($validate); + // } + $prefix = Config::get('database.prefix'); + //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name + $importHeadType = 'comment';//name + $table = $prefix.'user4s_user'; + $params['newtable'] = false; + + $params['table'] = $table; + $fileData = $this->fileData($params); + + + $fileData['params'] = http_build_query($params); + $fileData['newtable'] = $params['newtable']; + if (!$step) { + $this->success('匹配到' . $fileData['count'] . '列,开始预览', '', $fileData); + } + $insert = $fileData['insert']; + $fieldArr = $fileData['fieldArr']; + //是否包含admin_id字段 + $has_admin_id = false; + foreach ($fieldArr as $name => $key) { + if ($key == 'admin_id') { + $has_admin_id = true; + break; + } + } + if ($has_admin_id) { + foreach ($insert as $key => &$val) { + if (!isset($val['admin_id']) || empty($val['admin_id'])) { + $val['admin_id'] = $this->auth->isLogin() ? $this->auth->id : 0; + } + } + } + foreach ($insert as $key => &$val) { + //处理字段 + $cardinfo = $this->checkcardid($val['cardid']); + if ($cardinfo['iscard'] == false) { + unset($insert[$key]); + }else{ + $val['birthday'] = $cardinfo['birthday']; + $val['genderdata'] = $cardinfo['sex']; + } + if(!empty($val['frameno'])){ + $check_frameno = $this->check_frameno($val['frameno']); + if($check_frameno == false){ + unset($insert[$key]); + } + } + //todo:分组 + if(empty($val['category_id'])){ + $val['category_id'] = $this->all_cates[1]; + } + if(in_array($val['category_id'],$this->all_cates_name)){ + $val['category_id'] = $this->all_cates[1]; + } + $val['category_id'] = $this->all_cates_name[$val['category_id']]; + //todo:等级 + if(empty($val['level_id'])){ + $val['level_id'] = $this->all_levels[1]; + } + if(in_array($val['level_id'],$this->all_levels_name)){ + $val['level_id'] = $this->all_levels[1]; + } + $val['level_id'] = $this->all_levels_name[$val['level_id']]; + } + var_dump($insert);exit(); + $prefix = Config::get('database.prefix'); + $count = 0; + if ($params['update']) { + foreach ($insert as &$val) { + $count += Db::name('user4s_user') + ->where($params['update'], $val['pid']) + ->update($val); + } + } else { + $res = Db::name('user4s_user')->insertAll($insert); + $count = count($insert); + } + + + Db::commit(); + } catch (ValidateException $e) { + Db::rollback(); + $this->error($e->getMessage()); + } catch (PDOException $e) { + Db::rollback(); + $this->error($e->getMessage()); + } catch (Exception $e) { + Db::rollback(); + $this->error($e->getMessage()); + } + if ($count !== false) { + $params['status'] = 'normal'; + $result = $this->model->allowField(true)->save($params); + $tip = $params['update'] ? '成功更新' : '成功新增'; + $this->success($tip . $count . '条记录', '', array('count' => $count)); + } else { + $this->error(__('No rows were inserted')); + } + } + + $this->error(__('Parameter %s can not be empty', '')); + } + $this->view->assign("update", $this->request->request('update')); + $this->view->assign("to", $this->request->request('to')); + return $this->view->fetch(); + } + + + /** + * 编辑 + * + */ + public function edit($ids = null) + { + $row = $this->model->get($ids); + if (!$row) { + $this->error(__('No Results were found')); + } + $adminIds = $this->getDataLimitAdminIds(); + if (is_array($adminIds)) { + if (!in_array($row[$this->dataLimitField], $adminIds)) { + $this->error(__('You have no permission')); + } + } + if ($this->request->isPost()) { + $params = $this->request->post("row/a"); + if ($params) { + $params = $this->preExcludeFields($params); + $result = false; + Db::startTrans(); + try { + $params['newtable'] = ''; + $fileData = $this->fileData($params); + $fileData['params'] = http_build_query($params); + $this->success('匹配到' . $fileData['count'] . '列,开始预览', '', $fileData); + Db::commit(); + } catch (ValidateException $e) { + Db::rollback(); + $this->error($e->getMessage()); + } catch (PDOException $e) { + Db::rollback(); + $this->error($e->getMessage()); + } catch (Exception $e) { + Db::rollback(); + $this->error($e->getMessage()); + } + if ($result !== false) { + $this->success('设置成功', url('doimport', ['ids' => $row['id']])); + } else { + $this->error(__('No rows were updated')); + } + } + $this->error(__('Parameter %s can not be empty', '')); + } + $row['params'] = http_build_query(array( + 'table' => $row['table'], + 'row' => $row['row'], + 'head_type' => $row['head_type'], + 'path' => $row['path'], + )); + + $this->view->assign("row", $row); + return $this->view->fetch(); + } + + + public function preview() + { + $params = $this->request->post("row/a"); + if (!isset($params["path"])) { + $this->error(__('No Results were found')); + } + if ($this->request->isAjax()) { + $fileData = $this->fileData($params); + + if (isset($params["columns"])) { + return json(array("code" => 1, "data" => $fileData['field'])); + } + return json(["code" => 1, 'data' => ['field' => $fileData['field'], 'data' => $fileData['data'], 'fieldArr' => $fileData['fieldArr']]]); + } + } + + public function check_frameno($frameno) + { + if(empty($frameno)){ + return false; + } + $user = new \app\common\model\user4s\User; + $has_frameno = $user->where(['frameno' =>$frameno])->find(); + if (empty($has_frameno->id)) { + return true; + }else{ + return false; + } + } + protected function fileData($params,$is_check=true) + { + $file = $path = $params['path']; + $row = 2; + $sheet = 0; + if (!$file) { + $this->error(__('Parameter %s can not be empty', 'file')); + } + $filePath = ROOT_PATH . DS . 'public' . DS . $file; + if (!is_file($filePath)) { + $this->error(__('No results were found')); + } + //实例化reader + $ext = pathinfo($filePath, PATHINFO_EXTENSION); + if (!in_array($ext, ['csv', 'xls', 'xlsx'])) { + $this->error(__('Unknown data format')); + } + if ($ext === 'csv') { + $file = fopen($filePath, 'r'); + $filePath = tempnam(sys_get_temp_dir(), 'import_csv'); + $fp = fopen($filePath, "w"); + $n = 0; + while ($line = fgets($file)) { + $line = rtrim($line, "\n\r\0"); + $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']); + if ($encoding != 'utf-8') { + $line = mb_convert_encoding($line, 'utf-8', $encoding); + } + if ($n == 0 || preg_match('/^".*"$/', $line)) { + fwrite($fp, $line . "\n"); + } else { + fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n"); + } + $n++; + } + fclose($file) || fclose($fp); + + $reader = new Csv(); + } elseif ($ext === 'xls') { + $reader = new Xls(); + } else { + $reader = new Xlsx(); + } + + $prefix = Config::get('database.prefix'); + //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name + $importHeadType = 'comment';//name + $table = $prefix.'user4s_user'; + $params['newtable'] = false; + $database = \think\Config::get('database.database'); + $fieldArr = []; + $notnull = []; + + if (!$params['newtable']) { + $pk = Db::getTableInfo($table, 'pk'); + $list = db()->query( + "SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", + [$table, $database] + ); + //var_dump($list,$table, $database); + foreach ($list as $k => $v) { + if ($v['COLUMN_NAME'] !== $pk) { + if ($importHeadType == 'comment') { + if ($v['COLUMN_COMMENT']) { + $importField[] = $v['COLUMN_COMMENT']; + if ($v['IS_NULLABLE']) { + $notnull[] = $v['COLUMN_COMMENT']; + } + } + $fieldArr[$v['COLUMN_COMMENT']] = $v; //['COLUMN_NAME'] + } else { + $importField[] = $v['COLUMN_NAME']; + if ($v['IS_NULLABLE']) { + $notnull[] = $v['COLUMN_NAME']; + } + $fieldArr[$v['COLUMN_NAME']] = $v; //['COLUMN_NAME'] + } + } + } + } + + + $insert = []; + $allData = []; + $count = 0; + try { + if (!$PHPExcel = $reader->load($filePath)) { + $this->error(__('格式错误,请检查!')); + } + $currentSheet = $PHPExcel->getSheet($sheet); //读取文件中的第一个工作表 + $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号 + $allColumn = 'O'; //todo:取得最大的列号 + //var_dump($allColumn); + $allRow = $currentSheet->getHighestRow(); //取得一共有多少行 + $maxColumnNumber = Coordinate::columnIndexFromString($allColumn); + $fields = []; + //todo:处理表头第一行 + for ($currentRow = 1; $currentRow <= 1; $currentRow++) { + for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) { + $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue(); + $fields[] = $val; + $col[] = array( + 'title' => $val, + 'class' => isset($fieldArr[$val]) ? 'success' : '-', + 'type' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_TYPE'] : '--', + 'field' => $val, + 'fieldName' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_NAME'] : '--' //Pinyin::get($val), + ); + + //手动加入表头字段 + // if($val == '身份证' && $currentColumn == 3){ + // $val = '性别'; + // $fields[] = $val; + // $col[] = array( + // 'title' => $val, + // 'class' => isset($fieldArr[$val]) ? 'success' : '-', + // 'type' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_TYPE'] : '--', + // 'field' => $val, + // 'fieldName' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_NAME'] : '--' //Pinyin::get($val), + // ); + // $val = '生日'; + // $fields[] = $val; + // $col[] = array( + // 'title' => $val, + // 'class' => isset($fieldArr[$val]) ? 'success' : '-', + // 'type' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_TYPE'] : '--', + // 'field' => $val, + // 'fieldName' => isset($fieldArr[$val]) ? $fieldArr[$val]['COLUMN_NAME'] : '--' //Pinyin::get($val), + // ); + // //var_dump($col);exit(); + // $count += 2; + // } + // if($currentColumn == $maxColumnNumber){ + // $fields[] = '身份证校验'; + // $fields[] = '车架号校验'; + // } + if (isset($fieldArr[$val])) { + $count += 1; + } + } + } + for ($currentRow = $row; $currentRow <= $allRow; $currentRow++) { + $values = []; + $check_cardid = true; + $check_frameno = true; + //每行数据 + for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) { + //var_dump($currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)); + //$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue(); + $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getCalculatedValue(); + //var_dump($val); + //todo:处理日期格式 + if($currentColumn == 8 || $currentColumn == 15){ + $val = date('Y-m-d',Date::excelToTimestamp($val)); + } + //todo:身份证校验 + if($currentColumn == 3){ + $cardinfo = $this->checkcardid($val); + $check_cardid = $cardinfo['iscard']; + if($check_cardid==false){ + $val=$val.'(身份证号错误)'; + } + } + //todo:车牌重复检测 + if($currentColumn == 10 && strlen($val) > 3){ + $check_frameno = $this->check_frameno($val); + if($check_frameno==false){ + $val=$val.'(车牌号重复)'; + } + } + //todo:分组和等级 + if($currentColumn == 6 && !in_array($val,$this->all_cates)){ + $val=$this->all_cates[1]; + } + if($currentColumn == 7 && !in_array($val,$this->all_levels)){ + //var_dump($this->all_levels,$val);exit(); + $val=$this->all_levels[1]; + } + + $values[] = is_null($val) ? '' : $val; + } + //exit(); + $rows = []; + $all = []; + if($is_check){ + if($check_cardid && $check_frameno){ + $temp = array_combine($fields, $values); + foreach ($temp as $k => $v) { + if (isset($fieldArr[$k]) && $k !== '') { + $rows[$fieldArr[$k]['COLUMN_NAME']] = $v; + } + $all[$k] = $v; + } + + if ($rows) {$insert[] = $rows;} + $allData[] = $all; + } + }else{ + $temp = array_combine($fields, $values); + foreach ($temp as $k => $v) { + if (isset($fieldArr[$k]) && $k !== '') { + $rows[$fieldArr[$k]['COLUMN_NAME']] = $v; + } + $all[$k] = $v; + } + if ($rows) {$insert[] = $rows;} + $allData[] = $all; + } + } + + return array( + 'path' => $path, + 'field' => $col, + 'fieldArr' => $fieldArr, + 'data' => $allData, + 'insert' => $insert, + 'excelField' => $fields, + 'count' => $count + ); + } catch (Exception $exception) { + $this->error($exception->getMessage()); + } + } +} diff --git a/application/admin/view/user4s/import/index.html b/application/admin/view/user4s/import/index.html new file mode 100644 index 0000000..1391c30 --- /dev/null +++ b/application/admin/view/user4s/import/index.html @@ -0,0 +1,113 @@ +
+ {:token()} +
+
导入客户档案
+
+ + + + + + + +
+ +
+ +
+
+ +
+ +
+ {:Form::upload('row[path]', '', ['data-rule'=>'required'])} +
+
+
+ +
+ + + + +
+
+ +
+
+ + + +
+
+ 导入数据预览 + +
+
+
+
+
+ + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/js/backend/user4s/import.js b/public/assets/js/backend/user4s/import.js new file mode 100644 index 0000000..bf7f2bc --- /dev/null +++ b/public/assets/js/backend/user4s/import.js @@ -0,0 +1,208 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'editable'], function($, undefined, Backend, Table, Form, undefined) { + + var Controller = { + index2: function() { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'import/log/index' + location.search, + add_url: 'import/log/add', + del_url: 'import/log/del', + multi_url: 'import/log/multi', + table: 'import_log', + import_url: 'import/log/import', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: 'id', + sortName: 'id', + fixedColumns: true, + columns: [ + [ + { checkbox: true }, + { field: 'id', title: __('Id') }, + { field: 'table', title: __('Table') }, + { field: 'row', title: __('Row') }, + { + field: 'head_type', + title: __('head_type'), + searchList: { "comment": __('comment'), "name": __('name') }, + formatter: Table.api.formatter.status + }, + { field: 'path', title: __('Path'), formatter: Table.api.formatter.url }, + // {field: 'admin_id', title: __('Admin_id')}, + { + field: 'createtime', + title: __('Createtime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'updatetime', + title: __('Updatetime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'status', + title: __('Status'), + searchList: { "normal": __('Normal'), "hidden": __('Hidden') }, + formatter: Table.api.formatter.status + }, + { + field: 'operate', + title: __('Operate'), + table: table, + events: Table.api.events.operate, + formatter: Table.api.formatter.operate, + buttons: [{ + name: 'detail', + text: __('查看'), + title: __('查看'), + classname: 'btn btn-xs btn-primary btn-dialog', + icon: 'fa fa-eye', + extend: 'data-area=\'["1000px","800px"]\'', + url: 'import/log/edit', + callback: function(data) { + Layer.alert("接收到回传数据:" + JSON.stringify(data), { title: "回传数据" }); + }, + visible: function(row) { + //返回true时按钮显示,返回false隐藏 + return true; + } + }] + } + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + index: function() { + function reset() { + $("#step").val(0); + $("#import").addClass("disabled"); + if ($("#c-row").val() && $("#c-rowpath").val()) { + Toastr.success('开始检测数据'); + Fast.api.ajax({ + url: 'user4s/import/preview', + data: $("form[role=form]").serialize(), + dataType: 'json', + }, function(data) { + console.log(data) + let columns = data.field + let xlsdata = data.data + let tableField = data.fieldArr + var select = "" + if (xlsdata.length) { + $("#step").val(1); + $("#import").removeClass("disabled"); + } + // $.each(tableField, function(i, item) { + // select += "" + // }); + html = "" + $.each(columns, function(i, item) { + html += "" + item.field + "" + + }); + html += "" + html += "" + // $.each(columns, function(i, item) { + // if (item.class != "success") html += "" + // else html += "" + // }); + html += "" + $.each(xlsdata, function(i, item) { + html += "" + $.each(columns, function(i, f) { + html += "" + item[f.field] + "" + + }); + + html += "" + + }); + + $("#tableset").html(html) + }, function() { + return false; + }); + } + } + + // $("#selectable select").on("change", function() { + // $("#c-newtable").val('') + // reset() + // }) + // $("#c-newtable").on("change", function() { + // $("#selectable select").val(""); + // reset() + // }) + $("#c-row").on("change", function() { + reset() + }) + $("#c-rowpath").on("change", function() { + reset() + }) + $("#selecthead_type select").on("change", function() { + reset() + }) + $("#import").on("click", function() { + $("#submit").trigger("click"); + }) + Controller.api.bindevent(); + }, + edit: function() { + Controller.api.bindevent(); + }, + + api: { + bindevent: function() { + // Form.api.bindevent($("form[role=form]")); + Form.api.bindevent($("form[role=form]"), function(data, ret) { + console.log(ret) + if (ret.data.count) { + $("#step").val(1); + $("#import").show(); + Toastr.success(ret.msg); + } else { + Toastr.error(ret.msg); + } + if (ret.data.params) { + // 初始化表格参数配置 + var params = ret.data.params + + return false; + } + if (ret.url) { + window.location.href = ret.url; + return false; + } + }, + function(data) { + + }, + function(data) { + //Form.api.submit(this); + // return false; + + $("#xxxx").val($("#setop").val()) + console.log($("#setop").val()) + }, + + + ); + } + } + }; + return Controller; +}); \ No newline at end of file