https://forum.fastadmin.net/thread/323

fa_admin”管理员表”
fa_admin_log”管理员日志表”
fa_attachment”附件表”
fa_auth_group”分组表”
fa_auth_group_access”权限分组表”
fa_auth_rule”节点表”
fa_category”分类表”
fa_config”系统配置”
fa_ems”邮箱验证码表”
fa_sms”短信验证码表”
fa_user”会员表”
fa_user_group”会员组表”
fa_user_money_log”会员余额变动表”
fa_user_rule”会员规则表”
fa_user_score_log”会员积分变动表”
fa_user_token”会员Token表”
fa_version”版本表”

post-body.bs.table

时间名称onPostBody jquery事件post-body.bs.table data 在表格体渲染完成,并在 DOM 中可见后触发

            //在表格内容渲染完成后回调的事件
            table.on('post-body.bs.table', function (e, json) {
                $("tbody tr[data-index]", this).each(function () {
                    if (parseInt($("td:eq(1)", this).text()) == Config.admin.id) {
                        $("input[type=checkbox]", this).prop("disabled", true);
                    }
                });
            });
 
$("input[type=checkbox]", this).prop("disabled", true);  禁用一个按钮
 
 
alert(JSON.stringify($.fn.bootstrapTable.defaults.extend));
{"index_url":"auth/admin/index","add_url":"auth/admin/add","edit_url":"auth/admin/edit","del_url":"auth/admin/del","import_url":"","multi_url":"auth/admin/multi","dragsort_url":"ajax/weigh"}
 
            Table.api.init({
                extend: {
                    index_url: 'auth/admin/index',
                    add_url: 'auth/admin/add2',
                    edit_url: 'auth/admin/edit',
                    del_url: 'auth/admin/del',
                    multi_url: 'auth/admin/multi',
                }
            });
 
 
 Table.api.init会覆盖$.fn.bootstrapTable.defaults.extend的内容
 
// 初始化表格  field为字段名
            table.bootstrapTable({
                url: $.fn.bootstrapTable.defaults.extend.index_url,
                columns: [
                    [
                        {field: 'state', checkbox: true, },  //复选框
                        {field: 'id', title: 'ID'},  //
                        {field: 'username', title: __('Username')},
                        {field: 'nickname', title: __('Nickname')},
                        {field: 'groups_text', title: __('Group'), operate:false, formatter: Table.api.formatter.label},
                        {field: 'email', title: __('Email')},
                        {field: 'status', title: __("Status"), formatter: Table.api.formatter.status},
                        {field: 'logintime', title: __('Login time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
                        {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
                                if(row.id == Config.admin.id){
                                    return '';
                                }
                                return Table.api.formatter.operate.call(this, value, row, index);
                            }}
                    ]
                ]
            });
{field: 'state', checkbox: true, }

FastAdmin封装了许多常用的formatter方法,我们可以快速的调用即可。

> `Table.api.formatter.icon` 快速将字段渲染成一个按钮,仅支持Fontawesome按钮
> `Table.api.formatter.image` 快速将字段渲染成图片展示的形式
> `Table.api.formatter.images` 快速将字段渲染成多图片展示的形式,字段数据请以`,`进行分隔
> `Table.api.formatter.status` 快速将字段渲染成状态,默认`normal/hidden/deleted/locked`这四个状态
> `Table.api.formatter.url` 快速将字段渲染成URL框
> `Table.api.formatter.search` 快速将字段渲染成可搜索的链接,点击后将执行搜索
> `Table.api.formatter.addtabs` 快速将字段渲染成可添加到选项卡的链接,点击后将把链接添加到选项卡
> `Table.api.formatter.flag` 快速将字段渲染成标志,仅支持`index/hot/recommend/new`这四种标志
> `Table.api.formatter.label` 快速将字段渲染Label标签
> `Table.api.formatter.datetime` 快速时间戳数据渲染成日期时间数据
> `Table.api.formatter.operate` 操作栏固定按钮
> `Table.api.formatter.buttons` 快速生成多个按钮
> `Table.api.formatter.toggle` 快速生成切换按钮

flag格式化

 
                        {field: 'platform', title: __('platform'),
                            formatter: Table.api.formatter.flag,
                            custom: { 'Mp': 'info', 'MpShop': 'success'},
                            searchList: {'Mp': '用户端', 'MpShop': '商家端'}
                        },

关联模型

data-source 请求的接口,数据源,可以根据data-params属性自定义请求参数
data-primary-key 列表选中后渲染的字段(value值)
data-field 列表显示读取的字段 option值

<input id="c-car_brand_id" data-rule="required" data-primary-key='Id' data-field="brandname" data-source="car/brand/index" class="form-control selectpage" name="row[car_brand_id]" type="text" value="{$row.car_brand_id}">
                $("#c-type_name").data("params", function (obj) {
                    return {custom: {classification_id:$('#c-type_id').val()}};
                });
            Controller.api.bindevent();
        add: function () {
 
            $("#c-category_id").data("params", function (obj) {
                    return {"custom": {"pid": $('#c-parent_category_id').val(), "type": "project_type"}}
                }
            );
            Controller.api.bindevent();
        },

更多参考:https://doc.fastadmin.net/docs/component.html

{:__(‘Car_brand_id’)} 在此控制器的语言配置文件中可以自定义

列表首页允许显示关联模型字段 在js文件columns中定义

            foreach ($list as $row) {
                $row->getRelation('brand')->visible(['brandname']);
            }

select单选框

<select id="c-type" data-rule="required" class="form-control selectpicker" name="row[type]">
     {foreach name="typeList" item="vo"}
      <option value="{$key}" {in name="key" value=""}selected{/in}>{$vo}</option>
      {/foreach}
</select>

select多选框 multiple=””

<select  id="c-flag" class="form-control selectpicker" multiple="" name="row[flag][]">
    {foreach name="flagList" item="vo"}
    <option value="{$key}" {in name="key" value=""}selected{/in}>{$vo}</option>
    {/foreach}
</select>

开发示例
省市区联动(通过AJAX读取数据)

<form id="cxselectform">
    <div class="form-inline" data-toggle="cxselect" data-selects="province,city,area">
        <select class="province form-control" name="province" data-url="ajax/area">
            <option value="1964" selected="">广东省</option>
        </select>
        <select class="city form-control" name="city" data-url="ajax/area">
            <option value="1988" selected="">深圳市</option>
        </select>
        <select class="area form-control" name="area" data-url="ajax/area">
            <option value="1991" selected="">南山区</option>
        </select>
    </div>
</form>

对应的js文件绑定

 Form.api.bindevent($("form#cxselectform"));

多表格示例
前端页面

<div class="panel panel-default panel-intro">
    <div class="panel-heading">
        <div class="panel-lead"><em>多表格(Multitable)</em>用于展示在一个页面展示多个表格数据,并且每次切换时刷新</div>
        <ul class="nav nav-tabs">
            <li class="active"><a href="#first" data-toggle="tab">表格1</a></li>
            <li><a href="#second" data-toggle="tab">表格2</a></li>
        </ul>
    </div>
    <div class="panel-body">
        <div id="myTabContent" class="tab-content">
            <div class="tab-pane fade active in" id="first">
                <div id="toolbar1" class="toolbar">
                    {:build_toolbar('refresh')}
                </div>
                <table id="table1" class="table table-striped table-bordered table-hover" width="100%">
                </table>
            </div>
            <div class="tab-pane fade" id="second">
                <div id="toolbar2" class="toolbar">
                    {:build_toolbar('refresh')}
                </div>
                <table id="table2" class="table table-striped table-bordered table-hover" width="100%">
                </table>
            </div>
        </div>
    </div>
</div>

对应js

define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
 
    var Controller = {
        index: function () {
            // 初始化表格参数配置
            Table.api.init();
            //绑定事件
            // shown.bs.tab为Bootstrap中Tab组件定义的事件
            // 该事件在标签页显示时触发,但是必须在某个标签页已经显示之后
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                var panel = $($(this).attr("href"));  //$('#first')或者$('#second')
                if (panel.size() > 0) {
                    Controller.table[panel.attr("id")].call(this);
                    $(this).on('click', function (e) {
                        $($(this).attr("href")).find(".btn-refresh").trigger("click");
                    });
                }
                //移除绑定的事件
                $(this).unbind('shown.bs.tab');
            });
 
            //必须默认触发shown.bs.tab事件
            $('ul.nav-tabs li.active a[data-toggle="tab"]').trigger("shown.bs.tab");
        },
        table: {
            first: function () {
                // 表格1
                var table1 = $("#table1");
                table1.bootstrapTable({
                    url: 'example/multitable/table1',
                    toolbar: '#toolbar1',
                    sortName: 'id',
                    search: false,
                    columns: [
                        [
                            {field: 'state', checkbox: true, },
                            {field: 'id', title: 'ID'},
                            {field: 'url', title: __('Url'), formatter: Table.api.formatter.url},
                            {field: 'imagewidth', title: __('Imagewidth')},
                            {field: 'imageheight', title: __('Imageheight')},
                            {field: 'mimetype', title: __('Mimetype')},
                            {field: 'operate', title: __('Operate'), table: table1, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
                        ]
                    ]
                });
 
                // 为表格1绑定事件
                Table.api.bindevent(table1);
            },
            second: function () {
                // 表格2
                var table2 = $("#table2");
                table2.bootstrapTable({
                    url: 'example/multitable/table2',
                    extend: {
                        index_url: '',
                        add_url: '',
                        edit_url: '',
                        del_url: '',
                        multi_url: '',
                        table: '',
                    },
                    toolbar: '#toolbar2',
                    sortName: 'id',
                    search: false,
                    columns: [
                        [
                            {field: 'id', title: 'ID'},
                            {field: 'title', title: __('Title')},
                            {field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
                            {field: 'ip', title: __('ip')},
                            {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
                        ]
                    ]
                });
 
                // 为表格2绑定事件
                Table.api.bindevent(table2);
            }
        },
        add: function () {
            Controller.api.bindevent();
        },
        edit: function () {
            Controller.api.bindevent();
        },
        api: {
            bindevent: function () {
                Form.api.bindevent($("form[role=form]"));
            },
        }
    };
    return Controller;
});

动态调整弹窗高度,在初始化表格后,添加如下代码即可:

            // 为表格绑定事件
            Table.api.bindevent(table);
 
            table.on('post-body.bs.table', function (e, settings, json, xhr) {
                $(".btn-editone").data("area", ["600px", "250px"]);
            });

后台添加或者编辑图片上传

    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Payment_code')}:</label>
        <div class="col-xs-12 col-sm-8">
            <div class="input-group">
                <input id="c-image" data-rule="required" class="form-control" size="50" name="row[payment_code]" type="text" value="{$row.payment_code}">
                <div class="input-group-addon no-border no-padding">
                    <span><button type="button" id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
                    <span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-input-id="c-image" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
                </div>
                <span class="msg-box n-right" for="c-image"></span>
            </div>
            <ul class="row list-inline plupload-preview" id="p-image"></ul>
        </div>
    </div>

编辑或者添加页状态
①模型赋值

   public function statusList(){
       return ['0' => __('未审核'),'1' => __('审核成功')];
   }

②控制器赋值

$this->assign('statusList',$this->model->statusList());

③html页面

    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
        <div class="col-xs-12 col-sm-8">
            <div class="radio">
                {foreach name="statusList" item="vo"}
                <label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="$row.status"}checked{/in} /> {$vo}</label>
                {/foreach}
            </div>
        </div>
    </div>

列表使用,出现获取不到ids情况 /index/multi/ids/undefined,修改require-table.js文件

                toggle: function (value, row, index) {
                    var options = $(table).bootstrapTable('getOptions'); // 1.新增这行
                    var color = typeof this.color !== 'undefined' ? this.color : 'success';
                    var yes = typeof this.yes !== 'undefined' ? this.yes : 1;
                    var no = typeof this.no !== 'undefined' ? this.no : 0;
                    var url = typeof this.url !== 'undefined' ? this.url : '';
                    var disable = false;
                    if (typeof this.disable !== "undefined") {
                        disable = typeof this.disable === "function" ? this.disable.call(this, value, row, index) : this.disable;
                    }
                    return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Click to toggle') + "' class='btn-change " + (disable ? 'btn disabled' : '') + "' data-id='"
                        + row[options.pk] + "' " + (url ? "data-url='" + url + "'" : "") + " data-params='" + this.field + "=" + (value == yes ? no : yes) + "'><i class='fa fa-toggle-on " + (value == yes ? 'text-' + color : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";  //  2.row.id替换为row[options.pk]
 
                },

未更新任何行,如下,修改控制器文件

{"code":0,"msg":"未更新任何行","data":"","url":"","wait":3}
    protected $multiFields = 'state';

致命错误: Call to a member function visible() on null

 
        //当前是否为关联查询
        $this->relationSearch = true;
 
 
            $list = $this->model
                    ->with(array('coursecategory'))
                    ->where($where)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();
 
            foreach ($list as $row) {
                $row->visible(['course_id','check_id','course_name','course_money','courate_image','courate_suo_image','course_amount','course_brief','createtime','updatetime','chu_state','state']);
                $row->visible(['coursecategory']);
                $row->getRelation('coursecategory')->visible(['category_name']);
            }
 
			模型中设置
			public function coursecategory()
			{
				return $this->belongsTo('CourseCategory', 'category_id', 'id', [], 'LEFT')->setEagerlyType(0);
			}

1.首先检查表名字是否存在
2.检查字段是否存在
3.with关联,模型中定义的方法必须小写或者下划线

使用thinkphp的软删除功能
1.模型中引入 use traits\model\SoftDelete; 类
2.模型类中使用
use SoftDelete;
protected $deleteTime = ‘delete_time’;
3.创建软删除字段

上传文件限制设置
①设置文件/application/extra/upload.php

     * 可上传的文件类型
     */
    'mimetype'  => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx,doc,docx,pdf'

②设置页面中控件

 <span><button type="button" id="plupload-file" class="btn btn-danger plupload" data-input-id="c-file" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,application/pdf" data-multiple="false" data-preview-id="p-file"><i class="fa fa-upload"></i> 上传</button></span>

③自定义控件的回调方法

        jxupload:function(){   // 绩效文件上传
 
            Controller.api.bindevent();
 
            $('#plupload-file').data('upload-success',function(data){
                console.log(data)
                console.log(data.file_name)
                $('#file_before_name').val(data.file_name)
            })
 
 
        },

行为
fastadmin\application\index\controller\User.php

class User extends Frontend
{
 
    public function _initialize()
    {
        parent::_initialize();
        $auth = $this->auth;
 
        if (!Config::get('fastadmin.usercenter')) {
            $this->error(__('User center already closed'));
        }
 
        $ucenter = get_addon_info('ucenter');
        if ($ucenter && $ucenter['state']) {
            include ADDON_PATH . 'ucenter' . DS . 'uc.php';
        }
 
        //监听注册登录注销的事件
        Hook::add('user_login_successed', function ($user) use ($auth) {
            $expire = input('post.keeplogin') ? 30 * 86400 : 0;
            Cookie::set('uid', $user->id, $expire);
            Cookie::set('token', $auth->getToken(), $expire);
        });
        Hook::add('user_register_successed', function ($user) use ($auth) {
            Cookie::set('uid', $user->id);
            Cookie::set('token', $auth->getToken());
        });
        Hook::add('user_delete_successed', function ($user) use ($auth) {
            Cookie::delete('uid');
            Cookie::delete('token');
        });
        Hook::add('user_logout_successed', function ($user) use ($auth) {
            Cookie::delete('uid');
            Cookie::delete('token');
        });
    }

fastadmin\application\common\library\Auth.php

    /**
     * 注册用户
     *
     * @param string $username  用户名
     * @param string $password  密码
     * @param string $email     邮箱
     * @param string $mobile    手机号
     * @param array $extend    扩展参数
     * @return boolean
     */
    public function register($username, $password, $email = '', $mobile = '', $extend = [])
    {
        // 检测用户名或邮箱、手机号是否存在
        if (User::getByUsername($username))
        {
            $this->setError('Username already exist');
            return FALSE;
        }
        if ($email && User::getByEmail($email))
        {
            $this->setError('Email already exist');
            return FALSE;
        }
        if ($mobile && User::getByMobile($mobile))
        {
            $this->setError('Mobile already exist');
            return FALSE;
        }
 
        $ip = request()->ip();
        $time = time();
 
        $data = [
            'username' => $username,
            'password' => $password,
            'email'    => $email,
            'mobile'   => $mobile,
            'level'    => 1,
            'score'    => 0,
            'avatar'   => '',
        ];
        $params = array_merge($data, [
            'nickname'  => $username,
            'salt'      => Random::alnum(),
            'jointime'  => $time,
            'joinip'    => $ip,
            'logintime' => $time,
            'loginip'   => $ip,
            'prevtime'  => $time,
            'status'    => 'normal'
        ]);
        $params['password'] = $this->getEncryptPassword($password, $params['salt']);
        $params = array_merge($params, $extend);
 
        ////////////////同步到Ucenter////////////////
        if (defined('UC_STATUS') && UC_STATUS)
        {
            $uc = new \addons\ucenter\library\client\Client();
            $user_id = $uc->uc_user_register($username, $password, $email);
            // 如果小于0则说明发生错误
            if ($user_id <= 0)
            {
                $this->setError($user_id > -4 ? 'Username is incorrect' : 'Email is incorrect');
                return FALSE;
            }
            else
            {
                $params['id'] = $user_id;
            }
        }
 
        //账号注册时需要开启事务,避免出现垃圾数据
        Db::startTrans();
        try
        {
            $user = User::create($params);
            Db::commit();
 
            // 此时的Model中只包含部分数据
            $this->_user = User::get($user->id);
 
            //设置Token
            $this->_token = Random::uuid();
            Token::set($this->_token, $user->id, $this->keeptime);
 
            //注册成功的事件
            Hook::listen("user_register_successed", $this->_user);
 
            return TRUE;
        }
        catch (Exception $e)
        {
            $this->setError($e->getMessage());
            Db::rollback();
            return FALSE;
        }
    }

重新刷新列表

table.bootstrapTable('refresh');

js文件接收控制器参数
控制器文件

        $this->assignconfig('card_id',$cardId);

js文件

		add_url: 'card_attr/add?card_id='+Config.card_id

固定列table.bootstrapTable配置如下

                //启用固定列
                fixedColumns: true,
                //固定右侧列数
                fixedRightNumber: 1,
                //固定左侧列数
                fixedNumber:3,

bower安装layui

npm install -g bower
 
bower help
 
bower install layui

\assets\js\require-backend.js配置
paths配置

        'layui': '../libs/layui/dist/layui',
 
 // shim依赖配置
        'layui': {
            deps: ['css!../libs/layui/dist/css/layui.css'],
            exports: "layui"
        }

使用

define(['jquery', 'bootstrap', 'backend', 'table', 'form','layui'], function ($, undefined, Backend, Table, Form,layui){})
 
生产模式下打包静态文件
//一键压缩打包后台的JS和CSS
php think min -m backend -r all

https://doc.fastadmin.net/doc/162.html

使用腾讯地图
addon.js引入

define([], function () {
    require.config({
    paths: {
        'async': '../addons/example/js/async',
        'BMap': ['//api.map.baidu.com/api?v=2.0&ak=mXijumfojHnAaN2VxpBGoqHM'],
        'TMap': ['//map.qq.com/api/gljs?v=1.exp&key=YUBBZ-752KR-2M3WC-W52Q2-L5FPS-CFB6D'],
    },
    shim: {
        'BMap': {
            deps: ['jquery'],
            exports: 'BMap'
        },
        'BMap': {
            exports: 'TMap'
        }
    }
});

对应js使用

            require(['TMap'], function () {
                //定义地图中心点坐标
                var center = new TMap.LatLng(35.42492, 116.572507)
            });

发表评论

邮箱地址不会被公开。 必填项已用*标注