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