提交 d8aa058a 编写于 作者: D Devil

应用插件在线升级开发

上级 75ee4aca
......@@ -74,12 +74,16 @@ class Appmini extends Common
{
// 首页
case 'index' :
// 默认主题
$this->assign('theme', AppMiniService::DefaultTheme());
// 获取主题列表
$data = AppMiniService::ThemeList($this->params);
$this->assign('data_list', $data);
// 默认主题
$this->assign('theme', AppMiniService::$default_theme);
// 插件更新信息
$upgrade = AppMiniService::AppMiniUpgradeInfo(['terminal'=>$this->params['application_name'], 'data'=>$data]);
$this->assign('upgrade_info', $upgrade['data']);
break;
// 源码包列表
......@@ -209,7 +213,12 @@ class Appmini extends Common
{
$key = AppMiniService::DefaultThemeKey($this->params);
$params[$key] = empty($this->data_request['theme']) ? 'default' : $this->data_request['theme'];
return ConfigService::ConfigSave($params);
$ret = ConfigService::ConfigSave($params);
if($ret['code'] == 0)
{
$ret['msg'] = '切换成功';
}
return $ret;
}
/**
......
......@@ -17,6 +17,7 @@ use app\service\AdminService;
use app\service\AdminPowerService;
use app\service\ConfigService;
use app\service\ResourcesService;
use app\service\StoreService;
/**
* 管理员公共控制器
......@@ -266,6 +267,18 @@ class Common extends Controller
// 站点名称
$this->assign('admin_theme_site_name', MyC('admin_theme_site_name', 'ShopXO', true));
// 站点商店信息
$site_store_info = StoreService::SiteStoreInfo();
if(empty($site_store_info))
{
$res = StoreService::SiteStoreAccountsBindHandle();
if($res['code'] == 0)
{
$site_store_info = StoreService::SiteStoreInfo();
}
}
$this->assign('site_store_info', $site_store_info);
}
/**
......
......@@ -12,7 +12,6 @@ namespace app\admin\controller;
use app\service\StatisticalService;
use app\service\StoreService;
use app\service\ConfigService;
/**
* 首页
......@@ -114,26 +113,6 @@ class Index extends Common
$goods_hot_sale = StatisticalService::GoodsHotSaleSevenTodayTotal();
$this->assign('goods_hot_sale', $goods_hot_sale['data']);
// 配置信息
$config = ConfigService::ConfigList();
$this->assign('config_data', $config);
// 站点商店信息
$site_store_info = StoreService::SiteStoreInfo();
if(empty($site_store_info))
{
$site_params = [
'common_store_accounts' => MyC('common_store_accounts'),
'common_store_password' => MyC('common_store_password'),
];
$res = StoreService::SiteStoreAccountsBind($site_params);
if($res['code'] == 0)
{
$site_store_info = StoreService::SiteStoreInfo();
}
}
$this->assign('site_store_info', $site_store_info);
return $this->fetch();
}
......
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\service\PluginsUpgradeService;
/**
* 软件包更新
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
class Packageupgrade extends Common
{
/**
* 构造方法
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-28
* @desc description
*/
public function __construct()
{
// 调用父类前置方法
parent::__construct();
// 登录校验
$this->IsLogin();
// 权限校验
$this->IsPower();
}
/**
* 软件更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-02-22
* @desc description
*/
public function Upgrade()
{
return PluginsUpgradeService::Run($this->data_post);
}
}
?>
\ No newline at end of file
......@@ -64,6 +64,12 @@ class Payment extends Common
// 应用商店
$this->assign('store_payment_url', StoreService::StorePaymentUrl());
// 插件更新信息
$upgrade = PaymentService::PaymentUpgradeInfo($ret['data']);
$this->assign('upgrade_info', $upgrade['data']);
// print_r($upgrade);
// print_r($ret['data']);
return $this->fetch();
}
......
......@@ -13,6 +13,8 @@ namespace app\admin\controller;
use app\service\StoreService;
use app\service\PluginsAdminService;
use app\service\ResourcesService;
use app\service\PluginsService;
use app\service\PluginsUpgradeService;
/**
* 应用管理
......@@ -66,8 +68,14 @@ class Pluginsadmin extends Common
// 页面类型
if($this->view_type == 'home')
{
// 插件列表
$ret = PluginsAdminService::PluginsList();
$this->assign('data_list', $ret['data']);
// 插件更新信息
$upgrade = PluginsService::PluginsUpgradeInfo($ret['data']);
$this->assign('upgrade_info', $upgrade['data']);
return $this->fetch();
} else {
return $this->fetch('upload');
......@@ -288,5 +296,25 @@ class Pluginsadmin extends Common
// 开始操作
return PluginsAdminService::SortSave($this->data_post);
}
/**
* 插件更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-01-05
* @desc description
*/
public function Upgrade()
{
// 是否ajax请求
if(!IS_AJAX)
{
$this->error('非法访问');
}
// 开始操作
return PluginsUpgradeService::Run($this->data_post);
}
}
?>
\ No newline at end of file
......@@ -65,12 +65,16 @@ class Theme extends Common
// 是否默认首页
if($this->view_type == 'index')
{
// 默认主题
$this->assign('theme', ThemeService::DefaultTheme());
// 获取主题列表
$data = ThemeService::ThemeList();
$this->assign('data_list', $data);
// 默认主题
$this->assign('theme', ThemeService::DefaultTheme());
// 插件更新信息
$upgrade = ThemeService::ThemeUpgradeInfo($data);
$this->assign('upgrade_info', $upgrade['data']);
}
return $this->fetch($this->view_type);
}
......@@ -85,7 +89,12 @@ class Theme extends Common
public function Save()
{
$params['common_default_theme'] = empty($this->data_request['theme']) ? 'default' : $this->data_request['theme'];
return ConfigService::ConfigSave($params);
$ret = ConfigService::ConfigSave($params);
if($ret['code'] == 0)
{
$ret['msg'] = '切换成功';
}
return $ret;
}
/**
......
......@@ -23,11 +23,14 @@
<h3 class="am-gallery-title am-margin-top-0">
{{$v.name}}
<div class="am-fr am-text-right">
{{if !empty($upgrade_info) and isset($upgrade_info[$v['theme']]) and $upgrade_info[$v['theme']]['version_new'] neq $v['ver']}}
<a href="javascript:;" class="am-icon-refresh am-text-danger package-upgrade-event" title="更新" data-type="minitheme" data-name="{{$v.name}}" data-value="{{$v.theme}}" data-terminal="{{$nav_type}}" data-json="{{:urlencode(json_encode($upgrade_info[$v['theme']]))}}"></a>
{{/if}}
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
<a href="{{:MyUrl('admin/appmini/themedownload', ['id'=>$v['theme'], 'nav_type'=>$nav_type])}}" class="am-icon-trash-o am-icon-download" title="打包"></a>
<a href="{{:MyUrl('admin/appmini/themedownload', ['id'=>$v['theme'], 'nav_type'=>$nav_type])}}" class="am-icon-trash-o am-icon-download am-margin-left-sm" title="打包"></a>
{{/if}}
{{if $v.is_delete eq 1}}
<a href="javascript:;" class="am-icon-trash-o submit-delete am-margin-left-sm" title="删除" data-url="{{:MyUrl('admin/appmini/themedelete', ['nav_type'=>$nav_type])}}" data-id="{{$v.theme}}"></a>
<a href="javascript:;" class="am-icon-trash-o submit-delete am-margin-left-sm am-text-warning" title="删除" data-url="{{:MyUrl('admin/appmini/themedelete', ['nav_type'=>$nav_type])}}" data-id="{{$v.theme}}"></a>
{{/if}}
</div>
</h3>
......
......@@ -245,35 +245,6 @@
</div>
<!-- right content end -->
<!-- 应用商店账户绑定 -->
<div class="am-popup popup-not-title" id="store-accounts-popup">
<div class="am-popup-inner">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<div class="am-popup-bd">
<!-- form start -->
<form class="am-form form-validation view-save" action="{{:MyUrl('admin/index/storeaccountsbind')}}" method="POST" request-type="ajax-reload">
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>账号<span class="am-form-group-label-tips-must">必填</span></label>
<input type="text" name="common_store_accounts" placeholder="用户名/手机/邮箱" data-validation-message="账号格式1~30个字符" class="am-radius" value="{{if !empty($config_data) and !empty($config_data['common_store_accounts'])}}{{$config_data.common_store_accounts.value}}{{/if}}" required />
</div>
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>密码<span class="am-form-group-label-tips-must">必填</span></label>
<input type="password" name="common_store_password" placeholder="登录密码" data-validation-message="登录密码格式6~30个字符" class="am-radius" value="{{if !empty($config_data) and !empty($config_data['common_store_password'])}}{{$config_data.common_store_password.value}}{{/if}}" required />
</div>
<div class="am-form-group am-form-group-refreshing am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'绑定中...'}">绑定</button>
</div>
<div class="am-margin-top-xr am-text-right am-padding-right-xs">
<a href="https://store.shopxo.net/regster.html" target="_blank">未有账号,去注册</a>
</div>
<p class="am-text-warning am-text-center am-margin-top-sm">一个账号支持绑定多台ShopXO商城</p>
</form>
<!-- form end -->
</div>
</div>
</div>
<!-- 检查更新显示信息 -->
<div class="am-popup popup-not-title" id="inspect-upgrade-popup">
<div class="am-popup-inner">
......
......@@ -21,4 +21,11 @@
<i class="am-icon-remove"></i>
<span>卸载</span>
</button>
{{/if}}
{{if !empty($upgrade_info) and isset($upgrade_info[$module_data['payment']]) and $upgrade_info[$module_data['payment']]['version_new'] neq $module_data['version']}}
<button type="button" class="am-btn am-btn-danger am-btn-xs am-radius am-btn-block package-upgrade-event" data-type="payment" data-name="{{$module_data.name}}" data-value="{{$module_data.payment}}" data-json="{{:urlencode(json_encode($upgrade_info[$module_data['payment']]))}}">
<i class="am-icon-refresh"></i>
<span>更新</span>
</button>
{{/if}}
\ No newline at end of file
......@@ -26,6 +26,12 @@
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-margin-left-xs am-icon-check submit-move-sort-save am-hide"> 保存</button>
<button type="button" class="am-btn am-btn-danger am-radius am-btn-xs am-margin-left-xs am-icon-close submit-move-sort-cancel am-hide"> 取消</button>
</p>
{{if empty($site_store_info)}}
<p>
<span>3. 绑定ShopXO应用商店帐号、获取插件最新版本信息、在线安装及更新</span>
<button type="button" class="am-btn am-btn-secondary am-radius am-btn-xs am-margin-left-xs am-icon-gg" data-am-modal="{target: '#store-accounts-popup'}"> 绑定ShopXO商店账户</button>
</p>
{{/if}}
</div>
<!-- 已安装 -->
<ul data-am-widget="gallery" class="am-gallery am-avg-sm-1 am-avg-md-2 am-avg-lg-3 am-gallery-bordered already-install" data-am-gallery="{}" data-sort-save-url="{{:MyUrl('admin/pluginsadmin/sortsave')}}">
......@@ -51,13 +57,17 @@
<button class="am-btn am-btn-default am-btn-xs am-radius am-icon-circle-o submit-ajax" data-url="{{:MyUrl('admin/pluginsadmin/uninstall')}}" data-id="{{$v.plugins}}" data-view="reload" data-msg="卸载可能会丢失插件基础配置数据不可恢复、确认操作吗?" title="卸载"></button>
<a href="javascript:;" class="am-icon-btn am-icon-check submit-state {{if $v['is_enable'] eq 1}}am-success{{else /}}am-default{{/if}}" data-url="{{:MyUrl('admin/pluginsadmin/statusupdate')}}" data-id="{{$v.plugins}}" data-state="{{$v['is_enable']}}" data-is-update-status="1" title="状态"></a>
<a href="javascript:;" class="am-btn am-btn-default am-btn-xs am-icon-check submit-state {{if $v['is_enable'] eq 1}}am-success{{/if}}" data-url="{{:MyUrl('admin/pluginsadmin/statusupdate')}}" data-id="{{$v.plugins}}" data-state="{{$v['is_enable']}}" data-is-update-status="1" title="状态"></a>
{{if isset($v['is_home']) and $v['is_home'] eq true}}
<a href="{{:PluginsHomeUrl($v['plugins'], 'index', 'index')}}" class="am-btn am-btn-default am-btn-xs am-radius am-icon-home" title="首页" target="_blank"></a>
{{/if}}
<button type="button" class="am-btn am-btn-secondary am-btn-xs am-radius am-icon-arrows submit-move am-hide" title="排序"></button>
{{if !empty($upgrade_info) and isset($upgrade_info[$v['plugins']]) and $upgrade_info[$v['plugins']]['version_new'] neq $v['version']}}
<button class="am-btn am-btn-danger am-btn-xs am-radius am-icon-refresh package-upgrade-event" title="更新" data-type="plugins" data-name="{{$v.name}}" data-value="{{$v.plugins}}" data-json="{{:urlencode(json_encode($upgrade_info[$v['plugins']]))}}"></button>
{{/if}}
</div>
</div>
</li>
......
......@@ -2,11 +2,9 @@
<li {{if $view_type eq 'home'}}class="am-active"{{/if}}>
<a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'home'])}}">应用管理</a>
</li>
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
<li {{if $view_type eq 'upload'}}class="am-active"{{/if}}>
<a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'upload'])}}">上传应用</a>
</li>
{{/if}}
<li {{if $view_type eq 'upload'}}class="am-active"{{/if}}>
<a href="{{:MyUrl('admin/pluginsadmin/index', ['view_type'=>'upload'])}}">上传应用</a>
</li>
<li class="fr">
<a class="am-margin-left-sm" href="{{$store_url}}" target="_blank">更多插件下载 <i class="am-icon-external-link"></i></a>
</li>
......
<!-- 应用商店账户绑定 -->
<div class="am-popup popup-not-title" id="store-accounts-popup">
<div class="am-popup-inner">
<span data-am-modal-close class="am-close am-close-alt am-icon-times"></span>
<div class="am-popup-bd">
<!-- form start -->
<form class="am-form form-validation-store-accounts view-save" action="{{:MyUrl('admin/index/storeaccountsbind')}}" method="POST" request-type="ajax-reload">
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>账号<span class="am-form-group-label-tips-must">必填</span></label>
<input type="text" name="common_store_accounts" placeholder="用户名/手机/邮箱" data-validation-message="账号格式1~30个字符" class="am-radius" value="{{:MyC('common_store_accounts', '', true)}}" required />
</div>
<div class="am-form-group am-form-group-refreshing business-form-block am-margin-top-xs">
<label>密码<span class="am-form-group-label-tips-must">必填</span></label>
<input type="password" name="common_store_password" placeholder="登录密码" data-validation-message="登录密码格式6~30个字符" class="am-radius" value="{{:MyC('common_store_password', '', true)}}" required />
</div>
<div class="am-form-group am-form-group-refreshing am-margin-top-sm">
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'绑定中...'}">绑定</button>
</div>
<div class="am-margin-top-xr am-text-right am-padding-right-xs">
<a href="https://store.shopxo.net/regster.html" target="_blank">未有账号,去注册</a>
</div>
<p class="am-text-warning am-text-center am-margin-top-sm">一个账号支持绑定多台ShopXO商城</p>
</form>
<!-- form end -->
</div>
</div>
</div>
<!-- 插件包更新弹窗 -->
<div class="am-modal am-modal-no-btn" tabindex="-1" id="package-upgrade-modal">
<div class="am-modal-dialog">
<div class="am-modal-hd">
<a href="javascript: void(0)" class="am-close" data-am-modal-close>&times;</a>
</div>
<div class="am-modal-bd">
<p class="am-margin-bottom-sm"><strong class="upgrade-name">...</strong></p>
<div class="am-scrollable-vertical am-text-left"></div>
<div class="am-text-left am-nbfc am-margin-top-sm">
<span class="am-icon-calendar-check-o upgrade-date"> ...</span>
<span class="am-icon-vimeo am-margin-left-sm upgrade-version"> ...</span>
<div class="am-fr">
<button type="button" class="am-btn am-btn-default am-radius am-btn-xs" data-am-modal-close>取消</button>
<button type="button" class="am-btn am-btn-success am-radius am-btn-xs am-margin-left-sm package-upgrade-submit" data-type="" data-value="" data-url="{{:MyUrl('admin/packageupgrade/upgrade')}}">更新</button>
</div>
</div>
</div>
</div>
</div>
<!-- commom html -->
<textarea id="upload-editor-view" data-url="{{:MyUrl('admin/ueditor/index', ['path_type'=>empty($editor_path_type) ? 'common' : $editor_path_type])}}" style="display: none;"></textarea>
......
......@@ -2,50 +2,53 @@
<!-- right content start -->
<div class="content-right">
<div class="content">
<!-- nav start -->
{{include file="theme/nav" /}}
<!-- nav end -->
<div class="content">
<!-- nav start -->
{{include file="theme/nav" /}}
<!-- nav end -->
<!-- list start -->
{{if !empty($data_list)}}
<ul data-am-widget="gallery" class="am-gallery am-avg-sm-2 am-avg-md-3 am-avg-lg-4 am-gallery-bordered data-list" data-am-gallery="{}" data-select-url="{{:MyUrl('admin/theme/save')}}">
{{foreach $data_list as $v}}
<li id="data-list-{{$v.theme}}">
<div class="am-gallery-item am-radius am-padding-0 {{if $v['theme'] eq $theme}}theme-active{{/if}}">
<a href="javascript:;" class="select-theme am-block" data-theme="{{$v.theme}}">
<img src="{{$v.preview}}" alt="{{$v.name}}" class="am-block" />
</a>
<div class="am-gallery-item-bottom am-padding-sm">
<h3 class="am-gallery-title am-margin-top-0">
{{$v.name}}
<div class="am-fr am-text-right">
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
<a href="{{:MyUrl('admin/theme/download', ['id'=>$v['theme']])}}" class="am-icon-trash-o am-icon-download" title="打包"></a>
{{/if}}
{{if $v.is_delete eq 1}}
<a href="javascript:;" class="am-icon-trash-o submit-delete am-margin-left-sm" title="删除" data-url="{{:MyUrl('admin/theme/delete')}}" data-id="{{$v.theme}}"></a>
{{/if}}
</div>
</h3>
<div class="am-gallery-desc">作者:
{{if empty($v['home'])}}
{{$v.author}}
{{else /}}
<a href="{{$v.home}}" target="_blank">{{$v.author}}</a>
{{/if}}
</div>
<div class="am-gallery-desc">适用版本:{{$v.ver}}</div>
</div>
</div>
</li>
{{/foreach}}
<ul>
{{else /}}
{{include file="public/not_data" /}}
{{/if}}
<!-- lis end -->
</div>
<!-- list start -->
{{if !empty($data_list)}}
<ul data-am-widget="gallery" class="am-gallery am-avg-sm-2 am-avg-md-3 am-avg-lg-4 am-gallery-bordered data-list" data-am-gallery="{}" data-select-url="{{:MyUrl('admin/theme/save')}}">
{{foreach $data_list as $v}}
<li id="data-list-{{$v.theme}}">
<div class="am-gallery-item am-radius am-padding-0 {{if $v['theme'] eq $theme}}theme-active{{/if}}">
<a href="javascript:;" class="select-theme am-block" data-theme="{{$v.theme}}">
<img src="{{$v.preview}}" alt="{{$v.name}}" class="am-block" />
</a>
<div class="am-gallery-item-bottom am-padding-sm">
<h3 class="am-gallery-title am-margin-top-0">
{{$v.name}}
<div class="am-fr am-text-right">
{{if !empty($upgrade_info) and isset($upgrade_info[$v['theme']]) and $upgrade_info[$v['theme']]['version_new'] neq $v['ver']}}
<a href="javascript:;" class="am-icon-refresh am-text-danger package-upgrade-event" title="更新" data-type="webtheme" data-name="{{$v.name}}" data-value="{{$v.theme}}" data-json="{{:urlencode(json_encode($upgrade_info[$v['theme']]))}}"></a>
{{/if}}
{{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
<a href="{{:MyUrl('admin/theme/download', ['id'=>$v['theme']])}}" class="am-icon-trash-o am-icon-download am-margin-left-sm" title="打包"></a>
{{/if}}
{{if $v.is_delete eq 1}}
<a href="javascript:;" class="am-icon-trash-o submit-delete am-margin-left-sm am-text-warning" title="删除" data-url="{{:MyUrl('admin/theme/delete')}}" data-id="{{$v.theme}}"></a>
{{/if}}
</div>
</h3>
<div class="am-gallery-desc">作者:
{{if empty($v['home'])}}
{{$v.author}}
{{else /}}
<a href="{{$v.home}}" target="_blank">{{$v.author}}</a>
{{/if}}
</div>
<div class="am-gallery-desc">适用版本:{{$v.ver}}</div>
</div>
</div>
</li>
{{/foreach}}
<ul>
{{else /}}
{{include file="public/not_data" /}}
{{/if}}
<!-- lis end -->
</div>
</div>
<!-- right content end -->
......
......@@ -1673,9 +1673,10 @@ function IsJson($jsonstr)
* @version 1.0.0
* @date 2020-08-07
* @desc description
* @param [string] $value [本地文件路径或者远程url地址]
* @param [string] $value [本地文件路径或者远程url地址]
* @param [int] $timeout [超时时间(默认10秒)]
*/
function RequestGet($value)
function RequestGet($value, $timeout = 10)
{
// 远程
if(substr($value, 0, 4) == 'http')
......@@ -1683,7 +1684,7 @@ function RequestGet($value)
// 是否有curl模块
if(function_exists('curl_init'))
{
return CurlGet($value);
return CurlGet($value, $timeout);
}
return file_get_contents($value);
}
......
......@@ -147,6 +147,13 @@ return [
'qq' => ['value' => 'qq', 'name' => 'QQ小程序'],
],
// app平台
'common_app_type' => [
'ios' => ['value' => 'ios', 'name' => '苹果APP'],
'android' => ['value' => 'android', 'name' => '安卓APP'],
],
// 小程序平台
'common_appmini_type' => [
'weixin' => ['value' => 'weixin', 'name' => '微信小程序'],
......
......@@ -177,7 +177,7 @@ class AppMiniService
}
// 上传处理
return self::ThemeUploadHandle($_FILES['file']['tmp_name'], $params);
return self::ThemeUploadHandle($_FILES['theme']['tmp_name'], $params);
}
/**
......@@ -339,16 +339,12 @@ class AppMiniService
}
// 获取配置信息
$config_file = self::$old_path.DS.$theme.DS.'config.json';
if(!file_exists($config_file))
{
return DataReturn('主题配置文件不存在', -1);
}
$config = json_decode(file_get_contents($config_file), true);
if(empty($config))
$config_res = self::MiniThemeConfig($theme, $params);
if($config_res['code'] != 0)
{
return DataReturn('主题配置信息有误', -1);
return $config_res;
}
$config = $config_res['data'];
// 目录不存在则创建
$new_dir = ROOT.'runtime'.DS.'data'.DS.'theme_appmini_package'.DS.$theme;
......@@ -382,7 +378,9 @@ class AppMiniService
\base\FileUtil::UnlinkDir($new_dir);
// 开始下载
if(\base\FileUtil::DownloadFile($new_dir.'.zip', $config['name'].'.zip'))
$appmini_type = lang('common_appmini_type');
$application_name = array_key_exists(self::$application_name, $appmini_type) ? $appmini_type[self::$application_name]['name'].'-' : '';
if(\base\FileUtil::DownloadFile($new_dir.'.zip', $application_name.$config['name'].'.zip'))
{
@unlink($new_dir.'.zip');
} else {
......@@ -390,6 +388,35 @@ class AppMiniService
}
}
/**
* 主题配置信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $theme [主题标识]
* @param [array] $params [输入参数]
*/
public static function MiniThemeConfig($theme, $params)
{
// 初始化
self::Init($params);
// 获取配置信息
$config_file = self::$old_path.DS.$theme.DS.'config.json';
if(!file_exists($config_file))
{
return DataReturn('小程序主题配置文件不存在', -1);
}
$config = json_decode(file_get_contents($config_file), true);
if(empty($config))
{
return DataReturn('主小程序题配置信息有误', -1);
}
return DataReturn('success', 0, $config);
}
/**
* 获取小程序下载包数据列表
* @author Devil
......@@ -727,5 +754,52 @@ class AppMiniService
return DataReturn('成功['.$sucs.'],失败['.$fail.']');
}
/**
* 小程序主题更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function AppMiniUpgradeInfo($params = [])
{
if(!empty($params) && !empty($params['data']) && !empty($params['terminal']))
{
// 数据处理
$data = [];
foreach($params['data'] as $v)
{
if(!empty($v['name']) && !empty($v['ver']) && !empty($v['theme']) && !empty($v['author']))
{
$data[] = [
'plugins' => $v['theme'],
'name' => $v['name'],
'ver' => $v['ver'],
'author' => $v['author'],
];
}
}
if(!empty($data))
{
// 获取更新信息
$request_params = [
'plugins_type' => 'minitheme',
'plugins_data' => $data,
'plugins_terminal' => $params['terminal'],
];
$res = StoreService::PluginsUpgradeInfo($request_params);
if(!empty($res['data']))
{
$res['data'] = array_column($res['data'], null, 'plugins');
}
return $res;
}
}
return DataReturn('无插件数据', 0);
}
}
?>
\ No newline at end of file
......@@ -211,7 +211,7 @@ class PackageInstallService
\base\FileUtil::CreateDir($res['dir'].$res['path']);
// 下载保存
if(@file_put_contents($res['url'], RequestGet($url)) !== false)
if(@file_put_contents($res['url'], RequestGet($url, 300000)) !== false)
{
return DataReturn('success', 0, $key);
}
......
......@@ -12,6 +12,7 @@ namespace app\service;
use think\Db;
use app\service\ResourcesService;
use app\service\StoreService;
/**
* 支付方式服务层
......@@ -138,7 +139,7 @@ class PaymentService
* @desc description
* @param [string] $payment [模块名称]
*/
private static function GetPaymentConfig($payment)
public static function GetPaymentConfig($payment)
{
$payment = '\payment\\'.$payment;
if(class_exists($payment))
......@@ -945,5 +946,51 @@ php;
}
return DataReturn('校验成功', 0);
}
/**
* 支付插件更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function PaymentUpgradeInfo($params = [])
{
if(!empty($params))
{
// 数据处理
$data = [];
foreach($params as $v)
{
if(!empty($v['name']) && !empty($v['version']) && !empty($v['payment']) && !empty($v['author']))
{
$data[] = [
'plugins' => $v['payment'],
'name' => $v['name'],
'ver' => $v['version'],
'author' => $v['author'],
];
}
}
if(!empty($data))
{
// 获取更新信息
$request_params = [
'plugins_type' => 'payment',
'plugins_data' => $data,
];
$res = StoreService::PluginsUpgradeInfo($request_params);
if(!empty($res['data']))
{
$res['data'] = array_column($res['data'], null, 'plugins');
}
return $res;
}
}
return DataReturn('无插件数据', 0);
}
}
?>
\ No newline at end of file
......@@ -935,7 +935,7 @@ php;
}
/**
* 应用添加
* 应用是否存在
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
......@@ -945,13 +945,7 @@ php;
*/
private static function PluginsExist($plugins)
{
// 应用是否存在
if(is_dir(APP_PATH.'plugins'.DS.$plugins))
{
return DataReturn('应用名称已存在['.$plugins.']', -1);
}
return DataReturn('添加成功', 0);
return is_dir(APP_PATH.'plugins'.DS.$plugins);
}
/**
......@@ -1055,16 +1049,7 @@ php;
}
// 资源目录
$dir_list = [
'_controller_' => APP_PATH.'plugins'.DS,
'_view_' => APP_PATH.'plugins'.DS.'view'.DS,
'_css_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS,
'_js_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js'.DS,
'_images_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images'.DS,
'_uploadfile_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'file'.DS,
'_uploadimages_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'images'.DS,
'_uploadvideo_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'video'.DS,
];
$dir_list = self::PluginsDirStructureMapping();
// 包名
$plugins = '';
......@@ -1111,11 +1096,10 @@ php;
}
// 应用是否存在
$ret = self::PluginsExist($plugins);
if($ret['code'] != 0)
if(self::PluginsExist($plugins))
{
zip_entry_close($temp_resource);
return $ret;
return DataReturn('应用名称已存在['.$plugins.']', -1);
}
}
......@@ -1193,6 +1177,28 @@ php;
return DataReturn('安装成功');
}
/**
* 插件目录结构
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
*/
public static function PluginsDirStructureMapping()
{
return [
'_controller_' => APP_PATH.'plugins'.DS,
'_view_' => APP_PATH.'plugins'.DS.'view'.DS,
'_css_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS,
'_js_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js'.DS,
'_images_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images'.DS,
'_uploadfile_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'file'.DS,
'_uploadimages_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'images'.DS,
'_uploadvideo_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'video'.DS,
];
}
/**
* 应用打包
* @author Devil
......@@ -1367,6 +1373,156 @@ php;
}
}
/**
* 插件更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $package_file [插件包文件]
* @param [array] $params [输入参数]
*/
public static function PluginsUpgradeHandle($package_file, $params = [])
{
// 权限校验
$ret = self::PowerCheck();
if($ret['code'] != 0)
{
return $ret;
}
// 基础业务参数
if(empty($params['plugins_value']))
{
return DataReturn('插件标识为空', -1);
}
// 应用是否存在
if(!self::PluginsExist($params['plugins_value']))
{
return DataReturn('应用不已存在['.$params['plugins_value'].']、请先安装', -1);
}
// 资源目录
$dir_list = self::PluginsDirStructureMapping();
// 包名
$plugins = '';
// 开始解压文件
$resource = zip_open($package_file);
if(!is_resource($resource))
{
return DataReturn('压缩包打开失败['.$resource.']', -10);
}
// 处理文件
while(($temp_resource = zip_read($resource)) !== false)
{
if(zip_entry_open($resource, $temp_resource))
{
// 当前压缩包中项目名称
$file = zip_entry_name($temp_resource);
// 获取包名
if(empty($plugins))
{
// 应用名称
$plugins = substr($file, 0, strpos($file, '/'));
if(empty($plugins))
{
// 应用名称为空、则校验是否为支付插件
$file_size = zip_entry_filesize($temp_resource);
$file_content = zip_entry_read($temp_resource, $file_size);
if(stripos($file_content, 'namespace payment') !== false)
{
return DataReturn('支付插件请到[ 网站管理->支付方式 ]模块里面去上传安装', -1);
}
// 不是支付插件则提示插件包错误
return DataReturn('插件包有误', -30);
}
// 应用是否存在
if($plugins != $params['plugins_value'])
{
zip_entry_close($temp_resource);
return DataReturn('应用标识与指定不一致['.$plugins.'<>'.$params['plugins_value'].']', -1);
}
}
// 排除临时文件和临时目录
if(strpos($file, '/.') === false && strpos($file, '__') === false)
{
// 文件包对应系统所在目录
$is_has_find = false;
foreach($dir_list as $dir_key=>$dir_value)
{
if(strpos($file, $dir_key) !== false)
{
// 仅控制器模块支持php文件
if($dir_key != '_controller_')
{
// 排除后缀文件
$pos = strripos($file, '.');
if($pos !== false)
{
$info = pathinfo($file);
if(isset($info['extension']) && in_array($info['extension'], self::$exclude_ext))
{
continue;
}
}
}
// 匹配成功文件路径处理、跳出循环
$file = str_replace($plugins.'/'.$dir_key.'/', '', $dir_value.$file);
$is_has_find = true;
break;
}
}
// 没有匹配到则指定目录跳过
if($is_has_find == false)
{
continue;
}
// 截取文件路径
$file_path = substr($file, 0, strrpos($file, '/'));
// 路径不存在则创建
\base\FileUtil::CreateDir($file_path);
// 如果不是目录则写入文件
if(!is_dir($file))
{
// 读取这个文件
$file_size = zip_entry_filesize($temp_resource);
$file_content = zip_entry_read($temp_resource, $file_size);
@file_put_contents($file, $file_content);
}
// 关闭目录项
zip_entry_close($temp_resource);
}
}
}
// 更新sql
$sql_file = APP_PATH.'plugins'.DS.$plugins.DS.'update.sql';
if(!empty($plugins) && file_exists($sql_file))
{
SqlconsoleService::Implement(['sql'=>file_get_contents($sql_file)]);
}
// 插件事件回调
PluginsService::PluginsEventCall($plugins, 'Upgrade', $params);
return DataReturn('更新成功');
}
/**
* 排序保存
* @author Devil
......
......@@ -324,15 +324,17 @@ class PluginsService
if(empty($status))
{
$config = PluginsAdminService::GetPluginsConfig($plugins);
if(!empty($config) && is_array($config))
if(empty($config) || empty($config['base']))
{
unset($config['hook']);
} else {
$config = [];
return DataReturn('应用插件配置信息有误', -1);
}
$check_params = [
'type' => 'plugins',
'config' => $config,
'plugins' => $plugins,
'author' => $config['base']['author'],
'ver' => $config['base']['version'],
];
$ret = StoreService::PluginsLegalCheck($check_params);
if($ret['code'] != 0)
......@@ -354,7 +356,7 @@ class PluginsService
* @version 1.0.0
* @date 2020-01-02
* @param [string] $plugins [应用标记]
* @param [string] $action [事件方法(Upload 上传, Install 安装, Uninstall 卸载, Download 下载, Delete 删除)]
* @param [string] $action [事件方法(Upload 上传, Install 安装, Uninstall 卸载, Download 下载, Upgrade 更新, Delete 删除)]
* @param [array] $params [输入参数]
*/
public static function PluginsEventCall($plugins, $action, $params = [])
......@@ -405,5 +407,51 @@ class PluginsService
}
return $data;
}
/**
* 插件更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-21
* @desc description
* @param [array] $params [输入参数、插件信息]
*/
public static function PluginsUpgradeInfo($params = [])
{
if(!empty($params) && !empty($params['db_data']) && is_array($params['db_data']))
{
// 数据处理
$data = [];
foreach($params['db_data'] as $v)
{
if(!empty($v['name']) && !empty($v['version']) && !empty($v['plugins']) && !empty($v['author']))
{
$data[] = [
'plugins' => $v['plugins'],
'name' => $v['name'],
'ver' => $v['version'],
'author' => $v['author'],
];
}
}
if(!empty($data))
{
// 获取更新信息
$request_params = [
'plugins_type' => 'plugins',
'plugins_data' => $data,
];
$res = StoreService::PluginsUpgradeInfo($request_params);
if(!empty($res['data']))
{
$res['data'] = array_column($res['data'], null, 'plugins');
}
return $res;
}
}
return DataReturn('无插件数据', 0);
}
}
?>
\ No newline at end of file
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service;
use think\Db;
use app\service\PluginsAdminService;
use app\service\PaymentService;
use app\service\ThemeService;
use app\service\AppMiniService;
/**
* 插件更新服务层
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
*/
class PluginsUpgradeService
{
// 输入参数
public static $params;
// 远程插件更新接口
public static $store_plugins_upgrade_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=pluginsupgradeurl';
/**
* 更新入口
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function Run($params = [])
{
// 参数校验
$ret = self::ParamsCheck($params);
if($ret['code'] != 0)
{
return $ret;
}
// 插件信息获取
$config = self::ConfigInit();
if($config['code'] != 0)
{
return $config;
}
// 操作类型
switch(self::$params['opt'])
{
// 获取url地址
case 'url' :
$ret = self::UrlHandle(self::$params);
break;
// 下载软件包
case 'download' :
$ret = self::DownloadHandle(self::$params['key']);
break;
// 更新软件包
case 'upgrade' :
$ret = self::UpgradeHandle(self::$params);
break;
}
return $ret;
}
/**
* 更新软件包
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function UpgradeHandle($params)
{
// 获取目录文件
$res = self::DirFileData($params['key']);
if(!file_exists($res['url']))
{
return DataReturn('软件包不存在、请重新更新', -1);
}
// 根据插件类型调用安装程序
switch($params['plugins_type'])
{
// 功能插件
case 'plugins' :
$ret = PluginsAdminService::PluginsUpgradeHandle($res['url'], $params);
break;
// 支付插件
case 'payment' :
$ret = PaymentService::UploadHandle($res['url'], $params);
break;
// web主题
case 'webtheme' :
$ret = ThemeService::ThemeUploadHandle($res['url'], $params);
break;
// 小程序主题
case 'minitheme' :
if(empty($params['plugins_terminal']))
{
return DataReturn('未指定终端类型', -1);
}
$params['application_name'] = $params['plugins_terminal'];
$ret = AppMiniService::ThemeUploadHandle($res['url'], $params);
break;
// 默认
default :
$ret = DataReturn('插件操作类型未定义['.$params['plugins_type'].']', -1);
}
// 移除session
session($params['key'], null);
// 删除本地文件
\base\FileUtil::UnlinkFile($res['url']);
// 返回提示
if($ret['code'] == 0)
{
$ret['msg'] = '更新成功';
}
return $ret;
}
/**
* 下载软件包
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $key [缓存key]
*/
public static function DownloadHandle($key)
{
// 获取下载地址
$url = session($key);
if(empty($url))
{
return DataReturn('下载地址为空', -1);
}
// 获取目录文件
$res = self::DirFileData($key);
// 目录不存在则创建
\base\FileUtil::CreateDir($res['dir'].$res['path']);
// 下载保存
if(@file_put_contents($res['url'], RequestGet($url, 300000)) !== false)
{
return DataReturn('success', 0, $key);
}
return DataReturn('插件下载失败', -1);
}
/**
* 获取下载地址
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function UrlHandle($params = [])
{
// 帐号信息
$accounts = MyC('common_store_accounts');
$password = MyC('common_store_password');
// 获取信息
$ret = StoreService::RemoteStoreData($accounts, $password, self::$store_plugins_upgrade_url, $params);
if(!empty($ret) && isset($ret['code']) && $ret['code'] == 0)
{
$key = md5($ret['data']);
session($key, $ret['data']);
$ret['data'] = $key;
}
return $ret;
}
/**
* 获取软件存储信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $key [缓存key]
*/
public static function DirFileData($key)
{
// 将软件包下载到磁盘
$dir = ROOT;
$path = 'runtime'.DS.'data'.DS.'plugins_package_upgrade'.DS;
$filename = $key.'.zip';
// 目录不存在则创建
\base\FileUtil::CreateDir($dir.$path);
return [
'dir' => $dir,
'path' => $path,
'file' => $filename,
'url' => $dir.$path.$filename,
];
}
/**
* 配置信息初始化
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
*/
public static function ConfigInit()
{
// 根据插件类型获取不通的配置信息
switch(self::$params['plugins_type'])
{
// 功能插件
case 'plugins' :
$config = PluginsAdminService::GetPluginsConfig(self::$params['plugins_value']);
if(empty($config) || empty($config['base']))
{
return DataReturn('应用插件配置信息有误', -1);
}
self::$params['plugins_config'] = $config;
self::$params['plugins_ver'] = $config['base']['version'];
self::$params['plugins_author'] = $config['base']['author'];
break;
// 支付插件
case 'payment' :
$config = PaymentService::GetPaymentConfig(self::$params['plugins_value']);
if(empty($config))
{
return DataReturn('支付插件配置信息有误', -1);
}
self::$params['plugins_config'] = $config['base'];
self::$params['plugins_ver'] = $config['base']['version'];
self::$params['plugins_author'] = $config['base']['author'];
break;
// web主题
case 'webtheme' :
$config = ThemeService::ThemeConfig(self::$params['plugins_value']);
if($config['code'] != 0)
{
return $config;
}
self::$params['plugins_config'] = $config['data'];
self::$params['plugins_ver'] = $config['data']['ver'];
self::$params['plugins_author'] = $config['data']['author'];
break;
// 小程序主题
case 'minitheme' :
if(empty(self::$params['plugins_terminal']))
{
return DataReturn('未指定终端类型', -1);
}
self::$params['application_name'] = self::$params['plugins_terminal'];
$config = AppMiniService::MiniThemeConfig(self::$params['plugins_value'], self::$params);
if($config['code'] != 0)
{
return $config;
}
self::$params['plugins_config'] = $config['data'];
self::$params['plugins_ver'] = $config['data']['ver'];
self::$params['plugins_author'] = $config['data']['author'];
break;
// 默认
default :
return DataReturn('插件操作类型未定义['.self::$params['plugins_type'].']', -1);
}
return DataReturn('success', 0);
}
/**
* 输入参数校验
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function ParamsCheck($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'plugins_type',
'error_msg' => '更新类型有误',
],
[
'checked_type' => 'empty',
'key_name' => 'plugins_value',
'error_msg' => '插件标识有误',
],
[
'checked_type' => 'in',
'key_name' => 'opt',
'checked_data' => ['url', 'download', 'upgrade'],
'error_msg' => '操作类型有误',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 下载和安装需要校验key
if(in_array($params['opt'], ['download', 'upgrade']) && empty($params['key']))
{
return DataReturn('操作key有误', -1);
}
self::$params = $params;
return DataReturn('success', 0);
}
}
?>
\ No newline at end of file
......@@ -30,6 +30,9 @@ class StoreService
// 远程插件安全合法校验接口
public static $store_plugins_legal_check_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=pluginslegalcheck';
// 远程插件更新信息接口
public static $store_plugins_upgrade_info_url = 'https://store.shopxo.net/index.php?s=/api/plugins/index&pluginsname=store&pluginscontrol=index&pluginsaction=pluginsupgradeinfo';
// 站点商店数据缓存key
public static $site_store_info_key = 'admin_site_store_info_data';
......@@ -146,8 +149,34 @@ class StoreService
return $ret;
}
// 绑定处理
return self::SiteStoreAccountsBindHandle($params['common_store_accounts'], $params['common_store_password']);
}
/**
* 站点应用商店帐号绑定处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-16
* @desc description
* @param [string] $accounts [帐号]
* @param [string] $password [密码]
*/
public static function SiteStoreAccountsBindHandle($accounts = '', $password = '')
{
// 帐号信息
if(empty($accounts))
{
$accounts = MyC('common_store_accounts');
}
if(empty($password))
{
$password = MyC('common_store_password');
}
// 获取信息
$res = self::RemoteStoreData($params['common_store_accounts'], $params['common_store_password'], self::$store_site_info_url);
$res = self::RemoteStoreData($accounts, $password, self::$store_site_info_url);
if($res['code'] == 0)
{
// 存储缓存、取远程给的时间,未拿到时间则默认30分钟
......@@ -187,21 +216,53 @@ class StoreService
* @desc description
* @param [array] $params [输入参数]
*/
public static function PluginsLegalCheck($params)
public static function PluginsLegalCheck($params = [])
{
// 参数校验
if(empty($params) || empty($params['type']) || empty($params['plugins']) || empty($params['author']) || empty($params['ver']))
{
return DataReturn('插件参数有误', -1);
}
// 帐号信息
$accounts = MyC('common_store_accounts');
$password = MyC('common_store_password');
// 获取信息
$request_params = [
'plugins_type' => 0,
'plugins_type' => $params['type'],
'plugins_value' => $params['plugins'],
'plugins_config' => empty($params['config']) ? [] : $params['config'],
'plugins_author' => $params['author'],
'plugins_ver' => $params['ver'],
'plugins_config' => $params['config'],
];
return self::RemoteStoreData($accounts, $password, self::$store_plugins_legal_check_url, $request_params);
}
/**
* 插件更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-21
* @desc description
* @param [array] $params [输入参数、插件信息]
*/
public static function PluginsUpgradeInfo($params = [])
{
if(!empty($params) && !empty($params['plugins_type']) && !empty($params['plugins_data']) && is_array($params['plugins_data']))
{
// 帐号信息
$accounts = MyC('common_store_accounts');
$password = MyC('common_store_password');
// 获取更新信息
return self::RemoteStoreData($accounts, $password, self::$store_plugins_upgrade_info_url, $params);
}
return DataReturn('无插件数据', 0);
}
/**
* 远程获取数据
* @author Devil
......
......@@ -313,16 +313,12 @@ class ThemeService
}
// 获取配置信息
$config_file = ROOT.self::$html_path.$theme.DS.'config.json';
if(!file_exists($config_file))
{
return DataReturn('主题配置文件不存在', -1);
}
$config = json_decode(file_get_contents($config_file), true);
if(empty($config))
$config_res = self::ThemeConfig($theme);
if($config_res['code'] != 0)
{
return DataReturn('主题配置信息有误', -1);
return $config_res;
}
$config = $config_res['data'];
// 目录不存在则创建
$new_dir = ROOT.'runtime'.DS.'data'.DS.'theme_package'.DS.$theme;
......@@ -387,5 +383,76 @@ class ThemeService
return DataReturn('下载失败', -100);
}
}
/**
* 主题配置信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $theme [主题标识]
*/
public static function ThemeConfig($theme)
{
// 获取配置信息
$config_file = ROOT.self::$html_path.$theme.DS.'config.json';
if(!file_exists($config_file))
{
return DataReturn('主题配置文件不存在', -1);
}
$config = json_decode(file_get_contents($config_file), true);
if(empty($config))
{
return DataReturn('主题配置信息有误', -1);
}
return DataReturn('success', 0, $config);
}
/**
* web主题更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeUpgradeInfo($params = [])
{
if(!empty($params))
{
// 数据处理
$data = [];
foreach($params as $v)
{
if(!empty($v['name']) && !empty($v['ver']) && !empty($v['theme']) && !empty($v['author']))
{
$data[] = [
'plugins' => $v['theme'],
'name' => $v['name'],
'ver' => $v['ver'],
'author' => $v['author'],
];
}
}
if(!empty($data))
{
// 获取更新信息
$request_params = [
'plugins_type' => 'webtheme',
'plugins_data' => $data,
];
$res = StoreService::PluginsUpgradeInfo($request_params);
if(!empty($res['data']))
{
$res['data'] = array_column($res['data'], null, 'plugins');
}
return $res;
}
}
return DataReturn('无插件数据', 0);
}
}
?>
\ No newline at end of file
......@@ -35,24 +35,19 @@ return array (
'plugins_css' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\multilingual\\Hook',
3 => 'app\\plugins\\commonrightnavigation\\Hook',
4 => 'app\\plugins\\store\\Hook',
1 => 'app\\plugins\\multilingual\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_js' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\multilingual\\Hook',
3 => 'app\\plugins\\commonrightnavigation\\Hook',
4 => 'app\\plugins\\store\\Hook',
1 => 'app\\plugins\\multilingual\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_navigation_header_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_quick_navigation_pc' =>
array (
......@@ -87,7 +82,6 @@ return array (
'plugins_service_goods_handle_end' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
),
'plugins_view_buy_form_inside' =>
array (
......@@ -107,151 +101,117 @@ return array (
'plugins_service_buy_order_insert_end' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_order_status_change_history_success_handle' =>
array (
0 => 'app\\plugins\\points\\Hook',
1 => 'app\\plugins\\shop\\Hook',
2 => 'app\\plugins\\store\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_base_data_return_api_buy_index' =>
array (
0 => 'app\\plugins\\points\\Hook',
),
'plugins_admin_css' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\orderpricerevision\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_users_center_left_menu_handle' =>
'plugins_common_page_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_service_header_navigation_top_right_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\multilingual\\Hook',
2 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_save_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_service_editor_path_type_admin_goods_saveinfo' =>
array (
0 => 'app\\plugins\\shop\\Hook',
0 => 'app\\plugins\\multilingual\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_goods_detail_right_content_bottom' =>
'plugins_view_common_top' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_view_goods_detail_base_bottom' =>
'plugins_view_common_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_view_goods_detail_base_buy_nav_min_inside_begin' =>
'plugins_service_search_goods_list_where' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\multilingual\\Hook',
),
'plugins_service_warehouse_handle_end' =>
'plugins_admin_css' =>
array (
0 => 'app\\plugins\\shop\\Hook',
0 => 'app\\plugins\\orderpricerevision\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_service_buy_handle' =>
'plugins_admin_js' =>
array (
0 => 'app\\plugins\\shop\\Hook',
0 => 'app\\plugins\\orderpricerevision\\Hook',
),
'plugins_service_buy_order_insert_begin' =>
'plugins_admin_view_common_bottom' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\orderpricerevision\\Hook',
),
'plugins_service_order_aftersale_audit_handle_end' =>
'plugins_view_admin_order_list_operate' =>
array (
0 => 'app\\plugins\\shop\\Hook',
0 => 'app\\plugins\\orderpricerevision\\Hook',
1 => 'app\\plugins\\store\\Hook',
),
'plugins_view_admin_goods_save' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_module_form_admin_goods_index' =>
array (
0 => 'app\\plugins\\shop\\Hook',
),
'plugins_module_form_admin_goods_detail' =>
'plugins_service_users_center_left_menu_handle' =>
array (
0 => 'app\\plugins\\shop\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_buy_nav_button_handle' =>
'plugins_service_warehouse_goods_inventory_deduct' =>
array (
0 => 'app\\plugins\\shop\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_common_page_bottom' =>
'plugins_service_warehouse_goods_inventory_rollback' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_view_common_top' =>
'plugins_service_warehouse_goods_inventory_sync' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_view_common_bottom' =>
'plugins_service_goods_field_status_update' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
1 => 'app\\plugins\\commonrightnavigation\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_search_goods_list_where' =>
'plugins_service_goods_delete' =>
array (
0 => 'app\\plugins\\multilingual\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_admin_js' =>
'plugins_service_goods_save_end' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_admin_view_common_bottom' =>
'plugins_service_editor_path_type_admin_goods_saveinfo' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_view_admin_order_list_operate' =>
'plugins_view_goods_detail_right_content_bottom' =>
array (
0 => 'app\\plugins\\orderpricerevision\\Hook',
1 => 'app\\plugins\\store\\Hook',
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_deduct' =>
'plugins_view_goods_detail_base_bottom' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_rollback' =>
'plugins_view_goods_detail_base_buy_nav_min_inside_begin' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_warehouse_goods_inventory_sync' =>
'plugins_service_warehouse_handle_end' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_field_status_update' =>
'plugins_service_buy_order_insert_begin' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_delete' =>
'plugins_service_system_begin' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_goods_save_end' =>
'plugins_service_order_aftersale_audit_handle_end' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
'plugins_service_system_begin' =>
'plugins_service_goods_buy_nav_button_handle' =>
array (
0 => 'app\\plugins\\store\\Hook',
),
......
......@@ -12,7 +12,4 @@
}
.theme-active {
border: 3px solid #5eb95e !important;
}
.am-gallery-title .submit-delete {
color:#C13932 !important;
}
\ No newline at end of file
......@@ -654,4 +654,38 @@ table.am-table .am-btn-danger:hover {
max-height: calc(100% - 50px);
overflow-x: auto;
overflow-y: auto;
}
/**
* 商店帐号信息
*/
#store-accounts-popup {
width: 360px;
height: 350px;
left: 50%;
top: 50%;
}
@media (min-width: 630px) {
#store-accounts-popup {
margin-left: -180px;
margin-top: -175px;
}
}
@media only screen and (max-width: 641px) {
#store-accounts-popup {
left: calc(50% - 180px);
top: calc(50% - 175px);
}
}
/**
* 插件更新弹窗
*/
#package-upgrade-modal .am-scrollable-vertical {
height: 160px;
border: 1px solid #eee;
padding: 5px;
}
#package-upgrade-modal .am-modal-bd {
padding: 0 10px 10px 10px;
}
\ No newline at end of file
......@@ -212,28 +212,6 @@ html, body {
}
}
/**
* 商店帐号信息
*/
#store-accounts-popup {
width: 360px;
height: 350px;
left: 50%;
top: 50%;
}
@media (min-width: 630px) {
#store-accounts-popup {
margin-left: -180px;
margin-top: -175px;
}
}
@media only screen and (max-width: 641px) {
#store-accounts-popup {
left: calc(50% - 180px);
top: calc(50% - 175px);
}
}
/**
* 更新信息展示
*/
......
......@@ -76,10 +76,12 @@
height: 28px;
border-radius: 2px;
font-size: 12px;
line-height: 24px;
line-height: 14px;
}
.content ul.am-gallery-bordered li .submit-state.am-default {
background-color: #e6e6e6;
.content ul.am-gallery-bordered li .submit-state.am-success {
border: 1px solid #4caf50;
background-color: #4caf50;
color: #fff;
}
.content ul.am-gallery-bordered li .submit-move {
cursor: move !important;
......
......@@ -12,7 +12,4 @@
}
.theme-active {
border: 3px solid #5eb95e !important;
}
.am-gallery-title .submit-delete {
color:#C13932 !important;
}
\ No newline at end of file
// 表单初始化
FromInit('form.form-validation-store-accounts');
/**
* 商品参数数据创建
* @author Devil
......@@ -75,8 +78,143 @@ function FormTableHeightHandle()
}
}
/**
* 软件更新异步请求步骤
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-02-22
* @desc description
* @param {[string]} url [url地址]
* @param {[string]} type [操作类型(plugins、payment、webtheme、minitheme)]
* @param {[string]} value [操作标识值]
* @param {[string]} opt [操作类型(url 获取下载地址, download 下载插件包, upgrade 安装插件包)]
* @param {[string]} key [操作key(仅download和install需要)]
* @param {[string]} terminal [小程序需要的指定端值]
* @param {[string]} msg [提示信息]
*/
function PackageUpgradeRequestHandle(params)
{
// 参数处理
if((params || null) == null)
{
Prompt('操作参数有误');
return false;
}
var url = params.url || null;
var type = params.type || null;
var value = params.value || null;
var key = params.key || '';
var terminal = params.terminal || '';
var opt = params.opt || 'url';
var msg = params.msg || '正在获取中...';
// 加载提示
AMUI.dialog.loading({title: msg});
// ajax
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
timeout: 305000,
data: {"plugins_type":type, "plugins_value":value, "plugins_terminal":terminal, "opt":opt, "key":key},
success: function(result)
{
if((result || null) != null && result.code == 0)
{
switch(opt)
{
// 获取下载地址
case 'url' :
params['key'] = result.data;
params['opt'] = 'download';
params['msg'] = '正在下载中...';
PackageUpgradeRequestHandle(params);
break;
// 下载插件包
case 'download' :
params['key'] = result.data;
params['opt'] = 'upgrade';
params['msg'] = '正在更新中...';
PackageUpgradeRequestHandle(params);
break;
// 更新完成
case 'upgrade' :
Prompt(result.msg, 'success');
setTimeout(function()
{
window.location.reload();
}, 1500);
break;
}
} else {
AMUI.dialog.loading('close');
Prompt(((result || null) == null) ? '返回数据格式错误' : (result.msg || '异常错误'));
}
},
error: function(xhr, type)
{
AMUI.dialog.loading('close');
Prompt(HtmlToString(xhr.responseText) || '异常错误');
}
});
}
$(function()
{
// 插件更新操作事件
$(document).on('click', '.package-upgrade-event', function()
{
// 参数处理
var json = $(this).attr('data-json') || null;
if(json != null)
{
var json = JSON.parse(decodeURIComponent(json)) || null;
}
var name = $(this).data('name') || null;
var type = $(this).data('type') || null;
var value = $(this).data('value') || null;
var terminal = $(this).data('terminal') || '';
if(name == null || type == null || value == null || json == null)
{
Prompt('操作事件参数配置有误');
return false;
}
// 数据处理打开弹窗
var $modal = $('#package-upgrade-modal');
$modal.find('.upgrade-name').text(name);
$modal.find('.upgrade-date').text(' '+json.add_time);
$modal.find('.upgrade-version').text(' '+json.version_new);
$modal.find('.am-scrollable-vertical').html(json.describe.join('<br />'));
$modal.find('.package-upgrade-submit').attr('data-type', type).attr('data-value', value).attr('data-terminal', terminal);
$modal.modal({
closeViaDimmer: false,
width: 330,
height: 257
});
});
// 插件更新操作确认
$(document).on('click', '.package-upgrade-submit', function()
{
// 基础配置、url、插件类型、标识值、小程序终端类型
var url = $(this).attr('data-url') || null;
var type = $(this).attr('data-type') || null;
var value = $(this).attr('data-value') || null;
var terminal = $(this).attr('data-terminal') || '';
if(url == null || type == null || value == null)
{
Prompt('操作参数有误');
return false;
}
$('#package-upgrade-modal').modal('close');
PackageUpgradeRequestHandle({"url":url, "type":type, "value":value, "terminal":terminal});
});
// 商品规格和参数上下移动
$('.specifications-table,.parameters-table').on('click', '.line-move', function()
{
......
/**
* 异步请求步骤
* 软件安装异步请求步骤
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
......@@ -45,7 +45,7 @@ function RequestHandle(key, opt, msg)
url: url,
type: 'POST',
dataType: 'json',
timeout: 30000,
timeout: 305000,
data: {"id":id, "type":type, "opt":opt, "key":key || '', "terminal":terminal || ''},
success: function(result)
{
......
......@@ -103,20 +103,25 @@ dialog.loading = function(options) {
options = options || {};
options.title = options.title || '正在载入...';
var html = [];
html.push('<div class="am-modal am-modal-loading am-modal-no-btn" tabindex="-1" id="my-modal-loading">');
html.push('<div class="am-modal-dialog">');
html.push('<div class="am-modal-bd">');
html.push('<span class="am-icon-spinner am-icon-spin"></span>');
html.push('<span class="am-margin-left-xs">' + options.title + '</span>');
html.push('</div>');
html.push('</div>');
html.push('</div>');
return $(html.join('')).appendTo('body').modal()
.on('closed.modal.amui', function() {
$(this).remove();
});
if($('#my-modal-loading').length > 0)
{
$('#my-modal-loading .am-modal-bd .am-margin-left-xs').text(options.title);
} else {
var html = [];
html.push('<div class="am-modal am-modal-loading am-modal-no-btn" tabindex="-1" id="my-modal-loading">');
html.push('<div class="am-modal-dialog">');
html.push('<div class="am-modal-bd">');
html.push('<span class="am-icon-spinner am-icon-spin"></span>');
html.push('<span class="am-margin-left-xs">' + options.title + '</span>');
html.push('</div>');
html.push('</div>');
html.push('</div>');
return $(html.join('')).appendTo('body').modal()
.on('closed.modal.amui', function() {
$(this).remove();
});
}
}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册