mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-28 06:47:24 +08:00
feat: support theme update and various improvements
- Add support for updating themes if a newer version is uploaded - Hide config button for plugins without configuration items - Auto refresh theme cache after panel update - Fix issue where user used traffic cannot be set as a decimal - Fix subscription issue for shadowrocket in v2board theme
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Services\ThemeService;
|
||||||
use App\Services\UpdateService;
|
use App\Services\UpdateService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
@@ -46,6 +47,8 @@ class XboardUpdate extends Command
|
|||||||
Artisan::call('horizon:terminate');
|
Artisan::call('horizon:terminate');
|
||||||
$updateService = new UpdateService();
|
$updateService = new UpdateService();
|
||||||
$updateService->updateVersionCache();
|
$updateService->updateVersionCache();
|
||||||
|
$themeService = app(ThemeService::class);
|
||||||
|
$themeService->switch(admin_setting('current_theme'));
|
||||||
$this->info('更新完毕,队列服务已重启,你无需进行任何操作。');
|
$this->info('更新完毕,队列服务已重启,你无需进行任何操作。');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,9 +206,10 @@ class UserController extends Controller
|
|||||||
if (!$user) {
|
if (!$user) {
|
||||||
return $this->fail([400202, '用户不存在']);
|
return $this->fail([400202, '用户不存在']);
|
||||||
}
|
}
|
||||||
// 检查邮箱是否被使用
|
if (isset($params['email'])) {
|
||||||
if (User::where('email', $params['email'])->first() && $user->email !== $params['email']) {
|
if (User::where('email', $params['email'])->first() && $user->email !== $params['email']) {
|
||||||
return $this->fail([400201, '邮箱已被使用']);
|
return $this->fail([400201, '邮箱已被使用']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 处理密码
|
// 处理密码
|
||||||
if (isset($params['password'])) {
|
if (isset($params['password'])) {
|
||||||
@@ -223,7 +224,6 @@ class UserController extends Controller
|
|||||||
if (!$plan) {
|
if (!$plan) {
|
||||||
return $this->fail([400202, '订阅计划不存在']);
|
return $this->fail([400202, '订阅计划不存在']);
|
||||||
}
|
}
|
||||||
// return json_encode($plan);
|
|
||||||
$params['group_id'] = $plan->group_id;
|
$params['group_id'] = $plan->group_id;
|
||||||
}
|
}
|
||||||
// 处理邀请用户
|
// 处理邀请用户
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ class UserUpdate extends FormRequest
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|email:strict',
|
'id' => 'required|integer',
|
||||||
|
'email' => 'email:strict',
|
||||||
'password' => 'nullable|min:8',
|
'password' => 'nullable|min:8',
|
||||||
'transfer_enable' => 'numeric',
|
'transfer_enable' => 'numeric',
|
||||||
'expired_at' => 'nullable|integer',
|
'expired_at' => 'nullable|integer',
|
||||||
|
|||||||
@@ -156,7 +156,21 @@ class ThemeService
|
|||||||
|
|
||||||
$targetPath = $userThemePath . $config['name'];
|
$targetPath = $userThemePath . $config['name'];
|
||||||
if (File::exists($targetPath)) {
|
if (File::exists($targetPath)) {
|
||||||
throw new Exception('主题已存在');
|
$oldConfigFile = $targetPath . '/config.json';
|
||||||
|
if (!File::exists($oldConfigFile)) {
|
||||||
|
throw new Exception('已存在主题缺少配置文件');
|
||||||
|
}
|
||||||
|
$oldConfig = json_decode(File::get($oldConfigFile), true);
|
||||||
|
$oldVersion = $oldConfig['version'] ?? '0.0.0';
|
||||||
|
$newVersion = $config['version'] ?? '0.0.0';
|
||||||
|
if (version_compare($newVersion, $oldVersion, '>')) {
|
||||||
|
File::deleteDirectory($targetPath);
|
||||||
|
File::copyDirectory($sourcePath, $targetPath);
|
||||||
|
$this->initConfig($config['name']);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Exception('主题已存在且不是新版本');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File::copyDirectory($sourcePath, $targetPath);
|
File::copyDirectory($sourcePath, $targetPath);
|
||||||
@@ -180,9 +194,6 @@ class ThemeService
|
|||||||
public function switch(string $theme): bool
|
public function switch(string $theme): bool
|
||||||
{
|
{
|
||||||
$currentTheme = admin_setting('current_theme');
|
$currentTheme = admin_setting('current_theme');
|
||||||
if ($theme === $currentTheme) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 验证主题是否存在
|
// 验证主题是否存在
|
||||||
@@ -196,12 +207,6 @@ class ThemeService
|
|||||||
throw new Exception('主题视图文件不存在');
|
throw new Exception('主题视图文件不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制主题文件到public目录
|
|
||||||
$targetPath = public_path('theme/' . $theme);
|
|
||||||
if (!File::copyDirectory($themePath, $targetPath)) {
|
|
||||||
throw new Exception('复制主题文件失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理旧主题文件
|
// 清理旧主题文件
|
||||||
if ($currentTheme) {
|
if ($currentTheme) {
|
||||||
$oldPath = public_path('theme/' . $currentTheme);
|
$oldPath = public_path('theme/' . $currentTheme);
|
||||||
@@ -210,6 +215,12 @@ class ThemeService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 复制主题文件到public目录
|
||||||
|
$targetPath = public_path('theme/' . $theme);
|
||||||
|
if (!File::copyDirectory($themePath, $targetPath)) {
|
||||||
|
throw new Exception('复制主题文件失败');
|
||||||
|
}
|
||||||
|
|
||||||
admin_setting(['current_theme' => $theme]);
|
admin_setting(['current_theme' => $theme]);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
Vendored
+11
-11
File diff suppressed because one or more lines are too long
@@ -30,7 +30,6 @@ Route::get('/', function (Request $request) {
|
|||||||
$themeService = new ThemeService();
|
$themeService = new ThemeService();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查主题是否存在,不存在则尝试切换到默认主题
|
|
||||||
if (!$themeService->exists($theme)) {
|
if (!$themeService->exists($theme)) {
|
||||||
if ($theme !== 'Xboard') {
|
if ($theme !== 'Xboard') {
|
||||||
Log::warning('Theme not found, switching to default theme', ['theme' => $theme]);
|
Log::warning('Theme not found, switching to default theme', ['theme' => $theme]);
|
||||||
@@ -40,12 +39,10 @@ Route::get('/', function (Request $request) {
|
|||||||
$themeService->switch($theme);
|
$themeService->switch($theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查主题视图文件是否存在
|
|
||||||
if (!$themeService->getThemeViewPath($theme)) {
|
if (!$themeService->getThemeViewPath($theme)) {
|
||||||
throw new Exception('主题视图文件不存在');
|
throw new Exception('主题视图文件不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查主题是否已复制到public目录
|
|
||||||
$publicThemePath = public_path('theme/' . $theme);
|
$publicThemePath = public_path('theme/' . $theme);
|
||||||
if (!File::exists($publicThemePath)) {
|
if (!File::exists($publicThemePath)) {
|
||||||
$themePath = $themeService->getThemePath($theme);
|
$themePath = $themeService->getThemePath($theme);
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user