diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d465120 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/.idea +/.vscode +/vendor +*.log +.env \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..36f7b6f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +sudo: false + +language: php + +branches: + only: + - stable + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - composer self-update + +install: + - composer install --no-dev --no-interaction --ignore-platform-reqs + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . + - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" + - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . + +script: + - php think unit + +deploy: + provider: releases + api_key: + secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= + file: + - ThinkPHP_Core.zip + - ThinkPHP_Full.zip + skip_cleanup: true + on: + tags: true diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..574a39c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..abb0098 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +vaeThink 2.0 +=============== + +## 介绍 + +本项目是面向PHP开发者的轻量级内容管理(权限管理)框架 + +本项目采用ThinkPHP6.X + Layui2.X开发 + +本项目包含了权限、多角色、菜单、路由、配置、内容管理等几乎每个项目都需要的基础性功能 + +本项目旨在帮助开发者们直接开始自己的业务逻辑开发 + +> 运行环境要求PHP7.1+。 + +## 特性 + +* 包含所有ThinkPHP6.X的特性 +* 包含所有Layui2.X的特性 +* 原汁原味的ThinkPHP6体验 +* 帮助开发者直接开始自己的业务逻辑 + +## 安装 + +~~~ +1.请配置域名指向项目的public目录 +2.访问你配置的域名并完成安装引导 +~~~ + +如果需要更新ThinkPHP框架请使用 +~~~ +composer update topthink/framework +~~~ + +如果需要更新Layui框架请使用 +~~~ +1.下载最新的Layui +2.替换public/static/admin_static/lib/layui下的所有文件 +~~~ + +## 文档 + +[ThinkPHP6.X完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content) +[Layui2.X完全开发手册](https://www.layui.com/doc/) + +## 版权 + +vaeThink遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2018-2020 by vaeThink (http://vaethink.com) + +All rights reserved。 + +## 鸣谢 + +感谢ThinkPHP + +感谢Layui + +感谢所有支持者。 diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000..3418e55 --- /dev/null +++ b/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/app/BaseController.php b/app/BaseController.php new file mode 100644 index 0000000..d8ea0d9 --- /dev/null +++ b/app/BaseController.php @@ -0,0 +1,99 @@ +app = $app; + $this->request = $this->app->request; + + // 控制器初始化 + $this->initialize(); + } + + // 初始化 + protected function initialize() + {} + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @return array|string|true + * @throws ValidateException + */ + protected function validate(array $data, $validate, array $message = [], bool $batch = false) + { + if (is_array($validate)) { + $v = new Validate(); + $v->rule($validate); + } else { + if (strpos($validate, '.')) { + // 支持场景 + list($validate, $scene) = explode('.', $validate); + } + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); + $v = new $class(); + if (!empty($scene)) { + $v->scene($scene); + } + } + + $v->message($message); + + // 是否批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + + return $v->failException(true)->check($data); + } + +} diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php new file mode 100644 index 0000000..453d126 --- /dev/null +++ b/app/ExceptionHandle.php @@ -0,0 +1,58 @@ +app = $app; + $this->request = $this->app->request; + + // 控制器初始化 + $this->initialize(); + } + + // 初始化 + protected function initialize() + { + $this->user = Session::get('adminToken'); + $this->param = $this->request->param(); + // Session::delete('adminToken'); + } + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @return array|string|true + * @throws ValidateException + */ + protected function validate(array $data, $validate, array $message = [], bool $batch = false) + { + if (is_array($validate)) { + $v = new Validate(); + $v->rule($validate); + } else { + if (strpos($validate, '.')) { + // 支持场景 + list($validate, $scene) = explode('.', $validate); + } + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); + $v = new $class(); + if (!empty($scene)) { + $v->scene($scene); + } + } + + $v->message($message); + + // 是否批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + + try { + $v->failException(true)->check($data); + } catch (\Exception $e) { + return vae_assign(202,$e->getMessage()); + } + + // 系统默认认为需要验证的表单同样需要验证令牌 + $this->checkFormToken(); + + // return $v->failException(true)->check($data); + } + + protected function checkFormToken() + { + $check = $this->request->checkToken('__token__', $this->request->param()); + + if(false === $check) { + return vae_assign(202, '令牌无效,请刷新页面'); + } + + // ... + } +} diff --git a/app/admin/common.php b/app/admin/common.php new file mode 100644 index 0000000..d529de0 --- /dev/null +++ b/app/admin/common.php @@ -0,0 +1,90 @@ +toArray(); + } + if(!empty($data['total'])){ + $res['count'] = $data['total']; + } else { + $res['count'] = 0; + } + $res['data'] = $data['data']; + $response = \think\Response::create($res, "json",$httpCode, $header, $options); + throw new \think\exception\HttpResponseException($response); +} + +//接收参数方法,方便后期解密 +function vae_input($name='') +{ + if($name) { + $param = Request::param($name); + } + else + { + $param = Request::param(); + } + return $param; +} + +//随机字符串,默认长度10 +function vae_set_salt($num = 10){ + $str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'; + $salt = substr(str_shuffle($str), 10, $num); + return $salt; +} + +//递归排序 +function vae_set_recursion($result,$pid=0,$format="L "){ + /*记录排序后的类别数组*/ + static $list=array(); + + foreach ($result as $k => $v){ + if($v['pid']==$pid){ + if($pid!=0){ + $v['title']=' '.$format.$v['title']; + } + /*将该类别的数据放入list中*/ + $list[]=$v; + vae_set_recursion($result,$v['id']," ".$format); + } + } + + return $list; +} + +function vae_list_to_tree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0) +{ + // 创建Tree + $tree = array(); + if (is_array($list)) { + // 创建基于主键的数组引用 + $refer = array(); + foreach ($list as $key => $data) { + $refer[$data[$pk]] =& $list[$key]; + } + foreach ($list as $key => $data) { + // 判断是否存在parent + $parentId = $data[$pid]; + if ($root == $parentId) { + $tree[] =& $list[$key]; + } else { + if (isset($refer[$parentId])) { + $parent =& $refer[$parentId]; + $parent[$child][] =& $list[$key]; + } + } + } + } + return $tree; +} + +//vaeThink加密方式 +function vae_set_password($pwd, $salt){ + return md5(md5($pwd.$salt).$salt); +} \ No newline at end of file diff --git a/app/admin/config/session.php b/app/admin/config/session.php new file mode 100644 index 0000000..60d5bb3 --- /dev/null +++ b/app/admin/config/session.php @@ -0,0 +1,19 @@ + 'PHPSESSID', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // 驱动方式 支持file cache + 'type' => 'file', + // 存储连接标识 当type使用cache的时候有效 + 'store' => null, + // 过期时间 + 'expire' => 1440, + // 前缀 + 'prefix' => 'VAE_ADMIN_', +]; diff --git a/app/admin/config/view.php b/app/admin/config/view.php new file mode 100644 index 0000000..e6ec71b --- /dev/null +++ b/app/admin/config/view.php @@ -0,0 +1,28 @@ + 'Think', + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 模板目录名 + 'view_dir_name' => 'template', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + 'tpl_replace_string' => [ + '__AVIEW__' => '/static/admin_static' + ] +]; diff --git a/app/admin/controller/Admin.php b/app/admin/controller/Admin.php new file mode 100644 index 0000000..e10e51d --- /dev/null +++ b/app/admin/controller/Admin.php @@ -0,0 +1,164 @@ +request->isAjax()) + { + $param = $this->param; + $where = []; + if(!empty($param['keywords'])) { + $where[] = ['nickname|username|desc','like',$param['keywords'].'%']; + } + $list = Db::name('admin') + ->field('id,username,nickname,status,last_login_time,desc,thumb,groups,last_login_ip') + ->where($where) + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]) + ->each(function($item, $key){ + $item['groupName'] = implode('|',Db::name('admin_group')->where('id','in',explode(',',$item['groups']))->column('title')); + $item['last_login_time'] = date('Y-m-d H:i:s',$item['last_login_time']); + return $item; + }); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + } + + /** + * 添加管理员 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function add() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'username' => 'require|unique:admin', + 'password' => 'require|confirm', + 'nickname' => 'require', + 'thumb' => 'require', + 'group_id' => 'require', + ]); + + $param['salt'] = vae_set_salt(20); + $param['pwd'] = vae_set_password($param['password'],$param['salt']); + $param['groups'] = implode(',',$param['group_id']); + $param['create_time'] = time(); + + if(false == Db::name('admin')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('group',Db::name('admin_group')->where('status',1)->select()->toArray()); + return View::fetch(); + } + + } + + /** + * 修改管理员 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function edit() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'nickname' => 'require', + 'thumb' => 'require', + 'group_id' => 'require', + ]); + + // 不允许其他管理员修改id=1的管理员 + if($param['id'] == 1 and Session::get('admin_tiken')['id'] !== 1) + { + return vae_assign(202,'不允许其他人修改系统所有者'); + } + + unset($param['username']); + if(!empty($param['password'])) { + //重置密码 + if(empty($param['password_confirm']) or $param['password_confirm'] !== $param['password']) { + return vae_assign(202,'两次密码不一致'); + } + $param['salt'] = vae_set_salt(20); + $param['pwd'] = vae_set_password($param['password'],$param['salt']); + } else { + unset($param['pwd']); + unset($param['salt']); + } + $param['groups'] = implode(',',$param['group_id']); + $param['update_time'] = time(); + + if(false == Db::name('admin')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + Cache::delete('uRulesSrc'.$param['id']); + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('admin')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):$data['groups']=explode(',', $data['groups']); + View::assign('data',$data); + View::assign('group',Db::name('admin_group')->where('status',1)->select()->toArray()); + return View::fetch(); + } + } + + /** + * 删除管理员 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function delete() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if ($id == 1) { + return vae_assign(202,"系统拥有者,无法删除!"); + } + if (Db::name('admin')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除管理员成功!"); + } +} diff --git a/app/admin/controller/Cate.php b/app/admin/controller/Cate.php new file mode 100644 index 0000000..d642b00 --- /dev/null +++ b/app/admin/controller/Cate.php @@ -0,0 +1,213 @@ +request->isAjax()) + { + $param = $this->param; + + $list = Db::name('cate_group') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + } + + /** + * 添加导航组 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function addGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'name' => 'require|unique:cate_group', + 'key' => 'require|unique:cate_group', + ]); + + if(false == Db::name('cate_group')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + return View::fetch(); + } + + } + + /** + * 修改导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function editGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'name' => 'require|unique:cate_group', + 'key' => 'require|unique:cate_group', + ]); + + if(false == Db::name('cate_group')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('cate_group')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + /** + * 删除导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function deleteGroup() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + $count = Db::name('cate')->where(["cate_group_id" => $id])->count(); + if ($count > 0) { + return vae_assign(202,"该分组下还存在分类,请先删除分类数据"); + } + if (Db::name('cate_group')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } + + public function cateIndex() + { + $param = $this->param; + + if($this->request->isAjax()) + { + if(empty($param['cate_group_id'])) + { + return vae_assign(202,'非法请求'); + } + + $list = Db::name('cate') + ->where('cate_group_id',$param['cate_group_id']) + ->order('sort desc') + ->select() + ->toArray(); + return vae_assign(0,'',vae_set_recursion($list)); + } + else + { + View::assign('cate_group_id',$param['cate_group_id']); + return View::fetch(); + } + } + + public function addCate() + { + $param = $this->param; + + if($this->request->isPost()) + { + $this->validate($param,[ + 'title' => 'require', + 'cate_group_id' => 'require', + 'pid' => 'require' + ]); + + if(false == Db::name('cate')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('cate_group_id',$param['cate_group_id']); + View::assign('cate',Db::name('cate')->where('cate_group_id',$param['cate_group_id'])->select()->toArray()); + return View::fetch(); + } + + } + + public function editCate() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'title' => 'require', + 'pid' => 'require' + ]); + + if(false == Db::name('cate')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('cate')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + View::assign('cate',Db::name('cate')->where('cate_group_id',$data['cate_group_id'])->select()->toArray()); + return View::fetch(); + } + } + + public function deleteCate() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if(Db::name('cate')->where('pid',$id)->count() > 0) { + return vae_assign(202,'删除失败,该分类下还存在子分类'); + } + if (Db::name('cate')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/controller/Conf.php b/app/admin/controller/Conf.php new file mode 100644 index 0000000..1214074 --- /dev/null +++ b/app/admin/controller/Conf.php @@ -0,0 +1,146 @@ + +// +--------------------------------------------------------------------- +namespace app\admin\controller; +use app\admin\BaseController; +use think\facade\Config; +use think\facade\View; + +class Conf extends BaseController +{ + /** + * 配置首页 + * @Author 听雨 + * @DateTime 2020-03-16 + * @return [type] [description] + */ + public function index() + { + // web配置 + $webconf = Config::get('web'); + View::assign('webConf',[ + 'title' => empty($webconf['title']) ? '' : $webconf['title'], + 'keywords' => empty($webconf['keywords']) ? '' : $webconf['keywords'], + 'desc' => empty($webconf['desc']) ? '' : $webconf['desc'], + 'logo' => empty($webconf['logo']) ? '' : $webconf['logo'], + 'icp' => empty($webconf['icp']) ? '' : $webconf['icp'], + 'code' => empty($webconf['code']) ? '' : $webconf['code'], + ]); + + // email配置 + $emailconf = Config::get('email'); + View::assign('emailConf',[ + 'smtp' => empty($emailconf['smtp']) ? '' : $emailconf['smtp'], + 'username' => empty($emailconf['username']) ? '' : $emailconf['username'], + 'password' => empty($emailconf['password']) ? '' : $emailconf['password'], + 'port' => empty($emailconf['port']) ? '' : $emailconf['port'], + 'email' => empty($emailconf['email']) ? '' : $emailconf['email'], + 'from' => empty($emailconf['from']) ? '' : $emailconf['from'], + ]); + + // 大鱼配置 + $dayuconf = Config::get('dayu'); + View::assign('dayuConf',[ + 'appkey' => empty($dayuconf['appkey']) ? '' : $dayuconf['appkey'], + 'secretkey' => empty($dayuconf['secretkey']) ? '' : $dayuconf['secretkey'], + 'FreeSignName' => empty($dayuconf['FreeSignName']) ? '' : $dayuconf['FreeSignName'] + ]); + + return View::fetch(); + + } + + /** + * 配置提交 + * @Author 听雨 + * @DateTime 2020-03-16 + * @return [type] [description] + */ + public function confSubmit() + { + $param = $this->param; + + switch ($param['type']) { + case 'web': + $this->webConfSubmit($param); + break; + + case 'email': + $this->emailConfSubmit($param); + break; + + default: + $this->dayuConfSubmit($param); + break; + } + } + + //提交网站信息 + private function webConfSubmit($param) + { + $this->validate($param,[ + 'title|网站标题' => 'require', + ]); + + + $conf = "'{$param["title"]}','keywords'=>'{$param["keywords"]}','logo'=>'{$param["logo"]}','desc'=>'{$param["desc"]}','icp'=>'{$param["icp"]}','code'=>'{$param["code"]}'];"; + + try { + file_put_contents(config_path() . "web.php",$conf); + } catch (\Exception $e) { + return vae_assign(202,'配置失败:'.$e->getMessage()); + } + + return vae_assign(200,'配置成功'); + } + + //提交邮箱配置 + private function emailConfSubmit($param) + { + $this->validate($param,[ + 'smtp|smtp服务器' => 'require', + 'username|账户' => 'require', + 'password|密码' => 'require', + 'port|端口' => 'require', + 'email|发件邮箱' => 'require', + 'from|发件人' => 'require', + ]); + + $conf = "'{$param["smtp"]}','username'=>'{$param["username"]}','password'=>'{$param["password"]}','port'=>'{$param["port"]}','email'=>'{$param["email"]}','from'=>'{$param["from"]}'];"; + + try { + file_put_contents(config_path() . "email.php",$conf); + } catch (\Exception $e) { + return vae_assign(202,'配置失败:'.$e->getMessage()); + } + + return vae_assign(200,'配置成功'); + } + + //提交大鱼短信配置 + private function dayuConfSubmit($param) + { + $this->validate($param,[ + 'appkey' => 'require', + 'secretkey' => 'require', + 'FreeSignName|签名' => 'require', + ]); + + $conf = "'{$param["appkey"]}','secretkey'=>'{$param["secretkey"]}','FreeSignName'=>'{$param["FreeSignName"]}'];"; + + try { + file_put_contents(config_path() . "dayu.php",$conf); + } catch (\Exception $e) { + return vae_assign(202,'配置失败:'.$e->getMessage()); + } + + return vae_assign(200,'配置成功'); + } +} diff --git a/app/admin/controller/Content.php b/app/admin/controller/Content.php new file mode 100644 index 0000000..dfac312 --- /dev/null +++ b/app/admin/controller/Content.php @@ -0,0 +1,225 @@ +request->isAjax()) + { + $param = $this->param; + + $list = Db::name('content_group') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + } + + /** + * 添加导航组 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function addGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'name' => 'require|unique:content_group', + 'key' => 'require|unique:content_group', + 'cate_group_id' => 'require', + ]); + + if(false == Db::name('content_group')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('cate_group',Db::name('cate_group')->select()->toArray()); + return View::fetch(); + } + + } + + /** + * 修改导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function editGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'name' => 'require|unique:content_group', + 'key' => 'require|unique:content_group', + 'cate_group_id' => 'require', + ]); + + if(false == Db::name('content_group')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('content_group')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + View::assign('cate_group',Db::name('cate_group')->select()->toArray()); + return View::fetch(); + } + } + + /** + * 删除导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function deleteGroup() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + $count = Db::name('content')->where(["content_group_id" => $id])->count(); + if ($count > 0) { + return vae_assign(202,"该分组下还存在内容,请先删除内容数据"); + } + if (Db::name('content_group')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } + + public function contentIndex() + { + $param = $this->param; + + if($this->request->isAjax()) + { + if(empty($param['content_group_id'])) + { + return vae_assign(202,'非法请求'); + } + + $list = Db::name('content') + ->where('content_group_id',$param['content_group_id']) + ->order('sort create_time desc') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]) + ->each(function($item, $key){ + // $item['img'] = explode(',',$item['img']); + $item['create_time'] = date('Y-m-d',$item['create_time']); + $item['cate_name'] = Db::name('cate')->where('id',$item['cate_id'])->value('title'); + return $item; + }); + return vae_table_assign(0,'',$list); + } + else + { + View::assign('content_group_id',$param['content_group_id']); + return View::fetch(); + } + } + + public function addContent() + { + $param = $this->param; + + if($this->request->isPost()) + { + $this->validate($param,[ + 'title' => 'require', + 'img' => 'require', + 'content_group_id' => 'require', + ]); + + // $param['img'] = implode(',', $param['img']); + + if(false == Db::name('content')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('content_group_id',$param['content_group_id']); + View::assign('cate',Db::name('cate')->where('cate_group_id',Db::name('content_group')->where('id',$param['content_group_id'])->value('cate_group_id'))->select()->toArray()); + return View::fetch(); + } + + } + + public function editContent() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'title' => 'require', + 'img' => 'require', + ]); + + if(false == Db::name('content')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('content')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + View::assign('cate',Db::name('cate')->where('cate_group_id',Db::name('content_group')->where('id',$data['content_group_id'])->value('cate_group_id'))->select()->toArray()); + return View::fetch(); + } + } + + public function deleteContent() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if (Db::name('content')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/controller/Group.php b/app/admin/controller/Group.php new file mode 100644 index 0000000..5099366 --- /dev/null +++ b/app/admin/controller/Group.php @@ -0,0 +1,139 @@ +request->isAjax()) + { + $param = $this->param; + $where = []; + if(!empty($param['keywords'])) { + $where[] = ['title|desc','like',$param['keywords'].'%']; + } + $list = Db::name('admin_group') + ->field('id,title,status,desc') + ->where($where) + ->paginate([ + 'list_rows' => isset($param['list_rows']) ? $param['list_rows'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + + } + + /** + * 添加权限组 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function add() + { + if($this->request->isAjax()) + { + $param = $this->param; + + $this->validate($param,[ + 'title' => 'require|unique:admin_group', + ]); + + $param['rules'] = empty($param['rules'])?'':implode(',',$param['rules']); + $param['create_time'] = time(); + + if(false == Db::name('admin_group')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + return View::fetch(); + } + + } + + /** + * 修改权限组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function edit() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'title' => 'require|unique:admin_group', + ]); + + $param['rules'] = empty($param['rules'])?'':implode(',',$param['rules']); + + $param['update_time'] = time(); + + if(false == Db::name('admin_group')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + Cache::tag('adminRulesSrc')->clear(); + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + + $group = Db::name('admin_group')->find($id); + if(empty($group)) { + return vae_assign(202,'查询的数据不存在'); + } + // 为了配合layui的tree组件存在的bug,这里将已勾选的id倒叙 + $group['rules'] = array_reverse(explode(',',$group['rules'])); + View::assign('group',$group); + return View::fetch(); + } + + } + + /** + * 删除权限组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function delete() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if (Db::name('admin_group')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + Cache::tag('adminRulesSrc')->clear(); + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php new file mode 100644 index 0000000..51d2137 --- /dev/null +++ b/app/admin/controller/Index.php @@ -0,0 +1,256 @@ +user['id']); + if(!Cache::get('uRulesMenu'.$this->user['id'])) + { + //用户所在权限组及所拥有的权限 + if($this->user['id'] == 1) + { + //id=1的管理员默认拥有所有权限 + $uRulesMenu = Db::name('admin_rule')->where('is_menu',1)->order('sort desc')->field('id,pid,title,src as href,font_family as fontFamily,icon')->select()->toArray(); + } + else + { + $uGroupIds = explode(',',Db::name('admin')->where('id',$this->user['id'])->value('groups')); + $uRuleIds = Db::name('admin_group')->where('id','IN',$uGroupIds)->where('status',1)->column('rules','id'); + + $uRules = []; + foreach ($uRuleIds as $k => $v) { + $uRules = array_keys(array_flip($uRules)+array_flip(explode(',',$v))); + } + + //用户所拥有的所有菜单 + $uRulesMenu = Db::name('admin_rule')->where('id','in',$uRules)->where('is_menu',1)->order('sort desc')->field('id,pid,title,src as href,font_family as fontFamily,icon')->select()->toArray(); + } + + foreach ($uRulesMenu as $k => $v) { + if(!empty($v['href'])) { + $uRulesMenu[$k]['href'] = (string)url($v['href']); + } + } + + // 在菜单列表的开头添加首页 + array_unshift($uRulesMenu,['id'=>-1,'pid'=>0,'title'=>'首页','href'=>'','fontFamily'=>'','icon'=>'layui-icon-home']); + + array_push($uRulesMenu,['id'=>-2,'pid'=>0,'title'=>'文档','href'=>'http://vaethink.com','fontFamily'=>'','icon'=>'layui-icon-read']); + + $uRulesMenu = vae_list_to_tree($uRulesMenu); + + Cache::tag('adminRulesSrc')->set('uRulesMenu'.$this->user['id'],$uRulesMenu,36000); + } + $uRulesMenu = Cache::get('uRulesMenu'.$this->user['id']); + + return vae_assign(200,'',$uRulesMenu); + } + + /** + * 清空系统缓存 + * @Author 听雨 + * @DateTime 2020-03-09 + * @return [type] [description] + */ + public function cacheClear() + { + try { + Cache::clear(); + } catch (\Exception $e) { + return vae_assign(202,$e->getMessage()); + } + return vae_assign(200,'清除成功'); + } + + /** + * 管理员退出登录 + * @Author 听雨 + * @DateTime 2020-03-07 + * @return [type] [description] + */ + public function adminLogout() + { + try { + Session::delete('adminToken'); + } catch (\Exception $e) { + return vae_assign(202,$e->getMessage()); + } + return vae_assign(200,'已为您注销登录,再会!',(string)url('admin/publicer/adminLoginPage')); + } + + /** + * 权限节点,用于添加和修改权限组 + * @Author 听雨 + * @DateTime 2020-03-11 + * @return [type] [description] + */ + public function getRuleList() + { + if($this->request->isAjax()) + { + $list = Db::name('admin_rule') + ->field('id,pid,title,is_menu') + ->select() + ->toArray(); + // 配合layui树形组件提供的额外数据 + foreach ($list as $k => $v) { + // 默认全部展开 + // $list[$k]['spread'] = true; + // 标注菜单和纯权限节点 + $v['is_menu'] == 1?$list[$k]['title'] = '权限 菜单 ' . $v['title']:$list[$k]['title'] = '权限 ' . $v['title']; + + // if(!empty($this->param['id'])){ + // $sele = explode(',',Db::name('admin_group')->where('id',$this->param['id'])->value('rules')); + // if(in_array($v['id'], $sele)){ + // // $list[$k]['checked'] = true; + // }else{ + // $list[$k]['checked'] = false; + // } + // } + } + return vae_assign(200,'',vae_list_to_tree($list)); + } + else + { + return vae_assign(202,'非法请求'); + } + } + + /** + * 文件上传 + * @Author 听雨 + * @DateTime 2019-12-04 + * @return [type] [description] + */ + public function upload(){ + // 获取表单上传文件 例如上传了001.jpg + $param['image'] = request()->file('file'); + + // dump($param['image']);die; + + $validate = \think\facade\Validate::rule([ + 'image' => 'require|fileSize:102400|fileExt:jpg,png,jpeg,gif', + ]); + + if (!$validate->check($param)) { + return vae_assign(202,$validate->getError()); + } + // + + $file = $param['image']; + $savename = \think\facade\Filesystem::disk('public')->putFile( 'topic', $file); + + if($savename) { + $path = Config::get('filesystem.disks.public.url'); + $data = $path.'/'.$savename; + return vae_assign(200,'上传成功',$data); + } + else + { + return vae_assign(202,'上传失败,请稍后再试'); + } + } + + /** + * 异常提示页 + * @Author 听雨 + * @DateTime 2020-03-12 + * @param string $msg [description] + * @return [type] [description] + */ + public function errorShow($msg = '你没有这个操作的权限呀~') + { + View::assign('msg',$msg); + return View::fetch(); + } + + /** + * 修改个人资料 + * @Author 听雨 + * @DateTime 2020-03-12 + * @return [type] [description] + */ + public function editAdminInfo() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'nickname' => 'require', + 'thumb' => 'require', + ]); + + if(!empty($param['password'])) + { + //重置密码 + if(empty($param['password_confirm']) or $param['password_confirm'] !== $param['password']) { + return vae_assign(202,'两次密码不一致'); + } + $param['salt'] = vae_set_salt(20); + $param['pwd'] = vae_set_password($param['password'],$param['salt']); + } + else + { + unset($param['pwd']); + unset($param['salt']); + } + + $param['update_time'] = time(); + $param['id'] = Session::get('adminToken')['id']; + + unset($param['groups']); + + if(false == Db::name('admin')->strict(false)->field(true)->update($param)) + { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功,重新登录后生效'); + } + else + { + View::assign('admin',Session::get('adminToken')); + return View::fetch('admin@admin/edit_admin_info'); + } + } +} diff --git a/app/admin/controller/Menu.php b/app/admin/controller/Menu.php new file mode 100644 index 0000000..6f20288 --- /dev/null +++ b/app/admin/controller/Menu.php @@ -0,0 +1,141 @@ +request->isAjax()) + { + $where = []; + if(!empty($param['keywords'])) { + // dump($param['keywords']);die; + $where[] = ['title','like',$this->param['keywords'].'%']; + } + $list = Db::name('admin_rule') + ->field('id,pid,title,is_menu') + ->where($where) + ->select() + ->toArray(); + // 配合layui树形组件提供的额外数据 + foreach ($list as $k => $v) { + // 默认全部展开 + // $list[$k]['spread'] = true; + // 标注菜单和纯权限节点 + $v['is_menu'] == 1?$list[$k]['title'] = '权限 菜单 ' . $v['title']:$list[$k]['title'] = '权限 ' . $v['title']; + } + return vae_assign(200,'',vae_list_to_tree($list)); + } + else + { + return View::fetch(); + } + } + + /** + * 添加 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function add() + { + if($this->request->isAjax()) { + $param = $this->param; + + $this->validate($param,[ + 'pid' => 'require', + 'title' => 'require', + ]); + + $param['is_menu'] = empty($param['is_menu'])?0:$param['is_menu']; + + if(false == Db::name('admin_rule')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + //清除所有菜单缓存 + Cache::tag('adminRulesSrc')->clear(); + return vae_assign(200,'添加成功'); + } else { + View::assign('menu',Db::name('admin_rule')->select()->toArray()); + return View::fetch(); + } + } + + /** + * 修改 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function edit() + { + if($this->request->isPost()) { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'pid' => 'require', + 'title' => 'require', + ]); + + $param['is_menu'] = empty($param['is_menu'])?0:$param['is_menu']; + + if(false == Db::name('admin_rule')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + //清除所有菜单缓存 + Cache::tag('adminRulesSrc')->clear(); + return vae_assign(200,'修改成功'); + } else { + $id = $this->param['id']; + + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + + $data = Db::name('admin_rule')->field('id,pid,title,src,is_menu,font_family,icon,sort')->find($id); + + if(empty($data)) { + return vae_assign(202,'查询的数据不存在'); + } + View::assign('data',$data); + View::assign('menu',Db::name('admin_rule')->select()->toArray()); + return View::fetch(); + } + + } + + /** + * 删除 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function delete() + { + $id = $this->param['id']; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + $count = Db::name('admin_rule')->where(["pid" => $id])->count(); + if ($count > 0) { + return vae_assign(202,"该菜单下还存在子菜单,请先删除子菜单!"); + } + if (Db::name('admin_rule')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/controller/Nav.php b/app/admin/controller/Nav.php new file mode 100644 index 0000000..d8a13bf --- /dev/null +++ b/app/admin/controller/Nav.php @@ -0,0 +1,209 @@ +request->isAjax()) + { + $param = $this->param; + + $list = Db::name('nav_group') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + } + + /** + * 添加导航组 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function addGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'name' => 'require|unique:nav_group', + 'key' => 'require|unique:nav_group', + ]); + + if(false == Db::name('nav_group')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + return View::fetch(); + } + + } + + /** + * 修改导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function editGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'name' => 'require|unique:nav_group', + 'key' => 'require|unique:nav_group', + ]); + + if(false == Db::name('nav_group')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('nav_group')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + /** + * 删除导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function deleteGroup() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + $count = Db::name('nav')->where(["nav_group_id" => $id])->count(); + if ($count > 0) { + return vae_assign(202,"该分组下还存在导航,请先删除导航数据"); + } + if (Db::name('nav_group')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } + + public function navIndex() + { + $param = $this->param; + + if($this->request->isAjax()) + { + if(empty($param['nav_group_id'])) + { + return vae_assign(202,'非法请求'); + } + + $list = Db::name('nav') + ->where('nav_group_id',$param['nav_group_id']) + ->order('sort desc') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + View::assign('nav_group_id',$param['nav_group_id']); + return View::fetch(); + } + } + + public function addNav() + { + $param = $this->param; + + if($this->request->isPost()) + { + $this->validate($param,[ + 'title' => 'require', + 'nav_group_id' => 'require', + ]); + + if(false == Db::name('nav')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('nav_group_id',$param['nav_group_id']); + return View::fetch(); + } + + } + + public function editNav() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'title' => 'require', + ]); + + if(false == Db::name('nav')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('nav')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + public function deleteNav() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if (Db::name('nav')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/controller/Publicer.php b/app/admin/controller/Publicer.php new file mode 100644 index 0000000..1326039 --- /dev/null +++ b/app/admin/controller/Publicer.php @@ -0,0 +1,66 @@ +param; + $this->validate($param,[ + // 'captcha|验证码'=>'require|captcha', + 'username|用户名' => 'require', + 'password|密码' => 'require' + ]); + + $admin = Db::name('admin')->where(['username'=>$param['username']])->find(); + if(empty($admin)) { + return vae_assign(202,'用户名或密码错误'); + } + $param['pwd'] = vae_set_password($param['password'],$admin['salt']); + if($admin['pwd'] !== $param['pwd']) { + return vae_assign(202,'用户名或密码错误'); + } + if($admin['status'] == 0){ + return vae_assign(202,'该用户禁止登陆,请于系统所有者联系'); + } + + Session::set('adminToken', [ + 'id' => $admin['id'], + 'thumb' => $admin['thumb'], + 'nickname' => $admin['nickname'] + ]); + + $data = [ + 'last_login_time' => time(), + 'last_login_ip' => $this->request->ip(), + ]; + Db::name('admin')->where(['id'=>$admin['id']])->update($data); + return vae_assign(200,'登入成功'); + } +} diff --git a/app/admin/controller/Route.php b/app/admin/controller/Route.php new file mode 100644 index 0000000..67f84a8 --- /dev/null +++ b/app/admin/controller/Route.php @@ -0,0 +1,132 @@ + +// +--------------------------------------------------------------------- +namespace app\admin\controller; +use app\admin\BaseController; +use think\facade\Db; +use think\facade\View; +use think\facade\Cache; + +class Route extends BaseController +{ + /** + * 链接美化首页 + * @Author 听雨 + * @DateTime 2020-03-19 + * @return [type] [description] + */ + public function index() + { + if($this->request->isAjax()) + { + $param = $this->param; + $where = array(); + if(!empty($param['keywords'])) { + $where[] = ['id|full_url|url','like',$param['keywords'].'%']; + } + $route = Db::name('route') + ->order('create_time asc') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$route); + } + else + { + return View::fetch(); + } + } + + /** + * 添加链接美化 + * @Author 听雨 + * @DateTime 2020-03-19 + */ + public function add() + { + if($this->request->isPost()) + { + $param = $this->param; + $this->validate($param,[ + 'module' => 'require', + 'full_url' => 'require|unique:route', + 'url' => 'require|unique:route', + ]); + $param['create_time'] = time(); + + if(false == Db::name('route')->strict(false)->field(true)->insert($param)) + { + return vae_assign(202,'创建失败,请稍后再试'); + } + Cache::delete('route_'.$param['module']); + return vae_assign(200,'创建成功'); + } + else + { + return View::fetch(); + } + } + + /** + * 修改链接美化 + * @Author 听雨 + * @DateTime 2020-03-19 + * @return [type] [description] + */ + public function edit() + { + $param = $this->param; + + if($this->request->isPost()) + { + $this->validate($param,[ + 'module' => 'require', + 'full_url' => 'require|unique:route', + 'url' => 'require|unique:route', + 'status' => 'require', + 'id' => 'require', + ]); + + $param['update_time'] = time(); + + if(false == Db::name('route')->strict(false)->field(true)->update($param)) + { + return vae_assign(202,'修改失败,请稍后再试'); + } + Cache::delete('route_'.$param['module']); + return vae_assign(200,'修改成功'); + } + else + { + $data = Db::name('route')->find($param['id']); + empty($data)?vae_assign('202','查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + /** + * 删除链接美化 + * @Author 听雨 + * @DateTime 2020-03-19 + * @return [type] [description] + */ + public function delete() + { + $param = $this->param; + if (Db::name('Route')->delete($param['id']) !== false) { + Cache::delete('route_'.$param['module']); + return vae_assign(200,"删除成功!"); + } else { + return vae_assign(202,"删除失败!"); + } + } +} diff --git a/app/admin/controller/Slide.php b/app/admin/controller/Slide.php new file mode 100644 index 0000000..fe2d745 --- /dev/null +++ b/app/admin/controller/Slide.php @@ -0,0 +1,209 @@ +request->isAjax()) + { + $param = $this->param; + + $list = Db::name('slide_group') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + return View::fetch(); + } + } + + /** + * 添加导航组 + * @Author 听雨 + * @DateTime 2019-11-21 + */ + public function addGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'name' => 'require|unique:slide_group', + 'key' => 'require|unique:slide_group', + ]); + + if(false == Db::name('slide_group')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + return View::fetch(); + } + + } + + /** + * 修改导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function editGroup() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'name' => 'require|unique:slide_group', + 'key' => 'require|unique:slide_group', + ]); + + if(false == Db::name('slide_group')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('slide_group')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + /** + * 删除导航组 + * @Author 听雨 + * @DateTime 2019-11-22 + * @return [type] [description] + */ + public function deleteGroup() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + $count = Db::name('slide')->where(["slide_group_id" => $id])->count(); + if ($count > 0) { + return vae_assign(202,"该分组下还存在轮播图,请先删除轮播图数据"); + } + if (Db::name('slide_group')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } + + public function slideIndex() + { + $param = $this->param; + + if($this->request->isAjax()) + { + if(empty($param['slide_group_id'])) + { + return vae_assign(202,'非法请求'); + } + + $list = Db::name('slide') + ->where('slide_group_id',$param['slide_group_id']) + ->order('sort desc') + ->paginate([ + 'list_rows' => isset($param['limit']) ? $param['limit'] : 20, + 'page' => isset($param['page']) ? $param['page'] : 1, + 'query' => $param + ]); + return vae_table_assign(0,'',$list); + } + else + { + View::assign('slide_group_id',$param['slide_group_id']); + return View::fetch(); + } + } + + public function addSlide() + { + $param = $this->param; + + if($this->request->isPost()) + { + $this->validate($param,[ + 'icon' => 'require', + 'slide_group_id' => 'require', + ]); + + if(false == Db::name('slide')->strict(false)->field(true)->insert($param)) { + return vae_assign(202,'创建失败,请稍后再试'); + } + return vae_assign(200,'创建成功'); + } + else + { + View::assign('slide_group_id',$param['slide_group_id']); + return View::fetch(); + } + + } + + public function editSlide() + { + if($this->request->isPost()) + { + $param = $this->param; + + $this->validate($param,[ + 'id' => 'require', + 'icon' => 'require', + ]); + + if(false == Db::name('slide')->strict(false)->field(true)->update($param)) { + return vae_assign(202,'修改失败,请稍后再试'); + } + + return vae_assign(200,'修改成功'); + } + else + { + $id = $this->param['id']; + $data = Db::name('slide')->find($id); + empty($data)?vae_assign(202,'查询的数据不存在'):View::assign('data',$data); + return View::fetch(); + } + } + + public function deleteSlide() + { + $id = $this->param["id"]; + if(!$id) { + return vae_assign(202,'缺少必要条件'); + } + if (Db::name('slide')->delete($id) == false) { + return vae_assign(202,"删除失败!"); + } + return vae_assign(200,"删除成功!"); + } +} diff --git a/app/admin/event.php b/app/admin/event.php new file mode 100644 index 0000000..94d78e5 --- /dev/null +++ b/app/admin/event.php @@ -0,0 +1,16 @@ + [ + ], + + 'listen' => [ + 'HttpRun' => [], + 'HttpEnd' => [], + 'LogLevel' => [], + 'LogWrite' => [], + ], + + 'subscribe' => [ + ], +]; diff --git a/app/admin/middleware.php b/app/admin/middleware.php new file mode 100644 index 0000000..568ec8b --- /dev/null +++ b/app/admin/middleware.php @@ -0,0 +1,10 @@ +ext(),'',$request->pathInfo())); + + if(count($pathInfo) !== 2) + { + // 由于中间件里不能正常使用$request->controller()获取用户访问的控制器及方法,因此只能通过pathInfo来获取url并进行截取,但这就要求用户访问时必须输入完整的url,不然就抛出异常 + return abort(202, '非法请求,请输入完整的url'); + } + + $controller = strtolower($pathInfo[0]); + $action = strtolower($pathInfo[1]); + + //验证用户登录 + if($controller !== 'publicer') + { + if(!Session::has('adminToken')) + { + return $request->isAjax()?vae_assign(404,'请先登录'):redirect((string)url('/admin/publicer/adminLoginPage')); + } + + // 验证用户访问权限 + if($controller !== 'index') + { + if(!$this->checkAuth($controller,$action,Session::get('adminToken')['id'])) + { + return $request->isAjax()?vae_assign(202,'你没有权限!'):redirect((string)url('/admin/index/errorShow')); + } + } + } + + return $next($request); + } + + /** + * 验证用户访问权限 + * @Author 听雨 + * @DateTime 2019-11-21 + * @param string $controller 当前访问控制器 + * @param string $action 当前访问方法 + * @param string $uid 当前用户id + * @return [type] + */ + protected function checkAuth($controller,$action,$uid) + { + // Cache::delete('uRulesSrc'.$uid); + if($uid == 1) + { + // id=1的管理员默认拥有所有权限 + return true; + } + else + { + if(!Cache::get('uRulesSrc'.$uid)) + { + + //用户所在权限组及所拥有的权限 + $uGroupIds = explode(',',Db::name('admin')->where('id',$uid)->value('groups')); + $uRuleIds = Db::name('admin_group')->where('id','IN',$uGroupIds)->where('status',1)->column('rules','id'); + + $uRules = []; + foreach ($uRuleIds as $k => $v) { + $uRules = array_keys(array_flip($uRules)+array_flip(explode(',',$v))); + } + //用户所拥有的所有权限节点 + $uRulesSrc = Db::name('admin_rule')->where('id','in',$uRules)->column('src','id'); + Cache::tag('adminRulesSrc')->set('uRulesSrc'.$uid,$uRulesSrc,36000); + } + else + { + $uRulesSrc = Cache::get('uRulesSrc'.$uid); + } + + if(!in_array((string)$controller.'/'.$action, $uRulesSrc)) + { + return false; + } + + return true; + } + } +} diff --git a/app/admin/middleware/Install.php b/app/admin/middleware/Install.php new file mode 100644 index 0000000..293128b --- /dev/null +++ b/app/admin/middleware/Install.php @@ -0,0 +1,17 @@ +isAjax()?vae_assign(202,'请先完成系统安装引导'):redirect((string)url('/install/install/index')); + } + + return $next($request); + } +} diff --git a/app/admin/provider.php b/app/admin/provider.php new file mode 100644 index 0000000..5a99e25 --- /dev/null +++ b/app/admin/provider.php @@ -0,0 +1,5 @@ + + +