| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216 |
- <?php
- // +----------------------------------------------------------------------
- // | Description: 商业智能-客户分析
- // +----------------------------------------------------------------------
- // | Author: Michael_xu | gengxiaoxu@5kcrm.com
- // +----------------------------------------------------------------------
-
- namespace app\bi\controller;
-
- use app\admin\controller\ApiCommon;
- use app\bi\logic\BiCustomerLogic;
- use app\bi\model\Customer as CustomerModel;
- use app\admin\model\User as UserModel;
- use app\bi\traits\SortTrait;
- use think\Hook;
- use think\Request;
- use think\Db;
- use app\bi\logic\ExcelLogic;
-
- class Customer extends ApiCommon
- {
- use SortTrait;
-
- /**
- * 用于判断权限
- * @permission 无限制
- * @allow 登录用户可访问
- * @other 其他根据系统设置
- **/
- public function _initialize()
- {
- $action = [
- 'permission' => [''],
- 'allow' => [
- 'statistics',
- 'total',
- 'recordtimes',
- 'recordlist',
- 'recordmode',
- 'conversion',
- 'conversioninfo',
- 'pool',
- 'poollist',
- 'usercycle',
- 'usercyclelist',
- 'productcycle',
- 'addresscycle',
- 'addressanalyse',
- 'portrait',
- 'customersatisfaction',
- 'productsatisfaction',
- 'excelexport'
- ]
- ];
- Hook::listen('check_auth', $action);
- $request = Request::instance();
- $a = strtolower($request->action());
- if (!in_array($a, $action['permission'])) {
- parent::_initialize();
- }
- // if (!checkPerByAction('bi', 'customer', 'read')) {
- // header('Content-Type:application/json; charset=utf-8');
- // exit(json_encode(['code' => 102, 'error' => '无权操作']));
- // }
- }
-
- /**
- * 员工客户分析
- * @param
- * @return
- * @author Michael_xu
- */
- public function statistics($param='')
- {
- $customerModel = new \app\crm\model\Customer();
- if($param['excel_type']!=1){
- $param = $this->param;
- }
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- if ($param['type']) {
- $timeArr = getTimeByType($param['type']);
- $param['start_time'] = $timeArr[0];
- $param['end_time'] = $timeArr[1];
- } else {
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- }
-
- $data = $customerModel->getStatistics($param);
-
- # 排序
- if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
- //导出使用
- if (!empty($param['excel_type'])) return $data;
- return resultArray(['data' => $data]);
- }
-
- /**
- * 员工客户总量分析
- * @param
- * @return
- * @author zhi
- */
- public function total()
- {
- $customerModel = new \app\crm\model\Customer();
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereArr['userIds'];
-
- # 处理无员工的情况
- if (empty($userIds)) return resultArray(['data' => []]);
-
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
- $where = [
- 'create_user_id' => implode(',', $userIds),
- 'deal_status' => '已成交'
- ];
- $sql = [];
-
- foreach ($time['list'] as $val) {
- $whereArr = $where;
- $whereArr['type'] = $val['type'];
- $whereArr['start_time'] = $val['start_time'];
- $whereArr['end_time'] = $val['end_time'];
- $sql[] = $customerModel->getAddDealSql($whereArr);
- }
-
- $sql = implode(' UNION ALL ', $sql);
-
- $list = queryCache($sql);
- return resultArray(['data' => $list]);
- }
-
- /**
- * 员工客户跟进次数分析
- *
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function recordTimes()
- {
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereArr['userIds'];
- if (empty($userIds)) return resultArray(['data' => []]);
-
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
-
- $recordWhere['type'] = 1;
- $recordWhere['activity_type'] = 2;
- $recordWhere['create_user_id'] = ['in', $userIds];
- $recordWhere['create_time'] = ['between', [$time['between'][0], $time['between'][1]]];
- $sql = db('crm_activity')->
- field([
- "FROM_UNIXTIME(`create_time`, '".$time['time_format']."') AS `type`",
- 'COUNT(DISTINCT(`activity_type_id`)) AS `customerCount`',
- 'COUNT(*) AS `dataCount`'
- ])
- ->where($recordWhere)
- ->group('type')
- ->select();
- $res = array_column((array)$sql, null, 'type');
-
- foreach ($time['list'] as &$val) {
- $val['customerCount'] = (int)$res[$val['type']]['customerCount'];
- $val['dataCount'] = (int)$res[$val['type']]['dataCount'];
- }
- return resultArray(['data' => $time['list']]);
- }
-
- /**
- * 员工客户跟进次数分析 具体员工列表
- *
- * @param string $param
- * @return array|\think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function recordList($param='')
- {
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- if($param['excel_type']!=1){
- $param = $this->param;
- }
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereArr['userIds'];
- if (empty($userIds)) return resultArray(['data' => []]);
-
- # 员工列表
- $userData = [];
- $userList = db('admin_user')->field(['id', 'realname'])->whereIn('id', $userIds)->select();
- foreach ($userList AS $key => $value) {
- $userData[$value['id']] = $value['realname'];
- }
-
- # 跟进记录列表
- $recordData = [];
- $recordWhere['type'] = 1;
- $recordWhere['activity_type'] = 2;
- $recordWhere['create_user_id'] = ['in', $userIds];
- $recordWhere['create_time'] = ['between', [$whereArr['between_time'][0], $whereArr['between_time'][1]]];
- $recordList = db('crm_activity')->field(['count(*) as count', 'create_user_id', 'activity_type_id'])->where($recordWhere)
- ->group('create_user_id, activity_type_id')->select();
-
- # 跟进列表
- foreach ($recordList AS $key => $value) {
- if (empty($recordData[$value['create_user_id']]['realname'])) {
- $recordData[$value['create_user_id']]['realname'] = $userData[$value['create_user_id']];
- $recordData[$value['create_user_id']]['record_num'] = $value['count'];
- $recordData[$value['create_user_id']]['customer_num'] = 1;
- } else {
- $recordData[$value['create_user_id']]['record_num'] = $recordData[$value['create_user_id']]['record_num'] + $value['count'];
- $recordData[$value['create_user_id']]['customer_num'] = $recordData[$value['create_user_id']]['customer_num'] + 1;
- }
-
- if (!empty($userData[$value['create_user_id']])) unset($userData[(int)$value['create_user_id']]);
- }
-
- # 跟进客户总数
- $customerCount = db('crm_activity')->where($recordWhere)->group('activity_type_id')->count();
-
- # 没有跟进的员工设置默认值
- foreach ($userData AS $key => $value) {
- $recordData[$key]['realname'] = $value;
- $recordData[$key]['record_num'] = 0;
- $recordData[$key]['customer_num'] = 0;
- }
-
- $result = ['list' => array_values($recordData), 'total' => ['realname' => '总计', 'customer_num' => $customerCount]];
-
- # 排序
- if (!empty($result['list'])) $result['list'] = $this->sortCommon($result['list'], $sortField, $sortValue);
- //导出使用
- if (!empty($param['excel_type'])) return $recordData;
- return resultArray(['data' => $result]);
- }
-
- /**
- * 员工跟进方式分析
- *
- * @param string $param
- * @return mixed|\think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function recordMode($param='')
- {
- $biCustomerModel = new \app\bi\model\Customer();
- if($param['excel_type']!=1){
- $param = $this->param;
- }
- $userId = $this->userInfo['id'];
-
- # 处理无部门无员工的情况
- $groupType = !empty($param['group_type']) ? $param['group_type'] : 1; # 组类型:1部门;2员工
- if (empty($param['user_id']) && empty($param['structure_id'])) {
- if ($groupType == 1) $param['structure_id'] = Db::name('admin_user')->where('id', $userId)->value('structure_id');
- if ($groupType == 2) $param['user_id'] = $userId;
- }
- unset($param['group_type']);
-
- # 判断部门下是否有员工
- if (!empty($param['structure_id'])) {
- $userModel = new \app\admin\model\User();
- $userIds = $userModel->getSubUserByStr($param['structure_id'], 2);
- if (empty($userIds)) return resultArray(['data' => []]);
- }
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
-
- $whereArr = $biCustomerModel->getParamByWhere($param, 'record');
-
- //跟进类型
- $record_type = db('crm_config')->where(['name' => 'record_type'])->find();
- if ($record_type) {
- $record_categorys = json_decode($record_type['value']);
- } else {
- $record_categorys = array('打电话', '发邮件', '发短信', '见面拜访', '活动');
- }
-
- $sql = db('crm_activity')
- ->field([
- 'category',
- 'COUNT(*)' => 'count'
- ])
- ->where([
- 'create_time' => $whereArr['create_time'],
- 'create_user_id' => $whereArr['create_user_id'],
- 'type' => 1,
- 'activity_type' => 2
- ])
- ->group('category')
- ->fetchSql()
- ->select();
-
- $list = queryCache($sql);
- $list = array_column($list, null, 'category');
- $sum = array_sum(array_column($list, 'count'));
-
- $res = [];
- $recordCount = 0; # 跟进类型总数
- foreach ($record_categorys as $val) {
- $item['category'] = $val;
- if ($sum) {
- $item['recordNum'] = (int)$list[$val]['count'];
- $item['proportion'] = round(($item['recordNum'] / $sum * 100), 4);
- } else {
- $item['recordNum'] = $item['proportion'] = 0;
- }
- $res[] = $item;
-
- $recordCount += $item['recordNum'];
- }
-
- $result = [
- 'list' => $res,
- 'total' => [
- 'category' => '合计',
- 'recordNum' => $recordCount,
- 'proportion' => !empty($recordCount) ? 100 : 0
- ]
- ];
-
- # 排序
- if (!empty($result['list'])) $result['list'] = $this->sortCommon($result['list'], $sortField, $sortValue);
- //导出使用
- if (!empty($param['excel_type'])) return $result['list'];
- return resultArray(['data' => $result]);
- }
-
- /**
- * 客户转化率分析
- *
- * @param
- * @return
- * @author zhi
- */
- public function conversion()
- {
- $customerModel = new \app\crm\model\Customer();
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- if (empty($whereArr['userIds'])) resultArray(['data' => []]);
- $userIds = $whereArr['userIds'];
- $user_ids = implode(',',$userIds);
-
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
- $sql = [];
- foreach ($time['list'] as $val) {
- $sql[] = $customerModel->getAddDealSql([
- 'create_user_id' => $user_ids ? $user_ids : '9999999999',
- 'type' => $val['type'],
- 'start_time' => $val['start_time'],
- 'end_time' => $val['end_time'],
- 'deal_status' => '已成交',
- ]);
- }
- $sql = implode(' UNION ALL ', $sql);
- $list = queryCache($sql);
- foreach ($list as &$val) {
- $val['proportion'] = $val['customer_num'] ? number_format($val['deal_customer_num'] / $val['customer_num'] * 100, 2) : 0;
- }
- return resultArray(['data' => $list]);
- }
-
- /**
- * 客户转化率分析具体数据
- *
- * @return \think\response\Json
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function conversionInfo()
- {
- $customerModel = new \app\bi\model\Customer();
- $userModel = new \app\admin\model\User();
- $param = $this->param;
- $userIds = [];
- $userId = $this->userInfo['id'];
-
- # 处理无部门无员工的情况
- $groupType = !empty($param['group_type']) ? $param['group_type'] : 1; # 组类型:1部门;2员工
- if (empty($param['user_id']) && empty($param['structure_id'])) {
- if ($groupType == 1) $param['structure_id'] = Db::name('admin_user')->where('id', $userId)->value('structure_id');
- if ($groupType == 2) $param['user_id'] = $userId;
- }
- unset($param['group_type']);
-
- # 如果存在员工参数,则不再使用部门参数
- if (!empty($param['user_id'])) {
- $userIds = [$param['user_id']];
- } elseif (!empty($param['structure_id'])) {
- $userIds = $userModel->getSubUserByStr($param['structure_id'], 2);
- }
- if (empty($userIds)) return resultArray(['data' => []]);
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- # 日期条件
- if (!empty($param['type'])) {
- $param['start_time'] = strtotime($param['type'] . '-01 00:00:00');
- $endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
- $param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth));
- unset($param['type']);
- }
-
- $whereArr = $customerModel->getParamByWhere($param);
- $whereArr['deal_status'] = '已成交';
-
- $list = $customerModel->getWhereByList($whereArr, $sortField, $sortValue);
-
- return resultArray(['data' => $list]);
- }
-
- /**
- * 公海客户分析
- *
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function pool()
- {
- $actionRecordModel = new \app\bi\model\ActionRecord();
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereArr['userIds'];
-
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
- $sql = $actionRecordModel
- ->field([
- "FROM_UNIXTIME(`create_time`, '{$time['time_format']}')" => 'type',
- 'SUM(CASE WHEN `content` = "将客户放入公海" THEN 1 ELSE 0 END)' => 'put_in',
- 'SUM(CASE WHEN `content` = "领取了客户" THEN 1 ELSE 0 END)' => 'receive'
- ])
- ->where([
- 'user_id' => ['IN', !empty($userIds) ? $userIds : '9999999999'],
- 'create_time' => ['BETWEEN', $time['between']],
- 'content' => ['IN', ['将客户放入公海', '领取了客户']]
- ])
- ->group('type')
- ->fetchSql()
- ->select();
- $res = queryCache($sql);
- $res = array_column($res, null, 'type');
-
- foreach ($time['list'] as &$val) {
- $val['put_in'] = (int)$res[$val['type']]['put_in'];
- $val['receive'] = (int)$res[$val['type']]['receive'];
- }
-
- return resultArray(['data' => $time['list']]);
- }
-
- /**
- * 公海客户分析 具体列表
- *
- * @param string $param
- * @return mixed|\think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function poolList($param='')
- {
- $userModel = new \app\admin\model\User();
- $actionRecordModel = new \app\bi\model\ActionRecord();
- $adminModel = new \app\admin\model\Admin();
- if($param['excel_type']!=1){
- $param = $this->param;
- }
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereArr['userIds'];
- $between_time = $whereArr['between_time'];
-
- $sql = CustomerModel::field([
- 'COUNT(*)' => 'customer_num',
- 'owner_user_id'
- ])
- ->where([
- 'create_time' => ['BETWEEN', $between_time],
- 'owner_user_id' => ['IN', !empty($userIds) ? $userIds : '9999999999']
- ])
- ->group('owner_user_id')
- ->fetchSql()
- ->select();
- $customer_num_list = queryCache($sql);
- $customer_num_list = array_column($customer_num_list, null, 'owner_user_id');
-
- $sql = $actionRecordModel
- ->field([
- 'user_id',
- 'SUM(CASE WHEN `content` = "将客户放入公海" THEN 1 ELSE 0 END)' => 'put_in',
- 'SUM(CASE WHEN `content` = "领取了客户" THEN 1 ELSE 0 END)' => 'receive'
- ])
- ->group('user_id')
- ->where([
- 'create_time' => ['BETWEEN', $between_time],
- 'user_id' => ['IN', $userIds],
- 'content' => ['IN', ['将客户放入公海', '领取了客户']],
- 'types' => 'crm_customer',
- ])
- ->fetchSql()
- ->select();
- $action_record_list = queryCache($sql);
- $action_record_list = array_column($action_record_list, null, 'user_id');
-
- $res = [];
- $receiveCount = 0; # 领取公海客户总数
- $putInCount = 0; # 进入公海客户总数
- foreach ($userIds as $val) {
- $item['put_in'] = !empty($action_record_list[$val]['put_in']) ? (int)$action_record_list[$val]['put_in'] : 0;
- $item['receive'] = !empty($action_record_list[$val]['receive']) ? (int)$action_record_list[$val]['receive'] : 0;
- $item['customer_num'] = !empty($customer_num_list[$val]['customer_num']) ? (int)$customer_num_list[$val]['customer_num'] : 0;
- $user_info = $userModel->getUserById($val);
- $item['realname'] = $user_info['realname'];
- $item['username'] = $user_info['structure_name'];
- $res[] = $item;
-
- $receiveCount += $item['receive'];
- $putInCount += $item['put_in'];
- }
-
- $result = ['list' => $res, 'total' => ['realname' => '总计', 'receive' => $receiveCount, 'put_in' => $putInCount]];
-
- # 排序
- if (!empty($result['list'])) $result['list'] = $this->sortCommon($result['list'], $sortField, $sortValue);
- //导出使用
- if (!empty($param['excel_type'])) return $result['list'];
- return resultArray(['data' => $result]);
- }
-
- /**
- * 员工客户成交周期
- *
- * @param string $param
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function userCycle($param='')
- {
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- if($param['excel_type']!=1){
- $param = $this->param;
- }
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereData['userIds'];
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
-
- $prefix = config('database.prefix');
-
- $sql = CustomerModel::alias('a')
- ->field([
- "FROM_UNIXTIME(`a`.`create_time`, '{$time['time_format']}')" => 'type',
- 'COUNT(*)' => 'customer_num',
- 'SUM(
- CASE WHEN ISNULL(`b`.`order_date`) THEN 0 ELSE (
- UNIX_TIMESTAMP(`b`.`order_date`) - `a`.`create_time`
- ) / 86400 END
- )' => 'cycle_sum'
- ])
- ->join(
- "(
- SELECT
- `customer_id`, MIN(`order_date`) AS `order_date`
- FROM
- `{$prefix}crm_contract`
- WHERE
- `check_status` = 2
- GROUP BY
- `customer_id`
- ) b",
- '`a`.`customer_id` = `b`.`customer_id`',
- 'LEFT'
- )
- ->where([
- 'a.deal_status' => '已成交',
- 'a.create_time' => ['BETWEEN', $time['between']],
- 'a.owner_user_id' => ['IN', !empty($userIds) ? $userIds : '9999999999']
- ])
- ->group('type')
- ->fetchsql()
- ->select();
- $res = queryCache($sql);
- $res = array_column($res, null, 'type');
-
- foreach ($time['list'] as &$val) {
- $val['customer_num'] = (int)$res[$val['type']]['customer_num'];
- if ($res[$val['type']]['customer_num']) {
- $val['cycle'] = intval($res[$val['type']]['cycle_sum'] / $res[$val['type']]['customer_num']);
- } else {
- $val['cycle'] = 0;
- }
- }
- $datas = $time['list'];
-
- return resultArray(['data' => $datas]);
- }
-
- /**
- * 成交周期列表
- *
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function userCycleList()
- {
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- # 排序参数
- $sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
- $sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
- unset($param['sort_field']);
- unset($param['sort_value']);
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereData['userIds'];
-
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
-
- $prefix = config('database.prefix');
-
- $sql = CustomerModel::alias('a')
- ->field([
- 'a.owner_user_id',
- 'COUNT(*)' => 'customer_num',
- 'SUM(
- CASE WHEN ISNULL(b.order_date) THEN 0 ELSE (
- UNIX_TIMESTAMP(b.order_date) - a.create_time
- ) / 86400 END
- )' => 'cycle_sum'
- ])
- ->join(
- "(
- SELECT
- `customer_id`,
- MIN(`order_date`) AS `order_date`
- FROM
- `{$prefix}crm_contract`
- WHERE
- `check_status` = 2
- GROUP BY
- `customer_id`
- ) b",
- 'a.customer_id = b.customer_id',
- 'LEFT'
- )
- ->where([
- 'a.deal_status' => '已成交',
- 'a.create_time' => ['BETWEEN', $time['between']],
- 'a.owner_user_id' => ['IN', !empty($userIds) ? $userIds : '9999999999']
- ])
- ->group('a.owner_user_id')
- ->fetchSql()
- ->select();
- $res = queryCache($sql);
- $res = array_column($res, null, 'owner_user_id');
-
- $user_data = [];
- $customerCount = 0; # 成交客户总数
- $cycleCount = 0; # 成交周期总数
- foreach ($userIds as $value) {
- $item['customer_num'] = !empty($res[$value]['customer_num']) ? $res[$value]['customer_num'] : 0;
- $item['cycle'] = $res[$value]['customer_num'] ? intval($res[$value]['cycle_sum'] / $res[$value]['customer_num']) : 0;
- $item['realname'] = $userModel->getUserById($value)['realname'];
-
- $user_data[] = $item;
-
- $customerCount += $item['customer_num'];
- $cycleCount += $item['cycle'];
- }
- $datas['list'] = $user_data;
-
- $datas['total'] = [
- 'realname' => '总计',
- 'customer_num' => $customerCount,
- 'cycle' => $cycleCount
-
- ];
-
- # 排序
- if (!empty($datas['users'])) $datas['users'] = $this->sortCommon($datas['users'], $sortField, $sortValue);
- //导出使用
- if (!empty($param['excel_type'])) return $datas['list'];
- return resultArray(['data' => $datas]);
- }
-
- /**
- * 产品成交周期
- * @param
- * @return
- * @author zhi
- */
- public function productCycle()
- {
- $biCustomerModel = new \app\bi\model\Customer();
- $productModel = new \app\bi\model\Product();
- $param = $this->param;
- $list = $productModel->getDealByProduct($param);
- $datas = array();
- $cycleCount = 0;
- $customerCount = 0;
- foreach ($list as $key => $value) {
- $item = array();
- //周期
- $customer_ids = $productModel->getCycleByProduct($param, $value['product_id']);
- $whereArr = array();
- $whereArr['customer_id'] = array('in', $customer_ids);
- $cycle = $biCustomerModel->getWhereByCycle($whereArr);
- $item['product_name'] = $value['product_name'];
- $item['customer_num'] = !empty($value['num']) ? (int)$value['num'] : 0;
- $item['cycle'] = !empty($cycle) ? (int)$cycle : 0;
- $datas['list'][] = $item;
-
- $cycleCount += $item['cycle'];
- $customerCount += $item['customer_num'];
- }
-
- $datas['total'] = ['product_name' => '总计', 'cycle' => $cycleCount, 'customer_num' => $customerCount];
-
- return resultArray(['data' => $datas]);
- }
-
- /**
- * 地区成交周期
- * @param
- * @return
- * @author zhi
- */
- public function addressCycle()
- {
- $userModel = new \app\admin\model\User();
- $customerModel = new \app\crm\model\Customer();
- $biCustomerModel = new \app\bi\model\Customer();
- $address_arr = \app\crm\model\Customer::$address;
- $param = $this->param;
- if (empty($param['type']) && empty($param['start_time'])) {
- $param['type'] = 'month';
- }
- $map_user_ids = [];
- if ($param['user_id']) {
- $map_user_ids = array($param['user_id']);
- } else {
- if ($param['structure_id']) {
- $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2);
- }
- }
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集
- $time = getTimeArray();
-
- $prefix = config('database.prefix');
- $sql = CustomerModel::alias('a')
- ->field([
- 'SUBSTR(`a`.`address`, 1, 2)' => 'addr',
- 'COUNT(*)' => 'customer_num',
- 'SUM(
- CASE WHEN ISNULL(b.order_date) THEN 0 ELSE (
- UNIX_TIMESTAMP(b.order_date) - a.create_time
- ) / 86400 END
- )' => 'cycle_sum'
- ])
- ->join(
- "(
- SELECT
- `customer_id`,
- MIN(`order_date`) AS `order_date`
- FROM
- `{$prefix}crm_contract`
- WHERE
- `check_status` = 2
- GROUP BY
- `customer_id`
- ) b",
- 'a.customer_id = b.customer_id',
- 'LEFT'
- )
- ->where([
- 'a.deal_status' => '已成交',
- 'a.create_time' => ['BETWEEN', $time['between']],
- 'a.owner_user_id' => ['IN', $userIds]
- ])
- ->group('addr')
- ->fetchSql()
- ->select();
- $list = queryCache($sql);
- $list = array_column($list, null, 'addr');
- $list['黑龙江'] = $list['黑龙'];
- $list['内蒙古'] = $list['内蒙'];
- $res = [];
- $cycleCount = 0;
- $customerCount = 0;
- foreach ($address_arr as $val) {
- $item['address'] = $val;
- $item['customer_num'] = !empty($list[$val]['customer_num']) ? $list[$val]['customer_num'] : 0;
- $item['cycle'] = $list[$val]['customer_num'] ? intval($list[$val]['cycle_sum'] / $list[$val]['customer_num']) : 0;
- $res['list'][] = $item;
-
- $cycleCount += $item['cycle'];
- $customerCount += $item['customer_num'];
- }
-
- $res['total'] = ['address' => '总计', 'cycle' => $cycleCount, 'customer_num' => $customerCount];
-
- return resultArray(['data' => $res]);
- }
-
- /**
- * 客户所在城市分析
- *
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function addressAnalyse()
- {
- $param = $this->param;
- // $customerModel = new \app\crm\model\Customer();
- $userModel = new \app\admin\model\User();
- $address_arr = \app\crm\model\Customer::$address;
- $map_user_ids = [];
- # 如果存在员工参数,则不再使用部门参数
- if (!empty($param['user_id'])) {
- $map_user_ids = array($param['user_id']);
- } elseif (!empty($param['structure_id'])) {
- $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2);
- }
- if (empty($map_user_ids)) return resultArray(['data' => []]);
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集
-
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
- $sql = CustomerModel::alias('a')
- ->field([
- 'SUBSTR(`address`, 1, 2)' => 'addr',
- 'COUNT(*)' => 'allCustomer',
- 'SUM(
- CASE WHEN `deal_status` = "已成交" THEN 1 ELSE 0 END
- )' => 'dealCustomer',
- ])
- ->where([
- 'create_time' => ['BETWEEN', $time['between']],
- 'owner_user_id' => ['IN', $userIds]
- ])
- ->group('addr')
- ->fetchSql()
- ->select();
- $list = queryCache($sql);
- $list = array_column($list, null, 'addr');
- $list['黑龙江'] = $list['黑龙'];
- $list['内蒙古'] = $list['内蒙'];
- $data = [];
- foreach ($address_arr as $val) {
- $item['address'] = $val;
- $item['allCustomer'] = !empty($list[$val]['allCustomer']) ? (int)$list[$val]['allCustomer'] : 0;
- $item['dealCustomer'] = !empty($list[$val]['dealCustomer']) ? (int)$list[$val]['dealCustomer'] : 0;
- $data[] = $item;
- }
- return resultArray(['data' => $data]);
- }
-
- /**
- * 客户行业/级别/来源分析
- *
- * @return \think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function portrait()
- {
- $biCustomerModel = new \app\bi\model\Customer();
- $userModel = new \app\admin\model\User();
- $adminModel = new \app\admin\model\Admin();
- $param = $this->param;
-
- $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
- $whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
- $userIds = $whereData['userIds'];
-
- if (!in_array($param['type_analyse'], ['industry', 'source', 'level'])) {
- return resultArray(['error' => '参数错误']);
- }
- $poolWhere = $this->getWhereByPool();
- $poolId = db('crm_customer')->alias('customer')->where($poolWhere)->column('customer_id');
- $whereArr = array();
- $whereArr['types'] = 'crm_customer';
- $whereArr['field'] = $param['type_analyse'];
- $setting = $biCustomerModel->getOptionByField($whereArr);
- if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
- if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
- $time = getTimeArray($param['start_time'], $param['end_time']);
- $sql = CustomerModel::field([
- "(
- CASE WHEN
- `{$param['type_analyse']}` = ''
- THEN '(空)'
- ELSE {$param['type_analyse']} END
- )" => $param['type_analyse'],
- 'COUNT(*)' => 'allCustomer',
- 'SUM(
- CASE WHEN `deal_status` = "已成交" THEN 1 ELSE 0 END
- )' => 'dealCustomer',
- ])
- ->where([
- 'create_time' => ['BETWEEN', $time['between']],
- 'owner_user_id' => ['IN', !empty($userIds) ? $userIds : '9999999999']
- ])
- ->whereNotIn('customer_id', $poolId)
- ->group($param['type_analyse'])
- ->fetchSql()
- ->select();
- $list = queryCache($sql);
- $list = array_column($list, null, $param['type_analyse']);
- $other_keys = array_diff(array_keys($list), $setting);
- $setting = array_merge($setting, $other_keys);
-
- $data = [];
- foreach ($setting as $val) {
- $item = [];
-
- $item[$param['type_analyse']] = $val;
- $item['allCustomer'] = !empty($list[$val]['allCustomer']) ? (int)$list[$val]['allCustomer'] : 0;
- $item['dealCustomer'] = !empty($list[$val]['dealCustomer']) ? (int)$list[$val]['dealCustomer'] : 0;
-
- $data[] = $item;
- }
-
- return resultArray(['data' => $data]);
- }
-
- /**
- * [客户公海条件]
- * @author Michael_xu
- * @param
- * @return
- */
- public function getWhereByPool()
- {
- $configModel = new \app\crm\model\ConfigData();
- $configInfo = $configModel->getData();
- $config = $configInfo['config'] ? : 0;
- $follow_day = $configInfo['follow_day'] ? : 0;
- $deal_day = $configInfo['deal_day'] ? : 0;
- $whereData = [];
- //启用
- if ($config == 1) {
- //默认公海条件(没有负责人或已经到期)
- $data['follow_time'] = time()-$follow_day*86400;
- $data['deal_time'] = time()-$deal_day*86400;
- $data['deal_status'] = '未成交';
- if ($follow_day < $deal_day) {
- $whereData = function($query) use ($data){
- $query->where(['customer.owner_user_id'=>0])
- ->whereOr(function ($query) use ($data) {
- $query->where(function ($query) use ($data) {
- $query->where(['customer.update_time' => array('elt',$data['follow_time'])])
- ->whereOr(['customer.deal_time' => array('elt',$data['deal_time'])]);
- })
- ->where(['customer.is_lock' => 0])
- ->where(['customer.deal_status' => ['neq','已成交']]);
- });
- };
- } else {
- $whereData = function($query) use ($data){
- $query->where(['customer.owner_user_id'=>0])
- ->whereOr(function ($query) use ($data) {
- $query->where(function ($query) use ($data) {
- $query->where(['customer.deal_time' => array('elt',$data['deal_time'])]);
- })
- ->where(['customer.is_lock' => 0])
- ->where(['customer.deal_status' => ['neq','已成交']]);
- });
- };
- }
- } else {
- $whereData['customer.owner_user_id'] = 0;
- }
- return $whereData ? : '';
- }
-
- /**
- * 员工客户满意度分析
- *
- * @param BiCustomerLogic $biCustomerLogic
- * @param string $param
- * @return array|\think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function customerSatisfaction(BiCustomerLogic $biCustomerLogic, $param='')
- {
- $param = $this->param;
-
- $param['start_time'] = !empty($param['start_time']) ? strtotime($param['start_time']) : '';
- $param['end_time'] = !empty($param['end_time']) ? strtotime($param['end_time']) : '';
-
- if (!empty($param['type'])) {
- # 日期工具类
- $timeArr = getTimeByType($param['type']);
- # 设置日期参数
- $param['start_time'] = $timeArr[0];
- $param['end_time'] = $timeArr[1];
- }
-
- $data = $biCustomerLogic->getCustomerSatisfaction($param);
- //导出使用
- if (!empty($param['excel_type'])) return $data;
- return resultArray(['data' => $data]);
- }
-
- /**
- * 产品满意度分析
- *
- * @param BiCustomerLogic $biCustomerLogic
- * @param string $param
- * @return array|\think\response\Json
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function productSatisfaction(BiCustomerLogic $biCustomerLogic, $param='')
- {
- $param = $this->param;
-
- $param['start_time'] = !empty($param['start_time']) ? strtotime($param['start_time']) : '';
- $param['end_time'] = !empty($param['end_time']) ? strtotime($param['end_time']) : '';
-
- if (!empty($param['type'])) {
- # 日期工具类
- $timeArr = getTimeByType($param['type']);
- # 设置日期参数
- $param['start_time'] = $timeArr[0];
- $param['end_time'] = $timeArr[1];
- }
-
- $data = $biCustomerLogic->getProductSatisfaction($param);
- //导出使用
- if (!empty($param['excel_type'])) return $data;
- return resultArray(['data' => $data]);
- }
-
- /**
- * 导出
- *
- * @return mixed
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function excelExport()
- {
- $param = $this->param;
- $excel_type = $param['excel_type'];
-
- $type=[];
- $type['excel_types']=$param['excel_types'];
-
- switch ($param['excel_types']) {
- case 'statistics':
-
- $list = $this->statistics($param);
-
- $list=$list['list'];
- $type['type'] = '客户总量分析列表';
- break;
- case'recordList':
- $list = $this->recordList($param);
- $list=$list['list'];
- $type['type'] = '客户跟进次数分析';
- break;
- case 'recordMode':
- $list = $this->recordMode($param);
- $type['type'] = '客户跟进方式分析';
- break;
- case 'poolList':
- $list = $this->poolList($param);
- $type['type'] = '公海客户分析';
- break;
- case 'userCycle':
- $list = $this->userCycle($param);
- $list=$list['list'];
- $type['type'] = '员工客户成交周期分析';
- break;
- case 'customerSatisfaction':
- $list = $this->customerSatisfaction($param);
- $list=$list['list'];
- $type['type'] = '员工客户满意度分析';
- break;
- case 'productSatisfaction':
- $list = $this->productSatisfaction($param);
- $list=$list['list'];
- $type['type'] = '产品满意度分析';
- break;
- }
-
- if(empty($list)){
- return resultArray(['data'=>'数据不存在']);
- }
- $excelLogic = new ExcelLogic();
- $data = $excelLogic->biexcle($type, $list);
- return $data;
- }
- }
|