Business.php 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. <?php
  2. namespace app\admin\controller\qingdong\customer;
  3. use addons\qingdong\model\BusinessStatus;
  4. use addons\qingdong\model\Customer;
  5. use addons\qingdong\model\Field;
  6. use addons\qingdong\model\File;
  7. use addons\qingdong\model\BusinessProduct;
  8. use addons\qingdong\model\FormField;
  9. use addons\qingdong\model\Product;
  10. use addons\qingdong\model\Staff;
  11. use app\admin\controller\qingdong\Base;
  12. use addons\qingdong\model\BusinessOther;
  13. use addons\qingdong\model\Form;
  14. use addons\qingdong\model\Contract;
  15. use addons\qingdong\model\Record;
  16. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  17. use PhpOffice\PhpSpreadsheet\Reader\Csv;
  18. use PhpOffice\PhpSpreadsheet\Reader\Xls;
  19. use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  20. use PhpOffice\PhpSpreadsheet\RichText\RichText;
  21. use think\Db;
  22. use think\Exception;
  23. /**
  24. * 商机管理
  25. */
  26. class Business extends Base
  27. {
  28. protected $relationSearch = true;
  29. /**
  30. * @var \addons\qingdong\model\Business
  31. */
  32. protected $model = null;
  33. public function _initialize()
  34. {
  35. parent::_initialize();
  36. $this->model = new \addons\qingdong\model\Business;
  37. }
  38. /**
  39. * 查看
  40. */
  41. public function index()
  42. {
  43. //设置过滤方法
  44. $this->request->filter(['strip_tags', 'trim']);
  45. if ($this->request->isAjax()) {
  46. if ($this->request->request('keyField')) {
  47. return $this->selectpage();
  48. }
  49. //0:全部 1:我负责的 2:下属负责的 3:今日待跟进 4:今日已跟进 5:从未跟进的
  50. $type = input('type', 0);
  51. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  52. switch ($type) {
  53. case 1:
  54. $staff = Staff::info();
  55. $wheres['owner_staff_id'] = $staff->id;
  56. break;
  57. case 2:
  58. $wheres['owner_staff_id'] = array('in', Staff::getLowerStaffId());
  59. break;
  60. case 3:
  61. $start = date('Y-m-d 00:00:00');
  62. $end = date('Y-m-d 23:59:59');
  63. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array(array('egt', $start), array('elt', $end))))->field("id,relation_id")->select())->toArray();
  64. $relationId = [];
  65. foreach ($record as $k => $v) {
  66. $whereRe['id'] = array('gt', $v['id']);
  67. $whereRe['relation_id'] = $v['relation_id'];
  68. $recordData = Record::where($whereRe)->count();
  69. if ($recordData == 0) {
  70. $relationId[] = $v['relation_id'];
  71. }
  72. }
  73. $wheres['id'] = array('in', $relationId);
  74. $staff = Staff::info();
  75. $wheres['owner_staff_id'] = $staff->id;
  76. break;
  77. case 4:
  78. $start = date('Y-m-d 00:00:00');
  79. $end = date('Y-m-d 23:59:59');
  80. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array(array('egt', $start), array('elt', $end))))->field("id,relation_id")->select())->toArray();
  81. $relationId = [];
  82. foreach ($record as $k => $v) {
  83. $whereRe['id'] = array('gt', $v['id']);
  84. $whereRe['relation_id'] = $v['relation_id'];
  85. $recordData = Record::where($whereRe)->count();
  86. if ($recordData >= 1) {
  87. $relationId[] = $v['relation_id'];
  88. }
  89. }
  90. $wheres['id'] = array('in', $relationId);
  91. $staff = Staff::info();
  92. $wheres['owner_staff_id'] = $staff->id;
  93. break;
  94. case 5:
  95. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array('neq', '')))->column('relation_id'))->toArray();
  96. $wheres['id'] = array('not in', $record);
  97. $staff = Staff::info();
  98. $wheres['owner_staff_id'] = $staff->id;
  99. break;
  100. default:
  101. $wheres['owner_staff_id'] = array('in', Staff::getMyStaffIds());
  102. break;
  103. }
  104. $ids = [];
  105. $group_id = input('group_id');
  106. $staff_id = input('staff_id');
  107. if ($group_id) {//角色组
  108. $ids = Staff::getGroupStaffIds($group_id);
  109. }
  110. if ($staff_id) {
  111. $ids = $staff_id;
  112. }
  113. if ($group_id || $staff_id) {
  114. $wheres['owner_staff_id'] = ['in', $ids];
  115. }
  116. $list = $this->model->where($where)
  117. ->where($wheres)
  118. ->with([
  119. 'customer',
  120. 'ownerStaff',
  121. 'product'
  122. ])->order($sort, $order)->paginate($limit);
  123. foreach($list as $k=>$v){
  124. $types = BusinessStatus::where(array('business_id'=>$v['id']))->order('id desc')->value('type');
  125. $list[$k]['type'] = $types ? (int)$types : 0;
  126. }
  127. $result = array("total" => $list->total(), "rows" => $list->items());
  128. return json($result);
  129. }
  130. $field = FormField::getFields(FormField::BUSINESS_TYPE);
  131. $this->assignconfig('fields', $field);
  132. return $this->view->fetch();
  133. }
  134. /**
  135. * 添加
  136. */
  137. public function add()
  138. {
  139. if ($this->request->isPost()) {
  140. $params = $this->request->post("row/a");
  141. if ($params) {
  142. $params = $this->preExcludeFields($params);
  143. $result = FormField::checkFields(FormField::BUSINESS_TYPE, $params);
  144. if ($result !== true) {
  145. $this->error($result);
  146. }
  147. $result = false;
  148. Db::startTrans();
  149. try {
  150. $params = Form::updateFormParams(Form::BUSINESS_TYPE, $params);
  151. if ($params['product']) {
  152. $params['product'] = json_decode($params['product'], true);
  153. }
  154. $result = $this->model::createBusiness($params);
  155. Db::commit();
  156. } catch (Exception $e) {
  157. Db::rollback();
  158. $this->error($e->getMessage());
  159. }
  160. if ($result !== false) {
  161. $this->success();
  162. } else {
  163. $this->error(__('No rows were inserted'));
  164. }
  165. }
  166. $this->error(__('Parameter %s can not be empty', ''));
  167. }
  168. $customer_id = input('customer_id');
  169. $this->assign('customer_id', $customer_id);
  170. $this->assign('customer', Customer::get($customer_id));
  171. $this->assign('staffs', Staff::allList());
  172. $this->assign('form_data', Form::getDataValue('business'));
  173. return $this->view->fetch();
  174. }
  175. /**
  176. * 修改
  177. */
  178. public function edit($ids = null)
  179. {
  180. $map['id'] = $ids;
  181. if ($this->request->isAjax()) {
  182. $params = $this->request->post('row/a');
  183. $params = $this->preExcludeFields($params);
  184. $result = FormField::checkFields(FormField::BUSINESS_TYPE, $params,$ids);
  185. if ($result !== true) {
  186. $this->error($result);
  187. }
  188. Db::startTrans();
  189. try {
  190. $params = Form::updateFormParams(Form::BUSINESS_TYPE, $params);
  191. $params['id'] = $ids;
  192. $result = $this->model::updateBusiness($params);
  193. Db::commit();
  194. } catch (Exception $e) {
  195. Db::rollback();
  196. $this->error($e->getMessage());
  197. }
  198. if ($result !== false) {
  199. $this->success();
  200. } else {
  201. $this->error(__('No rows were inserted'));
  202. }
  203. }
  204. $row = $this->model->where($map)->with(['customer'])->find();
  205. $product=BusinessProduct::where(['business_id'=>$ids])->with(['productinfo'])->select();
  206. foreach ($product as $k=>$v){
  207. if($v['productinfo']){
  208. $v['product_name']=$v['productinfo']['name'];
  209. $v['cost_price']=$v['productinfo']['cost_price'];
  210. $v['type']=$v['productinfo']['type'];
  211. if($v['productinfo']['goods']){
  212. $v['goods_name']=$v['productinfo']['goods']['name'];
  213. }
  214. }
  215. $product[$k]=$v;
  216. }
  217. $row['product']=json_encode($product);
  218. $row = $row->toArray();
  219. $row = BusinessOther::getOther($row);
  220. $this->view->assign("row", $row);
  221. $this->assign('customers', Customer::getList());
  222. $this->assign('form_data', Form::getDataValue('business', $row));
  223. return $this->view->fetch();
  224. }
  225. /**
  226. * 详情
  227. */
  228. public function detail($ids = null)
  229. {
  230. $row = $this->model->where(['id' => $ids])->with([
  231. 'customer',
  232. 'ownerStaff'
  233. ])->find();
  234. if (empty($row)) {
  235. $this->error(__('No Results were found'));
  236. }
  237. $row = $row->toArray();
  238. $row = BusinessOther::getOther($row);
  239. //跟进记录
  240. $this->assign('records', Record::getList(Record::CONTRACT_TYPE, $ids));
  241. $type = BusinessStatus::where(array('business_id'=>$ids))->order('id desc')->value('type');
  242. $row['type'] = $type ? (int)$type : 0;
  243. $this->assign('row', $row);
  244. $this->assign('ids', $ids);
  245. $this->assign('form_data', Form::getDataValue('business', $row));
  246. $this->assignconfig("idinfo", ['id' => $ids]);
  247. return $this->view->fetch();
  248. }
  249. /**
  250. * 添加跟进
  251. */
  252. public function record($ids = null) {
  253. if ($this->request->isPost()) {
  254. $params = $this->request->post('row/a');
  255. $params['relation_type'] = 5;
  256. $params['relation_id'] = $ids;
  257. if(!empty($params['files'])){
  258. $params['files']=File::getId($params['files']);
  259. }
  260. Db::startTrans();
  261. try {
  262. $result = Record::createRecord($params);
  263. Db::commit();
  264. } catch (Exception $e) {
  265. Db::rollback();
  266. $this->error($e->getMessage());
  267. }
  268. if ($result) {
  269. $this->success('创建跟进记录成功');
  270. }
  271. $this->error('创建失败');
  272. }
  273. $staff=Staff::where([])->column('name','id');
  274. $follow= Field::getField('商机状态');
  275. $this->assign('follow', $follow);
  276. $this->assign('ids', $ids);
  277. $this->assign('staff', $staff);
  278. return $this->view->fetch();
  279. }
  280. /**
  281. * 批量转移商机
  282. */
  283. public function batch_change($ids = null)
  284. {
  285. $ids = json_decode($ids, true);
  286. $ids = $this->model->where([
  287. 'id' => ['in', $ids]
  288. ])->column('id');
  289. if (empty($ids)) {
  290. $this->error(__('No Results were found'));
  291. }
  292. if ($this->request->isPost()) {
  293. $params = $this->request->post("row/a");
  294. if ($params) {
  295. $params = $this->preExcludeFields($params);
  296. $result = false;
  297. Db::startTrans();
  298. try {
  299. $result = $this->model::batchTransfer($ids, $params['owner_staff_id']);
  300. Db::commit();
  301. } catch (Exception $e) {
  302. Db::rollback();
  303. $this->error($e->getMessage());
  304. }
  305. if ($result !== false) {
  306. $this->success();
  307. } else {
  308. $this->error(__('No rows were inserted'));
  309. }
  310. }
  311. $this->error(__('Parameter %s can not be empty', ''));
  312. }
  313. $staffs = Staff::getList();
  314. $this->assign('staffs', $staffs);
  315. $this->assign('ids', json_encode($ids));
  316. return $this->view->fetch();
  317. }
  318. /**
  319. * 产品信息
  320. */
  321. public function product() {
  322. $this->request->filter(['strip_tags']);
  323. if ($this->request->isAjax()) {
  324. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  325. $business_id = input('business_id');
  326. $wheres['business_product.business_id'] =$business_id;
  327. $list = BusinessProduct::where($where)->where($wheres)->with(['product'])->order($sort, $order)->paginate($limit);
  328. foreach($list as $k=>$v){
  329. if(!$v['product']['id']){
  330. unset($list[$k]);
  331. }
  332. }
  333. $row = $list->items();
  334. $result = array("total" => $list->total(), "rows" => $row);
  335. return json($result);
  336. }
  337. return $this->view->fetch();
  338. }
  339. /**
  340. * 获取相关合同
  341. */
  342. public function get_contract()
  343. {
  344. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  345. $business_id = input('business_id');
  346. $wheres['business_id'] =$business_id;
  347. $list = Contract::where([
  348. 'business_id' => $business_id,
  349. ])->with('customer')->paginate($limit);
  350. $result = array("total" => $list->total(), "rows" => $list->items());
  351. return json($result);
  352. }
  353. /**
  354. * 删除商机
  355. */
  356. public function delete($ids = null)
  357. {
  358. if(!$ids){
  359. $this->error('参数不正确');
  360. }
  361. $data = $this->model->where([
  362. 'id' => $ids
  363. ])->column('id');
  364. if (empty($data)) {
  365. $this->error('商机不存在');
  366. }
  367. $result = $this->model->where(array('id'=>$ids))->update(array('updatetime'=>time(),'deletetime'=>time()));
  368. if(!$result){
  369. $this->error('删除失败');
  370. }
  371. $this->success('删除成功');
  372. }
  373. /**
  374. * 推进商机
  375. */
  376. public function batch_status($ids = null)
  377. {
  378. $ids = $this->model->where([
  379. 'id' => $ids
  380. ])->value('id');
  381. if (empty($ids)) {
  382. $this->error('商机不存在');
  383. }
  384. if ($this->request->isPost()) {
  385. $params = $this->request->post("row/a");
  386. if ($params) {
  387. $params = $this->preExcludeFields($params);
  388. if(!empty($params['file'])){
  389. $params['file']=File::getId($params['file']);
  390. }
  391. $result = false;
  392. Db::startTrans();
  393. try {
  394. $params['id'] = $ids;
  395. $result = $this->model::batchStatus($params);
  396. Db::commit();
  397. } catch (Exception $e) {
  398. Db::rollback();
  399. $this->error($e->getMessage());
  400. }
  401. if ($result !== false) {
  402. $this->success();
  403. } else {
  404. $this->error('推进失败');
  405. }
  406. }
  407. $this->error('推进失败');
  408. }
  409. return $this->view->fetch();
  410. }
  411. /**
  412. * 获取推进商机
  413. */
  414. public function get_business_status()
  415. {
  416. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  417. $business_id = input('business_id');
  418. $wheres['business_id'] =$business_id;
  419. $list = BusinessStatus::where([
  420. 'business_id' => $business_id,
  421. ])->order('id desc')->paginate($limit);
  422. foreach($list as $k=>$v){
  423. if($v['file']){
  424. $list[$k]['file'] = File::where(array('id'=>['in',$v['file']]))->select();
  425. }
  426. }
  427. $result = array("total" => $list->total(), "rows" => $list->items());
  428. return json($result);
  429. }
  430. /**
  431. * 导入客户
  432. * @return string|void
  433. */
  434. public function import()
  435. {
  436. set_time_limit(0);
  437. if ($this->request->isPost()) {
  438. $file = $this->request->request('file');
  439. $staff_id = $this->request->request('staff_id', 0);
  440. if (!$file) {
  441. $this->error(__('Parameter %s can not be empty', 'file'));
  442. }
  443. $filePath = ROOT_PATH . 'public' . $file;
  444. if (!is_file($filePath)) {
  445. $this->error(__('No results were found'));
  446. }
  447. //实例化reader
  448. $ext = pathinfo($filePath, PATHINFO_EXTENSION);
  449. if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
  450. $this->error(__('Unknown data format'));
  451. }
  452. if ($ext === 'csv') {
  453. $file = fopen($filePath, 'r');
  454. $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
  455. $fp = fopen($filePath, "w");
  456. $n = 0;
  457. while ($line = fgets($file)) {
  458. $line = rtrim($line, "\n\r\0");
  459. $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
  460. if ($encoding != 'utf-8') {
  461. $line = mb_convert_encoding($line, 'utf-8', $encoding);
  462. }
  463. if ($n == 0 || preg_match('/^".*"$/', $line)) {
  464. fwrite($fp, $line . "\n");
  465. } else {
  466. fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
  467. }
  468. $n++;
  469. }
  470. fclose($file) || fclose($fp);
  471. $reader = new Csv();
  472. } elseif ($ext === 'xls') {
  473. $reader = new Xls();
  474. } else {
  475. $reader = new Xlsx();
  476. }
  477. if (!$PHPExcel = $reader->load($filePath)) {
  478. $this->error(__('Unknown data format'));
  479. }
  480. $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
  481. $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
  482. $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
  483. $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
  484. //开始读取数据
  485. $fields = [];
  486. for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
  487. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  488. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  489. $fields[$currentRow][] = $val;
  490. if ($val instanceof RichText) {//富文本转换字符串
  491. $val = $val->__toString();
  492. }
  493. $values[] = is_null($val) ? '' : trim($val);
  494. }
  495. }
  496. if (!isset($fields[1])) {
  497. $this->error('导入文件第一行没有数据');
  498. }
  499. $lastid = $this->model->withTrashed()->order('id desc')->value('id');
  500. $lastid = $lastid + 5;//防止重复
  501. $customerRow = [];
  502. $errorInfo = [];
  503. $customerNames=Customer::where([])->column('id,owner_staff_id','name');
  504. $fieldnames = FormField::where(['types' => FormField::BUSINESS_TYPE])->column('field', 'name');
  505. if(!$fieldnames){
  506. $this->error('请在系统管理->字段管理中保存商机管理表单生成商机导入字段');
  507. }
  508. $fn = [];
  509. for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
  510. $values = [];
  511. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  512. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  513. $values[] = is_null($val) ? '' : $val;
  514. }
  515. foreach ($values as $l) {
  516. $fn[] = $fieldnames[$l] ?? '';
  517. }
  518. }
  519. for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
  520. $values = [];
  521. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  522. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  523. if ($val instanceof RichText) {//富文本转换字符串
  524. $val = $val->__toString();
  525. }
  526. $values[] = is_null($val) ? NULL : trim($val);
  527. }
  528. $lastid++;
  529. $addBusiness = ['id' => $lastid];
  530. $customer=isset($customerNames[$values[0]])?$customerNames[$values[0]]:0;
  531. if(empty($customer)){
  532. $errorInfo[] = "第{$currentRow}行,客户名称不存在;";
  533. continue;
  534. }
  535. $addBusiness['customer_id']=$customer['id'];
  536. $addBusiness['owner_staff_id']=$customer['owner_staff_id'];
  537. foreach ($values as $kv => $value) {
  538. if (!isset($fn[$kv]) || empty($fn[$kv])) {
  539. continue;
  540. }
  541. $addBusiness[$fn[$kv]] = $value;
  542. }
  543. if (empty($addBusiness['name'])) {
  544. $errorInfo[] = "第{$currentRow}行,商机名称不能为空;";
  545. continue;
  546. }
  547. $customerRow[] = $addBusiness;
  548. }
  549. if (!empty($errorInfo)) {
  550. $this->error(implode(',', $errorInfo));
  551. }
  552. Db::startTrans();
  553. try {
  554. $this->model::importBusiness($customerRow);
  555. Db::commit();
  556. } catch (Exception $e) {
  557. Db::rollback();
  558. $this->error($e->getMessage());
  559. }
  560. $this->success('导入成功');
  561. }
  562. $this->assign('staffs', Staff::getList());
  563. return $this->view->fetch();
  564. }
  565. /**
  566. * 模板
  567. */
  568. public function template()
  569. {
  570. $title = ['客户名称'];
  571. $dataValue = Form::getDataValue(Form::BUSINESS_TYPE);
  572. foreach ($dataValue as $val) {
  573. $title[] = $val['config']['label'];
  574. }
  575. $file = export_excel($title, [], '商机');
  576. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  577. header('Content-Disposition: attachment;filename=' . $file['fileName']);
  578. header('Cache-Control: max-age=0');
  579. $obj = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  580. // 以下内容是excel文件的信息描述信息
  581. $obj->getProperties()->setTitle('导出文件'); //设置标题
  582. $obj->setActiveSheetIndex(0);
  583. $obj->getActiveSheet()->setTitle('导出文件');
  584. /* 循环读取每个单元格的数据 */
  585. $a = 'A';
  586. $currentSheet = $obj->getActiveSheet();
  587. foreach ($title as $key => $value) {
  588. //读取工作表1
  589. // 设置第一行加粗
  590. $obj->getActiveSheet()->getStyle($a . '1')->getFont()->setBold(true);
  591. //这里是设置单元格的内容
  592. $currentSheet->getCell($a . '1')->setValue($value);
  593. $a++;
  594. }
  595. $PHPWriter = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($obj);
  596. $PHPWriter->save('php://output');
  597. }
  598. /**
  599. * 导出信息
  600. */
  601. public function export()
  602. {
  603. $this->request->filter(['strip_tags', 'trim']);
  604. $ids = input('ids');
  605. $isall = input('isall',1);
  606. $wheres = array();
  607. //导出其中几条
  608. if (isset($ids) && $ids) {
  609. $wheres['id'] = array('in', $ids);
  610. }
  611. //导出全部
  612. if ($isall == 3) {
  613. unset($wheres['id']);
  614. }
  615. //0:全部 1:我负责的 2:下属负责的 3:今日待跟进 4:今日已跟进 5:从未跟进的
  616. $type = input('type', 0);
  617. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  618. $staff = Staff::info();
  619. $staff_id = $staff->id;
  620. switch ($type) {
  621. case 1:
  622. $wheres['owner_staff_id'] = $staff_id;
  623. break;
  624. case 2:
  625. $wheres['owner_staff_id'] = array('in', Staff::getLowerStaffId());
  626. break;
  627. case 3:
  628. $start = date('Y-m-d 00:00:00');
  629. $end = date('Y-m-d 23:59:59');
  630. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array(array('egt', $start), array('elt', $end))))->field("id,relation_id")->select())->toArray();
  631. $relationId = [];
  632. foreach ($record as $k => $v) {
  633. $whereRe['id'] = array('gt', $v['id']);
  634. $whereRe['relation_id'] = $v['relation_id'];
  635. $recordData = Record::where($whereRe)->count();
  636. if ($recordData == 0) {
  637. $relationId[] = $v['relation_id'];
  638. }
  639. }
  640. $wheres['id'] = array('in', $relationId);
  641. $staff = Staff::info();
  642. $wheres['owner_staff_id'] = $staff->id;
  643. break;
  644. case 4:
  645. $start = date('Y-m-d 00:00:00');
  646. $end = date('Y-m-d 23:59:59');
  647. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array(array('egt', $start), array('elt', $end))))->field("id,relation_id")->select())->toArray();
  648. $relationId = [];
  649. foreach ($record as $k => $v) {
  650. $whereRe['id'] = array('gt', $v['id']);
  651. $whereRe['relation_id'] = $v['relation_id'];
  652. $recordData = Record::where($whereRe)->count();
  653. if ($recordData >= 1) {
  654. $relationId[] = $v['relation_id'];
  655. }
  656. }
  657. $wheres['id'] = array('in', $relationId);
  658. $staff = Staff::info();
  659. $wheres['owner_staff_id'] = $staff->id;
  660. break;
  661. case 5:
  662. $record = collection(Record::where(array('relation_type' => 5, 'next_time' => array('neq', '')))->column('relation_id'))->toArray();
  663. $wheres['id'] = array('not in', $record);
  664. $staff = Staff::info();
  665. $wheres['owner_staff_id'] = $staff->id;
  666. break;
  667. default:
  668. $wheres['owner_staff_id'] = array('in', Staff::getMyStaffIds());
  669. break;
  670. }
  671. $list = $this->model->with([
  672. 'ownerStaff','businessOther','customer'
  673. ])->where($where)->where($wheres)->order($sort, $order)->select();
  674. $list = collection($list)->toArray();
  675. if (!$list) {
  676. $this->error('无导出数据');
  677. }
  678. $title = [
  679. '序号',
  680. '客户名称',
  681. '负责人',
  682. '创建时间',
  683. '下次联系时间',
  684. ];
  685. $dataValue = Form::getDataValue(Form::BUSINESS_TYPE);
  686. foreach ($dataValue as $val) {
  687. $title[] = $val['config']['label'];
  688. }
  689. foreach ($list as $k => $v) {
  690. if($v['business_other']){//其他客户
  691. $other=$v['business_other']['otherdata'];
  692. $other=json_decode($other,true);
  693. $v = array_merge($v, $other);
  694. }
  695. $field = array(
  696. $v['id'],
  697. $v['customer']['name'],
  698. $v['owner_staff']['name'],
  699. date('Y-m-d H:i:s',$v['createtime']),
  700. $v['next_time'],
  701. );
  702. foreach ($dataValue as $val) {
  703. if ($val['component'] == 'uploadImage' || $val['component'] == 'uploadFile') {
  704. $field[] = $v[$val['id'] . '_str'] ?? '';
  705. } else {
  706. $field[] = ($v[$val['id']] ?? '');
  707. }
  708. }
  709. $data[] = $field;
  710. }
  711. $file = export_excel($title, $data, '商机');
  712. if ($file['filePath']) {
  713. $this->success('导出成功', '', $file);
  714. }
  715. $this->error('导出失败');
  716. }
  717. /**
  718. * 导入产品明细
  719. * @return string|void
  720. */
  721. public function import_product()
  722. {
  723. set_time_limit(0);
  724. if ($this->request->isPost()) {
  725. $file = $this->request->request('file');
  726. if (!$file) {
  727. $this->error(__('Parameter %s can not be empty', 'file'));
  728. }
  729. $filePath = ROOT_PATH . 'public' . $file;
  730. if (!is_file($filePath)) {
  731. $this->error(__('No results were found'));
  732. }
  733. //实例化reader
  734. $ext = pathinfo($filePath, PATHINFO_EXTENSION);
  735. if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
  736. $this->error(__('Unknown data format'));
  737. }
  738. if ($ext === 'csv') {
  739. $file = fopen($filePath, 'r');
  740. $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
  741. $fp = fopen($filePath, "w");
  742. $n = 0;
  743. while ($line = fgets($file)) {
  744. $line = rtrim($line, "\n\r\0");
  745. $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
  746. if ($encoding != 'utf-8') {
  747. $line = mb_convert_encoding($line, 'utf-8', $encoding);
  748. }
  749. if ($n == 0 || preg_match('/^".*"$/', $line)) {
  750. fwrite($fp, $line . "\n");
  751. } else {
  752. fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
  753. }
  754. $n++;
  755. }
  756. fclose($file) || fclose($fp);
  757. $reader = new Csv();
  758. } elseif ($ext === 'xls') {
  759. $reader = new Xls();
  760. } else {
  761. $reader = new Xlsx();
  762. }
  763. if (!$PHPExcel = $reader->load($filePath)) {
  764. $this->error(__('Unknown data format'));
  765. }
  766. $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
  767. $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
  768. $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
  769. $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
  770. //开始读取数据
  771. $fields = [];
  772. for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
  773. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  774. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  775. $fields[$currentRow][] = $val;
  776. if ($val instanceof RichText) {//富文本转换字符串
  777. $val = $val->__toString();
  778. }
  779. $values[] = is_null($val) ? '' : trim($val);
  780. }
  781. }
  782. if (!isset($fields[1])) {
  783. $this->error('导入文件第一行没有数据');
  784. }
  785. $lastid = BusinessProduct::order('id desc')->value('id');
  786. $lastid = $lastid + 5;//防止重复
  787. $businessProductRow = [];
  788. $errorInfo = [];
  789. $businessName=$this->model::where([])->column('id,name,money','name');
  790. $productName=Product::where([])->column('id,price','name');
  791. for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
  792. $values = [];
  793. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  794. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  795. $values[] = is_null($val) ? '' : $val;
  796. }
  797. }
  798. for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
  799. $values = [];
  800. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  801. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  802. if ($val instanceof RichText) {//富文本转换字符串
  803. $val = $val->__toString();
  804. }
  805. $values[] = is_null($val) ? NULL : trim($val);
  806. }
  807. $lastid++;
  808. $addContractProduct = ['id' => $lastid];
  809. $business = isset($businessName[$values[0]]) ? $businessName[$values[0]] : 0;
  810. if (empty($business)) {
  811. $errorInfo[] = "第{$currentRow}行,商机名称不存在;";
  812. continue;
  813. }
  814. $product = isset($productName[$values[1]]) ? $productName[$values[1]] : 0;
  815. if (empty($product)) {
  816. $errorInfo[] = "第{$currentRow}行,产品名称不存在;";
  817. continue;
  818. }
  819. if (empty($values[2])) {
  820. $errorInfo[] = "第{$currentRow}行,产品数量不能为空;";
  821. continue;
  822. }
  823. if (empty($values[3])) {
  824. $errorInfo[] = "第{$currentRow}行,产品售价不能为空;";
  825. continue;
  826. }
  827. $addContractProduct['business_id'] = $business['id'];
  828. $addContractProduct['product_id'] = $product['id'];
  829. $addContractProduct['number'] = $values[2];
  830. $addContractProduct['price'] = $values[3];
  831. $businessProductRow[]=$addContractProduct;
  832. }
  833. if (!empty($errorInfo)) {
  834. $this->error(implode(',', $errorInfo));
  835. }
  836. Db::startTrans();
  837. try {
  838. BusinessProduct::importProduct($businessProductRow);
  839. Db::commit();
  840. } catch (Exception $e) {
  841. Db::rollback();
  842. $this->error($e->getMessage());
  843. }
  844. $this->success('导入成功');
  845. }
  846. $this->assign('staffs', Staff::getList());
  847. return $this->view->fetch();
  848. }
  849. /**
  850. * 模板
  851. */
  852. public function template_product()
  853. {
  854. $title = [
  855. '商机名称',
  856. '商品名称',
  857. '数量',
  858. '售价',
  859. ];
  860. $file = export_excel($title, [], '产品明细');
  861. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  862. header('Content-Disposition: attachment;filename=' . $file['fileName']);
  863. header('Cache-Control: max-age=0');
  864. $obj = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  865. // 以下内容是excel文件的信息描述信息
  866. $obj->getProperties()->setTitle('导出文件'); //设置标题
  867. $obj->setActiveSheetIndex(0);
  868. $obj->getActiveSheet()->setTitle('导出文件');
  869. /* 循环读取每个单元格的数据 */
  870. $a = 'A';
  871. $currentSheet = $obj->getActiveSheet();
  872. foreach ($title as $key => $value) {
  873. //读取工作表1
  874. // 设置第一行加粗
  875. $obj->getActiveSheet()->getStyle($a . '1')->getFont()->setBold(true);
  876. //这里是设置单元格的内容
  877. $currentSheet->getCell($a . '1')->setValue($value);
  878. $a++;
  879. }
  880. $PHPWriter = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($obj);
  881. $PHPWriter->save('php://output');
  882. }
  883. /**
  884. * 导出信息
  885. */
  886. public function export_product()
  887. {
  888. $this->request->filter(['strip_tags', 'trim']);
  889. $ids = input('ids');
  890. $type = input('type');
  891. $wheres = array();
  892. //导出其中几条
  893. if (isset($ids)) {
  894. $wheres['business_id'] = array('in', $ids);
  895. }
  896. //导出全部
  897. if (isset($type)) {
  898. if ($type == 3) {
  899. unset($wheres['business_id']);
  900. }
  901. }
  902. $list=BusinessProduct::where($wheres)->with(['business','productinfo'])->select();
  903. $list = collection($list)->toArray();
  904. if (!$list) {
  905. $this->error('无导出数据');
  906. }
  907. $title = [
  908. '序号',
  909. '商机名称',
  910. '商品名称',
  911. '售价',
  912. '批发价',
  913. '产品',
  914. '规格',
  915. '数量',
  916. ];
  917. foreach ($list as $k => $v) {
  918. $field = array(
  919. $v['id'],
  920. $v['business']['name'],
  921. $v['productinfo']['name']??'',
  922. $v['price']??'',
  923. $v['productinfo']['cost_price']??'',
  924. $v['productinfo']['goods']['name']??'',
  925. $v['productinfo']['unit']??'',
  926. $v['number']??'',
  927. );
  928. $data[] = $field;
  929. }
  930. $file = export_excel($title, $data, '产品明细');
  931. if ($file['filePath']) {
  932. $this->success('导出成功', '', $file);
  933. }
  934. $this->error('导出失败');
  935. }
  936. }