代码提交优化新增的渠道码限制24小时有效
This commit is contained in:
@@ -9,6 +9,8 @@ use library\ResponseHelper;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use think\facade\Env;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel;
|
||||
use EasyWeChat\Factory;
|
||||
@@ -860,6 +862,43 @@ class ChannelController extends BaseController
|
||||
'expireTime' => time() + 86400 // 24小时后过期
|
||||
];
|
||||
$token = base64_encode(json_encode($tokenData));
|
||||
|
||||
// 如果是小程序码,提前计算scene并存储映射关系到数据库
|
||||
if ($type === 'miniprogram') {
|
||||
$scene = substr(md5($token), 0, 32);
|
||||
|
||||
// 使用数据库存储映射关系(更可靠)
|
||||
try {
|
||||
Db::name('distribution_channel_scene_token')->insert([
|
||||
'scene' => $scene,
|
||||
'token' => $token,
|
||||
'companyId' => $companyId,
|
||||
'expireTime' => time() + 86400,
|
||||
'createTime' => time()
|
||||
]);
|
||||
Log::info('生成小程序码 - 存储映射到数据库,scene: ' . $scene . ', companyId: ' . $companyId);
|
||||
} catch (\Exception $e) {
|
||||
// 如果表不存在,尝试创建表
|
||||
Log::warning('存储映射关系失败,尝试创建表: ' . $e->getMessage());
|
||||
$this->createSceneTokenTable();
|
||||
// 重试一次
|
||||
try {
|
||||
Db::name('distribution_channel_scene_token')->insert([
|
||||
'scene' => $scene,
|
||||
'token' => $token,
|
||||
'companyId' => $companyId,
|
||||
'expireTime' => time() + 86400,
|
||||
'createTime' => time()
|
||||
]);
|
||||
} catch (\Exception $e2) {
|
||||
Log::error('重试存储映射关系失败: ' . $e2->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 同时存储到缓存(双重保险)
|
||||
$sceneCacheKey = 'channel_register_scene_' . $scene;
|
||||
Cache::set($sceneCacheKey, $token, 86400);
|
||||
}
|
||||
|
||||
if ($type === 'h5') {
|
||||
// 生成H5二维码
|
||||
@@ -905,6 +944,18 @@ class ChannelController extends BaseController
|
||||
|
||||
// scene参数长度限制为32位,使用token的MD5值
|
||||
$scene = substr(md5($token), 0, 32);
|
||||
|
||||
// 再次确保映射关系已存储到数据库和缓存(双重保险)
|
||||
$sceneCacheKey = 'channel_register_scene_' . $scene;
|
||||
Cache::set($sceneCacheKey, $token, 86400);
|
||||
|
||||
// 验证数据库和缓存是否存储成功
|
||||
$dbToken = Db::name('distribution_channel_scene_token')
|
||||
->where('scene', $scene)
|
||||
->where('expireTime', '>', time())
|
||||
->value('token');
|
||||
$cacheToken = Cache::get($sceneCacheKey);
|
||||
Log::info('生成小程序码 - scene: ' . $scene . ', 数据库验证: ' . ($dbToken ? '成功' : '失败') . ', 缓存验证: ' . ($cacheToken ? '成功' : '失败'));
|
||||
|
||||
// 调用接口生成小程序码
|
||||
// 注意:page 必须是小程序里已经存在且发布过的页面路径
|
||||
@@ -1125,6 +1176,43 @@ class ChannelController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
// 记录接收到的参数
|
||||
Log::info('registerByQrCode - 接收到的token参数: ' . $token . ', 长度: ' . strlen($token) . ', 是否为32位MD5: ' . (preg_match('/^[a-f0-9]{32}$/i', $token) ? '是' : '否'));
|
||||
|
||||
// 判断传入的是scene(32位MD5)还是token(base64编码)
|
||||
// 如果是32位MD5字符串,则从数据库或缓存中查找对应的token
|
||||
if (strlen($token) == 32 && preg_match('/^[a-f0-9]{32}$/i', $token)) {
|
||||
// 这是scene,先从数据库查找对应的token
|
||||
$sceneData = Db::name('distribution_channel_scene_token')
|
||||
->where('scene', $token)
|
||||
->where('expireTime', '>', time())
|
||||
->find();
|
||||
|
||||
if ($sceneData && !empty($sceneData['token'])) {
|
||||
$realToken = $sceneData['token'];
|
||||
Log::info('registerByQrCode - 从数据库获取token成功,scene: ' . $token);
|
||||
} else {
|
||||
// 如果数据库中没有,尝试从缓存获取
|
||||
$sceneCacheKey = 'channel_register_scene_' . $token;
|
||||
$realToken = Cache::get($sceneCacheKey);
|
||||
|
||||
if (empty($realToken)) {
|
||||
Log::warning('registerByQrCode - 数据库和缓存中均未找到token,scene: ' . $token);
|
||||
return json([
|
||||
'code' => 400,
|
||||
'success' => false,
|
||||
'msg' => '二维码已过期,请重新生成',
|
||||
'data' => null
|
||||
]);
|
||||
}
|
||||
Log::info('registerByQrCode - 从缓存获取token成功,scene: ' . $token);
|
||||
}
|
||||
|
||||
$token = $realToken;
|
||||
} else {
|
||||
Log::info('registerByQrCode - 识别为token(非scene),直接使用,token长度: ' . strlen($token));
|
||||
}
|
||||
|
||||
// 解析token
|
||||
$tokenData = json_decode(base64_decode($token), true);
|
||||
if (!$tokenData || !isset($tokenData['companyId'])) {
|
||||
@@ -1307,5 +1395,31 @@ class ChannelController extends BaseController
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建scene和token映射表(如果不存在)
|
||||
*/
|
||||
protected function createSceneTokenTable()
|
||||
{
|
||||
try {
|
||||
$sql = "CREATE TABLE IF NOT EXISTS `ck_distribution_channel_scene_token` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`scene` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '小程序scene参数(MD5值)',
|
||||
`token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原始token(base64编码)',
|
||||
`companyId` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '公司ID',
|
||||
`expireTime` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期时间戳',
|
||||
`createTime` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_scene` (`scene`) USING BTREE,
|
||||
INDEX `idx_companyId` (`companyId`) USING BTREE,
|
||||
INDEX `idx_expireTime` (`expireTime`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销渠道小程序码scene和token映射表';";
|
||||
|
||||
Db::execute($sql);
|
||||
Log::info('创建scene和token映射表成功');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('创建scene和token映射表失败: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user