优化插件系统

This commit is contained in:
taoser 2022-11-27 23:13:06 +08:00
parent 6cf239b1cf
commit b147198b0c
14 changed files with 510 additions and 204 deletions

View File

@ -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' => '<div>{{d.version}}</div>', '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' => '<div>{{d.version}} {{# if(d.have_newversion == 1){ }}<span class="layui-badge-dot"></span>{{# } }}</div>','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]);
}
}
}

View File

@ -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']);

View File

@ -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'
];

View File

@ -133,5 +133,7 @@ return [
'Authorized' => '已授权',
'Unauthorized' => '未授权',
'Free version'=> '免费版',
'username or email' => '用户名或邮箱',
'account or password cannot empty' => '账号和密码不能为空'
];

View File

@ -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' => '账号和密码不能为空'
];

View File

@ -20,39 +20,47 @@
<script type="text/html" id="toolbar">
<div class="layui-btn-group" style="padding-bottom: 10px;">
<a href="#denable" type="button" class="layui-btn layui-btn-sm" lay-event="onlineAddons">在线</a>
<a href="#enable" type="button" class="layui-btn layui-btn-sm" lay-event="installed">已安装</a>
<a href="#denable" type="button" class="layui-btn layui-btn-sm" lay-event="allAddons">全部</a>
<button type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons">免费</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="payAddons">付费</button>
<a href="#enable" type="button" class="layui-btn layui-btn-sm" lay-event="installed">已安装</a>
</div>
<div class="layui-btn-group" style="padding-bottom: 10px;">
<button class="layui-btn layui-btn-sm layuiadmin-btn-admin" data-type="add">离线安装</button>
<button class="layui-btn layui-btn-sm layuiadmin-btn-admin" data-type="user-info">用户信息</button>
</div>
</script>
<script type="text/html" id="addons-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install" data-url="{:url('Addons/install')}"><i class="layui-icon layui-icon-edit"></i>安装</a>
<select id="vers{{d.name}}" name="sss" class="layui-border" lay-ignore lay-filter="versSelect">
{{# d.vers.forEach(function(item, index){ }}
<option value="{{ item }}">{{ item }}</option>
{{# }); }}
</select>
{{# if(d.have_newversion === 1){ }}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="install" data-url="{:url('Addons/install')}"><i class="layui-icon layui-icon-edit"></i>升级</a>
{{# } else { }}
{{# if(d.isInstall ===1) { }}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="config" data-url="{:url('Addons/config')}"><i class="layui-icon layui-icon-set"></i>设置</a>
{{# } else { }}
<a class="layui-btn layui-btn-xs" lay-event="install" data-url="{:url('Addons/install')}" data-userlogin="{:url('Addons/userLogin')}"><i class="layui-icon layui-icon-edit"></i>安装</a>
<select id="vers{{d.name}}" name="sss" class="layui-border" lay-ignore lay-filter="versSelect">
{{# d.vers.forEach(function(item, index){ }}
<option value="{{ item }}">{{ item }}</option>
{{# }); }}
</select>
{{# } }}
{{# } }}
</script>
<script type="text/html" id="addons-installed-tool">
{{# if(d.status == 1){ }}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="status" data-url="{:url('Addons/status')}"><i class="layui-icon layui-icon-pause"></i>禁用</a>
<a class="layui-btn layui-btn-xs" lay-event="status" data-url="{:url('Addons/status')}"><i class="layui-icon layui-icon-pause"></i>禁用</a>
{{# } else { }}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="status" data-url="{:url('Addons/status')}"><i class="layui-icon layui-icon-play"></i>启动</a>
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="status" data-url="{:url('Addons/status')}"><i class="layui-icon layui-icon-play"></i>启动</a>
{{# } }}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="config" data-url="{:url('Addons/config')}"><i class="layui-icon layui-icon-set"></i>设置</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="uninstall" data-url="{:url('Addons/uninstall')}"><i class="layui-icon layui-icon-delete"></i>卸载</a>
</script>
</form>
</div>
</div>
</div>
{include file="public/user_login" /}
{/block}
{block name="js"}
<script src="/static/notify.js"></script>

View File

@ -336,6 +336,7 @@
</div>
</div>
{include file="public/user_login" /}
{/block}
{block name="js"}
<script>
@ -343,12 +344,29 @@
base: '/static/admin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'console','element', 'layedit','form','table'],function(){
}).use(['index', 'console','element', 'layedit','form','table','notify'],function(){
var $ = layui.jquery
,form = layui.form
,layedit = layui.layedit
,table = layui.table
,element = layui.element; //Tab的切换功能切换事件监听等需要依赖element模块
var notify = layui.notify;
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");
}
}
}
}
var index = layedit.build('L_content', {
height: 120 //设置编辑器高度
@ -374,64 +392,99 @@
}
});
// 系统调试
// 系统调试
form.on('switch(sys-sys)',function(data){
var status = data.elem.checked;
console.log(status);
$.post("{:url('index/sysSys')}",{status:status},function(res){
if (res.code == 0) {
layer.msg(res.msg,{
icon:6,
time:2000
}, function(){
location.reload();
});
} else {
layer.open({
content:res.msg,
icon:5,
anim:6
});
}
if (res.code == 0) { notify.info(res.msg)} else {
notify.error(res.msg);
}
})
});
// 发送反馈
form.on('submit(cunsult-add)',function(data){
var field = data.field;
var userinfo = api.userinfo.get();
if(!userinfo) {
// 登录
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 = "{:url('Addons/userLogin')}";
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();
},
});
});
} else {
field.id = userinfo.uid;
$.ajax({
type:"post",
url:"{:url('Index/cunsult')}",
data:field,
dataType:"json",
success:function (data){
if (data.code == 0) {
notify.success(data.msg, function(){location.reload()});
} else {
notify.error(res.msg);
}
}
});
}
return false;
});
form.on('submit(cunsult-add)',function(data){
var field = data.field;
$.ajax({
type:"post",
url:"{:url('Index/cunsult')}",
data:field,
dataType:"json",
success:function (data){
if (data.code == 0) {
layer.msg(data.msg,{
icon:6,
time:2000
}, function(){
location.reload();
});
} else {
layer.open({
content:data.msg,
icon:5,
anim:6
});
}
}
});
return false;
});
//监听工具条
//监听工具条
table.on('tool(LAY-index-topreply)', function(obj){
var data = obj.data;
if(obj.event === 'del'){
layer.confirm('确定删除此站点?', function(index){
layer.confirm('确定删除?', function(index){
$.ajax({
type:'post',
url:"{:url('Index/delReply')}",
@ -439,24 +492,16 @@
dataType:'json',
success:function(data){
if(data.code == 0){
layer.msg(data.msg,{
icon:6,
time:2000
},function(){
notify.success(data.msg,function(){
location.reload();
});
} else {
layer.open({
title:'删除失败',
content:data.msg,
icon:5,
adim:6
})
notify.error(res.msg);
}
}
});
//obj.del();
table.reload('LAY-index-topreply');
table.reload('LAY-index-topreply');
layer.close(index);
});
}
@ -468,8 +513,17 @@
$('#up_version').html(data);
})
})();
// 用户信息清理
(function (){
var time = Date.parse(new Date());
var userinfo = api.userinfo.get();
if(userinfo) {
if(time > userinfo.expiretime *1000) {
api.userinfo.set();
}
}
})()
$('.layui-btn.layuiadmin-btn-oiltank').on('click', function(){
var type = $(this).data('type');
active[type] ? active[type].call(this) : '';
@ -479,8 +533,8 @@
var indexForums = "{:url('Index/forums')}", //帖子
indexReplys = "{:url('Index/replys')}", //回复
indexNews = "{:url('Index/news')}", //动态
indexReply = "{:url('Index/reply')}", //反馈
indexReply = "{:url('Index/reply')}", //反馈
monthTime = "{$monthTime}",
monthUserCount = "{$monthUserCount}";
monthUserCount = "{$monthUserCount}";
</script>
{/block}

View File

@ -0,0 +1,27 @@
<script type="text/html" id="user-info">
<div>
<div class="layui-card">
<div class="layui-card-header" style="">
<blockquote class="layui-elem-quote" style="">温馨提示 此处账号为: <a class="font" target="_blank" href="https://www.aieok.com">TaoLer社区账号</a>
</blockquote>
</div>
<br>
<div class="layui-card-body" style="padding: 0 40px 10px 0">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label required">账号 *</label>
<div class="layui-input-block">
<input type="text" class="layui-input" lay-verify="required" id="username" value="" placeholder="{:lang('username or email')}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label required">密码 *</label>
<div class="layui-input-block">
<input type="password" class="layui-input" lay-verify="required" id="password" value="" placeholder="{:lang('password')}">
</div>
</div>
</form>
</div>
</div>
</div>
</script>

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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(
[

View File

@ -16,7 +16,7 @@ return [
// 应用名,此项不可更改
'appname' => 'TaoLer',
// 版本配置
'version' => '2.0.3',
'version' => '2.0.4',
// 加盐
'salt' => 'taoler',
// 数据库备份目录

View File

@ -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 = '<div class="layui-form-item">\n' +
// '<label class="layui-form-label"></label>\n' +
// '<div class="layui-input-inline">\n' +
// ' <input type="text" name="'+ names +'[key][]" value="" placeholder="key" autocomplete="off" class="layui-input input-double-width">\n' +
// '</div>\n' +
// '<div class="layui-input-inline">\n' +
// ' <input type="text" name="'+ names +'[value][]" value="" placeholder="value" autocomplete="off" class="layui-input input-double-width">\n' +
// '</div>\n' +
// '<button data-name="'+ names +'" type="button" class="layui-btn layui-btn-danger layui-btn-sm removeInupt" lay-event="removeInupt">\n' +
// ' <i class="layui-icon"></i>\n' +
// '</button>\n' +
// '</div>';
// $(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 = '<div class="layui-form-item">\n' +
// '<label class="layui-form-label"></label>\n' +
// '<div class="layui-input-inline">\n' +
// ' <input type="text" name="'+ names +'[key][]" value="" placeholder="key" autocomplete="off" class="layui-input input-double-width">\n' +
// '</div>\n' +
// '<div class="layui-input-inline">\n' +
// ' <input type="text" name="'+ names +'[value][]" value="" placeholder="value" autocomplete="off" class="layui-input input-double-width">\n' +
// '</div>\n' +
// '<button data-name="'+ names +'" type="button" class="layui-btn layui-btn-danger layui-btn-sm removeInupt" lay-event="removeInupt">\n' +
// ' <i class="layui-icon"></i>\n' +
// '</button>\n' +
// '</div>';
// $(this).parent().parent().append(html);
// } else {
// $(this).parent().remove();
// }
});
},
});
});
}
if (event === "edit") {

View File

@ -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;
}
}