Compare commits
19 Commits
v2.0.20-20
...
v2.0.36-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c7136ff0f | ||
|
|
86be0ca786 | ||
|
|
1ece1135ea | ||
|
|
cec87b24f2 | ||
|
|
1d379543f5 | ||
|
|
0038e27493 | ||
|
|
3646cfba93 | ||
|
|
6a418f6c7f | ||
|
|
33386c75dc | ||
|
|
0bc6f7bea5 | ||
|
|
82e8321432 | ||
|
|
4bc10f7c25 | ||
|
|
65edb94998 | ||
|
|
1733e995d6 | ||
|
|
332cd313fb | ||
|
|
b6b0d7efe5 | ||
|
|
3073302069 | ||
|
|
c24b348f30 | ||
|
|
b5b2707c3c |
@@ -1,8 +1,12 @@
|
||||
# Apache配置文件
|
||||
RewriteEngine On
|
||||
RewriteRule ^(data|system|templates)/.*.(db|db3|sql|tar|gz|zip|info|log)$ - [F]
|
||||
# 安全规则(必选)
|
||||
RewriteRule ^templates/.*\.(php|tar|gz|zip|info|log|json)$ - [F]
|
||||
RewriteRule ^data/.*\.(db|db3|php|sql|tar|gz|zip|info|log|json)$ - [F]
|
||||
# 重写规则(可选)
|
||||
RewriteRule '^login$' ./index.php?c=login [L]
|
||||
RewriteRule '^admin$' ./index.php?c=admin [L]
|
||||
RewriteRule '^ico/(.+)' ./index.php?c=icon&url=$1 [L]
|
||||
RewriteRule '^([A-Za-z0-9]+)$' ./index.php?u=$1 [L]
|
||||
RewriteRule '^(.+)/click/([A-Za-z0-9]+)$' ./index.php?c=$2&id=$3&u=$1 [L]
|
||||
RewriteRule '^(.+)/click/(.+)' ./$3 [L]
|
||||
10
README.md
@@ -1,4 +1,4 @@
|
||||
TwoNav 是一款开源免费的书签(导航)管理程序,界面简洁,安装简单,使用方便。TwoNav可帮助你将浏览器书签集中式管理,解决跨设备、跨平台、跨浏览器之间同步和访问困难问题,做到一处部署,随处访问。
|
||||
TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装简单,使用方便,基础功能免费。TwoNav可帮助你将浏览器书签集中式管理,解决跨设备、跨平台、跨浏览器之间同步和访问困难问题,做到一处部署,随处访问。
|
||||
|
||||
- **演示站**: [http://two.lm21.top](http://two.lm21.top)
|
||||
- **仅供体验,定期清理数据** 账号密码`admin`
|
||||
@@ -26,14 +26,18 @@ TwoNav 是一款开源免费的书签(导航)管理程序,界面简洁,
|
||||
* 支持加密链接
|
||||
* 支持分享链接
|
||||
* 支持二级分类
|
||||
* 支持用户分组
|
||||
* 支持用户分组/权限管理
|
||||
* 支持Chrome/Firefox/Edge书签批量导入
|
||||
* 支持多种主题风格
|
||||
* 支持批量更新链接图标/标题/描述等信息
|
||||
* 支持链接信息自动识别
|
||||
* 支持API
|
||||
* 支持Docker部署
|
||||
* 支持uTools插件
|
||||
* 支持Chromium内核的[浏览器扩展]
|
||||
* 支持简易文章管理
|
||||
* 支持更换各种模板/支持混搭,20+个主题模板
|
||||
* 安全性支持:更换登录入口/二级密码/OTP双重验证
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -34,11 +34,13 @@ if($db_config['type'] == 'sqlite'){
|
||||
$global_config = unserialize( get_db("global_config", "v", ["k" => "o_config"]) ); //全局配置
|
||||
$c = Get('c');
|
||||
$libs = $global_config['Libs'];
|
||||
$layui['js'] = $libs.'/Layui/v2.8.10/layui.js';
|
||||
$layui['css'] = $libs.'/Layui/v2.8.10/css/layui.css';
|
||||
define('libs',$global_config['Libs']);
|
||||
define('SysVer',Get_Version());
|
||||
define('Debug',$global_config['Debug'] == 1);
|
||||
|
||||
if($c != $global_config["Register"]){
|
||||
if(!in_array($c,[$global_config["Register"],'ico','icon'])){
|
||||
$u = Get('u');
|
||||
if(empty($u) && $global_config['Sub_domain'] == 1 && is_subscribe('bool')){
|
||||
$cut = explode('.',$_SERVER["HTTP_HOST"]);
|
||||
@@ -70,9 +72,9 @@ if(empty($c) || $c == 'index'){
|
||||
require "./system/Register.php";//注册
|
||||
}elseif($c == $global_config['Login'] || $c == $USER_DB['Login']){
|
||||
require "./system/login.php";//登陆
|
||||
}elseif(in_array($c,['admin','click','api','ico','verify'])){
|
||||
}elseif(in_array($c,['admin','click','api','ico','icon','verify'])){
|
||||
require "./system/{$c}.php";
|
||||
}elseif(in_array($c,['apply','guestbook'])){
|
||||
}elseif(in_array($c,['apply','guestbook','article'])){
|
||||
if($global_config['Maintenance'] != 0){Amsg(-1,'网站正在进行维护,请稍后再试!');}
|
||||
require "./system/expand/{$c}.php";
|
||||
}else{
|
||||
|
||||
1
static/Layui/v2.8.10/css/layui.css
Normal file
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 322 KiB |
1
static/Layui/v2.8.10/layui.js
Normal file
@@ -165,6 +165,14 @@ if(!empty($_GET['type'])){
|
||||
update_db("user_login_info", ["user" => $_POST['new_user_name']], ["user" => $USER['User']]);
|
||||
update_db("user_log", ["user" => $_POST['new_user_name']], ["user" => $USER['User']]);
|
||||
update_db("global_user", ["User" => $_POST['new_user_name']], ["ID" => $_POST['ID']],[1,'操作成功']);
|
||||
}elseif($_GET['type'] == 'del_otp'){
|
||||
$user_data = get_db('global_user','*',['ID'=>$_POST['ID']]);
|
||||
$LoginConfig = unserialize($user_data['LoginConfig']);
|
||||
if(empty($LoginConfig['totp_key'])){
|
||||
msgA(['code'=>-1,'msg'=>'当前账号未开启OTP双重验证']);
|
||||
}
|
||||
$LoginConfig['totp_key'] = '';
|
||||
update_db("global_user", ["LoginConfig" => $LoginConfig], ["ID" => $_POST['ID']],[1,'操作成功']);
|
||||
}
|
||||
|
||||
msgA(['code'=>-1,'msg'=>'请求类型错误']);
|
||||
@@ -218,7 +226,7 @@ function echo_Atool(){
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ATool 工具箱</title>
|
||||
<link rel="stylesheet" href="../static/Layui/v2.8.3/css/layui.css">
|
||||
<link rel="stylesheet" href="../static/Layui/v2.8.10/css/layui.css">
|
||||
<style>
|
||||
html, body {min-width: 1200px;background-color: #fff;position: relative;}
|
||||
.page-wrapper {width: 1200px;margin: 0 auto;padding: 0 15px;}
|
||||
@@ -267,9 +275,10 @@ function echo_Atool(){
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_pwd">改密码</a>
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_root">设站长</a>
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_user_name">改账号</a>
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="del_otp" title="移除OTP登录验证">删OTP</a>
|
||||
</div>
|
||||
</script>
|
||||
<script src="../static/Layui/v2.8.3/layui.js"></script>
|
||||
<script src="../static/Layui/v2.8.10/layui.js"></script>
|
||||
<script src="../static/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src="../static/jquery/jquery.md5.js"></script>
|
||||
<script src="../templates/admin/js/public.js?v=<?php echo time();?>"></script>
|
||||
@@ -280,7 +289,7 @@ function echo_Atool(){
|
||||
var table = layui.table;
|
||||
var cols = [[
|
||||
{field:'ID',title:'ID',width:60,sort:true}
|
||||
,{title:'操作',toolbar:'#tablebar',width:175}
|
||||
,{title:'操作',toolbar:'#tablebar',width:220}
|
||||
,{field:'User',title:'账号',minWidth:120,templet:function(d){
|
||||
return '<a style="color:#3c78d8" title="打开用户主页" target="_blank" href="../?u='+d.User+'">'+d.User+'</a>'
|
||||
}}
|
||||
@@ -359,6 +368,14 @@ function echo_Atool(){
|
||||
}
|
||||
});
|
||||
});
|
||||
}else if(obj.event == 'del_otp'){
|
||||
$.post('./ATool.php?type=del_otp',{ID:data.ID},function(data,status){
|
||||
if(data.code == 1) {
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
$('.set').click(function () {
|
||||
@@ -398,7 +415,7 @@ function echo_verify(){ ?>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ATool 工具箱</title>
|
||||
<link rel="stylesheet" href="../static/Layui/v2.8.3/css/layui.css">
|
||||
<link rel="stylesheet" href="../static/Layui/v2.8.10/css/layui.css">
|
||||
<link rel="stylesheet" href="../static/Other/login.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -423,7 +440,7 @@ function echo_verify(){ ?>
|
||||
</div>
|
||||
</div>
|
||||
<script src = "../static/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "../static/Layui/v2.8.3/layui.js"></script>
|
||||
<script src = "../static/Layui/v2.8.10/layui.js"></script>
|
||||
<script src = '../static/jquery/jquery.md5.js'></script>
|
||||
<script>
|
||||
layui.use(['form','jquery'], function () {
|
||||
|
||||
161
system/Authenticator.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
class PHPGangsta_GoogleAuthenticator
|
||||
{
|
||||
protected $_codeLength = 6;
|
||||
public function createSecret($secretLength = 16)
|
||||
{
|
||||
$validChars = $this->_getBase32LookupTable();
|
||||
if ($secretLength < 16 || $secretLength > 128) {
|
||||
throw new Exception('Bad secret length');
|
||||
}
|
||||
$secret = '';
|
||||
$rnd = false;
|
||||
if (function_exists('random_bytes')) {
|
||||
$rnd = random_bytes($secretLength);
|
||||
} elseif (function_exists('mcrypt_create_iv')) {
|
||||
$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
|
||||
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||
$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
|
||||
if (!$cryptoStrong) {
|
||||
$rnd = false;
|
||||
}
|
||||
}
|
||||
if ($rnd !== false) {
|
||||
for ($i = 0; $i < $secretLength; ++$i) {
|
||||
$secret .= $validChars[ord($rnd[$i]) & 31];
|
||||
}
|
||||
} else {
|
||||
throw new Exception('No source of secure random');
|
||||
}
|
||||
|
||||
return $secret;
|
||||
}
|
||||
public function getCode($secret, $timeSlice = null)
|
||||
{
|
||||
if ($timeSlice === null) {
|
||||
$timeSlice = floor(time() / 30);
|
||||
}
|
||||
|
||||
$secretkey = $this->_base32Decode($secret);
|
||||
$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
|
||||
$hm = hash_hmac('SHA1', $time, $secretkey, true);
|
||||
$offset = ord(substr($hm, -1)) & 0x0F;
|
||||
$hashpart = substr($hm, $offset, 4);
|
||||
$value = unpack('N', $hashpart);
|
||||
$value = $value[1];
|
||||
$value = $value & 0x7FFFFFFF;
|
||||
$modulo = pow(10, $this->_codeLength);
|
||||
return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
|
||||
}
|
||||
public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
|
||||
{
|
||||
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
|
||||
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
|
||||
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
|
||||
|
||||
$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
|
||||
if (isset($title)) {
|
||||
$urlencoded .= urlencode('&issuer='.urlencode($title));
|
||||
}
|
||||
|
||||
return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";
|
||||
}
|
||||
|
||||
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
|
||||
{
|
||||
if ($currentTimeSlice === null) {
|
||||
$currentTimeSlice = floor(time() / 30);
|
||||
}
|
||||
|
||||
if (strlen($code) != 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
|
||||
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
|
||||
if ($this->timingSafeEquals($calculatedCode, $code)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setCodeLength($length)
|
||||
{
|
||||
$this->_codeLength = $length;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function _base32Decode($secret)
|
||||
{
|
||||
if (empty($secret)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$base32chars = $this->_getBase32LookupTable();
|
||||
$base32charsFlipped = array_flip($base32chars);
|
||||
|
||||
$paddingCharCount = substr_count($secret, $base32chars[32]);
|
||||
$allowedValues = array(6, 4, 3, 1, 0);
|
||||
if (!in_array($paddingCharCount, $allowedValues)) {
|
||||
return false;
|
||||
}
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
if ($paddingCharCount == $allowedValues[$i] &&
|
||||
substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$secret = str_replace('=', '', $secret);
|
||||
$secret = str_split($secret);
|
||||
$binaryString = '';
|
||||
for ($i = 0; $i < count($secret); $i = $i + 8) {
|
||||
$x = '';
|
||||
if (!in_array($secret[$i], $base32chars)) {
|
||||
return false;
|
||||
}
|
||||
for ($j = 0; $j < 8; ++$j) {
|
||||
$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
||||
}
|
||||
$eightBits = str_split($x, 8);
|
||||
for ($z = 0; $z < count($eightBits); ++$z) {
|
||||
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $binaryString;
|
||||
}
|
||||
|
||||
protected function _getBase32LookupTable()
|
||||
{
|
||||
return array(
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7',
|
||||
'=',
|
||||
);
|
||||
}
|
||||
|
||||
private function timingSafeEquals($safeString, $userString)
|
||||
{
|
||||
if (function_exists('hash_equals')) {
|
||||
return hash_equals($safeString, $userString);
|
||||
}
|
||||
$safeLen = strlen($safeString);
|
||||
$userLen = strlen($userString);
|
||||
|
||||
if ($userLen != $safeLen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
|
||||
for ($i = 0; $i < $userLen; ++$i) {
|
||||
$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
|
||||
}
|
||||
return $result === 0;
|
||||
}
|
||||
}
|
||||
23
system/MySQL/20230522.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql ="
|
||||
CREATE TABLE IF NOT EXISTS `global_icon` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`url_md5` varchar(32) NOT NULL COMMENT 'url_md5',
|
||||
`url` text NOT NULL COMMENT 'url',
|
||||
`ico_url` text NOT NULL COMMENT 'url_ico',
|
||||
`add_time` int(10) UNSIGNED NOT NULL COMMENT '创建时间',
|
||||
`update_time` int(10) UNSIGNED NOT NULL COMMENT '更新时间',
|
||||
`file_name` text NOT NULL COMMENT '文件名',
|
||||
`file_mime` text NOT NULL COMMENT 'MIME类型',
|
||||
`extend` text NOT NULL COMMENT '预留扩展',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('icon_pull', '图标拉取', '允许用户拉取链接图标');
|
||||
";
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
17
system/MySQL/20230605.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql ="
|
||||
ALTER TABLE `global_user` CHANGE `RegIP` `RegIP` VARCHAR( 64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '注册IP';
|
||||
ALTER TABLE `user_apply` CHANGE `ip` `ip` VARCHAR( 64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'ip';
|
||||
ALTER TABLE `user_apply` CHANGE `ua` `ua` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '浏览器UA';
|
||||
ALTER TABLE `user_share` CHANGE `description` `description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '备注';
|
||||
ALTER TABLE `user_log` CHANGE `ip` `ip` VARCHAR( 64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求ip';
|
||||
ALTER TABLE `user_log` CHANGE `description` `description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '描述';
|
||||
ALTER TABLE `user_login_info` CHANGE `ip` `ip` VARCHAR( 64 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '登录IP';
|
||||
ALTER TABLE `user_login_info` CHANGE `ua` `ua` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '浏览器UA';
|
||||
|
||||
";
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
9
system/MySQL/20230715.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql ="
|
||||
ALTER TABLE `user_links` ADD `keywords` TEXT NOT NULL DEFAULT '' COMMENT '关键字' AFTER `weight` ;
|
||||
";
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
32
system/MySQL/20230723.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql =<<<EOF
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `user_article_list` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uid` varchar(32) NOT NULL COMMENT '用户id',
|
||||
`title` text NOT NULL COMMENT '标题',
|
||||
`category` int(10) UNSIGNED NOT NULL COMMENT '分类id',
|
||||
`state` int(10) UNSIGNED NOT NULL COMMENT '状态',
|
||||
`password` text NOT NULL COMMENT '访问密码',
|
||||
`top` int(10) UNSIGNED NOT NULL COMMENT '置顶',
|
||||
`add_time` int(10) UNSIGNED NOT NULL COMMENT '创建时间',
|
||||
`up_time` int(10) UNSIGNED NOT NULL COMMENT '修改时间',
|
||||
`browse_count` int(10) UNSIGNED NOT NULL COMMENT '浏览次数',
|
||||
`summary` text NOT NULL COMMENT '摘要',
|
||||
`content` text NOT NULL COMMENT '内容',
|
||||
`cover` text NOT NULL COMMENT '封面',
|
||||
`extend` text NOT NULL COMMENT '扩展',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE `user_count` ADD `e` TEXT NOT NULL DEFAULT '' COMMENT '扩展';
|
||||
|
||||
INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('article', '文章管理', '允许使用文章管理功能'),
|
||||
('article_image', '文章图片', '允许在文章编辑器上传图片');
|
||||
EOF;
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
@@ -26,7 +26,8 @@ CREATE TABLE IF NOT EXISTS `user_count` (
|
||||
`uid` int(10) UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`k` varchar(32) NOT NULL COMMENT '键',
|
||||
`v` bigint(10) UNSIGNED DEFAULT '0' COMMENT '值',
|
||||
`t` varchar(32) NOT NULL COMMENT '类型'
|
||||
`t` varchar(32) NOT NULL COMMENT '类型',
|
||||
`e` text NOT NULL DEFAULT ''
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
@@ -45,6 +46,9 @@ CREATE TABLE IF NOT EXISTS `updatadb_logs` (
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230417.php', '1681719049', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230420.php', '1681977368', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230518.php', '1684393068', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230522.php', '1684762253', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230715.php', '1689427853', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230723.php', '1690119053', 'TRUE', '');
|
||||
|
||||
-- 创建用户表
|
||||
DROP TABLE IF EXISTS `global_user`;
|
||||
@@ -57,7 +61,7 @@ CREATE TABLE IF NOT EXISTS `global_user` (
|
||||
`Email` varchar(32) NOT NULL COMMENT '邮箱',
|
||||
`SecretKey` varchar(32) NOT NULL DEFAULT '' COMMENT 'SecretKey',
|
||||
`Token` varchar(32) NOT NULL DEFAULT '' COMMENT 'Token',
|
||||
`RegIP` varchar(15) NOT NULL COMMENT '注册IP',
|
||||
`RegIP` varchar(64) NOT NULL DEFAULT '' COMMENT '注册IP',
|
||||
`RegTime` int(10) UNSIGNED NOT NULL COMMENT '注册时间',
|
||||
`Login` varchar(16) NOT NULL COMMENT '登录入口',
|
||||
`LoginConfig` text NOT NULL COMMENT '登陆配置',
|
||||
@@ -108,6 +112,7 @@ CREATE TABLE IF NOT EXISTS `user_links` (
|
||||
`url` text NOT NULL COMMENT '主链接',
|
||||
`url_standby` text NOT NULL COMMENT '备用链接',
|
||||
`weight` int(11) NOT NULL DEFAULT '0' COMMENT '权重',
|
||||
`keywords` text NOT NULL DEFAULT '' COMMENT '关键字',
|
||||
`description` text NOT NULL DEFAULT '' COMMENT '描述',
|
||||
`icon` text NOT NULL DEFAULT '' COMMENT '图标',
|
||||
`click` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '点击数',
|
||||
@@ -130,8 +135,8 @@ CREATE TABLE IF NOT EXISTS `user_login_info` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uid` int(10) UNSIGNED NOT NULL COMMENT '用户id',
|
||||
`user` varchar(32) NOT NULL COMMENT '用户名',
|
||||
`ip` varchar(15) NOT NULL COMMENT '登录IP',
|
||||
`ua` varchar(256) NOT NULL COMMENT '浏览器UA',
|
||||
`ip` varchar(64) NOT NULL DEFAULT '' COMMENT '登录IP',
|
||||
`ua` TEXT NOT NULL DEFAULT '' COMMENT '浏览器UA',
|
||||
`login_time` int(10) UNSIGNED NOT NULL COMMENT '登录时间',
|
||||
`last_time` int(10) UNSIGNED NOT NULL COMMENT '最后访问时间',
|
||||
`expire_time` int(10) UNSIGNED NOT NULL COMMENT '过期时间',
|
||||
@@ -145,11 +150,11 @@ CREATE TABLE IF NOT EXISTS `user_log` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uid` int(10) UNSIGNED NOT NULL COMMENT '用户id',
|
||||
`user` varchar(32) NOT NULL COMMENT '用户名',
|
||||
`ip` varchar(15) NOT NULL COMMENT '请求ip',
|
||||
`ip` varchar(64) NOT NULL DEFAULT '' COMMENT '请求ip',
|
||||
`time` varchar(13) NOT NULL COMMENT '请求时间',
|
||||
`type` varchar(16) NOT NULL COMMENT '日志类型',
|
||||
`content` text NOT NULL COMMENT '请求内容',
|
||||
`description` varchar(128) NOT NULL COMMENT '描述',
|
||||
`description` text NOT NULL DEFAULT '' COMMENT '描述',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='日志';
|
||||
|
||||
@@ -191,7 +196,10 @@ INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('guestbook', '留言板', '允许使用留言板功能'),
|
||||
('link_extend', '链接扩展', '允许使用链接扩展字段'),
|
||||
('theme_in', '主题设置', '后台显示主题设置菜单'),
|
||||
('theme_set', '主题配置', '允许自定义主题配置');
|
||||
('theme_set', '主题配置', '允许自定义主题配置'),
|
||||
('icon_pull', '图标拉取', '允许用户拉取链接图标'),
|
||||
('article', '文章管理', '允许使用文章管理功能'),
|
||||
('article_image', '文章图片', '允许在文章编辑器上传图片');
|
||||
|
||||
-- 注册码列表
|
||||
DROP TABLE IF EXISTS `regcode_list`;
|
||||
@@ -228,9 +236,9 @@ CREATE TABLE IF NOT EXISTS `user_apply` (
|
||||
`iconurl` varchar(512) NOT NULL COMMENT '图标url',
|
||||
`title` varchar(512) NOT NULL COMMENT '标题',
|
||||
`url` varchar(512) NOT NULL COMMENT '链接',
|
||||
`ip` varchar(16) NOT NULL DEFAULT '' COMMENT 'ip',
|
||||
`ip` varchar(64) NOT NULL DEFAULT '' COMMENT 'ip',
|
||||
`email` varchar(128) NOT NULL DEFAULT '' COMMENT '邮箱',
|
||||
`ua` varchar(512) NOT NULL DEFAULT '' COMMENT '浏览器UA',
|
||||
`ua` TEXT NOT NULL DEFAULT '' COMMENT '浏览器UA',
|
||||
`time` int(10) NOT NULL DEFAULT '0' COMMENT '时间',
|
||||
`state` int(1) NOT NULL DEFAULT '0' COMMENT '状态',
|
||||
`category_id` int(10) NOT NULL DEFAULT '0' COMMENT '分类id',
|
||||
@@ -251,10 +259,44 @@ CREATE TABLE IF NOT EXISTS `user_share` (
|
||||
`up_time` Bigint(13) NOT NULL DEFAULT '0' COMMENT '修改时间',
|
||||
`expire_time` Bigint(13) UNSIGNED NOT NULL DEFAULT '0' COMMENT '到期时间',
|
||||
`views` Bigint(13) NOT NULL DEFAULT '0' COMMENT '浏览数',
|
||||
`description` varchar(13) NOT NULL DEFAULT '' COMMENT '备注',
|
||||
`description` TEXT NOT NULL DEFAULT '' COMMENT '备注',
|
||||
`type` int(1) NOT NULL COMMENT '类型',
|
||||
`data` text NOT NULL COMMENT '数据',
|
||||
`pv` int(1) NOT NULL COMMENT '私有可见',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- 图标缓存
|
||||
CREATE TABLE IF NOT EXISTS `global_icon` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`url_md5` varchar(32) NOT NULL COMMENT 'url_md5',
|
||||
`url` text NOT NULL COMMENT 'url',
|
||||
`ico_url` text NOT NULL COMMENT 'url_ico',
|
||||
`add_time` int(10) UNSIGNED NOT NULL COMMENT '创建时间',
|
||||
`update_time` int(10) UNSIGNED NOT NULL COMMENT '更新时间',
|
||||
`file_name` text NOT NULL COMMENT '文件名',
|
||||
`file_mime` text NOT NULL COMMENT 'MIME类型',
|
||||
`extend` text NOT NULL COMMENT '预留扩展',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
-- 用户文章列表
|
||||
CREATE TABLE IF NOT EXISTS `user_article_list` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uid` varchar(32) NOT NULL COMMENT '用户id',
|
||||
`title` text NOT NULL COMMENT '标题',
|
||||
`category` int(10) UNSIGNED NOT NULL COMMENT '分类id',
|
||||
`state` int(10) UNSIGNED NOT NULL COMMENT '状态',
|
||||
`password` text NOT NULL COMMENT '访问密码',
|
||||
`top` int(10) UNSIGNED NOT NULL COMMENT '置顶',
|
||||
`add_time` int(10) UNSIGNED NOT NULL COMMENT '创建时间',
|
||||
`up_time` int(10) UNSIGNED NOT NULL COMMENT '修改时间',
|
||||
`browse_count` int(10) UNSIGNED NOT NULL COMMENT '浏览次数',
|
||||
`summary` text NOT NULL COMMENT '摘要',
|
||||
`content` text NOT NULL COMMENT '内容',
|
||||
`cover` text NOT NULL COMMENT '封面',
|
||||
`extend` text NOT NULL COMMENT '扩展',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
22
system/SQLite/20230522.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql =<<<EOF
|
||||
CREATE TABLE IF NOT EXISTS "global_icon" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"url_md5" text(32) NOT NULL DEFAULT "",
|
||||
"url" text NOT NULL DEFAULT "",
|
||||
"ico_url" text NOT NULL DEFAULT "",
|
||||
"add_time" integer(10) NOT NULL,
|
||||
"update_time" integer(10) NOT NULL,
|
||||
"file_name" text NOT NULL DEFAULT "",
|
||||
"file_mime" text NOT NULL DEFAULT "",
|
||||
"extend" text NOT NULL DEFAULT "",
|
||||
CONSTRAINT "id" UNIQUE ("id" ASC)
|
||||
);
|
||||
INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('icon_pull', '图标拉取', '允许用户拉取链接图标');
|
||||
EOF;
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
9
system/SQLite/20230715.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql ='
|
||||
ALTER TABLE user_links ADD keywords TEXT(128) NOT NULL DEFAULT "";
|
||||
';
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
31
system/SQLite/20230723.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
$sql =<<<EOF
|
||||
CREATE TABLE "user_article_list" (
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT,
|
||||
"uid" integer(10) NOT NULL,
|
||||
"title" TEXT NOT NULL DEFAULT "",
|
||||
"category" integer NOT NULL,
|
||||
"state" integer(1) DEFAULT 0,
|
||||
"password" TEXT NOT NULL DEFAULT "",
|
||||
"top" integer(10),
|
||||
"add_time" integer(10),
|
||||
"up_time" integer(10),
|
||||
"browse_count" integer DEFAULT 0,
|
||||
"summary" TEXT,
|
||||
"content" TEXT,
|
||||
"cover" TEXT,
|
||||
"extend" TEXT,
|
||||
CONSTRAINT "id" UNIQUE ("id" ASC)
|
||||
);
|
||||
|
||||
ALTER TABLE user_count ADD e TEXT NOT NULL DEFAULT "";
|
||||
|
||||
INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('article', '文章管理', '允许使用文章管理功能'),
|
||||
('article_image', '文章图片', '允许在文章编辑器上传图片');
|
||||
EOF;
|
||||
if(exe_sql($sql)){
|
||||
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
|
||||
}else{
|
||||
msg(-1,'数据库更新失败');
|
||||
}
|
||||
@@ -23,7 +23,8 @@ CREATE TABLE IF NOT EXISTS "user_count" (
|
||||
"uid" integer(10) NOT NULL,
|
||||
"k" text(32) NOT NULL DEFAULT "",
|
||||
"v" integer(10) NOT NULL DEFAULT 0,
|
||||
"t" text(32) NOT NULL DEFAULT ""
|
||||
"t" text(32) NOT NULL DEFAULT "",
|
||||
"e" text NOT NULL DEFAULT ""
|
||||
);
|
||||
|
||||
-- 数据库升级记录
|
||||
@@ -37,6 +38,10 @@ CREATE TABLE IF NOT EXISTS "updatadb_logs" (
|
||||
);
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230417.php', '1681719049', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230420.php', '1681977368', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230522.php', '1684762253', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230715.php', '1689427853', 'TRUE', '');
|
||||
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230723.php', '1690119053', 'TRUE', '');
|
||||
|
||||
|
||||
-- 创建用户表
|
||||
CREATE TABLE IF NOT EXISTS "global_user" (
|
||||
@@ -48,7 +53,7 @@ CREATE TABLE IF NOT EXISTS "global_user" (
|
||||
"Email" TEXT(32) NOT NULL,
|
||||
"SecretKey" TEXT(32) NOT NULL DEFAULT "",
|
||||
"Token" TEXT(32) NOT NULL DEFAULT "",
|
||||
"RegIP" TEXT(15) NOT NULL,
|
||||
"RegIP" TEXT(64) NOT NULL DEFAULT "",
|
||||
"RegTime" integer(10) NOT NULL,
|
||||
"Login" TEXT(16) NOT NULL,
|
||||
"LoginConfig" TEXT NOT NULL,
|
||||
@@ -92,6 +97,7 @@ CREATE TABLE IF NOT EXISTS "user_links" (
|
||||
"url" TEXT(1024) NOT NULL,
|
||||
"url_standby" text NOT NULL DEFAULT "",
|
||||
"weight" integer(11) NOT NULL DEFAULT 0,
|
||||
"keywords" TEXT(128) NOT NULL DEFAULT "",
|
||||
"description" TEXT(128) NOT NULL DEFAULT "",
|
||||
"icon" text NOT NULL DEFAULT "",
|
||||
"click" integer(10) NOT NULL DEFAULT 0,
|
||||
@@ -107,8 +113,8 @@ CREATE TABLE IF NOT EXISTS "user_login_info" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"uid" integer(10) NOT NULL,
|
||||
"user" TEXT(32) NOT NULL,
|
||||
"ip" TEXT(15) NOT NULL,
|
||||
"ua" TEXT(256) NOT NULL,
|
||||
"ip" TEXT(64) NOT NULL,
|
||||
"ua" TEXT NOT NULL,
|
||||
"login_time" integer(10) NOT NULL,
|
||||
"last_time" integer(10) NOT NULL,
|
||||
"expire_time" integer(10) NOT NULL,
|
||||
@@ -120,11 +126,11 @@ CREATE TABLE IF NOT EXISTS "user_log" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"uid" integer(10) NOT NULL,
|
||||
"user" TEXT(32) NOT NULL,
|
||||
"ip" TEXT(15) NOT NULL,
|
||||
"ip" TEXT(64) NOT NULL,
|
||||
"time" TEXT(13) NOT NULL,
|
||||
"type" TEXT(16) NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"description" TEXT(128) NOT NULL
|
||||
"description" TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- 用户组
|
||||
@@ -163,7 +169,10 @@ INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
|
||||
('guestbook', '留言板', '允许使用留言板功能'),
|
||||
('link_extend', '链接扩展', '允许使用链接扩展字段'),
|
||||
('theme_in', '主题设置', '后台显示主题设置菜单'),
|
||||
('theme_set', '主题配置', '允许自定义主题配置');
|
||||
('theme_set', '主题配置', '允许自定义主题配置'),
|
||||
('icon_pull', '图标拉取', '允许用户拉取链接图标'),
|
||||
('article', '文章管理', '允许使用文章管理功能'),
|
||||
('article_image', '文章图片', '允许在文章编辑器上传图片');
|
||||
|
||||
-- 注册码列表
|
||||
CREATE TABLE IF NOT EXISTS "regcode_list" (
|
||||
@@ -197,8 +206,8 @@ CREATE TABLE IF NOT EXISTS "user_apply" (
|
||||
"title" TEXT(512) DEFAULT "",
|
||||
"url" TEXT(512) DEFAULT "",
|
||||
"email" TEXT(128) DEFAULT "",
|
||||
"ip" TEXT(16) DEFAULT "",
|
||||
"ua" TEXT(512) DEFAULT "",
|
||||
"ip" TEXT(64) DEFAULT "",
|
||||
"ua" TEXT DEFAULT "",
|
||||
"time" integer DEFAULT "0",
|
||||
"state" integer DEFAULT "0",
|
||||
"category_id" INTEGER DEFAULT "0",
|
||||
@@ -217,8 +226,41 @@ CREATE TABLE IF NOT EXISTS "user_share" (
|
||||
"up_time" integer(13) DEFAULT "0",
|
||||
"expire_time" integer(13) DEFAULT "0",
|
||||
"views" integer(13) DEFAULT "0",
|
||||
"description" TEXT(13) DEFAULT "",
|
||||
"description" TEXT DEFAULT "",
|
||||
"type" integer(1) NOT NULL,
|
||||
"data" TEXT,
|
||||
"pv" integer(1) DEFAULT "0"
|
||||
);
|
||||
|
||||
-- 图标缓存
|
||||
CREATE TABLE IF NOT EXISTS "global_icon" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"url_md5" text(32) NOT NULL DEFAULT "",
|
||||
"url" text NOT NULL DEFAULT "",
|
||||
"ico_url" text NOT NULL DEFAULT "",
|
||||
"add_time" integer(10) NOT NULL,
|
||||
"update_time" integer(10) NOT NULL,
|
||||
"file_name" text NOT NULL DEFAULT "",
|
||||
"file_mime" text NOT NULL DEFAULT "",
|
||||
"extend" text NOT NULL DEFAULT "",
|
||||
CONSTRAINT "id" UNIQUE ("id" ASC)
|
||||
);
|
||||
|
||||
-- 用户文章列表
|
||||
CREATE TABLE "user_article_list" (
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT,
|
||||
"uid" integer(10) NOT NULL,
|
||||
"title" TEXT NOT NULL DEFAULT "",
|
||||
"category" integer NOT NULL,
|
||||
"state" integer(1) DEFAULT 0,
|
||||
"password" TEXT NOT NULL DEFAULT "",
|
||||
"top" integer(10),
|
||||
"add_time" integer(10),
|
||||
"up_time" integer(10),
|
||||
"browse_count" integer DEFAULT 0,
|
||||
"summary" TEXT,
|
||||
"content" TEXT,
|
||||
"cover" TEXT,
|
||||
"extend" TEXT,
|
||||
CONSTRAINT "id" UNIQUE ("id" ASC)
|
||||
);
|
||||
@@ -392,7 +392,7 @@ if($_GET['type'] == 'upload'){
|
||||
}
|
||||
//数据库清除
|
||||
if(!empty($_POST['TABLE'])){
|
||||
$TABLE = ["user_categorys","user_links","user_pwd_group","user_share","user_apply"];
|
||||
$TABLE = ["user_categorys","user_links","user_pwd_group","user_share","user_apply","user_article_list"];
|
||||
foreach($_POST['TABLE'] as $key =>$value){
|
||||
if(in_array($key,$TABLE)){
|
||||
delete_db($key,['uid'=>UID]);
|
||||
@@ -418,7 +418,7 @@ if($_GET['type'] == 'upload'){
|
||||
|
||||
//文件删除
|
||||
if(!empty($_POST['FILE'])){
|
||||
$FILE = ["MessageBoard","favicon"];
|
||||
$FILE = ["MessageBoard","favicon","upload"];
|
||||
foreach($_POST['FILE'] as $key =>$value){
|
||||
$path = DIR.'/data/user/'.U.'/'.$key;
|
||||
if(in_array($key,$FILE) && is_dir($path)){
|
||||
|
||||
@@ -47,7 +47,7 @@ if(!defined('DIR')){
|
||||
$info['file_db'] = $info['backup_dir'] .'/'. $info['file'].'.db3';
|
||||
$info['file_info'] = $info['backup_dir'] .'/'. $info['file'].'.info';
|
||||
$info['file_gz'] = $info['backup_dir'] .'/'. $info['file'].'.tar';
|
||||
$info['table_arr'] = ['user_config','user_categorys','user_links','user_pwd_group','user_apply','user_share'];
|
||||
$info['table_arr'] = ['user_config','user_categorys','user_links','user_pwd_group','user_apply','user_share','user_article_list'];
|
||||
$info['lock'] = DIR.'/data/user/'.U.'/lock.'.UID;
|
||||
if (!extension_loaded('phar')) {
|
||||
msg(-1,'不支持phar扩展');
|
||||
@@ -167,7 +167,7 @@ if(!defined('DIR')){
|
||||
}
|
||||
|
||||
//遍历删除用户数据
|
||||
$info['table_arr'] = ['user_config','user_categorys','user_links','user_pwd_group','user_apply','user_share'];
|
||||
$info['table_arr'] = ['user_config','user_categorys','user_links','user_pwd_group','user_apply','user_share','user_article_list'];
|
||||
foreach($info['table_arr'] as $table_name){
|
||||
|
||||
//删除数据
|
||||
@@ -186,8 +186,15 @@ if(!defined('DIR')){
|
||||
$where['name'] = $table_name;
|
||||
$where['LIMIT'] = [($page - 1) * $limit,$limit];
|
||||
$datas = $MyDB->select('backup','data',$where);
|
||||
foreach($datas as $data){
|
||||
foreach($datas as $key => $data){
|
||||
$data = unserialize($data);
|
||||
//处理null
|
||||
foreach ($data as $key => $value) {
|
||||
if ($value === null) {
|
||||
$data[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['id'])){
|
||||
unset($data['id']);
|
||||
}
|
||||
@@ -330,6 +337,10 @@ if(!defined('DIR')){
|
||||
deldir($temp_dir);
|
||||
msg(-1,'tar文件效验失败');
|
||||
}
|
||||
//检查目录
|
||||
if(!Check_Path(DIR."/data/backup/".U)){
|
||||
msg(-1,'创建backup目录失败,请检查权限');
|
||||
}
|
||||
//复制到用户数据
|
||||
try {
|
||||
$backup_dir = DIR."/data/backup/".U."/";
|
||||
|
||||
@@ -131,7 +131,7 @@ if($_POST['step'] == 2){
|
||||
'add_time'=>$data['add_time'] ?? time(),
|
||||
'up_time'=>$data['up_time'] ?? time(),
|
||||
'weight'=>0,
|
||||
'description'=>htmlspecialchars($data['description'],ENT_QUOTES),
|
||||
'description'=>htmlspecialchars($data['description'],ENT_QUOTES) ?? '',
|
||||
'font_icon'=> strstr($data['Icon'],'fa') ? 'fa '.$data['Icon'] : 'fa fa-folder',
|
||||
'icon'=>''
|
||||
]
|
||||
@@ -149,7 +149,7 @@ if($_POST['step'] == 2){
|
||||
'title' => $data['title'],
|
||||
'url' => $data['url'],
|
||||
'url_standby' => empty($data['url_standby']) ? '': [$data['url_standby']] ,
|
||||
'description' => $data['description'],
|
||||
'description' => $data['description']?? '',
|
||||
'add_time' => $data['add_time'] ?? time(),
|
||||
'up_time' => $data['up_time'] ?? time(),
|
||||
'click' => $data['click'] ?? 0,
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}AccessControl();
|
||||
|
||||
//获取请求参数
|
||||
$page = trim($_GET['page']);
|
||||
|
||||
//layui版本路径,方便后期切换版本
|
||||
$layui['js'] = $libs.'/Layui/v2.8.3/layui.js';$layui['css'] = $libs.'/Layui/v2.8.3/css/layui.css';
|
||||
$Ver = !Debug?SysVer:SysVer.'.'.time();
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
define('offline',$global_config['offline'] == 1);
|
||||
define('is_login',is_login());
|
||||
$page = trim($_GET['page']); //获取请求参数
|
||||
$Ver = !Debug?SysVer:SysVer.'.'.time(); //版本
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']); //登录配置
|
||||
define('offline',$global_config['offline'] == 1); //是否离线模式
|
||||
define('is_login',is_login()); //是否已登录
|
||||
//未登录,载入登录提示页
|
||||
if(!is_login){
|
||||
require(DIR.'/templates/admin/page/LoginPrompt.php');
|
||||
@@ -68,7 +64,7 @@ if($page == 'config_home'){
|
||||
$theme_config = empty($theme_config['config']) ? []:$theme_config['config'];
|
||||
|
||||
//读取用户主题配置
|
||||
if(!in_array($_GET['fn'],['home','login','register','transit','guide'])){
|
||||
if(!in_array($_GET['fn'],['home','login','register','transit','guide','article'])){
|
||||
msg(-1,"参数错误");
|
||||
}
|
||||
$theme_config_db = get_db('user_config','v',['t'=>'theme_'.$_GET['fn'],'k'=>$theme,'uid'=>UID]);
|
||||
@@ -87,7 +83,7 @@ if($page == 'config_home'){
|
||||
}
|
||||
|
||||
//主题设置页面
|
||||
if( $page == 'theme_home' || $page == 'theme_login' || $page == 'theme_transit' || $page == 'theme_register' || $page == 'theme_guide') {
|
||||
if( $page == 'theme_home' || $page == 'theme_login' || $page == 'theme_transit' || $page == 'theme_register' || $page == 'theme_guide' || $page == 'theme_article') {
|
||||
if(!check_purview('theme_in',1)){
|
||||
require(DIR.'/templates/admin/page/404.php');
|
||||
exit;
|
||||
@@ -133,14 +129,22 @@ if( $page == 'theme_home' || $page == 'theme_login' || $page == 'theme_transit'
|
||||
|
||||
//没有缓存 或 禁止缓存 或 缓存过时
|
||||
if(empty($template) || $_GET['cache'] === 'no' || time() - $data["time"] > 1800 ){
|
||||
$urls = [ "https://update.lm21.top/TwoNav/{$fn}_template.json"];
|
||||
$urls = [
|
||||
"lm21" => "https://update.lm21.top/TwoNav/{$fn}_template.json",
|
||||
"gitee" => "https://gitee.com/tznb/twonav_updata/raw/master/{$fn}_template.json"
|
||||
];
|
||||
$Source = $global_config['Update_Source'] ?? '';
|
||||
if (!empty($Source) && isset($urls[$Source])) {
|
||||
$urls = [$Source => $urls[$Source]];
|
||||
}
|
||||
}else{
|
||||
$cache = true;
|
||||
}
|
||||
|
||||
//读取超时参数
|
||||
$overtime = !isset($global_config['Update_Overtime']) ? 3 : ($global_config['Update_Overtime'] < 3 || $global_config['Update_Overtime'] > 60 ? 3 : $global_config['Update_Overtime']);
|
||||
//远程获取
|
||||
foreach($urls as $url){
|
||||
$Res = ccurl($url,3);
|
||||
foreach($urls as $key => $url){
|
||||
$Res = ccurl($url,$overtime);
|
||||
$data = json_decode($Res["content"], true);
|
||||
if($data["code"] == 200 ){ //如果获取成功
|
||||
$data["time"] = time(); //记录当前时间
|
||||
@@ -204,7 +208,9 @@ if ($page == 'menu') {
|
||||
if($global_config['guestbook'] == 1 && check_purview('guestbook',1)){
|
||||
array_push($extend,['title'=>'留言管理','href'=>'expand/guestbook-admin','icon'=>'fa fa-commenting-o']);
|
||||
}
|
||||
|
||||
if($global_config['article'] > 0 && check_purview('article',1)){
|
||||
array_push($extend,['title'=>'文章管理','href'=>'expand/article-list','icon'=>'fa fa-file-text-o']);
|
||||
}
|
||||
if(!empty($extend)){
|
||||
$extend = ['title'=>'扩展功能','icon'=>'fa fa-folder-open-o','href'=>'','child'=> $extend];
|
||||
array_push($menu,$extend);
|
||||
@@ -217,7 +223,7 @@ if ($page == 'menu') {
|
||||
[
|
||||
['title'=>'系统设置','href'=>'root/sys_setting','icon'=>'fa fa-gears'],
|
||||
['title'=>'授权管理','href'=>'root/vip','icon'=>'fa fa-diamond'],
|
||||
['title'=>'默认设置','href'=>'root/default_setting','icon'=>'fa fa-heart-o'],
|
||||
//['title'=>'默认设置','href'=>'root/default_setting','icon'=>'fa fa-heart-o'],
|
||||
['title'=>'用户管理','href'=>'root/user_control','icon'=>'fa fa-user'],
|
||||
['title'=>'用户分组','href'=>'root/users_control','icon'=>'fa fa-users'],
|
||||
['title'=>'注册管理','href'=>'root/reg_control','icon'=>'fa fa-user-plus'],
|
||||
@@ -238,6 +244,13 @@ if(empty($page)){
|
||||
exit;
|
||||
}
|
||||
|
||||
// 插件编辑链接跳转
|
||||
if($page === 'edit_link' && !empty($_GET['id'])){
|
||||
header("HTTP/1.1 302 Moved Permanently");
|
||||
header("Location: ./index.php?c=admin&page=link_edit&u=".U."&id=".$_GET['id']);
|
||||
exit;
|
||||
}
|
||||
|
||||
//页面文件不存在时载入404
|
||||
if(!empty($page)){
|
||||
if(!is_file(DIR.'/templates/admin/page/'.$page.'.php')){
|
||||
@@ -253,18 +266,19 @@ if(!empty($page)){
|
||||
function load_static($type){
|
||||
if($type == 'css'){
|
||||
echo
|
||||
'<link rel="stylesheet" href="'.$GLOBALS['libs'].'/Layui/v2.8.3/css/layui.css" media="all">
|
||||
'<link rel="stylesheet" href="'.$GLOBALS['layui']['css'].'" media="all">
|
||||
<link rel="stylesheet" href="./templates/admin/css/public.css?v='.$GLOBALS['Ver'].'" media="all">
|
||||
';
|
||||
}elseif($type == 'js'){
|
||||
echo
|
||||
'<script src="'.$GLOBALS['libs'].'/Layui/v2.8.3/layui.js" charset="utf-8"></script>
|
||||
'<script src="'.$GLOBALS['layui']['js'].'" charset="utf-8"></script>
|
||||
<script src="./templates/admin/js/lay-config.js?v='.$GLOBALS['Ver'].'" charset="utf-8"></script>
|
||||
<script>layui.config({version:"'.$GLOBALS['Ver'].'"})</script>
|
||||
';
|
||||
}elseif($type == 'js.layui'){
|
||||
echo
|
||||
'<script src="'.$GLOBALS['libs'].'/Layui/v2.8.3/layui.js" charset="utf-8"></script>
|
||||
'<script src="'.$GLOBALS['layui']['js'].'" charset="utf-8"></script>
|
||||
<script src="./templates/admin/js/lay-config.js?v='.$GLOBALS['Ver'].'" charset="utf-8"></script>
|
||||
<script>layui.config({version:"'.$GLOBALS['Ver'].'"})</script>
|
||||
';
|
||||
}
|
||||
|
||||
517
system/api.php
@@ -4,51 +4,48 @@ header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Headers: Access-Control-Allow-Private-Network,Content-Type, AccessToken, X-CSRF-Token, Authorization, Token,X-Token,X-Cid");
|
||||
AccessControl();
|
||||
//鉴权验证 Cookie验证通过,验证二级密码,Cookie验证失败时尝试验证token
|
||||
if(!empty(trim($_REQUEST['token']))){ $_COOKIE = []; } //兼容浏览器插件,避免干扰
|
||||
|
||||
//获取请求方法
|
||||
$method = htmlspecialchars(trim($_GET['method']),ENT_QUOTES);
|
||||
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
$api_model = $LoginConfig['api_model']; //API模式
|
||||
|
||||
if(!is_login()){
|
||||
//没登录,根据API模式来限制
|
||||
$api_model = $LoginConfig['api_model']; //API模式
|
||||
$token = trim($_REQUEST['token']); //尝试获取令牌
|
||||
|
||||
if( empty($USER_DB['Token']) && $api_model != 'compatible+open' ){
|
||||
Amsg(-1,'未设置token');
|
||||
//没登录,尝试验证token
|
||||
if( empty($USER_DB['Token']) ){
|
||||
msg(-1,'鉴权失败:未登录且未设置token');
|
||||
}
|
||||
//获取请求token
|
||||
$token = trim($_REQUEST['token']);
|
||||
if(empty($token)){
|
||||
if($api_model != 'compatible+open'){
|
||||
Amsg(-1,'非开放模式,token不能为空!');
|
||||
}
|
||||
if(in_array($method,['link_list','get_a_link','q_category_link','category_list','get_a_category','check_login'])){
|
||||
define('Access_Type','open'); //数据访问类型:仅开放
|
||||
require 'api_compatible.php';
|
||||
exit;
|
||||
}else{
|
||||
Amsg(-1,'token为空时不允许访问此接口');
|
||||
}
|
||||
msg(-1,'鉴权失败:未登录且请求未携带token');
|
||||
}else{
|
||||
if($token === $USER_DB['Token']){
|
||||
define('Access_Type','all');
|
||||
//验证通过
|
||||
}else{
|
||||
Amsg(-1,'token验证失败');
|
||||
msg(-1,'鉴权失败:未登录且token错误');
|
||||
}
|
||||
}
|
||||
if($api_model === 'compatible' || $api_model ==='compatible+open'){
|
||||
require 'api_compatible.php';
|
||||
}
|
||||
//Cookie登录验证OK,验证二级密码
|
||||
}elseif(Check_Password2($LoginConfig)){
|
||||
// Cookie 二级密码验证成功(未设置时也认为成功)
|
||||
}else{
|
||||
msg(-1,'请先验证二级密码!');
|
||||
}
|
||||
//是否加载扩展API
|
||||
|
||||
//扩展API
|
||||
if($global_config['api_extend'] == 1 && is_file('./system/api_extend.php')){
|
||||
require './system/api_extend.php';
|
||||
}
|
||||
|
||||
//兼容API
|
||||
$compatible_list = ['add_link','edit_link','del_link','link_list','get_a_link','q_category_link','category_list','get_a_category','add_category','edit_category','app_info','check_login','global_search'];
|
||||
if(in_array($api_model,['compatible','compatible+open']) && in_array($method,$compatible_list)){
|
||||
require 'api_compatible.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
//站长相关方法名
|
||||
$root = ['write_subscribe','write_sys_settings','write_default_settings','read_user_list','write_user_info','read_purview_list','read_users_list','write_users','read_regcode_list','write_regcode','other_upsys','read_log','other_root'];
|
||||
if(in_array($method,$root)){
|
||||
@@ -62,9 +59,7 @@ if(in_array($method,$root)){
|
||||
if ( preg_match("/^read_|^write_|^other_/",$method) && function_exists($method) ) {
|
||||
$method();
|
||||
}else{
|
||||
if($api_model == 'security'){
|
||||
Amsg(-1,'方法未找到 >> '.$method);
|
||||
}
|
||||
Amsg(-1,'方法未找到 >> '.$method);
|
||||
}
|
||||
|
||||
//读分类列表
|
||||
@@ -176,7 +171,7 @@ function write_category(){
|
||||
'fid'=>intval($_POST['fid']??'0'),
|
||||
'pid'=>intval($_POST['pwd_id']??'0'),
|
||||
'status'=>1,
|
||||
'property'=>$_POST['property']??'0',
|
||||
'property'=>intval($_POST['property']??'0'),
|
||||
'name'=>htmlspecialchars($_POST['name'],ENT_QUOTES),
|
||||
'add_time'=>time(),
|
||||
'up_time'=>time(),
|
||||
@@ -230,7 +225,7 @@ function write_category(){
|
||||
$data = [
|
||||
'fid'=>$_POST['fid'],
|
||||
'pid'=>intval($_POST['pwd_id']??'0'),
|
||||
'property'=>$_POST['property']??'0',
|
||||
'property'=>intval($_POST['property']??'0'),
|
||||
'name'=>$_POST['name'],
|
||||
'up_time'=>time(),
|
||||
'description'=>$_POST['description'],
|
||||
@@ -306,7 +301,7 @@ function read_link_list(){
|
||||
$list = unserialize($list);
|
||||
msgA(['code'=>1,'msg'=>'获取成功','count'=>count($list),'data'=>$list]);
|
||||
}
|
||||
|
||||
$field = ['lid','fid','pid(pwd_id)','status','property','title','url','url_standby','weight','description','icon','click','add_time','up_time'];
|
||||
$query = $_POST['query'];
|
||||
$fid = intval(@$_POST['fid']); //获取分类ID
|
||||
$page = empty(intval($_REQUEST['page'])) ? 1 : intval($_REQUEST['page']);
|
||||
@@ -334,14 +329,20 @@ function read_link_list(){
|
||||
|
||||
//统计条数
|
||||
$count = count_db('user_links',$where);
|
||||
//权重排序(数字小的排前面)
|
||||
|
||||
$where['ORDER']['weight'] = 'ASC';
|
||||
$where['ORDER']['lid'] = 'ASC';
|
||||
//前端指定排序方式,过滤字段名和方式
|
||||
if(!empty($_POST['order']) && !empty($_POST['field']) && in_array($_POST['field'],$field) && in_array($_POST['order'],['ASC','DESC'])){
|
||||
$where['ORDER'][$_POST['field']] = $_POST['order'];
|
||||
}else{
|
||||
//默认排序方式 权重排序(数字小的排前面)
|
||||
$where['ORDER']['weight'] = 'ASC';
|
||||
$where['ORDER']['lid'] = 'ASC';
|
||||
}
|
||||
|
||||
//分页
|
||||
$where['LIMIT'] = [$offset,$limit];
|
||||
//查询
|
||||
$datas = select_db('user_links',['lid','fid','pid(pwd_id)','status','property','title','url','url_standby','weight','description','icon','click','add_time','up_time'],$where);
|
||||
$datas = select_db('user_links',$field,$where);
|
||||
|
||||
msgA(['code'=>1,'msg'=>'获取成功','count'=>$count,'data'=>$datas]);
|
||||
}
|
||||
@@ -372,6 +373,7 @@ function write_link(){
|
||||
$url = $_POST['url'];
|
||||
$icon = empty($_POST['icon']) ? '' : $_POST['icon'];
|
||||
$description = empty($_POST['description']) ? '' : $_POST['description'];
|
||||
$keywords = empty($_POST['keywords']) ? '' : $_POST['keywords'];
|
||||
$property = empty($_POST['property']) ? 0 : 1;
|
||||
//检测链接是否合法
|
||||
check_link($fid,$title,$url,$_POST['url_standby']);
|
||||
@@ -384,7 +386,10 @@ function write_link(){
|
||||
if($length_limit['l_desc'] > 0 && strlen($description) > $length_limit['l_desc'] ){
|
||||
msg(-1,'描述长度不能大于'.$length_limit['l_desc'].'个字节');
|
||||
}
|
||||
|
||||
//关键字长度检测
|
||||
if($length_limit['l_key'] > 0 && strlen($keywords) > $length_limit['l_key'] ){
|
||||
msg(-1,'关键字长度不能大于'.$length_limit['l_key'].'个字节');
|
||||
}
|
||||
//取最大链接ID
|
||||
$lid = get_maxid('link_id');
|
||||
//图标处理
|
||||
@@ -410,6 +415,7 @@ function write_link(){
|
||||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||||
'url' => $url,
|
||||
'url_standby' => $_POST['url_standby']??'',
|
||||
'keywords' => htmlspecialchars($keywords,ENT_QUOTES),
|
||||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||||
'add_time' => time(),
|
||||
'up_time' => time(),
|
||||
@@ -419,7 +425,20 @@ function write_link(){
|
||||
'property' => $property,
|
||||
'icon' => $icon
|
||||
];
|
||||
|
||||
//扩展字段
|
||||
if($GLOBALS['global_config']['link_extend'] == 1 && check_purview('link_extend',1)){
|
||||
$list = get_db("user_config","v",["k"=>"s_extend_list","uid"=>UID]);
|
||||
if(!empty($list)){
|
||||
$list = unserialize($list);
|
||||
$extend = [];
|
||||
foreach($list as $field){
|
||||
$name = "_{$field['name']}";
|
||||
if(isset($_POST[$name])){
|
||||
$data['extend'][$name] = $_POST[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//插入数据库
|
||||
insert_db('user_links',$data);
|
||||
msgA(['code'=>1,'msg'=>'添加成功','id'=>$lid]);
|
||||
@@ -438,7 +457,10 @@ function write_link(){
|
||||
@unlink($_FILES["file"]["tmp_name"]);
|
||||
msg(-1,'文件格式不被支持!');
|
||||
}
|
||||
|
||||
//限制文件大小
|
||||
if(filesize($_FILES["file"]["tmp_name"]) > 1 * 1024 * 1024){
|
||||
msg(-1,'文件大小超限');
|
||||
}
|
||||
session_start();
|
||||
$sid = $_POST['page_sid'];
|
||||
//添加链接
|
||||
@@ -492,7 +514,39 @@ function write_link(){
|
||||
}else{
|
||||
msg(-1,'参数错误');
|
||||
}
|
||||
|
||||
//扩展上传图片
|
||||
}elseif($_GET['type'] == 'extend_up_img'){
|
||||
//权限检测
|
||||
if(!check_purview('Upload_icon',1)){
|
||||
msg(-1,'您的用户组无权限上传图片');
|
||||
}elseif(empty($_FILES["file"]) || $_FILES["file"]["error"] > 0){
|
||||
msg(-1,'文件上传失败');
|
||||
}
|
||||
|
||||
//取后缀并判断是否支持
|
||||
$suffix = strtolower(end(explode('.',$_FILES["file"]["name"])));
|
||||
if(!preg_match('/^(jpg|jpeg|png|ico|bmp|svg)$/',$suffix)){
|
||||
@unlink($_FILES["file"]["tmp_name"]);
|
||||
msg(-1,'文件格式不被支持!');
|
||||
}
|
||||
//限制文件大小
|
||||
if(filesize($_FILES["file"]["tmp_name"]) > 1 * 1024 * 1024){
|
||||
msg(-1,'文件大小超限');
|
||||
}
|
||||
//文件临时路径
|
||||
$path = DIR . "/data/user/{$u}/upload";
|
||||
//检测目录,不存在则创建!
|
||||
if(!Check_Path($path)){
|
||||
msg(-1,'创建upload目录失败,请检查权限');
|
||||
}
|
||||
$tmp_name = 'LE_'.uniqid().'.'.$suffix;
|
||||
//移动文件
|
||||
if(!move_uploaded_file($_FILES["file"]["tmp_name"],"{$path}/{$tmp_name}")) {
|
||||
msg(-1,'上传失败,请检查目录权限');
|
||||
}else{
|
||||
msgA(['code'=>1,'msg'=>'上传成功','url'=>"./data/user/".U.'/upload/'.$tmp_name]);
|
||||
}
|
||||
|
||||
//删除图标
|
||||
}elseif($_GET['type'] === 'del_images'){
|
||||
session_start();
|
||||
@@ -514,7 +568,9 @@ function write_link(){
|
||||
}
|
||||
//删除图标(如果是本地图标则同时删除文件)
|
||||
if(preg_match("/^\.\/data\/user\/{$u}\/favicon\//",$link['icon']) && is_file($link['icon'])){
|
||||
@unlink($link['icon']);
|
||||
if(!has_db('user_links',['uid'=>UID,'lid[!]'=>$link['lid'],'icon'=>$link['icon'] ])){ //判断是否共用
|
||||
@unlink($link['icon']);
|
||||
}
|
||||
}
|
||||
//更新记录
|
||||
update_db('user_links',['icon'=>''],['uid'=>UID,'lid'=>$_POST['link_id']],[1,'删除成功']);
|
||||
@@ -529,6 +585,7 @@ function write_link(){
|
||||
$title = $_POST['title'];
|
||||
$url = $_POST['url'];
|
||||
$icon = $_POST['icon'];
|
||||
$keywords = empty($_POST['keywords']) ? '' : $_POST['keywords'];
|
||||
$description = empty($_POST['description']) ? '' : $_POST['description'];
|
||||
$property = empty($_POST['property']) ? 0 : 1;
|
||||
//检测链接是否合法
|
||||
@@ -538,6 +595,10 @@ function write_link(){
|
||||
if($length_limit['l_desc'] > 0 && strlen($description) > $length_limit['l_desc'] ){
|
||||
msg(-1,'描述长度不能大于'.$length_limit['l_desc'].'个字节');
|
||||
}
|
||||
//关键字长度检测
|
||||
if($length_limit['l_key'] > 0 && strlen($keywords) > $length_limit['l_key'] ){
|
||||
msg(-1,'关键字长度不能大于'.$length_limit['l_key'].'个字节');
|
||||
}
|
||||
//检查链接是否已存在
|
||||
if(has_db('user_links',['uid'=>UID ,'lid[!]'=>$lid, "url" => $url])){msg(-1,'链接已存在!');}
|
||||
//检查链接ID是否存在
|
||||
@@ -549,6 +610,7 @@ function write_link(){
|
||||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||||
'url' => $url,
|
||||
'url_standby' => $_POST['url_standby']??'',
|
||||
'keywords' => htmlspecialchars($keywords,ENT_QUOTES),
|
||||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||||
'up_time' => time(),
|
||||
'property' => $property,
|
||||
@@ -568,7 +630,6 @@ function write_link(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//非必须参数,未传递参数时
|
||||
@@ -590,8 +651,11 @@ function write_link(){
|
||||
if(!isset($_POST['pwd_id'])){
|
||||
unset($data['pid']);
|
||||
}
|
||||
if(!isset($_POST['keywords'])){
|
||||
unset($data['keywords']);
|
||||
}
|
||||
//更新数据
|
||||
update_db('user_links',$data,['uid'=>UID,'lid'=>intval($_POST['lid']) ]);
|
||||
update_db('user_links',$data,['uid'=>UID,'lid'=>$lid ]);
|
||||
msgA(['code'=>1,'msg'=>'修改成功','icon' => $icon]);
|
||||
//删除
|
||||
}elseif($_GET['type'] === 'del'){
|
||||
@@ -603,7 +667,9 @@ function write_link(){
|
||||
|
||||
//如果存在本地图标,则先删除
|
||||
if(!empty($link['icon']) && preg_match("/^\.\/data\/user\/{$u}\/favicon\//",$link['icon']) && is_file($link['icon'])){
|
||||
@unlink($link['icon']);
|
||||
if(!has_db('user_links',['uid'=>UID,'lid[!]'=>$link['lid'],'icon'=>$link['icon'] ])){ //判断是否共用
|
||||
@unlink($link['icon']);
|
||||
}
|
||||
}
|
||||
//删除数据
|
||||
delete_db('user_links',['uid'=>UID ,"lid" => intval($_POST['lid'])],[1,'删除成功']);
|
||||
@@ -670,40 +736,157 @@ function write_link(){
|
||||
if(empty($fid)){msg(-1,'分类ID错误');}
|
||||
//加一个查找分类是否存在
|
||||
update_db('user_links',['fid'=>$fid],['uid'=>UID ,"lid" => json_decode($_POST['lid']) ],[1,'设置成功']);
|
||||
//图标拉取(不完善,未开放使用)
|
||||
//检测是否满足要求
|
||||
}elseif($_GET['type'] === 'msg_pull_check'){
|
||||
if($global_config['offline']){
|
||||
msg(-1,"离线模式不可用");
|
||||
}
|
||||
if(!is_subscribe('bool')){
|
||||
msg(-1,"未检测到有效授权,无法使用该功能!");
|
||||
}
|
||||
if(intval($_POST['icon']) > 0){
|
||||
if(!check_purview('icon_pull',1)){
|
||||
msg(-1,'您所在的用户组,无法使用网站图标获取功能');
|
||||
}
|
||||
$path = DIR ."/data/user/".U."/favicon";
|
||||
if(!Check_Path($path)){
|
||||
msg(-1,'创建目录失败,请检查目录权限');
|
||||
}
|
||||
$config = unserialize( get_db("global_config", "v", ["k" => "icon_config"])) ?? [];
|
||||
if($config['o_switch'] == '0'){
|
||||
msg(-1,'相关服务处于关闭状态,请联系站长开启');
|
||||
}
|
||||
}
|
||||
session_start();
|
||||
$key = md5(uniqid().Get_Rand_Str(8));
|
||||
$_SESSION['msg_pull']["$key"] = true;
|
||||
msgA(['code'=>1,'msg'=>'success','key'=>$key]);
|
||||
}elseif($_GET['type'] === 'msg_pull'){
|
||||
session_start();
|
||||
$key = $_POST['key'];
|
||||
if(empty($key) || !$_SESSION['msg_pull']["$key"]){
|
||||
msg(-1,'key验证失败,请重试!');
|
||||
}elseif(empty($_POST['link_id'])){
|
||||
msg(-1,'链接ID不能为空');
|
||||
}
|
||||
//读取信息
|
||||
$link = get_db('user_links','*',['uid'=>UID ,'lid'=>$_POST['link_id'] ]);
|
||||
//检查链接
|
||||
if(empty($link)){
|
||||
msg(-1,'链接ID不存在');
|
||||
}elseif(!preg_match("/^(http:\/\/|https:\/\/).*/",$link['url'])){
|
||||
msg(-1,'只支持识别http/https协议的链接!');
|
||||
}elseif( !filter_var($link['url'], FILTER_VALIDATE_URL) ) {
|
||||
msg(-1,'URL无效!');
|
||||
}
|
||||
|
||||
//是否获取站点信息
|
||||
if( ( intval($_POST['title']) + intval($_POST['keywords']) + intval($_POST['description']) ) > 0 ){
|
||||
//读取长度限制配置
|
||||
$length_limit = unserialize(get_db("global_config","v",["k"=>"length_limit"]));
|
||||
//获取网站标题
|
||||
$c = curl_init();
|
||||
curl_setopt($c, CURLOPT_URL, $link['url']);
|
||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36');
|
||||
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($c , CURLOPT_TIMEOUT, 10);
|
||||
$data = curl_exec($c);
|
||||
curl_close($c);
|
||||
require (DIR .'/system/get_page_info.php');
|
||||
$info = get_page_info($data);
|
||||
$new = [];
|
||||
if(intval($_POST['title']) > 0 && !empty($info['site_title'])){
|
||||
$new['title'] = $info['site_title'];
|
||||
if($length_limit['l_name'] > 0 && strlen($new['title']) > $length_limit['l_name'] ){
|
||||
$new['title'] = mb_substr($new['title'], 0, $length_limit['l_name'], 'utf-8');
|
||||
}
|
||||
}
|
||||
if(intval($_POST['keywords']) > 0 && !empty($info['site_keywords'])){
|
||||
$new['keywords'] = (empty($link['keywords']) || $_POST['keywords'] == '2') ? $info['site_keywords'] : $link['keywords'];
|
||||
if($length_limit['l_key'] > 0 && strlen($new['keywords']) > $length_limit['l_key'] ){
|
||||
$new['keywords'] = mb_substr($new['keywords'], 0, $length_limit['l_key'], 'utf-8');
|
||||
}
|
||||
}
|
||||
if(intval($_POST['description']) > 0 && !empty($info['site_description'])){
|
||||
$new['description'] = (empty($link['description']) || $_POST['description'] == '2') ? $info['site_description'] : $link['description'];
|
||||
if($length_limit['l_desc'] > 0 && strlen($new['description']) > $length_limit['l_desc'] ){
|
||||
$new['description'] = mb_substr($new['description'], 0, $length_limit['l_desc'], 'utf-8');
|
||||
}
|
||||
}
|
||||
if(empty($new)){
|
||||
$r['info'] = 'fail';
|
||||
}else{
|
||||
update_db('user_links',$new,['uid'=>UID ,"lid" => $link['lid'] ]);
|
||||
$r['info'] = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
//是否获取图标
|
||||
if(intval($_POST['icon']) > 0){
|
||||
//检查跳过已存在图标的链接
|
||||
if($_POST['icon'] == '1' && !empty($link['icon'])){
|
||||
$r['icon'] = 'skip';
|
||||
}
|
||||
$api = Get_Index_URL().'?c=icon&url='.base64_encode($link['url']);
|
||||
$res = ccurl($api,30,true);
|
||||
$data = get_db('global_icon','*',['url_md5'=>md5($link['url'])]);
|
||||
if(empty($data)){
|
||||
$r['icon'] = 'fail';
|
||||
}
|
||||
$new_path = "./data/user/".U.'/favicon/'.$data['file_name'];
|
||||
if(copy("./data/icon/{$data['file_name']}",$new_path)){
|
||||
update_db('user_links',['icon'=>$new_path],['uid'=>UID ,"lid" => $link['lid'] ]);
|
||||
$r['icon'] = 'success';
|
||||
}else{
|
||||
$r['icon'] = 'fail';
|
||||
}
|
||||
}
|
||||
|
||||
msg(1,$r);
|
||||
//图标拉取
|
||||
}elseif($_GET['type'] === 'icon_pull'){
|
||||
$link = get_db('user_links','url',['uid'=>UID,'lid'=>$_POST['id']]);
|
||||
if($global_config['offline']){
|
||||
msg(-1,"离线模式不可用");
|
||||
}
|
||||
if(!is_subscribe('bool')){
|
||||
msg(-1,"未检测到有效授权,无法使用该功能!");
|
||||
}
|
||||
if(!check_purview('icon_pull',1)){
|
||||
msg(-1,'无权限');
|
||||
}
|
||||
$link = get_db('user_links','*',['uid'=>UID,'lid'=>$_POST['id']]);
|
||||
if(empty($link)){
|
||||
msg(-1,'请求的链接id不存在');
|
||||
}
|
||||
$s_site = unserialize(get_db("user_config","v",["k"=>"s_site","uid"=>UID]));
|
||||
if(empty($s_site['link_icon']) || $s_site['link_icon'] == 0){
|
||||
msg(-1,'站点设置链接图标不能是离线图标!请先修改配置!');
|
||||
$path = DIR ."/data/user/".U."/favicon";
|
||||
if(!Check_Path($path)){
|
||||
msg(-1,'创建目录失败,请检查权限');
|
||||
}
|
||||
$icon = $s_site['link_icon'];
|
||||
if($icon ==2){
|
||||
function base64($url){
|
||||
$urls = parse_url($url);
|
||||
$scheme = empty( $urls['scheme'] ) ? 'http://' : $urls['scheme'].'://'; //获取请求协议
|
||||
$host = $urls['host']; //获取主机名
|
||||
$port = empty( $urls['port'] ) ? '' : ':'.$urls['port']; //获取端口
|
||||
$new_url = $scheme.$host.$port;
|
||||
return base64_encode($new_url);
|
||||
}
|
||||
$api = 'https://favicon.rss.ink/v1/'.base64($link);
|
||||
}elseif($icon ==4){
|
||||
$api = 'https://api.15777.cn/get.php?url='.$link;
|
||||
}elseif($icon ==5){
|
||||
$api = 'https://favicon.cccyun.cc/'.$link;
|
||||
}elseif($icon ==6){
|
||||
$api = 'https://api.iowen.cn/favicon/'.parse_url($link)['host'].'.png';
|
||||
}elseif($icon ==7){
|
||||
$api = 'https://toolb.cn/favicon/'.parse_url($link)['host'];
|
||||
//检查配置
|
||||
$config = unserialize( get_db("global_config", "v", ["k" => "icon_config"])) ?? [];
|
||||
if($config['o_switch'] == '0'){
|
||||
msg(-1,'相关服务处于关闭状态,请联系站长开启');
|
||||
}
|
||||
if(downFile($api,$_POST['id'].'.ico',DIR ."/data/user/".U."/favicon/")){
|
||||
update_db('user_links',['icon'=>"./data/user/".U.'/favicon/'.$_POST['id'].'.ico'],['uid'=>UID ,"lid" => $_POST['id'] ],[1,'获取成功']);
|
||||
|
||||
//跳过存在图标的链接
|
||||
if(empty($_POST['cover']) && !empty($link['icon'])){
|
||||
msg(1,'skip');
|
||||
}
|
||||
msg(-1,'获取失败');
|
||||
|
||||
$api = Get_Index_URL().'?c=icon&url='.base64_encode($link['url']);
|
||||
$res = ccurl($api,30,true);
|
||||
$data = get_db('global_icon','*',['url_md5'=>md5($link['url'])]);
|
||||
if(empty($data)){
|
||||
msg(1,'fail');
|
||||
}
|
||||
$new_path = "./data/user/".U.'/favicon/'.$data['file_name'];
|
||||
if(copy("./data/icon/{$data['file_name']}",$new_path)){
|
||||
update_db('user_links',['icon'=>$new_path],['uid'=>UID ,"lid" => $_POST['id'] ],[1,'success']);
|
||||
}
|
||||
msg(1,'fail');
|
||||
|
||||
}elseif($_GET['type'] == 'extend_list'){
|
||||
if($GLOBALS['global_config']['link_extend'] != 1 ||!check_purview('link_extend',1)){
|
||||
@@ -722,7 +905,7 @@ function write_link(){
|
||||
if(empty($data['name']) || check_xss($data['name']) || !preg_match('/^[A-Za-z0-9]{3,18}$/',$data['name'])){
|
||||
msgA( ['code' => -1,'msg' => '字段名错误,请输入长度3-18的字母/数字'] );
|
||||
}
|
||||
if(!in_array($data['type'],['text','textarea'])){
|
||||
if(!in_array($data['type'],['text','textarea','up_img'])){
|
||||
msgA( ['code' => -1,'msg' => '类型错误'] );
|
||||
}
|
||||
}
|
||||
@@ -736,7 +919,7 @@ function write_link(){
|
||||
|
||||
$datas = [];
|
||||
foreach ($lists as $key => $data ){
|
||||
array_push($datas,['title'=>$data['title'],'name'=>$data['name'],'weight'=>$data['weight'],'type'=>$data['type'],'default'=> "{$data['default']}"]);
|
||||
array_push($datas,['title'=>$data['title'],'name'=>$data['name'],'weight'=>$data['weight'],'type'=>$data['type'],'default'=> "{$data['default']}",'tip'=>$data['tip']]);
|
||||
}
|
||||
//根据序号排序
|
||||
usort($datas, function($a, $b) {
|
||||
@@ -755,7 +938,7 @@ function write_security_setting(){
|
||||
global $USER_DB;
|
||||
if($USER_DB['Password'] !== Get_MD5_Password($_POST['Password'],$USER_DB['RegTime'])){
|
||||
msg(-1,'密码错误,请核对后再试!');
|
||||
}elseif( $_POST['KeyClear'] > $_POST['Session']){
|
||||
}elseif( intval($_POST['Session']) > 0 && intval($_POST['KeyClear']) > intval($_POST['Session'])){
|
||||
msg(-1,'Key清理时间不能大于登录保持时间');
|
||||
}
|
||||
|
||||
@@ -764,11 +947,11 @@ function write_security_setting(){
|
||||
'HttpOnly'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'HttpOnly参数错误'],
|
||||
'KeySecurity'=>['int'=>true,'min'=>0,'max'=>2,'msg'=>'Key安全参数错误'],
|
||||
'KeyClear'=>['int'=>true,'min'=>1,'max'=>60,'msg'=>'Key清理参数错误'],
|
||||
'api_model'=>['v'=>['security','compatible','compatible+open'],'msg'=>'API模式参数错误'],
|
||||
'api_model'=>['v'=>['security','compatible'],'msg'=>'API模式参数错误'],
|
||||
'login_page'=>['v'=>['admin','index','auto'],'msg'=>'登录成功参数错误'],
|
||||
'Password2'=>['empty'=>true]
|
||||
];
|
||||
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
foreach ($datas as $key => $data){
|
||||
if($data['int']){
|
||||
$LoginConfig[$key] = ($_POST[$key] >= $data['min'] && $_POST[$key] <= $data['max'])?intval($_POST[$key]):msg(-1,$data['msg']);
|
||||
@@ -809,11 +992,19 @@ function write_apply(){
|
||||
if($_GET['type'] == 'set'){
|
||||
$s['apply'] = intval($_POST['apply']); // 功能选项0.关闭 1.需要审核 2.无需审核
|
||||
$s['Notice'] = $_POST['Notice']??''; // 公告
|
||||
$s['submit_limit'] = intval($_POST['submit_limit']); //提交限制
|
||||
$s['iconurl'] = $_POST['iconurl'];
|
||||
$s['description'] = $_POST['description'];
|
||||
$s['email'] = $_POST['email'];
|
||||
|
||||
if($s['apply'] < 0 || $s['apply'] > 2 ){
|
||||
msg(-1102,'参数错误!');
|
||||
msg(-1,'参数错误!');
|
||||
}elseif(strlen($s['Notice']) > 512){
|
||||
msg(-1102,'公告长度超限!');
|
||||
msg(-1,'公告长度超限!');
|
||||
}if(empty($_POST['submit_limit']) || !preg_match("/^\d*$/",$_POST['submit_limit'])){
|
||||
msg(-1,'提交限制必须为正整数!');
|
||||
}
|
||||
|
||||
write_user_config('apply',$s,'config','收录配置');
|
||||
msg(1,'保存成功');
|
||||
}elseif($_GET['type'] == '2'){ //通过
|
||||
@@ -842,6 +1033,7 @@ function write_apply(){
|
||||
'url' => $link['url'],
|
||||
'description' => $link['description'],
|
||||
'add_time' => time(),
|
||||
'up_time' => time(),
|
||||
'icon' => $link['iconurl']
|
||||
];
|
||||
insert_db('user_links',$data);//插入链接
|
||||
@@ -948,10 +1140,10 @@ function write_site_setting(){
|
||||
'description'=>['empty'=>true],
|
||||
'link_model'=>['v'=>['direct','Privacy','Privacy_js','Privacy_meta','301','302','Transition'],'msg'=>'链接模式参数错误'],
|
||||
'main_link_priority'=>['int'=>true,'min'=>0,'max'=>3,'msg'=>'主链优先参数错误'],
|
||||
'link_icon'=>['int'=>true,'min'=>0,'max'=>10,'msg'=>'链接图标参数错误'],
|
||||
'link_icon'=>['int'=>true,'min'=>0,'max'=>30,'msg'=>'链接图标参数错误'],
|
||||
'site_icon'=>['empty'=>true],
|
||||
'top_link'=>['int'=>true,'min'=>0,'max'=>20,'msg'=>'热门链接参数错误'],
|
||||
'new_link'=>['int'=>true,'min'=>0,'max'=>20,'msg'=>'最新链接参数错误'],
|
||||
'top_link'=>['int'=>true,'min'=>0,'max'=>100,'msg'=>'热门链接参数错误'],
|
||||
'new_link'=>['int'=>true,'min'=>0,'max'=>100,'msg'=>'最新链接参数错误'],
|
||||
'max_link'=>['int'=>true,'min'=>0,'max'=>100,'msg'=>'输出上限参数错误'],
|
||||
'custom_header'=>['empty'=>true],
|
||||
'custom_footer'=>['empty'=>true]
|
||||
@@ -980,7 +1172,8 @@ function write_site_setting(){
|
||||
function write_transit_setting(){
|
||||
$datas = [
|
||||
'visitor_stay_time'=>['int'=>true,'min'=>0,'max'=>60,'msg'=>'访客停留时间范围0-60'],
|
||||
'admin_stay_time'=>['int'=>true,'min'=>0,'max'=>60,'msg'=>'管理员停留时间范围0-60']
|
||||
'admin_stay_time'=>['int'=>true,'min'=>0,'max'=>60,'msg'=>'管理员停留时间范围0-60'],
|
||||
'default_keywords'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'默认关键字参数错误']
|
||||
];
|
||||
|
||||
foreach ($datas as $key => $data){
|
||||
@@ -1018,6 +1211,65 @@ function write_user_password(){
|
||||
msg(1,'修改成功');
|
||||
}
|
||||
|
||||
|
||||
//读双重验证
|
||||
function read_totp(){
|
||||
global $USER_DB;
|
||||
if($USER_DB['Password'] !== Get_MD5_Password($_POST['Password'],$USER_DB['RegTime'])){
|
||||
msg(-1102,'密码错误,请核对后再试!');
|
||||
}
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
if(empty($LoginConfig['totp_key'])){
|
||||
require DIR . '/system/Authenticator.php';
|
||||
$totp = new PHPGangsta_GoogleAuthenticator();
|
||||
$key = $totp->createSecret();
|
||||
msgA(['code'=>2,'msg'=>'未开启双重验证','key'=> $key ]);
|
||||
}
|
||||
msgA(['code'=>1,'msg'=>'已开启双重验证']);
|
||||
}
|
||||
|
||||
//写双重验证
|
||||
function write_totp(){
|
||||
global $USER_DB;
|
||||
if($USER_DB['Password'] !== Get_MD5_Password($_POST['Password'],$USER_DB['RegTime'])){
|
||||
msg(-1102,'密码错误,请核对后再试!');
|
||||
}
|
||||
|
||||
if($_GET['type'] === 'delete'){ //删除双重验证
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
if(empty($LoginConfig['totp_key'])){
|
||||
msgA(['code'=>-1,'msg'=>'未开启双重验证',]);
|
||||
}
|
||||
$LoginConfig['totp_key'] = '';
|
||||
update_db("global_user", ["LoginConfig"=>$LoginConfig],["ID"=>UID],[1,'操作成功']);
|
||||
}elseif($_GET['type'] === 'set'){ //设置双重验证
|
||||
//必填项验证
|
||||
if(empty($_POST['key'])){
|
||||
msgA(['code'=>-1,'msg'=>'Key不能为空']);
|
||||
}elseif(empty($_POST['code'])){
|
||||
msgA(['code'=>-1,'msg'=>'验证码不能为空']);
|
||||
}
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
if(!empty($LoginConfig['totp_key'])){
|
||||
msgA(['code'=>-1,'msg'=>'已开启双重验证,无法继续开启!']);
|
||||
}
|
||||
//载入totp库
|
||||
require DIR . '/system/Authenticator.php';
|
||||
$totp = new PHPGangsta_GoogleAuthenticator();
|
||||
$checkResult = $totp->verifyCode($_POST['key'], $_POST['code'], 2);
|
||||
if(!$checkResult){
|
||||
msgA(['code'=>-1,'msg'=>'验证失败,请重试']);
|
||||
}
|
||||
//写入数据库
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
$LoginConfig['totp_key'] = $_POST['key'];
|
||||
update_db("global_user", ["LoginConfig"=>$LoginConfig],["ID"=>UID],[1,'操作成功']);
|
||||
}else{
|
||||
msg(-1,'请求参数有误');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//查Token
|
||||
function read_token(){
|
||||
global $USER_DB;
|
||||
@@ -1101,7 +1353,7 @@ function other_testing_link(){
|
||||
if ( $global_config['offline'] == '1'){ msg(-1,"离线模式无法使用此功能"); }
|
||||
$code = get_http_code($_POST['url']);
|
||||
if($code != 200 && $code != 302 && $code != 301){
|
||||
$code = ccurl($_POST['url'])['code'];
|
||||
$code = ccurl($_POST['url'],30)['code'];
|
||||
}
|
||||
msgA(['code' => 0 ,'StatusCode'=> $code]);
|
||||
}
|
||||
@@ -1109,7 +1361,7 @@ function other_testing_link(){
|
||||
//主题下载/更新/删除
|
||||
function write_theme(){
|
||||
global $global_config;
|
||||
$fn = $_POST['fn'];if($_GET['type'] != 'config' && !in_array($fn,['home','login','transit','register','guide'])){msg(-1,'fn参数错误');}
|
||||
$fn = $_POST['fn'];if($_GET['type'] != 'config' && !in_array($fn,['home','login','transit','register','guide','article'])){msg(-1,'fn参数错误');}
|
||||
if($_GET['type'] == 'download'){
|
||||
is_root();
|
||||
if($global_config['offline']){msg(-1,"离线模式禁止下载主题!");} //离线模式
|
||||
@@ -1121,6 +1373,9 @@ function write_theme(){
|
||||
}else{
|
||||
msg(-1,"获取程序版本异常");
|
||||
}
|
||||
if(!is_writable('./templates')){
|
||||
msg(-1,"检测到模板目录不可写<br />请检查templates目录权限<br />宝塔面板请注意所有者为www<br />其他疑问请联系技术支持");
|
||||
}
|
||||
//从数据库查找主题信息
|
||||
$template = get_db('global_config','v',['k'=> 'theme_'.$fn.'_cache']);
|
||||
if(empty($template)){
|
||||
@@ -1140,7 +1395,10 @@ function write_theme(){
|
||||
}
|
||||
|
||||
//下载主题包
|
||||
if (!is_dir('./data/temp')) mkdir('./data/temp',0755,true) or msg(-1,'下载失败,创建临时[/data/temp]目录失败');
|
||||
if(!is_dir('./data/temp')) mkdir('./data/temp',0755,true) or msg(-1,'下载失败,创建临时[/data/temp]目录失败');
|
||||
if(!is_writable('./data/temp')){
|
||||
msg(-1,"检测到临时目录不可写<br />请检查data/temp目录权限<br />宝塔面板请注意所有者为www<br />其他疑问请联系技术支持");
|
||||
}
|
||||
$data = $key;
|
||||
foreach($data['url'] as $url){
|
||||
if(downFile( $url , $file , DIR.'/data/temp/')){
|
||||
@@ -1224,6 +1482,8 @@ function write_theme(){
|
||||
$s_templates['login'] = $name;
|
||||
}elseif($fn == 'transit'){
|
||||
$s_templates['transit'] = $name;
|
||||
}elseif($fn == 'article'){
|
||||
$s_templates['article'] = $name;
|
||||
}elseif($fn == 'register'){
|
||||
$global_templates['register'] = $name;
|
||||
update_db('global_config',['v'=>$global_templates],['k'=>'s_templates'],[1,'注册模板设置成功']);
|
||||
@@ -1248,7 +1508,7 @@ function write_theme(){
|
||||
msg(-1,"获取模板类型错误");
|
||||
}
|
||||
$fn = empty($GET['fn']) ? $_GET['template_type'] : $GET['fn'];
|
||||
if(!in_array($fn,['home','login','register','transit','guide'])){
|
||||
if(!in_array($fn,['home','login','register','transit','guide','article'])){
|
||||
msg(-1,"参数错误");
|
||||
}
|
||||
//0420 END
|
||||
@@ -1264,7 +1524,7 @@ function read_login_info(){
|
||||
$limit = empty(intval($_REQUEST['limit'])) ? 50 : intval($_REQUEST['limit']);
|
||||
$offset = ($page - 1) * $limit; //起始行号
|
||||
$where["uid"] = UID;
|
||||
$where["cookie_key[!]"] = md5($_COOKIE[U.'_key']);
|
||||
//$where["cookie_key[!]"] = md5($_COOKIE[U.'_key']); //不显示当前设备
|
||||
//统计条数
|
||||
$count = count_db('user_login_info',$where);
|
||||
//权重排序(数字小的排前面)
|
||||
@@ -1273,7 +1533,10 @@ function read_login_info(){
|
||||
$where['LIMIT'] = [$offset,$limit];
|
||||
//查询
|
||||
$datas = select_db('user_login_info',['id','ip','ua','login_time','last_time','expire_time'],$where);
|
||||
msgA(['code'=>1,'msg'=>'获取成功','count'=>$count,'data'=>$datas]);
|
||||
//获取当前登录ID,用于前端标记
|
||||
$where["cookie_key"] = md5($_COOKIE[U.'_key']);
|
||||
$current_id = get_db('user_login_info','id',$where);
|
||||
msgA(['code'=>1,'msg'=>'获取成功','count'=>$count,'data'=>$datas,'current_id'=>$current_id]);
|
||||
}
|
||||
|
||||
//写登录信息
|
||||
@@ -1428,7 +1691,7 @@ function write_data_control(){
|
||||
function read_data(){
|
||||
global $USER_DB;
|
||||
//指定类型限制仅root账号可用!
|
||||
if(in_array($USER_DB['UserGroup'] != 'root' && $_GET['type'],['diagnostic_log','phpinfo'])){
|
||||
if($USER_DB['UserGroup'] != 'root' && in_array( $_GET['type'],['diagnostic_log','connectivity_test','phpinfo'])){
|
||||
msg(-1,'无权限');
|
||||
}
|
||||
|
||||
@@ -1439,7 +1702,26 @@ function read_data(){
|
||||
$index_count = get_db('user_count','v',['uid'=>UID,'k'=>date('Ym'),'t'=>'index_Ym'])??0;
|
||||
$click_count = get_db('user_count','v',['uid'=>UID,'k'=>date('Ym'),'t'=>'click_Ym'])??0;
|
||||
msgA( ['code'=>1,'data'=>[$category_count,$link_count,$index_count,$click_count] ]);
|
||||
|
||||
//连通测试
|
||||
}elseif($_GET['type'] == 'connectivity_test'){
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $_POST['url']);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
$start = microtime(true);
|
||||
$response = curl_exec($ch);
|
||||
$end = microtime(true);
|
||||
$time = round(($end - $start) * 1000, 2);
|
||||
if(curl_errno($ch)) {
|
||||
$log .= "请求发生错误:".curl_error($ch);
|
||||
} else {
|
||||
$log .= "响应内容:".$response ?? 'Null' ;
|
||||
$log .= ",访问耗时:{$time} 毫秒。" ;
|
||||
}
|
||||
curl_close($ch);
|
||||
msg(1,$log);
|
||||
//一键诊断
|
||||
}elseif($_GET['type'] == 'diagnostic_log'){
|
||||
clearstatcache(); //清除缓存
|
||||
@@ -1507,7 +1789,53 @@ function read_data(){
|
||||
msg(1,$log);
|
||||
//输出phpinfo信息
|
||||
}elseif($_GET['type'] == 'phpinfo'){
|
||||
phpinfo();
|
||||
session_start();
|
||||
if($_SESSION['phpinfo_id'] != $_GET['pid']){
|
||||
exit('验证失败,请刷新页面后重试!');
|
||||
}elseif(Get_MD5_Password($_GET["p"],$GLOBALS['USER_DB']["RegTime"]) === $GLOBALS['USER_DB']["Password"]){
|
||||
$_COOKIE = [];
|
||||
$_SERVER['HTTP_COOKIE'] = 'privacy';
|
||||
phpinfo();
|
||||
}else{
|
||||
exit('密码验证失败,请重试!');
|
||||
}
|
||||
//报表统计
|
||||
}elseif($_GET['type'] == 'echarts'){
|
||||
$days = isset($_GET['date']) && !empty($_GET['date']) ? $_GET['date'] : 7;
|
||||
$dates = [];
|
||||
for ($i = 0; $i < $days; $i++) {
|
||||
$date = date('Ymd', strtotime("-$i days"));
|
||||
$dates[] = $date;
|
||||
}
|
||||
$dates = array_reverse($dates);
|
||||
$day_data = [];
|
||||
array_push($day_data, ['name' => '访问量', 'type' => 'line', 'data' => []]);
|
||||
array_push($day_data, ['name' => '点击量', 'type' => 'line', 'data' => []]);
|
||||
array_push($day_data, ['name' => 'IP数', 'type' => 'line', 'data' => []]);
|
||||
foreach ($dates as $date) {
|
||||
array_push($day_data[0]['data'], get_db('user_count', 'v', ['uid' => UID, 'k' => $date, 't' => 'index_Ymd']) ?? 0);
|
||||
array_push($day_data[1]['data'], get_db('user_count', 'v', ['uid' => UID, 'k' => $date, 't' => 'click_Ymd']) ?? 0);
|
||||
array_push($day_data[2]['data'], get_db('user_count', 'v', ['uid' => UID, 'k' => $date, 't' => 'ip_count']) ?? 0);
|
||||
}
|
||||
|
||||
$data = ['dates'=>$dates,'day_data'=>$day_data];
|
||||
msgA(['code'=>1,'data'=>$data]);
|
||||
}elseif($_GET['type'] == 'tongji_ip_list'){
|
||||
$days = isset($_GET['date']) && !empty($_GET['date']) ? $_GET['date'] : 7;
|
||||
$dates = [];
|
||||
for ($i = 0; $i < $days; $i++) {
|
||||
$date = date('Ymd', strtotime("-$i days"));
|
||||
$dates[] = $date;
|
||||
}
|
||||
|
||||
$dates = array_reverse($dates);
|
||||
$day_data = [];
|
||||
foreach ($dates as $date) {
|
||||
$list = get_db('user_count', 'e', ['uid' => UID, 'k' => $date, 't' => 'ip_list']);
|
||||
$list = unserialize($list);
|
||||
$day_data[$date] = empty($list) ? [] : $list ;
|
||||
}
|
||||
msgA(['code'=>1,'data'=>$day_data]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1516,6 +1844,17 @@ function other_local_backup(){
|
||||
require DIR . '/system/UseFew/local_backup.php';
|
||||
exit;
|
||||
}
|
||||
//读文章
|
||||
function read_article(){
|
||||
require DIR . '/system/api_article.php';
|
||||
exit;
|
||||
}
|
||||
//写文章
|
||||
function write_article(){
|
||||
require DIR . '/system/api_article.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
//获取链接信息
|
||||
function other_get_link_info(){
|
||||
global $global_config;
|
||||
@@ -1535,6 +1874,7 @@ function other_get_link_info(){
|
||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36');
|
||||
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1); //允许重定向,解决http跳转到https无法识别
|
||||
curl_setopt($c , CURLOPT_TIMEOUT, 5); //设置超时时间
|
||||
$data = curl_exec($c);
|
||||
@@ -1543,6 +1883,7 @@ function other_get_link_info(){
|
||||
require (DIR .'/system/get_page_info.php');
|
||||
$info = get_page_info($data);
|
||||
$link['title'] = $info['site_title'];
|
||||
$link['keywords'] = $info['site_keywords'];
|
||||
$link['description'] = $info['site_description'];
|
||||
msgA(['code'=>1,'data'=>$link]);
|
||||
}
|
||||
|
||||
222
system/api_article.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
|
||||
$type = htmlspecialchars(trim($_GET['type']),ENT_QUOTES);
|
||||
|
||||
if (function_exists($type) ) {
|
||||
if($GLOBALS['global_config']['article'] < 1 || !check_purview('article',1)){
|
||||
msg(-1,'无权限');
|
||||
}
|
||||
$type();
|
||||
}else{
|
||||
Amsg(-1,'请求类型错误 >> '.$type);
|
||||
}
|
||||
|
||||
//上传图片
|
||||
function uploadImage(){
|
||||
global $u;
|
||||
//权限检测
|
||||
if(!check_purview('article_image',1)){
|
||||
msgA(['errno'=>-1,'message'=>'您的用户组无权限上传图片']);
|
||||
}elseif(empty($_FILES["file"]) || $_FILES["file"]["error"] > 0){
|
||||
msgA(['errno'=>-1,'message'=>'文件上传失败']);
|
||||
}
|
||||
|
||||
//取后缀并判断是否支持
|
||||
$suffix = strtolower(end(explode('.',$_FILES["file"]["name"])));
|
||||
if(!preg_match('/^(jpg|png|gif|bmp|jpeg|svg|webp)$/',$suffix)){
|
||||
@unlink($_FILES["file"]["tmp_name"]);
|
||||
msgA(['errno'=>-1,'message'=>'文件格式不被支持']);
|
||||
}
|
||||
//限制文件大小
|
||||
if(filesize($_FILES["file"]["tmp_name"]) > 5 * 1024 * 1024){
|
||||
msgA(['errno'=>-1,'message'=>'文件大小超限']);
|
||||
}
|
||||
//文件临时路径
|
||||
$ym = date("Ym");
|
||||
$path = DIR . "/data/user/{$u}/upload/{$ym}/";
|
||||
//检测目录,不存在则创建!
|
||||
if(!Check_Path($path)){
|
||||
msgA(['errno'=>-1,'message'=>'创建upload目录失败,请检查权限']);
|
||||
}
|
||||
$tmp_name = 'AI_'.uniqid().'.'.$suffix;
|
||||
//移动文件
|
||||
if(!move_uploaded_file($_FILES["file"]["tmp_name"],"{$path}/{$tmp_name}")) {
|
||||
msgA(['errno'=>-1,'message'=>'上传失败,请检查目录权限']);
|
||||
}else{
|
||||
msgA(['errno'=>0,'data'=>['url'=>"./data/user/{$u}/upload/{$ym}/$tmp_name",'alt'=>$_FILES["file"]["name"],'href'=>''],'message'=>'上传成功']);
|
||||
}
|
||||
}
|
||||
//删除图片
|
||||
function deleteImage(){
|
||||
global $u;
|
||||
if(empty($_POST['path'])){
|
||||
msg(-1,'请求参数错误');
|
||||
}
|
||||
$path = $_POST['path'];
|
||||
$pattern = "/^\.\/data\/user\/{$u}\/upload\/\d{6}\/AI_[A-Za-z0-9_]+\.(jpg|png|gif|bmp|jpeg|svg|webp)$/i";
|
||||
if(preg_match($pattern,$path) && is_file($path)){
|
||||
@unlink($path);
|
||||
}else{
|
||||
msg(-1,'请求参数错误');
|
||||
}
|
||||
//需考虑编辑文章删除封面时未点击保存的情况
|
||||
if(is_file($path)){
|
||||
msg(-1,'删除失败');
|
||||
}else{
|
||||
msg(1,'删除成功');
|
||||
}
|
||||
}
|
||||
//上传视频
|
||||
function uploadVideo(){
|
||||
msgA(['errno'=>-1,'message'=>'未开放']);
|
||||
global $u;
|
||||
//权限检测
|
||||
if(!check_purview('article_image',1)){
|
||||
msgA(['errno'=>-1,'message'=>'您的用户组无权限上传视频']);
|
||||
}elseif(empty($_FILES["file"]) || $_FILES["file"]["error"] > 0){
|
||||
msgA(['errno'=>-1,'message'=>'文件上传失败']);
|
||||
}
|
||||
|
||||
//取后缀并判断是否支持
|
||||
$suffix = strtolower(end(explode('.',$_FILES["file"]["name"])));
|
||||
if(!preg_match('/^(avi|mp4|wma|rmvb|rm|flash|3gp|flv)$/',$suffix)){
|
||||
@unlink($_FILES["file"]["tmp_name"]);
|
||||
msgA(['errno'=>-1,'message'=>'文件格式不被支持']);
|
||||
}
|
||||
//限制文件大小
|
||||
if(filesize($_FILES["file"]["tmp_name"]) > 20 * 1024 * 1024){
|
||||
msgA(['errno'=>-1,'message'=>'文件大小超限']);
|
||||
}
|
||||
//文件临时路径
|
||||
$ym = date("Ym");
|
||||
$path = DIR . "/data/user/{$u}/upload/{$ym}/";
|
||||
//检测目录,不存在则创建!
|
||||
if(!Check_Path($path)){
|
||||
msgA(['errno'=>-1,'message'=>'创建upload目录失败,请检查权限']);
|
||||
}
|
||||
$tmp_name = 'AV_'.uniqid().'.'.$suffix;
|
||||
//移动文件
|
||||
if(!move_uploaded_file($_FILES["file"]["tmp_name"],"{$path}/{$tmp_name}")) {
|
||||
msgA(['errno'=>-1,'message'=>'上传失败,请检查目录权限']);
|
||||
}else{
|
||||
msgA(['errno'=>0,'data'=>['url'=>"./data/user/{$u}/upload/{$ym}/$tmp_name",'alt'=>$_FILES["file"]["name"],'href'=>''],'message'=>'上传成功']);
|
||||
}
|
||||
}
|
||||
|
||||
//获取文章列表
|
||||
function article_list(){
|
||||
$where['uid'] = UID;
|
||||
//分类筛选
|
||||
if(intval(@$_POST['category']) > 0){
|
||||
$where['AND']['category'] = intval(@$_POST['category']);
|
||||
}
|
||||
//状态筛选
|
||||
if(intval(@$_POST['state']) > 0){
|
||||
$where['AND']['state'] = intval(@$_POST['state']);
|
||||
}
|
||||
//关键字筛选
|
||||
$query = $_POST['keyword'];
|
||||
if(!empty($query)){
|
||||
$where['AND']['OR'] = ["title[~]" => $query,"summary[~]" => $query,"content[~]" => $query];
|
||||
}
|
||||
//统计条数
|
||||
$count = count_db('user_article_list',$where);
|
||||
//分页
|
||||
$page = empty(intval($_REQUEST['page'])) ? 1 : intval($_REQUEST['page']);
|
||||
$limit = empty(intval($_REQUEST['limit'])) ? 50 : intval($_REQUEST['limit']);
|
||||
$offset = ($page - 1) * $limit; //起始行号
|
||||
$where['LIMIT'] = [$offset,$limit];
|
||||
|
||||
$datas = select_db('user_article_list',['id','title','category','state','password','top','add_time','up_time','browse_count','summary','cover'],$where);
|
||||
|
||||
//查询分类
|
||||
$categorys = select_db('user_categorys',['cid(id)','name'],['uid'=>UID]);
|
||||
$categorys = array_column($categorys,'name','id');
|
||||
//为文章添加分类名称
|
||||
foreach ($datas as &$data) {
|
||||
$data['category_name'] = $categorys[$data['category']] ?? 'Null';
|
||||
}
|
||||
msgA(['code'=>1,'count'=>$count,'data'=>$datas]);
|
||||
}
|
||||
|
||||
//保存文章
|
||||
function save_article(){
|
||||
if(empty($_POST['category']) || !has_db('user_categorys',['uid'=>UID,'cid'=>$_POST['category']])){
|
||||
msg(-1,'分类不存在');
|
||||
}
|
||||
$time = time();
|
||||
//id为空,添加文章
|
||||
if(empty($_POST['id'])){
|
||||
insert_db('user_article_list',[
|
||||
'uid'=>UID,
|
||||
'title'=>$_POST['title'],
|
||||
'category'=>$_POST['category'],
|
||||
'state'=>$_POST['state'],
|
||||
'password'=>'',
|
||||
'top'=>0,
|
||||
'add_time'=>$time,
|
||||
'up_time'=>$time,
|
||||
'browse_count'=>0,
|
||||
'summary'=>$_POST['summary'],
|
||||
'content'=>$_POST['content'],
|
||||
'cover'=>$_POST['cover_url'],
|
||||
'extend'=>''
|
||||
],[1,'保存成功']);
|
||||
//存在id,更新文章数据
|
||||
}else{
|
||||
if(!has_db('user_article_list',['uid'=>UID,'id'=>$_POST['id']])){
|
||||
msg(-1,'文章id错误');
|
||||
}
|
||||
update_db('user_article_list',[
|
||||
'title'=>$_POST['title'],
|
||||
'category'=>$_POST['category'],
|
||||
'state'=>$_POST['state'],
|
||||
'up_time'=>$time,
|
||||
'summary'=>$_POST['summary'],
|
||||
'content'=>$_POST['content'],
|
||||
'cover'=>$_POST['cover_url']
|
||||
],['uid'=>UID,'id'=>$_POST['id']],[1,'保存成功']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//删除文章
|
||||
function del_article(){
|
||||
$id = json_decode($_POST['id']);
|
||||
if(empty($id)) msg(-1,'参数错误');
|
||||
delete_db('user_article_list',['uid'=>UID,'id'=>$id],[1,'操作成功']);
|
||||
}
|
||||
//修改分类
|
||||
function up_category(){
|
||||
$id = json_decode($_POST['id']);
|
||||
if(empty($id)) msg(-1,'参数错误');
|
||||
if(empty($_POST['category_id']) || !has_db('user_categorys',['uid'=>UID,'cid'=>$_POST['category_id']])){
|
||||
msg(-1,'分类不存在');
|
||||
}
|
||||
update_db('user_article_list',['category'=>$_POST['category_id']],['uid'=>UID,'id'=>$id],[1,'操作成功']);
|
||||
}
|
||||
//修改状态
|
||||
function up_state(){
|
||||
$id = json_decode($_POST['id']);
|
||||
if(empty($id)) msg(-1,'参数错误');
|
||||
if(!in_array($_POST['state_id'],['1','2','3','4'])){
|
||||
msg(-1,'状态参数错误');
|
||||
}
|
||||
update_db('user_article_list',['state'=>$_POST['state_id']],['uid'=>UID,'id'=>$id],[1,'操作成功']);
|
||||
}
|
||||
|
||||
|
||||
//保存设置 (与站点配置共享)
|
||||
function save_article_set(){
|
||||
//检查配置参数
|
||||
if(!in_array($_POST['visual'],['0','1','2']) || !in_array($_POST['icon'],['0','1','2'])){
|
||||
msg(-1,'参数错误');
|
||||
}
|
||||
//读取站点配置
|
||||
$s_site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
$s_site['article_visual'] = $_POST['visual'];
|
||||
$s_site['article_icon'] = $_POST['icon'];
|
||||
update_db("user_config",["v"=>$s_site],["k"=>'s_site',"uid"=>UID],[1,'保存成功']);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
|
||||
if ( in_array($method,['link_list','get_a_link','q_category_link','category_list','get_a_category','check_login','add_link']) && function_exists($method) ) {
|
||||
if (function_exists($method)) {
|
||||
$method();
|
||||
}else{
|
||||
Amsg(-1,'方法未找到 >> '.$method);
|
||||
@@ -42,17 +42,83 @@ function add_link(){
|
||||
insert_db('user_links',$data);
|
||||
msgA(['code'=>0,'id'=>$lid]);
|
||||
}
|
||||
|
||||
//编辑链接
|
||||
function edit_link(){
|
||||
$lid = intval(@$_POST['id']);
|
||||
$fid = intval(@$_POST['fid']);
|
||||
$title = $_POST['title'];
|
||||
$url = $_POST['url'];
|
||||
$description = empty($_POST['description']) ? '' : $_POST['description'];
|
||||
$property = empty($_POST['property']) ? 0 : 1;
|
||||
//检测链接是否合法
|
||||
check_link($fid,$title,$url,'');
|
||||
//描述长度检测
|
||||
$length_limit = unserialize(get_db("global_config","v",["k"=>"length_limit"]));
|
||||
if($length_limit['l_desc'] > 0 && strlen($description) > $length_limit['l_desc'] ){
|
||||
msg(-1,'描述长度不能大于'.$length_limit['l_desc'].'个字节');
|
||||
}
|
||||
//关键字长度检测
|
||||
if($length_limit['l_key'] > 0 && strlen($keywords) > $length_limit['l_key'] ){
|
||||
msg(-1,'关键字长度不能大于'.$length_limit['l_key'].'个字节');
|
||||
}
|
||||
//检查链接是否已存在
|
||||
if(has_db('user_links',['uid'=>UID ,'lid[!]'=>$lid, "url" => $url])){msg(-1011,'链接已存在!');}
|
||||
//检查链接ID是否存在
|
||||
if(!has_db('user_links',['uid'=>UID ,'lid'=>$lid])){msg(-1012,'链接ID不存在!');}
|
||||
$data = [
|
||||
'fid' => $fid,
|
||||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||||
'url' => $url,
|
||||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||||
'up_time' => time(),
|
||||
'property' => $property
|
||||
];
|
||||
|
||||
//更新数据
|
||||
update_db('user_links',$data,['uid'=>UID,'lid'=>$lid ]);
|
||||
msgA(['code'=>0,'msg'=>'successful']);
|
||||
}
|
||||
|
||||
|
||||
//删除链接
|
||||
function del_link(){
|
||||
$lid = intval(trim($_REQUEST['id']));
|
||||
if(empty($lid)){
|
||||
msg(-1010,'链接ID不能为空');
|
||||
}
|
||||
$where['lid'] = $lid;
|
||||
$where['uid'] = UID;
|
||||
if(!has_db('user_links',$where)){
|
||||
msg(-1010,'链接id不存在');
|
||||
}
|
||||
delete_db('user_links',$where,[0,'删除成功']);
|
||||
}
|
||||
|
||||
//搜索链接
|
||||
function global_search(){
|
||||
$keyword = htmlspecialchars($_REQUEST['keyword']);
|
||||
if( strlen($keyword) < 2 ) {
|
||||
msg(-2000,'关键字的长度太短');
|
||||
}elseif( strlen($keyword) > 32 ) {
|
||||
msg(-2000,'关键字长度过长');
|
||||
}
|
||||
$where['uid'] = UID;
|
||||
$where['status'] = 1;
|
||||
$where['AND']['OR'] = ["title[~]" => $keyword,"url[~]" => $keyword, "url_standby[~]" => $keyword,"description[~]" => $keyword];
|
||||
$where['ORDER'] = ['weight'=>'DESC'];
|
||||
$field = ['lid(id)','fid','status','property','title','url','url_standby','weight','description','click','add_time','up_time'];
|
||||
$datas = select_db('user_links',$field,$where);
|
||||
links_add_category_field($datas); //添加分类信息
|
||||
msgA(['code'=>0,'msg'=>'获取成功','count'=>count($datas),'data'=>$datas]);
|
||||
}
|
||||
//查询链接列表
|
||||
function link_list(){
|
||||
$page = empty(intval($_REQUEST['page'])) ? 1 : intval($_REQUEST['page']);
|
||||
$limit = empty(intval($_REQUEST['limit'])) ? 50 : intval($_REQUEST['limit']);
|
||||
$offset = ($page - 1) * $limit; //起始行号
|
||||
$where['uid'] = UID;
|
||||
$where['AND']['status'] = 1;
|
||||
if(Access_Type != 'all'){
|
||||
$where['property'] = 0;
|
||||
}
|
||||
|
||||
$where['status'] = 1;
|
||||
$count = count_db('user_links',$where); //统计条数
|
||||
//权重排序(数字小的排前面)
|
||||
$where['ORDER']['weight'] = 'ASC';
|
||||
@@ -61,6 +127,7 @@ function link_list(){
|
||||
$where['LIMIT'] = [$offset,$limit];
|
||||
//查询
|
||||
$datas = select_db('user_links',['lid(id)','fid','property','title','url','url_standby','weight','description','icon','click','add_time','up_time'],$where);
|
||||
links_add_category_field($datas); //添加分类信息
|
||||
msgA(['code'=>0,'msg'=>'获取成功','count'=>$count,'data'=>$datas]);
|
||||
}
|
||||
//查询单个链接
|
||||
@@ -68,7 +135,6 @@ function get_a_link(){
|
||||
$lid = intval(trim($_REQUEST['id']));
|
||||
if(empty($lid)){
|
||||
msg(-1,'id不能为空');
|
||||
|
||||
}
|
||||
$where['lid'] = $lid;
|
||||
$where['uid'] = UID;
|
||||
@@ -76,11 +142,7 @@ function get_a_link(){
|
||||
if(empty($link_info)){
|
||||
msgA(['code'=>-1,'msg'=>'没有找到链接信息','data'=>[]]);
|
||||
}else{
|
||||
if(Access_Type == 'all' || $link_info['property'] == 0){
|
||||
msgA(['code'=>0,'data'=>$link_info]);
|
||||
}else{
|
||||
msgA(['code'=>-1,'msg'=>'私有链接,无权查看','data'=>[]]);
|
||||
}
|
||||
msgA(['code'=>0,'data'=>$link_info]);
|
||||
}
|
||||
}
|
||||
//查询指定分类的链接
|
||||
@@ -92,9 +154,6 @@ function q_category_link(){
|
||||
$where['uid'] = UID;
|
||||
$where['AND']['status'] = 1;
|
||||
$where['AND']['fid'] = $category_id;
|
||||
if(Access_Type != 'all'){
|
||||
$where['property'] = 0;
|
||||
}
|
||||
|
||||
$count = count_db('user_links',$where); //统计条数
|
||||
//权重排序(数字小的排前面)
|
||||
@@ -104,17 +163,120 @@ function q_category_link(){
|
||||
$where['LIMIT'] = [$offset,$limit];
|
||||
//查询
|
||||
$datas = select_db('user_links',['lid(id)','fid','property','title','url','url_standby','weight','description','icon','click','add_time','up_time'],$where);
|
||||
links_add_category_field($datas); //添加分类信息
|
||||
|
||||
|
||||
msgA(['code'=>0,'msg'=>'获取成功','count'=>$count,'data'=>$datas]);
|
||||
}
|
||||
//查询分类列表
|
||||
function category_list(){
|
||||
$where = ['uid'=>UID,'status'=>1,'ORDER' => ['weight'=>'ASC']];
|
||||
if(Access_Type != 'all'){
|
||||
$where['property'] = 0;
|
||||
}
|
||||
$datas = select_db('user_categorys',['cid(id)','fid','property','name','add_time','up_time','weight','description','font_icon'],$where);
|
||||
msgA(['code'=>0,'msg'=>'获取成功','count'=>count($datas),'data'=>$datas ]);
|
||||
}
|
||||
|
||||
//添加分类
|
||||
function add_category(){
|
||||
if(empty($_POST['name'])){
|
||||
msg(-1,'分类名称不能为空');
|
||||
}elseif(!preg_match('/^(fa fa-|layui-icon layui-icon-)([A-Za-z0-9]|-)+$/',$_POST['font_icon'])){
|
||||
$_POST['font_icon'] = 'fa fa-star-o';
|
||||
}
|
||||
//分类名查重
|
||||
if(get_db('user_categorys','cid',['uid'=>UID ,"name" => $_POST['name']])){
|
||||
msg(-1,'分类名称已存在');
|
||||
}
|
||||
//父分类不能是二级分类
|
||||
if(intval($_POST['fid']) !=0 && get_db('user_categorys','fid',['uid'=>UID ,"cid" => intval($_POST['fid']) ]) !=0 ){
|
||||
msg(-1,'父分类不能是二级分类');
|
||||
}
|
||||
|
||||
//长度检测
|
||||
$length_limit = unserialize(get_db("global_config","v",["k"=>"length_limit"]));
|
||||
if($length_limit['c_name'] > 0 && strlen($_POST['name']) > $length_limit['c_name'] ){
|
||||
msg(-1,'名称长度不能大于'.$length_limit['c_name'].'个字节');
|
||||
}
|
||||
if($length_limit['c_desc'] > 0 && strlen($_POST['description']) > $length_limit['c_desc'] ){
|
||||
msg(-1,'名称长度不能大于'.$length_limit['c_desc'].'个字节');
|
||||
}
|
||||
//取最大CID
|
||||
$cid = get_maxid('category_id');
|
||||
//插入数据库
|
||||
insert_db('user_categorys',[
|
||||
'uid'=>UID,
|
||||
'cid'=>$cid,
|
||||
'fid'=>intval($_POST['fid']??'0'),
|
||||
'pid'=>0,
|
||||
'status'=>1,
|
||||
'property'=>intval($_POST['property']??'0'),
|
||||
'name'=>htmlspecialchars($_POST['name'],ENT_QUOTES),
|
||||
'add_time'=>time(),
|
||||
'up_time'=>time(),
|
||||
'weight'=>$cid,
|
||||
'description'=>htmlspecialchars($_POST['description'],ENT_QUOTES),
|
||||
'font_icon'=>$_POST['font_icon'],
|
||||
'icon'=>''
|
||||
],[0,'添加成功']
|
||||
);
|
||||
}
|
||||
//编辑分类
|
||||
function edit_category(){
|
||||
if(empty($_POST['name'])){
|
||||
msg(-1,'分类名称不能为空');
|
||||
}elseif(!preg_match('/^(fa fa-|layui-icon layui-icon-)([A-Za-z0-9]|-)+$/',$_POST['font_icon'])){
|
||||
$_POST['font_icon'] = 'fa fa-star-o';
|
||||
}
|
||||
//父分类不能是自己
|
||||
if($_POST['id'] == $_POST['fid']){
|
||||
msg(-1,'父分类不能是自己');
|
||||
}
|
||||
//查CID是否存在
|
||||
if(!get_db('user_categorys','cid',['uid'=>UID ,"cid" => intval($_POST['id'])])){
|
||||
msg(-1,'分类不存在');
|
||||
}
|
||||
//分类名查重(排除自身)
|
||||
if(get_db('user_categorys','cid',['uid'=>UID,'cid[!]'=>intval($_POST['id']),"name" => $_POST['name']])){
|
||||
msg(-1,'分类名称已存在');
|
||||
}
|
||||
//父分类不能是二级分类
|
||||
if(intval($_POST['fid']) !=0 && get_db('user_categorys','fid',['uid'=>UID ,"cid" => intval($_POST['fid']) ]) !=0 ){
|
||||
msg(-1,'父分类不能是二级分类');
|
||||
}
|
||||
//分类下存在子分类,禁止修改父分类
|
||||
if( $_POST['fid']!=0 && count_db('user_categorys',['uid'=>UID,'fid'=>$_POST['id']])>0){
|
||||
msg(-1,'该分类下已存在子分类!');
|
||||
}
|
||||
//查父分类是否存在
|
||||
if( $_POST['fid'] !=0 && !get_db('user_categorys','cid',['uid'=>UID ,"cid" => intval($_POST['fid'])])){
|
||||
msg(-1,'父分类不存在');
|
||||
}
|
||||
//长度检测
|
||||
$length_limit = unserialize(get_db("global_config","v",["k"=>"length_limit"]));
|
||||
if($length_limit['c_name'] > 0 && strlen($_POST['name']) > $length_limit['c_name'] ){
|
||||
msg(-1,'名称长度不能大于'.$length_limit['c_name'].'个字节');
|
||||
}
|
||||
if($length_limit['c_desc'] > 0 && strlen($_POST['description']) > $length_limit['c_desc'] ){
|
||||
msg(-1,'名称长度不能大于'.$length_limit['c_desc'].'个字节');
|
||||
}
|
||||
|
||||
//更新数据
|
||||
$data = [
|
||||
'fid'=>$_POST['fid'],
|
||||
'property'=>intval($_POST['property']??'0'),
|
||||
'name'=>$_POST['name'],
|
||||
'up_time'=>time(),
|
||||
'description'=>$_POST['description']??'',
|
||||
'font_icon'=>$_POST['font_icon'],
|
||||
];
|
||||
if(!isset($_POST['fid'])){ //为空时不修改父id,避免二级变一级
|
||||
unset($data['fid']);
|
||||
}
|
||||
if(!isset($_POST['font_icon'])){
|
||||
unset($data['font_icon']);
|
||||
}
|
||||
update_db('user_categorys',$data,['uid'=>UID ,"cid"=>intval($_POST['id'])],[0,'successful']);
|
||||
}
|
||||
|
||||
//查询单个分类信息
|
||||
function get_a_category(){
|
||||
$cid = intval(trim($_REQUEST['id']));
|
||||
@@ -127,19 +289,33 @@ function get_a_category(){
|
||||
if(empty($category_info)){
|
||||
msgA(['code'=>-1,'msg'=>'没有找到分类信息','data'=>[]]);
|
||||
}else{
|
||||
if(Access_Type == 'all' || $category_info['property'] == 0){
|
||||
msgA(['code'=>0,'data'=>$category_info]);
|
||||
}else{
|
||||
msgA(['code'=>-1,'msg'=>'私有分类,无权查看','data'=>[]]);
|
||||
}
|
||||
msgA(['code'=>0,'data'=>$category_info]);
|
||||
}
|
||||
}
|
||||
|
||||
//是否已登录
|
||||
//获取TwoNav信息
|
||||
function app_info(){
|
||||
$data['php_version'] = floatval(PHP_VERSION);
|
||||
$data['onenav_version'] = SysVer;
|
||||
$data['cat_num'] = count_db('user_categorys',['uid'=>UID])??0;
|
||||
$data['link_num'] = count_db('user_links',['uid'=>UID])??0;
|
||||
$data['username'] = U;
|
||||
msgA(['code'=>200,'msg'=>'success','data'=>$data]);
|
||||
}
|
||||
|
||||
//是否已登录,由于上游已经拦截未登录状态,所以这里固定返回已登录
|
||||
function check_login(){
|
||||
if(Access_Type == 'open'){
|
||||
msgA(['code'=>-1002,'data'=>'false','err_msg'=>'Authorization failure!']);
|
||||
}else{
|
||||
msgA(['code'=>200,'data'=>'true','msg'=>'success']);
|
||||
msgA(['code'=>200,'data'=>'true','msg'=>'success']);
|
||||
}
|
||||
//给链接数组添加分类字段
|
||||
function links_add_category_field(&$arr){
|
||||
$where['uid'] = UID;
|
||||
$where['status'] = 1;
|
||||
$categorys = select_db('user_categorys',['cid(id)','name'],$where);
|
||||
$newCategorys = array_column($categorys,'name','id');
|
||||
foreach ($arr as &$data) {
|
||||
$data['category_name'] = $newCategorys[$data['fid']];
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,20 @@ function other_upsys(){
|
||||
}
|
||||
//设置执行最长时间,0为无限制。单位秒!
|
||||
set_time_limit(5*60);
|
||||
$overtime = !isset($GLOBALS['global_config']['Update_Overtime']) ? 3 : ($GLOBALS['global_config']['Update_Overtime'] < 3 || $GLOBALS['global_config']['Update_Overtime'] > 60 ? 3 : $GLOBALS['global_config']['Update_Overtime']);
|
||||
|
||||
//加载远程数据
|
||||
$urls = [ "https://update.lm21.top/TwoNav/updata.json"];
|
||||
foreach($urls as $url){
|
||||
$Res = ccurl($url,3);
|
||||
$urls = [
|
||||
"lm21" => "https://update.lm21.top/TwoNav/updata.json",
|
||||
"gitee" => "https://gitee.com/tznb/twonav_updata/raw/master/updata.json"
|
||||
];
|
||||
$Source = $GLOBALS['global_config']['Update_Source'] ?? '';
|
||||
if (!empty($Source) && isset($urls[$Source])) {
|
||||
$urls = [$Source => $urls[$Source]];
|
||||
}
|
||||
|
||||
foreach($urls as $key => $url){
|
||||
$Res = ccurl($url,$overtime);
|
||||
$data = json_decode($Res["content"], true);
|
||||
if($data["code"] == 200 ){ //如果获取成功
|
||||
break; //跳出循环.
|
||||
@@ -342,6 +352,25 @@ function write_user_info(){
|
||||
delete_db('global_user',["ID" => $uids]);
|
||||
msg(1,'删除成功');
|
||||
break;
|
||||
//删除OTP验证
|
||||
case "Del_OTP":
|
||||
$uids = json_decode($_POST['ID']);
|
||||
$USER_S = select_db('global_user',['LoginConfig','ID','User'],['ID'=>$uids]);
|
||||
$fail = 0;
|
||||
foreach($USER_S as $USER){
|
||||
$LoginConfig = unserialize($USER['LoginConfig']);
|
||||
if(empty($LoginConfig['totp_key'])){
|
||||
$fail ++;
|
||||
continue;
|
||||
}
|
||||
$LoginConfig['totp_key'] = '';
|
||||
update_db("global_user", ["LoginConfig" => $LoginConfig], ["ID" => $USER['ID']]);
|
||||
}
|
||||
if($fail > 0){
|
||||
msg(1,'操作完毕,有'.$fail.'个账号未开启OTP双重验证');
|
||||
}
|
||||
msg(1,'操作成功');
|
||||
break;
|
||||
//设用户组
|
||||
case "set_UserGroup":
|
||||
if(empty($_POST['UserGroup'])){
|
||||
@@ -511,7 +540,7 @@ function write_sys_settings(){
|
||||
}
|
||||
|
||||
//长度限制
|
||||
foreach (['c_name','c_desc','l_name','l_url','l_desc'] as $name){
|
||||
foreach (['c_name','c_desc','l_name','l_url','l_key','l_desc'] as $name){
|
||||
$length_limit[$name] = is_subscribe('bool') ? intval($_POST[$name]) : 0;
|
||||
}
|
||||
write_global_config("length_limit",$length_limit,'长度限制');
|
||||
@@ -537,10 +566,15 @@ function write_sys_settings(){
|
||||
'global_header'=>['empty'=>true],
|
||||
'global_footer'=>['empty'=>true],
|
||||
'api_extend'=>['empty'=>true],
|
||||
'c_code'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'自定义代码参数错误'],
|
||||
//更新设置
|
||||
'Update_Source'=>['empty'=>true],
|
||||
'Update_Overtime'=>['int'=>true,'min'=>3,'max'=>60,'msg'=>'资源超时参数错误'],
|
||||
//扩展功能-(全局开关)
|
||||
'apply'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'收录管理参数错误'],
|
||||
'guestbook'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'留言管理参数错误'],
|
||||
'link_extend'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'链接扩展参数错误'],
|
||||
'article'=>['int'=>true,'min'=>0,'max'=>2,'msg'=>'文章管理参数错误']
|
||||
];
|
||||
$o_config = [];
|
||||
foreach ($datas as $key => $data){
|
||||
@@ -561,9 +595,30 @@ function write_sys_settings(){
|
||||
if($_POST['apply'] == 1){$o_config['apply'] = 0;$filter = true;}
|
||||
if($_POST['guestbook'] == 1){$o_config['guestbook'] = 0;$filter = true;}
|
||||
if($_POST['link_extend'] == 1){$o_config['link_extend'] = 0;$filter = true;}
|
||||
if($_POST['article'] == 1){$o_config['article'] = 0;$filter = true;}
|
||||
}
|
||||
//检测于下载文章管理依赖资源
|
||||
clearstatcache();
|
||||
if($o_config['article'] == 1 && ( !is_file('./static/wangEditor/wangEditor.js') || !is_file('./static/wangEditor/wangEditor.css'))){
|
||||
$filePath = "./data/temp/wangEdito.tar.gz";
|
||||
if(downFile('https://update.lm21.top/TwoNav/updata/wangEdito.tar.gz','wangEdito.tar.gz','./data/temp/')){
|
||||
$file_md5 = md5_file($filePath);
|
||||
if($file_md5 != "95f830656ba8972cca39a1ddd6ebaeda"){
|
||||
unlink($filePath);
|
||||
msg(-1,'效验wangEdito失败<br/>!');
|
||||
}
|
||||
}else{
|
||||
msg(-1,'下载wangEdito失败,请重试!<br/>如需手动安装可联系技术支持!');
|
||||
}
|
||||
try {
|
||||
$phar = new PharData($filePath);
|
||||
$phar->extractTo('./static/', null, true);
|
||||
unlink($filePath);
|
||||
clearstatcache();
|
||||
} catch (Exception $e) {
|
||||
msg(-1,'安装wangEdito失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
update_db("global_config", ["v" => $o_config], ["k" => "o_config"],[1,($filter ?"保存成功,未检测到有效授权,带*号的配置无法为你保存":"保存成功")]);
|
||||
}
|
||||
@@ -574,7 +629,7 @@ function write_default_settings(){
|
||||
if(!is_subscribe('bool')){
|
||||
msg(-1,'未检测到有效授权');
|
||||
}
|
||||
if( $_POST['KeyClear'] > $_POST['Session']){
|
||||
if(intval($_POST['Session']) > 0 && intval($_POST['KeyClear']) > intval($_POST['Session'])){
|
||||
msg(-1,'Key清理时间不能大于登录保持时间');
|
||||
}
|
||||
// 安全配置(登录配置)
|
||||
@@ -583,7 +638,8 @@ function write_default_settings(){
|
||||
'HttpOnly'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'HttpOnly参数错误'],
|
||||
'KeySecurity'=>['int'=>true,'min'=>0,'max'=>2,'msg'=>'Key安全参数错误'],
|
||||
'KeyClear'=>['int'=>true,'min'=>1,'max'=>60,'msg'=>'Key清理参数错误'],
|
||||
'api_model'=>['v'=>['security','compatible','compatible+open'],'msg'=>'API模式参数错误']
|
||||
'api_model'=>['v'=>['security','compatible','compatible+open'],'msg'=>'API模式参数错误'],
|
||||
'login_page'=>['v'=>['admin','index','auto'],'msg'=>'登录成功参数错误']
|
||||
];
|
||||
foreach ($datas as $key => $data){
|
||||
if($data['int']){
|
||||
@@ -718,6 +774,30 @@ function other_root(){
|
||||
$_POST['Subject'] = 'TwoNav 测试邮件' . time();
|
||||
$_POST['Body'] = '<h1>TwoNav 测试邮件</h1>' . date('Y-m-d H:i:s');
|
||||
send_email($_POST);
|
||||
}elseif($_GET['type'] == 'write_icon_config'){
|
||||
if($GLOBALS['global_config']['offline'] == '1'){msg(-1,"离线模式无法使用此功能");}
|
||||
if(!is_subscribe('bool')){msg(-1,"未检测到有效授权,无法使用该功能!");}
|
||||
write_global_config('icon_config',$_POST,'图标配置');
|
||||
msg(1,'保存成功');
|
||||
}elseif($_GET['type'] == 'write_icon_del_cache'){
|
||||
//删除数据库缓存信息
|
||||
if(empty(count_db('global_icon','*'))){
|
||||
msg(-1,'无缓存记录..');
|
||||
}
|
||||
delete_db('global_icon','*');
|
||||
|
||||
//删除缓存目录下的所有文件
|
||||
$files = glob(DIR.'/data/icon' . '/*');
|
||||
if (empty($files)) {
|
||||
msg(-1,'无缓存文件..');
|
||||
}
|
||||
foreach ($files as $file) {
|
||||
if (is_file($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
msg(1,'操作成功');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php if(!defined('DIR')){Not_Found();}AccessControl();
|
||||
//负责过渡页/跳转/隐私保护/密码访问
|
||||
$id = intval($_GET['id']);
|
||||
|
||||
//IP数统计
|
||||
count_ip();
|
||||
//如果id为空,则显示404
|
||||
if(empty($id)){Not_Found();}
|
||||
|
||||
@@ -128,6 +129,22 @@ if($global_config['link_extend'] == 1 && check_purview('link_extend',1) && in_ar
|
||||
$extend = empty($link['extend']) ? [] : unserialize($link['extend']);
|
||||
}
|
||||
|
||||
//载入过渡页设置
|
||||
$transition_page = unserialize(get_db("user_config", "v", ["uid"=>UID,"k"=>"s_transition_page"]));
|
||||
|
||||
//关键字处理
|
||||
if(!empty($link['url_standby']) || $site['link_model'] == 'Transition'){
|
||||
if(empty($link['keywords'])){
|
||||
if($transition_page['default_keywords'] == '0'){
|
||||
$link['keywords'] = $link['title'];
|
||||
}else if($transition_page['default_keywords'] == '1'){
|
||||
$link['keywords'] = $site['keywords'];
|
||||
}else{
|
||||
$link['keywords'] = $link['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//如果存在备用链接,则强制载入过渡页
|
||||
if(!empty($link['url_standby'])) {
|
||||
$link['url_standby'] = unserialize($link['url_standby']);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
$apply = $global_config['apply'];
|
||||
|
||||
// 如果管理了收录功能则返回404
|
||||
if ($apply != 1 ){
|
||||
load_tip();
|
||||
@@ -45,22 +44,22 @@ foreach($_POST as $key =>$value){
|
||||
|
||||
$title = $_POST['title'];
|
||||
$url = $_POST['url'];
|
||||
$iconurl = $_POST['iconurl'];
|
||||
$description = $_POST['description'];
|
||||
$iconurl = $_POST['iconurl'] ?? '';
|
||||
$description = $_POST['description'] ?? '';
|
||||
$category_id = intval ($_POST['category_id']);
|
||||
$email = $_POST['email'];
|
||||
$email = $_POST['email'] ?? '';
|
||||
$user_ip = Get_IP();
|
||||
if( !filter_var($url, FILTER_VALIDATE_URL) ) {
|
||||
msg(-1,'URL无效!');
|
||||
}elseif( !empty($iconurl) && !filter_var($iconurl, FILTER_VALIDATE_URL) ){
|
||||
}elseif(!empty($apply['iconurl']) && !filter_var($iconurl, FILTER_VALIDATE_URL) ){
|
||||
msg(-1,'网站图标无效!');
|
||||
}elseif(!preg_match('/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/',$email)){
|
||||
}elseif(!empty($apply['email']) && !preg_match('/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/',$email)){
|
||||
msg(-1,'联系邮箱无效!');
|
||||
}elseif(!isset($_POST['category_id'])){
|
||||
msg(-1,'分类ID不能为空!');
|
||||
}elseif(!isset($_POST['title'])){
|
||||
msg(-1,'网站标题不能为空!');
|
||||
}elseif(!isset($_POST['description'])){
|
||||
}elseif(!empty($apply['description']) && empty($_POST['description'])){
|
||||
msg(-1,'网站描述不能为空!');
|
||||
}
|
||||
//获取和检查分类信息
|
||||
@@ -85,7 +84,7 @@ if(isset($url_data['id'])){
|
||||
|
||||
// 统计IP 24小时内提交的数量!,超限则拦截!
|
||||
$count = count_db("user_apply", ["uid"=>UID , "ip" => $user_ip ,"time[>]" => time() - 60*60*24]);
|
||||
if ($count >= 5){
|
||||
if ($count >= $apply['submit_limit'] ?? 5){
|
||||
msg(-1,'您提交的申请数量已达到上限!请明天再试!');
|
||||
}
|
||||
|
||||
@@ -113,13 +112,16 @@ if($apply['apply'] == 1){
|
||||
if(!empty(get_db("user_links","*",["url"=> $url,'uid'=>UID ]))){
|
||||
msg(-1,'URL已经存在!'); //存在于链接列表中!
|
||||
}
|
||||
$lid = get_maxid('link_id');
|
||||
$url_data = [
|
||||
'lid' => $lid,
|
||||
'uid' => UID,
|
||||
'fid' => $category_id,
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'add_time' => time(),
|
||||
'up_time' => time(),
|
||||
'weight' => 0,
|
||||
'property' => 0,
|
||||
'icon' => $iconurl
|
||||
|
||||
65
system/expand/article.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php if(!defined('DIR')){Not_Found();}AccessControl();
|
||||
if($global_config['article'] < 1 | !check_purview('article',1)){
|
||||
Not_Found();
|
||||
}
|
||||
|
||||
$id = intval($_GET['id']);
|
||||
//IP数统计
|
||||
count_ip();
|
||||
//如果id为空,则显示404
|
||||
if(empty($id)){Not_Found();}
|
||||
|
||||
//查询文章
|
||||
$where['uid'] = UID;
|
||||
if(!is_login()){
|
||||
$where['state'] = 1; //状态筛选
|
||||
}
|
||||
$where['id'] = $id;
|
||||
$data = get_db('user_article_list','*',$where);
|
||||
|
||||
//查找失败时显示404
|
||||
if(empty($data)){Not_Found();}
|
||||
|
||||
//var_dump($data);
|
||||
//exit;
|
||||
//站点设置和站点图标
|
||||
$site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
$site['Title'] = $site['title'].(empty($site['subtitle'])?'':' - '.$site['subtitle']);
|
||||
//免费用户请保留版权,谢谢!
|
||||
$copyright = empty($global_config['copyright'])?'<a target="_blank" href="https://gitee.com/tznb/TwoNav">Copyright © TwoNav</a>':$global_config['copyright'];
|
||||
$ICP = empty($global_config['ICP'])?'':'<a target="_blank" href="https://beian.miit.gov.cn">'.$global_config['ICP'].'</a>';
|
||||
$favicon = ( !empty($site['site_icon_file'])) ? $site['site_icon'] : './favicon.ico';
|
||||
|
||||
|
||||
//取模板信息
|
||||
require DIR ."/system/templates.php";
|
||||
$dir_path = DIR.'/templates/article/'.$s_templates['article'];
|
||||
$theme_dir = str_replace(DIR.'/templates/article',"./templates/article",$dir_path);
|
||||
$path = $dir_path.'/index.php';
|
||||
//检查是否存在,不存在则使用默认
|
||||
if(!is_file($path)){
|
||||
$path= DIR.'/templates/article/default/index.php';
|
||||
$theme_dir = './templates/article/default';
|
||||
}
|
||||
|
||||
//统计点击数
|
||||
update_db("user_article_list", ["browse_count[+]"=>1],['uid'=>UID,'id'=>$id]);
|
||||
|
||||
//读取用户主题配置
|
||||
$theme_config_db = unserialize(get_db('user_config','v',['t'=>'theme_article','k'=>$s_templates['article'],'uid'=>UID]));
|
||||
|
||||
//读取默认主题配置
|
||||
$theme_info = json_decode(@file_get_contents($theme_dir.'/info.json'),true);
|
||||
$theme_config = empty($theme_info['config']) ? []:$theme_info['config'];
|
||||
$theme_ver = !Debug?$theme_info['version']:$theme_info['version'].'.'.time();
|
||||
|
||||
//合并配置数据
|
||||
$theme_config = empty($theme_config_db) ? $theme_config : array_merge ($theme_config??[],$theme_config_db??[]);
|
||||
|
||||
require $path;
|
||||
exit;
|
||||
|
||||
//返回404
|
||||
function Not_Found() {
|
||||
header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;
|
||||
}
|
||||
@@ -11,7 +11,9 @@ foreach($_POST as $key =>$value){
|
||||
if($method =='write_site_setting' && ($key =='custom_header' || $key =='custom_footer')){
|
||||
continue;
|
||||
}
|
||||
|
||||
if($method == 'write_article'){
|
||||
continue;
|
||||
}
|
||||
if(preg_match('/<(iframe|script|body|img|layer|div|meta|style|base|object|input)/i',$value)){
|
||||
$code = 2001;
|
||||
}elseif(preg_match('/(onmouseover|onerror|onload)\=/i',$value)){
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
// 来源 https://blog.mimvp.com/article/23089.html
|
||||
|
||||
function get_page_info($output, $friend_link = '', $curl_info=array()) {
|
||||
$page_info = array();
|
||||
@@ -71,16 +70,39 @@ function get_page_info($output, $friend_link = '', $curl_info=array()) {
|
||||
|
||||
preg_match('/<META\s+content="([\w\W]*?)"\s+scheme="([\w\W]*?)"/si', $meta_str, $res);
|
||||
if(!empty($res)) $meta_array[strtolower($res[2])] = $res[1];
|
||||
|
||||
// 20230716 新增匹配语法
|
||||
preg_match('/<META\s+content=[\'"](.*?)[\'"]\s+itemprop=[\'"](.*?)[\'"]\s+name=[\'"](.*?)[\'"]>/si', $meta_str, $res);
|
||||
if(!empty($res)) $meta_array[strtolower($res[3])] = $res[1];
|
||||
|
||||
preg_match('/<meta\s+itemprop=[\'"](.*?)[\'"]\s+name=[\'"](.*?)[\'"]\s+content=[\'"](.*?)[\'"]>/si', $meta_str, $res);
|
||||
if(!empty($res)) $meta_array[strtolower($res[2])] = $res[3];
|
||||
}
|
||||
|
||||
|
||||
//如果正则匹配失败则使用php函数尝试再次匹配
|
||||
if(empty($meta_array['keywords']) || empty($meta_array['description'])){
|
||||
//将html保存为临时文件
|
||||
$key = md5(uniqid().Get_Rand_Str(8));
|
||||
$tempFile = DIR ."/data/temp/".md5(uniqid().Get_Rand_Str(8)).".html";
|
||||
file_put_contents($tempFile, $output);
|
||||
$tags = get_meta_tags($tempFile);
|
||||
unlink($tempFile); //删除临时文件
|
||||
if(empty($meta_array['keywords']) && !empty($tags['keywords'])){
|
||||
$meta_array['keywords'] = $tags['keywords'];
|
||||
}
|
||||
if(empty($meta_array['description']) && !empty($tags['description'])){
|
||||
$meta_array['description'] = $tags['description'];
|
||||
}
|
||||
}
|
||||
|
||||
$page_info['site_keywords'] = $meta_array['keywords'];
|
||||
$page_info['site_description'] = $meta_array['description'];
|
||||
//$page_info['meta_array'] = $meta_array; //暂时不需要全部meta
|
||||
|
||||
|
||||
# 判断是否存在友链
|
||||
if(!empty($friend_link) && strstr($output, $friend_link) != "") {
|
||||
$page_info['friend_link_status'] = 1;
|
||||
}
|
||||
|
||||
|
||||
return $page_info;
|
||||
}
|
||||
297
system/icon.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
//读取配置
|
||||
$config = unserialize( get_db("global_config", "v", ["k" => "icon_config"])) ?? [];
|
||||
$config['analysis_timeout'] = (intval($config['analysis_timeout']) >= 3 && intval($config['analysis_timeout']) <= 20) ? intval($config['analysis_timeout']) : 6; //解析超时
|
||||
$config['download_timeout'] = (intval($config['download_timeout']) >= 3 && intval($config['download_timeout']) <= 20) ? intval($config['download_timeout']) : 6; //下载超时
|
||||
$config['icon_size'] = (intval($config['icon_size']) >= 5 && intval($config['icon_size']) <= 1024) ? intval($config['icon_size']) : 256; //大小限制
|
||||
$favicon_url = '';
|
||||
//防盗链
|
||||
if($config['referer_test'] == 1){
|
||||
if(empty($_SERVER['HTTP_REFERER']) || !strstr($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST'])){
|
||||
header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit('404 Not Found');
|
||||
}
|
||||
}
|
||||
|
||||
//获取URL
|
||||
$url = base64_decode($_GET['url']);
|
||||
$url_md5 = md5($url);
|
||||
|
||||
//维护模式/离线模式/关闭服务 > 输出固定图标
|
||||
if($global_config['Maintenance'] != 0 || $global_config['offline'] == '1' || $config['o_switch'] == '0' || !is_subscribe('bool')){
|
||||
echo_link_type_icon();
|
||||
}
|
||||
|
||||
//如果不是http(s)则根据类型输出固定图标
|
||||
if(!preg_match("/^(http:\/\/|https:\/\/)/",$url)){
|
||||
echo_link_type_icon();
|
||||
}else{
|
||||
$uri_part = parse_url($url);
|
||||
$url_root = $uri_part['scheme'] . '://' . $uri_part['host'] . (isset($uri_part['port']) ? ':' . $uri_part['port'] : '');
|
||||
}
|
||||
|
||||
//检查目录 > 不存在则自动创建 > 创建失败显示错误图标
|
||||
if(!Check_Path(DIR.'/data/icon')){
|
||||
echo_icon(DIR . '/templates/admin/img/error.svg',$config);
|
||||
}
|
||||
|
||||
//读取缓存 > 存在且可用则输出
|
||||
$cache_data = get_db('global_icon','*',['url_md5'=>$url_md5]);
|
||||
if(!empty($cache_data) && $cache_data['update_time'] > time() - intval($config['server_cache_time']) && is_file(DIR . '/data/icon/' . $cache_data['file_name'])){
|
||||
echo_icon(DIR . '/data/icon/' . $cache_data['file_name'],$config,$cache_data);
|
||||
}
|
||||
|
||||
//缓存不可用
|
||||
//获取URL的html内容
|
||||
$html = get_html($url,$config['analysis_timeout']);
|
||||
|
||||
//获取html失败
|
||||
if(empty($html)){
|
||||
backup_api($url,$config); //调用备选接口
|
||||
}
|
||||
|
||||
//html获取成功>尝试解析
|
||||
try {
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($html);
|
||||
$links = $doc->getElementsByTagName('link');
|
||||
//后续可以考虑将所有声明的图标加入数组,然后按特定规则排序,实现多图标时获取较大尺寸的图标
|
||||
foreach ($links as $link) {
|
||||
if (in_array($link->getAttribute('rel'),['shortcut icon','icon','alternate icon','apple-touch-icon'])) {
|
||||
$favicon_url = $link->getAttribute('href');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}catch (Exception $e) {
|
||||
//解析异常,不做处理!下面继续尝试其他方法获取!
|
||||
}
|
||||
|
||||
//解析失败(可能是未设置图标)
|
||||
if(empty($favicon_url)){
|
||||
//尝试获取根目录的favicon.ico
|
||||
$res = down_ico($url_root.'/favicon.ico','./data/icon/',$url,$config['download_timeout']);
|
||||
if($res){
|
||||
echo_icon(DIR . '/data/icon/'.$url_md5.".ico",$config);
|
||||
}
|
||||
//调用备选接口
|
||||
backup_api($url,$config);
|
||||
}
|
||||
|
||||
//解析到图标
|
||||
$favicon_url = url_patch($favicon_url,$url);
|
||||
|
||||
//if 如果图标类型是base64或者svg则不需要下载
|
||||
|
||||
//匹配图标类型>下载>输出
|
||||
$suffix = strtolower(end(explode('.',$favicon_url)));
|
||||
$suffix = strtolower(reset(explode('?',$suffix)));
|
||||
$suffix = preg_match('/^(jpg|jpeg|png|ico|bmp|svg|webp)$/i',$suffix) ? $suffix : 'ico';
|
||||
|
||||
//下载图标 > 成功则输出
|
||||
$res = down_ico($favicon_url,'./data/icon/',$url,$config['download_timeout']);
|
||||
if($res){
|
||||
echo_icon(DIR . '/data/icon/'.$url_md5.".$suffix",$config);
|
||||
}else{
|
||||
echo_link_type_icon();
|
||||
}
|
||||
|
||||
//使用备用接口
|
||||
function backup_api($url,$config){
|
||||
global $uri_part,$url_root;
|
||||
//未设置时直接输出ie图标
|
||||
$backup_api = intval($config['backup_api']);
|
||||
if($backup_api == 0){
|
||||
echo_icon(DIR . '/templates/admin/img/ie.svg',$config);
|
||||
}elseif($backup_api == 6){
|
||||
$res = down_ico('https://api.iowen.cn/favicon/'.parse_url($url)['host'].'.png','./data/icon/','',$config['download_timeout']);
|
||||
if($res){
|
||||
echo_icon(DIR . '/data/icon/'.$GLOBALS['url_md5'].".png",$config);
|
||||
}
|
||||
}elseif($backup_api == 2){
|
||||
$res = down_ico('https://favicon.png.pub/v1/'.base64_encode($url_root),'./data/icon/','',$config['download_timeout']);
|
||||
if($res){
|
||||
echo_icon(DIR . '/data/icon/'.$GLOBALS['url_md5'].".png",$config);
|
||||
}
|
||||
}
|
||||
|
||||
//如果都失败,则输出默认图标
|
||||
echo_icon(DIR . '/templates/admin/img/ie.svg',$config);
|
||||
}
|
||||
//检测URL自动补全
|
||||
function url_patch($favicon_url,$url){
|
||||
global $uri_part,$url_root;
|
||||
//包含协议表示URL完整,直接返回
|
||||
if(strpos($favicon_url, '://')){
|
||||
return $favicon_url;
|
||||
}
|
||||
|
||||
//忽略协议的绝对路径
|
||||
if(strpos($favicon_url, '//') === 0 ) {
|
||||
return $uri_part['scheme'] . ':' . $favicon_url;
|
||||
}
|
||||
|
||||
//位于根目录
|
||||
if(strpos($favicon_url, '/') === 0 ){
|
||||
return $url_root.$favicon_url;
|
||||
}
|
||||
//当前目录
|
||||
if(strpos($favicon_url, './') === 0){
|
||||
return $url_root . $uri_part['path'] . substr($favicon_url, 2);
|
||||
}
|
||||
//向上N级目录
|
||||
if(strpos($favicon_url, '../') === 0){
|
||||
$N = substr_count($favicon_url,'../');
|
||||
$url_temp = $uri_part['path'];
|
||||
for ($i = 0; $i < $N; $i++) {
|
||||
$url_temp = dirname($url_temp);
|
||||
$favicon_url = preg_replace('/^\.\.\//', '', $favicon_url);
|
||||
}
|
||||
return $url_root . $url_temp . $favicon_url;
|
||||
}
|
||||
|
||||
//base64
|
||||
|
||||
//SVG
|
||||
|
||||
//默认路径
|
||||
return $url_root . $uri_part['path'] . $favicon_url;
|
||||
}
|
||||
|
||||
//获取html
|
||||
function get_html($url,$TIMEOUT = 5){
|
||||
try {
|
||||
$c = curl_init();
|
||||
curl_setopt($c, CURLOPT_URL, $url);
|
||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($c, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($c, CURLOPT_TIMEOUT, $TIMEOUT);
|
||||
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36');
|
||||
$data = curl_exec($c);
|
||||
//如果是gzip则解压
|
||||
$prefix = dechex(ord($data[0])) . dechex(ord($data[1]));
|
||||
if(strtolower($prefix) == '1f8b'){
|
||||
$data = gzdecode($data);
|
||||
}
|
||||
curl_close($c);
|
||||
return $data;
|
||||
}catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function down_ico($ico_url, $savePath = './data/temp/',$referer = '',$TIMEOUT = 60){
|
||||
$suffix = strtolower(end(explode('.',$ico_url)));
|
||||
$suffix = strtolower(reset(explode('?',$suffix))); //截取?前面的
|
||||
if(!preg_match('/^(jpg|jpeg|png|ico|bmp|svg|webp)$/i',$suffix)){
|
||||
$suffix = 'ico'; //没匹配到后缀名则默认为ico
|
||||
}
|
||||
$file = "{$GLOBALS['url_md5']}.{$suffix}";
|
||||
$c = curl_init();
|
||||
curl_setopt($c, CURLOPT_URL, $ico_url);
|
||||
curl_setopt($c, CURLOPT_TIMEOUT, $TIMEOUT);
|
||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($c, CURLOPT_HEADER, FALSE);
|
||||
curl_setopt($c, CURLOPT_NOBODY, FALSE);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36');
|
||||
if(!empty($referer)){
|
||||
curl_setopt($c, CURLOPT_REFERER, $referer);
|
||||
}
|
||||
try{
|
||||
$res = curl_exec($c);
|
||||
}finally{
|
||||
$code = curl_getinfo($c, CURLINFO_HTTP_CODE);
|
||||
curl_close($c);
|
||||
}
|
||||
|
||||
if ($code == '200') { //状态码正常
|
||||
//十六进制取文件头
|
||||
$prefix = strtolower( dechex(ord($res[0])) . dechex(ord($res[1])) );
|
||||
//根据头判断类型
|
||||
if($prefix == '1f8b'){ //gzip解码
|
||||
$res = gzdecode($res);
|
||||
}elseif( $prefix != '3c73' && strpos($prefix, '3c') === 0){ // <开头视为文本 <?开头是svg除外
|
||||
return false;
|
||||
}
|
||||
//3c73>svg 3c21>html 1f8b>gzip
|
||||
|
||||
//文件大小限制
|
||||
if((strlen($res) / 1024)> $GLOBALS['config']['icon_size']){
|
||||
return false;
|
||||
}
|
||||
$fullName = rtrim($savePath, '/') . '/' . $file;
|
||||
$type = ['jpg'=>'jpeg','jpeg'=>'jpeg','svg'=>'svg+xml','ico'=>'x-icon']; //类型表
|
||||
$mime = $type[$suffix] ?? 'x-icon';
|
||||
|
||||
//黑名单(后期考虑使用在线名单缓存到本地,以便以更好的维护)
|
||||
$_md5 = md5($res);
|
||||
if($_md5 == 'c531ffbdad1ba93bd84f2398052958dc') return false; //阿里云
|
||||
if($_md5 == '05231fb6b69aff47c3f35efe09c11ba0') return false; //一为默认
|
||||
if($_md5 == '3ca64f83fdcf25135d87e08af65e68c9') return false; //小z默认
|
||||
|
||||
$data = ['update_time'=>time(),'file_name'=>$file,'file_mime'=>$mime,'ico_url'=>$ico_url,'extend'=>''];
|
||||
if(!has_db('global_icon',['url_md5'=>$GLOBALS['url_md5']])){
|
||||
$data['url_md5'] = $GLOBALS['url_md5'];
|
||||
$data['url'] = $GLOBALS['url'];
|
||||
$data['add_time'] = time();
|
||||
insert_db('global_icon',$data);
|
||||
}else{
|
||||
update_db('global_icon',$data,['url_md5'=>$GLOBALS['url_md5']]);
|
||||
}
|
||||
|
||||
return file_put_contents($fullName, $res);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function echo_icon($path,$config,$db = false){
|
||||
//文件不存在时输出固定图标(理论上执行到这里不会出现文件不存在)
|
||||
if(!is_file($path)){
|
||||
echo_icon(DIR . '/templates/admin/img/ie.svg',$config);
|
||||
}
|
||||
//如果存在mime类型则直接读取,否则根据文件类型声明(从缓存读取时才会有mime)
|
||||
if(empty($db['mime'])){
|
||||
$suffix = strtolower(end(explode('.',$path))); //文件类型
|
||||
$type = ['jpg'=>'jpeg','jpeg'=>'jpeg','svg'=>'svg+xml','ico'=>'x-icon']; //类型表
|
||||
$mime = $type[$suffix] ?? 'x-icon';
|
||||
}else{
|
||||
$mime = $db['mime'];
|
||||
}
|
||||
//MIME类型
|
||||
header("Content-Type: image/{$mime};text/html; charset=utf-8");
|
||||
//缓存时间
|
||||
$cache_time = intval($config['browse_cache_time']);
|
||||
if($cache_time > 0 ){
|
||||
header ("Last-Modified: " .gmdate("D, d M Y H:i:s", empty($db['mime']) ? filemtime($path):$db['mime'] )." GMT"); //更新时间
|
||||
header("Expires: " .gmdate("D, d M Y H:i:s", time() + $cache_time)." GMT"); //过期时间 HTTP1.0
|
||||
header("Cache-Control: public, max-age={$cache_time}"); //存活时间 HTTP1.1
|
||||
}
|
||||
//输出文件
|
||||
exit(file_get_contents($path,true));
|
||||
}
|
||||
|
||||
|
||||
//根据链接类型输出图标
|
||||
function echo_link_type_icon(){
|
||||
global $config;$config['browse_cache_time'] = 60;
|
||||
if(preg_match("/^(http:\/\/|https:\/\/)/",$GLOBALS['url'])){
|
||||
echo_icon(DIR . '/templates/admin/img/ie.svg',$config);
|
||||
}elseif(preg_match("/^(ftp:\/\/|ftps:\/\/|sftp:\/\/)/",$GLOBALS['url'])){
|
||||
echo_icon(DIR . '/templates/admin/img/ftp.svg',$config);
|
||||
}elseif(preg_match("/^magnet:?/",$GLOBALS['url'])){
|
||||
echo_icon(DIR . '/templates/admin/img/magnet.svg',$config);
|
||||
}elseif(preg_match("/^(tcp:\/\/|udp:\/\/|rtsp:\/\)/",$GLOBALS['url'])){
|
||||
echo_icon(DIR . '/templates/admin/img/tcpudp.svg',$config);
|
||||
}elseif(preg_match("/^thunder:\/\//",$GLOBALS['url'])){
|
||||
echo_icon(DIR . '/templates/admin/img/xunlei.png',$config);
|
||||
}else{
|
||||
echo_icon(DIR . '/templates/admin/img/ie.svg',$config);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
@@ -10,6 +10,10 @@ if(!is_login && ($global_config['Privacy'] == 1 || !check_purview('Common_home',
|
||||
}
|
||||
//载入站点设置
|
||||
$site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
//如果没有权限则清除自定义代码
|
||||
if(!check_purview('header',1)){$site['custom_header'] = '';}
|
||||
if(!check_purview('footer',1)){$site['custom_footer'] = '';}
|
||||
|
||||
$site['Title'] = $site['title'].(empty($site['subtitle'])?'':' - '.$site['subtitle']);
|
||||
//免费用户请保留版权,谢谢!
|
||||
$copyright = empty($global_config['copyright'])?'<a target="_blank" href="https://gitee.com/tznb/TwoNav">Copyright © TwoNav</a>':$global_config['copyright'];
|
||||
@@ -73,7 +77,7 @@ $theme_ver = !Debug?$theme_info['version']:$theme_info['version'].'.'.time();
|
||||
$site['ex_theme'] = in_array($theme,['snail-nav','heimdall']); //例外主题,不支持热门网址/最新网址/输出上限
|
||||
//分类查找条件
|
||||
$categorys = []; //声明一个空数组
|
||||
$content = ['cid(id)','name','property','font_icon','icon','description'];//需要的内容
|
||||
$content = ['cid(id)','fid','name','property','font_icon','icon','description'];//需要的内容
|
||||
$where['uid'] = UID;
|
||||
$where['fid'] = 0;
|
||||
$where['status'] = 1;
|
||||
@@ -98,7 +102,7 @@ function get_category_sub($id) {
|
||||
if(!empty($share)){
|
||||
$where['cid'] = $data;
|
||||
}
|
||||
$content = ['cid(id)','name','property','font_icon','icon','description'];
|
||||
$content = ['cid(id)','name','fid','property','font_icon','icon','description'];
|
||||
$where['uid'] = UID;
|
||||
$where['fid'] = intval($id);
|
||||
$where['status'] = 1;
|
||||
@@ -125,7 +129,6 @@ function get_links($fid) {
|
||||
$where['ORDER']['lid'] = 'ASC';
|
||||
if(!is_login){
|
||||
$where['property'] = 0;
|
||||
|
||||
}
|
||||
//书签分享>私有可见
|
||||
if(isset($share['pv']) && $share['pv'] == 1){
|
||||
@@ -159,7 +162,7 @@ function get_links($fid) {
|
||||
$where['LIMIT'] = $site['max_link'];
|
||||
$max_link = true;
|
||||
}
|
||||
$links = select_db('user_links',['lid(id)','fid','property','title','url(real_url)','url_standby','description','icon','click','pid'],$where);
|
||||
$links = select_db('user_links',['lid(id)','fid','property','title','url(real_url)','url_standby','description','icon','click','pid','extend'],$where);
|
||||
foreach ($links as $key => $link) {
|
||||
$click = false; $lock = false;
|
||||
|
||||
@@ -193,7 +196,41 @@ function get_links($fid) {
|
||||
|
||||
//获取图标链接
|
||||
$links[$key]['ico'] = $lock ? $GLOBALS['libs'].'/Other/lock.svg' : geticourl($site['link_icon'],$link);
|
||||
$links[$key]['type'] = 'link';
|
||||
}
|
||||
//处理扩展信息
|
||||
if($GLOBALS['global_config']['link_extend'] == 1 && check_purview('link_extend',1) && in_array($GLOBALS['theme_info']['support']['link_extend'],["true","1"])){
|
||||
foreach ($links as &$link) {
|
||||
if(!empty($link['extend'])){
|
||||
$link = array_merge ($link,unserialize($link['extend']));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//生成文章链接, 条件:非隐藏,且主题未声明不显示文章
|
||||
if( intval($site['article_visual'] ?? '1') > 0 && $GLOBALS['theme_info']['support']['article'] != 'notdisplay'){
|
||||
$articles = get_article_list($fid);
|
||||
foreach ($articles['data'] as $article) {
|
||||
$url = "./index.php?c=article&id={$article['id']}&u={$u}";
|
||||
if($site['article_icon'] == '1'){ //站点图标
|
||||
$icon = $GLOBALS['favicon'];
|
||||
}elseif($site['article_icon'] == '2' && !empty($article['cover'])){ //封面
|
||||
$icon = $article['cover'];
|
||||
}else{ //首字
|
||||
$icon = './system/ico.php?text='.mb_strtoupper(mb_substr($article['title'], 0, 1));
|
||||
}
|
||||
$article_link = ['type'=>'article','id'=>0,'title'=>$article['title'],'url'=>$url,'real_url'=>$url,'description'=>$article['summary'],'ico'=>$icon,'icon'=>$icon];
|
||||
//判断靠前还是靠后
|
||||
if($site['article_visual'] == '1'){
|
||||
array_unshift($links,$article_link);
|
||||
}else{
|
||||
array_push($links,$article_link);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($max_link && $count > $site['max_link']){
|
||||
$oc_url = "./index.php?u={$u}&oc={$fid}" . (empty($_GET['theme']) ? '':"&theme={$_GET['theme']}");
|
||||
array_push($links,['id'=>0,'title'=>'查看全部','url'=>$oc_url,'real_url'=>$oc_url,'description'=>'该分类共有'.$count.'条数据','ico'=>'./favicon.ico']);
|
||||
@@ -284,5 +321,6 @@ if(empty($_GET['share']) && !$site['ex_theme']){
|
||||
//访问统计
|
||||
write_user_count(date('Ym'),'index_Ym');
|
||||
write_user_count(date('Ymd'),'index_Ymd');
|
||||
count_ip();
|
||||
//载入模板
|
||||
require($index_path);
|
||||
@@ -4,6 +4,8 @@ if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Fou
|
||||
//初始化
|
||||
session_name('TwoNav_initial');
|
||||
session_start();
|
||||
$layui['js'] = './static/Layui/v2.8.10/layui.js';
|
||||
$layui['css'] = './static/Layui/v2.8.10/css/layui.css';
|
||||
|
||||
//判断请求类型
|
||||
if($_SERVER['REQUEST_METHOD'] === 'POST'){
|
||||
@@ -282,7 +284,7 @@ function Write_Config(){
|
||||
//写站点配置
|
||||
$o_config['Login'] = 'login'; //登录入口
|
||||
$o_config['Register'] = 'register'; //注册入口
|
||||
$o_config['RegOption'] = '1'; //注册配置
|
||||
$o_config['RegOption'] = '0'; //注册配置
|
||||
$o_config['Libs'] = './static'; //静态库路径
|
||||
$o_config['Default_User'] = $_POST['User']; //默认用户
|
||||
$o_config['XSS_WAF'] = '1'; //防XSS脚本
|
||||
@@ -292,6 +294,7 @@ function Write_Config(){
|
||||
$o_config['Maintenance'] = '0'; //维护模式
|
||||
$o_config['Sub_domain'] = '0'; //二级域名
|
||||
$o_config['copyright'] = ''; //版权信息
|
||||
$o_config['c_code'] = '0'; //禁用默认用户使用自定义代码
|
||||
|
||||
insert_db("global_config", ["k" => "o_config","v" => $o_config,"d" => '网站配置']);
|
||||
|
||||
@@ -339,7 +342,7 @@ function Write_Config(){
|
||||
<meta charset="utf-8" />
|
||||
<title>TwoNav 安装引导</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel='stylesheet' href='<?php echo $libs?>/Layui/v2.8.3/css/layui.css'>
|
||||
<link rel='stylesheet' href='<?php echo $layui['css']; ?>'>
|
||||
<style>
|
||||
body{ background-color:rgba(0, 0, 51, 0.8); }
|
||||
.login-logo h1 { color:#FFFFFF; text-align: center; }
|
||||
@@ -433,7 +436,7 @@ function Write_Config(){
|
||||
</div>
|
||||
</div>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery-3.6.0.min.js'></script>
|
||||
<script src = '<?php echo $libs?>/Layui/v2.8.3/layui.js'></script>
|
||||
<script src = '<?php echo $layui['js']; ?>'></script>
|
||||
<script>
|
||||
|
||||
var file = "data_" + Date.now() + '_' + getRandomString(20) + ".db3" //生成文件名
|
||||
@@ -445,6 +448,25 @@ set_db_type(db_type);
|
||||
layui.use(['form'], function(){
|
||||
var form = layui.form;
|
||||
|
||||
//伪静态检测
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', './static/Other/login.css?t=' + new Date().getTime(), true);
|
||||
request.onload = function() {
|
||||
if (request.status >= 200 && request.status < 400) {
|
||||
var fileContent = request.responseText;
|
||||
if (fileContent.startsWith('<!DOCTYPE html>')) {
|
||||
layer.alert(
|
||||
"系统检测到您的站点可能配置了不属于TwoNav的伪静态规则<br />通常是因为之前使用过其他程序,例如:OneNav Extend 或 OneNav <br />您需要将它清除,否则会影响到程序的正常使用 ( 如登录页异常 )<br />并在安装完成后在站长工具>生成伪静态>重新配置到站点中"
|
||||
,{title:'环境异常提示',anim: 2,closeBtn: 0,btn: ['刷新页面']},function () {
|
||||
location.reload();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
|
||||
|
||||
//开始安装
|
||||
form.on('submit(register)', function(data){
|
||||
var d = data.field;
|
||||
@@ -508,12 +530,12 @@ function open_msg(u,p){
|
||||
layer.open({ //弹出结果
|
||||
type: 1
|
||||
,title: '安装成功'
|
||||
,area: ['230px', '220px']
|
||||
,area: ['230px', '260px']
|
||||
,maxmin: false
|
||||
,shadeClose: false
|
||||
,resize: false
|
||||
,closeBtn: 0
|
||||
,content: '<div style="padding: 15px;">管理员账号: '+u+'<br>管理员密码: '+p+'<br><h3><a href="?c=admin&u='+u+'" style="color: #0000FF;" class="fl"> <br> >>点我进入后台</a></h3><h3><a href="?u='+u+'" style="color: #0000FF;" class="fl"> <br> >>点我进入首页</a></h3></div>'
|
||||
,content: '<div style="padding: 15px;">管理员账号: '+u+'<br>管理员密码: '+p+'<br><h3><a href="?c=admin&u='+u+'" style="color: #0000FF;" class="fl"> <br> >>点我进入后台</a></h3><h3><a href="?u='+u+'" style="color: #0000FF;" class="fl"> <br> >>点我进入首页</a></h3> <h3><a href="https://gitee.com/tznb/TwoNav/wikis/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/%E5%AE%89%E5%85%A8%E9%85%8D%E7%BD%AE" style="color: #0000FF;" class="fl" target="_blank"> <br> >>安全配置说明</a></h3> </div>'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
|
||||
//登录入口
|
||||
require "./system/templates.php";
|
||||
|
||||
//如果是Get请求则载入登录模板
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET'){
|
||||
require DIR ."/system/templates.php";
|
||||
@@ -18,29 +17,48 @@ if($_SERVER['REQUEST_METHOD'] === 'GET'){
|
||||
AccessControl(); //访问控制
|
||||
$User = $_POST["User"];$Password = $_POST["Password"]; //获取请求数据
|
||||
|
||||
if(empty($User)){
|
||||
insert_db("user_log", ["uid" => '',"user"=>'',"ip"=>Get_IP(),"time"=>time(),"type" => 'login',"content"=>Get_Request_Content(),"description"=>"请求登录>账号为空"]);
|
||||
msg(-1,'账号不能为空!');
|
||||
}elseif($User != $USER_DB['User']){
|
||||
insert_db("user_log", ["uid" => '',"user"=>$User,"ip"=>Get_IP(),"time"=>time(),"type" => 'login',"content"=>Get_Request_Content(),"description"=>"请求登录>账号不存在"]);
|
||||
msg(-1,'账号不存在!');
|
||||
}
|
||||
|
||||
//记录请求日志
|
||||
insert_db("user_log", ["uid" => $USER_DB['ID'],"user"=>$USER_DB['User'],"ip"=>Get_IP(),"time"=>time(),"type" => 'login',"content"=>Get_Request_Content(),"description"=>"请求登录"]);
|
||||
$log_id = $db->id();
|
||||
//基础判断
|
||||
if(!isset($User)){
|
||||
update_db_db("user_log", ["description" => "请求登录>账号不能为空"], ["id"=>$log_id]);
|
||||
msg(-1,'账号不能为空!');
|
||||
}elseif(strlen($Password)!==32){
|
||||
if(strlen($Password)!==32){
|
||||
update_db("user_log", ["description" => "请求登录>密码错误(长度应该是32位的MD5)"], ["id"=>$log_id]);
|
||||
msg(-1,'密码错误!');
|
||||
}elseif($c != $global_config["Login"] && $c != $USER_DB['Login'] ){
|
||||
update_db("user_log", ["description" => "请求登录>登录入口错误"], ["id"=>$log_id]);
|
||||
msg(-1,"登录入口错误");
|
||||
}elseif(strlen($_SERVER['HTTP_USER_AGENT'])>256){
|
||||
}elseif(strlen($_SERVER['HTTP_USER_AGENT'])>1024){
|
||||
update_db("user_log", ["description" => "请求登录>浏览器UA长度异常"], ["id"=>$log_id]);
|
||||
msg(-1,"浏览器UA长度异常,请更换浏览器!");
|
||||
}
|
||||
|
||||
$LoginConfig = unserialize( $USER_DB['LoginConfig'] );
|
||||
//开启双重验证时验证OTP验证码
|
||||
if(!empty($LoginConfig['totp_key'])){
|
||||
if(empty($_POST['otp_code'])){
|
||||
msgA(['code'=>-1,'msg'=>'您已开启双重验证,请输入OTP验证码']);
|
||||
}
|
||||
require DIR . '/system/Authenticator.php';
|
||||
$totp = new PHPGangsta_GoogleAuthenticator();
|
||||
$checkResult = $totp->verifyCode($LoginConfig['totp_key'], $_POST['otp_code'], 2);
|
||||
if(!$checkResult){
|
||||
msgA(['code'=>-1,'msg'=>'OTP验证码错误,请重试!']);
|
||||
}
|
||||
}
|
||||
|
||||
//计算请求密码和数据库的对比
|
||||
if(Get_MD5_Password($Password,$USER_DB["RegTime"]) === $USER_DB["Password"]){
|
||||
update_db("user_log", ["description" => "请求登录>登录成功"], ["id"=>$log_id]);
|
||||
Set_key($USER_DB);
|
||||
$LoginConfig = unserialize( $USER_DB['LoginConfig'] );
|
||||
|
||||
if(empty($LoginConfig['login_page']) || $LoginConfig['login_page'] == 'admin'){
|
||||
$url = "./?c=admin&u={$USER_DB['User']}";
|
||||
}elseif($LoginConfig['login_page'] == 'index'){
|
||||
|
||||
@@ -234,7 +234,7 @@ function echo_pwds(){
|
||||
}
|
||||
//检查链接
|
||||
function check_link($fid,$title,$url,$url_standby_s=''){
|
||||
$pattern = "/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|sftp:\/\/|magnet:?|ed2k:\/\/|thunder:\/\/|tcp:\/\/|udp:\/\/|rtsp:\/\/).+/";
|
||||
$pattern = "/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|sftp:\/\/|magnet:?|ed2k:\/\/|thunder:\/\/|tcp:\/\/|udp:\/\/|rtsp:\/\/|wsa:\/\/|vmrc:\/\/).+/";
|
||||
$length_limit = unserialize(get_db("global_config","v",["k"=>"length_limit"]));
|
||||
if (empty($fid)) msg(-1,'分类id(fid)不能为空');
|
||||
if (empty($title)) msg(-1,'名称不能为空');
|
||||
@@ -335,21 +335,39 @@ function Get_ExpireTime($day =30){
|
||||
}
|
||||
//验证登录
|
||||
function is_login(){
|
||||
global $USER_DB,$db;
|
||||
global $USER_DB;
|
||||
$time = time();
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
|
||||
if (!function_exists('delete_expired_info')) {
|
||||
function delete_expired_info($time,$LoginConfig){
|
||||
global $USER_DB;
|
||||
if(empty($LoginConfig['Session'])){
|
||||
$where = [
|
||||
"uid" => $USER_DB['ID'],
|
||||
//"expire_time" => 0,
|
||||
"OR" => [
|
||||
"last_time[<]" => strtotime('-1 day'),
|
||||
"login_time[<]" => strtotime('-15 day')
|
||||
]
|
||||
];
|
||||
}else{
|
||||
$where = [
|
||||
"uid" => $USER_DB['ID'],
|
||||
"OR" => [
|
||||
"expire_time[<]" => $time,
|
||||
"last_time[<]" => strtotime("-{$LoginConfig['KeyClear']} day")
|
||||
]
|
||||
];
|
||||
}
|
||||
//var_dump(select_db('user_login_info','*',$where),$where);exit;
|
||||
delete_db("user_login_info", $where); //清理到期Key
|
||||
update_db("global_user",["kct"=>$time],["User" => $USER_DB['User']]); //记录清理时间
|
||||
}
|
||||
}
|
||||
|
||||
//清理间隔30分钟(1800秒)
|
||||
if( ($USER_DB['kct'] + 1800) < $time ){
|
||||
$lt = $time - ($LoginConfig['KeyClear'] * 24 * 60 * 60);
|
||||
$where = ["AND" =>
|
||||
[
|
||||
"uid" => $USER_DB['ID'],
|
||||
"OR" => ["expire_time[<]" => $time,"last_time[<]" => $lt]
|
||||
]
|
||||
];
|
||||
delete_db("user_login_info", $where); //清理到期Key
|
||||
update_db("global_user",["kct"=>$time],["User" => $USER_DB['User']]); //记录清理时间
|
||||
delete_expired_info($time,$LoginConfig);
|
||||
}
|
||||
|
||||
//查询登录信息
|
||||
@@ -359,26 +377,22 @@ function is_login(){
|
||||
//没找到返回未登录
|
||||
if(empty($info)){return false;}
|
||||
|
||||
|
||||
|
||||
//UA验证
|
||||
if($LoginConfig['KeySecurity'] > 0 && $_SERVER['HTTP_USER_AGENT'] != $info['ua']){return false;}
|
||||
//IP验证
|
||||
if($LoginConfig['KeySecurity'] > 1 && Get_IP() != $info['ip']){return false;}
|
||||
|
||||
//到期验证(同时重新计算)
|
||||
if( $info['expire_time'] != 0 && ($time > $info['expire_time'] || $time > ($info['login_time'] + ($LoginConfig['Session'] * 24 * 60 * 60) ) )){
|
||||
delete_db("user_login_info", $where);
|
||||
return false;
|
||||
}
|
||||
//会话Key验证(没有到期时间时如果距上次访问时间大于24小时认为无效)
|
||||
if($info['expire_time'] == 0 && ($info['last_time'] + 86400) < $time){
|
||||
delete_db("user_login_info", $where);
|
||||
return false;
|
||||
}//有到期时间,且开启了Key清理
|
||||
elseif($LoginConfig['KeyClear'] != 0 && ($info['last_time'] + ($LoginConfig['KeyClear'] * 24 * 60 * 60)) < $time ){
|
||||
delete_db("user_login_info", $where);
|
||||
return false;
|
||||
//根据登录保持选项来判断key是否有效
|
||||
if(empty($LoginConfig['Session'])){ //浏览器关闭时
|
||||
if($info['last_time'] < strtotime('-1 day') || $info['login_time'] < strtotime('-15 day')){ //上次访问超过1天 或 登录时间超过15天
|
||||
delete_expired_info($time,$LoginConfig);
|
||||
return false;
|
||||
}
|
||||
}else{ //保持天数(已到期或上次访问时间超时)
|
||||
if($info['expire_time'] < $time || $info['last_time'] < strtotime("-{$LoginConfig['KeyClear']} day")){
|
||||
delete_expired_info($time,$LoginConfig);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Key验证
|
||||
@@ -431,10 +445,10 @@ function is_subscribe($type = 'bool'){
|
||||
$count = count($host);
|
||||
if($count != 2){
|
||||
$data['host'] = $host[$count-2].'.'.$host[$count-1];
|
||||
//如果存在端口则去除
|
||||
if(preg_match("/(.+):\d+/",$data['host'],$host)) {
|
||||
$data['host'] = $host[1];
|
||||
}
|
||||
}
|
||||
//如果存在端口则去除
|
||||
if(preg_match("/(.+):\d+/",$data['host'],$host)) {
|
||||
$data['host'] = $host[1];
|
||||
}
|
||||
}
|
||||
if(!stristr($data['domain'],$data['host'])){
|
||||
@@ -516,7 +530,7 @@ function get_http_code($url,$TIMEOUT = 10 ,$NOBODY = true) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
function ccurl($url,$overtime = 3){
|
||||
function ccurl($url,$overtime = 3,$Referer = false){
|
||||
try {
|
||||
$curl = curl_init ( $url ) ; //初始化
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, $overtime ); //超时
|
||||
@@ -525,6 +539,11 @@ function ccurl($url,$overtime = 3){
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
if($Referer === true){
|
||||
curl_setopt($curl, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
|
||||
}elseif(!empty($Referer)){
|
||||
curl_setopt($curl, CURLOPT_REFERER, $Referer);
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36');
|
||||
$Res["content"] = curl_exec ( $curl ) ;
|
||||
$Res["code"] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
@@ -536,17 +555,19 @@ function ccurl($url,$overtime = 3){
|
||||
return $Res;
|
||||
}
|
||||
|
||||
function downFile($url, $file = '', $savePath = './data/temp/'){
|
||||
function downFile($url, $file = '', $savePath = './data/temp/',$referer = '',$TIMEOUT = 60){
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //超时/秒
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $TIMEOUT); //超时/秒
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //不直接输出
|
||||
curl_setopt($ch, CURLOPT_HEADER, FALSE); //不需要response header
|
||||
curl_setopt($ch, CURLOPT_NOBODY, FALSE); //需要response body
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //允许重定向(适应网盘下载)
|
||||
|
||||
if(!empty($referer)){
|
||||
curl_setopt($ch, CURLOPT_REFERER, $referer);
|
||||
}
|
||||
try{
|
||||
$res = curl_exec($ch);
|
||||
}finally{
|
||||
@@ -626,6 +647,10 @@ function is_Duplicated($array, $field){
|
||||
//检查权限(有权限返回true 没有权限时根传递参数1是返回false 2是直接返回错误信息)
|
||||
function check_purview($name,$return_type){
|
||||
global $USER_DB;
|
||||
//230705新增,禁止判断默认用户是否可以使用自定义代码
|
||||
if($USER_DB['UserGroup'] == 'default' && $GLOBALS['global_config']['c_code'] != '1' && ( $name == 'header' || $name == 'footer' )){
|
||||
return false;
|
||||
}
|
||||
if($USER_DB['UserGroup'] == 'root' || $USER_DB['UserGroup'] == 'default'){
|
||||
return true;
|
||||
}
|
||||
@@ -688,10 +713,10 @@ function send_email($config){
|
||||
$mail->SMTPSecure = $config['secure'];
|
||||
$mail->Port = intval($config['port']);
|
||||
|
||||
if(preg_match('/(.+)<(.+)>/', $config['sender'], $match)){
|
||||
if(preg_match('/(.+)<(.+@.+)>$/', $config['sender'], $match)){
|
||||
$mail->setFrom($match[2],$match[1]);
|
||||
}else{
|
||||
$mail->setFrom($config['sender']);
|
||||
$mail->setFrom($config['user'],empty($config['sender'])?'TwoNav':$config['sender']);
|
||||
}
|
||||
|
||||
$mail->addAddress($config['addressee']); //收件人
|
||||
@@ -714,4 +739,22 @@ function send_email($config){
|
||||
msg(-1,'发送失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//统计访问ip数
|
||||
function count_ip(){
|
||||
$ip = Get_IP(); //取访客IP
|
||||
$k = date('Ymd'); $t = 'ip_list';
|
||||
$ip_list = get_db('user_count','e',['uid'=>UID,'k'=>$k,'t'=>$t]); //取列表
|
||||
$ip_list = empty($ip_list) ? [] : unserialize($ip_list); //反序列化
|
||||
//判断IP是否存在列表中
|
||||
if(!in_array($ip, $ip_list)){
|
||||
$ip_list[] = $ip; //加入列表
|
||||
if(!has_db('user_count',['uid'=>UID,'t'=>$t,'k'=>$k])){
|
||||
insert_db("user_count", ['uid'=>UID,"k"=>$k,"e"=>$ip_list,'t'=>$t]);
|
||||
}else{
|
||||
update_db("user_count", ["e"=>$ip_list],['uid'=>UID,'t'=>$t,'k'=>$k]);
|
||||
}
|
||||
write_user_count($k,'ip_count');//访问ip数+1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ if(empty($s_templates)){
|
||||
}
|
||||
|
||||
//载入辅助函数
|
||||
if(empty($c) || in_array($c,['index','click'])){
|
||||
if(empty($c) || in_array($c,['index','click','article'])){
|
||||
//将URL转换为base64编码
|
||||
function base64($url){
|
||||
$urls = parse_url($url);
|
||||
@@ -28,7 +28,7 @@ if(empty($c) || in_array($c,['index','click'])){
|
||||
function is_apply(){
|
||||
global $global_config;
|
||||
$apply_user = unserialize( get_db("user_config", "v", ["k" => "apply","uid"=>UID]));
|
||||
return ($global_config['apply'] == 1 && $apply_user['apply'] == 1);
|
||||
return ($global_config['apply'] == 1 && $apply_user['apply'] > 0);
|
||||
}
|
||||
//是否启用留言
|
||||
function is_guestbook(){
|
||||
@@ -48,8 +48,10 @@ if(empty($c) || in_array($c,['index','click'])){
|
||||
}
|
||||
if ($site['link_icon'] == 'default'){
|
||||
return($GLOBALS['libs'].'/Other/default.ico');
|
||||
}elseif ($icon ==1){
|
||||
return('./favicon/index2.php?url='.$link['real_url']);
|
||||
}elseif ($icon ==20){
|
||||
return('./index.php?c=icon&url='.base64_encode($link['real_url']));
|
||||
}elseif ($icon ==21){
|
||||
return('./ico/'.base64_encode($link['real_url']));
|
||||
}elseif($icon ==2){
|
||||
return('//favicon.png.pub/v1/'.base64($link['real_url']));
|
||||
}elseif($icon ==4){
|
||||
@@ -96,3 +98,83 @@ if(empty($c) || in_array($c,['index','click'])){
|
||||
|
||||
}
|
||||
|
||||
//获取文章列表
|
||||
function get_article_list($category = 0,$limit = 0){
|
||||
$where['uid'] = UID;
|
||||
if(!is_login()){
|
||||
$where['AND']['state'] = 1; //状态筛选
|
||||
}else{
|
||||
$where['AND']['OR']['state'] = [1,2]; //状态筛选
|
||||
}
|
||||
|
||||
//分类筛选
|
||||
if($category > 0){
|
||||
$where['AND']['category'] = $category;
|
||||
}
|
||||
//统计条数
|
||||
$count = count_db('user_article_list',$where);
|
||||
//获取条数
|
||||
if($limit > 0){
|
||||
$where['LIMIT'] = [0,$limit];
|
||||
}
|
||||
//获取文章列表
|
||||
$datas = select_db('user_article_list','*',$where);
|
||||
|
||||
//查询分类
|
||||
$categorys = select_db('user_categorys',['cid(id)','name'],['uid'=>UID]);
|
||||
$categorys = array_column($categorys,'name','id');
|
||||
//为文章添加分类名称
|
||||
foreach ($datas as &$data) {
|
||||
$data['category_name'] = $categorys[$data['category']] ?? 'Null';
|
||||
}
|
||||
return ['data'=>$datas,'count'=>$count];
|
||||
}
|
||||
//根据文章id获取内容
|
||||
function get_article_content($id){
|
||||
$where['uid'] = UID;
|
||||
if(!is_login()){
|
||||
$where['AND']['state'] = 1; //状态筛选
|
||||
}else{
|
||||
$where['AND']['OR']['state'] = [1,2]; //状态筛选
|
||||
}
|
||||
$where['id'] = $id;
|
||||
$data = get_db('user_article_list','*',$where);
|
||||
$data['category_name'] = get_db('user_categorys','name',['uid'=>UID,'cid'=>$data['category']]);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//获取分类列表
|
||||
function get_category_list($layer = false){
|
||||
//查询条件
|
||||
$where = [];
|
||||
$where['uid'] = UID;
|
||||
$where['fid'] = 0;
|
||||
$where['status'] = 1;
|
||||
$where['ORDER'] = ['weight'=>'ASC'];
|
||||
if(!is_login()){
|
||||
$where['property'] = 0;
|
||||
}
|
||||
//查找一级分类
|
||||
$content = ['cid(id)','name','property','font_icon','icon','description'];
|
||||
$category_parent = select_db('user_categorys',$content,$where);
|
||||
//查找二级分类
|
||||
$categorys = [];
|
||||
if($layer === true){
|
||||
foreach ($category_parent as $key => $category) {
|
||||
$where['fid'] = $category['id'];
|
||||
$category_subitem = select_db('user_categorys',$content,$where);
|
||||
$category['subitem_count'] = count($category_subitem);
|
||||
$category['subitem'] = $category_subitem;
|
||||
array_push($categorys,$category);
|
||||
}
|
||||
}else{
|
||||
foreach ($category_parent as $key => $category) {
|
||||
$where['fid'] = $category['id'];
|
||||
$category_subitem = select_db('user_categorys',$content,$where);
|
||||
$category['subitem_count'] = count($category_subitem);
|
||||
array_push($categorys,$category);
|
||||
$categorys = array_merge ($categorys,$category_subitem);
|
||||
}
|
||||
}
|
||||
return $categorys;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ switch ($type) {
|
||||
setcookie($USER_DB['User'].'_Password2', md5($USER_DB['Password'].$_COOKIE[U.'_key'].$_POST['Password2']), 0,'','',false,true);
|
||||
msg(1,'二级密码正确!');
|
||||
}else{
|
||||
msg(-1,'二级密码错误!'.$LoginConfig['Password2']);
|
||||
msg(-1,'二级密码错误!');
|
||||
}
|
||||
break;
|
||||
case "link_pwd":
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.0.20-20230520
|
||||
v2.0.36-20230823
|
||||
@@ -649,7 +649,17 @@
|
||||
padding: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/**菜单缩放*/
|
||||
.popup-tips .layui-layer-TipsG{
|
||||
display: none;
|
||||
}
|
||||
.popup-tips.layui-layer-tips .layui-layer-content{
|
||||
padding: 0;
|
||||
}
|
||||
.popup-tips .layui-nav-tree{
|
||||
width: 150px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/**左侧菜单字体间距*/
|
||||
.layuimini-menu-left .layui-nav-item a span {
|
||||
letter-spacing: 1px;
|
||||
@@ -879,4 +889,4 @@
|
||||
.layui-layout-admin .layui-logo {width: 155px;}
|
||||
.layui-body {left: 155px;}
|
||||
.layuimini-tool {left: 190px;}
|
||||
.layui-nav-tree {width: 155px!important;}
|
||||
.layui-nav-tree {width: 155px!important;}
|
||||
|
||||
1
templates/admin/img/error.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684742765171" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8745" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M0 511.19a512 511.19 0 1 0 1024 0 512 511.19 0 1 0-1024 0z" fill="#FF3333" p-id="8746"></path><path d="M512.768 460.245l129.28-129.28a36.65 36.65 0 1 1 51.797 51.798l-129.28 129.28 129.579 129.536a36.565 36.565 0 0 1-51.755 51.712L512.853 563.755l-129.28 129.28a36.65 36.65 0 0 1-51.754-51.798l129.28-129.28L331.52 382.421a36.565 36.565 0 0 1 51.712-51.754l129.536 129.536z" fill="#FFFFFF" p-id="8747"></path></svg>
|
||||
|
After Width: | Height: | Size: 746 B |
1
templates/admin/img/file_bt.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684722792069" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5418" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M748 183.5V0H96v1024h836V183.5z" fill="#68B2FC" p-id="5419"></path><path d="M932 184H748V0" fill="#86CAEF" p-id="5420"></path><path d="M331.5 344.9H391v315.7h-59.5V344.9z m26.1 258.3h100.7c13.6 0 24.1-3.3 31.6-9.9 7.5-6.6 11.2-15.8 11.2-27.7v-0.6c0-8-1.7-14.8-5-20.4-3.3-5.6-8.2-9.9-14.7-12.9-6.4-3-14.1-4.5-23.1-4.5H357.6v-57.3h100.7c12.3 0 21.8-3.1 28.5-9.3 6.7-6.2 10.1-15 10.1-26.3 0-10.1-3.4-18-10.1-23.7s-16.2-8.5-28.5-8.5H357.6v-57.3h102.7c20.4 0 37.8 3.4 52.3 10.1 14.5 6.7 25.5 16.5 33 29.3s11.3 28.2 11.3 46.1c0 12.3-2.4 23.2-7.3 32.7-4.9 9.5-11.9 17.3-21.2 23.3-9.3 6.1-20.4 10.2-33.4 12.4 13.9 1.9 25.8 6.1 35.7 12.7 9.9 6.6 17.4 15.2 22.6 25.7 5.1 10.6 7.7 22.8 7.7 36.7v0.7c0 18.1-3.8 33.6-11.4 46.5-7.6 12.9-18.7 22.7-33.2 29.4-14.5 6.7-32 10.1-52.4 10.1H357.6v-57.3zM596.8 435.2h110.3V486H596.8v-50.8z m37 211.4c-9.2-10.1-13.8-24.9-13.8-44.6V369.7h59.5v217.5c0 5.5 1.1 9.7 3.3 12.7 2.2 3 5.4 4.5 9.6 4.5h14.8v57.3h-30c-19.7-0.1-34.2-5.1-43.4-15.1z" fill="#FFFFFF" p-id="5421"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
templates/admin/img/ftp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684722980058" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6352" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M575.829333 211.057778L458.296889 79.644444H79.644444v659.911112h864.711112V211.057778z m-140.856889-79.644445l70.656 79.644445H131.982222v-79.644445zM892.017778 687.217778H131.982222V263.395556h760.035556z" fill="#F5A333" p-id="6353"></path><path d="M485.831111 713.272889h52.337778v204.8h-52.337778z" fill="#F5A333" p-id="6354"></path><path d="M79.644444 838.542222h864.711112v52.337778H79.644444z" fill="#F5A333" p-id="6355"></path><path d="M273.521778 807.822222h456.362666v113.777778H273.521778zM240.298667 591.644444V371.712h150.755555v37.205333H284.444444v52.110223h91.818667v37.205333H284.444444V591.644444zM477.184 591.644444V408.917333H411.875556v-37.205333h174.762666v37.205333h-65.080889V591.644444zM615.310222 591.644444V371.712h71.224889A261.688889 261.688889 0 0 1 739.555556 375.466667a57.685333 57.685333 0 0 1 31.630222 21.504 68.266667 68.266667 0 0 1 12.743111 42.894222 72.021333 72.021333 0 0 1-7.281778 34.133333 61.44 61.44 0 0 1-18.659555 21.731556 64.967111 64.967111 0 0 1-22.755556 10.353778 247.239111 247.239111 0 0 1-45.511111 3.185777H659.911111V591.644444zM659.911111 408.917333v62.464h24.234667a111.616 111.616 0 0 0 35.157333-3.527111 28.103111 28.103111 0 0 0 13.880889-10.808889 29.809778 29.809778 0 0 0 5.006222-17.066666 28.672 28.672 0 0 0-7.054222-19.797334 30.606222 30.606222 0 0 0-17.863111-9.784889 227.555556 227.555556 0 0 0-31.971556-1.479111z" fill="#F5A333" p-id="6356"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
templates/admin/img/ie.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684722468651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3256" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M511.500488 512.499512m-511.500488 0a511.500488 511.500488 0 1 0 1023.000976 0 511.500488 511.500488 0 1 0-1023.000976 0Z" fill="#1BC1FA" p-id="3257"></path><path d="M627.84487 635.935969c46.679415-41.745233 105.950533-55.146146 147.110338-37.076792a271.239118 271.239118 0 0 0 8.025163-28.063595H606.727493c-5.224898 25.43616-22.521007 61.271165-78.893955 61.271165-87.284761 0-89.78432-86.027988-89.78432-86.027988h170.81319v0.175828h178.51367c1.582455-11.920359 2.675387-23.990572 2.675387-36.325526 0-121.298544-79.270587-223.983266-188.799625-259.353724 234.507988-164.407446 192.141362 66.50905 192.141362 66.509049 48.220909-132.993124-8.31488-194.503056-186.188176-98.074224-13.778544 7.448726-26.942689 15.198158-39.855079 23.074466-16.204176-3.002068-32.846923-4.77234-49.929241-4.772339-146.408023 0-265.546677 115.508199-272.003371 260.370731 81.419489-119.615188 220.491676-187.255134 220.491676-187.255133l0.138864 3.981112C370.74894 393.839391 306.249928 484.227122 259.750338 571.385007c-66.50905 124.665257-53.182064 234.409085-8.289905 264.315879 67.501081 44.992062 161.166611-11.480788 219.272867-57.351992 15.173182 2.637424 30.748972 4.169928 46.688405 4.169927 19.477979 0 38.468433-2.05799 56.780551-5.942197-12.501791-42.754248 7.480695-99.357971 53.642614-140.640655zM519.104062 382.698271c87.271774 0 89.759344 86.040976 89.759345 86.040976h-170.81319s-6.230915-86.040976 81.053845-86.040976zM286.366345 662.828706l2.687376-4.836277c37.481397 57.867489 96.190064 100.573783 165.161709 117.028714-278.421104 160.752016-167.849085-112.192437-167.849085-112.192437z" fill="#FFFFFF" p-id="3258"></path><path d="M774.955208 598.858178c-41.159805-18.069354-100.430923-4.668441-147.110338 37.076792-46.16192 41.282685-66.144406 97.886408-53.642614 140.640655 93.943259-19.92754 169.895087-88.292777 200.752952-177.717447z" fill="#FFFFFF" opacity=".4" p-id="3259"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
templates/admin/img/magnet.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684722857208" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6433" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M728.817346 446.041567L416.705043 758.091873c-41.55991 41.621907-109.244506 41.621907-150.804416 0-41.623907-41.55991-41.623907-109.244506 0-150.806415l312.046306-312.110303-165.927655-165.899657L99.968972 441.353803c-133.307296 133.307296-133.307296 349.392428 0 482.665725 133.307296 133.307296 349.422427 133.307296 482.665726 0l312.112303-312.048306-165.929655-165.929655z" fill="#DA4453" p-id="6434"></path><path d="M261.212863 280.111912l165.929655 165.929655 150.804415-150.868412-165.927655-165.897657z" fill="#CCD1D9" p-id="6435"></path><path d="M932.371108 438.479948a21.294929 21.294929 0 0 0 6.249686-15.12324c0-11.781407-9.561519-21.310928-21.310928-21.310928a21.352926 21.352926 0 0 0-15.12324 6.249686l-60.308967 60.308966a21.222933 21.222933 0 0 0-6.249685 15.091242c0 11.781407 9.561519 21.342927 21.310928 21.342926 5.937701 0 11.249434-2.405879 15.123239-6.281684l60.308967-60.276968zM1017.678818 528.945398a21.220933 21.220933 0 0 0-15.061243-6.249686h-85.307709a21.220933 21.220933 0 0 0-15.061243 6.249686c-8.375579 8.34358-8.375579 21.842901 0 30.154483 4.123793 4.187789 9.623516 6.249686 15.061243 6.249686h85.307709c5.437727 0 10.93745-2.061896 15.061243-6.249686 8.375579-8.311582 8.375579-21.810903 0-30.154483zM811.689178 322.953758c-8.311582-8.34358-21.810903-8.34358-30.122485 0-4.187789 4.155791-6.249686 9.623516-6.249686 15.093241v85.309709c0 5.437727 2.061896 10.93745 6.249686 15.061243a21.196934 21.196934 0 0 0 30.122485 0c4.187789-4.123793 6.249686-9.623516 6.249685-15.061243v-85.309709c0-5.469725-2.061896-10.93745-6.249685-15.093241z" fill="#AAB2BD" p-id="6436"></path><path d="M615.695035 121.741877a21.206933 21.206933 0 0 0 6.251685-15.061242c0-11.811406-9.563519-21.342927-21.374925-21.342927-5.875704 0-11.187437 2.405879-15.061242 6.249686v-0.031999l-60.308967 60.372964a21.148936 21.148936 0 0 0-6.249686 15.061243c0 11.781407 9.561519 21.342927 21.310929 21.342926 5.875704 0 11.249434-2.405879 15.061242-6.249685l60.370964-60.340966zM701.006744 212.239326a21.330927 21.330927 0 0 0-15.061242-6.249686h-85.30971c-5.499723 0-10.93745 2.093895-15.123239 6.249686-8.311582 8.34358-8.311582 21.842901 0 30.186482a21.366925 21.366925 0 0 0 15.123239 6.249685h85.30971c5.437727 0 10.875453-2.093895 15.061242-6.249685 8.311582-8.34358 8.311582-21.842901 0-30.186482zM495.015104 6.247686c-8.311582-8.313582-21.810903-8.313582-30.186482 0-4.123793 4.187789-6.249686 9.623516-6.249685 15.123239v85.245713c0 5.499723 2.123893 10.93745 6.249685 15.123239 8.375579 8.313582 21.8749 8.313582 30.186482 0a21.214933 21.214933 0 0 0 6.249686-15.093241V21.340927c0-5.467725-2.063896-10.905452-6.249686-15.093241z" fill="#AAB2BD" p-id="6437"></path><path d="M894.747001 611.971222l-165.929655-165.929655-150.870413 150.806416 165.931655 165.931655z" fill="#CCD1D9" p-id="6438"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
templates/admin/img/tcpudp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1684724768873" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20171" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M960 511.1c0-125.5-52-238.7-135.4-319.9-83.5-81.5-195.7-127.1-312.6-127-116.9-0.1-229.1 45.5-312.6 127.1-13.6 13.2-26.2 27.3-38.1 42.2-63 78.8-97.3 176.7-97.2 277.6 0 246.8 200.5 447 448 447 116.9 0.1 229.1-45.6 312.6-127.1 13.6-13.2 26.3-27.3 38.1-42.2C925.7 710 960 612 960 511.1zM405.6 128.9c-29.7 40.2-54.7 84.1-74.4 130.7-30.4-10.4-59.8-23.7-88-39.7 46.1-44.3 101.9-75.6 162.4-91zM345.3 480c2.7-49.7 12.8-97.4 29.5-142.3 34.1 7.4 69.3 12 105.3 13.6V480H345.3z m134.3 64.4v126.4c-35.3 1.5-70.4 6-104.9 13.3-17-45.1-26.9-92.1-29.5-139.8h134.4zM208 276.2c33 18.8 67.7 34.2 103.7 46.1-17.2 51-27.2 104.2-29.6 158.1H127.5c5.1-74.9 33.3-146.2 80.5-204.2z m0 470.9c-47.2-57.3-75.4-127.7-80.5-201.5H282c2.6 54.4 12.7 106.7 29.7 156.1-36 11.6-70.7 26.9-103.7 45.4z m35.2 57c28.2-16 57.6-29.3 88-39.7 19.7 46.6 44.7 90.5 74.4 130.7-60.5-15.5-116.3-46.8-162.4-91zM484 879.8c-35.1-40-64.4-84.7-87-132.9 28.7-6.1 57.8-10 87-11.5v144.4z m0-592.9c-29.3-1.5-58.4-5.4-87-11.5 22.6-48.2 51.9-92.9 87-132.9v144.4zM815.9 276c46.6 58.1 74.3 129.5 79.4 204.4H742.9c-2.4-53.9-12.3-107.2-29.3-158.3 35.5-11.8 69.7-27.3 102.3-46.1-0.1 0-0.1 0 0 0z m-34.3-56.4c-28 16-57.2 29.3-87.4 39.8-19.6-46.7-44.4-90.6-73.9-130.9 61.1 15.7 116.2 47.5 161.3 91.1zM544.1 479.9V351.3c35.4-1.6 70.6-6.1 105.1-13.6 17 45.8 26.9 93.7 29.5 142.2H544.1z m134.7 64.6c-2.6 47.6-12.5 94.6-29.5 139.6-34.5-7.3-69.7-11.8-105.1-13.3V544.5h134.6zM540 142.4c35.1 40 64.4 84.7 87 132.9-28.3 6-57.3 10-87 11.5V142.4z m0 593c29.7 1.6 58.7 5.5 87 11.5-22.6 48.2-51.8 92.9-87 132.9V735.4z m80.3 160.3c29.5-40.2 54.3-84.2 73.9-130.9 30.4 10.5 59.6 23.9 87.3 39.8-45.7 44.3-101.1 75.6-161.2 91.1z m195.5-148.2c-32.5-18.6-66.8-33.8-102.3-45.6 17-50.4 26.9-103 29.3-156.2h152.4c-5 74-32.8 144.5-79.4 201.8z" fill="#4AAF47" p-id="20172"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
BIN
templates/admin/img/xunlei.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
@@ -23,8 +23,9 @@
|
||||
<div class="layui-header header">
|
||||
<div class="layui-logo layuimini-logo"></div>
|
||||
<div class="layuimini-header-content">
|
||||
<a><div class="layuimini-tool"><i title="左侧栏展开/收缩" class="fa fa-outdent" data-side-fold="1"></i></div></a>
|
||||
<a><div class="layuimini-tool"><i title="左侧栏展开/收缩" class="fa fa-outdent" style="font-size: 1.1rem;" data-side-fold="1"></i></div></a>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
<li class="layui-nav-item" lay-unselect><a href="javascript:;" data-home="主页" title="主页"><i class="fa fa-home" style="font-size: 1.08rem;"></i></a></li>
|
||||
<li class="layui-nav-item" lay-unselect><a href="javascript:;" data-refresh="刷新" title="刷新"><i class="fa fa-refresh"></i></a></li>
|
||||
<li class="layui-nav-item mobile layui-hide-xs" lay-unselect><a href="javascript:;" title="全屏" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a></li>
|
||||
<li class="layui-nav-item layuimini-setting">
|
||||
|
||||
@@ -82,6 +82,15 @@
|
||||
}
|
||||
limit = false; //取消修改限制
|
||||
layer.closeAll('loading'); //关闭加载层
|
||||
//加载加密分组数据
|
||||
$.post(get_api('read_pwd_group_list'),{'page':'1','limit':'9999'},function(data,status){
|
||||
if(data.code == 1){
|
||||
pwds = [];
|
||||
for(var i =0;i<data.count;i++){
|
||||
pwds['pid_'+data.data[i].pid] = {'pwd':data.data[i].password,'name':data.data[i].name};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -92,7 +101,7 @@
|
||||
//行点击事件
|
||||
table.on('row(table)', function(obj) {
|
||||
obj.tr.addClass('layui-bg-black').siblings().removeClass('layui-bg-black');
|
||||
obj.tr.find('i[class="layui-anim layui-icon"]').trigger("click");
|
||||
obj.tr.find('i[class="layui-anim layui-icon layui-icon-circle"]').trigger("click");
|
||||
$("#Tips").text('当前选中: ' + obj.data.name);
|
||||
});
|
||||
|
||||
|
||||
@@ -23,66 +23,72 @@ layui.use(['layer','miniTab'], function(){
|
||||
layer.tips("点击此处更新到最新版","#sysup",{tips: [3, "#ff5722"],time: 60*1000,anim: 6});
|
||||
layer.msg(' 检测到新版本,请尽快更新 ', {offset: 'b',anim: 6,time: 60*1000});
|
||||
}
|
||||
}
|
||||
//点击更新事件
|
||||
$('#sysup').on('click', function(){
|
||||
let tip = layer.open({
|
||||
title:"系统更新"
|
||||
,content: "1.更新有风险请备份后再更新<br />2.更新后检查主题是否可更新<br />3.更新时请勿有其他操作<br />4.更新时请勿刷新或关闭页面<br />5.确保所有文件(夹)是可写权限"
|
||||
,btn: ['确定更新', '更新内容', '取消']
|
||||
,yes: function(index, layero){
|
||||
let fail = false;
|
||||
let up_info = {'code':0};
|
||||
let i=0;
|
||||
layer.close(tip);
|
||||
layer.load(1, {shade:[0.3,'#fff']});//加载层
|
||||
let msg_id = layer.msg('正在准备更新,请勿操作.', {icon: 16,time: 1000*300});
|
||||
//设置同步模式
|
||||
$.ajaxSetup({ async : false });
|
||||
|
||||
//获取更新信息
|
||||
$.post(get_api("other_upsys"),{"i":0}, function(data, status) {
|
||||
up_info = data;
|
||||
});
|
||||
|
||||
//如果失败
|
||||
if(up_info.code != 1){
|
||||
layer.closeAll();
|
||||
layer.alert(up_info.msg || "错误代码:404",{icon:2,title:'更新失败',anim: 2,shadeClose: false,closeBtn: 0,btn: ['知道了']});
|
||||
return;
|
||||
}
|
||||
//设为异步模式
|
||||
$.ajaxSetup({ async : true });
|
||||
//开始请求更新
|
||||
request_update(); let msg = '';
|
||||
function request_update(){
|
||||
if( i >= up_info.info.length){
|
||||
layer.closeAll();
|
||||
layer.alert('更新完毕,请刷新页面!',{icon:1,title:'更新成功',anim: 2,shadeClose: false,closeBtn: 0,btn: ['刷新页面']},function () {parent.location.reload();});
|
||||
return;
|
||||
}else{
|
||||
i++;
|
||||
}
|
||||
$("#layui-layer"+ msg_id+" .layui-layer-padding").html('<i class="layui-layer-ico layui-layer-ico16"></i>[ ' + i + ' / ' + up_info.info.length + ' ] ' + up_info.info[i-1]);
|
||||
//点击更新事件
|
||||
$('#sysup').on('click', function(){
|
||||
let tip = layer.open({
|
||||
title:"系统更新"
|
||||
,content: "1.更新有风险请备份后再更新<br />2.更新后检查主题是否可更新<br />3.更新时请勿有其他操作<br />4.更新时请勿刷新或关闭页面<br />5.确保所有文件(夹)是可写权限"
|
||||
,btn: ['确定更新', '更新内容', '取消']
|
||||
,yes: function(index, layero){
|
||||
let fail = false;
|
||||
let up_info = {'code':0};
|
||||
let i=0;
|
||||
layer.close(tip);
|
||||
layer.load(1, {shade:[0.3,'#fff']});//加载层
|
||||
let msg_id = layer.msg('正在准备更新,请勿操作.', {icon: 16,time: 1000*300});
|
||||
//设置同步模式
|
||||
$.ajaxSetup({ async : false });
|
||||
|
||||
$.post(get_api("other_upsys"),{"i":i}, function(data, status) {
|
||||
if (data.code == 1) {
|
||||
request_update();
|
||||
}else{
|
||||
layer.closeAll();
|
||||
layer.alert(data.msg || "未知错误,请联系开发者!",{icon:5,title:up_info.info[i-1],anim: 2,shadeClose: false,closeBtn: 0,btn: ['知道了']});
|
||||
}
|
||||
//获取更新信息
|
||||
$.post(get_api("other_upsys"),{"i":0}, function(data, status) {
|
||||
up_info = data;
|
||||
});
|
||||
|
||||
//如果失败
|
||||
if(up_info.code != 1){
|
||||
layer.closeAll();
|
||||
layer.alert(up_info.msg || "错误代码:404",{icon:2,title:'更新失败',anim: 2,shadeClose: false,closeBtn: 0,btn: ['知道了']});
|
||||
return;
|
||||
}
|
||||
//设为异步模式
|
||||
$.ajaxSetup({ async : true });
|
||||
//开始请求更新
|
||||
request_update(); let msg = '';
|
||||
function request_update(){
|
||||
if( i >= up_info.info.length){
|
||||
layer.closeAll();
|
||||
layer.alert('更新完毕,请刷新页面!',{icon:1,title:'更新成功',anim: 2,shadeClose: false,closeBtn: 0,btn: ['刷新页面']},function () {parent.location.reload();});
|
||||
return;
|
||||
}else{
|
||||
i++;
|
||||
}
|
||||
$("#layui-layer"+ msg_id+" .layui-layer-padding").html('<i class="layui-layer-face layui-icon layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>[ ' + i + ' / ' + up_info.info.length + ' ] ' + up_info.info[i-1]);
|
||||
|
||||
$.post(get_api("other_upsys"),{"i":i}, function(data, status) {
|
||||
if (data.code == 1) {
|
||||
request_update();
|
||||
}else{
|
||||
layer.closeAll();
|
||||
layer.alert(data.msg || "未知错误,请联系开发者!",{icon:5,title:up_info.info[i-1],anim: 2,shadeClose: false,closeBtn: 0,btn: ['知道了']});
|
||||
}
|
||||
});
|
||||
}
|
||||
},btn2: function(index, layero){
|
||||
window.open("https://gitee.com/tznb/TwoNav/releases");
|
||||
},btn3: function(index, layero){
|
||||
return true;
|
||||
},cancel: function(){
|
||||
return true;
|
||||
}
|
||||
},btn2: function(index, layero){
|
||||
window.open("https://gitee.com/tznb/TwoNav/releases");
|
||||
},btn3: function(index, layero){
|
||||
return true;
|
||||
},cancel: function(){
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}else{
|
||||
$("#new_ver").append(' <span id="sysup" style="cursor:pointer;color: rgb(1, 170, 237);"> 更新系统</span>');
|
||||
$('#sysup').on('click', function(){
|
||||
layer.alert("暂无可用更新,当前为最新版本",{icon:1,title:"更新系统",anim: "slideDown",shadeClose: true,closeBtn: 0,btn: ['知道了']});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//查看更新日志
|
||||
$('#ver').css({"cursor":"pointer","color":"#01AAED"}); //设置鼠标形状和字体颜色
|
||||
|
||||
@@ -160,11 +160,51 @@ layui.define(["jquery", "miniMenu", "element","miniTab", "miniTheme"], function
|
||||
},
|
||||
// 监听
|
||||
listen: function () {
|
||||
//主页
|
||||
$('body').on('click','[data-home]', function () {
|
||||
top.location.href='./index.php?u='+u;
|
||||
});
|
||||
//刷新
|
||||
$('body').on('click','[data-refresh]', function () {
|
||||
$(".layui-tab-item.layui-show").find("iframe")[0].contentWindow.location.reload();
|
||||
miniAdmin.success('刷新成功');
|
||||
});
|
||||
// 悬停菜单>移入
|
||||
$("body").on("mouseenter", ".layui-nav-tree .menu-li", function () {
|
||||
if (miniAdmin.checkMobile()) {
|
||||
return false;
|
||||
}
|
||||
var classInfo = $(this).attr('class'),
|
||||
tips = $(this).prop("innerHTML"),
|
||||
isShow = $('.layuimini-tool i').attr('data-side-fold');
|
||||
if (isShow == 0 && tips) {
|
||||
tips = "<ul class='layuimini-menu-left-zoom layui-nav layui-nav-tree layui-this'><li class='layui-nav-item layui-nav-itemed'>"+tips+"</li></ul>" ;
|
||||
window.openTips = layer.tips(tips, $(this), {
|
||||
tips: [2, '#2f4056'],
|
||||
time: 300000,
|
||||
skin:"popup-tips",
|
||||
success:function (el) {
|
||||
var left = $(el).position().left - 10 ;
|
||||
$(el).css({ left:left });
|
||||
element.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// 悬停菜单>移出
|
||||
$("body").on("mouseleave", ".popup-tips", function () {
|
||||
if (miniAdmin.checkMobile()) {
|
||||
return false;
|
||||
}
|
||||
var isShow = $('.layuimini-tool i').attr('data-side-fold');
|
||||
if (isShow == 0) {
|
||||
try {
|
||||
layer.close(window.openTips);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
//全屏
|
||||
$('body').on('click','[data-check-screen]', function () {
|
||||
var check = $(this).attr('data-check-screen');
|
||||
|
||||
@@ -129,7 +129,7 @@ layui.define(['table', 'jquery', 'form'], function (exports) {
|
||||
for (var j=0;j<checkedData.length;j++) {
|
||||
if(res.data[i][opt.checkedKey] == checkedData[j][opt.checkedKey]){
|
||||
res.data[i].LAY_CHECKED = true;
|
||||
var index= res.data[i]['LAY_TABLE_INDEX'];
|
||||
var index= res.data[i]['LAY_INDEX'];
|
||||
var checkbox = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="checkbox"]');
|
||||
checkbox.prop('checked', true).next().addClass('layui-form-checked');
|
||||
var radio = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="radio"]');
|
||||
|
||||
@@ -3,12 +3,11 @@ var bak_link_id = 0;
|
||||
var page_sid = '';
|
||||
var link_id = '';
|
||||
var load_index;
|
||||
|
||||
layui.use(['form','upload','miniTab'], function () {
|
||||
var module = _GET('source') === 'tpl' ? ['form', 'upload'] : ['form', 'upload', 'miniTab'];
|
||||
layui.use(module, function () {
|
||||
var $ = layui.jquery;
|
||||
var form = layui.form;
|
||||
var upload = layui.upload;
|
||||
var miniTab = layui.miniTab;
|
||||
var edit_mode = _GET('page') == 'link_edit'; //是否编辑模式
|
||||
//独立页面
|
||||
if(top.location == self.location){
|
||||
@@ -30,8 +29,8 @@ layui.use(['form','upload','miniTab'], function () {
|
||||
if(data.path != '' ){$("#iconurl").val(data.path);}
|
||||
//如果勾选连续添加
|
||||
if($("#continuity").is(":checked")){
|
||||
//$('#reset').click();//完全清空
|
||||
form.val('form',{'url':'','title':'','description':'','icon':''});
|
||||
form.val('form',{'url':'','title':'','description':'','icon':'','keywords':''});
|
||||
$('form input[name^="_"]').val(''); //扩展字段清空
|
||||
$('#icon_img').attr('src', blank_img);//清除缩略图
|
||||
layer.msg('添加成功', {icon: 1});
|
||||
$("#url").focus();//URL获取输入焦点
|
||||
@@ -108,9 +107,18 @@ layui.use(['form','upload','miniTab'], function () {
|
||||
if(top.location == self.location){
|
||||
layer.msg('已更新!', {icon: 1});
|
||||
}else{
|
||||
parent.layui.table.reload('table');//刷新父页面的表格
|
||||
parent.layui.layer.msg('已更新!', {icon: 1});
|
||||
$('#close').click();//关闭子页面
|
||||
if(_GET('source') == 'tpl'){ //第三方调用时刷新父页面
|
||||
layer.msg('添加成功!', {icon: 1,time: 700,
|
||||
end: function() {
|
||||
parent.location.reload();
|
||||
$('#close').click();//关闭子页面
|
||||
}
|
||||
});
|
||||
}else{
|
||||
parent.layui.table.reload('table');//刷新父页面的表格
|
||||
parent.layui.layer.msg('已更新!', {icon: 1});
|
||||
$('#close').click();//关闭子页面
|
||||
}
|
||||
}
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
@@ -132,7 +140,9 @@ layui.use(['form','upload','miniTab'], function () {
|
||||
window.close(); //关闭当前页面
|
||||
}else{
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));//关闭当前页(内嵌窗口)
|
||||
miniTab.deleteCurrentByIframe(); //关闭当前标签(标签窗口)
|
||||
if(_GET('source') != 'tpl'){
|
||||
layui.miniTab.deleteCurrentByIframe(); //关闭当前标签(标签窗口)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -194,6 +204,28 @@ layui.use(['form','upload','miniTab'], function () {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//链接扩展上传图片
|
||||
upload.render({
|
||||
elem: '.extend_up_img'
|
||||
,url: get_api('write_link','extend_up_img')
|
||||
,exts: 'jpg|jpeg|png|ico|bmp|svg'
|
||||
,acceptMime: 'image/*'
|
||||
,accept: 'file'
|
||||
,size: 1024
|
||||
,done: function(res){
|
||||
if(res.code == 1){
|
||||
let inpu = this.item.closest('.layui-form-item').find('input[name^="_"]');
|
||||
inpu.val(res.url);
|
||||
}else{
|
||||
layer.msg(res.msg || '上传失败', {icon: 5});
|
||||
}
|
||||
},error: function(){
|
||||
layer.msg("上传异常,请刷新重试", {icon: 5});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//layui>end
|
||||
});
|
||||
|
||||
@@ -206,7 +238,7 @@ function preview_icon(icon =''){
|
||||
}else if(icon.substr(0,4) == '<svg'){
|
||||
$('#icon_img').attr('src','data:image/svg+xml;base64,'+ btoa(icon.replace(/[\u00A0-\u2666]/g, function(c) {return '&#' + c.charCodeAt(0) + ';';})) );
|
||||
}else{
|
||||
$('#icon_img').attr('src',icon + '?t=' + Math.random() ) ;
|
||||
$('#icon_img').attr('src',icon + (icon.indexOf('?') !== -1 ? '&_t=' : '?_t=') + Math.random() ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,9 +255,12 @@ function get_link_info() {
|
||||
if(data.data.description != null) {
|
||||
$("#description").val(data.data.description);
|
||||
}
|
||||
if(data.data.keywords != null) {
|
||||
$("#keywords").val(data.data.keywords);
|
||||
}
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
layer.close(load_index);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
var IDs = [];
|
||||
var api = get_api('read_link_list'); //列表接口
|
||||
var limit = localStorage.getItem(u + "_limit") || 50; //尝试读取本地记忆数据,没有就默认50
|
||||
var link_sort = JSON.parse(localStorage.getItem(u + "_link_sort")) || {field: 'lid', type: null };
|
||||
var pwds = [];
|
||||
miniTab.listen();
|
||||
//渲染表格
|
||||
@@ -24,11 +25,11 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var cols=[[ //表头
|
||||
var img_src;
|
||||
var cols=[ //表头
|
||||
{type:'checkbox'} //开启复选框
|
||||
,{field: 'lid', title: 'ID', width:80, sort: true,hide:false}
|
||||
,{field: 'category_name', title: '所属分类',sort:true,width:140,event: 'edit_category',templet:function(d){
|
||||
,{field: 'lid', title: 'ID', width:80, sort: true,hide:true}
|
||||
,{field: 'fid', title: '所属分类',sort:true,width:140,event: 'edit_category',templet:function(d){
|
||||
//检查是否存在,避免特殊情况报错
|
||||
if (categorys && categorys[d.fid] && categorys[d.fid].font_icon && categorys[d.fid].name) {
|
||||
return '<i class="' + categorys[d.fid].font_icon + '"></i> ' + categorys[d.fid].name;
|
||||
@@ -36,45 +37,68 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
return 'Null';
|
||||
}
|
||||
}}
|
||||
,{field: 'title', title: '链接标题', width:200, edit: 'text'}
|
||||
,{field: 'icon', title: '图标', width:60, templet:function(d){
|
||||
if(d.icon == null || d.icon == ""){
|
||||
return '<img src="./templates/admin/img/ie.svg" width="28" height="28">';
|
||||
}else{
|
||||
if(d.icon.substr(0,5) =='data:') {
|
||||
img_src = d.icon;
|
||||
}else if(d.icon.substr(0,4) == '<svg'){
|
||||
img_src = 'data:image/svg+xml;base64,'+ btoa(d.icon.replace(/[\u00A0-\u2666]/g, function(c) {return '&#' + c.charCodeAt(0) + ';';}));
|
||||
}else{
|
||||
img_src = d.icon + (d.icon.indexOf('?') !== -1 ? '&_t=' : '?_t=') + Date.now();
|
||||
}
|
||||
return '<img src="' + img_src + '" width="28" height="28">';
|
||||
}
|
||||
}}
|
||||
,{field: 'title', title: '链接标题',sort:true, width:200, edit: 'text'}
|
||||
,{ title:'操作', toolbar: '#tablebar',width:110}
|
||||
,{field:'pwd_id',title:'密码',width:70,templet: function(d){
|
||||
return d.pwd_id>0?'<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="pwd">查看</a>':'';
|
||||
}}
|
||||
return d.pwd_id>0?'<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="pwd">查看</a>':'';
|
||||
}}
|
||||
,{field: 'property', title: '私有', width: 100, sort: true,templet: function(d){
|
||||
return "<input type='checkbox' value='" + d.lid + "' lay-filter='property' lay-skin='switch' lay-text='私有|公开' " + (d.property == 1?"checked":"" )+ ">";
|
||||
}}
|
||||
,{field: 'status', title: '状态', width: 100, sort: true,templet: function(d){
|
||||
return "<input type='checkbox' value='" + d.lid + "' lay-filter='status' lay-skin='switch' lay-text='启用|禁用' " + (d.status == 1?"checked":"" )+ ">";
|
||||
}}
|
||||
,{field: 'url', title: 'URL',templet:function(d){
|
||||
return '<a color="" target = "_blank" href = "' + d.url + '" title = "' + d.url + '" referrerpolicy="same-origin" >' + d.url + '</a>';
|
||||
,{field: 'url',sort:true, title: 'URL',templet:function(d){
|
||||
return '<a color="" target = "_blank" href = "' + d.url + '" title = "' + d.url + '" referrerpolicy="same-origin" >' + d.url + '</a>';
|
||||
}}
|
||||
,{field: 'click', title: '点击数',width:90,sort:true}
|
||||
,{field: 'add_time', title: '添加时间', width:160, sort: true,templet:function(d){
|
||||
var add_time = timestampToTime(d.add_time);
|
||||
return add_time;
|
||||
var add_time = timestampToTime(d.add_time);
|
||||
return add_time;
|
||||
}}
|
||||
,{field: 'up_time', title: '修改时间', width:160,sort:true,templet:function(d){
|
||||
return d.up_time == null ?'':timestampToTime(d.up_time);
|
||||
}}
|
||||
]];
|
||||
];
|
||||
//读取列筛选
|
||||
var local = layui.data('table-filter-link-list');
|
||||
layui.each(cols, function(index, item){
|
||||
if(item.field in local){
|
||||
item.hide = local[item.field];
|
||||
}
|
||||
});
|
||||
|
||||
//渲染表格函数
|
||||
var renderTable2 = function () {
|
||||
where = link_sort.type === null ? {} : {field:link_sort.field,order:link_sort.type.toUpperCase()};
|
||||
table.render({
|
||||
elem: '#table'
|
||||
,height: 'full-110' //自适应高度
|
||||
,url: api //数据接口
|
||||
,where: where
|
||||
,page: true //开启分页
|
||||
,limit:limit //默认每页显示行数
|
||||
,limits: [20,50,100,300,500]
|
||||
,even:true //隔行背景色
|
||||
,loading:true //加载条
|
||||
//,defaultToolbar:false
|
||||
,toolbar: '#toolbar'
|
||||
,id:'table'
|
||||
,cols: cols
|
||||
,initSort: link_sort
|
||||
,cols: [cols]
|
||||
,method: 'post'
|
||||
,response: {statusCode: 1 }
|
||||
,done: function (res, curr, count) {
|
||||
@@ -90,10 +114,9 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
$("[data-field='add_time']").addClass('layui-hide-xs');
|
||||
$("[data-field='up_time']").addClass('layui-hide-xs');
|
||||
$("[data-field='click']").addClass('layui-hide-xs');
|
||||
//$(".layui-laypage .layui-laypage-count").css("padding-left","35px");
|
||||
$(".layui-laypage .layui-laypage-prev").addClass('layui-hide-xs');
|
||||
$(".layui-laypage .layui-laypage-curr").addClass('layui-hide-xs');
|
||||
$(".layui-laypage .layui-laypage-next").addClass('layui-hide-xs');
|
||||
// $(".layui-laypage .layui-laypage-prev").addClass('layui-hide-xs');
|
||||
// $(".layui-laypage .layui-laypage-curr").addClass('layui-hide-xs');
|
||||
// $(".layui-laypage .layui-laypage-next").addClass('layui-hide-xs');
|
||||
$(".layui-laypage .layui-laypage-skip").addClass('layui-hide-xs');
|
||||
$(".layui-table-tool-self").addClass('layui-hide-xs');
|
||||
//加载加密分组数据
|
||||
@@ -105,23 +128,36 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
}
|
||||
}
|
||||
});
|
||||
//记忆列筛选
|
||||
var that = this;
|
||||
that.elem.next().on('mousedown', 'input[lay-filter="LAY_TABLE_TOOL_COLS"]+', function(){
|
||||
var input = $(this).prev()[0];
|
||||
layui.data('table-filter-link-list', {
|
||||
key: input.name,value: input.checked
|
||||
});
|
||||
});
|
||||
$('th[data-field="icon"]').attr('title', '仅显示已上传的图标');
|
||||
}
|
||||
});
|
||||
// 监听表格排序事件
|
||||
table.on('sort(table)', function(obj) {
|
||||
link_sort = {field:obj.field,type:obj.type};
|
||||
localStorage.setItem(u + "_link_sort",JSON.stringify(link_sort));
|
||||
link_search();
|
||||
});
|
||||
};
|
||||
|
||||
function link_search(){
|
||||
var fid = document.getElementById("fid").value;
|
||||
var keyword = document.getElementById("link_keyword").value;//获取输入内容
|
||||
var property = document.getElementById("property").value;
|
||||
var status = document.getElementById("status").value;
|
||||
let data = form.val('form');
|
||||
if(link_sort.type != null){
|
||||
data.field = link_sort.field;
|
||||
data.order = link_sort.type.toUpperCase();
|
||||
}
|
||||
table.reload('table', {
|
||||
url: api
|
||||
,method: 'post'
|
||||
,request: {
|
||||
pageName: 'page' //页码的参数名称
|
||||
,limitName: 'limit' //每页数据量的参数名
|
||||
}
|
||||
,where: {query:keyword,fid:fid,property:property,status:status}
|
||||
,request: {pageName: 'page',limitName: 'limit'}
|
||||
,where: data
|
||||
,page: {curr: 1}
|
||||
});
|
||||
}
|
||||
@@ -186,7 +222,8 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
var current = 0 ,fail = 0 ,INDEX = 0;
|
||||
var testapi = get_api('other_testing_link');
|
||||
var div = "div[lay-id='table'] .layui-table-main table tbody tr";
|
||||
layer.load(2, {shade: [0.1,'#fff']});//加载层
|
||||
layer.load(1, {shade: [0.5,'#fff']});//加载层
|
||||
layer.msg('正在检测死链接中,请稍后...', {icon: 16,time: 1000*300});
|
||||
$("#testing_tip").show();//显示进度提示
|
||||
layer.close(open_index); //关闭小窗口
|
||||
layer.tips("正在检测中,请勿操作页面...","#testing_tip",{tips: [3, "#3595CC"],time: 9000});
|
||||
@@ -195,7 +232,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
//未勾选的跳过
|
||||
if(trs[i].LAY_CHECKED != true){continue;}
|
||||
$.post(testapi,{url:trs[i].url},function(re,status){
|
||||
INDEX = trs[i].LAY_TABLE_INDEX; //行索引
|
||||
INDEX = trs[i].LAY_INDEX; //行索引
|
||||
if(re.StatusCode == 200 || re.StatusCode == 301 || re.StatusCode == 302 ){
|
||||
$("div[lay-id='table'] td .layui-form-checkbox").eq(INDEX).click();//正常的取消勾选
|
||||
if (re.StatusCode == 200){
|
||||
@@ -234,27 +271,43 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
}
|
||||
})
|
||||
}else if(event === 'icon_pull'){
|
||||
let i = 0;
|
||||
let total = checkStatus.data.length;
|
||||
layer.load(1, {shade:[0.3,'#fff']});//加载层
|
||||
let msg_id = layer.msg('正在拉取中', {icon: 16,time: 1000*300});
|
||||
icon_pull(i);
|
||||
function icon_pull(id){
|
||||
if(i >= total){
|
||||
layer.closeAll();
|
||||
layer.alert('拉取完毕',{icon:1,title:'信息',anim: 2,shadeClose: false,closeBtn: 0});
|
||||
return true;
|
||||
}
|
||||
$("#layui-layer"+ msg_id+" .layui-layer-padding").html('<i class="layui-layer-ico layui-layer-ico16"></i>[ ' + i + ' / ' + total + ' ] 正在拉取图标');
|
||||
$.post(get_api('write_link','icon_pull'),{id:checkStatus.data[i].lid},function(data,status){
|
||||
if(data.code == 1){
|
||||
layer.alert('存在链接图标时如何处理 ?', {icon: 3, title:'请选择',btn: ['保持原样', '重新拉取', '取消'],
|
||||
btnAlign: 'c',
|
||||
btn1: function(){icon_pull_test('0')}, //跳过
|
||||
btn2: function(){icon_pull_test('1')} //覆盖
|
||||
});
|
||||
function icon_pull_test(cover){
|
||||
let i = 0;
|
||||
let success = 0;
|
||||
let skip = 0;
|
||||
let fail = 0;
|
||||
let total = checkStatus.data.length;
|
||||
layer.load(1, {shade:[0.5,'#fff']});//加载层
|
||||
let msg_id = layer.msg('正在拉取中', {icon: 16,time: 1000*300});
|
||||
icon_pull(i);
|
||||
function icon_pull(id){
|
||||
if(i >= total){
|
||||
layer.closeAll();
|
||||
layer.alert('总计:' + total +',成功:' + success + ',失败:'+ fail + (skip > 0 ? (',跳过:' + skip):'' ),{icon:1,title:'信息',anim: 2,shadeClose: false,closeBtn: 0});
|
||||
return true;
|
||||
}
|
||||
$("#layui-layer"+ msg_id+" .layui-layer-padding").html('<i class="layui-layer-face layui-icon layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>[ ' + i + ' / ' + total + ' ] 正在拉取图标');
|
||||
$.post(get_api('write_link','icon_pull'),{id:checkStatus.data[i].lid,cover:cover},function(data,status){
|
||||
if(data.msg == 'success'){
|
||||
success ++;
|
||||
}else if(data.msg == 'fail'){
|
||||
fail ++;
|
||||
}else if(data.msg == 'skip'){
|
||||
skip ++;
|
||||
}else{
|
||||
layer.closeAll();
|
||||
layer.alert(data.msg,{icon:2,title:'信息',anim: 2,shadeClose: false,closeBtn: 0});
|
||||
return true;
|
||||
}
|
||||
i ++;
|
||||
icon_pull(i);
|
||||
} else{
|
||||
layer.closeAll();
|
||||
layer.alert(data.msg,{icon:5,title:'信息',anim: 2,shadeClose: false,closeBtn: 0});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}else if(event === 'link_extend'){
|
||||
extend_data = '';
|
||||
@@ -267,8 +320,44 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
layer.msg(data.msg);
|
||||
}
|
||||
});
|
||||
}else if(event === 'msg_pull'){
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '批量识别链接信息',area : ['100%', '100%'],content: $('.msg_pull')});
|
||||
}
|
||||
});
|
||||
|
||||
$('#start_pull').click(function () {
|
||||
let lits = table.checkStatus('table').data; console.log( lits );
|
||||
let config = form.val('msg_pull');
|
||||
let number = 0;
|
||||
let total = lits.length;
|
||||
let load_id = layer.load(1, {shade:[0.5,'#fff']});//加载层
|
||||
let msg_id = layer.msg('正在识别中', {icon: 16,time: 1000*300}); //进度提示
|
||||
//检查是否满足条件
|
||||
$.post(get_api('write_link','msg_pull_check'),config,function(data,status){
|
||||
if(data.code == 1){
|
||||
config.key = data.key;
|
||||
start_pull(number); //开始拉取
|
||||
}else{
|
||||
layer.alert(data.msg || '未知错误',{icon:5,title:'错误',anim: 2,closeBtn: 0,btn: ['刷新页面']},function () {location.reload();});
|
||||
}
|
||||
});
|
||||
function start_pull(number){
|
||||
if(number >= total){
|
||||
layer.closeAll();
|
||||
layer.alert('处理完毕,请刷新页面!' ,{icon:1,title:'提示',anim: 2,shadeClose: false,closeBtn: 0});
|
||||
return true;
|
||||
}
|
||||
$("#layui-layer"+ msg_id+" .layui-layer-padding").html('<i class="layui-layer-face layui-icon layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>[ ' + number + ' / ' + total + ' ] 正在处理中..');
|
||||
config.link_id = lits[number].lid;
|
||||
$.post(get_api('write_link','msg_pull'),config,function(data,status){
|
||||
number ++;
|
||||
start_pull(number);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
table.render({
|
||||
elem: '#link_extend_list'
|
||||
@@ -287,6 +376,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
,{field:'name',title:'字段名',edit:'text',width:256}
|
||||
,{field:'type',title:'类型',edit:'text',width:256}
|
||||
,{field:'default',title:'默认值',edit:'text',width:256}
|
||||
,{field:'tip',title:'提示内容',edit:'text',width:256}
|
||||
,{ title:'操作',toolbar:'#link_extend_toolbar',align:'center',width:118}
|
||||
]]
|
||||
});
|
||||
@@ -441,7 +531,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
"title": "请输入标题",
|
||||
"name":"请输入字段名(大小写字母或数字)",
|
||||
"weight":(max_weight + 1),
|
||||
"type":"请输入 text 或 textarea",
|
||||
"type":"请输入 text 或 textarea 或 up_img",
|
||||
"default":""
|
||||
});
|
||||
table.reload('link_extend_list', {data: data});
|
||||
@@ -453,7 +543,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
var tableBak = table.cache.link_extend_list;
|
||||
for (var i = 0; i < tableBak.length; i++) {
|
||||
//过滤掉被删除的空数据
|
||||
if(typeof tableBak[i].LAY_TABLE_INDEX == 'number'){
|
||||
if(typeof tableBak[i].LAY_INDEX == 'number'){
|
||||
data.push(tableBak[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ layui.use(['form','table'], function () {
|
||||
//行点击事件
|
||||
table.on('row(table)', function(obj) {
|
||||
obj.tr.addClass('layui-bg-black').siblings().removeClass('layui-bg-black');
|
||||
obj.tr.find('i[class="layui-anim layui-icon"]').trigger("click");
|
||||
obj.tr.find('i[class="layui-anim layui-icon layui-icon-circle"]').trigger("click");
|
||||
});
|
||||
|
||||
//监听工具栏
|
||||
|
||||
@@ -72,7 +72,8 @@ function theme_download(dir,name,desc,fn){
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
setTimeout(() => {location.reload();}, 500);//延迟刷新
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
//layer.msg(data.msg, {icon: 5});
|
||||
layer.alert(data.msg,{icon:5,title:"错误",anim: "slideDown",shadeClose: true,closeBtn: 0,btn: ['知道了']});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ $tip = $verify_type == 'link_pwd'?'请输入链接密码':'请输入分类密码
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Layui/v2.8.3/css/layui.css">
|
||||
<link rel="stylesheet" href="<?php echo $layui['css']; ?>">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Other/login.css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo $libs?>/Other/html5.min.js"></script>
|
||||
@@ -45,7 +45,7 @@ $tip = $verify_type == 'link_pwd'?'请输入链接密码':'请输入分类密码
|
||||
<?php echo $copyright.( !empty($ICP)?'<span class="padding-5">|</span>':'').$ICP; ?>
|
||||
</div>
|
||||
<script src = "<?php echo $libs?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "<?php echo $libs?>/Layui/v2.8.3/layui.js"></script>
|
||||
<script src = "<?php echo $layui['js']; ?>"></script>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
|
||||
<script>
|
||||
layui.use(['form','jquery'], function () {
|
||||
|
||||
@@ -12,7 +12,7 @@ $tip ='请输入二级密码';
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Layui/v2.8.3/css/layui.css">
|
||||
<link rel="stylesheet" href="<?php echo $layui['css']; ?>">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Other/login.css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo $libs?>/Other/html5.min.js"></script>
|
||||
@@ -45,7 +45,7 @@ $tip ='请输入二级密码';
|
||||
<?php echo $copyright.( !empty($ICP)?'<span class="padding-5">|</span>':'').$ICP; ?>
|
||||
</div>
|
||||
<script src = "<?php echo $libs?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "<?php echo $libs?>/Layui/v2.8.3/layui.js"></script>
|
||||
<script src = "<?php echo $layui['js']; ?>"></script>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
|
||||
<script>
|
||||
layui.use(['form','jquery'], function () {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Layui/v2.8.3/css/layui.css">
|
||||
<link rel="stylesheet" href="<?php echo $layui['css']; ?>">
|
||||
<link rel="stylesheet" href="<?php echo $libs?>/Other/login.css">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo $libs?>/Other/html5.min.js"></script>
|
||||
@@ -43,7 +43,7 @@
|
||||
<?php echo $copyright.( !empty($ICP)?'<span class="padding-5">|</span>':'').$ICP; ?>
|
||||
</div>
|
||||
<script src = "<?php echo $libs?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "<?php echo $libs?>/Layui/v2.8.3/layui.js"></script>
|
||||
<script src = "<?php echo $layui['js']; ?>"></script>
|
||||
<script>
|
||||
layui.use(['form','jquery'], function () {
|
||||
var $ = layui.jquery,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
@@ -19,7 +19,7 @@ layui.use(['form','table'], function () {
|
||||
var form = layui.form;
|
||||
var api = get_api('read_login_info'); //列表接口
|
||||
var limit = localStorage.getItem(u + "_limit") || 50; //尝试读取本地记忆数据,没有就默认50
|
||||
|
||||
var current_id = 0;
|
||||
var cols=[[ //表头
|
||||
{field: 'id', title: 'ID', width:60, sort: true,hide:true}
|
||||
,{ title: '操作',toolbar: '#tablebar',width:70}
|
||||
@@ -31,7 +31,7 @@ layui.use(['form','table'], function () {
|
||||
return timestampToTime(d.last_time);;
|
||||
}}
|
||||
,{field: 'expire_time', title: '到期时间', width:160, sort: true,templet:function(d){
|
||||
return timestampToTime(d.expire_time);;
|
||||
return d.expire_time <= 0 ? '':timestampToTime(d.expire_time);
|
||||
}}
|
||||
,{field: 'ua', title: '浏览器UA'}
|
||||
]]
|
||||
@@ -50,24 +50,47 @@ layui.use(['form','table'], function () {
|
||||
,method: 'post'
|
||||
,response: {statusCode: 1 }
|
||||
,done: function (res, curr, count) {
|
||||
current_id = res.current_id;
|
||||
var temp_limit = $(".layui-laypage-limits option:selected").val();
|
||||
if(temp_limit > 0 && localStorage.getItem(u + "_limit") != temp_limit){
|
||||
localStorage.setItem(u + "_limit",temp_limit);
|
||||
}
|
||||
//遍历表格数据,标记当前设备
|
||||
layui.each(table.cache.table, function(index, item){
|
||||
if(item.id == res.current_id){
|
||||
let tr = $('.layui-table-body.layui-table-main tr[data-index="' + index + '"]');
|
||||
tr.css('color', 'red');
|
||||
tr.attr('title','当前设备');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
table.on('tool(table)', function (obj) {
|
||||
var data = obj.data;
|
||||
if (obj.event === 'out') {
|
||||
$.post(get_api('write_login_info','out'),{id:data.id},function(data,status){
|
||||
if(data.code == 1) {
|
||||
obj.del();
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
if(data.id == current_id ){
|
||||
$.post('./index.php?c=admin&page=logout&u='+u,function(res,status){
|
||||
if(res.code == 1) {
|
||||
layer.alert("您已安全的退出登录!", function () {
|
||||
top.location.href='./index.php?u='+u;
|
||||
});
|
||||
}else{
|
||||
layer.msg(res.msg,{icon: 5});
|
||||
}
|
||||
});
|
||||
}else{
|
||||
$.post(get_api('write_login_info','out'),{id:data.id},function(res,status){
|
||||
if(res.code == 1) {
|
||||
obj.del();
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(res.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php $title='安全设置'; require 'header.php'; ?>
|
||||
<?php $title='安全设置'; require 'header.php';
|
||||
$LoginConfig = unserialize($USER_DB['LoginConfig']);
|
||||
$LoginConfig['totp_key'] = empty($LoginConfig['totp_key']) ? '0':'1';?>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
@@ -83,10 +85,9 @@
|
||||
<select name="api_model">
|
||||
<option value="security" selected>安全模式</option>
|
||||
<option value="compatible">兼容模式</option>
|
||||
<option value="compatible+open">兼容模式+开放</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">部分主题和插件需设为兼容+开放模式 <a href="javascript:;" layuimini-content-href="Token" data-title="Token"><font color="red"> 获取API ( Token )</font></a></div>
|
||||
<div class="layui-form-mid layui-word-aux">部分主题和插件需设为兼容 <a href="javascript:;" layuimini-content-href="Token" data-title="Token"><font color="red"> 获取API ( Token )</font></a></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -110,14 +111,58 @@
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block"><button class="layui-btn layui-btn-normal" lay-submit lay-filter="save">确认保存</button></div>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save">确认保存</button>
|
||||
<button class="layui-btn layui-bg-purple" lay-submit lay-filter="open_totp">OTP 双重验证</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="ul_totp" style="margin-top:18px;display:none;padding-right: 10px;">
|
||||
<form class="layui-form" lay-filter="ul_totp">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">二维码</label>
|
||||
<div id="qr"></div><div id="qrcode"></div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">秘钥</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="key" id="key" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">为了您的账户安全,成功保存后无法再查看秘钥,请勿泄漏秘钥</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">验证码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="code" id="code" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">请输入生成的验证码</div>
|
||||
</div>
|
||||
|
||||
<pre class="layui-code" >
|
||||
这东西叫法太多了,比如双重验证/动态密码/动态口令/动态令牌/身份验证器/双因子认证/2FA/TOTP验证码等等
|
||||
原理是基于时间的动态验证码,网上客户端也大把,喜欢那个安装那个
|
||||
开启后登录时需输入OTP验证码,作用是提高账号安全性
|
||||
</pre>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-warm" type="button" id="close" >关闭</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save_totp" id="save_totp">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</ul>
|
||||
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery.md5.js"></script>
|
||||
<script src = "<?php echo $libs; ?>/jquery/jquery.qrcode.min.js"></script>
|
||||
<script src = "./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<?php load_static('js');?>
|
||||
<script>
|
||||
@@ -127,9 +172,9 @@ layui.use(['jquery','form','miniTab'], function () {
|
||||
miniTab = layui.miniTab;
|
||||
miniTab.listen();
|
||||
//表单赋值
|
||||
form.val('form', <?php echo json_encode(unserialize( $USER_DB['LoginConfig'] ));?>);
|
||||
form.val('form', <?php echo json_encode($LoginConfig);?>);
|
||||
|
||||
//监听提交
|
||||
//保存
|
||||
form.on('submit(save)', function (data) {
|
||||
$("*").blur(); //失去焦点,解决按回车无限提交
|
||||
data.field.Password=$.md5(data.field.Password);
|
||||
@@ -137,7 +182,7 @@ layui.use(['jquery','form','miniTab'], function () {
|
||||
if(data.code == 1) {
|
||||
var index = layer.alert("保存成功!", function () {
|
||||
layer.close(index);
|
||||
//miniTab.deleteCurrentByIframe();
|
||||
//miniTab.deleteCurrentByIframe(); //关闭页面
|
||||
});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
@@ -145,6 +190,69 @@ layui.use(['jquery','form','miniTab'], function () {
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//双重验证
|
||||
form.on('submit(open_totp)', function (data) {
|
||||
$("*").blur(); //失去焦点,解决按回车无限提交
|
||||
data.field.Password=$.md5(data.field.Password);
|
||||
pwd_md5 = data.field.Password;
|
||||
$.post(get_api('read_totp'),data.field,function(data,status){
|
||||
if(data.code == 1){
|
||||
layer.confirm('已开启双重验证,是否要关闭?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
layer.closeAll();
|
||||
$.post(get_api('write_totp','delete'),{'Password':pwd_md5},function(data,status){
|
||||
if(data.code == 1) {
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
}else if(data.code == 2) {
|
||||
layer.confirm('未开启双重验证,是否要开启?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
layer.closeAll();
|
||||
$('#key').val(data.key);
|
||||
$('#code').val('');
|
||||
$("#qr").html('');//防止多次操作出现多个二维码
|
||||
let content = `otpauth://totp/${u}?secret=${data.key}&issuer=TwoNav`;
|
||||
$('#qr').qrcode({render: "canvas",width: 200,height: 200,text: content});
|
||||
var index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '双重验证',area : ['100%', '100%'],content: $('.ul_totp')});
|
||||
});
|
||||
return false;
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#key').on('input', function() {
|
||||
$("#key").html('');
|
||||
let key = $('#key').val();
|
||||
let content = `otpauth://totp/${u}?secret=${key}&issuer=TwoNav`;
|
||||
$("#qr").html('');
|
||||
$('#qr').qrcode({render: "canvas",width: 200,height: 200,text: content});
|
||||
});
|
||||
//保存双重验证
|
||||
form.on('submit(save_totp)', function (data) {
|
||||
$("*").blur(); //失去焦点,解决按回车无限提交
|
||||
data.field.Password = pwd_md5;
|
||||
$.post(get_api('write_totp','set'),data.field,function(data,status){
|
||||
if(data.code == 1) {
|
||||
layer.closeAll();
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//关闭页面
|
||||
$(document).on('click', '#close', function() {
|
||||
layer.closeAll();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -69,45 +69,35 @@
|
||||
<label class="layui-form-label">链接图标</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="link_icon">
|
||||
<option value="0" selected>离线图标</option>
|
||||
<!--<option value="1" >本地服务(支持缓存)</option>-->
|
||||
<option value="0" selected>离线图标(首字图标)</option>
|
||||
<option value="20" >本地服务</option>
|
||||
<option value="21" >本地服务(伪静态)</option>
|
||||
<option value="2" >favicon.png.pub (小图标)</option>
|
||||
<option value="4" >api.15777.cn</option>
|
||||
<option value="5" >favicon.cccyun.cc</option>
|
||||
<!--<option value="4" >api.15777.cn</option>-->
|
||||
<!--<option value="5" >favicon.cccyun.cc</option>-->
|
||||
<option value="6" >api.iowen.cn</option>
|
||||
<!--<option value="7" >toolb.cn</option>-->
|
||||
<!--<option value="8" >apis.jxcxin.cn</option>-->
|
||||
<!--<option value="9" >ico.kucat.cn</option>-->
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">所有API接口均由其他大佬提供!若有异常请尝试更换接口!</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">热门网址</label>
|
||||
<label class="layui-form-label">最新网址</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="top_link">
|
||||
<option value="0" selected>不显示</option>
|
||||
<option value="5" >显示5条</option>
|
||||
<option value="10" >显示10条</option>
|
||||
<option value="15" >显示15条</option>
|
||||
<option value="20" >显示20条</option>
|
||||
</select>
|
||||
<input type="number" name="new_link" class="layui-input" value="0" placeholder="输入范围: 0-100" lay-verify="required">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">在主页显示热门网址(点击排行)</div>
|
||||
<div class="layui-form-mid layui-word-aux">在主页显示最新的网址(创建时间)</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">最新网址</label>
|
||||
<label class="layui-form-label">热门网址</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="new_link">
|
||||
<option value="0" selected>不显示</option>
|
||||
<option value="5" >显示5条</option>
|
||||
<option value="10" >显示10条</option>
|
||||
<option value="15" >显示15条</option>
|
||||
<option value="20" >显示20条</option>
|
||||
</select>
|
||||
<input type="number" name="top_link" class="layui-input" value="0" placeholder="输入范围: 0-100" lay-verify="required">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">在主页显示最新的网址(创建时间)</div>
|
||||
<div class="layui-form-mid layui-word-aux">在主页显示热门网址(点击排行)</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
|
||||
@@ -3,8 +3,46 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<div class="layui-form layuimini-form layui-form-pane">
|
||||
<blockquote class="layui-elem-quote layui-text" style="">注意: Token(令牌),是您访问API的凭证 (不了解&不需要请勿设置) ,等同于您的账号密码,请妥善保管</blockquote>
|
||||
<div class="layui-form-item">
|
||||
|
||||
<div class="layui-collapse" lay-accordion>
|
||||
<div class="layui-colla-item" >
|
||||
<div class="layui-colla-title">注意事项</div>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<blockquote class="layui-elem-quote layui-text" style="">Token(令牌),是您访问API的凭证 (不了解&不需要请勿设置) ,等同于您的账号密码,请妥善保管</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<div class="layui-colla-title">API模式的差别</div>
|
||||
<div class="layui-colla-content">
|
||||
<p>安全模式: 仅提供TwoNav自身的API接口,不兼容Onenav的API接口!</p>
|
||||
<p>兼容模式: 兼容部分OneNav的API接口,以便于其他插件调用!不支持访客调用!</p>
|
||||
<p>如果你未使用相关扩展插件,则无需修改模式并将Token删除,以提高账号的安全性!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<div class="layui-colla-title">如何使用Chrome浏览器扩展 [非官方]</div>
|
||||
<div class="layui-colla-content">
|
||||
前言: 由于浏览器扩展插件非TwoNav所开发适配,如存在Bug或无法使用属正常现象!<br />
|
||||
安装: 谷歌应用商店下载<a href="https://chrome.google.com/webstore/detail/onenav/omlkjgkogkfpjbdigianpdbjncdchdco?hl=zh-CN&authuser=0" >OneNav</a>并安装 ( 已知0.9.24 - 1.0.1可用,其他版本未知 )<br />
|
||||
设置S: 1.TwoNav后台>右上角账号>安全设置>API模式>设为<兼容模式> 2.在本页面获取Token<br />
|
||||
设置C: 插件API设置>填入域名和Token并保存>完成<br />
|
||||
问题1: 对于单用户使用,确保系统设置中默认用户是当前用户即可!多用户使用时需开启二级域名功能并将域名替换成用户的二级域名,注意结尾不需要带/
|
||||
问题2: 因为插件非官方开发维护,能用就尽量不要更新,如果插件更新可能会导致无法正常使用,需这个更新获得兼容性!
|
||||
问题3: 因为国内环境限制,你可能无法访问谷歌,这种情况你可以在交流群获取插件(安装方法自行百度,部分浏览器可能需要开发者模式加载)
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-colla-item">
|
||||
<div class="layui-colla-title">如何使用uTools扩展插件 [非官方]</div>
|
||||
<div class="layui-colla-content">
|
||||
<p>前言: 由于uTools扩展插件非TwoNav所开发适配,如存在Bug或无法使用属正常现象!</p>
|
||||
<p>安装: 在uTools插件应用市场>搜索OneNav>点击获取 </p>
|
||||
<p>设置S: 1.TwoNav后台>右上角账号>安全设置>API模式>设为<兼容模式> 2.在本页面获取SecretKey ( 即插件设置中的API KEY )</p>
|
||||
<p>设置C: 打开uTools中的OneNav,点击右下角小齿轮>输入网站地址/用户名/API KEY</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="margin-top: 15px;">
|
||||
<label class="layui-form-label required">登录密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="Password" lay-verify="required" lay-reqtext="请输入登录密码" placeholder="请输入登录密码" class="layui-input">
|
||||
@@ -29,6 +67,7 @@
|
||||
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="delete">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<?php $title='添加链接'; require 'header.php'; ?>
|
||||
<style>
|
||||
.layui-textarea {min-height: 70px;}
|
||||
body {
|
||||
margin: 0px 0px 0px 0px;
|
||||
background: bottom;
|
||||
}
|
||||
margin: 0px 0px 0px 0px;
|
||||
background: bottom;
|
||||
}
|
||||
.layui-textarea {min-height: 70px;}
|
||||
.layui-form-select dl {max-height: 190px;}
|
||||
</style>
|
||||
<div class="layuimini-container" style="height: 420px;">
|
||||
<div class="layuimini-main" style=" margin-left: 0px; ">
|
||||
<form class="layui-form layuimini-form">
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main" style="margin-left: 0px;">
|
||||
<form class="layui-form layuimini-form" style="padding-bottom: 20px;">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required" >URL</label>
|
||||
@@ -40,11 +41,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关键字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="keywords" name="keywords" placeholder="可留空" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="description" id="description" placeholder="请输入内容" class="layui-textarea"></textarea>
|
||||
<textarea name="description" id="description" placeholder="可留空" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<meta name="HandheldFriendly" content="true">
|
||||
<title>快速添加</title>
|
||||
<link rel="stylesheet" type="text/css" href="./templates/admin/css/add_quick_tpl.css" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo $libs?>/Layui/v2.8.3/css/layui.css" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo $layui['css']; ?>" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="quick-main">
|
||||
@@ -35,7 +35,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<script src="<?php echo $libs?>/jquery/jquery-3.6.0.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="<?php echo $libs?>/Layui/v2.8.3/layui.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="<?php echo $layui['js']; ?>" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
var u = '<?php echo $u?>';
|
||||
var Auto_Off = Get('Auto_Off');
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
|
||||
@@ -110,7 +110,8 @@
|
||||
<button class="layui-btn layui-btn-disabled" lay-submit lay-filter="imp_link">开始导入</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<?php if(!preg_match('/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i',$_SERVER['HTTP_USER_AGENT'])){ ?>
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>一键添加</legend></fieldset>
|
||||
<blockquote class="layui-elem-quote" style="margin-top: 10px;border-left: 5px solid #5FB878; color: #333;">1.按需选择参数 > 将下方蓝色的「一键添加」拖拽到浏览器书签栏(收藏夹)<br />2.点击书签栏中的一键添加,即可将正在浏览的页面快速添加到TwoNav</blockquote>
|
||||
<form class="layui-form layui-form-pane" id="one">
|
||||
@@ -163,6 +164,7 @@
|
||||
<a class="layui-btn layui-btn-primary layui-border-blue" style="cursor:pointer;color: #1e9fff;" title="将此链接拖拽到书签栏" id="one-click-add" href=''>一键添加</a>
|
||||
</div>
|
||||
</form>
|
||||
<?php }?>
|
||||
<!--书签导出-->
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>书签导出</legend></fieldset>
|
||||
<blockquote class="layui-elem-quote" style="margin-top: 30px;">
|
||||
@@ -173,7 +175,7 @@
|
||||
</blockquote>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>本地备份 (订阅可用)</legend></fieldset>
|
||||
<blockquote class="layui-elem-quote" style="margin-top: 10px;border-left: 2px solid #FF5722; color: #FF5722;">1.备份数据库仅保存最近20份数据<br />2.该功能仅辅助备份使用,无法确保100%数据安全,因此定期对整个站点打包备份仍然是必要的</blockquote>
|
||||
<blockquote class="layui-elem-quote" style="margin-top: 10px;border-left: 2px solid #FF5722; color: #FF5722;">1.备份数据库仅保存最近20份数据<br />2.该功能仅辅助备份使用,无法确保100%数据安全,因此定期对整个站点打包备份仍然是必要的<br />3.不支持将新版本备份回滚到旧版本中,不建议跨数据库类型回滚</blockquote>
|
||||
<!-- 数据表格 -->
|
||||
<table class="layui-hide" id="list" lay-filter="list"></table>
|
||||
<!--本地备份备注输入-->
|
||||
@@ -226,13 +228,15 @@
|
||||
</blockquote>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block" style="margin-left: 32px;">
|
||||
<input type="checkbox" name="TABLE[user_categorys]" title="分类" checked="">
|
||||
<input type="checkbox" name="TABLE[user_links]" title="链接" checked="">
|
||||
<input type="checkbox" name="TABLE[user_pwd_group]" title="加密" checked="">
|
||||
<input type="checkbox" name="TABLE[user_share]" title="分享" checked="">
|
||||
<input type="checkbox" name="TABLE[user_apply]" title="收录" checked="">
|
||||
<input type="checkbox" name="FILE[MessageBoard]" title="留言" checked="">
|
||||
<input type="checkbox" name="FILE[favicon]" title="图标" checked="">
|
||||
<input type="checkbox" name="TABLE[user_categorys]" title="分类" checked>
|
||||
<input type="checkbox" name="TABLE[user_links]" title="链接" checked>
|
||||
<input type="checkbox" name="TABLE[user_pwd_group]" title="加密" checked>
|
||||
<input type="checkbox" name="TABLE[user_share]" title="分享" checked>
|
||||
<input type="checkbox" name="TABLE[user_apply]" title="收录" checked>
|
||||
<input type="checkbox" name="TABLE[user_article_list]" title="文章" checked>
|
||||
<input type="checkbox" name="FILE[MessageBoard]" title="留言" checked>
|
||||
<input type="checkbox" name="FILE[favicon]" title="图标" checked>
|
||||
<input type="checkbox" name="FILE[upload]" title="上传目录(如文章图片)" checked>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
@@ -386,7 +390,7 @@ layui.use(['layer','element','upload','form','table'], function(){
|
||||
|
||||
//数据清空>弹窗
|
||||
$('#data_empty').on('click', function(){
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '数据清空',area : ['500px', '300px'],content: $('.data_empty')});
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '数据清空',area : ['auto', '300px'],content: $('.data_empty')});
|
||||
});
|
||||
//数据清空>确定
|
||||
form.on('submit(define_data_empty)', function(data){
|
||||
@@ -465,7 +469,7 @@ layui.use(['layer','element','upload','form','table'], function(){
|
||||
,response: {statusCode: 1 }
|
||||
,cols: [[
|
||||
{width:60, type:'numbers', title: '序号'}
|
||||
,{field:'name', title:'数据库文件名 / 备注',templet:function(d){
|
||||
,{field:'name', title:'数据库文件名 / 备注',minWidth:400,templet:function(d){
|
||||
if(d.desc != '' && d.desc != null){
|
||||
return d.name + '  [ ' + d.desc+' ]';
|
||||
}else{
|
||||
@@ -475,7 +479,7 @@ layui.use(['layer','element','upload','form','table'], function(){
|
||||
,{ width:180, title: '备份时间',templet:function(d){
|
||||
return timestampToTime(d.backup_time);
|
||||
}}
|
||||
,{field:'size', width:80, title: '大小',templet:function(d){return bytesToSize(d.db_size + d.tar_size);}}
|
||||
,{field:'size', width:100, title: '大小',templet:function(d){return bytesToSize(d.db_size + d.tar_size);}}
|
||||
,{width:70, title: '分类',templet:function(d){return d.user_categorys.count;}}
|
||||
,{width:80, title: '链接',templet:function(d){return d.user_links.count;}}
|
||||
,{width:160, title:'操作', toolbar: '#tooloption'}
|
||||
|
||||
@@ -20,7 +20,7 @@ $title='收录管理';$awesome=true; require dirname(__DIR__).'/header.php';
|
||||
<script type="text/html" id="link_operate">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="operation">操作 <i class="layui-icon layui-icon-down"></i></a>
|
||||
</script>
|
||||
<table id="apply_list" class="layui-table" lay-filter="apply_list" style="margin: -3px 0;"></table>
|
||||
<table id="apply_list" class="layui-table" lay-filter="apply_list" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!--设置-->
|
||||
@@ -43,13 +43,29 @@ $title='收录管理';$awesome=true; require dirname(__DIR__).'/header.php';
|
||||
<textarea name = "Notice" placeholder="显示在收录页的公告使用HTML代码编写(如有拦截提示,请暂时关闭防XSS脚本和防SQL注入)" rows = "5" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">提交限制</label>
|
||||
<div class="layui-input-inline" style=" width: 71px;">
|
||||
<input type="number" name="submit_limit" lay-verify="required" placeholder='单位:秒' value="10" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:次,指最近24小时内可以提交多少次(为了防止恶意提交,删除记录可以恢复次数)</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">必填选项</label>
|
||||
<div class="layui-input-block" style="margin-left: 32px;">
|
||||
<input type="checkbox" name="iconurl" title="图标" >
|
||||
<input type="checkbox" name="description" title="描述" >
|
||||
<input type="checkbox" name="email" title="邮箱" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">使用说明</label>
|
||||
<div class="layui-form-mid ">部分主题没有收录入口,请自行添加到链接或者底部等你认为合适的地方!前往<a style="color:#3c78d8" target="_blank" href="./index.php?c=apply&u=<?php echo $u?>" target="_blank">申请收录</a></div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">安全限制</label>
|
||||
<div class="layui-form-mid ">1.禁止含有特殊字符<'&">等 2.SQL和XSS相关的敏感词 3.限制超过256个字符 <br /> 4.提交限频:IP/24小时/5次 (删除记录可恢复)</div>
|
||||
<div class="layui-form-mid ">1.禁止含有特殊字符<'&">等 2.SQL和XSS相关的敏感词 3.限制超过256个字符</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
@@ -183,7 +199,7 @@ layui.use(['element','table','layer','form','util','dropdown'], function(){
|
||||
|
||||
form.val('conf', <?php echo json_encode($data);?>);
|
||||
//表头
|
||||
var cols=[[
|
||||
var cols=[
|
||||
//{type:'checkbox'}, //开启复选框
|
||||
{field:'id',title:'ID',width:60,sort:true}
|
||||
,{field:'iconurl',title:'图标',width:60,templet:function(d){
|
||||
@@ -220,7 +236,14 @@ var cols=[[
|
||||
}
|
||||
}}
|
||||
,{title:'操作',toolbar:'#link_operate',width:130}
|
||||
]]
|
||||
]
|
||||
//读取列筛选
|
||||
var local = layui.data('table-filter-apply-list');
|
||||
layui.each(cols, function(index, item){
|
||||
if(item.field in local){
|
||||
item.hide = local[item.field];
|
||||
}
|
||||
});
|
||||
//表渲染
|
||||
table.render({
|
||||
elem: '#apply_list'
|
||||
@@ -232,7 +255,7 @@ table.render({
|
||||
,loading:true
|
||||
,toolbar: '#user_tool'
|
||||
,id:'apply_list'
|
||||
,cols: cols
|
||||
,cols: [cols]
|
||||
,response: {statusCode: 1 }
|
||||
,done: function (res, curr, count) {
|
||||
var temp_limit = $(".layui-laypage-limits option:selected").val();
|
||||
@@ -240,6 +263,14 @@ table.render({
|
||||
localStorage.setItem(u + "_limit",temp_limit);
|
||||
}
|
||||
$(".layui-table-tool-self").addClass('layui-hide-xs');//手机端隐藏defaultToolbar
|
||||
//记忆列筛选
|
||||
var that = this;
|
||||
that.elem.next().on('mousedown', 'input[lay-filter="LAY_TABLE_TOOL_COLS"]+', function(){
|
||||
var input = $(this).prev()[0];
|
||||
layui.data('table-filter-apply-list', {
|
||||
key: input.name,value: input.checked
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -325,7 +356,7 @@ table.on('toolbar(apply_list)', function(obj){
|
||||
var data = checkStatus.data;
|
||||
switch(obj.event){
|
||||
case 'conf':
|
||||
if(document.body.clientWidth < 768){area = ['100%' , '100%'];}else{area = ['768px' , '450px'];}
|
||||
if(document.body.clientWidth < 768){area = ['100%' , '100%'];}else{area = ['768px' , '520px'];}
|
||||
layer.open({
|
||||
type: 1,
|
||||
scrollbar: false,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<title>申请收录</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel='stylesheet' href='<?php echo $libs?>/Layui/v2.8.3/css/layui.css'>
|
||||
<link rel='stylesheet' href='<?php echo $layui['css']; ?>'>
|
||||
<style>
|
||||
/*body {*/
|
||||
/* background:url(<?php echo $libs;?>/Other/bg.png) 0% 0% / cover no-repeat;*/
|
||||
@@ -15,6 +15,7 @@
|
||||
body{background-color:rgba(0, 0, 51, 0.8);}
|
||||
.title{max-width: 400px;height: auto;margin-left: auto;margin-right: auto;margin-top:5em;}
|
||||
.title h1{color:#FFFFFF;text-align: center;}
|
||||
.required {color: red;margin-left: 5px;float: right;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -29,32 +30,21 @@
|
||||
<div class="layui-form-item" style="color: #fbfbfb;">
|
||||
<?php echo $apply['Notice'];?>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" required lay-verify="required" placeholder="例如 百度一下" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站标题<span class="required">*</span></label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" required lay-verify="required" placeholder="例如 百度一下" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站链接</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="url" name="url" required lay-verify="required|url" placeholder="例如 https://www.baidu.com" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站链接<span class="required">*</span></label>
|
||||
<div class="layui-input-block">
|
||||
<input type="url" name="url" required lay-verify="required|url" placeholder="例如 https://www.baidu.com" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站图标</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="url" name="iconurl" required lay-verify="url" placeholder="例如 https://www.baidu.com/favicon.ico" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站描述</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="description" placeholder="例如 搜索引擎" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站分类</label>
|
||||
<label class="layui-form-label">网站分类<span class="required">*</span></label>
|
||||
<div class="layui-input-block">
|
||||
<select name="category_id" lay-verify="required" lay-search>
|
||||
<option ></option>
|
||||
@@ -62,10 +52,22 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站图标</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="url" name="iconurl" lay-verify="url" placeholder="例如 https://www.baidu.com/favicon.ico" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站描述</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="description" placeholder="例如 搜索引擎" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">联系邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="email" lay-verify="required" placeholder="例如 admin@qq.com" autocomplete="off" class="layui-input">
|
||||
<input type="text" name="email" placeholder="例如 admin@qq.com" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
@@ -80,7 +82,7 @@
|
||||
</div>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery-3.6.0.min.js'></script>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
|
||||
<script src = '<?php echo $libs?>/Layui/v2.8.3/layui.js'></script>
|
||||
<script src = '<?php echo $layui['js']; ?>'></script>
|
||||
<script>
|
||||
layui.use(['form'], function(){
|
||||
var form = layui.form;
|
||||
|
||||
328
templates/admin/page/expand/article-edit.php
Normal file
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
if($global_config['article'] < 1 || !check_purview('article',1)){
|
||||
require(DIR.'/templates/admin/page/404.php');
|
||||
exit;
|
||||
}
|
||||
// if($global_config['article'] == 2 ){
|
||||
// if(is_file(DIR.'/static/UEditor/ueditor.all.min.js')){
|
||||
// require('article-edit-2.php');
|
||||
// exit;
|
||||
// }else{
|
||||
// $content = '未检测到UEditor资源';
|
||||
// require DIR.'/templates/admin/page/404.php';
|
||||
// exit;
|
||||
// }
|
||||
// }
|
||||
|
||||
if(!is_file(DIR.'/static/wangEditor/wangEditor.css') || !is_file(DIR.'/static/wangEditor/wangEditor.js')){
|
||||
$content = '由于缺少静态资源,当前无法加载编辑器!<br />如果您是站长,请在系统设置页面点击确定保存,系统将自动下载相关资源!<br />如果您是用户,请联系站长处理或耐心等候!';
|
||||
require DIR.'/templates/admin/page/404.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$article_id = Get('id');
|
||||
$mode = empty($article_id) ? 'add' : 'edit' ;
|
||||
|
||||
if($mode == 'edit'){
|
||||
if(has_db('user_article_list',['uid'=>UID,'id'=>$article_id])){
|
||||
$data = get_db('user_article_list','*',['uid'=>UID,'id'=>$article_id]);
|
||||
//var_dump($data);
|
||||
}else{
|
||||
$mode = 'add';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$title = $mode == 'add' ? '添加文章' : '编辑文章';
|
||||
|
||||
require dirname(__DIR__).'/header.php' ?>
|
||||
<link href="<?php echo $libs?>/wangEditor/wangEditor.css" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
#editor—wrapper { border: 1px solid #cccccc88; }
|
||||
#toolbar-container { border-bottom: 1px solid #ccc; }
|
||||
#editor-container { height: 400px; }
|
||||
.w40{width:40px;}
|
||||
.layui-upload-drag .layui-icon{font-size: 40px;color: #c2c2c2;}
|
||||
.layui-upload-drag{padding: 10px;}
|
||||
.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:11px;font-weight:700;color:#fff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#777;border-radius:10px}
|
||||
.bg-red{background-color:#e74c3c!important}
|
||||
.uploads-delete-tip{position: absolute;right: 10px;font-size: 12px;}
|
||||
.layui-input-block{margin-left: 70px;}
|
||||
@media screen and (max-width: 768px) {
|
||||
.layui-input-block {margin-left: 12px;}
|
||||
.content{display: none!important;}
|
||||
.layui-form-select .layui-edge {top: 75%;}
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<input class="layui-input layui-hide" name="id" autocomplete="off" value="<?php echo $data['id'];?>">
|
||||
<div class="layui-form-item ">
|
||||
<label class="layui-form-label w40">标题:</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" name="title" placeholder='请输入文章标题' autocomplete="off" value="<?php echo $data['title'];?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label w40">分类:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="category" lay-search>
|
||||
<?php echo_category(true); ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label w40">状态:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="state">
|
||||
<option value="1">公开</option>
|
||||
<option value="2">私有</option>
|
||||
<option value="3">草稿</option>
|
||||
<option value="4">废弃</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label w40">摘要:</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="summary" rows ="2" placeholder="文章摘要,留空时自动获取" class="layui-textarea" style="min-height: 45px;"><?php echo $data['summary'];?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label w40 content">正文:</label>
|
||||
<div class="layui-input-block" id="editor—wrapper">
|
||||
<div id="toolbar-container"></div>
|
||||
<div id="editor-container"></div>
|
||||
<textarea name="content" id="content" class="layui-textarea layui-hide"><?php echo $data['content'] ?? '<p><br></p>';?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label w40">封面:</label>
|
||||
<div class="layui-upload-drag">
|
||||
<input type="text" name="cover_url" id="cover_url" style="display: none;" value="<?php echo $data['cover'];?>">
|
||||
<small class="uploads-delete-tip bg-red badge" style="cursor:pointer;display: none;" id="del_cover_view">×</small>
|
||||
<i class="up_cover layui-icon layui-icon-add-1" id="up_cover" style="padding-right: 20px; padding-left: 20px;color: #e2e2e2;"></i>
|
||||
<p class="up_cover">上传封面</p>
|
||||
<div id="cover_view" style="display: none;"><img src="<?php echo $data['cover'];?>" style="max-width: 196px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-normal layui-btn-danger" id="cancel" >取消</button>
|
||||
<button class="layui-btn layui-btn-normal" id="save" >保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
|
||||
<script src = "./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<?php load_static('js');?>
|
||||
<script src="<?php echo $libs?>/wangEditor/wangEditor.js"></script>
|
||||
<script>
|
||||
|
||||
const { createEditor, createToolbar } = window.wangEditor
|
||||
const editorConfig = {
|
||||
placeholder: '请输入文章内容...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {}
|
||||
},
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml();
|
||||
$('#content').val(html);
|
||||
}
|
||||
}
|
||||
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
base64LimitSize: 128 * 1024, //小于该值就插入base64
|
||||
server: get_api('write_article','uploadImage'),
|
||||
fieldName: 'file',
|
||||
maxFileSize: 5 * 1024 * 1024, // 单文件限制5M
|
||||
maxNumberOfFiles: 10, //最多上传10个文件
|
||||
// 上传之前触发
|
||||
onBeforeUpload(file) {
|
||||
return file
|
||||
},
|
||||
// 上传进度的回调函数
|
||||
onProgress(progress) {
|
||||
console.log('progress', progress) //进度: 0-100
|
||||
},
|
||||
// 单个文件上传成功之后
|
||||
onSuccess(file, res) {
|
||||
parent.layer.msg('上传成功', {icon: 1});
|
||||
},
|
||||
// 单个文件上传失败
|
||||
onFailed(file, res) {
|
||||
layer.alert(`${res.message}`,{icon:5,title:`上传失败: ${file.name}`,anim: 2,closeBtn: 0});
|
||||
console.log(res );
|
||||
},
|
||||
// 上传错误,或者触发 timeout 超时
|
||||
onError(file, err, res) {
|
||||
layer.alert(`${err}`,{icon:5,title:`上传错误: ${file.name}`,anim: 2,closeBtn: 0});
|
||||
},
|
||||
}
|
||||
editorConfig.MENU_CONF['uploadVideo'] = {
|
||||
base64LimitSize: 128 * 1024, //小于该值就插入base64
|
||||
server: get_api('write_article','uploadVideo'),
|
||||
fieldName: 'file',
|
||||
maxFileSize: 20 * 1024 * 1024, // 单文件限制
|
||||
maxNumberOfFiles: 10, //最多上传10个文件
|
||||
// 上传之前触发
|
||||
onBeforeUpload(file) {
|
||||
return file
|
||||
},
|
||||
// 上传进度的回调函数
|
||||
onProgress(progress) {
|
||||
console.log('progress', progress) //进度: 0-100
|
||||
},
|
||||
// 单个文件上传成功之后
|
||||
onSuccess(file, res) {
|
||||
parent.layer.msg('上传成功', {icon: 1});
|
||||
},
|
||||
// 单个文件上传失败
|
||||
onFailed(file, res) {
|
||||
layer.alert(`${res.message}`,{icon:5,title:`上传失败: ${file.name}`,anim: 2,closeBtn: 0});
|
||||
console.log(res );
|
||||
},
|
||||
// 上传错误,或者触发 timeout 超时
|
||||
onError(file, err, res) {
|
||||
layer.alert(`${err}`,{icon:5,title:`上传错误: ${file.name}`,anim: 2,closeBtn: 0});
|
||||
},
|
||||
}
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: $('#content').val(),
|
||||
config: editorConfig,
|
||||
mode: 'default'
|
||||
})
|
||||
|
||||
const toolbarConfig = {excludeKeys: ['fullScreen','uploadVideo']}
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#toolbar-container',
|
||||
config: toolbarConfig,
|
||||
mode: 'default'
|
||||
})
|
||||
|
||||
|
||||
layui.use(['form','upload'], function () {
|
||||
var form = layui.form,
|
||||
upload = layui.upload;
|
||||
|
||||
<?php if($mode == 'edit'){ ?>
|
||||
form.val('form',{category:<?php echo $data['category'];?>,state:<?php echo $data['state'];?>});
|
||||
<?php }?>
|
||||
|
||||
var original_md5 = $.md5(JSON.stringify(form.val('form')));
|
||||
|
||||
$('#cancel').click(function () {
|
||||
let data = form.val('form');
|
||||
if($.md5(JSON.stringify(form.val('form'))) == original_md5){
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
return false;
|
||||
}
|
||||
layer.confirm('确定取消?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//如果存在封面则加载
|
||||
if($("#cover_url").val() != ''){
|
||||
layui.$('#cover_view img').attr('src', $("#cover_url").val());
|
||||
layui.$('#cover_view').show();
|
||||
layui.$('#del_cover_view').show();
|
||||
layui.$('.up_cover').hide();
|
||||
}
|
||||
|
||||
//上传
|
||||
var uploadInst = upload.render({
|
||||
elem: '.up_cover'
|
||||
,url: get_api('write_article','uploadImage')
|
||||
,accept: 'images'
|
||||
,acceptMime: 'image/*'
|
||||
,exts:'jpg|png|gif|bmp|jpeg|svg|webp'
|
||||
,size: 5*1024
|
||||
,done: function(res){
|
||||
if(res.errno == 0){
|
||||
$("#cover_url").val(res.data.url);
|
||||
layui.$('#cover_view img').attr('src', res.data.url);
|
||||
layui.$('#cover_view').show();
|
||||
layui.$('#del_cover_view').show();
|
||||
layui.$('.up_cover').hide();
|
||||
layer.msg('上传成功', {icon: 1});
|
||||
}else{
|
||||
layer.msg(res.message || '上传失败', {icon: 5});
|
||||
}
|
||||
},error: function(){
|
||||
layer.msg("上传异常,请刷新重试", {icon: 5});
|
||||
}
|
||||
});
|
||||
|
||||
//删除封面
|
||||
$(document).on('click', '#del_cover_view', function() {
|
||||
$.post(get_api('write_article','deleteImage'),{'path':$("#cover_url").val()},function(data,status){
|
||||
if(data.code == 1) {
|
||||
$("#cover_url").val('');
|
||||
layui.$('#cover_view').hide();
|
||||
layui.$('#del_cover_view').hide();
|
||||
layui.$('.up_cover').show();
|
||||
uploadInst.config.elem.next()[1].value = '';
|
||||
layer.msg("删除成功",{icon:1});
|
||||
}else{
|
||||
layer.msg(data.msg || '未知错误',{icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#save').click(function () {
|
||||
let data = form.val('form');
|
||||
if(data.title == ''){
|
||||
layer.msg('标题不能为空,请输入标题',{icon: 5});
|
||||
return false;
|
||||
}
|
||||
if(data.summary == ''){
|
||||
data.summary = truncateString(editor.getText(),120).replace(/\n/g, ' ');
|
||||
}
|
||||
let loading = layer.msg('正在处理,请稍后..', {icon: 16,time: 1000*300,shadeClose: false});
|
||||
$.post(get_api('write_article','save_article'),data,function(data,status){
|
||||
layer.close(loading);
|
||||
if(data.code == 1) {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
parent.layer.msg('操作成功', {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg || '未知错误',{icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
function truncateString(str,n) {
|
||||
var r=/[^\x00-\xff]/g;
|
||||
if(str.replace(r,"mm").length<=n){return str;}
|
||||
var m=Math.floor(n/2);
|
||||
for(var i=m;i<str.length;i++){
|
||||
if(str.substr(0,i).replace(r,"mm").length>=n){
|
||||
return str.substr(0,i)+"...";
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
392
templates/admin/page/expand/article-list.php
Normal file
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
if($global_config['article'] < 1 || !check_purview('article',1)){
|
||||
require(DIR.'/templates/admin/page/404.php');
|
||||
exit;
|
||||
}
|
||||
//读取设置
|
||||
$s_site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
$set['visual'] = $s_site['article_visual'] ?? '1';
|
||||
$set['icon'] = $s_site['article_icon'] ?? '1';
|
||||
$title='文章列表';
|
||||
require dirname(__DIR__).'/header.php' ?>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<label class="layui-form-label " style="width:60px;padding-left: 5px;padding-right: 5px;">文章筛选:</label>
|
||||
<div class="layui-input-inline" style="width: 150px;">
|
||||
<select name="category" lay-search>
|
||||
<option value="0" selected="">全部</option>
|
||||
<optgroup label="用户分类">
|
||||
<?php echo_category(true); ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<label class="layui-form-label layui-hide-sm" style="width:60px;padding-left: 5px;padding-right: 5px;">关键字:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input" name="keyword" id="keyword" placeholder='请输入标题或文章内容' autocomplete="off" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline layui-form layui-hide-xs" style="padding-bottom: 5px;" >
|
||||
<label class="layui-form-label layui-hide-sm" style="width:60px;padding-left: 5px;padding-right: 5px; ">属性筛选:</label>
|
||||
<div class="layui-input-inline" style="width: 80px;">
|
||||
<select name="state">
|
||||
<option value="0" selected="">全部</option>
|
||||
<option value="1">公开</option>
|
||||
<option value="2">私有</option>
|
||||
<option value="3">草稿</option>
|
||||
<option value="4">废弃</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<button class="layui-btn layui-btn-normal "type="button" id="search" style="height: 36px;">搜索</button>
|
||||
</div>
|
||||
</form>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
<script type="text/html" id="tablebar">
|
||||
<div class="layui-btn-group">
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>
|
||||
</div>
|
||||
</script>
|
||||
<!-- 表头工具栏 -->
|
||||
<script type="text/html" id="toolbar">
|
||||
<div class="layui-btn-group">
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" id="batch_operation"><span>批量操作</span><i class="layui-icon layui-icon-down layui-font-12"></i></button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="add_article">添加文章</button>
|
||||
<button class="layui-btn layui-btn-sm " lay-event="set">设置</button>
|
||||
</div>
|
||||
</script>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<?php load_static('js');?>
|
||||
<!--批量修改分类-->
|
||||
<ul class="batch_category" style="margin-top: 18px;display:none;padding-right: 10px;padding-left: 10px;">
|
||||
<form class="layui-form" lay-filter="batch_category">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">父级分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select id="batch_category_fid">
|
||||
<?php echo_category(true); ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-normal layui-btn-danger cancel" type="button">取消</button>
|
||||
<button class="layui-btn" type="button" id="batch_category" >确定修改</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</ul>
|
||||
<!--设置-->
|
||||
<ul class="set" style="margin-top: 18px;display:none;padding-right: 10px;padding-left: 10px;">
|
||||
<form class="layui-form" lay-filter="set_form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">显示文章</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="visual">
|
||||
<option value="1">显示靠前</option>
|
||||
<option value="2">显示靠后</option>
|
||||
<option value="0">隐藏</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">是否在主页显示文章链接</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">链接图标</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="icon">
|
||||
<option value="0">首字图标</option>
|
||||
<option value="1">站点图标</option>
|
||||
<option value="2">文章封面</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">设为文章封面且无封面时显示站点图标</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="padding-top: 10px;">
|
||||
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-normal layui-btn-danger cancel">取消</button>
|
||||
<button class="layui-btn" lay-submit id="save_set">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
<pre class="layui-code" >
|
||||
小提示:
|
||||
1.文章所属分类加密时不会对文章加密 (暂不支持文章加密,不想被看到可将文章设为私有)
|
||||
2.文章所属分类私有且未登录时不显示文章链接 (通过文章链接访问不受限制,不想被看到可将文章设为私有)
|
||||
3.上传图片支持格式:jpg|png|gif|bmp|jpeg|svg 大小限制:5M
|
||||
4.编辑器中上传图片小于128KB时使用base64编码存入数据库,大于128KB时将以文件的方式上传到服务器
|
||||
5.显示文章选项中的靠前/靠后是指文章链接在所属分类下的位置,隐藏则不在主页显示
|
||||
</pre>
|
||||
</form>
|
||||
</ul>
|
||||
<script>
|
||||
layui.use(['form','table','dropdown','miniTab'], function () {
|
||||
var $ = layui.jquery;
|
||||
var table = layui.table;
|
||||
var form = layui.form;
|
||||
var dropdown = layui.dropdown;
|
||||
var miniTab = layui.miniTab;
|
||||
var api = get_api('read_article','article_list');
|
||||
var limit = localStorage.getItem(u + "_limit") || 50;
|
||||
var state_data = ["Null","公开", "私有", "草稿", "废弃"];
|
||||
var cols=[ //表头
|
||||
{type:'checkbox'} //开启复选框
|
||||
,{ title:'操作', toolbar: '#tablebar',width:110}
|
||||
,{field: 'title', title: '标题', minWidth:200,templet: function(d){
|
||||
return '<a style="color:#3c78d8" target="_blank" href="./?c=article&id=' +d.id + '&u=' + u + '" title="' + d.summary + '">'+d.title+'</a>'
|
||||
}}
|
||||
,{field:'category',title:'分类',width:100,templet: function(d){
|
||||
return d.category_name;
|
||||
}}
|
||||
,{field:'state',title:'状态',width:100,templet: function(d){
|
||||
return state_data[d.state];
|
||||
}}
|
||||
,{field: 'browse_count', title: '浏览次数',width:120,sort:true}
|
||||
,{field: 'add_time', title: '添加时间', width:170, sort: true,templet:function(d){
|
||||
var add_time = timestampToTime(d.add_time);
|
||||
return add_time;
|
||||
}}
|
||||
,{field: 'up_time', title: '修改时间', width:170,sort:true,templet:function(d){
|
||||
return d.up_time == null ?'':timestampToTime(d.up_time);
|
||||
}}
|
||||
];
|
||||
|
||||
table.render({
|
||||
elem: '#table'
|
||||
,height: 'full-80'
|
||||
,url: api
|
||||
,page: true
|
||||
,limit:limit
|
||||
,limits: [20,50,100,300,500]
|
||||
,even:true
|
||||
,loading:true
|
||||
,toolbar: '#toolbar'
|
||||
,id:'table'
|
||||
,cols: [cols]
|
||||
,method: 'post'
|
||||
,response: {statusCode: 1 }
|
||||
,done: function (res, curr, count) {
|
||||
batch_operation();//初始化批量操作菜单
|
||||
//获取当前每页显示数量.并写入本都储存
|
||||
var temp_limit = $(".layui-laypage-limits option:selected").val();
|
||||
if(temp_limit > 0 && localStorage.getItem(u + "_limit") != temp_limit){
|
||||
localStorage.setItem(u + "_limit",temp_limit);
|
||||
}
|
||||
}
|
||||
});
|
||||
//批量操作
|
||||
function batch_operation(){
|
||||
dropdown.render({
|
||||
elem: '#batch_operation',
|
||||
data: [{
|
||||
title: ' 修改分类 ',
|
||||
id: 'up_category'
|
||||
},{
|
||||
title: '修改状态',
|
||||
child: [{
|
||||
title: '设为公开',
|
||||
id: "up_state",
|
||||
value: 1
|
||||
},{
|
||||
title: '设为私有',
|
||||
id: "up_state",
|
||||
value: 2
|
||||
},{
|
||||
title: '设为草稿',
|
||||
id: "up_state",
|
||||
value: 3
|
||||
},{
|
||||
title: '设为废弃',
|
||||
id: "up_state",
|
||||
value: 4
|
||||
}]
|
||||
},{
|
||||
title: '批量删除',
|
||||
id: 'del_article'
|
||||
}],
|
||||
click: function(obj){
|
||||
let checkStatus = table.checkStatus('table').data;
|
||||
if( checkStatus.length == 0 ) {
|
||||
layer.msg('未选中任何数据!');
|
||||
return;
|
||||
}
|
||||
//获取被选ID并格式化
|
||||
tableIds = checkStatus.map(function (value) {return value.id;});
|
||||
tableIds = JSON.stringify(tableIds);
|
||||
//删除文章
|
||||
if(obj.id == 'del_article'){
|
||||
layer.confirm('确认删除?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
$.post(get_api('write_article','del_article'),{id:tableIds},function(data,status){
|
||||
if(data.code == 1) {
|
||||
search();
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
}else if(obj.id == 'up_category'){
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: false ,area : ['100%', '100%'],closeBtn:0,content: $('.batch_category')});
|
||||
}else if(obj.id == 'up_state'){
|
||||
$.post(get_api('write_article','up_state'),{'id':tableIds,'state_id':obj.value},function(data,status){
|
||||
if(data.code == 1) {
|
||||
search();
|
||||
layer.msg('操作成功', {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg || '未知错误',{icon: 5});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//输入框回车事件和搜索按钮点击事件
|
||||
$('#keyword, #search').on('keydown click', function(e) {
|
||||
if ( (e.target.id === 'keyword' && e.keyCode === 13) || (e.target.id === 'search' && e.type === 'click') ) {
|
||||
search();
|
||||
}
|
||||
});
|
||||
//搜索
|
||||
function search(){
|
||||
let data = form.val('form');
|
||||
table.reload('table', {
|
||||
url: api
|
||||
,method: 'post'
|
||||
,request: {pageName: 'page',limitName: 'limit'}
|
||||
,where: data
|
||||
,page: {curr: 1}
|
||||
});
|
||||
}
|
||||
//监听工具栏
|
||||
table.on('toolbar(table)', function (obj) {
|
||||
var btn = obj.event;
|
||||
if (btn == 'add_article') { //添加文章
|
||||
layer.open({
|
||||
title: false,
|
||||
type: 2,
|
||||
scrollbar: false,
|
||||
shade: 0.2,
|
||||
maxmin:false,
|
||||
shadeClose: true,
|
||||
closeBtn:0,
|
||||
area: ['100%', '100%'],
|
||||
content: './?c=admin&page=expand/article-edit&u=' + u,
|
||||
end: function(){
|
||||
search();
|
||||
}
|
||||
});
|
||||
}else if(btn == 'set'){ //设置
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: false ,area : ['100%', '100%'],closeBtn:0,content: $('.set')});
|
||||
}else{ //综合批量操作
|
||||
//取选中数据
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
if( checkStatus.data.length == 0 && ['LAYTABLE_COLS','LAYTABLE_EXPORT','LAYTABLE_PRINT'].indexOf(btn) == -1 ) {
|
||||
layer.msg('未选中任何数据!');
|
||||
return;
|
||||
}
|
||||
//批量删除
|
||||
if(btn == 'batch_del'){
|
||||
tableIds = checkStatus.data.map(function (value) {return value.id;});
|
||||
tableIds = JSON.stringify(tableIds);
|
||||
layer.confirm('确认删除?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
$.post(get_api('write_article','del_article'),{id:tableIds},function(data,status){
|
||||
if(data.code == 1) {
|
||||
search();
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//监听行工具
|
||||
table.on('tool(table)', function (obj) {
|
||||
let btn = obj.event;
|
||||
let data = obj.data;
|
||||
if (btn === 'del') {
|
||||
layer.confirm('确认删除?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
$.post(get_api('write_article','del_article'),{id:'['+data.id+']'},function(data,status){
|
||||
if(data.code == 1) {
|
||||
obj.del();
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
}else if(btn === 'edit'){
|
||||
layer.open({
|
||||
title: false,
|
||||
type: 2,
|
||||
scrollbar: false,
|
||||
shade: 0.2,
|
||||
maxmin:false,
|
||||
shadeClose: true,
|
||||
closeBtn:0,
|
||||
area: ['100%', '100%'],
|
||||
content: './?c=admin&page=expand/article-edit&id='+data.id+'&u=' + u,
|
||||
end: function(){
|
||||
search();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//设置相关
|
||||
form.val('set_form', <?php echo json_encode($set);?>);
|
||||
$('#save_set').on('click', function(){
|
||||
$.post(get_api('write_article','save_article_set'),form.val('set_form'),function(data,status){
|
||||
if(data.code == 1) {
|
||||
layer.close(index);
|
||||
layer.msg('操作成功', {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg || '未知错误',{icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
//取消按钮
|
||||
$('.cancel').click(function () {
|
||||
layer.close(index);
|
||||
return false;
|
||||
});
|
||||
|
||||
//批量修改分类
|
||||
$('#batch_category').click(function () {
|
||||
fid = $('#batch_category_fid').val();
|
||||
$.post(get_api('write_article','up_category'),{'id':tableIds,'category_id':fid},function(data,status){
|
||||
if(data.code == 1) {
|
||||
search();
|
||||
layer.close(index);
|
||||
layer.msg('操作成功', {icon: 1});
|
||||
}else{
|
||||
layer.msg(data.msg || '未知错误',{icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>极简留言板</title>
|
||||
<link rel='stylesheet' href='<?php echo $libs?>/Layui/v2.8.3/css/layui.css'>
|
||||
<link rel='stylesheet' href='<?php echo $layui['css']; ?>'>
|
||||
<style>
|
||||
.layui-form-item {
|
||||
margin-bottom: 10px;
|
||||
@@ -66,7 +66,7 @@
|
||||
<!-- 内容主题区域END -->
|
||||
</div>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery-3.6.0.min.js'></script>
|
||||
<script src = '<?php echo $libs?>/Layui/v2.8.3/layui.js'></script>
|
||||
<script src = '<?php echo $layui['js']; ?>'></script>
|
||||
<script>
|
||||
layui.use(['form'], function(){
|
||||
var form = layui.form;
|
||||
|
||||
@@ -14,14 +14,27 @@ if(!empty($Notice)){
|
||||
}
|
||||
//是否下载数据
|
||||
if(!offline && $reload){
|
||||
$Res = ccurl('https://update.lm21.top/TwoNav/Notice.json',3);
|
||||
$new_data = json_decode($Res['content'], true);unset($Res);
|
||||
if($new_data["code"] == 200 ){ //下载成功,写入缓存
|
||||
$new_data['download_time'] = time();
|
||||
write_global_config('notice',json_encode($new_data),'官方公告(缓存)');
|
||||
$data = $new_data;
|
||||
$overtime = !isset($global_config['Update_Overtime']) ? 3 : ($global_config['Update_Overtime'] < 3 || $global_config['Update_Overtime'] > 60 ? 3 : $global_config['Update_Overtime']);
|
||||
$urls = [
|
||||
"lm21" => "https://update.lm21.top/TwoNav/Notice.json",
|
||||
"gitee" => "https://gitee.com/tznb/twonav_updata/raw/master/Notice.json"
|
||||
];
|
||||
$Source = $global_config['Update_Source'] ?? '';
|
||||
if (!empty($Source) && isset($urls[$Source])) {
|
||||
$urls = [$Source => $urls[$Source]];
|
||||
}
|
||||
|
||||
foreach($urls as $key => $url){
|
||||
$Res = ccurl($url,$overtime);
|
||||
$new_data = json_decode($Res['content'], true);unset($Res);
|
||||
if($new_data["code"] == 200 ){ //下载成功,写入缓存
|
||||
$new_data['download_time'] = time();
|
||||
write_global_config('notice',json_encode($new_data),'官方公告(缓存)');
|
||||
$data = $new_data;
|
||||
unset($new_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($new_data);
|
||||
}
|
||||
//判断是否为空
|
||||
if(empty($data['version'])){
|
||||
@@ -227,9 +240,16 @@ require 'header.php';
|
||||
</div>
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-line-chart icon"></i>报表统计</div>
|
||||
<div class="layui-card-header">
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<div id="tongji" style="cursor: pointer;"><i class="fa fa-line-chart icon" ></i>报表统计</div>
|
||||
<div>
|
||||
<button class="layui-btn layui-btn-primary echarts" style="border: none;display:none;"><span>最近7天</span><i class="layui-icon layui-icon-down layui-font-12"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="echarts-records" style="width: 100%;min-height:500px"></div>
|
||||
<div id="echarts-records" style="width: 100%; min-height: 500px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -258,7 +278,7 @@ require 'header.php';
|
||||
<?php if($USER_DB['UserGroup'] == 'root'){ ?>
|
||||
<tr>
|
||||
<td>最新版本</td>
|
||||
<td id="new_ver"><?php echo $data['version'] ?? SysVer; ?></td>
|
||||
<td id="new_ver"><a target="_blank" href="https://gitee.com/tznb/TwoNav/releases"><?php echo $data['version'] ?? SysVer; ?></a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>授权状态</td>
|
||||
@@ -273,7 +293,7 @@ require 'header.php';
|
||||
</tr>
|
||||
<tr>
|
||||
<td>技术支持</td>
|
||||
<td><a target="_blank" href="tencent://message/?uin=271152681">QQ:271152681</a></td>
|
||||
<td><a target="_blank" href="tencent://message/?uin=271152681">QQ:271152681</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>专属地址</td>
|
||||
@@ -310,29 +330,81 @@ if($USER_DB['UserGroup'] == 'root'){
|
||||
var $ = layui.jquery,
|
||||
layer = layui.layer,
|
||||
miniTab = layui.miniTab,
|
||||
echarts = layui.echarts;
|
||||
echarts = layui.echarts,
|
||||
dropdown = layui.dropdown;
|
||||
miniTab.listen();
|
||||
|
||||
//报表功能
|
||||
var echartsRecords = echarts.init(document.getElementById('echarts-records'), 'walden');
|
||||
var optionRecords = {
|
||||
tooltip: {trigger: 'axis'},
|
||||
legend: {data:['访问量','点击量']},
|
||||
grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: <?php echo json_encode($day)?>
|
||||
},
|
||||
yAxis: {},
|
||||
series: <?php echo json_encode($day_data)?>
|
||||
};
|
||||
echartsRecords.setOption(optionRecords);
|
||||
|
||||
// echarts 窗口缩放自适应
|
||||
window.onresize = function(){
|
||||
echartsRecords.resize();
|
||||
|
||||
//报表统计下拉初始化
|
||||
var home_echarts = localStorage.getItem(u + "_home_echarts") || 7 ;
|
||||
$('.echarts').find('span').text(`最近${home_echarts}天`);
|
||||
$('.echarts').show();
|
||||
dropdown.render({
|
||||
elem: '.echarts',
|
||||
data: [{
|
||||
title: '最近7天',
|
||||
value: 7
|
||||
},{
|
||||
title: '最近14天',
|
||||
value: 14
|
||||
},{
|
||||
title: '最近30天',
|
||||
value: 30
|
||||
}],
|
||||
click: function(obj){
|
||||
this.elem.find('span').text(obj.title);
|
||||
localStorage.setItem(u + "_home_echarts",obj.value);
|
||||
home_echarts = obj.value;
|
||||
load_echarts();
|
||||
}
|
||||
});
|
||||
|
||||
$('#tongji').on('click', function(){
|
||||
$.post('./index.php?c=api&method=read_data&date='+home_echarts+'&type=tongji_ip_list&u='+u,function(data,status){
|
||||
if(data.code == 1){
|
||||
var content = '<table class="layui-table" border="1"><thead><tr><th>日期</th><th>IP列表</th></tr></thead><tbody>';
|
||||
$.each(data.data, function (date, ipAddresses) {
|
||||
content += '<tr><td>' + date + '</td><td>';
|
||||
$.each(ipAddresses, function (index, ipAddress) {
|
||||
content += ipAddress + '<br>';
|
||||
});
|
||||
content += '</td></tr>';
|
||||
});
|
||||
content += '</tbody></table>';
|
||||
layer.open({
|
||||
title: '访问IP列表',
|
||||
content: content,
|
||||
area: ['100%', '100%']
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
//加载报表统计
|
||||
function load_echarts(){
|
||||
var echartsRecords = echarts.init(document.getElementById('echarts-records'), 'walden');
|
||||
$.post('./index.php?c=api&method=read_data&date='+home_echarts+'&type=echarts&u='+u,function(data,status){
|
||||
if(data.code == 1){
|
||||
var optionRecords = {
|
||||
tooltip: {trigger: 'axis'},
|
||||
legend: {data:['访问量','点击量','IP数']},
|
||||
grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: data.data.dates
|
||||
},
|
||||
yAxis: {},
|
||||
series: data.data.day_data
|
||||
};
|
||||
echartsRecords.setOption(optionRecords);
|
||||
window.onresize = function(){echartsRecords.resize();} // echarts 窗口缩放自适应
|
||||
return;
|
||||
}
|
||||
layer.alert("获取统计数据失败..",{icon:5,title:'错误',anim: 2,closeBtn: 0,btn: ['刷新页面']},function () {location.reload();});
|
||||
});
|
||||
}
|
||||
load_echarts();
|
||||
|
||||
//定时刷新
|
||||
setInterval(function() {
|
||||
if($("#layuiminiHomeTabId",parent.document).attr('class') == 'layui-this' && document.visibilityState == 'visible'){
|
||||
|
||||
@@ -79,14 +79,25 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关键字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="keywords" name="keywords" placeholder="可留空" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="description" id="description" placeholder="请输入内容" class="layui-textarea"></textarea>
|
||||
<textarea name="description" id="description" placeholder="可留空" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
//判断全局是否开启扩展
|
||||
if($global_config['link_extend'] && check_purview('link_extend',1)){
|
||||
require 'link_extend.php';
|
||||
}?>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" id="continuity" lay-skin="primary" title="连续添加">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
$link = get_db('user_links',['lid','fid','pid(pwd_id)','property','title','url','url_standby','description','icon'],['uid'=>UID,'lid'=>$_GET['id']]);
|
||||
$link = get_db('user_links',['lid','fid','pid(pwd_id)','property','title','url','url_standby','keywords','description','icon'],['uid'=>UID,'lid'=>$_GET['id']]);
|
||||
if(empty($link)){
|
||||
require(DIR.'/templates/admin/page/404.php');
|
||||
exit;
|
||||
@@ -92,11 +92,18 @@ $title='编辑链接';$awesome=true; require 'header.php';
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关键字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="keywords" name="keywords" placeholder="可留空" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="description" id="description" placeholder="请输入内容" class="layui-textarea"></textarea>
|
||||
<textarea name="description" id="description" placeholder="可留空" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
@@ -13,19 +13,22 @@ if(!empty($list)){
|
||||
foreach ($list as $data) {
|
||||
$field = "_".$data['name'];
|
||||
$data['value'] = isset($extend_data[$field]) ? $extend_data[$field] : $data['default'];
|
||||
$link["_{$data['name']}"] = ''.htmlentities($data['value']);
|
||||
if($data['type'] == 'text'){
|
||||
echo_text($data);
|
||||
}elseif($data['type'] == 'textarea'){
|
||||
echo_textarea($data);
|
||||
}elseif($data['type'] == 'up_img'){
|
||||
echo_up_img($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function echo_text($data){ ?>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><?php echo $data['title']?></label>
|
||||
<label class="layui-form-label" title="<?php echo $data['name']?>"><?php echo $data['title']?></label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="_<?php echo $data['name']?>" autocomplete="off" value="<?php echo htmlentities($data['value'])?>" class="layui-input">
|
||||
<input type="text" name="_<?php echo $data['name']?>" autocomplete="off" value="<?php echo htmlentities($data['value'])?>" placeholder="<?php echo htmlentities($data['tip'])?>" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
@@ -33,13 +36,26 @@ function echo_text($data){ ?>
|
||||
|
||||
function echo_textarea($data){ ?>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><?php echo $data['title']?></label>
|
||||
<label class="layui-form-label" title="<?php echo $data['name']?>"><?php echo $data['title']?></label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="_<?php echo $data['name']?>" class="layui-textarea"><?php echo htmlentities($data['value'])?></textarea>
|
||||
<textarea name="_<?php echo $data['name']?>" placeholder="<?php echo htmlentities($data['tip'])?>" class="layui-textarea"><?php echo htmlentities($data['value'])?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
function echo_up_img($data){ ?>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" title="<?php echo $data['name']?>"><?php echo $data['title']?></label>
|
||||
<div class="layui-input-block layuimini-upload" >
|
||||
<input type="text" name="_<?php echo $data['name']?>" autocomplete="off" class="layui-input obtn" value="<?php echo htmlentities($data['value'])?>" placeholder="<?php echo htmlentities($data['tip'])?>">
|
||||
<div style="position: absolute; top:0px;" >
|
||||
<span><a class="layui-btn layui-btn-primary extend_up_img"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<label class="layui-form-label " style="width:60px;padding-left: 5px;padding-right: 5px;">分类筛选:</label>
|
||||
<div class="layui-input-inline">
|
||||
<select id="fid" lay-filter="fid" name="categorys" lay-search>
|
||||
<select name="fid" lay-search>
|
||||
<option value="0" selected="">全部</option>
|
||||
<optgroup label="用户分类">
|
||||
<?php echo_category(true); ?>
|
||||
@@ -21,21 +21,20 @@
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<label class="layui-form-label layui-hide-sm" style="width:60px;padding-left: 5px;padding-right: 5px;">关键字:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input class="layui-input" name="keyword" id="link_keyword" placeholder='请输入标题或描述或URL' value=''autocomplete="off" >
|
||||
<input class="layui-input" name="query" id="link_keyword" placeholder='请输入标题或描述或URL' autocomplete="off" >
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="layui-inline layui-form layui-hide-xs" style="padding-bottom: 5px;" >
|
||||
<label class="layui-form-label layui-hide-sm" style="width:60px;padding-left: 5px;padding-right: 5px; ">属性筛选:</label>
|
||||
<div class="layui-input-inline" style=" width: 80px; ">
|
||||
<select id="property" >
|
||||
<select name="property" >
|
||||
<option value="" selected>不限</option>
|
||||
<option value="0" >公开</option>
|
||||
<option value="1" >私有</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style=" width: 80px; ">
|
||||
<select id="status" >
|
||||
<select name="status" >
|
||||
<option value="" selected>不限</option>
|
||||
<option value="0" >禁用</option>
|
||||
<option value="1" >启用</option>
|
||||
@@ -43,12 +42,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<button class="layui-btn layui-btn-normal " id="link_search" style="height: 36px;">搜索</button>
|
||||
<button class="layui-btn layui-btn-normal "type="button" id="link_search" style="height: 36px;">搜索</button>
|
||||
</div>
|
||||
|
||||
<span id = "testing_tip" style = "display:none;">测试中...</span>
|
||||
<span id = "subscribe" style = "display:none;"><?php echo is_subscribe('bool')?'1':'0' ?></span>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
</form>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
@@ -75,6 +74,7 @@
|
||||
<?php if($global_config['offline'] != 1 ){ ?>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger layui-hide-xs" lay-event="testing" id="testing">检测</button>
|
||||
<?php }?>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger layui-hide-xs" lay-event="msg_pull" id="msg_pull">识别</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger" layuimini-content-href="link_sort" data-title="链接排序">排序模式</button>
|
||||
</div>
|
||||
</script>
|
||||
@@ -113,5 +113,55 @@
|
||||
</div>
|
||||
</script>
|
||||
</ul>
|
||||
<ul class="msg_pull" style="margin-top: 18px;display:none;padding-right: 10px;padding-left: 10px;">
|
||||
<form class="layui-form layuimini-form" lay-filter="msg_pull">
|
||||
<pre class="layui-code" id="tip" >提示: 自动识别仅针对http/https有效,且不能保证百分百成功!未成功识别时不会对链接信息进行修改!大批量识别前建议先备份数据,效果不理想时可以回退!</pre>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站标题</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="title" >
|
||||
<option value="0">保持不变</option>
|
||||
<option value="1">获取 (覆盖)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关键字</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="keywords" >
|
||||
<option value="0">保持不变</option>
|
||||
<option value="1" selected>获取 (未填关键字时)</option>
|
||||
<option value="2">获取 (覆盖)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站描述</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="description" >
|
||||
<option value="0">保持不变</option>
|
||||
<option value="1" selected>获取 (未填描述时)</option>
|
||||
<option value="2">获取 (覆盖)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">网站图标</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="icon" >
|
||||
<option value="0">保持不变</option>
|
||||
<option value="1" selected>获取 (未上传图标时)</option>
|
||||
<option value="2">获取 (覆盖)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-warm" type="button" id="close" >关闭</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="start_pull" id="start_pull">开始</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表头工具栏 -->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
|
||||
@@ -9,7 +9,7 @@ $LoginConfig = unserialize( get_db("global_config", "v", ["k" => "LoginConfig"])
|
||||
<div class="layuimini-main">
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<div class="layui-form layuimini-form layui-form-pane">
|
||||
<blockquote class="layui-elem-quote layui-text" style="">1.本页功能<a href="https://gitee.com/tznb/OneNav/wikis/%E8%AE%A2%E9%98%85%E6%9C%8D%E5%8A%A1%E6%8C%87%E5%BC%95" target="_blank">授权用户</a>专享<br />2.用户注册后默认使用此方案<br />3.如果您不理解选项的作用请勿乱改 </blockquote>
|
||||
<blockquote class="layui-elem-quote layui-text" style="">1.本页功能<a href="https://gitee.com/tznb/OneNav/wikis/%E8%AE%A2%E9%98%85%E6%9C%8D%E5%8A%A1%E6%8C%87%E5%BC%95" target="_blank">授权用户</a>专享<br />2.用户注册后默认使用此方案<br />3.此功能不会修改现有用户的配置<br />4.如果您不理解选项的作用请勿乱改 </blockquote>
|
||||
<fieldset class="layui-elem-field layui-field-title"><legend>安全设置</legend></fieldset>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -77,6 +77,18 @@ $LoginConfig = unserialize( get_db("global_config", "v", ["k" => "LoginConfig"])
|
||||
<div class="layui-form-mid layui-word-aux">部分主题和插件需设为开放模式!</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录后</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="login_page">
|
||||
<option value="admin" selected>进入后台</option>
|
||||
<option value="index">进入主页</option>
|
||||
<option value="auto">自动识别</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">自动识别:移动设备登录则进入主页,反之进入后台</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title"><legend>站点设置</legend></fieldset>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">主标题</label>
|
||||
|
||||
143
templates/admin/page/root/icon_set.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
if($USER_DB['UserGroup'] != 'root'){$content='您没有权限访问此页面'; require(DIR.'/templates/admin/page/404.php');exit;}
|
||||
$title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
?>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<div class="layui-form layuimini-form layui-form-pane">
|
||||
<blockquote class="layui-elem-quote layui-text" style="">
|
||||
1.此功能<a href="https://gitee.com/tznb/OneNav/wikis/%E8%AE%A2%E9%98%85%E6%9C%8D%E5%8A%A1%E6%8C%87%E5%BC%95" target="_blank">授权用户</a>专享,请仔细阅读本页说明<br />
|
||||
2.缓存时间视自身需求而定,希望及时更新则短一点(实际上站点很少会更新图标),建议值: 604800 (7天)<br />
|
||||
3.修改缓存时间可能不会立即生效,因为浏览器已经缓存的图标会等过期后再刷新 (可以清理浏览器缓存来强制刷新)<br />
|
||||
4.用户需在站点设置>链接图标>选择本地服务或本地服务(伪静态),后者需要从站长工具生成伪静态并正确配置<br />
|
||||
5.站点处于维护模式/离线模式或下方全局开关处于关闭时调用此接口则返回默认图标<br />
|
||||
6.当显示默认图标会忽略下方浏览器缓存时间的设置,时间将被设为60秒<br />
|
||||
7.受限于网络的复杂性无法百分百获取成功,当获取失败时会显示默认图标
|
||||
</blockquote>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">全局开关</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="o_switch">
|
||||
<option value="0" selected="">关闭</option>
|
||||
<option value="1" >开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">关闭时请求本地图标将得到默认图标</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">防盗链</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="referer_test">
|
||||
<option value="0" >关闭</option>
|
||||
<option value="1" selected="">开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">Referer防盗链,即来路检测</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">服务器缓存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="server_cache_time" lay-verify="required" placeholder='服务器缓存时间,单位:秒' value="604800" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:秒,可节省服务器资源,值为0表示禁止缓存</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">浏览器缓存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="browse_cache_time" lay-verify="required" placeholder='浏览器缓存时间,单位:秒' value="604800" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:秒,可节省服务器资源,值为0表示禁止缓存</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">解析超时</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="analysis_timeout" lay-verify="required" placeholder='解析超时,单位:秒' value="6" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:秒,范围:3 - 20,默认6秒</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">下载超时</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="download_timeout" lay-verify="required" placeholder='下载超时,单位:秒' value="6" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:秒,范围:3 - 20,默认6秒</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">大小限制</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="icon_size" lay-verify="required" placeholder='下载超时,单位:KB' value="256" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:KB,范围:5 - 1024,默认256</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">备选接口</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="backup_api">
|
||||
<option value="0" selected="">关闭</option>
|
||||
<option value="6" >api.iowen.cn</option>
|
||||
<option value="2" >favicon.png.pub</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">本地解析失败时尝试使用备选第三方API接口获取(由其他大佬提供)</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-danger" type="button" id="clean">清除缓存</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save">确认保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php load_static('js.layui');?>
|
||||
<script src="./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<script>
|
||||
layui.use(['jquery','form'], function () {
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var $ = layui.jquery;
|
||||
|
||||
//表单赋值
|
||||
form.val('form', <?php echo json_encode(unserialize( get_db("global_config", "v", ["k" => "icon_config"])));?>);
|
||||
//清除缓存
|
||||
$('#clean').click(function() {
|
||||
layer.confirm('确定要清除全部缓存吗?',{icon: 3, title:'温馨提示'}, function(index){
|
||||
$.post(get_api('other_root','write_icon_del_cache'),function(data,status){
|
||||
if(data.code == 1) {
|
||||
if(data.msg!="操作成功"){
|
||||
layer.alert(data.msg)
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on('submit(save)', function (data) {
|
||||
$.post(get_api('other_root','write_icon_config'),data.field,function(data,status){
|
||||
if(data.code == 1) {
|
||||
if(data.msg!="保存成功"){
|
||||
layer.alert(data.msg)
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
}
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,18 +17,21 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
<div class="layui-input-inline">
|
||||
<input type="pass" name="user" lay-verify="required" lay-reqtext="账号不能为空" placeholder='请输入账号' autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">邮箱账号,例如: admin@qq.com</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password" name="pwd" lay-verify="required" lay-reqtext="密码不能为空" placeholder='请输入密码或授权码' autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">邮箱密码,也可能是独立密码或者授权码</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">服务器</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="host" lay-verify="required" lay-reqtext="服务器不能为空" placeholder='请输入发件服务器地址' autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">例如: smtp.qq.com</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -36,6 +39,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="port" lay-verify="required" lay-reqtext="端口不能为空" placeholder='请输入服务器端口' value="465" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">通常是: 465或587</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -46,13 +50,15 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
<option value="TLS" >TLS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">通常是: ssl</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发送人</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sender" lay-verify="required" lay-reqtext="发送人邮箱不能为空" placeholder='' autocomplete="off" class="layui-input">
|
||||
<input type="text" name="sender" lay-verify="required" lay-reqtext="发送人名称不能为空" placeholder='' autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">例如: TwoNav</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -60,6 +66,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="addressee" placeholder='仅用于发件测试' autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">例如:user@qq.com</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>注册参数</legend></fieldset>
|
||||
@@ -71,12 +78,14 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
<option value="1" >开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">开启时用户注册需通过邮箱接收验证码</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发送间隔</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="send_interval" lay-verify="required" lay-reqtext="发送间隔不能为空" placeholder='IP发送间隔,单位秒!' value="60" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">为了避免被恶意发送,建议不低于30秒</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
|
||||
@@ -9,7 +9,7 @@ $user_groups = select_db('user_group',['id','code','name'],'');
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表头工具栏 -->
|
||||
|
||||
@@ -28,7 +28,7 @@ require(dirname(__DIR__).'/header.php');
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<button class="layui-btn layui-btn-normal " id="search" style="height: 36px;">搜索</button>
|
||||
</div>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,9 +2,17 @@
|
||||
if($USER_DB['UserGroup'] != 'root'){$content='您没有权限访问此页面'; require(DIR.'/templates/admin/page/404.php');exit;}
|
||||
$title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
?>
|
||||
<style>
|
||||
.layui-btn-container .layui-btn{border-width: 1px; border-style: solid; border-color: #FF5722!important; color: #FF5722!important;background: none;height: 30px; line-height: 30px; padding: 0 10px; font-size: 12px;}
|
||||
</style>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<div class="layui-btn-container">
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/default_setting" data-title="默认设置">默认设置</button>
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/mail_set" data-title="邮件配置">邮件配置</button>
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/icon_set" data-title="图标配置">图标配置</button>
|
||||
</div>
|
||||
<form class="layui-form" lay-filter="form">
|
||||
<div class="layui-form layuimini-form layui-form-pane">
|
||||
<blockquote class="layui-elem-quote layui-text" style="">1.带*号的选项属<a href="https://gitee.com/tznb/OneNav/wikis/%E8%AE%A2%E9%98%85%E6%9C%8D%E5%8A%A1%E6%8C%87%E5%BC%95" target="_blank">授权用户</a>专享<br />2.原OneNav Extend的部分配置已下放到用户组配置中<br />3.如果您不理解选项的作用请勿乱改 </blockquote>
|
||||
@@ -180,14 +188,35 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" id="api_extend" style="display:none;">
|
||||
<label class="layui-form-label required">api_extend</label>
|
||||
<div class="layui-form-item layui-hide" id="api_extend">
|
||||
<label class="layui-form-label">api_extend</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="api_extend">
|
||||
<option value="0" selected="">关闭</option>
|
||||
<option value="1" >开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">请勿开启!请勿开启!请勿开启!</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-hide">
|
||||
<label class="layui-form-label">资源接口</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="Update_Source">
|
||||
<option value="0" selected="">自动</option>
|
||||
<option value="lm21">主线路</option>
|
||||
<option value="gitee">备用线路(gitee)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">备用资源不定期更新,非必要请勿使用!</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-hide">
|
||||
<label class="layui-form-label">资源超时</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="Update_Overtime" autocomplete="off" value="3" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">默认3秒,范围3-60</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>扩展功能</legend></fieldset>
|
||||
@@ -222,43 +251,70 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">自定义链接的扩展信息(需自行添加字段,目前仅用于自定义过渡页)</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">文章管理</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="article">
|
||||
<option value="0" selected="">关闭</option>
|
||||
<option value="1" >开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">简易文章管理功能 ( 请勿和专业的比,首次开启时自动下载相关资源 )</div>
|
||||
</div>
|
||||
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>长度限制</legend></fieldset>
|
||||
<blockquote class="layui-elem-quote layui-text" style="">程序采用UTF8编码,一个汉字约占用3个字节!英文字母和数组占用1个字节!值为0表示不限制!</blockquote>
|
||||
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"><legend>相关限制</legend></fieldset>
|
||||
<blockquote class="layui-elem-quote layui-text" style="">程序采用UTF8编码,一个汉字约占用3个字节!英文字母和数组占用1个字节!值为0表示不限制!<br />添加或编辑时长度超限则不允许添加,批量识别时超限则截断</blockquote>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">分类名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="c_name" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:字节。</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">分类描述</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="c_desc" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:字节。</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">链接名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="l_name" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:字节。</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">链接地址</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="l_url" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:字节。</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">链接关键字</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="l_key" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">链接描述</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" name="l_desc" autocomplete="off" value="0" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">单位:字节。</div>
|
||||
<div class="layui-form-mid layui-word-aux">字符长度限制,单位:字节。</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">自定义代码</label>
|
||||
<div class="layui-input-inline">
|
||||
<select name="c_code" lay-filter="c_code">
|
||||
<option value="0" selected="">禁止</option>
|
||||
<option value="1" >允许</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">是否允许默认用户组使用自定义代码!允许存在安全隐患!</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -268,22 +324,30 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<?php load_static('js.layui');?>
|
||||
<script>
|
||||
layui.use(['jquery','form'], function () {
|
||||
layui.use(['jquery','form','miniTab'], function () {
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var $ = layui.jquery;
|
||||
|
||||
var miniTab = layui.miniTab;
|
||||
miniTab.listen();
|
||||
//表单赋值
|
||||
form.val('form', <?php echo json_encode($global_config);?>);
|
||||
form.val('form', <?php echo json_encode(unserialize( get_db("global_config", "v", ["k" => "length_limit"])));?>);
|
||||
|
||||
|
||||
|
||||
|
||||
//危险提示
|
||||
form.on('select(c_code)', function(data){
|
||||
if (data.value === '1') {
|
||||
layer.alert("允许使用自定义代码存在安全隐患<br />除非您信任使用者!否则建议禁止<br />同时请避免在登录管理员账号时浏览其他用户的主页", { title: '危险提示:' })
|
||||
}
|
||||
});
|
||||
//监听提交
|
||||
form.on('submit(save)', function (data) {
|
||||
layer.msg('正在保存中,请稍后...', {icon: 16,time: 1000*300,shadeClose: false});
|
||||
$.post('./index.php?c=api&method=write_sys_settings&u='+u,data.field,function(data,status){
|
||||
layer.closeAll();
|
||||
if(data.code == 1) {
|
||||
if(data.msg!="保存成功"){
|
||||
layer.alert(data.msg)
|
||||
@@ -299,14 +363,13 @@ layui.use(['jquery','form'], function () {
|
||||
|
||||
//开启隐藏功能
|
||||
$('.layui-elem-field').click(function () {
|
||||
if(Number( $(this).attr('click')) >= 6){
|
||||
$("#api_extend").show();
|
||||
}else{
|
||||
let click = $(this).attr('click') ? Number($(this).attr('click')) + 1 : 0;
|
||||
$(this).attr('click',click)
|
||||
let clickCount = Number($(this).attr('click') || 0);
|
||||
if (clickCount >= 6) {
|
||||
$(".layui-hide").removeClass("layui-hide");
|
||||
} else {
|
||||
$(this).attr('click', clickCount + 1);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
if($USER_DB['UserGroup'] != 'root'){$content='您没有权限访问此页面'; require(DIR.'/templates/admin/page/404.php');exit;}
|
||||
$title='站长工具';
|
||||
session_start();
|
||||
$_SESSION['phpinfo_id'] = Get_Rand_Str(8);
|
||||
if(function_exists("opcache_reset")){
|
||||
opcache_reset(); //清理PHP缓存
|
||||
}
|
||||
@@ -18,6 +20,7 @@ require(dirname(__DIR__).'/header.php');
|
||||
<div class="layui-btn-container">
|
||||
<button type="button" class="layui-btn copy_log">复制内容</button>
|
||||
<button type="button" class="layui-btn diagnose">一键诊断</button>
|
||||
<button type="button" class="layui-btn connectivity_test">连通测试</button>
|
||||
<button type="button" class="layui-btn phpinfo">phpinfo</button>
|
||||
<?php if(preg_match('/nginx/i',$_SERVER['SERVER_SOFTWARE']) ){ ?>
|
||||
<button type="button" class="layui-btn rewrite">生成伪静态</button>
|
||||
@@ -27,7 +30,6 @@ require(dirname(__DIR__).'/header.php');
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/sys_log" data-title="系统日志">系统日志</button>
|
||||
<button type="button" class="layui-btn" layuimini-content-href="updatelog" data-title="更新日志">更新日志</button>
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/import_data" data-title="导入数据">导入数据</button>
|
||||
<button type="button" class="layui-btn" layuimini-content-href="root/mail_set" data-title="邮件配置">邮件配置</button>
|
||||
</div>
|
||||
<pre class="layui-code" id="console_log" >
|
||||
1.功能都集中在上方的按钮了,需要那个就点击那个!
|
||||
@@ -47,6 +49,7 @@ require(dirname(__DIR__).'/header.php');
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<script src = "<?php echo $libs?>/Other/ClipBoard.min.js"></script>
|
||||
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
|
||||
<?php load_static('js');?>
|
||||
<script>
|
||||
layui.use(['layer','form','miniTab'], function () {
|
||||
@@ -74,8 +77,47 @@ layui.use(['layer','form','miniTab'], function () {
|
||||
});
|
||||
});
|
||||
|
||||
//连通测试
|
||||
$('.connectivity_test').on('click', function(){
|
||||
$("#console_log").text("");
|
||||
$("#console_log").append("浏览器UA:" + navigator.userAgent +"\n");
|
||||
$("#console_log").append("客户端时间:" + timestampToTime(Math.round(new Date() / 1000) ) +"\n");
|
||||
|
||||
var urls = [
|
||||
['主线路', 'https://update.lm21.top/connectivity_test.txt'],
|
||||
['备用线路(Gitee)', 'https://gitee.com/tznb/twonav_updata/raw/master/connectivity_test.txt']
|
||||
];
|
||||
urls.forEach(function(route) {
|
||||
var routeName = route[0];
|
||||
var url = route[1];
|
||||
$("#console_log").append("正在检测: " + routeName +"\n");
|
||||
$.ajax({
|
||||
url: get_api('read_data', 'connectivity_test'),
|
||||
type: 'POST',
|
||||
data: { url: url },
|
||||
async: false,
|
||||
success: function(data, status) {
|
||||
$("#console_log").append(data.msg + "\n");
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
$("#console_log").append(routeName + ": 请求 " + url + " 发生错误:" + errorThrown + "\n");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
//phpinfo
|
||||
$('.phpinfo').on('click', function(){
|
||||
index = layer.prompt({formType: 1,value: '',title: '输入登录密码:',shadeClose: false,"success":function(){
|
||||
$("input.layui-layer-input").on('keydown',function(e){if(e.which == 13) {echo_phpinfo();}});
|
||||
}},function(){
|
||||
echo_phpinfo()
|
||||
});
|
||||
});
|
||||
|
||||
function echo_phpinfo(){
|
||||
let p = $("input.layui-layer-input").val();
|
||||
if(p == ''){ return false;}
|
||||
layer.close(index);
|
||||
layer.open({
|
||||
title: 'phpinfo',
|
||||
type: 2,
|
||||
@@ -84,21 +126,24 @@ layui.use(['layer','form','miniTab'], function () {
|
||||
maxmin:false,
|
||||
shadeClose: true,
|
||||
area: ['100%', '100%'],
|
||||
content: get_api('read_data','phpinfo'),
|
||||
content: get_api('read_data','phpinfo')+'&p='+$.md5(p)+'&pid=<?php echo $_SESSION['phpinfo_id'] ;?>'
|
||||
});
|
||||
});
|
||||
}
|
||||
//伪静态
|
||||
$('.rewrite').on('click', function(){
|
||||
let pathname = window.location.pathname;
|
||||
$("#console_log").text("");
|
||||
$("#console_log").append(`#安全设置\n`);
|
||||
$("#console_log").append(`location ~* ^${pathname}(data|system|templates)/.*.(db|db3|php|sql|tar|gz|zip|info|log)$ {\n\treturn 403;\n}\n`);
|
||||
$("#console_log").append(`#伪静态\n`);
|
||||
$("#console_log").append(`#安全规则(必选)\n`);
|
||||
$("#console_log").append(`location ^~ ${pathname}data/ {location ~* \\.(db|db3|php|sql|tar|gz|zip|info|log|json)$ {return 403;}}\n`);
|
||||
$("#console_log").append(`location ^~ ${pathname}templates/ {location ~* \\.(php|tar|gz|zip|info|log|json)$ {return 403;}}\n`);
|
||||
$("#console_log").append(`#重写规则(可选)\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}login$ ${pathname}index.php?c=login break;\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}admin$ ${pathname}index.php?c=admin break;\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}([A-Za-z0-9]+)$ ${pathname}index.php?u=$1 break; #HOST/USER\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}ico/(.+) ${pathname}index.php?c=icon&url=$1 break;\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}([A-Za-z0-9]+)$ ${pathname}index.php?u=$1 break;\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}(.+)/(click)/([A-Za-z0-9]+)$ ${pathname}index.php?c=$2&id=$3&u=$1 break;\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}(.+)/(click)/(.+) ${pathname}$3 break; #static\n`);
|
||||
$("#console_log").append(`rewrite ^${pathname}(.+)/(click)/(.+) ${pathname}$3 break;\n`);
|
||||
|
||||
});
|
||||
//清理缓存
|
||||
$('.CleanCache').on('click', function(){
|
||||
|
||||
@@ -28,13 +28,14 @@ $user_groups = select_db('user_group',['id','code','name'],'');
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<button class="layui-btn layui-btn-normal " id="search" style="height: 36px;">搜索</button>
|
||||
</div>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="user_tool">
|
||||
<div class="layui-btn-group">
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="Del">删除</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="Del_OTP" title="移除OTP双重验证">移除OTP验证</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="register" <?php echo $global_config['RegOption'] == 0? 'style = "display:none;"':'' ?> >注册账号</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="set_UserGroup">设用户组</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="username_retain">账号保留</button>
|
||||
@@ -163,6 +164,16 @@ layui.use(['table','layer','form'], function () {
|
||||
}else if(event == 'set_UserGroup'){
|
||||
IDs = tableIds;
|
||||
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '修改用户组',area : ['100%', '100%'],content: $('.set_UserGroup')});
|
||||
}else if(event == 'Del_OTP'){
|
||||
layer.alert("以下账号将被移除OTP双重验证,确定继续吗?<br />"+table_Users,{icon:3,title:'确认操作',anim: 2,closeBtn: 0,btn: ['确定','取消']},function () {
|
||||
$.post(get_api('write_user_info','Del_OTP'),{ID:tableIds},function(data,status){
|
||||
if(data.code == 1){
|
||||
layer.msg(data.msg,{icon: 1})
|
||||
} else{
|
||||
layer.msg(data.msg,{icon: 5});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
//行工具
|
||||
|
||||
@@ -6,7 +6,7 @@ require(dirname(__DIR__).'/header.php');
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="tool">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" min="0" max="60" lay-verify="required|number" name="visitor_stay_time" value = "3" autocomplete="off" placeholder="访客停留时间,单位s" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">访客停留时间,单位秒</div>
|
||||
<div class="layui-form-mid layui-word-aux">访客停留时间,单位秒(需模板支持)</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -18,7 +18,18 @@
|
||||
<div class="layui-input-inline">
|
||||
<input type="number" min="0" max="60" lay-verify="required|number" name="admin_stay_time" value = "5" autocomplete="off" placeholder="管理员停留时间,单位s" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">管理员停留时间,单位秒</div>
|
||||
<div class="layui-form-mid layui-word-aux">管理员停留时间,单位秒(需模板支持)</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label" >默认关键字</label>
|
||||
<div class="layui-input-inline" >
|
||||
<select name="default_keywords" >
|
||||
<option value="0">链接标题</option>
|
||||
<option value="1">站点关键字</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">指链接信息未填写关键字时选择其他值作为关键字</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
|
||||
<button class="layui-btn layui-btn-normal " id="search" style="height: 36px;">搜索</button>
|
||||
</div>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: -3px 0;"></table>
|
||||
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作列 -->
|
||||
|
||||
83
templates/admin/page/theme_article.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php $title='文章模板';$awesome=true; require 'header.php';
|
||||
$site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
?>
|
||||
<style type="text/css">
|
||||
.screenshot{
|
||||
width: 99%;
|
||||
height: 99%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
aspect-ratio:16/9;
|
||||
}
|
||||
#default #del {display: none;}
|
||||
</style>
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<blockquote class="layui-elem-quote layuimini-form" style="margin-top: 0px;border-left: 5px solid <?php echo $cache?"#1e9fff":($global_config['offline']?"":"#639d11") ?>;padding: 6px;">
|
||||
<span class="layui-breadcrumb" lay-separator="|">
|
||||
<a href="./index.php?c=admin&page=theme_article&cache=no&u=<?php echo U;?>">刷新数据</a>
|
||||
</span>
|
||||
</blockquote>
|
||||
<div class="layui-bg-gray" style="padding: 1px;" >
|
||||
<div class="layui-row layui-col-space15">
|
||||
<?php
|
||||
$Space = ' ';//占位符,强迫症想让输出的源码好看点而已...
|
||||
foreach ($themes as $key => $theme) {
|
||||
$online = !empty($theme['info']['md5']); //在线主题!
|
||||
if($s_templates['article'] == $key){
|
||||
$icon ='<i class="fa fa-magic" style="color: #03a9f4;" title = "正在使用"></i> ';
|
||||
}else{
|
||||
$icon ='';
|
||||
}
|
||||
$color = ($s_templates['article'] == $key ?"color: #03a9f4;":"");
|
||||
?>
|
||||
<!--主题卡片-->
|
||||
<div class="layui-col-xs layui-col-sm4 layui-col-md3 ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<div style="float:left; cursor:pointer;<?php echo $color; ?>" title="<?php echo $key; ?>"><?php echo $icon.$theme['info']['name']; ?></div>
|
||||
<div style="float:right;cursor:pointer;" title="<?php echo $theme['info']['update']; ?>"><?php echo $theme['info']['version']; ?></div>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="img-list"><img class="screenshot" layer-src="<?php echo $theme['info']['screenshot']; ?>" data-original="<?php echo $theme['info']['screenshot']; ?>"></div>
|
||||
</div>
|
||||
<div class="layui-card-header" style="height: 1px;"></div>
|
||||
<div class="layui-card-header" style="height: auto;" id="article">
|
||||
<div class="layui-btn-group" id="<?php echo $key;?>">
|
||||
<?php
|
||||
if($online){ //如果是在线主题则显示下载
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" id="dw">下载</button>'."\n";
|
||||
}elseif($theme['info']['up'] == 1){ //如果有更新则同时显示下载和使用
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" id="up">更新</button>'."\n";
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" id="set">使用</button>'."\n";
|
||||
}else{ //其他情况仅显示使用
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" id="set">使用</button>'."\n";
|
||||
}
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="detail">详情</button>'."\n";
|
||||
if($theme['info']['config'] == '1'){ //支持配置的主题显示配置
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="config">配置</button>'."\n";
|
||||
}
|
||||
if($USER_DB['UserGroup'] === 'root' && !$online){ //管理员&本地主题>显示删除
|
||||
echo $Space.'<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" id="del">删除</button>'."\n";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--主题卡片End-->
|
||||
<?php }?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
|
||||
<script src = "<?php echo $libs;?>/jquery/jquery.lazyload.min.js"></script>
|
||||
<script src = "./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<?php load_static('js');?>
|
||||
<script>var datas = <?php echo json_encode($themes)?>;</script>
|
||||
<script src = "./templates/admin/js/theme.js?v=<?php echo $Ver;?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,6 +17,7 @@
|
||||
<a href="./index.php?c=admin&page=theme_home&cache=no&u=<?php echo U;?>" >刷新数据</a>
|
||||
<a href="javascript:;" layuimini-content-href="theme_login" data-title="登录模板">登录模板</a>
|
||||
<a href="javascript:;" layuimini-content-href="theme_transit" data-title="过渡模板">过渡模板</a>
|
||||
<a href="javascript:;" layuimini-content-href="theme_article" data-title="文章模板">文章模板</a>
|
||||
<?php if($USER_DB['UserGroup'] === 'root'){echo '<a href="javascript:;" layuimini-content-href="theme_register" data-title="注册模板">注册模板</a>';} ?>
|
||||
<?php if($USER_DB['UserGroup'] === 'root'){echo '<a href="javascript:;" layuimini-content-href="theme_guide" data-title="引导页模板">引导页模板</a>';} ?>
|
||||
</span>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php $title='过渡模板';$awesome=true; require 'header.php'; ?>
|
||||
<?php $title='过渡模板';$awesome=true; require 'header.php';
|
||||
$site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
|
||||
$tip = $site['link_model'] == 'Transition';
|
||||
?>
|
||||
<style type="text/css">
|
||||
.screenshot{
|
||||
width: 99%;
|
||||
@@ -15,7 +18,8 @@
|
||||
<blockquote class="layui-elem-quote layuimini-form" style="margin-top: 0px;border-left: 5px solid <?php echo $cache?"#1e9fff":($global_config['offline']?"":"#639d11") ?>;padding: 6px;">
|
||||
<span class="layui-breadcrumb" lay-separator="|">
|
||||
<a href="./index.php?c=admin&page=theme_transit&cache=no&u=<?php echo U;?>">刷新数据</a>
|
||||
<a href="javascript:;" layuimini-content-href="set_transit" data-title="设置过渡页面">设置</a>
|
||||
<a href="javascript:;" layuimini-content-href="set_transit" data-title="设置过渡页面">设置</a><?php if(!$tip){echo '
|
||||
<a href="javascript:;" layuimini-content-href="SiteSetting" data-title="站点设置">注:请将站点设置>链接模式>改为过渡页面</a>';}?>
|
||||
</span>
|
||||
</blockquote>
|
||||
<div class="layui-bg-gray" style="padding: 1px;" >
|
||||
|
||||
@@ -2,6 +2,239 @@
|
||||
<body>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main" style=" margin-left: 20px;">
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.36-20230823</h4>
|
||||
<ul>
|
||||
<li>[修复] 判断是否显示收录的逻辑错误(导致设为无需审核时不显示)</li>
|
||||
<li>[变更] 移除2个链接图标API,因稳定性欠佳</li>
|
||||
<li>[修复] WebStack-Hugo主页模板悬停提示不显示</li>
|
||||
<li>[新增] 挽风导航主页模板(内置文章模板/拟态风格),注:内置文章模板在预览状态下是不生效的!</li>
|
||||
<li>[新增] 挽风导航登录模板/过度模板</li>
|
||||
<li>[新增] 后台概要页可以点击报表统计获取访问的IP列表</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.35-20230816</h4>
|
||||
<ul>
|
||||
<li>[新增] Atool工具箱增加关闭OTP双重验证选项(删OTP),用于解决站长丢失OTP令牌造成无法登录</li>
|
||||
<li>[新增] 用户管理支持关闭OTP双重验证选项,用于站长帮助用户关闭OTP双重验证</li>
|
||||
<li>[优化] 邮件配置发送人只填发送人名称未按要求格式填写邮箱时由系统自动完成拼接</li>
|
||||
<li>[优化] 文章管理特定情况造成缺少资源时提醒用户如何解决</li>
|
||||
<li>[模板] 新增爱导航V1主页模板,轻量化设计简洁不卡顿/支持缓存/自适应/站内搜索,适合书签多的用户使用</li>
|
||||
<li>[模板] WebStack-Hugo主页模板新增:夜间背景图/炫彩横幅</li>
|
||||
<li>[模板] 修复默认过度模板兼容问题</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.34-20230809</h4>
|
||||
<ul>
|
||||
<li>[新增] 安全设置新增OTP双重验证</li>
|
||||
<li>[模板] 所有登录模板:已开启双重验证时,支持输入OTP验证码,版本:2.0.4 </li>
|
||||
<li>[警告] 如果您正在使用非默认登录模板,请立即更新登录模板,以免因模板不支持输入OTP验证码造成无法登录</li>
|
||||
<li>[新增] 导出导入>清空数据>支持清空文章和上传目录(upload)</li>
|
||||
<li>[新增] 导出导入>本地备份>支持备份和回滚文章列表</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.33-20230802</h4>
|
||||
<ul>
|
||||
<li>[新增] 文章编辑新增封面上传功能,插入网络视频功能</li>
|
||||
<li>[新增] 文章列表以链接的方式展现到主页( 已登录时显示公开和私有,未登录时显示公开文章 )</li>
|
||||
<li>[新增] 文章列表新增批量操作,支持批量删除,批量修改文章分类和状态</li>
|
||||
<li>[修复] 文章相关功能的已知问题</li>
|
||||
<li>[变更] 移除文章功能的独立分类机制,改为使用链接分类 ( 已存在的文章需手动更新分类 )</li>
|
||||
<li>[变更] API接口鉴权逻辑调整,新增几个兼容API,移除API模式中的兼容+开放模式</li>
|
||||
<li>[变更] 默认主页模板右键对查看全部或文章链接操作给出提示,给文章链接添加黑色角标</li>
|
||||
<li>[新增] 主页模板:简约主题 ( 需将安全设置>API模式>改为兼容模式才能使用全部功能 ) 作者:涂山</li>
|
||||
<li>[新增] 主页模板:花森主页( 自带文章浏览功能 ),作者:花森JioJio</li>
|
||||
<li>[新增] 文章模板:挽风导航,作者:凌云</li>
|
||||
<li>[优化] 默认文章模板样式</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.32-20230727</h4>
|
||||
<ul>
|
||||
<li>[新增] 扩展功能新增简易文章管理 [ 半成品,尚未完善 ]</li>
|
||||
<li>[新增] 链接自定义字段类型新增up_img,该类型支持上传1M大小的图片,权限与上传图标共享</li>
|
||||
<li>[新增] 链接自定义字段新增提示内容</li>
|
||||
<li>[变更] 主页模板前置处理,若模板支持链接扩展时提供扩展信息</li>
|
||||
<li>[跟进] 支持onenav新版浏览器插件的兼容</li>
|
||||
<li>[修复] ip统计存在异常的问题</li>
|
||||
<li>[修复] 上传链接图标后端接口未限制大小</li>
|
||||
<li>[修复] 在使用CDN的情况下可能出现授权验证问题</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.31-20230720</h4>
|
||||
<ul>
|
||||
<li>[新增] 支持统计访问IP数,可在后台概要页报表统计展示</li>
|
||||
<li>[新增] 数据库链接表新增关键字列</li>
|
||||
<li>[新增] 添加/编辑链接页面新增关键字输入,用于过渡页SEO优化 (注:230715之前的过度模板固定用链接标题作为关键字)</li>
|
||||
<li>[新增] 过度模板设置新增默认关键字选项 (针对未填写关键字时选择其他值作为关键字,需更新过度页模板)</li>
|
||||
<li>[新增] 链接列表新增识别按钮,用于批量获取URL的标题/描述/关键字/图标</li>
|
||||
<li>[新增] 系统设置中新增链接关键字长度限制</li>
|
||||
<li>[新增] 链接列表排序模式支持记忆到客户端</li>
|
||||
<li>[新增] 已开启链接扩展字段时,添加链接时支持填写扩展字段 (原仅编辑支持)</li>
|
||||
<li>[修复] 编辑链接时重置按钮未对扩展内容重置</li>
|
||||
<li>[优化] 添加/编辑链接页面识别功能支持关键字识别</li>
|
||||
<li>[优化] 链接列表的图标拉取与自动识别功能合并</li>
|
||||
<li>[优化] 链接识别的成功率</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.30-20230713</h4>
|
||||
<ul>
|
||||
<li>[修复] 登录接口的一个错误</li>
|
||||
<li>[优化] 图标配置页面新增清除缓存按钮,优化图标拉取功能的成功率</li>
|
||||
<li>[优化] 主题设置>过渡模板,当站点设置中链接模式不为过度页面时显示提示信息</li>
|
||||
<li>[新增] 后台概要页的报表统计支持选择最近7/14/30天的统计数据 (终端记忆)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.29-20230705</h4>
|
||||
<ul>
|
||||
<li>[升级] Layui v2.8.3 升级到 v2.8.10</li>
|
||||
<li>[修复] 全新安装v2.0.22 - v2.0.28,未创建图标缓存表导致图标拉取失败的bug <a href="https://gitee.com/tznb/TwoNav/releases/tag/v2.0.22-20230523" target="_blank">手动修复说明</a></li>
|
||||
<li>[变更] 默认设置和站长工具中邮件配置/图标配置,移入系统设置中</li>
|
||||
<li>[新增] Token页面新增使用说明</li>
|
||||
<li>[安全] 优化安全性,站长工具>phpinfo使用时需输入密码核验,并移除Cookie相关信息!</li>
|
||||
<li>[安全] 系统设置中长度限制改为相关限制,并加入默认用户组禁止使用自定义代码的开关!默认为禁止!并在开启时提示站长存在安全隐患!</li>
|
||||
<li>[安全] 系统安装后默认禁止注册,如需开启请在系统设置>注册配置>设为开放注册</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.28-20230624</h4>
|
||||
<ul>
|
||||
<li>[优化] 收录管理允许用户自行设置必填项</li>
|
||||
<li>[优化] 可添加的链接类型新增wsa和vmrc</li>
|
||||
<li>[优化] 站点设置中热门网址和最新网址由下拉选项改为直接输入,范围:0-100</li>
|
||||
<li>[修复] 分类列表无法查看加密分类的bug</li>
|
||||
<li>[模板] 主页模板 WebStack-Hugo, 修复开启拖拽排序造成悬停提示失效的bug,禁止拖拽查看全部</li>
|
||||
<li>[模板] 过度模板可能无法设置的bug</li>
|
||||
<li>[新增] 链接列表添加图标显示 (仅显示自定义图标,未定义时显示ie图标)</li>
|
||||
<li>[优化] 链接列表排序由前端当前页排序改为后端全局排序</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.27-20230618</h4>
|
||||
<ul>
|
||||
<li>[优化] 增加在线数据冗余线路,以适应更多环境</li>
|
||||
<li>[优化] 安装时检测是否存在不属于本程序的伪静态规则,存在时提醒用户处理</li>
|
||||
<li>[优化] 安装成功提示内容添加安全配置说明</li>
|
||||
<li>[新增] 站长工具新增连通测试,用于检测是否能与资源服务器连通! </li>
|
||||
<li>[模板] 主页模板 WebStack-Hugo, 新增拖拽排序支持(默认关闭),修复使用分类个性图标时无法定位分类,优化iframe的自适应</li>
|
||||
<li>[模板] 非默认登录模板无法登录的bug</li>
|
||||
<li>[修复] 过度页停留时间设置无效的bug</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.26-20230611</h4>
|
||||
<ul>
|
||||
<li>[新增] 后台页面右上角新增主页图标用于返回主页</li>
|
||||
<li>[修复] 后台左侧栏收起时无法使用二级菜单</li>
|
||||
<li>[修复] 申请收录无法提交,v2.0.24更新造成</li>
|
||||
<li>[修复] 二级密码输错时提示正确密码的bug</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.25-20230607</h4>
|
||||
<ul>
|
||||
<li>[修复] 默认设置>登录保持设为浏览器关闭时无法保存</li>
|
||||
<li>[修复] 导入OneNav Extend 升级数据时,如果description存在Null值造成导入失败</li>
|
||||
<li>[新增] 默认设置>可定义登录后进入后台还是主页 (注:此页面配置仅对新注册账号有效,不会修改现有用户的配置)</li>
|
||||
<li>[优化] 前端主题WebStack-Hugo的适配性</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.24-20230606</h4>
|
||||
<ul>
|
||||
<li>[修复] 调整数据库字段长度限制,使其能够正确记录IPV6地址/较长的浏览器UA ( 同时解决MySQL严格模式报错 )</li>
|
||||
<li>[修复] 放宽登录时UA长度限制,使其能够在腾讯系列APP(微信/QQ/QQ浏览器等)的内置浏览器登录程序</li>
|
||||
<li>[修复] 安全设置>登录保持设为浏览器关闭时无法保存</li>
|
||||
<li>[优化] 站长工具>生成伪静态,优化配置规则提高站点安全性 ( 需站长手动将新规则写入指定位置,仅针对Nginx环境 )</li>
|
||||
<li>[优化] 下载主题前检测目录是否可写,不可写时提醒用户</li>
|
||||
<li>[优化] 管理员登录后台时始终显示更新系统入口 ( 避免用户不知道在哪里更新系统 )</li>
|
||||
<li>[优化] 登录设备页面支持显示当前设备(字体为红色)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.23-20230527</h4>
|
||||
<ul>
|
||||
<li>[优化] 本地获取链接图标的成功率</li>
|
||||
<li>[优化] 链接列表图标拉取时检测是否符合拉取条件并提醒用户/无权限时不显示按钮</li>
|
||||
<li>[优化] 收录管理设置允许用户自定义提交限制</li>
|
||||
<li>[修复] 收录管理设为无需审核时无法自动通过</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.22-20230523</h4>
|
||||
<ul>
|
||||
<li>[升级] 更新数据库,增加图标缓存记录/用户组权限列表增加图标拉取</li>
|
||||
<li>[新增] 本地获取链接图标功能,功能在网站管理>站长工具>图标配置,开启并设置参数 [ 需授权 ]</li>
|
||||
<li>[新增] 链接列表新增图标拉取,用于下载链接图标到本地储存 [ 需授权 ]</li>
|
||||
<li>[修复] v2.0.21 安装页面异常导致无法安装的问题</li>
|
||||
<li>[修复] 本地备份在未使用过备份时导入,因未自动创建目录造成导入失败</li>
|
||||
<li>[修复] 升级layui导致的链接检测无法标记异常数据/扩展字段无法保存/用户组权限/书签分享等异常</li>
|
||||
<li>[优化] 导出导入页面自适应能力,移动端访问时不显示一键添加(因为不支持)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<h4 class="layui-timeline-title">v2.0.21-20230521</h4>
|
||||
<ul>
|
||||
<li>[修复] 升级Layui导致的分类/链接排序功能异常</li>
|
||||
<li>[修复] 升级Layui导致的主题设置异常,请更新主题 (影响范围:全新安装≥2.0.20)</li>
|
||||
<li>[优化] 删除链接/图标时若存在本地图标共用的情况则不删除图标</li>
|
||||
<li>[优化] 链接/收录列表,支持记忆筛选列 (浏览器本地储存)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
|
||||
53
templates/article/default/config.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title><?php echo $theme;?> - 主题配置</title>
|
||||
<link rel='stylesheet' href='<?php echo $layui['css']; ?>'>
|
||||
<style>
|
||||
.layui-form-item {margin-bottom: 10px;}
|
||||
</style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-row" style = "margin-top:18px;">
|
||||
<div class="layui-container">
|
||||
<div class="layui-col-lg8 layui-col-md-offset2">
|
||||
<form class="layui-form" lay-filter="form">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">最大宽度</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="container_width" placeholder="默认为空(全宽),输入格式80%或1280px" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="padding-top: 10px;">
|
||||
<div class="layui-input-block"><button class="layui-btn" lay-submit lay-filter="save">保存</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php echo $layui['js']; ?>"></script>
|
||||
<script src="./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
|
||||
<script>
|
||||
var u = _GET('u');
|
||||
layui.use(['form'], function(){
|
||||
var form = layui.form;var $ = layui.$;
|
||||
form.val('form', <?php echo json_encode($theme_config);?>);
|
||||
form.on('submit(save)', function(data){
|
||||
$.post(get_api('write_theme','config') + '&t=' + _GET('theme'),data.field,function(data,status){
|
||||
if(data.code == 1) {
|
||||
layer.msg(data.msg, {icon: 1,time: 500,end: function() {if(_GET('source') != 'admin'){parent.location.reload();}}});
|
||||
}else{
|
||||
layer.msg(data.msg, {icon: 5});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||