代码提交

This commit is contained in:
wong
2025-10-14 17:03:05 +08:00
parent f2c25927eb
commit da63930f5e
9 changed files with 369 additions and 188 deletions

View File

@@ -62,9 +62,7 @@ class AccountController extends BaseController
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveAccount($item);
}
$this->saveAccount($response['results']);
}
if ($isInner) {
@@ -703,42 +701,41 @@ class AccountController extends BaseController
* 保存账号数据到数据库
* @param array $item 账号数据
*/
private function saveAccount($item)
private function saveAccount($data)
{
// 将日期时间字符串转换为时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null;
$deleteTime = isset($item['deleteTime']) ? strtotime($item['deleteTime']) : null;
$sqlData = [];
foreach ($data as $item) {
$sqlData[] = [
'id' => $item['id'],
'accountType' => isset($item['accountType']) ? $item['accountType'] : 0,
'status' => isset($item['status']) ? $item['status'] : 0,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'userName' => isset($item['userName']) ? $item['userName'] : '',
'realName' => isset($item['realName']) ? $item['realName'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'avatar' => isset($item['avatar']) ? $item['avatar'] : '',
'phone' => isset($item['phone']) ? $item['phone'] : '',
'memo' => isset($item['memo']) ? $item['memo'] : '',
'createTime' => $createTime,
'creator' => isset($item['creator']) ? $item['creator'] : 0,
'creatorUserName' => isset($item['creatorUserName']) ? $item['creatorUserName'] : '',
'creatorRealName' => isset($item['creatorRealName']) ? $item['creatorRealName'] : '',
'departmentId' => isset($item['departmentId']) ? $item['departmentId'] : 0,
'departmentName' => isset($item['departmentName']) ? $item['departmentName'] : '',
'privilegeIds' => isset($item['privilegeIds']) ? json_encode($item['privilegeIds']) : json_encode([]),
'alive' => isset($item['alive']) ? $item['alive'] : false,
'hasXiakeAccount' => isset($item['hasXiakeAccount']) ? $item['hasXiakeAccount'] : false,
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : false,
'deleteTime' => $deleteTime
];
}
$data = [
'id' => $item['id'],
'accountType' => isset($item['accountType']) ? $item['accountType'] : 0,
'status' => isset($item['status']) ? $item['status'] : 0,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'userName' => isset($item['userName']) ? $item['userName'] : '',
'realName' => isset($item['realName']) ? $item['realName'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'avatar' => isset($item['avatar']) ? $item['avatar'] : '',
'phone' => isset($item['phone']) ? $item['phone'] : '',
'memo' => isset($item['memo']) ? $item['memo'] : '',
'createTime' => $createTime,
'creator' => isset($item['creator']) ? $item['creator'] : 0,
'creatorUserName' => isset($item['creatorUserName']) ? $item['creatorUserName'] : '',
'creatorRealName' => isset($item['creatorRealName']) ? $item['creatorRealName'] : '',
'departmentId' => isset($item['departmentId']) ? $item['departmentId'] : 0,
'departmentName' => isset($item['departmentName']) ? $item['departmentName'] : '',
'privilegeIds' => isset($item['privilegeIds']) ? json_encode($item['privilegeIds']) : json_encode([]),
'alive' => isset($item['alive']) ? $item['alive'] : false,
'hasXiakeAccount' => isset($item['hasXiakeAccount']) ? $item['hasXiakeAccount'] : false,
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : false,
'deleteTime' => $deleteTime
];
// 使用tenantId作为唯一性判断
$account = CompanyAccountModel::where('id', $item['id'])->find();
if ($account) {
$account->save($data);
} else {
CompanyAccountModel::create($data);
}
$account = new CompanyAccountModel();
$account->saveAll($account);
}
}

View File

@@ -54,11 +54,9 @@ class WechatChatroomController extends BaseController
// 保存数据到数据库
if (!empty($response['results'])) {
$isUpdate = false;
foreach ($response['results'] as $item) {
$updated = $this->saveChatroom($item);
if($updated && $isDel == 0){
$isUpdate = true;
}
$updated = $this->saveChatroom($response['results']);
if($updated && $isDel == 0){
$isUpdate = true;
}
}
@@ -80,44 +78,51 @@ class WechatChatroomController extends BaseController
* 保存群聊数据到数据库
* @param array $item 群聊数据
*/
private function saveChatroom($item)
private function saveChatroom($data)
{
$data = [
'id' => $item['id'],
'wechatAccountId' => $item['wechatAccountId'],
'wechatAccountAlias' => $item['wechatAccountAlias'],
'wechatAccountWechatId' => $item['wechatAccountWechatId'],
'wechatAccountAvatar' => $item['wechatAccountAvatar'],
'wechatAccountNickname' => $item['wechatAccountNickname'],
'chatroomId' => $item['chatroomId'],
'hasMe' => $item['hasMe'],
'chatroomOwnerNickname' => isset($item['chatroomOwnerNickname']) ? $item['chatroomOwnerNickname'] : '',
'chatroomOwnerAvatar' => isset($item['chatroomOwnerAvatar']) ? $item['chatroomOwnerAvatar'] : '',
'conRemark' => isset($item['conRemark']) ? $item['conRemark'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'pyInitial' => isset($item['pyInitial']) ? $item['pyInitial'] : '',
'quanPin' => isset($item['quanPin']) ? $item['quanPin'] : '',
'chatroomAvatar' => isset($item['chatroomAvatar']) ? $item['chatroomAvatar'] : '',
'members' => is_array($item['members']) ? json_encode($item['members']) : json_encode([]),
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : 0,
'deleteTime' => !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : 0,
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'accountId' => isset($item['accountId']) ? $item['accountId'] : 0,
'accountUserName' => isset($item['accountUserName']) ? $item['accountUserName'] : '',
'accountRealName' => isset($item['accountRealName']) ? $item['accountRealName'] : '',
'accountNickname' => isset($item['accountNickname']) ? $item['accountNickname'] : '',
'groupId' => isset($item['groupId']) ? $item['groupId'] : 0,
'updateTime' => time()
];
$sqlData = [];
foreach ($data as $item) {
$sqlData[] = [
'id' => $item['id'],
'wechatAccountId' => $item['wechatAccountId'],
'wechatAccountAlias' => $item['wechatAccountAlias'],
'wechatAccountWechatId' => $item['wechatAccountWechatId'],
'wechatAccountAvatar' => $item['wechatAccountAvatar'],
'wechatAccountNickname' => $item['wechatAccountNickname'],
'chatroomId' => $item['chatroomId'],
'hasMe' => $item['hasMe'],
'chatroomOwnerNickname' => isset($item['chatroomOwnerNickname']) ? $item['chatroomOwnerNickname'] : '',
'chatroomOwnerAvatar' => isset($item['chatroomOwnerAvatar']) ? $item['chatroomOwnerAvatar'] : '',
'conRemark' => isset($item['conRemark']) ? $item['conRemark'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'pyInitial' => isset($item['pyInitial']) ? $item['pyInitial'] : '',
'quanPin' => isset($item['quanPin']) ? $item['quanPin'] : '',
'chatroomAvatar' => isset($item['chatroomAvatar']) ? $item['chatroomAvatar'] : '',
'members' => is_array($item['members']) ? json_encode($item['members']) : json_encode([]),
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : 0,
'deleteTime' => !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : 0,
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'accountId' => isset($item['accountId']) ? $item['accountId'] : 0,
'accountUserName' => isset($item['accountUserName']) ? $item['accountUserName'] : '',
'accountRealName' => isset($item['accountRealName']) ? $item['accountRealName'] : '',
'accountNickname' => isset($item['accountNickname']) ? $item['accountNickname'] : '',
'groupId' => isset($item['groupId']) ? $item['groupId'] : 0,
'updateTime' => time()
];
}
// 使用chatroomId和wechatAccountId的组合作为唯一性判断
$chatroom = WechatChatroomModel::where('id',$item['id'])->find();
$chatroom = new WechatChatroomModel();
$chatroom->saveAll($sqlData);
if ($chatroom) {
$chatroom->save($data);
return true;
} else {
WechatChatroomModel::create($data);
if ($chatroom->isUpdate()){
return true;
}else{
return false;
}
}else{
return false;
}

View File

@@ -488,6 +488,38 @@ if (!function_exists('getUserAction')) {
}
}
if (!function_exists('formatRelativeTime')) {
/**
* 将时间戳格式化为相对时间(中文)
* 例:半年前 / 1个月前 / 3周前 / 1天前 / 5小时前 / 5分钟前 / 刚刚
* @param int $timestamp Unix 时间戳(秒)
* @return string
*/
function formatRelativeTime($timestamp)
{
if (empty($timestamp) || !is_numeric($timestamp)) {
return '';
}
$now = time();
$diff = max(0, $now - (int)$timestamp);
$minute = 60;
$hour = 60 * $minute;
$day = 24 * $hour;
$week = 7 * $day;
$month = 30 * $day; // 近似
$halfYear = 6 * $month; // 近似
if ($diff >= $halfYear) return '半年前';
if ($diff >= $month) return floor($diff / $month) . '个月前';
if ($diff >= $week) return floor($diff / $week) . '周前';
if ($diff >= $day) return floor($diff / $day) . '天前';
if ($diff >= $hour) return floor($diff / $hour) . '小时前';
if ($diff >= $minute) return floor($diff / $minute) . '分钟前';
return '刚刚';
}
}
if (!function_exists('exit_data')) {

View File

@@ -62,14 +62,18 @@ Route::group('v1/', function () {
// 流量池相关
Route::group('traffic/pool', function () {
Route::get('getPackage', 'app\cunkebao\controller\TrafficController@getPackage');
Route::get('', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@index');
Route::get('getUserJourney', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@getUserJourney');
Route::get('getUserTags', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@getUserTags');
Route::get('getUserInfo', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@getUser');
Route::get('getPackage', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@getPackage');
Route::post('addPackage', 'app\cunkebao\controller\traffic\GetPotentialListWithInCompanyV1Controller@addPackage');
Route::get('converted', 'app\cunkebao\controller\traffic\GetConvertedListWithInCompanyV1Controller@index');
Route::get('types', 'app\cunkebao\controller\traffic\GetPotentialTypeSectionV1Controller@index');
Route::get('sources', 'app\cunkebao\controller\traffic\GetTrafficSourceSectionV1Controller@index');

View File

@@ -0,0 +1,55 @@
<?php
namespace app\cunkebao\controller;
class RFMController extends BaseController
{
/**
* 计算 RFM 评分(默认规则)
* @param int|null $recencyDays 最近购买天数
* @param int $frequency 购买次数
* @param float $monetary 购买金额
* @return array{R:int,F:int,M:int}
*/
public static function calcRfmScores($recencyDays, $frequency, $monetary)
{
$recencyDays = is_numeric($recencyDays) ? (int)$recencyDays : 9999;
$frequency = max(0, (int)$frequency);
$monetary = max(0, (float)$monetary);
return [
'R' => self::scoreR_Default($recencyDays),
'F' => self::scoreF_Default($frequency),
'M' => self::scoreM_Default($monetary),
];
}
// 默认规则
protected static function scoreR_Default(int $days): int
{
if ($days <= 30) return 5;
if ($days <= 60) return 4;
if ($days <= 90) return 3;
if ($days <= 120) return 2;
return 1;
}
protected static function scoreF_Default(int $times): int
{
if ($times >= 10) return 5;
if ($times >= 6) return 4;
if ($times >= 3) return 3;
if ($times >= 2) return 2;
if ($times >= 1) return 1;
return 0;
}
protected static function scoreM_Default(float $amount): int
{
if ($amount >= 2000) return 5;
if ($amount >= 1000) return 4;
if ($amount >= 500) return 3;
if ($amount >= 200) return 2;
if ($amount > 0) return 1;
return 0;
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace app\cunkebao\controller;
use library\ResponseHelper;
use think\Db;
use app\cunkebao\controller\RFMController;
class TrafficController extends BaseController
{
public function getPackage()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$companyId = $this->getUserInfo('companyId');
$package = Db::name('traffic_source_package')->alias('tsp')
->join('traffic_source_package_item tspi', 'tspi.packageId=tsp.id', 'left')
->whereIn('tsp.companyId', [$companyId, 0])
->field('tsp.id,tsp.name,tsp.description,tsp.pic,tsp.isSys as type,tsp.createTime,count(tspi.id) as num')
->group('tsp.id');
if (!empty($keyword)) {
$package->where('tsp.name|tsp.description', 'like', '%' . $keyword . '%');
}
$list = $package->page($page, $limit)->order('isSys ASC,id DESC')->select();
$total = $package->count();
$rfmRule = 'default';
foreach ($list as $k => &$v) {
if ($v['type'] != 1) {
$v['createTime'] = !empty($v['createTime']) ? formatRelativeTime($v['createTime']) : '';
}else{
$v['createTime'] = '';
}
// RFM 评分示例以创建时间近似最近活跃num 近似频次;金额若无则为 0
$recencyDays = isset($v['createTime']) && is_numeric($v['createTime']) ? floor((time() - (int)$v['createTime']) / 86400) : null;
// 如果上方被格式化为文本,则尝试从原始结果集取原值
if (!is_numeric($recencyDays) || $recencyDays === null) {
$rawCreate = isset($list[$k]['createTime']) ? $list[$k]['createTime'] : null;
$recencyDays = is_numeric($rawCreate) ? floor((time() - (int)$rawCreate) / 86400) : 9999;
}
$frequency = (int)($v['num'] ?? 0);
$monetary = (float)($v['monetary'] ?? 0);
$scores = RFMController::calcRfmScores($recencyDays, $frequency, $monetary);
$v['R'] = $scores['R'];
$v['F'] = $scores['F'];
$v['M'] = $scores['M'];
$v['RFM'] = $scores['R'] + $scores['F'] + $scores['M'];
}
unset($v);
$data = [
'total' => $total,
'list' => $list,
];
return ResponseHelper::success($data);
}
}

View File

@@ -359,39 +359,7 @@ class GetPotentialListWithInCompanyV1Controller extends BaseController
}
public function getPackage()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$companyId = $this->getUserInfo('companyId');
$package = Db::name('traffic_source_package')->alias('tsp')
->join('traffic_source_package_item tspi', 'tspi.packageId=tsp.id', 'left')
->whereIn('tsp.companyId', [$companyId, 0])
->field('tsp.id,tsp.name,tsp.description,tsp.createTime,count(tspi.id) as num')
->group('tsp.id');
if (!empty($keyword)) {
$package->where('tsp.name|tsp.description', 'like', '%' . $keyword . '%');
}
$list = $package->page($page, $limit)->select();
$total = $package->count();
foreach ($list as $k => &$v) {
$v['createTime'] = !empty($v['createTime']) ? date('Y-m-d H:i:s', $v['createTime']) : '';
}
unset($v);
$data = [
'total' => $total,
'list' => $list,
];
return ResponseHelper::success($data);
}
public function addPackage()

View File

@@ -108,93 +108,33 @@ class WorkbenchMomentsJob
public function execute2()
{
try {
// 每日重置发送次数允许10分钟误差
$now = time();
$todayStart = strtotime(date('Y-m-d 00:00:00'));
if ($now - $todayStart >= 0 && $now - $todayStart <= 600) {
$cacheKey = 'moments_settings_reset_' . date('Ymd');
if (!Cache::has($cacheKey)) {
Db::table('ck_kf_moments_settings')->where('sendNum', '<>', 0)
->update(['sendNum' => 0, 'updateTime' => $now]);
Cache::set($cacheKey, 1, 7200); // 2小时缓存防止重复重置
}
}
// 获取所有工作台
$kfMoments = KfMoments::where(['isSend' => 0, 'isDel' => 0])->where('sendTime', '<=', time() + 120)->order('id desc')->select();
// 1) 每日重置
$this->resetDailyCountersIfNeeded();
// 2) 获取发送窗口内的任务
[$nowTs, $kfMoments] = $this->getWindowTasks();
foreach ($kfMoments as $val) {
$sendData = json_decode($val->sendData,true);
$endTime = strtotime($sendData['endTime']);
if ($endTime <= time() + 1800){
$endTime = time() + 3600;
$sendData['endTime'] = date('Y-m-d H:i:s', $endTime);
}
switch ($sendData['momentContentType']) {
case 1:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
case 2:
$sendData['link'] = ['image' => ''];
$sendData['videoUrl'] = '';
break;
case 3:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
break;
case 4:
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
default:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
}
$companyId = (int)($val['companyId'] ?? 0);
$userId = (int)($val['userId'] ?? 0);
// 2.1) 数据规范化
$sendData = json_decode($val->sendData, true);
$sendData = $this->normalizeSendData($sendData);
// 2.2) 账号额度过滤
$items = $sendData['jobPublishWechatMomentsItems'] ?? [];
if (empty($items)) { continue; }
$allowed = $this->filterAccountsByQuota($companyId, $userId, $items);
if (empty($allowed)) { continue; }
$sendData['jobPublishWechatMomentsItems'] = $allowed;
// 3) 下发
$moments = new Moments();
$moments->addJob($sendData);
KfMoments::where(['id' => $val['id']])->update(['isSend' => 1]);
// 统计发送次数ck_kf_moments_settings
try {
$nowTs = time();
$companyId = (int)($val['companyId'] ?? 0);
$userId = (int)($val['userId'] ?? 0);
$items = $sendData['jobPublishWechatMomentsItems'] ?? [];
foreach ($items as $it) {
$wechatId = (int)($it['wechatAccountId'] ?? 0);
if ($wechatId <= 0) { continue; }
$cond = [
'companyId' => $companyId,
'userId' => $userId,
'wechatId' => $wechatId,
];
$setting = Db::table('ck_kf_moments_settings')->where($cond)->find();
if ($setting) {
Db::table('ck_kf_moments_settings')
->where('id', $setting['id'])
->update([
'sendNum' => Db::raw('sendNum + 1'),
'updateTime' => $nowTs,
]);
} else {
Db::table('ck_kf_moments_settings')->insert([
'companyId' => $companyId,
'userId' => $userId,
'wechatId' => $wechatId,
'max' => 5,
'sendNum' => 1,
'createTime' => $nowTs,
'updateTime' => $nowTs,
]);
}
}
} catch (\Throwable $statE) {
Log::error('朋友圈发送统计失败: ' . $statE->getMessage());
}
// 4) 统计
$this->incrementSendStats($companyId, $userId, $allowed);
}
} catch (\Exception $e) {
Log::error("朋友圈同步任务异常: " . $e->getMessage());
@@ -202,6 +142,118 @@ class WorkbenchMomentsJob
}
}
protected function resetDailyCountersIfNeeded()
{
$now = time();
$todayStart = strtotime(date('Y-m-d 00:00:00'));
if ($now - $todayStart >= 0 && $now - $todayStart <= 600) {
$cacheKey = 'moments_settings_reset_' . date('Ymd');
if (!Cache::has($cacheKey)) {
Db::table('ck_kf_moments_settings')->where('sendNum', '<>', 0)
->update(['sendNum' => 0, 'updateTime' => $now]);
Cache::set($cacheKey, 1, 7200);
}
}
}
protected function getWindowTasks()
{
$nowTs = time();
$windowStart = $nowTs - 300;
$windowEnd = $nowTs + 300;
$kfMoments = KfMoments::where(['isSend' => 0, 'isDel' => 0])
->whereBetween('sendTime', [$windowStart, $windowEnd])
->order('id desc')->select();
return [$nowTs, $kfMoments];
}
protected function normalizeSendData(array $sendData)
{
$endTime = strtotime($sendData['endTime'] ?? '');
if ($endTime <= time() + 1800) {
$endTime = time() + 3600;
$sendData['endTime'] = date('Y-m-d H:i:s', $endTime);
}
switch ($sendData['momentContentType'] ?? 1) {
case 1:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
case 2:
$sendData['link'] = ['image' => ''];
$sendData['videoUrl'] = '';
break;
case 3:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
break;
case 4:
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
default:
$sendData['link'] = ['image' => ''];
$sendData['picUrlList'] = [];
$sendData['videoUrl'] = '';
break;
}
return $sendData;
}
protected function filterAccountsByQuota(int $companyId, int $userId, array $items)
{
$wechatIds = array_values(array_filter(array_map(function($it){ return (int)($it['wechatAccountId'] ?? 0); }, $items)));
if (empty($wechatIds)) { return []; }
$settings = Db::table('ck_kf_moments_settings')
->where('companyId', $companyId)
->where('userId', $userId)
->whereIn('wechatId', $wechatIds)
->column('id,max,sendNum', 'wechatId');
$allowed = [];
foreach ($items as $it) {
$wid = (int)($it['wechatAccountId'] ?? 0);
if ($wid <= 0) { continue; }
if (isset($settings[$wid])) {
$max = (int)$settings[$wid]['max'];
$sent = (int)$settings[$wid]['sendNum'];
if ($sent < ($max > 0 ? $max : 5)) { $allowed[] = $it; }
} else {
$allowed[] = $it;
}
}
return $allowed;
}
protected function incrementSendStats(int $companyId, int $userId, array $items)
{
try {
$nowTs = time();
foreach ($items as $it) {
$wechatId = (int)($it['wechatAccountId'] ?? 0);
if ($wechatId <= 0) { continue; }
$cond = ['companyId' => $companyId, 'userId' => $userId, 'wechatId' => $wechatId];
$setting = Db::table('ck_kf_moments_settings')->where($cond)->find();
if ($setting) {
Db::table('ck_kf_moments_settings')->where('id', $setting['id'])
->update(['sendNum' => Db::raw('sendNum + 1'), 'updateTime' => $nowTs]);
} else {
Db::table('ck_kf_moments_settings')->insert([
'companyId' => $companyId,
'userId' => $userId,
'wechatId' => $wechatId,
'max' => 5,
'sendNum' => 1,
'createTime' => $nowTs,
'updateTime' => $nowTs,
]);
}
}
} catch (\Throwable $e) {
Log::error('朋友圈发送统计失败: ' . $e->getMessage());
}
}
/**
* 处理内容发送

View File

@@ -157,7 +157,7 @@ class Adapter implements WeChatServiceInterface
{
$task = Db::name('customer_acquisition_task')
->where(['status' => 1, 'deleteTime' => 0])
->whereRaw("id % $process_count_for_status_0 = {$current_worker_id}")
/* ->whereRaw("id % $process_count_for_status_0 = {$current_worker_id}")*/
->order('id desc')
->select();