Business.php 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 商机
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\crm\model;
  8. use think\Db;
  9. use app\admin\model\Common;
  10. use think\Request;
  11. use think\Validate;
  12. use app\crm\model\Business as CrmBusinessModel;
  13. class Business extends Common
  14. {
  15. /**
  16. * 为了数据库的整洁,同时又不影响Model和Controller的名称
  17. * 我们约定每个模块的数据表都加上相同的前缀,比如CRM模块用crm作为数据表前缀
  18. */
  19. protected $name = 'crm_business';
  20. protected $createTime = 'create_time';
  21. protected $updateTime = 'update_time';
  22. protected $autoWriteTimestamp = true;
  23. /**
  24. * [getDataList 商机list]
  25. *
  26. * @param $request
  27. * @return array
  28. * @throws \think\db\exception\DataNotFoundException
  29. * @throws \think\db\exception\ModelNotFoundException
  30. * @throws \think\exception\DbException
  31. */
  32. public function getDataList($request)
  33. {
  34. $userModel = new \app\admin\model\User();
  35. $structureModel = new \app\admin\model\Structure();
  36. $fieldModel = new \app\admin\model\Field();
  37. $search = $request['search'];
  38. $user_id = $request['user_id'];
  39. $scene_id = (int)$request['scene_id'];
  40. $contacts_id = $request['contacts_id'];
  41. $order_field = $request['order_field'];
  42. $order_type = $request['order_type'];
  43. $is_excel = $request['is_excel']; //导出
  44. $getCount = $request['getCount'];
  45. $businessTypeId = $request['typesId']; // 针对mobile
  46. $businessStatusId = $request['statusId']; // 针对mobile
  47. unset($request['scene_id']);
  48. unset($request['search']);
  49. unset($request['user_id']);
  50. unset($request['contacts_id']);
  51. unset($request['order_field']);
  52. unset($request['order_type']);
  53. unset($request['is_excel']);
  54. unset($request['getCount']);
  55. unset($request['typesId']);
  56. unset($request['statusId']);
  57. $request = $this->fmtRequest($request);
  58. $requestMap = $request['map'] ?: [];
  59. $sceneModel = new \app\admin\model\Scene();
  60. # getCount是代办事项传来的参数,代办事项不需要使用场景
  61. $sceneMap = [];
  62. if (empty($getCount)) {
  63. if ($scene_id) {
  64. //自定义场景
  65. $sceneMap = $sceneModel->getDataById($scene_id, $user_id, 'business') ?: [];
  66. } else {
  67. //默认场景
  68. $sceneMap = $sceneModel->getDefaultData('crm_business', $user_id) ?: [];
  69. }
  70. }
  71. if ($search || $search == '0') {
  72. //普通筛选
  73. $sceneMap['name'] = ['condition' => 'contains', 'value' => $search, 'form_type' => 'text', 'name' => '商机名称'];
  74. }
  75. if (isset($requestMap['type_id'])) {
  76. $requestMap['type_id']['value'] = $requestMap['type_id']['type_id'];
  77. if(in_array($requestMap['type_id']['status_id'],[1,2,3])){
  78. $requestMap['is_end']=$requestMap['type_id']['status_id'];
  79. }else{
  80. if ($requestMap['type_id']['status_id']) $requestMap['status_id']['value'] = $requestMap['type_id']['status_id'];
  81. $requestMap['is_end']=0;
  82. }
  83. }
  84. if ($sceneMap['type_id']) {
  85. $requestMap['type_id']['value'] = $sceneMap['type_id']['type_id'];
  86. if(in_array($sceneMap['type_id']['status_id'],[1,2,3])){
  87. $sceneMap['is_end']=$sceneMap['type_id']['status_id'];
  88. }else{
  89. if ($sceneMap['type_id']['status_id']) $requestMap['status_id']['value'] = $sceneMap['type_id']['status_id'];
  90. $sceneMap['is_end']=0;
  91. }
  92. unset($sceneMap['type_id']);
  93. }
  94. $partMap = [];
  95. //优先级:普通筛选>高级筛选>场景
  96. if ($sceneMap['ro_user_id'] && $sceneMap['rw_user_id']) {
  97. //相关团队查询
  98. $map = $requestMap;
  99. $partMap = function ($query) use ($sceneMap) {
  100. $query->where('business.ro_user_id', array('like', '%,' . $sceneMap['ro_user_id'] . ',%'))
  101. ->whereOr('business.rw_user_id', array('like', '%,' . $sceneMap['rw_user_id'] . ',%'));
  102. };
  103. } else {
  104. $map = $requestMap ? array_merge($sceneMap, $requestMap) : $sceneMap;
  105. }
  106. //高级筛选
  107. $map = where_arr($map, 'crm', 'business', 'index');
  108. $authMap = [];
  109. if (!$partMap) {
  110. $a = 'index';
  111. if ($is_excel) $a = 'excelExport';
  112. $auth_user_ids = $userModel->getUserByPer('crm', 'business', $a);
  113. if (isset($map['business.owner_user_id']) && $map['business.owner_user_id'][0] != 'like') {
  114. if (!is_array($map['business.owner_user_id'][1])) {
  115. $map['business.owner_user_id'][1] = [$map['business.owner_user_id'][1]];
  116. }
  117. if (in_array($map['business.owner_user_id'][0], ['neq', 'notin'])) {
  118. $auth_user_ids = array_diff($auth_user_ids, $map['business.owner_user_id'][1]) ?: []; //取差集
  119. } else {
  120. $auth_user_ids = array_intersect($map['business.owner_user_id'][1], $auth_user_ids) ?: []; //取交集
  121. }
  122. unset($map['business.owner_user_id']);
  123. $auth_user_ids = array_merge(array_unique(array_filter($auth_user_ids))) ?: ['-1'];
  124. $authMap['business.owner_user_id'] = array('in', $auth_user_ids);
  125. } else {
  126. $authMapData = [];
  127. $authMapData['auth_user_ids'] = $auth_user_ids;
  128. $authMapData['user_id'] = $user_id;
  129. $authMap = function ($query) use ($authMapData) {
  130. $query->where('business.owner_user_id', array('in', $authMapData['auth_user_ids']))
  131. ->whereOr('business.ro_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'))
  132. ->whereOr('business.rw_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'));
  133. };
  134. }
  135. }
  136. //联系人商机
  137. if ($contacts_id) {
  138. $business_id = Db::name('crm_contacts_business')->where(['contacts_id' => $contacts_id])->column('business_id');
  139. if ($business_id) {
  140. $map['business.business_id'] = array('in', $business_id);
  141. } else {
  142. $map['business.business_id'] = array('eq', -1);
  143. }
  144. }
  145. //列表展示字段
  146. $indexField = $fieldModel->getIndexField('crm_business', $user_id, 1) ?: array('name');
  147. if (!empty($indexField)) {
  148. foreach ($indexField as $key => $value) {
  149. if ($value == 'business.customer_name') unset($indexField[(int)$key]);
  150. }
  151. }
  152. $userField = $fieldModel->getFieldByFormType('crm_business', 'user'); //人员类型
  153. $structureField = $fieldModel->getFieldByFormType('crm_business', 'structure'); //部门类型
  154. $datetimeField = $fieldModel->getFieldByFormType('crm_business', 'datetime'); //日期时间类型
  155. # 处理人员和部门类型的排序报错问题(前端传来的是包含_name的别名字段)
  156. $temporaryField = str_replace('_name', '', $order_field);
  157. if (in_array($temporaryField, $userField) || in_array($temporaryField, $structureField)) {
  158. $order_field = $temporaryField;
  159. }
  160. //排序
  161. if ($order_type && $order_field) {
  162. $order = $fieldModel->getOrderByFormtype('crm_business', 'business', $order_field, $order_type);
  163. } else {
  164. $order = 'business.update_time desc';
  165. }
  166. # 商机组和商机状态搜索
  167. if (!empty($businessTypeId)) $map['business.type_id'] = ['eq', $businessTypeId];
  168. if (!empty($businessStatusId)) {
  169. if(preg_match("/^[1-9][0-9]*$/" ,$businessStatusId)){
  170. $map['is_end']=0;
  171. $map['business.status_id'] = ['eq', $businessStatusId];
  172. }else{
  173. $map['is_end']=abs($businessStatusId);
  174. }
  175. }
  176. $readAuthIds = $userModel->getUserByPer('crm', 'business', 'read');
  177. $updateAuthIds = $userModel->getUserByPer('crm', 'business', 'update');
  178. $deleteAuthIds = $userModel->getUserByPer('crm', 'business', 'delete');
  179. $dataCount = db('crm_business')
  180. ->alias('business')
  181. ->join('__CRM_CUSTOMER__ customer', 'business.customer_id = customer.customer_id', 'LEFT')
  182. ->where($map)->where($partMap)->where($authMap)->count('business_id');
  183. if (!empty($getCount) && $getCount == 1) {
  184. $data['dataCount'] = !empty($dataCount) ? $dataCount : 0;
  185. # 商机总金额
  186. $sumMoney = Db::name('crm_business')->alias('business')
  187. ->whereIn('is_end', [0, 1])->where($map)->where($partMap)->where($authMap)->sum('money');
  188. $data['extraData']['money'] = ['businessSumMoney' => !empty($sumMoney) ? sprintf("%.2f", $sumMoney) : 0.00];
  189. return $data;
  190. }
  191. $list = db('crm_business')
  192. ->alias('business')
  193. ->join('__CRM_CUSTOMER__ customer', 'business.customer_id = customer.customer_id', 'LEFT')
  194. ->where($map)
  195. ->where($partMap)
  196. ->where($authMap)
  197. ->limit($request['offset'], $request['length'])
  198. ->field('business.*,customer.name as customer_name')
  199. ->orderRaw($order)
  200. ->select();
  201. $endStatus = ['1' => '赢单', '2' => '输单', '3' => '无效'];
  202. foreach ($list as $k => $v) {
  203. $list[$k]['customer_id_info']['customer_id'] = $v['customer_id'];
  204. $list[$k]['customer_id_info']['name'] = $v['customer_name'];
  205. $list[$k]['create_user_id_info'] = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  206. $list[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  207. $list[$k]['create_user_name'] = !empty($list[$k]['create_user_id_info']['realname']) ? $list[$k]['create_user_id_info']['realname'] : '';
  208. $list[$k]['owner_user_name'] = !empty($list[$k]['owner_user_id_info']['realname']) ? $list[$k]['owner_user_id_info']['realname'] : '';
  209. foreach ($userField as $key => $val) {
  210. $usernameField = !empty($v[$val]) ? db('admin_user')->whereIn('id', stringToArray($v[$val]))->column('realname') : [];
  211. $list[$k][$val.'_name'] = implode($usernameField, ',');
  212. }
  213. foreach ($structureField as $key => $val) {
  214. $structureNameField = !empty($v[$val]) ? db('admin_structure')->whereIn('id', stringToArray($v[$val]))->column('name') : [];
  215. $list[$k][$val.'_name'] = implode($structureNameField, ',');
  216. }
  217. foreach ($datetimeField as $key => $val) {
  218. $list[$k][$val] = !empty($v[$val]) ? date('Y-m-d H:i:s', $v[$val]) : null;
  219. }
  220. $statusInfo = [];
  221. $status_count = 0;
  222. if (!$v['is_end']) {
  223. $statusInfo = db('crm_business_status')->where('status_id', $v['status_id'])->find();
  224. if ($statusInfo['order_id'] < 99) {
  225. $status_count = db('crm_business_status')->where('type_id', ['eq', $v['type_id']])->count();
  226. }
  227. //进度
  228. $list[$k]['status_progress'] = [$statusInfo['order_id'], $status_count + 1];
  229. } else {
  230. $statusInfo['name'] = $endStatus[$v['is_end']];
  231. }
  232. $list[$k]['status_id_info'] = $statusInfo['name'];//销售阶段
  233. $list[$k]['type_id_info'] = db('crm_business_type')->where('type_id', $v['type_id'])->value('name');//商机状态组
  234. //权限
  235. $roPre = $userModel->rwPre($user_id, $v['ro_user_id'], $v['rw_user_id'], 'read');
  236. $rwPre = $userModel->rwPre($user_id, $v['ro_user_id'], $v['rw_user_id'], 'update');
  237. $permission = [];
  238. $is_read = 0;
  239. $is_update = 0;
  240. $is_delete = 0;
  241. if (in_array($v['owner_user_id'], $readAuthIds) || $roPre || $rwPre) $is_read = 1;
  242. if (in_array($v['owner_user_id'], $updateAuthIds) || $rwPre) $is_update = 1;
  243. if (in_array($v['owner_user_id'], $deleteAuthIds)) $is_delete = 1;
  244. $permission['is_read'] = $is_read;
  245. $permission['is_update'] = $is_update;
  246. $permission['is_delete'] = $is_delete;
  247. $list[$k]['permission'] = $permission;
  248. # 下次联系时间
  249. $list[$k]['next_time'] = !empty($v['next_time']) ? date('Y-m-d H:i:s', $v['next_time']) : null;
  250. # 关注
  251. $starWhere = ['user_id' => $user_id, 'target_id' => $v['business_id'], 'type' => 'crm_business'];
  252. $star = Db::name('crm_star')->where($starWhere)->value('star_id');
  253. $list[$k]['star'] = !empty($star) ? 1 : 0;
  254. # 日期
  255. $list[$k]['create_time'] = !empty($v['create_time']) ? date('Y-m-d H:i:s', $v['create_time']) : null;
  256. $list[$k]['update_time'] = !empty($v['update_time']) ? date('Y-m-d H:i:s', $v['update_time']) : null;
  257. $list[$k]['last_time'] = !empty($v['last_time']) ? date('Y-m-d H:i:s', $v['last_time']) : null;
  258. }
  259. $data = [];
  260. $data['list'] = $list ?: [];
  261. $data['dataCount'] = $dataCount ?: 0;
  262. # 商机总金额
  263. $sumMoney = Db::name('crm_business')->alias('business')
  264. ->join('__CRM_CUSTOMER__ customer', 'business.customer_id = customer.customer_id', 'LEFT')
  265. ->whereIn('is_end', [0, 1])->where($map)->where($partMap)->where($authMap)->sum('money');
  266. $data['extraData']['money'] = ['businessSumMoney' => !empty($sumMoney) ? sprintf("%.2f", $sumMoney) : 0.00];
  267. return $data;
  268. }
  269. /**
  270. * 创建商机主表信息
  271. * @param
  272. * @return
  273. * @author Michael_xu
  274. */
  275. public function createData($param)
  276. {
  277. $fieldModel = new \app\admin\model\Field();
  278. $productModel = new \app\crm\model\Product();
  279. // 自动验证
  280. $validateArr = $fieldModel->validateField($this->name); //获取自定义字段验证规则
  281. $validate = new Validate($validateArr['rule'], $validateArr['message']);
  282. $result = $validate->check($param);
  283. if (!$result) {
  284. $this->error = $validate->getError();
  285. return false;
  286. }
  287. if (!$param['customer_id']) {
  288. $this->error = '请选择相关客户';
  289. return false;
  290. }
  291. // 处理部门、员工、附件、多选类型字段
  292. $arrFieldAtt = $fieldModel->getArrayField('crm_business');
  293. foreach ($arrFieldAtt as $k => $v) {
  294. $param[$v] = arrayToString($param[$v]);
  295. }
  296. // 处理日期(date)类型
  297. $dateField = $fieldModel->getFieldByFormType('crm_business', 'date');
  298. if (!empty($dateField)) {
  299. foreach ($param AS $key => $value) {
  300. if (in_array($key, $dateField) && empty($value)) $param[$key] = null;
  301. }
  302. }
  303. # 设置今日需联系商机
  304. if (!empty($param['next_time']) && $param['next_time'] >= strtotime(date('Y-m-d 00:00:00'))) $param['is_dealt'] = 0;
  305. $param['money'] = $param['money'] ?: '0.00';
  306. $param['discount_rate'] = $param['discount_rate'] ?: '0.00';
  307. if ($this->data($param)->allowField(true)->save()) {
  308. updateActionLog($param['create_user_id'], 'crm_business', $this->business_id, '', '', '创建了商机');
  309. RecordActionLog($param['create_user_id'],'crm_business','save',$param['name'],'','','新增了商机'.$param['name']);
  310. $business_id = $this->business_id;
  311. if ($param['product']) {
  312. //产品数据处理
  313. $resProduct = $productModel->createObject('crm_business', $param, $business_id);
  314. if ($resProduct == false) {
  315. $this->error = '产品添加失败';
  316. return false;
  317. }
  318. }
  319. //添加商机日志
  320. $data_log['business_id'] = $business_id;
  321. $data_log['is_end'] = 0;
  322. $data_log['status_id'] = $param['status_id'];
  323. $data_log['create_time'] = time();
  324. $data_log['owner_user_id'] = $param['owner_user_id'];
  325. $data_log['remark'] = '新建商机';
  326. Db::name('CrmBusinessLog')->insert($data_log);
  327. $data = [];
  328. $data['business_id'] = $business_id;
  329. # 添加活动记录
  330. Db::name('crm_activity')->insert([
  331. 'type' => 2,
  332. 'activity_type' => 5,
  333. 'activity_type_id' => $data['business_id'],
  334. 'content' => $param['name'],
  335. 'create_user_id' => $param['create_user_id'],
  336. 'update_time' => time(),
  337. 'create_time' => time(),
  338. 'customer_ids' => ',' . $param['customer_id'] . ','
  339. ]);
  340. return $data;
  341. } else {
  342. $this->error = '添加失败';
  343. return false;
  344. }
  345. }
  346. /**
  347. * 编辑商机主表信息
  348. * @param
  349. * @return
  350. * @author Michael_xu
  351. */
  352. public function updateDataById($param, $business_id = '')
  353. {
  354. $productModel = new \app\crm\model\Product();
  355. $dataInfo = $this->getDataById($business_id);
  356. if (!$dataInfo) {
  357. $this->error = '数据不存在或已删除';
  358. return false;
  359. }
  360. $param['business_id'] = $business_id;
  361. //过滤不能修改的字段
  362. $unUpdateField = ['create_user_id', 'is_deleted', 'delete_time'];
  363. foreach ($unUpdateField as $v) {
  364. unset($param[$v]);
  365. }
  366. $fieldModel = new \app\admin\model\Field();
  367. // 自动验证
  368. // $validateArr = $fieldModel->validateField($this->name); //获取自定义字段验证规则
  369. $validateArr = $fieldModel->validateField($this->name, 0, 'update'); //获取自定义字段验证规则
  370. $validate = new Validate($validateArr['rule'], $validateArr['message']);
  371. $result = $validate->check($param);
  372. if (!$result) {
  373. $this->error = $validate->getError();
  374. return false;
  375. }
  376. # 商机金额小数处理
  377. if (!empty($param['money']) && is_numeric($param['money']) && strpos($param['money'], ".") === false) {
  378. $param['money'] .= '.00';
  379. }
  380. // 处理部门、员工、附件、多选类型字段
  381. $arrFieldAtt = $fieldModel->getArrayField('crm_business');
  382. foreach ($arrFieldAtt as $k => $v) {
  383. if (isset($param[$v])) $param[$v] = arrayToString($param[$v]);
  384. }
  385. // 处理日期(date)类型
  386. $dateField = $fieldModel->getFieldByFormType('crm_business', 'date');
  387. if (!empty($dateField)) {
  388. foreach ($param AS $key => $value) {
  389. if (in_array($key, $dateField) && empty($value)) $param[$key] = null;
  390. }
  391. }
  392. # 设置今日需联系商机
  393. if (!empty($param['next_time']) && $param['next_time'] >= strtotime(date('Y-m-d 00:00:00'))) $param['is_dealt'] = 0;
  394. $param['money'] = $param['money'] ?: '0.00';
  395. $param['discount_rate'] = $param['discount_rate'] ?: '0.00';
  396. //商机状态改变
  397. $statusInfo = db('crm_business_status')->where(['status_id' => $param['status_id']])->find();
  398. if ($statusInfo['type_id']) {
  399. $param['is_end'] = 0;
  400. } else {
  401. $param['is_end'] = $param['status_id'];
  402. }
  403. if ($this->update($param, ['business_id' => $business_id], true)) {
  404. //产品数据处理
  405. $resProduct = $productModel->createObject('crm_business', $param, $business_id);
  406. //修改记录
  407. updateActionLog($param['user_id'], 'crm_business', $business_id, $dataInfo, $param);
  408. RecordActionLog($param['user_id'], 'crm_business', 'update',$dataInfo['name'], $dataInfo, $param);
  409. $data = [];
  410. $data['business_id'] = $business_id;
  411. return $data;
  412. } else {
  413. $this->rollback();
  414. $this->error = '编辑失败';
  415. return false;
  416. }
  417. }
  418. /**
  419. * 商机数据
  420. *
  421. * @param string $id
  422. * @param int $userId
  423. * @return Common|array|bool|\PDOStatement|string|\think\Model|null
  424. * @throws \think\db\exception\DataNotFoundException
  425. * @throws \think\db\exception\ModelNotFoundException
  426. * @throws \think\exception\DbException
  427. */
  428. public function getDataById($id = '', $userId = 0)
  429. {
  430. $dataInfo = db('crm_business')->where('business_id', $id)->find();
  431. if (!$dataInfo) {
  432. $this->error = '暂无此数据';
  433. return false;
  434. }
  435. $userModel = new \app\admin\model\User();
  436. $dataInfo['create_user_id_info'] = isset($dataInfo['create_user_id']) ? $userModel->getUserById($dataInfo['create_user_id']) : [];
  437. $dataInfo['owner_user_id_info'] = isset($dataInfo['owner_user_id']) ? $userModel->getUserById($dataInfo['owner_user_id']) : [];
  438. $dataInfo['create_user_name'] = !empty($dataInfo['create_user_id_info']['realname']) ? $dataInfo['create_user_id_info']['realname'] : '';
  439. $dataInfo['owner_user_name'] = !empty($dataInfo['owner_user_id_info']['realname']) ? $dataInfo['owner_user_id_info']['realname'] : '';
  440. $dataInfo['type_id_info'] = db('crm_business_type')->where(['type_id' => $dataInfo['type_id']])->value('name');
  441. $dataInfo['status_id_info'] = db('crm_business_status')->where(['status_id' => $dataInfo['status_id']])->value('name');
  442. $dataInfo['customer_id_info'] = db('crm_customer')->where(['customer_id' => $dataInfo['customer_id']])->field('customer_id,name')->find();
  443. $dataInfo['customer_name'] = !empty($dataInfo['customer_id_info']['name']) ? $dataInfo['customer_id_info']['name'] : '';
  444. # 关注
  445. $starId = empty($userId) ? 0 : Db::name('crm_star')->where(['user_id' => $userId, 'target_id' => $id, 'type' => 'crm_business'])->value('star_id');
  446. $dataInfo['star'] = !empty($starId) ? 1 : 0;
  447. # 首要联系人
  448. $primaryId = Db::name('crm_contacts')->where(['contacts_id' => $dataInfo['contacts_id']])->value('contacts_id');
  449. $dataInfo['contacts_id'] = !empty($primaryId) && $this->getContactsAuth($primaryId) ? $primaryId : 0;
  450. # 处理日期格式
  451. $fieldModel = new \app\admin\model\Field();
  452. $datetimeField = $fieldModel->getFieldByFormType('crm_business', 'datetime'); //日期时间类型
  453. foreach ($datetimeField as $key => $val) {
  454. $dataInfo[$val] = !empty($dataInfo[$val]) ? date('Y-m-d H:i:s', $dataInfo[$val]) : null;
  455. }
  456. if($dataInfo['is_end']!=1){
  457. $dataInfo['statusRemark']=db('crm_business_log')->where(['business_id'=>$id,'is_end'=>$dataInfo['is_end']])->value('remark');
  458. }
  459. $dataInfo['next_time'] = !empty($dataInfo['next_time']) ? date('Y-m-d H:i:s', $dataInfo['next_time']) : null;
  460. $dataInfo['create_time'] = !empty($dataInfo['create_time']) ? date('Y-m-d H:i:s', $dataInfo['create_time']) : null;
  461. $dataInfo['update_time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
  462. $dataInfo['last_time'] = !empty($dataInfo['last_time']) ? date('Y-m-d H:i:s', $dataInfo['last_time']) : null;
  463. // 字段授权
  464. if (!empty($userId)) {
  465. $grantData = getFieldGrantData($userId);
  466. $userLevel = isSuperAdministrators($userId);
  467. foreach ($dataInfo AS $key => $value) {
  468. if (!$userLevel && !empty($grantData['crm_business'])) {
  469. $status = getFieldGrantStatus($key, $grantData['crm_business']);
  470. # 查看权限
  471. if ($status['read'] == 0) unset($dataInfo[$key]);
  472. }
  473. }
  474. }
  475. return $dataInfo;
  476. }
  477. //根据IDs获取数组
  478. public function getDataByStr($idstr)
  479. {
  480. $idArr = stringToArray($idstr);
  481. if (!$idArr) {
  482. return [];
  483. }
  484. $list = Db::name('CrmBusiness')->where(['business_id' => ['in', $idArr]])->select();
  485. return $list;
  486. }
  487. /**
  488. * [商机漏斗]
  489. * @param
  490. * @return
  491. * @author Michael_xu
  492. */
  493. public function getFunnel($request)
  494. {
  495. $merge = $request['merge'] ?: 0;
  496. $perUserIds = $request['perUserIds'] ?: [];
  497. $adminModel = new \app\admin\model\Admin();
  498. $whereArr = $adminModel->getWhere($request, $merge, $perUserIds); //统计查询
  499. $userIds = $whereArr['userIds'];
  500. $between_time = $whereArr['between_time'];
  501. $where['owner_user_id'] = array('in', $userIds);
  502. $where['create_time'] = array('between', $between_time);
  503. //商机状态组
  504. $default_type_id = db('crm_business_type')->order('type_id asc')->value('type_id');
  505. $type_id = $request['type_id'] ? $request['type_id'] : $default_type_id;
  506. $statusList = db('crm_business_status')->where(['type_id' => $type_id])->select();
  507. $map = [];
  508. $map['create_time'] = $where['create_time'];
  509. $map['owner_user_id'] = ['in', $userIds];
  510. $map['type_id'] = $type_id;
  511. $sql_a = CrmBusinessModel::field([
  512. 'SUM(CASE WHEN is_end = 1 THEN money ELSE 0 END) AS sum_ying',
  513. 'SUM(CASE WHEN is_end = 2 THEN money ELSE 0 END) AS sum_shu',
  514. 'type_id'
  515. ])
  516. ->where($map)
  517. ->fetchSql()
  518. ->find();
  519. $res_a = queryCache($sql_a, 200);
  520. $sql = CrmBusinessModel::field([
  521. "status_id",
  522. 'COUNT(*)' => 'count',
  523. 'SUM(`money`)' => 'sum',
  524. 'type_id'
  525. ])
  526. ->where($where)
  527. ->whereNotIn('is_end', '1,2,3')
  528. ->group('status_id')
  529. ->fetchSql()
  530. ->select();
  531. $res = queryCache($sql, 200);
  532. $res = array_column($res, null, 'status_id');
  533. $sum_money = 0;
  534. $count = 0; # 商机数总和
  535. $moneyCount = 0; # 金额总和
  536. foreach ($statusList as $k => $v) {
  537. $v['count'] = $res[$v['status_id']]['count'] ?: 0;
  538. $v['money'] = $res[$v['status_id']]['sum'] ?: 0;
  539. $v['status_name'] = $v['name'];
  540. $statusList[$k] = $v;
  541. $sum_money += $v['money'];
  542. $moneyCount += $v['money'];
  543. $count += $v['count'];
  544. }
  545. $data['list'] = $statusList;
  546. $data['sum_ying'] = $res_a[0]['sum_ying'] ?: 0;
  547. $data['sum_shu'] = $res_a[0]['sum_shu'] ?: 0;
  548. $data['sum_money'] = $sum_money ?: 0;
  549. $data['total'] = ['name' => '合计', 'money_count' => $moneyCount, 'count' => $count];
  550. return $data ?: [];
  551. }
  552. /**
  553. * [商机转移]
  554. * @param ids 商机ID数组
  555. * @param owner_user_id 变更负责人
  556. * @param is_remove 1移出,2转为团队成员
  557. * @return
  558. * @author Michael_xu
  559. */
  560. public function transferDataById($ids, $owner_user_id, $type = 1, $is_remove)
  561. {
  562. $settingModel = new \app\crm\model\Setting();
  563. $errorMessage = [];
  564. foreach ($ids as $id) {
  565. $businessInfo = db('crm_business')->where(['business_id' => $id])->find();
  566. //团队成员
  567. $teamData = [];
  568. $teamData['type'] = $type; //权限 1只读2读写
  569. $teamData['user_id'] = [$businessInfo['owner_user_id']]; //协作人
  570. $teamData['types'] = 'crm_business'; //类型
  571. $teamData['types_id'] = $id; //类型ID
  572. $teamData['is_del'] = ($is_remove == 1) ? 1 : '';
  573. $res = $settingModel->createTeamData($teamData);
  574. $data = [];
  575. $data['owner_user_id'] = $owner_user_id;
  576. $data['update_time'] = time();
  577. if (!db('crm_business')->where(['business_id' => $id])->update($data)) {
  578. $errorMessage[] = '商机:' . $businessInfo['name'] . '"转移失败,错误原因:数据出错;';
  579. continue;
  580. } else {
  581. $businessArray = [];
  582. $teamBusiness = db('crm_business')->field(['owner_user_id', 'ro_user_id', 'rw_user_id'])->where('business_id', $id)->find();
  583. if (!empty($teamBusiness['ro_user_id'])) {
  584. $businessRo = arrayToString(array_diff(stringToArray($teamBusiness['ro_user_id']), [$teamBusiness['owner_user_id']]));
  585. $businessArray['ro_user_id'] = $businessRo;
  586. }
  587. if (!empty($teamBusiness['rw_user_id'])) {
  588. $businessRo = arrayToString(array_diff(stringToArray($teamBusiness['rw_user_id']), [$teamBusiness['owner_user_id']]));
  589. $businessArray['rw_user_id'] = $businessRo;
  590. }
  591. db('crm_business')->where('business_id', $id)->update($businessArray);
  592. }
  593. }
  594. if ($errorMessage) {
  595. return $errorMessage;
  596. } else {
  597. return true;
  598. }
  599. }
  600. /**
  601. * [商机统计]
  602. * @param
  603. * @return
  604. */
  605. public function getTrendql($map)
  606. {
  607. $prefix = config('database.prefix');
  608. $sql = "SELECT
  609. '{$map['type']}' AS type,
  610. '{$map['start_time']}' AS start_time,
  611. '{$map['end_time']}' AS end_time,
  612. IFNULL(
  613. (
  614. SELECT
  615. sum(money)
  616. FROM
  617. {$prefix}crm_business
  618. WHERE
  619. create_time BETWEEN {$map['start_time']} AND {$map['end_time']}
  620. AND owner_user_id IN ({$map['owner_user_id']})
  621. ),
  622. 0
  623. ) AS business_money,
  624. IFNULL(
  625. count(business_id),
  626. 0
  627. ) AS business_num
  628. FROM
  629. {$prefix}crm_business
  630. WHERE
  631. create_time BETWEEN {$map['start_time']} AND {$map['end_time']}
  632. AND owner_user_id IN ({$map['owner_user_id']})";
  633. return $sql;
  634. }
  635. /**
  636. * [赢单机会转化率趋势分析]
  637. * @param
  638. * @return
  639. */
  640. public function getWinSql($map)
  641. {
  642. $prefix = config('database.prefix');
  643. $sql = "SELECT
  644. '{$map['type']}' AS type,
  645. '{$map['start_time']}' AS start_time,
  646. '{$map['end_time']}' AS end_time,
  647. IFNULL(
  648. (
  649. SELECT
  650. count(business_id)
  651. FROM
  652. {$prefix}crm_business
  653. WHERE
  654. create_time BETWEEN {$map['start_time']} AND {$map['end_time']}
  655. AND owner_user_id IN ({$map['owner_user_id']})
  656. AND is_end = 1
  657. ),
  658. 0
  659. ) AS business_end,
  660. IFNULL(
  661. count(business_id),
  662. 0
  663. ) AS business_num
  664. FROM
  665. {$prefix}crm_business
  666. WHERE
  667. create_time BETWEEN {$map['start_time']} AND {$map['end_time']}
  668. AND owner_user_id IN ({$map['owner_user_id']})";
  669. return $sql;
  670. }
  671. /**
  672. * 获取系统信息
  673. *
  674. * @param $id
  675. * @return array
  676. * @throws \think\db\exception\DataNotFoundException
  677. * @throws \think\db\exception\ModelNotFoundException
  678. * @throws \think\exception\DbException
  679. */
  680. public function getSystemInfo($id)
  681. {
  682. # 商机
  683. $business = Db::name('crm_business')->field(['create_user_id', 'create_time', 'update_time', 'last_time'])->where('business_id', $id)->find();
  684. # 创建人
  685. $realname = Db::name('admin_user')->where('id', $business['create_user_id'])->value('realname');
  686. return [
  687. 'create_user_id' => $realname,
  688. 'create_time' => date('Y-m-d H:i:s', $business['create_time']),
  689. 'update_time' => date('Y-m-d H:i:s', $business['update_time']),
  690. 'last_time' => !empty($business['last_time']) ? date('Y-m-d H:i:s', $business['last_time']) : ''
  691. ];
  692. }
  693. /**
  694. * 判断联系人详情权限 todo 客户模块也在用,以后抽成一个公共的方法
  695. *
  696. * @param $contactsId
  697. * @return bool
  698. */
  699. private function getContactsAuth($contactsId)
  700. {
  701. $ownerUserId = db('crm_contacts')->where('contacts_id', $contactsId)->value('owner_user_id');
  702. $authUserIds = (new \app\admin\model\User())->getUserByPer('crm', 'contacts', 'read');
  703. return in_array($ownerUserId, $authUserIds);
  704. }
  705. }