初始化本地仓库
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*+------------------
|
||||
* madong
|
||||
*+------------------
|
||||
* Copyright (c) https://gitee.com/motion-code All rights reserved.
|
||||
*+------------------
|
||||
* Author: Mr. April (405784684@qq.com)
|
||||
*+------------------
|
||||
* Official Website: http://www.madong.tech
|
||||
*/
|
||||
|
||||
namespace app\service\core\plugin;
|
||||
|
||||
use core\base\BaseService;
|
||||
|
||||
/**
|
||||
* 插件基类服务
|
||||
*
|
||||
* 提供基础路径属性和插件方法执行能力
|
||||
* CLI 和在线模式共享同一套逻辑
|
||||
*/
|
||||
abstract class PluginBaseService extends BaseService
|
||||
{
|
||||
/**
|
||||
* 插件临时目录基础路径
|
||||
*/
|
||||
const RUNTIME_PLUGIN_PATH = 'install/plugin';
|
||||
|
||||
/**
|
||||
* 获取插件构建目录
|
||||
*/
|
||||
public static function getPluginBuildPath(): string
|
||||
{
|
||||
return self::RUNTIME_PLUGIN_PATH . '/build';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件包输出目录
|
||||
*/
|
||||
public static function getPluginPackagesPath(): string
|
||||
{
|
||||
return self::RUNTIME_PLUGIN_PATH . '/packages';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件终端输出目录
|
||||
*/
|
||||
public static function getPluginTerminalPath(): string
|
||||
{
|
||||
return self::RUNTIME_PLUGIN_PATH . '/terminal';
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件根目录
|
||||
*/
|
||||
protected string $plugin_path;
|
||||
|
||||
/**
|
||||
* 项目根目录(前端和后端的父级目录)
|
||||
* 注意:此路径已不再直接指向前端目录
|
||||
* 前端目录统一在 $project_path/frontend 下,如 admin、web、uni-app 等
|
||||
*/
|
||||
protected string $project_path;
|
||||
|
||||
/**
|
||||
* 后端根目录
|
||||
*/
|
||||
protected string $server_path;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->plugin_path = base_path('plugin');
|
||||
$this->project_path = dirname(base_path()); // 项目根目录(前端和后端的父级)
|
||||
$this->server_path = base_path(); // 后端根目录
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取前端基础目录
|
||||
* 前端代码统一在 frontend 目录下
|
||||
*
|
||||
* @return string 前端基础目录
|
||||
*/
|
||||
public function getFrontendPath(): string
|
||||
{
|
||||
return $this->project_path . DIRECTORY_SEPARATOR . 'frontend';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取前端指定项目目录
|
||||
*
|
||||
* @param string $frontendType 前端类型(admin/web/uni-app)
|
||||
* @return string 前端项目目录
|
||||
*/
|
||||
public function getFrontendProjectPath(string $frontendType): string
|
||||
{
|
||||
return $this->getFrontendPath() . DIRECTORY_SEPARATOR . $frontendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件配置(兼容 ConfigTrait)
|
||||
*
|
||||
* @param string $code 插件编码
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getPluginConfig(string $code): ?array
|
||||
{
|
||||
$configFile = $this->plugin_path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'info.php';
|
||||
if (is_file($configFile)) {
|
||||
return include $configFile;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插件 Install 类方法
|
||||
*
|
||||
* 统一调用插件的 install/uninstall/update 方法
|
||||
* CLI 和在线模式都通过此方法调用
|
||||
*
|
||||
* @param string $code 插件编码
|
||||
* @param string $action 方法名 (install/uninstall/update)
|
||||
* @param string|null $version 版本(对于 install 是目标版本,对于 update 是新版本)
|
||||
* @param string|null $oldVersion 旧版本(仅 update 时使用)
|
||||
* @param bool $silent 是否静默执行失败(true: 失败不抛出异常, false: 失败抛出异常)
|
||||
* @return bool 是否成功执行
|
||||
* @throws \Exception 当 silent=false 且执行失败时抛出异常
|
||||
*/
|
||||
protected function executePluginMethod(string $code, string $action, ?string $version = null, ?string $oldVersion = null, bool $silent = false): bool
|
||||
{
|
||||
$className = "plugin\\" . $code . "\\Install";
|
||||
if (!class_exists($className)) {
|
||||
// 插件未提供 Install 类,静默跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$pluginConfig = $this->getPluginConfig($code);
|
||||
$version = $pluginConfig['version'] ?? ($version ?? '1.0.0');
|
||||
|
||||
// 实例化插件 Install 类
|
||||
$installInstance = new $className();
|
||||
|
||||
switch ($action) {
|
||||
case 'install':
|
||||
if (method_exists($installInstance, 'install')) {
|
||||
$installInstance->install($version);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'uninstall':
|
||||
if (method_exists($installInstance, 'uninstall')) {
|
||||
$installInstance->uninstall($version);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
if (method_exists($installInstance, 'update')) {
|
||||
$installInstance->update($oldVersion ?? '1.0.0', $version);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
// 插件方法执行失败,记录日志
|
||||
$logLevel = $silent ? 'warning' : 'error';
|
||||
\support\Log::$logLevel('插件方法执行失败', [
|
||||
'plugin' => $code,
|
||||
'action' => $action,
|
||||
'version' => $version,
|
||||
'old_version' => $oldVersion,
|
||||
'exception' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
]);
|
||||
|
||||
// 静默模式不抛出异常,非静默模式抛出异常
|
||||
if (!$silent) {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用插件 Install 类的方法(兼容 CLI 模式)
|
||||
*
|
||||
* 此方法专门用于 CLI 命令直接调用插件方法
|
||||
* 与在线模式的区别:CLI 模式不需要 SSE 返回,直接执行
|
||||
*
|
||||
* @param string $code 插件编码
|
||||
* @param string $action 方法名 (install/uninstall/update)
|
||||
* @param string|null $version 版本
|
||||
* @param string|null $oldVersion 旧版本(仅 update 时使用)
|
||||
* @return bool 是否成功
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function callPluginInstallMethod(string $code, string $action, ?string $version = null, ?string $oldVersion = null): bool
|
||||
{
|
||||
return $this->executePluginMethod($code, $action, $version, $oldVersion, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user