Source Map
前端工程化的一个重要部分就是就是源码转换,一方面压缩体积,另一方面合并文件。当然还有可能是为了转换Typescript、ES6+或其他代码。但通常转换完的代码难以阅读和调试。Source Map就是为了解决这个问题而出现的。

找到一个神器
安装
Chrome web store
安装地址https://chrome.google.com/webstore/detail/source-detecotor/aioimldmpakibclgckpdfpfkadbflfkn?hl=zh-CN&gl=CN

源码安装

  1. 下载安装

git clone https://github.com/SunHuawei/SourceDetector.git
cd SourceDetector
npm install
bower install
gulp

打开Chrome设置-扩展程序
点击"加载已解压的扩展程序..."
选择path/to/source-detector/dist目录

之后你在浏览任何网页时,该插件将自动检测是否有.map文件。其会自动按网站分组显示源码文件,并可点击下载全部或部分源码文件。

tp5组合复杂的AND OR SQL语句

                if (!empty($spec_name)) {
                    $spec_where_item[] = array(
                        'like',
                        '%' . $spec_name . '%'
                    );
                }

                //重置
                $spec_where1 = [];
                foreach ($spec_value_info as $spec)
                {
                    $spec_value_name = $spec["spec_value_name"];

                    if (!empty($spec_value_name)) {
                        $spec_where1[] = array(
                            'like',
                            '%"spec_value_name":"' . $spec_value_name . '"%'
                        );
                    }
                }
                //这些条件用or
                $spec_where2 = [$spec_where1,'or'];
                $spec_where[] = [$spec_where_item,$spec_where2,'and'];

侧边商品筛选器的开发
基于filterMore组件,筛选器数据的json生成,解决选择后的参数URL拼接 ,后端参数获取,选中值页面重载后的加载等难题
基于模板标签的二级子站的显示

微信编辑器提供微信公众号文章排版和内容编辑的在线工具,样式丰富,支持秒刷、收藏样式和颜色、图片素材编辑、图片水印、一键排版等功能,轻松编辑微信公众号图文。是公众号编辑必备的工具,很多平台都需要加入VIP才能使用一些更好的资源,今天刚好研究微信编辑器的原理与开发,通过看JS代码发现很多平台的VIP判断很容易绕过。以下是方法,都需要在chrome的开发者工具的cosole面板中运行.

96editor

$('#user_vip').data('vip',3) 

135editor

vip_user = true

其它平台不断丰富中

以下是简要大纲,全文马上发布

1.发现问题
2.查找原因
3.查杀木马 linux下查杀不方便 将文件打包到本地用dwebshell查杀 检查文件
4.木马破坏的过程 目的 黑帽SEO

composer thinkphp 的版本配置 5.0.x的composer升级
通过composer更新
手工更新核心漏洞文件

thinkphp版本升级后的程序修改
yfcmf升级版本后出错 清理缓存 修改用到 exp 的地方

app/common.php
 Db::name("action_log")->where($where)->update(array("count"=>array("inc","1"),"last_time"=>$time,"ip"=>$ip));

news.php
//更新点击数
            Db::name('news')->update(array("n_id"=>input('id'),"news_hits"=>array("inc","1")));

清理木马
打包到本地 用WebshellKill扫描、杀木马后重新上传
用linux下工具 PHP扫木马工具

DophinPHP(海豚PHP)是一个基于ThinkPHP5.0.24开发的一套开源PHP快速开发框架,DophinPHP秉承极简、极速、极致的开发理念,为开发集成了基于数据-角色的权限管理机制,集成多种灵活快速构建工具,可方便快速扩展的模块、插件、钩子、数据包。统一了模块、插件、钩子、数据包之间的版本和依赖关系,进一步降低了代码和数据的冗余,以方便开发者快速构建自己的应用。

表单,表单构建器

使用DophinPHP(海豚PHP)自主开发的ZBuilder类,您可以轻松的应对复杂多变的表单、数据列表。数据列表集成类似EXCEL的快速筛选、排序、模糊搜索、AJAX编辑等功能,表单页集成常用的文本、下拉框、单选、多选、关键词、编辑器、文件上传、图片上传、图片裁切等控件,除此之外,您还可以灵活的扩展自己的控件,以便在自己的项目中重复使用。ZBuilder让您更加专注业务逻辑。

快速开发流程:建立数据库 > 新建控制器、模型、验证器 > 构建器快速生成表单、数据列表 > 添加业务逻辑
不需要在构建界面、通用代码等细节中浪费时间,快速实现系统功能,爽。

扩展html,js

构建器中可以定义扩展HTML,JS,相互配合可以实现丰富的页面交互功能,补充构建器复杂业务需求。

  1. 扩展js 实现动态添加表单元素
  2. 搜索区域的下拉联动

搜索区域

重设$map条件,有时候搜索区域的字段并不是实际的字段,需要做一些判断处理,并将搜索区域传过来的字段注销,以免影响查询
unset($map['']);

用户关联所属村居

多级用户 权限控制

 //村居只显示自己的信息
        if(session('user_auth.role') == 3){
            $map["v_id"] = session('user_auth.v_id');
        }

自动添加、自动编辑

追求极简的开发是DolphinPHP的核心思想之一,为了节省开发者的宝贵时间,我们为大家准备了一个神奇的方法,可以让开发者无需编写add方法也能实现创建表单和写入数据。
对于一些简单的数据,没有复杂的处理逻辑只是简单的crud,可以用自动添加、自动编辑功能快速实现,神奇!

select2的技巧

全选,联动,动态追加,提交判断

$(function(){

    //全局变量
    var count=1;
    var mselect = $("#members").select2();
    var btn = "<a id='allmember' class='btn btn-default'>选中全体人员</a>";

    $("#members").after(btn);

    $("#allmember").click(function() {
        mselect.val(allmember).trigger("change");
        mselect.change();
        //设置参会人员,重置选项
        resetSelect();
    });

    //改变参会人员选项
    $("#members").on("change",function () {
        //alert(mselect.val());
        //改变所有的下拉选项 事件处理
        resetSelect();
    });

    $("#members").change(function () {
        resetSelect();
    });

    //动态添加表决事项
    $("#additem").click(function() {
        //alert(count);
        count++;
        $(this).parent().parent().before(getHtml(count));
        //初始化选项
        $("#agreed" + count).append($("#agreed1").find("*").clone(true));
        //设置表决人员
        $("#agreed" + count).select2().val($("#agreed1").select2().val());
        resetSelect();
    });
    
    
    function resetSelect() {
       for (var i=1; i<=count;i++){
           $("#agreed" + i).select2().val(mselect.val());
       }
    }
    

    //追加表单
    function getHtml(ii) {
        var html = "";

        html += "  <div class=\"form-group col-lg-12 col-md-12 col-sm-12 col-xs-12 \" id=\"form_group_content" + ii +  "\">\n" +
            "    <label class=\"col-xs-12\" for=\"content" + ii + "\">表决事项内容" + ii + "</label>\n" +
            "    <div class=\"col-xs-12\">\n" +
            "        <textarea class=\"form-control\" id=\"content" + ii +  "\" rows=\"7\" name=\"content" + ii +  "\" placeholder=\"请输入表决事项内容\" ></textarea>\n" +
            "            </div>\n" +
            "</div>\n" +
            "                                                                                            \n" +
            "                                                <div class=\"form-group col-lg-12 col-md-12 col-sm-12 col-xs-12 \" id=\"form_group_result" + ii +  "\">\n" +
            "    <label class=\"col-xs-12\" for=\"result" + ii +  "\">表决结果" + ii + "</label>\n" +
            "    <div class=\"col-sm-12\">\n" +
            "        \n" +
            "        <input class=\"form-control\" type=\"text\" id=\"result" + ii +  "\" name=\"result" + ii +  "\" value=\"\" placeholder=\"请输入表决结果\" >\n" +
            "\n" +
            "            </div>\n" +
            "</div>\n" +
            "                                                                                            \n" +
            "                                                <div class=\"form-group col-lg-12 col-md-12 col-sm-12 col-xs-12 \" id=\"form_group_agreed" + ii +  "\">\n" +
            "    <label class=\"col-xs-12\" for=\"agreed" + ii +  "\">参会人员表决通过人员" + ii + "</label>\n" +
            "    <div class=\"col-sm-12\">\n" +
            "        <select class=\"js-select2 form-control\" id=\"agreed" + ii +  "\" name=\"agreed" + ii +  "[]\" data-allow-clear=\"true\" data-placeholder=\"请选择一项或多项\" multiple=\"multiple\" multiple>\n" +
            "                    </select>\n" +
            "            </div>\n" +
            "</div>\n";

        return html;
    }


    //提交判断 获取表决事项数量值
    $(".ajax-post").click( function () {

        if($("#members").select2().val()){
            ch = $("#members").select2().val().length;
        }
        else
        {
            layer.msg('请选择参会人员', {icon: 5});
            return false;
        }


        if($("#cw_title").val() == ""){
            layer.msg('请填写村务会议主题', {icon: 5});
            return false;
        }

        //判断
        if((ch / allmember.length) < 2/3){
            layer.msg('参会人员不达标,无法提交', {icon: 5});
            return false;
        }

        if($("#content1").val() == ""){
            layer.msg('请至少填写一项表决事项', {icon: 5});
            return false;
        }

        //追加事项数量的元素
        $(this).before("<input type='hidden' name='maxitem' id='maxitem' />");
        $("#maxitem").val(count);
        //alert($("#maxitem").val());
        //return false;
    } );

});

联动效果

//事件绑定
$(function () {

    //先把所有的村缓存起来
    //镇办更新的时候
    $("#search_town").on("change", function (e) {
        //获取镇办选择项
        var town = $("#search_town option:checked").val();
        
        //取出相应的村名 并重置选项 town为空的情况 全部村名
        //alert(town);
        $.get("/admin.php/wsgk/cunju/getcunju.html", {town: town},
            function (data) {
                //清空月份
                $("#search_v_id").select2().empty();
                $("#search_v_id").select2({data: null});

                var itemList = [];
                for (var i = 0; i < data.length; i++) {
                    itemList.push({id: data[i].id, text: data[i].text})
                }

                $('#search_v_id').select2({
                    placeholder: '请选择',
                    language: "zh-CN",
                    data: itemList
                });
                $('.select2').width('100%');

            });
    })


});

修改、删除操作申请与审核

二维码海报合成

图片处理库Grafika,二维码生成库, composer安装,依赖的管理,自动添加自动载入机制

function getQrBanner($vid)
{

    $result = Db::view('wsgk_village','vname')
        ->view('wsgk_town','name,jwcontact','wsgk_town.id=wsgk_village.town')
        ->where('wsgk_village.id',$vid)
        ->find();

    $name = $result['vname'];
    $town = $result['name'];
    $tel = $result['jwcontact'];

    //看有没有二维码 有打开 没有生成,返回图像
    $erwima = config('upload_path') . DS . "qrcode/" . $vid .  "_qrcode.png";
    if(!file_exists($erwima))
    {
        create_qrcode($vid);
    }

    $editor = Grafika::createEditor();
    $editor->open($image , 'bg.jpg');
//合成上二维码
    $editor->open($image2 , $erwima);
    $editor->blend ( $image, $image2 , 'normal', 1, 'top-left',520,480);
//画圆
    $drawingObject = Grafika::createDrawingObject('Ellipse', 150, 150, array(770,730), 1, new Color('#edf4ed'), new Color('#edf4ed'));
    $editor->draw( $image, $drawingObject );
//根据字的多少来计算x的位置 一个字多宽 770-50
    $editor->text($image ,$name,30,830 - ((strlen($name) / 3 / 2) * 30),790,new Color("#f27113"),config('upload_path') . DS . "qrcode/qr.ttf",0);
    $editor->text($image ,'如有问题,请向' . $town . '纪委举报,电话:' . $tel,30,400,2200,new Color("#ffffff"),config('upload_path') . DS . "qrcode/qr.ttf",0);
//保存
    $editor->save($image,config('upload_path') . DS . "qrcode/" . $vid . '_banner.png');
}
//生成二维码图片

function create_qrcode($vid)
{

    //获取村名信息
    $vinfo = Db::name("wsgk_village")->where("id",$vid)->find();

    $url = "http://wsgk.zbsylxh.com/index.php?vid=" . $vid;
    $qrCode = new QrCode();
    $qrCode->setText($url)
        ->setSize(650)
        ->setPadding(10)
        ->setErrorCorrection('high')
        ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
        ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0))

        ->setImageType(\Endroid\QrCode\QrCode::IMAGE_TYPE_PNG);


    $file_name = config('upload_path') . DS . "qrcode/" . $vid .  "_qrcode.png";
    $qrCode->save($file_name);
    return true;

}

搜索区域的下拉框多选

海豚PHP搜索区域的下拉框默认是不支持多选的,需要通过自定义模板、扩展JS等来实现

  1. 复制默认的buildertablelayout.html模板到控制器对应的VIEW目录中
  2. 修改模板中的搜索区域的select处理代码 添加multiple="multiple"
  3. 添加相应的扩展JS,处理搜索区域的SUBMIT处理事件及下拉框的联动逻辑,参考代码

    // @tofishes
    // var params = $('form').paramMap();  就可以获得整个表单的所有参数
    $.fn.paramMap = function (opts) {
        opts = $.extend({
            'separator': ',' // 同名参数的分隔符,多用于checkbox的值
        })
    
        var params = this.serializeArray()
            ,   paramMap = {}
    
            ,   i = 0
            ,   l = params.length
            ,   param;
    
        for (; i < l; i++) {
            param = params[i];
    
            if (paramMap[param.name]) {
                paramMap[param.name] += opts.separator + param.value;
            } else {
                paramMap[param.name] = param.value;
            }
        };
    
        return paramMap;
    };
    
    
    // 搜索区域
    $('#search-area-project').submit(function () {
        var items = $('#search-area-project').paramMap();
        var op  = $('#_o').val();
        var str = [];
        $.each(items, function (index, e) {
            str.push(index + '=' + e)
        });
        str = str.join('|');
        location.href = $(this).attr('action')+'?_s='+str+'&_o='+op;
        return false;
    });
    
    
    
    //事件绑定
    $(function () {
    
        //导出处理
        $("#exportbtn").on("click",function (e) {
            var items = $('#search-area-project').paramMap();
            var op  = $('#_o').val();
            var str = [];
            $.each(items, function (index, e) {
                str.push(index + '=' + e)
            });
            str = str.join('|');
            str1 = '/index.php/iot/data/export.html?_s='+str+'&_o='+op;
            //alert(str1);
            window.open(str1)
            //location.href = str1;
            return false;
        })
    
    
        //根据项目获取设备及变量
        $("#search_device_project_id").on("change", function (e) {
            //获取项目选择项
            var project_id = $("#search_device_project_id option:checked").val();
            //取出相应的从机 并重置选项 设备为空的情况 全部从机
            //alert(town);
            $.get("/index.php/iot/device/getdevicebyproject.html", {project_id: project_id},
                function (data) {
                    //初始化设备
                    $("#search_data_device_id").select2().empty();
                    $("#search_data_device_id").select2({data: null});
    
                    //初始化数据选项
                    var itemList = [];
                    //alert(data.device.length);
                    for (var i = 0; i < data.device.length; i++) {
                        itemList.push({id: data.device[i].id, text: data.device[i].text})
                    }
    
                    $('#search_data_device_id').select2({
                        placeholder: '请选择设备',
                        language: "zh-CN",
                        data: itemList
                    });
    
                    //初始化变量
                    $("#search_data_name").select2().empty();
                    $("#search_data_name").select2({data: null});
    
                    //初始化数据选项
                    var itemList1 = [];
                    for (var i = 0; i < data.data_name.length; i++) {
                        itemList1.push({id: data.data_name[i], text: data.data_name[i]})
                    }
    
                    $('#search_data_name').select2({
                        placeholder: '请选择变量',
                        language: "zh-CN",
                        data: itemList1
                    });
    
    
    
                    $('.select2').width('100%');
    
    
                });
        })
    
    
    });