2021-02-23 12:16:31 +08:00
|
|
|
|
<?php
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Author: Devil
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
namespace app\service;
|
|
|
|
|
|
|
|
|
|
use think\Db;
|
|
|
|
|
use app\service\PluginsAdminService;
|
2021-02-24 12:40:34 +08:00
|
|
|
|
use app\service\PaymentService;
|
|
|
|
|
use app\service\ThemeService;
|
2021-02-24 17:34:06 +08:00
|
|
|
|
use app\service\AppMiniService;
|
2021-02-23 12:16:31 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 软件安装服务层
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2020-09-12
|
|
|
|
|
* @desc description
|
|
|
|
|
*/
|
|
|
|
|
class PackageInstallService
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 获取安装参数
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function RequestInstallParams($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 商店商品id
|
|
|
|
|
$id = empty($params['id']) ? 0 : intval($params['id']);
|
|
|
|
|
|
|
|
|
|
// 类型
|
|
|
|
|
$type = empty($params['type']) ? '' : $params['type'];
|
|
|
|
|
|
2021-02-24 12:40:34 +08:00
|
|
|
|
// 适配终端
|
|
|
|
|
$terminal = empty($params['terminal']) ? '' : $params['terminal'];
|
|
|
|
|
|
|
|
|
|
// 返回页面url地址
|
|
|
|
|
switch($type)
|
|
|
|
|
{
|
|
|
|
|
// 功能插件
|
|
|
|
|
case 'plugins' :
|
|
|
|
|
$url = MyUrl('admin/pluginsadmin/index');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// 支付插件
|
|
|
|
|
case 'payment' :
|
|
|
|
|
$url = MyUrl('admin/payment/index');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// web端主题
|
|
|
|
|
case 'webtheme' :
|
|
|
|
|
$url = MyUrl('admin/theme/index');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// 小程序主题
|
|
|
|
|
case 'minitheme' :
|
|
|
|
|
$url = MyUrl('admin/appmini/index');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// app主题
|
|
|
|
|
case 'apptheme' :
|
|
|
|
|
$url = MyUrl('admin/app/index');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default :
|
|
|
|
|
$url = '';
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-23 12:16:31 +08:00
|
|
|
|
return [
|
|
|
|
|
'id' => $id,
|
|
|
|
|
'type' => $type,
|
2021-02-24 12:40:34 +08:00
|
|
|
|
'terminal' => $terminal,
|
2021-02-23 12:16:31 +08:00
|
|
|
|
'url' => MyUrl('admin/packageinstall/install'),
|
2021-02-24 12:40:34 +08:00
|
|
|
|
'admin_url' => MyUrl('admin/index/index', ['to_url'=>urlencode(base64_encode($url))]),
|
2021-02-23 12:16:31 +08:00
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 软件安装
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function Install($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 参数校验
|
|
|
|
|
$ret = self::ParamsCheck($params);
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 操作类型
|
|
|
|
|
switch($params['opt'])
|
|
|
|
|
{
|
|
|
|
|
// 获取url地址
|
|
|
|
|
case 'url' :
|
2021-02-24 12:40:34 +08:00
|
|
|
|
$ret = self::UrlHandle($params);
|
2021-02-23 12:16:31 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// 下载软件包
|
|
|
|
|
case 'download' :
|
|
|
|
|
$ret = self::DownloadHandle($params['key']);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// 安装软件包
|
|
|
|
|
case 'install' :
|
|
|
|
|
$ret = self::InstallHandle($params);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 安装软件包
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function InstallHandle($params)
|
|
|
|
|
{
|
|
|
|
|
// 获取目录文件
|
|
|
|
|
$res = self::DirFileData($params['key']);
|
|
|
|
|
if(!file_exists($res['url']))
|
|
|
|
|
{
|
|
|
|
|
return DataReturn('软件包不存在、请重新安装', -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据插件类型调用安装程序
|
|
|
|
|
switch($params['type'])
|
|
|
|
|
{
|
|
|
|
|
// 功能插件
|
|
|
|
|
case 'plugins' :
|
|
|
|
|
$ret = PluginsAdminService::PluginsUploadHandle($res['url'], $params);
|
|
|
|
|
break;
|
|
|
|
|
|
2021-02-24 12:40:34 +08:00
|
|
|
|
// 支付插件
|
|
|
|
|
case 'payment' :
|
|
|
|
|
$ret = PaymentService::UploadHandle($res['url'], $params);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// web主题
|
|
|
|
|
case 'webtheme' :
|
|
|
|
|
$ret = ThemeService::ThemeUploadHandle($res['url'], $params);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// 小程序主题
|
|
|
|
|
case 'minitheme' :
|
2021-02-24 17:34:06 +08:00
|
|
|
|
if(empty($params['terminal']))
|
|
|
|
|
{
|
|
|
|
|
return DataReturn('未指定小程序终端类型', -1);
|
|
|
|
|
}
|
|
|
|
|
$params['application_name'] = $params['terminal'];
|
|
|
|
|
$ret = AppMiniService::ThemeUploadHandle($res['url'], $params);
|
2021-02-24 12:40:34 +08:00
|
|
|
|
break;
|
|
|
|
|
|
2021-02-23 12:16:31 +08:00
|
|
|
|
// 默认
|
|
|
|
|
default :
|
2021-02-24 12:40:34 +08:00
|
|
|
|
$ret = DataReturn('插件操作类型未定义['.$params['type'].']', -1);
|
2021-02-23 12:16:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移除session
|
|
|
|
|
session($params['key'], null);
|
|
|
|
|
|
|
|
|
|
// 删除本地文件
|
|
|
|
|
\base\FileUtil::UnlinkFile($res['url']);
|
|
|
|
|
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载软件包
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-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)) !== false)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn('success', 0, $key);
|
|
|
|
|
}
|
|
|
|
|
return DataReturn('插件下载失败', -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取下载地址
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-22
|
|
|
|
|
* @desc description
|
2021-02-24 12:40:34 +08:00
|
|
|
|
* @param [array] $params [输入参数]
|
2021-02-23 12:16:31 +08:00
|
|
|
|
*/
|
2021-02-24 12:40:34 +08:00
|
|
|
|
public static function UrlHandle($params)
|
2021-02-23 12:16:31 +08:00
|
|
|
|
{
|
|
|
|
|
// 获取下载地址
|
|
|
|
|
$url = config('shopxo.store_download_url');
|
|
|
|
|
$data = [
|
2021-02-24 12:40:34 +08:00
|
|
|
|
'goods_id' => $params['id'],
|
2021-02-23 12:16:31 +08:00
|
|
|
|
'url' => __MY_URL__,
|
|
|
|
|
'host' => __MY_HOST__,
|
|
|
|
|
'ip' => __MY_ADDR__,
|
|
|
|
|
'ver' => APPLICATION_VERSION,
|
2021-02-24 12:40:34 +08:00
|
|
|
|
'terminal' => empty($params['terminal']) ? '' : $params['terminal'],
|
2021-02-23 12:16:31 +08:00
|
|
|
|
];
|
2021-02-28 01:21:50 +08:00
|
|
|
|
foreach($data as $k=>$v)
|
|
|
|
|
{
|
|
|
|
|
$data[$k] = urldecode(base64_encode($v));
|
|
|
|
|
}
|
2021-02-23 12:16:31 +08:00
|
|
|
|
$ret = self::HttpRequest($url, $data);
|
|
|
|
|
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-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $key [缓存key]
|
|
|
|
|
*/
|
|
|
|
|
public static function DirFileData($key)
|
|
|
|
|
{
|
|
|
|
|
// 将软件包下载到磁盘
|
|
|
|
|
$dir = ROOT;
|
|
|
|
|
$path = 'runtime'.DS.'data'.DS.'plugins_package_install'.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-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function ParamsCheck($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'id',
|
|
|
|
|
'error_msg' => '商品id有误',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'type',
|
|
|
|
|
'error_msg' => '插件类型有误',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'in',
|
|
|
|
|
'key_name' => 'opt',
|
|
|
|
|
'checked_data' => ['url', 'download', 'install'],
|
|
|
|
|
'error_msg' => '操作类型有误',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下载和安装需要校验key
|
|
|
|
|
if(in_array($params['opt'], ['download', 'install']) && empty($params['key']))
|
|
|
|
|
{
|
|
|
|
|
return DataReturn('操作key有误', -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DataReturn('success', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 网络请求
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-02-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $url [请求url]
|
|
|
|
|
* @param [array] $data [发送数据]
|
|
|
|
|
* @return [json] [请求返回数据]
|
|
|
|
|
*/
|
|
|
|
|
public static function HttpRequest($url, $data)
|
|
|
|
|
{
|
|
|
|
|
$ch = curl_init();
|
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
|
|
curl_setopt($ch, CURLOPT_FAILONERROR, false);
|
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
|
|
|
|
|
|
$body_string = '';
|
|
|
|
|
if(is_array($data) && 0 < count($data))
|
|
|
|
|
{
|
|
|
|
|
foreach($data as $k => $v)
|
|
|
|
|
{
|
|
|
|
|
$body_string .= $k.'='.urlencode($v).'&';
|
|
|
|
|
}
|
|
|
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_string);
|
|
|
|
|
}
|
|
|
|
|
$headers = [
|
|
|
|
|
'Content-type: application/x-www-form-urlencoded;charset=UTF-8',
|
|
|
|
|
'X-Requested-With: XMLHttpRequest',
|
|
|
|
|
];
|
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
|
|
$reponse = curl_exec($ch);
|
|
|
|
|
$error = curl_errno($ch);
|
|
|
|
|
curl_close($ch);
|
|
|
|
|
if($error)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn("curl出错,错误码:$error", -1);
|
|
|
|
|
}
|
2021-02-24 12:40:34 +08:00
|
|
|
|
|
|
|
|
|
// 是否json格式数据
|
|
|
|
|
if(substr($reponse, 0, 1) != '{')
|
|
|
|
|
{
|
|
|
|
|
return DataReturn("返回数据格式有误:$reponse", -1);
|
|
|
|
|
}
|
2021-02-23 12:16:31 +08:00
|
|
|
|
return json_decode($reponse, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|