Customer.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. <?php
  2. namespace addons\qingdongams\controller;
  3. use addons\qingdongams\model\AreaManagement;
  4. use addons\qingdongams\model\Contacts;
  5. use addons\qingdongams\model\Customer as CustomerModel;
  6. use addons\qingdongams\model\CustomerFile;
  7. use addons\qingdongams\model\CustomerOther;
  8. use addons\qingdongams\model\FormField;
  9. use addons\qingdongams\model\Message;
  10. use addons\qingdongams\model\OperationLog;
  11. use addons\qingdongams\model\Record;
  12. use addons\qingdongams\model\SeaOperation;
  13. use addons\qingdongams\model\Seastype;
  14. use addons\qingdongams\model\Staff;
  15. use addons\qingdongams\model\StaffCollect;
  16. use addons\qingdongams\model\StaffSignIn;
  17. use think\Db;
  18. use think\Exception;
  19. /**
  20. * @desc 操作文档:https://doc.fastadmin.net/qingdongams
  21. * @desc 软件介绍:https://www.fastadmin.net/store/qingdongams.html
  22. * @desc 售后微信:qingdong_crm
  23. */
  24. /**
  25. * 客户接口
  26. */
  27. class Customer extends StaffApi
  28. {
  29. protected $noNeedLogin = [];
  30. protected $noNeedRight = [];
  31. protected $customerType = ['A', 'B', 'C', 'D'];
  32. //获取select客户列表
  33. public function getSelectList()
  34. {
  35. $limit = input("limit/d", 20);
  36. $name = input('name');
  37. $id = input('id','');
  38. $where = [];
  39. if ($name) {
  40. $where['name'] = ['like', "%{$name}%"];
  41. }
  42. if ($id !== '') {
  43. $where['id'] = $id;
  44. }
  45. $list = CustomerModel::where($where)->with(['ownerStaff'])->field('id,name,owner_staff_id,follow')->paginate($limit);
  46. $this->success('请求成功', $list);
  47. }
  48. //获取搜索员工列表
  49. public function getSearchStaffList()
  50. {
  51. $ids = Staff::getMyStaffIds();
  52. $staff = Staff::where([
  53. 'id' => ['in', $ids],
  54. 'status' => 1
  55. ])->field('id,name,img,post')->select();
  56. $this->success('请求成功', $staff);
  57. }
  58. //获取客户列表
  59. public function getList()
  60. {
  61. $limit = input("limit/d", 10);
  62. $params = $this->request->post();
  63. $params['type'] = isset($params['type']) ? $params['type'] : 0;
  64. $where= FormField::updateWhereField(FormField::CUSTOMER_TYPE,$params);
  65. if (isset($params['name']) && $params['name']) {//客户名称
  66. $where['name|subname'] = ['like', "%{$params['name']}%"];
  67. }
  68. if (isset($params['level']) && $params['level']) {//客户星级
  69. $where['level'] = $params['level'];
  70. }
  71. if (isset($params['source']) && $params['source']) {//客户来源
  72. $where['source'] = $params['source'];
  73. }
  74. if (isset($params['follow']) && $params['follow']) {//跟进状态
  75. $where['follow'] = $params['follow'];
  76. }
  77. if (isset($params['createtime']) && $params['createtime']) {//创建时间
  78. $createtime = $params['createtime'];
  79. $times = setTimes($createtime, 'time');
  80. $where['createtime'] = ['between', $times];
  81. }
  82. $order = 'id desc';
  83. if (isset($params['sortid']) && $params['sortid']) {
  84. switch ($params['sortid']) {
  85. case 1://名称正序
  86. $order = 'name asc';
  87. break;
  88. case 2://名称倒序
  89. $order = 'name desc';
  90. break;
  91. case 3://创建时间正序
  92. $order = 'createtime asc';
  93. break;
  94. case 4://创建时间倒序
  95. $order = 'createtime desc';
  96. break;
  97. case 5://下次跟进时间正序
  98. $order = 'next_time asc';
  99. break;
  100. case 6://下次跟进时间倒序
  101. $order = 'next_time desc';
  102. break;
  103. }
  104. }
  105. if (isset($params['next_time']) && $params['next_time']) {//下次联系时间
  106. $next_time = $params['next_time'];
  107. $next_time = explode(',', $next_time);
  108. $where['next_time'] = ['between', [$next_time[0], $next_time[1]]];
  109. }
  110. $whereStaff = [];
  111. //0全部 1 我负责 2 我参与 11 我下属负责
  112. if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
  113. $where['owner_staff_id'] = $params['staff_id'];
  114. } else {
  115. $staff_id = $this->auth->id;
  116. $type = $params['type'] ?? 0;
  117. if ($type == 1) {//我的客户
  118. $whereStaff['owner_staff_id'] = $this->auth->id;
  119. } elseif ($type == 11) {//下属负责的客户
  120. $whereStaff['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
  121. } elseif ($type == 2) {//我参与的客户
  122. $whereStaff = function ($query) use ($staff_id) {
  123. $query->where('ro_staff_id', 'like', "%,{$staff_id},%")
  124. ->whereOr('rw_staff_id', 'like', "%,{$staff_id},%");
  125. };
  126. }else{
  127. $whereStaff = function ($query) use ($staff_id) {
  128. $query->where(['ro_staff_id' => ['like', "%,{$staff_id},%"]])
  129. ->whereOr('rw_staff_id', 'like', "%,{$staff_id},%")
  130. ->whereOr(['owner_staff_id' => ['in', Staff::getMyStaffIds()]]);
  131. };
  132. }
  133. }
  134. if (isset($params['contract_status']) && $params['contract_status'] !== '') {
  135. $where['contract_status'] = $params['contract_status'];
  136. }
  137. if (isset($params['is_import'])) {
  138. if ($params['is_import'] == 1) {
  139. $where['lng'] = 0;
  140. } elseif ($params['is_import'] == 2) {
  141. $where['lng'] = ['neq', 0];
  142. }
  143. }
  144. if (isset($params['prov']) && !empty(trim($params['prov']))) {//省市区筛选
  145. $prov = trim($params['prov']);
  146. $city = trim($params['city']);
  147. $area = trim($params['area']);
  148. $cityinfo = $prov.$city.$area;
  149. if (empty($city)) {
  150. $where['address|address_detail'] = ['like', "%{$prov}%"];
  151. } elseif (empty($area)) {
  152. $where['address|address_detail'] = ['like', "%{$city}%"];
  153. } else {
  154. $where['address|address_detail'] = ['like', "%{$cityinfo}%"];
  155. }
  156. }
  157. // $where['is_seas'] = 0;
  158. if(isset($params['id_list'])){//日志 查询id列表
  159. $where=[];
  160. $where['id']=['in',explode(',',$params['id_list'])];
  161. }
  162. $list = CustomerModel::where($where)->where($whereStaff);
  163. $list = $list->with([
  164. 'ownerStaff',
  165. 'contractTotal',
  166. 'receivablesTotal',
  167. 'contacts'
  168. ])->field('id,type,name,address,last_time,owner_staff_id,rw_staff_id,level,follow,lng,lat,address,updatetime,contract_status,last_time')->order($order)->paginate($limit)->toArray();
  169. $data = $list['data'];
  170. foreach ($data as $k => $v) {
  171. if ($v['owner_staff_id'] == $this->auth->id ||
  172. in_array($v['owner_staff_id'],Staff::getLowerStaffId()) ||
  173. in_array($this->auth->id, explode(',', $v['rw_staff_id'])) ) {
  174. $v['is_operation'] = 1;
  175. } else {
  176. $v['is_operation'] = 0;
  177. }
  178. if($v['contract_status']==1){
  179. $v['follow'] = '已成交';
  180. }else{
  181. $v['follow'] = '未成交';
  182. }
  183. $data[$k] = $v;
  184. }
  185. $this->success('请求成功', [
  186. 'total' => $list['total'],
  187. 'per_page' => $list['per_page'],
  188. 'current_page' => $list['current_page'],
  189. 'last_page' => $list['last_page'],
  190. 'data' => $data
  191. ]);
  192. }
  193. //获取公海客户列表
  194. public function getSeasList()
  195. {
  196. $limit = input("limit/d", 10);
  197. $params = $this->request->post();
  198. $where= FormField::updateWhereField(FormField::CUSTOMER_TYPE,$params);
  199. if (isset($params['name']) && $params['name']) {//客户名称
  200. $where['name|subname'] = ['like', "%{$params['name']}%"];
  201. }
  202. if (isset($params['level']) && $params['level']) {//客户星级
  203. $where['level'] = $params['level'];
  204. }
  205. if (isset($params['source']) && $params['source']) {//客户来源
  206. $where['source'] = $params['source'];
  207. }
  208. if (isset($params['follow']) && $params['follow']) {//跟进状态
  209. $where['follow'] = $params['follow'];
  210. }
  211. if (isset($params['createtime']) && $params['createtime']) {//跟进状态
  212. $createtime = $params['createtime'];
  213. $where['createtime'] = ['between', setTimes($createtime,'time')];
  214. }
  215. $order = 'id desc';
  216. if (isset($params['sortid']) && $params['sortid']) {//排序
  217. switch ($params['sortid']) {
  218. case 1://名称正序
  219. $order = 'name asc';
  220. break;
  221. case 2://名称倒序
  222. $order = 'name desc';
  223. break;
  224. case 3://创建时间正序
  225. $order = 'createtime asc';
  226. break;
  227. case 4://创建时间倒序
  228. $order = 'createtime desc';
  229. break;
  230. case 5://下次跟进时间正序
  231. $order = 'next_time asc';
  232. break;
  233. case 6://下次跟进时间倒序
  234. $order = 'next_time desc';
  235. break;
  236. }
  237. }
  238. if (isset($params['next_time']) && $params['next_time']) {//下次联系时间
  239. $next_time = $params['next_time'];
  240. $next_time = explode(',', $next_time);
  241. $where['next_time'] = ['between', [$next_time[0], $next_time[1]]];
  242. }
  243. if (isset($params['is_chengjiao']) && $params['is_chengjiao'] == 1) {
  244. $where['contract_status'] = 1;
  245. }
  246. if (isset($params['prov']) && !empty(trim($params['prov']))) {//省市区筛选
  247. $prov = trim($params['prov']);
  248. $city = trim($params['city']);
  249. $area = trim($params['area']);
  250. if (empty($city)) {
  251. $where['address|address_detail'] = ['like', "%{$prov}%"];
  252. } elseif (empty($area)) {
  253. $where['address|address_detail'] = ['like', "%{$city}%"];
  254. } else {
  255. $where['address|address_detail'] = ['like', "%{$area}%"];
  256. }
  257. }
  258. //公海权限
  259. $rules=Staff::getStaffRule('seas');
  260. $whereStaff = function ($query) use ($rules) {
  261. foreach ($rules as $rule) {
  262. $query->whereOr(['seas_id' => ['like', "%,{$rule},%"]]);
  263. }
  264. };
  265. $where['is_seas'] = 1;
  266. $list = CustomerModel::where($where)->where($whereStaff)->where('owner_staff_id is null or owner_staff_id = 0');
  267. $list = $list->with([
  268. 'ownerStaff',
  269. 'contractTotal',
  270. 'receivablesTotal',
  271. 'contacts'
  272. ])->field('id,type,name,address,last_time,owner_staff_id,level,follow,lng,lat,address')->order($order)->paginate($limit)->toArray();
  273. $data = $list['data'];
  274. $this->success('请求成功', [
  275. 'total' => $list['total'],
  276. 'per_page' => $list['per_page'],
  277. 'current_page' => $list['current_page'],
  278. 'last_page' => $list['last_page'],
  279. 'data' => $data
  280. ]);
  281. }
  282. //查重客户名称
  283. public function selectName()
  284. {
  285. $name = input('name');
  286. if (CustomerModel::where(['name' => $name])->find()) {
  287. $this->error('客户名称已存在');
  288. }
  289. $this->success('当前客户名称可使用');
  290. }
  291. //获取区域列表
  292. public function getSeastypeList()
  293. {
  294. $seasIds=Staff::getStaffRule('seas');
  295. $seastype = Seastype::where(['id'=>['in',$seasIds]])->select();
  296. $this->success('请求成功', $seastype);
  297. }
  298. //新增客户
  299. public function addCustomer()
  300. {
  301. $params = $this->request->post();
  302. if (empty($params['customer'])) {
  303. $this->error('客户信息不能为空');
  304. }
  305. // 表单验证
  306. if (($result = $this->qingdongamsValidate($params['customer'], get_class(),'create')) !== true) {
  307. $this->error($result);
  308. }
  309. if (CustomerModel::where(['name' => $params['customer']['name']])->find()) {
  310. $this->error('客户名称已存在');
  311. }
  312. $result = FormField::checkFields(FormField::CUSTOMER_TYPE,$params['customer']);
  313. if ($result !== true) {
  314. $this->error($result);
  315. }
  316. Db::startTrans();
  317. try {
  318. $customerId = CustomerModel::createCustomer($params['customer']);
  319. if(isset($params['customer']['mobile']) && $params['customer']['mobile']){
  320. $retC = array(
  321. 'customer_id'=>$customerId,
  322. 'is_major'=>1,
  323. 'region'=>1,
  324. 'name'=>$params['customer']['name'],
  325. 'mobile'=>$params['customer']['mobile'],
  326. 'next_time'=>date('Y-m-d H:i:s'),
  327. );
  328. Contacts::createContacts($retC);
  329. }
  330. $content = $this->auth->name . "刚刚新建了客户《{$params['customer']['name']}》,请您审阅!";
  331. Message::addMessage(Message::CUSTOMER_TYPE, $customerId, $params['reminds_id'], $this->auth->id, $content);
  332. Db::commit();
  333. } catch (Exception $e) {
  334. Db::rollback();
  335. $this->error($e->getMessage());
  336. }
  337. if ($result) {
  338. $this->success('新增客户成功',array('id'=>$customerId));
  339. }
  340. }
  341. public function getAddressProvince()
  342. {
  343. $address = input('address');
  344. $this->success('请求成功', AreaManagement::whereAddressProvince($address));
  345. }
  346. public function getAreaManagement()
  347. {
  348. $this->success('请求成功', AreaManagement::where([])->select());
  349. }
  350. //编辑客户
  351. public function editCustomer()
  352. {
  353. $id = input('id');
  354. $params = $this->request->post();
  355. $row = CustomerModel::where(['id' => $id])->find();
  356. if (empty($row)) {
  357. $this->error('客户信息不存在');
  358. }
  359. // 表单验证
  360. if (($result = $this->qingdongamsValidate($params, get_class(),'edit')) !== true) {
  361. $this->error($result);
  362. }
  363. $result = FormField::checkFields(FormField::CUSTOMER_TYPE,$params,$id);
  364. if ($result !== true) {
  365. $this->error($result);
  366. }
  367. Db::startTrans();
  368. try {
  369. $result = CustomerModel::updateCustomer($params);
  370. if(isset($param['mobile']) && $params['mobile']){
  371. Contacts::where(array('customer_id'=>$id,'is_major'=>1))->update(array('mobile'=>$params['mobile'],'updatetime'=>time()));
  372. }
  373. Db::commit();
  374. } catch (Exception $e) {
  375. Db::rollback();
  376. $this->error($e->getMessage());
  377. }
  378. $this->success('修改客户成功');
  379. }
  380. //合并客户
  381. public function mergeCustomer()
  382. {
  383. $new_id = input('id');
  384. $old_id = input('old_id');
  385. $contacts_id = input('contacts_id');
  386. $params = input('data/a');
  387. $params['id'] = $new_id;
  388. CustomerModel::updateCustomer($params);
  389. //合并联系人
  390. Contacts::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  391. //合并合同
  392. \addons\qingdongams\model\Contract::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  393. //合并费用
  394. \addons\qingdongams\model\Consume::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  395. //合并回款
  396. \addons\qingdongams\model\Receivables::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  397. //合并任务
  398. \addons\qingdongams\model\Event::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  399. //合并工单
  400. \addons\qingdongams\model\Workorder::where(['customer_id' => $old_id])->update(['customer_id' => $new_id]);
  401. //删除旧用户
  402. CustomerModel::destroy($old_id);
  403. Contacts::where(['customer_id' => $new_id])->update(['is_major'=>0]);
  404. Contacts::where(['id' => $contacts_id])->update(['is_major'=>1]);
  405. Message::setRead(Message::CUSTOMER_TYPE,$old_id);
  406. $this->success('合并成功');
  407. }
  408. //获取合并客户详情
  409. public function getMergeCustomerDetail()
  410. {
  411. $ids = input('ids');
  412. if (empty($ids)) {
  413. $this->error('参数不能为空');
  414. }
  415. $ids = explode(',', $ids);
  416. $customers = CustomerModel::where(['id' => ['in', $ids]])->select();
  417. $customers=collection($customers)->toArray();
  418. if(empty($customers)){
  419. $this->error('用户不存在');
  420. }
  421. foreach ($customers as $k=>$c) {
  422. $customers[$k] = CustomerOther::getOther($c);
  423. }
  424. $detail = [];
  425. foreach ($customers as $v) {
  426. foreach ($v as $key => $value) {
  427. if($value === null){
  428. $detail[$key]=[];
  429. continue;
  430. }
  431. if($key == 'name'){
  432. $detail[$key][] = ['id'=>$v['id'],'name'=>$value];
  433. }elseif($key == 'address'){
  434. $detail[$key][]=['name'=>$value,'lat'=>$v['lat'],'lng'=>$v['lng'],'address_detail'=>$v['address_detail']];
  435. }else{
  436. $detail[$key][] = $value;
  437. }
  438. }
  439. }
  440. $detail['parent_id']=CustomerModel::where(['id'=>['in',$detail['parent_id']]])->field('id,name')->select();
  441. $contacts=Contacts::where(['customer_id'=>['in',$ids]])->field('id,name')->select();
  442. $detail['contacts']=$contacts;
  443. $this->success('请求成功', $detail);
  444. }
  445. //获取子公司
  446. public function getLowerCustomer()
  447. {
  448. $id = input('id');
  449. $customers = CustomerModel::where(['parent_id' => $id])->with([
  450. 'ownerStaff',
  451. 'contacts'
  452. ])->field('id,name,next_time,owner_staff_id,level,follow')->select();
  453. $this->success('请求成功', $customers);
  454. }
  455. // 是否可以查看客户
  456. public function isShowCustomer()
  457. {
  458. $id = input('id');
  459. $customer = CustomerModel::where(['id' => $id])->find();
  460. if (empty($customer)) {
  461. $this->error('信息不存在');
  462. }
  463. $customer = $customer->toArray();
  464. if ($customer['owner_staff_id'] == $this->auth->id ||
  465. in_array($customer['owner_staff_id'], Staff::getLowerStaffId()) ||
  466. in_array($this->auth->id, explode(',', $customer['rw_staff_id'])) ||
  467. in_array($this->auth->id, explode(',', $customer['ro_staff_id']))
  468. ) {
  469. $this->success('请求成功', ['is_show' => 1]);
  470. }
  471. $this->success('请求成功', ['is_show' => 0]);
  472. }
  473. //客户详情
  474. public function customerDetail()
  475. {
  476. $id = input('id');
  477. $customer = CustomerModel::where(['id' => $id])->with([
  478. 'createStaff',
  479. 'ownerStaff',
  480. 'contacts',
  481. 'contractTotal',
  482. 'receivablesTotal',
  483. 'consumeTotal',
  484. 'workorderTotal'
  485. ])->find();
  486. if (empty($customer)) {
  487. $this->error('信息不存在');
  488. }
  489. $customer = $customer->toArray();
  490. if ($customer['owner_staff_id'] == $this->auth->id ||
  491. in_array($customer['owner_staff_id'],Staff::getLowerStaffId()) ||
  492. in_array($this->auth->id, explode(',', $customer['rw_staff_id'])) ) {
  493. $customer['operation'] = 'update';//修改权限
  494. $customer['is_operation'] = 1;
  495. } else {
  496. $customer['operation'] = 'read';//只读权限
  497. $customer['is_operation'] = 0;
  498. }
  499. $customer['is_collect'] = StaffCollect::isCollect(StaffCollect::CUSTOMER_TYPE, $customer['id']) ? 1 : 0;
  500. $customer = CustomerOther::getOther($customer);
  501. Message::setRead(Message::CUSTOMER_TYPE, $id, $this->auth->id);
  502. $this->success('请求成功', $customer);
  503. }
  504. //移入公海
  505. public function moveSeas()
  506. {
  507. $id = input('id');
  508. $row = CustomerModel::where(['id' => $id])->find();
  509. if (empty($row)) {
  510. $this->error('客户不存在');
  511. }
  512. Db::startTrans();
  513. try {
  514. CustomerModel::moveSeas($id);
  515. Db::commit();
  516. } catch (Exception $e) {
  517. Db::rollback();
  518. $this->error($e->getMessage());
  519. }
  520. $this->success('放入成功');
  521. }
  522. //批量移入公海
  523. public function batchMoveSeas()
  524. {
  525. $ids = input('ids');
  526. if(empty($ids)){
  527. $this->error('参数为空');
  528. }
  529. $ids=explode(',',$ids);
  530. $row = CustomerModel::where(['id' => ['in',$ids]])->select();
  531. if (empty($row)) {
  532. $this->error('客户不存在');
  533. }
  534. Db::startTrans();
  535. try {
  536. foreach ($ids as $id){
  537. CustomerModel::moveSeas($id);
  538. }
  539. Db::commit();
  540. } catch (Exception $e) {
  541. Db::rollback();
  542. $this->error($e->getMessage());
  543. }
  544. $this->success('放入成功');
  545. }
  546. //转移客户
  547. public function transfer()
  548. {
  549. $id = input('id');
  550. $staff_id = input('staff_id');
  551. if (empty($staff_id)) {
  552. $this->error('参数错误');
  553. }
  554. $staff = Staff::get($staff_id);
  555. if (empty($staff)) {
  556. $this->error('接收对象不存在');
  557. }
  558. //, 'owner_staff_id' => $this->auth->id
  559. $row = CustomerModel::where(['id' => $id])->find();
  560. if (empty($row)) {
  561. $this->error('客户不存在');
  562. }
  563. try {
  564. CustomerModel::transfer($id, $staff_id);
  565. } catch (Exception $e) {
  566. $this->error($e->getMessage());
  567. }
  568. $this->success('转移成功');
  569. }
  570. //批量转移客户
  571. public function batchTransfer()
  572. {
  573. $ids = input('ids');
  574. $staff_id = input('staff_id');
  575. if(empty($ids)){
  576. $this->error('参数为空');
  577. }
  578. $ids=explode(',',$ids);
  579. $row = CustomerModel::where(['id' => ['in',$ids]])->select();
  580. if (empty($row)) {
  581. $this->error('客户不存在');
  582. }
  583. Db::startTrans();
  584. try {
  585. foreach ($ids as $id){
  586. CustomerModel::transfer($id, $staff_id);
  587. }
  588. Db::commit();
  589. } catch (Exception $e) {
  590. Db::rollback();
  591. $this->error($e->getMessage());
  592. }
  593. $this->success('放入成功');
  594. }
  595. //领取公海客户
  596. public function receive()
  597. {
  598. $customer_id = input('customer_id');
  599. $where = ['owner_staff_id' => 0];
  600. if ($customer_id) {
  601. $where['id'] = $customer_id;
  602. }
  603. $customers = CustomerModel::where($where)->count();
  604. if ($customers == 0) {
  605. $this->error('公海内暂无客户');
  606. }
  607. try {
  608. $id = CustomerModel::receive($customer_id);
  609. } catch (Exception $e) {
  610. $this->error($e->getMessage());
  611. }
  612. $this->success('领取成功', ['id' => $id]);
  613. }
  614. //重点关注客户
  615. public function collect()
  616. {
  617. $customer_id = input('customer_id');
  618. try {
  619. StaffCollect::addCollect(StaffCollect::CUSTOMER_TYPE, $customer_id);
  620. } catch (Exception $e) {
  621. $this->error($e->getMessage());
  622. }
  623. $this->success('重点关注成功');
  624. }
  625. //取消重点关注
  626. public function cancelCollect()
  627. {
  628. $customer_id = input('customer_id');
  629. try {
  630. StaffCollect::cancel(StaffCollect::CUSTOMER_TYPE, $customer_id);
  631. } catch (Exception $e) {
  632. $this->error($e->getMessage());
  633. }
  634. $this->success('取消重点关注成功');
  635. }
  636. //重点关注客户列表
  637. public function collectList()
  638. {
  639. $limit = input("limit/d", 10);
  640. $ids = StaffCollect::where(['staff_id' => $this->auth->id, 'relation_type' => 1])->column('relation_id');
  641. $list = CustomerModel::where(['id' => ['in', $ids]])->with([
  642. 'ownerStaff',
  643. 'contacts'
  644. ])->field('id,name,next_time,owner_staff_id,level,follow')->order('id desc')->paginate($limit);
  645. $this->success('请求成功', $list);
  646. }
  647. //获取附件列表
  648. public function getFilesList()
  649. {
  650. $id = input('customer_id');
  651. $files = CustomerFile::where(['customer_id' => $id])->field('file_id')->with(['file'])->select();
  652. $this->success('请求成功', $files);
  653. }
  654. //获取附件列表
  655. public function addFiles()
  656. {
  657. $customer_id = input('customer_id');
  658. $files = input('files');
  659. $files = CustomerFile::addFiles($files, $customer_id);
  660. $this->success('添加成功');
  661. }
  662. //周围客户
  663. public function nearby()
  664. {
  665. $lng = input('lng');
  666. $lat = input('lat');
  667. //距离
  668. $distance = input('distance', 5, 'intval');
  669. if (empty($lng) && empty($lat)) {
  670. $this->error('参数错误');
  671. }
  672. $range = 180 / pi() * $distance / 6372.797; //里面的 1 就代表搜索 1km 之内,单位km
  673. $lngR = $range / cos($lat * pi() / 180);
  674. $maxLat = $lat + $range; //最大纬度
  675. $minLat = $lat - $range; //最小纬度
  676. $maxLng = $lng + $lngR; //最大经度
  677. $minLng = $lng - $lngR; //最小经度
  678. $where = ['lng' => ['between', [$minLng, $maxLng]], 'lat' => ['between', [$minLat, $maxLat]]];
  679. $params = $this->request->post();
  680. if (isset($params['name']['value']) && $params['name']['value']) {//客户名称
  681. $where['name|subname'] = ['like', "%{$params['name']['value']}%"];
  682. }
  683. if (isset($params['level']) && $params['level']) {//客户星级
  684. $where['level'] = $params['level'];
  685. }
  686. if (isset($params['source']) && $params['source']) {//客户来源
  687. $where['source'] = $params['source'];
  688. }
  689. if (isset($params['follow']) && $params['follow']) {//跟进状态
  690. $where['follow'] = $params['follow'];
  691. }
  692. if (isset($params['createtime']) && $params['createtime']) {//创建时间
  693. $createtime = $params['createtime'];
  694. $times = setTimes($createtime, 'time');
  695. $where['createtime'] = ['between', $times];
  696. }
  697. if (isset($params['next_time']) && $params['next_time']) {//下次联系时间
  698. $next_time = $params['next_time'];
  699. $next_time = explode(',', $next_time);
  700. $where['next_time'] = ['between', [$next_time[0], $next_time[1]]];
  701. }
  702. $whereStaff = [];
  703. //0全部 1 我负责 2 我参与 11 我下属负责
  704. if (isset($params['staff_id']) && $params['staff_id']) {//下级员工筛选
  705. $where['owner_staff_id'] = $params['staff_id'];
  706. } else {
  707. $staff_id = $this->auth->id;
  708. $type = $params['type'] ?? 0;
  709. if ($type == 1) {//我的客户
  710. $whereStaff['owner_staff_id'] = $this->auth->id;
  711. } elseif ($type == 11) {//下属负责的客户
  712. $whereStaff['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
  713. } elseif ($type == 2) {//我参与的客户
  714. $whereStaff = function ($query) use ($staff_id) {
  715. $query->where('ro_staff_id', 'like', "%,{$staff_id},%")
  716. ->whereOr('rw_staff_id', 'like', "%,{$staff_id},%");
  717. };
  718. }else{
  719. $whereStaff = function ($query) use ($staff_id) {
  720. $query->where(['ro_staff_id' => ['like', "%,{$staff_id},%"]])
  721. ->whereOr('rw_staff_id', 'like', "%,{$staff_id},%")
  722. ->whereOr(['owner_staff_id' => ['in', Staff::getMyStaffIds()]]);
  723. };
  724. }
  725. }
  726. if (isset($params['contract_status']) && $params['contract_status'] !== '') {
  727. $where['contract_status'] = $params['contract_status'];
  728. }
  729. if (isset($params['is_import'])) {
  730. if ($params['is_import'] == 1) {
  731. $where['lng'] = 0;
  732. } elseif ($params['is_import'] == 2) {
  733. $where['lng'] = ['neq', 0];
  734. }
  735. }
  736. if (isset($params['prov']) && !empty(trim($params['prov']))) {//省市区筛选
  737. $prov = trim($params['prov']);
  738. $city = trim($params['city']);
  739. $area = trim($params['area']);
  740. $cityinfo = $prov.$city.$area;
  741. if (empty($city)) {
  742. $where['address|address_detail'] = ['like', "%{$prov}%"];
  743. } elseif (empty($area)) {
  744. $where['address|address_detail'] = ['like', "%{$city}%"];
  745. } else {
  746. $where['address|address_detail'] = ['like', "%{$cityinfo}%"];
  747. }
  748. }
  749. $customers = CustomerModel::where($where)->where($whereStaff)->field('id,owner_staff_id,name,location,next_time,lng,lat,address_detail')
  750. ->with('ownerStaff')->select();
  751. $data = [];
  752. //所属员工列表
  753. $myStaffIds = Staff::getMyStaffIds();
  754. foreach ($customers as $k => $v) {
  755. if ($v['owner_staff_id'] == 0) {
  756. $v['type'] = 0;//公海
  757. } elseif ($v['owner_staff_id'] == $this->auth->id) {
  758. $v['type'] = 1;//自己的
  759. } elseif (in_array($v['owner_staff_id'], $myStaffIds)) {
  760. $v['type'] = 2;//团队的
  761. } else {
  762. $v['type'] = 3;//其他人
  763. }
  764. $v['juli_num'] = getdistance($lng, $lat, $v['lng'], $v['lat']);
  765. $v['juli'] = float_number($v['juli_num']);
  766. $data[$v['juli_num']][] = $v;
  767. }
  768. ksort($data);
  769. $result = [];
  770. foreach ($data as $v) {
  771. $result = array_merge($result, array_values($v));
  772. }
  773. $this->success('请求成功', $result);
  774. }
  775. //周围客户列表
  776. public function nearby_customer_list()
  777. {
  778. $id = input('id');
  779. $page = input('page', 0);
  780. $limit = input('limit', 100);
  781. $lng = input('lng');
  782. $lat = input('lat');
  783. //我的客户
  784. $type = input('type');
  785. //距离
  786. $distance = input('distance', 5, 'intval');
  787. $name = input('name', '');
  788. if (empty($lng) && empty($lat)) {
  789. $this->error('参数错误');
  790. }
  791. $range = 180 / pi() * $distance / 6372.797; //里面的 1 就代表搜索 1km 之内,单位km
  792. $lngR = $range / cos($lat * pi() / 180);
  793. $maxLat = $lat + $range; //最大纬度
  794. $minLat = $lat - $range; //最小纬度
  795. $maxLng = $lng + $lngR; //最大经度
  796. $minLng = $lng - $lngR; //最小经度
  797. $where = ['lng' => ['between', [$minLng, $maxLng]], 'lat' => ['between', [$minLat, $maxLat]]];
  798. //客户分类
  799. if ($type == 1) {//我的客户
  800. $where['owner_staff_id'] = $this->auth->id;
  801. } elseif ($type == 2) {//下属负责的客户
  802. $where['owner_staff_id'] = ['in', Staff::getLowerStaffId()];
  803. } elseif ($type == 3) {//已成交客户
  804. $where['contract_status'] = 1;
  805. }
  806. //单独查询用户
  807. if ($id) {
  808. $where['id'] = $id;
  809. }
  810. if ($name) {
  811. $where['name'] = ['like', "%{$name}%"];
  812. }
  813. $customers = CustomerModel::where($where)->where([
  814. 'lng' => [
  815. 'neq',
  816. 0
  817. ]
  818. ])->field('id,owner_staff_id,name,location,next_time,lng,lat,address_detail')
  819. ->with('ownerStaff')->select();
  820. $data = [];
  821. foreach ($customers as $k => $v) {
  822. $v['juli_num'] = getdistance($lng, $lat, $v['lng'], $v['lat']);
  823. $v['juli'] = float_number($v['juli_num']);
  824. $data[$v['juli']][] = $v;
  825. }
  826. ksort($data);
  827. $result = [];
  828. foreach ($data as $v) {
  829. $result = array_merge($result, array_values($v));
  830. }
  831. $total = count($result);
  832. $result = array_slice($result, $page * $limit, $limit) ?? [];
  833. $this->success('请求成功', ['data' => $result, 'total' => $total, 'last_page' => ceil($total / $limit)]);
  834. }
  835. // 转变 客户类型
  836. public function changeCustomerType()
  837. {
  838. $id = input('customer_id', '', 'intval');
  839. $type = input('type', '', '');
  840. $remark = input('remark', '');
  841. if (!$id) {
  842. $this->error('请输入客户Id!');
  843. }
  844. if (!$type || !in_array($type, $this->customerType)) {
  845. $this->error('请输入要转变的类型!');
  846. }
  847. if (!$remark) {
  848. $this->error('请输入转变原因!');
  849. }
  850. $where = [
  851. 'id' => $id,
  852. 'owner_staff_id' => ['in', Staff::getMyStaffIds()]
  853. ];
  854. $info = CustomerModel::where($where)->with('ownerStaff')->find();
  855. if (!$info) {
  856. $this->error('该客户不是您的客户,无法变更!');
  857. }
  858. if ($info['type'] == $type) {
  859. $this->error('客户原来正是' . $type . '级别!');
  860. }
  861. Db::startTrans();
  862. try {
  863. $remark = '[' . $this->auth->name . ']将客户' . $info['name'] . '从' . $info['type'] . '类型变更为' . $type . '类型【备注:' . $remark . '】';
  864. CustomerModel::changeCustomerType($id, $type, $remark);
  865. Db::commit();
  866. } catch (Exception $e) {
  867. Db::rollback();
  868. $this->error($e->getMessage());
  869. }
  870. $this->success('提交成功');
  871. }
  872. // 员工反馈给领导
  873. public function feedbackToLeader()
  874. {
  875. $id = input('id', '', 'intval');
  876. $remark = input('remark', '');
  877. if (!$id || !$remark) {
  878. $this->error('缺少参数');
  879. }
  880. $info = Message::where('id', $id)->find();
  881. if (!$info) {
  882. $this->error('找不到此条消息');
  883. }
  884. Db::startTrans();
  885. try {
  886. StaffSignIn::createSignIn([
  887. 'customer_id'=>$id,
  888. 'relation_type'=>'customer',
  889. 'relation_id'=>$id,
  890. 'content'=>$remark,
  891. 'staff_id'=>$this->auth->id
  892. ]);
  893. Db::commit();
  894. } catch (Exception $e) {
  895. Db::rollback();
  896. $this->error($e->getMessage());
  897. }
  898. $this->success('提交成功');
  899. }
  900. }