232 lines
7.3 KiB
PHP
232 lines
7.3 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||
// +----------------------------------------------------------------------
|
||
// | Author: CRMEB Team <admin@crmeb.com>
|
||
// +----------------------------------------------------------------------
|
||
|
||
namespace app\jobs\user;
|
||
|
||
use app\services\user\UserServices;
|
||
use crmeb\basic\BaseJobs;
|
||
use crmeb\traits\QueueTrait;
|
||
use think\facade\Log;
|
||
|
||
/**
|
||
* 用户生日格式转换队列任务
|
||
* Class UserBirthdayFormatJob
|
||
* @package app\jobs\user
|
||
*/
|
||
class UserBirthdayFormatJob extends BaseJobs
|
||
{
|
||
use QueueTrait;
|
||
|
||
/**
|
||
* 处理用户生日格式转换
|
||
* @param array $userIds 用户ID数组,如果为空则处理所有用户
|
||
* @param int $batchSize 批处理大小,默认100
|
||
* @return bool
|
||
*/
|
||
public function doJob($userIds = [], $batchSize = 100)
|
||
{
|
||
try {
|
||
/** @var UserServices $userServices */
|
||
$userServices = app()->make(UserServices::class);
|
||
|
||
Log::info('开始处理用户生日格式转换任务', [
|
||
'user_ids' => $userIds,
|
||
'batch_size' => $batchSize
|
||
]);
|
||
|
||
// 如果没有指定用户ID,则查询所有需要处理的用户
|
||
if (empty($userIds)) {
|
||
$userIds = $this->getUsersWithTimestampBirthday($userServices);
|
||
}
|
||
|
||
if (empty($userIds)) {
|
||
Log::info('没有找到需要处理的用户生日数据');
|
||
return true;
|
||
}
|
||
|
||
// 分批处理用户数据
|
||
$chunks = array_chunk($userIds, $batchSize);
|
||
$totalChunks = count($chunks);
|
||
|
||
Log::info('开始分批处理用户生日数据', [
|
||
'total_users' => count($userIds),
|
||
'total_chunks' => $totalChunks,
|
||
'batch_size' => $batchSize
|
||
]);
|
||
|
||
foreach ($chunks as $index => $chunk) {
|
||
$this->processBirthdayBatch($userServices, $chunk, $index + 1, $totalChunks);
|
||
}
|
||
|
||
Log::info('用户生日格式转换任务完成', [
|
||
'processed_users' => count($userIds)
|
||
]);
|
||
|
||
return true;
|
||
|
||
} catch (\Throwable $e) {
|
||
Log::error('用户生日格式转换任务执行失败', [
|
||
'message' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取生日字段为时间戳格式的用户ID
|
||
* @param UserServices $userServices
|
||
* @return array
|
||
*/
|
||
private function getUsersWithTimestampBirthday($userServices)
|
||
{
|
||
try {
|
||
// 查询birthday字段不为空且不为0的用户
|
||
// 时间戳通常是10位数字,大于946684800(2000-01-01的时间戳)
|
||
$users = $userServices->search([])
|
||
->where('birthday', '<>', 0)
|
||
->where('is_del', 0)
|
||
->column('uid');
|
||
|
||
Log::info('查询到需要处理的用户', [
|
||
'count' => count($users)
|
||
]);
|
||
|
||
return $users;
|
||
|
||
} catch (\Throwable $e) {
|
||
Log::error('查询用户生日数据失败', [
|
||
'message' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine()
|
||
]);
|
||
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 批量处理用户生日数据
|
||
* @param UserServices $userServices
|
||
* @param array $userIds
|
||
* @param int $currentBatch
|
||
* @param int $totalBatches
|
||
* @return void
|
||
*/
|
||
private function processBirthdayBatch($userServices, $userIds, $currentBatch, $totalBatches)
|
||
{
|
||
try {
|
||
Log::info("处理第 {$currentBatch}/{$totalBatches} 批用户数据", [
|
||
'user_ids' => $userIds,
|
||
'count' => count($userIds)
|
||
]);
|
||
|
||
// 获取用户数据
|
||
$users = $userServices->search([])
|
||
->whereIn('uid', $userIds)
|
||
->where('is_del', 0)
|
||
->field('uid,birthday')
|
||
->select()
|
||
->toArray();
|
||
|
||
$updateCount = 0;
|
||
$errorCount = 0;
|
||
|
||
foreach ($users as $user) {
|
||
try {
|
||
$uid = $user['uid'];
|
||
$birthday = $user['birthday'];
|
||
|
||
// 检查是否为时间戳格式(10位数字)
|
||
if (!$this->isTimestamp($birthday)) {
|
||
continue;
|
||
}
|
||
|
||
// 将时间戳转换为日期格式 Y-m-d
|
||
$birthdayDate = date('Y-m-d', $birthday);
|
||
|
||
// 更新用户生日数据
|
||
$result = $userServices->search([])
|
||
->where('uid', $uid)
|
||
->update(['birthday' => $birthdayDate]);
|
||
|
||
if ($result) {
|
||
$updateCount++;
|
||
Log::debug("用户 {$uid} 生日格式转换成功", [
|
||
'old_birthday' => $birthday,
|
||
'new_birthday' => $birthdayDate,
|
||
'timestamp' => strtotime($birthdayDate)
|
||
]);
|
||
}
|
||
|
||
} catch (\Throwable $e) {
|
||
$errorCount++;
|
||
Log::error("处理用户 {$uid} 生日数据失败", [
|
||
'uid' => $uid,
|
||
'birthday' => $birthday,
|
||
'message' => $e->getMessage()
|
||
]);
|
||
}
|
||
}
|
||
|
||
Log::info("第 {$currentBatch} 批处理完成", [
|
||
'total_users' => count($users),
|
||
'updated_count' => $updateCount,
|
||
'error_count' => $errorCount
|
||
]);
|
||
|
||
} catch (\Throwable $e) {
|
||
Log::error("批量处理用户生日数据失败", [
|
||
'batch' => $currentBatch,
|
||
'user_ids' => $userIds,
|
||
'message' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine()
|
||
]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查是否为时间戳格式
|
||
* @param mixed $value
|
||
* @return bool
|
||
*/
|
||
private function isTimestamp($value)
|
||
{
|
||
// 检查是否为数字且在合理的时间戳范围内
|
||
if (!is_numeric($value)) {
|
||
return false;
|
||
}
|
||
|
||
$timestamp = (int)$value;
|
||
|
||
// 时间戳应该在1970年到2100年之间
|
||
return $timestamp > 0 && $timestamp > 946684800 && $timestamp < 4102444800;
|
||
}
|
||
|
||
/**
|
||
* 手动触发处理指定用户的生日格式转换
|
||
* @param array $userIds 指定的用户ID数组
|
||
* @return bool
|
||
*/
|
||
public function processSpecificUsers($userIds)
|
||
{
|
||
if (empty($userIds)) {
|
||
return false;
|
||
}
|
||
|
||
return $this->doJob($userIds);
|
||
}
|
||
}
|