新增客户数据导入功能

This commit is contained in:
hdm 2022-10-10 09:18:51 +08:00
parent e18f59a030
commit 3132dd4640
7 changed files with 226 additions and 6 deletions

View File

@ -65,7 +65,7 @@ BOSS角色suhaizhen 123456
~~~
服务器运行环境要求:
~~~
PHP >= 7.2
PHP >= 7.2.5(建议7.4)
Mysql >= 5.5.0 (需支持innodb引擎)
Apache 或 Nginx
PDO PHP Extension

View File

@ -10,6 +10,7 @@ namespace app\api\controller;
use app\api\BaseController;
use think\facade\Db;
use app\user\model\Admin;
use app\customer\model\Customer;
use avatars\MDAvatars;
use Overtrue\Pinyin\Pinyin;
use PhpOffice\PhpSpreadsheet\IOFactory;
@ -189,4 +190,115 @@ class Import extends BaseController
return to_assign(1, $e->getMessage());
}
}
//导入客户
public function import_customer(){
// 获取表单上传文件
$file[]= request()->file('file');
if($this->uid>1){
return to_assign(1,'该操作只能是超级管理员有权限操作');
}
try {
// 验证文件大小,名称等是否正确
validate(['file' => 'filesize:51200|fileExt:xls,xlsx'])->check($file);
// 日期前綴
$dataPath = date('Ym');
$md5 = $file[0]->hash('md5');
$savename = \think\facade\Filesystem::disk('public')->putFile($dataPath, $file[0], function () use ($md5) {
return $md5;
});
$fileExtendName = substr(strrchr($savename, '.'), 1);
// 有Xls和Xlsx格式两种
if ($fileExtendName == 'xlsx') {
$objReader = IOFactory::createReader('Xlsx');
} else {
$objReader = IOFactory::createReader('Xls');
}
$objReader->setReadDataOnly(TRUE);
$path = get_config('filesystem.disks.public.url');
// 读取文件tp6默认上传的文件在runtime的相应目录下可根据实际情况自己更改
$objPHPExcel = $objReader->load('.'.$path . '/' .$savename);
//$objPHPExcel = $objReader->load('./storage/202209/d11544d20b3ca1c1a5f8ce799c3b2433.xlsx');
$sheet = $objPHPExcel->getSheet(0); //excel中的第一张sheet
$highestRow = $sheet->getHighestRow(); // 取得总行数
$highestColumn = $sheet->getHighestColumn(); // 取得总列数
Coordinate::columnIndexFromString($highestColumn);
$lines = $highestRow - 1;
if ($lines <= 0) {
return to_assign(1, '数据不能为空');
exit();
}
$source_array = Db::name('CustomerSource')->where(['status' => 1])->column('title', 'id');
$grade_array = Db::name('CustomerGrade')->where(['status' => 1])->column('title', 'id');
$industry_array = Db::name('Industry')->where(['status' => 1])->column('title', 'id');
//循环读取excel表格整合成数组。如果是不指定key的二维就用$data[i][j]表示。
for ($j = 3; $j <= $highestRow; $j++) {
$name = $objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue();
if(empty($name)){
continue;
}
$source_id = arraySearch($source_array,$objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue());
$grade_id = arraySearch($grade_array,$objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue());
$industry_id = arraySearch($industry_array,$objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue());
$tax_num = $objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue();
$bank = $objPHPExcel->getActiveSheet()->getCell("F" . $j)->getValue();
$bank_sn = $objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue();
$file_check['bank_sn'] = $bank_sn;
$bank_no = $objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue();
$cperson_mobile = $objPHPExcel->getActiveSheet()->getCell("I" . $j)->getValue();
$address = $objPHPExcel->getActiveSheet()->getCell("J" . $j)->getValue();
$content = $objPHPExcel->getActiveSheet()->getCell("K" . $j)->getValue();
$market = $objPHPExcel->getActiveSheet()->getCell("L" . $j)->getValue();
if(empty($source_id)){
return to_assign(1, '第'.($j - 2).'行的客户来源错误');
}
if(empty($grade_id)){
return to_assign(1, '第'.($j - 2).'行的客户等级错误');
}
if(empty($industry_id)){
return to_assign(1, '第'.($j - 2).'行的所属行业错误');
}
$validate_bank = \think\facade\Validate::rule([
'bank_sn' => 'number',
]);
if(!empty($bank_sn)){
if (!$validate_bank->check($file_check)) {
return to_assign(1, '第'.($j - 2).'行的银行卡账号'.$validate->getError());
}
}
else{
$bank_sn='';
}
$data[$j - 3] = [
'name' => $name,
'source_id' => $source_id,
'grade_id' => $grade_id,
'industry_id' => $industry_id,
'tax_num' => $tax_num,
'bank' => $bank,
'bank_sn' => $bank_sn,
'bank_no' => $bank_no,
'cperson_mobile' => $cperson_mobile,
'address' => $address,
'content' => $content,
'market' => $market,
'admin_id' => $this->uid,
'create_time' => time()
];
}
//dd($data);exit;
// 批量添加数据
if ((new Customer())->saveAll($data)) {
return to_assign(0, '导入成功');
}
else{
return to_assign(1, '导入失败请检查excel文件再试');
}
} catch (\think\exception\ValidateException $e) {
return to_assign(1, $e->getMessage());
}
}
}

View File

@ -64,6 +64,7 @@
</select>
</td>
</tr>
{eq name="$sea" value="0"}
<tr>
<td class="layui-td-gray">归属员工<font>*</font></td>
<td>
@ -81,6 +82,7 @@
<input type="hidden" name="share_ids" value="{$detail.share_ids}">
</td>
</tr>
{/eq}
<tr>
<td class="layui-td-gray" style="vertical-align:top">客户介绍<font>*</font></td>
<td colspan="5">

View File

@ -1,4 +1,12 @@
{extend name="../../base/view/common/base" /}
{block name="style"}
<style>
.gougu-upload-files{background-color: #ffffff; border:1px solid #e4e7ed;color: #c0c4cc;cursor: not-allowed; padding:0 12px; width:180px; box-sizing: border-box; display: inline-block; font-size: inherit; height: 38px; line-height: 35px; margin-right:8px; border-radius:2px;}
.gougu-upload-tips{color:#969696}
.layui-form-item{margin-bottom:8px;}
.layui-input-block{min-height:24px;}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="p-3">
@ -29,7 +37,8 @@
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-normal layui-btn-sm" title="添加客户" lay-event="add">+ 添加公海客户</span>
<button class="layui-btn layui-btn-sm" title="添加客户" lay-event="add">+ 添加公海客户</button>
<button class="layui-btn layui-btn-normal layui-btn-sm" lay-event="import"><i class="layui-icon">&#xe66f;</i>批量导入</button>
</div>
</script>
{/block}
@ -40,7 +49,7 @@
<script>
const moduleInit = ['tool','employeepicker'];
function gouguInit() {
var table = layui.table, tool = layui.tool ,form = layui.form, employeepicker = layui.employeepicker;
var table = layui.table, tool = layui.tool ,form = layui.form, employeepicker = layui.employeepicker,upload=layui.upload;
layui.pageTable = table.render({
elem: '#test',
title: '客户列表',
@ -93,14 +102,15 @@
field: 'right',
fixed:'right',
title: '操作',
width: 168,
width: 200,
align: 'center',
templet: function (d) {
var html = '<div class="layui-btn-group">';
var btn='<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
var btn0='<span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="distribute">分配</span>';
var btn1='<span class="layui-btn layui-btn-xs" lay-event="get">领取</span>';
var btn2='<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">转入废弃池</span>';
return html+btn0+btn1+btn2+'</div>';
return html+btn+btn0+btn1+btn2+'</div>';
}
}
]
@ -113,14 +123,108 @@
tool.side("/customer/index/add?sea=1");
return;
}
if (obj.event === 'import') {
uploadImport();
return;
}
});
let uploadFiles;
function clearFile() {
for (let x in uploadFiles) {
delete uploadFiles[x];
}
$('#gougu-upload-choosed').html('');
}
function uploadImport(){
layer.open({
'title':'批量导入客户',
'type':1,
'area': ['640px', '320px'],
'content':'<div class="layui-form p-3">\
<div id="uploadType1">\
<div class="layui-form-item">\
<label class="layui-form-label">文件:</label>\
<div class="layui-input-block">\
<span class="gougu-upload-files">.xls,.xlsx</span><button type="button" class="layui-btn layui-btn-normal" id="uploadSelect">选择文件</button><a href="/static/home/file/勾股OA客户导入模板.xlsx" class="layui-btn ml-4">Execl表格模板下载</a>\
</div>\
</div>\
<div class="layui-form-item">\
<label class="layui-form-label"></label>\
<div class="layui-input-block">\
<span class="gougu-upload-tips">1、只有超级管理员才能进行批量导入操作<br>2、只能上传 .xls、.xlsx文件<br>3、数据请勿放在合并的单元格中<br>4、文件大小请勿超过2MB导入数据不能超过3000条</span>\
</div>\
</div>\
<div class="layui-form-item">\
<label class="layui-form-label"></label>\
<div class="layui-input-block green" id="gougu-upload-choosed"></div>\
</div>\
<div class="layui-form-item">\
<label class="layui-form-label"></label>\
<div class="layui-input-block red" id="gougu-upload-note"></div>\
</div>\
<div class="layui-form-item layui-form-item-sm">\
<label class="layui-form-label"></label>\
<div class="layui-input-block">\
<button type="button" class="layui-btn" id="uploadAjax">上传并导入</button>\
</div>\
</div>\
</div> \
</div>',
success: function(layero, idx){
form.render();
//选文件
let uploadImport = upload.render({
elem: '#uploadSelect'
,url: '/api/import/import_customer'
,auto: false
,accept: 'file' //普通文件
,exts: 'xls|xlsx' //只允许上传文件格式
,bindAction: '#uploadAjax'
,choose: function(obj){
uploadFiles = obj.pushFile();
// 清空,防止多次上传
clearFile();
obj.preview(function(index, file, result){
obj.pushFile();// 再添加
$('#gougu-upload-choosed').html('已选择:'+file.name);
});
}
,before: function(obj){
}
,progress: function(n, elem, e){
$('#gougu-upload-note').html('文件上转中...');
if(n==100){
$('#gougu-upload-note').html('数据导入中...');
}
}
,error: function(index, upload){
clearFile();
$('#gougu-upload-note').html('数据导入失败,请关闭重试');
}
,done: function(res, index, upload){
clearFile();
layer.msg(res.msg);
$('#gougu-upload-note').html(res.msg);
if(res.code==0){
layer.close(idx);
layui.pageTable.reload();
}
}
});
}
});
}
//监听行工具事件
table.on('tool(test)', function(obj) {
var data = obj.data;
if(obj.event === 'view'){
tool.side('/customer/index/view?id='+data.id);
}
if(obj.event === 'edit'){
tool.side('/customer/index/add?sea=1&id='+data.id);
}
if (obj.event === 'distribute') {
//选择归属人人弹窗
employeepicker.init({

View File

@ -114,6 +114,7 @@ html{background-color:#fff;}
</div>
</td>
</tr>
{notempty name="$contact"}
<tr>
<td colspan="8"><strong>首要联系人信息</strong></td>
</tr>
@ -127,6 +128,7 @@ html{background-color:#fff;}
<td class="layui-td-gray">微信号码</td>
<td>{$contact.wechat}</td>
</tr>
{/notempty}
{notempty name="$detail.trace"}
<tr>
<td colspan="8"><strong>最近沟通记录</strong></td>

View File

@ -20,7 +20,7 @@
}
],
"require": {
"php": ">=7.1.0",
"php": ">=7.2.5",
"topthink/framework": "^6.0.0",
"topthink/think-orm": "^2.0",
"topthink/think-multi-app": "^1.0",