123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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'] = $param['start_time'] . ' 00:00:00';
  61. if (!empty($param['end_time'])) $param['end_time'] = $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. $adminModel = new \app\admin\model\Admin();
  120. $param = $this->param;
  121. unset($param['types']);
  122. # 日期条件
  123. if (!empty($param['type'])) {
  124. $param['start_time'] = strtotime($param['type'] . '-01 00:00:00');
  125. $endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
  126. $param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth));
  127. unset($param['type']);
  128. } else {
  129. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  130. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  131. }
  132. # 排序参数
  133. $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
  134. $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
  135. $dataList = $businessModel->getDataList($param);
  136. foreach ($dataList['list'] as $k => $v) {
  137. $business_info = $crmBusinessModel->getDataById($v['business_id']);
  138. $dataList['list'][$k]['business_name'] = $business_info['name'];
  139. $dataList['list'][$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time']));
  140. $dataList['list'][$k]['customer_id'] = $v['customer_id'];
  141. $customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find();
  142. $dataList['list'][$k]['customer_name'] = $customer['name'];
  143. $create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  144. $dataList['list'][$k]['create_user_name'] = $create_user_id_info['realname'];
  145. $owner_user_id_info = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  146. $dataList['list'][$k]['owner_user_name'] = $owner_user_id_info['realname'];
  147. if($v['is_end']!=0){
  148. $dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['is_end'])->value('name');//销售阶段
  149. }else{
  150. $dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
  151. }
  152. $dataList['list'][$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
  153. }
  154. # 排序
  155. if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
  156. return resultArray(['data' => $dataList]);
  157. }
  158. /**
  159. * 赢单机会转化率趋势分析
  160. *
  161. * @return \think\response\Json
  162. * @throws \think\db\exception\DataNotFoundException
  163. * @throws \think\db\exception\ModelNotFoundException
  164. * @throws \think\exception\DbException
  165. */
  166. public function win()
  167. {
  168. $businessModel = new \app\crm\model\Business();
  169. $userModel = new \app\admin\model\User();
  170. $adminModel = new \app\admin\model\Admin();
  171. $param = $this->param;
  172. $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
  173. $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
  174. $userIds = $whereArr['userIds'];
  175. if(empty($param['type']) && empty($param['start_time'])){
  176. $param['type'] = 'month';
  177. }
  178. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  179. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  180. $time = getTimeArray($param['start_time'], $param['end_time']);
  181. $sql = db('crm_business')->alias('business')->field([
  182. "FROM_UNIXTIME(business.create_time, '{$time['time_format']}')" => 'type',
  183. 'COUNT(business.business_id)' => 'business_num',
  184. 'COUNT(
  185. CASE WHEN
  186. `is_end` = 1
  187. THEN 1 ELSE NULL END
  188. )' => 'business_end'
  189. ])->join('__CRM_CONTRACT__ contract', 'contract.business_id = business.business_id', 'left')
  190. ->where([
  191. 'business.owner_user_id' => ['IN', $userIds],
  192. 'business.create_time' => ['BETWEEN', $time['between']]
  193. ])
  194. ->group('type')
  195. ->fetchSql()
  196. ->select();
  197. $res = queryCache($sql);
  198. $res = array_column($res, null, 'type');
  199. foreach ($time['list'] as $key =>$val) {
  200. $val['business_num'] = (int) $res[$val['type']]['business_num'];
  201. $val['business_end'] = (int) $res[$val['type']]['business_end'];
  202. if($res[$val['type']]['business_num']== 0 || $res[$val['type']]['business_end'] == 0){
  203. $val['proportion'] = 0;
  204. }else{
  205. $val['proportion'] = round(($res[$val['type']]['business_end']/$res[$val['type']]['business_num']),4)*100;
  206. }
  207. $time['list'][$key] = $val;
  208. }
  209. return resultArray(['data' => $time['list']]);
  210. }
  211. /**
  212. * 商机转化率分析 列表
  213. *
  214. * @return \think\response\Json
  215. * @throws \think\db\exception\DataNotFoundException
  216. * @throws \think\db\exception\ModelNotFoundException
  217. * @throws \think\exception\DbException
  218. */
  219. public function winList()
  220. {
  221. $businessModel = new \app\bi\model\Business();
  222. $crmBusinessModel = new \app\crm\model\Business();
  223. $userModel = new \app\admin\model\User();
  224. $adminModel = new \app\admin\model\Admin();
  225. $param = $this->param;
  226. unset($param['types']);
  227. # 日期条件
  228. if (!empty($param['type'])) {
  229. $param['start_time'] = strtotime($param['type'] . '-01 00:00:00');
  230. $endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
  231. $param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth));
  232. unset($param['type']);
  233. } else {
  234. if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
  235. if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
  236. }
  237. # 排序参数
  238. $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
  239. $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
  240. # 赢单条件
  241. $param['is_end'] = 1;
  242. $dataList = $businessModel->getDataList($param);
  243. foreach ($dataList['list'] as $k => $v) {
  244. $business_info = $crmBusinessModel->getDataById($v['business_id']);
  245. $dataList['list'][$k]['business_name'] = $business_info['name'];
  246. $dataList['list'][$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time']));
  247. $dataList['list'][$k]['customer_id'] = $v['customer_id'];
  248. $customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find();
  249. $dataList['list'][$k]['customer_name'] = $customer['name'];
  250. $create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  251. $dataList['list'][$k]['create_user_name'] = $create_user_id_info['realname'];
  252. $owner_user_id_info = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  253. $dataList['list'][$k]['owner_user_name'] = $owner_user_id_info['realname'];
  254. if($v['is_end']!=0){
  255. $dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['is_end'])->value('name');//销售阶段
  256. }else{
  257. $dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
  258. }
  259. $dataList['list'][$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
  260. }
  261. # 排序
  262. if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
  263. return resultArray(['data' => $dataList]);
  264. }
  265. }