manghe/app/api/controller/Login.php
2025-03-23 08:37:58 +00:00

681 lines
24 KiB
PHP
Executable File
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
declare(strict_types=1);
namespace app\api\controller;
use app\api\controller\Base;
use app\common\model\User;
use app\common\model\UserAccount;
use \think\Request;
use think\facade\Db;
use app\common\model\ProfitDraw;
use app\common\model\UserLoginIp;
use think\facade\Log;
use app\common\server\TencentCosUploader;
class Login extends Base
{
private $uploader;
public function initialize()
{
parent::initialize(); // 确保调用父类初始化方法
$config = getConfig('uploads');
if (!$config) {
$config = []; // 确保config是一个数组
}
$this->uploader = new TencentCosUploader($config);
}
/**
* 处理用户的UID
*
* @param User $user 用户对象
*/
private function processUid($user)
{
// 如果用户已有uid不处理
if (!empty($user['uid'])) {
return;
}
// 生成uid
$uid = $this->generateUid($user['id']);
if ($uid) {
// 更新用户uid
User::where('id', $user['id'])->update(['uid' => $uid]);
}
}
/**
* 生成用户UID
*
* @param int $user_id 用户ID
* @return string 生成的UID
*/
private function generateUid($user_id)
{
// 获取用户uid配置
$user_config = getConfig('user_config');
if (empty($user_config) || !isset($user_config['uid_type'])) {
return (string) $user_id; // 默认使用真实ID
}
$uid_type = (int) $user_config['uid_type'];
$uid_length = isset($user_config['uid_length']) ? (int) $user_config['uid_length'] : 6;
// 限制长度范围
if ($uid_length < 4) {
$uid_length = 4;
} elseif ($uid_length > 16) {
$uid_length = 16;
}
// 根据不同类型生成UID
switch ($uid_type) {
case 0: // 真实ID
return (string) $user_id;
case 1: // 数字ID
// 生成不以0开头的随机数字
$max_attempts = 10;
$attempt = 0;
while ($attempt < $max_attempts) {
// 生成随机数字
$min = pow(10, $uid_length - 1);
$max = pow(10, $uid_length) - 1;
$uid = (string) mt_rand($min, $max);
// 检查是否唯一
$exists = User::where('uid', $uid)->count();
if ($exists == 0) {
return $uid;
}
$attempt++;
}
// 如果多次尝试后仍无法生成唯一ID则使用更可靠的方法
return $this->generateUniqueNumericId($uid_length);
case 2: // 随机字符和数字
$length = max(8, $uid_length); // 字母数字混合至少8位
$max_attempts = 10;
$attempt = 0;
while ($attempt < $max_attempts) {
// 生成随机字母数字
$characters = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // 排除容易混淆的字符
$uid = '';
// 确保第一个字符不是数字
$uid .= $characters[mt_rand(8, strlen($characters) - 1)]; // 从字母开始
// 生成剩余字符
for ($i = 1; $i < $length; $i++) {
$uid .= $characters[mt_rand(0, strlen($characters) - 1)];
}
// 检查是否唯一
$exists = User::where('uid', $uid)->count();
if ($exists == 0) {
return $uid;
}
$attempt++;
}
// 如果多次尝试后仍无法生成唯一ID使用时间戳+随机数确保唯一性
return $this->generateUniqueAlphaNumId($length);
default:
return (string) $user_id;
}
}
/**
* 生成唯一的数字ID备用方法
*/
private function generateUniqueNumericId($length)
{
// 使用时间微秒 + 随机数的方式保证唯一性
$base = microtime(true) * 10000 . mt_rand(1000, 9999);
$uid = substr(preg_replace('/[^0-9]/', '', $base), 0, $length);
// 确保不以0开头且长度正确
while (strlen($uid) < $length || $uid[0] == '0') {
$uid = mt_rand(1, 9) . substr($uid, 1);
$uid = substr($uid, 0, $length);
}
return $uid;
}
/**
* 生成唯一的字母数字ID备用方法
*/
private function generateUniqueAlphaNumId($length)
{
// 使用时间戳 + 随机字符
$base = time() . mt_rand(1000, 9999);
$hash = md5($base);
// 转换为字母数字混合
$uid = '';
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // 排除容易混淆的字符
// 确保第一个字符是字母
$uid .= $chars[mt_rand(0, 25)]; // 前26个是字母
// 生成剩余字符
for ($i = 1; $i < $length; $i++) {
$uid .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $uid;
}
/**
* 微信授权,登录接口
*/
public function login()
{
try {
$code = request()->param("code", '');
if (empty($code)) {
return $this->renderError('请求参数错误');
}
$click_id = request()->header('clickid');
$wxServer = new \app\common\server\Wx($this->app);
$user_base = $wxServer->getOpenid($code);
$openid = $user_base['openid'];
$user = null;
$wx_unionid = null;
if ($user_base['unionid'] != null && $user_base['unionid'] != '') {
$wx_unionid = $user_base['unionid'];
$user = User::getInfo(['unionid' => $wx_unionid]);
}
if ($user == null) {
$user = User::getInfo(['openid' => $openid]);
}
// return $this->renderSuccess("登录成功", $user);
if ($user) {
if ($user['click_id'] != $click_id) {
$res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]);
}
//设置unionId
if ($wx_unionid && !empty($wx_unionid)) {
$unionid = $user['unionid'];
if ($unionid == null || empty($unionid)) {
$user['unionid'] = $wx_unionid;
// User::update($user);
$user->save();
}
}
// 检查并生成uid
$this->processUid($user);
#token时间戳
$time = time();
#token字符串
$token_num = getRandStr(10);
#加密token
$account_token = user_md5($user['id'] . $token_num . $time);
#更新账号信息
$last_login_ip1 = request()->ip();
$result = $this->ip_location($last_login_ip1);
$ip_province = '';
$ip_city = '';
$ip_adcode = '';
if ($result) {
$ip_province = $result['province'];
$ip_city = $result['city'];
$ip_adcode = $result['adcode'];
} else {
}
$res[] = UserAccount::where(['user_id' => $user['id']])->update([
'account_token' => $account_token,
'token_num' => $token_num,
'token_time' => $time,
'last_login_time' => $time,
'last_login_ip' => ip2long(request()->ip()),
'last_login_ip1' => $last_login_ip1,
'ip_adcode' => $ip_adcode,
'ip_province' => $ip_province,
'ip_city' => $ip_city,
]);
return $this->renderSuccess("登录成功", $account_token);
} else {
$nickname = request()->param('nickname', '');
$headimg = request()->param('headimg', '');
if (!$nickname) {
return $this->renderError('请求参数错误!');
}
$pid = 0;
$pid_pid = request()->param('pid', 0);
if ($pid_pid > 0) {
log::info("获取推荐人id" . $pid_pid);
}
$randx = rand(1000, 9999);
if ($nickname == "微信用户") {
$nickname = $nickname . $randx;
}
$identicon = new \Identicon\Identicon();
$imageData = $identicon->getImageData($openid . $nickname);
$uploadResult = $this->uploader->uploadFile($imageData, "storage/users/icon/default/" . $randx . ".png");
$headimg = $uploadResult['full_url'];
if ($pid_pid) {
$pid_info = User::where('id', '=', $pid_pid)->value("id");
if ($pid_info) {
log::info("获取推荐人id" . $pid_info);
$pid = $pid_info;
}
}
Db::startTrans();
$res[] = $user_id = User::insertGetId([
'openid' => $openid,
'nickname' => $nickname,
'headimg' => $headimg,
'pid' => $pid,
'addtime' => time(),
'click_id' => $click_id,
'unionid' => $wx_unionid,
'uid' => '',
]);
// 生成用户uid
$uid = $this->generateUid($user_id);
if ($uid) {
User::where('id', $user_id)->update(['uid' => $uid]);
}
$time = time();
#token字符串
$token_num = getRandStr(10);
#加密token
$account_token = user_md5($user_id . $token_num . $time);
#更新账号信息
$last_login_ip1 = request()->ip();
$result = $this->ip_location($last_login_ip1);
$ip_province = '';
$ip_city = '';
$ip_adcode = '';
if ($result) {
$ip_province = $result['province'];
$ip_city = $result['city'];
$ip_adcode = $result['adcode'];
} else {
}
$res[] = UserAccount::insert([
'user_id' => $user_id,
'account_token' => $account_token,
'token_num' => $token_num,
'token_time' => $time,
'last_login_time' => $time,
'last_login_ip' => ip2long(request()->ip()),
'last_login_ip1' => $last_login_ip1,
'ip_adcode' => $ip_adcode,
'ip_province' => $ip_province,
'ip_city' => $ip_city,
]);
#记录登录日志
#推荐成功之后获取一张抽奖券
#配置
$rule = getConfig('base');
$draw_people_num = $rule['draw_people_num'];
if (!empty($pid)) {
$num = 0;
$num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count();
if (bccomp("$num", "$draw_people_num") < 0) {
#可以获得一张抽奖券
$res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id);
}
}
if (resCheck($res)) {
Db::commit();
return $this->renderSuccess("登录成功", $account_token);
} else {
Db::rollback();
return $this->renderError("登录失败");
}
}
} catch (\Exception $e) {
Log::error('错误信息' . $e->getMessage());
Log::error('错误行数' . $e->getLine());
}
}
/**
* 微信授权
*/
public function h5login()
{
try {
$code = request()->param("code", '');
if (empty($code)) {
return $this->renderError('请求参数错误');
}
$click_id = request()->header('clickid');
$wxServer = new \app\common\server\WechatOfficialAccount($this->app);
$user_base = $wxServer->getAccessToken($code);
// $user_base_info = $wxServer->getUserInfo($user_base);
$retrieved_openid = $user_base['openid'];
$openid = $retrieved_openid;
$user = null;
if ($user_base['unionid'] != null && $user_base['unionid'] != '') {
$unionid = $user_base['unionid'];
$user = User::getInfo(['unionid' => $unionid]);
if ($user != null) {
// $user
if ($user['gzh_openid'] == null || $user['gzh_openid'] != $retrieved_openid) {
$user['gzh_openid'] = $retrieved_openid;
$user->save();
}
}
}
if ($user == null) {
$user = User::getInfo(['openid' => $openid]);
}
// return $this->renderSuccess("登录成功", $user);
if ($user) {
if ($user['click_id'] != $click_id) {
$res[] = User::where(['id' => $user['id']])->update(['click_id' => $click_id]);
}
#token时间戳
$time = time();
#token字符串
$token_num = getRandStr(10);
#加密token
$account_token = user_md5($user['id'] . $token_num . $time);
#更新账号信息
$last_login_ip1 = request()->ip();
$result = $this->ip_location($last_login_ip1);
$ip_province = '';
$ip_city = '';
$ip_adcode = '';
if ($result) {
$ip_province = $result['province'];
$ip_city = $result['city'];
$ip_adcode = $result['adcode'];
} else {
}
$res[] = UserAccount::where(['user_id' => $user['id']])->update([
'account_token' => $account_token,
'token_num' => $token_num,
'token_time' => $time,
'last_login_time' => $time,
'last_login_ip' => ip2long(request()->ip()),
'last_login_ip1' => $last_login_ip1,
'ip_adcode' => $ip_adcode,
'ip_province' => $ip_province,
'ip_city' => $ip_city,
]);
return $this->renderSuccess("登录成功", $account_token);
} else {
$userinfo = $wxServer->getUserInfo($user_base);
$nickname = $userinfo['nickname'];
$headimg = $userinfo['headimgurl'];
if (!$nickname || !$headimg) {
return $this->renderError('请求参数错误!');
}
$pid = 0;
$pid_pid = request()->param('pid', 0);
if ($pid_pid > 0) {
log::info("获取推荐人id" . $pid_pid);
}
if ($pid_pid) {
$pid_info = User::where('id', '=', $pid_pid)->value("id");
if ($pid_info) {
log::info("获取推荐人id" . $pid_info);
$pid = $pid_info;
}
}
Db::startTrans();
$res[] = $user_id = User::insertGetId([
'openid' => $openid,
'nickname' => $nickname,
'headimg' => $headimg,
'pid' => $pid,
'addtime' => time(),
'click_id' => $click_id,
'uid' => '',
]);
$time = time();
#token字符串
$token_num = getRandStr(10);
#加密token
$account_token = user_md5($user_id . $token_num . $time);
#更新账号信息
$last_login_ip1 = request()->ip();
$result = $this->ip_location($last_login_ip1);
$ip_province = '';
$ip_city = '';
$ip_adcode = '';
if ($result) {
$ip_province = $result['province'];
$ip_city = $result['city'];
$ip_adcode = $result['adcode'];
} else {
}
$res[] = UserAccount::insert([
'user_id' => $user_id,
'account_token' => $account_token,
'token_num' => $token_num,
'token_time' => $time,
'last_login_time' => $time,
'last_login_ip' => ip2long(request()->ip()),
'last_login_ip1' => $last_login_ip1,
'ip_adcode' => $ip_adcode,
'ip_province' => $ip_province,
'ip_city' => $ip_city,
]);
#记录登录日志
#推荐成功之后获取一张抽奖券
#配置
$rule = getConfig('base');
$draw_people_num = $rule['draw_people_num'];
if (!empty($pid)) {
$num = 0;
$num = ProfitDraw::where(['type' => 5, 'user_id' => $pid, 'share_uid' => $user_id])->count();
if (bccomp("$num", "$draw_people_num") < 0) {
#可以获得一张抽奖券
$res[] = User::changeDraw($pid, 1, 5, '获得一张抽奖券', $user_id);
}
}
if (resCheck($res)) {
Db::commit();
return $this->renderSuccess("登录成功", $account_token);
} else {
Db::rollback();
return $this->renderError("登录失败");
}
}
} catch (\Exception $e) {
Log::error('错误信息' . $e->getMessage());
Log::error('错误行数' . $e->getLine());
return $this->renderError('非法请求');
}
}
public function ip_location($last_login_ip)
{
if ($last_login_ip) {
$url = "https://restapi.amap.com/v3/ip?key=6a46ad822120e393956e89d498e8c40b&ip=" . "$last_login_ip" . "";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result, true);
if ($result['status'] == '1') {
return $result;
} else {
return false;
}
} else {
return false;
}
}
/**
* 绑定手机号
*/
public function login_bind_mobile()
{
$user = $this->getUser();
$user_id = $user['id'];
$code = request()->param("code", '');
$wxServer = new \app\common\server\Wx($this->app);
$mobile = $wxServer->getMobile($code);
// return $this->renderError($mobile,[$mobile,$code]);
Db::startTrans();
$res = [];
// $res[] = User::where(['id' => $user['id']])->update([
// 'mobile' => $mobile,
// 'update_time' => time(),
// ]);
$user_mobile = User::where(['mobile' => $mobile])->find();
if ($user_mobile) {
$old_user_account = UserAccount::where(['user_id' => $user_id])->find();
#修改openid
$res[] = User::where(['id' => $user_mobile['id']])
->update([
'openid' => $user['openid'],
// 'nickname' => $user['nickname'],
// 'headimg' => $user['headimg'],
]);
#修改token
$res[] = UserAccount::where(['user_id' => $user_mobile['id']])->update([
'account_token' => $old_user_account['account_token'],
'token_num' => $old_user_account['token_num'],
'token_time' => $old_user_account['token_time'],
'last_login_time' => $old_user_account['last_login_time'],
'last_login_ip' => $old_user_account['last_login_ip'],
]);
#修改
$res[] = User::where(['id' => $user['id']])->delete();
$res[] = UserAccount::where(['user_id' => $user_id])->delete();
// $res[] = UserAccount::where(['user_id' => $user['id']])->update([
// 'token_time' => time(),
// ]);
} else {
$res[] = User::where(['id' => $user['id']])->update([
'mobile' => $mobile,
'update_time' => time(),
]);
}
if (resCheck($res)) {
Db::commit();
return $this->renderSuccess("绑定成功2");
} else {
Db::rollback();
return $this->renderSuccess("绑定成功3");
}
}
/**
* 绑定手机号
*/
public function login_bind_mobile_h5()
{
$user = $this->getUser();
$user_id = $user['id'];
$mobile = request()->param("mobile", '');
Db::startTrans();
$res = [];
$res[] = User::where(['id' => $user_id])->update([
'mobile' => $mobile,
'update_time' => time(),
]);
if (resCheck($res)) {
Db::commit();
return $this->renderSuccess("绑定成功2");
} else {
Db::rollback();
return $this->renderSuccess("绑定成功3");
}
}
/**
*
*
* @return mixed
*/
public function getAccessTokenOffiaccountSign()
{
$wxServer = new \app\common\server\WechatOfficialAccount($this->app);
$url = request()->param("url", '');
$data = $wxServer->getAccessTokenOffiaccountSign($url);
return $this->renderSuccess('', $data);
}
public function test()
{
$account_token['token'] = "77f6358084be8d5545747911e7f9d5ad5644a114";
$account_token['logintype'] = "2";
return $this->renderSuccess("登录成功", $account_token);
}
public function test1()
{
$share_image = getConfig("base")['share_image'];
$public_path = dirname($_SERVER['SCRIPT_FILENAME']);
$poster_bg = $public_path . $share_image;
// var_dump($poster_bg);
// $rule = getConfig('base');
// $draw_people_num = $rule['draw_people_num'];
// $user_id = 31;
// $pid = 24;
// if(!empty($pid)){
// $num = 0;
// $num = ProfitDraw::where(['type'=>5,'user_id'=>$pid])->count();
// if(bccomp("$num","$draw_people_num") < 0){
// #可以获得一张抽奖券
// $res= User::changeDraw($pid, 1,5 , '获得一张抽奖券',$user_id);
// var_dump($res);
// }
// }
// log::info($res);
}
}