Fastadmin记录


前言

最近的一个项目后台要处理的东西比较多,正好整理在这里方便以后使用


一、JS方面的处理

在后台处理编辑删除 还需要设置其他按钮 来进行操作
文档链接 ------》 传送门 《---------
见文档中 15.自定义按钮

自定义按钮

  1. 发送ajax
{
    name: 'ajax',
     title: __('冻结'),
     text: __('冻结'),
     classname: 'btn btn-xs btn-danger btn-ajax',
     icon: 'fa fa-minus-circle',
     confirm: '确认冻结?',
     url: 'user/disable',
     success: function (data, ret) {
         Layer.alert(ret.msg);
         //成功之后刷新table
         table.bootstrapTable('refresh', {});
     },
     error: function (data, ret) {
         console.log(data, ret);
         Layer.alert(ret.msg);
         return false;
     },
     hidden:function (row) {
         if (row.status == '-1'){
             return true;
         }
     }
 },
  1. 弹窗打开
{
   name: 'detail',
    title: __('查看'),
    text: __('查看'),
    classname: 'btn btn-xs btn-primary btn-dialog',
    icon: 'fa fa-list',
    url: 'user/team_order',
    extend:'data-area=\'["90%;","80%"]\'',
    /*callback: function (data) {
        Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
    }*/
}

高级进阶(一)
自定义打开窗口内容 我这里需要的是一个可以输入金额的弹框

{
     name: 'no',
     title: __('修改余额'),
     text: __('修改余额'),
     classname: 'btn btn-xs btn-info btn-click',
     icon: 'fa fa-cny',

     click: function (data, row) {
     	//当点击的时候出发 appwhy 并携带参数 id
         appWhy(row.id);
     }
 },

appWhy 追加在js最后就可以

function appWhy(id) {
    var str = "<div  style='width:80%;margin-left:auto;margin-right:auto'>" +
        "<select class=\"form-control\" name=\"type\" id=\"more-template-select\" style=\"width: 80px;margin-right:5px;\">\n" +
        "      <option value=\"+\" selected=\"\">增加</option>\n" +
        "      <option value=\"-\">减少</option>\n" +
        "</select>" +
        "<input type=\"text\" class=\"form-control\" style=\"display: block;margin-top: 20px;\" id=\"input-user_money\" name=\"user_money\" value=\"0\" placeholder=\"\" οnkeyup=\"if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\\D/g,'')}\" onafterpaste=\"if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{this.value=this.value.replace(/\\D/g,'')}\"></div>";

    var table = $("#table");

    var openPage = Layer.open({
        title: __('修改余额'), //页面标题
        content: str,
        area: ['400px', '230px'], //自定义文本域宽高
        btn: ['确定', '取消'],
        //到这里已经触发并弹框了
        yes: function (e, value) {
            var zj = $("#more-template-select").val();
            var money = $("#input-user_money").val();
            var user_id = id;
            //这里是我发送ajax 处理参数  可以根据 实际情况处理
            Fast.api.ajax({
                    url: 'user/handle_balance',
                    data: {zj: zj, money: money, user_id: id}
                }, function (data, ret) {
                    //成功的回调
                    Layer.close(openPage);
                    table.bootstrapTable('refresh', {});
                }, function (data, ret) {
                    //失败的回调
                    return false;
                }
            );

        }, btn2: function () {
            return 0;
        }
    })
}

高级进阶(二)
按钮携带参数打开其他页面 用途:如查看指定用户的订单

按钮代码
特别注意url参数

{
      name: 'detail',
      title: __('查看订单'),
      text: __('查看订单'),
      classname: 'btn btn-xs btn-primary btn-dialog',
      icon: 'fa fa-list',
      //注意一下这个url 为 订单的页面的index
      url: 'order/index',
      extend:'data-area=\'["90%;","80%"]\'',
      /*callback: function (data) {
          Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
      }*/
  },

在订单控制器要处理穿过来的参数 也就是ids 因为Fastadmin是先渲染的页面然后通过ajax获取的参数 如果直接修改where条件 ajax请求的时候 ids获取不到 所以要 先把ids渲染到页面 再ajax请求回来

控制器中的处理
$this->assignconfig('ids',$this->request->param("ids"));

 public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage,则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $wheres = [];
            if ($this->request->param("ids")!==NULL) {
                $wheres['user_id'] = $this->request->param("ids");
            }

            $list = $this->model
                    ->with(['auctiongoods','user'])
                    ->where($where)
                    ->where($wheres)
                    ->order($sort, $order)
                    ->paginate($limit);

            $money = 0;
            foreach ($list as $row) {
                $row->visible(['id', 'order_sn', 'pay_money', 'total_money', 'status', 'is_transfer', 'pay_type', 'pay_time', 'examine_time', 'pay_img', 'create_time']);
                $row->visible(['auctiongoods']);
                $row->getRelation('auctiongoods')->visible(['goods_name']);
                $row->visible(['user']);
                $row->getRelation('user')->visible(['nick_name']);
                $money += intval($row['total_money']*100);
            }

            $result = array("total" => $list->total(), "rows" => $list->items(), "extend" => ['money' =>$money/100]);

            return json($result);
        }

        $this->assignconfig('ids',$this->request->param("ids"));
        return $this->view->fetch();
    }

ids通过渲染之后 在js中需要在携带请求
在初始化表格的时候携带

 queryParams: function (params) {
      //自定义搜索条件
       var filter = params.filter ? JSON.parse(params.filter) : {}; //判断当前是否还有其他高级搜索栏的条件
       var op = params.op ? JSON.parse(params.op) : {};  //并将搜索过滤器 转为对象方便我们追加条件
       //注意要做一下判断 不然不带参数访问不到
       if(Config.ids){
           filter.user_id = Config.ids;     //将透传的参数 Config.ids,追加到搜索条件中
       }
       op.user_id = "=";  
       params.filter = JSON.stringify(filter); //将搜索过滤器和操作方法 都转为JSON字符串
       params.op = JSON.stringify(op);
       //如果希望忽略搜索栏搜索条件,可使用
       //params.filter = JSON.stringify({url: 'login'});
       //params.op = JSON.stringify({url: 'like'});
       return params;

   },

获取选中的ids

Table.api.selectedids($("#table"));

时间格式的转换

后台生成后 时间格式是:**YYYY-MM-DD HH:mm:ss** 但是有时候我们只需要 年-月-日就够了 **datetimeFormat** 声明了时间格式为年月日
{
    field: 'time',
    title: __('时间'),
    operate: 'RANGE',
    addclass: 'datetimerange',
    autocomplete: false,
    datetimeFormat: "YYYY-MM-DD",
    formatter: Table.api.formatter.datetime,
},

自定义搜索功能时间搜索格式更换


 {
     field: 'today_time',
     title: __('时间'),
     operate: 'RANGE',
     addclass: 'datetimerange',
     autocomplete: false,
     datetimeFormat: "YYYY-MM-DD",
     formatter: Table.api.formatter.datetime,
     data: 'data-date-format="YYYY-MM-DD"'
 },

js追加样式

cellStyle: 用于给列表追加样式
formatter:自定义返回渲染结果

{
                            field: 'data_text',
                            title: __('提交内容'),
                            operate: false,
                            cellStyle: function (value, row, index) {
                                return {css: {"width": "350px"}}
                            },
                            formatter: function (value,row,index) {
                               /* console.log(value)
                                console.log(row)*/
                                var str = '';
                                $.each(value,function(i,v){
                                    console.log(v);
                                    str += '<span class="label label-success">'+v.title+'</span>';
                                    str += '<span class="th-inner ">'+v.value+'</span>';
                                    str += '<br/>';
                                });
                                return str;
                            }
                        },

新增按钮操作

index.html 中新增 类似于 添加/编辑/删除的 按钮

HTML中

<a class="btn btn-info operation"  
	href="javascript:;"  
	title="{:__('批量操作')}"> 
	<i class="fa fa-list-alt"></i> {:__('批量操作')}
	</a>

JS文件中:

$(".operation").click(function () {
	//获取选中IDS
    let ids = Table.api.selectedids(table);
    ids = ids.join(',');
    if (ids == '') {
        layer.alert('请先选择批量操作人选');
        return;
    }
    let url = "personnel/operation?ids=" + ids;
    //打开新窗口
    Fast.api.open(url, "批量操作");
})

知识点:

  1. Fast.api.open(url, "批量操作"); // 打开新窗口
  2. Fast.api.addtabs("链接","标题"); //新页面打开

Table.api.selectedids(table);获取选中的ids
table.bootstrapTable('refresh', {}); 表单刷新

常用

  1. search: false //关闭快速搜索 默认只会搜索主键id这个字段 如果想搜索其他字段
    需要带控制器中 声明控制字段 protected $searchFields = 'id,name,title';
  2. showToggle: false // 关闭浏览模式
  3. showColumns: false //关闭 显示隐藏列
  4. searchFormVisible: true // 设置默认显示 通用搜索指表格上方的搜索
  5. commonSearch: false // 关闭 通用搜索功能
  6. showExport: false //关闭 导出
    导出控制指定方式
exportTypes:['json','xml','csv','txt','doc','excel'],

//分页
pagination: false,
//公共搜索
commonSearch: false,
//搜索栏
search: false,
固定列
fixedColumns:true,

文档链接

控制添加/编辑页面大小
在js中 初始化之前使用

    Fast.config.openArea = ['1000px','800px'];

后台控制编辑页面打开大小

在·var table = $("#table"); 下添加以下代码

			var table = $("#table");
            table.on('post-body.bs.table', function (e, settings, json, xhr) {
                $(".btn-editone,.btn-edit").data("area", ["70%", "80%"]);
            });

index.html 对应按钮添加 data-area=["70%","80%"]
完整代码

<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('shop/add')?'':'hide'}"  data-area=["70%","80%"] title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('shop/edit')?'':'hide'}"  data-area=["70%","80%"]  title="{:__('Edit')}"  ><i class="fa fa-pencil"></i> {:__('Edit')}</a>

通过jsTree 实现 树形结构

效果如下
在这里插入图片描述
在html中添加 注意id为treeview 的div

	<input type="hidden" name="row[rules]" value="" />

    <div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('可选车辆')}:</label>
        <div class="col-xs-12 col-sm-8">
            <span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><span>{:__('Check all')}</span></label></span>
            <span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><span>{:__('Expand all')}</span></label></span>

            <div id="treeview"></div>
        </div>
    </div>

js中代码

		$(document).ready(function(){
                $.ajax({
                    url: "shop/roletree",
                    type: 'post',
                    dataType: 'json',
                    data:{id:id},
                    success: function (ret) {
                        console.log(ret);
                        if (ret.hasOwnProperty("code")) {
                            var data = ret.hasOwnProperty("data") && ret.data != "" ? ret.data : "";
                            if (ret.code === 1) {
                                console.log(data);
                                //销毁已有的节点树
                                $( "#treeview" ).jstree(
                                    {
                                        core:
                                            {
                                                data: data,
                                                check_callback:  true ,  //是否允许动态增加删除节点
                                                expand_selected_onload:  true ,  //加载完成后是否展开所有选中的节点
                                                themes:
                                                    {
                                                        dots:  true ,  //是否显示连接线
                                                        icons:  true ,  //是否显示图标
                                                    }
                                            },
                                        plugins: [
                                            "checkbox"
                                        ],
                                        checkbox:
                                            {
                                                keep_selected_style:  true ,  //是否默认选中
                                                three_state:  true ,  //是否父子级别级联
                                                tie_selection:  true ,  //复选框是否与树的选择绑定
                                                whole_node:  true   //复选框是否与节点关联
                                            }
                                    }
                                );

                                /*$("#treeview").jstree("destroy");
                                Controller.api.rendertree(data);*/
                            } else {
                                Backend.api.toastr.error(ret.msg);
                            }
                        }
                    }, error: function (e) {
                        Backend.api.toastr.error(e.message);
                    }
                });
                $('#treeview').on('changed.jstree', function (e, data) {
                    var selectedNodes = data.selected;
                    // 获取选中的值
                    console.log(selectedNodes);
                    var selectedValues = [];
                    for (var i = 0; i < selectedNodes.length; i++) {
                        var node = data.instance.get_node(selectedNodes[i]);
                        selectedValues.push(node.id);
                    }
                    // 将选中的值插入隐藏的表单字段中
                    $("input[name='row[rules]']").val(selectedValues.join(','));
                });
            });

请求为获取数据 数据结构为
必须按照以下结构 文档链接
其中state 中 opened 为 是否默认打开这个节点
selected 为是否选中

[
    {
        "id": "0",
        "text": "根节点1",
        "state":{
            "opened":true,
            "selected":true,
        },
        "children": [
            {
                "id": "1",
                'text': 'child1111'
            },
            {
                "id": "3",
                'text': 'child2333'
            },
        ]
    },
    {
        "id": "2",
        "text": "根节点2",
        "children": [
            {
                "id": "4",
                'text': 'child1444'
            },
            {
                "id": "6",
                'text': 'child2666'
            },
        ]
    },
    
]

后台添加/编辑页面根据字段值显示隐藏字段

需求:当Type字段 值为3优惠券时 显示 关联优惠券 表单
add.html

<div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
        <div class="col-xs-12 col-sm-8">
           <!-- <input id="c-type" class="form-control" name="row[type]" type="number">-->
            {:Form::radios('row[type]', ['1'=>'实物', '2'=>'积分', '3'=>'优惠券', '4'=>'再接再厉'], '4', ['data-rule'=>'required'])}
        </div>
    </div>
    <div class="form-group coupon" style="display: none" >
        <label class="control-label col-xs-12 col-sm-2">{:__('关联优惠券')}:</label>
        <div class="col-xs-12 col-sm-8">
            <input id="c-relation_id" data-rule="required" data-source="coupon/index" data-field="title"   data-multiple="false" class="form-control selectpage" name="row[relation_id]" type="text" value="">
        </div>
    </div>

js

 add: function () {
            Controller.api.bindevent();

            $("input[name='row[type]']").change(function () {
                type = $("input[name='row[type]']:checked").val();
                console.log(type);
                if (type == 3){
                    $(".coupon").show();
                }else{
                    $(".coupon").hide();
                }

            })
        },
        
        edit: function () {
            Controller.api.bindevent();
            //编辑需要给初始化的时候 渲染一下参数  
            type = $("input[name='row[type]']:checked").val();
            if (type == 3){
                $(".coupon").show();
            }else{
                $(".coupon").hide();
            }
            $("input[name='row[type]']").change(function () {
                type = $("input[name='row[type]']:checked").val();
                if (type == 3){
                    $(".coupon").show();
                }else{
                    $(".coupon").hide();
                }

            })
        },

后台首页提示

 <div class="panel-heading">
        <div class="panel-lead">
            <em>注意事项:</em>
            中奖概率需要控制在100% 奖品总数必须大于4 诺为九宫格 奖品总数必须等于8
        </div>
    </div>

编辑页面 追加属性 foreach 下拉 默认选中

<%=row.type=="{$key}"?'selected':''%>

<div class="form-group row" id="data-form">
        <label class="control-label col-xs-12 col-sm-2">{:__('表单属性')}:</label>
        <div class="col-xs-12 col-sm-8">
            <dl class="fieldlist" data-template="eventtpl" data-name="row[data]">
                <dd>
                    <ins>{:__('标题')}</ins>
                    <ins>{:__('类型')}</ins>
                    <!--<ins>{:__('登录时间')}</ins>-->
                </dd>
                <dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
                <!--请注意 dd和textarea间不能存在其它任何元素,实际开发中textarea应该添加个hidden进行隐藏-->
                <textarea name="row[data]" class="form-control hidden" cols="30" rows="5">{$row.data|htmlentities}</textarea>
            </dl>
            <script id="eventtpl" type="text/html">
                <dd class="form-inline">

                    <ins>
                        <input type="text" name="<%=name%>[<%=index%>][title]" class="form-control" placeholder="输入标题" value="<%=row.title%>"/>
                    </ins>
                    <ins>
                        <select name="<%=name%>[<%=index%>][type]" style="width: 100px;" class="form-control selectpicker">
                            {foreach name="ruleList" item="vo"}
                            <option value="{$key}" <%=row.type=="{$key}"?'selected':''%> >
                                {$vo}
                            </option>
                            {/foreach}
                        </select>
                    </ins>
                    <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
                    <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
                </dd>
            </script>
        </div>
    </div>

控制器操作

api控制器验证规则

		$validate = new \think\Validate([
            'name|姓名'           => 'require',
            'image|形象照'         => 'require',
            'position|职位'       => 'require',
            'tel|电话'            => 'require',
            'company_name|公司名称' => 'require',
            'industry|所属行业'     => 'require',
        ]);
        if (!$validate->check($data))
            $this->error($validate->getError());

模型获取器修改返回时间格式

	public function getLogintimeTextAttr($value, $data)
    {
        $value = $value ? $value : ($data['logintime'] ?? "");
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

微信操作

获取openid
引入use EasyWeChat\Factory;

//获取用户openid
    public function getCode(){
        $code = $this->request->post('code');
        $config = [
            'app_id' => 'wx123333321112',
            'secret' => '11bbbbbbsdjjwwiollll',
            // 下面为可选项
            // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];
        $app = Factory::miniProgram($config);
        $res = $app->auth->session($code);
        //halt($res);
        $this->success('',$res);
    }

获取手机号

public function getTel()
    {
        $config = [
            'app_id' => 'wx2222341232342',
            'secret' => '111dsggggddddddddsagsdafhdfsecczegtaq',
            // 下面为可选项
            // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];
        $session = $this->request->post('session');
        $iv = $this->request->post('iv');
        $encryptedData = $this->request->post('encryptedData');
        $app = Factory::miniProgram($config);
        $decryptedData = $app->encryptor->decryptData($session, $iv, $encryptedData);
        $this->success('', $decryptedData);
    }

总结

未完待续…

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
FastAdmin中,可以通过自定义志输出文件名来实现记录志时文件名自定义。 1. 在Logback配置文件中,可以使用变量来定义志输出文件名,例如: ``` <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file> ... </appender> ``` 这里使用了变量${LOG_FILE_NAME}来定义志输出文件名,可以在运行时根据需要进行修改。 2. 在应用程序中,可以使用Spring的Environment对象来获取配置文件中定义的变量值,例如: ``` import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; @Component public class LogFileNameProvider { @Autowired private Environment env; public String getLogFileName() { return env.getProperty("LOG_FILE_NAME"); } } ``` 这里创建了一个LogFileNameProvider类,用来获取配置文件中定义的LOG_FILE_NAME变量值。 3. 在应用程序中,可以在需要记录志的地方调用LogFileNameProvider类来获取志输出文件名,例如: ``` import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ExampleClass { private static final Logger logger = LoggerFactory.getLogger(ExampleClass.class); @Autowired private LogFileNameProvider logFileNameProvider; public void exampleMethod() { String logFileName = logFileNameProvider.getLogFileName(); logger.info("This is an example log message. Log file name: {}", logFileName); } } ``` 这里使用LogFileNameProvider类来获取志输出文件名,并在志消息中输出文件名。 这样,就可以在FastAdmin中实现记录志时文件名自定义了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wise man

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值