diff --git a/index.php b/index.php index 4dd89d0..9835507 100644 --- a/index.php +++ b/index.php @@ -40,7 +40,7 @@ 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"]); @@ -72,7 +72,7 @@ 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'])){ if($global_config['Maintenance'] != 0){Amsg(-1,'网站正在进行维护,请稍后再试!');} diff --git a/system/MySQL/20230522.php b/system/MySQL/20230522.php new file mode 100644 index 0000000..4dc3785 --- /dev/null +++ b/system/MySQL/20230522.php @@ -0,0 +1,23 @@ +$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']); +}else{ + msg(-1,'数据库更新失败'); +} diff --git a/system/SQLite/20230522.php b/system/SQLite/20230522.php new file mode 100644 index 0000000..780a7f5 --- /dev/null +++ b/system/SQLite/20230522.php @@ -0,0 +1,22 @@ +$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']); +}else{ + msg(-1,'数据库更新失败'); +} diff --git a/system/UseFew/local_backup.php b/system/UseFew/local_backup.php index b61736e..cc525e5 100644 --- a/system/UseFew/local_backup.php +++ b/system/UseFew/local_backup.php @@ -330,6 +330,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."/"; diff --git a/system/api.php b/system/api.php index fd933c1..0347407 100644 --- a/system/api.php +++ b/system/api.php @@ -674,40 +674,40 @@ 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'] === '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,'站点设置链接图标不能是离线图标!请先修改配置!'); + if(empty($_POST['cover']) && !empty($link['icon'])){ + msg(1,'skip');//跳过存在图标的链接 } - $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']; + $path = DIR ."/data/user/".U."/favicon"; + if(!Check_Path($path)){ + 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,'获取成功']); + $api = Get_Index_URL().'?c=icon&url='.base64_encode($link['url']); + $res = ccurl($api); + $data = get_db('global_icon','*',['url_md5'=>md5($link['url'])]); + if(empty($data)){ + msg(-1,'fail'); } - msg(-1,'获取失败'); + $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)){ @@ -952,7 +952,7 @@ 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'=>'最新链接参数错误'], diff --git a/system/api_root.php b/system/api_root.php index 67b1e25..8fe374b 100644 --- a/system/api_root.php +++ b/system/api_root.php @@ -718,6 +718,11 @@ function other_root(){ $_POST['Subject'] = 'TwoNav 测试邮件' . time(); $_POST['Body'] = '

TwoNav 测试邮件

' . 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,'保存成功'); } } diff --git a/system/icon.php b/system/icon.php new file mode 100644 index 0000000..2f45955 --- /dev/null +++ b/system/icon.php @@ -0,0 +1,296 @@ + "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 = 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))); + 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 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; +} diff --git a/system/public.php b/system/public.php index 24593e3..f73189d 100644 --- a/system/public.php +++ b/system/public.php @@ -536,17 +536,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{ diff --git a/system/templates.php b/system/templates.php index 7c7a8e6..a6fed41 100644 --- a/system/templates.php +++ b/system/templates.php @@ -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){ diff --git a/system/version.txt b/system/version.txt index a3035df..eaff14d 100644 --- a/system/version.txt +++ b/system/version.txt @@ -1 +1 @@ -v2.0.21-20230521 \ No newline at end of file +v2.0.22-20230523 \ No newline at end of file diff --git a/templates/admin/img/error.svg b/templates/admin/img/error.svg new file mode 100644 index 0000000..cabb0c9 --- /dev/null +++ b/templates/admin/img/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/file_bt.svg b/templates/admin/img/file_bt.svg new file mode 100644 index 0000000..5620f41 --- /dev/null +++ b/templates/admin/img/file_bt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/ftp.svg b/templates/admin/img/ftp.svg new file mode 100644 index 0000000..70e92c5 --- /dev/null +++ b/templates/admin/img/ftp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/ie.svg b/templates/admin/img/ie.svg new file mode 100644 index 0000000..2ea0535 --- /dev/null +++ b/templates/admin/img/ie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/magnet.svg b/templates/admin/img/magnet.svg new file mode 100644 index 0000000..41d0273 --- /dev/null +++ b/templates/admin/img/magnet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/tcpudp.svg b/templates/admin/img/tcpudp.svg new file mode 100644 index 0000000..7c32e14 --- /dev/null +++ b/templates/admin/img/tcpudp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/admin/img/xunlei.png b/templates/admin/img/xunlei.png new file mode 100644 index 0000000..161426d Binary files /dev/null and b/templates/admin/img/xunlei.png differ diff --git a/templates/admin/js/lay-module/tableSelect/tableSelect.js b/templates/admin/js/lay-module/tableSelect/tableSelect.js index 3e3a1ed..a34bc71 100644 --- a/templates/admin/js/lay-module/tableSelect/tableSelect.js +++ b/templates/admin/js/lay-module/tableSelect/tableSelect.js @@ -129,7 +129,7 @@ layui.define(['table', 'jquery', 'form'], function (exports) { for (var j=0;j= 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 + ' / ' + 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 + ' / ' + 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 ++; + } 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 = ''; @@ -468,7 +481,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]); } } diff --git a/templates/admin/page/SiteSetting.php b/templates/admin/page/SiteSetting.php index fa25d2e..3057d86 100644 --- a/templates/admin/page/SiteSetting.php +++ b/templates/admin/page/SiteSetting.php @@ -70,7 +70,8 @@
- - - - - - + + + + + + +
@@ -386,7 +388,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 +467,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 +477,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'} diff --git a/templates/admin/page/link_list.php b/templates/admin/page/link_list.php index 5c9e353..8a3d5fd 100644 --- a/templates/admin/page/link_list.php +++ b/templates/admin/page/link_list.php @@ -74,6 +74,7 @@ +
diff --git a/templates/admin/page/root/icon_set.php b/templates/admin/page/root/icon_set.php new file mode 100644 index 0000000..70e0cdc --- /dev/null +++ b/templates/admin/page/root/icon_set.php @@ -0,0 +1,125 @@ + + +
+
+
+
+
+ 1.此功能授权用户专享,请仔细阅读本页说明
+ 2.缓存时间视自身需求而定,希望及时更新则短一点(实际上站点很少会更新图标),建议值: 604800 (7天)
+ 3.修改缓存时间可能不会立即生效,因为浏览器已经缓存的图标会等过期后再刷新 (可以清理浏览器缓存来强制刷新)
+ 4.用户需在站点设置>链接图标>选择本地服务或本地服务(伪静态),后者需要从站长工具生成伪静态并正确配置
+ 5.站点处于维护模式/离线模式或下方全局开关处于关闭时调用此接口则返回默认图标
+ 6.当显示默认图标会忽略下方浏览器缓存时间的设置,时间将被设为60秒
+ 7.受限于网络的复杂性无法百分百获取成功,当获取失败时会显示默认图标 +
+ +
+ +
+ +
+
关闭时请求本地图标将得到默认图标
+
+
+ +
+ +
+
Referer防盗链,即来路检测
+
+
+ +
+ +
+
单位:秒,可节省服务器资源,值为0表示禁止缓存
+
+
+ +
+ +
+
单位:秒,可节省服务器资源,值为0表示禁止缓存
+
+
+ +
+ +
+
单位:秒,范围:3 - 20,默认6秒
+
+
+ +
+ +
+
单位:秒,范围:3 - 20,默认6秒
+
+
+ +
+ +
+
单位:KB,范围:5 - 1024,默认256
+
+
+ +
+ +
+
本地解析失败时尝试使用备选第三方API接口获取(由其他大佬提供)
+
+ +
+
+ +
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/templates/admin/page/root/tool.php b/templates/admin/page/root/tool.php index 5adedd8..efc31c0 100644 --- a/templates/admin/page/root/tool.php +++ b/templates/admin/page/root/tool.php @@ -28,6 +28,7 @@ require(dirname(__DIR__).'/header.php'); +
 1.功能都集中在上方的按钮了,需要那个就点击那个!
@@ -96,9 +97,11 @@ layui.use(['layer','form','miniTab'], function () {
         $("#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}(.+)/(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`);
+
     });
     //清理缓存
     $('.CleanCache').on('click', function(){
diff --git a/templates/admin/page/updatelog.php b/templates/admin/page/updatelog.php
index 948453f..fb474d6 100644
--- a/templates/admin/page/updatelog.php
+++ b/templates/admin/page/updatelog.php
@@ -2,6 +2,21 @@
 
 
+
  • + +
    +

    v2.0.22-20230523

    +
      +
    • [升级] 更新数据库,增加图标缓存记录/用户组权限列表增加图标拉取
    • +
    • [新增] 本地获取链接图标功能,功能在网站管理>站长工具>图标配置,开启并设置参数 [ 需授权 ]
    • +
    • [新增] 链接列表新增图标拉取,用于下载链接图标到本地储存 [ 需授权 ]
    • +
    • [修复] v2.0.21 安装页面异常导致无法安装的问题
    • +
    • [修复] 本地备份在未使用过备份时导入,因未自动创建目录造成导入失败
    • +
    • [修复] 升级layui导致的链接检测无法标记异常数据/扩展字段无法保存/用户组权限/书签分享等异常
    • +
    • [优化] 导出导入页面自适应能力,移动端访问时不显示一键添加(因为不支持)
    • +
    +
    +