<?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'] = date('y-m-d 00:00:00',$timeArr[0]);
            $param['end_time'] = date('y-m-d 23:59:59',$timeArr[1]);
        } else {
            if (!empty($param['start_time'])) $param['start_time'] = $param['start_time'] . ' 00:00:00';
            if (!empty($param['end_time']))   $param['end_time']   =$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 $result;
        }
        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;
        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()
    {
        $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 = db('crm_customer_pool_record')
//                ->field([
//                    "FROM_UNIXTIME(`create_time`, '{$time['time_format']}')" => 'time',
//                    'SUM(CASE WHEN `type` = 2 THEN 1 ELSE 0 END)' => 'put_in',
//                    'SUM(CASE WHEN `type` = 1 THEN 1 ELSE 0 END)' => 'receive'
//                ])
//                ->where([
//                    'user_id' => ['IN', !empty($userIds) ? $userIds : 0],
//                    'create_time' => ['BETWEEN', $time['between']],
//                ])
//                ->group('time')
//                ->fetchSql()
//                ->select();
        $prefix = config('database.prefix');
        $ids = !empty($userIds) ? implode(',', $userIds) : 0;
        $sql = "SELECT 
	                FROM_UNIXTIME( `create_time`, '%Y-%m' ) AS `time`, 
	                SUM( CASE WHEN `type` = 2 THEN 1 ELSE 0 END ) AS `put_in`, 
	                SUM( CASE WHEN `type` = 1 THEN 1 ELSE 0 END ) AS `receive` 
                FROM 
                    (SELECT * FROM `".$prefix."crm_customer_pool_record` GROUP BY `customer_id`, `type`) AS `record` 
                WHERE 
	                `user_id` IN ( ".$ids." ) AND `create_time` BETWEEN ".$time['between'][0]." AND ".$time['between'][1]." 
                GROUP BY `time`";
        $res = queryCache($sql);
        $res = array_column($res, null, 'time');

        $result = [];
        foreach ($time['list'] AS $key => $value) {
            $result[] = [
                'type'       => $value['type'],
                'start_time' => $value['start_time'],
                'end_time'   => $value['end_time'],
                'put_in'     => !empty($res[$value['type']]['put_in'])  ? (int)$res[$value['type']]['put_in']  : 0,
                'receive'    => !empty($res[$value['type']]['receive']) ? (int)$res[$value['type']]['receive'] : 0
            ];
        }

        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 poolList($param='')
    {
        $userModel = new \app\admin\model\User();
        $actionRecordModel = new \app\bi\model\ActionRecord();
        $CustomerModel = new \app\crm\model\Customer();
        $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 = db('crm_customer_pool_record')
//            ->field([
//                'user_id',
//                'SUM(CASE WHEN `type` = 2 THEN 1 ELSE 0 END)' => 'put_in',
//                'SUM(CASE WHEN `type` = 1 THEN 1 ELSE 0 END)' => 'receive'
//            ])
//            ->group('user_id')
//            ->where([
//                'create_time' => ['BETWEEN', $between_time],
//                'user_id' => ['IN', !empty($userIds) ? $userIds : 0]
//            ])
//            ->fetchSql()
//            ->select();
        $prefix = config('database.prefix');
        $ids = !empty($userIds) ? implode(',', $userIds) : 0;
        $sql = "SELECT 
	                `user_id`, 
	                SUM( CASE WHEN `type` = 2 THEN 1 ELSE 0 END ) AS `put_in`, 
	                SUM( CASE WHEN `type` = 1 THEN 1 ELSE 0 END ) AS `receive` 
                FROM 
	                (SELECT * FROM `".$prefix."crm_customer_pool_record` GROUP BY `customer_id`, `type`) AS `record` 
                WHERE 
	                `create_time` BETWEEN ".$between_time[0]." AND ".$between_time[1]." AND `user_id` IN ( ".$ids." ) 
                GROUP BY `user_id`";
        $poolRecord = queryCache($sql);
        $recordData = [];
        foreach ($poolRecord AS $key => $value) {
            $recordData[$value['user_id']] = [
                'put_in' => $value['put_in'],
                'receive' => $value['receive']
            ];
        }
//        $action_record_list = array_column($action_record_list, null, 'user_id');

        # 部门列表
        $structureData = [];
        $structureList = db('admin_structure')->select();
        foreach ($structureList AS $key => $value) {
            $structureData[$value['id']] = $value['name'];
        }

        # 员工列表
        $userList = db('admin_user')->field(['id', 'realname', 'structure_id'])->whereIn('id', $userIds)->select();

        $res = [];
        $receiveCount = 0; # 领取公海客户总数
        $putInCount = 0; # 进入公海客户总数
        foreach ($userList as $val) {
            $item['put'] = !empty($recordData[$val['id']]['put_in']) ? (int)$recordData[$val['id']]['put_in'] : 0;
            $item['put_in'] = !empty($recordData[$val['id']]['put_in']) ? (int)$recordData[$val['id']]['put_in'] : 0;
            $item['receive'] = !empty($recordData[$val['id']]['receive']) ? (int)$recordData[$val['id']]['receive'] : 0;
            $item['customer_num'] = 0;
            $item['realname'] = $val['realname'];
            $item['username'] = !empty($structureData[$val['structure_id']]) ? $structureData[$val['structure_id']] : '';
            $res[] = $item;

            $receiveCount += $item['receive'];
            $putInCount += $item['put_in'];
        }
//        foreach ($userIds as $val) {
//            $item['put'] = !empty($customer_list[$val]['put_in'])?(int)$customer_list[$val]['put_in']:0;
//            $item['put_in'] = !empty($customer_list[$val]['put_in']) ?  $item['put'] : (int)$action_record_list[$val]['put_in'] + $item['put'];
//            $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($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']);

        $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;
        return resultArray(['data' => $datas]);
    }

    /**
     * 产品成交周期
     * @param
     * @return
     * @author zhi
     */
    public function productCycle()
    {
        $biCustomerModel = new \app\bi\model\Customer();
        $productModel = new \app\bi\model\Product();
        if($param['excel_type']!=1){
            $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];
        //导出使用
        if (!empty($param['excel_type'])) return $datas;
        return resultArray(['data' => $datas]);
    }

    /**
     * 地区成交周期
     * @param
     * @return
     * @author zhi
     */
    public function addressCycle($param='')
    {
        $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;
        if($param['excel_type']!=1){
            $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];
        //导出使用
        
        if (!empty($param['excel_type'])) return $res;
        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='')
    {
        if($param['excel_type']!=1){
            $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;
        }
        //导出使用
        if (!empty($param['excel_type'])) return $res;
        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($param='')
    {
        $adminModel      = new \app\admin\model\Admin();
        $userModel = new \app\admin\model\User();
        $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']);
            # 设置日期参数pool
            $param['start_time'] = $timeArr[0];
            $param['end_time']   = $timeArr[1];
        }
        $biCustomerLogic=new BiCustomerLogic();
        $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($param='')
    {
        $param = $this->param;
        $userInfo=$this->userInfo;
        $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];
        }
    
        $biCustomerLogic= new BiCustomerLogic();
        $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);
                $list=$list['list'];
                $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);
                $type['type'] = '员工客户满意度分析';
                break;
            case 'productSatisfaction':
                $list = $this->productSatisfaction($param);
                $type['type'] = '产品满意度分析';
                break;
            case 'userCycleList':
                $list = $this->userCycleList($param);
                $list=$list['list'];
                $type['type'] = '成交周期';
                break;
            case 'productCycle':
                $list = $this->addressCycle($param);
               
                $list=$list['list'];
                $type['type'] = '地区成交周期';
                break;
            case 'addressCycle':
                $list = $this->productCycle($param);
                $list=$list['list'];
                $type['type'] = '地区成交周期';
                break;
        }

        if(empty($list)){
            return resultArray(['data'=>'数据不存在']);
        }
        $excelLogic = new ExcelLogic();
        $data = $excelLogic->biexcle($type, $list);
        return $data;
    }
}