123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: CRM工作台
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\crm\controller;
  8. use app\admin\controller\ApiCommon;
  9. use think\Hook;
  10. use think\Request;
  11. use app\bi\model\Common;
  12. use app\crm\model\Contract as CrmContractModel;
  13. use app\crm\model\Receivables as ReceivablesModel;
  14. use app\crm\logic\IndexLogic;
  15. use app\crm\model\Customer as CustomerModel;
  16. use think\Db;
  17. class Index extends ApiCommon
  18. {
  19. /**
  20. * 用于判断权限
  21. * @permission 无限制
  22. * @allow 登录用户可访问
  23. * @other 其他根据系统设置
  24. **/
  25. public function _initialize()
  26. {
  27. $action = [
  28. 'permission' => [''],
  29. 'allow' => [
  30. 'index',
  31. 'achievementdata',
  32. 'funnel',
  33. 'saletrend',
  34. 'search',
  35. 'indexlist',
  36. 'getrecordlist',
  37. 'forgottencustomercount',
  38. 'forgottencustomerpagelist',
  39. 'ranking',
  40. 'querydatainfo',
  41. 'queryrepeat',
  42. 'autonumberstatus',
  43. 'dashboard',
  44. 'updatedashboard',
  45. 'activitylist',
  46. ]
  47. ];
  48. Hook::listen('check_auth', $action);
  49. $request = Request::instance();
  50. $a = strtolower($request->action());
  51. if (!in_array($a, $action['permission'])) {
  52. parent::_initialize();
  53. }
  54. }
  55. //月份数组
  56. protected $monthName = [
  57. '01' => 'january',
  58. '02' => 'february',
  59. '03' => 'march',
  60. '04' => 'april',
  61. '05' => 'may',
  62. '06' => 'june',
  63. '07' => 'july',
  64. '08' => 'august',
  65. '09' => 'september',
  66. '10' => 'october',
  67. '11' => 'november',
  68. '12' => 'december',
  69. ];
  70. /**
  71. * CRM工作台(销售简报)
  72. * @param
  73. * @return
  74. * @author Michael_xu
  75. */
  76. public function index()
  77. {
  78. // Db::query('SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;');
  79. $param = $this->param;
  80. $indexModel = new IndexLogic;
  81. $data = $indexModel->index($param);
  82. // Db::query('COMMIT;');
  83. return resultArray(['data' => $data]);
  84. }
  85. /**
  86. * 业绩指标
  87. * @param
  88. * @return
  89. * @author Michael_xu
  90. */
  91. public function achievementData()
  92. {
  93. Db::query('SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;');
  94. $param = $this->param;
  95. $userInfo = $this->userInfo;
  96. $adminModel = new \app\admin\model\Admin();
  97. $status = $param['label'] ?: 1; //1合同目标2回款目标
  98. $userWhere['type']=3;
  99. $userWhere['status']=$param['label'];
  100. $userIds = [];
  101. if ($param['dataType'] == 3 || $param['dataType'] == 4) {
  102. $param['structure_id'] = $userInfo['structure_id'];
  103. $userWhere['type']=2;
  104. }
  105. $whereArr = $adminModel->getWhere($param, 1, '');
  106. if($param['user_id']){
  107. $userWhere['type']=3;
  108. }elseif ($param['structure_id']){
  109. $userWhere['type']=2;
  110. }
  111. $param['user_id'] = $param['user_id'] ?: $userInfo['id'];
  112. if ($param['dataType'] == 1) {
  113. $userIds[] = $param['user_id'];
  114. } else {
  115. $userIds = $whereArr['userIds'];
  116. }
  117. $where['owner_user_id'] = array('in', $userIds);
  118. if (!empty($param['type'])) {
  119. $between_time = getTimeByType($param['type']);
  120. $start_time = $between_time[0];
  121. $end_time = $between_time[1];
  122. } else {
  123. //自定义时间
  124. $start_time = $param['start_time'] ?strtotime($param['start_time'].'00:00:00'): strtotime(date('Y-01-01', time()));
  125. $end_time = $param['end_time'] ? strtotime($param['end_time'].'23:59:59') : strtotime(date('Y-m-01', time()) . ' +1 month -1 day');
  126. $between_time = array($start_time, $end_time);
  127. }
  128. if($param['label']==1){
  129. //合同金额
  130. $where_contract = $where;
  131. $where_contract['order_date'] = array('between', [date('Y-m-d', $between_time[0]), date('Y-m-d', $between_time[1])]);
  132. $sql = CrmContractModel::field([
  133. 'SUM(CASE WHEN check_status = 2 THEN money ELSE 0 END) as money'
  134. ])
  135. ->where($where_contract)
  136. ->fetchSql()
  137. ->select();
  138. $contractMoney = queryCache($sql, 200);
  139. }else{
  140. //回款金额
  141. $where_receivables = $where;
  142. $where_receivables['return_time'] = array('between', [date('Y-m-d', $between_time[0]), date('Y-m-d', $between_time[1])]);
  143. $where_receivables['check_status'] = 2; //审核通过
  144. $sql1 = db('crm_receivables')->field([
  145. 'SUM(CASE WHEN check_status = 2 THEN money ELSE 0 END) as money'
  146. ])
  147. ->where($where_receivables)
  148. ->fetchSql()
  149. ->select();
  150. $receivablesMoney = queryCache($sql1, 200);
  151. }
  152. if (!isset($param['user_id'])) {
  153. $userWhere['obj_id'] = $param['user_id'];
  154. } else {
  155. $userWhere['obj_id'] = ['in', $userIds];
  156. }
  157. //业绩目标
  158. //获取时间段包含年份
  159. $year = getYearByTime($start_time, $end_time);
  160. $achievement = db('crm_achievement')->where($userWhere)->select();
  161. $achievementMoney = 0.00;
  162. //获取需要查询的月份
  163. $month = getmonthByTime($start_time, $end_time);
  164. foreach ($achievement as $k => $v) {
  165. foreach ($month as $key => $val) {
  166. if ($v['year'] == $key) {
  167. foreach ($val as $key1 => $val1) {
  168. $achievementMoney += $v[$this->monthName[$val1]];
  169. }
  170. }
  171. }
  172. }
  173. $data = [];
  174. //完成率
  175. $rate = 0.00;
  176. if ($status == 1) {
  177. $rate = $achievementMoney ? $contractMoney[0]['money'] / $achievementMoney : 0.00;
  178. $data['contractMoney'] = $contractMoney[0]['money'] ?: '0.00';
  179. $data['achievementMoney'] = $achievementMoney ?: '0.00';
  180. $data['money'] = $contractMoney[0]['money'] ?: '0.00';
  181. $data['rate'] = round($rate * 100, 2);
  182. } else {
  183. $rate = $achievementMoney ? $receivablesMoney[0]['money'] / $achievementMoney : 0.00;
  184. $data['receivablesMoney'] = $receivablesMoney[0]['money'] ?: '0.00';
  185. $data['money'] = $receivablesMoney[0]['money'] ?: '0.00';
  186. $data['achievementMoney'] = $achievementMoney ?: '0.00';
  187. $data['rate'] = round($rate * 100, 2);
  188. }
  189. Db::query('COMMIT;');
  190. return resultArray(['data' => $data]);
  191. }
  192. /**
  193. * 销售漏斗
  194. * @param
  195. * @return
  196. * @author Michael_xu
  197. */
  198. public function funnel()
  199. {
  200. $param = $this->param;
  201. $userInfo = $this->userInfo;
  202. $param['user_id'] = $param['user_id'] ?: $userInfo['id'];;
  203. $businessModel = new \app\crm\model\Business();
  204. $param['merge'] = 1;
  205. if($param['start_time'] && $param['end_time']){
  206. $param['start_time']=$param['start_time'].' 00:00:00';
  207. $param['end_time']=$param['end_time'].' 23:59:59';
  208. }
  209. $list = $businessModel->getFunnel($param);
  210. return resultArray(['data' => $list]);
  211. }
  212. /**
  213. * 销售趋势
  214. * @return
  215. */
  216. public function saletrend()
  217. {
  218. $userModel = new \app\admin\model\User();
  219. $adminModel = new \app\admin\model\Admin();
  220. //统计条件
  221. $param = $this->param;
  222. $userInfo = $this->userInfo;
  223. $userWhere['status']=$param['label'];
  224. if ($param['dataType'] == 3 || $param['dataType'] == 4) {
  225. $userWhere['type']=2;
  226. }else{
  227. $userWhere['type']=3;
  228. }
  229. if ($param['type']) {
  230. $last_where_contract = getTimeByType($param['type']);
  231. $userWhere['year']=date('Y',$last_where_contract[0]);
  232. $time = getTimeArray();
  233. } else {
  234. //自定义时间
  235. $param['start_time']=$param['start_time']?$param['start_time'].' 00:00:00':0;
  236. $param['end_time']=$param['end_time'].' 23:59:59';
  237. $time = getTimeArray(strtotime($param['start_time']),strtotime($param['end_time']));
  238. }
  239. $whereArr = $adminModel->getWhere($param, 1, '');
  240. if($param['user_id']){
  241. $userWhere['type']=3;
  242. }elseif ($param['structure_id']){
  243. $userWhere['type']=2;
  244. }
  245. $userIds = $whereArr['userIds'];
  246. if (!empty($param['user_id'])) {
  247. $userWhere['obj_id'] = $param['user_id'];
  248. } else {
  249. $userWhere['obj_id'] = ['in', $userIds];
  250. }
  251. //时间
  252. $ax = 7;
  253. if ($time['time_format'] == '%Y-%m-%d') {
  254. $ax = 10;
  255. }
  256. $auth_customer_user_ids = $userModel->getUserByPer('crm', 'contract', 'index');
  257. $auth_customer_user_ids = $auth_customer_user_ids ? array_intersect($userIds, $auth_customer_user_ids) : []; //取交集
  258. $between_time = [date('Y-m-d', $whereArr['between_time'][0]), date('Y-m-d', $whereArr['between_time'][1])];
  259. if($param['label']==1){
  260. $field_contract["SUBSTR(`order_date`, 1, " . $ax . ")"] = 'type';
  261. $field_contract['SUM(`money`)'] = 'sum';
  262. $achievementData = CrmContractModel::field($field_contract)
  263. ->where([
  264. 'owner_user_id' => ['IN', $auth_customer_user_ids],
  265. 'check_status' => 2,
  266. 'order_date' => ['BETWEEN', $between_time]
  267. ])
  268. ->group('type')
  269. ->fetchSql()
  270. ->select();
  271. $res_contract = queryCache($achievementData, 200);
  272. $res_money = array_column($res_contract, null, 'type');
  273. }else{
  274. $field_receivables["SUBSTR(`return_time`, 1, " . $ax . ")"] = 'type';
  275. $field_receivables['SUM(`money`)'] = 'sum';
  276. $sql_receivables = ReceivablesModel::field($field_receivables)
  277. ->where([
  278. 'owner_user_id' => ['IN', $auth_customer_user_ids],
  279. 'check_status' => 2,
  280. 'return_time' => ['BETWEEN', $between_time]
  281. ])
  282. ->group('type')
  283. ->fetchSql()
  284. ->select();
  285. $res_receivables = queryCache($sql_receivables, 200);
  286. $res_money = array_column($res_receivables, null, 'type');
  287. }
  288. $list = array();
  289. $money = '0.00';
  290. foreach ($time['list'] as $val) {
  291. $item = [];
  292. $item['type'] = date('m-d',strtotime($val['type']));
  293. $item['money'] = $res_money[$val['type']]['sum'] ?: 0;
  294. $money += $item['money'];
  295. $achievement=Db::name('crm_achievement')->where($userWhere)->select();
  296. $data_time=date('m',strtotime($val['type']));
  297. $num='';
  298. if($achievement){
  299. foreach ($achievement as $val){
  300. $num+=(int)$val[$this->monthName[$data_time]];
  301. $item['achievement']=$num;
  302. }
  303. }else{
  304. $item['achievement']=0;
  305. }
  306. $list[] = $item;
  307. }
  308. $data['list'] = $list;
  309. $data['money'] = $money ?: '0.00';
  310. return resultArray(['data' => $data]);
  311. }
  312. /**
  313. * 回款计划提醒
  314. * @param day 最近7天 15天...
  315. * @return
  316. * @author Michael_xu
  317. */
  318. public function receivablesPlan()
  319. {
  320. $param = $this->param;
  321. $adminModel = new \app\admin\model\Admin();
  322. if($param['start_time'] && $param['end_time']){
  323. $param['start_time']=$param['start_time'].'00:00:00';
  324. $param['end_time']=$param['end_time'].'23:59:59';
  325. }
  326. $whereArr = $adminModel->getWhere($param, '', ''); //统计条件
  327. $userIds = $whereArr['userIds'];
  328. $where = [];
  329. $where['owner_user_id'] = array('in', $userIds);
  330. //已逾期
  331. $return_date = array('< time', date('Y-m-d', time()));
  332. $where['status'] = 0;
  333. if ($param['day']) {
  334. $return_date = array('between time', array(date('Y-m-d', time()), date('Y-m-d', strtotime(date('Y-m-d', time())) + 86399 + (86400 * (int)$param['day']))));
  335. }
  336. $where['return_date'] = $return_date;
  337. $planList = db('crm_receivables_plan')->where($where)->select();
  338. return resultArray(['data' => $planList]);
  339. }
  340. /**
  341. * 待跟进客户
  342. * @param day 最近3天 7天...
  343. * @return
  344. * @author Michael_xu
  345. */
  346. public function noFollowUp()
  347. {
  348. $param = $this->param;
  349. $adminModel = new \app\admin\model\Admin();
  350. $whereArr = $adminModel->getWhere($param, '', ''); //统计条件
  351. $userIds = $whereArr['userIds'];
  352. $where = [];
  353. $where['owner_user_id'] = array('in', $userIds);
  354. $day = (int)$param['day'] ?: 3;
  355. $where['next_time'] = array('between', array(strtotime(date('Y-m-d', time())), strtotime(date('Y-m-d', time())) + 86399 + (86400 * (int)$param['day'])));
  356. $customerList = db('crm_customer')->where($where)->select();
  357. return resultArray(['data' => $customerList]);
  358. }
  359. /**
  360. * 客户名称、联系人姓名、联系人手机号查询
  361. * @param
  362. * @return
  363. * @author Michael_xu
  364. */
  365. public function search()
  366. {
  367. $param = $this->param;
  368. $page = $param['page'] ?: 1;
  369. $limit = $param['limit'] ?: 15;
  370. $types = $param['types'] ?: '';
  371. $userModel = new \app\admin\model\User();
  372. //省数组
  373. $address_arr = array('北京', '天津', '河北', '山西', '内蒙古自治区', '辽宁', '吉林', '黑龙江', '上海', '江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '广西壮族自治区', '海南', '重庆', '四川', '贵州', '云南', '西藏自治区', '陕西', '甘肃', '青海', '宁夏回族自治区', '新疆维吾尔自治区', '台湾', '香港特别行政区', '澳门特别行政区',);
  374. $addr_arr = array('北京', '天津', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省', '黑龙江省', '上海', '江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省', '河南省', '湖北省', '湖南省', '广东省', '广西壮族自治区', '海南省', '重庆', '四川省', '贵州省', '云南省', '西藏自治区', '陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区', '台湾省', '香港特别行政区', '澳门特别行政区',);
  375. $city_arr = array('石家庄', '唐山', '秦皇岛', '邯郸', '邢台', '保定', '张家口', '承德', '沧州', '廊坊', '衡水', '太原', '大同', '阳泉', '长治', '晋城', '朔州', '晋中', '运城', '忻州', '临汾', '吕梁', '呼和浩特', '包头', '乌海', '赤峰', '通辽', '鄂尔多斯', '呼伦贝尔', '巴彦淖尔', '乌兰察布', '兴安盟', '锡林郭勒盟', '阿拉善盟', '沈阳', '大连', '鞍山', '抚顺', '本溪', '丹东', '锦州', '营口', '阜新', '辽阳', '盘锦', '铁岭', '朝阳', '葫芦岛', '长春', '吉林', '四平', '辽源', '通化', '白山', '松原', '白城', '延边朝鲜族自治州', '哈尔滨', '齐齐哈尔', '鸡西', '鹤岗', '双鸭山', '大庆', '伊春', '佳木斯', '七台河', '牡丹江', '黑河', '绥化', '大兴安岭', '南京', '无锡', '徐州', '常州', '苏州', '南通', '连云港', '淮安', '盐城', '扬州', '镇江', '泰州', '宿迁', '杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州', '舟山', '台州', '丽水', '合肥', '芜湖', '蚌埠', '淮南', '马鞍山', '淮北', '铜陵', '安庆', '黄山', '滁州', '阜阳', '宿州', '巢湖', '六安', '亳州', '池州', '宣城', '福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩', '宁德', '南昌', '景德镇', '萍乡', '九江', '新余', '鹰潭', '赣州', '吉安', '宜春', '抚州', '上饶', '济南', '青岛', '淄博', '枣庄', '东营', '烟台', '潍坊', '济宁', '泰安', '威海', '日照', '莱芜', '临沂', '德州', '聊城', '滨州', '荷泽', '郑州', '开封', '洛阳', '平顶山', '安阳', '鹤壁', '新乡', '焦作', '濮阳', '许昌', '漯河', '三门峡', '南阳', '商丘', '信阳', '周口', '驻马店', '武汉', '黄石', '十堰', '宜昌', '襄樊', '鄂州', '荆门', '孝感', '荆州', '黄冈', '咸宁', '随州', '恩施土家族苗族自治州', '长沙', '株洲', '湘潭', '衡阳', '邵阳', '岳阳', '常德', '张家界', '益阳', '郴州', '永州', '怀化', '娄底', '湘西土家族苗族自治州', '广州', '韶关', '深圳', '珠海', '汕头', '佛山', '江门', '湛江', '茂名', '肇庆', '惠州', '梅州', '汕尾', '河源', '阳江', '清远', '东莞', '中山', '潮州', '揭阳', '云浮', '南宁', '柳州', '桂林', '梧州', '北海', '防城港', '钦州', '贵港', '玉林', '百色', '贺州', '河池', '来宾', '崇左', '海口', '三亚', '成都', '自贡', '攀枝花', '泸州', '德阳', '绵阳', '广元', '遂宁', '内江', '乐山', '南充', '眉山', '宜宾', '广安', '达州', '雅安', '巴中', '资阳', '阿坝藏族羌族自治州', '甘孜藏族自治州', '凉山彝族自治州', '贵阳', '六盘水', '遵义', '安顺', '铜仁', '黔西南布依族苗族自治州', '毕节', '黔东南苗族侗族自治州', '黔南布依族苗族自治州', '昆明', '曲靖', '玉溪', '保山', '昭通', '丽江', '思茅', '临沧', '楚雄彝族自治州', '红河哈尼族彝族自治州', '文山壮族苗族自治州', '西双版纳傣族自治州', '大理白族自治州', '德宏傣族景颇族自治州', '怒江傈僳族自治州', '迪庆藏族自治州', '拉萨', '昌都', '山南', '日喀则', '那曲', '阿里', '林芝', '西安', '铜川', '宝鸡', '咸阳', '渭南', '延安', '汉中', '榆林', '安康', '商洛', '兰州', '嘉峪关', '金昌', '白银', '天水', '武威', '张掖', '平凉', '酒泉', '庆阳', '定西', '陇南', '临夏回族自治州', '甘南藏族自治州', '西宁', '海东', '海北藏族自治州', '黄南藏族自治州', '海南藏族自治州', '果洛藏族自治州', '玉树藏族自治州', '海西蒙古族藏族自治州', '银川', '石嘴山', '吴忠', '固原', '中卫', '乌鲁木齐', '克拉玛依', '吐鲁番', '哈密', '昌吉回族自治州', '博尔塔拉蒙古自治州', '巴音郭楞蒙古自治州', '阿克苏', '克孜勒苏柯尔克孜自治州', '喀什', '和田', '伊犁哈萨克自治州', '塔城', '阿勒泰', '省直辖行政单位',);
  376. $un_arr = ['中国', '公司', '有限公司', '有限责任公司', '股份有限公司'];
  377. $name = $param['name'] ? trim($param['name']) : '';
  378. if (in_array($name, $address_arr) || in_array($name, $addr_arr) || in_array($name, $city_arr) || in_array($name, $un_arr)) {
  379. return resultArray(['error' => '查询条件不符合规则']);
  380. }
  381. if ($types == 'crm_customer') {
  382. if (!$param['name'] && !$param['mobile'] && !$param['telephone']) return resultArray(['error' => '查询条件不能为空']);
  383. $resWhere = '';
  384. if ($param['name']) {
  385. $resWhere .= " `name` like '%" . $param['name'] . "%' ";
  386. } elseif ($param['mobile']) {
  387. if ($resWhere) $resWhere .= 'OR';
  388. $resWhere .= " `mobile` = '" . $param['mobile'] . "'";
  389. } elseif ($param['telephone']) {
  390. if ($resWhere) $resWhere .= 'OR';
  391. $resWhere .= " `telephone` = '" . $param['telephone'] . "' ";
  392. }
  393. $dataList = db('crm_customer')
  394. ->where($resWhere)
  395. ->field('name,customer_id,owner_user_id')
  396. ->limit(($page - 1) * $limit, $limit)
  397. ->select();
  398. $dataCount = db('crm_customer')
  399. ->where($resWhere)
  400. ->count();
  401. $customerModel = model('Customer');
  402. $wherePool = $customerModel->getWhereByPool();
  403. foreach ($dataList as $k => $v) {
  404. $dataList[$k]['name'] = $v['name'] ?: '查看详情';
  405. if ($v['owner_user_id'] > 0) {
  406. $pool = $customerModel->alias('customer')
  407. ->where(['customer_id' => $v['customer_id']])
  408. ->where($wherePool)
  409. ->value('customer_id');
  410. // 是客户池
  411. if ($pool) {
  412. $dataList[$k]['owner_user_id_info'] = [];
  413. } else {
  414. $dataList[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  415. }
  416. } else {
  417. $dataList[$k]['owner_user_id_info'] = [];
  418. }
  419. }
  420. } elseif ($types == 'crm_contacts') {
  421. if (!$param['name'] && !$param['customer_name'] && !$param['telephone'] && !$param['mobile']) return resultArray(['error' => '查询条件不能为空']);
  422. if (in_array($param['customer_name'], $address_arr) || in_array($param['customer_name'], $addr_arr) || in_array($param['customer_name'], $city_arr) || in_array($param['customer_name'], $un_arr)) {
  423. return resultArray(['error' => '查询条件不符合规则']);
  424. }
  425. $resWhere = '';
  426. if ($param['name']) {
  427. $resWhere .= " `contacts`.`name` like '%" . $param['name'] . "%' ";
  428. } elseif ($param['mobile']) {
  429. if ($resWhere) $resWhere .= 'OR';
  430. $resWhere .= " `contacts`.`mobile` = '" . $param['mobile'] . "' ";
  431. } elseif ($param['telephone']) {
  432. if ($resWhere) $resWhere .= 'OR';
  433. $resWhere .= " `contacts`.`telephone` = '" . $param['telephone'] . "' ";
  434. } elseif ($param['customer_name']) {
  435. if ($resWhere) $resWhere .= 'OR';
  436. $resWhere .= " `customer`.`name` like '%" . $param['customer_name'] . "%'";
  437. }
  438. $dataList = db('crm_contacts')
  439. ->alias('contacts')
  440. ->join('__CRM_CUSTOMER__ customer', 'contacts.customer_id = customer.customer_id', 'LEFT')
  441. ->where($resWhere)
  442. ->field('contacts.name,contacts.contacts_id,contacts.customer_id,contacts.owner_user_id,customer.name as customer_name')
  443. ->page($page, $limit)
  444. ->select();
  445. $dataCount = db('crm_contacts')
  446. ->alias('contacts')
  447. ->join('__CRM_CUSTOMER__ customer', 'contacts.customer_id = customer.customer_id', 'LEFT')
  448. ->where($resWhere)
  449. ->count();
  450. foreach ($dataList as $k => $v) {
  451. $dataList[$k]['name'] = $v['name'] ?: '查看详情';
  452. $dataList[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  453. }
  454. } elseif ($types == 'crm_leads') {
  455. if (!$param['name'] && !$param['telephone'] && !$param['mobile']) return resultArray(['error' => '查询条件不能为空']);
  456. $resWhere = '';
  457. if ($param['name']) {
  458. $resWhere .= " `name` like '%" . $param['name'] . "%' ";
  459. } elseif ($param['mobile']) {
  460. if ($resWhere) $resWhere .= 'OR';
  461. $resWhere .= " `mobile` = '" . $param['mobile'] . "'";
  462. } elseif ($param['telephone']) {
  463. if ($resWhere) $resWhere .= 'OR';
  464. $resWhere .= " `telephone` = '" . $param['telephone'] . "'";
  465. }
  466. $dataList = db('crm_leads')
  467. ->where($resWhere)
  468. ->field('name,leads_id,owner_user_id')
  469. ->page($page, $limit)
  470. ->select();
  471. $dataCount = db('crm_leads')
  472. ->where($resWhere)
  473. ->count();
  474. foreach ($dataList as $k => $v) {
  475. $dataList[$k]['name'] = $v['name'] ?: '查看详情';
  476. $dataList[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  477. }
  478. }
  479. $data = [];
  480. $data['dataList'] = $dataList ?: [];
  481. $data['dataCount'] = $dataCount ?: 0;
  482. return resultArray(['data' => $data]);
  483. }
  484. /**
  485. * 查重(客户、公海、线索)
  486. * @param \app\crm\model\Index $index
  487. * @return \think\response\Json
  488. */
  489. public function queryRepeat(\app\crm\model\Index $index)
  490. {
  491. if (empty($this->param['type'])) return resultArray(['error' => '请选择查重类型!']);
  492. if (empty($this->param['content'])) return resultArray(['error' => '请填写查重内容!']);
  493. $type = $this->param['type'];
  494. $content = $this->param['content'];
  495. $data = $index->getQueryRepeat($type, $content);
  496. return resultArray(['data' => $data]);
  497. }
  498. /**
  499. * CRM工作台跳转(销售简报)
  500. * @param
  501. * @return
  502. * @author Michael_xu
  503. */
  504. public function indexList()
  505. {
  506. $userModel = new \app\admin\model\User();
  507. $adminModel = new \app\admin\model\Admin();
  508. $param = $this->param;
  509. // 2客户 3联系人 5商机 6合同 7回款 ''跟进记录
  510. $label = $param['label'];
  511. $types = $param['types'];
  512. $userInfo = $this->userInfo;
  513. $user_id = $param['user_id'] ? : $userInfo['id'];
  514. if($param['start_time'] && $param['end_time']){
  515. $param['start_time']=$param['start_time'].' 00:00:00';
  516. $param['end_time']=$param['end_time'].' 23:59:59';
  517. }
  518. $whereArr = $adminModel->getWhere($param, 1, ''); //统计条件
  519. $userIds = $whereArr['userIds'];
  520. $between_time = $whereArr['between_time'];
  521. $start_time = $between_time[0];
  522. $end_time = $between_time[1];
  523. $where = [];
  524. $where['page'] = $param['page'];
  525. $where['limit'] = $param['limit'];
  526. $where['search'] = $param['search'];
  527. $typesArr = ['crm_customer', 'crm_contacts', 'crm_business', 'crm_contract', 'crm_receivables', 'crm_activity'];
  528. if (!in_array($types, $typesArr)) {
  529. return resultArray(['error' => '参数错误']);
  530. }
  531. $m = 'crm';
  532. $a = 'index';
  533. switch ($types) {
  534. case 'crm_customer' :
  535. $c = 'customer';
  536. $model = new \app\crm\model\Customer();
  537. break;
  538. case 'crm_contacts' :
  539. $c = 'contacts';
  540. $model = new \app\crm\model\Contacts();
  541. break;
  542. case 'crm_business' :
  543. case 'crm_business_status' :
  544. $c = 'business';
  545. $model = new \app\crm\model\Business();
  546. break;
  547. case 'crm_contract' :
  548. $c = 'contract';
  549. $model = new \app\crm\model\Contract();
  550. break;
  551. case 'crm_receivables' :
  552. $c = 'receivables';
  553. $model = new \app\crm\model\Receivables();
  554. break;
  555. case 'crm_activity' :
  556. $c = 'activity';
  557. $model = new \app\crm\model\Activity();
  558. break;
  559. }
  560. //场景默认全部
  561. $scene_id = db('admin_scene')->where(['types' => $types, 'bydata' => 'all'])->value('scene_id');
  562. $where['scene_id'] = $scene_id ?: '';
  563. $where['create_time']['start'] = $start_time;
  564. $where['create_time']['end'] = $end_time;
  565. $auth_user_ids = $userModel->getUserByPer('crm', $c, 'index');
  566. $auth_user_ids = $auth_user_ids ? array_intersect($userIds, $auth_user_ids) : []; //取交集
  567. if ($c != 'activity') {
  568. $where['owner_user_id']['value'] = $auth_user_ids;
  569. if($types=='crm_contract' || $types=='crm_receivables'){
  570. $where['check_status']=2;
  571. }
  572. $data = $model->getDataList($where);
  573. } else {
  574. $typesList = ['1', '2', '3', '5', '6'];
  575. $arr = [];
  576. $where1['create_time'] = ['between', [$start_time, $end_time]];
  577. $where1['create_user_id'] = ['in', $auth_user_ids]; //跟进记录查询条件
  578. $where1['type'] = 1;
  579. $where1['status'] = 1;
  580. foreach ($typesList as $k => $v) {
  581. $where1['activity_type'] = $v;
  582. $dataCount = db('crm_activity')->where($where1)->count();
  583. if($v==1){
  584. $arr[$k]['types'] ='crm_leads';
  585. $arr[$k]['activity_type'] =1;
  586. }elseif ($v==2){
  587. $arr[$k]['types'] ='crm_customer';
  588. $arr[$k]['activity_type'] =2;
  589. }elseif ($v==3){
  590. $arr[$k]['types'] ='crm_contacts';
  591. $arr[$k]['activity_type'] =3;
  592. }elseif ($v==5){
  593. $arr[$k]['types'] ='crm_business';
  594. $arr[$k]['activity_type'] =5;
  595. }elseif ($v==6){
  596. $arr[$k]['types'] ='crm_contract';
  597. $arr[$k]['activity_type'] =6;
  598. }
  599. $arr[$k]['dataCount'] = $dataCount;
  600. $arr[$k]['create_user_id'] = implode(',', $userIds);
  601. $arr[$k]['create_time'] = implode(',', $where['create_time']); //查询条件返回
  602. }
  603. $data = $arr;
  604. }
  605. return resultArray(['data' => $data]);
  606. }
  607. /**
  608. * 遗忘提醒
  609. * @return \think\response\Json
  610. */
  611. public function forgottenCustomerCount()
  612. {
  613. $param = $this->param;
  614. $userInfo = $this->userInfo;
  615. $param['user_id'] = $param['user_id'] ?: $userInfo['id'];
  616. $indexModel = new IndexLogic;
  617. $customerList = $indexModel->getDataList($param);
  618. return resultArray(['data' => $customerList]);
  619. }
  620. /**
  621. * 遗忘提醒列表
  622. * @return \think\response\Json
  623. */
  624. public function forgottenCustomerPageList()
  625. {
  626. $param = $this->param;
  627. $userInfo = $this->userInfo;
  628. $param['user_id'] = $param['user_id'] ?: $userInfo['id'];
  629. $indexModel = new IndexLogic;
  630. $customerList = $indexModel->forgottenCustomerPageList($param);
  631. return resultArray(['data' => $customerList]);
  632. }
  633. /**
  634. * 排行榜
  635. */
  636. public function ranking()
  637. {
  638. $param = $this->param;
  639. $userInfo = $this->userInfo;
  640. $param['user_id'] = $param['user_id']?:$userInfo['id'];
  641. $indexModel = new IndexLogic;
  642. $data = $indexModel->ranking($param);
  643. return resultArray(['data' => $data]);
  644. }
  645. /**
  646. *数据汇总
  647. */
  648. public function queryDataInfo()
  649. {
  650. $param = $this->param;
  651. $userInfo = $this->userInfo;
  652. $param['user_id'] = $param['user_id']?:$userInfo['id'];
  653. $indexModel = new IndexLogic;
  654. $data = $indexModel->queryDataInfo($param);
  655. return resultArray(['data' => $data]);
  656. }
  657. /**
  658. * 销售漏斗点击查看
  659. */
  660. public function businessList()
  661. {
  662. $param = $this->param;
  663. $userInfo = $this->userInfo;
  664. $param['user_id'] = $param['user_id'] ?: $userInfo['id'];
  665. $indexModel = new IndexLogic;
  666. $data = $indexModel->businessList($param);
  667. return resultArray(['data' => $data]);
  668. }
  669. /**
  670. * 查询自动编号是否开启
  671. *
  672. * @return \think\response\Json
  673. */
  674. public function autoNumberStatus()
  675. {
  676. $type = $this->param['type'];
  677. $typeArray = ['crm_contract' => 1, 'crm_receivables' => 2, 'crm_visit' => 3, 'crm_invoice' => 4];
  678. $status = Db::name('crm_number_sequence')->where('number_type', $typeArray[$type])->where('status', 0)
  679. ->value('number_sequence_id');
  680. return resultArray(['data' => ['status' => !empty($status) ? true : false]]);
  681. }
  682. /**
  683. * 仪表盘布局
  684. */
  685. public function dashboard()
  686. {
  687. $param = $this->param;
  688. unset($param['user_id']);
  689. $userInfo = $this->userInfo;
  690. $param['user_id'] = $userInfo['id'];
  691. $dashboard = new IndexLogic;
  692. $data = $dashboard->dashboard($param);
  693. return resultArray(['data' => $data]);
  694. }
  695. /**
  696. * 修改仪表盘布局
  697. * @return mixed
  698. */
  699. public function updateDashboard()
  700. {
  701. $param = $this->param;
  702. unset($param['user_id']);
  703. $param['dashboard'] = $param;
  704. $userInfo = $this->userInfo;
  705. $param['user_id'] = $userInfo['id'];
  706. $dashboard = new IndexLogic;
  707. $data = $dashboard->updateDashboard($param);
  708. return resultArray(['data' => '修改成功']);
  709. }
  710. /**
  711. * 跟进详情
  712. * @return \think\response\Json
  713. */
  714. public function activityList(){
  715. $param = $this->param;
  716. $userInfo = $this->userInfo;
  717. $param['id']=$userInfo['id'];
  718. $indexLogic=new IndexLogic();
  719. $data=$indexLogic->activityList($param);
  720. return resultArray(['data'=>$data]);
  721. }
  722. }