Эх сурвалжийг харах

refactor(core): 重构核心模块

- 更新命名空间:将 core 替换为 Core
- 移除 SixShopKernel 类,功能移至 CoreService
- 新增 CoreService 类,统一处理核心服务
- 更新 Helper 类,增加扩展路径和名称列表方法
- 调整 composer.json,添加 think-orm 依赖
- 更新其他类文件,适应新的命名空间和功能调整
runphp 7 сар өмнө
parent
commit
57becc5b8e

+ 1 - 1
README.md

@@ -6,7 +6,7 @@
 
 ## 特性
 
-- 提供 \SixShop\core\Entity\BaseEntity 类,作为所有实体的基类。
+- 提供 \SixShop\Core\Entity\BaseEntity 类,作为所有实体的基类。
 
 ## 安装
 

+ 13 - 5
composer.json

@@ -5,10 +5,7 @@
     "autoload": {
         "psr-4": {
             "SixShop\\Core\\": "src/"
-        },
-        "files": [
-            "src/helper.php"
-        ]
+        }
     },
     "authors": [
         {
@@ -18,6 +15,17 @@
     ],
     "require": {
         "php": ">=8.3",
-        "topthink/framework": "^8.1"
+        "topthink/framework": "^8.1",
+        "topthink/think-orm": "^4.0"
+    },
+    "extra": {
+        "think": {
+            "services": [
+                "SixShop\\Core\\Service\\CoreService"
+            ],
+            "config":{
+                "captcha": "src/config.php"
+            }
+        }
     }
 }

+ 1 - 1
src/Attribute/Cron.php

@@ -1,6 +1,6 @@
 <?php
 declare(strict_types=1);
-namespace SixShop\core\Attribute;
+namespace SixShop\Core\Attribute;
 
 #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
 class Cron

+ 1 - 1
src/Attribute/Hook.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Attribute;
+namespace SixShop\Core\Attribute;
 
 #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
 class Hook

+ 1 - 1
src/Contracts/ExtensionInterface.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Contracts;
+namespace SixShop\Core\Contracts;
 
 interface ExtensionInterface
 {

+ 1 - 1
src/Entity/BaseEntity.php

@@ -1,6 +1,6 @@
 <?php
 
-namespace SixShop\core\Entity;
+namespace SixShop\Core\Entity;
 
 use think\Entity;
 

+ 1 - 1
src/Exception/ExceptionHandle.php

@@ -1,6 +1,6 @@
 <?php
 declare(strict_types=1);
-namespace SixShop\core\Exception;
+namespace SixShop\Core\Exception;
 
 use think\db\exception\ModelNotFoundException;
 use think\exception\Handle;

+ 1 - 1
src/Exception/LogicException.php

@@ -1,6 +1,6 @@
 <?php
 declare(strict_types=1);
-namespace SixShop\core\Exception;
+namespace SixShop\Core\Exception;
 
 use think\exception\HttpResponseException;
 

+ 1 - 1
src/Exception/NotFoundException.php

@@ -1,6 +1,6 @@
 <?php
 
-namespace SixShop\core\Exception;
+namespace SixShop\Core\Exception;
 
 use Exception;
 use think\exception\HttpResponseException;

+ 1 - 1
src/Extension.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core;
+namespace SixShop\Core;
 
 
 class Extension extends ExtensionAbstract

+ 2 - 2
src/ExtensionAbstract.php

@@ -1,9 +1,9 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core;
+namespace SixShop\Core;
 
-use SixShop\core\Contracts\ExtensionInterface;
+use SixShop\Core\Contracts\ExtensionInterface;
 
 abstract class ExtensionAbstract implements ExtensionInterface
 {

+ 26 - 23
src/helper.php → src/Helper.php

@@ -1,19 +1,22 @@
 <?php
 declare(strict_types=1);
 
-use SixShop\core\Exception\LogicException;
-use SixShop\core\Response\Xml;
+namespace SixShop\Core;
+
+use SixShop\Core\Exception\LogicException;
+use SixShop\Core\Response\Xml;
+use SixShop\Core\Service\CoreService;
 use think\Container;
 use think\Paginator;
 use think\Response;
-use think\response\Json;
 
-if (!function_exists('success_response')) {
+class Helper
+{
 
     /**
      * 返回成功数据
      */
-    function success_response(mixed $data = [], string $status = 'ok', int $code = 200, string $msg = 'success', string $type = 'json', string $xslt = ''): Response
+    public static function success_response(mixed $data = [], string $status = 'ok', int $code = 200, string $msg = 'success', string $type = 'json', string $xslt = ''): Response
     {
         if ($xslt) {
             $type = 'xml';
@@ -33,13 +36,11 @@ if (!function_exists('success_response')) {
         }
         return $response;
     }
-}
 
-if (!function_exists('page_response')) {
     /**
      * 返回分页数据
      */
-    function page_response(Paginator $page, mixed $data = [], string $status = 'ok', int $code = 200, string $msg = 'success'): Response
+    public static function page_response(Paginator $page, mixed $data = [], string $status = 'ok', int $code = 200, string $msg = 'success'): Response
     {
         return json([
             'code' => $code,
@@ -49,13 +50,11 @@ if (!function_exists('page_response')) {
             'data' => $data
         ]);
     }
-}
 
-if (!function_exists('error_response')) {
     /**
      * 返回失败数据
      */
-    function error_response(string $msg = 'error', string $status = 'error', int $code = 1, mixed $data = [], int $httpCode = 400, $header = [], $options = []): Response
+    public static function error_response(string $msg = 'error', string $status = 'error', int $code = 1, mixed $data = [], int $httpCode = 400, $header = [], $options = []): Response
     {
         return json([
             'code' => $code,
@@ -64,19 +63,15 @@ if (!function_exists('error_response')) {
             'data' => $data
         ], $httpCode, $header, $options);
     }
-}
 
-if (!function_exists('throw_logic_exception')) {
     /**
      * 抛出逻辑异常
      */
-    function throw_logic_exception(string $msg = 'error', int $code = 1, string $status = 'error', mixed $data = [], int $httpCode = 200, $header = [], $options = []): void
+    public static function throw_logic_exception(string $msg = 'error', int $code = 1, string $status = 'error', mixed $data = [], int $httpCode = 200, $header = [], $options = []): void
     {
         throw new LogicException(error_response($msg, $status, $code, $data, $httpCode, $header, $options));
     }
-}
 
-if (!function_exists('build_tree_options')) {
     /**
      * 构建树形结构选项
      * @param array $data 数据源
@@ -87,7 +82,7 @@ if (!function_exists('build_tree_options')) {
      * @param string $childrenKey 子节点键
      * @param bool $preserveOriginal 是否保留原始数据
      */
-    function build_tree_options(
+    public static function build_tree_options(
         array  $data,
         string $valueField = 'id',
         string $labelField = 'name',
@@ -110,7 +105,7 @@ if (!function_exists('build_tree_options')) {
                     $node = array_merge($item, $node);
                 }
 
-                $children = build_tree_options(
+                $children = self::build_tree_options(
                     $data,
                     $valueField,
                     $labelField,
@@ -128,16 +123,13 @@ if (!function_exists('build_tree_options')) {
         }
         return $tree;
     }
-}
 
-
-if (!function_exists('secret_password')) {
     /**
      * 生成随机密码
      * @param int $length 密码长度
      * @return string 生成的密码
      */
-    function secret_password(int $length = 16): string
+    public static function secret_password(int $length = 16): string
     {
         // 确保密码包含各种字符类型
         $lowercase = 'abcdefghijklmnopqrstuvwxyz';
@@ -160,4 +152,15 @@ if (!function_exists('secret_password')) {
         // 打乱字符顺序
         return str_shuffle($password);
     }
-}
+
+
+    public static function extension_path()
+    {
+        return CoreService::$extensionPath;
+    }
+
+    public static function extension_name_list()
+    {
+        return CoreService::$extensionNameList;
+    }
+}

+ 1 - 1
src/Job/BaseJob.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Job;
+namespace SixShop\Core\Job;
 
 use think\facade\Log;
 use think\queue\Job;

+ 1 - 1
src/Job/JobDispatcher.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Job;
+namespace SixShop\Core\Job;
 
 class JobDispatcher
 {

+ 2 - 2
src/Middleware/ExtensionStatusMiddleware.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Middleware;
+namespace SixShop\Core\Middleware;
 
 use Closure;
 use SixShop\Extension\system\Enum\ExtensionStatusEnum;
@@ -18,7 +18,7 @@ class ExtensionStatusMiddleware
         $extensionModel = $this->extensionManager->getInfo($moduleName);
         return match ($extensionModel->status) {
             ExtensionStatusEnum::ENABLED => $next($request),
-            default => error_response(msg: '模块`' . $moduleName . '`未启用', httpCode: 403)
+            default => Helper::error_response(msg: '模块`' . $moduleName . '`未启用', httpCode: 403)
         };
     }
 }

+ 2 - 2
src/Middleware/MacroPageMiddleware.php

@@ -1,10 +1,10 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Middleware;
+namespace SixShop\Core\Middleware;
 
 use Closure;
-use SixShop\core\Request;
+use SixShop\Core\Request;
 use think\Exception;
 use think\Response;
 

+ 1 - 1
src/Request.php

@@ -1,6 +1,6 @@
 <?php
 declare(strict_types=1);
-namespace SixShop\core;
+namespace SixShop\Core;
 
 use think\helper\Macroable;
 

+ 1 - 1
src/Response/Xml.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Response;
+namespace SixShop\Core\Response;
 
 class Xml extends \think\response\Xml
 {

+ 6 - 6
src/Service/AutoloadService.php

@@ -1,20 +1,20 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Service;
+namespace SixShop\Core\Service;
 
 use Composer\Json\JsonFile;
-use SixShop\core\SixShopKernel;
+use SixShop\Core\Helper;
+use think\App;
 
 
 class AutoloadService
 {
-    public function init(SixShopKernel $app): void
+    public function init(App $app): void
     {
-        $extensionPath = $app->getExtensionPath();
+        $extensionPath = Helper::extension_path();
         $classLoader = $app->classLoader;
-        $moduleNameList = $app->getModuleNameList();
-        foreach ($moduleNameList as $moduleName) {
+        foreach (Helper::extension_name_list() as $moduleName) {
             $dir = $extensionPath.$moduleName;
             if (file_exists($dir . '/composer.json')) {
                 $composerJson = new JsonFile($dir . '/composer.json');

+ 3 - 3
src/Service/CommandService.php

@@ -1,15 +1,15 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Service;
+namespace SixShop\Core\Service;
 
-use SixShop\core\SixShopKernel;
 use SixShop\Extension\system\ExtensionManager;
 
 class CommandService
 {
-    public function init(SixShopKernel $app): void
+    public function init(App $app): void
     {
+        $app->re
         $commands = $app->config->get('console.commands', []);
         $extensionManager = $app->make(ExtensionManager::class);
         foreach (module_name_list() as $moduleName) {

+ 90 - 0
src/Service/CoreService.php

@@ -0,0 +1,90 @@
+<?php
+declare(strict_types=1);
+
+namespace SixShop\Core\Service;
+
+use SixShop\Core\Exception\ExceptionHandle;
+use SixShop\Core\Request;
+use think\event\HttpRun;
+use think\exception\Handle;
+use think\Service;
+
+class CoreService extends Service
+{
+    public static string $extensionPath;
+
+    public static array $extensionNameList = [];
+
+    public function register(): void
+    {
+        $this->app->bind(Handle::class, ExceptionHandle::class);
+        $this->app->bind('think\Request', Request::class);
+        $this->app->bind('classLoader',
+            require $this->app->getRootPath() . 'vendor/autoload.php');
+        self::$extensionPath = $this->app->getRootPath() . 'extension' . DIRECTORY_SEPARATOR;
+        $this->initExtensionList();
+
+    }
+
+    public function boot(): void
+    {
+        $this->app->make(AutoloadService::class)->init($this->app);
+        $this->app->make(HookAttributeService::class)->init($this->app);
+        $this->app->event->listen(HttpRun::class,function (){
+            $this->registerRoutes($this->app->make(RegisterRouteService::class)->init($this->app));
+        });
+
+        /*$this->app->make(CommandService::class)->init(function ($commands){
+            $this->commands($commands);
+        });*/
+    }
+
+    public function initExtensionList(): void
+    {
+        if (empty(self::$extensionNameList)) {
+            $coreFile = $this->app->getRootPath() . 'runtime/module_name_list_core.php';
+            if (file_exists($coreFile)) {
+                self::$extensionNameList = require $coreFile;
+            } else {
+                $extensionInfoList = [];
+                $extensionDirs = array_diff(scandir(self::extensionPath), ['.', '..']);
+                foreach ($extensionDirs as $item) {
+                    if (!is_dir(self::extensionPath . $item)) {
+                        continue;
+                    }
+                    $infoFile = self::extensionPath . $item . '/info.php';
+                    if (is_file($infoFile)) {
+                        $info = require $infoFile;
+                        $info['weight'] = $info['weight'] ?? 10000;
+                        if ($info['is_core'] ?? false) {
+                            self::$extensionNameList[] = $info['id'];
+                            $extensionInfoList[] = $info;
+                        }
+                    }
+                }
+                usort($extensionInfoList, function ($a, $b) {
+                    return $a['weight'] <=> $b['weight'];
+                });
+                $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL;
+                $content = '<?php ' . PHP_EOL . $header . "return " . var_export(array_column($extensionInfoList, 'id'), true) . ';';
+                file_put_contents($coreFile, $content);
+            }
+            $normalFile = $this->app->getRootPath() . 'runtime/module_name_list_normal.php';
+            if (file_exists($normalFile)) {
+                self::$extensionNameList = array_merge(self::$extensionNameList, require $normalFile);
+            }
+        }
+    }
+
+    public function loadEnv(string $envName = ''): void
+    {
+        $home = getenv('HOME');
+        $envFile = $envName ? $home . '/.env.' . $envName : $home . '/.env';
+        if (is_file($envFile)) {
+            $this->app->env->load($envFile);
+            return;
+        }
+        $this->app->loadEnv($envName);
+    }
+
+}

+ 8 - 7
src/Service/HookAttributeService.php

@@ -1,26 +1,27 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Service;
+namespace SixShop\Core\Service;
 
 use ReflectionClass;
 use ReflectionMethod;
-use SixShop\core\Attribute\Hook;
-use SixShop\core\SixShopKernel;
+use SixShop\Core\Attribute\Hook;
+use SixShop\Core\Helper;
 use SixShop\Extension\system\Enum\ExtensionStatusEnum;
 use SixShop\Extension\system\ExtensionManager;
+use think\App;
 use think\facade\Event;
 
 class HookAttributeService
 {
-    public function init(SixShopKernel $app): void
+    public function init(App $app): void
     {
         $extensionManager = $app->make(ExtensionManager::class);
-        foreach (module_name_list() as $moduleName) {
-            if ($extensionManager->getInfo($moduleName)->status !== ExtensionStatusEnum::ENABLED) {
+        foreach (Helper::extension_name_list() as $extensionName) {
+            if ($extensionManager->getInfo($extensionName)->status !== ExtensionStatusEnum::ENABLED) {
                 continue;
             }
-            $extension = $extensionManager->getExtension($moduleName);
+            $extension = $extensionManager->getExtension($extensionName);
             $hookClassList = $extension->getHooks();
             foreach ($hookClassList as $hookClass) {
                 $ref = new ReflectionClass($hookClass);

+ 11 - 10
src/Service/RegisterRouteService.php

@@ -1,33 +1,34 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Service;
+namespace SixShop\Core\Service;
 
-use SixShop\core\Middleware\ExtensionStatusMiddleware;
-use SixShop\core\SixShopKernel;
+use SixShop\Core\Helper;
+use SixShop\Core\Middleware\ExtensionStatusMiddleware;
 use SixShop\Extension\system\ExtensionManager;
+use think\App;
 use think\event\RouteLoaded;
 use think\facade\Route;
 
 class RegisterRouteService
 {
-    public function init(SixShopKernel $app): void
+    public function init(App $app)
     {
         $extensionManager = $app->make(ExtensionManager::class);
-        $app->event->listen(RouteLoaded::class, function () use ($extensionManager, $app) {
+        return function () use ($extensionManager, $app) {
             $appName = $app->http->getName();
-            foreach (module_name_list() as $moduleName) {
-                $extension = $extensionManager->getExtension($moduleName);
+            foreach (Helper::extension_name_list() as $extensionName) {
+                $extension = $extensionManager->getExtension($extensionName);
                 $routes = $extension->getRoutes();
                 if (isset($routes[$appName])) {
                     $routeFile = $routes[$appName];
-                    Route::group($moduleName, function () use ($routeFile) {
+                    Route::group($extensionName, function () use ($routeFile) {
                         include $routeFile;
                     })->middleware(
-                        ExtensionStatusMiddleware::class, $moduleName
+                        ExtensionStatusMiddleware::class, $extensionName
                     );
                 }
             }
-        });
+        };
     }
 }

+ 0 - 121
src/SixShopKernel.php

@@ -1,121 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace SixShop\core;
-
-use Composer\Autoload\ClassLoader;
-use SixShop\core\Exception\ExceptionHandle;
-use SixShop\core\Service\AutoloadService;
-use SixShop\core\Service\CommandService;
-use SixShop\core\Service\HookAttributeService;
-use SixShop\core\Service\RegisterRouteService;
-use think\App;
-use think\exception\Handle;
-
-/**
- * @property ClassLoader $classLoader
- */
-class SixShopKernel extends App
-{
-    /**
-     * 扩展目录
-     */
-    protected string $extensionPath = '';
-
-    protected array $initializerServices = [
-        AutoloadService::class,
-        RegisterRouteService::class,
-        HookAttributeService::class,
-    ];
-
-    private array $moduleNameList = [];
-
-    public function __construct(ClassLoader $classLoader, string $environment = '', string $rootPath = '')
-    {
-        parent::__construct($rootPath);
-        if ($environment === '') {
-            $environment = getenv('RUNTIME_ENVIRONMENT') ?: '';
-            if (getenv('IS_DDEV_PROJECT') == 'true') {
-                $environment = 'ddev';
-            }
-        }
-        $this->setEnvName($environment);
-        $this->bind('think\Request', Request::class);
-        $this->instance('classLoader', $classLoader);
-        $this->extensionPath = $this->rootPath . 'extension' . DIRECTORY_SEPARATOR; // todo config
-        $this->initializers = array_merge($this->initializers, $this->initializerServices);
-    }
-
-    public function runHttp(): void
-    {
-        $this->bind(Handle::class, ExceptionHandle::class);
-        $response = $this->http->run();
-        $response->send();
-        $this->http->end($response);
-    }
-
-    public function getExtensionPath(): string
-    {
-        return $this->extensionPath;
-    }
-
-    public function runConsole(): int
-    {
-        $this->initializers[] = CommandService::class;
-        return $this->initialize()->console->run();
-    }
-
-    public function getEnvName(): string
-    {
-        return $this->envName;
-    }
-
-    public function getModuleNameList(): array
-    {
-        if (empty($this->moduleNameList)) {
-            $coreFile = $this->rootPath . 'runtime/module_name_list_core.php';
-            if (file_exists($coreFile)) {
-                $this->moduleNameList = require $coreFile;
-            } else {
-                $moduleInfoList = [];
-                $extensionDirs = array_diff(scandir($this->extensionPath), ['.', '..']);
-                foreach ($extensionDirs as $item) {
-                    if (!is_dir($this->extensionPath . $item)) {
-                        continue;
-                    }
-                    $infoFile = $this->extensionPath . $item . '/info.php';
-                    if (is_file($infoFile)) {
-                        $info = require $infoFile;
-                        $info['weight'] = $info['weight'] ?? 10000;
-                        if ($info['is_core'] ?? false) {
-                            $this->moduleNameList[] = $info['id'];
-                            $moduleInfoList[] = $info;
-                        }
-                    }
-                }
-                usort($moduleInfoList, function ($a, $b) {
-                    return $a['weight'] <=> $b['weight'];
-                });
-                $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL;
-                $content = '<?php ' . PHP_EOL . $header . "return " . var_export(array_column($moduleInfoList, 'id'), true) . ';';
-                file_put_contents($coreFile, $content);
-            }
-            $normalFile = $this->rootPath . 'runtime/module_name_list_normal.php';
-            if (file_exists($normalFile)) {
-                $this->moduleNameList = array_merge($this->moduleNameList, require $normalFile);
-            }
-        }
-        return $this->moduleNameList;
-    }
-
-    public function loadEnv(string $envName = ''): void
-    {
-        $home = getenv('HOME');
-        $envFile = $envName ? $home . '/.env.' . $envName : $home . '/.env';
-        if (is_file($envFile)) {
-            $this->env->load($envFile);
-            return;
-        }
-        parent::loadEnv($envName);
-    }
-}

+ 1 - 1
src/Trait/ConfigTrait.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace SixShop\core\Trait;
+namespace SixShop\Core\Trait;
 
 use SixShop\Extension\system\ExtensionManager;
 

+ 1 - 1
src/Trait/EventTrait.php

@@ -1,6 +1,6 @@
 <?php
 declare(strict_types=1);
-namespace SixShop\core\Trait;
+namespace SixShop\Core\Trait;
 
 
 use think\facade\Event;