完成安装程序。

This commit is contained in:
Wisp X
2022-02-24 15:41:01 +08:00
parent 6172fc0a8c
commit af9d787efe
4 changed files with 217 additions and 94 deletions
+19 -5
View File
@@ -17,6 +17,7 @@ use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
@@ -31,6 +32,9 @@ class Controller extends BaseController
public function install(Request $request): View|Response
{
if (file_exists(base_path('installed.lock'))) {
if ($request->expectsJson()) {
return $this->error('Already installed. if you want to reinstall, please remove installed.lock file.');
}
abort(404);
}
@@ -67,13 +71,23 @@ class Controller extends BaseController
'account.email' => '管理员账号邮箱',
'account.password' => '管理员账号密码'
]);
} catch (ValidationException $e) {
$data = collect($request->except('account'))->transform(fn($item, $key) => ['--'.$key => $item])->collapse();
$stream = fopen('php://output', 'w');
$exitCode = Artisan::call('lsky:install', $data->toArray(), new StreamOutput($stream));
$response = str_replace(PHP_EOL, '<br/>', ob_get_clean());
$user = new User([
'name' => '超级管理员',
'email' => $request->input('account.email'),
'password' => Hash::make($request->input('account.password')),
'is_adminer' => true,
]);
$user->email_verified_at = date('Y-m-d H:i:s');
$user->save();
} catch (ValidationException|\Throwable $e) {
@unlink(base_path('installed.lock'));
return $this->error($e->getMessage());
}
$data = collect($request->except('account'))->transform(fn($item, $key) => ['--'.$key => $item])->collapse();
$stream = fopen('php://output', 'w');
$exitCode = Artisan::call('lsky:install', $data->toArray(), new StreamOutput($stream));
$response = str_replace(PHP_EOL, '<br/>', ob_get_clean());
if (! $exitCode) {
return $this->error('安装失败', compact('response'));
}
Generated
+88 -26
View File
@@ -6,6 +6,68 @@
],
"content-hash": "1fe0910fc1866099d3e670222bb1747d",
"packages": [
{
"name": "asm89/stack-cors",
"version": "v2.1.1",
"source": {
"type": "git",
"url": "https://github.com/asm89/stack-cors.git",
"reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/73e5b88775c64ccc0b84fb60836b30dc9d92ac4a",
"reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "^7.2|^8.0",
"symfony/http-foundation": "^4|^5|^6",
"symfony/http-kernel": "^4|^5|^6"
},
"require-dev": {
"phpunit/phpunit": "^7|^9",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"autoload": {
"psr-4": {
"Asm89\\Stack\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander",
"email": "iam.asm89@gmail.com"
}
],
"description": "Cross-origin resource sharing library and stack middleware",
"homepage": "https://github.com/asm89/stack-cors",
"keywords": [
"cors",
"stack"
],
"support": {
"issues": "https://github.com/asm89/stack-cors/issues",
"source": "https://github.com/asm89/stack-cors/tree/v2.1.1"
},
"time": "2022-01-18T09:12:03+00:00"
},
{
"name": "aws/aws-crt-php",
"version": "v1.0.2",
@@ -64,16 +126,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.209.29",
"version": "3.209.30",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "d2a7902ea12fbcfc26a0ae6a07d0e5f8c6e5e9a1"
"reference": "54c1e491b8de74360bbe94d727706db384c8d9a8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d2a7902ea12fbcfc26a0ae6a07d0e5f8c6e5e9a1",
"reference": "d2a7902ea12fbcfc26a0ae6a07d0e5f8c6e5e9a1",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/54c1e491b8de74360bbe94d727706db384c8d9a8",
"reference": "54c1e491b8de74360bbe94d727706db384c8d9a8",
"shasum": "",
"mirrors": [
{
@@ -155,9 +217,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.209.29"
"source": "https://github.com/aws/aws-sdk-php/tree/3.209.30"
},
"time": "2022-02-22T19:14:12+00:00"
"time": "2022-02-23T19:14:31+00:00"
},
{
"name": "brick/math",
@@ -999,16 +1061,16 @@
},
{
"name": "fruitcake/laravel-cors",
"version": "v2.1.0",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/fruitcake/laravel-cors.git",
"reference": "361d71f00a0eea8b74da26ae75d0d207c53aa5b3"
"reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/361d71f00a0eea8b74da26ae75d0d207c53aa5b3",
"reference": "361d71f00a0eea8b74da26ae75d0d207c53aa5b3",
"url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/783a74f5e3431d7b9805be8afb60fd0a8f743534",
"reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534",
"shasum": "",
"mirrors": [
{
@@ -1018,7 +1080,7 @@
]
},
"require": {
"fruitcake/php-cors": "^1",
"asm89/stack-cors": "^2.0.1",
"illuminate/contracts": "^6|^7|^8|^9",
"illuminate/support": "^6|^7|^8|^9",
"php": ">=7.2"
@@ -1068,7 +1130,7 @@
],
"support": {
"issues": "https://github.com/fruitcake/laravel-cors/issues",
"source": "https://github.com/fruitcake/laravel-cors/tree/v2.1.0"
"source": "https://github.com/fruitcake/laravel-cors/tree/v2.2.0"
},
"funding": [
{
@@ -1080,7 +1142,7 @@
"type": "github"
}
],
"time": "2022-02-19T14:17:28+00:00"
"time": "2022-02-23T14:25:13+00:00"
},
{
"name": "fruitcake/php-cors",
@@ -8676,16 +8738,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.11",
"version": "9.2.13",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f"
"reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f",
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/deac8540cb7bd40b2b8cfa679b76202834fd04e8",
"reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8",
"shasum": "",
"mirrors": [
{
@@ -8747,7 +8809,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.13"
},
"funding": [
{
@@ -8755,7 +8817,7 @@
"type": "github"
}
],
"time": "2022-02-18T12:46:09+00:00"
"time": "2022-02-23T17:02:38+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -9024,16 +9086,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.14",
"version": "9.5.16",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "1883687169c017d6ae37c58883ca3994cfc34189"
"reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189",
"reference": "1883687169c017d6ae37c58883ca3994cfc34189",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5ff8c545a50226c569310a35f4fa89d79f1ddfdc",
"reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc",
"shasum": "",
"mirrors": [
{
@@ -9055,7 +9117,7 @@
"phar-io/version": "^3.0.2",
"php": ">=7.3",
"phpspec/prophecy": "^1.12.1",
"phpunit/php-code-coverage": "^9.2.7",
"phpunit/php-code-coverage": "^9.2.13",
"phpunit/php-file-iterator": "^3.0.5",
"phpunit/php-invoker": "^3.1.1",
"phpunit/php-text-template": "^2.0.3",
@@ -9117,7 +9179,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.16"
},
"funding": [
{
@@ -9129,7 +9191,7 @@
"type": "github"
}
],
"time": "2022-02-18T12:54:07+00:00"
"time": "2022-02-23T17:10:58+00:00"
},
{
"name": "sebastian/cli-parser",
+19
View File
@@ -1181,6 +1181,9 @@ select {
--tw-divide-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-divide-opacity));
}
.overflow-auto {
overflow: auto;
}
.overflow-hidden {
overflow: hidden;
}
@@ -1375,6 +1378,14 @@ select {
--tw-bg-opacity: 1;
background-color: rgb(156 163 175 / var(--tw-bg-opacity));
}
.bg-slate-900 {
--tw-bg-opacity: 1;
background-color: rgb(15 23 42 / var(--tw-bg-opacity));
}
.bg-slate-700 {
--tw-bg-opacity: 1;
background-color: rgb(51 65 85 / var(--tw-bg-opacity));
}
.bg-opacity-75 {
--tw-bg-opacity: 0.75;
}
@@ -1576,6 +1587,10 @@ select {
font-size: 1rem;
line-height: 1.5rem;
}
.text-8xl {
font-size: 6rem;
line-height: 1;
}
.font-medium {
font-weight: 500;
}
@@ -1747,6 +1762,10 @@ select {
--tw-text-opacity: 1;
color: rgb(13 148 136 / var(--tw-text-opacity));
}
.text-teal-500 {
--tw-text-opacity: 1;
color: rgb(20 184 166 / var(--tw-text-opacity));
}
.underline {
-webkit-text-decoration-line: underline;
text-decoration-line: underline;
+91 -63
View File
@@ -1,27 +1,47 @@
<x-guest-layout>
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="relative min-full">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Lsky Pro 安装程序</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">
<link rel="stylesheet" href="{{ asset('css/fontawesome.css') }}">
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/common.css') }}">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"></script>
</head>
<body class="font-sans antialiased">
<div class="min-h-screen text-gray-900 bg-gray-100">
<div class="min-h-screen flex justify-center items-center px-6 py-10 md:py-20">
<div class="md:w-[600px]">
<h1 class="text-gray-700 text-3xl">Install Lsky Pro</h1>
<div id="checking" class="mt-4 p-6 rounded-md bg-white w-full">
<p class="text-md mb-4 block text-center">运行环境检测</p>
<p class="text-md mb-4 block text-center">Step 1 > 运行环境检测</p>
<div class="relative rounded-md bg-white overflow-hidden space-y-4 max-h-[500px] overflow-y-auto">
@foreach($extensions as $extension)
<dl>
<div class="rounded-md bg-gray-50 px-3 py-3 flex items-center justify-between">
<dt class="text-md font-medium text-gray-700 {{ ! $extension['result'] ? 'text-red-500' : '' }}">
{{ $extension['name'] }}
<p class="mt-2 text-sm text-gary-400">{{ $extension['intro'] }}</p>
</dt>
<dd class="mt-1 text-md text-gray-900 truncate">
@if($extension['result'])
<i class="fas fa-check text-green-500"></i>
@else
<i class="fas text-lg fa-times text-red-500"></i>
@endif
</dd>
</div>
</dl>
<dl>
<div class="rounded-md bg-gray-50 px-3 py-3 flex items-center justify-between">
<dt class="text-md font-medium text-gray-700 {{ ! $extension['result'] ? 'text-red-500' : '' }}">
{{ $extension['name'] }}
<p class="mt-2 text-sm text-gary-400">{{ $extension['intro'] }}</p>
</dt>
<dd class="mt-1 text-md text-gray-900 truncate">
@if($extension['result'])
<i class="fas fa-check text-green-500"></i>
@else
<i class="fas text-lg fa-times text-red-500"></i>
@endif
</dd>
</div>
</dl>
@endforeach
</div>
@@ -35,7 +55,7 @@
</div>
<div id="installing" class="mt-4 p-6 rounded-md bg-white w-full hidden">
<p class="text-md mb-4 block text-center">配置数据库和管理员账号</p>
<p class="text-md mb-4 block text-center">Step 2 > 配置数据库和管理员账号</p>
<form class="w-full" method="post">
<div class="px-3 py-4 bg-white sm:p-6">
@@ -82,7 +102,7 @@
</div>
</form>
<p id="response" class="text-red-500"></p>
<p id="response" class="rounded-md text-red-500 bg-slate-700 p-4 hidden overflow-auto"></p>
<div class="mt-6 text-right">
<a href="javascript:void(0)" id="install" class="rounded-md px-4 py-2 bg-blue-500 text-white">立即安装</a>
@@ -90,52 +110,60 @@
</div>
<div id="success" class="mt-4 p-6 rounded-md bg-white w-full hidden">
success
<i class="fas fa-check-circle text-5xl text-teal-500"></i>
<p class="mt-4 text-lg">程序安装完成。</p>
<div class="mt-3 space-y-1 text-gray-600">
<p>你可以点击 <a class="text-green-500" href="{{ route('/') }}">这里</a> 去首页。</p>
<p>更多帮助请访问 <a class="text-green-500" href="https://www.lsky.pro" target="_blank">https://www.lsky.pro</a></p>
<p>使用过程中出现任何问题请务必阅读 <a class="text-green-500" href="https://docs.lsky.pro" target="_blank">官方文档</a></p>
<p>如果你觉得兰空图床给你带来帮助,不妨请我喝一杯咖啡☕️ <a class="text-green-500" href="https://github.com/wisp-x/lsky-pro#-%E6%8D%90%E8%B5%A0" target="_blank">去打赏</a></p>
<p>这个页面将在下次访问时返回 404 错误,如果你想要重新安装,请删除程序根目录中的 installed.lock 文件,然后重新访问首页。</p>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
$('#next').click(function () {
$('#checking').remove();
$('#installing').removeClass('hidden');
});
@push('scripts')
<script>
$('#next').click(function () {
$('#checking').remove();
$('#installing').removeClass('hidden');
});
$('#connection').change(function () {
let selector = '#host, #port, #username, #password';
$(selector).parent().show();
let message = '';
switch ($(this).val()) {
case 'pgsql':
break;
case 'sqlite':
message = 'SQLite 数据库本质上只是一个存在你文件系统上的文件,下面的数据库路径如果为空,程序将会自动在根目录 database 文件夹中创建 database.sqlite 文件,否则请填写该数据库文件的绝对路径。';
$(selector).parent().hide();
break;
case 'sqlsrv':
message = '在使用 SQL Server 数据库前,你需要先确保你已安装并启用了 sqlsrv 和 pdo_sqlsrv PHP 扩展以及它们所需要的依赖项,例如 Microsoft SQL ODBC 驱动。';
break;
default:
}
if (message) {
$(this).siblings('p').text(message).removeClass('hidden');
} else {
$(this).siblings('p').text(message).addClass('hidden');
}
});
$('#connection').change(function () {
let selector = '#host, #port, #username, #password';
$(selector).parent().show();
let message = '';
switch ($(this).val()) {
case 'pgsql':
break;
case 'sqlite':
message = 'SQLite 数据库本质上只是一个存在你文件系统上的文件,下面的数据库路径如果为空,程序将会自动在根目录 database 文件夹中创建 database.sqlite 文件,否则请填写该数据库文件的绝对路径。';
$(selector).parent().hide();
break;
case 'sqlsrv':
message = '在使用 SQL Server 数据库前,你需要先确保你已安装并启用了 sqlsrv 和 pdo_sqlsrv PHP 扩展以及它们所需要的依赖项,例如 Microsoft SQL ODBC 驱动。';
break;
default:
}
if (message) {
$(this).siblings('p').text(message).removeClass('hidden');
} else {
$(this).siblings('p').text(message).addClass('hidden');
}
});
$('#install').click(function () {
$('#response').html('');
axios.post('{{ route('install') }}', $('#installing form').serialize()).then(response => {
if (response.data.status) {
// TODO
} else {
$('#response').html(response.data.message + ' ' +(response.data.data.response || ''));
}
});
});
</script>
@endpush
</x-guest-layout>
$('#install').click(function () {
$('#response').html('').addClass('hidden');
axios.post('{{ route('install') }}', $('#installing form').serialize()).then(response => {
$('#response').addClass('hidden')
if (response.data.status) {
$('#installing').hide();
$('#success').show();
} else {
$('#response').html(response.data.message + ' ' +(response.data.data.response || '')).removeClass('hidden');
}
});
});
</script>
</html>