header('token', ''); // 先从Redis中获取用户账户信息 $redis = (new \app\common\server\RedisHelper())->getRedis(); $redis_key = 'user_account_token:' . $token; $user_account = $redis->get($redis_key); if ($user_account) { // Redis中存在数据,直接使用 $user_account = json_decode($user_account, true); } else { // Redis中不存在,从数据库获取 $user_account = UserAccount::getInfo(['account_token' => $token]); // 如果数据库中存在该用户账户信息,则存入Redis if ($user_account) { $redis->set($redis_key, json_encode($user_account)); $redis->expire($redis_key, 600); // 设置过期时间为10分钟(600秒) } } if (!$user_account) { $data['status'] = '-1'; $data['msg'] = "没有找到用户信息1"; exit(json_encode($data, 1)); } $user_account_is = user_md5($user_account['user_id'] . $user_account['token_num'] . $user_account['token_time']); if ($token !== $user_account_is) { $data['status'] = '-1'; $data['msg'] = "没有找到用户信息2"; exit(json_encode($data, 1)); } $user = User::where(['id' => $user_account['user_id']])->find(); if (!$user) { $data['status'] = '-1'; $data['msg'] = "没有找到用户信息3"; exit(json_encode($data, 1)); } if ($user['status'] != 1) { $data['status'] = '-1'; $data['msg'] = "该账户已被封号,请联系客服解封"; exit(json_encode($data, 1)); } // 检查用户是否有UID,如果没有则生成 if (empty($user['uid'])) { // 获取用户uid配置 $user_config = getConfig('user_config'); if (!empty($user_config) && isset($user_config['uid_type'])) { // 生成UID $uid = $this->generateUidForUser($user['id']); if ($uid) { // 更新用户UID User::where('id', $user['id'])->update(['uid' => $uid]); $user['uid'] = $uid; } } } return $user; } /** * 获取当前登录用户ID * * @return int 用户ID,未登录或状态异常时返回0 */ protected function getUserId() { $token = request()->header('token', ''); // 尝试从请求参数中获取token if (empty($token)) { $token = $this->request->param('token', ''); } if (empty($token)) { return 0; } // 先从Redis中获取用户账户信息 $redis = (new \app\common\server\RedisHelper())->getRedis(); $redis_key = 'user_account_token:' . $token; $user_account = $redis->get($redis_key); if ($user_account) { // Redis中存在数据,直接使用 $user_account = json_decode($user_account, true); } else { // Redis中不存在,从数据库获取 $user_account = UserAccount::getInfo(['account_token' => $token]); // 如果数据库中存在该用户账户信息,则存入Redis if ($user_account) { $redis->set($redis_key, json_encode($user_account)); $redis->expire($redis_key, 600); // 设置过期时间为10分钟(600秒) } } if (!$user_account) { return 0; } // 验证token有效性 $user_account_is = user_md5($user_account['user_id'] . $user_account['token_num'] . $user_account['token_time']); if ($token !== $user_account_is) { return 0; } // 检查用户状态 $user = User::where(['id' => $user_account['user_id']])->find(); if (!$user || $user['status'] != 1) { return 0; } return $user['id']; } /** * 为用户生成UID * * @param int $user_id 用户ID * @return string 生成的UID */ protected function generateUidForUser($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; } /** * * 是否H5客户端 * @return bool */ protected function ish5() { $client = $this->getPlatform(); if ($client == "h5") { return true; } return false; } protected function getPlatform() { $client = request()->header('client', ''); if($client==""){ $client = request()->header('platform', ''); } return $client; } /* * 判断优惠券是否领过 */ protected function getUserid1($is_force = true) { $header = Request::header(); if ($header['token'] == '') { $token = $this->request->param('token'); } else { $token = $header['token']; } $header['logintype'] = 1; if (!isset($header['logintype']) or !in_array($header['logintype'], [1, 2])) { return false; } if (!$token) { if ($is_force) { return false; } } $user_account = UserAccount::getInfo(['account_token' => $token]); if (empty($user_account)) { if ($is_force) { return false; } return false; } $user = UserModel::getInfo(['id' => $user_account['user_id']]); if (empty($user)) { return false; } if ($user['status'] != 1) { return false; } #判断优惠券是否领过 if ($user['is_use_coupon'] == 1) { return false; } else { return true; } } /** * 判断用户是否已登录 * * @param bool $returnUserId 是否返回用户ID而不是布尔值 * @return bool|int 如果$returnUserId为true,返回用户ID(未登录时为0);否则返回布尔值 */ protected function isLogin($returnUserId = false) { $token = request()->header('token', ''); if (empty($token)) { $token = $this->request->param('token', ''); } if (empty($token)) { return $returnUserId ? 0 : false; } $user_account = UserAccount::getInfo(['account_token' => $token]); if (!$user_account) { return $returnUserId ? 0 : false; } // 验证token有效性 $user_account_is = user_md5($user_account['user_id'] . $user_account['token_num'] . $user_account['token_time']); if ($token !== $user_account_is) { return $returnUserId ? 0 : false; } // 检查用户状态 $user = User::where(['id' => $user_account['user_id']])->find(); if (!$user || $user['status'] != 1) { return $returnUserId ? 0 : false; } return $returnUserId ? $user['id'] : true; } /** * 检查用户登录状态,未登录时返回JSON错误响应 * * @param string $msg 自定义错误消息 * @return array|bool 登录时返回用户信息数组,未登录时输出JSON并终止执行 */ protected function checkLogin($msg = '请先登录') { $user = $this->getUser(); if (!$user) { $data = [ 'status' => -1, 'msg' => $msg ]; echo json_encode($data, JSON_UNESCAPED_UNICODE); exit; } return $user; } /** * 检查用户是否满足解锁盒子的条件 * * @param int $unlock_amount 解锁所需金额 * @return bool 是否满足解锁条件 */ protected function checkUnlockCondition($unlock_amount) { if ($unlock_amount <= 0) { return true; // 无需解锁 } // 获取用户ID $userId = $this->isLogin(true); if (!$userId) { return false; // 未登录 } // 获取用户消费总额 $user = User::where('id', $userId)->find(); if (!$user) { return false; } // 用户消费总额大于等于解锁金额时可以解锁 return isset($user['total_consumption']) && $user['total_consumption'] >= $unlock_amount; } /** * 获取真实客户端IP地址 * 支持从代理服务器转发的请求 */ protected function getRealIp() { $ip = request()->ip(); // 检查常见的代理服务器IP头信息 $headers = [ 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP', 'REMOTE_ADDR' ]; foreach ($headers as $header) { if (isset($_SERVER[$header]) && !empty($_SERVER[$header])) { // 可能包含多个IP,取第一个 $ips = explode(',', $_SERVER[$header]); $client_ip = trim($ips[0]); // 验证IP格式是否合法 if (filter_var($client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return $client_ip; } } } return $ip; } }