feat:安装器

This commit is contained in:
atshike
2025-01-03 15:37:05 +08:00
parent 824d02aee4
commit 57fafbf3f2
10 changed files with 1123 additions and 8 deletions
+15
View File
@@ -5,8 +5,23 @@ namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\DB;
class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
public function welcome()
{
try {
DB::connection()->getPdo();
if (DB::table('sys_configs')->count() < 1) {
return redirect('install?step=1');
}
} catch (\Exception $e) {
return redirect('install?step=1');
}
return view('welcome');
}
}
@@ -0,0 +1,201 @@
<?php
namespace App\Http\Controllers\Install;
use App\Enums\UserType;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Validator;
use Ugly\Base\Traits\ApiResource;
class IndexController extends Controller
{
use ApiResource;
// 安装
public function index(Request $request)
{
$step = $request->get('step', 1);
$is_goon = true;
$data = [
'step' => $step,
'nextStep' => $is_goon ? $step + 1 : $step,
'lastStep' => $step < 1 ? 1 : $step - 1,
];
if ($step == '2') {
$data = array_merge($data, [
'nextStep' => $is_goon ? $step + 1 : $step,
'is_goon' => $is_goon,
'chk' => $this->base_ckh(),
]);
}
if ($step == '3') {
$chks = $this->base_ckh();
foreach ($chks as $index => $chk) {
if ($index != 'fred_disk_space' && $chk != '✓') {
return redirect('install?step='.$step - 1)
->withErrors("{$index} 检测未同通过")
->withInput();
}
}
$data = array_merge($data, [
'is_goon' => $is_goon,
'post' => [
'host' => $_POST['host'] ?? '127.0.0.1',
'port' => $_POST['port'] ?? '3306',
'user' => $_POST['user'] ?? 'root',
'password' => $_POST['password'] ?? '',
'name' => $_POST['name'] ?? 'likeshop',
'admin_user' => $_POST['admin_user'] ?? '',
'admin_password' => $_POST['admin_password'] ?? '',
'admin_confirm_password' => $_POST['admin_confirm_password'] ?? '',
],
]);
}
if ($step == '4') {
$rule = [
'host' => 'required',
'port' => 'required',
'user' => 'required',
'password' => 'required',
'name' => 'required',
'admin_user' => 'required',
'admin_password' => 'required|string|min:6|confirmed',
];
$validator = Validator::make($request->all(), $rule, [
'host.required' => '数据库主机不能为空',
'port.required' => '端口号不能为空',
'user.required' => '数据库用户不能为空',
'password.required' => '数据库密码不能为空',
'name.required' => '数据库名称不能为空',
'admin_user.required' => '管理员账号不能为空',
'admin_password.required' => '管理员密码不能为空',
'admin_password.min' => '管理员密码不能少于6位',
'admin_password.confirmed' => '确认密码不一致',
]);
if ($validator->fails()) {
return redirect('install?step='.$step - 1)
->withErrors($validator)
->withInput();
}
$params = $request->only(array_keys($rule));
// 临时修改数据库配置
config([
'database.connections.test' => [
'driver' => 'mysql',
'host' => $params['host'],
'port' => $params['port'],
'database' => $params['name'],
'username' => $params['user'],
'password' => $params['password'],
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
]);
try {
// 使用自定义配置创建数据库连接
DB::connection('test')->getPdo();
} catch (\Exception $e) {
return redirect('install?step='.$step - 1)
->withErrors('数据库链接不正确')
->withInput();
}
try {
exec('cp .env.example .env');
$this->updateEnv('DB_HOST', $params['host']);
$this->updateEnv('DB_PORT', $params['port']);
$this->updateEnv('DB_DATABASE', $params['name']);
$this->updateEnv('DB_USERNAME', $params['user']);
$this->updateEnv('DB_PASSWORD', $params['password']);
} catch (\Exception $e) {
return redirect('install?step='.$step - 1)
->withErrors($e->getMessage())
->withInput();
}
try {
Artisan::call('migrate');
DB::table('users')->insert([
'username' => $params['admin_user'],
'password' => bcrypt($params['admin_password']),
'type' => UserType::Admin,
'referral_code' => '100000',
'status' => true,
'created_at' => now(),
'updated_at' => now(),
]);
} catch (\Exception $e) {
return redirect('install?step='.$step - 1)
->withErrors('sql_error:'.$e->getMessage())
->withInput();
}
$data = array_merge($data, [
'is_goon' => $is_goon,
]);
}
$step = $step > 4 ? 1 : $step;
return view("install/step{$step}", $data);
}
public function updateEnv($search, $replace): void
{
$path = base_path('.env');
if (file_exists($path)) {
$content = file_get_contents($path);
$content = preg_replace(
'/^'.$search.'=(.*)$/m',
$search.'='.$replace,
$content
);
file_put_contents($path, $content);
}
}
private function base_ckh(): array
{
return [
'php_version' => version_compare(PHP_VERSION, '7.2.0') >= 0 ? '✓' : '×',
'fred_disk_space' => $this->fred_disk_space(),
'pdo_mysql' => extension_loaded('pdo_mysql') ? '✓' : '×',
'curl' => extension_loaded('curl') ? '✓' : '×',
'gd2' => extension_loaded('gd') ? '✓' : '×',
'log' => File::isWritable(storage_path('logs')) ? '✓' : '×',
'upload' => File::isWritable(storage_path('app')) ? '✓' : '×',
'cache' => File::isWritable(storage_path('framework')) ? '✓' : '×',
'env' => File::isWritable(base_path()) ? '✓' : '×',
];
}
private function fred_disk_space(): string
{
// M
$freeDiskSpace = disk_free_space(realpath(__DIR__)) / 1024 / 1024;
// G
if ($freeDiskSpace > 1024) {
return number_format($freeDiskSpace / 1024, 2).'G';
}
return number_format($freeDiskSpace, 2).'M';
}
}
+1
View File
@@ -7,6 +7,7 @@
"require": {
"php": "^8.1",
"ext-bcmath": "*",
"ext-pdo": "*",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.10",
"laravel/sanctum": "^3.3",
-7
View File
@@ -509,13 +509,6 @@ CREATE TABLE `users` (
UNIQUE KEY `users_referral_code_unique` (`referral_code`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Records of users
-- ----------------------------
BEGIN;
INSERT INTO `users` (`id`, `username`, `password`, `status`, `type`, `credit`, `accumulate_credit`, `commission`, `accumulate_commission`, `vip_id`, `agent_id`, `level_id`, `start_at`, `end_at`, `parent_id`, `referral_code`, `created_at`, `updated_at`) VALUES (1, 'admin', '$2y$12$KWrBehWoDo4.96vkU4NT8OqMCKID7NYR9HD58oBR5RInS.w0aKXIS', 1, 3, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, '100000', '2025-01-02 06:45:17', '2025-01-02 06:45:17');
COMMIT;
-- ----------------------------
-- Table structure for vip_logs
-- ----------------------------
+405
View File
@@ -0,0 +1,405 @@
body {
position: relative;
background-color: #F6F6F6;
}
.mounted {
background-color: #F6F6F6;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-bottom: 17px;
margin-top: 70px;
}
.header {
display: flex;
flex-direction: row;
background-color: #F6F6F6;
padding: 14px 39px;
}
.mounted-box {
display: flex;
width: 940px;
min-height: 611px;
background-color: white;
padding: 15px 30px 24px;
flex-direction: column;
align-items: center;
box-shadow:3px 2px 20px rgba(0,0,0,0.08);
}
.mounted-title {
font-size: 18px;
color: #222222;
font-weight: Bold;
}
.mounted-container {
width: 940px;
display: flex;
flex-direction: column;
justify-content: center;
}
.mounted-nav {
display: flex;
justify-content: center;
margin-top: 15px;
}
.mounted-nav .active {
color: white;
background-color: #2C85EA;
border: 1px solid #2C85EA !important;
}
.mounted-nav li:nth-of-type(even) {
width: 140px;
height: 36px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
font-family: PingFang SC;
border-top: 1px solid #E5E5E5;
border-bottom: 1px solid #E5E5E5;
}
.mounted-nav li:nth-of-type(odd) {
width: 140px;
height: 36px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
font-family: PingFang SC;
border: 1px solid #E5E5E5;
}
.mounted-nav li:last-child {
border-right: 1px solid #E5E5E5;
}
.mounted-content-item {
margin-top: 15px;
/* border:1px solid #E5E5E5; */
display: none;
}
.content-header {
background-color: #E5E5E5;
padding: 8px 16px;
font-family: PingFang SC;
}
.content {
padding: 16px;
height: 392px;
border: 1px solid #E5E5E5;
overflow-y: auto;
}
.content h2 {
font-size: 20px;
}
.content p {
font-size: 14px;
}
.content h3 {
font-size: 16px;
}
.mt6 {
margin-top: 6px;
}
.mt16 {
margin-top: 16px;
}
.content-form {
padding: 23px 60px;
border: 1px solid #E5E5E5;
}
.form-btn {
width: 100%; margin: 0 auto; text-align: center
}
.form-box-item {
display: flex;
align-items: center;
height: 40px;
}
.form-box-item:not(:nth-of-type(1)) {
display: flex;
align-items: center;
height: 40px;
margin-top: 16px;
}
.form-desc {
width: 60px;
font-size: 12px;
margin-right: 16px;
text-align: right;
}
.form-box-item div input {
width:328px;
height: 32px;
padding-left: 20px;
}
.cancel-btn {
padding: 7px 28px;
background-color: white;
border: 1px solid #D7D7D7;
cursor: pointer;
}
.accept-btn {
padding: 7px 28px;
color: white;
background-color: #2C85EA;
border: none;
flex: none;
cursor: pointer;
}
.item-btn-group .action {
background-color: #d1d1d1 !important;
}
.disabled-btn {
padding: 7px 28px;
color: #222222;
background-color: #D7D7D7;
border: none;
flex: none;
display: flex;
align-items: center;
border:1px solid #D7D7D7;
}
.item-btn-group {
display: none;
margin-top: 20px;
}
.show {
display: block !important;
}
.hidden {
display: none !important;
}
.form-box-check {
display: flex;
align-items: center;
margin-top: 12px;
}
footer {
font-size: 12px;
margin-bottom: 20px;
color:#707070;
font-weight: 400;
display: flex;
justify-content: center;
background-color: #F6F6F6;
}
.layui-table {
margin: 0;
}
.layui-table tr {
background-color: white !important;
}
.layui-table tr td{
font-size: 12px;
font-family:PingFang SC;
line-height:20px;
background-color: white !important;
}
.layui-table tr th {
font-size: 14px;
font-family:PingFang SC;
font-weight:bold;
line-height:20px;
}
.mounted-env-container {
height: 440px;
padding-bottom: 20px;
overflow-y: auto;
}
.mounted-tips {
padding: 15px 24px;
color: #2C85EA;
background-color: #eef4ff;
}
.mounting-container {
padding: 16px;
height: 479px;
max-height: 479px;
border: 1px solid #E5E5E5;
overflow-y: auto;
}
.item-cell {
padding: 4px 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.green{
color: #11d55c;
}
.wrong {
color: #FC4D4D;
}
.layui-icon {
font-size: 18px !important;
}
.success-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 392px;
border: 1px solid #E5E5E5;
}
img {
width: 100%;
height: 100%;
}
.success-content .tips {
width: 400px;
height: 80px;
padding: 9px 18px;
background-color: #F8F8F8;
font-size: 12px;
margin-top: 10px;
}
.success-content .btn-group {
display: flex;
align-items: center;
margin-top: 40px;
}
.success-content .result {
font-size:20px;
font-family:PingFang SC;
font-weight:bold;
line-height:28px;
}
.success-content .btn-group .store-btn {
padding: 7px 35px;
border: 1px solid #2C85EA;
background-color: white;
color: #2C85EA;
cursor: pointer;
}
.success-content .btn-group .btn {
padding: 7px 35px;
border: 1px solid #2C85EA;
background-color: #2C85EA;
color: white;
cursor: pointer;
}
.mounted-footer {
width: 940px;
background-color: white;
padding: 16px 30px 23px;
margin-top: 16px;
box-shadow:3px 2px 20px rgba(0,0,0,0.08);
display: none;
}
.mounted-footer-title {
font-size: 18px;
line-height: 25px;
margin-bottom: 16px;
}
.mounted-recommend-box {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
}
.mounted-recommend-item {
display: flex;
justify-content: center;
align-items: center;
width: 224px;
height: 140px;
border:1px solid #D7D7D7;
cursor: pointer;
}
.mounted-recommend-item .icon {
width: 128px;
height: 36px;
}
.mounted-recommend-item:hover {
background-color: #F6F9FF;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
width: 224px;
height: 140px;
}
.mounted-recommend-item:hover .icon{
display: none;
}
.recommend-content {
display: none;
}
.mounted-recommend-item:hover .recommend-content {
display: block;
padding: 6px 10px 10px;
}
.mounted-recommend-item:hover .recommend-content .title {
font-size: 16px;
line-height: 22px;
font-weight: bold;
}
.mounted-recommend-item:hover .recommend-content ul {
list-style-type: disc;
margin-left: 20px;
}
.mounted-recommend-item:hover .recommend-content li {
list-style-type: disc;
}
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>火星快链安装</title>
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css"/>
<link rel="stylesheet" type="text/css" href="/css/install.css"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<div class="mounted" id="mounted">
<div class="mounted-box">
<form method="post" action="?step=2">
<div class="mounted-title">安装步骤</div>
<div class="mounted-container" id="tab">
<ul class="mounted-nav" id="nav">
<li @if($step == "1") class="active" @endif>许可协议</li>
<li @if($step == "2") class="active" @endif>环境监测</li>
<li @if($step == "3") class="active" @endif>参数配置</li>
<li @if($step >= "4") class="active" @endif>安装</li>
</ul>
<!-- 阅读许可 -->
<div class="mounted-content-item show">
<div class="content-header">
开源系统授权协议
</div>
<div class="content">
<h2>版权所有(c)2019-<?=date('Y')?>,火星快链团队保留所有权利。</h2>
<p class="mt16">
<p class="mt6">为了正确并合法的使用本软件,请你在使用前务必阅读清楚下面的协议条款:</p>
<h3 class="mt16">一、本授权协议适用且仅适用于火星快链开源软件产品任何版本。</h3>
<h3 class="mt16">二、协议许可的权利</h3>
<p class="mt6">
1.免费版本可免费商用,不能私自去除官方版权。付费版本需要取得商业授权方可使用,可以去除官方版权,否则会被视为盗版行为并承担相应法律责任。
</p>
<p class="mt6">
2.请尊重火星快链团队劳动成果,严禁使用本系统转手、转卖、倒卖或二次开发后转手、转卖、倒卖等商业行为。
</p>
<p class="mt6">
3.任何企业和个人不允许对程序代码以任何形式任何目的再发布。
</p>
<p class="mt6">
4.你可以在协议规定的约束和限制范围内修改系列开源软件产品或界面风格以适应你的网站要求。
</p>
<p class="mt6">
5.你拥有使用本软件构建的系统全部内容所有权,并独立承担与这些内容的相关法律义务。
</p>
<p class="mt6">
6.获得商业授权之后,你可以将本软件应用于商业用途,同时依据所购买的授权类型中确定的技术支持内容,自购买时刻起,在技术支持期限内拥有通过指定的方式获得指定范围内的技术支持服务。商业授权用户享有反映和提出意见的权力,相关意见将被作为首要考虑,但没有一定被采纳的承诺或保证。
</p>
<h3 class="mt6">三、协议规定的约束和限制</h3>
<p class="mt6">
1.免费版本可免费商用,不能私自去除官方版权。付费版本需要取得商业授权方可使用,可以去除官方版权,否则会被视为盗版行为并承担相应法律责任。
</p>
<p class="mt6">
2.未经许可,不得对本软件或与之关联的商业授权进行出租、出售、抵押或发放子许可证。
</p>
<p class="mt6">
3.未经许可,禁止在开源系统的整体或任何部分基础上以发展任何派生版本、修改版本或第三方版本用于重新分发。
</p>
<p class="mt6">
4.如果你未能遵守本协议的条款,你的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。
</p>
<h3 class="mt6">四、有限担保和免责声明</h3>
<p class="mt6">
1.本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。
</p>
<p class="mt6">
2.用户出于自愿而使用本软件,你必须了解使用本软件的风险,在尚未购买产品技术服务之前,我们不承诺对免费用户提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。
</p>
<p class="mt6">
3.电子文本形式的授权协议如同双方书面签署的协议一样,具有完全的和等同的法律效力。你一旦开始确认本协议并安装本软件,即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时,受到相关的约束和限制。协议许可范围以外的行为,将直接违反本授权协议并构成侵权,我们有权随时终止授权,责令停止损害,并保留追究相关责任的权力。
</p>
<p class="mt6">
4.如果本软件带有其它软件的整合API示范例子包,这些文件版权不属于本软件官方,并且这些文件是没经过授权发布的,请参考相关软件的使用许可合法的使用。
</p>
<br><br>
<p class="mt6">
-----------------------------------------------------
</p>
</div>
</div>
</div>
<div class="form-btn">
<div class="item-btn-group show">
<button class="accept-btn">我已阅读并同意</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</div>
</div>
</form>
</div>
</div>
<footer>
Copyright © 2019-<?=date('Y')?>
</footer>
<script src="https://www.layuicdn.com/layui/layui.js"></script>
</body>
</html>
@@ -0,0 +1,201 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>火星快链安装</title>
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css"/>
<link rel="stylesheet" type="text/css" href="/css/install.css"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<div class="mounted" id="mounted">
<div class="mounted-box">
@if ($errors->any())
<div style="color: red;">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="?step={!! $nextStep !!}" name="main_form">
<div class="mounted-title">安装步骤</div>
<div class="mounted-container" id="tab">
<ul class="mounted-nav" id="nav">
<li @if($step == "1") class="active" @endif>许可协议</li>
<li @if($step == "2") class="active" @endif>环境监测</li>
<li @if($step == "3") class="active" @endif>参数配置</li>
<li @if($step >= "4") class="active" @endif>安装</li>
</ul>
<!-- 检查信息 -->
<div class="mounted-content-item show">
<div class="mounted-env-container">
<div class="mounted-item">
<div class="content-header">
服务器信息
</div>
<div class="content-table">
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="210">
<col width="730">
</colgroup>
<thead>
<tr>
<th>参数</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>服务器操作系统</td>
<td>{!! PHP_OS !!}</td>
</tr>
<tr>
<td>web服务器环境</td>
<td>{!! $_SERVER['SERVER_SOFTWARE'] !!}</td>
</tr>
<tr>
<td>PHP版本</td>
<td>{!! phpversion() !!}</td>
</tr>
<tr>
<td>程序安装目录</td>
<td>{!! base_path() !!}</td>
</tr>
<tr>
<td>磁盘空间</td>
<td>{!! $chk['fred_disk_space'] !!}</td>
</tr>
<tr>
<td>上传限制</td>
<td>
@if(ini_get('file_uploads'))
{!! ini_get('upload_max_filesize') !!}
@else
禁止上传
@endif
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mounted-tips mt16">PHP环境要求必须满足下列所有条件,否则系统或系统部分功能将无法使用。</div>
<div class="mounted-item mt16">
<div class="content-header">
PHP环境要求
</div>
<div class="content-table">
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="210">
<col width="210">
<col width="400">
</colgroup>
<thead>
<tr>
<th>选项</th>
<th>要求</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>PHP版本</td>
<td>大于7.2</td>
<td>{!! $chk['php_version'] !!}</td>
</tr>
<tr>
<td>PDO_MYSQL</td>
<td>支持</td>
<td>{!! $chk['pdo_mysql'] !!}</td>
</tr>
<tr>
<td>allow_url_fopen</td>
<td>支持 (建议支持cURL)</td>
<td>{!! $chk['curl'] !!}</td>
</tr>
<tr>
<td>GD2</td>
<td>支持</td>
<td>{!! $chk['gd2'] !!}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mounted-tips mt16">
系统要求likeshop开源商城安装目录下的runtime和upload必须可写,才能使用likeshop开源商城的所有功能。
</div>
<div class="mounted-item mt16">
<div class="content-header">
目录权限监测
</div>
<div class="content-table">
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="210">
<col width="210">
<col width="400">
</colgroup>
<thead>
<tr>
<th>目录</th>
<th>要求</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>/server/storage/logs</td>
<td>logs目录可写</td>
<td>{!! $chk['log'] !!}</td>
</tr>
<tr>
<td>/server/storage/app/public</td>
<td>uploads目录可写</td>
<td>{!! $chk['upload'] !!}</td>
</tr>
<tr>
<td>/server/storage/framework</td>
<td>cache目录可写</td>
<td>{!! $chk['cache'] !!}</td>
</tr>
<tr>
<td>/server/.env</td>
<td>.env文件可写</td>
<td>{!! $chk['env'] !!}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="form-btn">
<div class="item-btn-group show">
<a href="?step={!! $lastStep !!}" class="cancel-btn" style="padding: 7px 63px;margin-right: 16px">返回</a>
<button class="accept-btn @if(!$is_goon) action @endif" style="padding: 7px 63px;">
继续
</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
&nbsp;
<a href="?step={!! $step !!}" class="accept-btn" style="padding: 7px 63px;">重新检查
</a>
</div>
</div>
</form>
</div>
</div>
<footer>
Copyright © 2019-<?=date('Y')?>
</footer>
<script src="https://www.layuicdn.com/layui/layui.js"></script>
</body>
</html>
@@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>火星快链安装</title>
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css"/>
<link rel="stylesheet" type="text/css" href="/css/install.css"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<div class="mounted" id="mounted">
<div class="mounted-box">
@if ($errors->any())
<div style="color: red;">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="?step={!! $nextStep !!}" name="main_form">
<div class="mounted-title">安装步骤</div>
<div class="mounted-container" id="tab">
<ul class="mounted-nav" id="nav">
<li @if($step == "1") class="active" @endif>许可协议</li>
<li @if($step == "2") class="active" @endif>环境监测</li>
<li @if($step == "3") class="active" @endif>参数配置</li>
<li @if($step >= "4") class="active" @endif>安装</li>
</ul>
<!-- 数据库设置 -->
<div class="mounted-content-item show">
<div class="mounted-item">
<div class="content-header">
数据库选项
</div>
<div class="content-form">
<div class="form-box-item">
<div class="form-desc">
数据库主机
</div>
<div>
<input type="text" name="host" value="{!! $post['host'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
端口号
</div>
<div>
<input type="text" name="port" value="{!! $post['port'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
数据库用户
</div>
<div>
<input type="text" name="user" value="{!! $post['user'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
数据库密码
</div>
<div>
<input type="text" name="password" value="{!! $post['password'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
数据库名称
</div>
<div>
<input type="text" name="name" value="{!! $post['name'] !!}"/>
</div>
</div>
</div>
</div>
<div class="mounted-item">
<div class="content-header mt16">
管理选项
</div>
<div class="content-form">
<div class="form-box-item">
<div class="form-desc">
管理员账号
</div>
<div>
<input type="text" name="admin_user" value="{!! $post['admin_user'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
管理员密码
</div>
<div>
<input type="password" name="admin_password" value="{!! $post['admin_password'] !!}"/>
</div>
</div>
<div class="form-box-item">
<div class="form-desc">
确认密码
</div>
<div>
<input type="password" name="admin_password_confirmation" value="{!! $post['admin_confirm_password'] !!}"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-btn">
<div class="item-btn-group show">
<a href="?step={!! $lastStep !!}" class="cancel-btn" style="padding: 7px 63px;margin-right: 16px">返回</a>
<button class="accept-btn @if(!$is_goon) action @endif" style="padding: 7px 63px;">
继续
</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
&nbsp;
<a href="?step={!! $step !!}" class="accept-btn" style="padding: 7px 63px;">重新检查
</a>
</div>
</div>
</form>
</div>
</div>
<footer>
Copyright © 2019-<?=date('Y')?>
</footer>
<script src="https://www.layuicdn.com/layui/layui.js"></script>
</body>
</html>
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>火星快链安装</title>
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css"/>
<link rel="stylesheet" type="text/css" href="/css/install.css"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<div class="mounted" id="mounted">
<div class="mounted-box">
<form method="post" action="">
<div class="mounted-title">安装步骤</div>
<div class="mounted-container" id="tab">
<ul class="mounted-nav" id="nav">
<li @if($step == "1") class="active" @endif>许可协议</li>
<li @if($step == "2") class="active" @endif>环境监测</li>
<li @if($step == "3") class="active" @endif>参数配置</li>
<li @if($step >= "4") class="active" @endif>安装</li>
</ul>
<!-- 安装中 -->
<div class="mounted-content-item show">
<div id="mounting">
<div class="content-header">
正在安装中
</div>
</div>
<div class="show" id="mounting-success">
<div class="content-header">
安装成功
</div>
<div class="success-content">
<div class="mt16 result">安装完成,进入管理后台</div>
<div class="tips">
为了您站点的安全,安装完成后即可将网站根目录下的“install”文件夹删除,或者config/install.lock/目录下创建install.lock文件防止重复安装。
</div>
<div class="btn-group">
<a class="btn" href="/" style="margin-left: 20px;">进入首页</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<footer>
Copyright © 2019-<?=date('Y')?>
</footer>
<script src="https://www.layuicdn.com/layui/layui.js"></script>
</body>
</html>
+5 -1
View File
@@ -1,7 +1,11 @@
<?php
use App\Http\Controllers\Controller;
use App\Http\Controllers\Install\IndexController;
use App\Http\Controllers\JumpController;
use Illuminate\Support\Facades\Route;
Route::view('/', 'welcome');
Route::get('/', [Controller::class, 'welcome']);
Route::get('/j/{code}', [JumpController::class, 'show']);
Route::any('/install', [IndexController::class, 'index']);