123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 商业智能-商机分析
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\bi\controller;
  8. use app\admin\controller\ApiCommon;
  9. use app\bi\traits\SortTrait;
  10. use think\Db;
  11. use think\Hook;
  12. use think\Request;
  13. class Business extends ApiCommon
  14. {
  15. use SortTrait;
  16. /**
  17. * 用于判断权限
  18. * @permission 无限制
  19. * @allow 登录用户可访问
  20. * @other 其他根据系统设置
  21. **/
  22. public function _initialize()
  23. {
  24. $action = [
  25. 'permission'=>[''],
  26. 'allow'=>[
  27. 'funnel',
  28. 'businesstrend',
  29. 'trendlist',
  30. 'win',
  31. 'winlist'
  32. ]
  33. ];
  34. Hook::listen('check_auth',$action);
  35. $request = Request::instance();
  36. $a = strtolower($request->action());
  37. if (!in_array($a, $action['permission'])) {
  38. parent::_initialize();
  39. }
  40. if (!checkPerByAction('bi', 'business' , 'read')) {
  41. header('Content-Type:application/json; charset=utf-8');
  42. exit(json_encode(['code'=>102,'error'=>'无权操作']));
  43. }
  44. }
  45. /**
  46. * 销售漏斗
  47. * @author Michael_xu
  48. * @param
  49. * @return
  50. */
  51. public function funnel()
  52. {
  53. if (empty($this->param['type_id'])) return resultArray(['error' => '请选择商机组!']);
  54. $businessModel = new \app\crm\model\Business();
  55. $param = $this->param;
  56. $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
  57. $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
  58. unset($param['sort_field']);
  59. unset($param['sort_value']);
  60. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  61. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  62. $data = $businessModel->getFunnel($param);
  63. foreach ($data['list'] AS $key => $value) {
  64. if (empty($value['money']) && empty($value['count'])) unset($data['list'][(int)$key]);
  65. }
  66. if (empty($data['total']['money_count']) && empty($data['total']['count'])) return resultArray(['data' => ['list' => []]]);
  67. $data['list'] = array_values($data['list']);
  68. # 排序
  69. if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
  70. return resultArray(['data' => $data]);
  71. }
  72. /**
  73. * 新增商机数与金额趋势分析
  74. * @return
  75. */
  76. public function businessTrend()
  77. {
  78. $businessModel = new \app\crm\model\Business();
  79. $userModel = new \app\admin\model\User();
  80. $adminModel = new \app\admin\model\Admin();
  81. $param = $this->param;
  82. $perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds
  83. $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
  84. $userIds = $whereArr['userIds'];
  85. if(empty($param['type']) && empty($param['start_time'])){
  86. $param['type'] = 'month';
  87. }
  88. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  89. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  90. $time = getTimeArray($param['start_time'], $param['end_time']);
  91. $where = [
  92. 'owner_user_id' => !empty($userIds) ? implode(',',$userIds) : '9999999999'
  93. ];
  94. $sql = [];
  95. foreach ($time['list'] as $val) {
  96. $whereArr = $where;
  97. $whereArr['type'] = $val['type'];
  98. $whereArr['start_time'] = $val['start_time'];
  99. $whereArr['end_time'] = $val['end_time'];
  100. $sql[] = $businessModel->getTrendql($whereArr);
  101. }
  102. $sql = implode(' UNION ALL ', $sql);
  103. $list = queryCache($sql);
  104. return resultArray(['data' => $list]);
  105. }
  106. /**
  107. * 新增商机数与金额趋势分析 列表
  108. *
  109. * @return \think\response\Json
  110. * @throws \think\db\exception\DataNotFoundException
  111. * @throws \think\db\exception\ModelNotFoundException
  112. * @throws \think\exception\DbException
  113. */
  114. public function trendList()
  115. {
  116. $businessModel = new \app\bi\model\Business();
  117. $crmBusinessModel = new \app\crm\model\Business();
  118. $userModel = new \app\admin\model\User();
  119. $param = $this->param;
  120. unset($param['types']);
  121. # 日期条件
  122. if (!empty($param['type'])) {
  123. $param['start_time'] = strtotime($param['type'] . '-01 00:00:00');
  124. $endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
  125. $param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth));
  126. unset($param['type']);
  127. } else {
  128. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  129. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  130. }
  131. # 排序参数
  132. $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
  133. $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
  134. $dataList = $businessModel->getDataList($param);
  135. foreach ($dataList['list'] as $k => $v) {
  136. $business_info = $crmBusinessModel->getDataById($v['business_id']);
  137. $dataList['list'][$k]['business_name'] = $business_info['name'];
  138. $dataList['list'][$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time']));
  139. $dataList['list'][$k]['customer_id'] = $v['customer_id'];
  140. $customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find();
  141. $dataList['list'][$k]['customer_name'] = $customer['name'];
  142. $create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  143. $dataList['list'][$k]['create_user_name'] = $create_user_id_info['realname'];
  144. $owner_user_id_info = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  145. $dataList['list'][$k]['owner_user_name'] = $owner_user_id_info['realname'];
  146. $dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
  147. $dataList['list'][$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
  148. }
  149. # 排序
  150. if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
  151. return resultArray(['data' => $dataList]);
  152. }
  153. /**
  154. * 赢单机会转化率趋势分析
  155. *
  156. * @return \think\response\Json
  157. * @throws \think\db\exception\DataNotFoundException
  158. * @throws \think\db\exception\ModelNotFoundException
  159. * @throws \think\exception\DbException
  160. */
  161. public function win()
  162. {
  163. $businessModel = new \app\crm\model\Business();
  164. $userModel = new \app\admin\model\User();
  165. $adminModel = new \app\admin\model\Admin();
  166. $param = $this->param;
  167. $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
  168. $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
  169. $userIds = $whereArr['userIds'];
  170. if(empty($param['type']) && empty($param['start_time'])){
  171. $param['type'] = 'month';
  172. }
  173. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  174. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  175. $time = getTimeArray($param['start_time'], $param['end_time']);
  176. $sql = db('crm_business')->alias('business')->field([
  177. "FROM_UNIXTIME(business.create_time, '{$time['time_format']}')" => 'type',
  178. 'COUNT(business.business_id)' => 'business_num',
  179. 'SUM(
  180. CASE WHEN
  181. `check_status` = 2
  182. THEN 1 ELSE 0 END
  183. )' => 'business_end'
  184. ])->join('__CRM_CONTRACT__ contract', 'contract.business_id = business.business_id', 'left')
  185. ->where([
  186. 'business.owner_user_id' => ['IN', $userIds],
  187. 'business.create_time' => ['BETWEEN', $time['between']]
  188. ])
  189. ->group('type')
  190. ->fetchSql()
  191. ->select();
  192. $res = queryCache($sql);
  193. $res = array_column($res, null, 'type');
  194. foreach ($time['list'] as $key =>$val) {
  195. $val['business_num'] = (int) $res[$val['type']]['business_num'];
  196. $val['business_end'] = (int) $res[$val['type']]['business_end'];
  197. if($res[$val['type']]['business_num']== 0 || $res[$val['type']]['business_end'] == 0){
  198. $val['proportion'] = 0;
  199. }else{
  200. $val['proportion'] = round(($res[$val['type']]['business_end']/$res[$val['type']]['business_num']),4)*100;
  201. }
  202. $time['list'][$key] = $val;
  203. }
  204. return resultArray(['data' => $time['list']]);
  205. }
  206. /**
  207. * 商机转化率分析 列表
  208. *
  209. * @return \think\response\Json
  210. * @throws \think\db\exception\DataNotFoundException
  211. * @throws \think\db\exception\ModelNotFoundException
  212. * @throws \think\exception\DbException
  213. */
  214. public function winList()
  215. {
  216. $businessModel = new \app\bi\model\Business();
  217. $crmBusinessModel = new \app\crm\model\Business();
  218. $userModel = new \app\admin\model\User();
  219. $param = $this->param;
  220. # 日期条件
  221. if (!empty($param['date'])) {
  222. $param['start_time'] = strtotime($param['date'] . '-01 00:00:00');
  223. $endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
  224. $param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth)) ;
  225. unset($param['type']);
  226. }
  227. # 排序参数
  228. $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
  229. $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
  230. # 赢单条件
  231. $param['is_end'] = 1;
  232. $dataList = $businessModel->getDataList($param);
  233. foreach ($dataList as $k => $v) {
  234. $business_info = $crmBusinessModel->getDataById($v['business_id']);
  235. $dataList[$k]['business_name'] = $business_info['name'];
  236. $dataList[$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time']));
  237. $dataList[$k]['customer_id'] = $v['customer_id'];
  238. $customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find();
  239. $dataList[$k]['customer_name'] = $customer['name'];
  240. $create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  241. $dataList[$k]['create_user_name'] = $create_user_id_info['realname'];
  242. $owner_user_id_info = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  243. $dataList[$k]['owner_user_name'] = $owner_user_id_info['realname'];
  244. $dataList[$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
  245. $dataList[$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
  246. }
  247. # 排序
  248. if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
  249. return resultArray(['data' => $dataList]);
  250. }
  251. }