「这是我参与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
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
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
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。
总结
这样我们就实现了基于Laravel的cast特性,实现了时间戳和自定义日期的自动转换。