From b147198b0c66b61ec0865ff77b829f10c6ff62b1 Mon Sep 17 00:00:00 2001 From: taoser Date: Sun, 27 Nov 2022 23:13:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8F=92=E4=BB=B6=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/Addons.php | 100 +++++++-- app/admin/controller/Index.php | 3 +- app/admin/lang/en-us.php | 12 +- app/admin/lang/zh-cn.php | 2 + app/admin/lang/zh-tw.php | 12 +- app/admin/view/addons/index.html | 32 +-- app/admin/view/index/home.html | 182 ++++++++++------ app/admin/view/public/user_login.html | 27 +++ app/common/model/User.php | 7 + app/index/controller/Login.php | 1 + app/listener/UserLogin.php | 51 ++--- config/taoler.php | 2 +- public/static/admin/modules/addons.js | 246 +++++++++++++++------- vendor/taoser/think-addons/src/helper.php | 37 ++++ 14 files changed, 510 insertions(+), 204 deletions(-) create mode 100644 app/admin/view/public/user_login.html diff --git a/app/admin/controller/Addons.php b/app/admin/controller/Addons.php index 18aed6f..4249af2 100644 --- a/app/admin/controller/Addons.php +++ b/app/admin/controller/Addons.php @@ -31,17 +31,19 @@ class Addons extends AdminController */ public function addonsList() { - - $type = input('type'); - $data = Request::only(['page', 'limit']); - $res = []; - switch($type){ + $data = Request::param(); + $res = []; + //本地插件列表 + $addonsList = Files::getDirName('../addons/'); + $url = $this->getSystem()['api_url'].'/v1/addons'; + $addons = Api::urlGet($url); + + switch($data['type']){ //已安装 case 'installed': - $addons = Files::getDirName('../addons/'); - if($addons){ + if($addonsList){ $res = ['code'=>0,'msg'=>'','count'=>5]; - foreach($addons as $v){ + foreach($addonsList as $v){ $info_file = '../addons/'.$v.'/info.ini'; $info = parse_ini_file($info_file); $info['show'] = $info['status'] ? '启用' : '禁用'; @@ -52,7 +54,7 @@ class Addons extends AdminController ['type' => 'numbers'], ['field' => 'name','title'=> '插件', 'width'=> 120], ['field'=> 'title','title'=> '标题', 'width'=> 100], - ['field'=> 'version','title'=> '版本', 'width'=> 60], + ['field'=> 'version','title'=> '版本', 'templet' => '
{{d.version}}
', 'width'=> 60], ['field' => 'author','title'=> '作者', 'width'=> 80], ['field' => 'description','title'=> '简介', 'minWidth'=> 200], ['field' => 'show','title'=> '状态', 'width'=> 100], @@ -64,14 +66,54 @@ class Addons extends AdminController $res = ['code'=>-1,'msg'=>'没有安装任何插件']; } break; - //在线 + //在线全部 case 'onlineAddons': - $url = $this->getSystem()['api_url'].'/v1/addons'; - $addons = Api::urlGet($url); if( $addons->code !== -1){ + // 与本地文件对比 + foreach($addons->data as $v){ + switch ($data['selector']) { + case 'free': + if($v->price == 0) { + if(in_array($v->name,$addonsList)) { + $info = get_addons_info($v->name); + //已安装 + $v->isInstall = 1; + //判断是否有新版本 + if($v->version > $info['version']) $v->have_newversion = 1; + $v->price = $v->price ? $v->price : '免费'; + } + $res['data'][] = $v; + } + break; + case 'pay': + if($v->price > 0) { + if(in_array($v->name,$addonsList)) { + $info = get_addons_info($v->name); + //已安装 + $v->isInstall = 1; + //判断是否有新版本 + if($v->version > $info['version']) $v->have_newversion = 1; + $v->price = $v->price ? $v->price : '免费'; + } + $res['data'][] = $v; + } + break; + case 'all': + if(in_array($v->name,$addonsList)) { + $info = get_addons_info($v->name); + //已安装 + $v->isInstall = 1; + //判断是否有新版本 + if($v->version > $info['version']) $v->have_newversion = 1; + $v->price = $v->price ? $v->price : '免费'; + } + $res['data'][] = $v; + break; + } + }; + $res['code'] = 0; $res['msg'] = ''; - $res['data'] = $addons->data; $res['col'] = [ ['type' => 'numbers'], ['field' => 'title','title'=> '插件', 'width'=> 200], @@ -79,14 +121,13 @@ class Addons extends AdminController ['field' => 'author','title'=> '作者', 'width'=> 100], ['field' => 'price','title'=> '价格(元)','width'=> 80], ['field' => 'downloads','title'=> '下载', 'width'=> 70], - ['field' => 'version','title'=> '版本', 'width'=> 70], + ['field' => 'version','title'=> '版本', 'templet' => '
{{d.version}} {{# if(d.have_newversion == 1){ }}{{# } }}
','width'=> 70], ['field' => 'status','title'=> '状态', 'width'=> 70], ['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool'] ]; } else { $res = ['code'=>-1,'msg'=>'未获取到服务器信息']; } - break; } return json($res); @@ -181,10 +222,10 @@ class Addons extends AdminController //安装插件 public function install() { - $data = Request::param(); - + $data = Request::param(); $url = $this->getSystem()['api_url'].'/v1/getaddons'; - $addons = Api::urlPost($url,['name'=>$data['name'],'version'=>$data['version']]); + $data = ['name'=>$data['name'], 'version'=>$data['version'], 'uid'=>$data['uid'], 'token'=>$data['token']]; + $addons = Api::urlPost($url,$data); if( $addons->code == -1) { return json(['code'=>$addons->code,'msg'=>$addons->msg]); } @@ -246,6 +287,7 @@ class Addons extends AdminController //更新失败 if($cpData['code'] == -1) return json(['code'=>-1,'msg'=>$cpData['msg']]); + $class = get_addons_instance($data['name']); //添加数据库 $sqlInstallFile = root_path().'addons/'.$data['name'].'/install.sql'; if(file_exists($sqlInstallFile)) { @@ -262,6 +304,8 @@ class Addons extends AdminController $menu_arr[] = $menu['menu']; $this->addAddonMenu($menu_arr, (int)$pid,1); } + //执行插件安装 + $class->install(); Files::delDirAndFile('../runtime/addons/'.$data['name'] . DS); @@ -274,7 +318,9 @@ class Addons extends AdminController public function uninstall() { $name = input('name'); - + //执行插件卸载 + $class = get_addons_instance($name); + $class->uninstall(); //卸载菜单 $menu = get_addons_menu($name); if(!empty($menu)){ @@ -322,11 +368,13 @@ class Addons extends AdminController try{ $arr = ['status' => $info['status'] ? 0 :1]; set_addons_info($name,$arr); + $class = get_addons_instance($name); if($arr['status']) { $res = ['code'=>0,'msg'=>'启用成功']; } else { $res = ['code'=>0,'msg'=>'已被禁用']; } + $info['status']==1 ?$class->enabled():$class->disabled(); } catch (\Exception $e) { throw new Exception($e->getMessage()); } @@ -339,7 +387,7 @@ class Addons extends AdminController { $name = input('name'); $config = get_addons_config($name); - if(empty($config)) return json(['code'=>-1,'msg'=>'无配置项!']); + if(empty($config)) return json(['code'=>-1,'msg'=>'无配置项!无需操作']); if(Request::isAjax()){ $params = Request::param('params/a',[],'trim'); if ($params) { @@ -425,4 +473,16 @@ class Addons extends AdminController } + public function userLogin() + { + $data = Request::param(); + $url = $this->getSystem()['api_url'].'/v1/user/login'; + $user = Api::urlPost($url,$data); + if($user->code == 0) { + return $user; + } else { + return json(['code'=>-1,'msg'=>$user->msg]); + } + } + } diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php index 122c064..3b1fabc 100644 --- a/app/admin/controller/Index.php +++ b/app/admin/controller/Index.php @@ -182,9 +182,8 @@ class Index extends AdminController public function cunsult() { $url = $this->api.'/v1/reply'; - //$mail = Db::name('system')->where('id',1)->value('auth_mail'); // bug邮件发送 if(Request::isAjax()){ - $data = Request::only(['type','title','content','post']); + $data = Request::only(['type','title','content','post','uid']); $apiRes = Api::urlPost($url,$data); $data['poster'] = Session::get('admin_id'); unset($data['post']); diff --git a/app/admin/lang/en-us.php b/app/admin/lang/en-us.php index dfce03f..7cd5665 100644 --- a/app/admin/lang/en-us.php +++ b/app/admin/lang/en-us.php @@ -122,5 +122,15 @@ return [ 'in' => 'in', 'accumulate points' => 'Accumulate points', 'my post' => 'My post', - 'my auth' => 'My authorize' + 'my auth' => 'My authorize', + 'Please log in 10 minutes later' => 'Please log in 10 minutes later', + 'Login error 3, Please log in 10 minutes later' => 'Login error 3, Please log in 10 minutes later', + 'Account disabled' => 'Account disabled', + 'Pending approval' => 'Pending approval', + + 'Authorized' => 'Authorized', + 'Unauthorized' => 'Unauthorized', + 'Free version'=> 'Free version', + 'username or email' => 'Username or email', + 'account or password cannot empty' => 'Account or password cannot empty' ]; \ No newline at end of file diff --git a/app/admin/lang/zh-cn.php b/app/admin/lang/zh-cn.php index bcda12f..a8b4388 100644 --- a/app/admin/lang/zh-cn.php +++ b/app/admin/lang/zh-cn.php @@ -133,5 +133,7 @@ return [ 'Authorized' => '已授权', 'Unauthorized' => '未授权', 'Free version'=> '免费版', + 'username or email' => '用户名或邮箱', + 'account or password cannot empty' => '账号和密码不能为空' ]; \ No newline at end of file diff --git a/app/admin/lang/zh-tw.php b/app/admin/lang/zh-tw.php index 47ff9cf..376b22f 100644 --- a/app/admin/lang/zh-tw.php +++ b/app/admin/lang/zh-tw.php @@ -123,7 +123,17 @@ return [ 'in' => '在', 'accumulate points' => '積分', 'my post' => '我的帖子', - 'my auth' => '我的授权' + 'my auth' => '我的授权', + 'Please log in 10 minutes later' => '请10分钟后再登陆', + 'Login error 3, Please log in 10 minutes later' => '连续登陆错误3次,请10分钟后登录', + 'Account disabled' => '账号被禁用,请联系管理员', + 'Pending approval' => '待审核,请联系管理员', + + 'Authorized' => '已授权', + 'Unauthorized' => '未授权', + 'Free version'=> '免费版', + 'username or email' => '用户名或邮箱', + 'account or password cannot empty' => '账号和密码不能为空' ]; \ No newline at end of file diff --git a/app/admin/view/addons/index.html b/app/admin/view/addons/index.html index 6656959..aca6a32 100644 --- a/app/admin/view/addons/index.html +++ b/app/admin/view/addons/index.html @@ -20,39 +20,47 @@ + - +{include file="public/user_login" /} {/block} {block name="js"} diff --git a/app/admin/view/index/home.html b/app/admin/view/index/home.html index 61db1ee..611187e 100644 --- a/app/admin/view/index/home.html +++ b/app/admin/view/index/home.html @@ -336,6 +336,7 @@ +{include file="public/user_login" /} {/block} {block name="js"} {/block} \ No newline at end of file diff --git a/app/admin/view/public/user_login.html b/app/admin/view/public/user_login.html new file mode 100644 index 0000000..263fd8f --- /dev/null +++ b/app/admin/view/public/user_login.html @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/app/common/model/User.php b/app/common/model/User.php index ffe09c6..049e9fd 100644 --- a/app/common/model/User.php +++ b/app/common/model/User.php @@ -16,6 +16,7 @@ class User extends Model protected $autoWriteTimestamp = true; //开启自动时间戳 protected $createTime = 'false'; protected $updateTime = 'update_time'; + protected $loggedUser; //protected $auto = ['password']; //定义自动处理的字段 //自动对password进行md5加密 protected function setPasswordAttr($value){ @@ -88,6 +89,7 @@ class User extends Model event(new UserLogin($userInfo)); //查询结果1表示有用户,用户名密码正确 + $this->loggedUser = $user; return 1; } else {//密码错误登陆错误次数加1 $userInfo = ['type'=>'logError','id'=>$user->id]; @@ -181,6 +183,11 @@ class User extends Model return '修改失败,请改换密码'; } } + + // 登录用户 + public function getLoggedUser(){ + return $this->loggedUser; + } } \ No newline at end of file diff --git a/app/index/controller/Login.php b/app/index/controller/Login.php index 6aefce3..0b2daa1 100644 --- a/app/index/controller/Login.php +++ b/app/index/controller/Login.php @@ -83,6 +83,7 @@ class Login extends BaseController $user = new User(); $res = $user->login($data); if ($res == 1) { //登陆成功 + $user = $user->getLoggedUser(); return Msgres::success('login_success',$refer); } else { return Msgres::error($res); diff --git a/app/listener/UserLogin.php b/app/listener/UserLogin.php index 40ae0b3..2a6a740 100644 --- a/app/listener/UserLogin.php +++ b/app/listener/UserLogin.php @@ -35,30 +35,33 @@ class UserLogin if($type == 'log'){ //$name = $user->user['name']; $ip = request()->ip(); - //$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361'; - $url = 'http://freeapi.ipip.net/' . $ip; - - $ipJson = Api::urlGetRespond($url); - $respond = $ipJson->getData(); - - if($respond['code'] == 0){ - //字符串数组["中国","北京","北京"] - $data = $respond['data']; - //正则去掉[''],保留字符串 - $str = preg_replace('/(\"|\[|\])/','',$data); - //地址数组 - $arr = explode(',', $str); - if($arr[0] !== '本机地址') { - $city = $arr[2]; - } else { - $city = 'earth'; - } - } - // if($ipJson->status == 'success'){ - // $city = $ipJson->city; - // } else { - // $city ='未知'; - // } + + $url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361'; + $ipJson = Api::urlGetRespond($url); + $res = $ipJson->getData(); + + $data = json_decode($res['data']); + $city ='earth'; + if($res['code'] == 0 && !$data->status){ + $city = $data->city; + } + + //国内查询,接口已失效 +// $url = 'http://freeapi.ipip.net/' . $ip; +// $ipJson = Api::urlGetRespond($url); +// $respond = $ipJson->getData(); +// if($respond['code'] == 0){ +// //字符串数组["中国","北京","北京"] +// $data = $respond['data']; +// //正则去掉[''],保留字符串 +// $str = preg_replace('/(\"|\[|\])/','',$data); +// //地址数组 +// $arr = explode(',', $str); +// $city = 'earth'; +// if($arr[0] !== '本机地址') { +// $city = $arr[2]; +// } +// } $u->allowField(['city','last_login_ip','last_login_time','login_error_num'])->save( [ diff --git a/config/taoler.php b/config/taoler.php index e9a3648..17c9df7 100644 --- a/config/taoler.php +++ b/config/taoler.php @@ -16,7 +16,7 @@ return [ // 应用名,此项不可更改 'appname' => 'TaoLer', // 版本配置 - 'version' => '2.0.3', + 'version' => '2.0.4', // 加盐 'salt' => 'taoler', // 数据库备份目录 diff --git a/public/static/admin/modules/addons.js b/public/static/admin/modules/addons.js index 68096cf..32da7e7 100644 --- a/public/static/admin/modules/addons.js +++ b/public/static/admin/modules/addons.js @@ -7,11 +7,11 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { upload = layui.upload; var notify = layui.notify; - function addList(type) { + function getAddonsList(type,selector ) { $.ajax({ type: "post", url: addonsList, - data: { type: type }, + data: { type: type, selector: selector }, dataType: "json", success: function (res) { //渲染表格 @@ -19,7 +19,7 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { elem: "#addons-list", toolbar: "#toolbar", defaultToolbar: [], - url: addonsList + "?type=" + type, + url: addonsList + "?type=" + type + "&selector=" + selector, cols: [res["col"]], page: true, limit: 10, @@ -30,17 +30,39 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { }); } - addList("onlineAddons"); + getAddonsList("onlineAddons","all"); + + var api = { + userinfo: { + get: function () { + var userinfo = localStorage.getItem("taoleradmin_userinfo"); + return userinfo ? JSON.parse(userinfo) : null; + }, + set: function (data) { + if (data) { + localStorage.setItem("taoleradmin_userinfo", JSON.stringify(data)); + } else { + localStorage.removeItem("taoleradmin_userinfo"); + } + } + } + } //头工具栏事件 table.on("toolbar(addons-list)", function (obj) { var checkStatus = table.checkStatus(obj.config.id); switch (obj.event) { case "installed": - addList("installed"); + getAddonsList("installed",''); break; - case "onlineAddons": - addList("onlineAddons"); + case "allAddons": + getAddonsList("onlineAddons","all"); + break; + case "freeAddons": + getAddonsList("onlineAddons","free"); + break; + case "payAddons": + getAddonsList("onlineAddons","pay"); break; } }); @@ -53,15 +75,78 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { //安装插件 if (event === "install") { - var index = layer.load(1); - $.post(url, { name: data.name, version: data.version }, function (res) { - if (res.code == 0) { - notify.success(res.msg, "topRight"); - } else { - notify.error(res.msg, "topRight"); - } + // 检测权限 + var userinfo = api.userinfo.get(); + var userLoginUrl = $(this).data('userlogin'); + if(userinfo) { + notify.confirm("确认安装吗?", "vcenter",function(){ + var index = layer.load(1); + $.post(url, { name: data.name, version: data.version, uid: userinfo.uid, token: userinfo.token }, function (res) { + if (res.code == 0) { + notify.success(res.msg, "topRight"); + } else { + notify.error(res.msg, "topRight"); + } + layer.close(index); + }); + }); + } else { + // 登录 + layer.confirm('你当前还未登录TaoLer社区账号,请登录后操作!', { + title : '温馨提示', + btnAlign: 'c', + btn: ['立即登录'] //按钮 + },function (index){ layer.close(index); - }); + // 登录窗口 + layer.open({ + type: 1, + shadeClose: true, + title: '登录账号', + content: $("#user-info").html(), + area: ['400px','300px'], + btn: ['登录','注册'], + yes:function (index, layero) { + var url = userLoginUrl; + var data = { + name: $("#username", layero).val(), + password: $("#password", layero).val(), + }; + if (!data.name || !data.password) { + notify.error('Account Or Password Cannot Empty'); + return false; + } + $.ajax({ + url: url, type: 'post', data: data, dataType: "json", success: function (res) { + if (res.code === 0) { + layer.close(index); + api.userinfo.set(res.data); + notify.success("登录成功", function (){ + location.reload(); + }); + + } else { + notify.alert(res.msg); + } + }, error: function (res) { + notify.error(res.msg); + } + }) + }, + btn2: function () { + return false; + }, + success: function (layero, index) { + $(".layui-layer-btn1", layero).prop("href", "https://www.aieok.com/article/reg.html").prop("target", "_blank"); + }, + end: function () { + $("#login").hide(); + }, + + }); + }); + } + } // 启用禁用 @@ -74,12 +159,8 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { notify.error(res.msg, "topRight"); } table.reloadData("addons-list",{},'deep'); - // addList("installed"); }); - }); - - } // 卸载插件 @@ -100,67 +181,74 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) { // 配置插件 if (event === "config") { - layer.open({ - type: 2, - title: '配置插件', - content: url + "?name=" + data.name, - maxmin: true, - area: ["780px", "90%"], - btn: ["确定", "取消"], - yes: function (index, layero) { - var iframeWindow = window["layui-layer-iframe" + index], - submitID = "LAY-addons-config-submit", - submit = layero.find("iframe").contents().find("#" + submitID); - //监听提交 - iframeWindow.layui.form.on( - "submit(" + submitID + ")", - function (data) { - var field = data.field; //获取提交的字段 - $.ajax({ - type: "post", - url: url, - data: field, - daType: "json", - success: function (res) { - if (res.code == 0) { - notify.success(res.msg, "topRight"); - } else { - notify.error(res.msg, "topRight"); - } - }, - }); - layer.close(index); //关闭弹层 - } - ); - submit.trigger("click"); - }, - success: function (layero, index) { - var forms = layero.find("iframe").contents().find(".layui-form"); - var button = forms.find("button"); - //事件委托 - forms.on("click", "button", function (data) { - var even = this.getAttribute("lay-event"); - var names = this.dataset.name; - // if (even == "addInput") { - // var html = '
\n' + - // '\n' + - // '
\n' + - // ' \n' + - // '
\n' + - // '
\n' + - // ' \n' + - // '
\n' + - // '\n' + - // '
'; - // $(this).parent().parent().append(html); - // } else { - // $(this).parent().remove(); - // } - }); - }, + $.post(url,{name:data.name},function (res){ + // 无配置项拦截 + if (res.code == -1) { + notify.alert(res.msg); + return false; + } + layer.open({ + type: 2, + title: '配置插件', + content: url + "?name=" + data.name, + maxmin: true, + area: ["780px", "90%"], + btn: ["确定", "取消"], + yes: function (index, layero) { + var iframeWindow = window["layui-layer-iframe" + index], + submitID = "LAY-addons-config-submit", + submit = layero.find("iframe").contents().find("#" + submitID); + //监听提交 + iframeWindow.layui.form.on("submit(" + submitID + ")", + function (data) { + var field = data.field; //获取提交的字段 + $.ajax({ + type: "post", + url: url, + data: field, + daType: "json", + success: function (res) { + if (res.code == 0) { + notify.success(res.msg, "topRight"); + } else { + notify.error(res.msg, "topRight"); + } + }, + }); + layer.close(index); //关闭弹层 + } + ); + submit.trigger("click"); + }, + success: function (layero, index) { + var forms = layero.find("iframe").contents().find(".layui-form"); + var button = forms.find("button"); + //事件委托 + forms.on("click", "button", function (data) { + var even = this.getAttribute("lay-event"); + var names = this.dataset.name; + // if (even == "addInput") { + // var html = '
\n' + + // '\n' + + // '
\n' + + // ' \n' + + // '
\n' + + // '
\n' + + // ' \n' + + // '
\n' + + // '\n' + + // '
'; + // $(this).parent().parent().append(html); + // } else { + // $(this).parent().remove(); + // } + }); + }, + }); }); + } if (event === "edit") { diff --git a/vendor/taoser/think-addons/src/helper.php b/vendor/taoser/think-addons/src/helper.php index b726ddc..b84612b 100644 --- a/vendor/taoser/think-addons/src/helper.php +++ b/vendor/taoser/think-addons/src/helper.php @@ -284,3 +284,40 @@ if (!function_exists('get_addons_menu')) { } } +if (!function_exists('get_addons_list')) { + /** + * 获得插件列表 + * @return array + */ + function get_addons_list() + { + $list = Cache::get('addonslist'); + if (empty($list)) { + $addonsPath = app()->getRootPath().'addons'.DS; // 插件列表 + $results = scandir($addonsPath); + $list = []; + foreach ($results as $name) { + if ($name === '.' or $name === '..') + continue; + if (is_file($addonsPath . $name)) + continue; + $addonDir = $addonsPath . $name . DS; + if (!is_dir($addonDir)) + continue; + if (!is_file($addonDir . 'Plugin' . '.php')) + continue; + $info = get_addons_info($name); + if (!isset($info['name'])) + continue; + $info['url'] =isset($info['url']) && $info['url'] ?(string)addons_url($info['url']):''; + $list[$name] = $info; + } + Cache::set('addonslist', $list); + } + return $list; + } + + + +} +