1. fast 按照生成的菜单都是一级的,如果想生成2级的,例如 集成管理/个人管理.
答: 在生成控制器的时候, 自定义控制器名填入例如 pim/admin,这样就是2级了.
生成的菜单样式如下
2. 删除模式如何用?
答: 我们在网页上面的时候, 用 在线命令管理, 里面有一个删除模式,但是显示失败, 是因为, 页面上,无法输入 yes. 需要在 本地命令行中,输入命令.
我们先进入 项目文件夹所在的目录,然后运行上面红色框中的内容
3. bootstraptable 中的属性修改
参考文档:
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"}};
}
},
4.自定义数据显示的样式
需求: 原来是附件的样式,很长,如下.
要修改成,如果 有附件,就显示下载,然后点击之后是下载的样式. 这里用到 bootstraptable 中的 formatter,如下
{field: 'attachfile', title: __('Attachfile'),
formatter: function (value, row, index, field) {
if(value){
return `<a href="${value}">下载</a>`;
}else{
return "";
}
}
},
页面显示效果如下(如果没有数据,则不显示):
formatter 参数如下: (比较常用,可以根据数据库中数据来自己定义显示的样式)
5. 删除 编辑按钮和删除按钮, 也是通过 formatter 来实现.
{field: 'operate', title: __('Operate'),
table: table,
events: Table.api.events.operate,
formatter: function (value, row, index, field){
var that = $.extend({}, this);
var table = $(that.table).clone(true);
//隐藏操作按钮
$(table).data("operate-edit", null);
//隐藏删除按钮
$(table).data("operate-del", null);
that.table = table;
return Table.api.formatter.operate.call(that, value, row, index);
}
},
formatter 中,上下各2行是标准的写法,中间是 操作的代码.
6. 合理利用 lang 下面的变量,可以更好的在html和js中,使用变量. 例如
html 和 js中使用, __('Defaultnulltime') 即可. 不同地方要使用同一个变量内容,可以用 __('Defaultnulltime') 来代替.
7. 新增2个按钮,而且发送ajax请求.根据数据的不同,2个按钮之间区别显示.
如下,这里的 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个按钮是不会显示的.
8. 生成自定义的一栏
需求,数据库中,有一个开始时间和结束时间,根据这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')} 这样的写法即可.
9. 在数据库中新增一个字段, 不用后台在线命令,该怎么操作?
1. 现在数据库中,加入这个字段,例如 deadline(timestamp)
2. 在public/assets/js/backend 下面的对应js中,加入如下
{field: 'deadline', title: __('Deadline'), align: 'center'}
3. 在 application/admin/lang/zh-cn/ 对应的语言包中,加入
'DeadLine' => '截止时间'
4. 此时,后台中,已经有显示了,但是没有数据.
主要原因是,控制器中首页已经筛选了,可以显示的字段,在 applicaition/admin/controller 下对应的控制器中 加入刚刚新增的字段, deadline
foreach ($list as $row) {
$row->visible(['id', 'admin_id', 'stime', 'deadline', 'etime', 'title', 'attachfile', 'status', 'weigh']);
}
此时,加入上述代码之后,就可以查看到数据了
5. 这里做一个优化, 只要日期,不要后面的时间. 我们可以直接在 js中,用formatter实现. 但是这里我们用 fastadmin 自带的formatter来改造一个.
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},
6. 之后在 添加中.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="">
</div>
</div>
在 编辑 中, 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;
}
}
如上操作,一个字段就加入完毕.