mirror of
https://github.com/flucont/btcloud.git
synced 2025-10-14 14:20:22 +00:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ba7e07f18a | ||
![]() |
25292b8e34 | ||
![]() |
d80c0e9e44 | ||
![]() |
247e486181 | ||
![]() |
d856d3bc1c | ||
![]() |
e304e9acc2 | ||
![]() |
aba885f434 | ||
![]() |
5e1f19de53 | ||
![]() |
57cbf9315c | ||
![]() |
4608d4899b | ||
![]() |
272f3bfe97 | ||
![]() |
9d2d883668 | ||
![]() |
3d1f1b721a | ||
![]() |
fa9188b94d | ||
![]() |
2ddb4ff64c | ||
![]() |
963b675026 | ||
![]() |
5642ea3038 | ||
![]() |
2aff0d9e6d | ||
![]() |
0ca1c9d0e3 | ||
![]() |
c1681a9731 | ||
![]() |
911a567fde | ||
![]() |
b27349a416 |
@@ -68,37 +68,10 @@ class Clean extends Command
|
||||
if($file == '.' || $file == '..') continue;
|
||||
if(!in_array($file, $file_list)){
|
||||
$filepath = $data_dir . 'folder/' . $file;
|
||||
$this->delete_dir($filepath);
|
||||
deleteDir($filepath);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$output->writeln($os.'成功清理'.$count.'个历史版本插件目录');
|
||||
}
|
||||
|
||||
// 删除文件夹
|
||||
private function delete_dir($dir){
|
||||
$rd = opendir($dir);
|
||||
if (!$rd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (($file = readdir($rd)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = $dir . '/' . $file;
|
||||
|
||||
if (is_dir($file)) {
|
||||
$this->delete_dir($file);
|
||||
}
|
||||
else {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($rd);
|
||||
rmdir($dir);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
244
app/command/CleanViteJs.php
Normal file
244
app/command/CleanViteJs.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use app\lib\Plugins;
|
||||
|
||||
class CleanViteJs extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cleanvitejs')
|
||||
->addArgument('dir', Argument::REQUIRED, '/BTPanel/static/vite/js/路径')
|
||||
->setDescription('处理宝塔面板vite/js文件');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$dir = trim($input->getArgument('dir'));
|
||||
if(!file_exists($dir)){
|
||||
$output->writeln('目录不存在');
|
||||
return;
|
||||
}
|
||||
//$this->handlefile($dir.'/DockerImages.js');
|
||||
$this->checkdir($dir);
|
||||
}
|
||||
|
||||
private function getExtendCode($content, $part, $n = 1, $startChar = '{', $endChar = '}'){
|
||||
if(!$part) return false;
|
||||
$length = strlen($content);
|
||||
$start = strpos($content, $part);
|
||||
if($start===false)return false;
|
||||
$end = $start+strlen($part);
|
||||
$start--;
|
||||
$c = 0;
|
||||
for($i=$start;$i>=0;$i--){
|
||||
if(substr($content,$i,1) == $startChar) $c++;
|
||||
if(substr($content,$i,1) == $endChar) $c--;
|
||||
if($c == $n){
|
||||
$start = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$c = 0;
|
||||
for($i=$end;$i<=$length;$i++){
|
||||
if(substr($content,$i,1) == $endChar) $c++;
|
||||
if(substr($content,$i,1) == $startChar) $c--;
|
||||
if($c == $n){
|
||||
$end = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return substr($content, $start, $end - $start + 1);
|
||||
}
|
||||
|
||||
private function getExtendFunction($content, $part, $startChar = '(', $endChar = ')'){
|
||||
$code = $this->getExtendCode($content, $part, 1, $startChar, $endChar);
|
||||
if(!$code) return false;
|
||||
$start = strpos($content, $code) - 1;
|
||||
$end = $start + strlen($code);
|
||||
for($i=$start;$i>=0;$i--){
|
||||
$char = substr($content,$i,1);
|
||||
if(!ctype_alpha($char)){
|
||||
$start = $i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(substr($content,$start-1,1) == ',') $start--;
|
||||
else if(substr($content,$end+1,1) == ',') $end++;
|
||||
return substr($content, $start, $end - $start + 1);
|
||||
}
|
||||
|
||||
private function checkdir($basedir){
|
||||
if($dh=opendir($basedir)){
|
||||
while (($file=readdir($dh)) !== false){
|
||||
if($file != '.' && $file != '..'){
|
||||
if(!is_dir($basedir.'/'.$file) && substr($file,-3)=='.js'){
|
||||
$this->handlefile($basedir.'/'.$file);
|
||||
}else if(!is_dir($basedir.'/'.$file) && substr($file,-4)=='.map'){
|
||||
unlink($basedir.'/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
}
|
||||
|
||||
private function str_replace_once($needle, $replace, $haystack) {
|
||||
$pos = strpos($haystack, $needle);
|
||||
if ($pos === false) {
|
||||
return $haystack;
|
||||
}
|
||||
return substr_replace($haystack, $replace, $pos, strlen($needle));
|
||||
}
|
||||
|
||||
private function handlefile($filepath){
|
||||
$file = file_get_contents($filepath);
|
||||
if(!$file)return;
|
||||
|
||||
$flag = false;
|
||||
|
||||
if(strpos($file, 'window.location.protocol.indexOf("https")>=0')!==false){ //index
|
||||
$file = str_replace('(window.location.protocol.indexOf("https")>=0)', '1', $file);
|
||||
$file = preg_replace('!setTimeout\(\(\(\)=>\{\w+\(\)\}\),3e3\)!', '', $file);
|
||||
$file = preg_replace('!setTimeout\(\(function\(\)\{\w+\(\)\}\),3e3\)!', '', $file);
|
||||
$file = preg_replace('!recommendShow:\w+,!', 'recommendShow:!1,', $file);
|
||||
$code = $this->getExtendCode($file, '"需求反馈"', 2);
|
||||
if($code){
|
||||
$file = str_replace($code, '{}', $file);
|
||||
}
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '"WechatOfficial"')!==false){ //main
|
||||
$code = $this->getExtendCode($file, '"WechatOfficial"', 5);
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$start = strpos($file, $code) - 1;
|
||||
for($i=$start;$i>=0;$i--){
|
||||
if(substr($file,$i,1) == ','){
|
||||
$start = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$code = $this->getExtendCode($file, '"/other/customer-service.png"', 2);
|
||||
$code = $this->getExtendCode($file, $code, 2, '[', ']');
|
||||
$end = strpos($file, $code)+strlen($code);
|
||||
$code = substr($file, $start, $end - $start + 1);
|
||||
$file = str_replace($code, '', $file);
|
||||
$file = str_replace('startNegotiate(),', '', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '"calc"') !== false && strpos($file, '"checkConfirm"') !== false){ //main2
|
||||
$file = preg_replace('!,isCalc:\w+,isInput:\w+,!', ',isCalc:!1,isInput:!1,', $file);
|
||||
$file = preg_replace('!"calc"===\w+\.type!', '!1', $file);
|
||||
$file = preg_replace('!\w+\(\(\(\)=>"input"===\w+\.type\)\)!', '!1', $file);
|
||||
$file = preg_replace('!\w+\(\(function\(\)\{return"input"===\w+\.type\}\)\)!', '!1', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '请冷静几秒钟,确认以下要删除的数据')!==false && strpos($file, '"计算结果:"')!==false){ //site
|
||||
$code = $this->getExtendCode($file, '"计算结果:"', 2, '[', ']');
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$file = str_replace($code, '', $file);
|
||||
$file = preg_replace('!\w+\.sum===\w+\.addend1\+\w+\.addend2!', '!0', $file);
|
||||
$file = preg_replace('!\w+\.sum\!==\w+\.addend1\+\w+\.addend2!', '!1', $file);
|
||||
$file = preg_replace('!,disableDeleteButton:\w+,countdown:\w+,!', ',disableDeleteButton:!1,countdown:!1,', $file);
|
||||
if(preg_match('/startCountdown:(\w+),/', $file, $matchs)){
|
||||
$file = str_replace([';'.$matchs[1].'()', $matchs[1].'(),'], '', $file);
|
||||
}
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, 'svgtofont-left-waf')!==false){ //site.table
|
||||
$code = $this->getExtendCode($file, 'svgtofont-left-waf');
|
||||
$code = $this->getExtendCode($file, $code, 1, '[', ']');
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$file = str_replace($code, '""', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '"商用SSL证书"')!==false){ //site-ssl
|
||||
$code = $this->getExtendFunction($file, '"商用SSL证书"', '{', '}');
|
||||
$file = str_replace($code, '', $file);
|
||||
$code = $this->getExtendFunction($file, '"测试证书"', '{', '}');
|
||||
$file = str_replace($code, '', $file);
|
||||
$file = str_replace('"currentCertInfo":"busSslList"', '"currentCertInfo":"currentCertInfo"', $file);
|
||||
$file = preg_replace('!\{(\w+)\.value="busSslList",\w+\(\)\}!', '{$1.value="letsEncryptList"}', $file);
|
||||
$file = preg_replace('!defaultActive:(\w+)\("sslCertificate"\)!', 'defaultActive:$1("EncryptCertificate")', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '如果您希望添加其它Docker应用')!==false){
|
||||
$code = $this->getExtendCode($file, '如果您希望添加其它Docker应用', 1, '[', ']');
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$file = str_replace($code, '', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '"recom-view"')!==false){ //soft
|
||||
$code = $this->getExtendFunction($file, '"recom-view"');
|
||||
$file = str_replace($code, 'void(0)', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '"打开插件文件目录"')!==false){ //soft.table
|
||||
$code = $this->getExtendFunction($file, '"(续费)"');
|
||||
$file = str_replace($code, '""', $file);
|
||||
$code = $this->getExtendFunction($file, '"(续费)"');
|
||||
$file = str_replace($code, '""', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(strpos($file, '检测到同名文件')!==false){ //file.
|
||||
$code = $this->getExtendCode($file, '计算结果:', 3, '[', ']');
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$file = str_replace($code, '', $file);
|
||||
$file = preg_replace('!\w+\.sum===\w+\.addend1\+\w+\.addend2!', '!0', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
for($i=0;$i<5;$i++){
|
||||
$code = $this->getExtendCode($file, 'content:"需求反馈"', 2);
|
||||
if($code){
|
||||
$code = $this->getExtendFunction($file, $code);
|
||||
$start = strpos($file, $code);
|
||||
if(substr($file,$start-1,1) == ':'){
|
||||
$file = $this->str_replace_once($code, '{}', $file);
|
||||
}else{
|
||||
$file = $this->str_replace_once($code, '', $file);
|
||||
}
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$code = $this->getExtendFunction($file, '("需求反馈")');
|
||||
if($code){
|
||||
$file = str_replace($code, '', $file);
|
||||
$flag = true;
|
||||
}
|
||||
$code = $this->getExtendFunction($file, '(" 需求反馈 ")');
|
||||
if($code){
|
||||
$file = str_replace($code, '', $file);
|
||||
$flag = true;
|
||||
}
|
||||
if(strpos('暂无搜索结果,<span class="text-primary cursor-pointer NpsDialog">提交需求反馈</span>', $file)!==false){
|
||||
$file = str_replace('暂无搜索结果,<span class="text-primary cursor-pointer NpsDialog">提交需求反馈</span>', '暂无搜索结果', $file);
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(!$flag) return;
|
||||
if(file_put_contents($filepath, $file)){
|
||||
echo '文件:'.$filepath.' 处理成功'."\n";
|
||||
}else{
|
||||
echo '文件:'.$filepath.' 处理失败,可能无写入权限'."\n";
|
||||
}
|
||||
}
|
||||
}
|
@@ -180,6 +180,11 @@ function checkIfActive($string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function checkDomain($domain){
|
||||
if(empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0 ,1) == '.' || substr($domain, 0 ,1) == '*' && substr($domain, 1 ,1) != '.' || substr_count($domain, '*')>1 || strpos($domain, '*')>0 || strlen($domain)<4) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function errorlog($msg){
|
||||
$handle = fopen(app()->getRootPath()."record.txt", 'a');
|
||||
fwrite($handle, date('Y-m-d H:i:s')."\t".$msg."\r\n");
|
||||
@@ -224,4 +229,95 @@ function pemToBase64($pem){
|
||||
}
|
||||
}
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
function makeSelfSignSSL(string $commonName, array $domainList, $validity = 3650){
|
||||
// 加载 CA 证书和私钥
|
||||
$dir = app()->getBasePath().'script/';
|
||||
$caCert = file_get_contents($dir.'ca.crt');
|
||||
$caPrivateKey = file_get_contents($dir.'ca.key');
|
||||
|
||||
$opensslConfigFile = sys_get_temp_dir().'/openssl'.time().mt_rand(1000, 9999).'.cnf';
|
||||
$opensslConfigContent = <<<EOF
|
||||
[req]
|
||||
req_extensions = extension_section
|
||||
x509_extensions = extension_section
|
||||
distinguished_name = dn
|
||||
|
||||
[dn]
|
||||
|
||||
[extension_section]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
EOF;
|
||||
$ip_index = 1;
|
||||
$dns_index = 1;
|
||||
foreach ($domainList as $value) {
|
||||
if(empty($value)) continue;
|
||||
if(filter_var($value, FILTER_VALIDATE_IP)){
|
||||
$opensslConfigContent .= sprintf("\nIP.%d = %s", $ip_index, $value);
|
||||
$ip_index++;
|
||||
}else{
|
||||
$opensslConfigContent .= sprintf("\nDNS.%d = %s", $dns_index, $value);
|
||||
$dns_index++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!file_put_contents($opensslConfigFile, $opensslConfigContent)) return false;
|
||||
|
||||
// 生成域名证书的私钥和 CSR
|
||||
$domainPrivateKey = openssl_pkey_new([
|
||||
'private_key_bits' => 2048,
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
]);
|
||||
if(!$domainPrivateKey) return false;
|
||||
|
||||
$csrConfig = ['digest_alg' => 'sha256', 'config' => $opensslConfigFile];
|
||||
|
||||
$domainCsr = openssl_csr_new([
|
||||
'commonName' => $commonName
|
||||
], $domainPrivateKey, $csrConfig);
|
||||
if(!$domainCsr) return false;
|
||||
|
||||
// 生成域名证书
|
||||
$domainCertificate = openssl_csr_sign($domainCsr, $caCert, $caPrivateKey, $validity, $csrConfig);
|
||||
if(!$domainCertificate) return false;
|
||||
|
||||
// 导出域名证书
|
||||
openssl_x509_export($domainCertificate, $certificate);
|
||||
openssl_pkey_export($domainPrivateKey, $privateKey);
|
||||
$certificate .= $caCert;
|
||||
|
||||
unlink($opensslConfigFile);
|
||||
|
||||
return ['cert' => $certificate, 'key' => $privateKey];
|
||||
}
|
||||
|
||||
function deleteDir($dir){
|
||||
$rd = opendir($dir);
|
||||
if (!$rd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (($file = readdir($rd)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = $dir . '/' . $file;
|
||||
|
||||
if (is_dir($file)) {
|
||||
deleteDir($file);
|
||||
}
|
||||
else {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($rd);
|
||||
rmdir($dir);
|
||||
return true;
|
||||
}
|
@@ -400,4 +400,37 @@ class Admin extends BaseController
|
||||
Cache::clear();
|
||||
return json(['code'=>0,'msg'=>'succ']);
|
||||
}
|
||||
|
||||
public function ssl(){
|
||||
if(request()->isAjax()){
|
||||
$domain_list = input('post.domain_list', null, 'trim');
|
||||
$common_name = input('post.common_name', null, 'trim');
|
||||
$validity = input('post.validity/d');
|
||||
if(empty($domain_list) || empty($validity)){
|
||||
return json(['code'=>-1, 'msg'=>'参数不能为空']);
|
||||
}
|
||||
$array = explode("\n", $domain_list);
|
||||
$domain_list = [];
|
||||
foreach($array as $domain){
|
||||
$domain = trim($domain);
|
||||
if(empty($domain)) continue;
|
||||
if(!checkDomain($domain)) return json(['code'=>-1, 'msg'=>'域名或IP格式不正确:'.$domain]);
|
||||
$domain_list[] = $domain;
|
||||
}
|
||||
if(empty($domain_list)) return json(['code'=>-1, 'msg'=>'域名列表不能为空']);
|
||||
if(empty($common_name)) $common_name = $domain_list[0];
|
||||
$result = makeSelfSignSSL($common_name, $domain_list, $validity);
|
||||
if(!$result){
|
||||
return json(['code'=>-1, 'msg'=>'生成证书失败']);
|
||||
}
|
||||
return json(['code'=>0, 'msg'=>'生成证书成功', 'cert'=>$result['cert'], 'key'=>$result['key']]);
|
||||
}
|
||||
|
||||
$dir = app()->getBasePath().'script/';
|
||||
$ssl_path = app()->getRootPath().'public/ssl/baota_root.pfx';
|
||||
$ssl_path_mac = app()->getRootPath().'public/ssl/baota_root.crt';
|
||||
$isca = file_exists($dir.'ca.crt') && file_exists($dir.'ca.key') && file_exists($ssl_path) && file_exists($ssl_path_mac);
|
||||
View::assign('isca', $isca);
|
||||
return view();
|
||||
}
|
||||
}
|
@@ -48,7 +48,7 @@ class Api extends BaseController
|
||||
if(!preg_match('/^[a-zA-Z0-9_]+$/', $plugin_name) || !preg_match('/^[0-9.]+$/', $version)){
|
||||
return '参数不正确';
|
||||
}
|
||||
if(!$this->checklist()) '你的服务器被禁止使用此云端';
|
||||
if(!$this->checklist()) return '你的服务器被禁止使用此云端';
|
||||
$filepath = get_data_dir($os).'plugins/package/'.$plugin_name.'-'.$version.'.zip';
|
||||
if(file_exists($filepath)){
|
||||
$filename = $plugin_name.'.zip';
|
||||
@@ -70,19 +70,21 @@ class Api extends BaseController
|
||||
if(!preg_match('/^[a-zA-Z0-9_]+$/', $plugin_name) || !preg_match('/^[0-9.]+$/', $version)){
|
||||
return '参数不正确';
|
||||
}
|
||||
if(!$this->checklist()) '你的服务器被禁止使用此云端';
|
||||
$filepath = get_data_dir($os).'plugins/main/'.$plugin_name.'-'.$version.'.dat';
|
||||
if(file_exists($filepath)){
|
||||
if(!$this->checklist()) return '你的服务器被禁止使用此云端';
|
||||
$filepath = get_data_dir($os).'plugins/package/'.$plugin_name.'-'.$version.'.zip';
|
||||
$mainfilepath = get_data_dir($os).'plugins/folder/'.$plugin_name.'-'.$version.'/'.$plugin_name.'/'.$plugin_name.'_main.py';
|
||||
if(file_exists($mainfilepath)){
|
||||
$filename = $plugin_name.'_main.py';
|
||||
$this->output_file($filepath, $filename);
|
||||
}else{
|
||||
$filepath = get_data_dir($os).'plugins/folder/'.$plugin_name.'-'.$version.'/'.$plugin_name.'/'.$plugin_name.'_main.py';
|
||||
if(file_exists($filepath)){
|
||||
$filename = $plugin_name.'_main.py';
|
||||
$this->output_file($filepath, $filename);
|
||||
$this->output_file($mainfilepath, $filename);
|
||||
}elseif(file_exists($filepath)){
|
||||
$zip = new \ZipArchive;
|
||||
if ($zip->open($filepath) === true){
|
||||
echo $zip->getFromName($plugin_name.'/'.$plugin_name.'_main.py');
|
||||
}else{
|
||||
return '云端不存在该插件主文件';
|
||||
return '插件包解压缩失败';
|
||||
}
|
||||
}else{
|
||||
return '云端不存在该插件主文件';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +139,18 @@ class Api extends BaseController
|
||||
return $version;
|
||||
}
|
||||
|
||||
public function get_panel_version(){
|
||||
$version = config_get('new_version');
|
||||
$file = app()->getRootPath().'public/install/update/LinuxPanel-'.$version.'.zip';
|
||||
$hash = hash_file('sha256', $file);
|
||||
$data = [
|
||||
'version' => $version,
|
||||
'hash' => $hash,
|
||||
'update_time' => filemtime($file),
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
|
||||
//安装统计
|
||||
public function setup_count(){
|
||||
return 'ok';
|
||||
@@ -464,4 +478,36 @@ class Api extends BaseController
|
||||
fclose($handle);
|
||||
return json(['status'=>false, 'msg'=>'不支持当前操作']);
|
||||
}
|
||||
|
||||
//生成自签名SSL证书
|
||||
public function bt_cert(){
|
||||
$data = input('post.data');
|
||||
$param = json_decode($data, true);
|
||||
if(!$param || !isset($param['action']) || !isset($param['domain'])) return json(['status'=>false, 'msg'=>'参数错误']);
|
||||
|
||||
$dir = app()->getBasePath().'script/';
|
||||
$ssl_path = app()->getRootPath().'public/ssl/baota_root.pfx';
|
||||
$isca = file_exists($dir.'ca.crt') && file_exists($dir.'ca.key') && file_exists($ssl_path);
|
||||
if(!$isca) return json(['status'=>false, 'msg'=>'CA证书不存在']);
|
||||
|
||||
if($param['action'] == 'get_domain_cert'){
|
||||
if(!$this->checklist()) return json(['status'=>false, 'msg'=>'你的服务器被禁止使用此云端']);
|
||||
$domain = $param['domain'];
|
||||
if(empty($domain)) return json(['status'=>false, 'msg'=>'域名不能为空']);
|
||||
$domain_list = explode(',', $domain);
|
||||
foreach($domain_list as $d){
|
||||
if(!checkDomain($d)) return json(['status'=>false, 'msg'=>'域名或IP格式不正确:'.$d]);
|
||||
}
|
||||
$common_name = $domain_list[0];
|
||||
$validity = 3650;
|
||||
$result = makeSelfSignSSL($common_name, $domain_list, $validity);
|
||||
if(!$result){
|
||||
return json(['status'=>false, 'msg'=>'生成证书失败']);
|
||||
}
|
||||
$ca_pfx = base64_encode(file_get_contents($ssl_path));
|
||||
return json(['status'=>true, 'msg'=>'生成证书成功', 'cert'=>$result['cert'], 'key'=>$result['key'], 'pfx'=>$ca_pfx, 'password'=>'']);
|
||||
}else{
|
||||
return json(['status'=>false, 'msg'=>'不支持当前操作']);
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,13 +8,13 @@ class Index extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return 'Server is ok';
|
||||
return '';
|
||||
}
|
||||
|
||||
public function download()
|
||||
{
|
||||
if(config_get('download_page') == '0' && !request()->islogin){
|
||||
return redirect('/admin/login');
|
||||
return 'need login';
|
||||
}
|
||||
View::assign('siteurl', request()->root(true));
|
||||
return view();
|
||||
|
@@ -11,7 +11,7 @@ class BtPlugins
|
||||
private $os;
|
||||
|
||||
//需屏蔽的插件名称列表
|
||||
private static $block_plugins = ['dns'];
|
||||
private static $block_plugins = ['dns','bt_boce','ssl_verify'];
|
||||
|
||||
public function __construct($os){
|
||||
$this->os = $os;
|
||||
@@ -72,9 +72,10 @@ class BtPlugins
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($filepath) === true)
|
||||
{
|
||||
$zip->extractTo(get_data_dir($this->os).'plugins/folder/'.$plugin_name.'-'.$version);
|
||||
$plugins_dir = get_data_dir($this->os).'plugins/folder/'.$plugin_name.'-'.$version;
|
||||
$zip->extractTo($plugins_dir, $plugin_name.'/'.$plugin_name.'_main.py');
|
||||
$zip->close();
|
||||
$main_filepath = get_data_dir($this->os).'plugins/folder/'.$plugin_name.'-'.$version.'/'.$plugin_name.'/'.$plugin_name.'_main.py';
|
||||
$main_filepath = $plugins_dir.'/'.$plugin_name.'/'.$plugin_name.'_main.py';
|
||||
if(file_exists($main_filepath) && filesize($main_filepath)>10){
|
||||
if(!strpos(file_get_contents($main_filepath), 'import ')){ //加密py文件,需要解密
|
||||
$this->decode_plugin_main($plugin_name, $version, $main_filepath);
|
||||
@@ -84,6 +85,7 @@ class BtPlugins
|
||||
$zip->close();
|
||||
}
|
||||
}
|
||||
deleteDir($plugins_dir);
|
||||
}else{
|
||||
unlink($filepath);
|
||||
throw new Exception('插件包解压缩失败');
|
||||
@@ -197,6 +199,8 @@ class BtPlugins
|
||||
$data = str_replace('\'https://www.bt.cn/api/bt_waf/reportInterceptFail', 'public.GetConfigValue(\'home\')+\'/api/bt_waf/reportInterceptFail', $data);
|
||||
$data = str_replace('\'https://www.bt.cn/api/v2/contact/nps/questions', 'public.GetConfigValue(\'home\')+\'/panel/notpro', $data);
|
||||
$data = str_replace('\'https://www.bt.cn/api/v2/contact/nps/submit', 'public.GetConfigValue(\'home\')+\'/panel/notpro', $data);
|
||||
$data = str_replace('\'http://www.bt.cn/api/Auth', 'public.GetConfigValue(\'home\')+\'/api/Auth', $data);
|
||||
$data = str_replace('\'https://www.bt.cn/api/Auth', 'public.GetConfigValue(\'home\')+\'/api/Auth', $data);
|
||||
|
||||
file_put_contents($main_filepath, $data);
|
||||
}
|
||||
|
@@ -1,243 +1,243 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use Exception;
|
||||
|
||||
class Btapi
|
||||
{
|
||||
private $BT_KEY; //接口密钥
|
||||
private $BT_PANEL; //面板地址
|
||||
|
||||
public function __construct($bt_panel, $bt_key){
|
||||
$this->BT_PANEL = $bt_panel;
|
||||
$this->BT_KEY = $bt_key;
|
||||
}
|
||||
|
||||
//获取面板配置信息
|
||||
public function get_config(){
|
||||
$url = $this->BT_PANEL.'/config?action=get_config';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//获取已登录用户信息
|
||||
public function get_user_info(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_user_info';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//从云端获取插件列表
|
||||
public function get_plugin_list(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_plugin_list';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件包,返回文件路径
|
||||
public function get_plugin_filename($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件主程序文件,返回文件路径
|
||||
public function get_plugin_main_filename($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin_main';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//解密插件主程序py代码,返回文件路径
|
||||
public function get_decode_plugin_main($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=decode_plugin_main';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件其他文件,返回文件路径
|
||||
public function get_plugin_other_filename($fname){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin_other';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['fname'] = $fname;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载文件
|
||||
public function download($filename, $localpath){
|
||||
$url = $this->BT_PANEL.'/download';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['filename'] = $filename;
|
||||
|
||||
$result = $this->curl_download($url.'?'.http_build_query($p_data), $localpath);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//获取文件base64
|
||||
public function get_file($filename){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_file';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['filename'] = $filename;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//购买第三方插件
|
||||
public function create_plugin_other_order($pid){
|
||||
$url = $this->BT_PANEL.'/auth?action=create_plugin_other_order';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['pid'] = $pid;
|
||||
$p_data['cycle'] = '999';
|
||||
$p_data['type'] = '0';
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//获取一键部署列表
|
||||
public function get_deplist(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_deplist';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//BTWAF-获取蜘蛛列表
|
||||
public function btwaf_getspiders(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=btwaf_getspiders';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
$result = str_replace("\u0000", '', $result);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
private function GetKeyData(){
|
||||
$now_time = time();
|
||||
$p_data = array(
|
||||
'request_token' => md5($now_time.''.md5($this->BT_KEY)),
|
||||
'request_time' => $now_time
|
||||
);
|
||||
return $p_data;
|
||||
}
|
||||
|
||||
|
||||
private function curl($url, $data = null, $timeout = 60)
|
||||
{
|
||||
//定义cookie保存位置
|
||||
$cookie_file=app()->getRuntimePath().md5($this->BT_PANEL).'.cookie';
|
||||
if(!file_exists($cookie_file)){
|
||||
touch($cookie_file);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
if($data){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function curl_download($url, $localpath, $timeout = 300)
|
||||
{
|
||||
//定义cookie保存位置
|
||||
$cookie_file=app()->getRuntimePath().md5($this->BT_PANEL).'.cookie';
|
||||
if(!file_exists($cookie_file)){
|
||||
touch($cookie_file);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
|
||||
$fp = fopen($localpath, 'w+');
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$message = curl_error($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
throw new Exception('下载文件失败:'.$message);
|
||||
}
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if($httpcode>299){
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
throw new Exception('下载文件失败:HTTPCODE-'.$httpcode);
|
||||
}
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
return true;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use Exception;
|
||||
|
||||
class Btapi
|
||||
{
|
||||
private $BT_KEY; //接口密钥
|
||||
private $BT_PANEL; //面板地址
|
||||
|
||||
public function __construct($bt_panel, $bt_key){
|
||||
$this->BT_PANEL = $bt_panel;
|
||||
$this->BT_KEY = $bt_key;
|
||||
}
|
||||
|
||||
//获取面板配置信息
|
||||
public function get_config(){
|
||||
$url = $this->BT_PANEL.'/config?action=get_config';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//获取已登录用户信息
|
||||
public function get_user_info(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_user_info';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//从云端获取插件列表
|
||||
public function get_plugin_list(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_plugin_list';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件包,返回文件路径
|
||||
public function get_plugin_filename($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件主程序文件,返回文件路径
|
||||
public function get_plugin_main_filename($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin_main';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//解密插件主程序py代码,返回文件路径
|
||||
public function get_decode_plugin_main($plugin_name, $version){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=decode_plugin_main';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['plugin_name'] = $plugin_name;
|
||||
$p_data['version'] = $version;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载插件其他文件,返回文件路径
|
||||
public function get_plugin_other_filename($fname){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=download_plugin_other';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['fname'] = $fname;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//下载文件
|
||||
public function download($filename, $localpath){
|
||||
$url = $this->BT_PANEL.'/download';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['filename'] = $filename;
|
||||
|
||||
$result = $this->curl_download($url.'?'.http_build_query($p_data), $localpath);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//获取文件base64
|
||||
public function get_file($filename){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_file';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['filename'] = $filename;
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//购买第三方插件
|
||||
public function create_plugin_other_order($pid){
|
||||
$url = $this->BT_PANEL.'/auth?action=create_plugin_other_order';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
$p_data['pid'] = $pid;
|
||||
$p_data['cycle'] = '999';
|
||||
$p_data['type'] = '0';
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//获取一键部署列表
|
||||
public function get_deplist(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=get_deplist';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//BTWAF-获取蜘蛛列表
|
||||
public function btwaf_getspiders(){
|
||||
$url = $this->BT_PANEL.'/plugin?action=a&name=kaixin&s=btwaf_getspiders';
|
||||
|
||||
$p_data = $this->GetKeyData();
|
||||
|
||||
$result = $this->curl($url,$p_data);
|
||||
$result = str_replace("\u0000", '', $result);
|
||||
|
||||
$data = json_decode($result,true);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
private function GetKeyData(){
|
||||
$now_time = time();
|
||||
$p_data = array(
|
||||
'request_token' => md5($now_time.''.md5($this->BT_KEY)),
|
||||
'request_time' => $now_time
|
||||
);
|
||||
return $p_data;
|
||||
}
|
||||
|
||||
|
||||
private function curl($url, $data = null, $timeout = 60)
|
||||
{
|
||||
//定义cookie保存位置
|
||||
$cookie_file=app()->getRuntimePath().md5($this->BT_PANEL).'.cookie';
|
||||
if(!file_exists($cookie_file)){
|
||||
touch($cookie_file);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
if($data){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function curl_download($url, $localpath, $timeout = 300)
|
||||
{
|
||||
//定义cookie保存位置
|
||||
$cookie_file=app()->getRuntimePath().md5($this->BT_PANEL).'.cookie';
|
||||
if(!file_exists($cookie_file)){
|
||||
touch($cookie_file);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
|
||||
$fp = fopen($localpath, 'w+');
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$message = curl_error($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
throw new Exception('下载文件失败:'.$message);
|
||||
}
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
if($httpcode>299){
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
throw new Exception('下载文件失败:HTTPCODE-'.$httpcode);
|
||||
}
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -65,7 +65,6 @@ class ThirdPlugins
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($filepath) === true)
|
||||
{
|
||||
$zip->extractTo(get_data_dir($this->os).'plugins/folder/'.$plugin_name.'-'.$version);
|
||||
$zip->close();
|
||||
return true;
|
||||
}else{
|
||||
|
@@ -1,26 +1,26 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
|
||||
class AuthAdmin
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
$islogin = false;
|
||||
$cookie = cookie('admin_token');
|
||||
if($cookie){
|
||||
$token=authcode($cookie, 'DECODE', config_get('syskey'));
|
||||
if($token){
|
||||
list($user, $sid, $expiretime) = explode("\t", $token);
|
||||
$session=md5(config_get('admin_username').config_get('admin_password'));
|
||||
if($session==$sid && $expiretime>time()) {
|
||||
$islogin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
request()->islogin = $islogin;
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
|
||||
class AuthAdmin
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
$islogin = false;
|
||||
$cookie = cookie('admin_token');
|
||||
if($cookie){
|
||||
$token=authcode($cookie, 'DECODE', config_get('syskey'));
|
||||
if($token){
|
||||
list($user, $sid, $expiretime) = explode("\t", $token);
|
||||
$session=md5(config_get('admin_username').config_get('admin_password'));
|
||||
if($session==$sid && $expiretime>time()) {
|
||||
$islogin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
request()->islogin = $islogin;
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
@@ -1,19 +1,19 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
|
||||
class CheckAdmin
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if (!request()->islogin) {
|
||||
if ($request->isAjax() || !$request->isGet()) {
|
||||
return json(['code'=>-1, 'msg'=>'未登录'])->code(401);
|
||||
}
|
||||
return redirect((string)url('/admin/login'));
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
|
||||
class CheckAdmin
|
||||
{
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if (!request()->islogin) {
|
||||
if ($request->isAjax() || !$request->isGet()) {
|
||||
return json(['code'=>-1, 'msg'=>'未登录'])->code(401);
|
||||
}
|
||||
return redirect((string)url('/admin/login'));
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ namespace app\middleware;
|
||||
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use think\facade\View;
|
||||
|
||||
class LoadConfig
|
||||
{
|
||||
@@ -31,6 +32,7 @@ class LoadConfig
|
||||
$res = Db::name('config')->cache('configs',0)->column('value','key');
|
||||
Config::set($res, 'sys');
|
||||
|
||||
View::assign('cdnpublic', '//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/');
|
||||
return $next($request)->header([
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
|
@@ -1,24 +1,24 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use think\facade\View;
|
||||
|
||||
class RefererCheck
|
||||
{
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param \think\Request $request
|
||||
* @param \Closure $next
|
||||
* @return Response
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if(!checkRefererHost()){
|
||||
return response('Access Denied', 403);
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use think\facade\View;
|
||||
|
||||
class RefererCheck
|
||||
{
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param \think\Request $request
|
||||
* @param \Closure $next
|
||||
* @return Response
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
if(!checkRefererHost()){
|
||||
return response('Access Denied', 403);
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
31
app/script/cacert.sh
Normal file
31
app/script/cacert.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
OPENSSL_CHECK=$(which openssl)
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "未安装OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f ca.key ] && [ ! -f ca.crt ]; then
|
||||
openssl genrsa -out ca.key 2048
|
||||
openssl req -new -x509 -utf8 -days 3650 -extensions v3_ca -subj "/C=CN/O=宝塔面板/CN=宝塔面板" -key ca.key -out ca.crt
|
||||
fi
|
||||
|
||||
openssl genrsa -out server.key 2048
|
||||
openssl req -new -nodes -key server.key -subj "/C=CN/O=BTPanel/CN=BTPanel" -out server.csr
|
||||
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -extensions req_ext
|
||||
|
||||
cat ca.crt >> server.crt
|
||||
|
||||
openssl pkcs12 -export -out baota_root.pfx -inkey server.key -in server.crt -password pass:
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "生成CA根证书失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p ../../public/ssl
|
||||
\cp baota_root.pfx ../../public/ssl/baota_root.pfx
|
||||
\cp ca.crt ../../public/ssl/baota_root.crt
|
||||
rm -f server.crt server.key server.csr
|
||||
|
||||
echo "生成CA根证书成功"
|
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
Linux_Version="8.0.5"
|
||||
Windows_Version="7.9.0"
|
||||
Btm_Version="2.2.9"
|
||||
Linux_Version="9.2.0"
|
||||
Windows_Version="8.2.0"
|
||||
Btm_Version="2.3.0"
|
||||
|
||||
FILES=(
|
||||
public/install/src/panel6.zip
|
||||
|
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script>
|
||||
function refresh_deplist(os){
|
||||
var confirm = layer.confirm('是否确定从宝塔官方获取最新一键部署列表?', {
|
||||
|
@@ -1,60 +1,60 @@
|
||||
{extend name="admin/layout" /}
|
||||
{block name="title"}宝塔第三方云端管理中心{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
.table>tbody>tr>td{white-space: normal;}
|
||||
.query-title {
|
||||
background-color:#f5fafe;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.query-result{
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
<div class="container" style="padding-top:70px;">
|
||||
<div class="col-xs-12 col-sm-10 col-md-8 center-block" style="float: none;">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading"><h3 class="panel-title">后台管理首页</h3></div>
|
||||
<div class="list-group">
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-stats"></span> <b>宝塔插件统计:</b>共有 {$stat.total} 个,其中免费插件 {$stat.free} 个,专业版插件 {$stat.pro} 个,企业版插件 {$stat.ltd} 个,第三方插件 {$stat.third} 个</div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-tint"></span> <b>使用记录统计:</b>历史总共数量:{$stat.record_total},正在使用数量:{$stat.record_isuse}</div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-time"></span> <b>任务运行情况:</b>上次运行时间:{$stat.runtime|raw} <a href="/admin/set/mod/task" class="btn btn-xs btn-info">查看详情</a></div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-cog"></span> <b>常用功能入口:</b><a href="/admin/plugins" class="btn btn-xs btn-default">插件列表</a> <a href="/admin/record" class="btn btn-xs btn-default">使用记录</a> <a href="/admin/list" class="btn btn-xs btn-default">黑白名单</a> <a href="/download" class="btn btn-xs btn-default" target="_blank">安装脚本</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">服务器信息</h3>
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="query-title">框架版本</td>
|
||||
<td class="query-result">{$info.framework_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">PHP版本</td>
|
||||
<td class="query-result">{$info.php_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">MySQL版本</td>
|
||||
<td class="query-result">{$info.mysql_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">WEB软件</td>
|
||||
<td class="query-result">{$info.software}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">操作系统</td>
|
||||
<td class="query-result">{$info.os}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">服务器时间</td>
|
||||
<td class="query-result">{$info.date}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{extend name="admin/layout" /}
|
||||
{block name="title"}宝塔第三方云端管理中心{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
.table>tbody>tr>td{white-space: normal;}
|
||||
.query-title {
|
||||
background-color:#f5fafe;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.query-result{
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
<div class="container" style="padding-top:70px;">
|
||||
<div class="col-xs-12 col-sm-10 col-md-8 center-block" style="float: none;">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading"><h3 class="panel-title">后台管理首页</h3></div>
|
||||
<div class="list-group">
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-stats"></span> <b>宝塔插件统计:</b>共有 {$stat.total} 个,其中免费插件 {$stat.free} 个,专业版插件 {$stat.pro} 个,企业版插件 {$stat.ltd} 个,第三方插件 {$stat.third} 个</div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-tint"></span> <b>使用记录统计:</b>历史总共数量:{$stat.record_total},正在使用数量:{$stat.record_isuse}</div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-time"></span> <b>任务运行情况:</b>上次运行时间:{$stat.runtime|raw} <a href="/admin/set/mod/task" class="btn btn-xs btn-info">查看详情</a></div>
|
||||
<div class="list-group-item"><span class="glyphicon glyphicon-cog"></span> <b>常用功能入口:</b><a href="/admin/plugins" class="btn btn-xs btn-default">插件列表</a> <a href="/admin/record" class="btn btn-xs btn-default">使用记录</a> <a href="/admin/list" class="btn btn-xs btn-default">黑白名单</a> <a href="/download" class="btn btn-xs btn-default" target="_blank">安装脚本</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">服务器信息</h3>
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="query-title">框架版本</td>
|
||||
<td class="query-result">{$info.framework_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">PHP版本</td>
|
||||
<td class="query-result">{$info.php_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">MySQL版本</td>
|
||||
<td class="query-result">{$info.mysql_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">WEB软件</td>
|
||||
<td class="query-result">{$info.software}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">操作系统</td>
|
||||
<td class="query-result">{$info.os}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="query-title">服务器时间</td>
|
||||
<td class="query-result">{$info.date}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
@@ -5,15 +5,15 @@
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>{block name="title"}标题{/block}</title>
|
||||
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="{$cdnpublic}twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="{$cdnpublic}font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="/static/css/bootstrap-table.css" rel="stylesheet" />
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/modernizr/2.8.3/modernizr.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.4/jquery.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
|
||||
<script src="{$cdnpublic}modernizr/2.8.3/modernizr.min.js"></script>
|
||||
<script src="{$cdnpublic}jquery/2.1.4/jquery.min.js"></script>
|
||||
<script src="{$cdnpublic}twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
|
||||
<script src="{$cdnpublic}html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="{$cdnpublic}respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
@@ -51,6 +51,9 @@
|
||||
<li class="{:checkIfActive('log')}">
|
||||
<a href="/admin/log"><i class="fa fa-calendar"></i> 操作日志</a>
|
||||
</li>
|
||||
<li class="{:checkIfActive('ssl')}">
|
||||
<a href="/admin/ssl"><i class="fa fa-expeditedssl"></i> 自签SSL</a>
|
||||
</li>
|
||||
<li class="{:checkIfActive('set')}">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"></i> 系统设置<b
|
||||
class="caret"></b></a>
|
||||
|
@@ -42,9 +42,9 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
function setEnable(id,enable) {
|
||||
|
@@ -23,9 +23,9 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
|
||||
|
@@ -5,12 +5,12 @@
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>管理员登录</title>
|
||||
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/modernizr/2.8.3/modernizr.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.4/jquery.min.js"></script>
|
||||
<link href="{$cdnpublic}twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<script src="{$cdnpublic}modernizr/2.8.3/modernizr.min.js"></script>
|
||||
<script src="{$cdnpublic}jquery/2.1.4/jquery.min.js"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
|
||||
<script src="{$cdnpublic}html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="{$cdnpublic}respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
@@ -23,7 +23,7 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="./">宝塔第三方云端管理中心</a>
|
||||
<a class="navbar-brand" href="./">Cloud</a>
|
||||
</div><!-- /.navbar-header -->
|
||||
<div id="navbar" class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script>
|
||||
function submitlogin(){
|
||||
var user = $("input[name='user']").val();
|
||||
|
@@ -69,9 +69,9 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:340px;
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -157,8 +157,13 @@ function download_item(){
|
||||
layer.alert('成功下载'+$.downloadCount+'个插件包!', {icon:1}, function(){layer.closeAll();searchSubmit();});
|
||||
return;
|
||||
}
|
||||
$.downloadCount++;
|
||||
var plugin = $.preDownload[0];
|
||||
if(plugin.name == 'firewall'){
|
||||
$.preDownload.shift();
|
||||
download_item();
|
||||
return;
|
||||
}
|
||||
$.downloadCount++;
|
||||
var ii = layer.msg('['+$.downloadCount+'/'+$.preDownloadCount+']正在下载'+plugin.name+'-'+plugin.version, {icon: 16, shade:0.1, time: 0});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
|
@@ -69,9 +69,9 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:340px;
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -163,7 +163,7 @@ function download_item(){
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/admin/download_plugin',
|
||||
data: { name:plugin.name, version:plugin.version},
|
||||
data: { name:plugin.name, version:plugin.version, os:'Windows'},
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii)
|
||||
|
@@ -23,9 +23,9 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
|
||||
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
|
||||
<script src="/static/js/custom.js"></script>
|
||||
<script>
|
||||
|
||||
|
@@ -279,7 +279,7 @@ $("select[name='wbt_type']").change(function(){
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var items = $("select[default]");
|
||||
|
86
app/view/admin/ssl.html
Normal file
86
app/view/admin/ssl.html
Normal file
@@ -0,0 +1,86 @@
|
||||
{extend name="admin/layout" /}
|
||||
{block name="title"}自签名SSL证书生成{/block}
|
||||
{block name="main"}
|
||||
<style>
|
||||
.control-label[is-required]:before {
|
||||
content: "*";
|
||||
color: #f56c6c;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
<div class="container" style="padding-top:70px;">
|
||||
<div class="col-sm-12 col-md-10 col-lg-8 center-block" style="float: none;">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading"><h3 class="panel-title">自签名SSL证书生成</h3></div>
|
||||
<div class="panel-body">
|
||||
{if $isca}
|
||||
<div class="alert alert-warning" style="word-break:break-all;">下载CA证书并导入,可解决浏览器不安全提醒。<br/>Windows:<a href="/ssl/baota_root.pfx">baota_root.pfx</a>(密码为空),Mac/Linux:<a href="/ssl/baota_root.crt">baota_root.crt</a></div>
|
||||
<form onsubmit="return makeSSL(this)" method="post" class="form" role="form">
|
||||
<div class="form-group">
|
||||
<label is-required="true" class="control-label">域名列表:</label>
|
||||
<textarea class="form-control" name="domain_list" rows="6" placeholder="每行一个域名/IP,支持通配符" required></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">通用名称:</label>
|
||||
<input type="text" name="common_name" value="" placeholder="留空则为域名列表第一个域名" class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label is-required="true" class="control-label">有效天数:</label>
|
||||
<input type="number" name="validity" value="3650" class="form-control" required/>
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" name="submit" value="生成自签名证书" class="btn btn-success btn-block"/>
|
||||
</div>
|
||||
<div class="form-group row" id="result" style="display:none;">
|
||||
<div class="col-md-6">
|
||||
<label class="control-label">SSL证书:</label>
|
||||
<textarea class="form-control" name="ssl_cert" rows="5" onclick="copy(this)" title="点击复制"></textarea>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="control-label">SSL证书私钥:</label>
|
||||
<textarea class="form-control" name="ssl_key" rows="5" onclick="copy(this)" title="点击复制"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{else}
|
||||
<div class="alert alert-danger" role="alert">你还没有生成CA证书,无法生成SSL证书!</div>
|
||||
<div class="alert alert-info" style="word-break:break-all;">执行以下命令,生成自签名CA证书。然后,可通过接口或当前页面生成SSL证书,用于面板访问。</div>
|
||||
<div class="list-group-item" style="word-break:break-all;">cd {:app()->getRootPath()}app/script && chmod +x cacert.sh && ./cacert.sh</div><br/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
|
||||
<script>
|
||||
function makeSSL(obj){
|
||||
var ii = layer.load(2, {shade:[0.1,'#fff']});
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : '/admin/ssl',
|
||||
data : $(obj).serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
layer.close(ii);
|
||||
if(data.code == 0){
|
||||
$("textarea[name='ssl_cert']").val(data.cert);
|
||||
$("textarea[name='ssl_key']").val(data.key);
|
||||
$("#result").show();
|
||||
layer.msg('SSL证书生成成功', {icon:1, time:800});
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2})
|
||||
}
|
||||
},
|
||||
error:function(data){
|
||||
layer.close(ii);
|
||||
layer.msg('服务器错误');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
function copy(obj){
|
||||
if($(obj).val() == '') return;
|
||||
$(obj).select();
|
||||
document.execCommand("Copy");
|
||||
layer.msg('复制成功', {icon:1, time:500});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
@@ -1,60 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>温馨提示</title>
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
||||
<meta name="renderer" content="webkit"/>
|
||||
<style type="text/css">
|
||||
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
|
||||
body{padding:70px 0;background:#edf1f4;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
|
||||
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
|
||||
.system-message{margin:20px 5%;padding:40px 20px;background:#fff;box-shadow:1px 1px 1px hsla(0,0%,39%,.1);text-align:center}
|
||||
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:40px}
|
||||
.system-message .jump,.system-message .image{margin:20px 0;padding:0;padding:10px 0;font-weight:400}
|
||||
.system-message .jump{font-size:14px}
|
||||
.system-message .jump a{color:#333}
|
||||
.system-message p{font-size:9pt;line-height:20px}
|
||||
.system-message .btn{display:inline-block;margin-right:10px;width:138px;height:2pc;border:1px solid #44a0e8;border-radius:30px;color:#44a0e8;text-align:center;font-size:1pc;line-height:2pc;margin-bottom:5px;}
|
||||
.success .btn{border-color:#69bf4e;color:#69bf4e}
|
||||
.error .btn{border-color:#ff8992;color:#ff8992}
|
||||
.info .btn{border-color:#3498db;color:#3498db}
|
||||
.copyright p{width:100%;color:#919191;text-align:center;font-size:10px}
|
||||
.system-message .btn-grey{border-color:#bbb;color:#bbb}
|
||||
.clearfix:after{clear:both;display:block;visibility:hidden;height:0;content:"."}
|
||||
@media (max-width:768px){body {padding:20px 0;}}
|
||||
@media (max-width:480px){.system-message h1{font-size:30px;}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="system-message {$code}">
|
||||
<div class="image">
|
||||
<img src="/static/images/{$code}.svg" alt="" width="150" />
|
||||
</div>
|
||||
<h1>{$msg}</h1>
|
||||
{if $url}
|
||||
<p class="jump">
|
||||
页面将在 <span id="wait">{$wait}</span> 秒后自动跳转
|
||||
</p>
|
||||
{/if}
|
||||
<p class="clearfix">
|
||||
<a href="javascript:history.go(-1);" class="btn btn-grey">返回上一页</a>
|
||||
{if $url}
|
||||
<a href="{$url}" class="btn btn-primary">立即跳转</a>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
var wait = document.getElementById('wait');
|
||||
var interval = setInterval(function () {
|
||||
var time = --wait.innerHTML;
|
||||
if (time <= 0) {
|
||||
location.href = "{$url}";
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>温馨提示</title>
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
||||
<meta name="renderer" content="webkit"/>
|
||||
<style type="text/css">
|
||||
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
|
||||
body{padding:70px 0;background:#edf1f4;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
|
||||
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
|
||||
.system-message{margin:20px 5%;padding:40px 20px;background:#fff;box-shadow:1px 1px 1px hsla(0,0%,39%,.1);text-align:center}
|
||||
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:40px}
|
||||
.system-message .jump,.system-message .image{margin:20px 0;padding:0;padding:10px 0;font-weight:400}
|
||||
.system-message .jump{font-size:14px}
|
||||
.system-message .jump a{color:#333}
|
||||
.system-message p{font-size:9pt;line-height:20px}
|
||||
.system-message .btn{display:inline-block;margin-right:10px;width:138px;height:2pc;border:1px solid #44a0e8;border-radius:30px;color:#44a0e8;text-align:center;font-size:1pc;line-height:2pc;margin-bottom:5px;}
|
||||
.success .btn{border-color:#69bf4e;color:#69bf4e}
|
||||
.error .btn{border-color:#ff8992;color:#ff8992}
|
||||
.info .btn{border-color:#3498db;color:#3498db}
|
||||
.copyright p{width:100%;color:#919191;text-align:center;font-size:10px}
|
||||
.system-message .btn-grey{border-color:#bbb;color:#bbb}
|
||||
.clearfix:after{clear:both;display:block;visibility:hidden;height:0;content:"."}
|
||||
@media (max-width:768px){body {padding:20px 0;}}
|
||||
@media (max-width:480px){.system-message h1{font-size:30px;}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="system-message {$code}">
|
||||
<div class="image">
|
||||
<img src="/static/images/{$code}.svg" alt="" width="150" />
|
||||
</div>
|
||||
<h1>{$msg}</h1>
|
||||
{if $url}
|
||||
<p class="jump">
|
||||
页面将在 <span id="wait">{$wait}</span> 秒后自动跳转
|
||||
</p>
|
||||
{/if}
|
||||
<p class="clearfix">
|
||||
<a href="javascript:history.go(-1);" class="btn btn-grey">返回上一页</a>
|
||||
{if $url}
|
||||
<a href="{$url}" class="btn btn-primary">立即跳转</a>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
var wait = document.getElementById('wait');
|
||||
var interval = setInterval(function () {
|
||||
var time = --wait.innerHTML;
|
||||
if (time <= 0) {
|
||||
location.href = "{$url}";
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -193,10 +193,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{$cdnpublic}jquery/3.6.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{$cdnpublic}layer/3.5.1/layer.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script type="text/javascript" src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/clipboard.js/1.7.1/clipboard.min.js"></script>
|
||||
<script type="text/javascript" src="{$cdnpublic}clipboard.js/1.7.1/clipboard.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/dx.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
|
@@ -8,5 +8,6 @@ return [
|
||||
'updateall' => 'app\command\UpdateAll',
|
||||
'decrypt' => 'app\command\DecryptFile',
|
||||
'clean' => 'app\command\Clean',
|
||||
'cleanvitejs' => 'app\command\CleanViteJs',
|
||||
],
|
||||
];
|
||||
|
14
install.sql
14
install.sql
@@ -12,15 +12,15 @@ INSERT INTO `cloud_config` (`key`, `value`) VALUES
|
||||
('bt_key', ''),
|
||||
('whitelist', '0'),
|
||||
('download_page', '1'),
|
||||
('new_version', '8.0.5'),
|
||||
('new_version', '9.2.0'),
|
||||
('update_msg', '暂无更新日志'),
|
||||
('update_date', '2024-01-12'),
|
||||
('new_version_win', '7.9.0'),
|
||||
('update_date', '2024-09-13'),
|
||||
('new_version_win', '8.1.0'),
|
||||
('update_msg_win', '暂无更新日志'),
|
||||
('update_date_win', '2023-07-20'),
|
||||
('new_version_btm', '2.2.9'),
|
||||
('update_date_win', '2024-07-17'),
|
||||
('new_version_btm', '2.3.0'),
|
||||
('update_msg_btm', '暂无更新日志'),
|
||||
('update_date_btm', '2023-08-11'),
|
||||
('update_date_btm', '2024-04-24'),
|
||||
('updateall_type', '0'),
|
||||
('syskey', 'UqP94LtI8eWAIgCP');
|
||||
|
||||
@@ -48,7 +48,7 @@ CREATE TABLE `cloud_white` (
|
||||
DROP TABLE IF EXISTS `cloud_record`;
|
||||
CREATE TABLE `cloud_record` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ip` varchar(200) NOT NULL,
|
||||
`ip` varchar(20) NOT NULL,
|
||||
`addtime` datetime NOT NULL,
|
||||
`usetime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
|
@@ -3,6 +3,9 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
LANG=en_US.UTF-8
|
||||
|
||||
INSTALL_LOGFILE="/tmp/btpanel-install.log"
|
||||
# exec > >(tee -a "$INSTALL_LOGFILE") 2>&1
|
||||
|
||||
Btapi_Url='http://www.example.com'
|
||||
Check_Api=$(curl -Ss --connect-timeout 5 -m 2 $Btapi_Url/api/SetupCount)
|
||||
if [ "$Check_Api" != 'ok' ];then
|
||||
@@ -16,7 +19,8 @@ fi
|
||||
|
||||
is64bit=$(getconf LONG_BIT)
|
||||
if [ "${is64bit}" != '64' ];then
|
||||
Red_Error "抱歉, 当前面板版本不支持32位系统, 请使用64位系统或安装宝塔5.9!";
|
||||
echo "抱歉, 当前面板版本不支持32位系统, 请使用64位系统或安装宝塔5.9!";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Centos6Check=$(cat /etc/redhat-release | grep ' 6.' | grep -iE 'centos|Red Hat')
|
||||
@@ -27,7 +31,7 @@ fi
|
||||
|
||||
UbuntuCheck=$(cat /etc/issue|grep Ubuntu|awk '{print $2}'|cut -f 1 -d '.')
|
||||
if [ "${UbuntuCheck}" ] && [ "${UbuntuCheck}" -lt "16" ];then
|
||||
echo "Ubuntu ${UbuntuCheck}不支持安装宝塔面板,建议更换Ubuntu18/20安装宝塔面板"
|
||||
echo "Ubuntu ${UbuntuCheck}不支持安装宝塔面板,建议更换Ubuntu22/24安装宝塔面板"
|
||||
exit 1
|
||||
fi
|
||||
HOSTNAME_CHECK=$(cat /etc/hostname)
|
||||
@@ -36,6 +40,20 @@ if [ -z "${HOSTNAME_CHECK}" ];then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
UBUNTU_NO_LTS=$(cat /etc/issue|grep Ubuntu|grep -E "19|21|23|25")
|
||||
if [ "${UBUNTU_NO_LTS}" ];then
|
||||
echo "当前您使用的非Ubuntu-lts版本,无法进行宝塔面板的安装"
|
||||
echo "请使用Ubuntu-20/20/22/24进行安装宝塔面板"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEBIAN_9_C=$(cat /etc/issue|grep Debian|grep -E "8 |9 ")
|
||||
if [ "${DEBIAN_9_C}" ];then
|
||||
echo "当前您使用的Debian-8/9,官方已经停止支持、无法进行宝塔面板的安装"
|
||||
echo "请使用Debian-11/12进行安装宝塔面板"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ~
|
||||
setup_path="/www"
|
||||
python_bin=$setup_path/server/panel/pyenv/bin/python
|
||||
@@ -61,6 +79,15 @@ GetSysInfo(){
|
||||
echo -e ${SYS_INFO}
|
||||
echo -e "============================================"
|
||||
echo -e "请截图以上报错信息发帖至论坛www.bt.cn/bbs求助"
|
||||
echo -e "============================================"
|
||||
|
||||
if [ -f "/etc/redhat-release" ];then
|
||||
Centos7Check=$(cat /etc/redhat-release | grep ' 7.' | grep -iE 'centos')
|
||||
echo -e "============================================"
|
||||
echo -e "Centos7/8官方已经停止支持"
|
||||
echo -e "如是新安装系统服务器建议更换至Debian-12/Ubuntu-22/Centos-9系统安装宝塔面板"
|
||||
echo -e "============================================"
|
||||
fi
|
||||
}
|
||||
Red_Error(){
|
||||
echo '=================================================';
|
||||
@@ -104,38 +131,17 @@ System_Check(){
|
||||
fi
|
||||
}
|
||||
Set_Ssl(){
|
||||
echo -e ""
|
||||
echo -e "----------------------------------------------------------------------"
|
||||
echo -e "为了您的面板使用安全,建议您开启面板SSL,开启后请使用https访问宝塔面板"
|
||||
echo -e "输入y回车即开启面板SSL并进行下一步安装"
|
||||
echo -e "输入n回车跳过面板SSL配置,直接进行安装"
|
||||
echo -e "10秒后将跳过SSL配置,直接进行面板安装"
|
||||
echo -e "----------------------------------------------------------------------"
|
||||
echo -e ""
|
||||
read -t 10 -p "是否确定开启面板SSL ? (y/n): " yes
|
||||
|
||||
if [ $? != 0 ];then
|
||||
SET_SSL=false
|
||||
else
|
||||
case "$yes" in
|
||||
y)
|
||||
SET_SSL=true
|
||||
;;
|
||||
n)
|
||||
SET_SSL=false
|
||||
rm -f /www/server/panel/data/ssl.pl
|
||||
;;
|
||||
*)
|
||||
Set_Ssl
|
||||
esac
|
||||
SET_SSL=true
|
||||
if [ "${SSL_PL}" ];then
|
||||
SET_SSL=""
|
||||
fi
|
||||
}
|
||||
Add_lib_Install(){
|
||||
Get_Versions
|
||||
if [ "${os_type}" == "el" ] && [ "${os_version}" == "7" ];then
|
||||
cd /www/server/panel/class
|
||||
btpython -c "import panelPlugin; plugin = panelPlugin.panelPlugin(); plugin.check_install_lib('1')"
|
||||
echo "True" > /tmp/panelTask.pl
|
||||
#btpython -c "import panelPlugin; plugin = panelPlugin.panelPlugin(); plugin.check_install_lib('1')"
|
||||
#echo "True" > /tmp/panelTask.pl
|
||||
fi
|
||||
}
|
||||
Get_Pack_Manager(){
|
||||
@@ -184,7 +190,65 @@ Service_Add(){
|
||||
update-rc.d bt defaults
|
||||
fi
|
||||
}
|
||||
Set_Centos_Repo(){
|
||||
Set_Centos7_Repo(){
|
||||
# CN_YUM_URL=$(grep -E "aliyun|163|tencent|tsinghua" /etc/yum.repos.d/CentOS-Base.repo)
|
||||
# if [ -z "${CN_YUM_URL}" ];then
|
||||
# if [ -z "${download_Url}" ];then
|
||||
# download_Url="http://download.bt.cn"
|
||||
# fi
|
||||
# curl -Ss --connect-timeout 3 -m 60 ${download_Url}/install/vault-repo.sh|bash
|
||||
# return
|
||||
# fi
|
||||
MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Base.repo |grep "[^#]mirror.centos.org")
|
||||
if [ "${MIRROR_CHECK}" ] && [ "${is64bit}" == "64" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
|
||||
TSU_MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Base.repo |grep "tuna.tsinghua.edu.cn")
|
||||
if [ "${TSU_MIRROR_CHECK}" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=https://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|baseurl=https://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|baseurl=http://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
|
||||
ALI_CLOUD_CHECK=$(grep Alibaba /etc/motd)
|
||||
Tencent_Cloud=$(cat /etc/hostname |grep -E VM-[0-9]+-[0-9]+)
|
||||
if [ "${ALI_CLOUD_CHECK}" ] || [ "${Tencent_Cloud}" ];then
|
||||
return
|
||||
fi
|
||||
|
||||
yum install unzip -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
TAR_CHECK=$(which tar)
|
||||
if [ "$?" == "0" ] ;then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
if [ -z "${download_Url}" ];then
|
||||
download_Url="http://download.bt.cn"
|
||||
fi
|
||||
curl -Ss --connect-timeout 5 -m 60 -O ${download_Url}/src/el7repo.tar.gz
|
||||
rm -f /etc/yum.repos.d/*.repo
|
||||
tar -xvzf el7repo.tar.gz -C /etc/yum.repos.d/
|
||||
fi
|
||||
fi
|
||||
|
||||
yum install unzip -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
sed -i "s/vault.epel.cloud/mirrors.cloud.tencent.com/g" /etc/yum.repos.d/*.repo
|
||||
fi
|
||||
|
||||
}
|
||||
# Set_Centos7_Repo(){
|
||||
# if [ -z "${download_Url}" ];then
|
||||
# download_Url="http://download.bt.cn"
|
||||
# fi
|
||||
# curl -Ss --connect-timeout 3 -m 60 ${download_Url}/install/vault-repo.sh|bash
|
||||
# }
|
||||
Set_Centos8_Repo(){
|
||||
HUAWEI_CHECK=$(cat /etc/motd |grep "Huawei Cloud")
|
||||
if [ "${HUAWEI_CHECK}" ] && [ "${is64bit}" == "64" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
@@ -207,6 +271,25 @@ Set_Centos_Repo(){
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
|
||||
yum install unzip tar -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
if [ -z "${download_Url}" ];then
|
||||
download_Url="http://download.bt.cn"
|
||||
fi
|
||||
if [ ! -f "/usr/bin/tar" ] ;then
|
||||
curl -Ss --connect-timeout 5 -m 60 -O ${download_Url}/src/tar-1.30-5.el8.x86_64.rpm
|
||||
yum install tar-1.30-5.el8.x86_64.rpm -y
|
||||
fi
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
curl -Ss --connect-timeout 5 -m 60 -O ${download_Url}/src/el8repo.tar.gz
|
||||
rm -f /etc/yum.repos.d/*.repo
|
||||
tar -xvzf el8repo.tar.gz -C /etc/yum.repos.d/
|
||||
fi
|
||||
yum install unzip -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
sed -i "s/vault.epel.cloud/mirrors.cloud.tencent.com/g" /etc/yum.repos.d/*.repo
|
||||
fi
|
||||
}
|
||||
get_node_url(){
|
||||
if [ ! -f /bin/curl ];then
|
||||
@@ -226,7 +309,15 @@ get_node_url(){
|
||||
|
||||
echo '---------------------------------------------';
|
||||
echo "Selected download node...";
|
||||
nodes=(https://dg2.bt.cn https://download.bt.cn https://ctcc1-node.bt.cn https://cmcc1-node.bt.cn https://ctcc2-node.bt.cn https://hk1-node.bt.cn https://na1-node.bt.cn https://jp1-node.bt.cn https://cf1-node.aapanel.com);
|
||||
nodes=(https://dg2.bt.cn https://download.bt.cn https://ctcc1-node.bt.cn https://cmcc1-node.bt.cn https://ctcc2-node.bt.cn https://hk1-node.bt.cn https://na1-node.bt.cn https://jp1-node.bt.cn https://cf1-node.aapanel.com https://download.bt.cn);
|
||||
|
||||
CURL_CHECK=$(which curl)
|
||||
if [ "$?" == "0" ];then
|
||||
CN_CHECK=$(curl -sS --connect-timeout 10 -m 10 https://api.bt.cn/api/isCN)
|
||||
if [ "${CN_CHECK}" == "True" ];then
|
||||
nodes=(https://dg2.bt.cn https://download.bt.cn https://ctcc1-node.bt.cn https://cmcc1-node.bt.cn https://ctcc2-node.bt.cn https://hk1-node.bt.cn);
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" ];then
|
||||
nodes=($(echo ${nodes[*]}|sed "s#${1}##"))
|
||||
@@ -293,10 +384,25 @@ Remove_Package(){
|
||||
}
|
||||
Install_RPM_Pack(){
|
||||
yumPath=/etc/yum.conf
|
||||
|
||||
CentosStream8Check=$(cat /etc/redhat-release |grep Stream|grep 8)
|
||||
if [ "${CentosStream8Check}" ];then
|
||||
MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Stream-AppStream.repo|grep "[^#]mirror.centos.org")
|
||||
if [ "${MIRROR_CHECK}" ] && [ "${is64bit}" == "64" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
fi
|
||||
|
||||
Centos8Check=$(cat /etc/redhat-release | grep ' 8.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos8Check}" ];then
|
||||
Set_Centos_Repo
|
||||
Set_Centos8_Repo
|
||||
fi
|
||||
Centos7Check=$(cat /etc/redhat-release | grep ' 7.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos7Check}" ];then
|
||||
Set_Centos7_Repo
|
||||
fi
|
||||
isExc=$(cat $yumPath|grep httpd)
|
||||
if [ "$isExc" = "" ];then
|
||||
echo "exclude=httpd nginx php mysql mairadb python-psutil python2-psutil" >> $yumPath
|
||||
@@ -425,6 +531,24 @@ Get_Versions(){
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "/etc/os-release" ];then
|
||||
. /etc/os-release
|
||||
OS_V=${VERSION_ID%%.*}
|
||||
if [ "${ID}" == "opencloudos" ] && [[ "${OS_V}" =~ ^(9)$ ]];then
|
||||
os_type="opencloudos"
|
||||
os_version="9"
|
||||
pyenv_tt="true"
|
||||
elif { [ "${ID}" == "almalinux" ] || [ "${ID}" == "centos" ] || [ "${ID}" == "rocky" ]; } && [[ "${OS_V}" =~ ^(9)$ ]]; then
|
||||
os_type="el"
|
||||
os_version="9"
|
||||
pyenv_tt="true"
|
||||
fi
|
||||
if [ "${pyenv_tt}" ];then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f $redhat_version_file ];then
|
||||
os_type='el'
|
||||
is_aliyunos=$(cat $redhat_version_file|grep Aliyun)
|
||||
@@ -709,8 +833,8 @@ Install_Bt(){
|
||||
mv -f ${setup_path}/server/panel/data/port.pl ${setup_path}/server/panel/old_data/port.pl
|
||||
mv -f ${setup_path}/server/panel/data/admin_path.pl ${setup_path}/server/panel/old_data/admin_path.pl
|
||||
|
||||
if [ -f "${setup_path}/server/panel/data/db/default.db" ];then
|
||||
mv -f ${setup_path}/server/panel/data/db/ ${setup_path}/server/panel/old_data/
|
||||
if [ -d "${setup_path}/server/panel/data/db" ];then
|
||||
\cp -r ${setup_path}/server/panel/data/db ${setup_path}/server/panel/old_data/
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -732,8 +856,8 @@ Install_Bt(){
|
||||
mv -f ${setup_path}/server/panel/old_data/port.pl ${setup_path}/server/panel/data/port.pl
|
||||
mv -f ${setup_path}/server/panel/old_data/admin_path.pl ${setup_path}/server/panel/data/admin_path.pl
|
||||
|
||||
if [ -f "${setup_path}/server/panel/old_data/db/default.db" ];then
|
||||
mv -f ${setup_path}/server/panel/old_data/db/ ${setup_path}/server/panel/data/db
|
||||
if [ -d "${setup_path}/server/panel/old_data/db" ];then
|
||||
\cp -r ${setup_path}/server/panel/old_data/db ${setup_path}/server/panel/data/
|
||||
fi
|
||||
|
||||
if [ -d "/${setup_path}/server/panel/old_data" ];then
|
||||
@@ -819,6 +943,7 @@ Set_Bt_Panel(){
|
||||
btpip uninstall enum34 -y
|
||||
btpip install geoip2==4.7.0
|
||||
btpip install brotli
|
||||
btpip install PyMySQL
|
||||
fi
|
||||
auth_path=$(cat ${admin_auth})
|
||||
cd ${setup_path}/server/panel/
|
||||
@@ -848,11 +973,13 @@ Set_Bt_Panel(){
|
||||
echo "证书开启成功!"
|
||||
echo "========================================"
|
||||
fi
|
||||
/etc/init.d/bt restart
|
||||
sleep 3
|
||||
/etc/init.d/bt stop
|
||||
sleep 5
|
||||
/etc/init.d/bt start
|
||||
sleep 5
|
||||
isStart=$(ps aux |grep 'BT-Panel'|grep -v grep|awk '{print $2}')
|
||||
LOCAL_CURL=$(curl 127.0.0.1:${panelPort}/login 2>&1 |grep -i html)
|
||||
if [ -z "${isStart}" ] && [ -z "${LOCAL_CURL}" ];then
|
||||
if [ -z "${isStart}" ];then
|
||||
/etc/init.d/bt 22
|
||||
cd /www/server/panel/pyenv/bin
|
||||
touch t.pl
|
||||
@@ -1034,6 +1161,9 @@ while [ ${#} -gt 0 ]; do
|
||||
SAFE_PATH=$2
|
||||
shift 1
|
||||
;;
|
||||
--ssl-disable)
|
||||
SSL_PL="disable"
|
||||
;;
|
||||
-y)
|
||||
go="y"
|
||||
;;
|
||||
@@ -1053,6 +1183,29 @@ if [ "$go" == 'n' ];then
|
||||
exit;
|
||||
fi
|
||||
|
||||
if [ -f "/www/server/panel/BT-Panel" ];then
|
||||
AAPANEL_CHECK=$(grep www.aapanel.com /www/server/panel/BT-Panel)
|
||||
if [ "${AAPANEL_CHECK}" ];then
|
||||
echo -e "----------------------------------------------------"
|
||||
echo -e "检查已安装有aapanel,无法进行覆盖安装宝塔面板"
|
||||
echo -e "如继续执行安装将移去aapanel面板数据(备份至/www/server/aapanel路径) 全新安装宝塔面板"
|
||||
echo -e "aapanel is alreday installed,Can't install panel"
|
||||
echo -e "is install Baota panel, aapanel data will be removed (backed up to /www/server/aapanel)"
|
||||
echo -e "Beginning new Baota panel installation."
|
||||
echo -e "----------------------------------------------------"
|
||||
echo -e "已知风险/Enter yes to force installation"
|
||||
read -p "输入yes开始安装: " yes;
|
||||
if [ "$yes" != "yes" ];then
|
||||
echo -e "------------"
|
||||
echo "取消安装"
|
||||
exit;
|
||||
fi
|
||||
bt stop
|
||||
sleep 1
|
||||
mv /www/server/panel /www/server/aapanel
|
||||
fi
|
||||
fi
|
||||
|
||||
ARCH_LINUX=$(cat /etc/os-release |grep "Arch Linux")
|
||||
if [ "${ARCH_LINUX}" ] && [ -f "/usr/bin/pacman" ];then
|
||||
pacman -Sy
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -18,22 +18,18 @@ if [ ! -f "/www/server/panel/pyenv/bin/python3" ];then
|
||||
echo "请截图发帖至论坛www.bt.cn/bbs求助"
|
||||
exit 0;
|
||||
fi
|
||||
Centos6Check=$(cat /etc/redhat-release | grep ' 6.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos6Check}" ];then
|
||||
echo "Centos6不支持升级宝塔面板,建议备份数据重装更换Centos7/8安装宝塔面板"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
public_file=/www/server/panel/install/public.sh
|
||||
if [ ! -f $public_file ];then
|
||||
wget -O Tpublic.sh $Btapi_Url/install/public.sh -T 20;
|
||||
fi
|
||||
. $public_file
|
||||
|
||||
Centos8Check=$(cat /etc/redhat-release | grep ' 8.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos8Check}" ];then
|
||||
if [ ! -f "/usr/bin/python" ] && [ -f "/usr/bin/python3" ] && [ ! -d "/www/server/panel/pyenv" ]; then
|
||||
ln -sf /usr/bin/python3 /usr/bin/python
|
||||
if [ -f "/etc/redhat-release" ];then
|
||||
Centos6Check=$(cat /etc/redhat-release | grep ' 6.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos6Check}" ];then
|
||||
echo "Centos6不支持升级宝塔面板,建议备份数据重装更换Centos7/8安装宝塔面板"
|
||||
exit 1
|
||||
fi
|
||||
Centos8Check=$(cat /etc/redhat-release | grep ' 8.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos8Check}" ];then
|
||||
if [ ! -f "/usr/bin/python" ] && [ -f "/usr/bin/python3" ] && [ ! -d "/www/server/panel/pyenv" ]; then
|
||||
ln -sf /usr/bin/python3 /usr/bin/python
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -43,11 +39,71 @@ if [ -f $env_path ];then
|
||||
mypip="/www/server/panel/pyenv/bin/pip"
|
||||
fi
|
||||
|
||||
download_Url=$NODE_URL
|
||||
if [ -f "/www/server/panel/data/down_url.pl" ];then
|
||||
D_NODE_URL=$(cat /www/server/panel/data/down_url.pl|grep bt.cn)
|
||||
fi
|
||||
|
||||
if [ -z "${D_NODE_URL}" ];then
|
||||
D_NODE_URL="download.bt.cn"
|
||||
fi
|
||||
|
||||
download_Url=$D_NODE_URL
|
||||
|
||||
|
||||
Set_Centos7_Repo(){
|
||||
if [ -f "/etc/yum.repos.d/docker-ce.repo" ];then
|
||||
mv /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce.repo_backup
|
||||
fi
|
||||
MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Base.repo |grep "[^#]mirror.centos.org")
|
||||
if [ "${MIRROR_CHECK}" ] && [ "${is64bit}" == "64" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
|
||||
TSU_MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Base.repo |grep "tuna.tsinghua.edu.cn")
|
||||
if [ "${TSU_MIRROR_CHECK}" ];then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=https://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
sed -i 's|#baseurl=http://mirrors.tuna.tsinghua.edu.cn|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
|
||||
fi
|
||||
|
||||
ALI_CLOUD_CHECK=$(grep Alibaba /etc/motd)
|
||||
Tencent_Cloud=$(cat /etc/hostname |grep -E VM-[0-9]+-[0-9]+)
|
||||
if [ "${ALI_CLOUD_CHECK}" ] || [ "${Tencent_Cloud}" ];then
|
||||
return
|
||||
fi
|
||||
|
||||
yum install tree -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
TAR_CHECK=$(which tree)
|
||||
if [ "$?" == "0" ] ;then
|
||||
\cp -rpa /etc/yum.repos.d/ /etc/yumBak
|
||||
if [ -z "${download_Url}" ];then
|
||||
download_Url="http://download.bt.cn"
|
||||
fi
|
||||
curl -Ss --connect-timeout 5 -m 60 -O ${download_Url}/src/el7repo.tar.gz
|
||||
rm -f /etc/yum.repos.d/*.repo
|
||||
tar -xvzf el7repo.tar.gz -C /etc/yum.repos.d/
|
||||
fi
|
||||
fi
|
||||
|
||||
yum install tree -y
|
||||
if [ "$?" != "0" ] ;then
|
||||
sed -i "s/vault.epel.cloud/mirrors.cloud.tencent.com/g" /etc/yum.repos.d/*.repo
|
||||
fi
|
||||
}
|
||||
if [ -f "/etc/redhat-release" ];then
|
||||
Centos7Check=$(cat /etc/redhat-release | grep ' 7.' | grep -iE 'centos|Red Hat')
|
||||
if [ "${Centos7Check}" ];then
|
||||
Set_Centos7_Repo
|
||||
fi
|
||||
fi
|
||||
setup_path=/www
|
||||
version=$(curl -Ss --connect-timeout 5 -m 2 $Btapi_Url/api/panel/get_version)
|
||||
if [ "$version" = '' ];then
|
||||
version='8.0.5'
|
||||
if [ -z "$VERSION_CHECK" ];then
|
||||
version='9.2.0'
|
||||
fi
|
||||
armCheck=$(uname -m|grep arm)
|
||||
if [ "${armCheck}" ];then
|
||||
@@ -79,13 +135,18 @@ rm -f /www/server/panel/*.pyc
|
||||
rm -f /www/server/panel/class/*.pyc
|
||||
#pip install flask_sqlalchemy
|
||||
#pip install itsdangerous==0.24
|
||||
btpip install natsort
|
||||
pip_list=$($mypip list)
|
||||
|
||||
pip_list=$($mypip list 2>&1)
|
||||
request_v=$(btpip list 2>/dev/null|grep "requests "|awk '{print $2}'|cut -d '.' -f 2)
|
||||
if [ "$request_v" = "" ] || [ "${request_v}" -gt "28" ];then
|
||||
$mypip install requests==2.27.1
|
||||
fi
|
||||
|
||||
NATSORT_C=$(echo $pip_list|grep natsort)
|
||||
if [ -z "${NATSORT_C}" ];then
|
||||
btpip install natsort
|
||||
fi
|
||||
|
||||
openssl_v=$(echo "$pip_list"|grep pyOpenSSL)
|
||||
if [ "$openssl_v" = "" ];then
|
||||
$mypip install pyOpenSSL
|
||||
@@ -110,9 +171,35 @@ if [ -z "$BROTLI_C" ]; then
|
||||
btpip install brotli
|
||||
fi
|
||||
|
||||
PYMYSQL_C=$(btpip list 2> /dev/null |grep PyMySQL)
|
||||
if [ -z "$PYMYSQL_C" ]; then
|
||||
btpip install PyMySQL
|
||||
fi
|
||||
|
||||
|
||||
PY_CRPYT=$(btpip list 2> /dev/null |grep cryptography|awk '{print $2}'|cut -f 1 -d '.')
|
||||
if [ "${PY_CRPYT}" -le "10" ];then
|
||||
btpip install pyOpenSSL==24.1.0
|
||||
btpip install cryptography==42.0.5
|
||||
fi
|
||||
|
||||
PYMYSQL_SSL_CHECK=$(btpython -c "import pymysql" 2>&1|grep "AttributeError: module 'cryptography.hazmat.bindings._rust.openssl'")
|
||||
if [ "${PYMYSQL_SSL_CHECK}" ];then
|
||||
btpip uninstall pyopenssl cryptography -y
|
||||
btpip install pyopenssl cryptography
|
||||
fi
|
||||
|
||||
btpip uninstall enum34 -y
|
||||
btpip install geoip2==4.7.0
|
||||
btpip install pandas
|
||||
|
||||
GEOIP_C=$(echo $pip_list|grep geoip2)
|
||||
if [ -z "${GEOIP_C}" ];then
|
||||
btpip install geoip2==4.7.0
|
||||
fi
|
||||
|
||||
# PANDAS_C=$(echo $pip_list|grep pandas)
|
||||
# if [ -z "${PANDAS_C}" ];then
|
||||
# btpip install pandas
|
||||
# fi
|
||||
|
||||
pymysql=$(echo "$pip_list"|grep pycryptodome)
|
||||
if [ "$pymysql" = "" ];then
|
||||
@@ -122,6 +209,11 @@ fi
|
||||
echo "修复面板依赖完成!"
|
||||
echo "==========================================="
|
||||
|
||||
RE_UPDATE=$(cat /www/server/panel/data/db/update)
|
||||
if [ "$RE_UPDATE" -ge "4" ];then
|
||||
echo "2" > /www/server/panel/data/db/update
|
||||
fi
|
||||
|
||||
#psutil=$(echo "$pip_list"|grep psutil|awk '{print $2}'|grep '5.7.')
|
||||
#if [ "$psutil" = "" ];then
|
||||
# $mypip install -U psutil
|
||||
|
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@ Route::post('/down/download_plugin', 'api/download_plugin');
|
||||
Route::post('/down/download_plugin_main', 'api/download_plugin_main');
|
||||
Route::post('/panel/get_soft_list_status', 'api/return_success');
|
||||
Route::post('/panel/get_unbinding', 'api/return_success');
|
||||
Route::post('/bt_cert', 'api/return_error');
|
||||
Route::post('/bt_cert', 'api/bt_cert');
|
||||
Route::post('/Auth/GetAuthToken', 'api/get_auth_token');
|
||||
Route::post('/Auth/GetBindCode', 'api/return_error');
|
||||
Route::any('/bt_monitor/update_history', 'api/btm_update_history');
|
||||
@@ -39,6 +39,7 @@ Route::group('api', function () {
|
||||
Route::get('/getUpdateLogs', 'api/get_update_logs');
|
||||
Route::get('/panel/get_version', 'api/get_version');
|
||||
Route::get('/wpanel/get_version', 'api/get_version_win');
|
||||
Route::get('/panel/get_panel_version', 'api/get_panel_version');
|
||||
Route::get('/SetupCount', 'api/setup_count');
|
||||
Route::any('/panel/updateLinux', 'api/check_update');
|
||||
Route::any('/wpanel/updateWindows', 'api/check_update_win');
|
||||
@@ -57,8 +58,8 @@ Route::group('api', function () {
|
||||
Route::post('/Cert/get_product_list', 'api/return_success');
|
||||
Route::get('/Pluginother/get_file', 'api/download_plugin_other');
|
||||
|
||||
Route::post('/Pluginother/create_order', 'api/return_error');
|
||||
Route::post('/Pluginother/renew_order', 'api/return_error');
|
||||
Route::post('/Pluginother/create_order', 'api/return_success');
|
||||
Route::post('/Pluginother/renew_order', 'api/return_success');
|
||||
Route::post('/Pluginother/order_stat', 'api/return_empty');
|
||||
Route::post('/Pluginother/re_order_stat', 'api/return_empty');
|
||||
Route::post('/Pluginother/create_order_okey', 'api/return_empty');
|
||||
@@ -119,6 +120,13 @@ Route::group('api', function () {
|
||||
Route::post('/bt_waf/reportInterceptFail', 'api/return_empty');
|
||||
Route::any('/panel/get_spider', 'api/get_spider');
|
||||
|
||||
Route::post('/Auth/GetSocre', 'api/get_ssl_list');
|
||||
Route::post('/Auth/SetSocre', 'api/get_ssl_list');
|
||||
Route::post('/Auth/SubmitScore', 'api/get_ssl_list');
|
||||
|
||||
Route::post('/Cert_cloud_deploy/get_cert_list', 'api/return_success');
|
||||
Route::post('/Cert_cloud_deploy/del_cert', 'api/return_success');
|
||||
|
||||
Route::miss('api/return_error');
|
||||
});
|
||||
|
||||
@@ -146,6 +154,7 @@ Route::group('admin', function () {
|
||||
Route::get('/deplist', 'admin/deplist');
|
||||
Route::get('/refresh_deplist', 'admin/refresh_deplist');
|
||||
Route::get('/cleancache', 'admin/cleancache');
|
||||
Route::any('/ssl', 'admin/ssl');
|
||||
|
||||
})->middleware(\app\middleware\CheckAdmin::class);
|
||||
|
||||
|
@@ -1,53 +1,54 @@
|
||||
#coding: utf-8
|
||||
# +-------------------------------------------------------------------
|
||||
# | 宝塔Linux面板
|
||||
# +-------------------------------------------------------------------
|
||||
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
# +-------------------------------------------------------------------
|
||||
# | Author: hwliang <hwl@bt.cn>
|
||||
# +-------------------------------------------------------------------
|
||||
|
||||
#+--------------------------------------------------------------------
|
||||
#| 插件和模块加载器
|
||||
#+--------------------------------------------------------------------
|
||||
|
||||
import public,os,sys,json
|
||||
|
||||
#获取插件列表(0/1)
|
||||
def get_plugin_list(force = 0):
|
||||
api_root_url = 'https://api.bt.cn'
|
||||
api_url = api_root_url+ '/panel/get_plugin_list'
|
||||
cache_file = 'data/plugin_list.json'
|
||||
|
||||
if force==0 and os.path.exists(cache_file):
|
||||
jsonData = public.readFile(cache_file)
|
||||
softList = json.loads(jsonData)
|
||||
else:
|
||||
try:
|
||||
jsonData = public.HttpGet(api_url)
|
||||
except Exception as ex:
|
||||
raise public.error_conn_cloud(str(ex))
|
||||
softList = json.loads(jsonData)
|
||||
if type(softList)!=dict or 'list' not in softList:
|
||||
if type(softList)==str:
|
||||
raise Exception(softList)
|
||||
else:
|
||||
raise Exception('云端插件列表获取失败')
|
||||
public.writeFile(cache_file, jsonData)
|
||||
return softList
|
||||
|
||||
#获取授权状态() 返回:0.免费版 1.专业版 2.企业版 -1.获取失败
|
||||
def get_auth_state():
|
||||
try:
|
||||
softList = get_plugin_list()
|
||||
if softList['ltd'] > -1:
|
||||
return 2
|
||||
elif softList['pro'] > -1:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
except:
|
||||
return -1
|
||||
|
||||
#执行插件方法(插件名,方法名,参数)
|
||||
def plugin_run(plugin_name, def_name, args):
|
||||
def plugin_run(plugin_name,def_name,args):
|
||||
'''
|
||||
@name 执行插件方法
|
||||
@param plugin_name<string> 插件名称
|
||||
@param def_name<string> 方法名称
|
||||
@param args<dict_obj> 参数对像
|
||||
@return mixed
|
||||
'''
|
||||
if not plugin_name or not def_name: return public.returnMsg(False,'插件名称和插件方法名称不能为空!')
|
||||
if not path_check(plugin_name) or not path_check(def_name): return public.returnMsg(False,'插件名或方法名不能包含特殊符号!')
|
||||
p_path = public.get_plugin_path(plugin_name)
|
||||
if not os.path.exists(p_path + '/index.php') and not os.path.exists(p_path + '/%s_main.py' % plugin_name): return public.returnMsg(False,'插件不存在!')
|
||||
|
||||
is_php = os.path.exists(p_path + '/index.php')
|
||||
# 获取插件目录
|
||||
plugin_path = public.get_plugin_path(plugin_name)
|
||||
is_php = os.path.exists(os.path.join(plugin_path,'index.php'))
|
||||
|
||||
# 检查插件目录是否合法
|
||||
if is_php:
|
||||
plugin_file = os.path.join(plugin_path,'index.php')
|
||||
else:
|
||||
plugin_file = os.path.join(plugin_path, plugin_name + '_main.py')
|
||||
if not public.path_safe_check(plugin_file): return public.returnMsg(False,'插件路径不合法')
|
||||
|
||||
# 检查插件入口文件是否存在
|
||||
if not os.path.exists(plugin_file): return public.returnMsg(False,'指定插件入口文件不存在')
|
||||
|
||||
# 添加插件目录到系统路径
|
||||
public.sys_path_append(plugin_path)
|
||||
|
||||
if not is_php:
|
||||
public.package_path_append(p_path)
|
||||
plugin_main = __import__(plugin_name + '_main')
|
||||
# 引用插件入口文件
|
||||
_name = "{}_main".format(plugin_name)
|
||||
plugin_main = __import__(_name)
|
||||
|
||||
# 检查类名是否符合规范
|
||||
if not hasattr(plugin_main,_name):
|
||||
return public.returnMsg(False,'指定插件入口文件不符合规范')
|
||||
|
||||
try:
|
||||
if sys.version_info[0] == 2:
|
||||
reload(plugin_main)
|
||||
@@ -56,77 +57,161 @@ def plugin_run(plugin_name, def_name, args):
|
||||
reload(plugin_main)
|
||||
except:
|
||||
pass
|
||||
plu = eval('plugin_main.' + plugin_name + '_main()')
|
||||
if not hasattr(plu, def_name):
|
||||
|
||||
# 实例化插件类
|
||||
plugin_obj = getattr(plugin_main,_name)()
|
||||
|
||||
# 检查方法是否存在
|
||||
if not hasattr(plugin_obj,def_name):
|
||||
return public.returnMsg(False,'在[%s]插件中找不到[%s]方法' % (plugin_name,def_name))
|
||||
|
||||
if 'plugin_get_object' in args and args.plugin_get_object == 1:
|
||||
if not is_php:
|
||||
return getattr(plu, def_name)
|
||||
else:
|
||||
|
||||
if args is not None and 'plugin_get_object' in args and args.plugin_get_object == 1:
|
||||
return getattr(plugin_obj, def_name)
|
||||
|
||||
# 执行方法
|
||||
return getattr(plugin_obj,def_name)(args)
|
||||
else:
|
||||
if args is not None and 'plugin_get_object' in args and args.plugin_get_object == 1:
|
||||
return None
|
||||
else:
|
||||
if not is_php:
|
||||
data = eval('plu.' + def_name + '(args)')
|
||||
else:
|
||||
import panelPHP
|
||||
args.s = def_name
|
||||
args.name = plugin_name
|
||||
data = panelPHP.panelPHP(plugin_name).exec_php_script(args)
|
||||
return data
|
||||
import panelPHP
|
||||
args.s = def_name
|
||||
args.name = plugin_name
|
||||
return panelPHP.panelPHP(plugin_name).exec_php_script(args)
|
||||
|
||||
|
||||
#执行模块方法(模块名,方法名,参数)
|
||||
def module_run(mod_name, def_name, args):
|
||||
if not mod_name or not def_name: return public.returnMsg(False,'模块名称和模块方法名称不能为空!')
|
||||
if not path_check(mod_name) or not path_check(def_name): return public.returnMsg(False,'模块名或方法名不能包含特殊符号!')
|
||||
def get_module_list():
|
||||
'''
|
||||
@name 获取模块列表
|
||||
@return list
|
||||
'''
|
||||
module_list = []
|
||||
class_path = public.get_class_path()
|
||||
for name in os.listdir(class_path):
|
||||
path = os.path.join(class_path,name)
|
||||
# 过滤无效文件
|
||||
if not name or name.endswith('.py') or name[0] == '.' or not name.endswith('Model') or os.path.isfile(path):continue
|
||||
module_list.append(name)
|
||||
return module_list
|
||||
|
||||
def module_run(module_name,def_name,args):
|
||||
'''
|
||||
@name 执行模块方法
|
||||
@param module_name<string> 模块名称
|
||||
@param def_name<string> 方法名称
|
||||
@param args<dict_obj> 参数对像
|
||||
@return mixed
|
||||
'''
|
||||
if not module_name or not def_name: return public.returnMsg(False,'模块名称和模块方法名称不能为空!')
|
||||
model_index = args.get('model_index',None)
|
||||
class_path = public.get_class_path()
|
||||
panel_path = public.get_panel_path()
|
||||
|
||||
module_file = None
|
||||
if 'model_index' in args:
|
||||
if args.model_index:
|
||||
mod_file = "{}/{}Model/{}Model.py".format(public.get_class_path(),args.model_index,mod_name)
|
||||
# 新模块目录
|
||||
if model_index in ['mod']:
|
||||
module_file = os.path.join(panel_path,'mod','project',module_name + 'Mod.py')
|
||||
elif model_index:
|
||||
# 旧模块目录
|
||||
module_file = os.path.join(class_path,model_index+"Model",module_name + 'Model.py')
|
||||
else:
|
||||
mod_file = "{}/projectModel/{}Model.py".format(public.get_class_path(),mod_name)
|
||||
module_file = os.path.join(class_path,"projectModel",module_name + 'Model.py')
|
||||
else:
|
||||
# 如果没指定模块名称,则遍历所有模块目录
|
||||
module_list = get_module_list()
|
||||
for module_dir in module_list:
|
||||
mod_file = "{}/{}/{}Model.py".format(public.get_class_path(),module_dir,mod_name)
|
||||
if os.path.exists(mod_file): break
|
||||
for name in module_list:
|
||||
module_file = os.path.join(class_path,name,module_name + 'Model.py')
|
||||
if os.path.exists(module_file): break
|
||||
|
||||
# 判断模块入口文件是否存在
|
||||
if not os.path.exists(module_file):
|
||||
return public.returnMsg(False,'模块[%s]不存在' % module_name)
|
||||
|
||||
# 判断模块路径是否合法
|
||||
if not public.path_safe_check(module_file):
|
||||
return public.returnMsg(False,'模块路径不合法')
|
||||
|
||||
def_object = public.get_script_object(module_file)
|
||||
if not def_object: return public.returnMsg(False,'模块[%s]不存在' % module_name)
|
||||
|
||||
if not os.path.exists(mod_file):
|
||||
return public.returnMsg(False,'模块[%s]不存在' % mod_name)
|
||||
|
||||
def_object = public.get_script_object(mod_file)
|
||||
if not def_object: return public.returnMsg(False,'模块[%s]不存在!' % mod_name)
|
||||
# 模块实例化并返回方法对象
|
||||
try:
|
||||
run_object = getattr(def_object.main(),def_name,None)
|
||||
except:
|
||||
return public.returnMsg(False,'模块入口实例化失败' % mod_name)
|
||||
if not run_object: return public.returnMsg(False,'在[%s]模块中找不到[%s]方法' % (mod_name,def_name))
|
||||
return public.returnMsg(False,'模块[%s]入口实例化失败' % module_name)
|
||||
if not run_object: return public.returnMsg(False,'在[%s]模块中找不到[%s]方法' % (module_name,def_name))
|
||||
|
||||
if 'module_get_object' in args and args.module_get_object == 1:
|
||||
return run_object
|
||||
|
||||
# 执行方法
|
||||
result = run_object(args)
|
||||
return result
|
||||
|
||||
|
||||
#获取模块文件夹列表
|
||||
def get_module_list():
|
||||
list = []
|
||||
class_path = public.get_class_path()
|
||||
f_list = os.listdir(class_path)
|
||||
for fname in f_list:
|
||||
f_path = class_path+'/'+fname
|
||||
if os.path.isdir(f_path) and len(fname) > 6 and fname.find('.') == -1 and fname.find('Model') != -1:
|
||||
list.append(fname)
|
||||
return list
|
||||
def get_plugin_list(upgrade_force = False):
|
||||
'''
|
||||
@name 获取插件列表
|
||||
@param upgrade_force<bool> 是否强制重新获取列表
|
||||
@return dict
|
||||
'''
|
||||
|
||||
#检查路径是否合法
|
||||
def path_check(path):
|
||||
list = ["./","..",",",";",":","?","'","\"","<",">","|","\\","\n","\r","\t","\b","\a","\f","\v","*","%","&","$","#","@","!","~","`","^","(",")","+","=","{","}","[","]"]
|
||||
for i in path:
|
||||
if i in list:
|
||||
return False
|
||||
return True
|
||||
api_root_url = 'https://api.bt.cn'
|
||||
api_url = api_root_url+ '/panel/get_plugin_list'
|
||||
panel_path = public.get_panel_path()
|
||||
data_path = os.path.join(panel_path,'data')
|
||||
|
||||
if not os.path.exists(data_path):
|
||||
os.makedirs(data_path,384)
|
||||
|
||||
plugin_list = {}
|
||||
plugin_list_file = os.path.join(data_path,'plugin_list.json')
|
||||
if os.path.exists(plugin_list_file) and not upgrade_force:
|
||||
plugin_list_body = public.readFile(plugin_list_file)
|
||||
try:
|
||||
plugin_list = json.loads(plugin_list_body)
|
||||
except:
|
||||
plugin_list = {}
|
||||
|
||||
if not os.path.exists(plugin_list_file) or upgrade_force or not plugin_list:
|
||||
try:
|
||||
res = public.HttpGet(api_url)
|
||||
except Exception as ex:
|
||||
raise public.error_conn_cloud(str(ex))
|
||||
if not res: raise Exception(False,'云端插件列表获取失败')
|
||||
|
||||
plugin_list = json.loads(res)
|
||||
if type(plugin_list)!=dict or 'list' not in plugin_list:
|
||||
if type(plugin_list)==str:
|
||||
raise Exception(plugin_list)
|
||||
else:
|
||||
raise Exception('云端插件列表获取失败')
|
||||
public.writeFile(plugin_list_file,json.dumps(plugin_list))
|
||||
|
||||
return plugin_list
|
||||
|
||||
|
||||
def start_total():
|
||||
'''
|
||||
@name 启动统计服务
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
def get_soft_list(args):
|
||||
'''
|
||||
@name 获取软件列表
|
||||
@param args<dict_obj> 参数对像
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
#数据加密
|
||||
def db_encrypt(data):
|
||||
'''
|
||||
@name 数据库加密
|
||||
@param args<dict_obj> 参数对像
|
||||
@return dict
|
||||
'''
|
||||
try:
|
||||
key = __get_db_sgin()
|
||||
iv = __get_db_iv()
|
||||
@@ -143,8 +228,12 @@ def db_encrypt(data):
|
||||
}
|
||||
return result
|
||||
|
||||
#数据解密
|
||||
def db_decrypt(data):
|
||||
'''
|
||||
@name 数据库解密
|
||||
@param args<dict_obj> 参数对像
|
||||
@return dict
|
||||
'''
|
||||
try:
|
||||
key = __get_db_sgin()
|
||||
iv = __get_db_iv()
|
||||
@@ -215,3 +304,49 @@ def __aes_encrypt(data, key, iv):
|
||||
encryptedbytes = aes.encrypt(data)
|
||||
en_text = base64.b64encode(encryptedbytes)
|
||||
return en_text.decode('utf-8')
|
||||
|
||||
def plugin_end():
|
||||
'''
|
||||
@name 插件到期处理
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
def daemon_task():
|
||||
'''
|
||||
@name 后台任务守护
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
def daemon_panel():
|
||||
'''
|
||||
@name 面板守护
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
def flush_auth_key():
|
||||
'''
|
||||
@name 刷新授权密钥
|
||||
@return dict
|
||||
'''
|
||||
pass
|
||||
|
||||
def get_auth_state():
|
||||
'''
|
||||
@name 获取授权状态
|
||||
@return 返回:0.免费版 1.专业版 2.企业版 -1.获取失败
|
||||
'''
|
||||
try:
|
||||
softList = get_plugin_list()
|
||||
if softList['ltd'] > -1:
|
||||
return 2
|
||||
elif softList['pro'] > -1:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
except:
|
||||
return -1
|
||||
|
||||
|
@@ -1,369 +1,394 @@
|
||||
/*
|
||||
*宝塔面板去除各种计算题与延时等待
|
||||
*/
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("show_confirm")){
|
||||
bt.show_confirm = function(title, msg, fun, error) {
|
||||
if (error == undefined) {
|
||||
error = ""
|
||||
}
|
||||
var mess = layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class='bt-form webDelete pd20 pb70'><p>" + msg + "</p>" + error + "<div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm bt-cancel'>" + lan.public.cancel + "</button> <button type='button' id='toSubmit' class='btn btn-success btn-sm' >" + lan.public.ok + "</button></div></div>"
|
||||
});
|
||||
$(".bt-cancel").click(function () {
|
||||
layer.close(mess);
|
||||
});
|
||||
$("#toSubmit").click(function () {
|
||||
layer.close(mess);
|
||||
fun();
|
||||
})
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("prompt_confirm")){
|
||||
bt.prompt_confirm = function (title, msg, callback) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
btn: ['确认', '取消'],
|
||||
content: "<div class='bt-form promptDelete pd20'>\
|
||||
<p>" + msg + "</p>\
|
||||
</div>",
|
||||
yes: function (layers, index) {
|
||||
layer.close(layers)
|
||||
if (callback) callback()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("compute_confirm")){
|
||||
bt.compute_confirm = function (config, callback) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: config.title,
|
||||
area: '430px',
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
btn: [lan['public'].ok, lan['public'].cancel],
|
||||
content:
|
||||
'<div class="bt-form hint_confirm pd30">\
|
||||
<div class="hint_title">\
|
||||
<i class="hint-confirm-icon"></i>\
|
||||
<div class="hint_con">' +
|
||||
config.msg +
|
||||
'</div>\
|
||||
</div>\
|
||||
</div>',
|
||||
yes: function (layers, index) {
|
||||
layer.close(layers)
|
||||
if (callback) callback()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof database && database.hasOwnProperty("del_database")){
|
||||
database.del_database = function (wid, dbname,obj, callback) {
|
||||
var title = '',
|
||||
tips = '是否确认【删除数据库】,删除后可能会影响业务使用!';
|
||||
if(obj && obj.db_type > 0) tips = '远程数据库不支持数据库回收站,删除后将无法恢复,请谨慎操作';
|
||||
title = typeof dbname === "function" ?'批量删除数据库':'删除数据库 [ '+ dbname +' ]';
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
icon:0,
|
||||
skin:'delete_site_layer',
|
||||
area: "530px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content:"<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
"<i class=\'layui-layer-ico layui-layer-ico0\'></i>" +
|
||||
"<div class=\'f13 check_title\' style=\'margin-bottom: 20px;\'>"+tips+"</div>" +
|
||||
"<div style=\'color:red;margin:18px 0 18px 18px;font-size:14px;font-weight: bold;\'>注意:数据无价,请谨慎操作!!!"+(!recycle_bin_db_open?'<br>风险操作:当前数据库回收站未开启,删除数据库将永久消失!':'')+"</div>" +
|
||||
"</div>",
|
||||
btn:[lan.public.ok,lan.public.cancel],
|
||||
yes:function(indexs){
|
||||
var data = {id: wid,name: dbname};
|
||||
if(typeof dbname === "function"){
|
||||
delete data.id;
|
||||
delete data.name;
|
||||
}
|
||||
layer.close(indexs)
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof dbname === "function" ?'二次验证信息,批量删除数据库':'二次验证信息,删除数据库 [ ' + dbname + ' ]';
|
||||
var loadT = bt.load('正在检测数据库数据信息,请稍后...')
|
||||
|
||||
bt_tools.send({url:'database/'+bt.data.db_tab_name+'/check_del_data',data:{data:JSON.stringify({ids: ids})}},function(res){
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认是否要删除以下数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止数据库被误删</span></div>' +
|
||||
'</div>',
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
var filterData = rdata.filter(function(el){
|
||||
return ids.indexOf(el.id) != -1
|
||||
})
|
||||
for (var i = 0; i < filterData.length; i++) {
|
||||
var item = filterData[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
database_html = (function(item){
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.total,
|
||||
database_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.name + '">数据库:' + item.name + '</span>' +
|
||||
'<span title="' + t_size+'">大小:' + f_size +'</span>' +
|
||||
'<span title="' + (is_time_rule && item.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time+'">创建时间:<i ' + (is_time_rule && item.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if(database_html !== '') html += '<div class="check_layer_item">' + database_html +'</div>';
|
||||
}
|
||||
if(html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes:function(indes,layers){
|
||||
if(typeof dbname === "function"){
|
||||
dbname(data)
|
||||
}else{
|
||||
bt.database.del_database(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) database_table.$refresh_table_list(true);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof site && site.hasOwnProperty("del_site")){
|
||||
site.del_site = function(wid, wname, callback) {
|
||||
var title = typeof wname === "function" ? '批量删除站点' : '删除站点 [ ' + wname + ' ]';
|
||||
recycle_bin_open = bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle") == null ? true : false
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
icon: 0,
|
||||
skin: 'delete_site_layer',
|
||||
area: "440px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
"<div class=\'f13 check_title\'>是否要删除关联的FTP、数据库、站点目录!</div>" +
|
||||
"<div class=\"check_type_group\">" +
|
||||
"<label><input type=\"checkbox\" name=\"ftp\"><span>FTP</span></label>" +
|
||||
"<label><input type=\"checkbox\" name=\"database\"><span>数据库</span>" + (!recycle_bin_db_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"<label><input type=\"checkbox\" name=\"path\"><span>站点目录</span>" + (!recycle_bin_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
btn: [lan.public.ok, lan.public.cancel],
|
||||
success: function (layers, indexs) {
|
||||
$(layers).find('.check_type_group label').hover(function () {
|
||||
var name = $(this).find('input').attr('name');
|
||||
if (name === 'data' && !recycle_bin_db_open) {
|
||||
layer.tips('风险操作:当前数据库回收站未开启,删除数据库将永久消失!', this, { tips: [1, 'red'], time: 0 })
|
||||
} else if (name === 'path' && !recycle_bin_open) {
|
||||
layer.tips('风险操作:当前文件回收站未开启,删除站点目录将永久消失!', this, { tips: [1, 'red'], time: 0 })
|
||||
}
|
||||
}, function () {
|
||||
layer.closeAll('tips');
|
||||
})
|
||||
},
|
||||
yes: function (indexs) {
|
||||
var data = { id: wid, webname: wname };
|
||||
$('#site_delete_form input[type=checkbox]').each(function (index, item) {
|
||||
if ($(item).is(':checked')) data[$(item).attr('name')] = 1
|
||||
})
|
||||
var is_database = data.hasOwnProperty('database'), is_path = data.hasOwnProperty('path'), is_ftp = data.hasOwnProperty('ftp');
|
||||
if ((!is_database && !is_path) && (!is_ftp || is_ftp)) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
return false;
|
||||
}
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.close(indexs);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (typeof wname === "function") {
|
||||
delete data.id;
|
||||
delete data.webname;
|
||||
}
|
||||
layer.close(indexs)
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof wname === "function" ? '二次验证信息,批量删除站点' : '二次验证信息,删除站点 [ ' + wname + ' ]';
|
||||
var loadT = bt.load('正在检测站点数据信息,请稍后...')
|
||||
bt.send('check_del_data', 'site/check_del_data', { ids: ids }, function (res) {
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认以下要删除的数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (data.database && recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_error ' + (data.path && recycle_bin_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启文件回收站功能,删除站点目录后,站点目录将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止网站数据被误删</span></div>' +
|
||||
'</div>',
|
||||
// recycle_bin_db_open &&
|
||||
// recycle_bin_open &&
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var item = rdata[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
site_html = (function (item) {
|
||||
if (!is_path) return ''
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_path_rule = res.file_size <= item.total,
|
||||
dir_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
dir_size = bt.format_size(item.total);
|
||||
|
||||
var f_html = '<i ' + (is_path_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + dir_size + '</i> ' + (is_path_rule ? t_icon : '');
|
||||
var f_title = (is_path_rule ? '注意:此目录较大,可能为重要数据,请谨慎操作.\n' : '') + '目录:' + item.path + '(' + (item.limit ? '大于' : '') + dir_size + ')';
|
||||
|
||||
return '<div class="check_layer_site">' +
|
||||
'<span title="站点:' + item.name + '">站点名:' + item.name + '</span>' +
|
||||
'<span title="' + f_title + '" >目录:<span style="vertical-align: middle;max-width: 160px;width: auto;">' + item.path + '</span> (' + f_html + ')</span>' +
|
||||
'<span title="' + (is_time_rule ? '注意:此站点创建时间较早,可能为重要数据,请谨慎操作.\n' : '') + '时间:' + dir_time + '">创建时间:<i ' + (is_time_rule ? 'class="warning"' : '') + '>' + dir_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item)),
|
||||
database_html = (function (item) {
|
||||
if (!is_database || !item.database) return '';
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.database.total,
|
||||
database_time = bt.format_data(item.database.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.database.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.database.name + '">数据库:' + item.database.name + '</span>' +
|
||||
'<span title="' + t_size + '">大小:' + f_size + '</span>' +
|
||||
'<span title="' + (is_time_rule && item.database.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time + '">创建时间:<i ' + (is_time_rule && item.database.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if ((site_html + database_html) !== '') html += '<div class="check_layer_item">' + site_html + database_html + '</div>';
|
||||
}
|
||||
if (html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes: function (indes, layers) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
} else {
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) site.get_list();
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
if(bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle")==null){
|
||||
$('[name="path"]').attr('checked',true)
|
||||
}else{
|
||||
$('[name="path"]').removeProp('checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("firewall") && bt.firewall.hasOwnProperty("add_accept_port")){
|
||||
bt.firewall.add_accept_port = function(type, port, ps, callback) {
|
||||
var action = "AddDropAddress";
|
||||
if (type == 'port') {
|
||||
ports = port.split(':');
|
||||
if (port.indexOf('-') != -1) ports = port.split('-');
|
||||
for (var i = 0; i < ports.length; i++) {
|
||||
if (!bt.check_port(ports[i])) {
|
||||
layer.msg(lan.firewall.port_err, { icon: 5 });
|
||||
return;
|
||||
}
|
||||
}
|
||||
action = "AddAcceptPort";
|
||||
}
|
||||
|
||||
loading = bt.load();
|
||||
bt.send(action, 'firewall/' + action, { port: port, type: type, ps: ps }, function(rdata) {
|
||||
loading.close();
|
||||
if (callback) callback(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
function SafeMessage(j, h, g, f) {
|
||||
if(f == undefined) {
|
||||
f = ""
|
||||
}
|
||||
var mess = layer.open({
|
||||
type: 1,
|
||||
title: j,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class='bt-form webDelete pd20 pb70'><p>" + h + "</p>" + f + "<div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm bt-cancel'>"+lan.public.cancel+"</button> <button type='button' id='toSubmit' class='btn btn-success btn-sm' >"+lan.public.ok+"</button></div></div>"
|
||||
});
|
||||
$(".bt-cancel").click(function(){
|
||||
layer.close(mess);
|
||||
});
|
||||
$("#toSubmit").click(function() {
|
||||
layer.close(mess);
|
||||
g();
|
||||
})
|
||||
}
|
||||
$(document).ready(function () {
|
||||
if($('#updata_pro_info').length>0){
|
||||
$('#updata_pro_info').html('');
|
||||
bt.set_cookie('productPurchase', 1);
|
||||
}
|
||||
/*
|
||||
*宝塔面板去除各种计算题与延时等待
|
||||
*/
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("show_confirm")){
|
||||
bt.show_confirm = function(title, msg, fun, error) {
|
||||
if (error == undefined) {
|
||||
error = ""
|
||||
}
|
||||
var mess = layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class='bt-form webDelete pd20 pb70'><p>" + msg + "</p>" + error + "<div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm bt-cancel'>" + lan.public.cancel + "</button> <button type='button' id='toSubmit' class='btn btn-success btn-sm' >" + lan.public.ok + "</button></div></div>"
|
||||
});
|
||||
$(".bt-cancel").click(function () {
|
||||
layer.close(mess);
|
||||
});
|
||||
$("#toSubmit").click(function () {
|
||||
layer.close(mess);
|
||||
fun();
|
||||
})
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("prompt_confirm")){
|
||||
bt.prompt_confirm = function (title, msg, callback) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
btn: ['确认', '取消'],
|
||||
content: "<div class='bt-form promptDelete pd20'>\
|
||||
<p>" + msg + "</p>\
|
||||
</div>",
|
||||
yes: function (layers, index) {
|
||||
layer.close(layers)
|
||||
if (callback) callback()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("compute_confirm")){
|
||||
bt.compute_confirm = function (config, callback) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: config.title,
|
||||
area: '430px',
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
btn: [lan['public'].ok, lan['public'].cancel],
|
||||
content:
|
||||
'<div class="bt-form hint_confirm pd30">\
|
||||
<div class="hint_title">\
|
||||
<i class="hint-confirm-icon"></i>\
|
||||
<div class="hint_con">' +
|
||||
config.msg +
|
||||
'</div>\
|
||||
</div>\
|
||||
</div>',
|
||||
yes: function (layers, index) {
|
||||
layer.close(layers)
|
||||
if (callback) callback()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("input_confirm")){
|
||||
bt.input_confirm = function (config, callback) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: config.title,
|
||||
area: '430px',
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
btn: [lan['public'].ok, lan['public'].cancel],
|
||||
content:
|
||||
'<div class="bt-form hint_confirm pd30">\
|
||||
<div class="hint_title">\
|
||||
<i class="hint-confirm-icon"></i>\
|
||||
<div class="hint_con">' +
|
||||
config.msg +
|
||||
'</div>\
|
||||
</div>\
|
||||
</div>',
|
||||
yes: function (layers, index) {
|
||||
layer.close(layers);
|
||||
if (callback) callback();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof database && database.hasOwnProperty("del_database")){
|
||||
database.del_database = function (wid, dbname,obj, callback) {
|
||||
var title = '',
|
||||
tips = '是否确认【删除数据库】,删除后可能会影响业务使用!';
|
||||
if(obj && obj.db_type > 0) tips = '远程数据库不支持数据库回收站,删除后将无法恢复,请谨慎操作';
|
||||
title = typeof dbname === "function" ?'批量删除数据库':'删除数据库 [ '+ dbname +' ]';
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
icon:0,
|
||||
skin:'delete_site_layer',
|
||||
area: "530px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content:"<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
"<i class=\'layui-layer-ico layui-layer-ico0\'></i>" +
|
||||
"<div class=\'f13 check_title\' style=\'margin-bottom: 20px;\'>"+tips+"</div>" +
|
||||
"<div style=\'color:red;margin:18px 0 18px 18px;font-size:14px;font-weight: bold;\'>注意:数据无价,请谨慎操作!!!"+(!recycle_bin_db_open?'<br>风险操作:当前数据库回收站未开启,删除数据库将永久消失!':'')+"</div>" +
|
||||
"</div>",
|
||||
btn:[lan.public.ok,lan.public.cancel],
|
||||
yes:function(indexs){
|
||||
var data = {id: wid,name: dbname};
|
||||
if(typeof dbname === "function"){
|
||||
delete data.id;
|
||||
delete data.name;
|
||||
}
|
||||
layer.close(indexs)
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof dbname === "function" ?'二次验证信息,批量删除数据库':'二次验证信息,删除数据库 [ ' + dbname + ' ]';
|
||||
var loadT = bt.load('正在检测数据库数据信息,请稍后...')
|
||||
|
||||
bt_tools.send({url:'database/'+bt.data.db_tab_name+'/check_del_data',data:{data:JSON.stringify({ids: ids})}},function(res){
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认是否要删除以下数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止数据库被误删</span></div>' +
|
||||
'</div>',
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
var filterData = rdata.filter(function(el){
|
||||
return ids.indexOf(el.id) != -1
|
||||
})
|
||||
for (var i = 0; i < filterData.length; i++) {
|
||||
var item = filterData[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
database_html = (function(item){
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.total,
|
||||
database_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.name + '">数据库:' + item.name + '</span>' +
|
||||
'<span title="' + t_size+'">大小:' + f_size +'</span>' +
|
||||
'<span title="' + (is_time_rule && item.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time+'">创建时间:<i ' + (is_time_rule && item.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if(database_html !== '') html += '<div class="check_layer_item">' + database_html +'</div>';
|
||||
}
|
||||
if(html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes:function(indes,layers){
|
||||
if(typeof dbname === "function"){
|
||||
dbname(data)
|
||||
}else{
|
||||
bt.database.del_database(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) database_table.$refresh_table_list(true);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof site && site.hasOwnProperty("del_site")){
|
||||
site.del_site = function(wid, wname, callback) {
|
||||
var title = typeof wname === "function" ? '批量删除站点' : '删除站点 [ ' + wname + ' ]';
|
||||
recycle_bin_open = bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle") == null ? true : false
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
icon: 0,
|
||||
skin: 'delete_site_layer',
|
||||
area: "440px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
"<div class=\'f13 check_title\'>是否要删除关联的FTP、数据库、站点目录!</div>" +
|
||||
"<div class=\"check_type_group\">" +
|
||||
"<label><input type=\"checkbox\" name=\"ftp\"><span>FTP</span></label>" +
|
||||
"<label><input type=\"checkbox\" name=\"database\"><span>数据库</span>" + (!recycle_bin_db_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"<label><input type=\"checkbox\" name=\"path\"><span>站点目录</span>" + (!recycle_bin_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
btn: [lan.public.ok, lan.public.cancel],
|
||||
success: function (layers, indexs) {
|
||||
$(layers).find('.check_type_group label').hover(function () {
|
||||
var name = $(this).find('input').attr('name');
|
||||
if (name === 'data' && !recycle_bin_db_open) {
|
||||
layer.tips('风险操作:当前数据库回收站未开启,删除数据库将永久消失!', this, { tips: [1, 'red'], time: 0 })
|
||||
} else if (name === 'path' && !recycle_bin_open) {
|
||||
layer.tips('风险操作:当前文件回收站未开启,删除站点目录将永久消失!', this, { tips: [1, 'red'], time: 0 })
|
||||
}
|
||||
}, function () {
|
||||
layer.closeAll('tips');
|
||||
})
|
||||
},
|
||||
yes: function (indexs) {
|
||||
var data = { id: wid, webname: wname };
|
||||
$('#site_delete_form input[type=checkbox]').each(function (index, item) {
|
||||
if ($(item).is(':checked')) data[$(item).attr('name')] = 1
|
||||
})
|
||||
var is_database = data.hasOwnProperty('database'), is_path = data.hasOwnProperty('path'), is_ftp = data.hasOwnProperty('ftp');
|
||||
if ((!is_database && !is_path) && (!is_ftp || is_ftp)) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
return false;
|
||||
}
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.close(indexs);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (typeof wname === "function") {
|
||||
delete data.id;
|
||||
delete data.webname;
|
||||
}
|
||||
layer.close(indexs)
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof wname === "function" ? '二次验证信息,批量删除站点' : '二次验证信息,删除站点 [ ' + wname + ' ]';
|
||||
var loadT = bt.load('正在检测站点数据信息,请稍后...')
|
||||
bt.send('check_del_data', 'site/check_del_data', { ids: ids }, function (res) {
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认以下要删除的数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (data.database && recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_error ' + (data.path && recycle_bin_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启文件回收站功能,删除站点目录后,站点目录将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止网站数据被误删</span></div>' +
|
||||
'</div>',
|
||||
// recycle_bin_db_open &&
|
||||
// recycle_bin_open &&
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var item = rdata[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
site_html = (function (item) {
|
||||
if (!is_path) return ''
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_path_rule = res.file_size <= item.total,
|
||||
dir_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
dir_size = bt.format_size(item.total);
|
||||
|
||||
var f_html = '<i ' + (is_path_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + dir_size + '</i> ' + (is_path_rule ? t_icon : '');
|
||||
var f_title = (is_path_rule ? '注意:此目录较大,可能为重要数据,请谨慎操作.\n' : '') + '目录:' + item.path + '(' + (item.limit ? '大于' : '') + dir_size + ')';
|
||||
|
||||
return '<div class="check_layer_site">' +
|
||||
'<span title="站点:' + item.name + '">站点名:' + item.name + '</span>' +
|
||||
'<span title="' + f_title + '" >目录:<span style="vertical-align: middle;max-width: 160px;width: auto;">' + item.path + '</span> (' + f_html + ')</span>' +
|
||||
'<span title="' + (is_time_rule ? '注意:此站点创建时间较早,可能为重要数据,请谨慎操作.\n' : '') + '时间:' + dir_time + '">创建时间:<i ' + (is_time_rule ? 'class="warning"' : '') + '>' + dir_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item)),
|
||||
database_html = (function (item) {
|
||||
if (!is_database || !item.database) return '';
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.database.total,
|
||||
database_time = bt.format_data(item.database.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.database.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.database.name + '">数据库:' + item.database.name + '</span>' +
|
||||
'<span title="' + t_size + '">大小:' + f_size + '</span>' +
|
||||
'<span title="' + (is_time_rule && item.database.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time + '">创建时间:<i ' + (is_time_rule && item.database.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if ((site_html + database_html) !== '') html += '<div class="check_layer_item">' + site_html + database_html + '</div>';
|
||||
}
|
||||
if (html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes: function (indes, layers) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
} else {
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) site.get_list();
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
if(bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle")==null){
|
||||
$('[name="path"]').attr('checked',true)
|
||||
}else{
|
||||
$('[name="path"]').removeProp('checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("firewall") && bt.firewall.hasOwnProperty("add_accept_port")){
|
||||
bt.firewall.add_accept_port = function(type, port, ps, callback) {
|
||||
var action = "AddDropAddress";
|
||||
if (type == 'port') {
|
||||
ports = port.split(':');
|
||||
if (port.indexOf('-') != -1) ports = port.split('-');
|
||||
for (var i = 0; i < ports.length; i++) {
|
||||
if (!bt.check_port(ports[i])) {
|
||||
layer.msg(lan.firewall.port_err, { icon: 5 });
|
||||
return;
|
||||
}
|
||||
}
|
||||
action = "AddAcceptPort";
|
||||
}
|
||||
|
||||
loading = bt.load();
|
||||
bt.send(action, 'firewall/' + action, { port: port, type: type, ps: ps }, function(rdata) {
|
||||
loading.close();
|
||||
if (callback) callback(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
function SafeMessage(j, h, g, f) {
|
||||
if(f == undefined) {
|
||||
f = ""
|
||||
}
|
||||
var mess = layer.open({
|
||||
type: 1,
|
||||
title: j,
|
||||
area: "350px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: "<div class='bt-form webDelete pd20 pb70'><p>" + h + "</p>" + f + "<div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm bt-cancel'>"+lan.public.cancel+"</button> <button type='button' id='toSubmit' class='btn btn-success btn-sm' >"+lan.public.ok+"</button></div></div>"
|
||||
});
|
||||
$(".bt-cancel").click(function(){
|
||||
layer.close(mess);
|
||||
});
|
||||
$("#toSubmit").click(function() {
|
||||
layer.close(mess);
|
||||
g();
|
||||
})
|
||||
}
|
||||
$(document).ready(function () {
|
||||
if($('#updata_pro_info').length>0){
|
||||
$('#updata_pro_info').html('');
|
||||
bt.set_cookie('productPurchase', 1);
|
||||
}
|
||||
})
|
@@ -14,12 +14,18 @@
|
||||
|
||||
- 全局搜索替换 https://api.bt.cn => http://www.example.com
|
||||
|
||||
- 全局搜索替换 https://www.bt.cn/api/ => http://www.example.com/api/(需排除clearModel.py、scanningModel.py、ipsModel.py)
|
||||
- 全局搜索替换 https://www.bt.cn/api/ => http://www.example.com/api/(需排除clearModel.py、scanningModel.py、ipsModel.py、js文件)
|
||||
|
||||
- 全局搜索替换 http://www.bt.cn/api/ => http://www.example.com/api/(需排除js文件)
|
||||
|
||||
- 全局搜索替换 https://download.bt.cn/install/update6.sh => http://www.example.com/install/update6.sh
|
||||
|
||||
http://download.bt.cn/install/update6.sh => http://www.example.com/install/update6.sh
|
||||
|
||||
http://download.bt.cn/install/update/ => http://www.example.com/install/update/
|
||||
|
||||
- 搜索并删除提交异常报告的代码 bt_error/index.php
|
||||
|
||||
- class/ajax.py 文件 \# 是否执行升级程序 下面的 public.get_url() 改成 public.GetConfigValue('home')
|
||||
|
||||
class/jobs.py 文件 \#尝试升级到独立环境 下面的 public.get_url() 改成 public.GetConfigValue('home')
|
||||
@@ -42,6 +48,8 @@
|
||||
|
||||
在 def check_domain_cloud(domain): 这一行下面加上 return
|
||||
|
||||
在 def err_collect 这一行下面加上 return
|
||||
|
||||
在 def get_improvement(): 这一行下面加上 return False
|
||||
|
||||
在free_login_area方法内get_free_ips_area替换成get_ips_area
|
||||
@@ -50,9 +58,7 @@
|
||||
|
||||
在login_send_body方法内,free_login_area(login_ip=server_ip_area的server_ip_area改成login_ip
|
||||
|
||||
- class/panelPlugin.py 文件,download_icon方法内替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
|
||||
删除public.total_keyword(get.query)这一行
|
||||
- class/panelPlugin.py 文件,删除public.total_keyword(get.query)这一行
|
||||
|
||||
__set_pyenv方法内,temp_file = public.readFile(filename)这行代码下面加上
|
||||
|
||||
@@ -61,17 +67,30 @@
|
||||
temp_file = temp_file.replace('https://download.bt.cn/install/public.sh', 'http://www.example.com/install/public.sh')
|
||||
```
|
||||
|
||||
- class/plugin_deployment.py 文件,SetupPackage方法内替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
def check_status(self, softInfo): 方法最后一行加上
|
||||
|
||||
```python
|
||||
if 'endtime' in softInfo:
|
||||
softInfo['endtime'] = time.time() + 86400 * 3650
|
||||
```
|
||||
|
||||
plugin_bin.pl 改成 plugin_list.json
|
||||
|
||||
- class/plugin_deployment.py 文件,__setup_php_environment方法和GetJarPath方法内替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
|
||||
- class/config.py 文件,get_nps方法内data['nps'] = False改成True,get_nps_new方法下面加上 return public.returnMsg(False, "获取问卷失败")
|
||||
|
||||
def err_collection(self, get): 这一行下面加上 return public.returnMsg(True, "OK")
|
||||
|
||||
- class/push/site_push.py 文件,'https://www.bt.cn' => 'http://www.example.com'
|
||||
|
||||
- script/flush_plugin.py 文件,删除clear_hosts()一行
|
||||
|
||||
- script/reload_check.py 文件,在第2行插入sys.exit()
|
||||
|
||||
- script/local_fix.sh 文件,${D_NODE_URL}替换成www.example.com
|
||||
|
||||
- tools.py 文件,u_input == 16下面的public.get_url()替换成'http://www.example.com'
|
||||
- tools.py 文件,u_input == 16下面的public.get_url()替换成public.GetConfigValue('home')
|
||||
|
||||
- install/install_soft.sh 在. 执行之前加入以下代码
|
||||
|
||||
@@ -84,7 +103,9 @@
|
||||
|
||||
- 去除无用的定时任务:task.py 文件 删除以下几行
|
||||
|
||||
"check_panel_msg": check_panel_msg,
|
||||
"check_panel_msg": self.check_panel_msg,
|
||||
|
||||
"update_software_list": self.update_software_list,
|
||||
|
||||
PluginLoader.daemon_panel()
|
||||
|
||||
@@ -92,10 +113,6 @@
|
||||
|
||||
- 去除WebRTC连接:BTPanel/static/js/public.js 删除stun.start();这一行
|
||||
|
||||
- 去除首页广告:BTPanel/static/js/index.js 文件删除两处index.recommend_paid_version()
|
||||
|
||||
- 去除首页自动检测更新,避免频繁请求云端:BTPanel/static/js/index.js 文件注释掉bt.system.check_update这一段代码外的setTimeout
|
||||
|
||||
- 去除内页广告:BTPanel/templates/default/layout.html 删除两处getPaymentStatus();
|
||||
|
||||
- 删除问卷调查:BTPanel/templates/default/layout.html 删除if(window.localStorage.getItem('panelNPS') == null)以及下面的行
|
||||
@@ -106,6 +123,8 @@
|
||||
<script src="/static/bt.js"></script>
|
||||
```
|
||||
|
||||
在 BTPanel/templates/default/software.html 的 \<script\>window.vite_public_request_token 前面加入
|
||||
|
||||
- [可选]去除创建网站自动创建的垃圾文件:在class/panelSite.py,分别删除
|
||||
|
||||
htaccess = self.sitePath + '/.htaccess'
|
||||
@@ -120,9 +139,7 @@
|
||||
|
||||
- [可选]关闭自动生成访问日志:在 BTPanel/\_\_init\_\_.py 删除public.write_request_log这一行
|
||||
|
||||
- [可选]删除小图标广告:在BTPanel/static/js/site.js,删除“WAF防火墙”对应的span标签
|
||||
|
||||
- [可选]上传文件默认选中覆盖,在BTPanel/static/js/upload-drog.js,id="all_operation"加checked属性
|
||||
- [可选]新版vite页面去除需求反馈、各种广告、计算题等,执行 php think cleanvitejs <面板BTPanel/static/vite/js路径>
|
||||
|
||||
|
||||
解压安装包[panel6.zip](http://download.bt.cn/install/src/panel6.zip),将更新包改好的文件覆盖到里面,然后重新打包,即可更新安装包。(
|
||||
|
@@ -1,78 +1,84 @@
|
||||
# Windows面板官方更新包修改记录
|
||||
|
||||
查询最新版本号:https://www.bt.cn/api/wpanel/get_version?is_version=1
|
||||
|
||||
官方更新包下载链接:http://download.bt.cn/win/panel/panel_版本号.zip
|
||||
|
||||
假设搭建的宝塔第三方云端网址是 http://www.example.com
|
||||
|
||||
Windows版宝塔由于加密文件太多,无法全部解密,因此无法做到全开源。
|
||||
|
||||
- 删除PluginLoader.pyd,将win/PluginLoader.py复制到class文件夹
|
||||
|
||||
- 全局搜索替换 https://api.bt.cn => http://www.example.com
|
||||
|
||||
- 全局搜索替换 https://www.bt.cn/api/ => http://www.example.com/api/(需排除ipsModel.py)
|
||||
|
||||
- 全局搜索替换 http://www.bt.cn/api/ => http://www.example.com/api/
|
||||
|
||||
- 全局搜索替换 https://download.bt.cn/win/panel/data/setup.py => http://www.example.com/win/panel/data/setup.py
|
||||
|
||||
- class/panel_update.py 文件 public.get_url() => 'http://www.example.com'
|
||||
|
||||
- class/public.py 在
|
||||
|
||||
```python
|
||||
def GetConfigValue(key):
|
||||
```
|
||||
|
||||
这一行下面加上
|
||||
|
||||
```python
|
||||
if key == 'home': return 'http://www.example.com'
|
||||
```
|
||||
|
||||
在 def is_bind(): 这一行下面加上 return True
|
||||
|
||||
在 def check_domain_cloud(domain): 这一行下面加上 return
|
||||
|
||||
在 get_update_file() 方法里面 get_url() => GetConfigValue('home')
|
||||
|
||||
- class/plugin_deployment.py 文件 get_icon 和 SetupPackage 方法内,替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
|
||||
- 去除无用的定时任务:task.py 文件
|
||||
|
||||
删除 p = threading.Thread(target=check_files_panel) 以及下面2行
|
||||
|
||||
删除 p = threading.Thread(target=check_panel_msg) 以及下面2行
|
||||
|
||||
删除 p = threading.Thread(target=update_software_list) 以及下面2行
|
||||
|
||||
- 去除面板日志上报:script/site_task.py 文件
|
||||
|
||||
- 删除最下面 logs_analysis() 这1行
|
||||
|
||||
- 去除首页广告:BTPanel/static/js/index.js 文件删除最下面index.recommend_paid_version()这一行以及index.consultancy_services()这一行
|
||||
|
||||
- 去除首页自动检测更新,避免频繁请求云端:BTPanel/static/js/index.js 文件注释掉bt.system.check_update这一段代码外的setTimeout
|
||||
|
||||
- 去除内页广告:BTPanel/templates/default/layout.html 删除getPaymentStatus();这一行
|
||||
|
||||
- [可选]去除各种计算题:复制win/bt.js到 BTPanel/static/ ,在 BTPanel/templates/default/layout.html 的尾部加入
|
||||
|
||||
```javascript
|
||||
<script src="/static/bt.js"></script>
|
||||
```
|
||||
|
||||
- [可选]去除创建网站自动创建的垃圾文件:class/panelSite.py 文件
|
||||
|
||||
删除 htaccess = self.sitePath + '/.htaccess' 以及下面2行
|
||||
|
||||
删除 index = self.sitePath + '/index.html' 以及下面6行
|
||||
|
||||
删除 doc404 = self.sitePath + '/404.html' 以及下面6行
|
||||
|
||||
删除 if not os.path.exists(self.sitePath + '/.htaccess') 这一行
|
||||
|
||||
- [可选]关闭自动生成访问日志:在 BTPanel/\_\_init\_\_.py 删除public.write_request_log()这一行
|
||||
|
||||
# Windows面板官方更新包修改记录
|
||||
|
||||
查询最新版本号:https://www.bt.cn/api/wpanel/get_version?is_version=1
|
||||
|
||||
官方更新包下载链接:http://download.bt.cn/win/panel/panel_版本号.zip
|
||||
|
||||
假设搭建的宝塔第三方云端网址是 http://www.example.com
|
||||
|
||||
Windows版宝塔由于加密文件太多,无法全部解密,因此无法做到全开源。
|
||||
|
||||
- 删除PluginLoader.pyd,将win/PluginLoader.py复制到class文件夹
|
||||
|
||||
- 批量解密模块文件:执行 php think decrypt classdir <面板class文件夹路径>
|
||||
|
||||
- 全局搜索替换 https://api.bt.cn => http://www.example.com
|
||||
|
||||
- 全局搜索替换 https://www.bt.cn/api/ => http://www.example.com/api/(需排除ipsModel.py)
|
||||
|
||||
- 全局搜索替换 http://www.bt.cn/api/ => http://www.example.com/api/
|
||||
|
||||
- 全局搜索替换 https://download.bt.cn/win/panel/data/setup.py => http://www.example.com/win/panel/data/setup.py
|
||||
|
||||
- class/panel_update.py 文件 public.get_url() => 'http://www.example.com'
|
||||
|
||||
- class/public.py 在
|
||||
|
||||
```python
|
||||
def GetConfigValue(key):
|
||||
```
|
||||
|
||||
这一行下面加上
|
||||
|
||||
```python
|
||||
if key == 'home': return 'http://www.example.com'
|
||||
```
|
||||
|
||||
在 def is_bind(): 这一行下面加上 return True
|
||||
|
||||
在 def check_domain_cloud(domain): 这一行下面加上 return
|
||||
|
||||
在 get_update_file() 方法里面 get_url() => GetConfigValue('home')
|
||||
|
||||
- class/plugin_deployment.py 文件 get_icon 和 SetupPackage 方法内,替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
|
||||
- 去除无用的定时任务:task.py 文件
|
||||
|
||||
删除 p = threading.Thread(target=check_files_panel) 以及下面2行
|
||||
|
||||
删除 p = threading.Thread(target=check_panel_msg) 以及下面2行
|
||||
|
||||
删除 p = threading.Thread(target=update_software_list) 以及下面2行
|
||||
|
||||
- tools.py,删除#尝试删除本地hosts文件中的宝塔域名解析
|
||||
|
||||
- 去除面板日志上报:script/site_task.py 文件
|
||||
|
||||
- 删除最下面 logs_analysis() 这1行
|
||||
|
||||
- 去除首页广告:BTPanel/static/js/index.js 文件删除最下面index.recommend_paid_version()这一行以及index.consultancy_services()这一行
|
||||
|
||||
- 去除首页自动检测更新,避免频繁请求云端:BTPanel/static/js/index.js 文件注释掉bt.system.check_update这一段代码外的setTimeout
|
||||
|
||||
- 去除内页广告:BTPanel/templates/default/layout.html 删除getPaymentStatus();这一行
|
||||
|
||||
- [可选]去除各种计算题:复制win/bt.js到 BTPanel/static/ ,在 BTPanel/templates/default/layout.html 的尾部加入
|
||||
|
||||
```javascript
|
||||
<script src="/static/bt.js"></script>
|
||||
```
|
||||
|
||||
- [可选]去除创建网站自动创建的垃圾文件:class/panelSite.py 文件
|
||||
|
||||
删除 htaccess = self.sitePath + '/.htaccess' 以及下面2行
|
||||
|
||||
删除 index = self.sitePath + '/index.html' 以及下面6行
|
||||
|
||||
删除 doc404 = self.sitePath + '/404.html' 以及下面6行
|
||||
|
||||
删除 if not os.path.exists(self.sitePath + '/.htaccess') 这一行
|
||||
|
||||
- [可选]关闭自动生成访问日志:在 BTPanel/\_\_init\_\_.py 删除public.write_request_log()这一行
|
||||
|
||||
- [可选]上传文件默认选中覆盖,在BTPanel/static/js/upload-drog.js,id="all_operation"加checked属性
|
||||
|
||||
|
Reference in New Issue
Block a user