Compare commits

...

6 Commits

Author SHA1 Message Date
MI15\Win
82e8321432 v2.0.28-20230624 2023-06-24 13:58:46 +08:00
MI15\Win
4bc10f7c25 v2.0.27-20230618 2023-06-18 21:28:30 +08:00
MI15\Win
65edb94998 v2.0.26-20230611 2023-06-11 18:20:56 +08:00
MI15\Win
1733e995d6 v2.0.25-20230607 2023-06-07 20:53:30 +08:00
MI15\Win
332cd313fb v2.0.24-20230605 2023-06-06 13:45:44 +08:00
MI15\Win
b6b0d7efe5 v2.0.23-20230527 2023-05-27 21:51:23 +08:00
35 changed files with 686 additions and 261 deletions

View File

@@ -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]

17
system/MySQL/20230605.php Normal file
View 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,'数据库更新失败');
}

View File

@@ -45,6 +45,7 @@ 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', '');
-- 创建用户表
DROP TABLE IF EXISTS `global_user`;
@@ -57,7 +58,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 '登陆配置',
@@ -130,8 +131,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 +146,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 +192,8 @@ INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
('guestbook', '留言板', '允许使用留言板功能'),
('link_extend', '链接扩展', '允许使用链接扩展字段'),
('theme_in', '主题设置', '后台显示主题设置菜单'),
('theme_set', '主题配置', '允许自定义主题配置');
('theme_set', '主题配置', '允许自定义主题配置'),
('icon_pull', '图标拉取', '允许用户拉取链接图标');
-- 注册码列表
DROP TABLE IF EXISTS `regcode_list`;
@@ -228,9 +230,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,7 +253,7 @@ 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 '私有可见',

View File

@@ -37,6 +37,8 @@ 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 ('20230605.php', '1685960298', 'TRUE', '');
-- 创建用户表
CREATE TABLE IF NOT EXISTS "global_user" (
@@ -48,7 +50,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,
@@ -107,8 +109,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 +122,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 +165,8 @@ INSERT INTO `purview_list` (`code`, `name`, `description`) VALUES
('guestbook', '留言板', '允许使用留言板功能'),
('link_extend', '链接扩展', '允许使用链接扩展字段'),
('theme_in', '主题设置', '后台显示主题设置菜单'),
('theme_set', '主题配置', '允许自定义主题配置');
('theme_set', '主题配置', '允许自定义主题配置'),
('icon_pull', '图标拉取', '允许用户拉取链接图标');
-- 注册码列表
CREATE TABLE IF NOT EXISTS "regcode_list" (
@@ -197,8 +200,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,7 +220,7 @@ 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"

View File

@@ -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,

View File

@@ -129,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(); //记录当前时间

View File

@@ -306,7 +306,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 +334,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]);
}
@@ -677,7 +683,7 @@ function write_link(){
//图标拉取
}elseif($_GET['type'] === 'icon_pull'){
if($global_config['offline']){
msg(-1,"离线模式禁止下载主题!");
msg(-1,"离线模式不可用");
}
if(!is_subscribe('bool')){
msg(-1,"未检测到有效授权,无法使用该功能!");
@@ -689,25 +695,32 @@ function write_link(){
if(empty($link)){
msg(-1,'请求的链接id不存在');
}
if(empty($_POST['cover']) && !empty($link['icon'])){
msg(1,'skip');//跳过存在图标的链接
}
$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,'相关服务处于关闭状态,请联系站长开启');
}
//跳过存在图标的链接
if(empty($_POST['cover']) && !empty($link['icon'])){
msg(1,'skip');
}
$api = Get_Index_URL().'?c=icon&url='.base64_encode($link['url']);
$res = ccurl($api);
$res = ccurl($api,30);
$data = get_db('global_icon','*',['url_md5'=>md5($link['url'])]);
if(empty($data)){
msg(-1,'fail');
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');
msg(1,'fail');
}elseif($_GET['type'] == 'extend_list'){
if($GLOBALS['global_config']['link_extend'] != 1 ||!check_purview('link_extend',1)){
@@ -759,7 +772,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清理时间不能大于登录保持时间');
}
@@ -813,11 +826,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'){ //通过
@@ -846,6 +867,7 @@ function write_apply(){
'url' => $link['url'],
'description' => $link['description'],
'add_time' => time(),
'up_time' => time(),
'icon' => $link['iconurl']
];
insert_db('user_links',$data);//插入链接
@@ -954,8 +976,8 @@ function write_site_setting(){
'main_link_priority'=>['int'=>true,'min'=>0,'max'=>3,'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]
@@ -1105,7 +1127,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]);
}
@@ -1125,6 +1147,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)){
@@ -1144,7 +1169,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/')){
@@ -1268,7 +1296,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);
//权重排序(数字小的排前面)
@@ -1277,7 +1305,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]);
}
//写登录信息
@@ -1432,7 +1463,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(in_array($USER_DB['UserGroup'] != 'root' && $_GET['type'],['diagnostic_log','connectivity_test','phpinfo'])){
msg(-1,'无权限');
}
@@ -1443,7 +1474,24 @@ 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);
$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(); //清除缓存

View File

@@ -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; //跳出循环.
@@ -537,6 +547,9 @@ function write_sys_settings(){
'global_header'=>['empty'=>true],
'global_footer'=>['empty'=>true],
'api_extend'=>['empty'=>true],
//更新设置
'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'=>'留言管理参数错误'],
@@ -574,7 +587,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 +596,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']){

View File

@@ -128,6 +128,9 @@ 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'])) {
$link['url_standby'] = unserialize($link['url_standby']);

View File

@@ -44,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,'网站描述不能为空!');
}
//获取和检查分类信息
@@ -84,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,'您提交的申请数量已达到上限!请明天再试!');
}
@@ -112,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

View File

@@ -82,9 +82,9 @@ $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';
//下载图标 > 成功则输出
@@ -184,6 +184,7 @@ function get_html($url,$TIMEOUT = 5){
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
}

View File

@@ -447,6 +447,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;
@@ -510,12 +529,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>'
});
}

View File

@@ -31,7 +31,7 @@ if(!isset($User)){
}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长度异常,请更换浏览器!");
}

View File

@@ -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验证

View File

@@ -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":

View File

@@ -1 +1 @@
v2.0.22-20230523
v2.0.28-20230624

View File

@@ -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;}

View File

@@ -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">

View File

@@ -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};
}
}
});
}
});
};

View File

@@ -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);">&nbsp;更新系统</span>');
$('#sysup').on('click', function(){
layer.alert("暂无可用更新,当前为最新版本",{icon:1,title:"更新系统",anim: "slideDown",shadeClose: true,closeBtn: 0,btn: ['知道了']});
});
}
//查看更新日志
$('#ver').css({"cursor":"pointer","color":"#01AAED"}); //设置鼠标形状和字体颜色

View File

@@ -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');

View File

@@ -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){
@@ -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(); //关闭当前标签(标签窗口)
}
}
});
@@ -206,7 +216,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() ) ;
}
}
}
@@ -228,4 +238,4 @@ function get_link_info() {
}
layer.close(load_index);
});
}
}

View File

@@ -9,6 +9,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
var api = get_api('read_link_list'); //列表接口
var limit = localStorage.getItem(u + "_limit") || 50; //尝试读取本地记忆数据,没有就默认50
var pwds = [];
var field,order;
miniTab.listen();
//渲染表格
renderTable1();
@@ -24,11 +25,11 @@ layui.use(['form','table','dropdown','miniTab'], function () {
}
});
}
var img_src;
var cols=[ //表头
{type:'checkbox'} //开启复选框
,{field: 'lid', title: 'ID', width:80, sort: true,hide:true}
,{field: 'category_name', title: '所属分类',sort:true,width:140,event: 'edit_category',templet:function(d){
,{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,24 +37,38 @@ 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);
@@ -122,6 +137,12 @@ layui.use(['form','table','dropdown','miniTab'], function () {
});
}
});
// 监听表格排序事件
table.on('sort(table)', function(obj) {
field = obj.field; // 排序字段
order = obj.type == null ? '' : obj.type.toUpperCase(); // 排序方式asc,desc转为大写,null则默认排序
link_search();
});
};
function link_search(){
@@ -136,7 +157,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
pageName: 'page' //页码的参数名称
,limitName: 'limit' //每页数据量的参数名
}
,where: {query:keyword,fid:fid,property:property,status:status}
,where: {query:keyword,fid:fid,property:property,status:status,field:field,order:order}
,page: {curr: 1}
});
}
@@ -278,6 +299,10 @@ layui.use(['form','table','dropdown','miniTab'], function () {
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);

View File

@@ -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: ['知道了']});
}
});
}

View File

@@ -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});
}
});
}
}
});

View File

@@ -84,31 +84,19 @@
</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">

View File

@@ -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>

View File

@@ -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.禁止含有特殊字符<'&">等 &nbsp; 2.SQL和XSS相关的敏感词 &nbsp; 3.限制超过256个字符 <br /> 4.提交限频:IP/24小时/5次 (删除记录可恢复)</div>
<div class="layui-form-mid ">1.禁止含有特殊字符<'&">等 &nbsp; 2.SQL和XSS相关的敏感词 &nbsp; 3.限制超过256个字符</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
@@ -340,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,

View File

@@ -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">

View File

@@ -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'])){
@@ -258,7 +271,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 +286,7 @@ require 'header.php';
</tr>
<tr>
<td>技术支持</td>
<td><a target="_blank" href="tencent://message/?uin=271152681">QQ271152681</a></td>
<td><a target="_blank" href="tencent://message/?uin=271152681">QQ271152681</a></td>
</tr>
<tr>
<td>专属地址</td>

View File

@@ -48,7 +48,7 @@
<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>
<table id="table" class="layui-table" lay-filter="table" style="margin: 1px 0;"></table>
</div>
</div>
<!-- 操作列 -->
@@ -74,8 +74,10 @@
<?php }?>
<?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>
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger layui-hide-xs" lay-event="icon_pull" id="icon_pull">图标拉取</button>
<?php }?>
<?php if($global_config['offline'] != 1 && check_purview('icon_pull',1)){ ?>
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger layui-hide-xs" lay-event="icon_pull" id="icon_pull">图标拉取</button>
<?php }?>
<button class="layui-btn layui-btn-sm layui-btn-normal layui-btn-danger" layuimini-content-href="link_sort" data-title="链接排序">排序模式</button>
</div>
</script>

View File

@@ -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>

View File

@@ -180,14 +180,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>
@@ -279,8 +300,6 @@ layui.use(['jquery','form'], function () {
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('submit(save)', function (data) {
$.post('./index.php?c=api&method=write_sys_settings&u='+u,data.field,function(data,status){
@@ -299,14 +318,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>

View File

@@ -18,6 +18,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>
@@ -75,6 +76,34 @@ 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(){
layer.open({
@@ -92,15 +121,16 @@ layui.use(['layer','form','miniTab'], function () {
$('.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}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; #HOST/USER\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`);
});
//清理缓存

View File

@@ -2,6 +2,88 @@
<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.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">