Compare commits

..

7 Commits

Author SHA1 Message Date
MI15\Win
b35403dbe1 修改README.md 2025-07-11 13:52:25 +08:00
MI15\Win
f87af906d9 v2.1.18-20241105 2024-11-07 00:59:43 +08:00
MI15\Win
72f4cee174 v2.1.18-20241018 2024-10-17 16:29:12 +08:00
MI15\Win
b9eaa4099d v2.1.17-20240730 2024-07-30 17:28:39 +08:00
MI15\Win
d104bf66ce v2.1.16-20240525 2024-05-26 15:04:28 +08:00
MI15\Win
7c1b69b089 v2.1.15-20240513 2024-05-13 16:01:12 +08:00
MI15\Win
2d152489af v2.1.15-20240513 2024-05-13 14:44:55 +08:00
42 changed files with 773 additions and 25896 deletions

View File

@@ -4,8 +4,8 @@ TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装
- **仅供体验,定期清理数据** 账号密码`admin`
### 相关文档
* [安装教程](https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968668&doc_id=3767990) | [使用说明](https://gitee.com/tznb/TwoNav/wikis) | [下载TwoNav](https://gitee.com/tznb/TwoNav/releases)
* [OneNav Extend 升级到 TwoNav](https://gitee.com/tznb/OneNav/wikis/pages?sort_id=7955135&doc_id=2439895)
* [安装教程](https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968668&doc_id=3767990) | [使用说明](https://gitee.com/tznb/TwoNav/wikis) | [下载TwoNav](https://gitee.com/tznb/TwoNav/releases) | [获取授权](https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968669&doc_id=3767990)
### 作者声明
* 本程序没有二开版、除了下面的项目地址均为盗版。
@@ -33,6 +33,45 @@ TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装
* PHP: 7.3 - 8.2
* 数据库: SQLite3 或 MySQL > 5.6.0
### 版本差别
* 免费版无需授权即可使用 / 标准版|高级版需[获取授权](https://pay.twonav.cn/)
* 以下是简要的差别对比, 还有很多细节无法全部列举出来
| 功能 | 免费版 | 标准版 | 高级版 |
| ---------------------------- | ---------------- | ---------------- | ---------------------------|
| 多用户支持 | 不支持 | 支持 | 支持 |
| 系统更新 | 不支持 | 一键更新 | 一键更新 |
| 下载主题 | 不支持 | 一键下载 | 一键下载 |
| 链接识别 | 支持单个 | 支持批量 | 支持批量 |
| 链接检测 | 不支持 | 支持 | 支持 |
| 本地备份 | 不支持 | 备份+回滚 | 备份+回滚 |
| 收录管理 | 不支持 | 支持 | 支持 |
| 留言管理 | 不支持 | 支持 | 支持 |
| 文章管理 | 不支持 | 支持 | 支持 |
| 热点新闻 | 不支持 | 支持 | 支持 |
| 账号保留 | 不支持 | 支持 | 支持 |
| 站点地图 | 不支持 | 支持 | 支持 |
| 用户组管理 | 不支持 | 支持 | 支持 |
| 自定义版权 | 不支持 | 支持 | 支持 |
| 自定义代码 | 不支持 | 支持 | 支持 |
| 注册码功能 | 不支持 | 支持 | 支持 |
| 图标获取 | 支持第三方 | 本地获取、第三方获取 | 本地获取、第三方获取 |
| 找回密码 | 不支持 | 不支持 | **支持** |
| 注册验证 | 不支持 | 邮箱 | **邮箱、短信** |
| 第三方登录 | 不支持 | 不支持 | **支持** |
| 短信登录 | 不支持 | 不支持 | **支持** |
| 域名防红 | 不支持 | 不支持 | **支持** |
| 个性域名 | 不支持 | 不支持 | **支持** |
| 登录保护 | 不支持 | 不支持 | **支持** |
| 广告功能 | 不支持 | 不支持 | **支持** |
| 多域名授权 | 不支持 | 不支持 | **付费支持** |
* 个性域名: 允许用户自定义域名前缀、访问前缀.主域名等于访问对应用户的主页、标准版支持用户名.主域名访问对应用户的主页
* 登录保护: 用于防止暴力破解、可根据IP或账号自动限制登录行为
* 广告功能: 支持在后台添加文字广告、大横幅、小横幅等、可设置到期后自动停用
* 多域名授权: 支持授权多个主域名、支持给不同域名设置不同主页、从而节省成本(具体可联系客服咨询)
### 功能特色
* 支持后台管理
* 支持私有链接
@@ -48,9 +87,14 @@ TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装
* 支持uTools插件
* 支持Chromium内核的[浏览器扩展]
* 支持简易文章管理
* 支持更换各种模板/支持混搭,20+个主题模板
* 支持更换各种模板/支持混搭,26个主题模板
* 安全性支持:更换登录入口/二级密码/OTP双重验证
### 赞助商
* [此项目的 CDN 加速和安全防护由腾讯 EdgeOne 赞助。](https://edgeone.ai/?from=github "此项目的 CDN 加速和安全防护由腾讯 EdgeOne 赞助。")
[![](https://edgeone.ai/media/34fe3a45-492d-4ea4-ae5d-ea1087ca7b4b.png)](https://edgeone.ai/?from=github)
[Best Asian CDN, Edge, and Secure Solutions - Tencent EdgeOne](https://edgeone.ai/?from=github "Best Asian CDN, Edge, and Secure Solutions - Tencent EdgeOne")
![](https://foruda.gitee.com/images/1680680754989095293/fcc56e76_10359480.jpeg "主页预览")
![](https://foruda.gitee.com/images/1680680836189756220/8c227c34_10359480.jpeg "主题模板")

View File

@@ -35,8 +35,8 @@ if($db_config['type'] == 'sqlite'){
$global_config = unserialize( get_db("global_config", "v", ["k" => "o_config"]) ); //全局配置
$c = Get('c');
$libs = $global_config['Libs'];
$layui['js'] = $libs.'/Layui/v2.9.8/layui.js';
$layui['css'] = $libs.'/Layui/v2.9.8/css/layui.css';
$layui['js'] = $libs.'/Layui/v2.9.18/layui.js';
$layui['css'] = $libs.'/Layui/v2.9.18/css/layui.css';
$global_config['static_link'] = isset($global_config['static_link']) ? $global_config['static_link'] : 0;
define('libs',$global_config['Libs']);
define('SysVer',Get_Version());

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 322 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -91,7 +91,7 @@ if(!empty($_GET['type'])){
$user_group['root'] = '站长';
$user_group['default'] = '默认';
foreach ($datas as $key => $data){
$datas[$key]['UserGroupName'] = $user_group[$data['UserGroup']]??'Null';
$datas[$key]['UserGroupName'] = $user_group[$data['UserGroup']]??$data['UserGroup'];
}
}
msgA(['code'=>1,'msg'=>'获取成功','count'=>$count,'data'=>$datas]);
@@ -116,6 +116,10 @@ if(!empty($_GET['type'])){
}elseif($_GET['type'] == 'set_close_Maintenance'){
$global_config['Maintenance'] = 0;
update_db("global_config", ["v" => $global_config], ["k" => "o_config"],[1,'设置成功']);
//开启调试模式
}elseif($_GET['type'] == 'set_open_debug'){
$global_config['Debug'] = 1;
update_db("global_config", ["v" => $global_config], ["k" => "o_config"],[1,'设置成功']);
//重置静态路径
}elseif($_GET['type'] == 'Set_Libs'){
$global_config['Libs'] = "./static";
@@ -127,6 +131,10 @@ if(!empty($_GET['type'])){
opcache_reset(); //清理PHP缓存
}
msgA(['code'=>1,'msg'=>'操作成功']);
//清空统计
}elseif($_GET['type'] == 'del_tongji'){
delete_db('user_count',[]);
msgA(['code'=>1,'msg'=>'操作成功']);
//改账号
}elseif($_GET['type'] == 'set_user_name'){
//新用户名是否合规
@@ -181,6 +189,14 @@ if(!empty($_GET['type'])){
}
$LoginConfig['totp_key'] = '';
update_db("global_user", ["LoginConfig" => $LoginConfig], ["ID" => $_POST['ID']],[1,'操作成功']);
}elseif($_GET['type'] == 'get_pwd2'){
$user_data = get_db('global_user','*',['ID'=>$_POST['ID']]);
$LoginConfig = unserialize($user_data['LoginConfig']);
if(empty($LoginConfig['Password2'])){
msgA(['code'=>-1,'msg'=>'当前账号未设置二级密码']);
}else{
msgA(['code'=>1,'msg'=> "当前账号: {$user_data['User']}<br />二级密码: {$LoginConfig['Password2']}"]);
}
}
msgA(['code'=>-1,'msg'=>'请求类型错误']);
@@ -252,9 +268,11 @@ function echo_Atool(){
<a class="layui-btn layui-btn-sm layui-btn-primary" href="../index.php?c=<?php echo $global_config['Register'];?>" target="_blank"><i class="layui-icon layui-icon-add-1"></i>打开注册页</a>
<button type="set_allow_register" class="set layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>允许注册</button>
<button type="set_close_Maintenance" class="set layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>关闭维护模式</button>
<button type="set_open_debug" class="set layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>打开调试模式</button>
<button type="Set_Libs" class="set layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>重置静态路径</button>
<button type="Set_clear_cache" class="set layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>清除缓存</button>
<a class="layui-btn layui-btn-sm layui-btn-primary" href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7993451&doc_id=3767990" target="_blank"><i class="layui-icon layui-icon-align-left"></i>帮助</a>
<button type="del_tongji" class="del_tongji layui-btn layui-btn-sm layui-btn-primary"><i class="layui-icon layui-icon-set-sm"></i>清空统计</button>
<a class="layui-btn layui-btn-sm layui-btn-primary" href="https://docs.twonav.cn/#/books/start-07" target="_blank"><i class="layui-icon layui-icon-align-left"></i>帮助</a>
</div>
<hr>
<div class="layui-inline layui-form" style="padding-bottom: 5px;">
@@ -281,10 +299,7 @@ function echo_Atool(){
<!-- 表格操作列 -->
<script type="text/html" id="tablebar">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_pwd">改密码</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_root">设站长</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_user_name">改账号</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="del_otp" title="移除OTP登录验证">删OTP</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="more">操作 <i class="layui-icon layui-icon-down"></i></a>
</div>
</script>
<script src="<?php echo $GLOBALS['layui']['js']; ?>"></script>
@@ -292,13 +307,14 @@ function echo_Atool(){
<script src="../static/jquery/jquery.md5.js"></script>
<script src="../templates/admin/js/public.js?v=<?php echo time();?>"></script>
<script>
layui.use(['layer','table'], function () {
layui.use(function () {
var $ = layui.jquery;
var layer = layui.layer;
var table = layui.table;
var dropdown = layui.dropdown;
var cols = [[
{field:'ID',title:'ID',width:60,sort:true}
,{title:'操作',toolbar:'#tablebar',width:220}
,{title:'操作',toolbar:'#tablebar',width:90}
,{field:'User',title:'账号',minWidth:120,templet:function(d){
return '<a style="color:#3c78d8" title="打开用户主页" target="_blank" href="../?u='+d.User+'">'+d.User+'</a>'
}}
@@ -310,6 +326,7 @@ function echo_Atool(){
,{field:'RegTime',title: '注册时间',minWidth:100,templet:function(d){
return d.RegTime == null ? '' : timestampToTime(d.RegTime,true);
}}
]]
//用户表渲染
table.render({
@@ -345,47 +362,67 @@ function echo_Atool(){
table.on('tool(table)', function (obj) {
console.log(obj.data);
var data = obj.data;
if (obj.event == 'set_pwd') {
layer.prompt({formType: 3,value: '',title: '请输入新密码'}, function(value, index, elem){
$.post('./ATool.php?type=set_pwd',{ID:data.ID,new_pwd:$.md5(value)},function(data,status){
if(data.code == 1) {
layer.close(index);
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
if(obj.event == 'more'){
dropdown.render({
elem: this,
show: true,
data: [{
title: '修改密码',
id: 'set_pwd'
},{
title: '设为站长',
id: 'set_root'
},{
title: '修改账号',
id: 'set_user_name'
},{
title: '取消双重验证',
id: 'del_otp'
},{
title: '查看二级密码',
id: 'get_pwd2'
}
});
});
}else if(obj.event == 'set_root'){
$.post('./ATool.php?type=set_root',{ID:data.ID},function(data,status){
if(data.code == 1) {
table.reload('table');
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
}else if(obj.event == 'set_user_name'){
layer.prompt({formType: 3,value: '',title:'请输入新账号 (原账号:'+data.User+')'}, function(value, index, elem){
$.post('./ATool.php?type=set_user_name',{ID:data.ID,new_user_name:value},function(data,status){
if(data.code == 1) {
layer.close(index);
table.reload('table');
layer.msg(data.msg, {icon: 1});
],
click: function(menu, othis){
if(menu.id == 'set_pwd'){
layer.prompt({formType: 3,value: '',title: '请输入新密码'}, function(value, index, elem){
$.post('./ATool.php?type=set_pwd',{ID:data.ID,new_pwd:$.md5(value)},function(data,status){
if(data.code == 1) {
layer.close(index);
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
});
}else if(menu.id == 'set_user_name'){
layer.prompt({formType: 3,value: '',title:'请输入新账号 (原账号:'+data.User+')'}, function(value, index, elem){
$.post('./ATool.php?type=set_user_name',{ID:data.ID,new_user_name:value},function(data,status){
if(data.code == 1) {
layer.close(index);
table.reload('table');
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
});
}else if(menu.id == 'set_root' || menu.id == 'del_otp' || menu.id == 'get_pwd2'){
$.post('./ATool.php?type=' + menu.id,{ID:data.ID},function(data,status){
if(data.code == 1) {
table.reload('table');
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
}else{
layer.msg(data.msg, {icon: 5});
layer.msg('无效操作', {icon: 5});
}
});
});
}else if(obj.event == 'del_otp'){
$.post('./ATool.php?type=del_otp',{ID:data.ID},function(data,status){
if(data.code == 1) {
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
})
}
return false;
});
$('.set').click(function () {
let type = $(this).attr("type");
@@ -398,6 +435,22 @@ function echo_Atool(){
});
return false;
});
//清空统计
$('.del_tongji').on('click', function(){
layer.confirm('确认后将删除所有账号的统计数据(访问统计/点击统计/报表统计),是否继续?',{icon: 3, title:'此操作不可逆'}, function(index){
$.post('./ATool.php?type=del_tongji',function(data,status){
layer.closeLast('loading');
if(data.code == 1){
layer.msg(data.msg,{icon: 1})
} else{
layer.msg(data.msg,{icon: 5});
}
}).fail(function(xhr, textStatus, errorThrown) {
layer.closeLast('loading');
layer.alert('请求失败');
});
});
});
$('#logout').click(function () {
layer.confirm('退出后ATool将被关闭并重置Key',{icon: 3, title:'为了您的站点安全:'}, function(index){
$.post('./ATool.php?type=logout',function(re,status){

File diff suppressed because it is too large Load Diff

16
system/MySQL/20240720.php Normal file
View File

@@ -0,0 +1,16 @@
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
$sql ='
CREATE INDEX category_idx_1
ON user_categorys (fid, uid, status, property, pid, weight);
CREATE INDEX link_idx_1
ON user_links (uid, fid, status, property, pid, add_time, click);
';
//创建索引用于优化效率
if(exe_sql($sql)){
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
}else{
msg(-1,'数据库更新失败');
}

View File

@@ -51,6 +51,7 @@ INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALU
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230723.php', '1690119053', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20231218.php', '1702828800', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20240328.php', '1711296000', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20240720.php', '1721404800', 'TRUE', '');
-- 创建用户表
DROP TABLE IF EXISTS `global_user`;
@@ -102,7 +103,7 @@ CREATE TABLE IF NOT EXISTS `user_categorys` (
INSERT INTO `user_categorys` (`id`, `cid`, `fid`, `uid`, `pid`, `status`, `property`, `name`, `add_time`, `up_time`, `weight`, `description`, `font_icon`, `icon`, `extend`) VALUES
(1, 1, 0, 0, 0, 1, 0, '默认分类', 1672502400, 1672502400, 0, 'TwoNav默认分类', 'fa fa-book', '', '');
CREATE INDEX category_idx_1 ON user_categorys (fid, uid, status, property, pid, weight);
-- 用户链接表
DROP TABLE IF EXISTS `user_links`;
@@ -133,7 +134,7 @@ INSERT INTO `user_links` (`id`, `lid`, `uid`, `fid`, `pid`, `status`, `property`
(1, 1, 0, 1, 0, 1, 0, 'TwoNav 源码', 'https://gitee.com/tznb/TwoNav', '', 0, '项目开源地址', '', 0, 1672502400, 1672502400, ''),
(2, 2, 0, 1, 0, 1, 0, '使用说明', 'https://gitee.com/tznb/TwoNav/wikis', '', 0, '使用说明', '', 0, 1672502400, 1672502400, '');
CREATE INDEX link_idx_1 ON user_links (uid, fid, status, property, pid, add_time, click);
-- 登录信息表
DROP TABLE IF EXISTS `user_login_info`;

View File

@@ -47,149 +47,8 @@ if(!preg_match('/^[A-Za-z0-9]{4,13}$/', $user)){
msg(-1,'POST提交的密码异常≠32!');
}elseif(preg_match("/^(system|data|static|templates|index|root|admin)$/i",$user) ) {
msg(-1,'改用户名已被系统保留!');
}elseif(!empty(get_db('global_user','ID',['User'=>$user ]))){
msg(-1,'该账号已被注册!');
}elseif(!empty(get_db('global_user','ID',['Email'=>$Email ]))){
msg(-1,'该邮箱已被使用!');
}elseif(!preg_match("/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/i",$Email)){
msg(-1,'邮箱错误!');
}elseif(username_retain_verify($user)){
msg(-1,'该账号已被站长保留!');
}
//插入用户表和创建初始数据库
$RegTime = time();
$PassMD5 = Get_MD5_Password($pass,$RegTime);
$Elogin = Get_Exclusive_Login($user);
//用户组
if(!empty($regcode_info['u_group'])){
$UserGroup = $regcode_info['u_group'];
}elseif(!empty($global_config['default_UserGroup'])){
$UserGroup = $global_config['default_UserGroup'];
}else{
$UserGroup = 'default';
}
//读取用户组信息,如果用户组不存在则设为默认用户组
if(!in_array($UserGroup,['default','root','visitor'])){
$Group = get_db('user_group','*',['code' => $UserGroup]);
if(empty( $Group )){
$UserGroup = 'default';
}
}
$blueprint = !empty(get_db('global_user','ID',['ID'=>$Group['uid']]));
if($blueprint){
$LoginConfig = unserialize(get_db('global_user','LoginConfig',['ID'=>$Group['uid']]));
$LoginConfig['Password2'] = '';
}else{
//不需要修改内容,无需反序化
$LoginConfig = get_db('global_config','v',['k'=>'LoginConfig']);
}
//父ID
if(!empty($regcode_info['user'])){
$FID = get_db('global_user','ID',['User'=>$regcode_info['user']]);
}else{
$FID = 0;
}
insert_db("global_user", [
"FID"=>$FID,
"User"=>$user,
"Password"=>$PassMD5,
"UserGroup"=>$UserGroup,
"Email"=>$Email,
"SecretKey"=>'',
"Token"=>'',
"RegIP"=>$IP,
"RegTime"=>$RegTime,
"Login"=>$Elogin,
"LoginConfig"=>$LoginConfig
]);
//读取用户信息
$USER_DB = get_db("global_user", "*", ["User"=>$user]);
//记录日志
insert_db("user_log", ["uid" => $USER_DB['ID'],"user"=>$USER_DB['User'],"ip"=>$IP,"time"=>time(),"type" => 'register',"content"=>Get_Request_Content(),"description"=>"注册账号"]);
//生成Cookie
Set_key($USER_DB);
//注册码注册时回写数据
if(!empty($regcode_info)){
update_db('regcode_list',['use_time'=>time(),'use_state'=>'已使用,用户名:'.$user],['id'=>$regcode_info['id']]);
}
//写默认站点配置
if($blueprint){
$s_site = get_db('user_config','v',['k'=>'s_site','uid'=>$Group['uid']]);
}else{
$s_site = get_db('global_config','v',['k'=>'s_site']);
}
insert_db("user_config", ["uid"=>$USER_DB['ID'], "k" => "s_site","v" => $s_site,"d" => '站点配置','t'=>'config']);
//写默认模板
if($blueprint){
$global_templates = unserialize(get_db('user_config','v',['k'=>'s_templates','uid'=>$Group['uid']]));
}else{
$global_templates = unserialize(get_db('global_config','v',['k'=>'s_templates']));
}
insert_db("user_config", ["uid" => $USER_DB['ID'],"k"=>"s_templates","v"=>$global_templates,"t"=>"config","d" => '默认模板']);
//写初始分类和链接
$time = time();
if($blueprint){
$categorys = select_db('user_categorys','*',['uid'=>$Group['uid']]);
$links = select_db('user_links','*',['uid'=>$Group['uid']]);
}else{
$categorys = select_db('user_categorys','*',['uid'=>0]);
$links = select_db('user_links','*',['uid'=>0]);
}
foreach ($categorys as $key => $data){
$data['uid'] = $USER_DB['ID'];
$data['add_time'] = $time;
$data['up_time'] = $time;
unset($data['id']);
insert_db('user_categorys',$data);
}
foreach ($links as $key => $data){
$data['uid'] = $USER_DB['ID'];
$data['add_time'] = $time;
$data['up_time'] = $time;
unset($data['id']);
insert_db('user_links',$data);
}
//写初始ID
$link_id = intval(max_db('user_links','lid',['uid'=>$USER_DB['ID']])) +1;
insert_db("user_config", ["uid"=>$USER_DB['ID'],"k"=>"link_id","v"=>$link_id,"t"=>"max_id","d"=>'链接ID']);
$category_id = intval(max_db('user_categorys','cid',['uid'=>$USER_DB['ID']])) +1;
insert_db("user_config", ["uid"=>$USER_DB['ID'],"k"=>"category_id","v"=>$category_id,"t"=>"max_id","d"=>'分类ID']);
insert_db("user_config", ["uid"=>$USER_DB['ID'],"k"=>"pwd_group_id","v"=>1,"t"=>"max_id","d"=>'加密组ID']);
//账号保留
function username_retain_verify($username){
$list = get_db("global_config", "v", ["k" => "username_retain"]);
if(empty($list)){
return false;
}
$patterns = explode("\n", $list);
foreach($patterns as $pattern){
if (preg_match($pattern, $username)) {
return true;
}
}
return false;
}
//返回注册成功
msg(1,'注册成功');
msg(-1,'免费版不支持此功能<br /> <a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968669&doc_id=3767990" target="_blank" style="color: #1e9fff;">点击此处前往购买页面</a>');

View File

@@ -0,0 +1,16 @@
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
$sql ='
CREATE INDEX "category_idx_1"
ON "user_categorys" ("fid","uid","status","property","pid","weight");
CREATE INDEX "link_idx_1"
ON "user_links" ("uid","fid","status","property","pid","add_time","click");
';
//创建索引用于优化效率
if(exe_sql($sql)){
insert_db('updatadb_logs',['file_name'=>$file_name,'update_time'=>time(),'status'=>'TRUE','extra'=>'']);
}else{
msg(-1,'数据库更新失败');
}

View File

@@ -43,6 +43,7 @@ INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALU
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20230723.php', '1690119053', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20231218.php', '1702828800', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20240328.php', '1711296000', 'TRUE', '');
INSERT INTO "updatadb_logs" ("file_name", "update_time", "status", "extra") VALUES ('20240720.php', '1721404800', 'TRUE', '');
-- 创建用户表
CREATE TABLE IF NOT EXISTS "global_user" (
@@ -88,6 +89,7 @@ CREATE TABLE IF NOT EXISTS "user_categorys" (
);
INSERT INTO "user_categorys"("id", "cid", "fid", "uid", "pid", "status", "property", "name", "add_time", "up_time", "weight", "description", "font_icon", "icon", "extend") VALUES (1, 1, 0, 0, 0, 1, 0, '默认分类', 1672502400, 1672502400, 0, 'TwoNav默认分类', 'fa fa-book', '', '');
CREATE INDEX "category_idx_1" ON "user_categorys" ("fid","uid","status","property","pid","weight");
-- 用户链接表
CREATE TABLE IF NOT EXISTS "user_links" (
@@ -112,7 +114,8 @@ CREATE TABLE IF NOT EXISTS "user_links" (
);
INSERT INTO "user_links"("id", "lid", "uid", "fid", "pid", "status", "property", "title", "url", "url_standby", "weight", "description", "icon", "click", "add_time", "up_time", "extend") VALUES (1, 1, 0, 1, 0, 1, 0, 'TwoNav 源码', 'https://gitee.com/tznb/TwoNav', '', 0, '项目开源地址', '', 0, 1672502400, 1672502400, '');
INSERT INTO "user_links"("id", "lid", "uid", "fid", "pid", "status", "property", "title", "url", "url_standby", "weight", "description", "icon", "click", "add_time", "up_time", "extend") VALUES (2, 2, 0, 1, 0, 1, 0, '使用说明', 'https://gitee.com/tznb/TwoNav/wikis', '', 0, '使用说明', '', 0, 1672502400, 1672502400, '');
CREATE INDEX "link_idx_1" ON "user_links" ("uid","fid","status","property","pid","add_time","click");
-- 登录信息表
CREATE TABLE IF NOT EXISTS "user_login_info" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,

View File

@@ -406,7 +406,11 @@ function write_link(){
$tmp_path = $_SESSION['upload_images'][UID][$_POST['file']];
if(!empty($tmp_path) && is_file($tmp_path)){
$suffix = strtolower(end(explode('.',$tmp_path)));
$path = "./data/user/{$u}/favicon/{$lid}.{$suffix}";
$path = "./data/user/{$u}/favicon";
if(!Check_Path($path)){
msg(-1,'创建目录失败,请检查权限');
}
$path .= "/{$lid}.{$suffix}";
if(rename($tmp_path,$path)) { //移动文件到用户目录
$icon = $path;
}else{
@@ -1084,7 +1088,7 @@ function read_theme(){
//没有缓存 或 禁止缓存 或 缓存过时
if(empty($template) || $_GET['cache'] === 'no' || time() - $data["time"] > 1800 ){
$urls = ["gitee" => "http://tznb.gitee.io/twonav_resource/{$request_dir}_template.json"];
$urls = ["gitee" => "http://gitee.com/tznb/TwoNav_Resource/raw/master/{$request_dir}_template.json"];
$Source = $global_config['Update_Source'] ?? '';
if (!empty($Source) && isset($urls[$Source])) {
$urls = [$Source => $urls[$Source]];

View File

@@ -453,7 +453,7 @@ function other_services(){
'method' => $_GET['type'],
'sys' => $_POST['sys']
];
$overtime = !isset($global_config['Update_Overtime']) ? 3 : ($global_config['Update_Overtime'] < 3 || $global_config['Update_Overtime'] > 60 ? 3 : $global_config['Update_Overtime']);
$overtime = 30;
// 判断操作类型
if($_GET['type'] == 'query_key' || $_GET['type'] == 'save_key'){
$Res = ccurl("http://service.twonav.cn/service.php",$overtime,true,$post);
@@ -522,7 +522,7 @@ function other_services(){
if(is_subscribe('bool')){
$Res = ccurl('http://service.twonav.cn/service.php',$overtime,true,data_encryption('get_new_ver',['ver'=>SysVer]));
}else{
$Res = ccurl('http://tznb.gitee.io/twonav_resource/Notice.json',$overtime);
$Res = ccurl('http://gitee.com/tznb/TwoNav_Resource/raw/master/Notice.json',$overtime);
}
$new_data = json_decode($Res['content'], true);
if($new_data["code"] == 200 ){

View File

@@ -21,7 +21,7 @@ foreach($_POST as $key =>$value){
}
}
//拦截SQL注入
if($global_config['SQL_WAF'] == 1 ){
if(!isset($code) && $global_config['SQL_WAF'] == 1 ){
if(preg_match("/\s+(or|xor|and)\s+(=|<|>|'|".'")/i',$value)){
$code = 2101;
}elseif(preg_match("/select.+(from|limit)/i",$value)){
@@ -43,5 +43,10 @@ foreach($_POST as $key =>$value){
}
}
if(!empty($code)){msgA(['code'=>$code,'msg'=>$code.':已拦截不合法参数!','key'=>$key,'Value'=>$value,'method'=>$method ]);}
if(!empty($code)){
$tips = $code <= 2100 ?
'<br />如果您是站长,请前往系统设置关闭防XSS脚本<br />如果您是用户,请联系站长处理':
'<br />如果您是站长,请前往系统设置关闭防SQL注入<br />如果您是用户,请联系站长处理';
msgA(['code'=>$code,'msg'=>$code.':已拦截不合法参数!'.$tips,'key'=>$key,'Value'=>$value,'method'=>$method ]);
}
}

View File

@@ -388,6 +388,9 @@ function Write_Config(){
<div class="login-logo"><h1>TwoNav 安装引导</h1></div>
<div class="layui-col-lg6 layui-col-md-offset3" style ="margin-top:4em;">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-mid layui-word-aux" style="width: 99%;">
<span>禁止用于违法用途、使用者造成的一切法律后果由使用者自行承担、安装视为同意。</span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">管理员账号</i></label>
<div class="layui-input-block">
@@ -411,7 +414,7 @@ function Write_Config(){
<label class="layui-form-label">数据库类型</label>
<div class="layui-input-block">
<select id="db_type" name="db_type" lay-filter="db_type" >
<option value="sqlite" selected="">SQLite ( 推荐 )</option>
<option value="sqlite" selected="">SQLite</option>
<option value="mysql" >MySQL ≥ 5.6.0 </option>
<option value="mariadb" >MariaDB ≥ 10.1 </option>
</select>

View File

@@ -121,7 +121,11 @@ if($config_type == 'user'){
if(!check_purview('header',1)){$site['custom_header'] = '';}
if(!check_purview('footer',1)){$site['custom_footer'] = '';}
//主页标题( 主标题 - 副标题 )
//主页标题(分类页面显示分类名-描述)
if(isset($_GET['cid']) && intval($_GET['cid']) > 0){
$teml_cd = get_db('user_categorys',['name','description'],['uid'=>UID,'cid'=>intval($_GET['cid'])]);
$site['title'] = $teml_cd['name']; $site['subtitle'] = $teml_cd['description'];
}
$site['Title'] = $site['title'].(empty($site['subtitle'])?'':' - '.$site['subtitle']);
//站点图标
@@ -167,22 +171,14 @@ function geticourl($icon,$link){
}
if ($site['link_icon'] == 'default'){
return($GLOBALS['libs'].'/Other/default.ico');
}elseif ($icon ==20){
}elseif ($icon == 20){
return('./index.php?c=icon&url='.base64_encode($link['real_url']));
}elseif ($icon ==21){
}elseif ($icon == 21){
return('./ico/'.base64_encode($link['real_url']));
}elseif($icon ==2){
}elseif($icon == 2){
return('https://favicon.png.pub/v1/'.base64_encode(get_url_host($link['real_url'],true,true)));
}elseif($icon ==4){
return('https://api.15777.cn/get.php?url='.$link['real_url']);
}elseif($icon ==5){
return('https://favicon.cccyun.cc/'.$link['real_url']);
}elseif($icon ==6){
return('https://api.iowen.cn/favicon/'.parse_url($link['real_url'])['host'].'.png');
}elseif($icon ==7){
return('https://toolb.cn/favicon/'.parse_url($link['real_url'])['host']);
}elseif($icon ==8){
return('https://apis.jxcxin.cn/api/Favicon?url='.$link['real_url']);
}elseif($icon == 6){
return('https://t3.gstatic.cn/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&size=128&url='.$link['real_url']);
}else{
return('./system/ico.php?text='.mb_strtoupper(mb_substr($link['title'], 0, 1)));
}

View File

@@ -1 +1 @@
v2.1.14-20240419
v2.1.18-20241105

View File

@@ -14,7 +14,7 @@
<link rel="stylesheet" href="<?php echo $layui['css'];?>" media="all">
<link rel="stylesheet" href="./templates/admin/css/layuimini.css?v=<?php echo $Ver;?>" media="all">
<link rel="stylesheet" href="./templates/admin/css/themes/default.css?v=<?php echo $Ver;?>" media="all">
<link rel="stylesheet" href="<?php echo $libs?>/Font-awesome/4.7.0/css/font-awesome.css" media="all">
<link rel="stylesheet" href="<?php echo $libs?>/Font-awesome/4.7.0/css/font-awesome.min.css" media="all">
<link rel="shortcut icon" href="<?php echo $favicon;?>">
<style id="layuimini-bg-color"></style>
</head>

View File

@@ -72,11 +72,11 @@
<option value="0" selected>离线图标(首字图标)</option>
<option value="20" >本地服务</option>
<option value="21" >本地服务(伪静态)</option>
<option value="2" >favicon.png.pub (小图标)</option>
<option value="6" >api.iowen.cn</option>
<option value="2" >第三方:favicon.png.pub (小图标)</option>
<option value="6" >第三方:gstatic.cn (大图标)</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">所有API接口由其他大佬提供!若有异常请尝试更换接口!</div>
<div class="layui-form-mid layui-word-aux">三方接口由其他站长提供!若有异常请尝试更换接口!建议使用本地服务!</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">重复链接</label>

View File

@@ -8,6 +8,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="referrer" content="no-referrer-when-downgrade">
<?php load_static('css');if($awesome) echo str_replace('#',$libs,' <link rel="stylesheet" href="#/Font-awesome/4.7.0/css/font-awesome.css" media="all">'."\n");?>
<?php load_static('css');if($awesome) echo str_replace('#',$libs,' <link rel="stylesheet" href="#/Font-awesome/4.7.0/css/font-awesome.min.css" media="all">'."\n");?>
<script>var u = "<?php echo U;?>";</script>
</head>

View File

@@ -15,21 +15,21 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="pass" name="user" lay-verify="required" lay-reqtext="账号不能为空" placeholder='请输入账号' autocomplete="off" class="layui-input">
<input type="pass" name="user" lay-reqtext="账号不能为空" placeholder='请输入账号' autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">邮箱账号,例如: admin@qq.com</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" name="pwd" lay-verify="required" lay-reqtext="密码不能为空" placeholder='请输入密码或授权码' autocomplete="off" class="layui-input">
<input type="password" name="pwd" lay-reqtext="密码不能为空" placeholder='请输入密码或授权码' autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">邮箱密码,也可能是独立密码或者授权码</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">服务器</label>
<div class="layui-input-inline">
<input type="text" name="host" lay-verify="required" lay-reqtext="服务器不能为空" placeholder='请输入发件服务器地址' autocomplete="off" class="layui-input">
<input type="text" name="host" lay-reqtext="服务器不能为空" placeholder='请输入发件服务器地址' autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">例如: smtp.qq.com</div>
</div>
@@ -37,7 +37,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-item">
<label class="layui-form-label">端口</label>
<div class="layui-input-inline">
<input type="number" name="port" lay-verify="required" lay-reqtext="端口不能为空" placeholder='请输入服务器端口' value="465" autocomplete="off" class="layui-input">
<input type="number" name="port" lay-reqtext="端口不能为空" placeholder='请输入服务器端口' value="465" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">通常是: 465或587</div>
</div>
@@ -56,7 +56,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-item">
<label class="layui-form-label">发送人</label>
<div class="layui-input-inline">
<input type="text" name="sender" lay-verify="required" lay-reqtext="发送人名称不能为空" placeholder='' autocomplete="off" class="layui-input">
<input type="text" name="sender" lay-reqtext="发送人名称不能为空" placeholder='' autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">例如: TwoNav</div>
</div>
@@ -83,7 +83,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-item">
<label class="layui-form-label">发送间隔</label>
<div class="layui-input-inline">
<input type="number" name="send_interval" lay-verify="required" lay-reqtext="发送间隔不能为空" placeholder='IP发送间隔,单位秒!' value="60" autocomplete="off" class="layui-input">
<input type="number" name="send_interval" lay-reqtext="发送间隔不能为空" placeholder='IP发送间隔,单位秒!' value="60" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">为了避免被恶意发送,建议不低于30秒</div>
</div>
@@ -112,37 +112,15 @@ layui.use(['jquery','form'], function () {
var form = layui.form;
var layer = layui.layer;
var $ = layui.jquery;
//表单赋值
form.val('form', <?php echo json_encode(unserialize( get_db("global_config", "v", ["k" => "mail_config"])));?>);
//监听提交
form.on('submit(save)', function (data) {
$.post(get_api('other_root','write_mail_config'),data.field,function(data,status){
if(data.code == 1) {
if(data.msg!="保存成功"){
layer.alert(data.msg)
}else{
layer.msg(data.msg, {icon: 1});
}
}else{
layer.msg(data.msg, {icon: 5});
}
});
layer.msg('当前版本不支持此功能,如需此功能请购买高级版授权', {icon: 5,time: 1000*300});
return false;
});
//测试
form.on('submit(send_test)', function (data) {
layer.load(1, {shade:[0.3,'#fff']});
layer.msg('正在发送中..', {icon: 16,time: 1000*300});
$.post(get_api('other_root','write_mail_test'),data.field,function(data,status){
layer.closeAll();
if(data.code == 1) {
layer.alert(data.msg);
}else{
layer.msg(data.msg, {icon: 5});
}
});
layer.msg('当前版本不支持此功能,如需此功能请购买高级版授权', {icon: 5,time: 1000*300});
return false;
});

View File

@@ -47,7 +47,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">直接访问域名不带任何参数时显示的页面</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label required">默认分组</label>
<div class="layui-input-inline">
<input type="text" name="default_UserGroup" lay-reqtext="默认用户不能为空" placeholder='default' autocomplete="off" class="layui-input">
@@ -55,7 +55,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">用户注册成功后所在分组代号,留空则使用默认分组</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">注册配置</label>
<div class="layui-input-inline" >
<select name="RegOption">
@@ -67,7 +67,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">个人使用时建议禁止注册</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">注册入口</label>
<div class="layui-input-inline">
<input type="text" name="Register" lay-verify="required" lay-reqtext="注册入口不能为空" placeholder='register' autocomplete="off" class="layui-input">
@@ -75,7 +75,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">不想被随意注册时可以修改</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">登录入口</label>
<div class="layui-input-inline">
<input type="text" name="Login" lay-verify="required" lay-reqtext="登录入口不能为空" placeholder='login' autocomplete="off" class="layui-input">
@@ -83,7 +83,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">修改可以防止被爆破,修改请记好入口名,否则无法登录后台</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">静态路径</label>
<div class="layui-input-inline">
<input type="text" name="Libs" lay-verify="required" lay-reqtext="静态路径不能为空,填错会导致无法正常加载网页!默认./static" placeholder='./static' autocomplete="off" class="layui-input">
@@ -99,7 +99,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">主页底部显示的备案信息</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">防XSS脚本</label>
<div class="layui-input-inline" >
<select name="XSS_WAF">
@@ -110,7 +110,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">拦截POST表单中的XSS恶意代码,提升网站安全性</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">防SQL注入</label>
<div class="layui-input-inline" >
<select name="SQL_WAF">
@@ -121,7 +121,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">拦截POST表单中的SQL注入代码,提升网站安全性</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">离线模式</label>
<div class="layui-input-inline" >
<select name="offline">
@@ -140,6 +140,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<option value="1">国内-1</option>
<option value="2">国内-2</option>
<option value="3">海外-3</option>
<option value="4">国内-4</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">默认为自动 (非必要请勿修改)</div>
@@ -164,7 +165,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">开发者调试模式,请不要随意开启</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label">维护模式</label>
<div class="layui-input-inline">
<select name="Maintenance">
@@ -175,7 +176,7 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">开启时将关闭主页/登录/注册等服务,站长账号不受影响(网站升级迁移时适用)</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item layui-hide">
<label class="layui-form-label required">静态链接</label>
<div class="layui-input-inline">
<select name="static_link">

View File

@@ -15,7 +15,7 @@ if(!empty($Notice)){
<h4 style = "margin-bottom:1em;"><font color="red">不要使用盗版/破解版,盗版无法升级却存在诸多问题,所造成的损失与本程序无关</font></h4>
<blockquote class="layui-elem-quote layui-text" style="color:red" >
<li> 如何激活授权: </li>
<li>1. 购买授权后将授权号(卡密)和邮箱填入下方并点击保存</li>
<li>1. 购买授权后将授权卡密和邮箱填入下方并点击保存</li>
<li>2. 返回概要页面 > 刷新 > 更新系统 ( 不更新还是免费版 )</li>
<li>3. 更新成功后就是授权版的系统了,可使用全部功能</li>
<li>4. 禁止传播/破解授权版源代码,违者封授权并追责</li>
@@ -66,21 +66,11 @@ if(!empty($Notice)){
<input type="text" name="type_name" id ="type_name" value="<?php echo $subscribe['type_name'] ?? ''; ?>" autocomplete="off" placeholder="若未正确显示请点击保存设置" class="layui-input">
</div>
</div>
<?php if(get_db('global_config','v',["k" => "sys_switch"]) == 'show' && $subscribe['type'] == '3'){ ?>
<div class="layui-form-item">
<label class="layui-form-label">版本切换</label>
<div class="layui-input-inline" >
<select name="sys" id="sys">
<option value="biaozhun" selected>标准版</option>
<option value="gaoji" >高级版</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">希望使用的系统版本 ( 下次更新时 )</div>
</div>
<?php } ?>
<div class="layui-btn-group">
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save_key">保存</button>
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="buy_vip" data-url="<?php echo empty($data['pay_rul']) ?'':$data['pay_rul']?>" >购买授权</button>
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="Modify_Domain" data-url="https://docs.twonav.cn/#/books/root-02?id=%e4%bf%ae%e6%94%b9%e5%9f%9f%e5%90%8d" >修改域名</button>
<button class="layui-btn layui-bg-purple" type="button" id="validate" style="<?php echo empty($subscribe['order_id']) ? 'display:none;':''; ?>">正版验证</button>
</div>
@@ -141,7 +131,11 @@ layui.use(['jquery','form'], function () {
$("#order_id").val(data.data.order_id);
$("#end_time").val(timestampToTime(data.data.end_time));
$("#type_name").val(data.data.type_name);
layer.msg(data.msg, {icon: 1,time: 10000});
layer.msg('保存成功,稍后请更新系统..', {icon: 16,shade: [0.1, '#f5f5f5'],scrollbar: false,offset: 'auto',time: 3666,
end: function() {
window.parent.location.href = './?c=admin';
}
});
}else{
layer.alert(data.msg,{icon:5,title:'保存结果',anim: 2,closeBtn: 0,btn: ['我知道了']});
}
@@ -149,7 +143,12 @@ layui.use(['jquery','form'], function () {
layer.msg('请求失败', {icon: 5});
});
});
//修改域名
form.on('submit(Modify_Domain)', function(data){
let url = $(this).attr('data-url');
window.open($(this).attr('data-url'));
return false;
});
//购买授权
form.on('submit(buy_vip)', function(data){
let url = $(this).attr('data-url');
@@ -158,53 +157,6 @@ layui.use(['jquery','form'], function () {
return false;
});
//清空订阅信息
form.on('submit(del_key)', function(data){
vcode = randomnum(6);
index = layer.prompt({formType: 0,value: '',title: '请输入验证码: ' + vcode,shadeClose: false,"success":function(){
$("input.layui-layer-input").on('keydown',function(e){
if(e.which == 13) {
del_key(data);
}
});
}},function(){
del_key(data)
});
return false;
});
function del_key(data){
layer.close(index);
if($("input.layui-layer-input").val() != vcode){
layer.msg('验证码错误', {icon: 5});
return false;
}
var order_id = data.field.order_id;
if(order_id.length < 20){
layer.msg('订单号错误,请核对', {icon: 5});
return false;
}
if(data.field.email.length == 0){
layer.msg('邮箱不能为空,请核对', {icon: 5});
return false;
}
layer.load(2, {shade: [0.1,'#fff']});
$.post(get_api('other_services','del_key'),{'order_id':data.field.order_id,'email':data.field.email},function(data,status){
layer.closeAll('loading');
if(data.code == 200) {
$("#order_id").val('');
$("#email").val('');
$("#end_time").val('1970-01-01 08:00:00');
$("#type_name").val('');
layer.msg(data.msg, {icon: 1,time: 10000});
}else{
layer.alert(data.msg,{icon:5,title:'保存结果',anim: 2,closeBtn: 0,btn: ['我知道了']});
}
}).fail(function () {
layer.msg('请求失败', {icon: 5});
});
}
// 正版验证
$('#validate').on('click', function(){
vcode = randomnum(6);

View File

@@ -5,7 +5,59 @@
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.14-20240419</h4>
<h4 class="layui-timeline-title">v2.1.18-20241105</h4>
<ul>
<li>[升级] Layui组件由2.9.14升级到2.9.18</li>
<li>[升级] Medoo组件由2.1.8升级到2.1.12</li>
<li>[新增] 授权管理页面增加修改域名入口</li>
<li>[变更] 分类页面标题显示分类名称-分类描述</li>
<li>[修复] 默认登录模板输入密码处点击小眼睛未显示密码</li>
<li>[优化] 调高超时参数以兼顾网络较慢的环境</li>
<li>[优化] 默认登录模板检测到使用IE浏览器时弹出提示</li>
<li>[优化] 内置防火墙拦截时提示如何解决</li>
<li>[修复] 替换已失效的第三方图标接口</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.17-20240730</h4>
<ul>
<li>[升级] Layui组件由2.9.10升级到v2.9.13</li>
<li>[增加] Atool工具箱增加查看二级密码功能</li>
<li>[增加] Atool工具箱增加清空统计数据 ( 指全部账号概要页面的报表统计/访问统计/点击统计 )</li>
<li>[优化] 性能优化 ( 存在数据库更新,建议先备份在升级 )</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.16-20240525</h4>
<ul>
<li>[升级] Layui组件由2.9.9升级到2.9.10</li>
<li>[修复] 添加链接时上传图标未自动创建目录</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.15-20240513</h4>
<ul>
<li>[修复] 因 Gitee Pages 停止服务导致的相关问题</li>
<li>[升级] Layui组件由2.9.8升级到2.9.9</li>
<li>[变更] 系统设置隐藏部分配置(防止乱搞导致系统异常)</li>
<li>[变更] 保存授权后自动刷新页面并跳转到概要页方便新手用户更新系统</li>
<li>[移除] 自助注册功能</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.14-20240416</h4>
<ul>
<li>[修复] 修复已知的安全漏洞提高安全性</li>
<li>[修复] 分类停用时链接列表查找全部时出现已停用分类下的链接</li>

View File

@@ -31,7 +31,7 @@ if ($DescrRowNumber <= 0 ){
<?php if($referrer == 'overall' && $site['link_model'] == 'direct'){echo '<meta name="referrer" content="same-origin">'."\n";}?>
<link rel='stylesheet' href='<?php echo $libs?>/MDUI/v1.0.1/css/mdui.min.css'>
<link rel='stylesheet' href='<?php echo $libs?>/ContextMenu/2.9.2/jquery.contextMenu.min.css'>
<link rel="stylesheet" href="<?php echo $libs?>/Font-awesome/4.7.0/css/font-awesome.css">
<link rel="stylesheet" href="<?php echo $libs?>/Font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="<?php echo $theme_dir?>/static/style<?php echo $theme_config['CardNum'];?>.css?v=<?php echo $theme_ver; ?>">
<link rel="shortcut icon" href="<?php echo $favicon;?>">
<style>

View File

@@ -13,10 +13,6 @@
<link rel="stylesheet" href="<?php echo $layui['css']; ?>">
<link rel="stylesheet" href="<?php echo $libs?>/Other/login.css?v=<?php echo SysVer; ?>">
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
<!--[if lt IE 9]>
<script src="<?php echo $libs?>/Other/html5.min.js"></script>
<script src="<?php echo $libs?>/Other/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="main-body">
@@ -59,6 +55,11 @@
<script src = "<?php echo $libs?>/jquery/jquery-3.6.0.min.js"></script>
<script src = "<?php echo $layui['js']; ?>"></script>
<script src = '<?php echo $libs?>/jquery/jquery.md5.js'></script>
<script>
if (/Trident/.test(navigator.userAgent) || /MSIE/.test(navigator.userAgent)) {
alert("当前浏览器版本过低请使用Chrome浏览器或火狐浏览器等现代浏览器");
}
</script>
<script>
layui.use(['form','jquery'], function () {
var $ = layui.jquery,
@@ -68,10 +69,10 @@
$('.bind-password').on('click', function () {
if ($(this).hasClass('icon-5')) {
$(this).removeClass('icon-5');
$("input[name='Password']").attr('type', 'password');
$("input[name='password']").attr('type', 'password');
} else {
$(this).addClass('icon-5');
$("input[name='Password']").attr('type', 'text');
$("input[name='password']").attr('type', 'text');
}
});

View File

@@ -2,7 +2,7 @@
"name": "默认模板",
"description": "默认",
"homepage": "https://gitee.com/tznb/TwoNav",
"version": "2.1.1",
"update": "2023/12/20",
"version": "2.1.2",
"update": "2024/10/18",
"author": "TwoNav"
}