每天定时执行命令,在命令中同步一张表中的某个字段值的汇总至另一张表中
1、现在场景如下,在一张表中,有一个付款方式的字段,现在有需要,将付款方式定时汇总至另一张表中。为了防止每次定时执行时,重复查询之前的记录,所以需要记录一个上次的执行时间。
2、决定先查询出所有的不重复的付款方式,如果存在上次的执行时间,则加入条件,记录的创建时间小于等于上次的执行时间。
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$startTime = time();
$this->line('同步付款方式到选项');
$now = Carbon::now();
// 上一次的执行时间
// $lastTime = Carbon::now();
$builder = Model::query()
->select('payment_type')
->where('table.created_at_gmt', '<', $now)
->distinct();
if (!empty($lastTime)) {
$builder->where('table.created_at_gmt', '>=', $now);
}
$paymentTypes = $builder->pluck('payment_type')->filter()->unique()->toArray();
print_r($paymentTypes);exit;
$endTime = time();
Log::info("同步付款方式到选项; time:" . Carbon::now('GMT+8')->toDateTimeString() . ' 耗时:' . $endTime - $startTime . '秒');
$this->line('同步完成' . ' 耗时:' . $endTime - $startTime . '秒');
return Command::SUCCESS;
}
3、查看生成的 SQL
select distinct `payment_type` from `table` where `table`.`created_at_gmt` < '2024-09-12 02:56:29'
4、打印出 $paymentTypes,结果符合预期。
Array
(
[1] => PP
[2] => credit
[3] => payssion
[4] => 网上支付
[5] => 1
[6] => 21
[7] => paypal_cluster_rest
[8] => asiabill
[9] => nspayment_local
[10] => worldpay
[11] => paypal_rest
[12] => srpay
[13] => nspayment
[14] => 1000
[15] => worldpay_googlepay
)
5、先尝试设置当前时间为 6 个月前,最终代码实现如下
private string $cachedLastTimeKey = 'table:sync-payment-type-to-option:last_time';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$startTime = time();
$this->line('同步付款方式到选项');
$now = Carbon::now()->subMonths(3);
$optionRepository = app(IOptionRepository::class);
$title = 'payment_types';
// 选项中的付款方式
$optionPaymentType = $optionRepository->fetchBy(['title' => $title]);
// 上一次的执行时间
$lastTime = Cache::store('redis')->get($this->cachedLastTimeKey);
$builder = Model::query()
->select('payment_type')
->where('table.created_at_gmt', '<', $now)
->distinct();
if (isset($lastTime)) {
$builder->where('table.created_at_gmt', '>=', $lastTime);
}
$paymentTypes = $builder->pluck('payment_type')->filter()->unique()->values()->all();
if (!empty($optionPaymentType)) {
// 获取两个数组的并集
$optionPaymentTypes = array_values(array_unique(array_merge($optionPaymentType->value, $paymentTypes)));
} else {
$optionPaymentTypes = $paymentTypes;
}
$optionRepository->updateOrCreateOptionBy(['title' => $title], ['value' => $optionPaymentTypes]);
Cache::store('redis')->put($this->cachedLastTimeKey, $now->toDateTimeString());
$endTime = time();
Log::info("同步付款方式到选项; time:" . Carbon::now('GMT+8')->toDateTimeString() . ' 耗时:' . $endTime - $startTime . '秒');
$this->line('同步完成' . ' 耗时:' . $endTime - $startTime . '秒');
return Command::SUCCESS;
}
第1次执行同步命令:
select
*
from
`options`
where
`title` = 'payment_types'
limit
1;
select
distinct `payment_type`
from
`table`
where
`table`.`created_at_gmt` < '2024-03-12 05:59:02';
select
*
from
`options`
where
`title` = 'payment_types'
limit
1;
insert into
`options` (`title`, `value`)
values
(
'payment_type',
'[\"PP\",\"credit\",\"payssion\",\"\u7f51\u4e0a\u652f\u4ed8\",\"1\",\"21\",\"paypal_cluster_rest\",\"asiabill\",\"nspayment_local\",\"worldpay\",\"paypal_rest\",\"srpay\",\"nspayment\",\"1000\",\"worldpay_googlepay\"]'
);
6、再尝试设置当前时间为 3 个月前,第2次执行同步命令,执行的 SQL 如下。符合预期。
$now = Carbon::now()->subMonths(3);
select * from `options` where `title` = 'payment_types' limit 1; select distinct `payment_type` from `table` where `table`.`created_at_gmt` < '2024-06-12 06:00:50' and `table`.`created_at_gmt` >= '2024-03-12 05:59:02'; select * from `options` where `title` = 'payment_types' limit 1; update `options` set `value` = '[\"PP\",\"credit\",\"payssion\",\"\u7f51\u4e0a\u652f\u4ed8\",\"1\",\"21\",\"paypal_cluster_rest\",\"asiabill\",\"nspayment_local\",\"worldpay\",\"paypal_rest\",\"srpay\",\"nspayment\",\"1000\",\"worldpay_googlepay\"]' where `id` = 75;
6、再尝试设置当前时间为现在,第3次执行同步命令,执行的 SQL 如下。符合预期。如图1
$now = Carbon::now();
select * from `options` where `title` = 'payment_types' limit 1; select distinct `payment_type` from `table` where `table`.`created_at_gmt` < '2024-09-12 06:04:35' and `table`.`created_at_gmt` >= '2024-06-12 06:00:50'; select * from `options` where `title` = 'payment_types' limit 1; update `options` set `value` = '[\"PP\",\"credit\",\"payssion\",\"\u7f51\u4e0a\u652f\u4ed8\",\"1\",\"21\",\"paypal_cluster_rest\",\"asiabill\",\"nspayment_local\",\"worldpay\",\"paypal_rest\",\"srpay\",\"nspayment\",\"1000\",\"worldpay_googlepay\",\"paypal\",\"stripe\"]' where `id` = 75;

近期评论