123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- <?php
- namespace app\wechat\service;
- use app\model\Consultant;
- use app\model\MarketCustomer;
- use app\model\MarketCustomerFollow;
- use app\model\SysDept;
- use Carbon\Carbon;
- use support\Db;
- use support\exception\BusinessException;
- use Tinywan\Jwt\JwtToken;
- class UserService
- {
- /**
- * Notes: 获取所有顾问
- * User: yb
- * Date: 2024/8/15
- * Time: 11:51
- * @param $params
- */
- public static function getAll($params)
- {
- $ids = self::getIds(1);
- $where = [
- [function($query) use ($ids) {
- $query->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();
- } else if ($userInfo->type == 4) {
- //外渠账号
- $ids[] = $userId;
- }
- return $ids;
- }
- /**
- * Notes: 获取用户类型
- * User: yb
- * Date: 2024/9/13
- * Time: 13:57
- * @return mixed
- */
- public static function getUserType()
- {
- $userId = JwtToken::getCurrentId();
- return Consultant::where('id', $userId)->value('type');
- }
- /**
- * Notes: 首页统计分析
- * User: yb
- * Date: 2024/8/14
- * Time: 10:23
- */
- public static function statistics($params)
- {
- //统计客户总数
- $userIds = self::getIds();
- $currentTime = time();
- $diffNums = CustomService::DIFF_TIME;
- $userType = self::getUserType();
- $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);
- }];
- if ($userType != 4) {
- $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();
- $userType = self::getUserType();
- $where = [
- [function($query) use ($userIds) {
- $query->whereIn('consultant_id', $userIds);
- }]
- ];
- if ($userType != 4) {
- $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)");
- }];
- }
- $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));
- }
- }
|