Import.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <?php
  2. /**
  3. +-----------------------------------------------------------------------------------------------
  4. * GouGuOPEN [ 左手研发,右手开源,未来可期!]
  5. +-----------------------------------------------------------------------------------------------
  6. * @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
  7. +-----------------------------------------------------------------------------------------------
  8. * @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
  9. +-----------------------------------------------------------------------------------------------
  10. * @Author 勾股工作室 <hdm58@qq.com>
  11. +-----------------------------------------------------------------------------------------------
  12. */
  13. declare (strict_types = 1);
  14. namespace app\api\controller;
  15. use app\api\BaseController;
  16. use think\facade\Db;
  17. use app\user\model\Admin;
  18. use app\customer\model\Customer;
  19. use avatars\MDAvatars;
  20. use Overtrue\Pinyin\Pinyin;
  21. use PhpOffice\PhpSpreadsheet\IOFactory;
  22. use PhpOffice\PhpSpreadsheet\Shared\Date as Shared;
  23. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  24. class Import extends BaseController
  25. {
  26. //生成头像
  27. public function to_avatars($char)
  28. {
  29. $defaultData = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  30. 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'S', 'Y', 'Z',
  31. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  32. '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾',
  33. '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
  34. if (isset($char)) {
  35. $Char = $char;
  36. } else {
  37. $Char = $defaultData[mt_rand(0, count($defaultData) - 1)];
  38. }
  39. $OutputSize = min(512, empty($_GET['size']) ? 36 : intval($_GET['size']));
  40. $Avatar = new MDAvatars($Char, 256, 1);
  41. $avatar_name = '/avatars/avatar_256_' . set_salt(10) . time() . '.png';
  42. $path = get_config('filesystem.disks.public.url') . $avatar_name;
  43. $res = $Avatar->Save(public_path() . ltrim($path, '/'), 256);
  44. $Avatar->Free();
  45. return $path;
  46. }
  47. //登录名校验
  48. public function check_name($name,$arr)
  49. {
  50. if(in_array($name,$arr)){
  51. $name = $this->check_name($name.'1',$arr);
  52. }
  53. return $name;
  54. }
  55. //导入员工
  56. public function import_admin(){
  57. // 获取表单上传文件
  58. $file[]= request()->file('file');
  59. if($this->uid>1){
  60. return to_assign(1,'该操作只能是超级管理员有权限操作');
  61. }
  62. try {
  63. // 验证文件大小,名称等是否正确
  64. validate(['file' => 'filesize:51200|fileExt:xls,xlsx'])->check($file);
  65. // 日期前綴
  66. $dataPath = date('Ym');
  67. $md5 = $file[0]->hash('md5');
  68. $savename = \think\facade\Filesystem::disk('public')->putFile($dataPath, $file[0], function () use ($md5) {
  69. return $md5;
  70. });
  71. $fileExtendName = substr(strrchr($savename, '.'), 1);
  72. // 有Xls和Xlsx格式两种
  73. if ($fileExtendName == 'xlsx') {
  74. $objReader = IOFactory::createReader('Xlsx');
  75. } else {
  76. $objReader = IOFactory::createReader('Xls');
  77. }
  78. $objReader->setReadDataOnly(TRUE);
  79. $path = get_config('filesystem.disks.public.url');
  80. // 读取文件,tp6默认上传的文件,在runtime的相应目录下,可根据实际情况自己更改
  81. $objPHPExcel = $objReader->load('.'.$path . '/' .$savename);
  82. $sheet = $objPHPExcel->getSheet(0); //excel中的第一张sheet
  83. $highestRow = $sheet->getHighestRow(); // 取得总行数
  84. $highestColumn = $sheet->getHighestColumn(); // 取得总列数
  85. Coordinate::columnIndexFromString($highestColumn);
  86. $lines = $highestRow - 1;
  87. if ($lines <= 0) {
  88. return to_assign(1, '数据不能为空');
  89. exit();
  90. }
  91. $sex_array=['未知','男','女'];
  92. $type_array=['未知','正式','试用','实习'];
  93. $mobile_array = Db::name('Admin')->where([['status','>=',0],['delete_time','=',0]])->column('mobile');
  94. $email_array = Db::name('Admin')->where([['status','>=',0],['delete_time','=',0]])->column('email');
  95. $username_array = Db::name('Admin')->where([['status','>=',0],['delete_time','=',0]])->column('username');
  96. $department_array = Db::name('Department')->where(['status' => 1])->column('title', 'id');
  97. $position_array = Db::name('Position')->where(['status' => 1])->column('title', 'id');
  98. //循环读取excel表格,整合成数组。如果是不指定key的二维,就用$data[i][j]表示。
  99. for ($j = 3; $j <= $highestRow; $j++) {
  100. $salt = set_salt(20);
  101. $reg_pwd = '123456';
  102. $name = $objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue();
  103. if(empty($name)){
  104. continue;
  105. }
  106. $char = mb_substr($name, 0, 1, 'utf-8');
  107. $sex = array_search_plus($sex_array,$objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue());
  108. $department = array_search_plus($department_array,$objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue());
  109. $position = array_search_plus($position_array,$objPHPExcel->getActiveSheet()->getCell("f" . $j)->getValue());
  110. $type = array_search_plus($type_array,$objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue());
  111. $username = Pinyin::name($name,'none')->join('');
  112. //$username = implode('-', $pinyinname);
  113. $mobile = $objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue();
  114. $email = $objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue();
  115. $file_check['mobile'] = $mobile;
  116. $file_check['email'] = $email;
  117. $validate_mobile = \think\facade\Validate::rule([
  118. 'mobile' => 'require|mobile',
  119. ]);
  120. $validate_email = \think\facade\Validate::rule([
  121. 'email' => 'email',
  122. ]);
  123. if (!$validate_mobile->check($file_check)) {
  124. return to_assign(1, '第'.($j - 2).'行的手机号码的格式错误');
  125. }
  126. else{
  127. if(in_array($mobile,$mobile_array)){
  128. return to_assign(1, '第'.($j - 2).'行的手机号码已存在或者重复');
  129. }
  130. else{
  131. array_push($mobile_array,$mobile);
  132. }
  133. }
  134. if(!empty($email)){
  135. if (!$validate_email->check($file_check)) {
  136. return to_assign(1, '第'.($j - 2).'行的电子邮箱的格式错误');
  137. }
  138. else{
  139. if(in_array($email,$email_array)){
  140. return to_assign(1, '第'.($j - 2).'行的电子邮箱已存在或者重复');
  141. }
  142. else{
  143. array_push($email_array,$email);
  144. }
  145. }
  146. }
  147. else{
  148. $email='';
  149. }
  150. if(empty($department)){
  151. return to_assign(1, '第'.($j - 2).'行的所在部门错误');
  152. }
  153. if(empty($position)){
  154. return to_assign(1, '第'.($j - 2).'行的所属职位错误');
  155. }
  156. $newusername = $this->check_name($username,$username_array);
  157. array_push($username_array,$newusername);
  158. $data[$j - 3] = [
  159. 'name' => $name,
  160. 'nickname' => $name,
  161. 'mobile' => $mobile,
  162. 'email' => $email,
  163. 'sex' => $sex,
  164. 'did' => $department,
  165. 'position_id' => $position,
  166. 'type' => $type,
  167. 'entry_time' => Shared::excelToTimestamp($objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue(),'Asia/Shanghai'),
  168. 'username' => $newusername,
  169. 'salt' => $salt,
  170. 'pwd' => set_password($reg_pwd, $salt),
  171. 'reg_pwd' => $reg_pwd,
  172. 'thumb' => $this->to_avatars($char)
  173. ];
  174. }
  175. //dd($data);exit;
  176. $count=0;
  177. foreach ($data as $a => $aa) {
  178. $aid = Admin::strict(false)->field(true)->insertGetId($aa);
  179. if($aid>0){
  180. //Db::name('DepartmentAdmin')->insert(['admin_id'=>$aid,'department_id'=>$aa['did'],'create_time' => time()]);
  181. $count++;
  182. }
  183. }
  184. return to_assign(0, '共成功导入了'.$count.'条员工数据');
  185. } catch (\think\exception\ValidateException $e) {
  186. return to_assign(1, $e->getMessage());
  187. }
  188. }
  189. //导入客户
  190. public function import_customer(){
  191. // 获取表单上传文件
  192. $file[]= request()->file('file');
  193. $param = get_params();
  194. $type = 'sea';
  195. if(isset($param['type'])){
  196. $type = $param['type'];
  197. }
  198. try {
  199. // 验证文件大小,名称等是否正确
  200. validate(['file' => 'filesize:51200|fileExt:xls,xlsx'])->check($file);
  201. // 日期前綴
  202. $dataPath = date('Ym');
  203. $md5 = $file[0]->hash('md5');
  204. $savename = \think\facade\Filesystem::disk('public')->putFile($dataPath, $file[0], function () use ($md5) {
  205. return $md5;
  206. });
  207. $fileExtendName = substr(strrchr($savename, '.'), 1);
  208. // 有Xls和Xlsx格式两种
  209. if ($fileExtendName == 'xlsx') {
  210. $objReader = IOFactory::createReader('Xlsx');
  211. } else {
  212. $objReader = IOFactory::createReader('Xls');
  213. }
  214. $objReader->setReadDataOnly(TRUE);
  215. $path = get_config('filesystem.disks.public.url');
  216. // 读取文件,tp6默认上传的文件,在runtime的相应目录下,可根据实际情况自己更改
  217. $objPHPExcel = $objReader->load('.'.$path . '/' .$savename);
  218. //$objPHPExcel = $objReader->load('./storage/202209/d11544d20b3ca1c1a5f8ce799c3b2433.xlsx');
  219. $sheet = $objPHPExcel->getSheet(0); //excel中的第一张sheet
  220. $highestRow = $sheet->getHighestRow(); // 取得总行数
  221. $highestColumn = $sheet->getHighestColumn(); // 取得总列数
  222. Coordinate::columnIndexFromString($highestColumn);
  223. $lines = $highestRow - 1;
  224. if ($lines <= 0) {
  225. return to_assign(1, '数据不能为空');
  226. exit();
  227. }
  228. $name_array = [];
  229. $source_array = Db::name('CustomerSource')->where(['status' => 1])->column('title', 'id');
  230. $grade_array = Db::name('CustomerGrade')->where(['status' => 1])->column('title', 'id');
  231. $industry_array = Db::name('Industry')->where(['status' => 1])->column('title', 'id');
  232. //循环读取excel表格,整合成数组。如果是不指定key的二维,就用$data[i][j]表示。
  233. for ($j = 3; $j <= $highestRow; $j++) {
  234. $file_check = [];
  235. $name = $objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue();
  236. if(empty($name)){
  237. continue;
  238. }
  239. $count_name = Db::name('Customer')->where(['name'=>$name,'delete_time'=>0])->count();
  240. if($count_name>0){
  241. return to_assign(1, '第'.($j - 2).'行的客户名称已经存在');
  242. }
  243. if(in_array($name,$name_array)){
  244. return to_assign(1, '上传的文件存在相同的客户名称,请删除再操作');
  245. }
  246. array_push($name_array,$name);
  247. $source_id = array_search_plus($source_array,$objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue());
  248. $grade_id = array_search_plus($grade_array,$objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue());
  249. $industry_id = array_search_plus($industry_array,$objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue());
  250. $c_name = $objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue();
  251. $c_mobile = $objPHPExcel->getActiveSheet()->getCell("F" . $j)->getValue();
  252. $file_check['c_mobile'] = $c_mobile;
  253. $tax_num = $objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue();
  254. $bank = $objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue();
  255. $bank_sn = $objPHPExcel->getActiveSheet()->getCell("I" . $j)->getValue();
  256. $file_check['bank_sn'] = $bank_sn;
  257. $bank_no = $objPHPExcel->getActiveSheet()->getCell("K" . $j)->getValue();
  258. $cperson_mobile = $objPHPExcel->getActiveSheet()->getCell("K" . $j)->getValue();
  259. $address = $objPHPExcel->getActiveSheet()->getCell("L" . $j)->getValue();
  260. $content = $objPHPExcel->getActiveSheet()->getCell("M" . $j)->getValue();
  261. $market = $objPHPExcel->getActiveSheet()->getCell("N" . $j)->getValue();
  262. if(empty($c_name)){
  263. return to_assign(1, '第'.($j - 2).'行的客户联系人姓名没完善');
  264. }
  265. if(empty($c_mobile)){
  266. return to_assign(1, '第'.($j - 2).'行的客户联系人手机号码没完善');
  267. }
  268. $validate_mobile = \think\facade\Validate::rule([
  269. 'c_mobile' => 'mobile',
  270. ]);
  271. if (!$validate_mobile->check($file_check)) {
  272. return to_assign(1, '第'.($j - 2).'行的客户联系人手机号码格式错误');
  273. }
  274. if(empty($source_id)){
  275. return to_assign(1, '第'.($j - 2).'行的客户来源错误');
  276. }
  277. if(empty($grade_id)){
  278. return to_assign(1, '第'.($j - 2).'行的客户等级错误');
  279. }
  280. if(empty($industry_id)){
  281. return to_assign(1, '第'.($j - 2).'行的所属行业错误');
  282. }
  283. if(empty($tax_num)){
  284. $tax_num='';
  285. }
  286. if(empty($bank)){
  287. $bank='';
  288. }
  289. $validate_bank = \think\facade\Validate::rule([
  290. 'bank_sn' => 'number',
  291. ]);
  292. if(!empty($bank_sn)){
  293. if (!$validate_bank->check($file_check)) {
  294. return to_assign(1, '第'.($j - 2).'行的银行卡账号格式错误');
  295. }
  296. }
  297. else{
  298. $bank_sn='';
  299. }
  300. if(empty($bank_no)){
  301. $bank_no='';
  302. }
  303. if(empty($cperson_mobile)){
  304. $cperson_mobile='';
  305. }
  306. if(empty($address)){
  307. $address='';
  308. }
  309. if(empty($content)){
  310. $content='';
  311. }
  312. if(empty($market)){
  313. $market='';
  314. }
  315. $belong_uid = 0;
  316. $belong_did = 0;
  317. if($type != 'sea'){
  318. $belong_uid = $this->uid;
  319. $belong_did = $this->did;
  320. }
  321. $data[$j - 3] = [
  322. 'name' => $name,
  323. 'source_id' => $source_id,
  324. 'grade_id' => $grade_id,
  325. 'industry_id' => $industry_id,
  326. 'tax_num' => $tax_num,
  327. 'bank' => $bank,
  328. 'bank_sn' => $bank_sn,
  329. 'bank_no' => $bank_no,
  330. 'cperson_mobile' => $cperson_mobile,
  331. 'address' => $address,
  332. 'content' => $content,
  333. 'market' => $market,
  334. 'admin_id' => $this->uid,
  335. 'belong_uid' => $belong_uid,
  336. 'belong_did' => $belong_did,
  337. 'c_mobile' => $c_mobile,
  338. 'c_name' => $c_name,
  339. 'create_time' => time(),
  340. 'update_time' => time()
  341. ];
  342. }
  343. //dd($data);exit;
  344. // 批量添加数据
  345. $count=0;
  346. foreach ($data as $a => $aa) {
  347. $cid = Customer::strict(false)->field(true)->insertGetId($aa);
  348. if($cid>0){
  349. $contact = [
  350. 'name' => $aa['c_name'],
  351. 'mobile' => $aa['c_mobile'],
  352. 'sex' => 1,
  353. 'cid' => $cid,
  354. 'is_default' => 1,
  355. 'create_time' => time(),
  356. 'admin_id' => $this->uid
  357. ];
  358. Db::name('CustomerContact')->strict(false)->field(true)->insert($contact);
  359. $count++;
  360. }
  361. }
  362. return to_assign(0, '共成功导入了'.$count.'条客户数据');
  363. } catch (\think\exception\ValidateException $e) {
  364. return to_assign(1, $e->getMessage());
  365. }
  366. }
  367. }