瀏覽代碼

fix:
- 签到设置
- 公告管理修改
- 专家列表接口
- 还原安装程序

zzb 2 年之前
父節點
當前提交
91e0b3438e

+ 11 - 2
app/admin/controller/Announcement.php

@@ -4,6 +4,7 @@ namespace app\admin\controller;
 
 
 use app\admin\controller\base\Permissions;
 use app\admin\controller\base\Permissions;
 use think\Db;
 use think\Db;
+use think\Session;
 
 
 class Announcement extends Permissions
 class Announcement extends Permissions
 {
 {
@@ -37,8 +38,16 @@ class Announcement extends Permissions
             $count = $model->where($where)->count();
             $count = $model->where($where)->count();
             $data = $model->where($where)->page($post['page']??0, $post['limit']??15)->order('id desc')->select();
             $data = $model->where($where)->page($post['page']??0, $post['limit']??15)->order('id desc')->select();
 
 
+            $adminModel = new \app\admin\model\Admin();
+            $adminIdAndName = $adminModel->column('nickname', 'id');
+            foreach ($data as $key => $value) {
+                $value['admin_name'] = $adminIdAndName[$value['admin_id']]??"";
+                $data[$key] = $value;
+            }
             return array('code' => 0, 'count' => $count, 'data' => $data);
             return array('code' => 0, 'count' => $count, 'data' => $data);
         } else {
         } else {
+            //创建人
+            $this->assign('admins', Db::name('admin')->select());
             return $this->fetch();
             return $this->fetch();
         }
         }
     }
     }
@@ -50,8 +59,6 @@ class Announcement extends Permissions
         $model = $this->getModel();
         $model = $this->getModel();
         $post = $this->request->post();
         $post = $this->request->post();
         if ($this->request->isPost()) {
         if ($this->request->isPost()) {
-
-
             //验证
             //验证
             $validate = new \think\Validate([
             $validate = new \think\Validate([
                 ['title|标题', 'max:50'],
                 ['title|标题', 'max:50'],
@@ -69,6 +76,7 @@ class Announcement extends Permissions
                 $this->error('id不正确');
                 $this->error('id不正确');
             }
             }
             if ($this->request->isPost()) {
             if ($this->request->isPost()) {
+                $post['admin_id'] = Session::get(self::ADMIN_ID);
                 if (false == $model->allowField(true)->save($post, ['id' => $id])) {
                 if (false == $model->allowField(true)->save($post, ['id' => $id])) {
                     $this->error('修改失败');
                     $this->error('修改失败');
                 } else {
                 } else {
@@ -81,6 +89,7 @@ class Announcement extends Permissions
         } else {
         } else {
             //新增
             //新增
             if ($this->request->isPost()) {
             if ($this->request->isPost()) {
+                $post['admin_id'] = Session::get(self::ADMIN_ID);
                 if (false == $model->allowField(true)->save($post)) {
                 if (false == $model->allowField(true)->save($post)) {
                     $this->error('添加失败');
                     $this->error('添加失败');
                 } else {
                 } else {

+ 63 - 54
app/admin/controller/Specialist.php

@@ -17,33 +17,40 @@ class Specialist extends Permissions
         if ($this->request->isAjax()) {
         if ($this->request->isAjax()) {
             $post = $this->request->param();
             $post = $this->request->param();
             $where = [];
             $where = [];
-                                if (isset($post['ids']) and !empty($post['ids'])) {
-                        $where['id'] = ['in', $post['ids']];
-                    }
-                                        if (!empty($post["name"])) {
-                        $where["name"] = ['like', '%' . $post["name"] . '%'];
-                    }
-                                        if (!empty($post["head_pic"])) {
-                        $where["head_pic"] = ['like', '%' . $post["head_pic"] . '%'];
-                    }
-                                        if (isset($post["sex"]) and ""!=$post["sex"]) {
-                        $where["sex"] = $post["sex"];
-                    }
-                                        if (!empty($post["desc"])) {
-                        $where["desc"] = ['like', '%' . $post["desc"] . '%'];
-                    }
-                                        if (!empty($post["consultation_direction"])) {
-                        $where["consultation_direction"] = ['like', '%' . $post["consultation_direction"] . '%'];
-                    }
-                                        if (isset($post["address_id"]) and ""!=$post["address_id"]) {
-                        $where["address_id"] = $post["address_id"];
-                    }
-                    
+            if (isset($post['ids']) and !empty($post['ids'])) {
+                $where['id'] = ['in', $post['ids']];
+            }
+            if (!empty($post["name"])) {
+                $where["name"] = ['like', '%' . $post["name"] . '%'];
+            }
+            if (!empty($post["title"])) {
+                $where["title"] = ['like', '%' . $post["title"] . '%'];
+            }
+            if (!empty($post["head_pic"])) {
+                $where["head_pic"] = ['like', '%' . $post["head_pic"] . '%'];
+            }
+            if (isset($post["sex"]) and "" != $post["sex"]) {
+                $where["sex"] = $post["sex"];
+            }
+            if (!empty($post["desc"])) {
+                $where["desc"] = ['like', '%' . $post["desc"] . '%'];
+            }
+            if (!empty($post["consultation_direction"])) {
+                $where["consultation_direction"] = ['like', '%' . $post["consultation_direction"] . '%'];
+            }
+            if (isset($post["address_id"]) and "" != $post["address_id"]) {
+                $where["address_id"] = $post["address_id"];
+            }
+
             $model = $this->getModel();
             $model = $this->getModel();
             $count = $model->where($where)->count();
             $count = $model->where($where)->count();
             $data = $model->where($where)->page($post['page']??0, $post['limit']??15)->order('id desc')->select();
             $data = $model->where($where)->page($post['page']??0, $post['limit']??15)->order('id desc')->select();
 
 
-                        return array('code' => 0, 'count' => $count, 'data' => $data);
+            foreach ($data as $key => $value) {
+                $value['head_pic_url'] = geturl($value['head_pic']);
+                $data[$key] = $value;
+            }
+            return array('code' => 0, 'count' => $count, 'data' => $data);
         } else {
         } else {
             return $this->fetch();
             return $this->fetch();
         }
         }
@@ -57,50 +64,52 @@ class Specialist extends Permissions
         $post = $this->request->post();
         $post = $this->request->post();
         if ($this->request->isPost()) {
         if ($this->request->isPost()) {
 
 
-            
+
             //验证
             //验证
             $validate = new \think\Validate([
             $validate = new \think\Validate([
-                                    ['name|名字', 'max:50'],
-                                        ['head_pic|头像', 'max:255'],
-                                        ['sex|性别', 'number'],
-                                        ['desc|简介', 'max:500'],
-                                        ['consultation_direction|咨询方向', 'max:500'],
-                                        ['address_id|地址', 'require|number'],
-                                ]);
+                ['name|名字', 'max:50'],
+                ['title|职称', 'max:50'],
+                ['head_pic|头像', 'max:255'],
+                ['sex|sex', 'number'],
+                ['desc|简介', 'max:500'],
+                ['consultation_direction|咨询方向', 'max:500'],
+                ['address_id|地址id', 'require|number'],
+            ]);
             if (!$validate->check($post)) {
             if (!$validate->check($post)) {
                 $this->error('提交失败:' . $validate->getError());
                 $this->error('提交失败:' . $validate->getError());
             }
             }
         }
         }
 
 
         if ($id > 0) {
         if ($id > 0) {
-                            //修改
-                $data = $model->where('id', $id)->find();
-                if (empty($data)) {
-                    $this->error('id不正确');
-                }
-                if ($this->request->isPost()) {
-                    if (false == $model->allowField(true)->save($post, ['id' => $id])) {
-                        $this->error('修改失败');
-                    } else {
-                        $this->success('修改成功');
-                    }
+            //修改
+            $data = $model->where('id', $id)->find();
+            if (empty($data)) {
+                $this->error('id不正确');
+            }
+            if ($this->request->isPost()) {
+                if (false == $model->allowField(true)->save($post, ['id' => $id])) {
+                    $this->error('修改失败');
                 } else {
                 } else {
-                    $this->assign('data', $data);
-                    return $this->fetch();
+                    $this->success('修改成功');
                 }
                 }
-                    } else {
-                            //新增
-                if ($this->request->isPost()) {
-                    if (false == $model->allowField(true)->save($post)) {
-                        $this->error('添加失败');
-                    } else {
-                        $this->success('添加成功', 'index');
-                    }
+            } else {
+                $this->assign('data', $data);
+                return $this->fetch();
+            }
+        } else {
+            //新增
+            if ($this->request->isPost()) {
+                if (false == $model->allowField(true)->save($post)) {
+                    $this->error('添加失败');
                 } else {
                 } else {
-                    return $this->fetch();
+                    $this->success('添加成功', 'index');
                 }
                 }
-                    }
+            } else {
+                return $this->fetch();
+            }
+        }
     }
     }
+
     public function delete()
     public function delete()
     {
     {
         if ($this->request->isAjax()) {
         if ($this->request->isAjax()) {

+ 10 - 4
app/admin/controller/Webconfig.php

@@ -18,15 +18,20 @@ use think\Db;
 
 
 class Webconfig extends Permissions
 class Webconfig extends Permissions
 {
 {
+    protected function _initialize()
+    {
+        parent::_initialize();
+        //扩展配置标签
+        $tabs = (new configTabModel())->where('status', configTabModel::STATUS_OPEN)->order('sort desc')->select();
+        $this->assign('tabs', $tabs);
+    }
+
     public function index()
     public function index()
     {
     {
         $this->assign('web_config', Db::name('webconfig')->where('id', 1)->find());
         $this->assign('web_config', Db::name('webconfig')->where('id', 1)->find());
         $this->assign('is_close_site_key', (new Urlconfig())->getCloseSiteKey());
         $this->assign('is_close_site_key', (new Urlconfig())->getCloseSiteKey());
         $this->assign('admin_log_num', (new AdminLog())->count());
         $this->assign('admin_log_num', (new AdminLog())->count());
         $this->assign('backend_pass', (new Urlconfig())->getBackendPass());
         $this->assign('backend_pass', (new Urlconfig())->getBackendPass());
-        //扩展配置标签
-        $tabs = (new configTabModel())->where('status', configTabModel::STATUS_OPEN)->order('sort desc')->select();
-        $this->assign('tabs', $tabs);
         return $this->fetch();
         return $this->fetch();
     }
     }
 
 
@@ -60,6 +65,7 @@ class Webconfig extends Permissions
 
 
     public function appointmentConfig()
     public function appointmentConfig()
     {
     {
-
+        $this->assign('web_config', Db::name('webconfig')->where('id', 1)->find());
+        return $this->fetch();
     }
     }
 }
 }

+ 10 - 4
app/admin/view/announcement/index.html

@@ -53,9 +53,15 @@
                 <input type="text" name="title" autocomplete="off" placeholder="标题(模糊搜索)"
                 <input type="text" name="title" autocomplete="off" placeholder="标题(模糊搜索)"
                        class="layui-input layui-btn-sm">
                        class="layui-input layui-btn-sm">
             </div>
             </div>
-            <div class="layui-input-inline" style="width:100px">
-                <input type="number" name="admin_id" autocomplete="off" placeholder="发布人"
-                       class="layui-input layui-btn-sm">
+            <div class="layui-input-inline" style="width: 100px">
+                <div class="layui-inline">
+                    <select name="admin_id" lay-search="">
+                        <option value="">创建人</option>
+                        {volist name="$admins" id="vo"}
+                        <option value="{$vo.id}">{$vo.nickname}</option>
+                        {/volist}
+                    </select>
+                </div>
             </div>
             </div>
             <div class="layui-input-inline">
             <div class="layui-input-inline">
                 <input type="text" class="layui-input time_range" id="time_range_create_time" autocomplete="off"
                 <input type="text" class="layui-input time_range" id="time_range_create_time" autocomplete="off"
@@ -98,7 +104,7 @@
 
 
                     {field: 'id', title: 'ID', width: 60},
                     {field: 'id', title: 'ID', width: 60},
                     {field: "title", title: '标题'},
                     {field: "title", title: '标题'},
-                    {field: "admin_id", title: '发布人'},
+                    {field: "admin_name", title: '创建人'},
                     {field: "create_time", title: '日期'},
                     {field: "create_time", title: '日期'},
                     {field: 'action', title: '操作', toolbar: '#barDemo', fixed: 'right'}
                     {field: 'action', title: '操作', toolbar: '#barDemo', fixed: 'right'}
                 ]],
                 ]],

+ 73 - 46
app/admin/view/specialist/index.html

@@ -19,7 +19,8 @@
             display: none;
             display: none;
             color: #fff;
             color: #fff;
         }
         }
-        .tooltip > img{
+
+        .tooltip > img {
             width: 20px;
             width: 20px;
             height: 20px;
             height: 20px;
         }
         }
@@ -28,53 +29,74 @@
 <body style="padding:10px;">
 <body style="padding:10px;">
 <div class="tplay-body-div">
 <div class="tplay-body-div">
 
 
-        <div class="layui-tab">
+    <div class="layui-tab">
         <ul class="layui-tab-title">
         <ul class="layui-tab-title">
             <li class="layui-this">列表</li>
             <li class="layui-this">列表</li>
             <li><a href="{:url('publish')}" class="a_menu">新增</a></li>
             <li><a href="{:url('publish')}" class="a_menu">新增</a></li>
         </ul>
         </ul>
     </div>
     </div>
-    
+
     <script type="text/html" id="toolbarDemo">
     <script type="text/html" id="toolbarDemo">
         <div class="layui-btn-container">
         <div class="layui-btn-container">
-                        <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="deletes">批量删除</button>
-                    </div>
+            <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="deletes">批量删除</button>
+        </div>
     </script>
     </script>
 
 
     <form class="layui-form serch" action="index" method="post">
     <form class="layui-form serch" action="index" method="post">
         <div class="layui-form-item" style="float: left;">
         <div class="layui-form-item" style="float: left;">
 
 
             <div class="layui-input-inline">
             <div class="layui-input-inline">
-                                <input type="text" name="ids" autocomplete="off" placeholder="请输入ID,多个id逗号分隔" class="layui-input layui-btn-sm">
-                            </div><div class="layui-input-inline">
-                            <input type="text" name="name" autocomplete="off" placeholder="名字(模糊搜索)" class="layui-input layui-btn-sm">
-                        </div><div class="layui-input-inline">
-                            <input type="text" name="head_pic" autocomplete="off" placeholder="头像(模糊搜索)" class="layui-input layui-btn-sm">
-                        </div><div class="layui-input-inline" style="width:100px">
-                                <input type="number" name="sex" autocomplete="off" placeholder="性别" class="layui-input layui-btn-sm">
-                            </div><div class="layui-input-inline">
-                            <input type="text" name="desc" autocomplete="off" placeholder="简介(模糊搜索)" class="layui-input layui-btn-sm">
-                        </div><div class="layui-input-inline">
-                            <input type="text" name="consultation_direction" autocomplete="off" placeholder="咨询方向(模糊搜索)" class="layui-input layui-btn-sm">
-                        </div><div class="layui-input-inline" style="width:100px">
-                                <input type="number" name="address_id" autocomplete="off" placeholder="地址" class="layui-input layui-btn-sm">
-                            </div>
+                <input type="text" name="ids" autocomplete="off" placeholder="请输入ID,多个id逗号分隔"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline">
+                <input type="text" name="name" autocomplete="off" placeholder="名字(模糊搜索)"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline">
+                <input type="text" name="title" autocomplete="off" placeholder="职称(模糊搜索)"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline">
+                <input type="text" name="head_pic" autocomplete="off" placeholder="头像(模糊搜索)"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline" style="width: 100px">
+                <select name="sex" lay-search="">
+                    <option value="">sex</option>
+                    <option value="0">性别</option>
+                </select>
+            </div>
+            <div class="layui-input-inline">
+                <input type="text" name="desc" autocomplete="off" placeholder="简介(模糊搜索)"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline">
+                <input type="text" name="consultation_direction" autocomplete="off" placeholder="咨询方向(模糊搜索)"
+                       class="layui-input layui-btn-sm">
+            </div>
+            <div class="layui-input-inline" style="width:100px">
+                <input type="number" name="address_id" autocomplete="off" placeholder="地址id"
+                       class="layui-input layui-btn-sm">
+            </div>
             <button class="layui-btn layui-btn-sm" lay-submit="" lay-filter="serch">立即提交</button>
             <button class="layui-btn layui-btn-sm" lay-submit="" lay-filter="serch">立即提交</button>
         </div>
         </div>
     </form>
     </form>
 
 
-        <script type="text/html" id="barDemo">
+    <script type="text/html" id="barDemo">
         <div class="layui-btn-group">
         <div class="layui-btn-group">
-                        <button class="layui-btn layui-btn-xs a_menu" lay-event="edit"><i class="layui-icon" style="margin-right: 0;"></i></button>
-                        <button class="layui-btn layui-btn-xs delete" lay-event="del"><i class="layui-icon" style="margin-right: 0;"></i></button>
-                    </div>
+            <button class="layui-btn layui-btn-xs a_menu" lay-event="edit"><i class="layui-icon"
+                                                                              style="margin-right: 0;"></i></button>
+            <button class="layui-btn layui-btn-xs delete" lay-event="del"><i class="layui-icon"
+                                                                             style="margin-right: 0;"></i></button>
+        </div>
     </script>
     </script>
-    
+
     <table class="layui-table" id="table" lay-filter="table"></table>
     <table class="layui-table" id="table" lay-filter="table"></table>
     {include file="public/foot"}
     {include file="public/foot"}
 
 
     <script type="text/javascript">
     <script type="text/javascript">
-        layui.use(['table', 'layer', 'form','laydate'], function () {
+        layui.use(['table', 'layer', 'form', 'laydate'], function () {
             var table = layui.table,
             var table = layui.table,
                 form = layui.form,
                 form = layui.form,
                 layer = layui.layer;
                 layer = layui.layer;
@@ -84,31 +106,36 @@
                 id: 'table'
                 id: 'table'
                 , elem: '#table'
                 , elem: '#table'
                 , size: 'sm' //小尺寸的表格
                 , size: 'sm' //小尺寸的表格
-                                , toolbar: '#toolbarDemo'
-                                , limit: 15
+                , toolbar: '#toolbarDemo'
+                , limit: 15
                 , limits: [15, 20, 30, 40, 50, 100]
                 , limits: [15, 20, 30, 40, 50, 100]
                 , url: "{:url('index')}" //数据接口
                 , url: "{:url('index')}" //数据接口
                 , page: true //开启分页
                 , page: true //开启分页
                 , cols: [[ //表头
                 , cols: [[ //表头
                     {type: 'checkbox'},
                     {type: 'checkbox'},
 
 
-                                                {field: 'id', title: 'ID', width: 60},
-                                                        {field: "name", title: '名字'},
-                                                        {field: "head_pic", title: '头像'},
-                                                        {field: "sex", title: '性别'},
-                                                        {field: "desc", title: '简介'},
-                                                        {field: "consultation_direction", title: '咨询方向'},
-                                                        {field: "address_id", title: '地址'},
-                                                    {field: 'action', title: '操作', toolbar: '#barDemo', fixed: 'right'}
-                                    ]],
+                    {field: 'id', title: 'ID', width: 60},
+                    {field: "name", title: '名字'},
+                    {field: "title", title: '职称'},
+                    {
+                        field: "head_pic", title: '头像', width: 70, align: 'center', templet: function (row) {
+                        return (row.head_pic_url == '') ? '' : '<a href="' + row.head_pic_url + '" class="tooltip" target="_blank"><img src="' + row.head_pic_url + '"></a>';
+                    }
+                    },
+                    {field: "sex", title: 'sex'},
+                    {field: "desc", title: '简介'},
+                    {field: "consultation_direction", title: '咨询方向'},
+                    {field: "address_id", title: '地址id'},
+                    {field: 'action', title: '操作', toolbar: '#barDemo', fixed: 'right'}
+                ]],
                 done: function () {
                 done: function () {
                     if (isExitsFunction('showThumb')) {
                     if (isExitsFunction('showThumb')) {
                         showThumb()
                         showThumb()
                     }
                     }
-                                    }
+                }
             });
             });
 
 
-            
+
             form.on('submit(serch)', function (data) {
             form.on('submit(serch)', function (data) {
                 table.reload('table', {
                 table.reload('table', {
                     where: data.field
                     where: data.field
@@ -119,16 +146,16 @@
                 return false;
                 return false;
             });
             });
 
 
-                        table.on('tool(table)', function (obj) {
+            table.on('tool(table)', function (obj) {
                 if (obj.event == 'edit') {
                 if (obj.event == 'edit') {
-                                     window.parent.tab.tabAdd({
+                    window.parent.tab.tabAdd({
                         icon: "fa-bookmark",
                         icon: "fa-bookmark",
                         id: "tplay_specialist" + obj.data.id,
                         id: "tplay_specialist" + obj.data.id,
                         title: obj.data.title == null ? "专家" + obj.data.id : obj.data.title,
                         title: obj.data.title == null ? "专家" + obj.data.id : obj.data.title,
                         url: "/admin/specialist/publish?id=" + obj.data.id
                         url: "/admin/specialist/publish?id=" + obj.data.id
                     });
                     });
-                                  }
-                                else if (obj.event == 'del') {
+                }
+                else if (obj.event == 'del') {
                     layer.confirm('确定要删除?', function (index) {
                     layer.confirm('确定要删除?', function (index) {
                         $.ajax({
                         $.ajax({
                             url: "{:url('delete')}",
                             url: "{:url('delete')}",
@@ -143,8 +170,8 @@
                         })
                         })
                     })
                     })
                 }
                 }
-                            });
-                        //监听事件
+            });
+            //监听事件
             table.on('toolbar(table)', function (obj) {
             table.on('toolbar(table)', function (obj) {
                 if (obj.event == 'deletes') {
                 if (obj.event == 'deletes') {
                     var checkStatus = table.checkStatus(obj.config.id);//获取选中的数据
                     var checkStatus = table.checkStatus(obj.config.id);//获取选中的数据
@@ -174,10 +201,10 @@
                     }
                     }
                 }
                 }
             });
             });
-                    });
+        });
     </script>
     </script>
 
 
-    
+
 </div>
 </div>
 </body>
 </body>
 </html>
 </html>

+ 104 - 75
app/admin/view/specialist/publish.html

@@ -6,100 +6,116 @@
     <meta name="renderer" content="webkit">
     <meta name="renderer" content="webkit">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-    <link rel="stylesheet" href="/static/public/layui/css/layui.css"  media="all">
-    <link rel="stylesheet" href="/static/public/font-awesome/css/font-awesome.min.css" media="all" />
-    <link rel="stylesheet" href="/static/admin/css/admin.css"  media="all">
+    <link rel="stylesheet" href="/static/public/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="/static/public/font-awesome/css/font-awesome.min.css" media="all"/>
+    <link rel="stylesheet" href="/static/admin/css/admin.css" media="all">
     <script src="/static/public/layui/layui.js"></script>
     <script src="/static/public/layui/layui.js"></script>
     <script src="/static/public/jquery/jquery.min.js"></script>
     <script src="/static/public/jquery/jquery.min.js"></script>
 </head>
 </head>
 <style>
 <style>
-  .layui-upload-img{
-    cursor: pointer;
-    width:150px;
-    height:150px;
-    background: url('/static/public/images/uploadimg.jpg');
-    background-size:contain;
-    border-radius: 2px;
-    border-width: 1px;
-    border-style: solid;
-    border-color: #e6e6e6;
-  }
+    .layui-upload-img {
+        cursor: pointer;
+        width: 150px;
+        height: 150px;
+        background: url('/static/public/images/uploadimg.jpg');
+        background-size: contain;
+        border-radius: 2px;
+        border-width: 1px;
+        border-style: solid;
+        border-color: #e6e6e6;
+    }
 </style>
 </style>
 <body style="padding:10px;">
 <body style="padding:10px;">
-  <div class="tplay-body-div">
+<div class="tplay-body-div">
 
 
     {empty name="$data"}
     {empty name="$data"}
     <div class="layui-tab">
     <div class="layui-tab">
-      <ul class="layui-tab-title">
-        <li><a href="index" class="a_menu">列表</a></li>
-        <li class="layui-this">新增</li>
-      </ul>
+        <ul class="layui-tab-title">
+            <li><a href="index" class="a_menu">列表</a></li>
+            <li class="layui-this">新增</li>
+        </ul>
     </div>
     </div>
     {/empty}
     {/empty}
 
 
     <div style="margin-top: 20px;"></div>
     <div style="margin-top: 20px;"></div>
     <form class="layui-form" id="publish" method="post">
     <form class="layui-form" id="publish" method="post">
 
 
-                      <!-- 输入框 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">名字</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="name"  autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty name="$data"}value="{$data.name}"{/notempty}>
-                </div>
-                                </div>
-                          <!-- 输入框 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">头像</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="head_pic"  autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty name="$data"}value="{$data.head_pic}"{/notempty}>
-                </div>
-                                </div>
-                            <!-- 数字 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">性别</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="sex"  autocomplete="off" placeholder="请输入" class="layui-input" type="number" {notempty name="$data"}value="{$data.sex}"{/notempty}>
-                </div>
-                                </div>
-                          <!-- 输入框 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">简介</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="desc"  autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty name="$data"}value="{$data.desc}"{/notempty}>
-                </div>
-                                </div>
-                          <!-- 输入框 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">咨询方向</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="consultation_direction"  autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty name="$data"}value="{$data.consultation_direction}"{/notempty}>
-                </div>
-                                </div>
-                            <!-- 数字 -->
-              <div class="layui-form-item">
-                <label class="layui-form-label">地址</label>
-                <div class="layui-input-inline" style="max-width:300px;">
-                  <input name="address_id" lay-verify="required" autocomplete="off" placeholder="请输入" class="layui-input" type="number" {notempty name="$data"}value="{$data.address_id}"{/notempty}>
-                </div>
-                                      <div class="layui-form-mid layui-word-aux">必填</div>
-                                </div>
-            
+        <!-- 输入框 -->
+        <div class="layui-form-item">
+            <label class="layui-form-label">名字</label>
+            <div class="layui-input-inline" style="max-width:300px;">
+                <input name="name" autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty
+                       name="$data" }value="{$data.name}" {/notempty}>
+            </div>
+        </div>
+        <!-- 输入框 -->
+        <div class="layui-form-item">
+            <label class="layui-form-label">职称</label>
+            <div class="layui-input-inline" style="max-width:300px;">
+                <input name="title" autocomplete="off" placeholder="请输入" class="layui-input" type="text" {notempty
+                       name="$data" }value="{$data.title}" {/notempty}>
+            </div>
+        </div>
+        <!-- 图片 -->
+        <div class="layui-upload">
+            <label class="layui-form-label">头像</label>
+            <div class="layui-upload-list">
+                <img class="layui-upload-img" id="upload_img_head_pic" {notempty name="$data.head_pic"
+                     }src="{$data.head_pic|geturl}" {/notempty}>
+                <input type="hidden" id="upload_value_head_pic" name="head_pic"
+                       value='{notempty name="$data.head_pic"}{$data.head_pic}{/notempty}'>
+            </div>
+        </div>
+
+        <!-- 单选框 -->
+        <div class="layui-form-item">
+            <label class="layui-form-label">sex</label>
+            <div class="layui-input-block">
+                <input type="radio" name="sex" value="0" title="女" {notempty name="$data" }{eq name="$data.sex"
+                       value="0" } checked {/eq}{/notempty}>
+                <input type="radio" name="sex" value="1" title="男" {notempty name="$data" }{eq name="$data.sex"
+                       value="1" } checked {/eq}{/notempty}>
+            </div>
+        </div>
+        <!-- 纯文本段落 -->
+        <div class="layui-form-item layui-form-text">
+            <label class="layui-form-label">简介</label>
+            <div class="layui-input-inline" style="width:80%;">
+                <textarea name="desc" class="layui-textarea">{notempty name="$data"}{$data.desc}{/notempty}</textarea>
+            </div>
+        </div>
+        <!-- 纯文本段落 -->
+        <div class="layui-form-item layui-form-text">
+            <label class="layui-form-label">咨询方向</label>
+            <div class="layui-input-inline" style="width:80%;">
+                <textarea name="consultation_direction" class="layui-textarea">{notempty name="$data"}{$data.consultation_direction}{/notempty}</textarea>
+            </div>
+        </div>
+        <!-- 数字 -->
+        <div class="layui-form-item">
+            <label class="layui-form-label">地址id</label>
+            <div class="layui-input-inline" style="max-width:300px;">
+                <input name="address_id" lay-verify="required" autocomplete="off" placeholder="请输入" class="layui-input"
+                       type="number" {notempty name="$data" }value="{$data.address_id}" {/notempty}>
+            </div>
+            <div class="layui-form-mid layui-word-aux">必填</div>
+        </div>
+
 
 
-        
         {notempty name="$data"}
         {notempty name="$data"}
-          <input type="hidden" name="id" value="{$data.id}">
+        <input type="hidden" name="id" value="{$data.id}">
         {/notempty}
         {/notempty}
-       
-      <div class="layui-form-item">
-        <div class="layui-input-block">
-          <button class="layui-btn" lay-submit lay-filter="admin">立即提交</button>
-          <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+
+        <div class="layui-form-item">
+            <div class="layui-input-block">
+                <button class="layui-btn" lay-submit lay-filter="admin">立即提交</button>
+                <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+            </div>
         </div>
         </div>
-      </div>
     </form>
     </form>
 
 
     <script>
     <script>
-        layui.use(['layer', 'form' ,'laydate'], function () {
+        layui.use(['layer', 'form', 'laydate'], function () {
             var layer = layui.layer,
             var layer = layui.layer,
                 $ = layui.jquery,
                 $ = layui.jquery,
                 form = layui.form;
                 form = layui.form;
@@ -119,7 +135,7 @@
                                     layer.alert(res.msg, function (index) {
                                     layer.alert(res.msg, function (index) {
                                         location.href = res.url;
                                         location.href = res.url;
                                     })
                                     })
-                                }else{
+                                } else {
                                     layer.confirm(res.msg, {
                                     layer.confirm(res.msg, {
                                         btn: ['关闭', '继续编辑']
                                         btn: ['关闭', '继续编辑']
                                     }, function (index) {
                                     }, function (index) {
@@ -136,10 +152,23 @@
                     return false;
                     return false;
                 });
                 });
 
 
-                
+                $('#upload_img_head_pic').click(function () {
+                    layer.open({
+                        type: 2,
+                        title: '选择图片',
+                        area: ['570px', '485px'],
+                        id: 'layerDemo', //防止重复弹出
+                        anim: 4,
+                        content: "/admin/attachment/selectimage.html?suffix=_head_pic",
+                        cancel: function () {
+                            //右上角关闭回调
+                        }
+                    });
+                })
+
             });
             });
         });
         });
     </script>
     </script>
-  </div>
+</div>
 </body>
 </body>
 </html>
 </html>

+ 13 - 139
app/admin/view/webconfig/appointment_config.html

@@ -19,81 +19,23 @@
     </div>
     </div>
     <form class="layui-form" id="admin">
     <form class="layui-form" id="admin">
 
 
-        <div class="layui-col-md12">
-            <div class="layui-form-item">
-                <label class="layui-form-label">系统别名</label>
-                <div class="layui-input-inline" style="max-width: 400px">
-                    <input name="name" placeholder="请输入" autocomplete="off" class="layui-input"
-                           type="text" value="{:systemName()}">
-                </div>
-                <div class="layui-form-mid layui-word-aux">给后台取个别名</div>
-            </div>
-
-            <div class="layui-form-item">
-                <label class="layui-form-label">安全入口</label>
-                <div class="layui-input-inline">
-                    <input placeholder="请输入" autocomplete="off" class="layui-input"
-                           type="text" disabled value="{$backend_pass}">
-                </div>
-                <div class="layui-input-inline" style="width: 35px;">
-                    <button type="button" class="layui-btn layui-btn-xs" style="margin-top: 8px;"
-                            onclick="set_pass()">设置
-                    </button>
-                </div>
-                <div class="layui-form-mid layui-word-aux">设置后只能通过安全入口登录后台</div>
-            </div>
-
-            <div class="layui-form-item">
-                <label class="layui-form-label">操作日志</label>
-                <div class="layui-input-inline" style="width: 73px;">
-                    <input name="is_log" lay-skin="switch" lay-filter="switchTest" lay-text="开启|关闭" type="checkbox"
-                           {if condition="$web_config.is_log eq 1" }checked="" {/if} value="1">
-                </div>
-                <div class="layui-input-inline">
-                    <div class="layui-form-mid layui-word-aux">当前日志数:{$admin_log_num}</div>
-                </div>
-            </div>
-
-            <div class="layui-form-item">
-                <label class="layui-form-label">网站维护</label>
-                <div class="layui-input-inline" style="width:73px">
-                    <input name="is_close_site" lay-skin="switch" lay-text="开启|关闭" type="checkbox"
-                           {if condition="$web_config.is_close_site eq 1" }checked="" {/if} value="1">
+        <div class="layui-form-item">
+            <div class="layui-inline">
+                <label class="layui-form-label">爽约</label>
+                <div class="layui-input-inline" style="width: 100px;">
+                    <input type="number" name="break_the_promise_times" placeholder="0" autocomplete="off" class="layui-input" value="{$web_config.break_the_promise_times}">
                 </div>
                 </div>
-                <div class="layui-form-mid layui-word-aux">开启后可使用维护入口访问:{:url('/', '', false,
-                    true)}?key={$is_close_site_key}
+                <div class="layui-form-mid">次</div>
+                <div class="layui-input-inline" style="width: 100px;">
+                    <input type="number" name="stop_appointment_day" placeholder="0" autocomplete="off" class="layui-input" value="{$web_config.stop_appointment_day}">
                 </div>
                 </div>
+                <div class="layui-form-mid">天内无法再预约</div>
             </div>
             </div>
+        </div>
 
 
-
-            <div class="layui-form-item">
-                <label class="layui-form-label">上传类型</label>
-                <div class="layui-input-inline" style="max-width: 400px">
-                    <input name="file_type" lay-verify="pass" placeholder="多个类型请用(英文,逗号)隔开" autocomplete="off" class="layui-input"
-                           type="text" value="{$web_config.file_type}">
-                </div>
-                <div class="layui-form-mid layui-word-aux">限制上传类型(注意:不限制ueditor中上传)</div>
-            </div>
-
-            <div class="layui-form-item">
-                <label class="layui-form-label">最大上传值</label>
-                <div class="layui-input-inline" style="max-width: 600px">
-                    <input name="file_size" lay-verify="pass" placeholder="单位kb" autocomplete="off" class="layui-input"
-                           type="number" value="{$web_config.file_size}">
-                </div>
-                <div class="layui-form-mid layui-word-aux">单位KB ( php.ini 的 post_max_size、upload_max_filesize
-                    也会限制上传大小 )
-                </div>
-            </div>
-            <div class="layui-form-item">
-                <label class="layui-form-label">文章编辑器</label>
-                <div class="layui-input-inline" style="width: 500px">
-                    <input type="radio" name="article_editor" value="wangEditor" title="wangEditor" {if condition="$web_config.article_editor eq 'wangEditor'"}checked{/if}>
-                    <input type="radio" name="article_editor" value="tinymce" title="tinymce" {if condition="$web_config.article_editor eq 'tinymce'"}checked{/if}>
-                    <input type="radio" name="article_editor" value="ueditor" title="ueditor" {if condition="$web_config.article_editor eq 'ueditor'"}checked{/if}>
-                    <input type="radio" name="article_editor" value="markdown" title="markdown" {if condition="$web_config.article_editor eq 'markdown'"}checked{/if}>
-                </div>
-            </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label"></label>
+            <div class="layui-form-mid layui-word-aux">数字0表示不限制</div>
         </div>
         </div>
 
 
         <div class="layui-form-item">
         <div class="layui-form-item">
@@ -104,23 +46,8 @@
         </div>
         </div>
     </form>
     </form>
 
 
-
     {include file="public/foot"}
     {include file="public/foot"}
 
 
-    <form id="setForm" style="display:none;margin: 10px 30px;" class="layui-form alert-form">
-        <div class="layui-form-item">
-            <label class="layui-form-label">入口密码</label>
-            <div class="layui-input-inline">
-                <input id="login_pass" autocomplete="off" placeholder="请输入" class="layui-input" type="text">
-            </div>
-            <div class="layui-input-inline" style="width: 60px;">
-                <button type="button" class="layui-btn layui-btn-xs" style="margin-top: 8px;"
-                        onclick="$('#login_pass').val(randomPassword(20))">随机
-                </button>
-            </div>
-        </div>
-    </form>
-
     <script>
     <script>
         layui.use(['layer', 'form'], function () {
         layui.use(['layer', 'form'], function () {
             var layer = layui.layer,
             var layer = layui.layer,
@@ -147,59 +74,6 @@
                 });
                 });
             });
             });
         });
         });
-
-    </script>
-    <script>
-        function set_pass() {
-            var fromobj = $('#setForm');
-            layer.open({
-                type: 1,
-                title: '设置安全入口',
-                area: ['450px', '180px'],
-                id: 'layerDemo', //防止重复弹出
-                content: fromobj,
-                btn: ['提交', '关闭'],
-                btnAlign: 'r', //按钮居中
-                yes: function (index, layero) {
-                    save_pass();
-                }, btn2: function (index) {
-                }, zIndex: 999 //重点1
-            });
-        }
-
-        function save_pass() {
-            var login_pass = $("#login_pass").val();
-            var aliases = login_pass == "" ? "admin_login" : "admin_login/" + login_pass + "$";
-            layer.confirm("确定修改?", function (index) {
-                $.ajax({
-                    url: "{:url('admin/urlsconfig/publish')}",
-                    data: {
-                        id: 1,
-                        status: 1,
-                        url: "admin/common/login",
-                        desc: "后台登录地址",
-                        aliases: aliases
-                    },
-                    dataType: 'json',
-                    type: 'post',
-                    success: function (res) {
-                        if (res.code == 1) {
-                            var text = "设置成功,请保存新的登录地址:<br/> {:url('/', '', false, true)}admin_login/" + login_pass;
-                            layer.alert(text, {icon: 1}, function (index) {
-                                layer.confirm('立即重新登录?', function (index) {
-                                    window.parent.document.getElementById('logout').click();
-                                }, function (index) {
-                                    location.reload()
-                                })
-                            })
-                        }else{
-                            layer.msg(res.msg);
-                        }
-                    }
-                })
-            })
-            return false;
-        }
     </script>
     </script>
 </div>
 </div>
 </body>
 </body>

+ 6 - 1
app/admin/view/webconfig/index.html

@@ -118,6 +118,11 @@
                         onclick="$('#login_pass').val(randomPassword(20))">随机
                         onclick="$('#login_pass').val(randomPassword(20))">随机
                 </button>
                 </button>
             </div>
             </div>
+
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label"></label>
+            <div class="layui-form-mid layui-word-aux">置空则表示清除安全入口</div>
         </div>
         </div>
     </form>
     </form>
 
 
@@ -155,7 +160,7 @@
             layer.open({
             layer.open({
                 type: 1,
                 type: 1,
                 title: '设置安全入口',
                 title: '设置安全入口',
-                area: ['450px', '180px'],
+                area: ['450px', '220px'],
                 id: 'layerDemo', //防止重复弹出
                 id: 'layerDemo', //防止重复弹出
                 content: fromobj,
                 content: fromobj,
                 btn: ['提交', '关闭'],
                 btn: ['提交', '关闭'],

+ 4 - 3
app/admin/view/webconfig/tab.html

@@ -1,11 +1,12 @@
 <div class="layui-tab">
 <div class="layui-tab">
     <ul class="layui-tab-title">
     <ul class="layui-tab-title">
-        <li {eq name="$Request.baseUrl" value=":url('admin/webconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/webconfig/index')}" class="a_menu">系统设置</a></li>
-        <li {eq name="$Request.baseUrl" value=":url('admin/emailconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/emailconfig/index')}" class="a_menu">邮件配置</a></li>
-        <li {eq name="$Request.baseUrl" value=":url('admin/smsconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/smsconfig/index')}" class="a_menu">短信配置</a></li>
+        <li {eq name="$Request.baseUrl" value=":url('admin/webconfig/appointmentConfig')"}class="layui-this"{/eq}><a href="{:url('admin/webconfig/appointmentConfig')}" class="a_menu">预约签到设置</a></li>
         <!--扩展配置-->
         <!--扩展配置-->
         {foreach $tabs as $tab}
         {foreach $tabs as $tab}
         <li {if condition="$Request.baseUrl==url('admin/config/indexWebconfig') && $Request.param.tab_id==$tab->id"}class="layui-this"{/if}><a href="{:url('admin/config/indexWebconfig')}?tab_id={$tab.id}" class="a_menu">{$tab.name}</a></li>
         <li {if condition="$Request.baseUrl==url('admin/config/indexWebconfig') && $Request.param.tab_id==$tab->id"}class="layui-this"{/if}><a href="{:url('admin/config/indexWebconfig')}?tab_id={$tab.id}" class="a_menu">{$tab.name}</a></li>
         {/foreach}
         {/foreach}
+        <li {eq name="$Request.baseUrl" value=":url('admin/webconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/webconfig/index')}" class="a_menu">系统设置</a></li>
+        <li {eq name="$Request.baseUrl" value=":url('admin/emailconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/emailconfig/index')}" class="a_menu">邮件配置</a></li>
+        <li {eq name="$Request.baseUrl" value=":url('admin/smsconfig/index')"}class="layui-this"{/eq}><a href="{:url('admin/smsconfig/index')}" class="a_menu">短信配置</a></li>
     </ul>
     </ul>
 </div>
 </div>

+ 48 - 0
app/api/controller/Announcement.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace app\api\controller;
+
+use app\api\controller\base\Base;
+use time\DateHelper;
+
+class Announcement extends Base
+{
+    private function getModel()
+    {
+        return new \app\common\model\Announcement();
+    }
+
+    public function index()
+    {
+        $post = $this->request->param();
+        $validate = new \think\Validate([
+            ['id', 'number'],
+            ['page', 'number'],
+            ['pagenum', 'number|<=:1000']
+        ]);
+        if (!$validate->check($post)) {
+            $this->json_error('提交失败:' . $validate->getError());
+        }
+
+        $where = [];
+        if (isset($post['id'])) {
+            $where['id'] = $post['id'];
+        }
+
+        if (isset($post['id'])) {
+            $datalist = ($this->getModel())->where($where)->find();
+        } else {
+            $pagenum = $this->request->param('pagenum', 20, 'intval');
+            $datalist = ($this->getModel())->where($where)->order('id desc')->paginate($pagenum, true);
+            foreach ($datalist as $key => $item) {
+                $item['create_day'] = DateHelper::dateFormat($item->getData('create_time'), 'Y-m-d');
+                $datalist[$key] = $item;
+            }
+        }
+        if (empty($datalist)) {
+            $this->json_error("没有数据");
+        }
+        $this->json_success("查询成功", $datalist);
+    }
+
+}

+ 1 - 1
app/api/controller/Common.php

@@ -43,7 +43,7 @@ class Common extends Base
             ['unionid', 'max:50'],
             ['unionid', 'max:50'],
             ['nickname|昵称', 'max:50'],
             ['nickname|昵称', 'max:50'],
             ['head_pic|头像', 'max:255'],
             ['head_pic|头像', 'max:255'],
-            ['sex|性别', 'in:1,2'],
+            ['sex|性别', 'in:0,1,2'],
             ['country|国家', 'max:50'],
             ['country|国家', 'max:50'],
             ['province|省份', 'max:50'],
             ['province|省份', 'max:50'],
             ['city|城市', 'max:50'],
             ['city|城市', 'max:50'],

+ 43 - 0
app/api/controller/Specialist.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace app\api\controller;
+
+use app\api\controller\base\Base;
+
+class Specialist extends Base
+{
+    private function getModel()
+    {
+        return new \app\common\model\Specialist();
+    }
+
+    public function index()
+    {
+        $post = $this->request->param();
+        $validate = new \think\Validate([
+            ['id', 'number'],
+            ['page', 'number'],
+            ['pagenum', 'number|<=:1000']
+        ]);
+        if (!$validate->check($post)) {
+            $this->json_error('提交失败:' . $validate->getError());
+        }
+
+        $where = [];
+        if (isset($post['id'])) {
+            $where['id'] = $post['id'];
+        }
+
+        if (isset($post['id'])) {
+            $datalist = ($this->getModel())->where($where)->find();
+        } else {
+            $pagenum = $this->request->param('pagenum', 20, 'intval');
+            $datalist = ($this->getModel())->where($where)->paginate($pagenum, true);
+        }
+        if (empty($datalist)) {
+            $this->json_error("没有数据");
+        }
+        $this->json_success("查询成功", $datalist);
+    }
+
+}

+ 2 - 2
app/api/controller/User.php

@@ -36,9 +36,9 @@ class User extends Permissions
         $post['user_id'] = $this->getUserId();
         $post['user_id'] = $this->getUserId();
         $res = $model->allowField(true)->save($post);
         $res = $model->allowField(true)->save($post);
         if ($res) {
         if ($res) {
-            $this->json_success("创建成功", $model);
+            $this->json_success("成功");
         } else {
         } else {
-            $this->json_error("创建失败");
+            $this->json_error("失败");
         }
         }
     }
     }
 }
 }

+ 90 - 2
app/api/controller/接口文档.md

@@ -1,7 +1,7 @@
 # 登入接口
 # 登入接口
 接口地址:/api/common/login
 接口地址:/api/common/login
 
 
-请求方式:get
+请求方式:跳转地址方式
 
 
 请求数据:
 请求数据:
 
 
@@ -19,12 +19,13 @@
 # 提交反馈接口
 # 提交反馈接口
 接口地址:/api/user/feedback
 接口地址:/api/user/feedback
 
 
-请求方式:get / post
+请求方式:post
 
 
 请求数据:
 请求数据:
 
 
 | 参数名 | 说明  | 备注  |
 | 参数名 | 说明  | 备注  |
 | ---   | ---   | ---  |
 | ---   | ---   | ---  |
+| jwt   | 登入令牌 |  必填 |
 | content | 内容 |  max:500 |
 | content | 内容 |  max:500 |
 
 
 
 
@@ -37,3 +38,90 @@
     "data": null // 结果数据,json格式,没数据时为 null
     "data": null // 结果数据,json格式,没数据时为 null
 }
 }
 ```
 ```
+
+
+# 查询公告列表
+接口地址:/api/announcement/index
+
+请求方式:get
+
+请求数据:
+
+| 参数名 | 说明  | 备注  |
+| ---   | ---   | ---  |
+|  page    | 第几页,默认1           |  int   |
+|  pagenum | 每页几条,默认20        |  int,<=1000 |
+
+
+响应数据:(json格式)
+```
+{
+    "code": 1,
+    "err_code": 0,
+    "msg": "查询成功",
+    "time": "1682076315",
+    "data": {
+        "per_page": 20, //分页数
+        "current_page": 1, //当前页码
+        "has_more": false, //是否还有下一页
+        "next_item": null, //下一条数据
+        "data": [
+            {
+                "id": 1,
+                "title": "联系我们",
+                "content": "<p>我们的地址是 xxx 市区 xxx 街道 xxx 号<\/p><p><br\/><\/p><p><img src=\"http:\/\/local.appointment.com\/static\/public\/images\/tx.jpg\" style=\"max-width:100%;\"\/><br\/><\/p>",
+                "admin_id": 1,
+                "create_time": "2023-04-20 23:48:32"
+            },
+            {
+                "id": 2,
+                "title": "测试",
+                "content": "<p>测试<img src=\"\/uploads\/admin\/article_content\/20230421\/ee2a2b125a3c174e11683530a931a69e.jpg\" style=\"max-width: 100%;\"\/><\/p>",
+                "admin_id": 2,
+                "create_time": "2023-04-21 18:58:00"
+            }
+        ]
+    }
+}
+```
+
+# 查询专家列表
+接口地址:/api/specialist/index
+
+请求方式:get / post
+
+请求数据:
+
+| 参数名 | 说明  | 备注  |
+| ---   | ---   | ---  |
+|  page    | 第几页,默认1           |  int   |
+|  pagenum | 每页几条,默认20        |  int,<=:1000 |
+
+
+响应数据:(json格式)
+```
+{
+    "code": 1,
+    "err_code": 0,
+    "msg": "查询成功",
+    "time": "1682090806",
+    "data": {
+        "per_page": 20,
+        "current_page": 1,
+        "has_more": false,
+        "next_item": null,
+        "data": [
+            {
+                "id": 1,
+                "name": "张站长", //姓名
+                "title": "心里医生", //职称
+                "head_pic": "6", //头像
+                "sex": 1, //性别
+                "desc": "心里医生",
+                "consultation_direction": "心里医生",
+                "address_id": 1
+            }
+        ]
+    }
+}
+```

+ 1 - 1
app/helper_env.php

@@ -84,7 +84,7 @@ function register_route()
         if (think\Cache::get('vae_route')) {
         if (think\Cache::get('vae_route')) {
             $runtimeRoute = think\Cache::get('vae_route');
             $runtimeRoute = think\Cache::get('vae_route');
         } else {
         } else {
-            $runtimeRoute = \think\Db::name("urlconfig")->where(['status' => 1])->column('aliases,url');
+            $runtimeRoute = \think\Db::name("urlconfig")->where(['status' => 1])->order('id desc')->column('aliases,url');
             think\Cache::set('vae_route', $runtimeRoute);
             think\Cache::set('vae_route', $runtimeRoute);
         }
         }
         if ($runtimeRoute) {
         if ($runtimeRoute) {

+ 2 - 2
app/index/controller/Index.php

@@ -8,9 +8,9 @@
 
 
 namespace app\index\controller;
 namespace app\index\controller;
 
 
-use think\Controller;
+use app\index\controller\base\Base;
 
 
-class Index extends Controller
+class Index extends Base
 {
 {
     public function index()
     public function index()
     {
     {

+ 150 - 0
app/install/controller/Index.php

@@ -0,0 +1,150 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: 中闽 < 1464674022@qq.com >
+ * Date: 2020/2/4
+ * Time: 12:47
+ */
+
+namespace app\install\controller;
+
+use mysqli;
+use think\Controller;
+use think\Env;
+
+class Index extends Controller
+{
+    protected function _initialize()
+    {
+        if (is_installed()) {
+            $this->error('无法重复安装,请删除install.lock才能再次安装!', '/');
+        }
+    }
+
+    public function index()
+    {
+        return $this->fetch('step1');
+    }
+
+    public function step2()
+    {
+        $data['pdo'] = class_exists('pdo') ? 1 : 0;
+        $data['pdo_mysql'] = extension_loaded('pdo_mysql') ? 1 : 0;
+        $data['curl'] = extension_loaded('curl') ? 1 : 0;
+        $data['putenv'] = function_exists('putenv') ? 1 : 0;
+        $data['upload_size'] = ini_get('file_uploads') ? ini_get('upload_max_filesize') : 0;
+        $data['session'] = function_exists('session_start') ? 1 : 0;
+        return $this->fetch('', ['data' => $data]);
+    }
+
+    public function step3()
+    {
+        $this->assign('db_host', Env::get('db_host', '127.0.0.1'));
+        $this->assign('db_port', Env::get('db_port', '3306'));
+        $this->assign('db_name', Env::get('db_name', 'tplay'));
+        $this->assign('db_username', Env::get('db_username', 'root'));
+        $this->assign('db_password', Env::get('db_password', ''));
+        $this->assign('db_prefix', Env::get('db_prefix', 'tplay_'));
+        return $this->fetch();
+    }
+
+
+    private function initEnvConfig($data)
+    {
+        $env_str = "app_debug = false
+app_trace = false
+db_host = {$data['DB_HOST']}
+db_port = {$data['DB_PORT']}
+db_name = {$data['DB_NAME']}
+db_username = {$data['DB_USER']}
+db_password = {$data['DB_PWD']}
+db_prefix = {$data['DB_PREFIX']}";
+
+        if (false == file_put_contents(ROOT_PATH . ".env", $env_str)) {
+            $this->error('创建env配置文件失败,请检查目录权限');
+        }
+    }
+
+    public function createData()
+    {
+        if ($this->request->isPost()) {
+            $data = $this->request->param();
+            $validate = new \think\Validate([
+                ['DB_TYPE|数据库类型', 'require|eq:mysql'],
+                ['DB_HOST|数据库地址', 'require'],
+                ['DB_PORT|数据库端口', 'require'],
+                ['DB_USER|数据库用户名', 'require'],
+//                ['DB_PWD|数据库密码', 'require'],
+                ['DB_NAME|数据库名字', 'require'],
+                ['DB_PREFIX|表前缀', 'require'],
+                ['username|管理员账户', 'require'],
+                ['password|密码', 'require|confirm'],
+            ]);
+            if (!$validate->check($data)) {
+                $this->error('提交失败:' . $validate->getError());
+            }
+
+            // create .env
+            $this->initEnvConfig($data);
+
+            // connect db
+            $link = @new mysqli("{$data['DB_HOST']}:{$data['DB_PORT']}", $data['DB_USER'], $data['DB_PWD']);
+            $error = $link->connect_error;
+            if (!is_null($error)) {
+                // 转义防止和alert中的引号冲突
+                $error = addslashes($error);
+                $this->error('数据库链接失败:' . $error);
+            }
+            $link->query("SET NAMES 'utf8'");
+            if ($link->server_info < 5.0) {
+                $this->error('请将您的mysql升级到5.0以上');
+            }
+
+            if (!$link->select_db($data['DB_NAME'])) {
+                //创建库
+                $create_sql = 'CREATE DATABASE IF NOT EXISTS ' . $data['DB_NAME'] . ' DEFAULT CHARACTER SET utf8;';
+                if (!$link->query($create_sql)) {
+                    $this->error('数据库链接失败');
+                }
+                $link->select_db($data['DB_NAME']);
+            }
+
+            // 导入sql
+            if (file_exists(APP_PATH . 'install/data/db.sql')) {
+                $tplay_sql = file_get_contents(APP_PATH . 'install/data/db.sql');
+            } else {
+                $tplay_sql = file_get_contents(APP_PATH . 'install/data/tplay.sql');
+            }
+
+            $search = [
+                "tplay_",
+                "USE `tplay`",
+                "CREATE DATABASE IF NOT EXISTS `tplay`",
+            ];
+            $replace = [
+                $data['DB_PREFIX'],
+                "USE `" . $data['DB_NAME'] . "`",
+                "CREATE DATABASE IF NOT EXISTS `" . $data['DB_NAME'] . "`",
+            ];
+            $sql_array = preg_split("/;[\r\n]+/", str_replace($search, $replace, $tplay_sql));
+            foreach ($sql_array as $k => $v) {
+                if (!empty($v)) {
+                    $link->query($v);
+                }
+            }
+
+            // create install.lock
+            $salt = random_string();
+            if (false == file_put_contents(ROOT_PATH . "install.lock", "安装鉴定文件,请勿删除,勿修改,勿泄露此文件!!!此次安装时间:" . date('Y-m-d H:i:s', time()) . " - {$salt}")) {
+                $this->error('创建安装鉴定文件失败,请检查目录权限');
+            }
+
+            // update admin password
+            $link->query("UPDATE `{$data['DB_PREFIX']}admin` SET `name` = '{$data['username']}',`password` = '" . password($data['password']) . "' WHERE `id` = 1");
+            $link->close();
+
+            $this->success('安装成功');
+        }
+    }
+}
+

+ 32 - 0
app/install/controller/Init.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: 中闽 < 1464674022@qq.com >
+ * Date: 2020/2/4
+ * Time: 12:47
+ */
+
+namespace app\install\controller;
+
+use file\DirHelper;
+use think\Controller;
+
+class Init extends Controller
+{
+    protected function _initialize()
+    {
+        if (!is_installed()) {
+            $this->error('未找到安裝文件,请重新安装!', '/');
+        }
+    }
+
+    public function delete()
+    {
+        $install_path = APP_PATH . 'install' . DS;
+        DirHelper::delDir($install_path);
+        if (file_exists($install_path)) {
+            $this->error("删除失败,请检查目录权限");
+        }
+        $this->success("删除成功");
+    }
+}

+ 54 - 50
db.sql → app/install/data/db.sql

@@ -39,12 +39,13 @@ CREATE TABLE IF NOT EXISTS `tplay_admin` (
   `create_time` int(11) NOT NULL,
   `create_time` int(11) NOT NULL,
   `update_time` int(11) NOT NULL,
   `update_time` int(11) NOT NULL,
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='管理员';
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='管理员';
 
 
--- 正在导出表  appointment.tplay_admin 的数据:~1 rows (大约)
+-- 正在导出表  appointment.tplay_admin 的数据:~2 rows (大约)
 /*!40000 ALTER TABLE `tplay_admin` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin` DISABLE KEYS */;
 INSERT INTO `tplay_admin` (`id`, `nickname`, `name`, `password`, `thumb`, `login_time`, `login_ip`, `admin_cate_id`, `create_time`, `update_time`) VALUES
 INSERT INTO `tplay_admin` (`id`, `nickname`, `name`, `password`, `thumb`, `login_time`, `login_ip`, `admin_cate_id`, `create_time`, `update_time`) VALUES
-	(1, 'Tplay', 'admin', 'ecb2702e5545cd163a63b128a2cc010c', 0, 1682058086, '127.0.0.1', 1, 1649328230, 1651808242);
+	(1, 'Tplay', 'admin', 'ecb2702e5545cd163a63b128a2cc010c', 0, 1682058086, '127.0.0.1', 1, 1649328230, 1651808242),
+	(2, 'test', 'test', '582833c7a791bae18e77c4151efafc57', 6, 0, '', 2, 1682075579, 1682075579);
 /*!40000 ALTER TABLE `tplay_admin` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_admin_cate 结构
 -- 导出  表 appointment.tplay_admin_cate 结构
@@ -57,12 +58,13 @@ CREATE TABLE IF NOT EXISTS `tplay_admin_cate` (
   `create_time` int(11) NOT NULL,
   `create_time` int(11) NOT NULL,
   `update_time` int(11) NOT NULL,
   `update_time` int(11) NOT NULL,
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='角色';
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='角色';
 
 
--- 正在导出表  appointment.tplay_admin_cate 的数据:~1 rows (大约)
+-- 正在导出表  appointment.tplay_admin_cate 的数据:~2 rows (大约)
 /*!40000 ALTER TABLE `tplay_admin_cate` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin_cate` DISABLE KEYS */;
 INSERT INTO `tplay_admin_cate` (`id`, `name`, `permissions`, `desc`, `create_time`, `update_time`) VALUES
 INSERT INTO `tplay_admin_cate` (`id`, `name`, `permissions`, `desc`, `create_time`, `update_time`) VALUES
-	(1, '超级管理员', '52,87,88,120,121,132,139,141,89,138,46,48,84,85,86,119,144,152,153,154,155,156,111,112,113,114,115,116,127,142,64,66,67,71,118,65,68,69,75,102,103,146,147,33,34,35,76,100,101,143,36,37,38,39,40,98,99,128,22,7,8,24,25,26,91,27,28,29,96,30,97,1,10,12,13,14,15,16,17,148,11,41,42,44,45,106,145,43,105,108,2,3,4,5,51,117,18,19,20,21,57,58,59,130,131,129,133,134,135,136,53,54,55,56,61,122,140,92,94,137,149,150,151,77,78,79,80,81,82,83,110', '', 1649328138, 1682006828);
+	(1, '超级管理员', '52,87,88,120,121,132,139,141,89,138,46,48,84,85,86,119,144,152,153,154,155,156,111,112,113,114,115,116,127,142,64,66,67,71,118,65,68,69,75,102,103,146,147,33,34,35,76,100,101,143,36,37,38,39,40,98,99,128,22,7,8,24,25,26,91,27,28,29,96,30,97,1,10,12,13,14,15,16,17,148,11,41,42,44,45,106,145,43,105,108,2,3,4,5,51,117,18,19,20,21,57,58,59,130,131,129,133,134,135,136,53,54,55,56,61,122,140,92,94,137,149,150,151,77,78,79,80,81,82,83,110', '', 1649328138, 1682006828),
+	(2, '测试', '52,87,88,120,121,132,139,141,152,153,154,155,156,111,112,113,114,115,116,142', '', 1682075047, 1682075310);
 /*!40000 ALTER TABLE `tplay_admin_cate` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin_cate` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_admin_log 结构
 -- 导出  表 appointment.tplay_admin_log 结构
@@ -76,9 +78,9 @@ CREATE TABLE IF NOT EXISTS `tplay_admin_log` (
   `params` varchar(2000) NOT NULL DEFAULT '',
   `params` varchar(2000) NOT NULL DEFAULT '',
   `create_time` int(11) NOT NULL COMMENT '操作时间',
   `create_time` int(11) NOT NULL COMMENT '操作时间',
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=179 DEFAULT CHARSET=utf8 COMMENT='后台日志';
+) ENGINE=InnoDB AUTO_INCREMENT=203 DEFAULT CHARSET=utf8 COMMENT='后台日志';
 
 
--- 正在导出表  appointment.tplay_admin_log 的数据:~119 rows (大约)
+-- 正在导出表  appointment.tplay_admin_log 的数据:~163 rows (大约)
 /*!40000 ALTER TABLE `tplay_admin_log` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin_log` DISABLE KEYS */;
 INSERT INTO `tplay_admin_log` (`id`, `admin_menu_id`, `admin_id`, `ip`, `url`, `params`, `create_time`) VALUES
 INSERT INTO `tplay_admin_log` (`id`, `admin_menu_id`, `admin_id`, `ip`, `url`, `params`, `create_time`) VALUES
 	(1, 77, 1, '127.0.0.1', '/admin/databackup/index.html', '', 1682040980),
 	(1, 77, 1, '127.0.0.1', '/admin/databackup/index.html', '', 1682040980),
@@ -258,7 +260,31 @@ INSERT INTO `tplay_admin_log` (`id`, `admin_menu_id`, `admin_id`, `ip`, `url`, `
 	(175, 10, 1, '127.0.0.1', '/admin/webconfig/index.html', '', 1682062028),
 	(175, 10, 1, '127.0.0.1', '/admin/webconfig/index.html', '', 1682062028),
 	(176, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1&check_permission=true', 'tab_id=1&check_permission=true', 1682062030),
 	(176, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1&check_permission=true', 'tab_id=1&check_permission=true', 1682062030),
 	(177, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1', 'tab_id=1', 1682062030),
 	(177, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1', 'tab_id=1', 1682062030),
-	(178, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1&page=1&limit=15', 'tab_id=1&page=1&limit=15', 1682062031);
+	(178, 0, 1, '127.0.0.1', '/admin/config/indexwebconfig.html?tab_id=1&page=1&limit=15', 'tab_id=1&page=1&limit=15', 1682062031),
+	(179, 10, 1, '127.0.0.1', '/admin/webconfig/index.html', '', 1682073850),
+	(180, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html?check_permission=true', 'check_permission=true', 1682073852),
+	(181, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073853),
+	(182, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073868),
+	(183, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073955),
+	(184, 10, 1, '127.0.0.1', '/admin/webconfig/index.html', '', 1682073967),
+	(185, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html?check_permission=true', 'check_permission=true', 1682073968),
+	(186, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073969),
+	(187, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073988),
+	(188, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682073998),
+	(189, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074006),
+	(190, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074023),
+	(191, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074133),
+	(192, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074163),
+	(193, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074206),
+	(194, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074224),
+	(195, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074238),
+	(196, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074261),
+	(197, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074271),
+	(198, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074345),
+	(199, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074382),
+	(200, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074389),
+	(201, 0, 1, '127.0.0.1', '/admin/webconfig/appointmentconfig.html', '', 1682074499),
+	(202, 11, 1, '127.0.0.1', '/admin/webconfig/publish.html', '上传附件:\\uploads\\admin\\article_content\\20230421\\ee2a2b125a3c174e11683530a931a69e.jpg', 1682074584);
 /*!40000 ALTER TABLE `tplay_admin_log` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin_log` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_admin_menu 结构
 -- 导出  表 appointment.tplay_admin_menu 结构
@@ -285,7 +311,7 @@ CREATE TABLE IF NOT EXISTS `tplay_admin_menu` (
   KEY `function` (`function`) USING BTREE
   KEY `function` (`function`) USING BTREE
 ) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8 COMMENT='系统菜单表';
 ) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8 COMMENT='系统菜单表';
 
 
--- 正在导出表  appointment.tplay_admin_menu 的数据:~138 rows (大约)
+-- 正在导出表  appointment.tplay_admin_menu 的数据:~128 rows (大约)
 /*!40000 ALTER TABLE `tplay_admin_menu` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_admin_menu` DISABLE KEYS */;
 INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`, `parameter`, `description`, `is_display`, `type`, `pid`, `icon`, `is_open`, `orders`, `create_time`, `update_time`) VALUES
 INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`, `parameter`, `description`, `is_display`, `type`, `pid`, `icon`, `is_open`, `orders`, `create_time`, `update_time`) VALUES
 	(1, '系统', '', '', '', '', '系统设置。', 1, 1, 0, 'fa-cog', 0, 10, 0, 1581073013),
 	(1, '系统', '', '', '', '', '系统设置。', 1, 1, 0, 'fa-cog', 0, 10, 0, 1581073013),
@@ -329,8 +355,6 @@ INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`
 	(43, '附件上传', 'admin', 'attachment', 'upload', '', '附件上传。', 2, 1, 41, '', 0, 1, 1516953392, 1516953392),
 	(43, '附件上传', 'admin', 'attachment', 'upload', '', '附件上传。', 2, 1, 41, '', 0, 1, 1516953392, 1516953392),
 	(44, '附件下载', 'admin', 'attachment', 'download', '', '附件下载。', 2, 1, 41, '', 0, 0, 1516953430, 1516953430),
 	(44, '附件下载', 'admin', 'attachment', 'download', '', '附件下载。', 2, 1, 41, '', 0, 0, 1516953430, 1516953430),
 	(45, '附件删除', 'admin', 'attachment', 'delete', '', '附件删除。', 2, 1, 41, '', 0, 0, 1516953477, 1516953477),
 	(45, '附件删除', 'admin', 'attachment', 'delete', '', '附件删除。', 2, 1, 41, '', 0, 0, 1516953477, 1516953477),
-	(46, '消息', 'admin', 'Tomessages', 'index', '', '消息管理。', 2, 1, 87, 'fa-comments', 0, 2, 1516953526, 1681701805),
-	(48, '删除', 'admin', 'Tomessages', 'delete', '', '消息删除。', 2, 1, 46, 'fa-asterisk', 0, 0, 1516953648, 1681701813),
 	(50, '管理员登录', 'admin', 'common', 'login', '', '不可以加入权限路由', 2, 2, 104, 'fa-asterisk', 0, 3, 1516954517, 1645174792),
 	(50, '管理员登录', 'admin', 'common', 'login', '', '不可以加入权限路由', 2, 2, 104, 'fa-asterisk', 0, 3, 1516954517, 1645174792),
 	(51, '排序', 'admin', 'menu', 'orders', '', '系统菜单排序。', 2, 1, 3, '', 0, 0, 1517562047, 1517562047),
 	(51, '排序', 'admin', 'menu', 'orders', '', '系统菜单排序。', 2, 1, 3, '', 0, 0, 1517562047, 1517562047),
 	(52, '网站', 'admin', '', '', '', '', 1, 1, 0, 'fa-send', 1, 0, 1581067786, 1681897704),
 	(52, '网站', 'admin', '', '', '', '', 1, 1, 0, 'fa-send', 1, 0, 1581067786, 1681897704),
@@ -358,12 +382,8 @@ INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`
 	(81, '备份', 'admin', 'Databackup', 'export', '', '', 2, 1, 77, '', 0, 0, 1600938638, 1600938638),
 	(81, '备份', 'admin', 'Databackup', 'export', '', '', 2, 1, 77, '', 0, 0, 1600938638, 1600938638),
 	(82, '修复表', 'admin', 'Databackup', 'repair', '', '', 2, 1, 77, '', 0, 0, 1600938694, 1600938694),
 	(82, '修复表', 'admin', 'Databackup', 'repair', '', '', 2, 1, 77, '', 0, 0, 1600938694, 1600938694),
 	(83, '优化表', 'admin', 'Databackup', 'optimize', '', '', 2, 1, 77, '', 0, 0, 1600938718, 1600938718),
 	(83, '优化表', 'admin', 'Databackup', 'optimize', '', '', 2, 1, 77, '', 0, 0, 1600938718, 1600938718),
-	(84, '审核', 'admin', 'Tomessages', 'status', '', '', 2, 1, 46, '', 0, 0, 1604907214, 1604907214),
-	(85, '新增/编辑', 'admin', 'Tomessages', 'publish', '', '', 2, 1, 46, '', 0, 0, 1604908198, 1604908198),
-	(86, '发送系统消息', 'admin', 'Tomessages', 'sysmessage', '', '', 2, 1, 46, '', 0, 0, 1604908198, 1604908198),
 	(87, '用户', 'admin', 'User', 'index', '', '', 1, 1, 52, 'fa-user', 0, 0, 1604912892, 1681701781),
 	(87, '用户', 'admin', 'User', 'index', '', '', 1, 1, 52, 'fa-user', 0, 0, 1604912892, 1681701781),
 	(88, '新增/修改', 'admin', 'User', 'publish', '', '', 2, 1, 87, 'fa-tag', 0, 0, 1604912952, 1681701787),
 	(88, '新增/修改', 'admin', 'User', 'publish', '', '', 2, 1, 87, 'fa-tag', 0, 0, 1604912952, 1681701787),
-	(89, '积分', 'admin', 'PointLog', 'index', '', '', 2, 1, 87, 'fa-bitcoin', 0, 1, 1604917674, 1681701707),
 	(91, '重置密码', 'admin', 'admin', 'resetpass', '', '', 2, 1, 24, '', 0, 0, 1612342055, 1612342055),
 	(91, '重置密码', 'admin', 'admin', 'resetpass', '', '', 2, 1, 24, '', 0, 0, 1612342055, 1612342055),
 	(92, '代码生成', 'admin', 'CodeGeneration', 'index', '', '', 1, 1, 2, 'fa-asterisk', 0, 0, 1617266817, 1617266817),
 	(92, '代码生成', 'admin', 'CodeGeneration', 'index', '', '', 1, 1, 2, 'fa-asterisk', 0, 0, 1617266817, 1617266817),
 	(94, '生成', 'admin', 'CodeGeneration', 'generation', '', '', 2, 1, 92, '', 0, 0, 1617336327, 1617336327),
 	(94, '生成', 'admin', 'CodeGeneration', 'generation', '', '', 2, 1, 92, '', 0, 0, 1617336327, 1617336327),
@@ -389,14 +409,12 @@ INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`
 	(116, '新增目录', 'admin', 'FileManage', 'createDir', '', '', 2, 1, 111, '', 0, 0, 1623231379, 1623231379),
 	(116, '新增目录', 'admin', 'FileManage', 'createDir', '', '', 2, 1, 111, '', 0, 0, 1623231379, 1623231379),
 	(117, '批量添加', 'admin', 'Menu', 'batchAdd', '', '', 2, 1, 3, '', 0, 0, 1623231501, 1623231501),
 	(117, '批量添加', 'admin', 'Menu', 'batchAdd', '', '', 2, 1, 3, '', 0, 0, 1623231501, 1623231501),
 	(118, '重命名', 'admin', 'Templet', 'rename', '', '', 2, 1, 64, '', 0, 0, 1623231501, 1623231501),
 	(118, '重命名', 'admin', 'Templet', 'rename', '', '', 2, 1, 64, '', 0, 0, 1623231501, 1623231501),
-	(119, '批量删除', 'admin', 'Tomessages', 'deletes', '', '', 2, 1, 46, '', 0, 0, 1623231501, 1623231501),
 	(120, '删除', 'admin', 'User', 'delete', '', '', 2, 1, 87, '', 0, 0, 1623231501, 1623231501),
 	(120, '删除', 'admin', 'User', 'delete', '', '', 2, 1, 87, '', 0, 0, 1623231501, 1623231501),
 	(121, '修改积分', 'admin', 'User', 'setPoint', '', '', 2, 1, 87, '', 0, 0, 1623231501, 1623231501),
 	(121, '修改积分', 'admin', 'User', 'setPoint', '', '', 2, 1, 87, '', 0, 0, 1623231501, 1623231501),
 	(122, '排序', 'admin', 'ConfigOption', 'sort', '', '', 2, 1, 53, '', 0, 0, 1623231782, 1623231782),
 	(122, '排序', 'admin', 'ConfigOption', 'sort', '', '', 2, 1, 53, '', 0, 0, 1623231782, 1623231782),
 	(123, '首页', 'admin', 'Main', 'index', '', '', 2, 2, 104, '', 0, 0, 1623231782, 1623231782),
 	(123, '首页', 'admin', 'Main', 'index', '', '', 2, 2, 104, '', 0, 0, 1623231782, 1623231782),
 	(124, '清理缓存', 'admin', 'Main', 'clear', '', '', 2, 2, 104, 'fa-asterisk', 0, 0, 1623231782, 1645173920),
 	(124, '清理缓存', 'admin', 'Main', 'clear', '', '', 2, 2, 104, 'fa-asterisk', 0, 0, 1623231782, 1645173920),
 	(126, '后台布局', 'admin', 'Index', 'index', '', '', 2, 2, 104, '', 0, 0, 1623232537, 1623232537),
 	(126, '后台布局', 'admin', 'Index', 'index', '', '', 2, 2, 104, '', 0, 0, 1623232537, 1623232537),
-	(127, '发布到远程', 'admin', 'FileManage', 'ftpCover', '', '', 2, 1, 111, '', 0, 0, 1624613010, 1624613010),
 	(128, '重新生成', 'admin', 'Article', 'createFile', '', '', 2, 1, 36, 'fa-asterisk', 0, 0, 1629975856, 1629975856),
 	(128, '重新生成', 'admin', 'Article', 'createFile', '', '', 2, 1, 36, 'fa-asterisk', 0, 0, 1629975856, 1629975856),
 	(129, '配置组标签', 'admin', 'ConfigTab', 'index', '', '', 2, 1, 57, 'fa-asterisk', 0, 1, 1629975856, 1629975856),
 	(129, '配置组标签', 'admin', 'ConfigTab', 'index', '', '', 2, 1, 57, 'fa-asterisk', 0, 1, 1629975856, 1629975856),
 	(130, '排序', 'admin', 'Config', 'sort', '', '', 2, 1, 57, 'fa-asterisk', 0, 0, 1629975856, 1629975856),
 	(130, '排序', 'admin', 'Config', 'sort', '', '', 2, 1, 57, 'fa-asterisk', 0, 0, 1629975856, 1629975856),
@@ -407,13 +425,11 @@ INSERT INTO `tplay_admin_menu` (`id`, `name`, `module`, `controller`, `function`
 	(135, '排序', 'admin', 'ConfigTab', 'sort', '', '', 2, 1, 129, 'fa-asterisk', 0, 0, 1629975894, 1629975894),
 	(135, '排序', 'admin', 'ConfigTab', 'sort', '', '', 2, 1, 129, 'fa-asterisk', 0, 0, 1629975894, 1629975894),
 	(136, '审核', 'admin', 'ConfigTab', 'status', '', '', 2, 1, 129, 'fa-asterisk', 0, 0, 1629975894, 1629975894),
 	(136, '审核', 'admin', 'ConfigTab', 'status', '', '', 2, 1, 129, 'fa-asterisk', 0, 0, 1629975894, 1629975894),
 	(137, '获取表字段信息', 'admin', 'CodeGeneration', 'getFieldsInfo', '', '', 2, 1, 92, 'fa-asterisk', 0, 0, 1645172736, 1645172736),
 	(137, '获取表字段信息', 'admin', 'CodeGeneration', 'getFieldsInfo', '', '', 2, 1, 92, 'fa-asterisk', 0, 0, 1645172736, 1645172736),
-	(138, '批量删除', 'admin', 'PointLog', 'deletes', '', '', 2, 1, 89, 'fa-asterisk', 0, 0, 1645172736, 1645172736),
 	(139, '设置会员', 'admin', 'User', 'setVips', '', '', 2, 1, 87, 'fa-asterisk', 0, 0, 1645172736, 1645172736),
 	(139, '设置会员', 'admin', 'User', 'setVips', '', '', 2, 1, 87, 'fa-asterisk', 0, 0, 1645172736, 1645172736),
 	(140, '单选开关', 'admin', 'ConfigOption', 'single_status', '', '', 2, 1, 53, 'fa-asterisk', 0, 0, 1645180213, 1645180213),
 	(140, '单选开关', 'admin', 'ConfigOption', 'single_status', '', '', 2, 1, 53, 'fa-asterisk', 0, 0, 1645180213, 1645180213),
 	(141, '审核', 'admin', 'User', 'status', '', '', 2, 1, 87, 'fa-asterisk', 0, 0, 1650266964, 1650266964),
 	(141, '审核', 'admin', 'User', 'status', '', '', 2, 1, 87, 'fa-asterisk', 0, 0, 1650266964, 1650266964),
 	(142, '解压', 'admin', 'FileManage', 'unzip', '', '', 2, 1, 111, 'fa-asterisk', 0, 0, 1650593397, 1650593397),
 	(142, '解压', 'admin', 'FileManage', 'unzip', '', '', 2, 1, 111, 'fa-asterisk', 0, 0, 1650593397, 1650593397),
 	(143, '更新treepath', 'admin', 'Articlecate', 'updateTreePath', '', '', 2, 1, 33, 'fa-asterisk', 0, 0, 1655952413, 1670839553),
 	(143, '更新treepath', 'admin', 'Articlecate', 'updateTreePath', '', '', 2, 1, 33, 'fa-asterisk', 0, 0, 1655952413, 1670839553),
-	(144, '阅读状态', 'admin', 'Tomessages', 'look', '', '', 2, 1, 46, 'fa-asterisk', 0, 0, 1655952414, 1655952414),
 	(145, '批量删除', 'admin', 'Attachment', 'deletes', '', '', 2, 1, 41, 'fa-asterisk', 0, 0, 1655952465, 1655952465),
 	(145, '批量删除', 'admin', 'Attachment', 'deletes', '', '', 2, 1, 41, 'fa-asterisk', 0, 0, 1655952465, 1655952465),
 	(146, '审核', 'admin', 'Catalog', 'status', '', '', 2, 1, 65, 'fa-tag', 0, 0, 1670839160, 1670839160),
 	(146, '审核', 'admin', 'Catalog', 'status', '', '', 2, 1, 65, 'fa-tag', 0, 0, 1670839160, 1670839160),
 	(147, '更新treepath', 'admin', 'Catalog', 'updateTreePath', '', '', 2, 1, 65, 'fa-tag', 0, 0, 1670839160, 1670839160),
 	(147, '更新treepath', 'admin', 'Catalog', 'updateTreePath', '', '', 2, 1, 65, 'fa-tag', 0, 0, 1670839160, 1670839160),
@@ -434,15 +450,16 @@ CREATE TABLE IF NOT EXISTS `tplay_announcement` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
   `title` varchar(50) NOT NULL DEFAULT '' COMMENT '标题',
   `content` varchar(5000) NOT NULL DEFAULT '' COMMENT '内容',
   `content` varchar(5000) NOT NULL DEFAULT '' COMMENT '内容',
-  `admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '发布人',
+  `admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '创建人',
   `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '日期',
   `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '日期',
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='公告表';
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='公告表';
 
 
--- 正在导出表  appointment.tplay_announcement 的数据:~1 rows (大约)
+-- 正在导出表  appointment.tplay_announcement 的数据:~2 rows (大约)
 /*!40000 ALTER TABLE `tplay_announcement` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_announcement` DISABLE KEYS */;
 INSERT INTO `tplay_announcement` (`id`, `title`, `content`, `admin_id`, `create_time`) VALUES
 INSERT INTO `tplay_announcement` (`id`, `title`, `content`, `admin_id`, `create_time`) VALUES
-	(1, '联系我们', '<p>我们的地址是 xxx 市区 xxx 街道 xxx 号</p><p><br/></p><p><img src="http://local.appointment.com/static/public/images/tx.jpg" style="max-width:100%;"/><br/></p>', 0, 1682005712);
+	(1, '联系我们', '<p>我们的地址是 xxx 市区 xxx 街道 xxx 号</p><p><br/></p><p><img src="http://local.appointment.com/static/public/images/tx.jpg" style="max-width:100%;"/><br/></p>', 1, 1682005712),
+	(2, '测试', '<p>测试<img src="/uploads/admin/article_content/20230421/ee2a2b125a3c174e11683530a931a69e.jpg" style="max-width: 100%;"/></p>', 2, 1682074680);
 /*!40000 ALTER TABLE `tplay_announcement` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_announcement` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_appointment 结构
 -- 导出  表 appointment.tplay_appointment 结构
@@ -566,16 +583,17 @@ CREATE TABLE IF NOT EXISTS `tplay_attachment` (
   `download` int(11) NOT NULL DEFAULT '0' COMMENT '下载量',
   `download` int(11) NOT NULL DEFAULT '0' COMMENT '下载量',
   `create_time` int(11) unsigned NOT NULL DEFAULT '0',
   `create_time` int(11) unsigned NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='附件表';
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='附件表';
 
 
--- 正在导出表  appointment.tplay_attachment 的数据:~5 rows (大约)
+-- 正在导出表  appointment.tplay_attachment 的数据:~6 rows (大约)
 /*!40000 ALTER TABLE `tplay_attachment` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_attachment` DISABLE KEYS */;
 INSERT INTO `tplay_attachment` (`id`, `module`, `filename`, `filepath`, `filesize`, `fileext`, `user_id`, `uploadip`, `status`, `admin_id`, `audit_time`, `use`, `download`, `create_time`) VALUES
 INSERT INTO `tplay_attachment` (`id`, `module`, `filename`, `filepath`, `filesize`, `fileext`, `user_id`, `uploadip`, `status`, `admin_id`, `audit_time`, `use`, `download`, `create_time`) VALUES
 	(3, 'admin', 'tx.jpg', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%872&fg=666666&bg=cccccc', 0, 'jpg', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 0, 1682058779),
 	(3, 'admin', 'tx.jpg', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%872&fg=666666&bg=cccccc', 0, 'jpg', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 0, 1682058779),
 	(4, 'admin', '879x200?fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%871&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 1, 1682058974),
 	(4, 'admin', '879x200?fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%871&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 1, 1682058974),
 	(5, 'admin', '?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%873&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%873&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 0, 1682059505),
 	(5, 'admin', '?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%873&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E8%BD%AE%E6%92%AD%E5%9B%BE%E7%89%873&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\1', 0, 1682059505),
 	(6, 'admin', '?text=%E5%BF%83%E9%87%8C%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E5%BF%83%E9%87%8C%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\2', 0, 1682059751),
 	(6, 'admin', '?text=%E5%BF%83%E9%87%8C%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E5%BF%83%E9%87%8C%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\2', 0, 1682059751),
-	(7, 'admin', '?text=%E6%B3%95%E5%BE%8B%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E6%B3%95%E5%BE%8B%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\2', 0, 1682059794);
+	(7, 'admin', '?text=%E6%B3%95%E5%BE%8B%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 'https://iph.href.lu/400x200/?text=%E6%B3%95%E5%BE%8B%E5%92%A8%E8%AF%A2&fg=666666&bg=cccccc', 0, 'webp', 1, '127.0.0.1', 1, 0, 0, 'admin\\config_option\\publish\\pid\\2', 0, 1682059794),
+	(8, 'admin', 'ee2a2b125a3c174e11683530a931a69e.jpg', '\\uploads\\admin\\article_content\\20230421\\ee2a2b125a3c174e11683530a931a69e.jpg', 106558, 'jpg', 1, '127.0.0.1', 1, 1, 1682074697, 'article_content', 0, 1682074697);
 /*!40000 ALTER TABLE `tplay_attachment` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_attachment` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_catalog 结构
 -- 导出  表 appointment.tplay_catalog 结构
@@ -760,23 +778,6 @@ CREATE TABLE IF NOT EXISTS `tplay_point_log` (
 /*!40000 ALTER TABLE `tplay_point_log` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_point_log` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_point_log` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_point_log` ENABLE KEYS */;
 
 
--- 导出  表 appointment.tplay_service_provider 结构
-DROP TABLE IF EXISTS `tplay_service_provider`;
-CREATE TABLE IF NOT EXISTS `tplay_service_provider` (
-  `id` int(11) NOT NULL AUTO_INCREMENT,
-  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名字',
-  `head_pic` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
-  `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别',
-  `desc` varchar(500) NOT NULL DEFAULT '' COMMENT '简介',
-  `consultation_direction` varchar(500) NOT NULL DEFAULT '' COMMENT '咨询方向',
-  `address_id` int(11) NOT NULL COMMENT '地址',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务人员';
-
--- 正在导出表  appointment.tplay_service_provider 的数据:~0 rows (大约)
-/*!40000 ALTER TABLE `tplay_service_provider` DISABLE KEYS */;
-/*!40000 ALTER TABLE `tplay_service_provider` ENABLE KEYS */;
-
 -- 导出  表 appointment.tplay_smsconfig 结构
 -- 导出  表 appointment.tplay_smsconfig 结构
 DROP TABLE IF EXISTS `tplay_smsconfig`;
 DROP TABLE IF EXISTS `tplay_smsconfig`;
 CREATE TABLE IF NOT EXISTS `tplay_smsconfig` (
 CREATE TABLE IF NOT EXISTS `tplay_smsconfig` (
@@ -802,16 +803,19 @@ DROP TABLE IF EXISTS `tplay_specialist`;
 CREATE TABLE IF NOT EXISTS `tplay_specialist` (
 CREATE TABLE IF NOT EXISTS `tplay_specialist` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名字',
   `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名字',
+  `title` varchar(50) NOT NULL DEFAULT '' COMMENT '职称',
   `head_pic` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
   `head_pic` varchar(255) NOT NULL DEFAULT '' COMMENT '头像',
   `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别',
   `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别',
   `desc` varchar(500) NOT NULL DEFAULT '' COMMENT '简介',
   `desc` varchar(500) NOT NULL DEFAULT '' COMMENT '简介',
   `consultation_direction` varchar(500) NOT NULL DEFAULT '' COMMENT '咨询方向',
   `consultation_direction` varchar(500) NOT NULL DEFAULT '' COMMENT '咨询方向',
-  `address_id` int(11) NOT NULL COMMENT '地址',
+  `address_id` int(11) NOT NULL COMMENT '地址id',
   PRIMARY KEY (`id`)
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='专家';
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='专家';
 
 
--- 正在导出表  appointment.tplay_specialist 的数据:~0 rows (大约)
+-- 正在导出表  appointment.tplay_specialist 的数据:~1 rows (大约)
 /*!40000 ALTER TABLE `tplay_specialist` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_specialist` DISABLE KEYS */;
+INSERT INTO `tplay_specialist` (`id`, `name`, `title`, `head_pic`, `sex`, `desc`, `consultation_direction`, `address_id`) VALUES
+	(1, '张站长', '心里医生', '6', 1, '心里医生', '心里医生', 1);
 /*!40000 ALTER TABLE `tplay_specialist` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_specialist` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_urlconfig 结构
 -- 导出  表 appointment.tplay_urlconfig 结构
@@ -830,7 +834,7 @@ CREATE TABLE IF NOT EXISTS `tplay_urlconfig` (
 -- 正在导出表  appointment.tplay_urlconfig 的数据:~1 rows (大约)
 -- 正在导出表  appointment.tplay_urlconfig 的数据:~1 rows (大约)
 /*!40000 ALTER TABLE `tplay_urlconfig` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_urlconfig` DISABLE KEYS */;
 INSERT INTO `tplay_urlconfig` (`id`, `aliases`, `url`, `desc`, `status`, `create_time`, `update_time`) VALUES
 INSERT INTO `tplay_urlconfig` (`id`, `aliases`, `url`, `desc`, `status`, `create_time`, `update_time`) VALUES
-	(1, 'admin_login/6xy8h3PBxycrCsBj4pI8$', 'admin/common/login', '后台登录地址', 1, 1517621629, 1681894088);
+	(1, 'admin_login', 'admin/common/login', '后台登录地址', 1, 1517621629, 1681894088);
 /*!40000 ALTER TABLE `tplay_urlconfig` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_urlconfig` ENABLE KEYS */;
 
 
 -- 导出  表 appointment.tplay_user 结构
 -- 导出  表 appointment.tplay_user 结构
@@ -862,7 +866,7 @@ CREATE TABLE IF NOT EXISTS `tplay_user` (
   PRIMARY KEY (`id`) USING BTREE
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户表';
 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户表';
 
 
--- 正在导出表  appointment.tplay_user 的数据:~0 rows (大约)
+-- 正在导出表  appointment.tplay_user 的数据:~1 rows (大约)
 /*!40000 ALTER TABLE `tplay_user` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_user` DISABLE KEYS */;
 INSERT INTO `tplay_user` (`id`, `pid`, `passport`, `nickname`, `password`, `user_type`, `user_cate`, `level`, `head_pic`, `point`, `money`, `status`, `ip`, `remark`, `stop_time`, `create_time`, `login_time`, `openid`, `unionid`, `sex`, `country`, `province`, `city`) VALUES
 INSERT INTO `tplay_user` (`id`, `pid`, `passport`, `nickname`, `password`, `user_type`, `user_cate`, `level`, `head_pic`, `point`, `money`, `status`, `ip`, `remark`, `stop_time`, `create_time`, `login_time`, `openid`, `unionid`, `sex`, `country`, `province`, `city`) VALUES
 	(1, 0, '111', '111', '', 1, 0, 0, '1111', 0, 0, 1, '127.0.0.1', '', 0, 1682071180, 1682071180, '', '', 0, '', '', '');
 	(1, 0, '111', '111', '', 1, 0, 0, '1111', 0, 0, 1, '127.0.0.1', '', 0, 1682071180, 1682071180, '', '', 0, '', '', '');
@@ -887,7 +891,7 @@ CREATE TABLE IF NOT EXISTS `tplay_webconfig` (
 -- 正在导出表  appointment.tplay_webconfig 的数据:~1 rows (大约)
 -- 正在导出表  appointment.tplay_webconfig 的数据:~1 rows (大约)
 /*!40000 ALTER TABLE `tplay_webconfig` DISABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_webconfig` DISABLE KEYS */;
 INSERT INTO `tplay_webconfig` (`id`, `name`, `is_log`, `is_close_site`, `file_type`, `file_size`, `black_ip`, `article_editor`, `break_the_promise_times`, `stop_appointment_day`) VALUES
 INSERT INTO `tplay_webconfig` (`id`, `name`, `is_log`, `is_close_site`, `file_type`, `file_size`, `black_ip`, `article_editor`, `break_the_promise_times`, `stop_appointment_day`) VALUES
-	(1, '咨询预约', 1, 0, 'jpg,png,gif,mp4,zip,jpeg,html', 1024, '', 'wangEditor', 0, 0);
+	(1, '咨询预约', 0, 0, 'jpg,png,gif,mp4,zip,jpeg,html', 1024, '', 'wangEditor', 1, 2);
 /*!40000 ALTER TABLE `tplay_webconfig` ENABLE KEYS */;
 /*!40000 ALTER TABLE `tplay_webconfig` ENABLE KEYS */;
 
 
 /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
 /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;

+ 44 - 0
app/install/view/index/step1.html

@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>安装引导</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link rel="stylesheet" href="/static/public/layui/css/layui.css" media="all">
+</head>
+<body>
+<div style="width:800px;margin: 100px auto;">
+    <div class="layui-layout layui-layout-admin">
+        <div class="layui-header layui-bg-cyan">
+            <div class="layui-logo" style="color: #fff">{:systemName()} 安装引导</div>
+            <ul class="layui-nav layui-layout-right">
+                <li class="layui-nav-item">{$Think.const.PRODUCT_VERSION}</li>
+        </div>
+        <div style="border:1px solid #eee;padding:20px;line-height: 25px;">
+            <p>
+                欢迎使用{:systemName()},{:systemName()}搭载了ThinkPHP5和Layui,是一款轻量级、高速度的PHP内容管理系统。<br>
+                您在使用中如有任何问题都可以登录{:systemName()}官方网站获取帮助。<br><br>
+                开源协议:<br>
+                {:systemName()}遵循Apache Lisense 2.0开源协议发布,并提供免费使用。<br>
+                Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,允许代码修改,再作为开源或商业软件发布。需要满足的条件:<br>
+                1、需要给用户一份Apache Licence<br>
+                2、如果你修改了代码,需要在被修改的文件中说明<br>
+                3、在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明<br>
+                4、如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有本协议内容。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。<br><br>
+                免责声明:<br>
+                1、使用{:systemName()}构建的网站的任何信息内容以及导致的任何版权纠纷和法律争议及后果,{:systemName()}官方不承担任何责任。<br>
+                2、您一旦安装使用{:systemName()},即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时,受到相关的约束和限制。
+            </p>
+            <div style="margin:10px auto;width: 90px;">
+                <a href="{:url('install/index/step2')}" class="layui-btn layui-bg-cyan">接受协议</a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="/static/public/layui/layui.js" charset="utf-8"></script>
+
+</body>
+</html>

+ 180 - 0
app/install/view/index/step2.html

@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>安装引导</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link rel="stylesheet" href="/static/public/layui/css/layui.css" media="all">
+</head>
+<style>
+    .layui-icon-close {
+        color: red;
+        font-weight: bold;
+    }
+</style>
+<body>
+<div style="width:800px;margin: 100px auto;">
+    <div class="layui-layout layui-layout-admin">
+        <div class="layui-header layui-bg-cyan">
+            <div class="layui-logo" style="color: #fff">{:systemName()} 安装引导</div>
+            <ul class="layui-nav layui-layout-right">
+                <li class="layui-nav-item">{$Think.const.PRODUCT_VERSION}</li>
+        </div>
+        <div style="border:1px solid #eee;padding:20px;line-height: 25px;">
+            <h3>环境检测</h3>
+            <table class="layui-table" lay-skin="nob" lay-size="sm">
+                <colgroup>
+                    <col width="150">
+                    <col width="200">
+                    <col width="200">
+                    <col width="100">
+                    <col>
+                </colgroup>
+                <thead>
+                <tr>
+                    <th>环境</th>
+                    <th>最低配置</th>
+                    <th>当前配置</th>
+                    <th>是否符合</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>操作系统</td>
+                    <td>不限</td>
+                    <td><?php echo php_uname('s'); ?></td>
+                    <td class="yes"><i class="layui-icon layui-icon-ok"></i></td>
+                </tr>
+                <tr>
+                    <td>php版本</td>
+                    <td>7 ~ 7.2.*</td>
+                    <td><?php echo PHP_VERSION ?></td>
+                    <?php $php_version=explode('.', PHP_VERSION); ?>
+                    <td>
+                        {if condition="$php_version[0] >=7 && $php_version[1] < 3"}
+                        <i class="layui-icon layui-icon-ok yes"></i>
+                        {else/}
+                        <i class="layui-icon layui-icon-close"></i>
+                        {/if}
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+            <h3>模块检测</h3>
+            <table class="layui-table" lay-skin="nob" lay-size="sm">
+                <colgroup>
+                    <col width="150">
+                    <col width="200">
+                    <col width="200">
+                    <col width="100">
+                    <col>
+                </colgroup>
+                <thead>
+                <tr>
+                    <th>环境</th>
+                    <th>最低配置</th>
+                    <th>当前配置</th>
+                    <th>是否符合</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>session</td>
+                    <td>支持</td>
+                    <td>{eq name="$data.session" value="1"}支持{else /}不支持{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.session" value="1"}layui-icon-ok yes{else
+                        /}layui-icon-close{/eq}"></i></td>
+                </tr>
+                <tr>
+                    <td>pdo</td>
+                    <td>开启</td>
+                    <td>{eq name="$data.pdo" value="1"}已开启{else /}未开启{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.pdo" value="1"}layui-icon-ok yes{else
+                        /}layui-icon-close{/eq}"></i></td>
+                </tr>
+                <tr>
+                    <td>pdo_mysql</td>
+                    <td>开启</td>
+                    <td>{eq name="$data.pdo_mysql" value="1"}已开启{else /}未开启{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.pdo_mysql" value="1"}layui-icon-ok yes{else
+                        /}layui-icon-close{/eq}"></i></td>
+                </tr>
+                <tr>
+                    <td>curl</td>
+                    <td>支持</td>
+                    <td>{eq name="$data.curl" value="0"}不支持{else /}支持{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.curl" value="0"}layui-icon-close{else
+                        /}layui-icon-ok yes{/eq}"></i></td>
+                </tr>
+                <tr>
+                    <td>putenv</td>
+                    <td>支持</td>
+                    <td>{eq name="$data.putenv" value="0"}不支持{else /}支持{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.putenv" value="0"}layui-icon-close{else
+                        /}layui-icon-ok yes{/eq}"></i></td>
+                </tr>
+                <tr>
+                    <td>上传限制</td>
+                    <td>≥ 2M</td>
+                    <td>{eq name="$data.upload_size" value="0"}不支持{else /}{$data.upload_size}{/eq}</td>
+                    <td><i class="layui-icon {eq name=" $data.upload_size" value="0"}layui-icon-close{else
+                        /}layui-icon-ok yes{/eq}"></i></td>
+                </tr>
+                </tbody>
+            </table>
+            <h3>目录权限</h3>
+            <table class="layui-table" lay-skin="nob" lay-size="sm">
+                <colgroup>
+                    <col width="150">
+                    <col width="200">
+                    <col width="200">
+                    <col width="100">
+                    <col>
+                </colgroup>
+                <thead>
+                <tr>
+                    <th>环境</th>
+                    <th>最低配置</th>
+                    <th>当前配置</th>
+                    <th>是否符合</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>{:ROOT_PATH}</td>
+                    <td>可写</td>
+                    <td>{:is_writable(ROOT_PATH) ? '可写' : '不可写'}</td>
+                    <td>
+                        {:is_writable(ROOT_PATH) ? '<i class="layui-icon layui-icon-ok yes"></i>' : '<i
+                            class="layui-icon layui-icon-close"></i>'}
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+            <div style="margin:10px auto;width: 190px;">
+                <a href="{:url('install/index/index')}" class="layui-btn layui-bg-cyan">上一步</a>
+                <a href="javascript:;" class="layui-btn layui-bg-cyan" id="step3">下一步</a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="/static/public/layui/layui.js" charset="utf-8"></script>
+<script>
+    layui.use(['jquery', 'layer'], function () {
+        var $ = layui.jquery, layer = layui.layer;
+
+        $('#step3').click(function () {
+            if ($('.yes').length != 9) {
+                layer.tips('您的配置或权限不符合要求', this);
+            } else {
+                location.href = "{:url('install/index/step3')}";
+            }
+        })
+    });
+</script>
+
+</body>
+</html>

+ 199 - 0
app/install/view/index/step3.html

@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>安装引导</title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link rel="stylesheet" href="/static/public/layui/css/layui.css" media="all">
+</head>
+<body>
+<div style="width:800px;margin: 100px auto;">
+    <div class="layui-layout layui-layout-admin">
+        <div class="layui-header layui-bg-cyan">
+            <div class="layui-logo" style="color: #fff">{:systemName()} 安装引导</div>
+            <ul class="layui-nav layui-layout-right">
+                <li class="layui-nav-item">{$Think.const.PRODUCT_VERSION}</li>
+        </div>
+        <div style="border:1px solid #eee;padding:20px;line-height: 25px;">
+            <h3>数据库配置</h3><br>
+            <form class="layui-form" action="" id="form">
+                <div class="layui-form-item">
+                    <label class="layui-form-label">数据库类型</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_TYPE" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="mysql" disabled="disabled">
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">数据库地址</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_HOST" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="{$db_host}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">数据库不在当前机器上才需要修改此ip</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">数据库端口</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_PORT" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="{$db_port}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">数据库端口,默认为3306</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">账号</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_USER" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="{$db_username}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">数据库账号</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">密码</label>
+                    <div class="layui-input-inline">
+                        <input type="password" name="DB_PWD" lay-verify="" autocomplete="off" class="layui-input"
+                               value="{$db_password}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">数据库密码</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">数据库名</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_NAME" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="{$db_name}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">不能有"-"等特殊符号</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">表前缀</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="DB_PREFIX" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="{$db_prefix}">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">不能有"-"等特殊符号</div>
+                </div>
+
+                <hr>
+                <h3>管理员配置</h3><br>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">账号</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="username" lay-verify="required" autocomplete="off" class="layui-input"
+                               value="admin">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">后台登入账号</div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">密码</label>
+                    <div class="layui-input-inline">
+                        <input type="password" name="password" lay-verify="required" autocomplete="off"
+                               class="layui-input" value="123456">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">默认为123456</div>
+                </div>
+
+                <div class="layui-form-item">
+                    <label class="layui-form-label">确认密码</label>
+                    <div class="layui-input-inline">
+                        <input type="password" name="password_confirm" lay-verify="required" autocomplete="off"
+                               class="layui-input" value="123456">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">必须和填写的密码一致</div>
+                </div>
+
+                <br>
+
+                <div class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="demo"
+                     style="display: none;" id="progress">
+                    <div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div>
+                </div>
+
+                <div class="layui-form-item">
+                    <div style="margin:10px auto;width: 190px;">
+                        <a href="{:url('install/index/step2')}" class="layui-btn layui-bg-cyan">上一步</a>
+                        <button class="layui-btn layui-bg-cyan" lay-submit="" id="formDemo" lay-filter="formDemo">创建数据
+                        </button>
+                    </div>
+                </div>
+            </form>
+            <div style="display: none;text-align: center;" id="complete">
+                <h1>安装完成</h1>
+                <br><br>
+                <a href="/" class="layui-btn layui-bg-cyan">访问前台</a>
+                <a href="/admin_login" class="layui-btn layui-bg-cyan">访问后台</a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="/static/public/layui/layui.js" charset="utf-8"></script>
+<script>
+    layui.use(['element', 'jquery', 'layer', 'form'], function () {
+        var $ = layui.jquery, layer = layui.layer, form = layui.form, element = layui.element;
+
+        var n = 0;
+
+        //监听提交
+        form.on('submit(formDemo)', function (data) {
+            $('#progress').css('display', 'block');
+            var timer = setInterval(function () {
+                n = n + Math.random() * 10 | 0;
+                if (n > 99) {
+                    n = 99;
+                    clearInterval(timer);
+                }
+                element.progress('demo', n + '%');
+            }, 30 + Math.random() * 100);
+
+            $.ajax({
+                url: "{:url('install/index/createData')}",
+                type: "post",
+                data: data.field,
+                dataType: 'json',
+                beforeSend: function () {
+                    // 禁用按钮防止重复提交
+                    $("#formDemo").attr({disabled: "disabled"});
+                    $('#formDemo').html('创建中...');
+                },
+                success: function (res) {
+                    if (res.code == 0) {
+                        $('#progress').css('display', 'none');
+                        layer.msg(res.msg);
+                    } else {
+                        if (n == 99) {
+                            element.progress('demo', 100 + '%');
+                            $('#form').hide();
+                            $('#complete').show();
+                            return false;
+                        } else if (n < 99) {
+                            var ref = setInterval(function () {
+                                if (n == 99) {
+                                    clearInterval(ref);
+                                    element.progress('demo', 100 + '%');
+                                    $('#form').hide();
+                                    $('#complete').show();
+                                }
+                            }, 500)
+                        }
+                    }
+                },
+                error: function () {
+                    element.progress('demo', 0 + '%');
+                    $('#progress').css('display', 'none');
+                    layer.msg('创建失败');
+                },
+                complete: function () {
+                    $("#formDemo").removeAttr("disabled");
+                    $('#formDemo').html('创建数据');
+                }
+            })
+            return false;
+        });
+
+    });
+</script>
+
+</body>
+</html>