whereIn('id', $ids); }] ]; if (!empty($params['not_id'])) { $where[] = ['id', '<>', $params['not_id']]; } //获取所有团队 $teamKeys = TeamService::getTeams()->pluck('dept_name', 'dept_id'); $list = Consultant::where($where)->select(['id','name','mobile','gender','status','dept_id','created_at'])->orderBy('created_at', 'desc')->get(); if (!empty($list)) { foreach ($list as $item) { $item->dept_name = $teamKeys[$item->dept_id] ?? ''; } } return json_success('请求成功', $list); } /** * Notes: 团队成员 * User: yb * Date: 2024/8/14 * Time: 15:34 * @param $params */ public static function index($params) { $page = $params['page'] ?? 1; $size = $params['size'] ?? 10; $ids = self::getIds(1); $where = [ [function($query) use ($ids) { $query->whereIn('id', $ids); }] ]; if (!empty($params['status'])) { $where[] = ['status', '=', $params['status']]; } if (!empty($params['consultant'])) { $keywords = $params['consultant']; $where[] = [function($query) use ($keywords) { $query->orWhere('name', 'like', "%{$keywords}%")->orWhere('mobile', 'like', "%{$keywords}%"); }]; } if (!empty($params['dept_id'])) { $deptIds = $params['dept_id']; $deptId = end($deptIds); $where[] = ['dept_id', '=', $deptId]; } if (!empty($params['created_at'])) { $datetime = $params['created_at']; $startTime = strtotime($datetime['start'].' 00:00:00'); $endTime = strtotime($datetime['end'].' 23:59:59'); $where[] = [function($query) use ($startTime, $endTime) { $query->whereBetween('created_at', [$startTime, $endTime]); }]; } $paginator = Consultant::where($where)->orderBy('created_at', 'desc')->paginate($size, ['id','name','mobile','gender','status','dept_id','created_at'], 'page', $page); $total = $paginator->total(); $items = $paginator->items(); $data = [ 'total' => $total, 'rows' => $items ]; return json_success('success', $data); } /** * Notes: 删除成员 * User: yb * Date: 2024/8/15 * Time: 11:39 * @param $id */ public static function del($id) { if(MarketCustomer::where('consultant_id', $id)->exists()) { return json_fail('成员下存在客户,请移交客户后删除成员'); } $result = Consultant::where('id', $id)->delete(); if ($result) { return json_success('删除成功'); } else { return json_fail('删除失败'); } } /** * Notes: 成员详情 * User: yb * Date: 2024/8/15 * Time: 10:19 * @param $id */ public static function getInfoById($id) { $info = Consultant::firstWhere(['id' => $id]); if (empty($info)) { return json_fail('成员信息不存在'); } return json_success('请求成功', $info); } /** * Notes: 编辑成员 * User: yb * Date: 2024/8/15 * Time: 10:28 * @param $params */ public static function updateById($params) { if (empty($params['id'])) { return json_fail('成员id不能为空'); } //查找员工信息 $info = Consultant::find($params['id']); $oldDeptId = $info->dept_id; if (empty($info)) { return json_fail('成员不存在'); } if (!self::checkMobile($params['mobile'])) { return json_fail('请输入正确的手机号'); } //查询员工是否已被注册 if (Consultant::where('mobile', $params['mobile'])->where('id', '<>', $params['id'])->exists()) { return json_fail('手机号已存在,成员已被注册'); } //校验密码规则 if (!empty($params['password'])) { $passwordLen = strlen($params['password']); if ($passwordLen > 20 || $passwordLen < 6) { return json_fail('请输入6-20位密码'); } $password = self::handlePassword($params['password']); } //查询上级团队 $topDeptId = SysDept::where('dept_id', $params['dept_id'])->where('dept_category', TeamService::DEPT_CATEGORY)->value('dept_super_id'); if (!is_numeric($topDeptId)) { return json_fail('团队不存在'); } $updateData = [ 'name' => $params['name'], 'mobile' => $params['mobile'], 'dept_id' => $params['dept_id'], 'top_dept_id' => $topDeptId, 'gender' => $params['gender'] ?? 1, 'status' => $params['status'] ?? 1, 'updated_at' => time() ]; if (!empty($params['password'])) { $updateData['password'] = $password; } $result = false; Db::beginTransaction(); try { $result = Consultant::where('id', $params['id'])->update($updateData); if ($updateData['dept_id'] != $oldDeptId) { //修改成员所属部门 MarketCustomer::where('consultant_id', '=', $params['id'])->update(['updated_at' => time(), 'dept_id' => $updateData['dept_id']]); } Db::commit(); }catch (BusinessException|\Exception $e) { Db::rollBack(); return json_fail($e->getMessage()); } if ($result) { return json_success('编辑成功'); } else { return json_fail('编辑失败'); } } /** * Notes: 添加员工 * User: yb * Date: 2024/8/15 * Time: 9:55 * @param $params */ public static function add($params) { if (!self::checkMobile($params['mobile'])) { return json_fail('请输入正确的手机号'); } //查询员工是否已被注册 if (Consultant::where('mobile', $params['mobile'])->exists()) { return json_fail('手机号已存在,成员已被注册'); } //校验密码规则 if (!empty($params['password'])) { $passwordLen = strlen($params['password']); if ($passwordLen > 20 || $passwordLen < 6) { return json_fail('请输入6-20位密码'); } } //查询上级团队 $topDeptId = SysDept::where('dept_id', $params['dept_id'])->where('dept_category', TeamService::DEPT_CATEGORY)->value('dept_super_id'); if (!is_numeric($topDeptId)) { return json_fail('团队不存在'); } if (empty($params['password'])) { $showPassword = substr($params['mobile'], 5); $password = self::handlePassword($showPassword); } else { $password = self::handlePassword($params['password']); } $insertData = [ 'name' => $params['name'], 'mobile' => $params['mobile'], 'dept_id' => $params['dept_id'], 'top_dept_id' => $topDeptId, 'gender' => $params['gender'] ?? 1, 'password' => $password, 'status' => $params['status'] ?? 1, 'relation_user_id' => $params['relation_user_id'] ?? null, 'type' => 2, 'created_at' => time() ]; $result = Consultant::insert($insertData); if ($result) { return json_success('新增成功'); } else { return json_fail('新增失败'); } } /** * Notes: 登录 * User: yb * Date: 2024/8/8 * Time: 9:20 * @param $data */ public static function login($data) { $password = $data['password']; $mobile = $data['mobile']; $userInfo = Consultant::firstWhere(['mobile' => $mobile]); if (empty($userInfo)) { return json_fail('用户不存在'); } //校验密码 $confoundPassword = $userInfo->password; if ($confoundPassword != md5(md5($password))) { return json_fail('密码错误'); } $status = $userInfo->status; if ($status != 1) { return json_fail('用户已离职'); } $extend = [ 'id' => $userInfo->id, 'client' => 'wechat', 'name'=> $userInfo->name, 'user_type' => $userInfo->type ]; $token = JwtToken::generateToken($extend); $token['user_type'] = $extend['user_type']; return json_success('', $token); } /** * Notes: 获取身份信息 * User: yb * Date: 2024/8/8 * Time: 10:09 */ public static function auth() { $userId = JwtToken::getCurrentId(); $userInfo = Consultant::firstWhere(['id' => $userId]); if (empty($userInfo)) { return json_fail('用户不存在'); } $status = $userInfo->status; if ($status != 1) { return json_fail('用户已离职'); } $type = $userInfo->type; $relationUserId = $userInfo->relation_user_id; return json_success('请求成功', ['type' => $type, 'relation_user_id' => $relationUserId]); } /** * Notes: 获取需要查询的ids * User: yb * Date: 2024/8/13 * Time: 15:58 * @return array */ public static function getIds($clearSelf = 0) { $userId = JwtToken::getCurrentId(); $userInfo = Consultant::firstWhere(['id' => $userId]); if (empty($userInfo)) { return []; } $ids = []; if ($userInfo->type == 1) { //管理账号 $deptId = $userInfo->dept_id; $deptIds = TeamService::getIds($deptId); //团队下的所有员工 $where = [ [function($query) use ($deptIds) { $query->whereIn('dept_id', $deptIds); }] ]; if ($clearSelf == 1) { $where[] = ['id', '<>', $userId]; } $ids = Consultant::where($where)->pluck('id')->toArray(); } else if ($userInfo->type == 2){ //普通账号 $ids[] = $userId; } else if ($userInfo->type == 3) { //判客账户 $ids = Consultant::pluck('id')->toArray(); } return $ids; } /** * Notes: 首页统计分析 * User: yb * Date: 2024/8/14 * Time: 10:23 */ public static function statistics($params) { //统计客户总数 $userIds = self::getIds(); $currentTime = time(); $diffNums = CustomService::DIFF_TIME; $whereFollow = [ [function($query) use ($userIds) { $query->whereIn('consultant_id', $userIds); }] ]; $where = []; $where[] = [function($query) use ($userIds) { $query->orWhereIn('consultant_id', $userIds)->orWhereIn('report_consultant_id', $userIds); }]; $where[] = [function($query) use ($diffNums, $currentTime){ $query->orWhereRaw("check_status IN (-1, 1)") ->orWhereRaw("check_status = 2 AND current_status IN (-1,3,4)") ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2)") ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} <= 0 AND (visit_time + ({$diffNums} * 4)) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2 AND belong_status = 1)")->whereOr('belong_status','<>', 1); }]; //客户总量 $customNums = MarketCustomer::where($where)->count(); if (!empty($params['time'])) { $time = $params['time']; $start = strtotime($time[0]); $end = strtotime($time[1]); } else { $startDate = date('Y-m-01', strtotime(date('Y-m-d'))); $endDate = date('Y-m-t', strtotime(date('Y-m-d'))); $start = strtotime($startDate.' 00:00:00'); $end = strtotime($endDate.' 23:59:59'); } $where[] = [function($query) use ($start, $end) { $query->whereBetween('created_at', [$start, $end]); }]; $whereFollow[] = [function($query) use ($start, $end) { $query->whereBetween('created_at', [$start, $end]); }]; //待转到访客户数量 $checkCustomNums = MarketCustomer::where($where)->where('check_status', 1)->where('current_status', 1)->count(); //新增客户 $newCustomNums = MarketCustomer::where($where)->count(); //已报备客户数 $reportCustomNums = MarketCustomer::where($where)->where('current_status', 1)->count(); //已到访客户数量 $visitCustomNums = MarketCustomer::where($where)->where('current_status', 2)->where('check_status', 2)->count(); //已缴费客户数量 $payCustomNums = MarketCustomer::where($where)->where('current_status', 3)->where('check_status', 2)->count(); //已成交客户数量 $dealCustomNums = MarketCustomer::where($where)->where('current_status', 4)->where('check_status', 2)->count(); //新增跟进记录数量 $newFollowNums = MarketCustomerFollow::where($whereFollow)->count(); /* 男女数量 */ $genderDataNums = [ ['label' => '男', 'value' => 1, 'nums' => 0], ['label' => '女', 'value' => 2, 'nums' => 0], ]; $genderData = MarketCustomer::where($where)->select(Db::raw('gender, count(*) as nums'))->groupBy('gender')->get(); if (!$genderData->isEmpty()) { $genderData = $genderData->toArray(); foreach ($genderDataNums as $genderKey => $genderVal) { foreach ($genderData as $genderItem) { if ($genderItem['gender'] == $genderVal['value']) { $genderDataNums[$genderKey]['nums'] = $genderItem['nums']; } } } } /* 客户级别 */ $levelDataNums = [ ['label' => 'A类', 'value' => 1, 'nums' => 0], ['label' => 'B类', 'value' => 2, 'nums' => 0], ['label' => 'C类', 'value' => 3, 'nums' => 0], ['label' => 'D类', 'value' => 4, 'nums' => 0], ['label' => '其他', 'value' => "", 'nums' => 0], ]; $levelData = MarketCustomer::where($where)->select(Db::raw('level, count(*) as nums'))->groupBy('level')->get(); if (!$levelData->isEmpty()) { $levelData = $levelData->toArray(); $levelData = array_column($levelData, 'nums', 'level'); foreach ($levelDataNums as $levelKey => $levelVal) { if (isset($levelData[$levelVal['value']])) { $levelDataNums[$levelKey]['nums'] = $levelData[$levelVal['value']]; } } } $data = [ 'custom_nums' => $customNums, 'check_custom_nums' => $checkCustomNums, 'new_custom_nums' => $newCustomNums, 'report_custom_nums' => $reportCustomNums, 'visit_custom_nums' => $visitCustomNums, 'pay_custom_nums' => $payCustomNums, 'deal_custom_nums' => $dealCustomNums, 'new_follow_nums' => $newFollowNums, 'gender_data_nums' => $genderDataNums, 'level_data_nums' => $levelDataNums ]; return json_success('请求成功', $data); } /** * Notes: 近7日客户走势 * User: yb * Date: 2024/8/17 * Time: 17:44 */ public static function customTrend($params) { $currentTime = time(); $diffNums = CustomService::DIFF_TIME; //统计客户总数 $userIds = self::getIds(); $where = [ [function($query) use ($userIds) { $query->whereIn('consultant_id', $userIds); }], [function($query) use ($diffNums, $currentTime){ $query->orWhereRaw("check_status IN (-1, 1)") ->orWhereRaw("check_status = 2 AND current_status IN (-1,3,4)") ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2)"); }] ]; $whereTrend = []; if (!empty($params['type'])) { $whereTrend[] = ['current_status', '=', $params['type']]; } // 获取当前日期 $today = Carbon::now(); // 初始化日期数组和数量数组 $dates = [date('Y-m-d')]; // 循环7次,获取从今天开始往前推7天的日期 for ($i = 0; $i < 6; $i++) { // 将日期推回到7天前 $date = $today->subDay()->toDateString(); // 将日期字符串存入数组 $dates[] = $date; } // 逆序日期数组,因为我们是从今天往前计算的 $dates = array_reverse($dates); $dateList = []; foreach ($dates as $item) { $dateList[] = ['label' => $item, 'nums' => 0, 'label_sim' => date('m/d', strtotime($item))]; } $datesStr = implode('","', $dates); $datesStr = '"'.$datesStr.'"'; $dateRaw = Db::raw("DATE_FORMAT(FROM_UNIXTIME(created_at), '%Y-%m-%d') IN ({$datesStr})"); // 构建查询,使用whereBetween或whereIn根据需要筛选日期 $results = MarketCustomer::select(Db::raw("DATE_FORMAT(FROM_UNIXTIME(created_at), '%Y-%m-%d') AS date,count(*) AS nums")) ->where($where) ->where($whereTrend) ->whereRaw($dateRaw) ->groupBy('date')->get(); if (!$results->isEmpty()) { $results = $results->toArray(); $results = array_column($results, 'nums', 'date'); foreach ($dateList as $key => $val) { $dateList[$key]['nums'] = $results[$val['label']] ?? 0; } } //总数 $customNums = MarketCustomer::where($where)->whereRaw($dateRaw)->count(); //到访数 $visitCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 2)->count(); //已缴费数 $payCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 3)->count(); //已成交数 $dealCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 4)->count(); $data = [ 'dateList' => $dateList, 'visit_nums' => $visitCustomNums, 'pay_nums' => $payCustomNums, 'deal_nums' => $dealCustomNums, 'total_nums' => $customNums ]; return json_success('请求成功', $data); } /** * Notes: 用户详情 * User: yb * Date: 2024/8/14 * Time: 13:35 */ public static function info() { $userId = JwtToken::getCurrentId(); $info = Consultant::firstWhere(['id' => $userId]); if (!empty($info)) { $info->dept_name = SysDept::where('dept_id', $info->dept_id)->value('dept_name'); } return json_success('请求成功', $info); } /** * Notes: 修改个人信息 * User: yb * Date: 2024/8/14 * Time: 14:19 * @param $params */ public static function update($params) { $userId = JwtToken::getCurrentId(); if (!self::checkMobile($params['mobile'])) { return json_fail('请输入正确的手机号'); } //查询员工是否已被注册 if (Consultant::where('mobile', $params['mobile'])->where('id', '<>', $userId)->exists()) { return json_fail('手机号已存在'); } $info = Consultant::firstWhere(['id' => $userId]); if (empty($info)) { return json_fail('用户不存在'); } $info->name = $params['name']; $info->gender = $params['gender']; $info->mobile = $params['mobile']; $result = $info->save(); if ($result) { return json_success('修改成功'); } else { return json_fail('修改失败'); } } /** * Notes: 修改密码 * User: yb * Date: 2024/8/14 * Time: 14:20 * @param $params */ public static function editPassword($params) { $oldPassword = $params['old_password']; $password = $params['new_password']; $rePassword = $params['check_password'] ?? ''; $len = mb_strlen($password); if ($len < 6) { return json_fail('密码长度最少为6位'); } if ($len > 20) { return json_fail('密码长度最大为20位'); } if ($password != $rePassword) { return json_fail('密码与确认密码不一致'); } $userId = JwtToken::getCurrentId(); $info = Consultant::firstWhere(['id' => $userId]); if (empty($info)) { return json_fail('用户不存在'); } //校验密码 $confoundPassword = $info->password; if ($confoundPassword != md5(md5($oldPassword))) { return json_fail('旧密码错误'); } $info->password = md5(md5($password)); $result = $info->save(); if ($result) { return json_success('修改成功'); } else { return json_fail('修改失败'); } } /** * Notes: 团队列表 * User: yb * Date: 2024/8/14 * Time: 16:32 */ public static function getTeamList() { $userId = JwtToken::getCurrentId(); $info = Consultant::firstWhere(['id' => $userId]); if (empty($info)) { return json_success('请求成功'); } $deptId = $info->dept_id; $list = TeamService::getTeamList($deptId); return $list; } /** * Notes:校验手机号 * User: yb * Date: 2024/8/2 * Time: 11:12 * @param $mobile * @return bool */ protected static function checkMobile($mobile) { if (preg_match('/^1[0-9]\d{9}$/', $mobile)) { return true; } else { return false; } } /** * Notes: 处理密码 * User: yb * Date: 2024/8/2 * Time: 11:19 * @param $password * @return mixed */ protected static function handlePassword($password) { return md5(md5($password)); } }