更新细节
|
@ -14,11 +14,6 @@ namespace think;
|
|||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!file_exists(__DIR__ .'/../config/install.lock')) {
|
||||
header("location:/install/install.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
// 执行HTTP应用并响应
|
||||
$http = (new App())->http;
|
||||
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
class YxEnv
|
||||
{
|
||||
/**
|
||||
* 环境变量数据
|
||||
* @var array
|
||||
*/
|
||||
protected $data = [];
|
||||
protected $filePath = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
//$this->data = $_ENV;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取环境变量定义文件
|
||||
* @access public
|
||||
* @param string $file 环境变量定义文件
|
||||
* @return void
|
||||
*/
|
||||
public function load($file)
|
||||
{
|
||||
$this->filePath = $file;
|
||||
$env = parse_ini_file($file, true);
|
||||
$this->set($env);
|
||||
}
|
||||
|
||||
public function makeEnv($file)
|
||||
{
|
||||
if(!file_exists($file)){
|
||||
try{
|
||||
touch($file);
|
||||
}catch (Exception $e){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取环境变量值
|
||||
* @access public
|
||||
* @param string $name 环境变量名
|
||||
* @param mixed $default 默认值
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($name = null, $default = null, $php_prefix = true)
|
||||
{
|
||||
if (is_null($name)) {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
if (isset($this->data[$name])) {
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
return $this->getEnv($name, $default, $php_prefix);
|
||||
}
|
||||
|
||||
protected function getEnv($name, $default = null, $php_prefix = true)
|
||||
{
|
||||
if ($php_prefix) {
|
||||
$name = 'PHP_' . $name;
|
||||
}
|
||||
|
||||
$result = getenv($name);
|
||||
|
||||
if (false === $result) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if ('false' === $result) {
|
||||
$result = false;
|
||||
} elseif ('true' === $result) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
if ( !isset($this->data[$name])) {
|
||||
$this->data[$name] = $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 写入Env文件
|
||||
* @author luzg(2020/8/27 18:12)
|
||||
* @param $envFilePath
|
||||
* @param array $databaseEnv
|
||||
*/
|
||||
public function putEnv($envFilePath, array $databaseEnv)
|
||||
{
|
||||
$applyDbEnv = [
|
||||
'DATABASE.HOSTNAME' => $databaseEnv['host'],
|
||||
'DATABASE.DATABASE' => $databaseEnv['name'],
|
||||
'DATABASE.USERNAME' => $databaseEnv['user'],
|
||||
'DATABASE.PASSWORD' => $databaseEnv['password'],
|
||||
'DATABASE.HOSTPORT' => $databaseEnv['port'],
|
||||
'DATABASE.PREFIX' => $databaseEnv['prefix'],
|
||||
];
|
||||
|
||||
$envLine = array_merge($this->data, $applyDbEnv);
|
||||
|
||||
$content = '';
|
||||
$lastPrefix = '';
|
||||
|
||||
global $uniqueSalt;
|
||||
|
||||
foreach ($envLine as $index => $value) {
|
||||
|
||||
if ($index == 'PROJECT.UNIQUE_IDENTIFICATION' && !empty($uniqueSalt)) {
|
||||
$value = $uniqueSalt;
|
||||
}
|
||||
|
||||
@list($prefix, $key) = explode('.', $index);
|
||||
|
||||
if ($prefix != $lastPrefix && $key != null) {
|
||||
if ($lastPrefix != '')
|
||||
$content .= "\n";
|
||||
$content .= "[$prefix]\n";
|
||||
$lastPrefix = $prefix;
|
||||
}
|
||||
|
||||
if ($prefix != $lastPrefix && $key == null) {
|
||||
$content .= "$index = \"$value\"\n";
|
||||
} else {
|
||||
$content .= "$key = \"$value\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($content)) {
|
||||
file_put_contents($envFilePath, $content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置环境变量值
|
||||
* @access public
|
||||
* @param string|array $env 环境变量
|
||||
* @param mixed $value 值
|
||||
* @return void
|
||||
*/
|
||||
public function set($env, $value = null)
|
||||
{
|
||||
if (is_array($env)) {
|
||||
|
||||
foreach ($env as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
foreach ($val as $k => $v) {
|
||||
$this->data[$key . '.' . $k] = $v;
|
||||
}
|
||||
} else {
|
||||
$this->data[$key] = $val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$name = strtoupper(str_replace('.', '_', $env));
|
||||
|
||||
$this->data[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,400 +0,0 @@
|
|||
body {
|
||||
position: relative;
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.mounted {
|
||||
background-color: #F6F6F6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
|
||||
.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-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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 6.2 KiB |
|
@ -1,97 +0,0 @@
|
|||
<?php
|
||||
// error_reporting(0);
|
||||
include "model.php";
|
||||
include "YxEnv.php";
|
||||
|
||||
define('install', true);
|
||||
define('INSTALL_ROOT', __DIR__);
|
||||
define('TESTING_TABLE', 'config');
|
||||
|
||||
$step = $_GET['step'] ?? 1;
|
||||
|
||||
$installDir = "install";
|
||||
$modelInstall = new installModel();
|
||||
|
||||
// Env设置
|
||||
$yxEnv = new YxEnv();
|
||||
|
||||
// 检查是否有安装过
|
||||
$envFilePath = $modelInstall->getAppRoot() . '/.env';
|
||||
if ($modelInstall->appIsInstalled() && in_array($step, [1, 2, 3, 4])) {
|
||||
die('可能已经安装过本系统了,请删除配置目录下面的install.lock文件再尝试');
|
||||
}
|
||||
|
||||
// 加载Example文件
|
||||
$yxEnv->load($modelInstall->getAppRoot() . '/.example.env');
|
||||
|
||||
//尝试生成.env
|
||||
$yxEnv->makeEnv($modelInstall->getAppRoot() . '/.env');
|
||||
|
||||
$post = [
|
||||
'host' => $_POST['host'] ?? '127.0.0.1',
|
||||
'port' => $_POST['port'] ?? '3306',
|
||||
'user' => $_POST['user'] ?? 'root',
|
||||
'password' => $_POST['password'] ?? '',
|
||||
'name' => $_POST['name'] ?? 'likeadmin',
|
||||
'admin_user' => $_POST['admin_user'] ?? '',
|
||||
'admin_password' => $_POST['admin_password'] ?? '',
|
||||
'admin_confirm_password' => $_POST['admin_confirm_password'] ?? '',
|
||||
'prefix' => $_POST['prefix'] ?? 'la_',
|
||||
'import_test_data' => $_POST['import_test_data'] ?? 'off',
|
||||
'clear_db' => $_POST['clear_db'] ?? 'off',
|
||||
];
|
||||
|
||||
$message = '';
|
||||
|
||||
// 检查数据库正确性
|
||||
if ($step == 4) {
|
||||
$canNext = true;
|
||||
if (empty($post['prefix'])) {
|
||||
$canNext = false;
|
||||
$message = '数据表前缀不能为空';
|
||||
} elseif ($post['admin_user'] == '') {
|
||||
$canNext = false;
|
||||
$message = '请填写管理员用户名';
|
||||
} elseif (empty(trim($post['admin_password']))) {
|
||||
$canNext = false;
|
||||
$message = '管理员密码不能为空';
|
||||
} elseif ($post['admin_password'] != $post['admin_confirm_password']) {
|
||||
$canNext = false;
|
||||
$message = '两次密码不一致';
|
||||
} else {
|
||||
// 检查 数据库信息
|
||||
$result = $modelInstall->checkConfig($post['name'], $post);
|
||||
if ($result->result == 'fail') {
|
||||
$canNext = false;
|
||||
$message = $result->error;
|
||||
}
|
||||
|
||||
// 导入测试数据
|
||||
if ($canNext == true && $post['import_test_data'] == 'on') {
|
||||
if (!$modelInstall->importDemoData()) {
|
||||
$canNext = false;
|
||||
$message = '导入测试数据错误';
|
||||
}
|
||||
}
|
||||
|
||||
// 写配置文件
|
||||
if ($canNext) {
|
||||
$yxEnv->putEnv($envFilePath, $post);
|
||||
$modelInstall->mkLockFile();
|
||||
}
|
||||
|
||||
// 恢复admin和index入口
|
||||
if ($canNext) {
|
||||
$modelInstall->restoreIndexLock();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$canNext)
|
||||
$step = 3;
|
||||
}
|
||||
|
||||
// 取得安装成功的表
|
||||
$successTables = $modelInstall->getSuccessTable();
|
||||
|
||||
$nextStep = $step + 1;
|
||||
include __DIR__ . "/template/main.php";
|
|
@ -1,94 +0,0 @@
|
|||
var canClick = true;
|
||||
var installIndex = 0;
|
||||
|
||||
String.prototype.format = function(args)
|
||||
{
|
||||
if (arguments.length > 0)
|
||||
{
|
||||
var result = this;
|
||||
if (arguments.length === 1 && typeof (args) == "object")
|
||||
{
|
||||
for (var key in args)
|
||||
{
|
||||
var reg = new RegExp("({" + key + "})", "g");
|
||||
result = result.replace(reg, args[key]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
if (arguments[i] === undefined)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
var reg = new RegExp("({[" + i + "]})", "g");
|
||||
result = result.replace(reg, arguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 将内容推送到内容里面
|
||||
*/
|
||||
function pushSuccessTableToBox(successLine) {
|
||||
var installBox = document.getElementById('install_message');
|
||||
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.className = 'item-cell';
|
||||
var lineHtml = `
|
||||
<div style="display: flex;align-items: center;">
|
||||
<div class="layui-icon green"></div>
|
||||
<div style="margin-left: 10px;">创建数据表{0}完成!</div>
|
||||
</div>
|
||||
<div>{1}</div>
|
||||
`;
|
||||
div.innerHTML = lineHtml.format(successLine[0], successLine[1]);
|
||||
|
||||
installBox.append(div);
|
||||
|
||||
}
|
||||
|
||||
function showParts(index) {
|
||||
function getRndInteger(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) ) + min;
|
||||
}
|
||||
|
||||
if (index <= successTables.length) {
|
||||
setTimeout(function () { pushSuccessTableToBox(successTables[index]); showParts(++index); }, getRndInteger(50, 150));
|
||||
}
|
||||
|
||||
if (index === successTables.length) {
|
||||
goStep(5);
|
||||
}
|
||||
}
|
||||
|
||||
function goStep(step) {
|
||||
//var form = document.getElementsByTagName('form')[0];
|
||||
if (canClick === false)
|
||||
return;
|
||||
|
||||
canClick = false;
|
||||
document.main_form.action = "?step=" + step;
|
||||
document.main_form.submit();
|
||||
// form.action = "?step=" + step;
|
||||
// window.location.href = "?step=" + step;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
window.history.go(-1);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
showParts(0);
|
||||
}, 100);
|
|
@ -1,786 +0,0 @@
|
|||
<?php
|
||||
/** 安装界面需要的各种模块 */
|
||||
|
||||
class installModel
|
||||
{
|
||||
private $host;
|
||||
private $name;
|
||||
private $user;
|
||||
private $encoding;
|
||||
private $password;
|
||||
private $port;
|
||||
private $prefix;
|
||||
private $successTable = [];
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $allowNext = true;
|
||||
/**
|
||||
* @var PDO|string
|
||||
*/
|
||||
private $dbh = null;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $clearDB = false;
|
||||
|
||||
/**
|
||||
* Notes: php版本
|
||||
* @author luzg(2020/8/25 9:56)
|
||||
* @return string
|
||||
*/
|
||||
public function getPhpVersion()
|
||||
{
|
||||
return PHP_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 当前版本是否符合
|
||||
* @author luzg(2020/8/25 9:57)
|
||||
* @return string
|
||||
*/
|
||||
public function checkPHP()
|
||||
{
|
||||
return $result = version_compare(PHP_VERSION, '8.0.0') >= 0 ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否有PDO
|
||||
* @author luzg(2020/8/25 9:57)
|
||||
* @return string
|
||||
*/
|
||||
public function checkPDO()
|
||||
{
|
||||
return $result = extension_loaded('pdo') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否有PDO::MySQL
|
||||
* @author luzg(2020/8/25 9:58)
|
||||
* @return string
|
||||
*/
|
||||
public function checkPDOMySQL()
|
||||
{
|
||||
return $result = extension_loaded('pdo_mysql') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持JSON
|
||||
* @author luzg(2020/8/25 9:58)
|
||||
* @return string
|
||||
*/
|
||||
public function checkJSON()
|
||||
{
|
||||
return $result = extension_loaded('json') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持openssl
|
||||
* @author luzg(2020/8/25 9:58)
|
||||
* @return string
|
||||
*/
|
||||
public function checkOpenssl()
|
||||
{
|
||||
return $result = extension_loaded('openssl') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持mbstring
|
||||
* @author luzg(2020/8/25 9:58)
|
||||
* @return string
|
||||
*/
|
||||
public function checkMbstring()
|
||||
{
|
||||
return $result = extension_loaded('mbstring') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持zlib
|
||||
* @author luzg(2020/8/25 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkZlib()
|
||||
{
|
||||
return $result = extension_loaded('zlib') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持curl
|
||||
* @author luzg(2020/8/25 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkCurl()
|
||||
{
|
||||
return $result = extension_loaded('curl') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查GD2扩展
|
||||
* @author luzg(2020/8/26 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkGd2()
|
||||
{
|
||||
return $result = extension_loaded('gd') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查Dom扩展
|
||||
* @author luzg(2020/8/26 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkDom()
|
||||
{
|
||||
return $result = extension_loaded('dom') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持filter
|
||||
* @author luzg(2020/8/25 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkFilter()
|
||||
{
|
||||
return $result = extension_loaded('filter') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否支持iconv
|
||||
* @author luzg(2020/8/25 9:59)
|
||||
* @return string
|
||||
*/
|
||||
public function checkIconv()
|
||||
{
|
||||
return $result = extension_loaded('iconv') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 检查fileinfo扩展
|
||||
* @author 段誉(2021/6/28 11:03)
|
||||
* @return string
|
||||
*/
|
||||
public function checkFileInfo()
|
||||
{
|
||||
return $result = extension_loaded('fileinfo') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 取得临时目录路径
|
||||
* @author luzg(2020/8/25 10:05)
|
||||
* @return array
|
||||
*/
|
||||
public function getTmpRoot()
|
||||
{
|
||||
$path = $this->getAppRoot() . '/runtime';
|
||||
return [
|
||||
'path' => $path,
|
||||
'exists' => is_dir($path),
|
||||
'writable' => is_writable($path),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查临时路径
|
||||
* @author luzg(2020/8/25 10:06)
|
||||
* @return string
|
||||
*/
|
||||
public function checkTmpRoot()
|
||||
{
|
||||
$tmpRoot = $this->getTmpRoot()['path'];
|
||||
return $result = (is_dir($tmpRoot) and is_writable($tmpRoot)) ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: SESSION路径是否可写
|
||||
* @author luzg(2020/8/25 10:06)
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSessionSavePath()
|
||||
{
|
||||
$sessionSavePath = preg_replace("/\d;/", '', session_save_path());
|
||||
|
||||
return [
|
||||
'path' => $sessionSavePath,
|
||||
'exists' => is_dir($sessionSavePath),
|
||||
'writable' => is_writable($sessionSavePath),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查session路径可写状态
|
||||
* @author luzg(2020/8/25 10:13)
|
||||
* @return string
|
||||
*/
|
||||
public function checkSessionSavePath()
|
||||
{
|
||||
$sessionSavePath = preg_replace("/\d;/", '', session_save_path());
|
||||
$result = (is_dir($sessionSavePath) and is_writable($sessionSavePath)) ? 'ok' : 'fail';
|
||||
if ($result == 'fail') return $result;
|
||||
|
||||
file_put_contents($sessionSavePath . '/zentaotest', 'zentao');
|
||||
$sessionContent = file_get_contents($sessionSavePath . '/zentaotest');
|
||||
if ($sessionContent == 'zentao') {
|
||||
unlink($sessionSavePath . '/zentaotest');
|
||||
return 'ok';
|
||||
}
|
||||
return 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取得data目录是否可选
|
||||
* @author luzg(2020/8/25 10:58)
|
||||
* @return array
|
||||
*/
|
||||
public function getDataRoot()
|
||||
{
|
||||
$path = $this->getAppRoot();
|
||||
return [
|
||||
'path' => $path . 'www' . DS . 'data',
|
||||
'exists' => is_dir($path),
|
||||
'writable' => is_writable($path),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取得root路径
|
||||
* @author luzg(2020/8/25 11:02)
|
||||
* @return string
|
||||
*/
|
||||
public function checkDataRoot()
|
||||
{
|
||||
$dataRoot = $this->getAppRoot() . 'www' . DS . 'data';
|
||||
return $result = (is_dir($dataRoot) and is_writable($dataRoot)) ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取得php.ini信息
|
||||
* @author luzg(2020/8/25 11:03)
|
||||
* @return string
|
||||
*/
|
||||
public function getIniInfo()
|
||||
{
|
||||
$iniInfo = '';
|
||||
ob_start();
|
||||
phpinfo(1);
|
||||
$lines = explode("\n", strip_tags(ob_get_contents()));
|
||||
ob_end_clean();
|
||||
foreach ($lines as $line) if (strpos($line, 'ini') !== false) $iniInfo .= $line . "\n";
|
||||
return $iniInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 创建安装锁定文件
|
||||
* @author luzg(2020/8/28 11:32)
|
||||
* @return bool
|
||||
*/
|
||||
public function mkLockFile()
|
||||
{
|
||||
return touch($this->getAppRoot() . '/config/install.lock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查之前是否有安装
|
||||
* @author luzg(2020/8/28 11:36)
|
||||
*/
|
||||
public function appIsInstalled()
|
||||
{
|
||||
return file_exists($this->getAppRoot() . '/config/install.lock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取得配置信息
|
||||
* @author luzg(2020/8/25 11:05)
|
||||
* @param string $dbName 数据库名称
|
||||
* @param array $connectionInfo 连接信息
|
||||
* @return stdclass
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkConfig($dbName, $connectionInfo)
|
||||
{
|
||||
$return = new stdclass();
|
||||
$return->result = 'ok';
|
||||
|
||||
/* Connect to database. */
|
||||
$this->setDBParam($connectionInfo);
|
||||
$this->dbh = $this->connectDB();
|
||||
if (strpos($dbName, '.') !== false) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '没有发现数据库信息';
|
||||
return $return;
|
||||
}
|
||||
if ( !is_object($this->dbh)) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '安装错误,请检查连接信息:'.mb_strcut($this->dbh,0,30).'...';
|
||||
echo $this->dbh;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/* Get mysql version. */
|
||||
$version = $this->getMysqlVersion();
|
||||
|
||||
/* check mysql sql_model */
|
||||
// if(!$this->checkSqlMode($version)) {
|
||||
// $return->result = 'fail';
|
||||
// $return->error = '请在mysql配置文件修改sql-mode添加NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
|
||||
// return $return;
|
||||
// }
|
||||
|
||||
/* If database no exits, try create it. */
|
||||
if ( !$this->dbExists()) {
|
||||
if ( !$this->createDB($version)) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '创建数据库错误';
|
||||
return $return;
|
||||
}
|
||||
} elseif ($this->tableExits() and $this->clearDB == false) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '数据表已存在,您之前可能已安装本系统,如需继续安装请选择新的数据库。';
|
||||
return $return;
|
||||
} elseif ($this->dbExists() and $this->clearDB == true) {
|
||||
if (!$this->dropDb($connectionInfo['name'])) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '数据表已经存在,删除已存在库错误,请手动清除';
|
||||
return $return;
|
||||
} else {
|
||||
if ( !$this->createDB($version)) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '创建数据库错误!';
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create tables. */
|
||||
if ( !$this->createTable($version, $connectionInfo)) {
|
||||
$return->result = 'fail';
|
||||
$return->error = '创建表格失败';
|
||||
return $return;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 设置数据库相关信息
|
||||
* @author luzg(2020/8/25 11:17)
|
||||
* @param $post
|
||||
*/
|
||||
public function setDBParam($post)
|
||||
{
|
||||
$this->host = $post['host'];
|
||||
$this->name = $post['name'];
|
||||
$this->user = $post['user'];
|
||||
$this->encoding = 'utf8mb4';
|
||||
$this->password = $post['password'];
|
||||
$this->port = $post['port'];
|
||||
$this->prefix = $post['prefix'];
|
||||
$this->clearDB = $post['clear_db'] == 'on';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 连接数据库
|
||||
* @author luzg(2020/8/25 11:56)
|
||||
* @return PDO|string
|
||||
*/
|
||||
public function connectDB()
|
||||
{
|
||||
$dsn = "mysql:host={$this->host}; port={$this->port}";
|
||||
try {
|
||||
$dbh = new PDO($dsn, $this->user, $this->password);
|
||||
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$dbh->exec("SET NAMES {$this->encoding}");
|
||||
$dbh->exec("SET NAMES {$this->encoding}");
|
||||
try{
|
||||
$dbh->exec("SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';");
|
||||
}catch (Exception $e){
|
||||
|
||||
}
|
||||
return $dbh;
|
||||
} catch (PDOException $exception) {
|
||||
return $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查数据库是否存在
|
||||
* @author luzg(2020/8/25 11:56)
|
||||
* @return mixed
|
||||
*/
|
||||
public function dbExists()
|
||||
{
|
||||
$sql = "SHOW DATABASES like '{$this->name}'";
|
||||
return $this->dbh->query($sql)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查表是否存在
|
||||
* @author luzg(2020/8/25 11:56)
|
||||
* @return mixed
|
||||
*/
|
||||
public function tableExits()
|
||||
{
|
||||
$configTable = sprintf("'%s'", $this->prefix . TESTING_TABLE);
|
||||
$sql = "SHOW TABLES FROM {$this->name} like $configTable";
|
||||
return $this->dbh->query($sql)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取mysql版本号
|
||||
* @author luzg(2020/8/25 11:56)
|
||||
* @return false|string
|
||||
*/
|
||||
public function getMysqlVersion()
|
||||
{
|
||||
$sql = "SELECT VERSION() AS version";
|
||||
$result = $this->dbh->query($sql)->fetch();
|
||||
return substr($result->version, 0, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 检测数据库sql_mode
|
||||
* @param $version
|
||||
* @return bool
|
||||
* @author 段誉
|
||||
* @date 2021/8/27 17:17
|
||||
*/
|
||||
public function checkSqlMode($version)
|
||||
{
|
||||
$sql = "SELECT @@global.sql_mode";
|
||||
$result = $this->dbh->query($sql)->fetch();
|
||||
$result = (array)$result;
|
||||
|
||||
if ($version >= 5.7 && $version < 8.0) {
|
||||
if ((strpos($result['@@global.sql_mode'],'NO_AUTO_CREATE_USER') !== false)
|
||||
&& (strpos($result['@@global.sql_mode'],'NO_ENGINE_SUBSTITUTION') !== false)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 创建数据库
|
||||
* @author luzg(2020/8/25 11:57)
|
||||
* @param $version
|
||||
* @return mixed
|
||||
*/
|
||||
public function createDB($version)
|
||||
{
|
||||
$sql = "CREATE DATABASE `{$this->name}`";
|
||||
if ($version > 4.1) $sql .= " DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
|
||||
return $this->dbh->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 创建表
|
||||
* @author luzg(2020/8/25 11:57)
|
||||
* @param $version
|
||||
* @param $post
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createTable($version, $post)
|
||||
{
|
||||
$dbFile = $this->getInstallRoot() . '/db/like.sql';
|
||||
//file_put_contents($dbFile, $this->initAccount($post), FILE_APPEND);
|
||||
$content = str_replace(";\r\n", ";\n", file_get_contents($dbFile));
|
||||
$tables = explode(";\n", $content);
|
||||
$tables[] = $this->initAccount($post);
|
||||
$installTime = microtime(true) * 10000;
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$table = trim($table);
|
||||
if (empty($table)) continue;
|
||||
|
||||
if (strpos($table, 'CREATE') !== false and $version <= 4.1) {
|
||||
$table = str_replace('DEFAULT CHARSET=utf8', '', $table);
|
||||
}
|
||||
// elseif (strpos($table, 'DROP') !== false and $this->clearDB != false) {
|
||||
// $table = str_replace('--', '', $table);
|
||||
// }
|
||||
|
||||
/* Skip sql that is note. */
|
||||
if (strpos($table, '--') === 0) continue;
|
||||
|
||||
$table = str_replace('`la_', $this->name . '.`la_', $table);
|
||||
$table = str_replace('`la_', '`' . $this->prefix, $table);
|
||||
|
||||
if (strpos($table, 'CREATE') !== false) {
|
||||
$tableName = explode('`', $table)[1];
|
||||
$installTime += random_int(3000, 7000);
|
||||
$this->successTable[] = [$tableName, date('Y-m-d H:i:s', $installTime / 10000)];
|
||||
}
|
||||
|
||||
// if (strpos($table, "INSERT INTO ") !== false) {
|
||||
// $table = str_replace('INSERT INTO ', 'INSERT INTO ' .$this->name .'.', $table);
|
||||
// }
|
||||
|
||||
try {
|
||||
if ( !$this->dbh->query($table)) return false;
|
||||
} catch (Exception $e) {
|
||||
echo 'error sql: ' . $table . "<br>";
|
||||
echo $e->getMessage() . "<br>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 删除数据库
|
||||
* @param $db
|
||||
* @return false|PDOStatement
|
||||
*/
|
||||
public function dropDb($db)
|
||||
{
|
||||
$sql = "drop database {$db};";
|
||||
return $this->dbh->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取得安装成功的表列表
|
||||
* @author luzg(2020/8/26 18:28)
|
||||
* @return array
|
||||
*/
|
||||
public function getSuccessTable()
|
||||
{
|
||||
return $this->successTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 创建演示数据
|
||||
* @author luzg(2020/8/25 11:58)
|
||||
* @return bool
|
||||
*/
|
||||
public function importDemoData()
|
||||
{
|
||||
$demoDataFile = 'ys.sql';
|
||||
$demoDataFile = $this->getInstallRoot() . '/db/' . $demoDataFile;
|
||||
if (!is_file($demoDataFile)) {
|
||||
echo "<br>";
|
||||
echo 'no file:' .$demoDataFile;
|
||||
return false;
|
||||
}
|
||||
$content = str_replace(";\r\n", ";\n", file_get_contents($demoDataFile));
|
||||
$insertTables = explode(";\n", $content);
|
||||
foreach ($insertTables as $table) {
|
||||
$table = trim($table);
|
||||
if (empty($table)) continue;
|
||||
|
||||
$table = str_replace('`la_', $this->name . '.`la_', $table);
|
||||
$table = str_replace('`la_', '`' .$this->prefix, $table);
|
||||
if ( !$this->dbh->query($table)) return false;
|
||||
}
|
||||
|
||||
// 移动图片资源
|
||||
$this->cpFiles($this->getInstallRoot().'/uploads', $this->getAppRoot().'/public/uploads');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个文件夹下的所有文件及文件夹
|
||||
* 复制到另一个文件夹里(保持原有结构)
|
||||
*
|
||||
* @param <string> $rootFrom 源文件夹地址(最好为绝对路径)
|
||||
* @param <string> $rootTo 目的文件夹地址(最好为绝对路径)
|
||||
*/
|
||||
function cpFiles($rootFrom, $rootTo){
|
||||
|
||||
$handle = opendir($rootFrom);
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
//DIRECTORY_SEPARATOR 为系统的文件夹名称的分隔符 例如:windos为'/'; linux为'/'
|
||||
$fileFrom = $rootFrom . DIRECTORY_SEPARATOR . $file;
|
||||
$fileTo = $rootTo . DIRECTORY_SEPARATOR . $file;
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($fileFrom)) {
|
||||
if (!is_dir($fileTo)) { //目标目录不存在则创建
|
||||
mkdir($fileTo, 0777);
|
||||
}
|
||||
$this->cpFiles($fileFrom, $fileTo);
|
||||
} else {
|
||||
if (!file_exists($fileTo)) {
|
||||
@copy($fileFrom, $fileTo);
|
||||
if (strstr($fileTo, "access_token.txt")) {
|
||||
chmod($fileTo, 0777);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 当前应用程序的相对路径
|
||||
* @author luzg(2020/8/25 10:55)
|
||||
* @return string
|
||||
*/
|
||||
public function getAppRoot()
|
||||
{
|
||||
return realpath($this->getInstallRoot() . '/../../');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取安装目录
|
||||
* @author luzg(2020/8/26 16:15)
|
||||
* @return string
|
||||
*/
|
||||
public function getInstallRoot()
|
||||
{
|
||||
return INSTALL_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 目录的容量
|
||||
* @author luzg(2020/8/25 15:21)
|
||||
* @param $dir
|
||||
* @return string
|
||||
*/
|
||||
public function freeDiskSpace($dir)
|
||||
{
|
||||
// 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';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取状态标志
|
||||
* @author luzg(2020/8/25 16:10)
|
||||
* @param $statusSingle
|
||||
* @return string
|
||||
*/
|
||||
public function correctOrFail($statusSingle)
|
||||
{
|
||||
if ($statusSingle == 'ok')
|
||||
return '<td class="layui-icon green"></td>';
|
||||
$this->allowNext = false;
|
||||
return '<td class="layui-icon wrong">ဆ</td>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否允许下一步
|
||||
* @author luzg(2020/8/25 17:29)
|
||||
* @return bool
|
||||
*/
|
||||
public function getAllowNext()
|
||||
{
|
||||
return $this->allowNext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查session auto start
|
||||
* @author luzg(2020/8/25 16:55)
|
||||
* @return string
|
||||
*/
|
||||
public function checkSessionAutoStart()
|
||||
{
|
||||
return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查auto tags
|
||||
* @author luzg(2020/8/25 16:55)
|
||||
* @return string
|
||||
*/
|
||||
public function checkAutoTags()
|
||||
{
|
||||
return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查目录是否可写
|
||||
* @param $dir
|
||||
* @return string
|
||||
*/
|
||||
public function checkDirWrite($dir='')
|
||||
{
|
||||
$route = $this->getAppRoot().'/'.$dir;
|
||||
return $result = is_writable($route) ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 检查目录是否可写
|
||||
* @param $dir
|
||||
* @return string
|
||||
*/
|
||||
public function checkSuperiorDirWrite($dir='')
|
||||
{
|
||||
$route = $this->getAppRoot().'/'.$dir;
|
||||
return $result = is_writable($route) ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 初始化管理账号
|
||||
* @param $post
|
||||
* @return string
|
||||
*/
|
||||
public function initAccount($post)
|
||||
{
|
||||
$time = time();
|
||||
$salt = substr(md5($time . $post['admin_user']), 0, 4);//随机4位密码盐
|
||||
|
||||
global $uniqueSalt;
|
||||
$uniqueSalt = $salt;
|
||||
|
||||
$password = $this->createPassword($post['admin_password'], $salt);
|
||||
|
||||
// 超级管理员
|
||||
$sql = "INSERT INTO `la_admin`(`id`, `root`, `name`, `avatar`, `account`, `password`, `login_time`, `login_ip`, `multipoint_login`, `disable`, `create_time`, `update_time`, `delete_time`) VALUES (1, 1, '{$post['admin_user']}', '', '{$post['admin_user']}', '{$password}','{$time}', '', 1, 0, '{$time}', '{$time}', NULL);";
|
||||
// 超级管理员关联部门
|
||||
$sql .= "INSERT INTO `la_admin_dept` (`admin_id`, `dept_id`) VALUES (1, 1);";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 生成密码密文
|
||||
* @param $pwd
|
||||
* @param $salt
|
||||
* @return string
|
||||
*/
|
||||
public function createPassword($pwd, $salt)
|
||||
{
|
||||
return md5($salt . md5($pwd . $salt));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @notes 恢复admin,mobile index文件
|
||||
* @author 段誉
|
||||
* @date 2021/9/16 15:51
|
||||
*/
|
||||
public function restoreIndexLock()
|
||||
{
|
||||
$this->checkIndexFile($this->getAppRoot().'/public/mobile');
|
||||
$this->checkIndexFile($this->getAppRoot().'/public/admin');
|
||||
}
|
||||
|
||||
public function checkIndexFile($path)
|
||||
{
|
||||
if(file_exists($path.'/index_lock.html')) {
|
||||
// 删除提示文件
|
||||
unlink($path.'/index.html');
|
||||
// 恢复原入口
|
||||
rename($path.'/index_lock.html', $path.'/index.html');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,524 +0,0 @@
|
|||
<?php !defined('install') && exit(); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>likeadmin安装</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./css/mounted.css"/>
|
||||
<link rel="shortcut icon" href="./favicon.ico"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="logo" style="width: 220px;">
|
||||
<img src="./images/slogn.png?v=1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mounted" id="mounted">
|
||||
<div class="mounted-box">
|
||||
<form method="post" action="#" name="main_form">
|
||||
<!-- <div class="mounted-title">安装步骤</div>-->
|
||||
<div class="mounted-container" id="tab">
|
||||
<ul class="mounted-nav" id="nav">
|
||||
<li <?php if ($step == "1") { ?>class="active"<?php } ?>>许可协议</li>
|
||||
<li <?php if ($step == "2") { ?>class="active"<?php } ?>>环境监测</li>
|
||||
<li <?php if ($step == "3") { ?>class="active"<?php } ?>>参数配置</li>
|
||||
<li <?php if ($step == "4" or $step == '5') { ?>class="active"<?php } ?>>安装</li>
|
||||
</ul>
|
||||
|
||||
<!-- 阅读许可 -->
|
||||
<?php if ($step == '1') { ?>
|
||||
<div class="mounted-content-item show">
|
||||
<div class="content-header">
|
||||
阅读许可协议
|
||||
</div>
|
||||
<div class="content">
|
||||
<h2>likeadmin应用授权协议</h2>
|
||||
<div class="white-space;pre">
|
||||
|
||||
</div>
|
||||
|
||||
<p class="mt16">
|
||||
likeadmin在此特别提醒您(用户)在订阅使用likeadmin软件系统(以下简称“应用”)之前,请认真阅读本《likeadmin应用授权协议》(以下简称“协议”),确保您充分理解本协议中各条款。请您审慎阅读并选择接受或不接受本协议。除非您接受本协议所有条款,否则您无权注册、登录、购买或使用本协议所涉服务。您的注册、登录、购买、使用等行为将视为对本协议的接受,并同意接受本协议各项条款的约束。
|
||||
</p>
|
||||
<p class="mt16">
|
||||
本协议约定likeadmin官网与用户之间的权利义务。“用户”是指注册、登录、订阅或使用likeadmin应用的个人或企业。本协议可由likeadmin官网随时更新,更新后的协议条款一旦公布即代替原来的协议条款,不再另行通知,用户可在本网站查阅最新版协议条款。在likeadmin官网修改协议条款后,如果用户不接受修改后的条款,请立即停止使用likeadmin官网提供的服务,用户继续使用likeadmin官网提供的服务将被视为接受修改后的协议。
|
||||
</p>
|
||||
<h3 class="mt16">一、订阅应用</h3>
|
||||
<p class="mt16">
|
||||
1、用户可以在likeadmin官网在线订阅likeadmin付费应用,购买时需提前注册好likeadmin官网账号。 <br>
|
||||
2、用户以likeadmin官网允许的支付方式订阅likeadmin付费应用时,用户应当是具备完全民事权利能力和完全民事行为能力的自然人、法人或其他组织。若用户不具备前述主体资格,则用户及用户的监护人应承担因此而导致的一切后果,同时likeadmin官网将保留追究用户及其监护人民事、刑事责任等权利,且likeadmin官网有权注销(永久冻结)用户的likeadmin官网帐号,并有权向用户及用户的监护人索赔。 <br>
|
||||
3、用户应当在订阅使用likeadmin付费应用之前认真阅读全部协议内容。用户确认likeadmin官网对协议中所含免除或限制其责任的条款已尽提示、说明义务,用户同意此等条款,用户如对协议内容有任何异议的,应向likeadmin官网咨询。但无论用户事实上是否在订阅或使用likeadmin付费应用之前认真阅读了本协议内容,只要用户订阅或使用likeadmin付费应用,即与likeadmin官网缔结了本协议,本协议即对用户产生约束,届时用户不应以未阅读本协议的内容或者未获得likeadmin官网对用户问询的解答等理由,主张本协议无效或要求撤销本协议。 <br>
|
||||
4、用户承诺接受并遵守本协议的约定。如果用户不同意本协议的约定,应立即停止购买使用likeadmin付费应用。 <br>
|
||||
5、likeadmin官网有权根据需要不时地制订、修改本协议或各类规则,并以公示的方式进行公告,不再单独通知用户。变更后的协议和规则一经公布后,立即自动生效。如用户不同意相关变更,应当立即停止使用likeadmin付费应用。用户继续订阅或使用likeadmin付费应用,即表示用户接受经修订的协议。 <br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">二、应用下载</h3>
|
||||
<p class="mt16">
|
||||
1、用户可以在likeadmin官网在线下载likeadmin应用。 <br>
|
||||
2、likeadmin付费应用需要在注册登录且订阅后才可以下载安装使用。 <br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">三、应用使用</h3>
|
||||
<p class="mt16">
|
||||
1、likeadmin应用禁止在各类平台以任何形式(包括二次修改后)进行二次分发(出售)。<br>
|
||||
2、基于likeadmin应用从事的一切商业行业和本站无关。<br>
|
||||
3、likeadmin应用禁止分享、复制、转售和传播。<br>
|
||||
4、likeadmin应用只支持中国大陆及港澳台地区安装使用。<br>
|
||||
5、likeadmin付费应用务必正确录入授权主体信息后再进行使用。<br>
|
||||
6、用户不得利用likeadmin应用制作、上载、复制、发布、传播如下法律、法规和政策禁止的内容:<br>
|
||||
(1) 反对宪法所确定的基本原则的;<br>
|
||||
(2) 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;<br>
|
||||
(3) 损害国家荣誉和利益的;<br>
|
||||
(4) 煽动民族仇恨、民族歧视,破坏民族团结的;<br>
|
||||
(5) 破坏国家宗教政策,宣扬邪教和封建迷信的;<br>
|
||||
(6) 散布谣言,扰乱社会秩序,破坏社会稳定的;<br>
|
||||
(7) 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;<br>
|
||||
(8) 侮辱或者诽谤他人,侵害他人合法权益的;<br>
|
||||
(9) 不遵守法律法规底线、社会主义制度底线、国家利益底线、公民合法权益底线、社会公共秩序底线、道德风尚底线和信息真实性底线的“七条底线”要求的;<br>
|
||||
(10) 含有法律、行政法规禁止的其他内容的信息。<br>
|
||||
|
||||
如果用户违反相关上述相关使用条例,likeadmin官网有权利收回用户订阅的付费应用和用户在likeadmin官网注册的账号,如果有违反法律、法规和政策禁用的内容进行使用的,likeadmin官网有权向公安机关举报并配合公安机关提供用户相关隐私个人信息。
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">四、应用更新</h3>
|
||||
<p class="mt16">
|
||||
1、在更新likeadmin应用到最新版本时,请做好当前应用版本的整站备份,likeadmin不对应用更新升级造成的损失承担任何责任。<br>
|
||||
2、如因likeadmin应用下架造成的应用无法更新,likeadmin不承担任何责任。<br>
|
||||
3、如因likeadmin应用开发商放弃更新应用造成的无法更新,likeadmin不承担任何责任。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">五、应用价格</h3>
|
||||
<p class="mt16">
|
||||
1、应用金额以最终结算价格为准,已售出的付费应用不做任何差价补偿。<br>
|
||||
2、如果利用系统漏洞或用户使用特殊手段以低价或免费的形式购买的应用,likeadmin有权收回售出的应用。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">六、应用授权</h3>
|
||||
<p class="mt16">
|
||||
1、likeadmin付费应用可用于个人或企业自营网站应用,可用于外包开发,禁止二次转售应用源码。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">七、退款和转让</h3>
|
||||
<p class="mt16">
|
||||
1、likeadmin付费应用因提供全部源码,且源码可以拷贝,购买后不提供任何原因退款,请在购买前慎重考虑和仔细阅读此协议。<br>
|
||||
2、likeadmin付费应用如果价格发生变动,此前购买的应用不提供任何的补偿或退款。<br>
|
||||
3、likeadmin付费应用禁止以任何形式进行转让和出售。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">八、知识产权声明</h3>
|
||||
<p class="mt16">
|
||||
1、likeadmin应用源代码所有权和著作权归应用开发商所有。<br>
|
||||
2、除另有特别声明外,likeadmin应用所依托的代码、文字、图片等著作权、专利权及其他知识产权均归其开发商所有。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">九、法律责任</h3>
|
||||
<p class="mt16">
|
||||
1、如果likeadmin官网发现或收到他人举报或投诉用户违反本协议约定的,likeadmin官网有权不经通知随时对相关内容,包括但不限于用户资料、聊天记录进行审查、删除,并视情节轻重对违规帐号处以包括但不限于警告、帐号封禁、设备封禁、功能封禁的处罚。<br>
|
||||
2、用户理解并同意,likeadmin官网有权依合理判断对违反有关法律法规或本协议规定的行为进行处罚,对违法违规的任何用户采取适当的法律行动,并依据法律法规保存有关信息向有关部门报告等,用户应承担由此而产生的一切法律责任。<br>
|
||||
3、用户理解并同意,因用户违反本协议约定,导致或产生的任何第三方主张的任何索赔、要求或损失,包括合理的律师费,用户应当赔偿likeadmin官网与合作公司、关联公司,并使之免受损害。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">十、不可抗力及其他免责事由</h3>
|
||||
<p class="mt16">
|
||||
1、用户理解并确认,在使用本服务的过程中,可能会遇到不可抗力等风险因素,使本服务发生中断。不可抗力是指不能预见、不能克服并不能避免且对一方或双方造成重大影响的客观事件,包括但不限于自然灾害如洪水、地震、瘟疫流行和风暴等以及社会事件如战争、动乱、政府行为等。出现上述情况时,likeadmin官网将努力在第一时间与相关单位配合,及时进行修复,但是由此给用户或第三方造成的损失,likeadmin官网及合作单位在法律允许的范围内免责。<br>
|
||||
2、本服务同大多数互联网服务一样,受包括但不限于用户原因、网络服务质量、社会环境等因素的差异影响,可能受到各种安全问题的侵扰,如他人利用用户的资料,造成现实生活中的骚扰;用户下载安装的其它软件或访问的其他网站中含有“特洛伊木马”等病毒,威胁到用户的计算机信息和数据的安全,继而影响本服务的正常使用等等。用户应加强信息安全及使用者资料的保护意识,要注意加强帐号保护,以免遭致损失和骚扰。<br>
|
||||
3、用户理解并确认,本服务存在因不可抗力、计算机病毒或黑客攻击、系统不稳定、用户所在位置、用户关机以及其他任何技术、互联网络、通信线路原因等造成的服务中断或不能满足用户要求的风险,因此导致的用户或第三方任何损失,likeadmin官网不承担任何责任。<br>
|
||||
4、用户理解并确认,在使用本服务过程中存在来自任何他人的包括误导性的、欺骗性的、威胁性的、诽谤性的、令人反感的或非法的信息,或侵犯他人权利的匿名或冒名的信息,以及伴随该等信息的行为,因此导致的用户或第三方的任何损失,likeadmin官网不承担任何责任。<br>
|
||||
5、用户理解并确认,likeadmin官网需要定期或不定期地对likeadmin官网平台或相关的设备进行检修或者维护,如因此类情况而造成服务在合理时间内的中断,likeadmin官网无需为此承担任何责任。<br>
|
||||
6、likeadmin官网依据法律法规、本协议约定获得处理违法违规或违约内容的权利,该权利不构成likeadmin官网的义务或承诺,likeadmin官网不能保证及时发现违法违规或违约行为或进行相应处理。<br>
|
||||
7、用户理解并确认,对于likeadmin官网向用户提供的下列产品或者服务的质量缺陷及其引发的任何损失,likeadmin官网无需承担任何责任:<br>
|
||||
(1) likeadmin官网向用户免费提供的服务;<br>
|
||||
(2) likeadmin官网向用户赠送的任何产品或者服务。<br>
|
||||
8、在任何情况下,likeadmin官网均不对任何间接性、后果性、惩罚性、偶然性、特殊性或刑罚性的损害,包括因用户使用likeadmin官网或本服务而遭受的利润损失,承担责任(即使likeadmin官网已被告知该等损失的可能性亦然)。尽管本协议中可能含有相悖的规定,likeadmin官网对用户承担的全部责任,无论因何原因或何种行为方式,始终不超过用户因使用likeadmin官网提供的服务而支付给likeadmin官网的费用(如有)。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">十一、服务的变更、中断、终止</h3>
|
||||
<p class="mt16">
|
||||
1、鉴于网络服务的特殊性,用户同意likeadmin官网有权随时变更、中断或终止部分或全部的服务(包括收费服务)。likeadmin官网变更、中断或终止的服务,likeadmin官网应当在变更、中断或终止之前通知用户。<br>
|
||||
2、如发生下列任何一种情形,likeadmin官网有权变更、中断或终止向用户提供的免费服务或收费服务,而无需对用户或任何第三方承担任何责任:<br>
|
||||
(1) 根据法律规定用户应提交真实信息,而用户提供的个人资料不真实、或与注册时信息不一致又未能提供合理证明;<br>
|
||||
(2) 用户违反相关法律法规或本协议的约定;<br>
|
||||
(3) 按照法律规定或有权机关的要求;<br>
|
||||
(4) 出于安全的原因或其他必要的情形。<br>
|
||||
</p>
|
||||
|
||||
<h3 class="mt16">十二、其他</h3>
|
||||
<p class="mt16">
|
||||
1、likeadmin官网郑重提醒用户注意本协议中免除likeadmin官网责任和限制用户权利的条款,请用户仔细阅读,自主考虑风险。未成年人应在法定监护人的陪同下阅读本协议。<br>
|
||||
2、本协议的效力、解释及纠纷的解决,适用于中华人民共和国法律。若用户和likeadmin官网之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户同意将纠纷或争议提交likeadmin官网住所地有管辖权的人民法院管辖。<br>
|
||||
3、本协议的任何条款无论因何种原因无效或不具可执行性,其余条款仍有效,对双方具有约束力。<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- 检查信息 -->
|
||||
<?php if ($step == '2') { ?>
|
||||
<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 echo PHP_OS ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>web服务器环境</td>
|
||||
<td><?php echo $_SERVER['SERVER_SOFTWARE']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PHP版本</td>
|
||||
<td><?php echo @phpversion(); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>程序安装目录</td>
|
||||
<td><?php echo realpath(__DIR__ . '../../../'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>磁盘空间</td>
|
||||
<td><?php echo $modelInstall->freeDiskSpace(realpath(__DIR__ . '../../../')) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>上传限制</td>
|
||||
<?php if (ini_get('file_uploads')): ?>
|
||||
<td><?php echo ini_get('upload_max_filesize'); ?></td>
|
||||
<?php else: ?>
|
||||
<td>禁止上传</td>
|
||||
<?php endif; ?>
|
||||
</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="120">
|
||||
<col width="400">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>选项</th>
|
||||
<th>要求</th>
|
||||
<th>状态</th>
|
||||
<th>说明及帮助</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PHP版本</td>
|
||||
<td>大于8.0</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkPHP()) ?>
|
||||
<td>建议使用PHP8.0.8版本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PDO_MYSQL</td>
|
||||
<td>支持 (强烈建议支持)</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkPDOMySQL()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>allow_url_fopen</td>
|
||||
<td>支持 (建议支持cURL)</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkCurl()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GD2</td>
|
||||
<td>支持</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkGd2()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DOM</td>
|
||||
<td>支持</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDom()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>fileinfo</td>
|
||||
<td>支持</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkFileInfo()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>session.auto_start</td>
|
||||
<td>关闭</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkSessionAutoStart()) ?>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mounted-tips mt16">
|
||||
系统要求likeadmin安装目录下的runtime和upload必须可写,才能使用likeadmin的所有功能。
|
||||
</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="120">
|
||||
<col width="400">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>目录</th>
|
||||
<th>要求</th>
|
||||
<th>状态</th>
|
||||
<th>说明及帮助</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>/runtime</td>
|
||||
<td>runtime目录可写</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDirWrite('runtime')) ?>
|
||||
<td><?php if($modelInstall->checkDirWrite('runtime') =='fail') echo'请给runtime目录权限,若目录不存在先新建';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>/public/uploads</td>
|
||||
<td>uploads目录可写</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDirWrite('public/uploads')) ?>
|
||||
<td><?php if($modelInstall->checkDirWrite('public/uploads')=='fail') echo'请给public/uploads目录权限,若目录不存在先新建';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>/public/admin</td>
|
||||
<td>admin目录可写</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDirWrite('public/admin')) ?>
|
||||
<td><?php if($modelInstall->checkDirWrite('public/uploads')=='fail') echo'请给public/admin目录权限,若目录不存在先新建';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>../config</td>
|
||||
<td>config目录可写</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDirWrite('config')) ?>
|
||||
<td><?php if($modelInstall->checkDirWrite('config')=='fail') echo'请给config目录权限,若目录不存在先新建';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>../.env</td>
|
||||
<td>.env文件可写</td>
|
||||
<?php echo $modelInstall->correctOrFail($modelInstall->checkDirWrite('.env')) ?>
|
||||
<td><?php if($modelInstall->checkDirWrite('.env')=='fail') echo'请给.env文件权限,若文件不存在,注意文件名第1字符是" . "';?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- 数据库设置 -->
|
||||
<?php if ($step == '3') { ?>
|
||||
<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 class="form-box-item">
|
||||
<div class="form-desc">
|
||||
数据表前缀
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="prefix" value="<?= $post['prefix'] ?>"/>
|
||||
</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_confirm_password"
|
||||
value="<?= $post['admin_confirm_password'] ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-box-check">
|
||||
<div class="form-desc"></div>
|
||||
<div style="display: flex;align-items: center;">
|
||||
<input type="checkbox" name="import_test_data"
|
||||
<?php if ($post['import_test_data'] == 'on'): ?>checked<?php endif; ?>
|
||||
title="导入测试数据"/>
|
||||
<div style="color: #666666;"> 导入测试数据</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<!-- 安装中 -->
|
||||
<?php if ($step == '4' or $step == '5') { ?>
|
||||
<div class="mounted-content-item show">
|
||||
<?php if ($step == '4') { ?>
|
||||
<div id="mounting">
|
||||
<div class="content-header">
|
||||
正在安装中
|
||||
</div>
|
||||
<div class="mounting-container " id="install_message">
|
||||
<?php if (count($successTables) > 0): ?>
|
||||
<p style="margin-bottom: 4px;">成功创建数据库:<?= $post['name'] ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($step == '5') { ?>
|
||||
<div class="show" id="mounting-success">
|
||||
<div class="content-header">
|
||||
安装成功
|
||||
</div>
|
||||
<div class="success-content">
|
||||
<div style="width: 48px;height: 48px;">
|
||||
<img src="./images/icon_mountSuccess.png"/>
|
||||
</div>
|
||||
<div class="mt16 result">安装完成,进入管理后台</div>
|
||||
<div style="margin-top: 5px;font-size:14px;">版本号:1.6.0</div>
|
||||
<div class="tips">
|
||||
为了您站点的安全,安装完成后即可将网站根目录下的“install”文件夹删除,或者config/install.lock/目录下创建install.lock文件防止重复安装。
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn" href="/admin" style="margin-left: 20px;">进入管理平台</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php if ($step == '1') { ?>
|
||||
<div class="item-btn-group show">
|
||||
<button class="accept-btn" onclick="goStep(<?php echo $nextStep ?>)">我已阅读并同意</button>
|
||||
</div>
|
||||
<?php } elseif (in_array($step, ['2', "3"])) { ?>
|
||||
<div class="item-btn-group show">
|
||||
<button class="cancel-btn" onclick="cancel()" style="padding: 7px 63px;margin-right: 16px">返回
|
||||
</button>
|
||||
<?php if ($modelInstall->getAllowNext()): ?>
|
||||
<button class="accept-btn" onclick="goStep(<?php echo $nextStep ?>)" style="padding: 7px 63px;">
|
||||
继续
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button class="accept-btn" onclick="goStep(<?php echo $step ?>)" style="padding: 7px 63px;">重新检查
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php } elseif ($step == "4") { ?>
|
||||
<div class="item-btn-group show">
|
||||
<button class="disabled-btn" disabled="disabled">
|
||||
<div class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></div>
|
||||
<div style="font-size: 14px;margin-left: 7px;">正在安装中...</div>
|
||||
</button>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
Copyright © 2019-<?=date('Y')?> 广州好象科技有限公司 粤ICP备16101670号-2
|
||||
</footer>
|
||||
<script src="https://www.layuicdn.com/layui/layui.js"></script>
|
||||
<?php if (count($successTables) > 0): ?>
|
||||
<script>var successTables = eval(<?=json_encode($successTables) ?>); </script>
|
||||
<?php endif; ?>
|
||||
<script src="./js/mounted.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<?php if ($message != ''): ?>
|
||||
<script>alert('<?=$message; ?>');</script>
|
||||
<?php endif; ?>
|