答: 在生成控制器的时候, 自定义控制器名填入例如 pim/admin,这样就是2级了.
生成的菜单样式如下
答: 我们在网页上面的时候, 用 在线命令管理, 里面有一个删除模式,但是显示失败, 是因为, 页面上,无法输入 yes. 需要在 本地命令行中,输入命令.
我们先进入 项目文件夹所在的目录,然后运行上面红色框中的内容
参考文档:
https://www.bootstrap-table.com.cn/doc/api/column-options/ (中文)
https://bootstrap-table.com/docs/getting-started/introduction/ (英文)
例如要修改,列中的文字对齐. ,如下, 用这个属性即可.
在 public/assets/js/backend/pim/schedule.js中, 修改如下,即为 左对齐. (默认是居中.)
{field: 'title', title: __('Title'), align:'left'},还可以用如下方式实现 左对齐(较麻烦,但是在特定的场景下,比较好用), cellStyle 具体参数看上面文档介绍.
{field: 'title', title: __('Title'), cellStyle: function (value, row, index, field) { return {css: {"text-align" : "left!important"}}; } },需求: 原来是附件的样式,很长,如下.
要修改成,如果 有附件,就显示下载,然后点击之后是下载的样式. 这里用到 bootstraptable 中的 formatter,如下
{field: 'attachfile', title: __('Attachfile'), formatter: function (value, row, index, field) { if(value){ return `<a href="${value}">下载</a>`; }else{ return ""; } } },页面显示效果如下(如果没有数据,则不显示):
formatter 参数如下: (比较常用,可以根据数据库中数据来自己定义显示的样式)
formatter 中,上下各2行是标准的写法,中间是 操作的代码.
html 和 js中使用, __('Defaultnulltime') 即可. 不同地方要使用同一个变量内容,可以用 __('Defaultnulltime') 来代替.
如下,这里的 classname 中有 btn-ajax表示是ajax请求. start 和 finish是2个按钮.分别对应方法 pim/schedule下面的start和finish.formatter中的代码,是操作2个按钮的显示. 根据status这个值来区别.
文档: https://ask.fastadmin.net/article/323.html
{ field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, buttons: [ { name: 'start', text: '', classname: 'btn btn-xs btn-info btn-ajax btn-restoreit', icon: 'fa fa-play', url: 'pim/schedule/start', confirm: '是否开始?', refresh: true }, { name: 'finish', text: '', classname: 'btn btn-xs btn-danger btn-ajax btn-restoreit', icon: 'fa fa-stop', url: 'pim/schedule/finish', confirm: '是否结束?', refresh: true } ], formatter: function (value, row, index) { var that = $.extend({}, this); var table = $(that.table).clone(true); //隐藏操作按钮 $(table).data("operate-edit", null); //隐藏删除按钮 $(table).data("operate-del", null); //自定义了2个按钮的显示和隐藏 if (row.status == 0) { $(table).data("operate-finish", null); } else if (row.status == 1) { $(table).data("operate-start", null); }else if(row.status == 2){ $(table).data("operate-start", null); $(table).data("operate-finish", null); } that.table = table; return Table.api.formatter.operate.call(that, value, row, index); } },pim/schedule 中控制器的代码. (这个代码未完善,但是流程值得学习.),
如下,上面需要 加 注释,这个就是后面的权限. (新增之后,需要fastadmin后台,生成菜单,重新生成之后,就可以赋给角色权限了)
/** * 开始事务 */ public function start($ids = null) { // step.I 从数据库里面取得该条数据 $row = $this->model->get($ids); if (!$row) { $this->error(__('No results were found')); } // step.II 数据操作权限 $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { if (!in_array($row[$this->dataLimitField], $adminIds)) { $this->error(__('You have no permission')); } } // step.III 更新数据库 if ($this->request->isPost()) { $row->status = 1; $row->stime = date('Y-m-d H:i:00'); $row->save(); } // step.IV 返回处理结果 $rst = array( 'code' => 1, 'msg' => '事务成功开始', 'data' => $row, 'url' => '.', 'wait' => 3 ); return json($rst); }如上,还没有结束,因为这些都是有权限的,我们在 view中,还需要加入权限判断.
在 application/admin/view/pim/schedule/index.html 中,加入如下2行代码, 则无权限的,2个按钮是不会显示的.
需求,数据库中,有一个开始时间和结束时间,根据这2个时间计算出 消耗时间.(只在后台显示,数据库中不存储)
{ field: 'costhours', title: `${__('Costhours')}(${__('Unit')})` , formatter: function (value, row, index) { //如果还没有结束 if(row.status < 2){ return '未设定'; }else{ let etime = new Date(row.etime.toString()); let stime = new Date(row.stime.toString()); if( (etime - stime) < 0){ return `${__('stime')}或${__('etime')}错误`; }else{ return ((etime - stime) / (1000 * 60 * 60)).toFixed(1); } } } },如上,利用 formatter, 可以实现需求.
PS: 在 es6 中的模板字符串中, 使用 tp5的 变量,用 ${__('xxxx')} 这样的写法即可.
主要原因是,控制器中首页已经筛选了,可以显示的字段,在 applicaition/admin/controller 下对应的控制器中 加入刚刚新增的字段, deadline
foreach ($list as $row) { $row->visible(['id', 'admin_id', 'stime', 'deadline', 'etime', 'title', 'attachfile', 'status', 'weigh']); }此时,加入上述代码之后,就可以查看到数据了
fastadmin 自带的 formatter 地址在: public/assets/js/require-table.js 中.
复制一个原来的datetime,改名dateonly
dateonly: function (value, row, index) { var datetimeFormat = typeof this.datetimeFormat === 'undefined' ? 'YYYY-MM-DD' : this.datetimeFormat; if (isNaN(value)) { return value ? Moment(value).format(datetimeFormat) : __('None'); } else { return value ? Moment(parseInt(value) * 1000).format(datetimeFormat) : __('None'); } },然后在 我们的js中,使用这个formatter
{field: 'deadline', title: __('DeadLine'), align: 'center', formatter: Table.api.formatter.dateonly},在 编辑 中, view下,加入代码
<div class="form-group"> <label class="control-label col-xs-12 col-sm-2">{:__('Deadline')}:</label> <div class="col-xs-12 col-sm-8"> <input id="c-deadline" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-use-current="true" name="row[deadline]" type="text" value="{:$row.deadline?datetime($row.deadline):''}"> </div> </div>如上,会有一个问题, deadline默认是为null的,但是如果添加中不填入的话,还是会报错的. 此时,应该在 model层中, 加入一个方法,如下
public function setDeadlineAttr($value) { if ($value == '' || !isset($value)) { // 如果画面截止为空,则插入null return null; } else { // 如果不为空,原值插入 return $value; } }
如上操作,一个字段就加入完毕.