ComposerUpdate

This commit is contained in:
Anyon 2020-08-05 10:46:24 +08:00
parent 11f00c254a
commit 12f94b19e6
13 changed files with 115 additions and 59 deletions

View File

@ -38,7 +38,7 @@ class Module extends Controller
} }
/** /**
* 安装模块代码 * 安装更新模块
* @auth true * @auth true
*/ */
public function install() public function install()

View File

@ -27,22 +27,19 @@ use think\admin\service\ModuleService;
class Update extends Controller class Update extends Controller
{ {
/**
* 获取模块信息
*/
public function version()
{
$modules = ModuleService::instance()->getModules();
$this->success('获取模块信息成功!', $modules);
}
/** /**
* 读取文件内容 * 读取文件内容
*/ */
public function get() public function get()
{ {
if (file_exists($file = $this->app->getRootPath() . decode(input('encode', '0')))) { $filename = decode(input('encode', '0'));
$this->success('读取文件成功!', ['content' => base64_encode(file_get_contents($file))]); if (!ModuleService::instance()->checkAllowDownload($filename)) {
$this->error('下载的文件不在认证规则中!');
}
if (file_exists($realname = $this->app->getRootPath() . $filename)) {
$this->success('读取文件内容成功!', [
'content' => base64_encode(file_get_contents($realname)),
]);
} else { } else {
$this->error('读取文件内容失败!'); $this->error('读取文件内容失败!');
} }
@ -59,4 +56,12 @@ class Update extends Controller
)); ));
} }
/**
* 获取模块信息
*/
public function version()
{
$this->success('获取模块信息成功!', ModuleService::instance()->getModules());
}
} }

View File

@ -17,11 +17,15 @@
return [ return [
'name' => 'admin', 'name' => 'admin',
'author' => 'Anyon', 'author' => 'Anyon',
'version' => '2020.08.01.00', 'version' => '2020.08.05.00',
'content' => 'ThinkAdmin 系统基础模块', 'content' => 'ThinkAdmin 系统基础模块',
'changes' => [ 'changes' => [
'2020.08.05.00' => [
'content' => '优化系统模块管理',
'database' => ['select version()'],
],
'2020.08.03.00' => [ '2020.08.03.00' => [
'content' => '模块初始化提交', 'content' => '系统模块初始化提交',
'database' => ['select version()'], 'database' => ['select version()'],
], ],
], ],

8
composer.lock generated
View File

@ -879,12 +879,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git", "url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5" "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/d799064954094a3ca5d548d2b6e1e575a4dbeac5", "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/8e1a13fd20d0a454ecccab056a0f6ebe477fe65f",
"reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5", "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -928,7 +928,7 @@
], ],
"description": "ThinkPHP v6.0 Development Library", "description": "ThinkPHP v6.0 Development Library",
"homepage": "http://thinkadmin.top", "homepage": "http://thinkadmin.top",
"time": "2020-08-03T09:33:56+00:00" "time": "2020-08-05T02:41:59+00:00"
}, },
{ {
"name": "zoujingli/wechat-developer", "name": "zoujingli/wechat-developer",

View File

@ -903,12 +903,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git", "url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5" "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/d799064954094a3ca5d548d2b6e1e575a4dbeac5", "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/8e1a13fd20d0a454ecccab056a0f6ebe477fe65f",
"reference": "d799064954094a3ca5d548d2b6e1e575a4dbeac5", "reference": "8e1a13fd20d0a454ecccab056a0f6ebe477fe65f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -924,7 +924,7 @@
"ext-json": "*", "ext-json": "*",
"topthink/framework": "^6.0" "topthink/framework": "^6.0"
}, },
"time": "2020-08-03T09:33:56+00:00", "time": "2020-08-05T02:41:59+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php <?php
// This file is automatically generated at:2020-08-03 18:04:42 // This file is automatically generated at:2020-08-05 10:46:09
declare (strict_types = 1); declare (strict_types = 1);
return array ( return array (
0 => 'think\\admin\\Library', 0 => 'think\\admin\\Library',

View File

@ -62,18 +62,20 @@ class Library extends Service
*/ */
public function register() public function register()
{ {
// 输入默认过滤
$this->app->request->filter(['trim']);
// 加载中文语言 // 加载中文语言
$this->app->lang->load(__DIR__ . '/lang/zh-cn.php', 'zh-cn'); $this->app->lang->load(__DIR__ . '/lang/zh-cn.php', 'zh-cn');
$this->app->lang->load(__DIR__ . '/lang/en-us.php', 'en-us'); $this->app->lang->load(__DIR__ . '/lang/en-us.php', 'en-us');
// 输入变量默认过滤
$this->app->request->filter(['trim']);
// 判断访问模式,兼容 CLI 访问控制器 // 判断访问模式,兼容 CLI 访问控制器
if ($this->app->request->isCli()) { if ($this->app->request->isCli()) {
if (empty($_SERVER['REQUEST_URI']) && isset($_SERVER['argv'][1])) { if (empty($_SERVER['REQUEST_URI']) && isset($_SERVER['argv'][1])) {
$this->app->request->setPathinfo($_SERVER['argv'][1]); $this->app->request->setPathinfo($_SERVER['argv'][1]);
} }
} else { } else {
if ($this->app->request->request('not_init_session', 0) == 0) { $isSess = $this->app->request->request('not_init_session', 0) > 0;
$notYar = stripos($this->app->request->header('user-agent', ''), 'PHP Yar RPC-') !== false;
if ($notYar && $isSess) {
// 注册会话初始化中间键 // 注册会话初始化中间键
$this->app->middleware->add(SessionInit::class); $this->app->middleware->add(SessionInit::class);
// 注册语言包处理中间键 // 注册语言包处理中间键

View File

@ -117,7 +117,7 @@ class Install extends Command
$data = InstallService::instance()->grenerateDifference($this->rules, $this->ignore); $data = InstallService::instance()->grenerateDifference($this->rules, $this->ignore);
if (empty($data)) $this->output->writeln('No need to update the file if the file comparison is consistent'); if (empty($data)) $this->output->writeln('No need to update the file if the file comparison is consistent');
else foreach ($data as $file) { else foreach ($data as $file) {
[$state, $mode, $name] = InstallService::instance()->fileSynchronization($file); [$state, $mode, $name] = InstallService::instance()->updateFileByDownload($file);
if ($state) { if ($state) {
if ($mode === 'add') $this->output->writeln("--- {$name} add successfully"); if ($mode === 'add') $this->output->writeln("--- {$name} add successfully");
if ($mode === 'mod') $this->output->writeln("--- {$name} update successfully"); if ($mode === 'mod') $this->output->writeln("--- {$name} update successfully");

View File

@ -142,7 +142,7 @@ class AdminService extends Service
*/ */
public function clearCache() public function clearCache()
{ {
$this->app->cache->delete('system_auth_node'); $this->app->cache->delete('SystemAuthNode');
return $this; return $this;
} }

View File

@ -60,12 +60,12 @@ class InstallService extends Service
*/ */
protected function initialize() protected function initialize()
{ {
// 应用根目录
$this->root = strtr($this->app->getRootPath(), '\\', '/');
// 应用框架版本 // 应用框架版本
$this->version = $this->app->config->get('app.thinkadmin_ver') ?: 'v4'; $this->version = $this->app->config->get('app.thinkadmin_ver') ?: 'v4';
// 线上应用代码 // 线上应用代码
$this->server = "https://{$this->version}.thinkadmin.top"; $this->server = "https://{$this->version}.thinkadmin.top";
// 应用根目录
$this->root = strtr($this->app->getRootPath(), '\\', '/');
} }
/** /**
@ -87,11 +87,11 @@ class InstallService extends Service
} }
/** /**
* 同步更新文件 * 下载并更新文件
* @param array $file * @param array $file 文件信息
* @return array * @return array
*/ */
public function fileSynchronization($file) public function updateFileByDownload(array $file): array
{ {
if (in_array($file['type'], ['add', 'mod'])) { if (in_array($file['type'], ['add', 'mod'])) {
if ($this->downloadFile(encode($file['name']))) { if ($this->downloadFile(encode($file['name']))) {
@ -117,7 +117,8 @@ class InstallService extends Service
*/ */
private function downloadFile($encode) private function downloadFile($encode)
{ {
$result = json_decode(HttpExtend::get("{$this->server}?s=admin/api.update/get&encode={$encode}"), true); $source = "{$this->server}/admin/api.update/get?encode={$encode}";
$result = json_decode(HttpExtend::get($source), true);
if (empty($result['code'])) return false; if (empty($result['code'])) return false;
$filename = $this->root . decode($encode); $filename = $this->root . decode($encode);
file_exists(dirname($filename)) || mkdir(dirname($filename), 0755, true); file_exists(dirname($filename)) || mkdir(dirname($filename), 0755, true);
@ -141,10 +142,10 @@ class InstallService extends Service
* @param array $ignore 忽略规则 * @param array $ignore 忽略规则
* @return array * @return array
*/ */
public function grenerateDifference($rules = [], $ignore = []) public function grenerateDifference(array $rules = [], array $ignore = []): array
{ {
[$this->rules, $this->ignore, $data] = [$rules, $ignore, []]; [$this->rules, $this->ignore, $data] = [$rules, $ignore, []];
$result = json_decode(HttpExtend::post("{$this->server}?s=/admin/api.update/node", [ $result = json_decode(HttpExtend::post("{$this->server}/admin/api.update/node", [
'rules' => json_encode($this->rules), 'ignore' => json_encode($this->ignore), 'rules' => json_encode($this->rules), 'ignore' => json_encode($this->ignore),
]), true); ]), true);
if (!empty($result['code'])) { if (!empty($result['code'])) {
@ -164,24 +165,24 @@ class InstallService extends Service
* @param array $local 本地文件列表信息 * @param array $local 本地文件列表信息
* @return array * @return array
*/ */
private function grenerateDifferenceContrast(array $serve = [], array $local = []) private function grenerateDifferenceContrast(array $serve = [], array $local = []): array
{ {
// 数据扁平化 // 数据扁平化
[$_serve, $_local, $_new] = [[], [], []]; [$_serve, $_local, $_diffy] = [[], [], []];
foreach ($serve as $t) $_serve[$t['name']] = $t; foreach ($serve as $t) $_serve[$t['name']] = $t;
foreach ($local as $t) $_local[$t['name']] = $t; foreach ($local as $t) $_local[$t['name']] = $t;
unset($serve, $local); unset($serve, $local);
// 线上数据差异计算 // 线上数据差异计算
foreach ($_serve as $t) isset($_local[$t['name']]) ? array_push($_new, [ foreach ($_serve as $t) isset($_local[$t['name']]) ? array_push($_diffy, [
'type' => $t['hash'] === $_local[$t['name']]['hash'] ? null : 'mod', 'name' => $t['name'], 'type' => $t['hash'] === $_local[$t['name']]['hash'] ? null : 'mod', 'name' => $t['name'],
]) : array_push($_new, ['type' => 'add', 'name' => $t['name']]); ]) : array_push($_diffy, ['type' => 'add', 'name' => $t['name']]);
// 本地数据增量计算 // 本地数据增量计算
foreach ($_local as $t) if (!isset($_serve[$t['name']])) array_push($_new, ['type' => 'del', 'name' => $t['name']]); foreach ($_local as $t) if (!isset($_serve[$t['name']])) array_push($_diffy, ['type' => 'del', 'name' => $t['name']]);
unset($_serve, $_local); unset($_serve, $_local);
usort($_new, function ($a, $b) { usort($_diffy, function ($a, $b) {
return $a['name'] !== $b['name'] ? ($a['name'] > $b['name'] ? 1 : -1) : 0; return $a['name'] !== $b['name'] ? ($a['name'] > $b['name'] ? 1 : -1) : 0;
}); });
return $_new; return $_diffy;
} }
/** /**
@ -191,7 +192,7 @@ class InstallService extends Service
* @param array $data 扫描结果列表 * @param array $data 扫描结果列表
* @return array * @return array
*/ */
public function getList(array $rules, array $ignore = [], array $data = []) public function getList(array $rules, array $ignore = [], array $data = []): array
{ {
// 扫描规则文件 // 扫描规则文件
foreach ($rules as $key => $rule) { foreach ($rules as $key => $rule) {
@ -199,9 +200,10 @@ class InstallService extends Service
$data = array_merge($data, $this->scanList("{$this->root}{$name}")); $data = array_merge($data, $this->scanList("{$this->root}{$name}"));
} }
// 清除忽略文件 // 清除忽略文件
foreach ($data as $key => $item) foreach ($ignore as $ingore) { foreach ($data as $key => $item) foreach ($ignore as $igr) {
if (stripos($item['name'], $ingore) === 0) unset($data[$key]); if (stripos($item['name'], $igr) === 0) unset($data[$key]);
} }
// 返回文件数据
return ['rules' => $rules, 'ignore' => $ignore, 'list' => $data]; return ['rules' => $rules, 'ignore' => $ignore, 'list' => $data];
} }
@ -211,7 +213,7 @@ class InstallService extends Service
* @param array $data 扫描结果 * @param array $data 扫描结果
* @return array * @return array
*/ */
private function scanList($path, $data = []) private function scanList($path, $data = []): array
{ {
if (file_exists($path)) if (is_dir($path)) foreach (scandir($path) as $sub) { if (file_exists($path)) if (is_dir($path)) foreach (scandir($path) as $sub) {
if (strpos($sub, '.') !== 0) if (is_dir($temp = "{$path}/{$sub}")) { if (strpos($sub, '.') !== 0) if (is_dir($temp = "{$path}/{$sub}")) {
@ -227,14 +229,14 @@ class InstallService extends Service
/** /**
* 获取指定文件信息 * 获取指定文件信息
* @param string $filename * @param string $realname 文件路径
* @return array * @return array
*/ */
private function getInfo($filename) private function getInfo($realname): array
{ {
return [ return [
'name' => str_replace($this->root, '', $filename), 'name' => str_replace($this->root, '', $realname),
'hash' => md5(preg_replace('/\s+/', '', file_get_contents($filename))), 'hash' => md5(preg_replace('/\s+/', '', file_get_contents($realname))),
]; ];
} }
} }

View File

@ -81,7 +81,7 @@ class ModuleService extends Service
} else { } else {
$lines = []; $lines = [];
foreach ($data as $file) { foreach ($data as $file) {
[$state, $mode, $name] = InstallService::instance()->fileSynchronization($file); [$state, $mode, $name] = InstallService::instance()->updateFileByDownload($file);
if ($state) { if ($state) {
if ($mode === 'add') $lines[] = "add {$name} successed"; if ($mode === 'add') $lines[] = "add {$name} successed";
if ($mode === 'mod') $lines[] = "modify {$name} successed"; if ($mode === 'mod') $lines[] = "modify {$name} successed";
@ -113,6 +113,39 @@ class ModuleService extends Service
return $data; return $data;
} }
/**
* 获取允许下载的规则
* @return array
*/
public function getAllowDownloadRule(): array
{
$data = $this->app->cache->get('moduleAllowRule', []);
if (is_array($data) && count($data) > 0) return $data;
$data = ['config', 'public/static'];
foreach (array_keys($this->getModules()) as $name) $data[] = "app/{$name}";
$this->app->cache->set('moduleAllowRule', $data, 30);
return $data;
}
/**
* 检查文件是否可下载
* @param string $name 文件名称
* @return boolean
*/
public function checkAllowDownload($name): bool
{
// 禁止下载数据库配置文件
if (stripos($name, 'database.php') !== false) {
return false;
}
// 检查允许下载的文件规则
foreach ($this->getAllowDownloadRule() as $rule) {
if (stripos($name, $rule) !== false) return true;
}
// 不在允许下载的文件规则
return false;
}
/** /**
* 获取模块版本信息 * 获取模块版本信息
* @param string $name 模块名称 * @param string $name 模块名称

View File

@ -94,7 +94,7 @@ class NodeService extends Service
static $data = []; static $data = [];
if (empty($force)) { if (empty($force)) {
if (count($data) > 0) return $data; if (count($data) > 0) return $data;
$data = $this->app->cache->get('system_auth_node', []); $data = $this->app->cache->get('SystemAuthNode', []);
if (count($data) > 0) return $data; if (count($data) > 0) return $data;
} else { } else {
$data = []; $data = [];
@ -113,7 +113,7 @@ class NodeService extends Service
} }
} }
$data = array_change_key_case($data, CASE_LOWER); $data = array_change_key_case($data, CASE_LOWER);
$this->app->cache->set('system_auth_node', $data); $this->app->cache->set('SystemAuthNode', $data);
return $data; return $data;
} }

View File

@ -55,6 +55,17 @@ class OpenService extends Service
$this->appkey = $appkey ?: sysconf('data.cuci_open_appkey'); $this->appkey = $appkey ?: sysconf('data.cuci_open_appkey');
} }
/**
* 接口数据签名
* @param array $data [time, nostr, json, sign]
* @return array
*/
public function signData(array $data): array
{
[$time, $nostr, $json] = [time(), uniqid(), json_encode($data, JSON_UNESCAPED_UNICODE)];
return [$time, $nostr, $json, md5("{$this->appid}#{$json}#{$time}#{$this->appkey}#{$nostr}")];
}
/** /**
* 接口数据请求 * 接口数据请求
* @param string $uri 接口地址 * @param string $uri 接口地址
@ -64,11 +75,10 @@ class OpenService extends Service
*/ */
public function doRequest(string $uri, array $data = []): array public function doRequest(string $uri, array $data = []): array
{ {
[$time, $nostr, $json] = [time(), uniqid(), json_encode($data)]; [$time, $nostr, $json, $sign] = $this->signData($data);
$sign = md5($this->appid . '#' . $json . '#' . $time . '#' . $this->appkey . '#' . $nostr); $post = ['appid' => $this->appid, 'time' => $time, 'nostr' => $nostr, 'sign' => $sign, 'data' => $json];
$data = ['appid' => $this->appid, 'time' => $time, 'nostr' => $nostr, 'sign' => $sign, 'data' => $json]; $result = json_decode(HttpExtend::post("https://open.cuci.cc/{$uri}", $post), true);
$result = json_decode(HttpExtend::post("https://open.cuci.cc/{$uri}", $data), true); if (empty($result)) throw new \think\admin\Exception('服务端接口响应异常');
if (empty($result)) throw new \think\admin\Exception('接口响应异常');
if (empty($result['code'])) throw new \think\admin\Exception($result['info']); if (empty($result['code'])) throw new \think\admin\Exception($result['info']);
return $result['data'] ?? []; return $result['data'] ?? [];
} }