Skip to content

Laravel-admin实现时间戳和自定义日期的自动转换

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」。

我们管理后台是使用的laravel-admin快速搭建出来的,官方说法是: 在十分钟内构建一个功能齐全的管理后台

今天介绍我在使用laravel-admin遇到的坑,我数据库存储的时间是int类型的时间戳,需要在管理后台展示日期

怎么优雅的实现呢?

下面是我的实现流程,使用了laravel7+的新特性:cast。

基于cast实现了类型的自动转换。

需求分析

我们需要开发活动管理,活动有开始时间和结束时间,数据库对时间统一使用int时间戳进行处理。

但是管理后台需要展示给管理员“年月日-时分秒”这类数据。

考虑到后续模块还会有这种需求,为了提高程序复用性,我不打算每个模块都CV代码,调研如何进行封装抽取,来实现类型的自动转化。

cast就是比较好的选择

下面开始上代码

代码实现

自定义基类model:

我定义了CustomModel作为我的基类model,各模块的model层都会继承CustomModel

定义castAttribute方法,所有需要类型转换的方法都会执行到这里

自定义属性custom_date,返回return date('Y-m-d', intval($value));

当我需要返回指定格式的日期时,我就在对应的model,设置属性为custom_date就可以了。

php
<?php namespace App\Model; use App\Library\Utility; use Illuminate\Database\Eloquent\Model; class CustomModel extends Model {     .     .     .     protected function castAttribute($key, $value)     {         switch ($this->getCastType($key)) {             case 'int':             case 'integer':                 return (int)$value;             case 'real':             case 'float':             case 'double':                 return $this->fromFloat($value);             case 'decimal':                 return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]);             case 'string':                 return (string)$value;             case 'bool':             case 'boolean':                 return (bool)$value;             case 'object':                 return $this->fromJson($value, true);             case 'array':             case 'json':                 return $this->fromJson($value);             case 'collection':                 return new BaseCollection($this->fromJson($value));             case 'date':                 return $this->asDate($value);             case 'datetime':             case 'custom_datetime':                 return $this->asDateTime($value);             case 'timestamp':                 return $this->asTimestamp($value);             case 'geom':                 return Utility::decodePoint($value);             case 'carray':                 return empty($value) ? [] : $this->fromJson($value);             case 'not_empty':                 return empty($value) ? '[为空]' : $value;                 //定义自己的date格式             case 'custom_date':                 return date('Y-m-d', intval($value));             default:                 return $value;         }     } }

我们接着往下看

模块model层

需要使用时间戳转日期的model 设置$casts

注意:只有在model中设置了$casts,才会执行上面CustomModel中定义的类型转化函数castAttribute

特殊说明

下面的setStartTimeAttribute和int时间戳自动转成日期进行展示没有关系。

setStartTimeAttribute的作用是:保存时输入的日期字符串自动转成时间戳。

这样我们就智能的实现了时间戳和日期字符转的自动转换。

php
<?php namespace App\Model\House; class HouseGroupInfo extends CustomModel {     protected $table = 'xxxx';     protected $primaryKey = 'id';     protected $connection = 'xxxx';     protected $keyType = 'int';     public $incrementing = true;     protected $casts = [         'endTime'   => 'custom_date',         'startTime' => 'custom_date'     ];          //设置setXXXAttribute方法,查看源码得知的,作用是:保存时输入的日期字符串转时间戳。     public function setStartTimeAttribute($value)     {         $this->attributes['startTime'] = strtotime($value);     }          public function setEndTimeAttribute($value)     {         $this->attributes['endTime'] = strtotime($value);     } }

Controller层

php
<?php namespace App\Admin\Controllers; . . . class HouseGroupController extends AdminController {     /**      * Title for current resource.      *      * @var string      */     protected $title = 'myTitle';     /**      * Make a grid builder.      *      * @return Grid      */     protected function grid()     {         $grid = new Grid(new HouseGroupInfo());         $grid->model()->orderBy('id', 'desc');         .         .         .         $grid->column('startTime', '开始日期');         $grid->column('endTime', '结束日期');         $grid->column('createtime', '创建时间')->formatTimestamp();         $grid->actions(function ($actions) {             // 去掉删除             $actions->disableDelete();         });         return $grid;     }     /**      * Make a show builder.      *      * @param mixed $id      * @return Show      */     protected function detail($id)     {         $show = new Show(HouseGroupInfo::findOrFail($id));         return $show;     }     /**      * Make a form builder.      *      * @return Form      */     protected function form()     {         $form = new Form(new HouseGroupInfo());                  $form->date('startTime', '活动开始日期')->format('YYYY-MM-DD')->width(200);         $form->date('endTime', '活动结束日期')->format('YYYY-MM-DD')->width(200);         $form->text('code', '邀请码')->rules("required|max:50");         $form->saving(function (Form $form) {             //保存前的操作 钩子函数             if ($form->code) {                          }         });         //保存后的操作:钩子函数         $form->saved(function (Form $form) {                  });         return $form;     } }

小坑分享

注意:下面截图的set方式是设置值,xxx = yyy;

而不是return出去值,只有get方法才是return。

image.png

总结

这样我们就实现了基于Laravel的cast特性,实现了时间戳和自定义日期的自动转换。

🚀 学习遇到瓶颈?想进大厂?

看完这篇技术文章,如果还是觉得不够系统,或者想在实战中快速提升?
王中阳的就业陪跑训练营,提供定制化学习路线 + 企业级实战项目 + 简历优化 + 模拟面试。

了解训练营详情