manghe/app/api/controller/Base.php
2025-06-16 22:02:14 +08:00

463 lines
14 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
namespace app\api\controller;
use app\MyController;
use app\common\model\User;
use app\common\model\UserAccount;
use think\facade\Request;
use app\common\model\User as UserModel;
header('Access-Control-Allow-Origin: *');
/**
* 商户后台控制器基类
*/
class Base extends MyController
{
public $page = '10';
/**
* 获取当前用户信息
*/
protected function getUser()
{
$token = request()->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;
}
}