|
@@ -243,6 +243,7 @@ class Crm extends Base
|
|
} else {
|
|
} else {
|
|
$model = Customer::where($condition);
|
|
$model = Customer::where($condition);
|
|
}
|
|
}
|
|
|
|
+
|
|
// or 条件处理
|
|
// or 条件处理
|
|
foreach ($whereOr as $v) {
|
|
foreach ($whereOr as $v) {
|
|
$model = $model->where(function($query) use ($v){
|
|
$model = $model->where(function($query) use ($v){
|
|
@@ -574,114 +575,6 @@ class Crm extends Base
|
|
return json(['code' => 0, 'data' => $row, 'msg' => '操作成功']);
|
|
return json(['code' => 0, 'data' => $row, 'msg' => '操作成功']);
|
|
}
|
|
}
|
|
|
|
|
|
- public function test(){
|
|
|
|
- // $aw[] = ['id', 'in', array_keys($cidList)];
|
|
|
|
- // array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', ' chaos'))
|
|
|
|
- $where = [
|
|
|
|
- ['state', 'not in', Customer::changeState('无效', 'chaos')],
|
|
|
|
- ['died', '<>', 2]
|
|
|
|
- ];
|
|
|
|
- $month = request()->param('month');
|
|
|
|
- if (isset($month)){
|
|
|
|
- // 获取当前年份,或者你也可以从 GET 参数中获取年份
|
|
|
|
- $year = date('Y'); // 你可以修改为 $_GET['year'] 如果你有年份参数
|
|
|
|
- // 创建 DateTime 对象表示该月的第一天
|
|
|
|
- $firstDayOfMonth = \DateTime::createFromFormat('!Y-m-d', "$year-$month-01");
|
|
|
|
- // 获取该月第一天的时间戳
|
|
|
|
- $startTimeStamp = $firstDayOfMonth->getTimestamp();
|
|
|
|
- // 克隆 DateTime 对象并修改到下个月的第一天,然后减去一秒得到该月的最后一天的时间戳
|
|
|
|
- $lastDayOfMonth = clone $firstDayOfMonth;
|
|
|
|
- $lastDayOfMonth->modify('+1 month -1 second');
|
|
|
|
- $endTimeStamp = $lastDayOfMonth->getTimestamp();
|
|
|
|
- // 输出开始时间和结束时间戳
|
|
|
|
- echo "Start Timestamp: $startTimeStamp\n";
|
|
|
|
- echo "End Timestamp: $endTimeStamp\n";
|
|
|
|
- $startdate = strtotime($startTimeStamp);
|
|
|
|
- $enddate = strtotime($endTimeStamp);
|
|
|
|
- $start_time = date('Y-m-d H:i:s', $startdate);
|
|
|
|
- $end_time = date('Y-m-d H:i:s', $enddate + 86400);
|
|
|
|
- $where[] = ['addtime', '>=', $start_time];
|
|
|
|
- $where[] = ['addtime', '<', $end_time];
|
|
|
|
- }
|
|
|
|
- $count = Customer::where($where)->count();
|
|
|
|
- if ($count == 0) {
|
|
|
|
- return json(['code' => 1, 'msg' => '没有可导出的数据']);
|
|
|
|
- }
|
|
|
|
- $res = Customer::with(['User', 'employee', 'org'])
|
|
|
|
- ->where($where)
|
|
|
|
- ->order('revisit_time desc,id desc')
|
|
|
|
- ->visible(['id', 'state', 'revisit_time', 'name', 'User.headimgurl', 'sex', 'community_name', 'level', 'phone','employee.name', 'employee_id', 'org_name']
|
|
|
|
- )->order('id desc')
|
|
|
|
- ->select()
|
|
|
|
- ->toArray();
|
|
|
|
- echo Customer::getLastSql();
|
|
|
|
- $new = [];
|
|
|
|
- // foreach ($res as $key => $val) {
|
|
|
|
- // $new[] = [
|
|
|
|
- // 'name' => $val['name'],
|
|
|
|
- // 'phone' => $val['phone'],
|
|
|
|
- // 'community_name' => $val['community_name'],
|
|
|
|
- // ];
|
|
|
|
- // }
|
|
|
|
-
|
|
|
|
- $header = [
|
|
|
|
- "A1" => "客户姓名",
|
|
|
|
- "B1" => "手机号",
|
|
|
|
- "C1" => "小区名称",
|
|
|
|
- "D1" => "所属员工",
|
|
|
|
- "E1" => "客户等级",
|
|
|
|
- "F1" => '来源渠道',
|
|
|
|
- "G1" => '面积',
|
|
|
|
- "H1" => '设计师',
|
|
|
|
- "I1" => '交房时间',
|
|
|
|
- "J1" => '注销时间',
|
|
|
|
- "K1" => '报备时间',
|
|
|
|
- "L1" => '状态',
|
|
|
|
- "M1" => '首次到店'];
|
|
|
|
- $fileName = date('Y-m-d H:i:s') . $month ? $month.'月': ''.'无效客户';
|
|
|
|
- return json(['code' => 0, 'data' => $res, 'count' => $count]);
|
|
|
|
- // $this->getExport($header, true, $new, $fileName);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 导出
|
|
|
|
- public function getExport($header = [], $type = false, $data = [], $fileName)
|
|
|
|
- {
|
|
|
|
- // 实例化类
|
|
|
|
- $preadsheet = new Spreadsheet();
|
|
|
|
- // 创建sheet
|
|
|
|
- $sheet = $preadsheet->getActiveSheet();
|
|
|
|
- // 循环设置表头数据
|
|
|
|
- foreach ($header as $k => $v) {
|
|
|
|
- $sheet->setCellValue($k, $v);
|
|
|
|
- }
|
|
|
|
- // 生成数据
|
|
|
|
- $sheet->fromArray($data, null, "A2");
|
|
|
|
- // 样式设置
|
|
|
|
- $sheet->getDefaultColumnDimension()->setWidth(12);
|
|
|
|
-
|
|
|
|
- // 设置下载与后缀
|
|
|
|
- if ($type) {
|
|
|
|
- header("Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
- $type = "Xlsx";
|
|
|
|
- $suffix = "xlsx";
|
|
|
|
- } else {
|
|
|
|
- header("Content-Type:application/vnd.ms-excel");
|
|
|
|
- $type = "Xls";
|
|
|
|
- $suffix = "xls";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ob_end_clean(); //清楚缓存区
|
|
|
|
- // 激活浏览器窗口
|
|
|
|
- header("Content-Disposition:attachment;filename=$fileName.$suffix");
|
|
|
|
- //缓存控制
|
|
|
|
- header("Cache-Control:max-age=0");
|
|
|
|
- // 调用方法执行下载
|
|
|
|
- $writer = IOFactory::createWriter($preadsheet, $type);
|
|
|
|
- // 数据流
|
|
|
|
- $writer->save("php://output");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 客户线索
|
|
* 客户线索
|
|
*/
|
|
*/
|
|
@@ -744,6 +637,646 @@ class Crm extends Base
|
|
$count = ClueLogic::count($condition);
|
|
$count = ClueLogic::count($condition);
|
|
return json(['code' => 0, 'data' => $data, 'count' => $count]);
|
|
return json(['code' => 0, 'data' => $data, 'count' => $count]);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public function test(){
|
|
|
|
+ // $aw[] = ['id', 'in', array_keys($cidList)];
|
|
|
|
+ // array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos'))
|
|
|
|
+ $type = input('type', '', 'intval');
|
|
|
|
+ $protected = input('protected', '', 'intval');
|
|
|
|
+
|
|
|
|
+ $request = request();
|
|
|
|
+ if (!$request->isAjax()) {
|
|
|
|
+ $type = input('type', '', 'intval');
|
|
|
|
+ $protected = input('protected', '', 'intval');
|
|
|
|
+ $request = request();
|
|
|
|
+ if (!$request->isAjax()) {
|
|
|
|
+ // 部门
|
|
|
|
+ $org = OrgLogic::struc($request->employee->root_id);
|
|
|
|
+ View::assign('org', $org);
|
|
|
|
+ $orgids = orgSubIds(request()->employee->root_id);
|
|
|
|
+ View::assign('orgids', json_encode($orgids));
|
|
|
|
+ View::assign('empid', $request->employee->id);
|
|
|
|
+ // View::assign('manager', $request->employee->is_manager);
|
|
|
|
+ View::assign('type', $type);
|
|
|
|
+ View::assign('protected', $protected);
|
|
|
|
+
|
|
|
|
+ $source = CustomerSource::where('root_id', '=', request()->employee->root_id)->select()->toArray();
|
|
|
|
+ View::assign('source', $source);
|
|
|
|
+
|
|
|
|
+ //设计师获取
|
|
|
|
+ $w[] = ['path', 'like', request()->employee->root_id . '-%'];
|
|
|
|
+ $w[] = ['org_type', '=', 2];
|
|
|
|
+ $orgs = Org::where($w)->column('id');
|
|
|
|
+ $designer = Employee::where([['org_id', 'in', $orgs], ['state', '=', '在职'], ['show', '=', 0]])->field('id,name,initials s')->order('s asc')->select()->toArray();
|
|
|
|
+ View::assign('designer', $designer);
|
|
|
|
+
|
|
|
|
+ //小区名称获取
|
|
|
|
+ /*$communities = Community::where('root_id', '=', request()->employee->root_id)->where([['type', '=', 0]])->order('pinyin asc')->select()->toArray();
|
|
|
|
+ if (!empty($communities)) {
|
|
|
|
+ $communities = hanziheadstr($communities);
|
|
|
|
+ }
|
|
|
|
+ View::assign('communityList', $communities);*/
|
|
|
|
+ $xinjushang = 0;
|
|
|
|
+ View::assign('xinjushang', $xinjushang);
|
|
|
|
+
|
|
|
|
+ return View::fetch();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $param = $request->only(['page', 'limit', 'order', 'org','died_time', 'emp_id', 'state','died', 'protected', 'type', 'time', 'followed_time', 'protected_time', 'square_start', 'square_end', 'source', 'designer', 'customer_type', 'community', 'level', 'name'=> '', 'phone'=> '', 'no_visit_time'=> '']);
|
|
|
|
+ $root_id = request()->employee->root_id;
|
|
|
|
+ $subOrg = orgSubIds($root_id);
|
|
|
|
+ if (!empty($param['org']) && in_array($param['org'], $subOrg)) {
|
|
|
|
+ $orgids = orgSubIds($param['org']);
|
|
|
|
+ } else {
|
|
|
|
+ $orgids = orgSubIds(request()->employee->root_id);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['protected'])) {
|
|
|
|
+ $org_employee = Employee::where('org_id', 'in', $orgids)->column('id');
|
|
|
|
+ $condition[] = ['employee_id', 'in', $org_employee];
|
|
|
|
+ } else {
|
|
|
|
+ $condition = [['org_id', 'in', $orgids]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $order = isset($param['order']) ? $param['order'] : 'id desc';
|
|
|
|
+ $cids = [];
|
|
|
|
+ // $condition[] = ['employee_id', 'not null', ''];
|
|
|
|
+ if (!empty($param['time'])) {
|
|
|
|
+ //录入时间
|
|
|
|
+ $addtimeArr = explode(' - ', $param['time']);
|
|
|
|
+ $start = $addtimeArr[0];
|
|
|
|
+ $end = date('Y-m-d', strtotime($addtimeArr[1]) + 86400);
|
|
|
|
+ $condition[] = ['addtime', '>=', $start];
|
|
|
|
+ $condition[] = ['addtime', '<', $end];
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['followed_time'])) $condition[] = ['last_contact_date', 'between', explode(' - ', $param['followed_time'])];
|
|
|
|
+
|
|
|
|
+ if (!empty($param['died_time'])) {
|
|
|
|
+ list($startDate, $endDate) = explode(' - ', $param['died_time']);
|
|
|
|
+ $endTime = date('Y-m-d', strtotime($endDate) + 86400);
|
|
|
|
+ $condition[] = ['died_date', '>=', $startDate . ' 00:00:00'];
|
|
|
|
+ $condition[] = ['died_date', '<', $endTime . ' 00:00:00'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['protected_time']) && !empty($param['protected'])) $condition[] = ['protected_to', 'between', explode(' - ', $param['protected_time'])];
|
|
|
|
+
|
|
|
|
+ $whereRaw = [];
|
|
|
|
+ if (!empty($param['square_start'])) {
|
|
|
|
+ $whereRaw[] = "square +0 >=" . $param['square_start'];
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['square_end'])) {
|
|
|
|
+ $whereRaw[] = "square +0 <=" . $param['square_end'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['source'])) {
|
|
|
|
+ if ($param['source'] == -1) {
|
|
|
|
+ $condition[] = ['source_id', '=', null];
|
|
|
|
+ } else {
|
|
|
|
+ $condition[] = ['source_id', '=', $param['source']];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['designer'])) $condition[] = ['designer_id', '=', $param['designer']];
|
|
|
|
+ if (!empty($param['customer_type'])) {
|
|
|
|
+ switch ($param['customer_type']) {
|
|
|
|
+ case 1:
|
|
|
|
+ $condition[] = ['crm_res_id', '>', 0];
|
|
|
|
+ $condition[] = ['remark', '<>', '公海获取'];
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ $condition[] = ['remark', '=', '活动报名建档'];
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ $condition[] = ['agents_id', '>', 0];
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ $condition[] = ['crm_res_id', 'NULL', null];
|
|
|
|
+ $condition[] = ['remark', '<>', '活动报名建档'];
|
|
|
|
+ $condition[] = ['agents_id', 'NULL', null];
|
|
|
|
+ break;
|
|
|
|
+ case 5:
|
|
|
|
+ $condition[] = ['remark', '=', '公海获取'];
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['community'])) $condition[] = ['community_name', 'like', '%' . $param['community'] . '%'];
|
|
|
|
+ if (!empty($param['level'])) $condition[] = ['level', '=', $param['level']];
|
|
|
|
+ if (!empty($param['name'])) $condition[] = ['name', 'like', '%' . $param['name'] . '%'];
|
|
|
|
+ if (!empty($param['phone'])){
|
|
|
|
+ $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
|
|
|
|
+ $value = $aec->encrypt($param['phone']);
|
|
|
|
+ $condition[] = ['phone', '=', $value];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['no_visit_time'])){
|
|
|
|
+ switch ((int)$param['no_visit_time']) {
|
|
|
|
+ case 3:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d'));
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 2*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 7:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 2*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 6*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 15:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 6*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 14*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 30:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 14*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 29*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 31:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 30*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ setCondition($param, ['emp_id', 'employee_id'], '=', $condition);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $whereOr = []; //or条件二维数据
|
|
|
|
+ if (empty($param['state'])) {
|
|
|
|
+ if (empty($param['died_time']) && empty($param['followed_time']) ){
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ $whereOr[] = [['died','=',2]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['followed_time']) ){
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['died_time'])){
|
|
|
|
+ $whereOr[] = [['died','=',2]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //2023-02-07 客户有效状态 为排除待确认和无效, 或者 待确认并且不是资源库过来的
|
|
|
|
+ // $state1 = Customer::changeState('待确认', 'chaos');
|
|
|
|
+ // $state1 = [];
|
|
|
|
+ // $state2 = Customer::changeState('无效', 'chaos');
|
|
|
|
+ // $whereOr[] = [['state', 'not in', array_merge($state1,$state2)], [['state', 'in',$state1],['crm_res_id','NULL',NULL]],[['state', 'in',$state1],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]];
|
|
|
|
+ } elseif ($param['state'] == '待确认') {
|
|
|
|
+ $state1 = Customer::changeState('待确认', 'chaos');
|
|
|
|
+ //$condition[] = ['crm_res_id', 'NULL', NULL];
|
|
|
|
+ //$condition[] = ['state', 'in', $state1];
|
|
|
|
+ $whereOr[] = [[['state', 'in', $state1],['crm_res_id','NULL',NULL]],[['state', 'in',$state1],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]];
|
|
|
|
+ } elseif ($param['state'] == '有效'){
|
|
|
|
+ $condition[] = ['state','not in',Customer::changeState('待确认','chaos')];
|
|
|
|
+ }elseif ($param['state'] == '无效'){
|
|
|
|
+ $condition[] = ['state','in',Customer::changeState('无效','chaos')];
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // die;
|
|
|
|
+ } elseif ($param['state'] == '死单'){
|
|
|
|
+ $condition[] = ['died', '=', 2];
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // die;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $where_raw = implode(' and ', $whereRaw);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // print_r($whereOr);
|
|
|
|
+ // print_r($where_raw);
|
|
|
|
+ // die;
|
|
|
|
+ if (!empty($param['died_time'])) {
|
|
|
|
+ $condition[] = ['died', '=', 2];
|
|
|
|
+ $whereOr = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['followed_time'])) {
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ $whereOr = [];
|
|
|
|
+ }
|
|
|
|
+ //保护期筛选判断
|
|
|
|
+ if ($where_raw) {
|
|
|
|
+ $model = Customer::where($condition)->whereRaw($where_raw);
|
|
|
|
+ } else {
|
|
|
|
+ $model = Customer::where($condition)->whereOr($whereOr);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $c_model = $model;
|
|
|
|
+
|
|
|
|
+ $data = $c_model->with(['employee', 'org', 'designer', 'source', 'visitLog' => function ($query) {
|
|
|
|
+ $query->field('id,customer_id,state')->group('state,customer_id');
|
|
|
|
+ }])->withCount(['visitLog' => function ($query) {
|
|
|
|
+ $query->where(function ($query) {
|
|
|
|
+ $query->whereOr([[CustomerVisitLog::changeState(['state', '=', '预约量房'])], [CustomerVisitLog::changeState(['state', '=', '预约到店'])], [CustomerVisitLog::changeState(['state', '=', '预约活动'])]]);
|
|
|
|
+ });
|
|
|
|
+ }])->withCount(['activityFrequency' => function ($query) {
|
|
|
|
+ $query->where([CustomerVisitLog::changeState(['state', '=', '确认到场'])]);
|
|
|
|
+ }])->page($param['page'], $param['limit'])
|
|
|
|
+ ->order($order)
|
|
|
|
+ ->select()
|
|
|
|
+ ->visible(['id', 'employee_id', 'name', 'died_date','community_name', 'phone', 'level', 'state', 'square', 'revisit_time', 'addtime', 'last_contact_date', 'org_id', 'protected_to', 'is_resource', 'employee.name', 'org_name', 'designer.name', 'visit_log_count', 'activity_frequency_count', 'source_id', 'source.source', 'phone1', 'phone2', 'crm_res_id', 'remark', 'agents_id'])
|
|
|
|
+ ->toArray();
|
|
|
|
+
|
|
|
|
+ foreach ($data as $k => $v) {
|
|
|
|
+ if ($v['remark'] == '公海获取') {
|
|
|
|
+ $customer_type = '公海获取';
|
|
|
|
+ } elseif ($v['agents_id']) {
|
|
|
|
+ $customer_type = '装修推荐官';
|
|
|
|
+ } elseif ($v['remark'] == '活动报名建档') {
|
|
|
|
+ $customer_type = '活动报名';
|
|
|
|
+ } elseif ($v['crm_res_id']) {
|
|
|
|
+ $customer_type = '资源库';
|
|
|
|
+ } else {
|
|
|
|
+ $customer_type = '自建';
|
|
|
|
+ }
|
|
|
|
+ $data[$k]['customer_type'] = $customer_type;
|
|
|
|
+ if ($data[$k]['state'] == '已签单') {
|
|
|
|
+ $data[$k]['state'] = '已转单';
|
|
|
|
+ }
|
|
|
|
+ if ($data[$k]['state'] == '已交定') {
|
|
|
|
+ $data[$k]['state'] = '已签单';
|
|
|
|
+ }
|
|
|
|
+ $data[$k]['phone'] = $v['phone'];
|
|
|
|
+ $data[$k]['phone1'] = $v['phone1'] ;
|
|
|
|
+ $data[$k]['phone2'] = $v['phone2'];
|
|
|
|
+ //处理历史记录
|
|
|
|
+ $allstate = '';
|
|
|
|
+ foreach ($v['visitLog'] as $m => $p) {
|
|
|
|
+ if ($p['state'] == '已签单') {
|
|
|
|
+ $p['state'] = '已转单';
|
|
|
|
+ }
|
|
|
|
+ if ($p['state'] == '已交定') {
|
|
|
|
+ $p['state'] = '已签单';
|
|
|
|
+ }
|
|
|
|
+ if ($p['state'] == '回访') {
|
|
|
|
+ $p['state'] = '待确认';
|
|
|
|
+ }
|
|
|
|
+ $allstate .= $p['state'] . ',';
|
|
|
|
+ }
|
|
|
|
+ $data[$k]['allstate'] = trim($allstate, ',');
|
|
|
|
+ //增加跟进次数
|
|
|
|
+ $data[$k]['lognum'] = CustomerVisitLog::with('employee')->where('customer_id', '=', $v['id'])->count();
|
|
|
|
+ }
|
|
|
|
+ $count = $c_model->count();
|
|
|
|
+ return json(['code' => 0, 'data' => $data, 'count' => $count]);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public function export(){
|
|
|
|
+ $type = input('type', '', 'intval');
|
|
|
|
+ $protected = input('protected', '', 'intval');
|
|
|
|
+
|
|
|
|
+ $request = request();
|
|
|
|
+ $param = $request->only(['page', 'limit', 'order', 'org', 'died_time', 'emp_id', 'state','died', 'protected', 'type', 'time', 'followed_time', 'protected_time', 'square_start', 'square_end', 'source', 'designer', 'customer_type', 'community', 'level', 'name'=> '', 'phone'=> '', 'no_visit_time'=> '']);
|
|
|
|
+ $root_id = request()->employee->root_id;
|
|
|
|
+ $subOrg = orgSubIds($root_id);
|
|
|
|
+ if (!empty($param['org']) && in_array($param['org'], $subOrg)) {
|
|
|
|
+ $orgids = orgSubIds($param['org']);
|
|
|
|
+ } else {
|
|
|
|
+ $orgids = orgSubIds(request()->employee->root_id);
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['protected'])) {
|
|
|
|
+ $org_employee = Employee::where('org_id', 'in', $orgids)->column('id');
|
|
|
|
+ $condition[] = ['employee_id', 'in', $org_employee];
|
|
|
|
+ } else {
|
|
|
|
+ $condition = [['org_id', 'in', $orgids]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $order = isset($param['order']) ? $param['order'] : 'id desc';
|
|
|
|
+ $cids = [];
|
|
|
|
+ // $condition[] = ['employee_id', 'not null', ''];
|
|
|
|
+ if (!empty($param['time'])) {
|
|
|
|
+ //录入时间
|
|
|
|
+ $addtimeArr = explode(' - ', $param['time']);
|
|
|
|
+ $start = $addtimeArr[0];
|
|
|
|
+ $end = date('Y-m-d', strtotime($addtimeArr[1]) + 86400);
|
|
|
|
+ $condition[] = ['addtime', '>=', $start];
|
|
|
|
+ $condition[] = ['addtime', '<', $end];
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['followed_time'])) $condition[] = ['last_contact_date', 'between', explode(' - ', $param['followed_time'])];
|
|
|
|
+
|
|
|
|
+ if (!empty($param['died_time'])) {
|
|
|
|
+ list($startDate, $endDate) = explode(' - ', $param['died_time']);
|
|
|
|
+ $endTime = date('Y-m-d', strtotime($endDate) + 86400);
|
|
|
|
+ $condition[] = ['died_date', '>=', $startDate . ' 00:00:00'];
|
|
|
|
+ $condition[] = ['died_date', '<', $endTime . ' 00:00:00'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['protected_time']) && !empty($param['protected'])) $condition[] = ['protected_to', 'between', explode(' - ', $param['protected_time'])];
|
|
|
|
+
|
|
|
|
+ $whereRaw = [];
|
|
|
|
+ if (!empty($param['square_start'])) {
|
|
|
|
+ $whereRaw[] = "square +0 >=" . $param['square_start'];
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['square_end'])) {
|
|
|
|
+ $whereRaw[] = "square +0 <=" . $param['square_end'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['source'])) {
|
|
|
|
+ if ($param['source'] == -1) {
|
|
|
|
+ $condition[] = ['source_id', '=', null];
|
|
|
|
+ } else {
|
|
|
|
+ $condition[] = ['source_id', '=', $param['source']];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['designer'])) $condition[] = ['designer_id', '=', $param['designer']];
|
|
|
|
+ if (!empty($param['customer_type'])) {
|
|
|
|
+ switch ($param['customer_type']) {
|
|
|
|
+ case 1:
|
|
|
|
+ $condition[] = ['crm_res_id', '>', 0];
|
|
|
|
+ $condition[] = ['remark', '<>', '公海获取'];
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ $condition[] = ['remark', '=', '活动报名建档'];
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ $condition[] = ['agents_id', '>', 0];
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ $condition[] = ['crm_res_id', 'NULL', null];
|
|
|
|
+ $condition[] = ['remark', '<>', '活动报名建档'];
|
|
|
|
+ $condition[] = ['agents_id', 'NULL', null];
|
|
|
|
+ break;
|
|
|
|
+ case 5:
|
|
|
|
+ $condition[] = ['remark', '=', '公海获取'];
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['community'])) $condition[] = ['community_name', 'like', '%' . $param['community'] . '%'];
|
|
|
|
+ if (!empty($param['level'])) $condition[] = ['level', '=', $param['level']];
|
|
|
|
+ if (!empty($param['name'])) $condition[] = ['name', 'like', '%' . $param['name'] . '%'];
|
|
|
|
+ if (!empty($param['phone'])){
|
|
|
|
+ $aec = new Aec(config('app.aec_key'), config('app.aec_iv'));
|
|
|
|
+ $value = $aec->encrypt($param['phone']);
|
|
|
|
+ $condition[] = ['phone', '=', $value];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['no_visit_time'])){
|
|
|
|
+ switch ((int)$param['no_visit_time']) {
|
|
|
|
+ case 3:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d'));
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 2*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 7:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 2*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 6*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 15:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 6*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 14*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 30:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 14*24*3600;
|
|
|
|
+ $no_date_e = strtotime(date('Y-m-d')) - 29*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ $condition[] = ['last_contact_date', '>=', date('Y-m-d', $no_date_e)];
|
|
|
|
+ break;
|
|
|
|
+ case 31:
|
|
|
|
+ $no_date_s = strtotime(date('Y-m-d')) - 30*24*3600;
|
|
|
|
+ $condition[] = ['last_contact_date', '<', date('Y-m-d', $no_date_s)];
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ setCondition($param, ['emp_id', 'employee_id'], '=', $condition);
|
|
|
|
+
|
|
|
|
+ $whereOr = []; //or条件二维数据
|
|
|
|
+ if (empty($param['state'])) {
|
|
|
|
+ if (empty($param['died_time']) && empty($param['followed_time']) ){
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ $whereOr[] = [['died','=',2]];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['followed_time']) ){
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['died_time'])){
|
|
|
|
+ $whereOr[] = [['died','=',2]];
|
|
|
|
+ }
|
|
|
|
+ //2023-02-07 客户有效状态 为排除待确认和无效, 或者 待确认并且不是资源库过来的
|
|
|
|
+ // $state1 = Customer::changeState('待确认', 'chaos');
|
|
|
|
+ // $state1 = [];
|
|
|
|
+ // $state2 = Customer::changeState('无效', 'chaos');
|
|
|
|
+ // $whereOr[] = [['state', 'not in', array_merge($state1,$state2)], [['state', 'in',$state1],['crm_res_id','NULL',NULL]],[['state', 'in',$state1],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]];
|
|
|
|
+ } elseif ($param['state'] == '待确认') {
|
|
|
|
+ $state1 = Customer::changeState('待确认', 'chaos');
|
|
|
|
+ //$condition[] = ['crm_res_id', 'NULL', NULL];
|
|
|
|
+ //$condition[] = ['state', 'in', $state1];
|
|
|
|
+ $whereOr[] = [[['state', 'in', $state1],['crm_res_id','NULL',NULL]],[['state', 'in',$state1],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]];
|
|
|
|
+ } elseif ($param['state'] == '有效'){
|
|
|
|
+ $condition[] = ['state','not in',Customer::changeState('待确认','chaos')];
|
|
|
|
+ }elseif ($param['state'] == '无效'){
|
|
|
|
+ $condition[] = ['state','in',Customer::changeState('无效','chaos')];
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // die;
|
|
|
|
+ } elseif ($param['state'] == '死单'){
|
|
|
|
+ $condition[] = ['died', '=', 2];
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // die;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $where_raw = implode(' and ', $whereRaw);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // print_r($condition);
|
|
|
|
+ // die;
|
|
|
|
+ //保护期筛选判断
|
|
|
|
+ if (!empty($param['died_time'])) {
|
|
|
|
+ $condition[] = ['died', '=', 2];
|
|
|
|
+ $whereOr = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!empty($param['followed_time'])) {
|
|
|
|
+ $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')];
|
|
|
|
+ $whereOr = [];
|
|
|
|
+ }
|
|
|
|
+ if ($where_raw) {
|
|
|
|
+ $model = Customer::where($condition)->whereRaw($where_raw);
|
|
|
|
+ } else {
|
|
|
|
+ $model = Customer::where($condition)->whereOr($whereOr);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $c_model = $model;
|
|
|
|
+
|
|
|
|
+ $data = $c_model->with(['employee', 'org', 'designer', 'source', 'visitLog' => function ($query) {
|
|
|
|
+ $query->field('id,customer_id,state')->group('state,customer_id');
|
|
|
|
+ }])->withCount(['visitLog' => function ($query) {
|
|
|
|
+ $query->where(function ($query) {
|
|
|
|
+ $query->whereOr([[CustomerVisitLog::changeState(['state', '=', '预约量房'])], [CustomerVisitLog::changeState(['state', '=', '预约到店'])], [CustomerVisitLog::changeState(['state', '=', '预约活动'])]]);
|
|
|
|
+ });
|
|
|
|
+ }])->withCount(['activityFrequency' => function ($query) {
|
|
|
|
+ $query->where([CustomerVisitLog::changeState(['state', '=', '确认到场'])]);
|
|
|
|
+ }])
|
|
|
|
+ ->order($order)
|
|
|
|
+ ->select()
|
|
|
|
+ ->visible(['id', 'employee_id', 'name', 'community_name','died_date', 'phone', 'level', 'state', 'square', 'revisit_time', 'addtime', 'last_contact_date', 'org_id', 'protected_to', 'is_resource', 'employee.name', 'org_name', 'designer.name', 'visit_log_count', 'activity_frequency_count', 'source_id', 'source.source', 'phone1', 'phone2', 'crm_res_id', 'remark', 'agents_id'])
|
|
|
|
+ ->toArray();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ foreach ($data as $k => $v) {
|
|
|
|
+ if ($v['remark'] == '公海获取') {
|
|
|
|
+ $customer_type = '公海获取';
|
|
|
|
+ } elseif ($v['agents_id']) {
|
|
|
|
+ $customer_type = '装修推荐官';
|
|
|
|
+ } elseif ($v['remark'] == '活动报名建档') {
|
|
|
|
+ $customer_type = '活动报名';
|
|
|
|
+ } elseif ($v['crm_res_id']) {
|
|
|
|
+ $customer_type = '资源库';
|
|
|
|
+ } else {
|
|
|
|
+ $customer_type = '自建';
|
|
|
|
+ }
|
|
|
|
+ $data[$k]['customer_type'] = $customer_type;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $data[$k]['phone'] = $v['phone'];
|
|
|
|
+ $data[$k]['phone1'] = $v['phone1'] ;
|
|
|
|
+ $data[$k]['phone2'] = $v['phone2'];
|
|
|
|
+ //处理历史记录
|
|
|
|
+ $allstate = '';
|
|
|
|
+ foreach ($v['visitLog'] as $m => $p) {
|
|
|
|
+ if ($p['state'] == '已签单') {
|
|
|
|
+ $p['state'] = '已转单';
|
|
|
|
+ }
|
|
|
|
+ if ($p['state'] == '已交定') {
|
|
|
|
+ $p['state'] = '已签单';
|
|
|
|
+ }
|
|
|
|
+ if ($p['state'] == '回访') {
|
|
|
|
+ $p['state'] = '待确认';
|
|
|
|
+ }
|
|
|
|
+ $allstate .= $p['state'] . ',';
|
|
|
|
+ }
|
|
|
|
+ $data[$k]['allstate'] = trim($allstate, ',');
|
|
|
|
+ //增加跟进次数
|
|
|
|
+ $data[$k]['lognum'] = CustomerVisitLog::with('employee')->where('customer_id', '=', $v['id'])->count();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // return json(['code' => 0, 'data' => $data]);
|
|
|
|
+ $result = [];
|
|
|
|
+ foreach($data as $v)
|
|
|
|
+ {
|
|
|
|
+ $vv = [];
|
|
|
|
+
|
|
|
|
+ $vv['id'] = $v['id'];
|
|
|
|
+ $vv['name'] = $v['name'];
|
|
|
|
+ $vv['phone'] = $v['phone'];
|
|
|
|
+ $vv['employee_name'] = $v['employee']['name'] ?? '无';
|
|
|
|
+ $vv['designer'] = $v['designer']['name'] ?? '无';
|
|
|
|
+ $vv['org_name'] = $v['org_name'] ?? '';
|
|
|
|
+ $vv['source'] = $v['source']['source'] ?? '';
|
|
|
|
+ $vv['customer_type'] = $v['customer_type'];
|
|
|
|
+ $vv['community_name'] = $v['community_name'];
|
|
|
|
+ $vv['level'] = $v['level'];
|
|
|
|
+ $vv['state'] = $v['state'];
|
|
|
|
+ $vv['square'] = $v['square'];
|
|
|
|
+ $vv['died_date'] = $v['died_date'];
|
|
|
|
+ $vv['last_contact_date'] = $v['last_contact_date'];
|
|
|
|
+ $vv['lognum'] = $v['lognum'];
|
|
|
|
+ $vv['revisit_time'] = $v['revisit_time'];
|
|
|
|
+ $vv['protected_to'] = $v['protected_to'];
|
|
|
|
+ $vv['visit_log_count'] = $v['visit_log_count'];
|
|
|
|
+ $vv['activity_frequency_count'] = $v['activity_frequency_count'];
|
|
|
|
+ $vv['addtime'] = $v['addtime'];
|
|
|
|
+ $result[] = $vv;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $header = [
|
|
|
|
+ "A1" => "编号",
|
|
|
|
+ "B1" => "业主姓名",
|
|
|
|
+ "C1" => "电话",
|
|
|
|
+ "D1" => "所属员工",
|
|
|
|
+ "E1" => "设计师",
|
|
|
|
+ "F1" => '所属部门',
|
|
|
|
+ "G1" => '来源渠道',
|
|
|
|
+ "H1" => '客户种类',
|
|
|
|
+ "I1" => '小区',
|
|
|
|
+ "J1" => '重要',
|
|
|
|
+ "K1" => '状态',
|
|
|
|
+ "L1" => '面积',
|
|
|
|
+ "M1" => '死单时间',
|
|
|
|
+ "N1" => '无效时间',
|
|
|
|
+ "O1" => '跟进次数',
|
|
|
|
+ "P1" => '下次回访时间',
|
|
|
|
+ "Q1" => '保护至',
|
|
|
|
+ "R1" => '预约次数',
|
|
|
|
+ "S1" => '参加活动次数',
|
|
|
|
+ "T1" => '添加时间',
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ if (!empty($param['died_time'])){
|
|
|
|
+ $param['state'] = '死单';
|
|
|
|
+ }
|
|
|
|
+ if (!empty($param['followed_time'])){
|
|
|
|
+ $param['state'] = '无效';
|
|
|
|
+ }
|
|
|
|
+ $fileName = empty($param['state']) ? '无效和死单客户_' : $param['state'].'客户_';
|
|
|
|
+ $fileName .= date('Y-m-d H:i');
|
|
|
|
+
|
|
|
|
+ // return json(['code' => 0, 'data' => $result]);
|
|
|
|
+ $this->getExport($header, true, $result, $fileName);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 导出
|
|
|
|
+ public function getExport($header = [], $type = false, $data = [], $fileName)
|
|
|
|
+ {
|
|
|
|
+ // 实例化类
|
|
|
|
+ $preadsheet = new Spreadsheet();
|
|
|
|
+ // 创建sheet
|
|
|
|
+ $sheet = $preadsheet->getActiveSheet();
|
|
|
|
+ // 循环设置表头数据
|
|
|
|
+ foreach ($header as $k => $v) {
|
|
|
|
+ $sheet->setCellValue($k, $v);
|
|
|
|
+ }
|
|
|
|
+ // 生成数据
|
|
|
|
+ $sheet->fromArray($data, null, "A2");
|
|
|
|
+ // 样式设置
|
|
|
|
+ $sheet->getDefaultColumnDimension()->setWidth(12);
|
|
|
|
+
|
|
|
|
+ // 设置下载与后缀
|
|
|
|
+ if ($type) {
|
|
|
|
+ header("Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
+ $type = "Xlsx";
|
|
|
|
+ $suffix = "xlsx";
|
|
|
|
+ } else {
|
|
|
|
+ header("Content-Type:application/vnd.ms-excel");
|
|
|
|
+ $type = "Xls";
|
|
|
|
+ $suffix = "xls";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ob_end_clean(); //清楚缓存区
|
|
|
|
+ // 激活浏览器窗口
|
|
|
|
+ header("Content-Disposition:attachment;filename=$fileName.$suffix");
|
|
|
|
+ //缓存控制
|
|
|
|
+ header("Cache-Control:max-age=0");
|
|
|
|
+ // 调用方法执行下载
|
|
|
|
+ $writer = IOFactory::createWriter($preadsheet, $type);
|
|
|
|
+ // 数据流
|
|
|
|
+ $writer->save("php://output");
|
|
|
|
+ }
|
|
/**
|
|
/**
|
|
* 客户跟进
|
|
* 客户跟进
|
|
*/
|
|
*/
|
|
@@ -902,7 +1435,7 @@ class Crm extends Base
|
|
|
|
|
|
if (count($datas) == 0) return json(['code' => 1, 'msg' => '请求错误,未传输数据']);
|
|
if (count($datas) == 0) return json(['code' => 1, 'msg' => '请求错误,未传输数据']);
|
|
|
|
|
|
- //客户来源扩展字段 $datass
|
|
|
|
|
|
+ //客户来源扩展字段
|
|
$ext_where = [
|
|
$ext_where = [
|
|
['root_id', '=', $request->employee->root_id],
|
|
['root_id', '=', $request->employee->root_id],
|
|
['keyname', '=', 'source_id']
|
|
['keyname', '=', 'source_id']
|