Просмотр исходного кода

Merge branch 'master' of https://gitee.com/ZhongBangKeJi/CRMEB

等风来 7 лет назад
Родитель
Сommit
6baaf52097

+ 0 - 3
.gitignore

@@ -2,8 +2,5 @@
 /runtime
 /.idea
 /application/database.php/
-/application/controller/server/
-/application/view/server/
-/application/model/server/
 /public/uploads/
 

+ 1 - 3
README.md

@@ -94,7 +94,7 @@ CRMEB微信小程序v2.0版:除了以上功能还带砍价、拼团功能
 
 还有定制开发服务,例如:预约系统、O2O、付费阅读、多店版、多商家版
 
-### 详情[<a href='https://shop120689819.taobao.com' target="_blank"> 进入淘宝 </a>]
+### 详情[<a href='https://xazbkj.taobao.com/' target="_blank"> 进入淘宝 </a>]
 
 官网线下定制服务版:http://www.crmeb.com
 
@@ -104,8 +104,6 @@ CRMEB微信小程序v2.0版:除了以上功能还带砍价、拼团功能
 
 ```
 Git clone https://gitee.com/ZhongBangKeJi/CRMEB.git
-或者
-Git clone https://github.com/sugar1569/CRMEB.git
 ```
     文档地址:https://gitee.com/ZhongBangKeJi/CRMEB/wikis
 

+ 2 - 0
application/admin/controller/article/Article.php

@@ -121,6 +121,8 @@ class Article extends AuthController
             'synopsis',
             'share_title',
             'share_synopsis',
+            'is_banner',
+            'is_hot',
             ['visit',0],
             ['sort',0],
             'url',

+ 3 - 3
application/admin/controller/store/StoreCategory.php

@@ -46,7 +46,7 @@ class StoreCategory extends AuthController
      */
     public function create()
     {
-        $form = Form::create(Url::build('save'),[
+        $field = [
             Form::select('pid','父级')->setOptions(function(){
                 $list = CategoryModel::getTierList();
                 $menus = [['value'=>0,'label'=>'顶级菜单']];
@@ -59,8 +59,8 @@ class StoreCategory extends AuthController
             Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')))->icon('image'),
             Form::number('sort','排序'),
             Form::radio('is_show','状态',1)->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]])
-        ]);
-        $form->setMethod('post')->setTitle('添加分类');
+        ];
+        $form = Form::make_post_form('添加产品',$field,Url::build('save'));
         $this->assign(compact('form'));
         return $this->fetch('public/form-builder');
     }

+ 64 - 18
application/admin/controller/system/SystemDatabackup.php

@@ -1,12 +1,11 @@
 <?php
 namespace app\admin\controller\system;
-
 use app\admin\controller\AuthController;
 use service\FormBuilder as Form;
 use think\Request;
 use service\JsonService as Json;
 use \tp5er\Backup;
-
+use think\Session;
 /**
  * 文件校验控制器
  * Class SystemDatabackup
@@ -19,7 +18,7 @@ class SystemDatabackup extends AuthController
     public function _initialize()
     {
         $config = array(
-            'path' => './backup/data/',
+            'path' => '.'.PUBILC_PATH.'backup/data/',
             //数据库备份路径
             'part' => 20971520,
             //数据库备份卷大小
@@ -29,15 +28,12 @@ class SystemDatabackup extends AuthController
         );
         $this->DB = new Backup($config);
     }
-
     /**
      * 数据类表列表
      */
     public function index(){
-
        return $this->fetch();
     }
-
     /**
      * 获取数据库表
      * @param Request|null $request
@@ -47,7 +43,6 @@ class SystemDatabackup extends AuthController
        $db= $this->DB;
        return Json::result(0,'sucess',$db->dataList(),count($db->dataList()));
     }
-
     /**
      * 查看表结构
      * @param Request|null $request
@@ -56,7 +51,6 @@ class SystemDatabackup extends AuthController
     {
         parent::__construct($request);
     }
-
     /**
      * 优化表
      * @param Request|null $request
@@ -68,7 +62,6 @@ class SystemDatabackup extends AuthController
         $res = $db->optimize($tables);
         return Json::successful($res ? '优化成功':'优化失败');
     }
-
     /**修复表
      * @param Request|null $request
      */
@@ -103,24 +96,77 @@ class SystemDatabackup extends AuthController
         $files = $db->fileList();
         $data = [];
         foreach ($files as $key=>$t){
-            $data[$key]['backtime'] = $key;
+            $data[$key]['filename'] = $t['filename'];
             $data[$key]['part'] = $t['part'];
             $data[$key]['size'] = $t['size'].'B';
             $data[$key]['compress'] = $t['compress'];
-            $data[$key]['time'] = date('Y-m-d H:i:s',$t['time']);
+            $data[$key]['backtime'] = $key;
+            $data[$key]['time'] = $t['time'];
         }
-
+        krsort($data);//根据时间降序
         return Json::result(0,'sucess',$data,count($data));
-    } /**删除备份记录表
+    }
+    /**删除备份记录表
      * @param Request|null $request
      */
     public function delFile(Request $request = null)
     {
-        $feilname = strtotime($request->post('feilname'));
-        echo $feilname;
-
-        
+        $feilname = intval($request->post('feilname'));
         $files = $this->DB->delFile($feilname);
-       // return Json::result(0,'sucess',$data,count($data));
+       return Json::result(0,'sucess');
+    }
+    /**倒入备份记录表
+     * @param Request|null $request
+     */
+    public function import(Request $request = null)
+    {
+        $part = $request->post('part') != '' ? intval($request->post('part')) :null;
+        $start = $request->post('start') != '' ? intval($request->post('start')) : null;
+        $time = intval($request->post('time'));
+        $db = $this->DB;
+        if(is_numeric($time) && is_null($part) && is_null($start)){
+            $list= $db->getFile('timeverif',$time);
+            if(is_array($list)){
+                session::set('backup_list',$list);
+                $this->success('初始化完成!','',array('part' =>1,'start'=>0));
+            }else{
+                $this->error('备份文件可能已经损坏,请检查!');
+            }
+        }else if(is_numeric($part)&&is_numeric($start)){
+                $list=session::get('backup_list');
+                $start=$db->setFile($list)->import($start);
+                if(false===$start){
+                    $this->error('还原数据出错!');
+                }elseif(0===$start){
+                    if(isset($list[++$part])){
+                        $data=array('part'=>$part,'start'=>0);
+                    $this->success("正在还原...#{$part}",'',$data);
+                    }else{
+                        session::delete('backup_list');
+                        $this->success('还原完成!');
+                    }
+                }else{
+                    $data=array('part'=>$part,'start'=>$start[0]);
+                    if($start[1]){
+                        $rate=floor(100*($start[0]/$start[1]));
+                        $this->success("正在还原...#{$part}({$rate}%)",'',$data);
+                    }else{
+                         $data['gz']=1;
+                        $this->success("正在还原...#{$part}",'',$data);
+                    }
+                    $this->success("正在还原...#{$part}",'');
+                }
+        }else{
+                $this->error('参数错误!');
+        }
+        // return Json::result(0,'sucess',$data,count($data));
+    }
+    /**下载备份记录表
+     * @param Request|null $request
+     */
+    public function downloadFile(Request $request = null)
+    {
+        $time = intval($request->param('feilname'));
+        $this->DB->downloadFile($time);
     }
 }

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
application/admin/view/article/article/create.php


+ 2 - 1
application/admin/view/public/container.php

@@ -8,7 +8,8 @@
     {block name="head"}{/block}
 </head>
 <body class="gray-bg">
-<div class="wrapper wrapper-content animated fadeInUp">
+<!--演示地址https://daneden.github.io/animate.css/?-->
+<div class="wrapper wrapper-content animated fadeInDown">
 {block name="content"}{/block}
 {block name="foot"}{/block}
 {block name="script"}{/block}

+ 84 - 36
application/admin/view/system/system_databackup/index.php

@@ -30,17 +30,11 @@
                 <div class="table-responsive">
                     <script type="text/html" id="toolbarDemo">
                         <div class="layui-btn-container">
-                            <button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
-                            <button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button>
-                            <button class="layui-btn layui-btn-sm" lay-event="isAll">验证是否全选</button>
+                            <button class="layui-btn layui-btn-sm" lay-event="backup">备份</button>
+                            <button class="layui-btn layui-btn-sm" lay-event="optimize">优化表</button>
+                            <button class="layui-btn layui-btn-sm" lay-event="repair">修复表</button>
                         </div>
                     </script>
-                    <div class="layui-btn-group conrelTable">
-                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="backup"><i class="fa fa-check-circle-o"></i>备份</button>
-                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="optimize"><i class="fa fa-check-circle-o"></i>优化表</button>
-                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="repair"><i class="fa fa-check-circle-o"></i>修复表</button>
-                        <button class="layui-btn layui-btn-sm layui-btn-normal" type="button" data-type="refresh"><i class="layui-icon layui-icon-refresh" ></i>刷新</button>
-                    </div>
                     <table class="layui-hide" id="tableListID" lay-filter="tableListID"></table>
                     <script type="text/html" id="barDemo">
                         <button type="button" class="layui-btn layui-btn-xs" lay-event="see"><i class="layui-icon layui-icon-edit"></i>详情</button>
@@ -52,40 +46,80 @@
 </div>
 <script src="{__ADMIN_PATH}js/layuiList.js"></script>
 <script>
-    layui.use('table', function(){
+    function ipmosrting(time,part = null,start = null) {
+        var datas = {
+            time:time,
+            part:part,
+            start:start
+        };
+        $.ajax({
+            url: layList.Url({a: 'import'}),
+            data: datas,
+            type: 'post',
+            dataType: 'json',
+            success: function (res) {
+                console.log(res);
+                if(res.data){
+                    if(res.code){
+                        setTimeout(ipmosrting(time,res.data.part,res.data.start),2000);
+                    }
+                }else{
+                    layList.msg(res.msg);
+                    return false;
+                }
+
+            },
+            error: function (err) {
+                console.log(err)
+            }
+        });
+
+    }
+    layui.use(['table', 'layer'], function(){
+        var layer = layui.layer;
         var fileList = layui.table;
         var tableList = layui.table;
         //加载sql备份列表
-        fileList.render({
+        var buckdata = fileList.render({
             elem: '#fileList'
             ,url:"{:Url('fileList')}"
             ,cols: [[
-                {field: 'backtime', title: '备份名称', sort: true},
-                {field: 'part', title: '备注'},
+                {field: 'filename', title: '备份名称', sort: true},
+                {field: 'part', title: 'part'},
                 {field: 'size', title: '大小'},
-                {field: 'compress', title: '类型'},
-                {field: 'time', title: '时间'},
+                {field: 'compress', title: 'compress'},
+                {field: 'backtime', title: '时间'},
                 {fixed: 'right', title: '操作', width: '20%', align: 'center', toolbar: '#fileListtool'}
             ]]
             ,page: false
         });
+
         //监听工具条
         fileList.on('tool(fileList)', function(obj){
             var data = obj.data;
-            if(obj.event === 'import'){
-                layer.msg('ID:'+ data.id + ' 的查看操作');
-            } else if(obj.event === 'delFile'){
-                layer.confirm('真的删除行么', function(index){
-                    layList.basePost(layList.Url({a:'delFile'}),{feilname:data.time},function (res) {
-                        layList.msg(res.msg);
-//                    layList.reload();
+            var layEvent = obj.event;
+            switch (layEvent){
+                case 'import':
+                    layer.confirm('真的倒入该备份吗?', function(index){
+                        ipmosrting(data.time,null,null);
+                        layer.close(index);
+                    });
+                    break;
+                case 'delFile':
+                    layer.confirm('真的删除该备份吗?', function(index){
+                        layList.basePost(layList.Url({a:'delFile'}),{feilname:data.time},function (res) {
+                            layer.msg(res.msg);
+                            buckdata.reload();
+                        });
+                        obj.del();
+                        layer.close(index);
                     });
-                    obj.del();
-                    layer.close(index);
-                });
-            } else if(obj.event === 'downloadFile'){
-                layer.alert('编辑行:<br>'+ JSON.stringify(data))
+                    break;
+                case 'downloadFile':
+                    location.href = layList.Url({a:'downloadFile',p:{feilname:data.time}});
+                    break;
             }
+
         });
         //加载table
         tableList.render({
@@ -97,7 +131,7 @@
                 {field: 'name', title: '表名称', sort: true},
                 {field: 'comment', title: '备注' },
                 {field: 'engine', title: '类型', sort: true},
-                {field: 'data_length', title: '大小', sort: true},
+                {field: 'data_length', title: '大小', sort: true,totalRow: true},
                 {field: 'update_time', title: '更新时间', sort: true},
                 {field: 'rows', title: '行数'},
                 {fixed: 'right', title: '操作', width: '10%', align: 'center', toolbar: '#barDemo'}
@@ -107,17 +141,31 @@
         //头工具栏事件
         tableList.on('toolbar(tableListID)', function(obj){
             var checkStatus = tableList.checkStatus(obj.config.id);
+            var data = checkStatus.data;
+            var tables = [];
+            $.each(data, function (name, value) {
+                if (value['name'] != undefined) tables.push(value['name']);
+            });
+            if(tables.length < 1 ){
+                return false;
+            }
             switch(obj.event){
-                case 'getCheckData':
-                    var data = checkStatus.data;
-                    layer.alert(JSON.stringify(data));
+                case 'backup':
+                    layList.basePost(layList.Url({a:'backup'}),{tables:tables},function (res) {
+                        layer.msg(res.msg,{icon:1,time:1000,end:function(){
+                            buckdata.reload();
+                        }});
+                    });
                     break;
-                case 'getCheckLength':
-                    var data = checkStatus.data;
-                    layer.msg('选中了:'+ data.length + ' 个');
+                case 'optimize':
+                    layList.basePost(layList.Url({a:'optimize'}),{tables:tables},function (res) {
+                        layer.msg(res.msg);
+                    });
                     break;
-                case 'isAll':
-                    layer.msg(checkStatus.isAll ? '全选': '未全选');
+                case 'repair':
+                    layList.basePost(layList.Url({a:'repair'}),{tables:tables},function (res) {
+                        layer.msg(res.msg);
+                    });
                     break;
             };
         });

+ 1 - 1
extend/service/FormBuilder.php

@@ -20,7 +20,7 @@ class FormBuilder extends Form
      * @param $jscallback null 不执行 1 父级刷新 2 父级刷新关闭弹框 str 自定义
      * @return $this
      */
-    public static function make_post_form($title,array $field,$url,$jscallback = null){
+    public static function make_post_form($title,array $field,$url,$jscallback = 1){
         $form = Form::create($url);//提交地址
         $form->setMethod('POST');//提交方式
         $form->components($field);//表单字段

Разница между файлами не показана из-за своего большого размера
+ 606 - 1368
public/install/crmeb.sql


+ 63 - 0
public/system/css/layui-admin.css

@@ -1,8 +1,71 @@
 @charset "UTF-8";
+/*
+部分样式重构
+ */
+.layui-form-pane .layui-input, .layui-select, .layui-textarea {
+    height: 32px;
+    line-height: 1.5;
+    padding: 4px 7px;
+    font-size: 12px;
+    border: 1px solid #dddee1;
+    color: #495060;
+    background-color: #fff;
+}
+.layui-card-body {
+}
+.layui-form-pane{
+    /*padding: 20px;*/
+}
+.layui-form-pane .layui-form-label {
+    padding: 5px 15px;
+    height: 32px;
+}
+.layui-fluid {
+    padding: 0;
+}
+.layui-btn-normal{
+    background-color:#0092DC;
+}
+.layui-btn .layui-icon {
+    font-size: 12px;
+}
+.layui-btn-sm i {
+    font-size: 12px!important;
+}
+.layui-form-onswitch {
+    border-color: #0092DC;
+    background-color: #0092DC;
+}
+.layui-table-cell p{
+    height: 20px;
+    line-height: 20px;
+}
+/*table复选框*/
+.layui-table-view .layui-form-checkbox[lay-skin=primary] i {
+    width: 14px;
+    height: 14px;
+}
+.layui-form-checked[lay-skin=primary] i {
+    border-color: #0093DE;
+    background-color: #0093DE;
+    color: #fff;
+}
+.layui-form-checkbox[lay-skin=primary] i {
+    width: 14px;
+    height: 14px;
+    line-height: 12px;
+}
+
 /*后台layui-admin样式*/
+.layui-tab-title .layui-this:after{
+    border-bottom: 2px solid #0092DC !important;
+}
 .layui-form-label{
     width: auto;
 }
+.layui-table-cell {
+    height: auto!important;
+}
 .layui-input-block .layui-admin-input{
     width: 50%;
     height: 34px;

Разница между файлами не показана из-за своего большого размера
+ 70 - 67
public/system/frame/css/style.min.css


+ 4 - 4
public/system/frame/js/contabs.min.js

@@ -239,14 +239,14 @@ $(function() {
     })
     //返回
     function rep() {
-        var l = $(".J_iframe:visible");
-        l[0].contentWindow.history.go(-1);
+        //$(".J_iframe:visible")[0].contentWindow.history.go(-1);
+        window.frames[$(".page-tabs-content .active").index()].history.go(-1);
     }
     $(".J_tabReply").on("click", rep);
     //刷新
     function ref() {
-        var l = $(".J_iframe:visible");
-        l[0].contentWindow.location.reload();
+        // $(".J_iframe:visible")[0].contentWindow.location.reload();
+        window.frames[$(".page-tabs-content .active").index()].location.reload();
     }
     $(".J_tabRefresh").on("click", ref);
 });

+ 2 - 0
vendor/tp5er/tp5-databackup/src/Backup.php

@@ -135,6 +135,7 @@ class Backup
         $glob = new \FilesystemIterator($path, $flag);
         $list = array();
         foreach ($glob as $name => $file) {
+            $info['filename'] = $name;
             if (preg_match('/^\\d{8,8}-\\d{6,6}-\\d+\\.sql(?:\\.gz)?$/', $name)) {
                 $name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d');
                 $date = "{$name[0]}-{$name[1]}-{$name[2]}";
@@ -179,6 +180,7 @@ class Backup
                     $gz = preg_match('/^\\d{8,8}-\\d{6,6}-\\d+\\.sql.gz$/', $basename);
                     $list[$match[6]] = array($match[6], $name, $gz);
                 }
+                ksort($list);
                 $last = end($list);
                 if (count($list) === $last[0]) {
                     return $list;