You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Lighthouse的GraphQL服务端Mutation Schema中设置当前时间戳?

好问题!在Laravel Lighthouse里,你没法直接在GraphQL Schema的默认参数里写current_timestamp这种数据库函数——因为Schema的默认值是在解析阶段处理的,不是直接传递给数据库执行的。不过有几种靠谱的方式能实现你要的服务端时间戳效果,我给你拆解下:

方法一:Field Middleware(推荐,复用性高)

这种方式适合需要在多个Mutation里复用“自动填充服务端时间”的场景,逻辑集中且易维护。

  1. 首先生成一个自定义中间件:
php artisan make:middleware SetCurrentTimestamp
  1. 修改中间件的处理逻辑,自动填充canceled_at参数:
<?php

namespace App\Http\Middleware;

use Closure;
use Carbon\Carbon;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class SetCurrentTimestamp
{
    public function handle($root, array $args, GraphQLContext $context, Closure $next)
    {
        // 如果客户端没传canceled_at,就用服务端当前时间填充
        if (!isset($args['canceled_at'])) {
            $args['canceled_at'] = Carbon::now();
        }

        return $next($root, $args, $context);
    }
}
  1. 在config/lighthouse.php的middleware数组里注册这个中间件:
'middleware' => [
    // ... 其他已注册的中间件
    'setCurrentTimestamp' => \App\Http\Middleware\SetCurrentTimestamp::class,
],
  1. 最后更新你的GraphQL Schema,给Mutation绑定这个中间件:
type Mutation {
  cancelOrder(id: ID!, canceled_at: DateTime): Order @update @middleware(name: "setCurrentTimestamp")
}

现在客户端调用cancelOrder时,可传可不传canceled_at:不传的话会自动用服务端时间,传了则优先使用传入的值,非常灵活。

方法二:自定义Resolver(适合复杂业务场景)

如果你的取消订单操作还有其他自定义逻辑(比如权限校验、状态校验),直接写自定义Resolver会更直观。

  1. 创建Resolver类:app/GraphQL/Mutations/CancelOrder.php
<?php

namespace App\GraphQL\Mutations;

use App\Models\Order;
use Carbon\Carbon;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class CancelOrder
{
    public function resolve($root, array $args, GraphQLContext $context)
    {
        $order = Order::findOrFail($args['id']);
        
        // 优先使用客户端传入的canceled_at,否则用服务端当前时间
        $order->canceled_at = $args['canceled_at'] ?? Carbon::now();
        $order->save();
        
        // 这里还可以加其他业务逻辑,比如发送取消通知、更新关联数据等
        return $order;
    }
}
  1. 更新Schema,指定使用这个自定义Resolver:
type Mutation {
  cancelOrder(id: ID!, canceled_at: DateTime): Order @field(resolver: "App\\GraphQL\\Mutations\\CancelOrder@resolve")
}

方法三:数据库层面默认值(最简单,适合无额外逻辑场景)

如果你的canceled_at字段只需要在取消时自动填充当前时间,也可以直接在数据库层面配置默认值:

  1. 修改Order模型的迁移文件,给canceled_at设置数据库默认值:
Schema::table('orders', function (Blueprint $table) {
    // MySQL用CURRENT_TIMESTAMP,PostgreSQL用CURRENT_TIMESTAMP或NOW()
    $table->timestamp('canceled_at')->nullable()->default(\DB::raw('CURRENT_TIMESTAMP'));
});
  1. 更新Schema,把canceled_at设为可选参数,@update指令会自动忽略未传入的字段,让数据库用默认值:
type Mutation {
  cancelOrder(id: ID!, canceled_at: DateTime): Order @update
}

⚠️ 注意:如果客户端传入null,会覆盖数据库的默认值,所以如果要防止这种情况,建议搭配模型的属性修改器或者上面的中间件方式使用。

内容的提问来源于stack exchange,提问作者Wald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:17:41