request->token; if (!$token['isEmployee'] || !isset($token['isManager']) || !$token['isManager']) abort('404', '未授权的用户'); $this->team_orgs = orgSubIds($token['org_id']); //(new Org())->getChildOrg($token['org_id']); } public function getCondition(){ //$type_arr = ['jiav', 'jiaofang', 'yjlf', 'liangfang', 'yjdd', 'daodian', 'jiaoding', 'qiandan', 'jianqun', 'zhibo', 'yydc', 'daochang', 'yygswjm', 'gswjm']; $param = $this->request->only(['start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'source' => '', 'empid' => '', 'org_id' => '', 'type' => '']); $token = $this->request->token; if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } $startTime = strtotime($param['start_date']) - 1; $endTime = strtotime($param['end_date']) + 86400; // 查询条件 // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); // 是哪个员工 if ($param['empid'] && in_array($param['empid'], $designer_employee)) { setCondition($param['empid'], 'designer_id', '=', $condition); } else { $condition[] = ['designer_id', 'in', $designer_employee]; } } else { // 是哪个员工 if ($param['empid']) { $condition[] = ['org_id', 'in', $param_sub_org]; setCondition($param['empid'], 'employee_id', '=', $condition); } else { $condition[] = ['org_id', 'in', $param_sub_org]; $condition[] = ['employee_id', '>', 0]; } } $condition[] = ['died', '<>', 2]; $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $state_n = Customer::changeState('待确认', 'chaos'); $state_w = Customer::changeState('无效', 'chaos'); $query1 = array_merge($condition,[['state', 'not in', array_merge($state_n,$state_w)]]); $query2 = array_merge($condition,[['state', 'in',$state_n],['crm_res_id','NULL',NULL]]); $query3 = array_merge($condition,[['state', 'in',$state_n],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]); $ids = Customer::whereOr([$query1, $query2,$query3])->column('id'); unset($condition); $condition[] = ['Customer.id', 'in', $ids]; // 有效 $state1 = CustomerVisitLog::changeState('未到访', 'chaos'); $state2 = CustomerVisitLog::changeState('已到访', 'chaos'); $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $state5 = CustomerVisitLog::changeState('交定', 'chaos'); $state6 = CustomerVisitLog::changeState('签单', 'chaos'); $state7 = CustomerVisitLog::changeState('已到场', 'chaos'); // 查询条件 switch ($param['type']) { case 'jiav': $condition[] = ['Customer.add_wechat_time', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['Customer.add_wechat_time', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'jiaofang': $condition[] = ['Customer.house_delivery_time', '>', date('Y/m/d H:i:s', $startTime)]; $condition[] = ['Customer.house_delivery_time', '<', date('Y/m/d H:i:s', $endTime)]; break; case 'yjlf': // 预计量房 $s_where[] = ['org_id', 'in', $param_sub_org]; $s_where[] = ['state', '=', 0]; $s_where[] = ['type', '=', 3]; $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id'); $condition[] = ['Customer.id', 'in', $customer_ids]; break; case 'liangfang': $condition[] = ['CustomerVisitLog.state', 'in', $state3]; $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'yjdd': // 预计到店 $s_where[] = ['org_id', 'in', $param_sub_org]; $s_where[] = ['state', '=', 0]; $s_where[] = ['type', '=', 1]; $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id'); $condition[] = ['Customer.id', 'in', $customer_ids]; break; case 'daodian': $condition[] = ['CustomerVisitLog.state', 'in', $state4]; $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'jiaoding': $condition[] = ['CustomerVisitLog.state', 'in', $state5]; $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'qiandan': $condition[] = ['CustomerVisitLog.state', 'in', $state6]; $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'jianqun': $condition[] = ['Customer.group_building_date', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['Customer.group_building_date', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'zhibo': $condition[] = ['Customer.live_broadcast_date', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['Customer.live_broadcast_date', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'yydc': $s_where[] = ['org_id', 'in', $param_sub_org]; $s_where[] = ['state', '=', 0]; $s_where[] = ['type', '=', 2]; $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $customer_ids = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id'); $condition[] = ['Customer.id', 'in', $customer_ids]; break; case 'daochang': $condition[] = ['CustomerVisitLog.state', 'in', $state7]; $condition[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'yygswjm': $condition[] = ['Customer.subscribe_meet_outside', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['Customer.subscribe_meet_outside', '<', date('Y-m-d H:i:s', $endTime)]; break; case 'gswjm': $condition[] = ['Customer.meet_outside', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['Customer.meet_outside', '<', date('Y-m-d H:i:s', $endTime)]; break; default: //$condition[] = ['Customer.addtime', '>', date('Y-m-d H:i:s', $startTime)]; //$condition[] = ['Customer.addtime', '<', date('Y-m-d H:i:s', $endTime)]; break; } return $condition; } /** * 以客户跟进为主的查询条件 * */ public function logCondition(){ $param = $this->request->only(['start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'source' => '', 'empid' => '', 'org_id' => '', 'type' => '']); if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } $startTime = strtotime($param['start_date']) - 1; $endTime = strtotime($param['end_date']) + 86400; $token = $this->request->token; // 查询条件 // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); // 是哪个员工 if ($param['empid'] && in_array($param['empid'], $designer_employee)) { setCondition($param['empid'], 'designer_id', '=', $condition); setCondition($param['empid'], 'Customer.designer_id', '=', $condition_log); setCondition($param['empid'], 'employee_id', '=', $s_where); } else { $condition[] = ['designer_id', 'in', $designer_employee]; $condition_log[] = ['Customer.designer_id', 'in', $designer_employee]; $s_where[] = ['employee_id', 'in', $designer_employee]; } } else { // 是哪个员工 if ($param['empid']) { $condition[] = ['org_id', 'in', $param_sub_org]; setCondition($param['empid'], 'employee_id', '=', $condition); $condition_log[] = ['Customer.org_id', 'in', $param_sub_org]; setCondition($param['empid'], 'Customer.employee_id', '=', $condition_log); $s_where[] = ['org_id', 'in', $param_sub_org]; setCondition($param['empid'], 'employee_id', '=', $s_where); } else { $condition[] = ['org_id', 'in', $param_sub_org]; $condition[] = ['employee_id', '>', 0]; $condition_log[] = ['Customer.org_id', 'in', $param_sub_org]; $condition_log[] = ['Customer.employee_id', '>', 0]; $s_where[] = ['org_id', 'in', $param_sub_org]; $s_where[] = ['employee_id', '>', 0]; } } $condition[] = ['died', '<>', 2]; $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $condition_log[] = ['Customer.died', '<>', 2]; $condition_log[] = ['Customer.state', 'not in', Customer::changeState('无效', 'chaos')]; $state_n = Customer::changeState('待确认', 'chaos'); $state_w = Customer::changeState('无效', 'chaos'); $query_nw = [ [['state', 'not in', array_merge($state_n,$state_w)]], [['state', 'in', $state_n], ['crm_res_id', 'NULL', NULL]] ]; // 加v $condition_jiav[] = ['add_wechat_time', '>', date('Y-m-d H:i:s', $startTime)]; $condition_jiav[] = ['add_wechat_time', '<', date('Y-m-d H:i:s', $endTime)]; // 交房 $condition_jiaofang[] = ['house_delivery_time', '>', date('Y/m/d H:i:s', $startTime)]; $condition_jiaofang[] = ['house_delivery_time', '<', date('Y/m/d H:i:s', $endTime)]; $ids = Customer::where($condition)->where(function($query) use ($query_nw){ $query->whereOr($query_nw); })->where(function($query) use ($condition_jiav, $condition_jiaofang){ $query->whereOr([$condition_jiav, $condition_jiaofang]); }) ->column('id'); //预计量房 预计到店 $s_where[] = ['org_id', 'in', $param_sub_org]; $s_where[] = ['state', '=', 0]; $s_where[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $s_where[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $s_where[] = ['type', 'in', [1,3]]; $yuji_ids_find = CustomersSubscribe::where($s_where)->group('customer_id')->column('customer_id'); $customer_ids_1 = array_values(array_unique(array_merge($ids, $yuji_ids_find))); // 时间段内有跟踪 $condition_log[] = ['CustomerVisitLog.addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition_log[] = ['CustomerVisitLog.addtime', '<', date('Y-m-d H:i:s', $endTime)]; $customer_ids_2_find = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition_log) ->group('Customer.id') ->column('Customer.id'); $customer_ids = array_values(array_unique(array_merge($customer_ids_1, $customer_ids_2_find))); return $customer_ids; } /** * 团队统计数据 * @param string $start_date * @param string $end_date * @return string */ public function statistics() { $type = input('type', '', 'trim'); $search_type = input('search_type', 1, 'intval'); //数据查询方式 1,以客户为主导 2,以满足的搜索状态为主导,合并出所有客户 $param = $this->request->only(['start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'source' => '', 'empid' => '', 'org_id' => '', 'type' => '']); $startTime = strtotime($param['start_date']) - 1; $endTime = strtotime($param['end_date']) + 86400; $token = $this->request->token; if ($type){ $condition = $this->getCondition(); // 客户总数 $customer_ids = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition) ->group('Customer.id') ->column('Customer.id'); $customer_num = count($customer_ids); if ($type == 'jiav'){ $jiawei = $customer_num; } else { $jiav_condition = $condition; $jiav_condition[] = ['Customer.add_wechat_time', '<>', '']; $jiaweiIds = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($jiav_condition) ->group('Customer.id') ->column('Customer.id'); $jiawei = count($jiaweiIds); } $customer_data = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition) ->group('Customer.id') ->column('Customer.return_visit,Customer.assigned_personnel'); $signed_money = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition) ->sum('signed_money'); $customerData['signed_money'] = $signed_money ? round($signed_money / 10000, 2) : 0; $handle = 0; foreach ($customer_data as $k => $v){ if ($v['return_visit'] == 1 || empty($v['assigned_personnel'])) { $handle ++; } } } else { if ($search_type == 1) { if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); if ($param['empid'] && in_array($param['empid'], $designer_employee)) { setCondition($param['empid'], 'designer_id', '=', $condition); } else { $condition[] = ['designer_id', 'in', $designer_employee]; } } else { $condition[] = ['org_id', 'in', $param_sub_org]; if ($param['empid']) { setCondition($param['empid'], 'employee_id', '=', $condition); } else { $condition[] = ['employee_id', '>', 0]; } } $condition[] = ['died', '<>', 2]; $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $condition[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $state_n = Customer::changeState('待确认', 'chaos'); $state_w = Customer::changeState('无效', 'chaos'); $query1 = array_merge($condition,[['state', 'not in', array_merge($state_n,$state_w)]]); $query2 = array_merge($condition,[['state', 'in',$state_n],['crm_res_id','NULL',NULL]]); $query3 = array_merge($condition,[['state', 'in',$state_n],['crm_res_id','NOTNULL',NULL],['valid_time','NOTNULL',NULL]]); $customer_ids = Customer::whereOr([$query1, $query2,$query3])->column('id'); $customer_num = count($customer_ids); unset($condition); $condition[] = ['id', 'in', $customer_ids]; // 加微数量 $condition1 = $condition; $condition1[] = ['add_wechat_time', '<>', '']; $jiawei = Customer::where($condition1)->count(); $customer_data = Customer::where($condition)->field('return_visit,assigned_personnel')->select()->toArray(); $signed_money = Customer::where($condition)->sum('signed_money'); $customerData['signed_money'] = $signed_money ? round($signed_money / 10000, 2) : 0; $handle = 0; foreach ($customer_data as $k => $v){ if ($v['return_visit'] == 1 || empty($v['assigned_personnel'])) { $handle ++; } } } else { $customer_ids = $this->logCondition(); $customer_num = count($customer_ids); // 加微数量 $condition1[] = ['id', 'in', $customer_ids]; $condition1[] = ['add_wechat_time', '<>', '']; $jiawei = Customer::where($condition1)->count(); $customer_data = Customer::where($condition1)->field('return_visit,assigned_personnel')->select()->toArray(); $signed_money = Customer::where($condition1)->sum('signed_money'); $customerData['signed_money'] = $signed_money ? round($signed_money / 10000, 2) : 0; $handle = 0; foreach ($customer_data as $k => $v){ if ($v['return_visit'] == 1 || empty($v['assigned_personnel'])) { $handle ++; } } } } //控制权限 $type_arr = ['customer_num' => 1, 'visit_num' => 1, 'valid_count' => 1, 'deposit_num' => 1, 'signed_num' => 1, 'yylf_num' => 1, 'lf_num' => 1, 'yydd_num' => 1, 'ydd_num' => 1, 'yyhd_num' => 1, 'ydc_num' => 1]; $setting = Setting::where([['name', '=', 'teamStatisticsJurisdiction'], ['root_id', '=', $token['root_org']]])->value('content'); $setting = $setting ? explode(',', $setting) : []; foreach ($type_arr as $k => $v) { $type_arr[$k] = in_array($k, $setting) ? 1 : 0; } $sum = array_sum(array_values($type_arr)); if ($sum < 5) $type_arr = ['customer_num' => 1, 'visit_num' => 1, 'valid_count' => 1, 'deposit_num' => 1, 'signed_num' => 1, 'yylf_num' => 1, 'lf_num' => 1, 'yydd_num' => 1, 'ydd_num' => 1, 'yyhd_num' => 1, 'ydc_num' => 1]; $customerData['customer_num'] = $customer_num; $customerData['visit_num'] = $jiawei; //装修意向下拉 $pid = CustomerPortraitField::where([['keyname', '=', 'intention'], ['root_id', '=', $token['root_org']]])->value('id'); $select = CustomerPortraitFieldSelect::where([['pid', '=', $pid]])->column('name,id value'); return json(['code' => 0, 'data' => $customerData, 'setting' => $type_arr, 'select'=> $select, 'handle'=> $handle]); } /** * 有效客户数量 (弃用 2023-02-10) */ public function statistics_valid(){ $type = input('type', '', 'trim'); $param = $this->request->only(['start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'source' => '', 'empid' => '', 'org_id' => '', 'type' => '']); $startTime = strtotime($param['start_date']) - 1; $endTime = strtotime($param['end_date']) + 86400; $token = $this->request->token; if ($type){ $condition = $this->getCondition(); // 客户总数 $customerIdList = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition) ->group('Customer.id') ->column('Customer.id'); } else { if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); $condition[] = ['designer_id', 'in', $designer_employee]; } else { $condition[] = ['org_id', 'in', $param_sub_org]; $condition[] = ['employee_id', '>', 0]; } $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $condition[] = ['addtime', '>', date('Y-m-d H:i:s', $startTime)]; $condition[] = ['addtime', '<', date('Y-m-d H:i:s', $endTime)]; $customerIdList = Customer::where($condition)->column('id'); } $state1 = CustomerVisitLog::changeState('未到访', 'chaos'); $state2 = CustomerVisitLog::changeState('已到访', 'chaos'); $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $state5 = CustomerVisitLog::changeState('交定', 'chaos'); $state6 = CustomerVisitLog::changeState('签单', 'chaos'); $state7 = CustomerVisitLog::changeState('已到场', 'chaos'); // 查询条件 $stateList = array_merge($state1, $state2, $state3, $state4, $state5, $state6, $state7); if ($param['org_id']) { $condition_org_path = Org::where('id', '=', $param['org_id'])->value('path'); } else { $condition_org_path = Org::where('id', '=', request()->token['org_id'])->value('path'); } // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $org_id = Org::where([['path', 'like', $condition_org_path . '%']])->column('id'); $designer_employee = Employee::where([['org_id', 'in', $org_id], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); $condition1[] = ['Customer.designer_id', 'in', $designer_employee]; } else { $condition1[] = ['Org.path', 'like', $condition_org_path . '%']; } $condition1[] = ['CustomerVisitLog.state', 'in', $stateList]; $youxiaoIds = Db::view('CustomerVisitLog') ->view('Customer', '', 'Customer.id=CustomerVisitLog.customer_id') ->view('Org', '', 'Org.id=Customer.org_id') ->where($condition1) ->group('CustomerVisitLog.customer_id') ->column('CustomerVisitLog.customer_id'); $youxiao = array_intersect($customerIdList, $youxiaoIds); return json(['code' => 0, 'data' => count($youxiao)]); } /** * 团队统计数据 * @param string $start_date * @param string $end_date * @return string */ public function statistics_more() { $type = input('type', '', 'trim'); $search_type = input('search_type', 1, 'intval'); //数据查询方式 1,以客户为主导 2,以满足的搜索状态为主导,合并出所有客户 $param = $this->request->only(['start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'source' => '', 'empid' => '', 'org_id' => '', 'type' => '']); $startTime = strtotime($param['start_date']); $endTime = strtotime($param['end_date']) + 86400 - 1; $token = $this->request->token; if ($type){ $condition = $this->getCondition(); // 客户总数 $customerIdList = Db::view('Customer') ->view('Org', '', 'Org.id=Customer.org_id') ->view('CustomerVisitLog', '', 'Customer.id=CustomerVisitLog.customer_id') ->where($condition) ->group('Customer.id') ->column('Customer.id'); } else { if ($search_type == 1) { if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); if ($param['empid'] && in_array($param['empid'], $designer_employee)) { setCondition($param['empid'], 'designer_id', '=', $condition); } else { $condition[] = ['designer_id', 'in', $designer_employee]; } } else { $condition[] = ['org_id', 'in', $param_sub_org]; if ($param['empid']) { setCondition($param['empid'], 'employee_id', '=', $condition); } else { $condition[] = ['employee_id', '>', 0]; } } $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $condition[] = ['addtime', 'between', [date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime)]]; $state_n = Customer::changeState('待确认', 'chaos'); $state_w = Customer::changeState('无效', 'chaos'); $query1 = array_merge($condition,[['state', 'not in', array_merge($state_n,$state_w)]]); $query2 = array_merge($condition,[['state', 'in',$state_n],['crm_res_id','NULL',NULL]]); $customerIdList = Customer::whereOr([$query1,$query2])->column('id'); } else { $customerIdList = $this->logCondition(); } } // 有效 $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $state5 = CustomerVisitLog::changeState('交定', 'chaos'); $state6 = CustomerVisitLog::changeState('签单', 'chaos'); $state7 = CustomerVisitLog::changeState('已到场', 'chaos'); $state8 = CustomerVisitLog::changeState('预约量房', 'chaos'); $state9 = CustomerVisitLog::changeState('预约到店', 'chaos'); $state10 = CustomerVisitLog::changeState('预约活动', 'chaos'); // 签单 if ($param['org_id']) { $condition_org_path = Org::where('id', '=', $param['org_id'])->value('path'); } else { $condition_org_path = Org::where('id', '=', $token['org_id'])->value('path'); } // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $org_id = Org::where([['path', 'like', $condition_org_path . '%']])->column('id'); $designer_employee = Employee::where([['org_id', 'in', $org_id], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); $condition_all[] = ['Customer.employee_id|Customer.designer_id', 'in', $designer_employee]; } else { $condition_all[] = ['Org.path', 'like', $condition_org_path . '%']; } // 签单 交定 预计量房 量房 预计到店 预约活动 已到店 已到场 $condition_state = array_merge($state3, $state4, $state5, $state6, $state7, $state8, $state9, $state10); $condition_all[] = ['CustomerVisitLog.state', 'in', $condition_state]; if (empty($type)){ $condition_all[] = ['CustomerVisitLog.addtime', 'between', [date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime)]]; } $visit_list = Db::view('CustomerVisitLog') ->view('Customer', '', 'Customer.id=CustomerVisitLog.customer_id') ->view('Org', '', 'Org.id=Customer.org_id') ->where($condition_all) ->column('CustomerVisitLog.customer_id,CustomerVisitLog.state,CustomerVisitLog.addtime'); $qiandanIds = []; // 签单 $jiaodingIds = []; // 交定 $yylfIds = []; //预约量房 $lfIds = []; // 量房 $yyddIds = []; // 预约到店 $yyhdIds = []; // 预约活动 $yddIds = []; // 已到店 $ydcIds = []; // 已到场 $ydc_list = []; // 已到场记录 $ydd_list = []; // 已到店记录 foreach ($visit_list as $k => $v) { if (in_array($v['state'], $state6)) { $qiandanIds[] = $v['customer_id']; } if (in_array($v['state'], $state5)) { $jiaodingIds[] = $v['customer_id']; } if (in_array($v['state'], $state8)) { $yylfIds[] = $v['customer_id']; } if (in_array($v['state'], $state3)) { $lfIds[] = $v['customer_id']; } if (in_array($v['state'], $state9)) { $yyddIds[] = $v['customer_id']; } if (in_array($v['state'], $state10)) { $yyhdIds[] = $v['customer_id']; } if (in_array($v['state'], $state7)) { $ydcIds[] = $v['customer_id']; $ydc_list[] = $v; } if (in_array($v['state'], $state4)) { $yddIds[] = $v['customer_id']; $ydd_list[] = $v; } } $qiandan = array_intersect($customerIdList, $qiandanIds); $jiaoding = array_intersect($customerIdList, $jiaodingIds); $yylf_ing = CustomersSubscribe::where([['state', '=', 0], ['type', '=', 3], ['customer_id', 'in', $yylfIds]])->column('customer_id'); $yylf = array_intersect($customerIdList, $yylf_ing); // 量房 $lf = array_intersect($customerIdList, $lfIds); // 预计到店 $yydd_ing = CustomersSubscribe::where([['state', '=', 0], ['type', '=', 1], ['customer_id', 'in', $yyddIds]])->column('customer_id'); $yydd = array_intersect($customerIdList, $yydd_ing); // 预约活动 $yyhd_ing = CustomersSubscribe::where([['state', '=', 0], ['type', '=', 2], ['customer_id', 'in', $yyhdIds]])->column('customer_id'); $yyhd = array_intersect($customerIdList, $yyhd_ing); // 已到店 // 客户5号加微信,10号到店,则10号手机端的到店数据要体现,15号再次到店,则15号手机端不计二次到店的数据,第二月5号再次到店,则5号的数据手机端计1次到店数据 小胖提 if (empty($type)) { $ydd = []; $year_s = date('Y', $startTime); $year_e = date('Y', $endTime); $month_s = intval(date('m', $startTime)); $month_e = intval(date('m', $endTime)); if($year_s != $year_e || $month_s != $month_e){ // 跨月 if ($year_s == $year_e){ // 同一年 for ($i = 0; $month_s <= $month_e; $i++){ if ($i == 0){ $startTimeFor = date('Y-m-d H:i:s', $startTime); //首次等于搜索的开始时间 } else { $startTimeFor = $year_s . '-' . $month_s . '-01 00:00:00'; // 后面月份的开始时间 } if ($month_s == $month_e) { // 等于搜索的结束月份 $endTimeFor = date('Y-m-d H:i:s', $endTime); } else { //中间月份的结束时间 $next_month = strtotime(($year_s . '-' . ($month_s + 1) . '-01 00:00:00'))-1; $endTimeFor = date('Y-m-d 23:59:59', $next_month); } $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydd_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydd_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydd = array_merge($ydd, $ids_for_one); $month_s ++; // 月份增加 } } else { for ($y = 0; $year_s <= $year_e; $y++){ if ($year_s == $year_e) { $month_s_for = 1; $month_e_for = $month_e; for ($i = 0; $month_s_for <= $month_e_for; $i++){ $startTimeFor = $year_s . '-' . $month_s_for . '-01 00:00:00'; if ($month_s_for == $month_e_for) { $endTimeFor = date('Y-m-d H:i:s', $endTime); } else { $next_month = strtotime(($year_s . '-' . ($month_s_for + 1) . '-01 00:00:00'))-1; $endTimeFor = date('Y-m-d 23:59:59', $next_month); } $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydd_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydd_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydd = array_merge($ydd, $ids_for_one); $month_s_for ++; } } else { if ($y == 0) { $month_s_for = $month_s; } else { $month_s_for = 1; } for ($i = 0; $month_s_for <= 12; $i++){ if ($y == 0 && $i == 0) { $startTimeFor = date('Y-m-d H:i:s', $startTime); } else { $startTimeFor = $year_s . '-' . $month_s_for . '-01 00:00:00'; } if ($month_s_for == 12) { $next_month = strtotime($year_s . '-12-31 23:59:59'); } else { $next_month = strtotime(($year_s . '-' . ($month_s_for + 1) . '-01 00:00:00'))-1; } $endTimeFor = date('Y-m-d 23:59:59', $next_month); $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydd_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydd_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydd = array_merge($ydd, $ids_for_one); $month_s_for ++; } } $year_s ++; // 下一年 } } } else { $ydd = array_intersect($customerIdList, $yddIds); } } else { $ydd = array_intersect($customerIdList, $yddIds); } // 已到场 if (empty($type)) { $ydc = []; $year_s = date('Y', $startTime); $year_e = date('Y', $endTime); $month_s = intval(date('m', $startTime)); $month_e = intval(date('m', $endTime)); if($year_s != $year_e || $month_s != $month_e){ // 跨月 if ($year_s == $year_e){ // 同一年 for ($i = 0; $month_s <= $month_e; $i++){ if ($i == 0){ $startTimeFor = date('Y-m-d H:i:s', $startTime); //首次等于搜索的开始时间 } else { $startTimeFor = $year_s . '-' . $month_s . '-01 00:00:00'; // 后面月份的开始时间 } if ($month_s == $month_e) { // 等于搜索的结束月份 $endTimeFor = date('Y-m-d H:i:s', $endTime); } else { //中间月份的结束时间 $next_month = strtotime(($year_s . '-' . ($month_s + 1) . '-01 00:00:00'))-1; $endTimeFor = date('Y-m-d 23:59:59', $next_month); } $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydc_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydc_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydc = array_merge($ydc, $ids_for_one); $month_s ++; // 月份增加 } } else { for ($y = 0; $year_s <= $year_e; $y++){ if ($year_s == $year_e) { $month_s_for = 1; $month_e_for = $month_e; for ($i = 0; $month_s_for <= $month_e_for; $i++){ $startTimeFor = $year_s . '-' . $month_s_for . '-01 00:00:00'; if ($month_s_for == $month_e_for) { $endTimeFor = date('Y-m-d H:i:s', $endTime); } else { $next_month = strtotime(($year_s . '-' . ($month_s_for + 1) . '-01 00:00:00'))-1; $endTimeFor = date('Y-m-d 23:59:59', $next_month); } $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydc_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydc_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydc = array_merge($ydc, $ids_for_one); $month_s_for ++; } } else { if ($y == 0) { $month_s_for = $month_s; } else { $month_s_for = 1; } for ($i = 0; $month_s_for <= 12; $i++){ if ($y == 0 && $i == 0) { $startTimeFor = date('Y-m-d H:i:s', $startTime); } else { $startTimeFor = $year_s . '-' . $month_s_for . '-01 00:00:00'; } if ($month_s_for == 12) { $next_month = strtotime($year_s . '-12-31 23:59:59'); } else { $next_month = strtotime(($year_s . '-' . ($month_s_for + 1) . '-01 00:00:00'))-1; } $endTimeFor = date('Y-m-d 23:59:59', $next_month); $month_ids = []; $ids_for_sel = []; $strtotime_start = strtotime($startTimeFor); $strtotime_end = strtotime($endTimeFor); foreach ($ydc_list as $k => $v) { if (strtotime($v['addtime']) > $strtotime_start && strtotime($v['addtime']) < $strtotime_end) { if(!in_array($v['customer_id'], $month_ids)){ $ids_for_sel[] = $v['customer_id']; } unset($ydc_list[$k]); } } $ids_for_one = array_intersect($customerIdList, $ids_for_sel); $ydc = array_merge($ydc, $ids_for_one); $month_s_for++; } } $year_s++; // 下一年 } } } else { $ydc = array_intersect($customerIdList, $ydcIds); } } else { $ydc = array_intersect($customerIdList, $ydcIds); } $customerData['signed_num'] = count($qiandan); $customerData['deposit_num'] = count($jiaoding); $customerData['yylf_num'] = count($yylf); $customerData['lf_num'] = count($lf); $customerData['yydd_num'] = count($yydd); $customerData['ydd_num'] = count($ydd); $customerData['yyhd_num'] = count($yyhd); $customerData['ydc_num'] = count($ydc); return json(['code' => 0, 'data' => $customerData]); } /** * 团队数据-客户列表 */ public function customers() { $param = $this->request->only([ 'state' => '', 'source' => '', 'empid' => '', 'org_id' => '', 'keyword' => '', 'page' => 1, 'limit' => 15, 'return_visit' => '', 'start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d'), 'order' => 'addtime', 'sort' => 'desc', 'type' => '', 'level' => '', 'intention' => '', 'is_assign' => '' ]); $condition = []; $search_type = input('search_type', 1, 'intval'); //数据查询方式 1,以客户为主导 2,以满足的搜索状态为主导,合并出所有客户 $startCondition = ['addtime', '>', date('Y-m-d H:i:s', strtotime($param['start_date']))]; $endCondition = ['addtime', '<', date('Y-m-d', strtotime($param['end_date'])) . ' 23:59:59']; if ($param['level']) $condition[] = ['level', '=', $param['level']]; //客户等级 if ($param['org_id']) { $param_sub_org = orgSubIds($param['org_id']); } else { $param_sub_org = $this->team_orgs; } $token = $this->request->token; if ($search_type == 1) { $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $condition[] = ['died', '<>', 2]; // 设计师部门管理员,需要查询指派给下属设计师的客户信息 if ($token['org_type'] == 2) { $designer_employee = Employee::where([['org_id', 'in', $param_sub_org], ['uid', '<>', 0], ['state', '=', '在职']])->column('id'); if ($param['empid'] && in_array($param['empid'], $designer_employee)) { setCondition($param['empid'], 'designer_id', '=', $condition); } else { $condition[] = ['designer_id', 'in', $designer_employee]; } } else { $condition[] = ['org_id', 'in', $param_sub_org]; if ($param['empid']) { setCondition($param['empid'], 'employee_id', '=', $condition); } else { $condition[] = ['employee_id', '>', 0]; } } if (empty($param['keyword'])) { $condition[] = $startCondition; $condition[] = $endCondition; } } else { $customerIdList = $this->logCondition(); $condition[] = ['id', 'in', $customerIdList]; } //意向程度 if ($param['intention']) { $intention_customer = Customer::where($condition)->where([['ext', 'like', '%intention%']])->column('id,ext'); $cid = []; foreach ($intention_customer as $value) { $json = json_decode($value['ext'], true); foreach ($json as $k2 => $v2) { if ($v2['keyname'] == 'intention' && !empty($v2['value']) && $v2['value'] == $param['intention']) { $cid[] = $value['id']; break; } } } if (empty($cid)) return json(['code' => 0, 'data' => []]); $condition[] = ['id', 'in', $cid]; } $source = [ 'ownadd' => [ ['crm_res_id', '=', null], ['is_resource', '=', 0], ['remark', '=', ''] ], 'crmres' => [ ['crm_res_id', 'not null', ''], ['is_resource', '=', 0] ], 'public' => [ ['remark', '=', '公海获取'] ] ]; if ($param['source'] && isset($source[$param['source']])) $condition = array_merge($condition, $source[$param['source']]); if (!empty($param['keyword'])) { if (preg_match('/^1[\d]{10}$/', $param['keyword'])) { $list = Customer::where($condition)->field('id,name,community_name,phone')->select(); $keyCustomersId = []; foreach ($list as $v) { if (strpos($v->phone, trim($param['keyword'])) !== false) $keyCustomersId[] = $v['id']; } $condition[] = ['id', 'in', $keyCustomersId]; } else { $name1 = array_merge($condition, [['name', 'like', '%' . $param['keyword'] . '%']]); $name2 = array_merge($condition, [['community_name', 'like', '%' . $param['keyword'] . '%']]); $keyCustomersId = Customer::whereOr([$name1, $name2])->column('id'); $condition[] = ['id', 'in', $keyCustomersId]; } } //待回访 if ($param['return_visit'] == 1) { $condition[] = ['return_visit', '=', 1]; } //待指派协作人 if ($param['return_visit'] == 2) { $condition[] = ['designer_id', '=', null]; } //客户的指派状态筛选 if (!empty($param['is_assign']) && $param['is_assign'] == 1) $condition[] = ['assigned_personnel', 'NOTNULL', null]; if (!empty($param['is_assign']) && $param['is_assign'] == 2) $condition[] = ['assigned_personnel', 'NULL', null]; // 状态筛选 if (!empty($param['state'])) { if ($param['state'] == '待确认') { //2022-10-30 小程序客户列表的待确认状态是根据客户表的当前状态来展示的,所以查询待确认状态时 查询客户当前 $customer_model = Customer::with(['employee', 'designer'])->withAttr('addtime', function ($value) { return explode(' ', $value)[0]; })->where($condition)->where(function ($query) { $state1 = Customer::changeState('待确认', 'chaos'); $query1 = [['state', 'in', $state1], ['crm_res_id', 'NULL', NULL]]; $query2 = [['state', 'in', $state1], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]]; $query->whereOr([$query1, $query2]); }); } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') { $customer_model = Customer::with(['employee', 'designer'])->withAttr('addtime', function ($value) { return explode(' ', $value)[0]; })->where($condition)->where([['state', 'not in', array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos'))]]); } else { $customersIdList = Customer::where($condition)->order('addtime desc')->column('id'); $visit_where[] = ['customer_id', 'in', $customersIdList]; $visit_where[] = ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]; $visit_where[] = $startCondition; $visit_where[] = $endCondition; $logCustomersIdList = CustomerVisitLog::where($visit_where)->group('customer_id')->column('customer_id'); $customer_model = Customer::with(['employee', 'designer'])->withAttr('addtime', function ($value) { return explode(' ', $value)[0]; })->where('id', 'in', $logCustomersIdList); // ->where(function($query){ // $state1 = Customer::changeState('待确认', 'chaos'); // $query1 = [['state', 'in', $state1], ['crm_res_id', 'NULL', NULL]]; // $query2 = [['state', 'in', $state1], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]]; // $query->whereOr([$query1, $query2]); // }); } } else { $customer_model = Customer::with(['employee', 'designer'])->withAttr('addtime', function ($value) { return explode(' ', $value)[0]; })->where($condition); // ->where(function ($query) { // $state1 = Customer::changeState('待确认', 'chaos'); // $query1 = [['state', 'in', $state1], ['crm_res_id', 'NULL', NULL]]; // $query2 = [['state', 'in', $state1], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]]; // $query->whereOr([$query1, $query2]); // }); } if ($param['order'] == 'visit') { $customers = $customer_model->page($param['page'], $param['limit'])->order('last_contact_date ' . $param['sort'])->select(); $data = $customers->visible(['id', 'name', 'sex', 'level', 'addtime', 'community_name', 'employee.name', 'designer.name', 'state', 'return_visit', 'assign_type', 'assigned_personnel', 'square', 'last_contact_date', 'assigned_personnel', 'designer_id', 'employee_id'])->toArray(); } else { $order = ($param['order'] ? $param['order'] : 'addtime') . ' ' . ($param['sort'] ? $param['sort'] : 'desc'); $customers = $customer_model->page($param['page'], $param['limit'])->order($order)->select(); $data = $customers->visible(['id', 'name', 'sex', 'level', 'addtime', 'community_name', 'employee.name', 'designer.name', 'state', 'return_visit', 'assign_type', 'assigned_personnel', 'square', 'last_contact_date', 'assigned_personnel', 'designer_id', 'employee_id'])->toArray(); } foreach ($data as $k => $v) { $data[$k]['return_visit'] = $token['org_type'] == 2 ? 0 : $v['return_visit']; //设计师身份不需要回访 } // 状态统计获取 $pageIdList = array_column($data, 'id'); $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('state,customer_id')->field('count(state) as num, state, customer_id')->select()->toArray(); $customersState = []; foreach ($customersStateList as $s) { if (!isset($customersState[$s['customer_id']])) $customersState[$s['customer_id']] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0]; $customersState[$s['customer_id']]['count'] += $s['num']; // 到店,量房,活动,定金,签单 if ($s['state'] == '已到店') $customersState[$s['customer_id']]['shop'] += $s['num']; elseif ($s['state'] == '已量房') $customersState[$s['customer_id']]['measure'] += $s['num']; elseif ($s['state'] == '已到场') $customersState[$s['customer_id']]['activity'] += $s['num']; elseif ($s['state'] == '已交定') $customersState[$s['customer_id']]['deposit'] += $s['num']; elseif ($s['state'] == '已签单') $customersState[$s['customer_id']]['signed'] += $s['num']; } //面积 //$cus = Customer::where([['id', 'in', $pageIdList]])->column('employee_id,square,id,assigned_personnel,designer_id,last_contact_date'); $square = array_column($data, 'square', 'id'); $last_contact_date = array_column($data, 'last_contact_date', 'id'); $assigned_personnel = array_column($data, 'assigned_personnel', 'id'); $designer = array_column($data, 'designer_id', 'id'); $emp = array_column($data, 'employee_id', 'id'); $eids = []; foreach ($data as $key => $val) { $data[$key]['stateNum'] = isset($customersState[$val['id']]) ? $customersState[$val['id']] : ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0]; $data[$key]['square'] = $square[$val['id']]; //上次沟通时间 $data[$key]['last_contact_date'] = $last_contact_date[$val['id']]; $designerid = $designer[$val['id']]; $data[$key]['designer_id'] = $designer[$val['id']]; $data[$key]['employee_id'] = $emp[$val['id']]; $eid = []; if ($designer) $eid[] = $designerid; if ($assigned_personnel[$val['id']]) $eid = array_merge($eid, explode(',', $assigned_personnel[$val['id']])); $data[$key]['ems'] = array_unique(array_filter($eid)); $eids = array_merge($eid, $eids); } $ems = Employee::with(['org' => function ($query) { $query->field('id,org_type')->bind(['org_type' => 'org_type']); }])->where([['id', 'in', $eids]])->field('id,org_id,name')->select()->toArray(); $emss = []; foreach ($ems as $vs) { $emss[$vs['id']] = $vs; } $arr = array_column($ems, 'org_type', 'id'); // 最后跟进时间获取 $lastTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList]])->group('customer_id')->column('max(addtime)', 'customer_id'); // 交定时间获取 $dingTime = CustomerVisitLog::where([['customer_id', 'in', $pageIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id"); foreach ($data as $keys => $vals) { $data[$keys]['designer'] = $vals['designer_id'] ? $emss[$vals['designer_id']]['name'] : ''; unset($sale); $sale[] = $vals['employee']['name'] ?? ''; $row = []; if ($vals['ems']) { foreach ($vals['ems'] as $vas) { $i = $emss[$vas]; if ($i['org_type'] == 1 && $i['id'] != $vals['employee_id']) { $sale[] = $i['name']; } } } $data[$keys]['sale'] = $sale; $data[$keys]['ems'] = $row; $data[$keys]['last_visit_day'] = isset($lastTime[$vals['id']]) ? get_date_diff(time(), $lastTime[$vals['id']])->days : -1; $data[$keys]['last_ding_day'] = isset($dingTime[$vals['id']]) ? get_date_diff(time(), $dingTime[$vals['id']])->days : 0; } // 返回结果 //2022-11-09 增加业务逻辑 在团队客户中高层和中高层领导不可以回访和跟进 ,只有基层领导可以 if (!$token['isManager']) { $is_manager = 0; } else { //判断是否是基层领导 , 最底层部门的管理员 $child = Org::where('pid', $token['org_id'])->field('id')->findOrEmpty(); $is_manager = $child->isEmpty() ? 1 : 0; } return json(['code' => 0, 'data' => $data, 'is_manager' => $is_manager]); } /** * 2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他客户的此重复客户就不能在跟进了,但是可以置为无效 */ private function forbiddenState($id, $status) { if ($status == '无效') return false; $token = $this->request->token; //保护规则 $provite = Setting::where([['name', '=', 'forbiddenState'], ['root_id', '=', $token['root_org']]])->value('content'); if (!$provite) return false; $info = Customer::where('id', $id)->column('phone,phone1,phone2'); //查询是否是重复客户 $orgs = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id'); $query[] = ['employee_id', '>', 0]; $query[] = ['org_id', 'in', $orgs]; $query[] = ['phone|phone1|phone2', 'in', array_filter($info[0])]; // $query[] = ['employee_id','<>',$token['employee_id']]; $check = Customer::where($query)->column('id,employee_id'); if (count($check) <= 1) return false; $provite = explode(',', $provite); $state = []; foreach ($provite as $v) { $state = array_merge($state, CustomerVisitLog::changeState($v, 'chaos')); } //查询该客户是否存在受保护的状态 只有第一个跟进的业务员可以继续跟进 $where[] = ['state', 'in', $state]; $where[] = ['customer_id', 'in', array_column($check, 'id')]; $where[] = ['employee_id|customer_employee_id', 'in', array_column($check, 'employee_id')]; $repeat = CustomerVisitLog::where($where)->order('id asc')->field('customer_id,state')->findOrEmpty(); if ($repeat->isEmpty() || (int)$repeat->customer_id == (int)$id) return false; //该客户已被其他员工 确认到店/确认量房/确认到场/交定/签单 无法更近 $state = str_replace('已', '', $repeat->state); $state = in_array(trim($state), ['交定', '签单']) ? trim($state) : '确认' . trim($state); return '该客户已被其他员工“' . $state . '”无法跟进'; } /** * 2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元 */ private function updateMoney($param) { $token = $this->request->token; $money = $param['money'] ?: 0; $where[] = ['id', '=', $param['customer_id']]; Customer::where($where)->update(['signed_money' => $money]); $token['name'] = Employee::where([['id', '=', $token['employee_id']]])->value('name'); $time = date('Y-m-d H:i:s'); //增加跟进记录 $save = [ 'customer_id' => $param['customer_id'], 'type' => '', 'next_contact_date' => date('Y-m-d'), 'remark' => '业务员' . $token['name'] . '修改签单金额为' . $money . '元', 'addtime' => $time, 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'state' => 1, 'org_id' => $token['org_id'], 'customer_employee_id' => $token['employee_id'], 'customer_org_id' => $token['org_id'], 'money' => $money ]; //2022-10-28 增加交定和签单凭证 凭证为图片 $deliverySignVoucher = request()->only(['sign_media_id' => '', 'sign_weixin_media' => '', 'sign_img' => '']); $save = $save + $deliverySignVoucher; CustomerVisitLog::insertGetId($save); if ($deliverySignVoucher['sign_media_id']) Console::call('download', ['sign']); return json(['code' => 0, 'msg' => '签单金额修改成功。', 'data' => '签单金额修改成功。']); } /** * 添加客户追踪记录 * 签单、收定时记录金额,更新客户状态,记录回访时间 */ public function addVisitlog() { $token = $this->request->token; if ($token['isManager'] != 1) return json(['code' => 1, 'msg' => '无权修改该信息']); $param = request()->only(['customer_id', 'type', 'next_contact_date', 'remark', 'img' => '', 'state', 'money' => 0, 'aid' => 0, 'addtime' => date('Y-m-d H:i:s'), 'confirm_date' => '', 'weixin_media' => '', 'media_id' => '', 'starts' => 0, 'weixin_media1' => '', 'media_id1' => '', 'img1' => '', 'number_of_visitors' => 0, 'measure_room_img_type' => '', 'package' => '', 'deposit_mode' => 0]); $param['confirm_date'] = $param['confirm_date'] ? $param['confirm_date'] . ' ' . date('H:i:s') : date('Y-m-d H:i:s'); $employeeTypeName = $token['org_type'] == 2 ? '设计师' : '销售'; $employeeType = $token['org_type'] == 2 ? 'designer_id' : 'employee_id'; //2022-10-04 逻辑修改,无效时无效原因必传remark // if ($param['state'] == '无效' && empty($param['remark'])) return json(['code' => 1, 'msg' => '请填写无效原因']); // 在跟进之前,增加了设计师必填判断,得先查一下设置 $state = Customer::changeState($param['state']); $stateCheck = ['已到店' => 'daodian', '已到场' => 'daochang', '已量房' => 'liangfang', '已交定' => 'qiandan', '已签单' => 'zhuandan']; if (in_array($state, ['已到店', '已到场', '已量房', '已交定', '已签单'])) { $need_designer[] = ['root_id', '=', $token['root_org']]; $need_designer[] = ['name', '=', 'add_visit_log_need_designer']; $need_designer_setting = Setting::where($need_designer)->findOrEmpty(); if (!$need_designer_setting->isEmpty()) { $need_state = explode(',', $need_designer_setting['content']); $input_state = $stateCheck[$state] ?? ''; if (!empty($input_state) && in_array($input_state, $need_state)) { // 需要验证 $customer_find = Customer::find($param['customer_id']); if (!empty($customer_find)) { if (empty($customer_find['assigned_personnel'])) { return json(['code'=> 1, 'msg'=> '请先指派设计师']); } $assigned_personnel = explode(',', $customer_find['assigned_personnel']); $assigned_personnel_employee_org = Employee::where('id', 'in', $assigned_personnel)->column('org_id'); $assigned_personnel_org_type = Org::where('id', 'in', $assigned_personnel_employee_org)->column('org_type'); if (!in_array(2, $assigned_personnel_org_type)) { return json(['code'=> 1, 'msg'=> '请先指派设计师']); } } } } } //2022-10-27 逻辑修改,跟进保护优化 如果后台设置了重复客户跟进保护规则 跟进到保护状态后其他业务员的此重复客户就不能在跟进了,但是可以置为无效 $forbiddenState = $this->forbiddenState($param['customer_id'], $param['state']); if ($forbiddenState != false) return json(['code' => 1, 'msg' => $forbiddenState]); //23-03-10 共有客户列表管理层查看下级部门所有员工指派的跟被指派的客户,同时还可以跟进修改查询客户的逻辑 $team_orgs = orgSubIds($token['org_id']); $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id'); $where = [ ['id', '=', $param['customer_id']], ['state', '<>', '无效'], ['employee_id', '=', $token['employee_id']] ]; //指派的客户 $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $param['customer_id']]]; $sub_employee = Employee::where([['org_id', 'in', $this->team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id'); $where_or1 = [['designer_id', 'in', $sub_employee], ['id', '=', $param['customer_id']]]; $where_or2 = [['employee_id', 'in', $sub_employee], ['id', '=', $param['customer_id']]]; $had = Customer::whereOr([$where, $where_or, $where_or1, $where_or2])->find(); if (!$had) return json(['code' => 1, 'msg' => '添加失败,数据不存在']); if ($had['died'] == 2) { return json(['code' => 1, 'msg' => '客户死单,暂无法跟踪']); } //签单之后不能置为无效 if ($param['state'] == '无效') { $is_orders = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count(); if ($is_orders) return json(['code' => 1, 'msg' => '该客户已签单,不能置为无效']); } //改为有效之后不能再改为待确认 if ($param['state'] == '待确认') { if ($had->state != '待确认') return json(['code' => 1, 'msg' => '该客户已标记为有效,不能修改为待确认']); } // 撞单机制 if ($param['state'] == '未到访') { // 标记有效 // 同部门能否重复录入开关设置 $empcrm_repeat[] = ['root_id', '=', $token['root_org']]; $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat']; $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty(); //判断同部门 if (!$repeat_setting->isEmpty()) { $repeat_org = explode(',', $repeat_setting['content']); if (in_array($token['org_id'], $repeat_org)) { // 需要验证 $not_sure = Customer::changeState('待确认', 'chaos'); $wuxiao = Customer::changeState('无效', 'chaos'); $phones_arr = array_filter([$had['phone'], $had['phone1'], $had['phone2']]); $repeat_where[] = ['phone|phone1|phone2', 'in', $phones_arr]; $repeat_where[] = ['org_id', 'in', $repeat_org]; $repeat_where[] = ['state', 'not in', array_merge($not_sure, $wuxiao)]; $customerExist = Customer::where($repeat_where)->field('id,employee_id'); if (!empty($customerExist)) { foreach ($customerExist as $ex) { if ($ex['employee_id'] != $token['employee_id'] && $ex['id'] != $param['customer_id']) { $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name'); return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . '撞单,无法标记有效']); } } } } } } if (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->state == '待确认') { $valid_time = date('Y-m-d H:i:s'); if (!empty($param['confirm_date'])) { $valid_time = $param['confirm_date']; } $had->valid_time = $valid_time; } // 如果是预约添加预约记录 $stateType = [ 1 => '到店', 2 => '到场', 3 => '量房' ]; $yylf_state = CustomerVisitLog::changeState('预约量房', 'chaos'); $lf_state = CustomerVisitLog::changeState('已量房', 'chaos'); $yydc_state = CustomerVisitLog::changeState('预约活动', 'chaos'); $dc_state = CustomerVisitLog::changeState('已到场', 'chaos'); $yydd_state = CustomerVisitLog::changeState('预约到店', 'chaos'); $dd_state = CustomerVisitLog::changeState('已到店', 'chaos'); $check_state = array_merge($yylf_state, $lf_state, $yydc_state, $dc_state, $yydd_state, $dd_state); if (in_array($param['state'], $check_state)) { // 保护设置 $sub_setting = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'subscribe_protected']])->findOrEmpty(); if (!$sub_setting->isEmpty()) { // 有设置 $setting_content = json_decode($sub_setting['content'], true); $org_ids = orgSubIds($token['root_org']); foreach ($setting_content as $k_s => $v_s) { if (!empty($v_s['state']) && !empty($v_s['day']) && $v_s['state'] == 1) { $continue = false; $sub_state = 0; $errmsg = '该客户在保护期内,无法提交'; $check_log = false; $check_where = []; switch ($k_s) { case 'liangfang': $sub_state = 3; $visit_state = 1; $check_log = true; $check_where[] = ['org_id', 'in', $org_ids]; $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])]; $check_where[] = ['employee_id', '<>', $token['employee_id']]; $check_where[] = ['state', 'in', $lf_state]; break; case 'yliangfang': //预约量房 $sub_state = 3; $visit_state = 0; break; case 'daodian': $sub_state = 1; $visit_state = 1; $check_log = true; $check_where[] = ['org_id', 'in', $org_ids]; $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])]; $check_where[] = ['employee_id', '<>', $token['employee_id']]; $check_where[] = ['state', 'in', $dd_state]; break; case 'ydaodian': $sub_state = 1; $visit_state = 0; break; case 'daochang': $sub_state = 2; $visit_state = 1; $check_log = true; $check_where[] = ['org_id', 'in', $org_ids]; $check_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])]; $check_where[] = ['employee_id', '<>', $token['employee_id']]; $check_where[] = ['state', 'in', $dc_state]; break; case 'ydaochang': $sub_state = 2; $visit_state = 0; break; default: $continue = true; break; } if ($continue) continue; // “确认” 不受预约的限制 if (in_array($k_s, ['yliangfang', 'ydaodian', 'ydaochang']) && in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) { continue; } if (in_array($param['state'], array_merge($lf_state, $dd_state, $dc_state))) { $errmsg = '该客户在保护期内,无法提交确认'; } elseif (in_array($param['state'], array_merge($yylf_state, $yydd_state, $yydc_state))) { $errmsg = '该客户在保护期内,无法预约'; } // 查询保护时间段内添加的预约量房记录 unset($v_where); $v_where[] = ['org_id', 'in', $org_ids]; $v_where[] = ['addtime', '>', date('Y-m-d H:i:s', time() - 24 * 3600 * $v_s['day'])]; $v_where[] = ['employee_id', '<>', $token['employee_id']]; $v_where[] = ['type', '=', $sub_state]; $v_where[] = ['state', '=', $visit_state]; $sub_list = CustomersSubscribe::where($v_where)->select()->toArray(); if (!empty($sub_list)) { $sub_list_ids = array_column($sub_list, 'customer_id'); $sub_employee_ids = array_column($sub_list, 'employee_id'); $sub_customers = Customer::where([['id', 'in', $sub_list_ids], ['employee_id', 'in', $sub_employee_ids]])->select()->toArray(); foreach ($sub_customers as $v) { if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } } } if ($check_log) { $log_list = CustomerVisitLog::where($check_where)->select()->toArray(); $log_list_ids = array_column($log_list, 'customer_id'); $log_employee_ids = array_column($log_list, 'employee_id'); $log_customers = Customer::where([['id', 'in', $log_list_ids], ['employee_id', 'in', $log_employee_ids]])->select()->toArray(); foreach ($log_customers as $v) { if (in_array($had->phone, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } if (!empty($had->phone1) && in_array($had->phone1, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } if (!empty($had->phone2) && in_array($had->phone2, [$v['phone'], $v['phone1'], $v['phone2']]) && $v['id'] != $had['id']) { return json(['code' => 1, 'msg' => $errmsg]); } } } } } } } // 更改客户信息 $state = Customer::changeState($param['state']); $orders = false; //签单之后不能签单交定,可以跟进 if ($state == '已签单') { $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count(); if ($is) { //2022-11-11 业务修改 签单之后可以编辑签单金额,跟进记录增加 业务员修改签单金额为3000元 return $this->updateMoney($param); // return json(['code' => 1, 'msg' => '该客户' . $state]); } $orders = true; } elseif ($state == '已交定') { $is = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')], ['customer_id', '=', $had->id]])->count(); if ($is) { return json(['code' => 1, 'msg' => '该客户已签单']); } $orders = true; } // 检测确认 到店/量房/交定/签单 $stateCheck = ['已到店' => 'visitShopConfirm', '已到场' => 'visitSiteConfirm', '已量房' => 'measureConfirm', '已交定' => 'depositConfirm', '已签单' => 'signConfirm']; if ($token['org_type'] == 1 || ($token['org_type'] == 2 && $token['employee_id'] != $had['employee_id'])) { foreach ($stateCheck as $ss => $set) { if ($ss != $state) continue; $setContent = Setting::where(['name' => $set, 'root_id' => $this->request->token['root_org'], 'state' => 1])->value('content'); // 没有找到则不限制 if ($setContent == null) continue; $setContent = json_decode($setContent, true); if (count($setContent) == 0) continue; if (in_array($had->designer_id, $org_employee) && in_array('designer', $setContent)) continue; if (in_array($had->employee_id, $org_employee) && in_array('salesperson', $setContent)) continue; // 共有客户 销售人员 $assigned_personnel = explode(',', $had['assigned_personnel']); $designer_arr = !empty($had['designer_id']) ? [$had['designer_id']] : []; $salesperson = array_diff($assigned_personnel, $designer_arr); if (array_intersect($salesperson, $org_employee) && in_array('salesperson', $setContent)) continue; return json(['code' => 1, 'msg' => '操作失败,无确认权限']); } } Db::startTrans(); if (!empty($state)) { $had->state = $state; } $had->revisit_time = !empty($param['next_contact_date']) ? $param['next_contact_date'] . ' 00:00:00' : null; $had->last_contact_date = date('Y-m-d', time()); $had->updatetime = date('Y-m-d H:i:s', time()); if ($param['aid'] && $param['state'] == '预约活动') $had->aid = $param['aid']; $had->fresh = 0; // 交定产品 $dingMsg = ''; if ($had->state == '已交定') { empty($param['money']) ?: $had->deposit_money = $param['money']; if (!empty($param['package'])) { $package = CustomerPackage::where([['root_id', '=', $this->request->token['root_org']], ['id', 'in', $param['package']]])->column('name', 'id'); if (!$package) return json(['code' => 1, 'msg' => '客户产品不存在']); $had->package_id = implode(',', array_keys($package)); $dingMsg = '交定金额:' . $param['money'] . '元,选择产品:' . implode(',', $package); } } if ($had->state == '已签单' && !empty($param['money'])) $had->signed_money = $param['money']; $had->save(); // 更新客户保护期 if ($param['state'] !== '无效' && !empty($state)) { $log_state = CustomerVisitLog::changeState($state, 'chaos'); $vis_where[] = ['employee_id', '=', $this->request->token['employee_id']]; $vis_where[] = ['state', 'in', $log_state]; $vis_where[] = ['customer_id', '=', $param['customer_id']]; if (!empty($had['employee_time'])) { $vis_where[] = ['addtime', '>', $had['employee_time']]; } $v_count = CustomerVisitLog::where($vis_where)->count(); //查看此状态的跟踪记录,如果有数据,说明此客户在此员工这里已经经历过此状态,不再更新保护期 if (!$v_count) { Customer::changeProtectedTo($had->id, $this->request->token['root_org']); } } // 添加确定消息内容 $confirmMsg = ''; if (!empty($param['confirm_date'])) { $confirmMsg = ', 时间:' . $param['confirm_date']; } // 备注 $employeeName = Employee::where(['id' => $token['employee_id']])->value('name'); $remark = $param['remark']; if (empty($remark)) { if (empty($state)) $remark = '部门领导' . $employeeName . '对客户进行了回访'; else $remark = '部门领导' . $employeeName . '更新客户状态为' . $state . $confirmMsg . ',' . $dingMsg; } // 添加追踪记录 $visitLog = [ 'customer_id' => $had->id, 'type' => $param['type'], 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : null, 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'remark' => $remark, 'state' => $param['state'], 'weixin_media' => $param['weixin_media'], 'media_id' => $param['media_id'], 'starts' => $param['starts'], 'money' => $param['money'], 'confirm_date' => $param['confirm_date'], 'org_id' => $token['org_id'], 'aid' => $param['aid'] ?: $had->aid, 'weixin_media1' => $param['weixin_media1'], 'media_id1' => $param['media_id1'], 'customer_employee_id' => $had->employee_id, 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id'), 'img' => $param['img'], 'img1' => $param['img1'], 'number_of_visitors' => $param['number_of_visitors'], 'measure_room_img_type' => $param['measure_room_img_type'], 'deposit_mode' => $param['deposit_mode'] ]; //2022-10-28 增加交定和签单凭证 凭证为图片 谈单时长talking_order_time $deliverySignVoucher = request()->only(['delivery_media_id' => '', 'delivery_weixin_media' => '', 'sign_media_id' => '', 'sign_weixin_media' => '', 'delivery_img' => '', 'sign_img' => '', 'talking_order_time' => '']); $visitLog = $visitLog + $deliverySignVoucher; empty($param['img']) ?: $visitLog['img'] = $param['img']; if (!empty($param['aid'])) { // 检测活动是否存在 $existActivity = Activity::where([['id', '=', $param['aid']], ['root_id', '=', $token['root_org']]])->count(); if ($existActivity == 0) { Db::rollback(); return json(['code' => 1, 'msg' => '活动不存在']); } $visitLog['aid'] = $param['aid']; } $visitLog = CustomerVisitLog::create($visitLog); if ($orders) $this->preformance_tasks($state, $param['customer_id'], $param['money'], $visitLog->id, $token['employee_id']); //计算业绩 // 如果是预约添加预约记录 if (strpos($visitLog->state, '预约') !== false) { //2022-11-09 增加指派客户逻辑 同一个客户可以指派多人, 但是该客户在同一天内只能有一个预约,预约之后其他人就不能预约了,,,不同日期可以继续预约 $state = str_replace('预约', '', $visitLog->state); // 一天只能预约一个 $hadSubscribe = CustomersSubscribe::where([ ['customer_id', '=', $had['id']], //['employee_id|designer_id', '=', $had['employee_id']], ['subscribe_date', '=', $param['confirm_date']], ['state', '=', 0] ])->count(); // 查找是否已经预约 $typeSubscribe = CustomersSubscribe::where([ ['customer_id', '=', $had['id']], //['employee_id|designer_id', '=', $had['employee_id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0] ])->find(); if ($hadSubscribe) { Db::rollback(); return json(['code' => 1, 'msg' => '该客户在当前日期已有预约']); } elseif ($typeSubscribe) { Db::rollback(); return json(['code' => 1, 'msg' => '该客户已有' . $state . '预约, 预约日期' . $typeSubscribe->subscribe_date]); } else { $subscribe = [ 'customer_id' => $had['id'], 'subscribe_date' => $param['confirm_date'], 'employee_id' => $had->employee_id, 'designer_id' => $had->designer_id, 'type' => $state, 'aid' => $param['aid'] ?: $had->aid, 'org_id' => $had->org_id ]; CustomersSubscribe::create($subscribe); } } //当设为无效时,记录当前操作人跟进的最后一次状态,此处在公海列表处展示 if ($param['state'] == '无效') { $last_cvl = CustomerVisitLog::where('customer_id', $param['customer_id'])->with('employee')->order('addtime desc')->find(); //获取"无效"并进入公海之前的那次跟进记录的信息 if ($last_cvl) { $before_pool = [ 'name' => $last_cvl->employee->name, 'state' => $last_cvl->state, 'addtime' => $last_cvl->addtime ]; } else { $before_pool = [ 'name' => Employee::find($had['employee_id'])->value('name'), 'state' => '待确认', 'addtime' => $had->addtime ]; } // 该客户预约中的状态置为无效 CustomersSubscribe::where([['customer_id', '=', $param['customer_id']], ['state', '=', 0]])->save(['state' => -1]); //公海内是否存在该客户信息,存在则合并客户信息(phone、phone1、phone2) $orgids = orgSubIds($token['root_org']); $phone_arr = []; !empty(trim($had['phone'])) ? $phone_arr[] = cypherphone(trim($had['phone'])) : ''; !empty(trim($had['phone1'])) ? $phone_arr[] = cypherphone(trim($had['phone1'])) : ''; !empty(trim($had['phone2'])) ? $phone_arr[] = cypherphone(trim($had['phone2'])) : ''; $phone_arr = array_filter($phone_arr); $pool_condition = [ ['employee_id', '=', NULL], ['is_resource', '=', 0], ['org_id', 'in', $orgids], ['phone|phone1|phone2', 'in', $phone_arr] ]; $pool_crm = Customer::where($pool_condition)->column('id'); if (!empty($pool_crm)) { //公海存在则删除 Customer::where([['id', 'in', $pool_crm]])->update(['delete_time' => time()]); //关联回访记录修改 CustomerVisitLog::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]); CustomersSubscribe::where([['customer_id', 'in', $pool_crm]])->update(['is_merge' => 1, 'customer_id' => $had['id']]); } //增加无效记录 $vlglist = CustomerVisitLog::where([['customer_id', '=', $param['customer_id']], ['customer_employee_id', '=', $had['employee_id']],['state','not in',array_merge(CustomerVisitLog::changeState('待确认','chaos'), CustomerVisitLog::changeState('无效', 'chaos'))], ['save_portrait_field', 'NULL', null]])->count(); $invalidlog = [ 'customer_id'=> $param['customer_id'], 'employee_id'=> $had->employee_id, 'designer_id'=> $had->designer_id ? $had->designer_id : 0, 'org_id' => $had->org_id, 'root_id' => $token['root_org'], 'cus_addtime' => $had->sign_time, 'visitlog_id' => $visitLog->id, 'assigned_personnel' => $had->assigned_personnel ? $had->assigned_personnel : '', 'source_id' => $had->source_id ? $had->source_id : 0, 'status' => !empty($vlglist) ? 1 : 2, 'cus_employee_time'=> $had->employee_time, 'is_resource'=> $had->is_resource, 'valid_time' => $had->valid_time ]; CustomerInvalidLog::create($invalidlog); Customer::where('id', $param['customer_id'])->update(['state' => 7, 'employee_id' => NULL, 'org_id' => $had['org_id'], 'is_resource' => 0, 'before_pool' => json_encode($before_pool), 'designer_id' => NULL, 'ext->ext6' => '', 'employee_time' => NULL]); } // //如果签单,默认交定 /*if (strpos($param['state'], "签单") !== false) { trace(strpos($param['state'], "签单")); $lw[] = CustomerVisitLog::changeState(['state', '=', '交定']); $lw[] = ['customer_id', '=', $param['customer_id']]; $check = CustomerVisitLog::where($lw)->find(); if (!$check) { $l_visitlog = $visitLog->toArray(); unset($l_visitlog['id']); $l_visitlog['state'] = '交定'; $l_visitlog['remark'] = !empty($param['remark']) ? $param['remark'] : $employeeName . '默认客户状态为交定'; $mr = CustomerVisitLog::create(array_merge($param, $l_visitlog)); $this->preformance_tasks('已交定', $param['customer_id'], $param['money'], $mr->id, $token['employee_id']); //计算业绩 } }*/ if (in_array($param['state'], ['已到店', '已量房', '已到场'])) { $state = str_replace('已', '', $param['state']); $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0], ['employee_id', '=', $had['employee_id']]])->find(); if (!empty($subscribe)) { $subscribe->state = 1; $subscribe->save(); } elseif ($param['aid'] && in_array($param['state'], ['已到场'])) { //没有预约可以直接确认到场 $this->activityState($param, $had); } } if (in_array($param['state'], ['未到店', '未量房', '未到场'])) { $state = str_replace('未', '', $param['state']); $subscribe = CustomersSubscribe::where([['customer_id', '=', $had['id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0], ['employee_id', '=', $token['employee_id']]])->find(); if (!empty($subscribe)) { $subscribe->state = -1; $subscribe->save(); } //取消预约后,待回访状态也要取消 $had->return_visit = 0; $had->save(); } //增加经纪人送积分功能 if ($had->agents_id && in_array($param['state'], ['已到店', '已交定', '已签单'])) { $this->agents_integral($had->agents_id, $param['state'], $had->id); } // 微爆活动 if (in_array($param['state'], ['已到店', '已量房', '已到场', '已交定', '已签单'])) { $activity_data['customer_id'] = $param['customer_id']; $activity_data['employee_id'] = $had->employee_id; $activity_data['org_id'] = $had->org_id; switch ($param['state']) { case '已到店': $activity_data['type'] = 2; break; case '已量房': $activity_data['type'] = 3; break; case '已交定': $activity_data['type'] = 4; break; case '已签单': $activity_data['type'] = 5; break; case '已到场': $activity_data['type'] = 7; break; default: break; } WechatActivityIntegral::addIntegral($activity_data, $token['root_org']); } Db::commit(); Console::call('download', ['customer']); Console::call('download', ['customer1']); //2022-10-28 更新交定/签单凭证 if (in_array($param['state'], ['已交定', '已签单'])) { $deliveryType = $param['state'] == '已交定' ? 'delivery' : 'sign'; Console::call('download', [$deliveryType]); } Console::call('medal', ['visit_log', (string)$this->request->token['employee_id'], (string)$this->request->token['root_org']]); //勋章 //经理回访后修改客户的待回访的状态 Customer::where('id', $had->id)->update(['return_visit' => 0]); $had['name'] = !empty($had['name']) ? $had['name'] : ''; if (in_array($param['state'], $dd_state)) { // 发送管理层模板消息 $msg = ['first'=>'行为通知', 'keyword1'=>'客户确认到店', 'keyword2'=>"客户".$had['name']."(".$had['phone'].")确认到店", 'keyword3'=>date('Y/m/d'), 'remark'=>'请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); } if ($state == '已签单') { // 发送管理层模板消息 $msg = ['first'=>'行为通知', 'keyword1'=>'客户签单', 'keyword2'=>"客户".$had['name']."(".$had['phone'].")签单", 'keyword3'=>date('Y/m/d'), 'remark'=>'请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); } return json(['code' => 0, 'msg' => '跟进成功']); } /** * 经纪人送积分功能 */ public function agents_integral($agentid, $state, $customer_id) { $token = $this->request->token; $agent_data = AgentUser::where('id', $agentid)->field('agent_name,type')->find(); if ($state == '已到店') { $code = 'daodian_integral'; $sta_type = 1; } if ($state == '已交定') { $code = 'jiaoding_integral'; $sta_type = 2; } if ($state == '已签单') { $code = 'qiandan_integral'; $sta_type = 3; } //添加与经纪人相关记录 $you = AgentCustomerLog::where([['agent_id', '=', $agentid], ['type', '=', $sta_type], ['customer_id', '=', $customer_id]])->count(); if (empty($you)) { $add = array( 'agent_id' => $agentid, 'type' => $sta_type, 'typename' => $state, 'addtime' => time(), 'customer_id' => $customer_id, 'agent_type' => $agent_data['type'], 'status' => 1 ); AgentCustomerLog::insert($add); } if ($agent_data['type'] == 2) return; //如果是网红经纪人直接返回 $jifen = CreditsSetting::where(['code' => $code, 'root_id' => $token['root_org']])->value('value'); /*if($agent_data['type']==2){ $jifen=0; }*/ $ye = AgentIntegral::where(['customer_id' => $customer_id, 'agent_id' => $agentid])->column('state'); //var_dump(!in_array($state,$ye)); //exit; if (!in_array($state, $ye) && $agent_data['type'] == 1) { $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen ? $jifen : 1, 'addtime' => time(), 'state' => $state, 'customer_id' => $customer_id ); //var_dump($add); //exit; AgentIntegral::insert($add); } if ($state == '已交定' && !in_array('已到店', $ye)) { $jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen ? $jifen : 1, 'addtime' => time(), 'state' => '已到店', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } if ($state == '已签单' && !in_array('已到店', $ye)) { $jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen ? $jifen : 1, 'addtime' => time(), 'state' => '已到店', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } if ($state == '已签单' && !in_array('已交定', $ye)) { $jifen = CreditsSetting::where(['code' => 'jiaoding_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen ? $jifen : 1, 'addtime' => time(), 'state' => '已交定', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } } //计算业绩任务 public function preformance_tasks($state, $customer_id, $money = 0, $vislog_id, $employee_id) { $token = $this->request->token; $info = Customer::where('id', $customer_id)->find(); //业绩算客户所属员工的 $token['employee_id'] = Customer::where('id', $customer_id)->value('employee_id'); //防止后台切换部门 $token['org_id'] = Employee::where('id', $token['employee_id'])->value('org_id'); if ($state == '已交定') { $w2[] = ['customer_id', '=', $customer_id]; $w2[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]; $w2[] = ['customer_employee_id', '=', $token['employee_id']]; $w2[] = ['customer_org_id', '=', $token['org_id']]; //切换部门重复交定仍然算业绩 $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩 if ($check == 1) { $time = date('Y-m-d H:i:s'); //查询进行中的指派到所属部门的所有进度 // $w[] = ['org_id','=',$token['org_id']]; $w[] = ['root_id', '=', $token['root_org']]; $w[] = ['start_date', '<=', $time]; $w[] = ['end_date', '>=', $time]; $w[] = ['is_deposit', '=', 1]; $preformance_tasks = PreformanceTasksModel::where($w)->column('id'); $w1[] = ['root_id', '=', $token['root_org']]; $w1[] = ['org_id', '=', $token['org_id']]; $w1[] = ['performance_tasks_id', 'in', $preformance_tasks]; $w1[] = ['is_deposit', '=', 1]; //指派到自己部门 $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*'); $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')]; $model = PreformanceTasksModel::where($w4)->column('*'); foreach ($model as $k => $v) { $u = []; $u['ok_deposit'] = $v['ok_deposit'] + 1; $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id; PreformanceTasksModel::where('id', $v['id'])->update($u); unset($u); } PreformanceTasksOrg::where($w1)->inc('ok_deposit')->update(); } } elseif ($state == '已签单') { $w2[] = ['customer_id', '=', $customer_id]; $w2[] = ['state', 'in', CustomerVisitLog::changeState('已签单', 'chaos')]; $w2[] = ['customer_employee_id', '=', $token['employee_id']]; $check = CustomerVisitLog::where($w2)->count(); //没有交定过计算业绩 if ($check == 1) { $time = date('Y-m-d H:i:s'); //查询进行中的指派到所属部门的所有进度 // $w[] = ['org_id','=',$token['org_id']]; $w[] = ['root_id', '=', $token['root_org']]; $w[] = ['start_date', '<=', $time]; $w[] = ['end_date', '>=', $time]; $w[] = ['is_money', '=', 1]; $preformance_tasks = PreformanceTasksModel::where($w)->column('id'); $w1[] = ['root_id', '=', $token['root_org']]; $w1[] = ['org_id', '=', $token['org_id']]; $w1[] = ['performance_tasks_id', 'in', $preformance_tasks]; $w1[] = ['is_money', '=', 1]; //指派到自己部门 $pid = PreformanceTasksOrg::where($w1)->group('performance_tasks_id')->column('*'); $w4[] = ['id', 'in', array_column($pid, 'performance_tasks_id')]; $model = PreformanceTasksModel::where($w4)->column('*'); foreach ($model as $k => $v) { $u = []; $u['ok_money'] = $v['ok_money'] + $money; $u['customer_visit_log_id'] = $v['customer_visit_log_id'] ? $v['customer_visit_log_id'] . ',' . $vislog_id : $vislog_id; PreformanceTasksModel::where('id', $v['id'])->update($u); unset($u); } PreformanceTasksOrg::where($w1)->inc('ok_money', $money)->update(); } } return 1; } /** * 没有预约活动,跟进时传了aid和state='预约活动' * 没有预约可以直接确认到场 * 补全数据添加预约和的追踪记录 */ public function activityState($param, $had) { $employeeTypeName = $this->request->token['org_type'] == 2 ? '设计师' : '销售'; // 备注 $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name'); $remark = $param['remark']; if (empty($remark)) { $remark = $employeeTypeName . $employeeName . '对客户进行了回访'; } //预约记录 $visitLog = [ 'customer_id' => $had->id, 'type' => $param['type'], 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : date('Y-m-d'), 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'remark' => $remark, 'state' => 6, 'weixin_media' => '', 'media_id' => '', 'starts' => $param['starts'], 'money' => $param['money'], 'confirm_date' => $param['confirm_date'], 'org_id' => $this->request->token['org_id'], 'aid' => $param['aid'], 'weixin_media1' => '', 'media_id1' => '', 'customer_employee_id' => $had->employee_id, 'customer_org_id' => Employee::where('id', $had->employee_id)->value('org_id') ]; CustomerVisitLog::create($visitLog); // $subscribe = [ 'customer_id' => $had['id'], 'subscribe_date' => $param['confirm_date'], 'employee_id' => $had->employee_id, 'designer_id' => $had->designer_id, 'type' => 2, 'aid' => $param['aid'], 'org_id' => $visitLog['customer_org_id'], 'state' => 1 ]; CustomersSubscribe::create($subscribe); return 1; } /** * 死单客户列表 */ public function dieCustomer() { $where[] = ['org_id', 'in', $this->team_orgs]; $status = input('status', 1, 'intval'); if ($status == 1) { //待审核 $where[] = ['died', '=', 1]; } else { $where[] = ['died', '=', 2]; } $name = input('name', '', 'trim'); if ($name) { $where[] = ['name', 'like', '%' . $name . '%']; } $page = input('page', 1, 'intval'); $limit = input('limit', 10, 'intval'); $list = Customer::where($where)->order('addtime desc')->page($page, $limit)->select()->toArray(); return json(['code' => 0, 'data' => $list]); } /** * 审核死单客户 */ public function checkDieCustomer() { $customer_id = input('customer_id', '', 'intval'); $check = input('check', '', 'intval'); $find = Customer::where('id', '=', $customer_id)->findOrEmpty(); if ($find->isEmpty()) { return json(['code' => 1, 'msg' => '审核失败']); } $sub_employee = Employee::where('org_id', 'in', $this->team_orgs)->column('id'); if (!in_array($find['employee_id'], $sub_employee)) { return json(['code' => 1, 'msg' => '审核失败']); } if ($check) { $employee = Employee::where('id', $find['employee_id'])->findOrEmpty(); Db::startTrans(); $result = Customer::where('id', '=', $customer_id)->save(['died' => 2]); if ($result === false) { Db::rollback(); return json(['code' => 1, 'msg' => '审核失败']); } $param = [ 'customer_id' => $customer_id, 'type' => 1, 'remark' => '死单', 'employee_id' => $find['employee_id'], 'user_id' => $employee['uid'], 'state' => '' ]; CustomerVisitLog::create($param); $msg = '您申请的客户死单已通过。'; } else { $result = Customer::where('id', '=', $customer_id)->save(['died' => 0]); if ($result === false) { Db::rollback(); return json(['code' => 1, 'msg' => '审核失败']); } $msg = '您申请的客户死单未通过。'; } event(new Msg($find['employee_id'], $msg, 'customer', $customer_id)); Db::commit(); return json(['code' => 0, 'msg' => '操作成功']); } /** * 重新激活死单客户 */ public function activeDieCustomer() { $customer_id = input('customer_id', '', 'intval'); $find = Customer::where('id', '=', $customer_id)->findOrEmpty(); if ($find->isEmpty()) { return json(['code' => 1, 'msg' => '激活失败']); } $sub_employee = Employee::where('org_id', 'in', $this->team_orgs)->column('id'); if (!in_array($find['employee_id'], $sub_employee)) { return json(['code' => 1, 'msg' => '激活失败']); } Db::startTrans(); $result = Customer::where('id', '=', $customer_id)->save(['died' => 0]); if ($result === false) { Db::rollback(); return json(['code' => 1, 'msg' => '激活失败']); } $param = [ 'customer_id' => $customer_id, 'type' => 1, 'remark' => '客户激活', 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '' ]; CustomerVisitLog::create($param); event(new Msg($find['employee_id'], '您的死单客户已重新激活。', 'customer', $customer_id)); Db::commit(); return json(['code' => 0, 'msg' => '操作成功']); } /** * 量房率,到店率,交定率,转单率 * 全部,团队,业务员 */ public function teamRate() { $token = $this->request->token; $param = $this->request->only(['org_id' => 0, 'eid' => 0]); if (!$param['org_id'] && !$param['eid']) { $orgids = orgSubIds($token['root_org']); $where = [ ['org_id', 'in', $orgids], ['uid', '>', 0], ['state', '=', '在职'] ]; } elseif ($param['eid']) { $where = [ ['id', '=', $param['eid']], ['root_id', '=', $token['root_org']], ['uid', '>', 0], ['state', '=', '在职'] ]; } elseif ($param['org_id']) { $orgids = orgSubIds($param['org_id']); $where = [ ['org_id', 'in', $orgids], ['uid', '>', 0], ['state', '=', '在职'] ]; } $eids = Employee::where($where)->column('id'); $cid = Customer::where([['employee_id', 'in', $eids]])->column('id'); $state = CustomerVisitLog::changeState('已到店', 'chaos'); $state1 = CustomerVisitLog::changeState('已交定', 'chaos'); $state2 = CustomerVisitLog::changeState('已量房', 'chaos'); $state3 = CustomerVisitLog::changeState('已签单', 'chaos'); $query = [ ['customer_id', 'in', $cid], ['state', 'in', array_merge($state, $state1, $state2, $state3)] ]; $vis = CustomerVisitLog::where($query)->column('customer_id,state'); $data['store_grawth'] = $data['room_grawth'] = $data['dep_grawth'] = $data['sign_grawth'] = []; foreach ($vis as $v) { if (in_array($v['state'], $state)) { $data['store_grawth'][] = $v['customer_id']; } elseif (in_array($v['state'], $state1)) { $data['dep_grawth'][] = $v['customer_id']; } elseif (in_array($v['state'], $state2)) { $data['room_grawth'][] = $v['customer_id']; } elseif (in_array($v['state'], $state3)) { $data['sign_grawth'][] = $v['customer_id']; } } if ($cid) { $count = count($cid); $data['store_grawth'] = round(count(array_unique($data['store_grawth'])) / $count * 100, 2) . '%'; $data['dep_grawth'] = round(count(array_unique($data['dep_grawth'])) / $count * 100, 2) . '%'; $data['room_grawth'] = round(count(array_unique($data['room_grawth'])) / $count * 100, 2) . '%'; $data['sign_grawth'] = round(count(array_unique($data['sign_grawth'])) / $count * 100, 2) . '%'; } else { $data['store_grawth'] = $data['room_grawth'] = $data['dep_grawth'] = $data['sign_grawth'] = '0%'; } return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']); } /** * 全部,团队,业务员 */ public function teamStatistics() { $token = $this->request->token; $param = $this->request->only(['org_id' => 0, 'page' => 1, 'limit' => 10, 'order' => '', 'sc' => 'desc']); $root_id = $param['org_id']==-1 ? $token['root_org'] : ($param['org_id'] ?: $token['org_id']); $info = Org::where([['id', '=', $root_id], ['status', '=', 1], ['path', 'like', $token['root_org'] . '-%']])->findOrEmpty(); if ($info->isEmpty()) return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']); // 获取部门列表(全部子部门) $childList = Org::where([['path', 'like', $info->path . '%'], ['id', '<>', $root_id]])->column('id,path'); // 子部门获取 $closetChildList = Org::where([['pid', '=', $info->id]])->column('name', 'id'); $childIdList = array_column($childList, 'id'); /** 数据获取 */ // 员工数量 $OrgEmployeeNum = Employee::where([['org_id', 'in', $childIdList], ['state', '=', '在职'], ['uid', '>', 0]])->group('org_id')->column('count(id) count', 'org_id'); // 客户数量 $orgCustomerNum = Customer::where([['employee_id', '>', 0], ['org_id', 'in', $childIdList]])->group('org_id')->column('count(id)', 'org_id'); //2023-03-07 有效状态修改 $state1 = Customer::changeState('待确认', 'chaos'); $state2 = Customer::changeState('无效', 'chaos'); $queryv1 = [['state', 'not in', array_merge($state1,$state2)],['employee_id', '>', 0],['org_id', 'in', $childIdList]]; $queryv2 = [['state', 'in',$state1],['crm_res_id','null',null],['employee_id', '>', 0],['org_id', 'in', $childIdList]]; $youxiaoNum = Customer::whereOr([$queryv1,$queryv2])->group('org_id')->column('count(id)', 'org_id'); // 有效 $state1 = CustomerVisitLog::changeState('未到访', 'chaos'); $state2 = CustomerVisitLog::changeState('已到访', 'chaos'); $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $state5 = CustomerVisitLog::changeState('交定', 'chaos'); $state6 = CustomerVisitLog::changeState('签单', 'chaos'); $state7 = CustomerVisitLog::changeState('已到场', 'chaos'); $stateList = array_merge($state1, $state2, $state3, $state4, $state5, $state6, $state7); // $stateStr = implode('|', $stateList); // $youxiaoNum = CustomerState::where([ // ['employee_id', '>', 0], // ['org_id', 'in', $childIdList], // ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] // ])->group('org_id')->column('count(id)', 'org_id'); // 加微 $wechatNum = Customer::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['ext', 'REGEXP', " 'value\": ?\"[0-9|\/|\-]+\", \"keyname\": \"add_wechat_time\"'"] ])->group('org_id')->column('count(id)', 'org_id'); // 业绩 $yejiNum = Customer::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList] ])->group('org_id')->column('sum(signed_money) money', 'org_id'); // 量房客户 $stateStr = implode('|', $state3); $liangfangNum = CustomerState::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] ])->group('org_id')->column('count(id)', 'org_id'); // 到店 $stateStr = implode('|', $state4); $daodianNum = CustomerState::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] ])->group('org_id')->column('count(id)', 'org_id'); // 到场 $stateStr = implode('|', $state7); $daochangNum = CustomerState::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] ])->group('org_id')->column('count(id)', 'org_id'); // 交定 $stateStr = implode('|', $state5); $jiaodingNum = CustomerState::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] ])->group('org_id')->column('count(id)', 'org_id'); // 签单 $stateStr = implode('|', $state6); $signNum = CustomerState::where([ ['employee_id', '>', 0], ['org_id', 'in', $childIdList], ['state', 'REGEXP', '(^|,)(' . $stateStr . ')(,|$)'] ])->group('org_id')->column('count(id)', 'org_id'); // 预约到店/量房/到场 $yuyue1 = CustomersSubscribe::where([ ['org_id', 'in', $childIdList], ['state', '=', 0], ['type', '=', 1] ])->group('org_id')->column('count(id)', 'org_id'); $yuyue2 = CustomersSubscribe::where([ ['org_id', 'in', $childIdList], ['state', '=', 0], ['type', '=', 2] ])->group('org_id')->column('count(id)', 'org_id'); $yuyue3 = CustomersSubscribe::where([ ['org_id', 'in', $childIdList], ['state', '=', 0], ['type', '=', 3] ])->group('org_id')->column('count(id)', 'org_id'); // 数量整合到部门中 $rdata = []; $pidList= array_keys($closetChildList); foreach ($childList as $cOrg) { $pathList = explode('-', trim($cOrg['path'], '-')); $pid = $cOrg['id']; foreach($pathList as $p){ if(in_array($p, $pidList)) { $pid = $p; break; } } if (!isset($rdata[$pid])) $rdata[$pid] = [ 'employee_count' => 0, 'customer_count' => 0, 'valid_count' => 0, 'wechat_count' => 0, 'yeji' => 0, 'lf_count' => 0, 'st_count' => 0, 'sign_count' => 0, 'dc_count' => 0, 'dep_count' => 0, 'yydd_count' => 0, 'yylf_count' => 0, 'yywc_count' => 0, 'name' => $closetChildList[$pid] ]; // 员工数量 $rdata[$pid]['employee_count'] += isset($OrgEmployeeNum[$cOrg['id']]) ? $OrgEmployeeNum[$cOrg['id']] : 0; // 客户数量 $rdata[$pid]['customer_count'] += isset($orgCustomerNum[$cOrg['id']]) ? $orgCustomerNum[$cOrg['id']] : 0; // 有效 $rdata[$pid]['valid_count'] += isset($youxiaoNum[$cOrg['id']]) ? $youxiaoNum[$cOrg['id']] : 0; // 加微 $rdata[$pid]['wechat_count'] += isset($wechatNum[$cOrg['id']]) ? $wechatNum[$cOrg['id']] : 0; // 业绩 $rdata[$pid]['yeji'] += isset($yejiNum[$cOrg['id']]) ? $yejiNum[$cOrg['id']] : 0; // 量房客户 $rdata[$pid]['lf_count'] += isset($liangfangNum[$cOrg['id']]) ? $liangfangNum[$cOrg['id']] : 0; // 到店 $rdata[$pid]['st_count'] += isset($daodianNum[$cOrg['id']]) ? $daodianNum[$cOrg['id']] : 0; // 到场 $rdata[$pid]['dc_count'] += isset($daochangNum[$cOrg['id']]) ? $daochangNum[$cOrg['id']] : 0; // 交定 $rdata[$pid]['dep_count'] += isset($jiaodingNum[$cOrg['id']]) ? $jiaodingNum[$cOrg['id']] : 0; // 签单 $rdata[$pid]['sign_count'] += isset($signNum[$cOrg['id']]) ? $signNum[$cOrg['id']] : 0; //预约到店 $rdata[$pid]['yydd_count'] += isset($yuyue1[$cOrg['id']]) ? $yuyue1[$cOrg['id']] : 0; //预约量房 $rdata[$pid]['yylf_count'] += isset($yuyue2[$cOrg['id']]) ? $yuyue2[$cOrg['id']] : 0; //预约到外场 $rdata[$pid]['yywc_count'] += isset($yuyue3[$cOrg['id']]) ? $yuyue3[$cOrg['id']] : 0; } $list = $rdata; //排序 业绩 加微 已量房 已到店 已交定 已签单 $arr = ['业绩'=>'yeji','加微'=>'wechat_count','已量房'=>'lf_count','已到店'=>'st_count','已交定'=>'dep_count','已签单'=>'sign_count']; if ($param['order'] && isset($arr[$param['order']])) { $field = $arr[$param['order']]; $sc = $param['sc'] == 'desc' ? SORT_DESC : SORT_ASC; array_multisort(array_column($list,$field), $sc, $list); } $count = count($list); $list = array_slice($list, ($param['page'] - 1) * $param['limit'], $param['limit']); $data = []; foreach ($list as $key => $value) { $value['yeji'] = $value['yeji'] ? round($value['yeji']/10000,2).'万元' : 0; $data[] = $value; } return json(['code' => 0, 'data' => $data, 'count' => $count, 'msg' => '获取成功']); } /** * 部门直属人员统计 */ public function OrgEmployeeStatistics() { $token = $this->request->token; $param = $this->request->only(['org_id' => 0, 'page' => 1, 'limit' => 10, 'order' => '', 'sc' => 'desc']); $root_id = ($param['org_id']==-1) ? $token['root_org'] : ($param['org_id'] ?: $token['org_id']); $info = Org::where([['id', '=', $root_id], ['status', '=', 1]])->findOrEmpty(); if ($info->isEmpty()) return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']); //部门直属人员 if (empty($param['order']) || empty($param['sc'])) { $list = Employee::where('org_id', $root_id)->where([['state', '=', '在职'], ['uid', '>', 0]])->page($param['page'], $param['limit'])->column('id,name,uid'); $count = Employee::where('org_id', $root_id)->where([['state', '=', '在职'], ['uid', '>', 0]])->count(); } else { $list = Employee::where('org_id', $root_id)->where([['state', '=', '在职'], ['uid', '>', 0]])->column('id,name,uid'); $sc = $param['sc'] == 'desc' ? SORT_DESC : SORT_ASC; //排序 $ids = array_column($list, 'id'); if ($param['order'] == '业绩') { //业绩排序 $order = Customer::where([['employee_id', 'in', $ids], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->group('employee_id')->column('sum(signed_money) money', 'employee_id'); } elseif ($param['order'] == '加微') { //加微数量排序 $order = Customer::where([['employee_id', 'in', $ids], ['ext', 'like', '%add_wechat_time%'], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('employee_id,ext'); $orders = []; foreach ($order as $v) { $json = json_decode($v['ext'], true); foreach ($json as $v2) { if ($v2['keyname'] == 'add_wechat_time' && !empty($v2['value'])) { @$orders[$v['employee_id']] += 1; } } } $order = $orders; } elseif (in_array($param['order'], ['已量房', '已到店', '已交定', '已签单'])) { $cid = Customer::where([['employee_id', 'in', $ids], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id,employee_id'); $cids = array_column($cid, 'id'); $state = CustomerVisitLog::changeState($param['order'], 'chaos'); $vislog = CustomerVisitLog::where([['state', 'in', $state], ['customer_id', 'in', $cids]])->group('customer_id')->column('customer_id'); $order = []; foreach ($cid as $k => $v) { if (in_array($v['id'], $vislog)) @$order[$v['employee_id']] += 1; } } else { return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']); } foreach ($list as $k => $v) { $list[$k]['order'] = isset($order[$v['id']]) ? $order[$v['id']] : 0; $list[$k]['order_type'] = $param['order']; } //排序 array_multisort(array_column($list, 'order'), $sc, $list); $count = count($list); $list = array_slice($list, ($param['page'] - 1) * $param['limit'], $param['limit']); } //////// $eids = array_column($list, 'id'); //业绩 if ($param['order'] == '业绩') { $yeji = $order; } else { $yeji = Customer::where([['employee_id', 'in', $eids], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->group('employee_id')->column('sum(signed_money) money', 'employee_id'); } //加微客户 if ($param['order'] == '加微') { $wechat = $order; } else { $order = Customer::where([['employee_id', 'in', $eids], ['ext', 'like', '%add_wechat_time%'], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('employee_id,ext'); $orders = []; foreach ($order as $v) { $json = json_decode($v['ext'], true); foreach ($json as $v2) { if ($v2['keyname'] == 'add_wechat_time' && !empty($v2['value'])) { @$orders[$v['employee_id']] += 1; } } } $wechat = $orders; } //有效 量房 到店 签单 // $customer_ids = Customer::where([['employee_id', 'in', $eids], ['died', '<>', 2], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('employee_id,id'); // $org_cus = []; // foreach ($customer_ids as $k3 => $v3) { // @$org_cus[$v3['employee_id']][] = $v3['id']; // } //2023-03-07 有效状态修改 $state1 = Customer::changeState('待确认', 'chaos'); $state2 = Customer::changeState('无效', 'chaos'); $queryv1 = [['state', 'not in', array_merge($state1,$state2)],['employee_id', 'in', $eids], ['died', '<>', 2]]; $queryv2 = [['state', 'in',$state1],['crm_res_id','null',null],['employee_id', 'in', $eids], ['died', '<>', 2]]; $customer_ids = Customer::whereOr([$queryv1,$queryv2])->column('employee_id,id'); $org_cus = []; foreach ($customer_ids as $k3 => $v3) { @$org_cus[$v3['employee_id']][] = $v3['id']; } $valid = array_column($customer_ids,'id'); $state1 = CustomerVisitLog::changeState('未到访', 'chaos'); $state2 = CustomerVisitLog::changeState('已到访', 'chaos'); $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $state5 = CustomerVisitLog::changeState('交定', 'chaos'); $state6 = CustomerVisitLog::changeState('签单', 'chaos'); $state7 = CustomerVisitLog::changeState('已到场', 'chaos'); $vis_where[] = ['customer_id', 'in', array_column($customer_ids, 'id')]; $vis_where[] = ['state', 'in', array_merge($state1, $state2, $state3, $state4, $state5, $state6, $state7)]; // $vis_where[] = ['employee_id', 'in', $eids]; $vislog_list = CustomerVisitLog::where($vis_where)->column('customer_id,state'); // $valid = array_column($vislog_list, 'customer_id'); //签单 量房 到店 $sign = $lf = $st = $dep = $dc = []; foreach ($vislog_list as $v4) { if (in_array($v4['state'], $state6)) { $sign[] = $v4['customer_id']; } elseif (in_array($v4['state'], $state3)) { $lf[] = $v4['customer_id']; } elseif (in_array($v4['state'], $state4)) { $st[] = $v4['customer_id']; } elseif (in_array($v4['state'], $state5)) { $dep[] = $v4['customer_id']; } elseif (in_array($v4['state'], $state7)) { $dc[] = $v4['customer_id']; } } $cids = []; foreach ($list as $k5 => $v5) { //客户id $list[$k5]['cid'] = $cid = isset($org_cus[$v5['id']]) ? $org_cus[$v5['id']] : []; // /客户数量 $list[$k5]['customer_count'] = count($cid); //有效 $list[$k5]['valid_count'] = $cid ? count(array_unique(array_intersect($cid, $valid))) : 0; //加微 $list[$k5]['wechat_count'] = isset($wechat[$v5['id']]) ? $wechat[$v5['id']] : 0; //业绩 $list[$k5]['yeji'] = isset($yeji[$v5['id']]) ? round($yeji[$v5['id']] / 10000, 2) . '万元' : ''; //量房客户 $list[$k5]['lf_count'] = $cid ? count(array_unique(array_intersect($cid, $lf))) : 0; //到店 $list[$k5]['st_count'] = $cid ? count(array_unique(array_intersect($cid, $st))) : 0; //签单 $list[$k5]['sign_count'] = $cid ? count(array_unique(array_intersect($cid, $sign))) : 0; //交定 $list[$k5]['dep_count'] = $cid ? count(array_unique(array_intersect($cid, $dep))) : 0; //外场到场 $list[$k5]['dc_count'] = $cid ? count(array_unique(array_intersect($cid, $dc))) : 0; $cids = array_merge($cid, $cids); } //预约 $sub = CustomersSubscribe::where([['customer_id', 'in', $cids], ['state', '=', 0], ['type', 'in', [1, 2, 3]]])->column('customer_id,type'); $sub1 = $sub2 = $sub3 = []; foreach ($sub as $key => $val) { $val['type'] == 1 ? $sub1[] = $val['customer_id'] : ($val['type'] == 3 ? $sub3[] = $val['customer_id'] : $sub2[] = $val['customer_id']); } $uids = array_column($list, 'uid'); $headerimgs = User::where([['id', 'in', $uids]])->column('headimgurl', 'id'); foreach ($list as $ke => $va) { //预约到店 $list[$ke]['yydd_count'] = $va['cid'] ? count(array_unique(array_intersect($va['cid'], $sub1))) : 0; //预约量房 $list[$ke]['yylf_count'] = $va['cid'] ? count(array_unique(array_intersect($va['cid'], $sub3))) : 0; //预约到外场 $list[$ke]['yywc_count'] = $va['cid'] ? count(array_unique(array_intersect($va['cid'], $sub2))) : 0; unset($list[$ke]['cid']); $list[$ke]['img'] = $headerimgs[$va['uid']]; } return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']); } }