Browse Source

Merge pull request #81 from helloxz/dev

0.9.22
pull/90/head 0.9.22
xiaoz 2 years ago committed by GitHub
parent
commit
bffa08f710
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      README.md
  2. 379
      class/Api.php
  3. 14
      controller/admin.php
  4. 110
      controller/api.php
  5. 13
      data/update.log
  6. 3872
      static/bootstrap4/css/bootstrap-grid.css
  7. 1
      static/bootstrap4/css/bootstrap-grid.css.map
  8. 7
      static/bootstrap4/css/bootstrap-grid.min.css
  9. 1
      static/bootstrap4/css/bootstrap-grid.min.css.map
  10. 325
      static/bootstrap4/css/bootstrap-reboot.css
  11. 1
      static/bootstrap4/css/bootstrap-reboot.css.map
  12. 8
      static/bootstrap4/css/bootstrap-reboot.min.css
  13. 1
      static/bootstrap4/css/bootstrap-reboot.min.css.map
  14. 10315
      static/bootstrap4/css/bootstrap.css
  15. 1
      static/bootstrap4/css/bootstrap.css.map
  16. 7
      static/bootstrap4/css/bootstrap.min.css
  17. 1
      static/bootstrap4/css/bootstrap.min.css.map
  18. 6972
      static/bootstrap4/js/bootstrap.bundle.js
  19. 1
      static/bootstrap4/js/bootstrap.bundle.js.map
  20. 7
      static/bootstrap4/js/bootstrap.bundle.min.js
  21. 1
      static/bootstrap4/js/bootstrap.bundle.min.js.map
  22. 4357
      static/bootstrap4/js/bootstrap.js
  23. 1
      static/bootstrap4/js/bootstrap.js.map
  24. 7
      static/bootstrap4/js/bootstrap.min.js
  25. 1
      static/bootstrap4/js/bootstrap.min.js.map
  26. 487
      static/module/iconHhys/iconHhysFa.js
  27. 37
      templates/admin/add_category.php
  28. 70
      templates/admin/click.php
  29. 38
      templates/admin/edit_category.php
  30. 3
      templates/admin/header.php
  31. 7
      templates/admin/index.php
  32. 1
      templates/admin/left.php
  33. 2
      templates/admin/setting/site.php
  34. 231
      templates/admin/setting/subscribe.php
  35. 17
      templates/admin/setting/theme.php
  36. 30
      templates/admin/setting/transition_page.php
  37. 98
      templates/admin/static/embed.js
  38. 12
      templates/admin/static/style.css
  39. 2
      version.txt

9
README.md

@ -24,6 +24,7 @@ OneNav是一款开源免费的书签(导航)管理程序,由xiaoz使用使
* 支持uTools插件 * 支持uTools插件
* 支持二级分类 * 支持二级分类
* 支持Chromium内核的[浏览器扩展](https://dwz.ovh/4kxn2)(插件) * 支持Chromium内核的[浏览器扩展](https://dwz.ovh/4kxn2)(插件)
* 支持在线更新
## 安装 ## 安装
@ -39,11 +40,11 @@ OneNav是一款开源免费的书签(导航)管理程序,由xiaoz使用使
```bash ```bash
docker run -itd --name="onenav" -p 80:80 \ docker run -itd --name="onenav" -p 80:80 \
-v /data/onenav:/data/wwwroot/default/data \ -v /data/onenav:/data/wwwroot/default/data \
helloz/onenav:0.9.19 helloz/onenav:0.9.22
``` ```
* 第一个`80`是自定义访问端口,可以自行修改,第二个`80`是容器端口,请勿修改 * 第一个`80`是自定义访问端口,可以自行修改,第二个`80`是容器端口,请勿修改
* `/data/onenav`:本机挂载目录,用于持久存储Onenav数据 * `/data/onenav`:本机挂载目录,用于持久存储Onenav数据
* `0.9.19`:改成OneNav最新版本号,可以通过[releases](https://github.com/helloxz/onenav/releases)查看最新版本号 * `0.9.22`:改成OneNav最新版本号,可以通过[releases](https://github.com/helloxz/onenav/releases)查看最新版本号
> 更多说明,请参考帮助文档:https://dwz.ovh/onenav > 更多说明,请参考帮助文档:https://dwz.ovh/onenav
@ -58,8 +59,8 @@ docker run -itd --name="onenav" -p 80:80 \
## 联系我 ## 联系我
* Blog:https://www.xiaoz.me/ * Blog:https://www.xiaoz.me/
* QQ:337003006 * QQ:446199062
* QQ群:147687134 * QQ群:932795364
* 社区支持:[https://dwz.ovh/vd0bw](https://dwz.ovh/vd0bw) * 社区支持:[https://dwz.ovh/vd0bw](https://dwz.ovh/vd0bw)
## 鸣谢 ## 鸣谢

379
class/Api.php

@ -5,6 +5,7 @@
* author:xiaoz<xiaoz93@outlook.com> * author:xiaoz<xiaoz93@outlook.com>
* blog:xiaoz.me * blog:xiaoz.me
*/ */
define("API_URL","https://onenav.xiaoz.top");
class Api { class Api {
protected $db; protected $db;
public function __construct($db){ public function __construct($db){
@ -155,7 +156,7 @@ class Api {
* name:返回错误(json) * name:返回错误(json)
* *
*/ */
protected function err_msg($code,$err_msg){ public function err_msg($code,$err_msg){
$data = [ $data = [
'code' => $code, 'code' => $code,
'err_msg' => $err_msg 'err_msg' => $err_msg
@ -738,53 +739,81 @@ class Api {
$limit = $data['limit']; $limit = $data['limit'];
$token = $data['token']; $token = $data['token'];
$offset = ($data['page'] - 1) * $data['limit']; $offset = ($data['page'] - 1) * $data['limit'];
$fid = @$data['category_id']; //$fid = @$data['category_id'];
$count = $this->db->count('on_links','*');
//如果存在分类ID,则根据分类ID进行查询 //如果成功登录,但token为空
if ($data['category_id'] != null) { if( ($this->is_login()) && (empty($token)) ){
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
}
$cid_sql = "WHERE fid = $fid"; //如果token验证通过
//统计链接总数 elseif( (!empty($token)) && ($this->auth($token)) ) {
$count = $this->db->count('on_links','*',[ $sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
'fid' => $fid
]);
} }
//如果即没有登录成功,又没有token,则默认为游客,游客查询链接属性为公有,分类为公有,不查询私有
else{ else{
//统计链接总数,没有分类ID的情况 $c_sql = "SELECT COUNT(*) AS num FROM on_links WHERE property = 0 AND fid IN (SELECT id FROM on_categorys WHERE property = 0)";
$count = $this->db->count('on_links','*'); $count = $this->db->query($c_sql)->fetchAll()[0]['num'];
$count = intval($count);
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE property = 0 AND fid IN (SELECT id FROM on_categorys WHERE property = 0) ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
}
//原生查询
$datas = $this->db->query($sql)->fetchAll();
$datas = [
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $datas
];
exit(json_encode($datas));
}
/**
* 查询某个分类下面的链接
* 接收一个数组作为参数
*/
public function q_category_link($data){
$limit = $data['limit'];
$token = $data['token'];
$offset = ($data['page'] - 1) * $data['limit'];
$fid = @$data['category_id'];
//$fid = @$data['category_id'];
$count = $this->db->count('on_links','*',[
'fid' => $fid
]);
//如果FID是空的,则直接终止
if( empty($fid) ) {
$datas = [
'code' => -2000,
'msg' => '分类ID不能为空!',
'count' => 0,
'data' => []
];
exit(json_encode($datas));
} }
//如果成功登录,但token为空 //如果成功登录,但token为空
if( ($this->is_login()) && (empty($token)) ){ if( ($this->is_login()) && (empty($token)) ){
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}"; $sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE fid = $fid ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
} }
//如果token验证通过 //如果token验证通过
elseif( (!empty($token)) && ($this->auth($token)) ) { elseif( (!empty($token)) && ($this->auth($token)) ) {
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}"; $sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE fid = $fid ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
} }
//如果即没有登录成功,又没有token,则默认为游客 //如果即没有登录成功,又没有token,则默认为游客,游客查询链接属性为公有,分类为公有,不查询私有
else{ else{
$cid_sql = empty($fid) ? null : "AND fid = $fid"; $c_sql = "SELECT COUNT(*) AS num FROM on_links WHERE property = 0 AND fid = $fid";
if($cid_sql == null) { $count = $this->db->query($c_sql)->fetchAll()[0]['num'];
//统计链接总数,不存在分类ID的情况 $count = intval($count);
$count = $this->db->count('on_links','*',[ 'property' => 0 ]);
}
else{
//统计链接总数,存在分类ID的情况
$count = $this->db->count('on_links','*',[
'property' => 0,
'fid' => $fid
]);
}
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE property = 0 ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}"; $sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE property = 0 AND fid IN (SELECT id FROM on_categorys WHERE property = 0) ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
} }
//打印SQL
//echo $sql;
//如果查询的总数大于limit,则以limit为准
//$count = ( $count > $limit) ? $limit : $count;
//原生查询 //原生查询
$datas = $this->db->query($sql)->fetchAll(); $datas = $this->db->query($sql)->fetchAll();
@ -810,6 +839,16 @@ class Api {
//var_dump($link_info); //var_dump($link_info);
//如果是公开链接,则直接返回 //如果是公开链接,则直接返回
if ( $link_info['property'] == "0" ) { if ( $link_info['property'] == "0" ) {
//链接是公开的,但是分类是私有的,则不显示
$category_property = $this->db->get("on_categorys","property",[
"id" => $link_info['fid']
]);
$category_property = intval($category_property);
//分类属性为1,则说明是私有链接,则未认证用户不允许查询
if( $category_property === 1 ){
//进行认证
$this->auth($token);
}
$datas = [ $datas = [
'code' => 0, 'code' => 0,
'data' => $link_info 'data' => $link_info
@ -1162,6 +1201,64 @@ class Api {
$this->err_msg(-2000,"写入配置失败!"); $this->err_msg(-2000,"写入配置失败!");
} }
} }
/**
* 删除主题
*/
public function delete_theme($name) {
//验证授权
$this->auth($token);
//正则判断主题名称是否合法
$pattern = "/^[a-zA-Z0-9][a-zA-Z0-9-_]+[a-zA-Z0-9]$/";
if ( !preg_match($pattern,$name) ) {
$this->return_json(-2000,'',"主题名称不合法!");
}
//如果是默认主题,则不允许删除
if( ($name === 'default') || ($name === 'admin') ) {
$this->return_json(-2000,'',"默认主题不允许删除!");
}
//查询当前使用中的主题
$current_theme = $this->db->get('on_options','value',[ 'key' => "theme" ]);
//如果是当前使用中的主题也不允许删除
if ( $current_theme == $name ) {
$this->return_json(-2000,'',"使用中的主题不允许删除!");
}
//删除主题
$this->deldir("templates/".$name);
$this->deldir("data/templates/".$name);
//判断主题文件夹是否还存在
if( is_dir("templates/".$name) || is_dir("data/templates/".$name) ) {
$this->return_json(-2000,'',"删除失败,可能是权限不足!");
}
else{
$this->return_json(200,'',"主题已删除!");
}
}
/**
* 删除一个目录
*/
protected function deldir($dir) {
//先删除目录下的文件:
$dh=opendir($dir);
while ($file=readdir($dh)) {
if($file!="." && $file!="..") {
$fullpath=$dir."/".$file;
if(!is_dir($fullpath)) {
unlink($fullpath);
} else {
$this->deldir($fullpath);
}
}
}
closedir($dh);
//删除当前文件夹:
if(rmdir($dir)) {
return true;
} else {
return false;
}
}
/** /**
* 获取主题参数 * 获取主题参数
*/ */
@ -1319,6 +1416,224 @@ class Api {
$status = $this->is_login() ? "true" : "false"; $status = $this->is_login() ? "true" : "false";
$this->return_json(200,$status,""); $this->return_json(200,$status,"");
} }
/**
* 验证订阅是否有效
*/
public function check_subscribe() {
//验证token是否合法
$this->auth($token);
//获取订阅信息
//获取当前站点信息
$subscribe = $this->db->get('on_options','value',[ 'key' => "s_subscribe" ]);
$domain = $_SERVER['HTTP_HOST'];
$subscribe = unserialize($subscribe);
//api请求地址
$api_url = API_URL."/v1/check_subscribe.php?order_id=".$subscribe['order_id']."&email=".$subscribe['email']."&domain=".$domain;
try {
#GET HTTPS
$curl = curl_init($api_url);
#设置useragent
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36");
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
#设置超时时间,最小为1s(可选)
curl_setopt($curl , CURLOPT_TIMEOUT, 30);
$html = curl_exec($curl);
curl_close($curl);
//解析json
$data = json_decode($html);
//var_dump($data->data->end_time);
//echo strtotime($data->data->end_time);
//var_dump($data->code);
//如果状态码返回200,并且订阅没有到期
if( (intval($data->code) === 200) && ( $data->data->end_time > ( strtotime( date("Y-m-d",time()) ) )) ) {
$this->return_json(200,$data->data,'success');
}
else if( intval($data->code === -1000 ) ) {
$this->return_json(-2000,'',$data->msg);
}
else{
$this->return_json(-2000,'',"请求接口失败,请重试!");
}
} catch (\Throwable $th) {
$this->return_json(-2000,'','网络请求失败,请重试!');
}
}
/**
* 验证订阅是否存在
*/
public function is_subscribe() {
//获取订阅SESSION状态
session_start();
//获取session订阅状态
$is_subscribe = $_SESSION['subscribe'];
//如果订阅是空的,则请求接口获取订阅状态
if ( !isset($is_subscribe) ) {
//获取当前站点信息
$subscribe = $this->db->get('on_options','value',[ 'key' => "s_subscribe" ]);
$domain = $_SERVER['HTTP_HOST'];
$subscribe = unserialize($subscribe);
//api请求地址
$api_url = API_URL."/v1/check_subscribe.php?order_id=".$subscribe['order_id']."&email=".$subscribe['email']."&domain=".$domain;
try {
#GET HTTPS
$curl = curl_init($api_url);
#设置useragent
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36");
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
#设置超时时间,最小为1s(可选)
curl_setopt($curl , CURLOPT_TIMEOUT, 30);
$html = curl_exec($curl);
curl_close($curl);
//解析json
$data = json_decode($html);
//var_dump($data->data->end_time);
//echo strtotime($data->data->end_time);
//var_dump($data->code);
//如果状态码返回200,并且订阅没有到期
if( (intval($data->code) === 200) && ( $data->data->end_time > ( strtotime( date("Y-m-d",time()) ) )) ) {
$_SESSION['subscribe'] = TRUE;
return TRUE;
}
else if( intval($data->code === -1000 ) ) {
$_SESSION['subscribe'] = FALSE;
return FALSE;
}
else{
$_SESSION['subscribe'] = NULL;
}
} catch (\Throwable $th) {
$_SESSION['subscribe'] = NULL;
}
}
if( $is_subscribe == TRUE ) {
return TRUE;
}
else{
return FALSE;
}
}
/**
* 无脑下载更新程序
*/
public function down_updater() {
$url = API_URL."/update.tar.gz";
// echo $url;
// exit;
try {
//检查本地是否存在更新程序
$curl = curl_init($url);
#设置useragent
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36");
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
#设置超时时间,最小为1s(可选)
curl_setopt($curl , CURLOPT_TIMEOUT, 60);
$html = curl_exec($curl);
curl_close($curl);
//var_dump($html);
//return $html;
//写入文件
file_put_contents("update.tar.gz",$html);
//解压覆盖文件
//解压文件
$phar = new PharData('update.tar.gz');
//路径 要解压的文件 是否覆盖
$phar->extractTo('./', null, true);
return TRUE;
} catch (\Throwable $th) {
$this->return_json(-2000,"","更新程序下载失败!");
}
finally{
//再次判断更新程序是否存在
if( is_file("update.php") ) {
//判断是否大约0
$file_size = filesize("update.php");
if( $file_size < 100 ) {
$this->return_json(-2000,"","更新程序异常,请检查目录权限!");
}
else{
return TRUE;
}
}
else{
$this->return_json(-2000,"","更新程序下载失败,请检查目录权限!");
}
}
}
/**更新升级程序 */
public function up_updater() {
//如果不存在,则下载更新程序
if( !is_file("update.php") ) {
if ( $this->down_updater() ) {
$this->return_json(200,"","更新程序准备就绪!");
}
}
//如果存在更新程序,验证大小,大小不匹配时进行更新
if( is_file("update.tar.gz") ) {
//获取header头
$header = get_headers(API_URL."/update.tar.gz",1);
$lentgh = $header['Content-Length'];
//获取文件大小
$file_size = filesize("update.tar.gz");
//如果本地文件大小和远程文件大小不一致,则下载更新
if ( $file_size != $lentgh ) {
if ( $this->down_updater() ) {
//更新完毕后提示
$this->return_json(200,"","更新程序更新完毕!");
}
else{
$this->return_json(-2000,"","更新程序下载失败,请检查目录权限!");
}
}
else {
$this->return_json(200,"","更新程序(压缩包)准备就绪!");
}
}
else if( is_file("update.php") ) {
$this->return_json(200,"","更新程序(PHP)准备就绪!");
}
else{
$this->return_json(200,"","更新程序(其它)准备就绪!");
}
}
/**
* 校验更新程序
*/
public function check_version($version) {
//获取当前版本信息
$current_version = explode("-",file_get_contents("version.txt"));
$current_version = str_replace("v","",$current_version[0]);
//获取用户传递的版本
//$version = $_REQUEST['version'];
if( $version == $current_version ) {
$this->return_json(200,"","success");
}
else{
$this->return_json(-2000,"","更新失败,版本校验不匹配,请检查目录权限!");
}
}
} }

14
controller/admin.php

@ -241,6 +241,20 @@ if( $page == 'setting/site' ) {
$site = unserialize($site); $site = unserialize($site);
} }
//站点订阅页面
if( $page == 'setting/subscribe' ) {
//获取当前站点信息
$subscribe = $db->get('on_options','value',[ 'key' => "s_subscribe" ]);
$subscribe = unserialize($subscribe);
//获取当前版本信息
$current_version = explode("-",file_get_contents("version.txt"));
$current_version = str_replace("v","",$current_version[0]);
}
//过渡页设置页面 //过渡页设置页面
if( $page == 'setting/transition_page' ) { if( $page == 'setting/transition_page' ) {
//获取当前站点信息 //获取当前站点信息

110
controller/api.php

@ -46,6 +46,10 @@ function add_category($api){
$description = htmlspecialchars($description); $description = htmlspecialchars($description);
//获取字体图标 //获取字体图标
$font_icon = htmlspecialchars($_POST['font_icon'],ENT_QUOTES); $font_icon = htmlspecialchars($_POST['font_icon'],ENT_QUOTES);
//搜索字体图标是否包含'fa ',如果不包含则自动加上
if( !strstr($font_icon,'fa ') ) {
$font_icon = 'fa '.$font_icon;
}
$api->add_category($token,$name,$property,$weight,$description,$font_icon,$fid); $api->add_category($token,$name,$property,$weight,$description,$font_icon,$fid);
} }
/** /**
@ -70,6 +74,10 @@ function edit_category($api){
$description = htmlspecialchars($description); $description = htmlspecialchars($description);
//字体图标 //字体图标
$font_icon = htmlspecialchars($_POST['font_icon'],ENT_QUOTES); $font_icon = htmlspecialchars($_POST['font_icon'],ENT_QUOTES);
//搜索字体图标是否包含'fa ',如果不包含则自动加上
if( !strstr($font_icon,'fa ') ) {
$font_icon = 'fa '.$font_icon;
}
$api->edit_category($token,$id,$name,$property,$weight,$description,$font_icon,$fid); $api->edit_category($token,$id,$name,$property,$weight,$description,$font_icon,$fid);
} }
/** /**
@ -160,6 +168,25 @@ function link_list($api){
$api->link_list($data); $api->link_list($data);
} }
/**
* 查询分类下的链接
*/
function q_category_link($api){
$page = empty(intval($_REQUEST['page'])) ? 1 : intval($_REQUEST['page']);
$limit = empty(intval($_REQUEST['limit'])) ? 10 : intval($_REQUEST['limit']);
//获取token
$token = $_POST['token'];
//获取分类ID
$category_id = empty($_REQUEST['category_id']) ? null : intval($_REQUEST['category_id']);
$data = [
'page' => $page,
'limit' => $limit,
'token' => $token,
'category_id' => $category_id
];
$api->q_category_link($data);
}
/** /**
* 获取链接标题、描述等信息 * 获取链接标题、描述等信息
*/ */
@ -277,10 +304,72 @@ function set_site($api) {
//序列化存储 //序列化存储
$value = serialize($data); $value = serialize($data);
if( !empty($data['custom_footer']) ) {
if( !$api->is_subscribe() ) {
$api->err_msg(-2000,'保存失败,自定义footer需要订阅用户才能使用,若未订阅请留空!');
}
}
$api->set_option('s_site',$value); $api->set_option('s_site',$value);
} }
//阻止非订阅用户保存设置
function _deny_set($content,$err_msg) {
global $api;
//验证订阅,返回TRUE或FALSE
if ( !isset($_SESSION['subscribe']) ) {
//验证订阅,返回TRUE或FALSE
$result = $api->is_subscribe();
}
//如果内容是空的,直接允许
if ( empty($content) ) {
return TRUE;
}
else{
if( $_SESSION['subscribe'] === TRUE ) {
return TRUE;
}
else{
$api->err_msg(-2000,$err_msg);
}
}
}
//设置订阅信息
function set_subscribe($api) {
//获取订单ID
$data['order_id'] = htmlspecialchars( trim($_REQUEST['order_id']) );
//获取邮箱
$data['email'] = htmlspecialchars( trim($_REQUEST['email']) );
//到期时间
$data['end_time'] = htmlspecialchars( trim($_REQUEST['end_time']) );
//重置订阅状态
session_start();
$_SESSION['subscribe'] = NULL;
//序列化存储
$value = serialize($data);
//序列化存储到数据库
$api->set_option('s_subscribe',$value);
}
//检查订阅信息
function check_subscribe($api) {
$api->check_subscribe();
}
//检查更新程序
function up_updater($api) {
$api->up_updater();
}
//验证当前版本是否匹配
function check_version($api) {
$version = $_REQUEST['version'];
$api->check_version($version);
}
//设置过渡页面 //设置过渡页面
function set_transition_page($api) { function set_transition_page($api) {
//获取传递过来的参数 //获取传递过来的参数
@ -290,10 +379,25 @@ function set_transition_page($api) {
$data['visitor_stay_time'] = intval($_POST['visitor_stay_time']); $data['visitor_stay_time'] = intval($_POST['visitor_stay_time']);
//获取管理员停留时间 //获取管理员停留时间
$data['admin_stay_time'] = intval($_POST['admin_stay_time']); $data['admin_stay_time'] = intval($_POST['admin_stay_time']);
//获取菜单
$data['menu'] = $_POST['menu'];
//获取footer
$data['footer'] = $_POST['footer'];
//获取广告
$data['a_d_1'] = $_POST['a_d_1'];
$data['a_d_2'] = $_POST['a_d_2'];
//验证订阅
_deny_set($data['menu'],'保存失败,过渡页菜单需要订阅用户才能使用!');
_deny_set($data['footer'],'保存失败,自定义footer需要订阅用户才能使用!');
_deny_set($data['a_d_1'],'保存失败,自定义广告需要订阅用户才能使用!');
_deny_set($data['a_d_2'],'保存失败,自定义广告需要订阅用户才能使用!');
//序列化存储 //序列化存储
$value = serialize($data); $value = serialize($data);
$api->set_option('s_transition_page',$value); $api->set_option('s_transition_page',$value);
} }
@ -408,3 +512,9 @@ EOF;
function check_login($api) { function check_login($api) {
$api->check_login(); $api->check_login();
} }
//删除主题
function delete_theme($api) {
$name = $_REQUEST['name'];
$api->delete_theme($name);
}

13
data/update.log

@ -117,3 +117,16 @@ CREATE INDEX on_options_key_IDX ON on_options ("key");
20220513 20220513
1. 主题分类排序优化 1. 主题分类排序优化
2. 修改分类优化 2. 修改分类优化
20220525
1. 修复link_list和get_a_link可以查询私有分类下的公有链接问题
2. 新增查询指定分类下的链接接口:q_category_link
3. 新增主题删除功能
20220527
1. 新增订阅后在线更新
20220601
1. 过渡页面完善
2. 新增分类字体图标选择
3. 修复360 LJ浏览器登录自动切换内核问题

3872
static/bootstrap4/css/bootstrap-grid.css vendored

File diff suppressed because it is too large Load Diff

1
static/bootstrap4/css/bootstrap-grid.css.map

File diff suppressed because one or more lines are too long

7
static/bootstrap4/css/bootstrap-grid.min.css vendored

File diff suppressed because one or more lines are too long

1
static/bootstrap4/css/bootstrap-grid.min.css.map

File diff suppressed because one or more lines are too long

325
static/bootstrap4/css/bootstrap-reboot.css vendored

@ -0,0 +1,325 @@
/*!
* Bootstrap Reboot v4.6.1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
[role="button"] {
cursor: pointer;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

1
static/bootstrap4/css/bootstrap-reboot.css.map

File diff suppressed because one or more lines are too long

8
static/bootstrap4/css/bootstrap-reboot.min.css vendored

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.6.1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

1
static/bootstrap4/css/bootstrap-reboot.min.css.map

File diff suppressed because one or more lines are too long

10315
static/bootstrap4/css/bootstrap.css vendored

File diff suppressed because it is too large Load Diff

1
static/bootstrap4/css/bootstrap.css.map

File diff suppressed because one or more lines are too long

7
static/bootstrap4/css/bootstrap.min.css vendored

File diff suppressed because one or more lines are too long

1
static/bootstrap4/css/bootstrap.min.css.map

File diff suppressed because one or more lines are too long

6972
static/bootstrap4/js/bootstrap.bundle.js

File diff suppressed because it is too large Load Diff

1
static/bootstrap4/js/bootstrap.bundle.js.map

File diff suppressed because one or more lines are too long

7
static/bootstrap4/js/bootstrap.bundle.min.js vendored

File diff suppressed because one or more lines are too long

1
static/bootstrap4/js/bootstrap.bundle.min.js.map

File diff suppressed because one or more lines are too long

4357
static/bootstrap4/js/bootstrap.js vendored

File diff suppressed because it is too large Load Diff

1
static/bootstrap4/js/bootstrap.js.map

File diff suppressed because one or more lines are too long

7
static/bootstrap4/js/bootstrap.min.js vendored

File diff suppressed because one or more lines are too long

1
static/bootstrap4/js/bootstrap.min.js.map

File diff suppressed because one or more lines are too long

487
static/module/iconHhys/iconHhysFa.js

@ -0,0 +1,487 @@
/**
* iconHhysFa 1.0 字体图标选择
* User: jackhhy
* Date: 2020/06/23-11:09
* Link: https://gitee.com/luckygyl/iconFonts
*/
layui.define(['laypage', 'form'], function (exports) {
"use strict";
var IconHhys =function () {
this.v = '1.0';
}, _MOD = 'iconHhysFa',
_this = this,
$ = layui.jquery,
laypage = layui.laypage,
form = layui.form,
BODY = 'body',
TIPS = '请选择图标';
/**
* 渲染组件
*/
IconHhys.prototype.render = function (options) {
var opts = options,
// DOM选择器
elem = opts.elem,
// 数据类型:fontClass/awesome
type = opts.type == null ? 'fontClass' : opts.type,
//当数据类型为awesome 的时候 需要配置 url
url = opts.url ,
// 是否分页:true/false
page = opts.page == null ? true : opts.page,
// 每页显示数量
limit = opts.limit == null ? 12 : opts.limit,
// 是否开启搜索:true/false
search = opts.search == null ? true : opts.search,
// 每个图标格子的宽度:'43px'或'20%'
cellWidth = opts.cellWidth == null ? '20%':opts.cellWidth,
// 点击回调
click = opts.click,
// 渲染成功后的回调
success = opts.success,
// json数据
data = {},
value = opts.value == null ? '' : opts.value,
// 唯一标识
tmp = new Date().getTime(),
// 初始化时input的值
ORIGINAL_ELEM_VALUE = value,
TITLE = 'layui-select-title',
TITLE_ID = 'layui-select-title-' + tmp,
ICON_BODY = 'layui-iconpicker-' + tmp,
PICKER_BODY = 'layui-iconpicker-body-' + tmp,
PAGE_ID = 'layui-iconpicker-page-' + tmp,
LIST_BOX = 'layui-iconpicker-list-box',
selected = 'layui-form-selected',
unselect = 'layui-unselect';
var a = {
init: function () {
if (type.indexOf("fontClass") > -1){
data = common.getfont[type]();
}else{
data = common.getData(url);
}
a.hideElem().createSelect().createBody().toggleSelect();
a.preventEvent().inputListen();
common.loadCss();
if (success) {
success(this.successHandle());
}
return a;
},
successHandle: function () {
var d = {
options: opts,
data: data,
id: tmp,
elem: $('#' + ICON_BODY)
};
return d;
},
/**
* 隐藏elem
*/
hideElem: function () {
$(elem).hide();
return a;
},
/**
* 绘制select下拉选择框
*/
createSelect: function () {
if (type.indexOf("fontClass") > -1){
var oriIcon = '<i class="layui-icon">';
// 默认图标
if(ORIGINAL_ELEM_VALUE === '') {
ORIGINAL_ELEM_VALUE = 'layui-icon-circle-dot';
}
oriIcon = '<i class="layui-icon '+ ORIGINAL_ELEM_VALUE +'">';
oriIcon += '</i>';
var selectHtml = '<div class="layui-iconpicker layui-unselect layui-form-select" id="'+ ICON_BODY +'">' +
'<div class="'+ TITLE +'" id="'+ TITLE_ID +'">' +
'<div class="layui-iconpicker-item">'+
'<span class="layui-iconpicker-icon layui-unselect">' +
oriIcon +
'</span>'+
'<i class="layui-edge"></i>' +
'</div>'+
'</div>' +
'<div class="layui-anim layui-anim-upbit" style="">' +
'123' +
'</div>';
$(elem).after(selectHtml);
return a;
}else{
var oriIcon = '<i class="fa">';
// 默认图标
if (ORIGINAL_ELEM_VALUE === '') {
ORIGINAL_ELEM_VALUE = 'fa-adjust';
}
oriIcon = '<i class="fa ' + ORIGINAL_ELEM_VALUE + '">';
oriIcon += '</i>';
var selectHtml = '<div class="layui-iconpicker layui-unselect layui-form-select" id="' + ICON_BODY + '">' +
'<div class="' + TITLE + '" id="' + TITLE_ID + '">' +
'<div class="layui-iconpicker-item">' +
'<span class="layui-iconpicker-icon layui-unselect">' +
oriIcon +
'</span>' +
'<i class="layui-edge"></i>' +
'</div>' +
'</div>' +
'<div class="layui-anim layui-anim-upbit" style="">' +
'123' +
'</div>';
$(elem).after(selectHtml);
return a;
}
},
/**
* 展开/折叠下拉框
*/
toggleSelect: function () {
var item = '#' + TITLE_ID + ' .layui-iconpicker-item,#' + TITLE_ID + ' .layui-iconpicker-item .layui-edge';
a.event('click', item, function (e) {
var $icon = $('#' + ICON_BODY);
if ($icon.hasClass(selected)) {
$icon.removeClass(selected).addClass(unselect);
} else {
// 隐藏其他picker
$('.layui-form-select').removeClass(selected);
// 显示当前picker
$icon.addClass(selected).removeClass(unselect);
}
e.stopPropagation();
});
return a;
},
/**
* 绘制主体部分
*/
createBody: function () {
// 获取数据
var searchHtml = '';
if (search) {
searchHtml = '<div class="layui-iconpicker-search">' +
'<input class="layui-input">' +
'<i class="layui-icon">&#xe615;</i>' +
'</div>';
}
// 组合dom
var bodyHtml = '<div class="layui-iconpicker-body" id="'+ PICKER_BODY +'">' +
searchHtml +
'<div class="'+ LIST_BOX +'"></div> '+
'</div>';
$('#' + ICON_BODY).find('.layui-anim').eq(0).html(bodyHtml);
a.search().createList().check().page();
return a;
},
/**
* 绘制图标列表
* @param text 模糊查询关键字
* @returns {string}
*/
createList: function (text) {
var d = data,
l = d.length,
pageHtml = '',
listHtml = $('<div class="layui-iconpicker-list">')//'<div class="layui-iconpicker-list">';
// 计算分页数据
var _limit = limit, // 每页显示数量
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1), // 总计多少页
_id = PAGE_ID;
// 图标列表
var icons = [];
for (var i = 0; i < l; i++) {
var obj = d[i];
// 判断是否模糊查询
if (text && obj.indexOf(text) === -1) {
continue;
}
// 是否自定义格子宽度
var style = '';
if (cellWidth !== null) {
style += ' style="width:' + cellWidth + '"';
}
// 每个图标dom
var icon = '<div class="layui-iconpicker-icon-item" title="'+ obj +'" '+ style +'>';
if(type.indexOf("fontClass") >-1){
icon += '<i class="layui-icon '+ obj +'"></i>';
}else {
icon += '<i class="fa ' + obj + '"></i>';
}
icon += '</div>';
icons.push(icon);
}
// 查询出图标后再分页
l = icons.length;
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1);
for (var i = 0; i < _pages; i++) {
// 按limit分块
var lm = $('<div class="layui-iconpicker-icon-limit" id="layui-iconpicker-icon-limit-' + tmp + (i+1) +'">');
for (var j = i * _limit; j < (i+1) * _limit && j < l; j++) {
lm.append(icons[j]);
}
listHtml.append(lm);
}
// 无数据
if (l === 0) {
listHtml.append('<p class="layui-iconpicker-tips">无数据</p>');
}
// 判断是否分页
if (page){
$('#' + PICKER_BODY).addClass('layui-iconpicker-body-page');
pageHtml = '<div class="layui-iconpicker-page" id="'+ PAGE_ID +'">' +
'<div class="layui-iconpicker-page-count">' +
'<span id="'+ PAGE_ID +'-current">1</span>/' +
'<span id="'+ PAGE_ID +'-pages">'+ _pages +'</span>' +
' (<span id="'+ PAGE_ID +'-length">'+ l +'</span>)' +
'</div>' +
'<div class="layui-iconpicker-page-operate">' +
'<i class="layui-icon" id="'+ PAGE_ID +'-prev" data-index="0" prev>&#xe603;</i> ' +
'<i class="layui-icon" id="'+ PAGE_ID +'-next" data-index="2" next>&#xe602;</i> ' +
'</div>' +
'</div>';
}
$('#' + ICON_BODY).find('.layui-anim').find('.' + LIST_BOX).html('').append(listHtml).append(pageHtml);
return a;
},
// 阻止Layui的一些默认事件
preventEvent: function() {
var item = '#' + ICON_BODY + ' .layui-anim';
a.event('click', item, function (e) {
e.stopPropagation();
});
return a;
},
// 分页
page: function () {
var icon = '#' + PAGE_ID + ' .layui-iconpicker-page-operate .layui-icon';
$(icon).unbind('click');
a.event('click', icon, function (e) {
var elem = e.currentTarget,
total = parseInt($('#' +PAGE_ID + '-pages').html()),
isPrev = $(elem).attr('prev') !== undefined,
// 按钮上标的页码
index = parseInt($(elem).attr('data-index')),
$cur = $('#' +PAGE_ID + '-current'),
// 点击时正在显示的页码
current = parseInt($cur.html());
// 分页数据
if (isPrev && current > 1) {
current=current-1;
$(icon + '[prev]').attr('data-index', current);
} else if (!isPrev && current < total){
current=current+1;
$(icon + '[next]').attr('data-index', current);
}
$cur.html(current);
// 图标数据
$('#'+ ICON_BODY + ' .layui-iconpicker-icon-limit').hide();
$('#layui-iconpicker-icon-limit-' + tmp + current).show();
e.stopPropagation();
});
return a;
},
/**
* 搜索
*/
search: function () {
var item = '#' + PICKER_BODY + ' .layui-iconpicker-search .layui-input';
a.event('input propertychange', item, function (e) {
var elem = e.target,
t = $(elem).val();
a.createList(t);
});
return a;
},
/**
* 点击选中图标
*/
check: function () {
if(type.indexOf("fontClass") >-1){
var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item';
a.event('click', item, function (e) {
var el = $(e.currentTarget).find('.layui-icon'),
icon = '';
var clsArr = el.attr('class').split(/[\s\n]/),
cls = clsArr[1],
icon = cls;
$('#' + TITLE_ID).find('.layui-iconpicker-item .layui-icon').html('').attr('class', clsArr.join(' '));
$('#' + ICON_BODY).removeClass(selected).addClass(unselect);
$(elem).val(icon).attr('value', icon);
// 回调
if (click) {
click({
icon: icon
});
}
});
}else{
var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item';
a.event('click', item, function (e) {
var el = $(e.currentTarget).find('.fa'),
icon = '';
var clsArr = el.attr('class').split(/[\s\n]/),
cls = clsArr[1],
icon = cls;
$('#' + TITLE_ID).find('.layui-iconpicker-item .fa').html('').attr('class', clsArr.join(' '));
$('#' + ICON_BODY).removeClass(selected).addClass(unselect);
$(elem).val(icon).attr('value', icon);
// 回调
if (click) {
click({
icon: icon
});
}
});
}
return a;
},
// 监听原始input数值改变
inputListen: function(){
var el = $(elem);
a.event('change', elem, function(){
var value = el.val();
})
// el.change(function(){
// });
return a;
},
event: function (evt, el, fn) {
$(BODY).on(evt, el, fn);
}
};
var common = {
/**
* 加载样式表
*/
loadCss: function () {
var css = '.layui-iconpicker {max-width: 280px;}.layui-iconpicker .layui-anim{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box;}.layui-iconpicker-item{border:1px solid #e6e6e6;width:90px;height:36px;border-radius:4px;cursor:pointer;position:relative;}.layui-iconpicker-icon{border-right:1px solid #e6e6e6;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;width:60px;height:100%;float:left;text-align:center;background:#fff;transition:all .3s;}.layui-iconpicker-icon i{line-height:38px;font-size:18px;}.layui-iconpicker-item > .layui-edge{left:70px;}.layui-iconpicker-item:hover{border-color:#D2D2D2!important;}.layui-iconpicker-item:hover .layui-iconpicker-icon{border-color:#D2D2D2!important;}.layui-iconpicker.layui-form-selected .layui-anim{display:block;}.layui-iconpicker-body{padding:6px;}.layui-iconpicker .layui-iconpicker-list{background-color:#fff;border:1px solid #ccc;border-radius:4px;}.layui-iconpicker .layui-iconpicker-icon-item{display:inline-block;width:21.1%;line-height:36px;text-align:center;cursor:pointer;vertical-align:top;height:36px;margin:4px;border:1px solid #ddd;border-radius:2px;transition:300ms;}.layui-iconpicker .layui-iconpicker-icon-item i.layui-icon{font-size:17px;}.layui-iconpicker .layui-iconpicker-icon-item:hover{background-color:#eee;border-color:#ccc;-webkit-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;-moz-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;box-shadow:0 0 2px #aaa,0 0 2px #fff inset;text-shadow:0 0 1px #fff;}.layui-iconpicker-search{position:relative;margin:0 0 6px 0;border:1px solid #e6e6e6;border-radius:2px;transition:300ms;}.layui-iconpicker-search:hover{border-color:#D2D2D2!important;}.layui-iconpicker-search .layui-input{cursor:text;display:inline-block;width:86%;border:none;padding-right:0;margin-top:1px;}.layui-iconpicker-search .layui-icon{position:absolute;top:11px;right:4%;}.layui-iconpicker-tips{text-align:center;padding:8px 0;cursor:not-allowed;}.layui-iconpicker-page{margin-top:6px;margin-bottom:-6px;font-size:12px;padding:0 2px;}.layui-iconpicker-page-count{display:inline-block;}.layui-iconpicker-page-operate{display:inline-block;float:right;cursor:default;}.layui-iconpicker-page-operate .layui-icon{font-size:12px;cursor:pointer;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit{display:none;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit:first-child{display:block;}';
var $style = $('head').find('style[iconpicker]');
if ($style.length === 0) {
$('head').append('<style rel="stylesheet" iconpicker>'+css+'</style>');
}
},
/**
* 获取数据
*/
getfont: {
fontClass: function () {
var arr = ["layui-icon-rate-half","layui-icon-rate","layui-icon-rate-solid","layui-icon-cellphone","layui-icon-vercode","layui-icon-login-wechat","layui-icon-login-qq","layui-icon-login-weibo","layui-icon-password","layui-icon-username","layui-icon-refresh-3","layui-icon-auz","layui-icon-spread-left","layui-icon-shrink-right","layui-icon-snowflake","layui-icon-tips","layui-icon-note","layui-icon-home","layui-icon-senior","layui-icon-refresh","layui-icon-refresh-1","layui-icon-flag","layui-icon-theme","layui-icon-notice","layui-icon-website","layui-icon-console","layui-icon-face-surprised","layui-icon-set","layui-icon-template-1","layui-icon-app","layui-icon-template","layui-icon-praise","layui-icon-tread","layui-icon-male","layui-icon-female","layui-icon-camera","layui-icon-camera-fill","layui-icon-more","layui-icon-more-vertical","layui-icon-rmb","layui-icon-dollar","layui-icon-diamond","layui-icon-fire","layui-icon-return","layui-icon-location","layui-icon-read","layui-icon-survey","layui-icon-face-smile","layui-icon-face-cry","layui-icon-cart-simple","layui-icon-cart","layui-icon-next","layui-icon-prev","layui-icon-upload-drag","layui-icon-upload","layui-icon-download-circle","layui-icon-component","layui-icon-file-b","layui-icon-user","layui-icon-find-fill","layui-icon-loading","layui-icon-loading-1","layui-icon-add-1","layui-icon-play","layui-icon-pause","layui-icon-headset","layui-icon-video","layui-icon-voice","layui-icon-speaker","layui-icon-fonts-del","layui-icon-fonts-code","layui-icon-fonts-html","layui-icon-fonts-strong","layui-icon-unlink","layui-icon-picture","layui-icon-link","layui-icon-face-smile-b","layui-icon-align-left","layui-icon-align-right","layui-icon-align-center","layui-icon-fonts-u","layui-icon-fonts-i","layui-icon-tabs","layui-icon-radio","layui-icon-circle","layui-icon-edit","layui-icon-share","layui-icon-delete","layui-icon-form","layui-icon-cellphone-fine","layui-icon-dialogue","layui-icon-fonts-clear","layui-icon-layer","layui-icon-date","layui-icon-water","layui-icon-code-circle","layui-icon-carousel","layui-icon-prev-circle","layui-icon-layouts","layui-icon-util","layui-icon-templeate-1","layui-icon-upload-circle","layui-icon-tree","layui-icon-table","layui-icon-chart","layui-icon-chart-screen","layui-icon-engine","layui-icon-triangle-d","layui-icon-triangle-r","layui-icon-file","layui-icon-set-sm","layui-icon-add-circle","layui-icon-404","layui-icon-about","layui-icon-up","layui-icon-down","layui-icon-left","layui-icon-right","layui-icon-circle-dot","layui-icon-search","layui-icon-set-fill","layui-icon-group","layui-icon-friends","layui-icon-reply-fill","layui-icon-menu-fill","layui-icon-log","layui-icon-picture-fine","layui-icon-face-smile-fine","layui-icon-list","layui-icon-release","layui-icon-ok","layui-icon-help","layui-icon-chat","layui-icon-top","layui-icon-star","layui-icon-star-fill","layui-icon-close-fill","layui-icon-close","layui-icon-ok-circle","layui-icon-add-circle-fine"];
return arr;
}
},
/**
* 获取数据
*/
getData: function (url) {
var iconlist = [];
$.ajax({
url: url,
type: 'get',
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
async: false,
success: function (ret) {
var exp = /fa-var-(.*):/ig;
var result;
while ((result = exp.exec(ret)) != null) {
iconlist.push('fa-' + result[1]);
}
},
error: function (xhr, textstatus, thrown) {
layer.msg('fa图标接口有误');
}
});
return iconlist;
}
};
a.init();
return new IconHhys();
}
/**
* 选中图标
* @param filter lay-filter
* @param iconName 图标名称自动识别fontClass/unicode
*/
/** IconHhys.prototype.checkIcon = function (filter, iconName){
var el = $('*[lay-filter='+ filter +']'),
p = el.next().find('.layui-iconpicker-item .layui-icon'),
c = iconName;
if (c.indexOf('#xe') > -1){
p.html(c);
} else {
p.html('').attr('class', 'layui-icon ' + c);
}
el.attr('value', c).val(c);
};*/
/**
* 选中图标auwosome
* @param filter lay-filter
* @param iconName 图标名称自动识别fontClass/unicode
*/
/** IconHhys.prototype.checkAwesome = function (filter, iconName) {
var el = $('*[lay-filter=' + filter + ']'),
p = el.next().find('.layui-iconpicker-item .fa'),
c = iconName;
if (c.indexOf('#xe') > 0) {
p.html(c);
} else {
p.html('').attr('class', 'fa ' + c);
}
el.attr('value', c).val(c);
};*/
var iconHhys = new IconHhys();
exports(_MOD, iconHhys);
});

37
templates/admin/add_category.php

@ -21,10 +21,10 @@
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">字体图标</label> <label for="" class="layui-form-label">字体图标</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="font_icon" placeholder="请输入字体图标,如:fa fa-bookmark-o" autocomplete="off" class="layui-input"> <input name="font_icon" type="text" id="iconHhys2" value="" lay-filter="iconHhys2" class="layui-input">
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
@ -74,3 +74,32 @@
</div> </div>
<?php include_once('footer.php'); ?> <?php include_once('footer.php'); ?>
<script>
//参考:https://gitee.com/luckygyl/iconFonts
layui.use(['iconHhysFa'], function(){
var iconHhysFa = layui.iconHhysFa;
iconHhysFa.render({
// 选择器,推荐使用input
elem: '#iconHhys2',
// 数据类型:fontClass/awesome,推荐使用fontClass
type: 'awesome',
// 是否开启搜索:true/false
search: true,
// fa 图标接口
url: './static/font-awesome/4.7.0/less/variables.less',
// 是否开启分页
page: true,
// 每页显示数量,默认12
limit: 30,
// 点击回调
value:'fa-bookmark-o', //自定义默认图标
click: function(data) {
console.log(data);
},
// 渲染成功后的回调
success: function(d) {
console.log(d);
}
});
})
</script>

70
templates/admin/click.php

@ -2,11 +2,13 @@
<html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml"> <html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title><?php echo $link['title']; ?> - OneNav</title> <title><?php echo $link['title']; ?> - <?php echo $site['title']; ?></title>
<meta name="keywords" content="<?php echo $link['title']; ?>" /> <meta name="keywords" content="<?php echo $link['title']; ?>" />
<meta name="description" content="<?php echo $link['description']; ?>" /> <meta name="description" content="<?php echo $link['description']; ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://lib.sinaapp.com/js/bootstrap/4.3.1/css/bootstrap.min.css" type="" media=""/> <link rel="stylesheet" href="static/bootstrap4/css/bootstrap.min.css" type="" media=""/>
<script src = "static/js/jquery.min.js"></script>
<script src="static/bootstrap4/js/bootstrap.min.js"></script>
<style> <style>
.prevent-overflow{ .prevent-overflow{
width:260px; width:260px;
@ -14,6 +16,15 @@
white-space: nowrap;/*不换行*/ white-space: nowrap;/*不换行*/
text-overflow:ellipsis;/*超出部分文字以...显示dsds*/ text-overflow:ellipsis;/*超出部分文字以...显示dsds*/
} }
.a_d img{
max-width:100%;
padding-top:1em;
padding-bottom:1em;
}
#menu{
width:100%;
background-color: #343a40!important;
}
</style> </style>
<?php echo $site['custom_header']; ?> <?php echo $site['custom_header']; ?>
<?php <?php
@ -35,7 +46,37 @@
?> ?>
</head> </head>
<body> <body>
<div id="menu">
<div class="container">
<div class = "row">
<div class="col-sm-8 offset-sm-2">
<!-- 顶部导航菜单 -->
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<a class="navbar-brand" href="/"><?php echo $site['title']; ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<!-- 输出自定义菜单 -->
<?php echo $transition_page['menu']; ?>
<!-- 输出自定义菜单END -->
</ul>
</div>
</nav>
<!-- 顶部导航菜单END -->
</div>
</div>
</div>
</div>
<div class="container" style = "margin-top:2em;"> <div class="container" style = "margin-top:2em;">
<!-- 广告1 -->
<div class= "row">
<div class="col-sm-8 offset-sm-2 a_d">
<?php echo $transition_page['a_d_1']; ?>
</div>
</div>
<!-- 广告1 END -->
<div class="row"> <div class="row">
<div class="col-sm-8 offset-sm-2"> <div class="col-sm-8 offset-sm-2">
<!-- 新建一个表格 --> <!-- 新建一个表格 -->
@ -44,7 +85,7 @@
<tbody> <tbody>
<tr class="table-info"> <tr class="table-info">
<td>标题</td> <td width="170">标题</td>
<td><?php echo $link['title']; ?></td> <td><?php echo $link['title']; ?></td>
</tr> </tr>
@ -96,10 +137,29 @@
<div class="xcdn-content"> <div class="xcdn-content">
<?php echo $msg; ?> <?php echo $msg; ?>
</div> </div>
<hr>
<div class="xcdn-footer">&copy;2022 Powered by <a href="https://www.xiaoz.me/" title = "小z博客" rel = "nofollow" target = "_blank">xiaoz</a></div>
</div> </div>
</div> </div>
<!-- 广告2 -->
<div class= "row">
<div class="col-sm-8 offset-sm-2 a_d">
<?php echo $transition_page['a_d_2']; ?>
</div>
</div>
<!-- 广告2 END -->
<!-- 底部footer -->
<div class = "row">
<div class="col-sm-8 offset-sm-2">
<hr>
<div class="xcdn-footer">
<?php if( empty($site['custom_footer']) ){ ?>
&copy;2022 Powered by <a href="https://www.xiaoz.me/" title = "小z博客" rel = "nofollow" target = "_blank">xiaoz</a>
<?php }else{
echo $site['custom_footer'];
} ?>
</div>
</div>
</div>
<!-- 底部footer end -->
</div> </div>
</body> </body>
</html> </html>

38
templates/admin/edit_category.php

@ -59,11 +59,18 @@
</div> </div>
</div> </div>
<div class="layui-form-item"> <!-- <div class="layui-form-item">
<label class="layui-form-label">字体图标</label> <label class="layui-form-label">字体图标</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="font_icon" value = '<?php echo $category_one['font_icon']; ?>' placeholder="请输入字体图标,如:fa fa-bookmark-o" autocomplete="off" class="layui-input"> <input type="text" name="font_icon" value = '<?php echo $category_one['font_icon']; ?>' placeholder="请输入字体图标,如:fa fa-bookmark-o" autocomplete="off" class="layui-input">
</div> </div>
</div> -->
<div class="layui-form-item">
<label for="" class="layui-form-label">字体图标:</label>
<div class="layui-input-block">
<input name="font_icon" type="text" id="iconHhys2" value="<?php echo $category_one['font_icon']; ?>" lay-filter="iconHhys2" class="layui-input">
</div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
@ -100,3 +107,32 @@
</div> </div>
<?php include_once('footer.php'); ?> <?php include_once('footer.php'); ?>
<script>
//参考:https://gitee.com/luckygyl/iconFonts
layui.use(['iconHhysFa'], function(){
var iconHhysFa = layui.iconHhysFa;
iconHhysFa.render({
// 选择器,推荐使用input
elem: '#iconHhys2',
// 数据类型:fontClass/awesome,推荐使用fontClass
type: 'awesome',
// 是否开启搜索:true/false
search: true,
// fa 图标接口
url: './static/font-awesome/4.7.0/less/variables.less',
// 是否开启分页
page: true,
// 每页显示数量,默认12
limit: 30,
// 点击回调
value:'<?php echo str_replace("fa ","",$category_one["font_icon"]); ?>', //自定义默认图标
click: function(data) {
console.log(data);
},
// 渲染成功后的回调
success: function(d) {
console.log(d);
}
});
})
</script>

3
templates/admin/header.php

@ -3,9 +3,12 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit"/>
<meta name="force-rendering" content="webkit"/>
<title>OneNav后台管理</title> <title>OneNav后台管理</title>
<link rel='stylesheet' href='static/layui/css/layui.css'> <link rel='stylesheet' href='static/layui/css/layui.css'>
<link rel='stylesheet' href='templates/admin/static/style.css?v=<?php echo $version; ?>'> <link rel='stylesheet' href='templates/admin/static/style.css?v=<?php echo $version; ?>'>
<link rel="stylesheet" href="static/font-awesome/4.7.0/css/font-awesome.css">
</head> </head>
<body class="layui-layout-body"> <body class="layui-layout-body">
<div class="layui-layout layui-layout-admin"> <div class="layui-layout layui-layout-admin">

7
templates/admin/index.php

@ -13,7 +13,10 @@
</div> </div>
</div> </div>
<div class="layui-col-lg4"> <div class="layui-col-lg4">
<div class = "admin-msg">最新版本:<span><span id = "getting">获取中...</span><a href = "https://github.com/helloxz/onenav/releases" title = "下载最新版OneNav" target = "_blank" id="latest_version"></a></span></div> <div class = "admin-msg">
最新版本:<span><span id = "getting">获取中...</span><a href = "https://github.com/helloxz/onenav/releases" title = "下载最新版OneNav" target = "_blank" id="latest_version"></a></span>
(<a href="/index.php?c=admin&page=setting/subscribe" title = "订阅后可一键更新">一键更新</a>)
</div>
</div> </div>
<div class="layui-col-lg4"> <div class="layui-col-lg4">
<div class = "admin-msg">QQ群1:147687134</div> <div class = "admin-msg">QQ群1:147687134</div>
@ -31,7 +34,7 @@
<div class = "admin-msg">帮助文档:<a href="https://dwz.ovh/onenav" rel = "nofollow" target="_blank">https://dwz.ovh/onenav</a></div> <div class = "admin-msg">帮助文档:<a href="https://dwz.ovh/onenav" rel = "nofollow" target="_blank">https://dwz.ovh/onenav</a></div>
</div> </div>
<div class="layui-col-lg4"> <div class="layui-col-lg4">
<div class = "admin-msg">QQ:337003006</div> <div class = "admin-msg">QQ:446199062</div>
</div> </div>
<div class="layui-col-lg4"> <div class="layui-col-lg4">
<div class = "admin-msg">Blog: <a href="https://www.xiaoz.me/" rel = "nofollow" target="_blank">https://www.xiaoz.me/</a></div> <div class = "admin-msg">Blog: <a href="https://www.xiaoz.me/" rel = "nofollow" target="_blank">https://www.xiaoz.me/</a></div>

1
templates/admin/left.php

@ -27,6 +27,7 @@
<li class="layui-nav-item layui-nav-itemed"> <li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">系统设置</a> <a class="" href="javascript:;">系统设置</a>
<dl class="layui-nav-child"> <dl class="layui-nav-child">
<dd><a href="/index.php?c=admin&page=setting/subscribe">订阅 & 更新</a></dd>
<dd><a href="/index.php?c=admin&page=setting/site">站点设置</a></dd> <dd><a href="/index.php?c=admin&page=setting/site">站点设置</a></dd>
<dd><a href="/index.php?c=admin&page=setting/theme">主题设置</a></dd> <dd><a href="/index.php?c=admin&page=setting/theme">主题设置</a></dd>
<dd><a href="/index.php?c=admin&page=setting/transition_page">过渡页面</a></dd> <dd><a href="/index.php?c=admin&page=setting/transition_page">过渡页面</a></dd>

2
templates/admin/setting/site.php

@ -59,7 +59,7 @@
</div> </div>
<div class="layui-form-item layui-form-text"> <div class="layui-form-item layui-form-text">
<label class="layui-form-label">自定义footer</label> <label class="layui-form-label">自定义footer(支持HTML代码,订阅可用)</label>
<div class="layui-input-block"> <div class="layui-input-block">
<textarea name = "custom_footer" placeholder="自定义站点底部信息,请填写HTML代码" class="layui-textarea"><?php echo $site['custom_footer']; ?></textarea> <textarea name = "custom_footer" placeholder="自定义站点底部信息,请填写HTML代码" class="layui-textarea"><?php echo $site['custom_footer']; ?></textarea>
</div> </div>

231
templates/admin/setting/subscribe.php

@ -0,0 +1,231 @@
<!-- 站点设置 -->
<!-- 主题设置 -->
<?php require_once(dirname(__DIR__).'/header.php'); ?>
<?php include_once(dirname(__DIR__).'/left.php'); ?>
<div class="layui-body">
<!-- 内容主体区域 -->
<div class="layui-row content-body place-holder" style="padding-bottom: 3em;">
<!-- 说明提示框 -->
<div class="layui-col-lg12">
<div class="setting-msg">
<ol>
<li>您可以前往:<a href="https://dwz.ovh/69h9q" rel = "nofollow" target = "_blank" title = "购买订阅服务">https://dwz.ovh/69h9q</a> 购买订阅服务,订阅后可以:</li>
<li>1. 享受一键更新OneNav</li>
<li>2. 可在线更新和下载主题(实现中...)</li>
<li>3. 可享受一对一售后服务(仅限高级版和商业版)</li>
<li>4. 可帮助OneNav持续发展,让OneNav变得更加美好</li>
<li>5. 更多高级功能(自定义版权、广告管理等)</li>
</ol>
</div>
</div>
<!-- 说明提示框END -->
<!-- 订阅表格 -->
<div class="layui-col-lg6">
<h2 style = "margin-bottom:1em;">我的订阅:</h2>
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<label class="layui-form-label">订单号</label>
<div class="layui-input-block">
<input type="text" id = "order_id" name="order_id" value = "<?php echo $subscribe['order_id']; ?>" required lay-verify="required" autocomplete="off" placeholder="请输入订单号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">订阅邮箱</label>
<div class="layui-input-block">
<input type="email" name="email" id = "email" value = "<?php echo $subscribe['email']; ?>" required lay-verify="required|email" autocomplete="off" placeholder="订阅邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item" style = "display:none;">
<label class="layui-form-label">域名</label>
<div class="layui-input-block">
<input type="text" name="domain" id = "domain" value = "<?php echo $_SERVER['HTTP_HOST']; ?>" autocomplete="off" placeholder="网站域名" 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="end_time" id = "end_time" readonly="readonly" value = "<?php echo date("Y-m-d",$subscribe['end_time']); ?>" autocomplete="off" placeholder="订阅到期时间" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" lay-submit="" lay-filter="set_subscribe">保存设置</button>
<button class="layui-btn" lay-submit="" lay-filter="reset_subscribe">删除订阅</button>
<a class="layui-btn layui-btn-danger" rel = "nofollow" target = "_blank" title = "点此购买订阅" href="https://dwz.ovh/69h9q"><i class="fa fa-shopping-cart"></i> 购买订阅</a>
</div>
</form>
</div>
<!-- 订阅表格END -->
<hr>
<div class="layui-col-lg12">
<!-- <h3>更新</h3> -->
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">当前版本</label>
<div class="layui-input-inline">
<input type="text" readonly = "readonly" id = "current_version" name="current_version" value = "<?php echo $current_version; ?>" required lay-verify="required" autocomplete="off" placeholder="当前版本" class="layui-input">
</div>
<label class="layui-form-label">可用版本</label>
<div class="layui-input-inline">
<input type="text" readonly = "readonly" name="new_version" id = "new_version" value = "" required lay-verify="required" autocomplete="off" placeholder="无可用版本" class="layui-input">
</div>
</div>
</div>
</form>
<div class="layui-input-inline">
<button id = "btn_update" class="layui-btn" lay-submit="" onclick = "update_main()">立即更新</button>
<button id = "btn_updating" style = "display:none;" class="layui-btn layui-btn-disabled" >更新中,请勿关闭窗口</button>
<a href="https://dwz.ovh/7q4z6" title = "点此查看更新失败的原因" rel = "nofollow" target = "_blank">更新失败?</a>
</div>
<!-- 更新进度条 -->
<div id="progress">
<div class="layui-progress layui-progress-big" lay-filter="update_progress" lay-showPercent="true">
<div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div>
</div>
<div id="msg" style = "margin-top:1em;"></div>
</div>
<!-- 更新进度条END -->
</div>
<!-- 日志面板 -->
<div class="layui-col-lg12" style = "margin-top:1em;">
<div class="layui-collapse">
<div class="layui-colla-item">
<h2 class="layui-colla-title">日志输出:</h2>
<div class="layui-colla-content">
<div id = "update_log"></div>
</div>
</div>
</div>
<!-- 日志面板END -->
</div>
</div>
<?php include_once(dirname(__DIR__).'/footer.php'); ?>
<script>
//获取可更新版本
function available_version() {
var current_version = $("#current_version").val();
$.get("https://onenav.xiaoz.top/v1/get_version.php",{version:current_version},function(data,status){
$("#new_version").val(data);
});
}
available_version();
//立即更新按钮
function update_main() {
//清空日志面板
var update_log = $("#update_log").html();
var current_version = $("#current_version").val();
var new_version = $("#new_version").val();
//如果当前版本和最新版本相同,则不能更新
if (current_version >= new_version) {
layer.msg("已经是最新版本,无需更新!",{icon:5});
return false;
}
//如果可用版本为空
if ( new_version == '' ) {
layer.msg("无可用版本,无需更新!",{icon:5});
return false;
}
//否则可以更新
else {
$("#btn_update").hide();
$("#btn_updating").show();
update_status("1%","准备更新...");
$("#update_log").append("准备更新...\n");
//第一步检查更新信息
$.get("/index.php?c=api&method=check_subscribe",function(data,status){
update_status("10%","正在验证订阅信息...");
$("#update_log").append("正在验证订阅信息...<br />");
if( data.code == 200 ) {
update_status("30%","订阅信息验证通过...");
$("#update_log").append("订阅信息验证通过...<br />");
//取得必要的变量
var email = data.data.email;
var domain = data.data.domain;
var key = data.data.key;
var value = data.data.value;
//下载更新程序
$.get("/index.php?c=api&method=up_updater",function(data,status) {
update_status("50%","正在检查更新程序...");
$("#update_log").append("正在检查更新程序...<br />");
if( data.code == 200 ) {
//继续往下执行
update_status("70%","更新程序准备完成...");
$("#update_log").append("更新程序准备完成...<br />");
//准备下载升级包
update_status("80%","准备下载升级包...");
$("#update_log").append("准备下载升级包...<br />");
$.get("/update.php",{version:new_version,key:key,value:value,type:'main'},function(data,stauts){
update_status("90%","升级包下载完毕,正在校验版本...");
$("#update_log").append("升级包下载完毕,正在校验版本...<br />");
if( data.code == 200 ) {
//校验新版本
$.get("/index.php?c=api&method=check_version",{version:new_version},function(data,status){
if(data.code == 200) {
update_status("100%","更新完成,请前往后台检查<a href = '/index.php?c=admin'>更新数据库</a>!");
$("#update_log").append("更新完成,请前往后台检查<a href = '/index.php?c=admin'>更新数据库</a><br />");
//$("#btn_update").show();
//$("#btn_updating").hide();
$("#btn_updating").show();
}
else {
update_error(data.msg);
//layer.msg(data.msg,{icon:5,time: 0});
}
});
}
else{
update_error(data.msg);
//layer.msg(data.msg,{icon:5,time: 0});
}
});
}
else {
update_error(data.msg);
//layer.msg(data.msg,{icon:5,time: 0});
}
});
}
else{
update_error(data.msg);
//layer.msg(data.msg,{icon:5,time: 0});
}
});
}
}
//进度和更新提示函数
function update_status(progress,msg) {
layui.use('element', function(){
var element = layui.element;
$("#progress").show();
element.progress('update_progress', progress);
$("#msg").html(msg);
});
}
//更新失败时的提示
function update_error(msg) {
layer.open({
title: '更新失败:'
,content: msg
,icon:5
});
$("#progress").hide();
$("#btn_update").show();
$("#btn_updating").hide();
}
</script>

17
templates/admin/setting/theme.php

@ -17,21 +17,24 @@
//var_dump($theme['info']->name); //var_dump($theme['info']->name);
?> ?>
<!-- 主题列表 --> <!-- 主题列表 -->
<div class="layui-col-lg3"> <div class="layui-col-lg3 layui-col-md6 layui-col-sm12">
<fieldset style = "padding:1em;border:0px;height:170px;border:1px dashed #1E9FFF;box-shadow: 2px 2px 3px #888888;color:#666666"> <fieldset style = "padding:1em;border:0px;height:280px;border:1px dashed #1E9FFF;box-shadow: 2px 2px 3px #888888;color:#666666">
<legend style = "font-size:32px;"><?php echo $key; ?></legend> <legend style = "font-size:24px;"><?php echo $key; ?> - <?php echo $theme['info']->version ?></legend>
<p><h2><?php echo $theme['info']->name ?></h2></p>
<p>版本:<?php echo $theme['info']->version ?></p> <!-- 主题图片 -->
<p>更新时间:<?php echo $theme['info']->update ?></p> <div class = "screenshot"><p><img src="<?php echo $theme['info']->screenshot; ?>" alt=""></p></div>
<br /> <!-- 主题图片END -->
<p> <p>
<div class="layui-btn-group"> <div class="layui-btn-group">
<button type="button" class="layui-btn layui-btn-sm" onclick = "set_theme('<?php echo $key; ?>')">使用</button> <button type="button" class="layui-btn layui-btn-sm" onclick = "set_theme('<?php echo $key; ?>')">使用</button>
<button type="button" class="layui-btn layui-btn-sm" onclick = "theme_detail('<?php echo $key; ?>')">详情</button> <button type="button" class="layui-btn layui-btn-sm" onclick = "theme_detail('<?php echo $key; ?>')">详情</button>
<button type="button" class="layui-btn layui-btn-sm" onclick = "theme_config('<?php echo $key; ?>')">参数设置</button> <button type="button" class="layui-btn layui-btn-sm" onclick = "theme_config('<?php echo $key; ?>')">参数设置</button>
<button type="button" class="layui-btn layui-btn-sm layui-btn-danger" onclick = "delete_theme('<?php echo $key; ?>')">删除</button>
<?php if( $current_them == $key ) { ?> <?php if( $current_them == $key ) { ?>
<button type="button" class="layui-btn layui-btn-sm layui-btn-danger">当前主题</button> <button type="button" class="layui-btn layui-btn-sm layui-btn-danger">当前主题</button>
<?php } ?> <?php } ?>
</div> </div>
</p> </p>
</fieldset> </fieldset>

30
templates/admin/setting/transition_page.php

@ -8,7 +8,7 @@
<!-- 说明提示框 --> <!-- 说明提示框 -->
<div class="layui-col-lg12"> <div class="layui-col-lg12">
<div class="setting-msg"> <div class="setting-msg">
过渡页使用说明,请参考:<a href="https://dwz.ovh/yoyaf" target = "_blank" title = "过渡页使用说明">https://dwz.ovh/c7goi</a> 过渡页使用说明,请参考:<a href="https://dwz.ovh/mrkx1" target = "_blank" title = "过渡页使用说明">https://dwz.ovh/mrkx1</a>
</div> </div>
</div> </div>
<!-- 说明提示框END --> <!-- 说明提示框END -->
@ -39,6 +39,34 @@
<div class="layui-form-mid layui-word-aux">管理员停留时间,单位秒</div> <div class="layui-form-mid layui-word-aux">管理员停留时间,单位秒</div>
</div> </div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">过渡页菜单(订阅可用)</label>
<div class="layui-input-block">
<textarea name = "menu" placeholder="请参考帮助文档进行设置!" rows = "4" class="layui-textarea"><?php echo $transition_page['menu']; ?></textarea>
</div>
</div>
<!-- <div class="layui-form-item layui-form-text">
<label class="layui-form-label">自定义footer,支持HTML(订阅可用)</label>
<div class="layui-input-block">
<textarea name = "footer" placeholder="请参考帮助文档进行设置!" rows = "4" class="layui-textarea"><?php echo $transition_page['footer']; ?></textarea>
</div>
</div> -->
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">广告1(订阅可用)</label>
<div class="layui-input-block">
<textarea name = "a_d_1" placeholder="请参考帮助文档进行设置!" rows = "2" class="layui-textarea"><?php echo $transition_page['a_d_1']; ?></textarea>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">广告2(订阅可用)</label>
<div class="layui-input-block">
<textarea name = "a_d_2" placeholder="请参考帮助文档进行设置!" rows = "2" class="layui-textarea"><?php echo $transition_page['a_d_2']; ?></textarea>
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<button class="layui-btn" lay-submit="" lay-filter="set_transition_page">保存设置</button> <button class="layui-btn" lay-submit="" lay-filter="set_transition_page">保存设置</button>
</div> </div>

98
templates/admin/static/embed.js

@ -1,5 +1,12 @@
layui.config({
base: './static/module/'
}).extend({
iconHhysFa: 'iconHhys/iconHhysFa'
});
// 2022014 // 2022014
layui.use(['element','table','layer','form','upload'], function(){ layui.use(['element','table','layer','form','upload','iconHhysFa'], function(){
var element = layui.element; var element = layui.element;
var table = layui.table; var table = layui.table;
var form = layui.form; var form = layui.form;
@ -377,29 +384,86 @@ layui.use(['element','table','layer','form','upload'], function(){
//保存站点设置 //保存站点设置
form.on('submit(set_site)', function(data){ form.on('submit(set_site)', function(data){
var index = layer.load(1);
$.post('/index.php?c=api&method=set_site',data.field,function(data,status){ $.post('/index.php?c=api&method=set_site',data.field,function(data,status){
if(data.code == 0) { if(data.code == 0) {
layer.closeAll('loading');
layer.msg(data.data, {icon: 1}); layer.msg(data.data, {icon: 1});
} }
else{ else{
layer.closeAll('loading');
layer.msg(data.err_msg, {icon: 5}); layer.msg(data.err_msg, {icon: 5});
} }
}); });
//console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//保存订阅信息
form.on('submit(set_subscribe)', function(data){
var order_id = data.field.order_id;
var index = layer.load(1);
$.get('https://onenav.xiaoz.top/v1/check_subscribe.php',data.field,function(data,status){
if(data.code == 200) {
//order_id = data.data.order_id;
email = data.data.email;
end_time = data.data.end_time;
//存储到数据库中
$.post("index.php?c=api&method=set_subscribe",{order_id:order_id,email:email,end_time:end_time},function(data,status){
if(data.code == 0) {
layer.closeAll('loading');
layer.msg(data.data, {icon: 1});
}
else{
layer.closeAll('loading');
layer.msg(data.err_msg, {icon: 5});
}
});
}
else{
layer.closeAll('loading');
layer.msg(data.msg, {icon: 5});
}
});
console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value} console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。 return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
}); });
//清空订阅信息
form.on('submit(reset_subscribe)', function(data){
//存储到数据库中
$.post("index.php?c=api&method=set_subscribe",{order_id:'',email:'',end_time:null},function(data,status){
if(data.code == 0) {
//清空表单
$("#order_id").val('');
$("#email").val('');
//$("#domain").val('');
$("#end_time").val('');
layer.msg(data.data, {icon: 1});
}
else{
layer.closeAll('loading');
layer.msg(data.err_msg, {icon: 5});
}
});
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//保存站点设置 //保存站点设置
form.on('submit(set_transition_page)', function(data){ form.on('submit(set_transition_page)', function(data){
var index = layer.load(1);
$.post('/index.php?c=api&method=set_transition_page',data.field,function(data,status){ $.post('/index.php?c=api&method=set_transition_page',data.field,function(data,status){
if(data.code == 0) { if(data.code == 0) {
layer.closeAll('loading');
layer.msg(data.data, {icon: 1}); layer.msg(data.data, {icon: 1});
} }
else{ else{
layer.closeAll('loading');
layer.msg(data.err_msg, {icon: 5}); layer.msg(data.err_msg, {icon: 5});
} }
}); });
console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value} //console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。 return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
}); });
@ -809,3 +873,33 @@ function export_link(url, fileName) {
}); });
} }
//删除主题
function delete_theme(name) {
layer.confirm('确认删除此主题(' + name + ')?', {icon: 3, title:'重要提示'}, function(index){
$.post("index.php?c=api&method=delete_theme",{name:name},function(data,status){
if( data.code == 200 ) {
layer.msg(data.msg,{icon:1});
setTimeout(() => {
window.location.reload();
}, 2000);
}
else{
layer.msg(data.msg,{icon:5});
}
});
});
}
//验证是否订阅
function check_subscribe(msg) {
$.get("/index.php?c=api&method=check_subscribe",function(data,status){
if( data.code == 200 ) {
return true;
}
else{
layer.msg(msg, {icon: 5});
return false;
}
});
}

12
templates/admin/static/style.css

@ -107,3 +107,15 @@
.place-holder{ .place-holder{
padding-bottom: 3em; padding-bottom: 3em;
} }
.screenshot {
height:220px;
}
.screenshot img{
max-width: auto;
max-height: 200px;
}
#progress{
display:none;
margin-top:1em;
}

2
version.txt

@ -1 +1 @@
v0.9.21-20220516 v0.9.22-20220602
Loading…
Cancel
Save