123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- <?php
- // +----------------------------------------------------------------------
- // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
- // +----------------------------------------------------------------------
- // | Author: CRMEB Team <admin@crmeb.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\services\user;
- use app\dao\user\UserDao;
- use app\services\BaseServices;
- use app\services\yihaotong\SmsRecordServices;
- use app\services\message\notice\SmsService;
- use app\services\wechat\WechatUserServices;
- use crmeb\exceptions\ApiException;
- use crmeb\services\CacheService;
- use think\facade\Config;
- /**
- *
- * Class LoginServices
- * @package app\services\user
- */
- class LoginServices extends BaseServices
- {
- /**
- * LoginServices constructor.
- * @param UserDao $dao
- */
- public function __construct(UserDao $dao)
- {
- $this->dao = $dao;
- }
- /**
- * H5账号登陆
- * @param $account
- * @param $password
- * @param $spread
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function login($account, $password, $spread)
- {
- $user = $this->dao->getOne(['account|phone' => $account, 'is_del' => 0]);
- if ($user) {
- if ($user->pwd !== md5((string)$password))
- throw new ApiException(410025);
- if ($user->pwd === md5('123456'))
- throw new ApiException(410026);
- } else {
- throw new ApiException(410025);
- }
- if (!$user['status'])
- throw new ApiException(410027);
- //更新用户信息
- $this->updateUserInfo(['code' => $spread], $user);
- $token = $this->createToken((int)$user['uid'], 'api');
- if ($token) {
- return ['token' => $token['token'], 'expires_time' => $token['params']['exp']];
- } else
- throw new ApiException(410019);
- }
- /**
- * 更新用户信息
- * @param $user
- * @param $userInfo
- * @param false $is_new
- * @return bool
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function updateUserInfo($user, $userInfo, $is_new = false)
- {
- $data = [];
- $data['phone'] = !isset($user['phone']) || !$user['phone'] ? $userInfo->phone : $user['phone'];
- $data['last_time'] = time();
- $data['last_ip'] = app()->request->ip();
- $spreadUid = $user['code'] ?? 0;
- //如果扫了员工邀请码,上级,代理商,区域代理都会改动。
- if (isset($user['is_staff']) && !$userInfo['is_agent'] && !$userInfo['is_division']) {
- $spreadInfo = $this->dao->get($spreadUid);
- if ($userInfo['uid'] != $spreadUid) {
- $data['spread_uid'] = $spreadUid;
- $data['spread_time'] = $userInfo->last_time;
- }
- $data['agent_id'] = $spreadInfo->agent_id;
- $data['division_id'] = $spreadInfo->division_id;
- $data['staff_id'] = $userInfo['uid'];
- $data['is_staff'] = $user['is_staff'] ?? 0;
- $data['division_type'] = 3;
- $data['division_status'] = 1;
- $data['division_change_time'] = time();
- $data['division_end_time'] = $spreadInfo->division_end_time;
- //如果店员切换代理商,则店员在之前代理商下推广的用户,他们的直接上级从当前店员变为之前代理商
- if ($userInfo->agent_id != 0 && $userInfo->agent_id != $spreadInfo->agent_id) {
- $this->dao->update($userInfo['uid'], ['spread_uid' => $userInfo->agent_id], 'spread_uid');
- }
- }
- if ($is_new) {
- if ($spreadUid) {
- $spreadInfo = $this->dao->get($spreadUid);
- $spreadUid = (int)$spreadUid;
- $data['spread_uid'] = $spreadUid;
- $data['spread_time'] = time();
- $data['agent_id'] = $spreadInfo->agent_id;
- $data['division_id'] = $spreadInfo->division_id;
- $data['staff_id'] = $spreadInfo->staff_id;
- //绑定用户后置事件
- event('UserRegisterListener', [$spreadUid, $userInfo['user_type'], $userInfo['nickname'], $userInfo['uid'], 0]);
- //推送消息
- event('NoticeListener', [['spreadUid' => $spreadUid, 'user_type' => $userInfo['user_type'], 'nickname' => $userInfo['nickname']], 'bind_spread_uid']);
- }
- } else {
- //永久绑定
- $store_brokerage_binding_status = sys_config('store_brokerage_binding_status', 1);
- if ($userInfo->spread_uid && $store_brokerage_binding_status == 1 && !isset($user['is_staff'])) {
- $data['login_type'] = $user['login_type'] ?? $userInfo->login_type;
- } else {
- //绑定分销关系 = 所有用户
- if (sys_config('brokerage_bindind', 1) == 1) {
- //分销绑定类型为时间段且过期 ||临时
- $store_brokerage_binding_time = sys_config('store_brokerage_binding_time', 30);
- if (!$userInfo['spread_uid'] || $store_brokerage_binding_status == 3 || ($store_brokerage_binding_status == 2 && ($userInfo['spread_time'] + $store_brokerage_binding_time * 24 * 3600) < time())) {
- if ($spreadUid && $user['code'] != $userInfo->uid && $userInfo->uid != $this->dao->value(['uid' => $spreadUid], 'spread_uid')) {
- $spreadInfo = $this->dao->get($spreadUid);
- $spreadUid = (int)$spreadUid;
- $data['spread_uid'] = $spreadUid;
- $data['spread_time'] = time();
- $data['agent_id'] = $spreadInfo->agent_id;
- $data['division_id'] = $spreadInfo->division_id;
- $data['staff_id'] = $spreadInfo->staff_id;
- //绑定用户后置事件
- event('UserRegisterListener', [$spreadUid, $userInfo['user_type'], $userInfo['nickname'], $userInfo['uid'], 0]);
- //推送消息
- event('NoticeListener', [['spreadUid' => $spreadUid, 'user_type' => $userInfo['user_type'], 'nickname' => $userInfo['nickname']], 'bind_spread_uid']);
- }
- }
- }
- }
- }
- if (!$this->dao->update($userInfo['uid'], $data, 'uid')) {
- throw new ApiException(100007);
- }
- return true;
- }
- public function verify(SmsService $services, $phone, $type, $time, $ip)
- {
- if ($this->dao->getOne(['account' => $phone, 'is_del' => 0]) && $type == 'register') {
- throw new ApiException(410028);
- }
- $default = Config::get('sms.default', 'yihaotong');
- $defaultMaxPhoneCount = Config::get('sms.maxPhoneCount', 10);
- $defaultMaxIpCount = Config::get('sms.maxIpCount', 50);
- $maxPhoneCount = Config::get('sms.stores.' . $default . '.maxPhoneCount', $defaultMaxPhoneCount);
- $maxIpCount = Config::get('sms.stores.' . $default . '.maxIpCount', $defaultMaxIpCount);
- /** @var SmsRecordServices $smsRecord */
- $smsRecord = app()->make(SmsRecordServices::class);
- if ($smsRecord->count(['phone' => $phone, 'add_ip' => $ip, 'time' => 'today']) >= $maxPhoneCount) {
- throw new ApiException(410029);
- }
- if ($smsRecord->count(['add_ip' => $ip, 'time' => 'today']) >= $maxIpCount) {
- throw new ApiException(410030);
- }
- $code = rand(100000, 999999);
- $data['code'] = $code;
- $data['time'] = $time;
- $res = $services->send(true, $phone, $data, 'verify_code');
- if ($res !== true)
- throw new ApiException(410031);
- return $code;
- }
- /**
- * H5用户注册
- * @param $account
- * @param $password
- * @param $spread
- * @param string $user_type
- * @return mixed
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function register($account, $password, $spread, $user_type = 'h5')
- {
- if ($this->dao->getOne(['account|phone' => $account, 'is_del' => 0])) {
- throw new ApiException(410028);
- }
- /** @var UserServices $userServices */
- $userServices = app()->make(UserServices::class);
- $phone = $account;
- $data['account'] = $account;
- $data['pwd'] = md5((string)$password);
- $data['phone'] = $phone;
- if ($spread) {
- $data['spread_uid'] = $spread;
- $data['spread_time'] = time();
- $spreadInfo = $userServices->get($spread);
- $data['division_id'] = $spreadInfo['division_id'];
- $data['agent_id'] = $spreadInfo['agent_id'];
- $data['staff_id'] = $spreadInfo['staff_id'];
- }
- $data['real_name'] = '';
- $data['birthday'] = 0;
- $data['card_id'] = '';
- $data['mark'] = '';
- $data['addres'] = '';
- $data['user_type'] = $user_type;
- $data['add_time'] = time();
- $data['add_ip'] = app('request')->ip();
- $data['last_time'] = time();
- $data['last_ip'] = app('request')->ip();
- $data['nickname'] = substr_replace($account, '****', 3, 4);
- $data['avatar'] = sys_config('h5_avatar');
- $data['city'] = '';
- $data['language'] = '';
- $data['province'] = '';
- $data['country'] = '';
- $data['status'] = 1;
- if (!$re = $this->dao->save($data)) {
- throw new ApiException(410014);
- } else {
- $userServices->rewardNewUser((int)$re->uid);
- //用户生成后置事件
- event('UserRegisterListener', [$spread, $user_type, $data['nickname'], $re->uid, 1]);
- //推送消息
- event('NoticeListener', [['spreadUid' => $spread, 'user_type' => $user_type, 'nickname' => $data['nickname']], 'bind_spread_uid']);
- return $re;
- }
- }
- /**
- * 重置密码
- * @param $account
- * @param $password
- * @return bool
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function reset($account, $password)
- {
- $user = $this->dao->getOne(['account|phone' => $account, 'is_del' => 0], 'uid');
- if (!$user) {
- throw new ApiException(410032);
- }
- if (!$this->dao->update($user['uid'], ['pwd' => md5((string)$password)], 'uid')) {
- throw new ApiException(410033);
- }
- return true;
- }
- /**
- * 手机号登录
- * @param $phone
- * @param $spread
- * @param string $user_type
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function mobile($phone, $spread, string $user_type = 'h5')
- {
- //数据库查询
- $user = $this->dao->getOne(['account|phone' => $phone, 'is_del' => 0]);
- if (!$user) {
- $user = $this->register($phone, '123456', $spread, $user_type);
- if (!$user) {
- throw new ApiException(410034);
- }
- }
- if (!$user->status)
- throw new ApiException(410027);
- // 设置推广关系
- $this->updateUserInfo(['code' => $spread], $user);
- $token = $this->createToken((int)$user['uid'], 'api');
- if ($token) {
- return ['token' => $token['token'], 'expires_time' => $token['params']['exp']];
- } else {
- throw new ApiException(410019);
- }
- }
- /**
- * 切换登录
- * @param $user
- * @param $from
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function switchAccount($user, $from)
- {
- if ($from === 'h5') {
- $where = [['phone', '=', $user['phone']], ['user_type', '<>', 'h5'], ['is_del', '=', 0]];
- $login_type = 'wechat';
- } else {
- //数据库查询
- $where = [['account|phone', '=', $user['phone']], ['user_type', '=', 'h5'], ['is_del', '=', 0]];
- $login_type = 'h5';
- }
- $switch_user = $this->dao->getOne($where);
- if (!$switch_user) {
- return app('json')->fail(410035);
- }
- if (!$switch_user->status) {
- return app('json')->fail(410027);
- }
- $edit_data = ['login_type' => $login_type];
- if (!$this->dao->update($switch_user['uid'], $edit_data, 'uid')) {
- throw new ApiException(410036);
- }
- $token = $this->createToken((int)$switch_user['uid'], 'api');
- if ($token) {
- return ['token' => $token['token'], 'expires_time' => $token['params']['exp']];
- } else {
- throw new ApiException(410019);
- }
- }
- /**
- * 绑定手机号(静默还没写入用户信息)
- * @param $phone
- * @param string $key
- * @return array
- * @throws \Psr\SimpleCache\InvalidArgumentException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function bindind_phone($phone, string $key = '')
- {
- if (!$key) {
- throw new ApiException(410037);
- }
- [$openid, $wechatInfo, $spreadId, $login_type, $userType] = $createData = CacheService::get($key);
- if (!$createData) {
- throw new ApiException(410037);
- }
- $wechatInfo['phone'] = $phone;
- /** @var WechatUserServices $wechatUser */
- $wechatUser = app()->make(WechatUserServices::class);
- //更新用户信息
- $user = $wechatUser->wechatOauthAfter([$openid, $wechatInfo, $spreadId, $login_type, $userType]);
- $token = $this->createToken((int)$user['uid'], 'api');
- if ($token) {
- return [
- 'token' => $token['token'],
- 'userInfo' => $user,
- 'expires_time' => $token['params']['exp'],
- ];
- } else
- return app('json')->fail(410019);
- }
- /**
- * 用户绑定手机号
- * @param int $uid
- * @param $phone
- * @param $step
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function userBindindPhone(int $uid, $phone, $step)
- {
- $userInfo = $this->dao->get($uid);
- if (!$userInfo) {
- throw new ApiException(410113);
- }
- if ($this->dao->getOne([['phone', '=', $phone], ['user_type', '<>', 'h5'], ['is_del', '=', 0]])) {
- throw new ApiException(410039);
- }
- if ($userInfo->phone) {
- throw new ApiException(410040);
- }
- $data = [];
- if ($this->dao->getOne(['account' => $phone, 'phone' => $phone, 'user_type' => 'h5', 'is_del' => 0])) {
- if (!$step) return ['msg' => 410041, 'data' => ['is_bind' => 1]];
- } else {
- $data['account'] = $phone;
- }
- $data['phone'] = $phone;
- if ($this->dao->update($userInfo['uid'], $data, 'uid') || $userInfo->phone == $phone)
- return ['msg' => 410016, 'data' => []];
- else
- throw new ApiException(410017);
- }
- /**
- * 用户绑定手机号
- * @param int $uid
- * @param $phone
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function updateBindindPhone(int $uid, $phone)
- {
- $userInfo = $this->dao->get(['uid' => $uid, 'is_del' => 0]);
- if (!$userInfo) {
- throw new ApiException(410113);
- }
- if ($userInfo->phone == $phone) {
- throw new ApiException(410042);
- }
- if ($this->dao->getOne([['phone', '=', $phone], ['is_del', '=', 0]])) {
- throw new ApiException(410043);
- }
- $data = [];
- $data['phone'] = $phone;
- $data['account'] = $phone;
- if ($this->dao->update($userInfo['uid'], $data, 'uid'))
- return ['msg' => 100001, 'data' => []];
- else
- throw new ApiException(100007);
- }
- }
|