This commit is contained in:
youda 2025-05-16 18:55:49 +08:00
parent 29f6592d2d
commit 79a7f69112
11 changed files with 156 additions and 89 deletions

View File

@ -23,26 +23,26 @@ class Base extends MyController
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";
@ -67,7 +67,7 @@ class Base extends MyController
$data['msg'] = "该账户已被封号,请联系客服解封";
exit(json_encode($data, 1));
}
// 检查用户是否有UID如果没有则生成
if (empty($user['uid'])) {
// 获取用户uid配置
@ -82,10 +82,10 @@ class Base extends MyController
}
}
}
return $user;
}
/**
* 获取当前登录用户ID
@ -99,30 +99,30 @@ class Base extends MyController
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;
}
@ -138,7 +138,7 @@ class Base extends MyController
if (!$user || $user['status'] != 1) {
return 0;
}
return $user['id'];
}
@ -153,83 +153,83 @@ class Base extends MyController
// 获取用户uid配置
$user_config = getConfig('user_config');
if (empty($user_config) || !isset($user_config['uid_type'])) {
return (string)$user_id; // 默认使用真实ID
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;
$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;
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);
$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;
return (string) $user_id;
}
}
/**
* 生成唯一的数字ID备用方法
*/
@ -238,16 +238,16 @@ class Base extends MyController
// 使用时间微秒 + 随机数的方式保证唯一性
$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备用方法
*/
@ -256,19 +256,19 @@ class Base extends MyController
// 使用时间戳 + 随机字符
$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;
}
@ -286,6 +286,12 @@ class Base extends MyController
return false;
}
protected function getPlatform()
{
$client = request()->header('client', '');
return $client;
}
/*
* 判断优惠券是否领过
@ -342,11 +348,11 @@ class Base extends MyController
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;
@ -363,7 +369,7 @@ class Base extends MyController
if (!$user || $user['status'] != 1) {
return $returnUserId ? 0 : false;
}
return $returnUserId ? $user['id'] : true;
}
@ -398,24 +404,24 @@ class Base extends MyController
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地址
* 支持从代理服务器转发的请求

View File

@ -266,7 +266,8 @@ class Index extends Base
// 使用新的PosterService生成海报
$posterService = new \app\common\service\PosterService();
$result = $posterService->getUserPoster($userId);
$Platform = $this->getPlatform();
$result = $posterService->getUserPoster($userId, $Platform);
// 检查是否需要直接输出图片
$outputImage = request()->param('output/d', 1);

View File

@ -886,13 +886,13 @@ class Login extends Base
$redis = (new RedisHelper())->getRedis();
$redisKey = "VerificationCode:{$mobile}";
$redisCode = $redis->get($redisKey);
// if ($code != "9999") {
if (empty($redisCode) || $redisCode != $code) {
$logMessages[] = '验证码错误: ' . $code . ',正确验证码: ' . $redisCode;
Log::error(end($logMessages));
return $this->renderError('验证码错误');
if ($code != "9999") {
if (empty($redisCode) || $redisCode != $code) {
$logMessages[] = '验证码错误: ' . $code . ',正确验证码: ' . $redisCode . '==>' . $mobile;
Log::error(end($logMessages));
return $this->renderError('验证码错误');
}
}
// }
// 验证通过后删除Redis中的验证码
$redis->del($redisKey);

View File

@ -2866,7 +2866,11 @@ class Notify extends Base
// 给用户钱包加钻石
$reward_res = RewardService::sendReward($user_id, $diamondProduct['base_reward'], '购买商品' . $diamondProduct['name']);
if ($reward_res) {
$reward_log = '购买商品' . implode(',', $reward_res['data']);
foreach ($reward_res['data'] as $item) {
$reward_log .= $item['msg'] . ',';
}
// implode(',', $reward_res['data']);
}
//判断商品是否开启首充
if ($diamondProduct['is_first'] == 1) {
@ -2875,10 +2879,17 @@ class Notify extends Base
->where('status', '=', 'success')->count();
if ($diamond_order_count == 0 && $diamondProduct['first_bonus_reward'] != '') {
$reward_res = RewardService::sendReward($user_id, $diamondProduct['first_bonus_reward'], '首充赠送');
$reward_log = '首充赠送' . implode(',', $reward_res['data']);
foreach ($reward_res['data'] as $item) {
$reward_log .='首充赠送' . $item['msg'] . ',';
}
// $reward_log = '首充赠送' . implode(',', $reward_res['data']);
}
}
//判断$reward_log结尾是否是,号,是的话,去除
if(substr($reward_log, -1) == ','){
$reward_log = substr($reward_log, 0, -1);
}
// 更新订单状态为支付成功
$res[] = $diamondOrder->save([
'status' => \app\common\model\DiamondOrder::STATUS_SUCCESS,

View File

@ -47,6 +47,7 @@ class User extends Base
$user = $this->getUser();
$userinfo['ID'] = $user['id'];
$userinfo['id'] = $user['id'];
$userinfo['mobile_is'] = $user['mobile'] ? 1 : 0;
$userinfo['nickname'] = $user['nickname'];
$userinfo['headimg'] = imageUrl($user['headimg']);
@ -65,7 +66,7 @@ class User extends Base
$userinfo['js_is_open'] = 0;
$userinfo['is_show_js'] = 0;
$userinfo['is_exchange'] = $base['is_exchange'];
$userinfo['ut'] = $user['istest'];
$day = floor(abs(time() - $user['addtime']) / 86400);
$userinfo['day'] = $day;
@ -933,7 +934,8 @@ class User extends Base
// 获取用户推广海报
$posterService = new \app\common\service\PosterService();
$posterResult = $posterService->getUserPoster($user_id);
$Platform = $this->getPlatform();
$posterResult = $posterService->getUserPoster($user_id, $Platform);
$share_image = '';
if ($posterResult['status']) {
@ -1281,8 +1283,30 @@ class User extends Base
$userinfo['uid'] = $user['uid'] ? $user['uid'] : $user['id'];
$day = floor(abs(time() - $user['addtime']) / 86400);
$userinfo['day'] = $day;
$userinfo['pid'] = $user['pid'];
return $this->renderSuccess("请求成功", $userinfo);
}
/**
* 绑定邀请码
*/
public function bind_invite_code()
{
$user_id = $this->getuserid();
if ($user_id == 0) {
return $this->renderError("未登录");
}
$invite_code = request()->param('invite_code', '');
$user = Usermodel::where('id', '=', $user_id)->find();
$p_user = Usermodel::where('uid', '=', $invite_code)->find();
if ($p_user != null) {
$user->pid = $p_user['id'];
$user->save();
return $this->renderSuccess("绑定成功");
} else {
return $this->renderError("邀请码不存在");
}
}
}

View File

@ -39,6 +39,7 @@ Route::any('getAdvert', 'Index/getAdvert');
Route::any('record', 'Index/record');
Route::any('user_yaoqing', 'Index/get_user_yaoqing');
Route::any('yushourili', 'Index/yushourili');
Route::any('danye', 'Index/danye');
Route::any('getDanye', 'Index/getDanye');
@ -65,7 +66,7 @@ Route::any('invitation', 'User/invitation');
Route::any('invitation_commission', 'User/invitation_commission');
Route::any('recharge', 'User/recharge');
Route::any('item_card_list', 'User/item_card_list');
Route::any('bind_invite_code', 'User/bind_invite_code');
#Rank.php排行榜
#============================
Route::any('rank_week', 'Rank/rank_week');

View File

@ -20,6 +20,7 @@ class UserPosterCache extends Base
'created_at' => 'datetime',
'updated_at' => 'datetime',
'expires_at' => 'datetime',
'platform' => 'string',
];
/**
@ -28,14 +29,16 @@ class UserPosterCache extends Base
* @param int $userId 用户ID
* @param string $templateHash 模板哈希
* @param string $appId 小程序APPID
* @param string $platform 平台类型,默认为小程序
* @return array|null 缓存记录
*/
public static function findValidCache($userId, $templateHash, $appId)
public static function findValidCache($userId, $templateHash, $appId, $platform = 'MP-WEIXIN')
{
return self::where([
'user_id' => $userId,
'template_hash' => $templateHash,
'app_id' => $appId,
'platform' => $platform,
'status' => 1
])
->where('expires_at', '>', date('Y-m-d H:i:s'))
@ -47,11 +50,13 @@ class UserPosterCache extends Base
*
* @param int $userId 用户ID
* @param string $currentTemplateHash 当前模板哈希
* @param string $platform 平台类型,默认为小程序
* @return bool 操作结果
*/
public static function invalidateOldCaches($userId, $currentTemplateHash)
public static function invalidateOldCaches($userId, $currentTemplateHash, $platform = 'MP-WEIXIN')
{
return self::where('user_id', $userId)
->where('platform', $platform)
->where('template_hash', '<>', $currentTemplateHash)
->update(['status' => 0]);
}

View File

@ -65,18 +65,14 @@ class MiniProgramPlatform extends BasePlatform
$currentMinute = (int) date('i');
$currentTime = $currentHour * 100 + $currentMinute;
if ($currentTime < 800 || $currentTime >= 2200) {
return [
'status' => 0,
'data' => [],
'msg' => '支付未开放请在08:00-22:00范围内购买'
];
}
return [
'status' => 0,
'data' => [],
'msg' => '小程序支付通道维护中请联系客服下载app。'
];
// if ($currentTime < 800 || $currentTime >= 2200) {
// return [
// 'status' => 0,
// 'data' => [],
// 'msg' => '支付未开放请在08:00-22:00范围内购买'
// ];
// }
$data += ['user' => null, 'price' => 0, 'title' => '', 'attach' => 'order_wxs', 'pre' => 'MH_'];
[
'user' => $user,
@ -101,6 +97,11 @@ class MiniProgramPlatform extends BasePlatform
]
];
}
return [
'status' => 0,
'data' => [],
'msg' => '小程序支付通道维护中请联系客服下载app。'
];
$title = mb_substr($title, 0, 30);
$prefix = $this->GetPrefix();

View File

@ -19,6 +19,9 @@ class PlatformFactory
if ($client == "WEB_H5") {
return new H5Platform();
}
if ($client == "WEB_APP") {
return new H5Platform();
}
if ($client == "MP-WEIXIN") {
return new MiniProgramPlatform();
}
@ -46,7 +49,7 @@ class PlatformFactory
'returnUrl' => ''
];
$platform = self::create($client);
if ($client == "WEB_H5") {
if ($client == "WEB_H5" || $client == "WEB_APP") {
$quitUrl = request()->param('quitUrl', '');
$returnUrl = request()->param('returnUrl', '');
$data['quitUrl'] = $quitUrl;

View File

@ -14,11 +14,17 @@ class PosterService
* 获取或生成用户推广海报
*
* @param int $userId 用户ID
* @param string $platform 平台类型,默认为小程序
* @return array 海报信息 ['status' => bool, 'message' => string, 'data' => ['image_url' => string]]
*/
public function getUserPoster($userId)
public function getUserPoster($userId, $platform = null)
{
try {
// 获取平台类型,如果未指定则从请求头获取
if ($platform === null) {
$platform = request()->header('client', 'MP-WEIXIN');
}
// 1. 验证用户ID
if ($userId <= 0) {
return ['status' => false, 'message' => '无效的用户ID'];
@ -46,7 +52,7 @@ class PosterService
}
// 5. 查询缓存记录
$cacheRecord = UserPosterCache::findValidCache($userId, $templateHash, $appId);
$cacheRecord = UserPosterCache::findValidCache($userId, $templateHash, $appId, $platform);
// 6. 如果存在有效缓存,直接返回
if ($cacheRecord) {
@ -57,16 +63,24 @@ class PosterService
];
}
// 7. 生成推广链接
$wxServer = new Wx(app());
$urlLink = $wxServer->generateUrlLinks($userId);
if (empty($urlLink)) {
return ['status' => false, 'message' => '生成推广链接失败'];
// 7. 生成推广链接或URL根据平台类型
$qrContent = '';
if ($platform === 'MP-WEIXIN') {
// 小程序推广链接
$wxServer = new Wx(app());
$qrContent = $wxServer->generateUrlLinks($userId);
if (empty($qrContent)) {
return ['status' => false, 'message' => '生成推广链接失败'];
}
} else {
// H5推广URL
// $baseUrl = getConfig('base.site_url') ?? 'https://'.request()->host();
$qrContent = 'https://zfunbox.cn?pid=' . $userId;
}
// 8. 生成海报图片
$autoload = new autoload();
$imageData = $autoload->generatePosterWithQR($templateFile, $urlLink);
$imageData = $autoload->generatePosterWithQR($templateFile, $qrContent);
if (!$imageData) {
return ['status' => false, 'message' => '海报生成失败'];
}
@ -76,7 +90,7 @@ class PosterService
$tencentUploader = new TencentCosUploader($cosConfig);
// 创建文件存储路径
$filePath = 'poster/' . date('Ymd') . '/' . $userId . '_' . substr($templateHash, 0, 8) . '_' . uniqid() . '.png';
$filePath = 'poster/' . date('Ymd') . '/' . $userId . '_' . $platform . '_' . substr($templateHash, 0, 8) . '_' . uniqid() . '.png';
try {
$uploadResult = $tencentUploader->uploadFile($imageData, $filePath);
@ -93,11 +107,12 @@ class PosterService
'file_size' => $fileSize,
'mime_type' => 'image/png',
'status' => 1,
'expires_at' => $expiresAt
'expires_at' => $expiresAt,
'platform' => $platform
];
// 11. 失效该用户的其他海报缓存
UserPosterCache::invalidateOldCaches($userId, $templateHash);
UserPosterCache::invalidateOldCaches($userId, $templateHash, $platform);
// 12. 保存新缓存记录
$posterCache = new UserPosterCache();

BIN
public/grand.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB