作者 Karson

新增插件在线一键升级功能

新增安装指定插件版本
修复二级管理员无法添加管理员的BUG
优化require-table在add_url的ids替换
... ... @@ -62,7 +62,6 @@ class Addon extends Backend
$params = $this->request->post("row/a");
if ($params)
{
$configList = [];
foreach ($config as $k => &$v)
{
if (isset($params[$v['name']]))
... ... @@ -124,9 +123,18 @@ class Addon extends Backend
{
$uid = $this->request->post("uid");
$token = $this->request->post("token");
Service::install($name, $force, ['uid' => $uid, 'token' => $token]);
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'faversion' => $faversion
];
Service::install($name, $force, $extend);
$info = get_addon_info($name);
$info['config'] = get_addon_config($name) ? 1 : 0;
$info['state'] = 1;
$this->success(__('Install successful'), null, ['addon' => $info]);
}
catch (AddonException $e)
... ... @@ -283,6 +291,42 @@ class Addon extends Backend
}
/**
* 更新插件
*/
public function upgrade()
{
$name = $this->request->post("name");
if (!$name)
{
$this->error(__('Parameter %s can not be empty', 'name'));
}
try
{
$uid = $this->request->post("uid");
$token = $this->request->post("token");
$version = $this->request->post("version");
$faversion = $this->request->post("faversion");
$extend = [
'uid' => $uid,
'token' => $token,
'version' => $version,
'faversion' => $faversion
];
//调用更新的方法
Service::upgrade($name, $extend);
$this->success(__('Operate successful'));
}
catch (AddonException $e)
{
$this->result($e->getData(), $e->getCode(), $e->getMessage());
}
catch (Exception $e)
{
$this->error($e->getMessage());
}
}
/**
* 刷新缓存
*/
public function refresh()
... ... @@ -314,14 +358,15 @@ class Addon extends Backend
{
if ($search && stripos($v['name'], $search) === FALSE && stripos($v['intro'], $search) === FALSE)
continue;
$v['flag'] = '';
$v['banner'] = '';
$v['image'] = '';
$v['donateimage'] = '';
$v['demourl'] = '';
$v['price'] = '0.00';
$v['url'] = '/addons/' . $v['name'];
$v['createtime'] = 0;
$v['url'] = addon_url($v['name']);
$v['createtime'] = filemtime(ADDON_PATH . $v['name']);
$list[] = $v;
}
$total = count($list);
... ...
... ... @@ -27,30 +27,38 @@ class Admin extends Backend
$this->model = model('Admin');
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin() ? true : false);
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
Tree::instance()->init($groupList);
$result = [];
$groupdata = [];
if ($this->auth->isSuperAdmin())
{
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
foreach ($result as $k => $v)
{
$groupdata[$v['id']] = $v['name'];
}
}
else
{
$result = [];
$groups = $this->auth->getGroups();
foreach ($groups as $m => $n)
{
$result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
$temp = [];
foreach ($childlist as $k => $v)
{
$temp[$v['id']] = $v['name'];
}
$result[__($n['name'])] = $temp;
}
}
$groupName = [];
foreach ($result as $k => $v)
{
$groupName[$v['id']] = $v['name'];
$groupdata = $result;
}
$this->view->assign('groupdata', $groupName);
$this->view->assign('groupdata', $groupdata);
$this->assignconfig("admin", ['id' => $this->auth->id]);
}
... ...
... ... @@ -22,11 +22,13 @@ return [
'Pay click tips' => '请点击这里在新窗口中进行支付!',
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
'Uninstall tips' => '确认卸载插件?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
'Upgrade tips' => '确认升级插件?<p class="text-danger">如果之前购买插件时未登录,此次升级可能出现购买后才可以下载的提示!!!<br>升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
'Offline installed tips' => '插件安装成功!你需要手动启用该插件,并清除缓存使之生效',
'Online installed tips' => '插件安装成功!清除插件缓存和框架缓存后生效!',
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
'Not installed tips' => '请安装后再访问插件前台页面!',
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
'Please disable addon first' => '请先禁用插件再进行升级',
'Login now' => '立即登录',
'Continue install' => '不登录,继续安装',
'Recommend' => '推荐',
... ... @@ -49,6 +51,7 @@ return [
'Feedback' => '反馈BUG',
'Install' => '安装',
'Uninstall' => '卸载',
'Upgrade' => '升级',
'Setting' => '配置',
'Disable' => '禁用',
'Enable' => '启用',
... ...
... ... @@ -2,7 +2,8 @@
.noimage {width:100%;text-align: center;background:#18bc9c;color:#fff;padding-bottom:66.66%;position:relative;}
.noimage > div {position: absolute;top:48%;width:100%;text-align:center;}
.addon {position: relative;}
.addon > span {position:absolute;left:15px;top:15px;}
.addon > span {position:absolute;left:15px;top:15px;z-index:9;}
.addon > span a{opacity: 0.5;border:none;color:#fff;}
.layui-layer-pay .layui-layer-content {padding:0;height:600px!important;}
.layui-layer-pay {border:none;}
.payimg{position:relative;width:800px;height:600px;}
... ... @@ -162,8 +163,14 @@
<% var label = labelarr[item.id % 5]; %>
<% var addon = typeof addons[item.name]!= 'undefined' ? addons[item.name] : null; %>
<div class="thumbnail addon">
<!--<span class="btn btn-primary"><%=item.name%></span>-->
<a href="<%=addon?addon.url:'javascript:;'%>" class="btn-addonindex" target="_blank">
<%if(addon){%>
<span>
<a href="<%=addon.url%>" target="_blank" class="btn btn-xs">
<i class="fa fa-home"></i>
</a>
</span>
<%}%>
<a href="<%=item.url%>" class="btn-addonindex" target="_blank">
<%if(item.image){%>
<img src="<%=item.image%>" class="img-responsive" alt="<%=item.title%>">
<%}else{%>
... ... @@ -190,9 +197,23 @@
<p class="text-muted">{:__('Intro')}: <%=item.intro%></p>
<p class="text-muted">{:__('Version')}: <%=# addon && item && addon.version!=item.version?'<span class="label label-danger">'+addon.version+'</span> -> <span class="label label-success">'+item.version+'</span>':item.version%></p>
<p class="text-muted">{:__('Createtime')}: <%=Moment(item.createtime*1000).format("YYYY-MM-DD HH:mm:ss")%></p>
<p class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
<div class="operate" data-id="<%=item.id%>" data-name="<%=item.name%>">
<% if(!addon){ %>
<a href="javascript:;" class="btn btn-primary btn-success btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
<span class="btn-group">
<a href="javascript:;" class="btn btn-primary btn-success btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
<a class="btn btn-success dropdown-toggle" data-toggle="dropdown" href="javascript:;">
<span class="fa fa-caret-down"></span>
</a>
<ul class="dropdown-menu">
<% for(var i=0;i< item.releaselist.length;i++){ %>
<li><a href="javascript:;" class="btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.releaselist[i].version%>"><%=item.releaselist[i].version%></a></li>
<% } %>
</ul>
</span>
<% }else{%>
<a href="javascript:;" class="btn btn-primary btn-success btn-install" data-type="<%=item.price<=0?'free':'price';%>" data-donateimage="<%=item.donateimage%>" data-version="<%=item.version%>"><i class="fa fa-cloud-download"></i> {:__('Install')}</a>
<% } %>
<% if(item.demourl){ %>
<a href="<%=item.demourl%>" class="btn btn-primary btn-info btn-demo" target="_blank"><i class="fa fa-flash"></i> {:__('Demo')}</a>
<% } %>
... ... @@ -209,12 +230,29 @@
<a href="javascript:;" class="btn btn-danger btn-uninstall"><i class="fa fa-times"></i> {:__('Uninstall')}</a>
<% } %>
<% } %>
<% if(addon && item && addon.version!=item.version){%>
<% if(typeof item.releaselist !="undefined" && item.releaselist.length>1){%>
<span class="btn-group">
<a href="javascript:;" class="btn btn-info btn-success btn-upgrade" data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
<a class="btn btn-info dropdown-toggle" data-toggle="dropdown" href="javascript:;">
<span class="fa fa-caret-down"></span>
</a>
<ul class="dropdown-menu">
<% for(var i=0;i< item.releaselist.length;i++){ %>
<li><a href="javascript:;" class="btn-upgrade" data-version="<%=item.releaselist[i].version%>"><%=item.releaselist[i].version%></a></li>
<% } %>
</ul>
</span>
<% }else{%>
<a href="javascript:;" class="btn btn-info btn-upgrade" data-version="<%=item.version%>"><i class="fa fa-cloud"></i> {:__('Upgrade')}</a>
<% }%>
<% }%>
<span class="pull-right" style="margin-top:10px;">
<a href="javascript:;" class="btn-addoninfo text-gray" data-index="<%=i%>" title="<%=item.title?item.title:'{:__('None')}'%>"><i class="fa fa-bars"></i></a>
</span>
</p>
</div>
</div>
</div>
</div>
... ...
... ... @@ -253,7 +253,7 @@ return [
//自动检测更新
'checkupdate' => false,
//版本号
'version' => '1.0.0.20180130_beta',
'version' => '1.0.0.20180204_beta',
'api_url' => 'http://api.fastadmin.net',
],
];
... ...
... ... @@ -22,8 +22,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
if (e.keyCode == 13) {
var that = this;
var options = table.bootstrapTable('getOptions');
var queryParams = options.queryParams;
options.pageNumber = 1;
options.queryParams = function (params) {
var params = queryParams(params);
params.search = $(that).val();
return params;
};
... ... @@ -53,7 +55,16 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
showExport: false,
commonSearch: false,
searchFormVisible: false,
pageSize: 12
pageSize: 12,
queryParams: function (params) {
var filter = params.filter ? JSON.parse(params.filter) : {};
var op = params.op ? JSON.parse(params.op) : {};
filter.faversion = Config.fastadmin.version;
op.faversion = "=";
params.filter = JSON.stringify(filter);
params.op = JSON.stringify(op);
return params;
}
});
// 为表格绑定事件
... ... @@ -64,7 +75,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
var data = table.bootstrapTable("getData");
var item = data[index];
var addon = typeof Config.addons[item.name] != 'undefined' ? Config.addons[item.name] : null;
console.log(item, addon);
Layer.alert(Template("addoninfotpl", {item: item, addon: addon}), {
btn: [__('OK'), __('Donate'), __('Feedback'), __('Document')],
title: __('Detail'),
... ... @@ -113,7 +123,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$(document).on("click", ".btn-addonindex", function () {
if ($(this).attr("href") == 'javascript:;') {
Layer.msg(__('Not installed tips'), {icon: 7});
} else if ($(this).parent().find("a.btn-enable").size() > 0) {
} else if ($(this).closest(".operate").find("a.btn-enable").size() > 0) {
Layer.msg(__('Not enabled tips'), {icon: 7});
return false;
}
... ... @@ -187,13 +197,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
$(document).on("click", ".btn-install", function () {
var that = this;
var name = $(this).closest(".operate").data("name");
var version = $(this).data("version");
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
var token = userinfo ? userinfo.token : '';
var install = function (name, force) {
Fast.api.ajax({
url: 'addon/install',
data: {name: name, force: force ? 1 : 0, uid: uid, token: token}
data: {name: name, force: force ? 1 : 0, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Layer.closeAll();
Config['addons'][data.addon.name] = ret.data.addon;
... ... @@ -367,6 +378,39 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
};
operate(name, action, false);
});
//点击升级
$(document).on("click", ".btn-upgrade", function () {
if ($(this).closest(".operate").find("a.btn-disable").size() > 0) {
Layer.alert(__('Please disable addon first'), {icon: 7});
return false;
}
var name = $(this).closest(".operate").data("name");
var version = $(this).data("version");
var userinfo = Controller.api.userinfo.get();
var uid = userinfo ? userinfo.id : 0;
var token = userinfo ? userinfo.token : '';
var upgrade = function (name) {
Fast.api.ajax({
url: 'addon/upgrade',
data: {name: name, uid: uid, token: token, version: version, faversion: Config.fastadmin.version}
}, function (data, ret) {
Config['addons'][name].version = version;
Layer.closeAll();
$('.btn-refresh').trigger('click');
}, function (data, ret) {
Layer.alert(ret.msg);
return false;
});
};
Layer.confirm(__('Upgrade tips'), function () {
upgrade(name);
});
});
$(document).on("click", ".operate .btn-group .dropdown-toggle", function () {
$(this).closest(".btn-group").toggleClass("dropup", $(document).height() - $(this).offset().top <= 200);
});
},
add: function () {
Controller.api.bindevent();
... ...
... ... @@ -9758,7 +9758,9 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
$(toolbar).on('click', Table.config.addbtn, function () {
var ids = Table.api.selectedids(table);
var url = options.extend.add_url;
url = Table.api.replaceurl(url, {ids: ids.length > 0 ? ids.join(",") : 0}, table);
if (url.indexOf("{ids}") !== -1) {
url = Table.api.replaceurl(url, {ids: ids.length > 0 ? ids.join(",") : 0}, table);
}
Fast.api.open(url, __('Add'), $(this).data() || {});
});
// 导入按钮事件
... ...
... ... @@ -160,7 +160,9 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
$(toolbar).on('click', Table.config.addbtn, function () {
var ids = Table.api.selectedids(table);
var url = options.extend.add_url;
url = Table.api.replaceurl(url, {ids: ids.length > 0 ? ids.join(",") : 0}, table);
if (url.indexOf("{ids}") !== -1) {
url = Table.api.replaceurl(url, {ids: ids.length > 0 ? ids.join(",") : 0}, table);
}
Fast.api.open(url, __('Add'), $(this).data() || {});
});
// 导入按钮事件
... ...