没有不值得去解决的问题,也没有不值得去学习的技术!

每天定时执行命令,在命令中同步一张表中的某个字段值的汇总至另一张表中

再尝试设置当前时间为现在,第3次执行同步命令,执行的 SQL 如下。符合预期
1、现在场景如下,在一张表中,有一个付款方式的字段,现在有需要,将付款方式定时汇总至另一张表中。为了防止每次定时执行时,重复查询之前的记录,所以需要记录一个上次的执行时间。 2、决定先查询出所有的不重复的付款方式,如果存在上次的执行时间,则加入条件,记录的创建时间小于等于上次的执行时间。
<pre class="wp-block-syntaxhighlighter-code">

    /**
     * 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;
    }

</pre>
3、查看生成的 SQL
<pre class="wp-block-syntaxhighlighter-code">

select
  distinct `payment_type`
from
  `table`
where
  `table`.`created_at_gmt` < '2024-09-12 02:56:29'

</pre>
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 个月前,最终代码实现如下
<pre class="wp-block-syntaxhighlighter-code">


    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;
    }

</pre>
第1次执行同步命令:
<pre class="wp-block-syntaxhighlighter-code">



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\"]'
  );

</pre>
6、再尝试设置当前时间为 3 个月前,第2次执行同步命令,执行的 SQL 如下。符合预期。


$now = Carbon::now()->subMonths(3);


<pre class="wp-block-syntaxhighlighter-code">

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;

</pre>
6、再尝试设置当前时间为现在,第3次执行同步命令,执行的 SQL 如下。符合预期。如图1
再尝试设置当前时间为现在,第3次执行同步命令,执行的 SQL 如下。符合预期
图1


$now = Carbon::now();


<pre class="wp-block-syntaxhighlighter-code">

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;

</pre>

PHP / Laravel / Yii2 老项目维护与长期技术支持

如果你的 PHP / Laravel / Yii2 项目已经上线,但遇到原开发离职、Bug 长期无人修复、接口不稳定、性能下降、代码难以接手等问题,可以联系我做一次远程技术排查。

适合以下情况:
✅ 老旧 PHP 系统无人维护
✅ Laravel / Yii2 项目 Bug 修复
✅ 后台管理系统小功能迭代
✅ RESTful API 接口排查
✅ MySQL / Redis / Nginx 性能问题
✅ 长期远程兼职维护

可先从一次小问题开始:
✅ 线上报错排查
✅ 接口异常分析
✅ 慢查询与性能瓶颈定位
✅ 代码结构初步评估
✅ 部署环境与日志检查

如需咨询,请联系我,并注明:PHP 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理