CRMEB/crmeb/app/services/user/LoginServices.php
2022-08-23 17:39:11 +08:00

422 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 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['nickname'] = !isset($user['nickname']) || !$user['nickname'] ? $userInfo->nickname : $user['nickname'];
$data['avatar'] = !isset($user['headimgurl']) || !$user['headimgurl'] ? $userInfo->avatar : $user['headimgurl'];
$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_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('user.register', [$spreadUid, $userInfo['user_type'], $userInfo['nickname'], $userInfo['uid'], 0]);
//推送消息
event('notice.notice', [['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('user.register', [$spreadUid, $userInfo['user_type'], $userInfo['nickname'], $userInfo['uid'], 0]);
//推送消息
event('notice.notice', [['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);
}
$phone = $account;
$data['account'] = $account;
$data['pwd'] = md5((string)$password);
$data['phone'] = $phone;
if ($spread) {
$data['spread_uid'] = $spread;
$data['spread_time'] = time();
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$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(md5($account . time()), 0, 12);
$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 {
//用户生成后置事件
event('user.register', [$spread, $user_type, $data['nickname'], $re->uid, 1]);
//推送消息
event('notice.notice', [['spreadUid' => $spread, 'user_type' => $user_type, 'nickname' => $data['nickname']], 'bind_spread_uid']);
return $re;
}
}
/**
* 重置密码
* @param $account
* @param $password
*/
public function reset($account, $password)
{
$user = $this->dao->getOne(['account|phone' => $account, 'is_del' => 0]);
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
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function mobile($phone, $spread, $user_type = 'h5')
{
//数据库查询
$user = $this->dao->getOne(['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
*/
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 $user
* @param $phone
* @param $step
* @return mixed
*/
public function bindind_phone($phone, $key = '')
{
if (!$key) {
throw new ApiException(410037);
}
[$openid, $wechatInfo, $spreadId, $login_type, $userType] = $createData = CacheService::getTokenBucket($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'], $userType);
if ($token) {
return [
'token' => $token['token'],
'userInfo' => $user,
'expires_time' => $token['params']['exp'],
];
} else
return app('json')->fail(410019);
}
/**
* 用户绑定手机号
* @param $user
* @param $phone
* @param $step
* @return mixed
*/
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 $user
* @param $phone
* @param $step
* @return mixed
*/
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);
}
}