You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wkcrm/application/bi/model/Customer.php

435 lines
16 KiB

4 years ago
<?php
// +----------------------------------------------------------------------
// | Description: 客户
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class Customer extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'crm_customer';
/**
* 获取转化客户信息
*
* @param $where
* @param string $sortField
* @param string $sortValue
* @return array
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
function getWhereByList($where, $sortField = '', $sortValue = '')
{
if (!empty($sortField) && $sortField == 'name') $sortField = 'a.customer_id';
if (!empty($sortField) && $sortField == 'contract_name') $sortField = 'b.name';
if (!empty($sortField) && $sortField == 'r_money') $sortField = 'r_money';
if (!empty($sortField) && $sortField == 'owner_realname') $sortField = 'a.owner_user_id';
if (!empty($sortField) && $sortField == 'create_time') $sortField = 'b.create_time';
if (!empty($sortField) && $sortField == 'order_time') $sortField = 'b.order_date';
if (empty($sortField)) $sortField = 'r_money';
if (empty($sortValue)) $sortValue = 'desc';
$userModel = new \app\admin\model\User();
$prefix = config('database.prefix');
$count = $this->alias('a')->join(
"(
SELECT
`contract_id`,
`customer_id`,
`name`,
`money`,
`create_time`,
`order_date`
FROM
{$prefix}crm_contract
WHERE
`contract_id` IN (
SELECT
MIN(`contract_id`) as `contract_id`
FROM
`{$prefix}crm_contract`
WHERE
`create_time` > 1572537600
AND `check_status` = 2
GROUP BY
`customer_id`
)
) b",
'b.customer_id = a.customer_id',
'LEFT'
)->join(
"(
SELECT
`contract_id`,
SUM(`money`) AS `r_money`
FROM
`{$prefix}crm_receivables`
GROUP BY
`contract_id`
) c",
'c.contract_id = b.contract_id',
'LEFT'
)->where([
'a.create_time' => $where['create_time'],
'a.owner_user_id' => $where['owner_user_id'],
'a.deal_status' => $where['deal_status'],
'b.money' => ['gt', 0]
])->count();
$sql = $this->alias('a')
->field([
'a.customer_id',
'a.name',
'a.owner_user_id',
'a.create_user_id',
'a.industry',
'a.source',
'a.create_time',
'b.name' => 'contract_name',
'b.money' => 'contract_money',
'b.order_date' => 'order_time',
'b.contract_id' => 'contract_id',
'c.r_money'
])
->join(
"(
SELECT
`contract_id`,
`customer_id`,
`name`,
`money`,
`create_time`,
`order_date`
FROM
{$prefix}crm_contract
WHERE
`contract_id` IN (
SELECT
MIN(`contract_id`) as `contract_id`
FROM
`{$prefix}crm_contract`
WHERE
`create_time` > 1572537600
AND `check_status` = 2
GROUP BY
`customer_id`
)
) b",
'b.customer_id = a.customer_id',
'LEFT'
)
->join(
"(
SELECT
`contract_id`,
SUM(`money`) AS `r_money`
FROM
`{$prefix}crm_receivables`
GROUP BY
`contract_id`
) c",
'c.contract_id = b.contract_id',
'LEFT'
)
->where([
'a.create_time' => $where['create_time'],
'a.owner_user_id' => $where['owner_user_id'],
'a.deal_status' => $where['deal_status'],
'b.money' => ['gt', 0]
])
->fetchSql()
->order($sortField, $sortValue)
->limit(15)
->select();
$list = queryCache($sql);
foreach ($list as &$val) {
$val['create_time'] = date('Y-m-d',$val['create_time']);
$owner_user = $userModel->getUserById($val['owner_user_id']);
$val['owner_realname'] = $owner_user['realname'];
$create_user = $userModel->getUserById($val['create_user_id']);
$val['create_realname'] = $create_user['realname'];
}
return ['dataCount' => $count, 'list' => $list];
}
/**
* 根据条件获取开始、结束时间
* @author zhi
* @param $type
* @param $year
* @param $i
* @return
*/
function getStartAndEnd($param,$year,$i)
{
$timeArr = array();
switch($param['type']) {
case 'year'://本年度
case 'lastYear'://上年度
$type = $year.'-'.$i;
$whereTime = $this->getMonthArray(strtotime($type.'-01'));
break;
case 'quarter'://本季度
$timeType = getTimeByType($param['type']);
$month = date('m',$timeType[0]);
if ($month+$i <= 13) {
$type = $year.'-'.($month+$i-1);
} else {
$type = ($year+1).'-'.'01';
}
$whereTime = $this->getMonthArray(strtotime($type.'-01'));
break;
case 'lastQuarter'://上季度
$timeType = getTimeByType($param['type']);
$month = date('m',$timeType[0]);
$type = $year.'-'.($month+$i-1);
$whereTime = $this->getMonthArray(strtotime($type.'-01'));
break;
case 'month'://本月
$type = $year.'-'.date('m').'-'.$i;
$dateArr = getDateRange(strtotime($type));
$whereTime = [$dateArr['sdate'],$dateArr['edate']];
break;
case 'lastMonth'://上月
$timeType = getTimeByType($param['type']);
$type = date('Y-m',$timeType['0']).'-'.$i;
$dateArr = getDateRange(strtotime($type));
$whereTime = [$dateArr['sdate'],$dateArr['edate']];
break;
case 'week'://本周
case 'lastWeek'://上周
$timeType = getTimeByType($param['type']);
$type = date('Y-m-d',$timeType['0']+($i-1)*86400);
$dateArr = getDateRange(strtotime($type));
$whereTime = [$dateArr['sdate'],$dateArr['edate']];
break;
case 'today'://今天
case 'yesterday'://昨天
$whereTime = getTimeByType($param['type']);
$type = date('Y-m-d',$whereTime[0]);
break;
default ://自定义时间
$subDay = ceil(($param['end_time']-$param['start_time'])/86400);
if ($subDay > 31) {
$param['type'] = 'year';
$res = $this->getStartAndEnd($param,$year,$i);
$whereTime[0] = $res['start_time'];
$whereTime[1] = $res['end_time'];
$type = $res['type'];
} else {
$type = date('Y-m-d',$param['start_time']+($i-1)*86400);
$dateArr = getDateRange(strtotime($type));
$whereTime = [$dateArr['sdate'],$dateArr['edate']];
}
break;
}
$timeArr['start_time'] = $whereTime[0];
$timeArr['end_time'] = $whereTime[1];
$timeArr['type'] = $type;
return $timeArr;
}
/**
* 根据条件获取单位
* @author zhi
* @param
* @return
*/
function getParamByCompany($param)
{
$company['year'] = date('Y');
$company['month'] = date('m');
switch($param['type']) {
case 'year'://本年度
$company['j'] = 12;
break;
case 'lastYear'://上年度
$company['j'] = 12;
$company['year'] = date('Y')-1;
break;
case 'quarter'://本季度
$company['j'] = 3;
break;
case 'lastQuarter'://上季度
$company['j'] = 3;
break;
case 'month'://本月
$company['j'] = date("t");
break;
case 'lastMonth'://上月
if (date('m') == 1) {
$m = 12;
} else {
$m = date('m')-1;
}
$days = date('t', strtotime(date('Y').'-'.$m.'-1'));
$company['j'] = $days;
break;
case 'week'://本周
$company['j'] = 7;
break;
case 'lastWeek'://上周
$company['j'] = 7;
break;
case 'today'://今天
$company['j'] = 1;
break;
case 'yesterday'://昨天
$company['j'] = 1;
break;
default ://自定义时间
$whereTime[0] = $param['start_time'];
$whereTime[1] = $param['end_time'];
$subDay = ceil(($param['end_time']-$param['start_time'])/86400);
if ($subDay > 31) {
$company['j'] = 12;
} else {
$company['j'] = $subDay;
}
break;
}
return $company;
}
function getMonthNum($start_m, $end_m){
$date1 = explode('-',$start_m);
$date2 = explode('-',$end_m);
if ($date1[1] < $date2[1]) { //判断月份大小,进行相应加或减
$month_number= abs($date1[0] - $date2[0]) * 12 + abs($date1[1] - $date2[1]);
} else {
$month_number= abs($date1[0] - $date2[0]) * 12 - abs($date1[1] - $date2[1]);
}
return $month_number;
}
/**
* 根据数据获取查询条件
* @author zhi
* @param
* @return
*/
function getParamByWhere($param,$type='')
{
$userModel = new \app\admin\model\User();
$whereArr = array();
if (empty($param['type']) && empty($param['start_time'])) {
$param['type'] = 'month';
}
//时间戳:客户跟进分析 、客户转化率分析
if (!empty($param['start_time'])) {
$whereArr['create_time'] = array('between',array($param['start_time'],$param['end_time']));
} else {
$create_time = getTimeByType($param['type']);
if ($create_time) {
$whereArr['create_time'] = array('between',array($create_time[0],$create_time[1]));
}
}
$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; //数组交集
if ($type && $type == 'record') {
$whereArr['create_user_id'] = array('in',$userIds);
} else {
$whereArr['owner_user_id'] = array('in',$userIds);
}
return $whereArr;
}
/**
* 根据自定义字段获取 下拉框数据
* @author zhi
* @param
* @return
*/
function getOptionByField($whereArr)
{
$setting = db('admin_field')->where($whereArr)->field('setting')->find();
return explode(chr(10),$setting['setting']);
}
/**
* 根据新增客户数排序
* @author zhi
* @param
* @return
*/
function getSortByCount($whereArr)
{
$count = db('crm_customer')->group('owner_user_id')->field('owner_user_id,count(customer_id) as count')->order('count desc')->where($whereArr)->select();
return $count;
}
/**
* 获取成交周期
* @author zhi
* @param
* @return
*/
function getWhereByCycle($whereArr)
{
$customerList = db('crm_customer')->field('customer_id,create_time,deal_time')->where($whereArr)->select();
//首次成交
if (!empty($customerList)) {
$cycle_num = 0;
$customer_num = 0;
foreach ($customerList as $key => $value) {
$cycle_time = 0;
$where = array();
$where['customer_id'] = $value['customer_id'];
$create_time = $value['create_time'];
$where['check_status'] = 2;
$contractInfo = db('crm_contract')->where($where)->field('order_date,create_time')->order('order_date asc')->find();
if ($contractInfo['order_date']) {
$cycle_time = ceil((strtotime($order_date)-$create_time)/86400);
} else {
$cycle_time = ceil(($value['deal_time']-$create_time)/86400);
}
if ($cycle_time > 0) {
$cycle_num += $cycle_time;
$customer_num ++;
}
}
if ($cycle_num == 0 || $customer_num == 0) {
$cycle = 0;
} else {
$cycle = ceil($cycle_num/$customer_num);
}
}
return $cycle;
}
/**
* 根据时间获取该时间所在月份开始结束时间
* @author zhi
* @param
* @return
*/
public function getMonthArray($time)
{
$start_time = strtotime(date('Y-m-01',$time));
$monthDay = getmonthdays($time);
$end_time = strtotime(date('Y-m-'.$monthDay,$time))+86399;
return array($start_time,$end_time);
}
}