| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 | <?phpnamespace 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']];        }        $list = Consultant::where($where)->select(['id','name','mobile','gender','status','dept_id','created_at'])->orderBy('created_at', 'desc')->get();        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 {            //普通账号            $ids[] = $userId;        }        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;        $where = [            [function($query) use ($userIds) {            $query->whereIn('consultant_id', $userIds);            }]        ];        //客户总量        $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]);        }];        //待审核客户数量        $checkCustomNums = MarketCustomer::where($where)->where('check_status', '=', 1)->count();        //新增客户        $newCustomNums = MarketCustomer::where($where)->count();        //已报备客户数        $whereReport = [            [function($query) use ($diffNums, $currentTime) {                $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0)")->where('current_status', '=', 1);            }],            ['check_status', '=', 2]        ];        $reportCustomNums = MarketCustomer::where($where)->where($whereReport)->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($where)->count();        //男女性别占比        $whereEffective = [            [function($query) {                $query->orWhere(function ($query){                    $diffNums = (60 * 60 * 24 * 30);                    $currentTime = time();                    $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0)")->where('current_status', '=', 1);                })->orWhereIn('current_status', [2,3,4]);            }],            ['check_status', '=', 2]        ];        /* 男女数量 */        $genderDataNums = [            ['label' => '男', 'value' => 1, 'nums' => 0],            ['label' => '女', 'value' => 2, 'nums' => 0],        ];        $genderData = MarketCustomer::where($where)->select(Db::raw('gender, count(*) as nums'))->where($whereEffective)->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'))->where($whereEffective)->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)    {        //统计客户总数        $userIds = self::getIds();        $where = [            [function($query) use ($userIds) {                $query->whereIn('consultant_id', $userIds);            }],            [function($query) {                $query->orWhere(function ($query){                    $diffNums = (60 * 60 * 24 * 30);                    $currentTime = time();                    $query->whereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0)")->where('current_status', '=', 1);                })->orWhereIn('current_status', [2,3,4]);            }],            ['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));    }}
 |