[fastadmin] 第四十篇 FastAdmin 日期字段为空导致数据库 datetime 格式错误问题 解决 给默认null

解决 ThinkPHP FastAdmin 日期字段为空导致数据库 datetime 格式错误问题

问题背景 🔍

在使用 FastAdmin(基于 ThinkPHP)开发过程中,遇到一个日期处理的问题:当用户不选择日期时,前端传入空值到数据库的 datetime 字段,导致报错:

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '' for column 'referenc_release_date' at row 1

问题分析 📊

数据库结构

`referenc_release_date` datetime DEFAULT NULL COMMENT '发布日期'

FastAdmin 模板代码

<div class="border-content-flex-style">
    <div class="form-group form-group-flex-style">
        <label class="control-label control-label-flex-style">发布日期:</label>
        <div class="form-ipt-style">
            <input id="c-referenc_release_date" class="form-control datetimepicker"
                name="row[referenc_release_date]" type="text" value="{$row.referenc_release_date|htmlentities}" >
        </div>
    </div>
    <div class="form-group form-group-flex-style-second">
        <label class="control-label control-label-flex-style">启用日期:</label>
        <div class="form-ipt-style">
            <input id="c-referenc_start_date" class="form-control datetimepicker"
                name="row[referenc_start_date]" type="text" value="{$row.referenc_start_date|htmlentities}" >
        </div>
    </div>
</div>

问题原因

  1. 数据库字段允许为 NULL,但不接受空字符串
  2. FastAdmin 表单未选择日期时,传入了空字符串
  3. 后端没有对空值进行适当处理

解决方案 💡

1. 控制器处理

// 在控制器中处理空值
public function edit($ids = null)
{
    $row = $this->model->get($ids);
    if ($this->request->isPost()) {
        $params = $this->request->post("row/a");

        // 处理日期字段
        $params['referenc_release_date'] = empty($params['referenc_release_date']) ? null : $params['referenc_release_date'];
        $params['referenc_start_date'] = empty($params['referenc_start_date']) ? null : $params['referenc_start_date'];

        // 其他处理逻辑...
    }
    // ...
}

2. 模板优化

<!-- 使用 ThinkPHP 的默认值处理 -->
<input id="c-referenc_release_date" 
       class="form-control datetimepicker"
       name="row[referenc_release_date]" 
       type="text" 
       value="{$row.referenc_release_date|default=''}" >

<!-- 或者使用三元运算符 -->
<input id="c-referenc_start_date" 
       class="form-control datetimepicker"
       name="row[referenc_start_date]" 
       type="text" 
       value="{$row.referenc_start_date ? $row.referenc_start_date : ''}" >

3. FastAdmin 前端处理

// 初始化 datetimepicker
$(document).on("click", ".datetimepicker", function () {
    $(this).datetimepicker({
        format: 'YYYY-MM-DD HH:mm:ss',
        icons: {
            time: 'fa fa-clock-o',
            date: 'fa fa-calendar',
            up: 'fa fa-chevron-up',
            down: 'fa fa-chevron-down',
            previous: 'fa fa-chevron-left',
            next: 'fa fa-chevron-right',
            today: 'fa fa-history',
            clear: 'fa fa-trash',
            close: 'fa fa-remove'
        },
        showTodayButton: true,
        showClose: true
    });
});

// 表单提交前处理
Form.api.bindevent($("form[role=form]"), function(data, ret){
    // 处理日期空值
    $('.datetimepicker').each(function() {
        if (!$(this).val()) {
            $(this).val(null);
        }
    });
});

4. 模型处理(可选)

// 在模型中定义获取器和修改器
class YourModel extends Model
{
    protected $type = [
        'referenc_release_date' => 'datetime',
        'referenc_start_date'   => 'datetime'
    ];

    // 获取器
    public function getReferencReleaseDateAttr($value)
    {
        return $value ?: null;
    }

    // 修改器
    public function setReferencReleaseDateAttr($value)
    {
        return empty($value) ? null : $value;
    }
}

最佳实践建议 📝

  1. 使用 FastAdmin 的表单验证功能

    protected $rule = [
     'referenc_release_date' => 'date|nullable',
     'referenc_start_date'   => 'date|nullable'
    ];
  2. 在 common.js 中添加全局处理

    // public/assets/js/backend/common.js
    define(['jquery'], function ($) {
     var Frontend = {
         init: function () {
             // 统一处理日期控件
             $(document).on("click", ".datetimepicker", function () {
                 // 日期控件初始化代码
             });
         }
     };
     return Frontend;
    });
  3. 使用 FastAdmin 的数据库迁移功能确保字段定义正确

    // database/migrations/xxx_create_your_table.php
    public function up()
    {
     Schema::create('your_table', function (Blueprint $table) {
         $table->datetime('referenc_release_date')->nullable()->comment('发布日期');
         $table->datetime('referenc_start_date')->nullable()->comment('启用日期');
     });
    }

总结 ✨

通过以上方案,我们可以优雅地解决 FastAdmin 中日期字段为空的问题。关键点在于:

  1. 控制器中处理空值转换
  2. 前端表单提交时的数据处理
  3. 适当使用 FastAdmin 提供的功能
  4. 确保数据库字段定义正确

相关资源 📚

希望这篇文章对你有所帮助!如果有任何问题,欢迎在评论区讨论。 😊

感谢克劳德 3.7

本作品采用《CC 协议》,转载必须注明作者和本文链接
嗨,我是波波。曾经创业,有收获也有损失。我积累了丰富教学与编程经验,期待和你互动和进步! 公众号:上海PHP自学中心
wangchunbo
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
司机 @ 某医疗行业
文章
303
粉丝
348
喜欢
563
收藏
1125
排名:61
访问:12.5 万
私信
所有博文
社区赞助商