增加模块管理

This commit is contained in:
Anyon 2020-08-03 17:07:10 +08:00
parent b6734f0c20
commit fc6b18b94f
13 changed files with 300 additions and 44 deletions

View File

@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: https://thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 代码仓库https://gitee.com/zoujingli/ThinkAdmin
// | github 代码仓库https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\admin\Controller;
use think\admin\service\ModuleService;
/**
* 系统模块管理
* Class Module
* @package app\admin\controller
*/
class Module extends Controller
{
/**
* 系统模块管理
* @auth true
* @menu true
*/
public function index()
{
$this->title = '系统模块管理';
$this->modules = ModuleService::instance()->change();
$this->fetch();
}
/**
* 安装模块代码
* @auth true
*/
public function install()
{
$data = $this->_vali(['name.require' => '模块名称不能为空!']);
[$state, $message] = ModuleService::instance()->install($data['name']);
$state ? $this->success($message) : $this->error($message);
}
}

View File

@ -17,7 +17,7 @@ namespace app\admin\controller\api;
use think\admin\Controller;
use think\admin\service\InstallService;
use think\admin\service\NodeService;
use think\admin\service\ModuleService;
/**
* 安装服务端支持
@ -32,38 +32,12 @@ class Update extends Controller
*/
public function version()
{
$input = $this->_vali(['name.default' => '_all']);
if ($input['name'] === '_all') {
$data = [];
foreach (NodeService::instance()->getModules() as $module) {
if (is_array($ver = $this->__getModuleVersion($module))) $data[] = $ver;
}
$this->success('获取所有模块版本成功!', $data);
} else {
$ver = $this->__getModuleVersion($input['name']);
if ($ver === null) $this->error('获取模块信息失败!');
if ($ver === false) $this->error('获取模块信息无效!');
if (is_array($ver)) $this->success('获取模块信息成功!', [$ver]);
}
$modules = ModuleService::instance()->getModules();
$this->success('获取模块信息成功!', $modules);
}
/**
* 获取模块版本信息
* @param string $name
* @return bool|array|null
*/
private function __getModuleVersion($name)
{
$file = $this->app->getBasePath() . $name . DIRECTORY_SEPARATOR . 'ver.php';
if (file_exists($file) && is_file($file) && is_array($vars = @include $file)) {
return isset($vars['name']) && isset($vars['version']) ? $vars : null;
} else {
return false;
}
}
/**
* 读取文件内容(旧版本)
* 读取文件内容
*/
public function get()
{
@ -75,7 +49,7 @@ class Update extends Controller
}
/**
* 读取文件列表(旧版本)
* 读取文件列表
*/
public function node()
{

View File

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

View File

@ -0,0 +1,43 @@
{extend name='main'}
{block name="content"}
<div class="think-box-shadow table-block">
<table class="layui-table margin-top-15" lay-skin="line">
{notempty name='modules'}
<thead>
<tr>
<th class='text-left nowrap'>模块名称</th>
<th class='text-left nowrap'>模块描述</th>
<th class='text-left nowrap'>当前版本</th>
<th></th>
</tr>
</thead>
{/notempty}
<tbody>
{foreach $modules as $key=>$vo}
<tr>
<td class='text-left nowrap'>{$vo.name}</td>
<td class='text-left nowrap'>{$vo.content}</td>
<td class='text-left nowrap'>
{if isset($vo.local)} {$vo.local.version}
{if $vo.version > $vo.local.version}
<span class="color-red margin-left-5">{$vo.local.version}</span>
{else}
<span class="color-desc margin-left-5">{$vo.type_desc}</span>
{/if}
{else}<span class="color-desc margin-left-5">{$vo.type_desc}</span>{/if}
</td>
<td class="text-left">
{if $vo.type_code eq 1} <a class="layui-btn layui-btn-xs" data-action="{:url('install')}" data-value="name#{$vo.name}"> </a>{/if}
{if $vo.type_code eq 2} <a class="layui-btn layui-btn-xs" data-action="{:url('install')}" data-value="name#{$vo.name}"> </a>{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{empty name='modules'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
</div>
{/block}

View File

@ -0,0 +1,61 @@
<fieldset>
<legend>条件搜索</legend>
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
<div class="layui-form-item layui-inline">
<label class="layui-form-label">任务编号</label>
<div class="layui-input-inline">
<input name="code" value="{:input('get.code')}" placeholder="请输入任务编号" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">任务名称</label>
<div class="layui-input-inline">
<input name="title" value="{:input('get.title')}" placeholder="请输入任务名称" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">任务指令</label>
<div class="layui-input-inline">
<input name="command" value="{:input('get.command')}" placeholder="请输入任务指令" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">任务状态</label>
<div class="layui-input-inline">
<select name="status" class="layui-select">
{foreach [''=>'-- 全部状态 --','1'=>'待处理','2'=>'处理中','3'=>'处理完成','4'=>'处理失败'] as $k=>$v}
{if input('get.status') eq $k}
<option selected value="{$k}">{$v}</option>
{else}
<option value="{$k}">{$v}</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">计划时间</label>
<div class="layui-input-inline">
<input data-date-range name="exec_time" value="{:input('get.exec_time')}" placeholder="请选择计划时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">执行时间</label>
<div class="layui-input-inline">
<input data-date-range name="enter_time" value="{:input('get.enter_time')}" placeholder="请选择执行时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<label class="layui-form-label">创建时间</label>
<div class="layui-input-inline">
<input data-date-range name="create_at" value="{:input('get.create_at')}" placeholder="请选择创建时间" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-inline">
<button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
</div>
</form>
</fieldset>
<script>form.render()</script>

View File

@ -21,6 +21,7 @@ return [
'content' => 'ThinkAdmin 微信基础模块',
'changes' => [
'2020.08.03.00' => [
'content' => '模块初始化提交',
'database' => [
'select version()',
],

8
composer.lock generated
View File

@ -879,12 +879,12 @@
"source": {
"type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "2ce8935d423feccfd59bba2963e9127f3fca8c90"
"reference": "3241ffefd6697d1bedcc9721e3275a24055bb77b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/2ce8935d423feccfd59bba2963e9127f3fca8c90",
"reference": "2ce8935d423feccfd59bba2963e9127f3fca8c90",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/3241ffefd6697d1bedcc9721e3275a24055bb77b",
"reference": "3241ffefd6697d1bedcc9721e3275a24055bb77b",
"shasum": "",
"mirrors": [
{
@ -928,7 +928,7 @@
],
"description": "ThinkPHP v6.0 Development Library",
"homepage": "http://thinkadmin.top",
"time": "2020-07-31T10:16:54+00:00"
"time": "2020-08-03T09:00:42+00:00"
},
{
"name": "zoujingli/wechat-developer",

View File

@ -194,6 +194,7 @@ return array(
'app\\admin\\controller\\Index' => $baseDir . '/app/admin/controller/Index.php',
'app\\admin\\controller\\Login' => $baseDir . '/app/admin/controller/Login.php',
'app\\admin\\controller\\Menu' => $baseDir . '/app/admin/controller/Menu.php',
'app\\admin\\controller\\Module' => $baseDir . '/app/admin/controller/Module.php',
'app\\admin\\controller\\Oplog' => $baseDir . '/app/admin/controller/Oplog.php',
'app\\admin\\controller\\Queue' => $baseDir . '/app/admin/controller/Queue.php',
'app\\admin\\controller\\User' => $baseDir . '/app/admin/controller/User.php',
@ -293,6 +294,7 @@ return array(
'think\\admin\\service\\InstallService' => $vendorDir . '/zoujingli/think-library/src/service/InstallService.php',
'think\\admin\\service\\MenuService' => $vendorDir . '/zoujingli/think-library/src/service/MenuService.php',
'think\\admin\\service\\MessageService' => $vendorDir . '/zoujingli/think-library/src/service/MessageService.php',
'think\\admin\\service\\ModuleService' => $vendorDir . '/zoujingli/think-library/src/service/ModuleService.php',
'think\\admin\\service\\NodeService' => $vendorDir . '/zoujingli/think-library/src/service/NodeService.php',
'think\\admin\\service\\OpenService' => $vendorDir . '/zoujingli/think-library/src/service/OpenService.php',
'think\\admin\\service\\ProcessService' => $vendorDir . '/zoujingli/think-library/src/service/ProcessService.php',

View File

@ -322,6 +322,7 @@ class ComposerStaticInitb911c14a0826c73d9f097343fd33a252
'app\\admin\\controller\\Index' => __DIR__ . '/../..' . '/app/admin/controller/Index.php',
'app\\admin\\controller\\Login' => __DIR__ . '/../..' . '/app/admin/controller/Login.php',
'app\\admin\\controller\\Menu' => __DIR__ . '/../..' . '/app/admin/controller/Menu.php',
'app\\admin\\controller\\Module' => __DIR__ . '/../..' . '/app/admin/controller/Module.php',
'app\\admin\\controller\\Oplog' => __DIR__ . '/../..' . '/app/admin/controller/Oplog.php',
'app\\admin\\controller\\Queue' => __DIR__ . '/../..' . '/app/admin/controller/Queue.php',
'app\\admin\\controller\\User' => __DIR__ . '/../..' . '/app/admin/controller/User.php',
@ -421,6 +422,7 @@ class ComposerStaticInitb911c14a0826c73d9f097343fd33a252
'think\\admin\\service\\InstallService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/InstallService.php',
'think\\admin\\service\\MenuService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/MenuService.php',
'think\\admin\\service\\MessageService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/MessageService.php',
'think\\admin\\service\\ModuleService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/ModuleService.php',
'think\\admin\\service\\NodeService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/NodeService.php',
'think\\admin\\service\\OpenService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/OpenService.php',
'think\\admin\\service\\ProcessService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/ProcessService.php',

View File

@ -903,12 +903,12 @@
"source": {
"type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "2ce8935d423feccfd59bba2963e9127f3fca8c90"
"reference": "3241ffefd6697d1bedcc9721e3275a24055bb77b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/2ce8935d423feccfd59bba2963e9127f3fca8c90",
"reference": "2ce8935d423feccfd59bba2963e9127f3fca8c90",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/3241ffefd6697d1bedcc9721e3275a24055bb77b",
"reference": "3241ffefd6697d1bedcc9721e3275a24055bb77b",
"shasum": "",
"mirrors": [
{
@ -924,7 +924,7 @@
"ext-json": "*",
"topthink/framework": "^6.0"
},
"time": "2020-07-31T10:16:54+00:00",
"time": "2020-08-03T09:00:42+00:00",
"type": "library",
"extra": {
"think": {

2
vendor/services.php vendored
View File

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

View File

@ -73,11 +73,11 @@ class Library extends Service
$this->app->request->setPathinfo($_SERVER['argv'][1]);
}
} else {
// 注册语言包处理中间键
$this->app->middleware->add(LoadLangPack::class);
// 注册会话初始化中间键
if ($this->app->request->request('not_init_session', 0) == 0) {
// 注册会话初始化中间键
$this->app->middleware->add(SessionInit::class);
// 注册语言包处理中间键
$this->app->middleware->add(LoadLangPack::class);
}
// 注册访问处理中间键
$this->app->middleware->add(function (Request $request, \Closure $next) {

View File

@ -0,0 +1,122 @@
<?php
// +----------------------------------------------------------------------
// | Library for ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: https://gitee.com/zoujingli/ThinkLibrary
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 仓库地址 https://gitee.com/zoujingli/ThinkLibrary
// | github 仓库地址 https://github.com/zoujingli/ThinkLibrary
// +----------------------------------------------------------------------
namespace think\admin\service;
use think\admin\extend\HttpExtend;
use think\admin\Service;
/**
* 系统模块管理
* Class ModuleService
* @package think\admin\service
*/
class ModuleService extends Service
{
/**
* 获取模块变更
* @return array
*/
public function change()
{
[$online, $locals] = [$this->online(), $this->getModules()];
foreach ($online as &$item) if (isset($locals[$item['name']])) {
$item['local'] = $locals[$item['name']];
if ($item['local']['version'] < $item['version']) {
$item['type_code'] = 2;
$item['type_desc'] = '需要更新';
} else {
$item['type_code'] = 3;
$item['type_desc'] = '无需更新';
}
} else {
$item['type_code'] = 1;
$item['type_desc'] = '未安装';
}
return $online;
}
/**
* 安装或更新模块
* @param string $name
* @return array
*/
public function install($name): array
{
$install = InstallService::instance();
$data = $install->grenerateDifference(["app/{$name}"]);
if (empty($data)) return [0, '没有需要安装的文件', []];
$lines = [];
foreach ($data as $file) {
[$state, $mode, $name] = $install->fileSynchronization($file);
if ($state) {
if ($mode === 'add') $lines[] = "add {$name} successed";
if ($mode === 'mod') $lines[] = "modify {$name} successed";
if ($mode === 'del') $lines[] = "delete {$name} successed";
} else {
if ($mode === 'add') $lines[] = "add {$name} failed";
if ($mode === 'mod') $lines[] = "modify {$name} failed";
if ($mode === 'del') $lines[] = "delete {$name} failed";
}
}
return [1, '模块安装成功', $lines];
}
/**
* 获取线上模块数据
* @return array
*/
public function online(): array
{
$data = $this->app->cache->get('module-online-data', []);
if (!empty($data)) return $data;
$result = json_decode(HttpExtend::get('https://v6.thinkadmin.top/admin/api.update/version'), true);
if (isset($result['code']) && $result['code'] > 0 && isset($result['data']) && is_array($result['data'])) {
foreach ($result['data'] as $item) $data[$item['name']] = $item;
$this->app->cache->set('module-online-data', $data, 1800);
return $data;
} else {
return [];
}
}
/**
* 获取系统模块信息
* @return array
*/
public function getModules(): array
{
$data = [];
foreach (NodeService::instance()->getModules() as $name) {
if (is_array($ver = $this->__getVersion($name))) $data[$name] = $ver;
}
return $data;
}
/**
* 获取模块版本信息
* @param string $name 模块名称
* @return bool|array|null
*/
private function __getVersion($name)
{
$file = $this->app->getBasePath() . $name . DIRECTORY_SEPARATOR . 'ver.php';
if (file_exists($file) && is_file($file) && is_array($vars = @include $file)) {
return isset($vars['name']) && isset($vars['version']) ? $vars : null;
} else {
return false;
}
}
}