token['root_org']; $empcrm_repeat[] = ['root_id', '=', $root_id]; $empcrm_repeat[] = ['name', '=', 'empcrm_customer_repeat']; $repeat_setting = Setting::where($empcrm_repeat)->findOrEmpty(); $emp_org = request()->token['org_id']; if ($id) { $this_customer = Customer::find($id); } else { $this_customer = null; } foreach ($pharr as $val) { if (empty($val)) continue; // 先判断公海 只有添加时候判断 if (empty($id)) { $poolExist = Customer::where([ ['phone|phone1|phone2', '=', cypherphone(trim($val))], ['org_id', '=', $emp_org], ['employee_id', 'null', null], ['is_resource', '=', 0] ])->column('id'); if (!empty($poolExist)) { $poolCrmIdStr = implode(',', $poolExist); return json(['code' => 3, 'data' => $poolCrmIdStr, 'msg' => '录入失败:客户信息已在公海中。']); } } // 新建档,检测手机号是否重复 $customerExist = Customer::where([ ['phone|phone1|phone2', '=', cypherphone(trim($val))], ['org_id', 'in', $org_id], ['employee_id', '>', 0] // 员工客户 ])->where( function ($query) { $not_sure = Customer::changeState('待确认', 'chaos'); $or1[] = ['crm_res_id', 'null', null]; $or2[] = ['crm_res_id', '>', 0]; $or2[] = ['state', 'not in', $not_sure]; $query->whereOr([$or1, $or2]); } )->field('id,employee_id,is_resource,org_id,source_id')->select()->toArray(); $id_arr = array_column($customerExist, 'id'); $employee_id_arr = array_column($customerExist, 'employee_id'); if (empty($id)) { // 对非当前业务员名下重复客户不在判断 if (in_array($employee_id, $employee_id_arr)) { // 是否已存在为自己的客户 return json(['code' => 2, 'msg' => '录入失败。' . $val . '已经是您的客户。']); } } else { if (!in_array($id, $id_arr) && in_array($employee_id, $employee_id_arr)) { // 是否已存在为自己的客户 return json(['code' => 2, 'msg' => '录入失败。' . $val . '已经是您的客户。']); } } //判断同部门 if (empty($id)) { // 添加时候按员工所属部门判断 if (!$repeat_setting->isEmpty()) { $repeat_org = explode(',', $repeat_setting['content']); if (!in_array($emp_org, $repeat_org)) { // 不属于判重部门 $repeat_org = [$emp_org]; // 判断自身部门 } } else { $repeat_org = [$emp_org]; // 判断自身部门 } } else { // 编辑时候按客户所属部门判断 if (!$repeat_setting->isEmpty()) { $repeat_org = explode(',', $repeat_setting['content']); if (!in_array($this_customer['org_id'], $repeat_org)) { $repeat_org = [$this_customer['org_id']]; } } else { $repeat_org = [$this_customer['org_id']]; } } // 需要验证 if (!empty($customerExist)) { foreach ($customerExist as $ex) { if (in_array($ex['org_id'], $repeat_org) && $ex['employee_id'] != $employee_id) { //查询撞单客户渠道 $source_name = ''; if ($ex['source_id']) { $source = CustomerSource::where(['id' => $ex['source_id']])->value('source'); $source_name = $source . '渠道客户'; } // 为了避免开启撞单之前都已经重复的情况,所以要查一下这个id的现数据 if ($id) { if ($this_customer) { $this_customer_phone = array_filter([$this_customer['phone'], $this_customer['phone1'], $this_customer['phone2']]); if (!in_array($val, $this_customer_phone)) { // 不是原来的客户手机号,编辑时候判断撞单 $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name'); return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法录入']); } } } else { $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name'); return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法录入']); } } } } } } /** * 客户建档 */ public function add() { $token = $this->request->token; $data = $this->request->only(['ext', 'name', 'phone', 'sex', 'level', 'state', 'last_contact_date' => date('Y-m-d'), 'product', 'source_id', 'deposit_money' => null, 'signed_money' => null, 'external_userid', 'phone1', 'phone2', 'agents_id']); // $data['employee_id'] = $token['employee_id']; // $data['org_id'] = $token['org_id']; $id = $this->request->param('id'); $aid = $this->request->param('aid') ?: 0; //状态为预约活动时预约的活动id $activity_id = $this->request->param('activity_id') ?: 0; //从活动邀约列表进入客户详情 活动id //在活动列表中编辑客户信息 if ($id && $activity_id) { $aw[] = ['customer_id', '=', $id]; $aw[] = ['aid', '>', 0]; $aw[] = CustomerVisitLog::changeState(['state', '=', '交定']); $info = CustomerVisitLog::with(['activity' => function ($query) { $query->visible(['title']); }])->where($aw)->find(); if ($info && isset($info['activity']['title']) && $info['activity']['title'] && $activity_id != $info['aid']) { return json(['code' => 1, 'msg' => '客户已经在《' . $info['activity']['title'] . '》活动中交定,请在此活动中修改状态']); } } $clueId = $this->request->param('clue_id'); $customer = new Customer(); // 添加客户需要查询所有部门id; // 设计师能否报备、获取客户 if (empty($id)) { $de_where[] = ['root_id', '=', $token['root_org']]; $de_where[] = ['name', '=', 'designer_get_customer']; $info_de_where = Setting::where($de_where)->findOrEmpty(); if (!$info_de_where->isEmpty() && $token['org_type'] == 2) { if ((int)$info_de_where['content'] != 1) { return json(['code' => 1, 'msg' => '您的身份为设计师,无法报备客户']); } } } if (!empty($data['phone']) && !empty($data['phone1']) && $data['phone'] == $data['phone1']) { return json(['code' => 1, 'msg' => '手机号不能重复']); } if (!empty($data['phone1']) && !empty($data['phone2']) && $data['phone1'] == $data['phone2']) { return json(['code' => 1, 'msg' => '手机号不能重复']); } if (!empty($data['phone']) && !empty($data['phone2']) && $data['phone'] == $data['phone2']) { return json(['code' => 1, 'msg' => '手机号不能重复']); } $orgids = orgSubIds($token['root_org']); $pharr = [ $data['phone'], !empty($data['phone1']) ? $data['phone1'] : '', !empty($data['phone2']) ? $data['phone2'] : '' ]; //判断手机号是否在公海,资源库,已建档,回收站 if (!$id) { $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id']); if (!empty($tips)) return $tips; } else { $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id'], $id); if (!empty($tips)) return $tips; } if ($id) { $sub_org = orgSubIds($token['org_id']); $sub_employee = Employee::where([['org_id', 'in', $sub_org], ['state', '=', '在职'], ['uid', '>', 0]])->column('id'); $where_c1[] = ['id', '=', $id]; $orgids = orgSubIds($token['root_org']); $where_c1[] = ['org_id', 'in', $orgids]; //$where_c1[] = ['employee_id|designer_id', 'in', $sub_employee]; $customer = Customer::where($where_c1)->where(function ($query) use ($sub_employee) { foreach ($sub_employee as $v) { $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]); } })->find(); if (empty($customer)) return json(['code' => 1, 'msg' => '数据不存在']); //记录修改客户基本信息 $this->cusbasic_field_savelog($data, $customer); if (!empty($data['state'])) { $state = Customer::changeState($data['state']); if (empty($state)) unset($data['state']); else $data['state'] = $state; } } elseif ($clueId) { // 如果是线索跳转建档 $clue = CustomerClue::where([['id', '=', $clueId], ['employee_id', '=', $token['employee_id']]])->find(); if (empty($clue)) return json(['code' => 1, 'msg' => '线索不存在']); if ($clue->state == 1) return json(['code' => 1, 'msg' => '线索已建档']); // 检测线索是否已经被其他同事建档过 /* $exist = CustomerClue::where([ ['org_id', 'in', $orgids], ['uid', '=', $clue->uid], ['state', '=', 1], ['id', '<>', $clueId] ])->find(); if ($exist) return json(['code' => 1, 'msg' => '建档失败,线索已被其他员工先行建档']); */ // 添加数据 $data['clue_id'] = $clue->id; $data['uid'] = $clue->uid; $data['employee_id'] = $token['employee_id']; $data['org_id'] = $token['org_id']; $data['agents_id'] = $clue->agent_id ?? NULL; //如果线索是经纪人端获取的记录 $state = Customer::changeState('待确认'); $data['state'] = $state; $clue->state = 1; } else { $data['employee_id'] = $token['employee_id']; $data['org_id'] = $token['org_id']; $state = Customer::changeState('待确认'); $data['state'] = $state; } Db::startTrans(); try { if (isset($clue)) $clue->save(); $old_data = $data; $data = array_filter($data); if (isset($old_data['phone1'])) $data['phone1'] = $old_data['phone1']; if (isset($old_data['phone2'])) $data['phone2'] = $old_data['phone2']; if ($aid) $data['aid'] = $aid; $customer->save($data); // 更新客户保护期 if (!$id) { $customer->save(['employee_time' => date('Y-m-d H:i:s')]); //保存员工获取客户时间 Customer::changeProtectedTo($customer->id, $token['root_org']); } // -------------------- 企业微信逻辑相关 start ----------------- // 如果有外部联系人id,说明是企业微信端添加的客户 if (!empty($data['external_userid'])) { $external_where['external_userid'] = $data['external_userid']; $external_where['employee_id'] = $this->request->token['employee_id']; $external_find = WeworksingleCustomer::where($external_where)->find(); if (empty($external_find)) { Db::rollback(); return json(['code' => 1, 'msg' => '外部联系人不存在']); } else { if (!empty($external_find['customer_id']) && $external_find['customer_id'] != 0) { Db::rollback(); return json(['code' => 1, 'msg' => '该外部联系人已绑定客户']); } } WeworksingleCustomer::where($external_where)->save(['customer_id' => $customer->id]); } // -------------------- 企业微信逻辑相关 end ----------------- //建档后添加一条跟进记录 if (empty($id)) $this->addFirstCustoemrVisitLog($customer->id, $clueId); Db::commit(); } catch (\Exception $e) { Db::rollback(); return json(['code' => 1, 'msg' => $e->getMessage()]); } // 发送管理层模板消息 $data['name'] = !empty($data['name']) ? $data['name'] : ''; $data['phone'] = substr_replace($data['phone'], '******', 3, 6); $msg = ['first' => '行为通知', 'keyword1' => '客户信息编辑', 'keyword2' => "员工" . $token['name'] . "对客户" . $data['name'] . "(" . $data['phone'] . ")信息编辑", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); return json(['code' => 0, 'data' => $customer->id, 'msg' => '添加成功']); } /** * 编辑部分字段 */ public function edit() { $id = input('id', '', 'intval'); $param = request()->post(); $token = request()->token; $customer = Customer::find($id); if (empty($customer)) { return json(['code' => 1, 'msg' => '数据不存在']); } $sub_org = orgSubIds(request()->token['root_org']); if (!in_array($customer['org_id'], $sub_org)) { return json(['code' => 1, 'msg' => '数据不存在']); } //记录修改客户基本信息 $this->cusbasic_field_savelog($param, $customer); $orgids = orgSubIds($token['root_org']); $pharr = [ !empty($param['phone']) ? $param['phone'] : '', !empty($param['phone1']) ? $param['phone1'] : '', !empty($param['phone2']) ? $param['phone2'] : '' ]; $pharr = array_filter($pharr); if (!empty($pharr)) { $repeat = []; foreach ($pharr as $key => $val) { if (empty($val)) continue; if (!in_array($val, $repeat)) { $repeat[] = $val; } else { return json(['code' => 1, 'msg' => '手机号不能重复']); } } //判断手机号是否在公海,资源库,已建档,回收站 $tips = $this->checkPepeat($pharr, $orgids, $token['employee_id'], $id); if (!empty($tips)) return $tips; } $result = $customer->save($param); if ($result) { // 发送管理层模板消息 $customer['name'] = !empty($customer['name']) ? $customer['name'] : ''; $customer['phone'] = substr_replace($customer['phone'], '******', 3, 6); $msg = ['first' => '行为通知', 'keyword1' => '客户信息编辑', 'keyword2' => "员工" . $token['name'] . "对客户" . $customer['name'] . "(" . $customer['phone'] . ")信息编辑", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); return json(['code' => 0, 'msg' => '操作成功']); } else { return json(['code' => 1, 'msg' => '操作失败']); } } /** * 记录客户基本信息的修改 */ public function cusbasic_field_savelog($param, $customer) { $token = request()->token; $baskey = ['name', 'phone', 'level', 'sex']; $basdata = CustomerPortraitField::with(['select'])->where([['root_id', '=', request()->token['root_org']], ['keyname', 'in', $baskey]])->select()->toArray(); $yes_save = []; foreach ($param as $key => $val) { if (in_array($key, $baskey) && $val != $customer[$key]) { if ($key == 'sex') { $val = $val == 1 ? '男' : '女'; } $yes_save[] = ['keyname' => $key, 'value' => $val]; } } if (!empty($yes_save)) { foreach ($yes_save as $key => $val) { foreach ($basdata as $k => $v) { if ($v['keyname'] == $val['keyname']) { $yes_save[$key]['id'] = $v['id']; $yes_save[$key]['name'] = $v['name']; $yes_save[$key]['type'] = $v['type']; $yes_save[$key]['valname'] = $val['value']; } } } // 添加追踪记录 $visitLog = [ 'customer_id' => $customer->id, 'type' => 1, 'next_contact_date' => null, 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'remark' => '修改客户基本信息', 'state' => 1, 'org_id' => $token['org_id'], 'customer_employee_id' => $customer->employee_id, 'customer_org_id' => Employee::where('id', $customer->employee_id)->value('org_id'), 'save_portrait_field' => json_encode($yes_save), 'down_portrait_field_status' => 0 ]; // var_dump($visitLog); // exit; CustomerVisitLog::create($visitLog); } } /** * 新建客户时添加一条跟进记录 * $id 客户id */ public function addFirstCustoemrVisitLog($id, $source = '') { $token = $this->request->token; $name = Employee::where('id', $token['employee_id'])->value('name'); $cname = Customer::where('id', $id)->value('name'); // $type = $source ? '建档' : '报备'; $type = '报备'; $remark = '业务员' . $name . '对客户' . $cname . '进行' . $type; $save = [ 'customer_id' => $id, 'type' => '', 'next_contact_date' => date('Y-m-d'), 'remark' => $remark, 'addtime' => date('Y-m-d H:i:s'), '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'] ]; CustomerVisitLog::insertGetId($save); return true; } /** * 经纪人送积分功能 */ public function agents_integral($agentid, $state, $customer_id, $state_type, $money, $state_type_num) { $token = $this->request->token; $agent_data = AgentUser::where([['id', '=', $agentid], ['root_id', '=', $token['root_org']]])->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; } if ($state == '已量房') { $code = 'measuring_integral'; $sta_type = 4; } if ($state_type . $state == '套房已量房') { $code = 'measuring_suite_integral'; $sta_type = 4; } if ($state_type . $state == '别墅已量房') { $code = 'measuring_villa_integral'; $sta_type = 4; } //添加与经纪人相关记录 $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); } $rule = AgentType::where([['root_id', '=', $token['root_org']], ['id', '=', $agent_data['type']]])->find(); $rule_list = !empty($rule['count']) ? json_decode($rule['count'], true) : ''; $jifen = !empty($rule_list) ? (isset($rule_list[$code]) ? $rule_list[$code] : 0) : 0; if ($jifen == 0 && $state == '已签单' && $money > 0 && !empty($rule_list)) { if (isset($rule_list['qiandan_money_integral']) && $rule_list['qiandan_money_integral'] > 0 && isset($rule_list['qiandan_scale_integral']) && $rule_list['qiandan_scale_integral'] > 0) { $jifen = intval($money / $rule_list['qiandan_money_integral']) * $rule_list['qiandan_scale_integral']; } } //$jifen = CreditsSetting::where(['code' => $code, 'root_id' => $token['root_org']])->value('value'); $ye = AgentIntegral::where(['customer_id' => $customer_id, 'agent_id' => $agentid])->column('state'); //if (!in_array($state, $ye) && $agent_data['type'] == 1) { if (!in_array($state, $ye)) { $add = array( 'agent_id' => $agentid, 'type' => $sta_type, 'integral' => $jifen, 'addtime' => time(), 'state' => $state, 'customer_id' => $customer_id ); AgentIntegral::insert($add); } if ($state == '已交定' && !in_array('已到店', $ye)) { $jifen = !empty($rule_list) ? $rule_list['daodian_integral'] : 0; //$jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen, 'addtime' => time(), 'state' => '已到店', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } if ($state == '已签单' && !in_array('已到店', $ye)) { $jifen = !empty($rule_list) ? $rule_list['daodian_integral'] : 0; //$jifen = CreditsSetting::where(['code' => 'daodian_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 1, 'integral' => $jifen, 'addtime' => time(), 'state' => '已到店', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } if ($state == '已签单' && !in_array('已交定', $ye)) { $jifen = !empty($rule_list) ? $rule_list['jiaoding_integral'] : 0; //$jifen = CreditsSetting::where(['code' => 'jiaoding_integral', 'root_id' => $token['root_org']])->value('value'); $add = array( 'agent_id' => $agentid, 'type' => 2, 'integral' => $jifen, 'addtime' => time(), 'state' => '已交定', 'customer_id' => $customer_id ); AgentIntegral::insert($add); } } /** * 客户扩展字段添加 */ public function customerExt($id, array $ext) { Db::startTrans(); try { $customer = Customer::where(['id' => $id, 'employee_id' => $this->request->token['employee_id']])->lock(true)->find(); if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']); // $customer->ext = NULL; // $customer->save(); $customer->ext = $ext; $customer->save(); Db::commit(); } catch (\Exception $e) { Db::rollback(); return json(['code' => 1, 'msg' => $e->getMessage()]); } return json(['code' => 0, 'msg' => '保存成功']); } /** * 设计师指定 * 2022-11-08 业务修改, 指派设计师改为指派人员 并且可以指派多人 * $id 客户id * $designerId 指派的人员 1,2,3,4 //为空取消指派人员 */ public function reserveDesigner($id, $designerId) { if (isset($this->request->token['isManager']) && $this->request->token['isManager']) { //修改指派逻辑,只要是管理层能看到的客户都可以指派 $orgids = orgSubIds($this->request->token['root_org']); $condition[] = ['org_id', 'in', $orgids]; $condition[] = ['id', '=', $id]; $customer = Customer::where($condition)->find(); // if ($this->request->token['org_type'] == 2) { // $sub_org = orgSubIds($this->request->token['org_id']); // $sub_employee = Employee::where([['org_id', 'in', $sub_org], ['state', '=', '在职'], ['uid', '<>', 0]])->column('id'); // $customer = Customer::where([['id', '=', $id], ['designer_id', 'in', $sub_employee]])->find(); // } else { // $customer = Customer::where([['id', '=', $id], ['org_id', 'in', orgSubIds($this->request->token['org_id'])]])->find(); // } } else { $customer = Customer::where(['id' => $id, 'employee_id' => $this->request->token['employee_id']])->find(); } if (empty($customer)) return json(['code' => 1, 'msg' => '您无权限指派此客户']); $old_customer = $customer->toArray(); $is_designer_manager = input('designer_manager', 0, 'intval'); if (empty($designerId)) { if ($is_designer_manager) { $customer->designer_id = NULL; } else { $customer->designer_id = NULL; $customer->assigned_personnel = NULL; } $customer->save(); return json(['code' => 0, 'msg' => '取消指派成功!']); } $designerId = explode(',', $designerId); if (in_array($old_customer['employee_id'], $designerId)) { return json(['code' => 1, 'msg' => '该员工名下已有该客户', 'data' => []]); } $designer = Employee::where([ ['id', 'in', $designerId], ['root_id', '=', $this->request->token['root_org']], ['state', '=', '在职'] ])->column('org_id', 'id'); if (empty($designer)) return json(['code' => 1, 'msg' => '指派人员不存在']); $orgs = Org::where([['id', 'in', array_values($designer)]])->column('org_type', 'id'); //第一个选择的设计师 $selectDesigner = []; foreach ($designerId as $k => $v) { if (empty($designer[$v]) || $orgs[$designer[$v]] !== 2) continue; $selectDesigner[] = $v; } if (count($selectDesigner) > 1) { return json(['code' => self::error_msg, 'msg' => '最多只能指派一名设计师']); } $designer_id = isset($selectDesigner[0]) ? $selectDesigner[0] : null; // 检测是否有设计师已指派满了 $limitNum = Setting::where(['root_id' => $this->request->token['root_org'], 'name' => 'designerNum'])->value('content'); if ($limitNum != 0) { //获取当月时间跨度 $start_time = date('Y-m') . '-01 00:00:00'; $end_time = date('Y-m-d', strtotime("$start_time +1 month -1 day")) . ' 23:59:59'; $where[] = ['addtime', 'between', [strtotime($start_time), strtotime($end_time)]]; $where[] = ['employee_id', 'in', $selectDesigner]; $had = CustomerSharing::field('employee_id,count(customer_id) as num')->group('employee_id')->where($where)->having("num >= $limitNum")->select(); // var_dump($had->toArray()); // exit; if (!$had->isEmpty()) return json(['code' => 1, 'msg' => '指派的设计师已无指派名额,请刷新后再试']); } // 检测部门是否是设计师 // $orgType = Org::where(['id' => $designer->org_id])->value('org_type'); // if ($orgType != 2) return json(['code' => 1, 'msg' => '设计师不存在']); $customer->designer_id = $designer_id; if (!$is_designer_manager) { $customer->assigned_personnel = implode(',', array_keys($designer)); } $customer->assign_time = date('Y-m-d H:i:s'); //增加记录指派时间 // 指派类型 $assign_type = input('assign_type', '', 'trim'); if ($assign_type && empty($old_customer['assign_type'])) { $customer->assign_type = $assign_type; } $customer->save(); $assign_type_default['yixiang'] = '[意向客户指派]'; $assign_type_default['liangfang'] = '[量房客户指派]'; $assign_type_default['daodian'] = '[到店客户指派]'; $assign_type_string = $assign_type_default[$customer['assign_type']] ?? ''; $remark_employee_name = Employee::where('id', 'in', array_keys($designer))->column('name'); $remark = $assign_type_string . '指派至员工' . implode(',', $remark_employee_name); $visit_Log = [ 'customer_id' => $id, 'type' => '', 'remark' => $remark, 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => 1, ]; CustomerVisitLog::create($visit_Log); // 发提醒 $old_assign = $old_customer['assigned_personnel']; if (empty($old_assign)) { // 之前未指派,新指派人员 $msg_employee = array_keys($designer); } else { $msg_employee = array_diff(array_keys($designer), explode(',', $old_assign)); } $employee_name = Employee::where('id', '=', request()->token['employee_id'])->value('name'); foreach ($msg_employee as $k => $v) { $msg = '员工' . $employee_name . '指派给你一个客户:' . ($old_customer['name'] ? $old_customer['name'] : '未知'); event(new Msg($v, $msg, 'customerAssign', $id)); } // 更新预约未确定的客户所属设计师id CustomersSubscribe::where(['customer_id' => $customer->id, 'state' => 0])->update(['designer_id' => $designer_id]); return json(['code' => 0, 'msg' => '指派成功!']); } /** * 产品(关注点) */ public function product() { $data = Product::field('id,product')->where('root_id', request()->token['root_org'])->column('product'); return json(['code' => 0, 'data' => $data]); } /** * 来源 */ public function source() { $data = CustomerSource::field('id,source')->where('root_id', request()->token['root_org'])->select(); return json(['code' => 0, 'data' => $data]); } public function count() { $token = request()->token; $param = request()->only([ 'type' => '', 'start_date' => '', 'end_date' => '', 'date' => '' ]); if ($param['date']) { $date_arr = $this->getDate($param['date']); if (!$date_arr) { $date_s = '2018-01-01 00:00:00'; $date_e = date('Y-m-d H:i:s'); $date_arr = [$date_s, $date_e]; } } elseif ($param['start_date'] && $param['start_date']) { $startTime = strtotime($param['start_date']); $endTime = strtotime($param['end_date']); $start_date = date('Y-m-d 00:00:00', $startTime); $end_date = date('Y-m-d 23:59:59', $endTime); $date_arr = [$start_date, $end_date]; } else { $date_s = '2018-01-01 00:00:00'; $date_e = date('Y-m-d H:i:s'); $date_arr = [$date_s, $date_e]; } $c_where[] = ['sign_time', 'between', $date_arr]; //客户的条件 $c_where[] = ['employee_id', '=', $token['employee_id']]; $c_where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $c_where[] = ['died', '<>', 2]; $countor1[] = ['crm_res_id', 'NULL', null]; $countor2[] = ['crm_res_id', 'NOTNULL', null]; $countor2[] = ['state', 'not in', Customer::changeState('待确认', 'chaos')]; $countor3[] = ['crm_res_id', 'NOTNULL', null]; $countor3[] = ['state', 'in', Customer::changeState('待确认', 'chaos')]; $countor3[] = ['valid_time', 'NOTNULL', null]; $customer_count = Customer::where($c_where)->where(function ($query) use ($countor1, $countor2, $countor3) { $query->whereOr([$countor1, $countor2, $countor3]); })->count(); $jv_where[] = ['add_wechat_time', 'between', $date_arr]; // 加微的条件 $jv_where[] = ['employee_id', '=', $token['employee_id']]; $jv_where[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; $jv_where[] = ['died', '<>', 2]; $jiav_count = Customer::where($jv_where)->where(function ($query) use ($countor1, $countor2) { $query->whereOr([$countor1, $countor2]); })->count(); $s_where[] = ['CustomersSubscribe.addtime', 'between', $date_arr]; //预约的条件 $s_where[] = ['CustomersSubscribe.state', '=', 0]; $s_where[] = ['Customer.employee_id', '=', $token['employee_id']]; $s_where[] = ['Customer.state', 'not in', Customer::changeState('无效', 'chaos')]; $s_where[] = ['Customer.died', '<>', 2]; $customer_subscribe = Db::view('Customer', 'id') ->view('CustomersSubscribe', 'id sid,state,type', 'Customer.id=CustomersSubscribe.customer_id') ->where($s_where) ->where(function ($query) { $countor1[] = ['Customer.crm_res_id', 'NULL', null]; $countor2[] = ['Customer.crm_res_id', 'NOTNULL', null]; $countor2[] = ['Customer.state', 'not in', Customer::changeState('待确认', 'chaos')]; $query->whereOr([$countor1, $countor2]); }) ->select() ->toArray(); $subscribe_lf = []; $subscribe_dd = []; foreach ($customer_subscribe as $k => $v) { if ((int)$v['state'] == 3 && !in_array($v['id'], $subscribe_lf)) { $subscribe_lf[] = $v['id']; } if ((int)$v['state'] == 1 && !in_array($v['id'], $subscribe_dd)) { $subscribe_dd[] = $v['id']; } } //确认数量 $state1 = CustomerVisitLog::changeState('交定', 'chaos'); $state2 = CustomerVisitLog::changeState('签单', 'chaos'); $state3 = CustomerVisitLog::changeState('已量房', 'chaos'); $state4 = CustomerVisitLog::changeState('已到店', 'chaos'); $log_state = array_merge($state1, $state2, $state3, $state4); $v_where[] = ['confirm_date', 'between', $date_arr]; // 日志的条件 $v_where[] = ['customer_employee_id', '=', $token['employee_id']]; $v_where[] = ['state', 'in', $log_state]; $visitlog = CustomerVisitLog::where($v_where)->column('state,customer_id'); $ding = $sign = $ok_house = $ok_store = []; foreach ($visitlog as $k => $v) { if (in_array($v['state'], $state1)) { $ding[] = $v['customer_id']; } elseif (in_array($v['state'], $state2)) { $sign[] = $v['customer_id']; } elseif (in_array($v['state'], $state3)) { $ok_house[] = $v['customer_id']; } elseif (in_array($v['state'], $state4)) { $ok_store[] = $v['customer_id']; } } // 查询有效数量 $validNum = CustomerStateCheck::where([ ['employee_id', '=', $token['employee_id']] ])->count(); return json([ 'code' => 0, 'data' => [ 'total' => $customer_count, 'ding' => count(array_unique($ding)), 'sign' => count(array_unique($sign)), 'make_house' => count(array_unique($subscribe_lf)), 'ok_house' => count(array_unique($ok_house)), 'make_store' => count(array_unique($subscribe_dd)), 'ok_store' => count(array_unique($ok_store)), 'wechat_count' => $jiav_count, 'valid_num' => $validNum, ] ]); } /** * 获取查询的时间范围 */ private function getDate($dateType) { switch ($dateType) { case 'today': return [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')]; case 'yesterday': return [date('Y-m-d 00:00:00', strtotime('yesterday')), date('Y-m-d 23:59:59', strtotime('yesterday'))]; case 'serven': return [date('Y-m-d 00:00:00', strtotime('6 days ago')), date('Y-m-d 23:59:59')]; case 'month': return [date('Y-m-d 00:00:00', strtotime('previous month')), date('Y-m-d 23:59:59')]; } return null; } /** * 客户列表 * @param state integer 1全部, 2待确认, 3未到访 4已到访,5定金,6签单,7无效 */ public function lists() { $token = $this->request->token; $param = $this->request->only([ 'state' => '', 'page' => 1, 'limit' => 20, 'keyword' => '', 'source' => '', 'date' => '', 'visit' => '', 'addtime' => '', 'following' => '', 'protected' => '', 'level' => '', 'repay' => '', 'type' => '', 'start_date' => date('Y-m-d', 0), 'end_date' => date('Y-m-d') ]); // 格式化时间格式 if (!empty($param['date'])) $param['date'] = date('Y-m-d', strtotime($param['date'])); $condition = []; if ($param['type']) { if (empty($param['start_date'])) { $param['start_date'] = date('Y-m-d', 0); } if (empty($param['end_date'])) { $param['end_date'] = date('Y-m-d'); } $startTime = strtotime($param['start_date']) - 1; $endTime = strtotime($param['end_date']) + 86400; // 查询条件 $condition[] = ['Customer.employee_id', '=', $token['employee_id']]; $condition[] = ['Customer.state', 'not in', Customer::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[] = ['employee_id', '=', $token['employee_id']]; $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', $startTime)]; break; case 'yjdd': // 预计到店 $s_where[] = ['employee_id', '=', $token['employee_id']]; $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', $startTime)]; 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', $startTime)]; 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', $startTime)]; 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[] = ['employee_id', '=', $token['employee_id']]; $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', $startTime)]; 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; } // 客户总数 $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'); unset($condition); $condition[] = ['id', 'in', $customer_ids]; } $condition[] = ['died', '<>', 2]; // 死单客户过滤 // 1)查询条件 if (empty($param['protected'])) { $condition[] = ['employee_id', '=', $token['employee_id']]; $condition[] = ['state', 'not in', Customer::changeState('无效', 'chaos')]; } // 可回收列表 if (!empty($param['protected'])) { $orgids = orgSubIds($this->request->token['org_id']); $org_employee = Employee::where('org_id', 'in', $orgids)->column('id'); $condition[] = ['employee_id', 'in', $org_employee]; } setCondition($param, 'level', '=', $condition); // 2)状态筛选 // empty($param['state']) ? $logCondition[] = ['state', 'not in', CustomerVisitLog::changeState('无效', 'chaos')] : $condition[] = ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]; // 3)来源筛选 $source = [ 'ownadd' => [ ['crm_res_id', 'NULL', null], ['is_resource', '=', 0], ['remark', '=', ''] ], 'crmres' => [ ['crm_res_id', 'NOTNULL', null], ['is_resource', '=', 0] ], 'public' => [ ['remark', '=', '公海获取'] ], 'agent' => [ ['agents_id', '<>', ''], ['agent_source_type', 'in', [1, 2]], //1表示手动报备2表示活动报名录入 ], 'agent_crm_add' => [ ['agents_id', '<>', ''], ['agent_source_type', '=', 3], //经纪人分享内容报名的客户 ] ]; // 来源 (empty($param['source']) || !isset($source[$param['source']])) ?: $condition = array_merge_recursive($condition, $source[$param['source']]); // 5)待回访 empty($param['visit']) ?: $condition[] = empty($param['date']) ? ['revisit_time', '=', date('Y-m-d') . ' 00:00:00'] : ['revisit_time', '=', $param['date'] . ' 00:00:00']; // 6)录入时间筛选 empty($param['addtime']) ?: $condition[] = ['addtime', 'like', date('Y-m-d', strtotime($param['addtime'])) . '%']; //增加按跟进时间排序 $order = 'addtime desc'; empty($param['following']) ?: $order = 'last_contact_date ' . $param['following'] . ',' . $order; //增加回访时间排序 empty($param['repay']) ?: $order = 'revisit_time ' . $param['repay'] . ',' . $order; //关键词搜索 if (!empty($param['keyword'])) { if (empty($param['protected'])) { $list = Customer::where($condition)->order($order)->field('id,name,community_name,phone')->select()->toArray(); $customersIdList = []; foreach ($list as $k => $v) { $str = $v['name'] . $v['community_name'] . $v['phone']; if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['id']; } } else { $search_employee = Employee::where([['id', 'in', $org_employee], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id'); $search_designer = Employee::where([['root_id', '=', $this->request->token['root_org']], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id'); $list = Customer::where($condition)->order($order)->field('id,name,community_name,phone,employee_id,designer_id')->select()->toArray(); $employee_customer = []; $customersIdList = []; foreach ($list as $k => $v) { $str = $v['name'] . $v['community_name']; if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['id']; if (in_array($v['employee_id'], $search_employee)) { $employee_customer[] = $v['id']; } if (in_array($v['designer_id'], $search_designer)) { $employee_customer[] = $v['id']; } $employee_customer = array_values(array_filter(array_unique($employee_customer))); } $customersIdList = array_values(array_filter(array_unique(array_merge($customersIdList, $employee_customer)))); } } else { // 不查询待确认的客户, 或待确认的客户不是资源库中的 $orCondition1 = $orCondition = $condition; $condition[] = ['state', 'not in', Customer::changeState('待确认', 'chaos')]; $orCondition[] = ['state', 'in', Customer::changeState('待确认', 'chaos')]; $orCondition[] = ['crm_res_id', 'NULL', null]; //从公海获取的客户是资源库的,当前状态是待确认的 $orCondition1[] = ['state', 'in', Customer::changeState('待确认', 'chaos')]; $orCondition1[] = ['crm_res_id', 'NOTNULL', null]; $orCondition1[] = ['valid_time', 'NOTNULL', null]; $customersIdList = Customer::whereOr([$condition, $orCondition, $orCondition1])->order($order)->column('id'); } // 剔除掉未经历该状态的客户id // 全部客户搜索当前状态 共有客户搜历史 2023-03-01 小胖 if (!empty($param['state'])) { if ($param['state'] == '待确认') { //2022-10-30 小程序客户列表的待确认状态是根据客户表的当前状态来展示的,所以查询待确认状态时 查询客户当前状态 //增加查询从公海获取的客户是资源库的,当前状态是待确认的 $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', NULL]]; $daior[] = [['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NOTNULL', NULL], ['valid_time', 'NOTNULL', NULL]]; //$customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id'); $customersIdList = Customer::whereOr($daior)->column('id'); } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') { //有效状态 未到访,已到访,确定到场,已量房,交定,签单 // $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单']; // $now_status = []; // foreach ($visit_status as $v) { // $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status); // } // $customersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'in', $now_status], ['employee_id|customer_employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id'); //客户表里排除了待确认的跟死单跟无效的客户就是有效的 $customersIdList = Customer::where([['id', 'in', $customersIdList], ['state', 'not in', array_merge(Customer::changeState('待确认', 'chaos'), Customer::changeState('无效', 'chaos'))], ['died', '<>', 2]])->column('id'); // 查询经历过回访以外所有状态的客户id(有效) // $expectCustomersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'not in', CustomerVisitLog::changeState('回访', 'chaos')], ['state', 'not in', CustomerVisitLog::changeState('无效', 'chaos')], ['employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id'); // if ($param['state'] == '有效') { // $customersIdList = $expectCustomersIdList; // } else { // $customersIdList = array_diff($customersIdList, $expectCustomersIdList); // } } else { $customersIdList = CustomerVisitLog::where([['customer_id', 'in', $customersIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id'); } } // 过保护期查询 $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $token['root_org']]])->findOrEmpty(); if (!empty($param['protected'])) { if (!$setting->isEmpty()) { $content = !empty($setting['content']) ? json_decode($setting['content'], true) : []; if (empty($content)) { return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]); } $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据 foreach ($content as $k => $v) { if (!isset($v['day']) || !isset($v['state'])) { $empty = true; } } if ($empty) { return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]); } $whereOr = []; foreach ($content as $k => $v) { if ($v['state'] == 1 && $v['day'] > 0) { $whereOr[] = [ ['state', 'in', Customer::changeState($k, 'chaos')], ['protected_to', '<', date('Y-m-d H:i:s')], ['protected_to', '<>', ' null'] ]; } } if (!empty($whereOr)) { $customersIdList = Customer::where([['id', 'in', $customersIdList]])->where(function ($query) use ($whereOr) { $query->whereOr($whereOr); })->column('id'); } else { return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]); } } else { return json(['code' => 0, 'data' => ['list' => [], 'count' => 0, 'ids' => []], 'page' => 1]); } } if (empty($param['protected'])) { // 置顶数据获取 $top = CustomerTop::where([['root_id', '=', $token['root_org']], ['employee_id', '=', $token['employee_id']]])->where([['customer_id', 'in', $customersIdList]])->order('addtoptime asc')->column('customer_id'); // 新数据获取 $new = Customer::where([['id', 'in', $customersIdList], ['fresh', '=', 1]])->order($order)->column('id'); // 剔除不应该出现的客户 $top = array_diff($top, array_diff($top, $customersIdList)); // // 剔除不应该出现的新客户 $new = array_diff($new, array_diff($new, $customersIdList)); // 剔除置顶的客户 $notTop = array_diff($customersIdList, $top); // 剔除新客户 $notNew = array_diff($notTop, $new); // 将置顶客户放置到前面 $customersIdList = array_unique(array_merge($top, $new, $notNew)); } else { $top = []; } //返回到特定位置 $id = input('id', 0); if ($id) { $ids = array_chunk($customersIdList, $param['limit']); foreach ($ids as $k => $v) { $a = false; foreach ($v as $k2 => $v2) { if ($id == $v2) { $a = true; $param['page'] = $k + 1; break; } } if ($a) break; } } // 分页 $pageIdList = array_slice($customersIdList, ($param['page'] - 1) * $param['limit'], $param['limit']); $id_where[] = ['id', 'in', $pageIdList]; $customers = Customer::with(['designer', 'designerOrg', 'employee', 'agent'])->where($id_where)->select(); // 总数获取 $count = count($customersIdList); $customers = $customers->visible(['id', 'employee_id', 'designer_id', 'name', 'sex', 'level', 'community_name', 'state', 'addtime', 'revisit_time', 'designer.name', 'designerOrg.name', 'fresh', 'square', 'last_contact_date', 'updatetime', 'employee.name', 'agent.agent_name', 'assign_type'])->toArray(); if (!empty($param['protected'])) { if (!$setting->isEmpty()) { $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : []; } else { $setting_content = []; } foreach ($customers as $k => $v) { $customers[$k]['un_protected'] = 0; $customers[$k]['protected_tips'] = ''; if (!empty($v['protected_to']) && time() > strtotime($v['protected_to'])) { $state_n = Customer::changeState($v['state'], 'n'); if (!empty($setting_content[$state_n]['state']) && $setting_content[$state_n]['state'] == 1) { $customers[$k]['un_protected'] = 1; $customers[$k]['protected_tips'] = '已过期'; } } if (!empty($v['protected_to']) && time() < strtotime($v['protected_to'])) { $day = floor((strtotime($v['protected_to']) - time()) / (24 * 3600)); $customers[$k]['protected_tips'] = $day ? '保护期' . $day . '天' : '即将过期'; } } } else { foreach ($customers as $k => $v) { $customers[$k]['un_protected'] = 0; $customers[$k]['protected_tips'] = ''; } } $customers = array_combine(array_column($customers, 'id'), $customers); // 状态统计获取 $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']; } // 最后跟进时间获取 $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"); trace(json_encode($dingTime)); // 排序(按每页id顺序取值) $listData = []; foreach ($pageIdList as $customerId) { $customers[$customerId]['top'] = 0; $customers[$customerId]['is_new'] = $customers[$customerId]['fresh'] == 1 ? 1 : 0; $customers[$customerId]['addtoptime'] = null; if (in_array($customerId, $top)) $customers[$customerId]['addtoptime'] = 1; if (isset($customersState[$customerId]) && !in_array($customers[$customerId]['state'], Customer::changeState('待确认', 'chaos'), true)) { $customers[$customerId]['stateNum'] = $customersState[$customerId]; } else { $customers[$customerId]['stateNum'] = ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0]; } $customers[$customerId]['last_visit_day'] = isset($lastTime[$customerId]) ? get_date_diff(time(), $lastTime[$customerId])->days : -1; $customers[$customerId]['last_ding_day'] = isset($dingTime[$customerId]) ? get_date_diff(time(), $dingTime[$customerId])->days : 0; $listData[] = $customers[$customerId]; } //重复录入功能,添加手机号 ,自动回收库里分配去重用 if ($listData) { $keys = array_column($listData, 'id'); $customer = Customer::where([['id', 'in', $keys]])->field('id,phone,phone1,phone2')->select(); $phones = []; foreach ($customer as $v) { $phones[$v->id] = $v->toArray(); } foreach ($listData as $k2 => $v2) { $listData[$k2] = array_merge($v2, $phones[$v2['id']]); } //小程序排序待回收和 后台待回收排序保持一致 if (!empty($param['protected'])) array_multisort(array_column($listData, 'id'), SORT_DESC, $listData); } $data = [ 'list' => $listData, 'count' => $count, 'ids' => Customer::where([['id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select() ]; return json(['code' => 0, 'data' => $data, 'page' => $param['page']]); } /** * 设计师待跟进接口 */ public function confirmList() { $param = $this->request->only(['state' => '', 'page' => 1, 'limit' => 20, 'date' => date('Y-m-d')]); $type = [ '到店' => 1, '活动' => 2, '量房' => 3 ]; if (!isset($type[$param['state']])) { $search = ['type', 'in', [1, 2, 3]]; } else { $search = ['type', '=', $type[$param['state']]]; } $condition = ['designer_id|employee_id', '=', $this->request->token['employee_id']]; $date = ['subscribe_date', '=', $param['date']]; // 排除掉无效的客户 $customerIdList = CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0]])->column('customer_id'); $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id'); $subscribe = CustomersSubscribe::with(['customer', 'employee', 'designer', 'activity', 'org'])->where([$condition, $date, $search, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->order('subscribe_date asc, hour asc')->page($param['page'], $param['limit'])->select(); $data = $subscribe->visible(['id', 'customer_id', 'employee_id', 'customer.name', 'customer.sex', 'customer.level', 'customer.community_name', 'customer.state', 'employee.name', 'org.name', 'activity.title', 'aid', 'subscribe_date', 'type'])->toArray(); // 保持原接口数据一致 $customers = []; foreach ($data as $c) { $customers[] = [ 'id' => $c['customer_id'], 'customer_id' => $c['customer_id'], 'employee_id' => $c['employee_id'], 'name' => $c['customer']['name'], 'sex' => $c['customer']['sex'], 'level' => $c['customer']['level'], 'community_name' => $c['customer']['community_name'], 'state' => $c['customer']['state'], 'subscribe_state' => $c['type'], 'employee' => ['name' => $c['employee']['name']], 'employeeOrg' => ['name' => $c['org']['name']], 'activity' => [ 'title' => empty($c['activity']) ? '' : $c['activity']['title'], 'id' => $c['aid'] ], 'last_contact_date' => $c['subscribe_date'] ]; } // 状态统计获取 $customersStateList = CustomerVisitLog::where([['customer_id', 'in', array_column($customers, 'customer_id')]])->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']; } foreach ($customers as &$item) { $item['stateNum'] = $customersState[$item['customer_id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0]; } $data = [ 'list' => $customers, 'count' => CustomersSubscribe::where([$condition, $date, $search, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(), 'allCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['customer_id', 'in', $customerIdList]])->count(), 'visitCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['到店']], ['customer_id', 'in', $customerIdList]])->count(), 'measureCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['量房']], ['customer_id', 'in', $customerIdList]])->count(), 'activityCount' => CustomersSubscribe::where([$condition, $date, ['state', '=', 0], ['type', '=', $type['活动']], ['customer_id', 'in', $customerIdList]])->count() ]; return json(['code' => 0, 'data' => $data]); } /* * 客户列表点击电话图标获取电话 */ public function getCrmPhone() { $id = $this->request->param('id'); $token = $this->request->token; $where = [ ['id', '=', $id], ['state', '<>', '无效'], ['employee_id', '=', $token['employee_id']] ]; //指派的客户 $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]]; $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $id]]; $had = Customer::whereOr([$where, $where_or, $where_or1])->find(); // 不是共有客户,检测是否是领导领导调用 if ($had == null) { $had = Customer::find($id); // 检测数据是否存在 if (!$had) return json(['code' => 1, 'msg' => '数据不存在']); // 登陆人部门及子部门获取 $my = Org::find($token['org_id']); $orgIdList = Org::where([['path', 'like', $my->path . '%']])->column('id'); // 不是可见部门的 返回空 // if (!in_array($had->org_id, $orgIdList)) { // return json(['code' => 1, 'msg' => '数据不存在']); // } if ($token['isManager']) { // 是管理员 if (!empty($had->employee_id)) { $employeeIdListStr = $had->employee_id . ',' . $had->assigned_personnel . ',' . $had->designer_id; $employeeIdListArr = explode(',', $employeeIdListStr); $employeeIdListArr = array_filter($employeeIdListArr); // 查找分享人是否在部门下 $exit = Employee::where([['org_id', 'in', $orgIdList], ['id', 'in', $employeeIdListArr]])->count(); if ($exit == 0) return json(['code' => 1, 'msg' => '数据不存在']); } } else { // 不是领导判断 客户是否属于自己 公海库不判断 if ($had->employee_id && ($had->employee_id != $token['employee_id'])) { return json(['code' => 1, 'msg' => '数据不存在']); } } } if (!$had) return json(['code' => 1, 'msg' => '数据不存在']); //客户电话 $phone = [ 'phone' => $had->phone, 'phone1' => $had->phone1, 'phone2' => $had->phone2, ]; //员工电话 $info = Employee::where('id', $token['employee_id'])->field('out_call_phone,phone')->find(); // 开启外呼的店面判断 $set = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty(); $out_call_check = 0; if (!$set->isEmpty()) { $out_call_check = 1; } return json(['code' => 0, 'phone' => $phone, 'out_call_phone' => $info->out_call_phone ? array_merge([$info->phone], explode(',', $info->out_call_phone)) : [$info->phone], 'out_call_check' => $out_call_check]); } /* * 星标置顶和取消 */ public function customer_top() { $id = $this->request->param('id'); $CustomerTop = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->find(); if (empty($CustomerTop)) { CustomerTop::create(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']]); } else { CustomerTop::where('id', $CustomerTop['id'])->delete(); } return json(['code' => 0, 'msg' => '操作成功']); } /* * 个人在系统内客户最早的待回访时间和录入时间,最晚待回访时间和录入时间,按以上时间之内可选 */ public function time_limit() { $data = Customer::where([['state', '<>', '无效'], ['employee_id', '=', $this->request->token['employee_id']]])->field('max(revisit_time) as max_revisit_time,min(revisit_time) as min_revisit_time,max(addtime) as max_addtime,min(addtime) as min_addtime')->find(); $data['max_revisit_time'] = !empty($data['max_revisit_time']) ? date('Y-m-d', strtotime($data['max_revisit_time'])) : null; $data['min_revisit_time'] = !empty($data['min_revisit_time']) ? date('Y-m-d', strtotime($data['min_revisit_time'])) : null; $data['max_addtime'] = !empty($data['max_addtime']) ? date('Y-m-d', strtotime($data['max_addtime'])) : null; $data['min_addtime'] = !empty($data['min_addtime']) ? date('Y-m-d', strtotime($data['min_addtime'])) : null; return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']); } /** * 待回访每日具体个数 */ public function visit_schedule() { $date = $this->request->get('date', date('Y-m')); $condition = [ ['state', '<>', '无效'], ['employee_id', '=', $this->request->token['employee_id']], ['revisit_time', '<>', 'null'], ['revisit_time', 'like', $date . '%'] ]; $futuredates = Customer::where(function ($query) { $query->whereOr([[['state', 'in', Customer::changeState('待确认', 'chaos')], ['crm_res_id', 'NULL', null]], [['state', 'not in', Customer::changeState('待确认', 'chaos')]]]); })->where($condition)->field("count(id) as num,date_format(revisit_time, '%Y-%m-%d') as days")->group('days')->select(); $schedule = []; foreach ($futuredates as $r) { $schedule[$r['days']] = $r['num']; } return json(['code' => 0, 'data' => $schedule]); } /** * 工作台待跟进每日具体个数 */ public function followup_schedule() { $date = $this->request->get('date', date('Y-m')); // $role = $this->request->token['org_type'] == 2 ? 'designer_id' : 'employee_id'; $condition = [ ['state', '=', '0'], ['designer_id|employee_id', '=', $this->request->token['employee_id']], ['subscribe_date', 'like', $date . '-%'] ]; // 排除掉无效的客户 $customerIdList = CustomersSubscribe::where($condition)->column('customer_id'); $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'not in', Customer::changeState('无效', 'chaos')]])->column('id'); $condition[] = ['customer_id', 'in', $customerIdList]; $futuredates = CustomersSubscribe::where($condition)->field("count(id) as num,subscribe_date as days")->group('days')->select(); $schedule = []; foreach ($futuredates as $r) { $schedule[$r['days']] = $r['num']; } return json(['code' => 0, 'data' => $schedule]); } /** * 待回访数据统计 */ public function visitCount() { $condition = [ ['employee_id', '=', $this->request->token['employee_id']] ]; // 总数统计 $total = Customer::where($condition)->count(); setCondition(date('Y-m-d H:i:s'), 'revisit_time', '<', $condition); $visit = Customer::where($condition)->count(); return json(['code' => 0, 'data' => ['total' => $total, 'visit' => $visit]]); } /** * 公共库 */ public function common() { $param = $this->request->param(); $page = $param['page']; $limit = $param['limit']; $condition[] = ['state', 'in', Customer::changeState('无效', 'chaos')]; $condition[] = ['employee_id', '=', $this->request->token['employee_id']]; // setCondition($param, ['keyword', 'community_name'], ['like', '%VALUE%'], $condition); if (isset($param['keyword']) && $param['keyword']) { $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%']; } $customers = Customer::where($condition)->page($page, $limit)->order('addtime desc')->select(); return json(['code' => 0, 'data' => $customers]); } /** * 客户追踪记录 */ public function visitlog() { $param = request()->param(['id']); $token = $this->request->token; // 判断是否是当前请求的用户 if ($this->request->token['isManager']) { $team_orgs = orgSubIds($this->request->token['org_id']); $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id'); $this_customer = Customer::find($param['id']); if ($this_customer->isEmpty()) { return json(['code' => 0, 'data' => [], 'count' => 0]); } $isMy = 0; if (in_array($this_customer['employee_id'], $empIdList)) { $isMy = 1; } if (in_array($this_customer['designer_id'], $empIdList)) { $isMy = 1; } $assigned_personnel = explode(',', $this_customer['assigned_personnel']); $assigned_personnel_arr = array_intersect($assigned_personnel, $empIdList); if (!empty($assigned_personnel_arr)) { $isMy = 1; } } else { $isMy = Customer::where([['id', '=', $param['id']], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->count(); } //指派人员 if ($isMy == 0) $isMy = Customer::where([['id', '=', $param['id']], ['assigned_personnel', 'find in set', $token['employee_id']]])->count(); if ($isMy == 0) return json(['code' => 0, 'data' => [], 'count' => 0]); //查询是否设置只显示员工跟进记录不展示修改客户扩展字段 $showEmpVistlog = Setting::where([['root_id', '=', $token['root_org']], ['name', '=', 'showEmpVistlog']])->findOrEmpty(); $visit = !$showEmpVistlog->isEmpty() ? (int)$showEmpVistlog->content : 0; $vlg_where[] = $visit ? ['save_portrait_field', 'NULL', null] : ['id', '>', 0]; $vlg_where[] = ['customer_id', '=', $param['id']]; $data = CustomerVisitLog::with(['employee' => function ($query) { $query->field('id,name,org_id'); }, 'user' => function ($query) { $query->field('id,headimgurl'); }])->where($vlg_where)->order('id desc')->select()->toArray(); //查询组织所属角色:销售、设计师 $column_employee_id = array_column($data, 'employee_id'); $employee = Employee::with(['org' => function ($query) { $query->field('id,org_type'); }])->field('id,org_id')->where('id', 'in', $column_employee_id)->select()->toArray(); $column_org_type = array_column($employee, null, 'id'); //预约活动 $aids = array_column($data, 'aid'); $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : []; $state1 = CustomerVisitLog::changeState('已到店', 'chaos'); $state2 = CustomerVisitLog::changeState('已到场', 'chaos'); foreach ($data as &$v) { $v['role'] = isset($column_org_type[$v['employee_id']]['org']['org_type']) ? $column_org_type[$v['employee_id']]['org']['org_type'] : null; $v['is_track'] = $v['remark'] == '公海获取' ? 1 : 0; $v['is_track'] = in_array($v['remark'], ['客户回收', '客户还原', '客户再分配', '资源库分配', '客户转移', '客戶指派', '取消客户下次回访时间']) ? 2 : $v['is_track']; //后台操作 if ($v['remark']) { if (strpos($v['remark'], '[意向客户指派]') !== false || strpos($v['remark'], '[量房客户指派]') !== false || strpos($v['remark'], '[到店客户指派]') !== false) { $v['is_track'] = 2; } } //确认到店 的选择的内场活动 if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) { $v['remark'] = $v['remark'] . '预约活动:《' . $activity[$v['aid']] . '》;'; } if (!empty($v['actmeet_type']) && in_array($v['state'], array_merge(CustomerVisitLog::changeState('已到场', 'chaos'), CustomerVisitLog::changeState('预约活动', 'chaos')), true)) { if ($v['actmeet_type'] == 1) { $v['remark'] .= ',见面方式为外场活动'; } elseif ($v['actmeet_type'] == 2) { $v['remark'] .= ',见面方式为茶楼见面'; } elseif ($v['actmeet_type'] == 3) { $v['remark'] .= ',见面方式为网谈登记'; } } if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state1)) { $v['remark'] = $v['remark'] . '到店人数:' . $v['number_of_visitors'] . '人;'; } if ($v['talking_order_time'] && in_array($v['state'], $state1)) { $v['remark'] = $v['remark'] . '谈单时长:' . $v['talking_order_time'] . '分钟;'; } if ($v['number_of_visitors'] > 0 && in_array($v['state'], $state2)) { $v['remark'] = $v['remark'] . '到场人数:' . $v['number_of_visitors'] . '人;'; } if ($v['stay_length'] && in_array($v['state'], $state2)) { $v['remark'] = $v['remark'] . '停留时间:' . $v['stay_length'] . '分钟;'; } //zhihuiping $v['wisdom_url'] = ''; $v['is_wisdom'] = 0; if ($v['remark'] && strpos($v['remark'], '讲解智慧屏##') !== false) { //remark = 接待了客户:张三,讲解时长21分钟@讲解智慧屏## url; $v['is_wisdom'] = 1; $arr = explode('##', $v['remark']); if (count($arr) == 2) { $ali_oss_bindurl = config('app.ali_oss_bindurl'); $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1]; $title = explode('@', $arr[0]); $v['remark'] = $title[0]; } } if ($token['client_type'] != 'vL0CQQ') { $v['remark'] = str_replace('签单', '转单', $v['remark']); $v['remark'] = str_replace('交定', '签单', $v['remark']); } // 检测是否有录音 if ($v['data_type'] == 'out_call') { $v['is_wisdom'] = 2; $v['wisdom_url'] = OutCallLog::where(['id' => $v['data_id']])->value('url'); } elseif ($v['data_type'] == 'mobile_call' && strpos($v['remark'], '#') !== false) { $ali_oss_bindurl = config('app.ali_oss_bindurl'); $arr = explode('#', $v['remark']); $v['wisdom_url'] = 'https://' . $ali_oss_bindurl . '/' . $arr[1]; $v['remark'] = $arr[0]; } //智慧屏跟进记录 if ($v['remark'] && strpos($v['remark'], '智慧屏客户图片##') !== false) { //remark = 智慧屏客户图片## ## url $arr = explode('##', $v['remark']); if (count($arr) == 3) { $ali_oss_bindurl = config('app.ali_oss_bindurl'); $imgs = explode(',', $arr[2]); $img = []; // $count = count($imgs)-1; // for ($i=$count; $i >= 0; $i--) { // $img[] = 'https://' . $ali_oss_bindurl . '/' . $imgs[$i]; // } foreach ($imgs as $item) { $img[] = 'https://' . $ali_oss_bindurl . '/' . $item; } $v['img'] = $img; $v['remark'] = $arr[1]; } } //增加取消下次回访时间员工姓名 if ($v['remark'] == '取消客户下次回访时间') { $empname = !empty($v['employee']['name']) ? $v['employee']['name'] : ''; $v['remark'] = $empname . $v['remark']; } //检测是否有下载文件 if (!empty($v['document_field']) && !empty($v['document_name'])) { $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $v['id']; $aec = new Aec(config('app.aec_key'), config('app.aec_iv')); $value = $aec->encrypt($str); $v['document_field'] = $this->request->domain() . '/downdocument/index.html?token=' . $value; } } $count = CustomerVisitLog::where($vlg_where)->count(); return json(['code' => 0, 'data' => $data, 'count' => $count]); } /* * 客户详情弹出框列表 * 确认量房、确认到店 */ public function visitlogDetails() { $param = request()->param(['id', 'state']); $w[] = ['customer_id', '=', $param['id']]; if ($param['state'] == '已交定') { $w[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]; } else { $w[] = CustomerVisitLog::changeState(['state', '=', '确认' . $param['state']]); } $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $w[] = ['org_id', 'in', $subOrg]; $data = CustomerVisitLog::with(['employee' => function ($query) { $query->visible(['name', 'org_id', 'id']); }])->where($w)->field('id,remark,addtime,money,img,img1,employee_id,number_of_visitors,talking_order_time,state,aid,shop_id,actmeet_type,stay_length')->order('addtime desc')->select(); $state1 = CustomerVisitLog::changeState('已到店', 'chaos'); $state2 = CustomerVisitLog::changeState('已到场', 'chaos'); //预约活动 $aids = array_column($data->toArray(), 'aid'); $activity = array_filter($aids) ? Activity::where([['id', 'in', $aids]])->column('title', 'id') : []; //店铺 // $shop_id = array_column($data->toArray(),'shop_id'); // $shop = array_filter($shop_id) ? Shop::where([['id','in',$shop_id]])->column('name','id') : []; foreach ($data as $k => &$v) { if ($v->employee) { $v->name = $v->employee->name; $v->identity = isset($v->employee->org->org_type) && $v->employee->org->org_type == 2 ? '设计师' : '业务员'; } else { $v->name = ''; $v->identity = '业务员'; } if ($v->number_of_visitors > 0 && in_array($v['state'], $state1)) { $v->remark = $v->remark . '到店人数:' . $v->number_of_visitors . '人;'; } if ($v->number_of_visitors > 0 && in_array($v['state'], $state2)) { $v->remark = $v->remark . '到场人数:' . $v->number_of_visitors . '人;'; } if ($v->talking_order_time) { $v->remark = $v->remark . '谈单时长:' . $v->talking_order_time . '分钟;'; } if ($v->stay_length) { $v->remark = $v->remark . '停留时间:' . $v->stay_length . '分钟;'; } //确认到店 的选择的内场活动 if ($v['aid'] && in_array($v['state'], $state1) && $activity && isset($activity[$v['aid']])) { $v->remark = $v->remark . '预约活动:《' . $activity[$v['aid']] . '》;'; } //增加馨居尚活动见面方式 if (!empty($v['actmeet_type']) && in_array($v['state'], CustomerVisitLog::changeState('已到场', 'chaos'))) { if ($v['actmeet_type'] == 1) { $actmeet_type = ',见面方式为外场活动'; } elseif ($v['actmeet_type'] == 2) { $actmeet_type = ',见面方式为茶楼见面'; } elseif ($v['actmeet_type'] == 3) { $actmeet_type = ',见面方式为网谈登记'; } $v->remark = !empty($actmeet_type) ? $v->remark . $actmeet_type : $v->remark; } //到达店面 // if ($v['shop_id'] && $shop && isset($shop[$v['shop_id']])) { // $v->remark = $v->remark . '到达店面:《' . $shop[$v['shop_id']] . '》;'; // } } return json(['code' => 0, 'data' => $data]); } /** * 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]); if (isset($param['vlogid']) && $param['vlogid']) CustomerVisitLog::where('id', $param['vlogid'])->update(['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']); $msg = '转单金额修改成功.'; //判断文字显示 return json(['code' => 0, 'msg' => $msg, 'data' => $msg]); } /** * 取消客户的下次回访时间 */ public function cancelNextContactDate() { $token = $this->request->token; $param = request()->only(['id']); $cusdata = Customer::where([['state', 'not in', Customer::changeState('无效', 'chaos')], ['id', '=', $param['id']], ['org_id', 'in', orgSubIds($token['root_org'])]])->find(); if (empty($cusdata)) return json(['code' => 1, 'msg' => '客户数据不存在']); $cusdata->revisit_time = null; $cusdata->save(); $add = [ 'customer_id' => $cusdata->id, 'type' => '', 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'remark' => '取消客户下次回访时间', 'state' => 10, 'confirm_date' => date('Y-m-d'), 'org_id' => $token['org_id'], 'customer_employee_id' => $cusdata['employee_id'], 'customer_org_id' => $cusdata['org_id'] ]; $ms = CustomerVisitLog::create($add); if ($ms) { return json(['code' => 0, 'msg' => '修改成功']); } else { return json(['code' => 1, 'msg' => '修改失败']); } } /** * 添加客户追踪记录 * 签单、收定时记录金额,更新客户状态,记录回访时间 * number_of_visitors 到店人数 * measure_room_img_type 量房图片类型 * * 2022-10-03 逻辑修改,预约到店和确认到店时必须要有内场活动 * */ public function addVisitlog() { $token = $this->request->token; // 防止后台切换部门 $token['org_id'] = Employee::where('id', $token['employee_id'])->value('org_id'); $param = request()->only(['customer_id', 'type', 'next_contact_date', 'remark', 'img' => '', 'state', 'state_type' => '', '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, 'stay_length' => '', 'down_payment' => '', 'shop_id' => 0, 'actmeet_type' => 0, 'vlogid' => 0, 'document_field' => '', 'document_name' => '', 'estimated_sign_money' => 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 共有客户列表管理层查看下级部门所有员工指派的跟被指派的客户,同时还可以跟进修改查询客户的逻辑 if (isset($token['isManager']) && $token['isManager']) { $team_orgs = orgSubIds($token['org_id']); $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id'); } else { $org_employee = [$token['employee_id']]; } $where = [ ['id', '=', $param['customer_id']], ['state', '<>', '无效'] ]; $had = Customer::where($where)->where(function ($query) use ($org_employee) { foreach ($org_employee as $k => $v) { $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]); } })->find(); // $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']]]; // $where_or1 = [['designer_id', '=', $token['employee_id']], ['id', '=', $param['customer_id']]]; // $had = Customer::whereOr($where, $where_or, $where_or1)->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 (in_array($state, ['未到访', '已到店', '已到场', '已量房', '已交定', '已签单', '已卖卡']) && $had->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($had['org_id'], $repeat_org)) { $repeat_org = [$had['org_id']]; } } else { $repeat_org = [$had['org_id']]; } // 需要验证 $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)]; $repeat_where[] = ['id', '<>', $param['customer_id']]; $customerExist = Customer::where($repeat_where)->field('id,employee_id,source_id'); if (!empty($customerExist)) { foreach ($customerExist as $ex) { if ($ex['employee_id'] != $had['employee_id']) { //查询撞单客户渠道 $source_name = ''; if ($ex['source_id']) { $source = CustomerSource::where(['id' => $ex['source_id']])->value('source'); $source_name = $source . '渠道客户'; } $have_emp = Employee::where('id', '=', $ex['employee_id'])->value('name'); return json(['code' => 2, 'msg' => '该客户与员工' . $have_emp . $source_name . '撞单,无法标记有效']); } } } } 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 ($token['org_type'] == 1 && array_intersect($salesperson, $org_employee) && in_array('salesperson', $setContent)) continue; // 多设计师指派时候,多的设计师会存在$salesperson 中 if ($token['org_type'] == 2 && array_intersect($salesperson, $org_employee) && in_array('designer', $setContent)) { continue; } return json(['code' => 1, 'msg' => '操作失败,无确认权限']); } } Db::startTrans(); if (!empty($state)) { $had->state = $state; } $had->revisit_time = $param['next_contact_date'] . ' 00:00:00'; $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']; empty($param['estimated_sign_money']) ?: $had->estimated_sign_money = $param['estimated_sign_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 = ', 时间:' . date('Y-m-d', strtotime($param['confirm_date'])); } // 到店消息 $state_msg = ''; if ($param['state'] == '已到店') { if ($param['shop_id']) { $shop_name = Shop::where('id', $param['shop_id'])->value('name'); $state_msg = ',所到店面为:' . $shop_name; } } // 备注 $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name'); $remark = $param['remark']; if (empty($remark)) { if (empty($state)) $remark = $employeeTypeName . $employeeName . '对客户进行了回访'; else $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $state_msg . $confirmMsg . $dingMsg; } //2022-10-04 逻辑修改,无效时增加无效原因 if ($param['state'] == '无效' && !empty($param['remark'])) { // $remark = $employeeTypeName . $employeeName . '更新客户状态为' . $state . $confirmMsg . ',原因是:' . $param['remark'] . $dingMsg; } // 添加追踪记录 $visitLog = [ 'customer_id' => $had->id, 'type' => $param['type'], 'next_contact_date' => !empty($param['next_contact_date']) ? $param['next_contact_date'] : null, 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->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'], 'stay_length' => $param['stay_length'], 'down_payment' => $param['down_payment'], 'shop_id' => $param['shop_id'], 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0, //馨居尚才可记录见面方式 'document_field' => $param['document_field'], 'document_name' => $param['document_name'] ]; $returnvisit = ['customer_org_id' => $visitLog['customer_org_id']]; //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', '=', $this->request->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); //计算业绩 // 如果是预约添加预约记录 if (strpos($visitLog->state, '预约') !== false) { //2022-11-09 增加指派客户逻辑 同一个客户可以指派多人, 但是该客户在同一天内只能有一个预约,预约之后其他人就不能预约了,,,不同日期可以继续预约 $state = str_replace('预约', '', $visitLog->state); // 查找是否已经预约 $hadSubscribe = CustomersSubscribe::where([ ['customer_id', '=', $had['id']], // ['employee_id|designer_id', '=', $this->request->token['employee_id']], ['subscribe_date', '=', date('Y-m-d', strtotime($param['confirm_date']))], ['state', '=', 0] ])->count(); $typeSubscribe = CustomersSubscribe::where([ ['customer_id', '=', $had['id']], // ['employee_id|designer_id', '=', $this->request->token['employee_id']], ['type', '=', array_search($state, $stateType)], ['state', '=', 0] ])->find(); $typeSubscribe = false; // 不是同一天的预约,同类型还可以预约 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, 'actmeet_type' => !empty($param['actmeet_type']) && $token['client_type'] == 'vL0CQQ' ? $param['actmeet_type'] : 0 //馨居尚才可记录见面方式 ]; 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($this->request->token['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' => $this->request->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' => $this->request->token['org_id'], 'is_resource' => 0, 'before_pool' => json_encode($before_pool), 'designer_id' => NULL, 'ext->ext6' => '', 'employee_time' => NULL, 'assigned_personnel' => NULL]); // -------------------- 企业微信逻辑相关 start ----------------- // 判断是否绑定有企业微信外部联系人关系,并做解绑操作 $company_id = Company::where('root_id', '=', $this->request->token['root_org'])->value('id'); $company_setting = WeworksingleCompanySetting::where('company_id', '=', $company_id)->find(); if (!empty($company_setting)) { $w_where['company_id'] = $company_id; $w_where['employee_id'] = $this->request->token['employee_id']; $w_where['customer_id'] = $param['customer_id']; WeworksingleCustomer::where($w_where)->save(['customer_id' => 0]); } // -------------------- 企业微信逻辑相关 end ----------------- } // //如果签单,默认交定 // 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'] : $employeeTypeName . $employeeName . '变更客户状态为交定'; // $new_visitlog = array_merge($param, $l_visitlog); // $new_visitlog['money'] = 0; //直接签单默认交定金额为0 // $mr = CustomerVisitLog::create($new_visitlog); // $this->preformance_tasks('已交定', $param['customer_id'], $param['money'], $mr->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]])->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]])->find(); if (!empty($subscribe)) { $subscribe->state = -1; $subscribe->save(); } $data = [ 'eid' => $had->employee_id, 'org_id' => $returnvisit['customer_org_id'], 'designer_id' => $had->designer_id, 'confirm_date' => $param['confirm_date'], 'customer_id' => $had->id, 'return_visit' => $had->return_visit, 'name' => $had->name, 'state' => $param['state'] ]; $this->cancelReservation($data); //取消预约后,待回访状态也要取消 $had->return_visit = 0; $had->save(); } //增加经纪人送积分功能 if ($had->agents_id && in_array($param['state'], ['已到店', '已交定', '已签单', '已量房'])) { $state_type = CustomerPortraitFieldSelect::where('id', $param['state_type'])->value('name'); $this->agents_integral($had->agents_id, $param['state'], $had->id, $state_type, $param['money'], $param['state_type']); } // 微爆活动 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(); // $from_wework = input('from_wework', '', 'trim'); // if ($from_wework) { // Console::call('download', ['customer', 'wework', (string)$token['root_org'], (string)$visitLog->id]); // Console::call('download', ['customer1', 'wework', (string)$token['root_org'], (string)$visitLog->id]); // } else { // Console::call('download', ['customer', 'mini', (string)$token['root_org'], (string)$visitLog->id]); // Console::call('download', ['customer1', 'mini', (string)$token['root_org'], (string)$visitLog->id]); // } //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']]); //勋章 //给业务经理和设计是发送提醒消息回访 $data = ['phone' => $had->phone, 'org_id' => $returnvisit['customer_org_id'], 'state' => $param['state'], 'confirm_date' => $param['confirm_date'], 'name' => $had->name, 'designer_id' => $had->designer_id, 'eid' => $had->employee_id, 'customer_id' => $had->id, 'assigned_personnel' => $had->assigned_personnel, 'actmeet_type' => $param['actmeet_type']]; $index = uniqid(); Cache::set($index, $data, 60); // $this->returnVisit($data); Customer::where('id', $had->id)->update(['return_visit' => 1]); //跟进后改为待回访状态 $data['name'] = !empty($data['name']) ? $data['name'] : ''; $data['phone'] = substr_replace($data['phone'], '******', 3, 6); //如果开关开启才发送消息 if (in_array($param['state'], $dd_state)) { // 发送管理层模板消息 $msg = ['first' => '行为通知', 'keyword1' => '客户确认到店', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")确认到店", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); } if ($state == '已签单') { // 发送管理层模板消息 $msg = ['first' => '行为通知', 'keyword1' => '客户签单', 'keyword2' => "客户" . $data['name'] . "(" . $data['phone'] . ")签单", 'keyword3' => date('Y/m/d'), 'remark' => '请悉知']; TmpMsg::sendMsgToLeader($msg, $token['org_id']); } return json(['code' => 0, 'msg' => '跟进成功', 'index' => $index]); } /** * 取消预约 给部门管理员和设计师发送消息提醒 * 张三取消了客户李四2020年8月1日的量房/到店/到场预约 */ public function cancelReservation($data) { $token = $this->request->token; if ($data['return_visit'] == 1) { $token['name'] = Employee::where([['id', '=', $data['eid']]])->value('name'); $eids = Employee::where([['root_id', '=', $token['root_org']], ['org_id', '=', $data['org_id']], ['state', '=', '在职'], ['is_manager', '=', 1], ['uid', '>', 0]])->column('id'); if ($data['designer_id']) array_push($eids, $data['designer_id']); $date = date('Y-m-d', strtotime($data['confirm_date'])); $date = explode('-', $date); $state = str_replace('未', '', $data['state']); $msg = $token['name'] . '取消了客户' . $data['name'] . ',于' . $date[0] . '年' . $date[1] . '月' . $date[2] . '日的' . $state; $eids = array_unique($eids); foreach ($eids as $key => $val) { event(new Msg($val, $msg, 'returnVisit', $data['customer_id'])); } return true; } return false; } /** * 消息提醒 * eid 客户所属业务员id, * org_id 业务员部门id * state 跟进状态 * name 业务员姓名 * designer_id 设计师id * 01、客户邀约提醒管理层和指派的设计师。没指派设计师时,不提醒设计师,提醒管理层去指派设计师。在员工客户里面需要管理层回访的客户红色标签提示。 * 02、业务员确认客户量房、到店、到场、交定、签单,提醒管理层回访客户。 * a、管理层点击提醒,进入对应客户详情页面。进行客户跟踪。 * b、在员工客户里面需要管理层回访的客户红色标签提示。 * 2022-11-14 发送消息范围修改 ,操作人员和所在部门管理员发消息,同时如果是确认操作要给客户所属业务员及其管理发消息 */ public function returnVisit($index = '') { $data = Cache::get($index); if (empty($index) || empty($data)) return true; $token = $this->request->token; $state1 = CustomerVisitLog::changeState('确认到店', 'chaos'); $state2 = CustomerVisitLog::changeState('确认量房', 'chaos'); $state3 = CustomerVisitLog::changeState('确认到场', 'chaos'); $state4 = CustomerVisitLog::changeState('交定', 'chaos'); $state5 = CustomerVisitLog::changeState('签单', 'chaos'); $make_state1 = array_merge($state1, $state2, $state3, $state4, $state5); $make_state3 = array_merge($state1, $state2, $state3); $state6 = CustomerVisitLog::changeState('预约到店', 'chaos'); $state7 = CustomerVisitLog::changeState('预约量房', 'chaos'); $state8 = CustomerVisitLog::changeState('预约活动', 'chaos'); $make_state2 = array_merge($state6, $state7, $state8); //增加馨居尚预约活动见面方式 $actmeet_type = null; //if($token['client_type'] == 'vL0CQQ' && !empty($data['actmeet_type'])){ if ($token['client_type'] == 'uwlxOU' && !empty($data['actmeet_type'])) { if ($data['actmeet_type'] == 1) { $actmeet_type = ',见面方式为外场活动'; } elseif ($data['actmeet_type'] == 2) { $actmeet_type = ',见面方式为茶楼见面'; } elseif ($data['actmeet_type'] == 3) { $actmeet_type = ',见面方式为网谈登记'; } } if (in_array($data['state'], $make_state2)) { // $date = $office_date = date('Y-m-d', strtotime($data['confirm_date'])); $date = $office_date = date('Y-m-d'); $state = str_replace('预约', '', $data['state']); $msg = $token['name'] . '预约了客户' . $data['name'] . ',预计于' . date('Y-m-d', strtotime($data['confirm_date'])) . $state; $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg; $msg = $data['designer_id'] ? $msg : $msg . ',该客户暂未指派设计师,请及时指派!!!'; $type = '预约'; //预约状态发送消息范围 预约状态只给操作人员,操作人员部门经理,(设计师/业务员)发送消息 $eid_where1[] = ['org_id', '=', $token['org_id']]; } elseif (in_array($data['state'], $make_state1)) { $date = $office_date = date('Y-m-d'); $state = str_replace('已', '', $data['state']); $msg = $token['name'] . '确认客户' . $data['name'] . ',于' . $data['confirm_date'] . $state; $msg = !empty($actmeet_type) ? $msg . $actmeet_type : $msg; $type = '确认'; //确认状态发送消息范围 操作业务员和设计师及双方部门经理都要发送 $org_ids = Employee::where([['id', 'in', [$token['employee_id'], $data['designer_id']]]])->column('org_id'); $eid_where1[] = ['org_id', 'in', $org_ids]; } else { return false; } $eid_where1[] = ['is_manager', '=', 1]; $eid_where1[] = ['state', '=', '在职']; $eid_where1[] = ['uid', '>', 0]; $eid_where1[] = ['root_id', '=', $token['root_org']]; $eid_where2[] = ['id', 'in', [$data['eid'], $data['designer_id']]]; $eids = Employee::whereOr([$eid_where1, $eid_where2])->column('id,official_openid'); $official = array_column($eids, 'official_openid', 'id'); $eids = array_column($eids, 'id'); $new_actmeet_type = !empty($actmeet_type) ? trim($actmeet_type, ',') . ',' : ''; $param = ['name' => $data['name'], 'sale_name' => $token['name'], 'type' => $type, 'state' => $state, 'phone' => $data['phone'], 'date' => $office_date, 'actmeet_type' => $new_actmeet_type]; //查询公众号信息 $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify'); $param['client_type'] = $client_type; $param['make_state2'] = $make_state2; $param['eids'] = Employee::where([['root_id', '=', $token['root_org']]])->column('id'); // $count_type = ($type == '确认') ? $make_state3 : $make_state2; $param['count'] = CustomerVisitLog::where([['addtime', 'like', '%' . date('Y-m-d') . '%'], ['state', 'in', $count_type], ['employee_id', 'in', $param['eids']]])->count(); //公众号appid $miniAppid = Miniprogram::where('root_id', $token['root_org'])->find()->appid; foreach ($eids as $key => $val) { event(new Msg($val, $msg, 'returnVisit', $data['customer_id'])); $param['count'] += 1; if (!empty($official[$val])) { //公众号消息 $param['employee_id'] = $val; $param['cid'] = $data['customer_id']; $param['official_openid'] = $official[$val]; $param['miniAppid'] = $miniAppid; $this->sendOfficialAccount($param); } } return true; } /** * 发送公众号消息 * $data['name'] 客户姓名 * $data['type'] 预约/确认 * $data['state'] 到店,量房,到场 * $data['phone'] 客户电话 * $data['sale_name'] 业务员姓名 * $data['employee_id] 业务员id * $data['date'] 日期 */ public function sendOfficialAccount($data) { if (in_array($data['state'], ['交定', '签单'])) return true; $token = $this->request->token; $dates = date('Ymd', strtotime($data['date'])); // $client_type = Miniprogram::where('root_id', $token['root_org'])->value('notify'); $client_type = $data['client_type']; $number = $dates . $data['count']; $data['page'] = "/pages/index/index?office_type=cread&cid=" . $data['cid'] . '&clientype=' . $client_type; if ($data['type'] == '预约') { $data['param'] = [ 'first' => '预约提醒', //标题 'keyword1' => $number, //预约编号 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目 'keyword3' => $data['date'], //预约时间 'keyword4' => substr_replace($data['phone'], '******', 3, 6), 'keyword5' => $data['name'], //预约姓名 'remark' => '您好,业务员' . $data['sale_name'] . '新增一次预约记录,' . $data['actmeet_type'] . '请及时回访' //电话 ]; } elseif ($data['type'] == '确认') { $data['param'] = [ 'first' => '确认提醒', //标题 'keyword1' => $number, //预约编号 'keyword2' => $data['type'] . $data['name'] . $data['state'], //预约项目 'keyword3' => $data['date'], //预约时间 'keyword4' => substr_replace($data['phone'], '******', 3, 6), //预约电话 'keyword5' => $data['name'], //预约姓名 'remark' => '您好,业务员' . $data['sale_name'] . '确认' . $data['name'] . $data['state'] . ',' . $data['actmeet_type'] . '请及时回访' //电话 ]; } $msg = [ 'type' => 'returnVisit', 'employee_id' => $data['employee_id'], 'official_openid' => $data['official_openid'], 'root_id' => $token['root_org'], 'miniAppid' => $data['miniAppid'] ]; EmployeeMsg::temploateMsg($msg, $data); return true; } /** * 计算业绩任务 * 2023/8/7 业绩算在客户所属人身上 */ public function preformance_tasks($state, $customer_id, $money = 0, $vislog_id) { $token = request()->token; $customer = Customer::find($customer_id); $org_id = Employee::where('id', $customer['employee_id'])->value('org_id'); if ($state == '已交定') { $w2[] = ['customer_id', '=', $customer_id]; $w2[] = ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]; $w2[] = ['customer_employee_id', '=', $customer['employee_id']]; $w2[] = ['customer_org_id', '=', $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', '=', $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', '=', $customer['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', '=', $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', (int) $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 line_chart() { $customerId = $this->request->param('customer_id'); $token = $this->request->token; $w[] = ['id', '=', $customerId]; $w[] = ['employee_id', '=', $token['employee_id']]; $check = Customer::where($w)->findOrEmpty(); if ($check->isEmpty()) return json(['code' => 0, 'data' => [], 'msg' => '操作成功']); $w1[] = ['customer_id', '=', $customerId]; $w1[] = ['starts', '>', 0]; $ids = CustomerVisitLog::where($w1)->order('id desc')->limit(30)->column('id'); $w1[] = ['id', 'in', $ids]; $row = CustomerVisitLog::where($w1)->order('id asc')->column('starts'); return json(['code' => 0, 'data' => $row, 'msg' => '操作成功']); } /** * 重新跟踪 */ public function transfer() { $customerId = $this->request->param('customer_id'); $condition = [ ['id', '=', $customerId], ['state', 'in', Customer::changeState('无效', 'chaos')] ]; $had = Customer::where($condition)->find(); if (!$had) return json(['code' => 0, 'msg' => '添加失败,数据不存在或已被分配,请刷新后再试']); $had->state = '未到访'; // 原客服获取 $oldEmployeeName = Employee::where([['id', '=', $had->employee_id]])->value('name'); $param = [ 'customer_id' => $customerId, 'type' => '重新跟踪', 'remark' => '公共库提取,重新跟踪, 原客服为:' . $oldEmployeeName, 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '未到访', ]; CustomerVisitLog::create($param); $had->employee_id = $this->request->token['employee_id']; $had->employee_time = date('Y-m-d H:i:s', time()); //更新员工获取此客户时间 $had->save(); // 更新客户保护期 Customer::changeProtectedTo($customerId, $this->request->token['root_org']); return json(['code' => 0, 'msg' => '重新跟踪成功']); } /** * 客户详情 */ public function detail() { $id = $this->request->param('id'); $share = input('share'); $token = $this->request->token; // 查询自己的客户 $condition1 = [ ['employee_id', '=', $this->request->token['employee_id']], ['id', '=', $id] ]; $condition2 = [ ['designer_id', '=', $this->request->token['employee_id']], ['id', '=', $id] ]; // 或者查询公司内,无效的客户 // 公司部门列表获取 $orgIdsList = Org::where([['path', 'like', $this->request->token['root_org'] . '-%']])->column('id'); $condition3 = [ ['id', '=', $id], ['org_id', 'in', $orgIdsList], ['state', 'in', Customer::changeState('无效', 'chaos')] ]; // 或者是公司领导看员工的客户 if (isset($this->request->token['isManager']) && $this->request->token['isManager']) { $team_orgs = (new Org())->getChildOrg($this->request->token['org_id']); if ($this->request->token['org_type'] == 1) { $condition4 = [ ['org_id', 'in', $team_orgs], ['id', '=', $id] ]; $orCondition = [$condition1, $condition2, $condition3, $condition4]; } else { $empIdList = Employee::where([['org_id', 'in', $team_orgs]])->column('id'); $condition4 = [ ['designer_id', 'in', $empIdList], ['id', '=', $id] ]; $condition5 = [ ['employee_id', 'in', $empIdList], ['id', '=', $id] ]; $orCondition = [$condition1, $condition2, $condition3, $condition4, $condition5]; } } else { $orCondition = [$condition1, $condition2, $condition3]; } //指派给自己的员工 $where_or = [['assigned_personnel', 'find in set', $token['employee_id']], ['id', '=', $id]]; $orCondition[] = $where_or; //共有客户管理层查看其他部门的客户 if ($share && isset($this->request->token['isManager']) && $this->request->token['isManager']) $orCondition[] = [['org_id', 'in', $orgIdsList], ['id', '=', $id]]; $data = Customer::with(['source', 'designer' => function ($query) { $query->field('id,name,headimgurl,org_id,uid'); }, 'employee' => function ($query) { $query->withField(['uid', 'id', 'headimgurl', 'is_manager', 'image_photo', 'is_newbie', 'name', 'nickname', 'org_id', 'position', 'role', 'root_id']); }])->whereOr($orCondition)->find(); if (empty($data)) return json(['code' => 1, 'msg' => '数据权限发生变化,无法查看']); // if ($data->aid) { // $data->date = CustomerVisitLog::where([['aid', '=', $data->aid], ['customer_id', '=', $id], ['state', '=', $data->state]])->value('next_contact_date') ?: ''; // } else { // $data->date = ''; // } // 获取设计师部门 if (!empty($data->designer)) $data->designer->orgName = Org::where(['id' => $data->designer->org_id])->value('name'); if ($data->employee_id == $this->request->token['employee_id'] && $data->fresh == 1) { $data->fresh = 2; $data->save(); } $count = CustomerVisitLog::where('customer_id', $id)->count(); $data['visit_count'] = $count; // 首付款 $data['down_payment'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('down_payment'); $data['deposit'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('confirm_date'); $data['sign'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '签单'])])->order('addtime desc')->value('addtime'); $data['deposit_mode'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '交定'])])->order('addtime desc')->value('deposit_mode'); // 量房、活动、到店次数统计 $data['liangfangNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认量房'])])->count(); $data['activityNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到场'])])->count(); $data['daodianNum'] = CustomerVisitLog::where([['customer_id', '=', $id], CustomerVisitLog::changeState(['state', '=', '确认到店'])])->count(); $data['deposit_count'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->count(); $data['square'] = floatval($data['square']); if ($data['employee_id'] != $this->request->token['employee_id'] && (empty($data['designer']) || $data['designer']['id'] != $this->request->token['employee_id'])) $data['editAble'] = false; else $data['editAble'] = true; // 设计师头像 if ($data['designer']) $data['designer']['headimgurl'] = User::where('id', $data['designer']['uid'])->value('headimgurl'); // 查询客户是否标星 $data['addtoptime'] = CustomerTop::where(['customer_id' => $id, 'employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->value('addtoptime'); // 查询客户是否有预约 $data['subscirbe'] = CustomersSubscribe::with(['activity' => function ($query) { $query->field('id,title'); }])->where([['customer_id', '=', $id], ['state', '=', 0]])->field('id,state,type,subscribe_date,aid')->select()->toArray(); //查询我最近一次的签单和交定金额 $state = CustomerVisitLog::changeState('已交定', 'chaos'); $data['deposit_money1'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('money') ?: 0; $data['money'] = $data->getData('signed_money'); //查询最近一次签单的记录id $state = CustomerVisitLog::changeState('已签单', 'chaos'); $data['vlogid'] = CustomerVisitLog::where([['customer_id', '=', $id], ['state', 'in', $state]])->order('id desc')->value('id') ?: 0; // 查询今日发送短信数量 $data['smsNum'] = CustomerSmsLog::where([['sendTime', 'between', [date('Ymd') . '000000', date('Ymd', strtotime('+1 day')) . '000000']], ['employee_id', '=', $this->request->token['employee_id']], ['state', '=', 0]])->count(); // 如果线索值为空,查询线索表跟本用户手机号一样并员工id一样,进行线索绑定 if (empty($data['clue_id']) && $data->employee_id == $this->request->token['employee_id']) { $clue_data = CustomerClue::where([['employee_id', '=', $this->request->token['employee_id']], ['phone', '=', $data['phone']]])->find(); if (!empty($clue_data)) { $data['clue_id'] = $clue_data['id']; $data->clue_id = $clue_data['id']; $data->save(); $clue_data->state = 1; $clue_data->save(); } } // 企业微信外部联系人 $external_customer = WeworksingleCustomer::where('customer_id', '=', $id)->findOrEmpty(); if (!$external_customer->isEmpty()) { $data['external_userid'] = $external_customer['external_userid']; $data['external_username'] = $external_customer['name']; } else { $data['external_userid'] = ''; $data['external_username'] = ''; } //业务员头像 if (!empty($data['employee']) && !$data['employee']['headimgurl']) $data['employee']['headimgurl'] = User::where('id', $data['employee']['uid'])->value('headimgurl'); //指派人员头像 if ($data->assigned_personnel) { $assigned_personnel = explode(',', $data->assigned_personnel); $assigned_business = array_diff($assigned_personnel, [$data['designer_id']]); $assigned_employee = Employee::with(['org', 'user'])->where('id', 'in', $assigned_business)->select()->toArray(); $assigned_employee_list = []; foreach ($assigned_employee as $ass) { $assigned_employee_list[] = [ 'name' => $ass['name'], 'headimgurl' => !empty($ass['user']) ? $ass['user']['headimgurl'] : '', 'orgName' => !empty($ass['org']) ? $ass['org']['name'] : '' ]; } $data['assigned_personnel_list'] = $assigned_employee_list; $uids = Employee::where([['id', 'in', $data->assigned_personnel]])->column('uid'); $data['assigned_personnel_imgs'] = User::where([['id', 'in', $uids]])->column('headimgurl'); } else { $data['assigned_personnel_imgs'] = []; $data['assigned_personnel_list'] = []; } //2022-11-09 增加业务逻辑 在团队客户中高层和中高层领导不可以回访和跟进 ,只有基层领导可以 if (!$token['isManager']) { $data['is_manager'] = 0; } else { //判断是否是基层领导 , 最底层部门的管理员 $child = Org::where('pid', $token['org_id'])->field('id')->findOrEmpty(); $data['is_manager'] = $child->isEmpty() ? 1 : 0; } // 有效申请 // 申请配置 $settingObj = Setting::where(['root_id' => $this->request->token['root_org'], 'name' => 'valid_check_person'])->find(); if ($settingObj) { $setting = explode(',', $settingObj['content']); if (in_array('xiaoshou', $setting) && $data['employee_id'] == $this->request->token['employee_id']) { $data['valid_check'] = true; } elseif (in_array('sheji', $setting) && $data['designer_id'] == $this->request->token['employee_id']) { $data['valid_check'] = true; } else { $data['valid_check'] = false; } // 检测是否已经提交 $check = CustomerStateCheck::where(['customer_id' => $id, 'root_id' => $this->request->token['root_org']])->find(); if ($check) $data['check_state'] = $check->check_state; else $data['check_state'] = -1; } else { $data['valid_check'] = false; } return json(['code' => 0, 'data' => $data]); } /** * 判断客户业务员是否重复 * */ public function checkRepeat() { $param = $this->request->param(['customer_id' => 0, 'employee_id' => 0]); $phone = Customer::where('employee_id', $param['employee_id'])->column('phone,phone1,phone2'); $c_phone = Customer::where('id', $param['customer_id'])->column('phone,phone1,phone2'); if (empty($phone) || empty($c_phone)) return json(['code' => 0, 'data' => 1]); $phones = []; foreach ($phone as $v) { $phones = array_merge($phones, array_values($v)); } $phones = array_filter($phones); $res = array_intersect($phones, array_filter($c_phone[0])); return json(['code' => 0, 'data' => $res ? 0 : 1]); } /** * 房源信息 */ public function house() { $id = $this->request->param('id'); $condition = [ ['id', '=', $id], ['employee_id', '=', $this->request->token['employee_id']] ]; Db::startTrans(); try { $customer = Customer::where($condition)->lock(true)->find(); if (empty($customer)) return json(['code' => 1, 'msg' => '数据不存在']); $param = request()->only(['community', 'area', 'house_type', 'delivery_time', 'estimate_date', 'budget', 'style', 'house_status']); $data = [ 'community_name' => $param['community'], 'square' => $param['area'], 'house_type' => $param['house_type'], 'house_status' => $param['house_status'], 'house_delivery_time' => $param['delivery_time'], 'plan_deco_time' => $param['estimate_date'], 'budget' => $param['budget'], 'deco_style' => $param['style'] ]; $data = array_filter($data); if (empty($data)) return json(['code' => 1, 'msg' => '请输入要保存的信息']); $customer->save($data); Db::commit(); } catch (Exception $e) { // 回滚事务 Db::rollback(); return json(['code' => 1, 'msg' => $e->getMessage()]); } return json(['code' => 0, 'msg' => '保存成功']); } public function forhouseinfo() { $communities = Community::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select(); $decostyles = Decostyle::field('id,name')->where([['root_id', '=', request()->token['root_org']], ['type', '=', 0]])->select(); $data = [ 'communities' => $communities, 'decostyles' => $decostyles ]; return json(['code' => 0, 'msg' => '获取成功', 'data' => $data]); } public function invalidCustomer() { $request = request(); $param = $request->param(); $customer_id = $param['customer_id']; $employee_id = $this->request->token['employee_id']; $tracking = new CustomerVisitLog(); $data = [ 'customer_id' => $customer_id, 'employee_id' => $employee_id, 'state' => '无效' ]; $tracking->save($data); // if (Customer::where('id', $customer_id)->update(['state' => 7, 'employee_id' => NULL, 'is_resource' => 0])) { return json(['code' => 0, 'msg' => '无效成功']); } else { return json(['code' => 1, 'msg' => '无效失败']); } } //////////// /// 资源库 //////////// public function resource_log_list() { $request = request(); $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $param = $request->only(['page', 'limit', 'org_id']); if (!in_array($param['org_id'], $subOrg)) { return json(['code' => 0, 'data' => [], 'count' => 0]); } $data = CrmImportLog::where('org_id', $param['org_id'])->with('employee')->page($param['page'])->limit($param['limit'])->order('addtime', 'desc')->select(); $count = CrmImportLog::where('org_id', $param['org_id'])->count(); return json(['code' => 0, 'data' => $data, 'count' => $count]); } public function resourcepool() { $request = request(); $param = $request->only(['page', 'limit', 'order', 'cilid']); $condition = []; $order = isset($param['order']) ? $param['order'] : 'id desc'; $condition[] = ['employee_id', '=', NULL]; $condition[] = ['is_resource', '=', 1]; $condition[] = ['crm_res_id', '=', $param['cilid']]; $condition[] = ['bad_phone', '=', 0]; $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $condition[] = ['org_id', 'in', $subOrg]; $data = CustomerLogic::resourcelist($condition, $param['page'], $param['limit'], $order); $count = CustomerLogic::count($condition); return json(['code' => 0, 'data' => $data, 'count' => $count]); } public function employee4resource($org) { $param['page'] = input('page', 1); $param['limit'] = input('limit', 1000000); $employee = EmployeeLogic::employeelist4resource($org, [], $param['page'], $param['limit']); return json(['code' => 0, 'data' => $employee]); } public function subnodes() { $request = request(); $param = $request->param(); //$nodes = OrgLogic::subnodes($param['org']); $nodes = OrgLogic::subfirstlevelnodes($param['org']); return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']); } /// public function subnodeswithempnum() { $request = request(); $param = $request->param(); $nodes = OrgLogic::subfirstlevelnodeswithempnum($param['org']); return json(['code' => 0, 'data' => $nodes, 'msg' => '获取成功']); } public function resdistributing() { $request = request(); $param = $request->param(); $token = $this->request->token; $target_customer_ids_arr = explode(',', $param['targets']); $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id'); $using_num = count($target_customer_ids_arr); Db::startTrans(); $repeat = 0; //重复phone if ($param['type'] == 'toemp' && isset($param['emp_id'])) { $employee_id = $param['emp_id']; $emp_obj = Employee::find($employee_id); $org_id = $emp_obj->org_id; // 设计师能否报备、获取客户 $de_where[] = ['root_id', '=', $root_id]; $de_where[] = ['name', '=', 'designer_get_customer']; $info_de_where = Setting::where($de_where)->findOrEmpty(); $org_type = Org::where('id', '=', $org_id)->value('org_type'); if (!$info_de_where->isEmpty() && $org_type == 2) { if ((int)$info_de_where['content'] != 1) { return json(['code' => 1, 'msg' => '无法分配给设计师']); } } $is_source = 0; //2022-10-16 逻辑修改重复录入客户表有重复手机号,手动分配需要去重 $customers = Customer::where([['id', 'in', $target_customer_ids_arr]])->column('id,phone,phone1,phone2'); $phone = Customer::where('employee_id', $employee_id)->column('phone,phone1,phone2'); $phones = []; foreach ($phone as $v) { $phones = array_merge($phones, array_values($v)); } $phones = array_filter($phones); $cids = []; foreach ($customers as $v2) { $l_phone = array_filter([$v2['phone'], $v2['phone1'], $v2['phone2']]); if (empty(array_intersect($l_phone, $phones))) { $cids[] = $v2['id']; } else { $repeat += 1; } } $using_num -= $repeat; if ($cids) { Customer::where([['id', 'in', $cids]])->update([ 'employee_id' => $employee_id, 'org_id' => $org_id, 'is_resource' => $is_source, 'ext->ext6' => '', 'designer_id' => NULL, 'employee_time' => date('Y-m-d H:i:s', time()), 'is_distribution' => 1 ]); Customer::changeProtectedTo($cids, $this->request->token['root_org']); // $this->sendOfficialAccount([$employee_id => count($cids)]); //添加一条跟进记录 $visitlog = []; foreach ($cids as $val) { $visitlog[] = [ 'customer_id' => $val, 'type' => 1, 'remark' => '资源库分配', 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'state' => '待确认' ]; } CustomerVisitLog::insertAll($visitlog); } // $employee_id = $param['emp_id']; // $emp_obj = Employee::find($employee_id); // $org_id = $emp_obj->org_id; // $is_source = 0; // foreach ($target_customer_ids_arr as $item_id) { // Customer::where(['id' => (int)$item_id])->update([ // 'employee_id' => $employee_id, // 'org_id' => $org_id, // 'is_resource' => $is_source, // 'ext->ext6' => '', // 'designer_id' => null, // 'employee_time' => date('Y-m-d H:i:s', time()) //更新员工获取客户时间 // ]); // } // // 更新客户保护期 // Customer::changeProtectedTo($target_customer_ids_arr, $this->request->token['root_org']); } else { $employee_id = null; $aimed_org = Org::find($param['org_pool']); $org_id = $aimed_org->id; $is_source = 1; foreach ($target_customer_ids_arr as $item_id) { Customer::where(['id' => (int)$item_id])->update([ 'employee_id' => $employee_id, 'org_id' => $org_id, 'is_resource' => $is_source ]); } //build log $metaLog = CrmImportLog::find($param['cilid']); $newlog = new CrmImportLog(); $newdata = [ 'pid' => $metaLog->id, 'employee_id' => $metaLog->employee_id, 'org_id' => $org_id, 'name' => $metaLog->name, 'count' => $using_num, 'state' => 0, 'left_num' => $using_num ]; $newlog->save($newdata); /// Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $org_id])->update(['crm_res_id' => $newlog->id]); } /// $leftNum = CrmImportLog::where('id', $param['cilid'])->column('left_num'); $newleftNum = ($leftNum[0] - $using_num) > 0 ? $leftNum[0] - $using_num : 0; if (CrmImportLog::where('id', $param['cilid'])->update(['state' => 1, 'left_num' => $newleftNum]) !== false) { Db::commit(); $result = $repeat ? ['code' => 1, 'msg' => '有' . $repeat . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功']; return json($result); } else { Db::rollback(); return json(['code' => 1, 'msg' => '操作失败']); } } public function patchdistributing() { $token = $this->request->token; $request = request(); $param = $request->param(); //$target_ids_arr = json_decode($param['targets'],true); $target_ids_arr = explode(',', $param['targets']); $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray(); $timesNum = floor(count($resource) / count($target_ids_arr)); $leftNum = count($resource) % count($target_ids_arr); $root_id = $request->token['root_org']; $repeat = []; Db::startTrans(); if ($param['type'] == 'topool') { $customer_data = []; for ($i = 0; $i < count($target_ids_arr); $i++) { for ($t = 0; $t < $timesNum; $t++) { unset($customer_data_once); $customer_data_once['id'] = $resource[$i + $t * count($target_ids_arr)]['id']; $customer_data_once['employee_id'] = NULL; $customer_data_once['org_id'] = $target_ids_arr[$i]; $customer_data_once['is_resource'] = 1; $customer_data[] = $customer_data_once; } } (new Customer())->saveAll($customer_data); ///build log $metaLog = CrmImportLog::find($param['cilid']); foreach ($target_ids_arr as $item) { $newlog = new CrmImportLog(); $newdata = [ 'pid' => $metaLog->id, 'employee_id' => $metaLog->employee_id, 'org_id' => $item, 'name' => $metaLog->name, 'count' => $timesNum, 'state' => 0, 'left_num' => $timesNum ]; $newlog->save($newdata); /// Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]); } } if ($param['type'] == 'toemp') { // 设计师能否报备、获取客户 $de_where[] = ['root_id', '=', $root_id]; $de_where[] = ['name', '=', 'designer_get_customer']; $info_de_where = Setting::where($de_where)->findOrEmpty(); $employee_org_ids = Employee::where('id', 'in', $target_ids_arr)->column('org_id'); $org_type = Org::where('id', 'in', $employee_org_ids)->column('org_type'); if (!$info_de_where->isEmpty() && in_array(2, $org_type)) { if ((int)$info_de_where['content'] != 1) { return json(['code' => 1, 'msg' => '无法分配给设计师']); } } //2023-02-18 待分配的业务员 $employees = Employee::where([['id', 'in', $target_ids_arr]])->column('org_id', 'id'); //待分配的客户 //只分配,后台分配到我部门下的客户资源 $customers = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL], ['org_id', '=', $token['org_id']], ['is_distribution', '=', 1]])->column('id'); //要分配的所有客户 //每人分得客户数量 $count = ceil(count($customers) / count($employees)); $arr = []; foreach ($employees as $kx => $vx) { $where = []; $where = [ ['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL], ['org_id', '=', $token['org_id']], ['is_distribution', '=', 1] ]; //已有手机号列表 $phone = Customer::where([['employee_id', '=', $kx]])->column('phone,phone1,phone2'); $phones = []; foreach ($phone as $kx1 => $vx2) { $lxs_phone = array_filter([$vx2['phone'], $vx2['phone1'], $vx2['phone2']]); $phones = array_merge($phones, $lxs_phone); } //手机号去重 if ($phones) $where[] = ['phone&phone1&phone2', 'not in', $phones]; $cids = Customer::where($where)->limit($count)->column('id'); Customer::where([['id', 'in', $cids]])->update([ 'employee_id' => $kx, 'org_id' => $vx, 'is_resource' => 0, 'ext->ext6' => '', 'designer_id' => NULL, 'employee_time' => date('Y-m-d H:i:s', time()), 'is_distribution' => 1 ]); $arr[$kx] = $cids; } if ($arr) { $visitlog = []; //分配客户 $send = []; //发送公众号消息数组 foreach ($arr as $k4 => $v4) { // 更新客户保护期 Customer::changeProtectedTo($v4, $token['root_org']); $send[$k4] = count($v4); //添加一条跟进记录 foreach ($v4 as $val) { $visitlog[] = [ 'customer_id' => $val, 'type' => 1, 'remark' => '资源库分配', 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'state' => '待确认' ]; } } if ($visitlog) CustomerVisitLog::insertAll($visitlog); // $this->sendOfficialAccount($send); } //剩余没有分配的人员 $repeat = Customer::where([['crm_res_id', '=', $param['cilid']], ['bad_phone', '=', 0], ['employee_id', '=', NULL]])->column('id'); $leftNum = count($repeat); } if ($param['type'] == 'toinstitue') { $resource = Customer::where(['crm_res_id' => $param['cilid'], 'bad_phone' => 0])->select()->toArray(); $resourceNum = count($resource); $leftNum = count($resource); $sumedempnum = 0; $empnumarr = []; foreach ($target_ids_arr as $targtid) { $orgids = orgSubIds($targtid); $allempnum = Employee::where([['org_id', 'in', $orgids]])->count(); if ($allempnum == 0) { return json(['code' => 1, 'msg' => '有机构人员为0,操作失败']); } $sumedempnum += $allempnum; $empnumarr[$targtid] = $allempnum; } if ($sumedempnum == 0) { return json(['code' => 1, 'msg' => '人员为0,操作失败']); } $data_arr = []; foreach ($target_ids_arr as $targtid) { unset($data_arr_once); $data_arr_once['key'] = $targtid; $data_arr_once['val'] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum)); $data_arr[] = $data_arr_once; } /*foreach ($target_ids_arr as $targtid) { $target_arr['_keys'][] = $targtid; $target_arr['_vals'][] = floor($resourceNum * ($empnumarr[$targtid] / $sumedempnum)); } //var_dump($target_arr['_keys']); //var_dump($target_arr['_vals']); $data_arr = []; for ($i = 0; $i < count($target_arr['_keys']); $i++) { $data_arr[$i] = [ 'key' => $target_arr['_keys'][$i], 'val' => $target_arr['_vals'][$i] ]; }*/ // $starter = 0; $customer_data = []; for ($k = 0; $k < count($data_arr); $k++) { $leftNum -= $data_arr[$k]['val']; if ($k > 0) { $starter += $k * $data_arr[$k - 1]['val']; } for ($n = $starter; $n < $starter + $data_arr[$k]['val']; $n++) { unset($customer_data_once); $customer_data_once['id'] = $resource[$n]['id']; $customer_data_once['employee_id'] = NULL; $customer_data_once['org_id'] = $data_arr[$k]['key']; $customer_data_once['is_resource'] = 1; $customer_data[] = $customer_data_once; /*$updatedata = [ 'employee_id' => null, 'org_id' => $data_arr[$k]['key'], 'is_resource' => 1 ]; Customer::where('id', $resource[$n]['id'])->update($updatedata);*/ } } (new Customer())->saveAll($customer_data); ///build log $metaLog = CrmImportLog::find($param['cilid']); foreach ($data_arr as $item) { $newlog = new CrmImportLog(); $newdata = [ 'pid' => $metaLog->id, 'employee_id' => $metaLog->employee_id, 'org_id' => $item['key'], 'name' => $metaLog->name, 'count' => $item['val'], 'state' => 0, 'left_num' => $item['val'] ]; $newlog->save($newdata); /// Customer::where(['crm_res_id' => $param['cilid'], 'org_id' => $item['key']])->update(['crm_res_id' => $newlog->id, 'is_distribution' => 1]); } } if (CrmImportLog::where('id', '=', $param['cilid'])->update(['state' => 1, 'left_num' => $leftNum > 0 ? $leftNum : 0]) !== false) { Db::commit(); $result = $repeat ? ['code' => 1, 'msg' => '有' . count($repeat) . '条客户手机号是重复数据,无法分配'] : ['code' => 0, 'msg' => '操作成功']; return json($result); } else { Db::rollback(); return json(['code' => 1, 'msg' => '操作失败']); } } public function cil_detail() { $request = request(); $param = $request->param(); $emparr = []; $resource = Customer::where([ ['crm_res_id', '=', $param['cilid']], ['employee_id', 'not null', ''] ])->select()->toArray(); $eids = array_unique(array_column($resource, 'employee_id')); $emps = Employee::with(['user' => function ($query) { $query->field('headimgurl,id')->bind(['headimgurl' => 'headimgurl']); }])->where([['id', 'in', $eids]])->field('id,name,uid')->select()->toArray(); $name = array_column($emps, 'name', 'id'); $headimgurl = array_column($emps, 'headimgurl', 'id'); $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', 'not null', '']])->group('employee_id')->column('count(id)', 'employee_id'); foreach ($resource as $customer) { // $emp = Employee::with('user')->find($customer['employee_id']); // $count = Customer::where([['crm_res_id', '=', $param['cilid']], ['employee_id', '=', $customer['employee_id']]])->count(); $id = $customer['employee_id']; $emparr[$id] = [ 'name' => isset($name[$id]) ? $name[$id] : '', 'headimgurl' => isset($headimgurl[$id]) ? $headimgurl[$id] : '', 'count' => isset($count[$id]) ? $count[$id] : 0, 'employee_id' => $id ]; } $emparrval = array_values($emparr); //// $logs = CrmImportLog::where('pid', $param['cilid'])->select(); $resourcePoolNodes = []; foreach ($logs as $item) { $orgob = Org::find($item['org_id']); $resourcePoolNodes[] = ['name' => $orgob->info, 'count' => $item['count'], 'org_id' => $item['org_id']]; } $data = [ 'respool' => $resourcePoolNodes, 'emp' => $emparrval ]; return json(['code' => 0, 'data' => $data, 'msg' => '操作成功', 'crm_res_id' => $param['cilid']]); } /////////// /// 公海 /////////// public function pool() { $request = request(); $param = $request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'keyword', 'state', 'date' => '']); $condition = []; $order = isset($param['order']) ? $param['order'] : 'id desc'; $condition[] = ['employee_id', '=', NULL]; $condition[] = ['is_resource', '=', 0]; $org_id = $request->token['org_id']; $subOrg = orgSubIds($org_id); if (isset($param['org']) && in_array($param['org'], $subOrg)) { $condition[] = ['org_id', '=', $param['org']]; } else { $condition[] = ['org_id', 'in', $subOrg]; } if (isset($param['keyword']) && $param['keyword']) { $condition[] = ['name|community_name', 'like', '%' . trim($param['keyword']) . '%']; } // 查询id列表 $customerIdList = Customer::where($condition)->column('id'); if (isset($param['state']) && $param['state']) { // 筛查状态 $customerIdList = CustomerVisitLog::where([['state', 'in', CustomerVisitLog::changeState($param['state'])], ['customer_id', 'in', $customerIdList]])->group('customer_id')->column('customer_id'); } $pageIdList = array_slice($customerIdList, ($param['page'] - 1) * $param['limit'], $param['limit']); $condition[] = ['id', 'in', $pageIdList]; $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']; } // 上方id已分页,此处分页参数传固定1 $data = CustomerLogic::poollist($condition, 1, $param['limit'], $order); $customer_id = array_column($data, 'id'); $visitLogNum = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->group('customer_id')->column('count(customer_id) as num', 'customer_id'); $visitLogDate = CustomerVisitLog::where([['customer_id', 'in', $customer_id], CustomerVisitLog::changeState(['state', '=', '无效'])])->order('addtime')->column('addtime', 'customer_id'); foreach ($data as &$value) { //回收次数 $value['recoverNum'] = isset($visitLogNum[$value['id']]) ? $visitLogNum[$value['id']] : 0; //最近的回收时间 $value['recoverLatelyDate'] = isset($visitLogDate[$value['id']]) ? $visitLogDate[$value['id']] : null; //上次跟进人信息 $value['before_pool'] = !empty($value['before_pool']) ? json_decode($value['before_pool'], true) : null; $value[$value['id']]['stateNum'] = $customersState[$value['id']] ?? ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0]; } foreach ($condition as $k => $v) { if ($v[0] == 'id') { if (isset($v[2])) { $condition[$k][2] = $customerIdList; } } } $count = CustomerLogic::count($condition); return json(['code' => 0, 'data' => $data, 'count' => $count]); } /** * 资源分配 */ public function resourceAllocation() { $param = Request()->only(['cids' => '', 'eid' => 0]); $token = $this->request->token; $info = Employee::where([['state', '=', '在职'], ['id', '=', $param['eid']], ['root_id', '=', $token['root_org']]])->findOrEmpty(); if ($info->isEmpty()) return json(['code' => 1, 'msg' => '指派失败']); $cids = explode(',', $param['cids']); $cids = Customer::where([['id', 'in', $cids], ['employee_id', '=', null]])->column('id'); if (empty($cids)) return json(['code' => 1, 'msg' => '指派失败']); foreach ($cids as $v) { if (Customer::where('id', $v)->update(['employee_id' => $param['eid'], 'org_id' => $info->org_id, 'state' => 0, 'remark' => '公海获取', 'fresh' => 1, 'ext->ext6' => '', 'designer_id' => null])) { CustomerVisitLog::create([ 'customer_id' => $v, 'type' => 1, 'remark' => '管理员指派', 'employee_id' => $param['eid'], 'user_id' => $info->uid, 'state' => '待确认' ]); } } return json(['code' => 0, 'msg' => '指派成功']); } public function distributing() { $request = request(); $param = $request->param(); $target_customer_ids_arr = explode(',', $param['targets']); $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $target_customer_ids_arr = Customer::where([['id', 'in', $target_customer_ids_arr], ['org_id', 'in', $subOrg]])->column('id'); if ($param['type'] == 'toemp' && isset($param['emp_id'])) { $employee_id = $param['emp_id']; $emp_obj = Employee::find($employee_id); $org_id = $emp_obj->org_id; } else { $employee_id = null; $org_id = $param['org_pool']; } foreach ($target_customer_ids_arr as $item_id) { $update = [ 'employee_id' => $employee_id, 'org_id' => $org_id, ]; if ($employee_id) { $update['ext->ext6'] = ''; $update['designer_id'] = null; } Customer::where(['id' => (int)$item_id])->update($update); } return json(['code' => 0, 'msg' => '操作成功']); } /** * 公海获取客户 * customer_id来源:业务员获取(int)、报备录入时查询公海存在自动获取(逗号分隔字符串) */ public function fetchpoolitem() { $param = request()->param(); $customer_id = explode(',', $param['customer_id']); $employee_id = $this->request->token['employee_id']; $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $otheremp = Customer::where([['id', 'in', $customer_id], ['employee_id', '=', NULL], ['org_id', 'in', $subOrg]])->field('employee_id,phone,phone1,phone2')->select(); if (empty($otheremp)) { return json(['code' => 1, 'msg' => '客户已被人抢先获取。记得下次抓住机会。']); } //判断名下是否存在该客户手机号,存在则不可获取 foreach ($otheremp as $item) { $phone_arr = []; !empty($item['phone']) ? $phone_arr[] = cypherphone($item['phone']) : ''; !empty($item['phone1']) ? $phone_arr[] = cypherphone($item['phone1']) : ''; !empty($item['phone2']) ? $phone_arr[] = cypherphone($item['phone2']) : ''; $phone_arr = array_filter($phone_arr); $haveCrm = Customer::where([['employee_id', '=', $employee_id], ['phone|phone1|phone2', 'in', $phone_arr]])->count(); if ($haveCrm) { return json(['code' => 1, 'msg' => '您名下已存在该客户信息。']); } } if (Customer::where([['id', 'in', $customer_id]])->update(['employee_id' => $employee_id, 'org_id' => $this->request->token['org_id'], 'state' => 0, 'remark' => '公海获取', 'fresh' => 1, 'ext->ext6' => '', 'designer_id' => null, 'employee_time' => date('Y-m-d H:i:s')])) { $saveAll = []; foreach ($customer_id as $ids) { $saveAll[] = [ 'customer_id' => $ids, 'type' => 1, 'remark' => '公海获取', 'employee_id' => $employee_id, 'user_id' => $this->request->token['uid'], 'state' => 1 ]; } if (CustomerVisitLog::insertAll($saveAll)) { return json(['code' => 0, 'msg' => '跟进成功']); } else { return json(['code' => 1, 'msg' => '跟进失败']); } } else { return json(['code' => 1, 'msg' => '跟进失败']); } } // /** // * 预约确认 // */ // public function subscribeConfirm($id, $type) // { // if ($this->request->token['org_type'] == 2) { // $column = 'designer_id'; // $employeeType = '设计师'; // } else { // $column = 'employee_id'; // $employeeType = '销售'; // } // $customer = Customer::where([[$column, '=', $this->request->token['employee_id']], ['id', '=', $id]])->find(); // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], [$column, '=', $this->request->token['employee_id']]])->find(); // if (!empty($subscribe)) { // $subscribe->state = 1; // $subscribe->save(); // } // $employeeName = Employee::find($this->request->token['employee_id'])->name; // $state = [ // 1 => '已到店', // 2 => '已到场', // 3 => '已量房' // ]; // $customer->state = $state[$type]; // $customer->save(); // // 跟进记录添加 // $visitLog = [ // 'customer_id' => $id, // 'type' => 4, // 'remark' => $employeeType . $employeeName . '确认客户' . $customer->name . $state[$type], // 'employee_id' => $this->request->token['employee_id'], // 'user_id' => $this->request->token['uid'], // 'state' => $state[$type] // ]; // CustomerVisitLog::create($visitLog); // return json(['code' => 0, 'msg' => '确认成功']); // } // /** // * 确认到店 // */ // public function visitConfirm($id) // { // return $this->subscribeConfirm($id, 1); // } // /** // * 确认到场 // */ // public function activityConfirm($id) // { // return $this->subscribeConfirm($id, 2); // } // /** // * 确认量房 // */ // public function measureConfirm($id, array $img) // { // return $this->subscribeConfirm($id, 3); // } // /** // * 取消到店/量房 // */ // public function cancelSubscribe($id) // { // $customer = Customer::where([['id', '=', $id], ['employee_id|designer_id', '=', $this->request->token['employee_id']]])->find(); // if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']); // $subscribe = CustomersSubscribe::where([['customer_id', '=', $id], ['type', '=', $type], ['state', '=', 0], ['subscribe_date', '=', date('Y-m-d')], [$column, '=', $this->request->token['employee_id']]])->find(); // if (!empty($subscribe)) { // $subscribe->state = 1; // $subscribe->save(); // } // // 跟进记录添加 // $employeeName = Employee::where(['id' => $this->request->token['employee_id']])->value('name'); // $visitLog = [ // 'customer_id' => $customer->id, // 'type' => 4, // 'remark' => "${employeeName}取消了客户的" . $customer->state, // 'employee_id' => $this->request->token['employee_id'], // 'user_id' => $this->request->token['uid'], // 'state' => $customer->state // ]; // $customer->state = $customer->state == '预约活动' ? '未到场' : str_replace('预约', '未', $customer->state); // // $customer->state = str_replace('预约', '未', $customer->state); // // 数据保存 // Db::startTrans(); // try { // CustomerVisitLog::create($visitLog); // $customer->save(); // Db::commit(); // } catch (\Exception $e) { // Db::rollback(); // return json(['code' => 1, 'msg' => $e->getMessage()]); // } // return json(['code' => 0, 'msg' => '取消成功']); // } /** * 共有客户头部统计 */ public function shareStatistics() { $token = $this->request->token; $is_manager = $token['isManager']; $param = $this->request->only(['org_id', 'start_time' => '', 'end_time' => '']); if ($is_manager == 1) { $team_orgs = orgSubIds($token['org_id']); $org_employee = Employee::where([['org_id', 'in', $team_orgs], ['state', '=', '在职'], ['uid', '>', 0]])->column('id'); } else { $org_employee = [$token['employee_id']]; } $condition = [ ['state', 'not in', Customer::changeState('无效', 'chaos')], //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']], ['designer_id|assigned_personnel', 'not null', ""], ['employee_id', '>', 0] ]; $condition[] = ['died', '<>', 2]; // 死单客户过滤 if ($param['start_time'] && $param['end_time']) { $condition[] = ['assign_time', 'between', [$param['start_time'] . ' 00:00:00', $param['end_time'] . ' 23:59:59']]; } $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) { foreach ($org_employee as $v) { $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]); } })->column('id'); $asg_num = count($customerIdList); $measure_num = $toshop_num = $deposit_num = $sing_num = 0; $cusvislog = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('state,customer_id')->field('id,state,customer_id')->select()->toArray(); foreach ($cusvislog as $key => $val) { if ($val['state'] == '已量房') $measure_num++; if ($val['state'] == '已到店') $toshop_num++; if ($val['state'] == '已交定') $deposit_num++; if ($val['state'] == '已签单') $sing_num++; } $data = ['asg_num' => $asg_num, 'measure_num' => $measure_num, 'toshop_num' => $toshop_num, 'deposit_num' => $deposit_num, 'sing_num' => $sing_num]; return json(['code' => 0, 'data' => $data, 'msg' => '获取成功']); } /** * 共有客户列表 */ public function shareList() { $token = $this->request->token; $is_manager = $token['isManager']; $team_orgs = orgSubIds($token['org_id']); $param = $this->request->only([ 'page' => 1, 'limit' => 20, 'keyword' => "", "state" => "", 'assign_start_time' => '', 'assign_end_time' => '', 'employee_name' => '' ]); $employee_where[] = ['org_id', 'in', $team_orgs]; $employee_where[] = ['state', '=', '在职']; $employee_where[] = ['uid', '>', 0]; if (!empty($param['employee_name'])) { $employee_where[] = ['name', 'like', '%' . $param['employee_name'] . '%']; } if ($is_manager == 1) { $org_employee = Employee::where($employee_where)->column('id'); } else { $org_employee = [$token['employee_id']]; } //2022-11-15 逻辑修改 销售/设计师已经指派的客户 在自己的共有客户中都能看到 $condition = [ ['state', 'not in', Customer::changeState('无效', 'chaos')], //['employee_id|designer_id|assigned_personnel', 'find in set', $token['employee_id']], ['designer_id|assigned_personnel', 'not null', ""], ['employee_id', '>', 0] ]; $condition[] = ['died', '<>', 2]; // 死单客户过滤 // $cids = Customer::where($condition)->select(); // if ($token['org_type'] == 2) { // $condition[] = ['designer_id', '=', $token['employee_id']]; // } else { // $condition[] = ['designer_id', 'not null', ""]; // $condition[] = ['employee_id', '=', $token['employee_id']]; // } if (!empty($param['keyword'])) { $list = Customer::where($condition)->where(function ($query) use ($org_employee) { foreach ($org_employee as $v) { $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]); } })->order('addtime desc')->field('id,name,community_name,phone')->select()->toArray(); $customerIdList = []; foreach ($list as $v) { $str = $v['name'] . $v['community_name'] . $v['phone']; if (strpos($str, trim($param['keyword'])) !== false) $customerIdList[] = $v['id']; } } else { $customerIdList = Customer::where($condition)->where(function ($query) use ($org_employee) { foreach ($org_employee as $v) { $query->whereOr([['employee_id|designer_id|assigned_personnel', 'find in set', $v]]); } })->column('id'); } if (!empty($param['state'])) { if ($param['state'] == '待确认') { // 筛查状态 /* $customerIdList1 = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'not in', CustomerVisitLog::changeState('待确认', 'chaos')]])->group('customer_id')->column('customer_id'); $customerIdList = array_diff($customerIdList, $customerIdList1); */ $customerIdList = Customer::where([['id', 'in', $customerIdList], ['state', 'in', Customer::changeState($param['state'], 'chaos')], ['crm_res_id', 'NULL', null]])->column('id'); } elseif (CustomerVisitLog::changeState($param['state']) == '回访' || $param['state'] == '有效') { //有效状态 未到访,已到访,确定到场,已量房,交定,签单 $visit_status = ['未到访', '已到访', '已量房', '已到场', '已到店', '交定', '签单']; $now_status = []; foreach ($visit_status as $v) { $now_status = array_merge(CustomerVisitLog::changeState($v, 'chaos'), $now_status); } $customerIdList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', $now_status], ['employee_id|customer_employee_id', '=', $token['employee_id']]])->group('customer_id')->column('customer_id'); } else { // 筛查状态 $customerIdList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState($param['state'], 'chaos')]])->group('customer_id')->column('customer_id'); } } //2022-11-14 增加 查询共有客户当天待到店,待量房列表 if (input('search_type', 0)) { $search_where = [ ['subscribe_date', '=', date('Y-m-d')], ['customer_id', 'in', $customerIdList], ['state', '=', 0], ['type', 'in', [1, 3]] //1到店,3量房 ]; $arr = CustomersSubscribe::where($search_where)->column('type', 'customer_id'); $customerIdList = array_keys($arr); } //增加按指派时间查询 if (!empty($param['assign_start_time']) && !empty($param['assign_end_time'])) { $assign_where[] = ['assign_time', 'between', [$param['assign_start_time'] . ' 00:00:00', $param['assign_end_time'] . ' 23:59:59']]; $assign_where[] = ['id', 'in', $customerIdList]; $assign_where[] = ['assigned_personnel', 'not null', null]; $customerIdList = Customer::where($assign_where)->column('id'); } $customers = Customer::where([['id', 'in', $customerIdList]])->order('assign_time desc')->page($param['page'], $param['limit'])->select(); //2022-11-08 增加指派人员 // $query1 = [['employee_id', '>', 0], ['assigned_personnel', 'find in set', $token['employee_id']]]; // if (input('search_type', 0)) $query1[] = ['id', 'in', $customerIdList]; //当天待到店,量房的客户 // $assigned_personnel = Customer::where($query1)->column('id'); // $where_or[] = ['id', 'in', $assigned_personnel]; // $customers = Customer::whereOr([$condition, $where_or])->page($param['page'], $param['limit'])->select(); $count = Customer::where([['id', 'in', $customerIdList]])->count(); $data = $customers->toArray(); $pageIdList = array_column($data, 'id'); $employeeList = array_column($data, 'employee_id'); $designerList = array_column($data, 'designer_id'); $empIdList = array_merge($employeeList, $designerList, [$token['employee_id']]); $empList = Employee::where([['id', 'in', $empIdList]])->column('name,org_id', 'id'); $orgList = Org::where([['id', 'in', array_column($empList, 'org_id')]])->column('name', 'id'); // $customers = $customers->visible(['id', 'name', 'sex', 'level', 'community_name', 'state'])->toArray(); // 查询跟踪记录 $depositVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已交定']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id'); $signVisitLog = CustomerVisitLog::where([CustomerVisitLog::changeState(['state', '=', '已签单']), ['customer_id', 'in', $pageIdList]])->group('customer_id')->column('count(id) as num', 'customer_id'); // 状态统计获取 $customersStateList = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->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']; } $data = []; // 最后跟进时间获取 $lastTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList]])->group('customer_id')->column('max(addtime)', 'customer_id'); // 交定时间获取 $dingTime = CustomerVisitLog::where([['customer_id', 'in', $customerIdList], ['state', 'in', CustomerVisitLog::changeState('已交定', 'chaos')]])->group('customer_id')->column("max(confirm_date)", "customer_id"); // 指派类型 $assign_type_default['yixiang'] = '意向客户指派'; $assign_type_default['liangfang'] = '量房客户指派'; $assign_type_default['daodian'] = '到店客户指派'; foreach ($customers as $item) { $assignIdList = !empty($item['assigned_personnel']) ? explode(',', $item['assigned_personnel']) : []; if (!empty($assignIdList) && !empty($item['designer_id'])) { $assignIdList = array_diff($assignIdList, [$item['designer_id']]); } $assignIdList[] = $item['employee_id']; // 所属销售 $assignIdList = array_unique($assignIdList); //$assignIdList[] = $item['designer_id']; // 指派的设计师 $assign_list = Employee::where('id', 'in', $assignIdList)->column('name'); $is_follow = 0; if (!in_array($item['org_id'], $team_orgs) && !in_array($token['employee_id'], $assignIdList) && $token['org_type'] != 2) $is_follow = 1; $assign_type_name = ''; if ($item['assign_type']) { if (isset($assign_type_default[$item['assign_type']])) { $assign_type_name = $assign_type_default[$item['assign_type']]; } } $data[] = [ 'id' => $item['id'], 'name' => $item['name'], 'sex' => $item['sex'], 'level' => $item['level'], 'community_name' => $item['community_name'], 'state' => $item['state'], 'deposit_num' => isset($depositVisitLog[$item['id']]) ? $depositVisitLog[$item['id']] : 0, 'sign_num' => isset($signVisitLog[$item['id']]) ? $signVisitLog[$item['id']] : 0, 'employee' => [ 'name' => $empList[$item['employee_id']]['name'] ], 'employeeOrg' => [ 'name' => $orgList[$empList[$item['employee_id']]['org_id']] ], 'designer' => empty($item['designer_id']) ? null : [ 'name' => $empList[$item['designer_id']]['name'] ], 'designerOrg' => empty($item['designer_id']) ? null : [ 'name' => $orgList[$empList[$item['designer_id']]['org_id']] ], 'btn_type' => !empty($arr[$item['id']]) ? $arr[$item['id']] : 0, ////1到店,3量房 'square' => $item['square'], //房屋面积 'agents' => !empty($item['agents_id']) ? $item['agents_id'] : '', //是否是经纪人推荐的 'stateNum' => !empty($customersState[$item['id']]) ? $customersState[$item['id']] : ['count' => 0, 'shop' => 0, 'measure' => 0, 'activity' => 0, 'deposit' => 0, 'signed' => 0], //'assign_time' => !empty($item['designer_id']) ? CustomerSharing::where([['employee_id','=',$item['designer_id']],['customer_id','=',$item['id']]])->value('addtime') ? date('Y-m-d H:i:s',CustomerSharing::where([['employee_id','=',$item['designer_id']],['customer_id','=',$item['id']]])->value('addtime')) : '' : '', 'assign_time' => !empty($item['assign_time']) ? $item['assign_time'] : '', 'assign_list' => $assign_list, 'assign_type' => $item['assign_type'], 'assigned_personnel' => $item['assigned_personnel'], 'assign_type_name' => $assign_type_name, 'is_follow' => $is_follow, 'last_visit_day' => isset($lastTime[$item['id']]) ? get_date_diff(time(), $lastTime[$item['id']])->days : -1, 'last_ding_day' => isset($dingTime[$item['id']]) ? get_date_diff(time(), $dingTime[$item['id']])->days : 0 ]; } return json(['code' => 0, 'data' => $data, 'count' => $count]); } /** * 获取客户画像展示字段 */ public function show_fields() { $token = $this->request->token; $w[] = ['root_id', '=', $token['root_org']]; $info = CustomerPortrait::where($w)->findOrEmpty(); $data = $info->fields; return json(['code' => 0, 'data' => $data]); } /** * 获取加微类型 * wechat_type 加微类型 * img_type 跟进图片类型 * employees 直播人员列表 * next_visit_time_is_ok 回访时间是否必传 默认必传 * */ public function get_setting() { $token = $this->request->token; //wechat_type 加微类型 $where[] = ['root_id', '=', $token['root_org']]; $where[] = ['name', '=', 'customerWechatSetting']; $info = Setting::where($where)->value('content'); $data['wechat_type'] = $info ? explode(',', $info) : ['常规加微']; //img_type 跟进图片类型 $where1[] = ['root_id', '=', $token['root_org']]; $where1[] = ['name', '=', 'customerLfSetting']; $info = Setting::where($where1)->value('content'); $data['img_type'] = $info ? explode(',', $info) : ['量房图片']; //employees 直播人员列表 $data['employees'] = $this->live_broadcast_personnel(1); //next_visit_time_is_ok 回访时间是否必传 默认必传 $where2[] = ['root_id', '=', $token['root_org']]; $where2[] = ['name', '=', 'nextVisitTimeIsOk']; $info = Setting::where($where2)->value('content'); $data['next_visit_time_is_ok'] = $info == 1 ? 1 : 0; $where3[] = ['root_id', '=', $token['root_org']]; $where3[] = ['name', '=', 'addWechatDay']; $visit = Setting::where($where3)->findOrEmpty(); $res = !$visit->isEmpty() ? explode('@', $visit->content) : [1, 0]; $data['add_wechat_day'] = $res[0]; $data['add_wechat_day_switch'] = isset($res[1]) ? $res[1] : 0; $company = Company::where('root_id', $token['root_org'])->find(); $data['city'] = $company->city; $data['province_city'] = $company->province_city; $data['province_city_code'] = $company->province_city_code; return json(['code' => 0, 'data' => $data]); } /** * 获取直播人员 */ public function live_broadcast_personnel($type = 0) { $token = $this->request->token; $param = Request()->only(['org_id' => 0, 'name']); $root_id = $token['root_org']; $subOrg = orgSubIds($root_id); if (in_array($param['org_id'], $subOrg)) { $path = Org::where('id', $param['org_id'])->value('path'); } else { $path = $token['root_org'] . '-'; } $where[] = ['path', 'like', $path . '%']; $empwhere[] = ['e.state', '=', '在职']; if (!empty($param['name'])) { $empwhere[] = ['e.name', 'like', '%' . $param['name'] . '%']; } $orgs = Org::with(['employee' => function ($query) use ($empwhere) { $query->field('e.id,e.name,user.headimgurl,e.org_id') ->alias('e') ->where($empwhere) ->join('user', 'user.id=e.uid'); }])->where($where)->order('level asc, id desc')->field('id,name,pid')->select()->toArray(); $data = []; while (!empty($orgs)) { $org = array_pop($orgs); // $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]) ? $data[$org['pid']]['designer_num'] + count($org['employee']) : 0; $childOrg = [ 'id' => $org['id'], 'name' => $org['name'], 'pid' => $org['pid'], 'designer' => $org['employee'], 'designer_num' => count($org['employee']) ]; if (isset($data[$org['id']])) { $childOrg['child_org'] = $data[$org['id']]['child_org']; $childOrg['designer_num'] += $data[$org['id']]['designer_num']; unset($data[$org['id']]); } $data[$org['pid']]['child_org'][] = $childOrg; $data[$org['pid']]['designer_num'] = isset($data[$org['pid']]['designer_num']) ? $data[$org['pid']]['designer_num'] + $childOrg['designer_num'] : $childOrg['designer_num']; } $data = array_pop($data); $result = [ 'designer' => isset($data['designer']) ? $data['designer'] : [], 'child_org' => isset($data['child_org']) ? $data['child_org'] : [] ]; if ($type) { return $result; } else { return json(['code' => 0, 'data' => $result]); } } /** * 新客户列表 */ public function newList() { $param = $this->request->only([ 'page' => 1, 'limit' => 20 ]); // 剔除掉关注过的客户 $customerTopIdList = CustomerTop::where(['employee_id' => $this->request->token['employee_id'], 'root_id' => request()->token['root_org']])->column('customer_id'); $condition = [ ['fresh', '>', 0], ['employee_id', '=', $this->request->token['employee_id']], ['id', 'not in', $customerTopIdList] ]; $data = Customer::where($condition)->page($param['page'], $param['limit'])->order('addtime desc')->select(); $count = Customer::where($condition)->count(); foreach ($data as &$item) { if (1 == $item->crm_res_id) $item->new = 1; } $data = $data->visible(['id', 'name', 'sex', 'community_name', 'square', 'new'])->toArray(); return json(['code' => 0, 'data' => $data, 'count' => $count]); } /** * 自动回收列表 */ public function drop_pool() { $param = $this->request->only(['page' => 1, 'limit' => 20, 'order', 'org', 'emp_id', 'state', 'keyword']); $orgids = orgSubIds($this->request->token['org_id']); $org_employee = Employee::where('org_id', 'in', $orgids)->column('id'); $condition[] = ['employee_id', 'in', $org_employee]; $order = isset($param['order']) ? $param['order'] : 'id desc'; setCondition($param, ['emp_id', 'employee_id'], '=', $condition); empty($param['state']) ?: setCondition(['state' => Customer::changeState($param['state'], 'chaos')], 'state', 'in', $condition); //关键词搜索 if (!empty($param['keyword'])) { $list = CustomerDropPool::where($condition)->order($order)->field('customer_id,name,community_name,phone,employee_id,designer_id')->select()->toArray(); $search_employee = Employee::where([['id', 'in', $org_employee], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id'); $search_designer = Employee::where([['root_id', '=', $this->request->token['root_org']], ['name', 'like', '%' . $param['keyword'] . '%']])->column('id'); $employee_customer = []; $customersIdList = []; foreach ($list as $k => $v) { $str = $v['name'] . $v['community_name']; if (strpos($str, trim($param['keyword'])) !== false) $customersIdList[] = $v['customer_id']; if (in_array($v['employee_id'], $search_employee)) { $employee_customer[] = $v['customer_id']; } if (in_array($v['designer_id'], $search_designer)) { $employee_customer[] = $v['customer_id']; } $employee_customer = array_values(array_filter(array_unique($employee_customer))); } $customersIdList = array_values(array_filter(array_unique(array_merge($customersIdList, $employee_customer)))); } else { $customersIdList = CustomerDropPool::where($condition)->order($order)->column('customer_id'); } $data = CustomerDropPool::with(['employee', 'org', 'designer'])->withCount(['visitLog' => function ($query) { $query->whereOr([[CustomerVisitLog::changeState(['state', '=', '预约量房'])], [CustomerVisitLog::changeState(['state', '=', '预约到店'])], [CustomerVisitLog::changeState(['state', '=', '预约活动'])]]); }])->withCount(['activityFrequency' => function ($query) { $query->where([CustomerVisitLog::changeState(['state', '=', '确认到场'])]); }]) ->where([['customer_id', 'in', $customersIdList]]) ->page($param['page'], $param['limit'])->order($order)->select(); $data = $data->visible(['id', 'customer_id', 'employee_id', 'designer_id', 'name', 'community_name', 'phone', 'phone1', 'phone2', 'level', 'state', 'square', 'revisit_time', 'addtime', 'org_id', 'protected_to', 'is_resource', 'employee.name', 'org_name', 'designer.name', 'visit_log_count', 'activity_frequency_count', 'droptime', 'sex'])->toArray(); $ids = CustomerDropPool::where([['customer_id', 'in', $customersIdList]])->field('id,phone,phone1,phone2')->select(); foreach ($data as &$item) { $item['protected'] = false; if (isset($item['protected_to']) && time() < strtotime($item['protected_to'])) { $item['protected'] = true; } $item['square'] = floatval($item['square']); $item['mobile'] = $item['phone']; $item['mobile1'] = $item['phone1']; $item['mobile2'] = $item['phone2']; $item['phone'] = substr_replace($item['phone'], '******', 3, 6); $record_list = CustomerDropRecord::where('customer_id', '=', $item['customer_id'])->order('droptime desc')->select(); $item['recoverNum'] = $record_list->count(); $item['recoverLatelyDate'] = isset($record_list[0]) ? $record_list[0]['droptime'] : ''; $latest_visit_log = CustomerVisitLog::where('customer_id', '=', $item['customer_id'])->order('id desc')->find(); if (empty($latest_visit_log)) { $item['latest_visit_employee'] = ''; $item['latest_visit_time'] = ''; } else { $latest_visit_employee = Employee::find($latest_visit_log['customer_id']); if (!empty($latest_visit_employee)) { $item['latest_visit_employee'] = $latest_visit_employee['name']; $item['latest_visit_time'] = $latest_visit_log['addtime']; } else { $item['latest_visit_employee'] = ''; $item['latest_visit_time'] = ''; } } } $count = CustomerDropPool::where($condition)->count(); return json(['code' => 0, 'data' => $data, 'count' => $count, 'ids' => $ids]); } /** * 自动回收还原 */ public function undrop() { $id = input('id', '', 'trim'); if (!$id) { return json(['code' => 1, 'msg' => '参数错误']); } $list = CustomerDropPool::where([['id', 'in', $id]])->select(); $root_id = $this->request->token['root_org']; $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty(); $error = 0; $repeat = 0; foreach ($list as $k => $v) { //查询重复 $l_phone = array_filter([$v->getData('phone'), $v->getData('phone1'), $v->getData('phone2')]); $query = []; $query[] = ['phone|phone1|phone2', 'in', $l_phone]; $query[] = ['employee_id', '=', $v->employee_id]; $check = Customer::where($query)->findOrEmpty(); if (!$check->isEmpty()) { $repeat += 1; continue; } $customer_state = Customer::changeState($v['state'], 'n'); $info = $v->toArray(); $info['protected_to'] = null; if (!empty($setting)) { $setting_content = json_decode($setting['content'], true); } else { $setting_content = []; } if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) { $day = $setting_content[$customer_state]['day']; $info['protected_to'] = $day > 0 ? date('Y-m-d H:i:s', time() + $day * 24 * 3600) : null; } $info['deposit_money'] = $v->getData('deposit_money'); $info['signed_money'] = $v->getData('signed_money'); $info['id'] = $info['customer_id']; unset($info['customer_id']); unset($info['droptime']); unset($info['add_wechat_time']); unset($info['group_building_date']); unset($info['live_broadcast_date']); unset($info['subscribe_meet_outside']); unset($info['meet_outside']); unset($info['sign_time']); unset($info['reputation_gather']); unset($info['into_owner_group']); Db::startTrans(); $result = Customer::create($info); $d_result = $v->delete(); if ($result && $d_result) { Db::commit(); $param = [ 'customer_id' => $info['id'], 'type' => 1, 'remark' => '客户还原', 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '' ]; CustomerVisitLog::create($param); } else { Db::rollback(); $error++; } } if ($repeat) return json(['code' => 1, 'msg' => '有' . $repeat . '条客户手机号已经属于业务员,无法还原']); if ($error == 0) { return json(['code' => 0, 'msg' => '操作成功']); } else { return json(['code' => 0, 'msg' => '操作成功,部分数据失败']); } } /** * 自动回收再分配 */ public function drop_pool_resdistribute() { $id = input('id', '', 'trim'); $employee_id = input('employee_id', '', 'intval'); $from = input('from', '', 'trim'); $target_ids_arr = explode(',', $id); if (!empty($employee_id)) { $emp_obj = Employee::find($employee_id); $org_id = $emp_obj->org_id; } else { return json(['code' => 1, 'msg' => '操作失败']); } $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $target_ids_arr = Customer::where([['id', 'in', $target_ids_arr], ['org_id', 'in', $subOrg]])->column('id'); //2022-10-21 19:25:59----------------- //2022-10-21 重复录入 重复验证 check=1,2&3,4 表示ID=2和3的客户手机号重复 1,4不重复 $repeat_customer = []; $vislog_id = []; //跟进记录合并数组 $z_type = $from; if (input('check', '')) { $target_ids_arr = []; $check_arr = explode(',', input('check', '')); //先已第一个位置 以后可能会已保护期排序 foreach ($check_arr as $check_arr_key => $check_arr_val) { //默认第一个ID 为准 $temporary_arr = explode('@', $check_arr_val); $vislog_id[$temporary_arr[0]] = $temporary_arr; } foreach ($vislog_id as $vislog_id_key => $vislog_id_val) { $temporary_customer = ($from == 'index') ? Customer::where('id', $vislog_id_key)->find() : CustomerDropPool::where('id', $vislog_id_key)->find(); $query = []; $query[] = ['employee_id', '=', $employee_id]; $l_phone = array_filter([$temporary_customer->getData('phone'), $temporary_customer->getData('phone1'), $temporary_customer->getData('phone2')]); $query[] = ['phone|phone1|phone2', 'in', $l_phone]; $check = Customer::where($query)->findOrEmpty(); if ($check->isEmpty()) { $target_ids_arr[] = $vislog_id_key; } else { $repeat_customer[] = $temporary_customer->name; } } } if ($repeat_customer) { return json(['code' => 1, 'msg' => '您选择的客户“' . implode('”,“', $repeat_customer) . '”手机号已经属于业务员' . $emp_obj->name . '请重新选择']); } if ($z_type != 'index') { $drop = $vislog_id; $vislog_ids = []; foreach ($vislog_id as $k => $v) { $ls_id = CustomerDropPool::where('id', $k)->value('customer_id'); $vislog_ids[$ls_id] = CustomerDropPool::where([['id', 'in', $v]])->column('customer_id'); } $vislog_id = $vislog_ids; } //2022-10-21 19:25:59----------------- $root_id = $this->request->token['root_org']; $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'pubpool']])->findOrEmpty(); $error = 0; $repeat = []; if (!empty($target_ids_arr)) { if ($from == 'index') { $list = Customer::where([['id', 'in', $target_ids_arr]])->select(); if (!$list->isEmpty()) { foreach ($list as $k => $v) { //如果该客户已经属于业务员则不需要分配 ,提示分配人 if ($v->employee_id == $employee_id) { $repeat[] = [$v->name, $v->phone]; continue; } $customer_state = Customer::changeState($v['state'], 'n'); $v_data['protected_to'] = null; if (!$setting->isEmpty()) { $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : []; if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) { $day = $setting_content[$customer_state]['day']; $v_data['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600); } } // //重复手机号验证 ,如果重复则合并客户信息和跟进记录 // $query = []; // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]); // $query[] = ['phone|phone1|phone2','in',$l_phone]; // $query[] = ['employee_id','=',$employee_id]; // $check = Customer::where($query)->column('*'); // if ($check) { // $this->customerMerge($v->id,$check,'emp',$v_data['protected_to']); // continue; // } $v_data['employee_id'] = $employee_id; $v_data['org_id'] = $org_id; $v_data['ext->ext6'] = ''; $v_data['designer_id'] = NULL; $v_data['revisit_time'] = NULL; $result = Customer::where('id', $v['id'])->update($v_data); if ($result === false) { $error++; } else { $param = [ 'customer_id' => $v->id, 'type' => 1, 'remark' => '客户再分配', 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '' ]; CustomerVisitLog::create($param); } } } } elseif ($from == 'drop') { $list = CustomerDropPool::where([['id', 'in', $target_ids_arr]])->select(); if (!$list->isEmpty()) { foreach ($list as $k => $v) { $customer_state = Customer::changeState($v['state'], 'n'); $info = $v->toArray(); $info['protected_to'] = null; if (!$setting->isEmpty()) { $setting_content = !empty($setting['content']) ? json_decode($setting['content'], true) : []; if (!empty($setting_content[$customer_state]['state']) && $setting_content[$customer_state]['state'] != 0 && !empty($setting_content[$customer_state]['day'])) { $day = $setting_content[$customer_state]['day']; $info['protected_to'] = date('Y-m-d H:i:s', time() + $day * 24 * 3600); } } // //重复手机号验证 ,如果重复则合并客户信息和跟进记录 // $query = []; // $l_phone = array_filter([$v->getData('phone'),$v->getData('phone1'),$v->getData('phone2')]); // $query[] = ['phone|phone1|phone2','in',$l_phone]; // $query[] = ['employee_id','=',$employee_id]; // $check = Customer::where($query)->column('*'); // if ($check) { // $this->customerMerge($v->id,$check,'drop',$info['protected_to']); // continue; // } Customer::where('id', $info['customer_id'])->delete(); //删除错误数据 $info['employee_id'] = $employee_id; $info['org_id'] = $org_id; $info['id'] = $info['customer_id']; $info['signed_money'] = $v->getData('signed_money'); $info['deposit_money'] = $v->getData('deposit_money'); $info['designer_id'] = NULL; $info['revisit_time'] = NULL; unset($info['customer_id']); unset($info['droptime']); unset($info['add_wechat_time']); unset($info['group_building_date']); unset($info['live_broadcast_date']); unset($info['subscribe_meet_outside']); unset($info['meet_outside']); unset($info['sign_time']); unset($info['reputation_gather']); unset($info['into_owner_group']); Db::startTrans(); $result = Customer::create($info); $d_result = $v->delete(); if (!empty($drop[$v->id])) CustomerDropPool::where([['id', 'in', $drop[$v->id]]])->delete(); if ($result && $d_result) { $result['ext->ext6'] = ''; $result->save(); Db::commit(); $param = [ 'customer_id' => $v->customer_id, 'type' => 1, 'remark' => '客户再分配', 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '' ]; CustomerVisitLog::create($param); } else { Db::rollback(); $error++; } } } } } // if($repeat) return json(['code' => 1, 'msg' => '有'.count($repeat).'条客户已经属于所选业务员,无法分配']); if ($error == 0) { //2022-10-21 19:25:59----------------- $this->customerMerge($vislog_id, $z_type); //2022-10-21 19:25:59----------------- return json(['code' => 0, 'msg' => '操作成功']); } else { return json(['code' => 0, 'msg' => '操作成功,部分数据失败']); } } /** * 合并跟进数据 */ private function customerMerge($array, $type) { foreach ($array as $array_key => $array_val) { foreach ($array_val as $item) { if ($array_key != $item) Customer::destroy($item); } $query = []; $query[] = ['customer_id', 'in', $array_val]; $query[] = ['customer_id', '<>', $array_key]; CustomerVisitLog::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]); CustomersSubscribe::where($query)->update(['customer_id' => $array_key, 'is_merge' => 1]); } return true; } /** * 主动回收 */ public function drop_to_pool() { $ids = input('id', '', 'trim'); $orgIds = orgSubIds($this->request->token['root_org']); $data = Customer::where([['org_id', 'in', $orgIds], ['id', 'in', $ids]])->select(); foreach ($data as $item) { Db::startTrans(); $drop_data = $item->toArray(); $drop_data['customer_id'] = $drop_data['id']; $drop_data['deposit_money'] = $item->getData('deposit_money'); $drop_data['signed_money'] = $item->getData('signed_money'); unset($drop_data['id']); unset($drop_data['add_wechat_time']); unset($drop_data['group_building_date']); unset($drop_data['live_broadcast_date']); unset($drop_data['subscribe_meet_outside']); unset($drop_data['meet_outside']); unset($drop_data['sign_time']); unset($drop_data['reputation_gather']); unset($drop_data['into_owner_group']); $save_result = CustomerDropPool::create($drop_data); $delete_result = $item->force()->delete(); $record_data['customer_id'] = $item->id; CustomerDropRecord::create($record_data); // 客户预约中改为无效 CustomersSubscribe::where([['customer_id', '=', $item->id], ['state', '=', 0]])->save(['state' => -1]); if ($save_result && $delete_result) { Db::commit(); $param = [ 'customer_id' => $item->id, 'type' => 1, 'remark' => '客户回收', 'employee_id' => $this->request->token['employee_id'], 'user_id' => $this->request->token['uid'], 'state' => '' ]; CustomerVisitLog::create($param); } else { Db::rollback(); } } return json(['code' => self::success, 'msg' => '回收成功']); } public function drop_to_pool_check() { $ids = input('id', '', 'trim'); $customer_list = Customer::where([['id', 'in', $ids]])->select(); $state_list = $customer_list->column('state'); $sign_state = Customer::changeState('签单', 'chaos'); $sign_count = 0; foreach ($state_list as $k => $v) { if (in_array($v, $sign_state)) { $sign_count++; } } $protected = 0; $setting = Setting::where([['name', '=', 'pubpool'], ['root_id', '=', $this->request->token['root_org']]])->find(); if (!empty($setting)) { $content = !empty($setting['content']) ? json_decode($setting['content'], true) : []; if (!empty($content)) { $empty = false; //判断是否是正常数据,因为之前可能有垃圾数据 foreach ($content as $k => $v) { if (!isset($v['day']) || !isset($v['state'])) { $empty = true; } } if (!$empty) { foreach ($customer_list as $k => $v) { $n = Customer::changeState($v['state'], 'n'); foreach ($content as $kk => $vv) { if (intval($kk) == intval($n) && $vv['state'] == 1 && $vv['day'] > 0 && !empty($v['protected_to']) && $v['protected_to'] > date('Y-m-d H:i:s', time())) { $protected++; } } } } } } $msg = ''; if ($sign_count && $protected) { $msg = '包含已签单及未到保护期客户'; } elseif ($sign_count) { $msg = '包含已签单客户'; } elseif ($protected) { $msg = '包含未到保护期客户'; } if ($msg == '') { return json(['code' => self::success, 'msg' => '']); } else { return json(['code' => self::error_msg, 'msg' => $msg]); } } /** * 客户互动 短信 */ public function sms($customerid, $type) { $num = CustomerSmsLog::where([['sendTime', 'between', [date('Ymd') . '000000', date('Ymd', strtotime('+1 day')) . '000000']], ['employee_id', '=', $this->request->token['employee_id']], ['state', '=', 0]])->count(); if ($num >= 3) return json(['code' => 1, 'msg' => '今日短信条数已用尽']); $customer = Customer::where([['id', '=', $customerid]])->find(); if (empty($customer)) return json(['code' => 1, 'msg' => '客户不存在']); if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) { if (isset($this->request->token['isManager']) && $this->request->token['isManager']) { $orgidList = orgSubIds($this->request->token['org_id']); $checkOrg = -1; if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) { $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id'); } elseif ($this->request->token['org_type'] == 1) { $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id'); } if (!in_array($checkOrg, $orgidList)) return json(['code' => 1, 'msg' => '客户不存在']); } } $param = $this->request->param(); // 存储参数 $data = [ 'content' => json_encode($param), 'type' => 'share' ]; $shortUrl = ShortUrl::create($data); // 将ID进行 $uri = dec52($shortUrl->id); $shortUrl->uri = $uri; $shortUrl->save(); $typeContentList = [ 'employeeCard' => '我的个人名片', 'screen' => '我推荐的内容', 'materialCase' => '我推荐的装修案例', 'evidenceCate' => '我推荐的公司口碑', ]; $typeContent = $typeContentList[$type]; $companyName = Org::where([['id', '=', $this->request->token['root_org']]])->value('name'); $employee_name = Employee::where([['id', '=', $this->request->token['employee_id']]])->value('name'); $domain = request()->domain(); $content = '【装修宝】老师您好, 我是{$var}的{$var},这是{$var}, 请您查看' . $domain . '/{$var}'; $param = "{$customer->phone},{$companyName},{$employee_name},{$typeContent},{$uri}"; $smsObj = new ChuanglanSmsApi(); $result = $smsObj->sendVariableSMS($content, $param); $rs = json_decode($result, true); if ($rs['code'] != 0) { return json(['code' => 1, 'msg' => $rs['errorMsg']]); } // 创建发送记录 $log = [ 'customer_id' => $customerid, 'employee_id' => $this->request->token['employee_id'], 'org_type' => $this->request->token['org_type'], 'type' => $type, 'phone' => $customer->phone, 'sendTime' => $rs['time'], 'msgId' => $rs['msgId'] ]; CustomerSmsLog::create($log); return json(['code' => 0, 'msg' => '发送成功']); } /** * 短信发送记录 */ public function smslog($id) { $customer = Customer::where(['id' => $id])->find(); if (empty($customer)) return json(['code' => 0, 'data' => []]); // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导) if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) { if (isset($this->request->token['isManager']) && $this->request->token['isManager']) { $orgidList = orgSubIds($this->request->token['org_id']); $checkOrg = -1; if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) { $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id'); } elseif ($this->request->token['org_type'] == 1) { $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id'); } if (!in_array($checkOrg, $orgidList)) return json(['code' => 0, 'data' => []]); } } // 查询记录 // $page = $this->request->only(['page', 'limit']); // $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg')->where(['customer_id' => $id])->page($page['page'], $page['limit'])->order('id desc')->select(); $log = CustomerSmsLog::with('employee')->field('id,type,errorMsg,state,sendTime,employee_id,org_type')->where(['customer_id' => $id])->order('id desc')->select(); return json(['code' => 0, 'data' => $log]); } /** * 获取提醒和跟进最新时间 */ public function get_date() { $token = $this->request->token; $w[] = ['employee_id', '=', $token['employee_id']]; //我的客户 $cids = Customer::where($w)->column('id'); $state1 = CustomerVisitLog::changeState('预约量房', 'chaos'); $state2 = CustomerVisitLog::changeState('预约到店', 'chaos'); $state3 = CustomerVisitLog::changeState('预约活动', 'chaos'); // //提醒的最新时间 // $w1[] = ['customer_id', 'in', $cids]; // $w1[] = ['state', 'in', array_merge($state1, $state2, $state3)]; // $date = CustomerVisitLog::where($w1)->order('next_contact_date desc')->value('next_contact_date'); // $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : ''; //跟进的最新时间 $state4 = CustomerVisitLog::changeState('无效', 'chaos'); //$state5 = CustomerVisitLog::changeState('预约回访', 'chaos'); $state = array_merge($state1, $state2, $state3, $state4); $w2[] = ['customer_id', 'in', $cids]; $w2[] = ['state', 'not in', $state]; $date1 = CustomerVisitLog::where($w2)->order('next_contact_date desc')->value('next_contact_date'); $date1 = $date1 ? (strtotime($date1) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date1)) : date('Y-m')) : ''; $date = CustomersSubscribe::where([ ['employee_id|designer_id', '=', $token['employee_id']], ['state', '=', 0] ])->order('subscribe_date desc')->value('subscribe_date'); $date = $date ? (strtotime($date) >= strtotime(date('Y-m')) ? date('Y-m', strtotime($date)) : date('Y-m')) : ''; $res['remind'] = $date; $res['followup'] = $date1; return json(['code' => 0, 'data' => $res]); } /** * 客户预约记录 */ public function subscribe($id) { // 检测是否是我的客户 $customer = Customer::where(['id' => $id])->find(); if (empty($customer)) return json(['code' => 0, 'data' => []]); // 检测客户所属(部门领导查看,设计师查看,销售查看,销售的部门领导) if ($customer->employee_id != $this->request->token['employee_id'] && $customer->designer_id != $this->request->token['employee_id']) { if (isset($this->request->token['isManager']) && $this->request->token['isManager']) { $orgidList = orgSubIds($this->request->token['org_id']); $checkOrg = -1; if ($this->request->token['org_type'] == 2 && !empty($customer->designer_id)) { $checkOrg = Employee::where(['id' => $customer->designer_id])->value('org_id'); } elseif ($this->request->token['org_type'] == 1) { $checkOrg = Employee::where(['id' => $customer->employee_id])->value('org_id'); } if (!in_array($checkOrg, $orgidList)) return json(['code' => 0, 'data' => []]); } else { return json(['code' => 0, 'data' => []]); } } // 查询记录 $data = CustomersSubscribe::withoutField('org_id')->with(['employee' => function ($query) { $query->withfield(['id', 'name']); }, 'designer' => function ($query) { $query->withfield(['id', 'name']); }])->where([['customer_id', '=', $customer->id]])->order('addtime desc')->select(); return json(['code' => 0, 'data' => $data]); } /** * 未回访记录 */ public function notVisitLog($page = 1, $date = null, $keyword = null) { // 判断当前登陆人是不是领导 if (!$this->request->token['isManager']) return json(['code' => 0, 'data' => []]); $cOrgId = (new Org())->getChildOrg($this->request->token['org_id']); $condition = [ ['org_id', 'in', $cOrgId] ]; $orCondition = []; if ($date) $condition[] = ['appoint_date', '=', $date]; if (!empty($keyword)) { $guodu = CustomerNotVisit::where($condition)->column('customer_id,employee_id,designer_id,org_id'); if (empty($guodu)) return json(['code' => 0, 'data' => []]); $customerIdLIst = Customer::where([['id', 'in', array_column($guodu, 'customer_id')], ['name', 'like', '%' . $keyword . '%']])->column('id'); $employeeIdList = Employee::where([ ['name', 'like', '%' . $keyword . '%'], ['id', 'in', array_column($guodu, 'employee_id')] ])->column('id'); $designerIdList = Employee::where([ ['name', 'like', '%' . $keyword . '%'], ['id', 'in', array_column($guodu, 'designer_id')] ])->column('id'); $orgIdList = Org::where([ ['name', 'like', '%' . $keyword . '%'], ['id', 'in', array_column($guodu, 'org_id')] ])->column('id'); $orCondition = [ ['employee_id', 'in', $employeeIdList], ['designer_id', 'in', $designerIdList], ['org_id', 'in', $orgIdList], ['customer_id', 'in', $customerIdLIst] ]; } $data = CustomerNotVisit::with([ 'customer' => function ($query) { $query->withField(['id', 'name', 'sex', 'level', 'community_name']); }, 'employee' => function ($query) { $query->withField(['id', 'name']); }, 'designer' => function ($query) { $query->withField(['id', 'name']); }, 'org' => function ($query) { $query->withField(['id', 'name']); } ])->where(function ($query) use ($orCondition) { $query->whereOr($orCondition); })->where($condition) ->page($page, 30) ->order('addtime desc') ->select(); return json(['code' => 0, 'data' => $data]); } /** * 客户报备自定义 * type:add根据后台勾选展示,edit展示全部 */ public function get_portrait_field() { $id = input('id', '', 'trim'); $type = input('type'); $token = $this->request->token; $where = [ ['root_id', '=', $token['root_org']], ['pid', '>', 0], ['status', '=', 0] ]; if ($type == 'add') { $setting = Setting::where([['name', '=', 'settingCustomerReportField'], ['root_id', '=', $token['root_org']]])->find(); if ($setting && !empty($setting['content'])) { $all_content = json_decode($setting['content'], true); $field_id = array_column($all_content, 'id'); $where[] = ['id', 'in', $field_id]; } else { //默认值 $where[] = ['keyname', 'in', ['name', 'phone', 'sex', 'age_range', 'intention', 'consumption_capacity', 'current_region', 'source_id', 'first', 'add_wechat_type', 'add_wechat_time', 'group_building', 'live_broadcast', 'group_building_date', 'follow', 'point', 'wechat', 'talking_about_single_time', 'community_name', 'unit_number', 'house_location', 'square', 'housetype_arrow', 'deco_style', 'house_type', 'house_status', 'plan_deco_time', 'budget', 'housing_use', 'peripheral_supporting', 'house_structure', 'decoration_mode', 'like_color', 'customer_demand', 'remarks_on_other_house_information', 'family_structure', 'decision_maker', 'family_opinion', 'hourse_price', 'car_price', 'buying_community', 'hobby', 'free_time', 'environmental_requirements', 'design', 'workmanship', 'space_design', 'service_satisfaction', 'quotation_satisfaction', 'program_satisfaction']]; } } //获取第二层 $all = CustomerPortraitField::with(['select'])->where($where)->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray(); if ($type == 'add' && $setting && !empty($setting['content'])) { //如果是设置自定义展示,则循序按照勾选的排序进行组装 $all_new = []; foreach ($all_content as $c) { foreach ($all as $vals) { if ($c['id'] == $vals['id']) { $all_new[] = $vals; } } } $all = $all_new; } $city = Company::where('root_id', $token['root_org'])->value('city'); foreach ($all as &$val) { if ($val['keyname'] == 'current_region') { $val['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $val['id']]; } if ($val['keyname'] == 'source_id') { $val['select'] = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray(); } if ($val['keyname'] == 'deco_style') { $val['select'] = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray(); } } //获取第一层 $pid = array_column($all, 'pid'); $list = CustomerPortraitField::where([['id', 'in', $pid], ['status', '=', 0], ['pid', '=', 0]]); if ($type == 'add' && $setting && !empty($setting['content'])) { //如果是添加页面,把自定义字段追加到基本信息child下 $list = $list->order('id')->limit(1)->select()->toArray(); } else { $list = $list->orderRaw('if(isnull(sort),1,0),sort asc')->select()->toArray(); } //组装数组 foreach ($list as &$p) { foreach ($all as &$item) { $item['value'] = ''; $item['valname'] = ''; if ($type == 'add' && $setting && !empty($setting['content'])) { $p['child'][] = $item; } else { if ($p['id'] == $item['pid']) $p['child'][] = $item; } } } $cuslog = new CustomerLogic; if (isset($id) && !empty($id)) { $cusdata = Customer::where([['id', '=', $id]])->find()->toArray(); if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') { $extdata = json_decode($cusdata['ext'], true); if (isset($extdata['ext1'])) { $list = $cuslog->old_data_save($cusdata, $list); } else { $list = $cuslog->new_data_save($cusdata, $extdata, $list); } } else { $list = $cuslog->no_ext_save($cusdata, $list); } } return json(['code' => 0, 'msg' => '获取成功', 'data' => $list]); } /** * 手机端验证报名客户必填字段 */ public function check_must_field($ext) { $token = $this->request->token; $house_type_value = ''; $live_broadcast_value = []; foreach ($ext as $key => $val) { if ($val['keyname'] == 'house_type' && !empty($val['value'])) { $house_type_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', '=', $val['value']]])->value('name'); } if ($val['keyname'] == 'live_broadcast' && !empty($val['value'])) { $live_broadcast_value = CustomerPortraitFieldSelect::where([['pid', '=', $val['id']], ['id', 'in', explode(',', $val['value'])]])->column('name'); } } //判断必填项 $must_list = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0], ['is_must', '=', 0]])->column('name', 'keyname'); foreach ($ext as $key => $val) { if ($house_type_value != '期房' && $val['keyname'] == 'house_delivery_time' && in_array($val['keyname'], array_keys($must_list))) continue; if (!in_array('1对1业务直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_business' && in_array($val['keyname'], array_keys($must_list))) continue; if (!in_array('1对1设计直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_design' && in_array($val['keyname'], array_keys($must_list))) continue; if (!in_array('一对多直播', $live_broadcast_value) && $val['keyname'] == 'live_broadcast_personnel' && in_array($val['keyname'], array_keys($must_list))) continue; if (in_array($val['keyname'], array_keys($must_list)) && empty($val['value'])) { return json(['code' => 1, 'msg' => $must_list[$val['keyname']] . '为必填项']); } } } //新添加客户扩展字段 public function add_customer_extfield() { $token = $this->request->token; $ext = input('ext', '', 'trim'); $id = input('id'); $subOrg = orgSubIds($token['root_org']); $cda = Customer::find($id); if (empty($cda) || !in_array($cda['org_id'], $subOrg)) { return json(['code' => 1, 'msg' => '客户数据为空']); } if (empty($ext)) return json(['code' => 1, 'msg' => '暂未设置数据']); $seldata = CustomerPortraitField::with(['select'])->where([['root_id', '=', $token['root_org']], ['type', 'in', [3, 4]]])->select()->toArray(); $allselid = []; foreach ($seldata as $key => $val) { foreach ($val['select'] as $k => $v) { $allselid[] = ['id' => $v['id'], 'name' => $v['name']]; } } foreach ($ext as $key => $val) { $selval = ''; if ($val['keyname'] == 'community_name') { $house_data['community_name'] = $val['value']; } if ($val['keyname'] == 'square') { $house_data['square'] = $val['value']; } if ($val['keyname'] == 'house_type') { foreach ($allselid as $k => $v) { if ($val['value'] == $v['id']) { $selval = $v['name']; } } $house_data['house_type'] = $selval; } if ($val['keyname'] == 'house_status') { foreach ($allselid as $k => $v) { if ($val['value'] == $v['id']) { $selval = $v['name']; } } $house_data['house_status'] = $selval; } if ($val['keyname'] == 'house_delivery_time') { $house_data['house_delivery_time'] = $val['value']; } if ($val['keyname'] == 'plan_deco_time') { $house_data['plan_deco_time'] = $val['value']; } if ($val['keyname'] == 'budget') { $house_data['budget'] = $val['value']; } if ($val['keyname'] == 'deco_style') { foreach ($allselid as $k => $v) { if ($val['value'] == $v['id']) { $selval = $v['name']; } } $house_data['deco_style'] = $selval; } if ($val['keyname'] == 'follow') { if (!empty($val['value'])) { $gza = explode(',', $val['value']); foreach ($allselid as $k => $v) { if (in_array($v['id'], $gza)) { $selval .= $v['name'] . ','; } } } $house_data['product'] = trim($selval, ','); } if ($val['type'] == 6 && !empty($val['value'])) { //上传图片类型 $file_media_id = []; foreach ($val['value'] as $k => $img) { $file_media_id[$k] = [ 'serverId' => !empty($img['serverId']) ? $img['serverId'] : '', 'img' => !empty($img['img']) ? str_replace('https://' . config('app.ali_oss_bindurl') . '/', '', $img['img']) : '' ]; } $house_data['ext_down_status'] = 1; $ext[$key]['value'] = json_encode($file_media_id); } else { //清除type类型 unset($ext[$key]['type']); } } $c_logic = new CustomerLogic(); if (!empty($cda['ext']) && $cda['ext'] != 'null') { $extdata = json_decode($cda['ext'], true); if (isset($extdata['ext1'])) { $new_ext = CustomerPortraitField::where([['root_id', '=', $token['root_org']], ['pid', '<>', 0]])->select()->toArray(); $c_logic->check_old_updatefield($cda, $ext, $new_ext, $token); $ext = $c_logic->old_ext_edit($cda, $ext, $new_ext); } else { $c_logic->check_new_updatefield($cda, $ext, $token); $ext = $c_logic->new_ext_edit($cda, $ext); } } if (empty($cda['ext'])) $c_logic->check_not_updatefield($cda, $ext, $token); $house_data['ext'] = json_encode($ext); $ms = $cda->save($house_data); // 微爆加微监听 $new_info = Customer::find($id); if ($new_info['add_wechat_time'] && empty($cda['add_wechat_time'])) { $i_data['add_wechat_time'] = $new_info['add_wechat_time']; $i_data['customer_id'] = $id; $i_data['employee_id'] = $new_info['employee_id']; $i_data['type'] = 1; $i_data['org_id'] = $new_info['org_id']; WechatActivityIntegral::addIntegral($i_data, $token['root_org']); } Console::call('download', ['crm_ext_field']); Console::call('download', ['save_portrait_field']); if ($ms) { return json(['code' => 0, 'msg' => '设置成功']); } else { return json(['code' => 1, 'msg' => '设置失败']); } } /** * 客户迁移 */ public function customerTransfer() { $param = $this->request->only(['customer_ids' => '', 'employee_id']); $root_id = request()->token['root_org']; $subOrg = orgSubIds($root_id); $arr = explode(',', $param['customer_ids']); $customers = Customer::where([['id', 'in', $arr], ['org_id', 'in', $subOrg]])->column('id,name,phone,phone1,phone2,employee_id'); $employee = Employee::find($param['employee_id']); if (empty($customers) || empty($employee) || !in_array($employee['org_id'], $subOrg)) { return json(['code' => 0, 'msg' => '迁移完成']); } // 要转移的客户电话合集 这个电话属于谁 $transfer_phones = []; $phone_employee = []; foreach ($customers as $k => $v) { $v_phone = array_filter([$v['phone'], $v['phone1'], $v['phone2']]); $transfer_phones = array_merge($transfer_phones, $v_phone); if (empty($phone_employee[$v['employee_id']])) { $phone_employee[$v['employee_id']] = $v_phone; } else { $phone_employee[$v['employee_id']] = array_merge($phone_employee[$v['employee_id']], $v_phone); } } $all_ids = array_column($customers, 'id'); // 先判断撞单 // 同部门能否重复录入开关设置 $empcrm_repeat[] = ['root_id', '=', $root_id]; $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($employee['org_id'], $repeat_org)) { $repeat_org = [$employee['org_id']]; } } else { $repeat_org = [$employee['org_id']]; } $ex_where[] = ['phone', 'in', $transfer_phones]; $ex_where[] = ['org_id', 'in', $repeat_org]; $ex_where[] = ['employee_id', '>', 0]; $ex_where[] = ['id', 'not in', $all_ids]; $customerExist = Customer::where($ex_where)->where( function ($query) { $not_sure = Customer::changeState('待确认', 'chaos'); $or1[] = ['crm_res_id', 'null', null]; $or2[] = ['crm_res_id', '>', 0]; $or2[] = ['state', 'not in', $not_sure]; $query->whereOr([$or1, $or2]); } )->column('id,name,phone,employee_id'); $repeat_ids = $repeat = $no_repeat = []; if (!empty($customerExist)) { foreach ($customerExist as $ex) { $repeat[] = $ex['name']; $repeat_ids[] = $ex['id']; } } $no_repeat = array_diff($all_ids, $repeat_ids); if ($no_repeat) { $org_id = Employee::where('id', $param['employee_id'])->value('org_id'); Customer::where([['id', 'in', $no_repeat]])->update(['employee_id' => $param['employee_id'], 'org_id' => $org_id]); //记录操作人信息PC端需要用到 Customer::where([['id', 'in', $no_repeat]])->update(['transfer_info' => json_encode(['transfer_empid' => request()->token['employee_id'], 'transfer_time' => date('Y-m-d H:i:s'), 'transfer_empname' => request()->token['name']])]); //修改转移的客户的跟进记录的customer_employee_id为新员工的id CustomerVisitLog::where([['customer_id', 'in', $no_repeat], ['org_id', 'in', $subOrg]])->update(['customer_employee_id' => $param['employee_id'], 'customer_org_id' => $org_id]); } if ($repeat) return json(['code' => 1, 'msg' => '迁移失败:[' . implode(',', $repeat) . ']撞单或员工名下已存在客户']); return json(['code' => 0, 'msg' => '迁移完成']); } /** * 客户自定义模块显示控制 */ public function moduleSwitch() { $root_id = $this->request->token['root_org']; // 客户信息完善开关 $perfect_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'modulePerfectSwitch']])->findOrEmpty(); if ($perfect_find->isEmpty()) { $perfect = 1; } else { $perfect = $perfect_find['content']; } $data['perfect'] = $perfect; // 客户转化开关 $change_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleChangeSwitch']])->findOrEmpty(); if ($change_find->isEmpty()) { $change = 1; } else { $change = $change_find['content']; } $data['change'] = $change; // 客户预约开关 $subscribe_find = Setting::where([['root_id', '=', $root_id], ['name', '=', 'moduleSubscribeSwitch']])->findOrEmpty(); if ($subscribe_find->isEmpty()) { $subscribe = 1; } else { $subscribe = $subscribe_find['content']; } $data['subscribe'] = $subscribe; return json(['code' => 0, 'data' => $data]); } /** * 客户跟踪快速标签 */ public function clueTag() { $where[] = ['name', '=', 'clueTag']; $where[] = ['root_id', '=', $this->request->token['root_org']]; $find = Setting::where($where)->findOrEmpty(); if ($find->isEmpty()) { $list = ['已装修', '无需求', '有需求', '超地域', '未交房', '在外地', '无购买力', '未接通电话']; } else { $list = array_filter(explode(',', $find['content'])); } return json(['code' => 0, 'data' => $list]); } /** * 客户跟踪字段 */ public function visitField() { $id = input('id', '', 'intval'); $token = $this->request->token; $v_where[] = ['root_id', '=', $token['root_org']]; $v_where[] = ['name', '=', 'visitSettingField']; $visitField = Setting::where($v_where)->findOrEmpty(); $field = []; if (!$visitField->isEmpty()) { $v_field = !empty($visitField['content']) ? json_decode($visitField['content'], true) : []; $ids = !empty($v_field) ? array_column($v_field, 'id') : []; $v_list = CustomerPortraitField::with(['select'])->where('id', 'in', $ids)->select()->toArray(); foreach ($v_field as $k => $v) { foreach ($v_list as $kk => $vv) { if ($v['id'] == $vv['id']) { $field[] = $vv; } } } } else { $field = CustomerPortraitField::with(['select'])->where([['root_id', '=', $token['root_org']], ['keyname', 'in', ['wechat', 'add_wechat_type', 'add_wechat_time', 'level', 'intention', 'plan_deco_time', 'group_building']]])->order('sort asc')->select()->toArray(); } $city = Company::where('root_id', $token['root_org'])->value('city'); foreach ($field as $k => $v) { if ($v['keyname'] == 'current_region') { $field[$k]['select'][] = ['id' => $token['root_org'], 'name' => $city, 'pid' => $v['pid']]; } if ($v['keyname'] == 'source_id') { $soudata = CustomerSource::field('id,source as name')->where('root_id', $token['root_org'])->select()->toArray(); $field[$k]['select'] = $soudata; } if ($v['keyname'] == 'deco_style') { $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $token['root_org']], ['type', '=', 0]])->select()->toArray(); $field[$k]['select'] = $decostyles; } } if (!empty($id)) { $c_logic = new CustomerLogic(); $cusdata = Customer::where([['id', '=', $id]])->find()->toArray(); if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') { // $extdata=get_object_vars($cusdata['ext']); $extdata = json_decode($cusdata['ext'], true); if (isset($extdata['ext1'])) { $field = $c_logic->old_data_saves($cusdata, $field); } else { $field = $c_logic->new_data_saves($cusdata, $extdata, $field); } } else { $field = $c_logic->no_ext_saves($cusdata, $field); } } return json(['code' => 0, 'data' => $field]); } /** * 客户转化自定义设置 */ public function changeModule() { $id = input('id', '', 'intval'); $root_id = $this->request->token['root_org']; // 子模块开关 量房、到店、活动、签单、转单、卖卡 $switch_where[] = ['name', 'in', ['changeSettingSwitchLF', 'changeSettingSwitchDD', 'changeSettingSwitchHD', 'changeSettingSwitchJD', 'changeSettingSwitchZD', 'changeSettingSwitchMK', 'changeSettingSwitchDDHD']]; $switch_where[] = ['root_id', '=', $root_id]; $z_setting = Setting::where($switch_where)->select()->toArray(); $lf_switch = 1; //量房 $dd_switch = 1; //到店 $hd_switch = 1; //活动 $jd_switch = 1; //签单 (交定) $zd_switch = 1; //转单 $mk_switch = 1; //卖卡 $ddhd_switch = 1; //到店活动 foreach ($z_setting as $k => $v) { if ($v['name'] == 'changeSettingSwitchLF') $lf_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchDD') $dd_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchHD') $hd_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchJD') $jd_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchZD') $zd_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchMK') $mk_switch = $v['content']; if ($v['name'] == 'changeSettingSwitchDDHD') $ddhd_switch = $v['content']; } $data['lf']['show'] = $lf_switch; $data['dd']['show'] = $dd_switch; $data['hd']['show'] = $hd_switch; $data['jd']['show'] = $jd_switch; $data['zd']['show'] = $zd_switch; $data['mk']['show'] = $mk_switch; $data['ddhd']['show'] = $ddhd_switch; $city = Company::where('root_id', $root_id)->value('city'); if (!empty($id)) { $cusdata = Customer::where([['id', '=', $id]])->find()->toArray(); } $array = ['LF', 'DD', 'HD', 'JD', 'ZD', 'MK']; foreach ($array as $k => $v) { $lower = strtolower($v); unset($c_where); $c_where[] = ['root_id', '=', $root_id]; $c_where[] = ['name', '=', 'changeSettingField' . $v]; $changeField = Setting::where($c_where)->findOrEmpty(); $new_list = []; if (!$changeField->isEmpty()) { $changeField_decode = !empty($changeField['content']) ? json_decode($changeField['content'], true) : []; $ids_one = array_column($changeField_decode, 'id'); $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray(); foreach ($changeField_decode as $kk => $vv) { foreach ($ids_list as $vvv) { if ($vv['id'] == $vvv['id']) { $new_list[] = $vvv; } } } } elseif ($v == 'JD') { $new_list = CustomerPortraitField::with('select')->where([['root_id', '=', $root_id], ['keyname', 'in', ['drawing_date', 'plan_issuing_date', 'plan_passing_date', 'material_selection_date', 'will_transfer_to_construction_date']]])->order('sort asc')->select()->toArray(); } foreach ($new_list as $kk => $vv) { if ($vv['keyname'] == 'current_region') { $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']]; } if ($vv['keyname'] == 'source_id') { $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray(); $new_list[$kk]['select'] = $soudata; } if ($vv['keyname'] == 'deco_style') { $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray(); $new_list[$kk]['select'] = $decostyles; } } $c_logic = new CustomerLogic(); if (!empty($id)) { if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') { // $extdata=get_object_vars($cusdata['ext']); $extdata = json_decode($cusdata['ext'], true); if (isset($extdata['ext1'])) { $new_list = $c_logic->old_data_saves($cusdata, $new_list); } else { $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list); } } else { $new_list = $c_logic->no_ext_saves($cusdata, $new_list); } } $data[$lower]['field'] = $new_list; } return json(['code' => 0, 'data' => $data]); } /** * 客户预约自定义设置 */ public function subscribeModule() { $id = input('id', '', 'intval'); $root_id = $this->request->token['root_org']; // 子模块开关 活动、到店、量房 $switch_where[] = ['name', 'in', ['subscribeSettingSwitchYYLF', 'subscribeSettingSwitchYYDD', 'subscribeSettingSwitchYYHD']]; $switch_where[] = ['root_id', '=', $root_id]; $z_setting = Setting::where($switch_where)->select()->toArray(); $hd_switch = 1; //活动 $dd_switch = 1; //到店 $lf_switch = 1; //量房 foreach ($z_setting as $k => $v) { if ($v['name'] == 'subscribeSettingSwitchYYLF') $lf_switch = $v['content']; if ($v['name'] == 'subscribeSettingSwitchYYDD') $dd_switch = $v['content']; if ($v['name'] == 'subscribeSettingSwitchYYHD') $hd_switch = $v['content']; } $data['lf']['show'] = $lf_switch; $data['dd']['show'] = $dd_switch; $data['hd']['show'] = $hd_switch; $city = Company::where('root_id', $root_id)->value('city'); if (!empty($id)) { $cusdata = Customer::where([['id', '=', $id]])->find()->toArray(); } $array = ['YYHD', 'YYDD', 'YYLF']; foreach ($array as $k => $v) { $lower = strtolower($v); unset($sub_where); $sub_where[] = ['root_id', '=', $root_id]; $sub_where[] = ['name', '=', 'subscribeSettingField' . $v]; $subscribeField = Setting::where($sub_where)->findOrEmpty(); $new_list = []; if (!$subscribeField->isEmpty()) { $subscribeField_decode = !empty($subscribeField['content']) ? json_decode($subscribeField['content'], true) : []; $ids_one = array_column($subscribeField_decode, 'id'); $ids_list = CustomerPortraitField::with('select')->where('id', 'in', $ids_one)->select()->toArray(); foreach ($subscribeField_decode as $kk => $vv) { foreach ($ids_list as $vvv) { if ($vv['id'] == $vvv['id']) { $new_list[] = $vvv; } } } } foreach ($new_list as $kk => $vv) { if ($vv['keyname'] == 'current_region') { $new_list[$kk]['select'][] = ['id' => $root_id, 'name' => $city, 'pid' => $vv['pid']]; } if ($vv['keyname'] == 'source_id') { $soudata = CustomerSource::field('id,source as name')->where('root_id', $root_id)->select()->toArray(); $new_list[$kk]['select'] = $soudata; } if ($vv['keyname'] == 'deco_style') { $decostyles = Decostyle::field('id,name')->where([['root_id', '=', $root_id], ['type', '=', 0]])->select()->toArray(); $new_list[$kk]['select'] = $decostyles; } } if (!empty($id)) { $c_logic = new CustomerLogic(); if (!empty($cusdata['ext']) && $cusdata['ext'] != 'null') { $extdata = json_decode($cusdata['ext'], true); if (isset($extdata['ext1'])) { $new_list = $c_logic->old_data_saves($cusdata, $new_list); } else { $new_list = $c_logic->new_data_saves($cusdata, $extdata, $new_list); } } else { $new_list = $c_logic->no_ext_saves($cusdata, $new_list); } } $data[$lower]['field'] = $new_list; } return json(['code' => 0, 'data' => $data]); } /** * 店面列表 */ public function shop_list() { $shop_list = Shop::where('root_id', '=', $this->request->token['root_org'])->select()->toArray(); return json(['code' => 0, 'data' => $shop_list]); } /** * 申请死单 */ public function dieCustomer() { $customer_id = input('customer_id', '', 'intval'); $reason = input('reason', '', 'trim'); $find = Customer::where('id', '=', $customer_id)->findOrEmpty(); if ($find->isEmpty() || $find['employee_id'] != request()->token['employee_id']) { return json(['code' => 1, 'msg' => '操作失败']); } $data['died'] = 1; $data['died_reason'] = $reason; $data['died_date'] = date('Y-m-d H:i:s', time()); $result = $find->save($data); if ($result !== false) { return json(['code' => 0, 'msg' => '操作成功']); } else { return json(['code' => 1, 'msg' => '操作失败']); } } /** * 操作设置 */ public function moduleHandel() { $root_id = request()->token['root_org']; $setting = Setting::where([['root_id', '=', $root_id], ['name', '=', 'customerHandel']])->findOrEmpty(); if (!$setting->isEmpty()) { $content = json_decode($setting['content'], true); } else { $content = [ 'wechat' => 1, 'group_building' => 1, 'live_broadcast' => 1 ]; } return json(['code' => 0, 'data' => $content]); } /** * 智慧屏 讲解链接 */ public function produceUrl() { $token = $this->request->token; $param = request()->only(['customer_id' => 0]); $str = $token['root_org'] . '#' . $token['employee_id'] . '#' . $param['customer_id']; $aec = new Aec(config('app.aec_key'), config('app.aec_iv')); $value = $aec->encrypt($str); // $ali_oss_bindurl = config('app.ali_oss_bindurl'); // $url = 'https://' . $ali_oss_bindurl . '/' . 'dashboard/wisdom?token='.$value; return json(['code' => 0, 'data' => $value]); } /** * 获取小区 */ public function getCommunity() { $token = $this->request->token; $name = input('name', '', 'trim'); if ($name) { $where[] = ['name', 'like', '%' . $name . '%']; } $where[] = ['root_id', '=', $token['root_org']]; $list = Community::where($where)->order('addtime desc')->select()->toArray(); // 交房时间新增到了小区信息中,下方代码注释不再使用 2023-03-06 /* foreach ($list as $k => $v) { $building = Building::where('community_id', '=', $v['id'])->order('addtime desc')->findOrEmpty(); if ($building->isEmpty()) { $list[$k]['duetime'] = ''; } else { $list[$k]['duetime'] = $building['duetime']; } } */ return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']); } /** * 小程序资源库分配 已分配客户列表 */ public function assignedCustomer() { $param = Request::only(['employee_id' => 0, 'crm_res_id' => 0, 'org_id' => 0, 'page' => 1, 'limit' => 10]); $token = $this->request->token; $root_id = $token['root_org']; $subOrg = orgSubIds($root_id); $p_where[] = ['org_id', 'in', $subOrg]; $p_where[] = ['pid|id', '=', $param['crm_res_id']]; $pid = CrmImportLog::where($p_where)->column('id'); $where[] = ['crm_res_id', 'in', $pid]; if ($param['employee_id']) { $where[] = ['employee_id', '=', $param['employee_id']]; } elseif ($param['org_id']) { $where[] = ['org_id', '=', $param['org_id']]; $where[] = ['is_resource', '=', 1]; $where[] = ['employee_id', 'NULL', null]; } else { return json(['code' => 0, 'data' => [], 'count' => 0, 'msg' => '获取成功']); } $list = Customer::where($where)->page($param['page'], $param['limit'])->field('name,phone')->select()->toArray(); $count = Customer::where($where)->count(); foreach ($list as $k => $v) { $list[$k]['phone'] = substr_replace($v['phone'], '******', 3, 6); } return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']); } /** * 客户智慧屏保存实景图,效果图 * [{img: "", serverId: ""},{img: "", serverId: ""}] */ public function saveWisdomImg() { $arr = input('content', []); $customer_id = input('customer_id', 0); $cate = input('type', 0); if (empty($arr) || !is_array($arr) || count($arr) == count($arr, 1) || !$customer_id) return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']); $img = array_filter(array_column($arr, 'img')); $media_id = array_filter(array_column($arr, 'serverId')); if ($img) { $type = 'img'; $arr = $img; } elseif ($media_id) { $type = 'media_id'; $arr = $media_id; } else { return json(['code' => 1, 'data' => '参数错误', 'msg' => '参数错误']); } $token = $this->request->token; // $token['root_org'] = 23; $save = []; foreach ($arr as $k => $v) { $save[] = [ 'root_id' => $token['root_org'], 'customer_id' => $customer_id, $type => $v, 'type' => $cate ]; } CustomerWisdomImg::insertAll($save); if ($media_id) Console::call('download', ['wisdom']); //保存客户跟进记录0实景图,1效果图 $str = $cate ? '智慧屏效果图上传' : '智慧屏实景图上传'; $field = $img ? 'img' : 'media_id'; if ($img) { $imgs = implode(',', $img); } else { $imgs = CustomerWisdomImg::where([['media_id', 'in', $arr]])->column('img'); $imgs = implode(',', $imgs); } $remark = $str . '##' . $imgs; $save = [ 'customer_id' => $customer_id, 'type' => '', 'next_contact_date' => date('Y-m-d'), 'remark' => '智慧屏客户图片##' . $remark, 'addtime' => date('Y-m-d H:i:s'), 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'state' => '未到访', 'org_id' => $token['org_id'], 'customer_employee_id' => $token['employee_id'], 'customer_org_id' => $token['org_id'] ]; CustomerVisitLog::insert($save); return json(['code' => 0, 'data' => '保存成功', 'msg' => '保存成功']); } /** * 获取客户智慧屏图片图片 */ public function getWisdomImg() { $param = Request::only(['customer_id' => 0, 'type' => 0]); $token = $this->request->token; // $token['root_org'] = 23; $where = [ 'customer_id' => $param['customer_id'], 'type' => $param['type'], 'root_id' => $token['root_org'] ]; $list = CustomerWisdomImg::where($where)->field('id,img')->order('id asc')->select()->toArray(); return json(['code' => 0, 'data' => $list, 'msg' => '获取成功']); } /** * 删除客户智慧屏图片图片 */ public function delWisdomImg() { $param = Request::only(['customer_id' => 0, 'id' => 0]); $info = CustomerWisdomImg::where('id', $param['id'])->findOrEmpty(); if ($info->isEmpty()) return json(['code' => 1, 'data' => '删除失败', 'msg' => '删除失败']); $token = $this->request->token; // $token['root_org'] = 23; $where = [ 'customer_id' => $param['customer_id'], 'id' => $param['id'], 'root_id' => $token['root_org'] ]; $list = CustomerWisdomImg::where($where)->delete(); $str = $info->type ? '智慧屏效果图删除' : '智慧屏实景图删除'; //智慧屏删除 $remark = $str . '##' . $info->getData('img'); $save = [ 'customer_id' => $param['customer_id'], 'type' => '', 'next_contact_date' => date('Y-m-d'), 'remark' => '智慧屏客户图片##' . $remark, 'addtime' => date('Y-m-d H:i:s'), 'employee_id' => $token['employee_id'], 'user_id' => $token['uid'], 'state' => '未到访', 'org_id' => $token['org_id'], 'customer_employee_id' => $token['employee_id'], 'customer_org_id' => $token['org_id'] ]; CustomerVisitLog::insert($save); return json(['code' => 0, 'data' => '删除成功', 'msg' => '删除成功']); } /** * 是否有外呼系统 */ public function haveOutCall() { $info = OutCallSetting::where('root_id', '=', request()->token['root_org'])->findOrEmpty(); $have = false; if (!$info->isEmpty()) { if (!isset($info->config['open']) || $info->config['open'] == 1) $have = true; } return json(['code' => 0, 'data' => $have, 'msg' => 'success']); } /** * 获取指派类型 */ public function getAssignType() { $setting = Setting::where([['root_id', '=', request()->token['root_org']], ['name', '=', 'assign_type']])->findOrEmpty(); $default['yixiang'] = '意向客户指派'; $default['liangfang'] = '量房客户指派'; $default['daodian'] = '到店客户指派'; $data = []; if (!$setting->isEmpty()) { $content = json_decode($setting['content'], true); if (!empty($content)) { foreach ($content as $k => $v) { if (isset($default[$v])) { $data[$v] = $default[$v]; } } } } return json(['code' => 0, 'data' => $data, 'msg' => 'success']); } /** * 智慧屏绑定客户 */ public function bindCustomers() { $token = $this->request->token; $param = Request::only(['customer_id' => 0, 'employee_id' => 0, 'token' => '']); if (strpos($param['token'], '@' . $token['root_org'] . '@') === false) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']); $org = Org::where([['path', 'like', $token['root_org'] . '-%']])->column('id'); $where = [ // ['employee_id|designer_id','=',$param['employee_id']], ['id', '=', $param['customer_id']], ['org_id', 'in', $org] ]; $find = Customer::where($where)->value('id'); if (!$find) return json(['code' => 1, 'data' => '绑定失败', 'msg' => '绑定失败']); $str = $token['root_org'] . '#' . $param['employee_id'] . '#' . $param['customer_id']; $aec = new Aec(config('app.aec_key'), config('app.aec_iv')); $str = $aec->encrypt($str); Cache::set($param['token'], $str, 60); return json(['code' => 0, 'data' => '绑定成功', 'msg' => '获取成功']); } /** * 龙虎榜 */ public function topStatistics() { $root_id = request()->token['root_org']; $orgList = orgSubIds($root_id); $param = request()->param(['start_date' => '2021-01-01', 'end_date' => date('Y-m-d')]); $type = input('type', '', 'trim'); !empty($param['start_date']) ?: $param['start_date'] = '2021-01-01'; !empty($param['end_date']) ?: $param['end_date'] = date('Y-m-d'); $start_date = date('Y-m-d 00:00:00', strtotime($param['start_date'])); $end_date = date('Y-m-d 00:00:00', strtotime($param['end_date']) + 86400); switch ($type) { case 'jiav': $where[] = ['org_id', 'in', $orgList]; $where[] = ['add_wechat_time', '>=', $start_date]; $where[] = ['add_wechat_time', '<', $end_date]; $where[] = ['employee_id', 'NOTNULL', '']; $e = Customer::where($where)->field('employee_id, count(id) as num')->group('employee_id')->order('num desc')->select(); break; case 'daodian': $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('已到店', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.employee_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('customer.employee_id'); $cvl = array_count_values($cvl); $e = []; foreach ($cvl as $employee_id => $num) { $e[] = [ 'employee_id' => $employee_id, 'num' => $num ]; } array_multisort(array_column($e, 'num'), SORT_DESC, $e); break; case 'qiandan': $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('签单', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.employee_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('sum(customer.signed_money) as money, customer.employee_id'); $dcvl = []; foreach ($cvl as $i) { if (!isset($dcvl[$i['employee_id']])) $dcvl[$i['employee_id']] = 0; $dcvl[$i['employee_id']] += $i['money']; } $e = []; foreach ($dcvl as $employee_id => $money) { $e[] = [ 'employee_id' => $employee_id, 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元', 'money' => $money ]; } array_multisort(array_column($e, 'money'), SORT_DESC, $e); break; case 'sj_qiandan': $cvl = CustomerVisitLog::withJoin('customer')->where([['customer.org_id', 'in', $orgList], ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('签单', 'chaos')], ['customer_visit_log.addtime', '>=', $start_date], ['customer_visit_log.addtime', '<', $end_date], ['customer.designer_id', 'NOTNULL', '']])->group('customer_visit_log.customer_id')->column('sum(customer.signed_money) as money, customer.designer_id'); $dcvl = []; foreach ($cvl as $i) { if (!isset($dcvl[$i['designer_id']])) $dcvl[$i['designer_id']] = 0; $dcvl[$i['designer_id']] += $i['money']; } $e = []; foreach ($dcvl as $employee_id => $money) { $e[] = [ 'employee_id' => $employee_id, 'num' => $money > 10000 ? round($money / 10000, 2) . '万元' : $money . '元', 'money' => $money ]; } array_multisort(array_column($e, 'money'), SORT_DESC, $e); break; } // 取前三名数据 $n = 3; $i = 0; $p = []; foreach ($e as $ei) { if (empty($p)) { $p[] = $ei; $i = $ei['num']; continue; } if ($i == $ei['num']) { $p[] = $ei; continue; } else { $n--; if ($n == 0) break; $p[] = $ei; $i = $ei['num']; } } $eid = array_column($p, 'employee_id'); $emp = Employee::with('org')->where([['id', 'in', $eid]])->select()->toArray(); $emp = array_combine(array_column($emp, 'id'), $emp); foreach ($p as &$ie) { $ie['employee_name'] = $emp[$ie['employee_id']]['name']; $ie['headimgurl'] = $emp[$ie['employee_id']]['headimgurl']; $ie['org_name'] = $emp[$ie['employee_id']]['org']['name']; } return json(['code' => 0, 'data' => $p]); } }