From 75c691c183b27abc65653b9f3b1c9528109de48d Mon Sep 17 00:00:00 2001
From: wzj <244142824@qq.com>
Date: Wed, 9 Jul 2025 00:35:26 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=A7=BB=E5=8A=A8=E7=AB=AF?=
=?UTF-8?q?=E6=A0=B7=E5=BC=8F=EF=BC=8C=E4=BC=98=E5=8C=96=E5=90=8E=E5=8F=B0?=
=?UTF-8?q?=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 6 +-
app.py | 42 +
data/attachments.json | 20 +
data/categories.json | 5 +
data/settings.json | 6 +-
templates/attachments.html | 179 +++--
templates/categories.html | 364 +++++++--
templates/index.html | 1478 +++++++++++++++++++-----------------
templates/manage.html | 173 +++--
9 files changed, 1395 insertions(+), 878 deletions(-)
diff --git a/README.md b/README.md
index d985e5f..a72473d 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@
## 待开发功能 ⏳
### 界面优化
1. logo图标设置区分明亮和暗黑模式
-2. 私有应用在首页添加标识
+2. 私有应用在首页添加标识 - 已完成
3. 首页卡片右键菜单
4. 应用支持配置多个URL,左键打开默认URL,右键可选择URL进行复制地址或者打开或者编辑应用
5. 新增应用界面便捷增加分类
@@ -37,10 +37,10 @@
2. 书签收藏工具
### BUG修复
-1. 游客通过接口能查看私有应用;
+1. 游客通过接口能查看私有应用 - 已修复
### 移动端适配
-1. 后台页面适配
+1. 后台页面适配 - 已完成
### 批量操作
1. 应用批量选择功能:
diff --git a/app.py b/app.py
index af3555b..3694355 100644
--- a/app.py
+++ b/app.py
@@ -1033,6 +1033,48 @@ def change_password(username, new_password):
else:
print("错误:只能修改管理员 (admin) 的密码")
+@app.route('/app/add_from_category', methods=['POST'])
+@login_required
+def add_app_from_category():
+ categories = load_categories()
+ icons = load_icons()
+ settings = load_settings()
+ attachments = load_attachments()
+
+ if request.method == 'POST':
+ title = request.form['title']
+ url = request.form['url']
+ icon = request.form['icon']
+ description = request.form.get('description', '')
+ private = 'private' in request.form
+ main_category = request.form['main_category']
+ sub_category = request.form['sub_category']
+
+ new_app = {
+ "title": title,
+ "url": url,
+ "icon": icon,
+ "description": description,
+ "private": private,
+ "category": {
+ "main": main_category,
+ "sub": sub_category
+ }
+ }
+
+ apps = load_apps()
+ apps.append(new_app)
+ save_apps(apps)
+
+ flash('应用添加成功', 'success')
+ return redirect(url_for('manage_categories'))
+
+ return render_template('add_app.html',
+ categories=categories,
+ settings=settings,
+ icons=load_icons(),
+ attachments=attachments)
+
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='导航系统管理工具')
diff --git a/data/attachments.json b/data/attachments.json
index 09656c9..642781c 100644
--- a/data/attachments.json
+++ b/data/attachments.json
@@ -63,5 +63,25 @@
"filename": "c77f6bbbb335.png",
"type": "icon",
"upload_time": "2025-07-06 20:22:28"
+ },
+ {
+ "filename": "hpCMDHrCJVq3.png",
+ "type": "logo",
+ "upload_time": "2025-07-08 21:54:48"
+ },
+ {
+ "filename": "ksDMQ8aEwEph.png",
+ "type": "logo",
+ "upload_time": "2025-07-08 21:55:09"
+ },
+ {
+ "filename": "gfpWMYOvTTuI.png",
+ "type": "logo",
+ "upload_time": "2025-07-08 21:55:20"
+ },
+ {
+ "filename": "G31hd5Kzu6t8.png",
+ "type": "logo",
+ "upload_time": "2025-07-08 21:55:29"
}
]
\ No newline at end of file
diff --git a/data/categories.json b/data/categories.json
index bae2580..96e33db 100644
--- a/data/categories.json
+++ b/data/categories.json
@@ -155,6 +155,11 @@
"name": "营养",
"color": "#4d908e",
"weight": 2
+ },
+ "swim": {
+ "name": "游泳",
+ "color": "#4895ef",
+ "weight": 4
}
},
"weight": 4,
diff --git a/data/settings.json b/data/settings.json
index 547d941..401e53a 100644
--- a/data/settings.json
+++ b/data/settings.json
@@ -1,15 +1,15 @@
{
"card_style": "compact",
"search_history": [],
- "theme": "light",
+ "theme": "dark",
"bg_image": "/upload/background/5dd4f5d3cd7b.png",
"dark_bg_image": "/upload/background/d078c01de3be.png",
"site_title": "应用导航中心",
"show_logo": true,
"logo_type": "image",
"logo_icon": "fa-solid fa-th-list",
- "logo_image": "/upload/logo/f40e2eb965b2.png",
+ "logo_image": "/upload/logo/hpCMDHrCJVq3.png",
"dark_bg_rotate": false,
"admin_password_hash": "pbkdf2:sha256:260000$ig0vNC2QdipLHgAy$6d734e5112bbdf94bc5cb49a38ca4764376ebb51c877a416d1a8f27d5fb5c415",
- "footer_html": "
\r\n
\r\n
© 2023 AIDaohang. All rights reserved. \r\n
| \r\n
Powered by AIDaohang \r\n
\r\n
"
+ "footer_html": "\r\n
\r\n
© 2023 AIDaohang. All rights reserved. \r\n
| \r\n
Powered by AIDaohang \r\n
\r\n
"
}
\ No newline at end of file
diff --git a/templates/attachments.html b/templates/attachments.html
index e6d8979..dc1c551 100644
--- a/templates/attachments.html
+++ b/templates/attachments.html
@@ -34,6 +34,8 @@
附件列表
+
+
-
-
-
-
- 预览
- 文件名
- 类型
- 上传时间
- 操作
-
-
-
- {% for attachment in attachments %}
-
-
- {% if attachment.type == 'logo' %}
-
- {% elif attachment.type == 'background' %}
-
- {% elif attachment.type == 'video' %}
-
-
-
- {% else %}
-
- {% endif %}
-
- {{ attachment.filename }}
-
- {% if attachment.type == 'logo' %}
- Logo
- {% elif attachment.type == 'background' %}
- 背景图片
- {% elif attachment.type == 'video' %}
- 背景视频
- {% else %}
- 图标图片
- {% endif %}
-
- {{ attachment.upload_time }}
-
-
-
-
- {% else %}
-
- 没有找到匹配的附件
-
- {% endfor %}
-
-
+
+
+
+
+
+
+
+ 预览
+ 文件名
+ 类型
+ 上传时间
+ 操作
+
+
+
+ {% for attachment in attachments %}
+
+
+ {% if attachment.type == 'logo' %}
+
+ {% elif attachment.type == 'background' %}
+
+ {% elif attachment.type == 'video' %}
+
+
+
+ {% else %}
+
+ {% endif %}
+
+ {{ attachment.filename }}
+
+ {% if attachment.type == 'logo' %}
+ Logo
+ {% elif attachment.type == 'background' %}
+ 背景图片
+ {% elif attachment.type == 'video' %}
+ 背景视频
+ {% else %}
+ 图标图片
+ {% endif %}
+
+ {{ attachment.upload_time }}
+
+
+
+
+ {% else %}
+
+ 没有找到匹配的附件
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+ {% for attachment in attachments %}
+
+
+
+
+
+ {% if attachment.type == 'logo' %}
+
+ {% elif attachment.type == 'background' %}
+
+ {% elif attachment.type == 'video' %}
+
+
+
+ {% else %}
+
+ {% endif %}
+
+
+
{{ attachment.filename }}
+
+ {% if attachment.type == 'logo' %}
+ Logo
+ {% elif attachment.type == 'background' %}
+ 背景图片
+ {% elif attachment.type == 'video' %}
+ 背景视频
+ {% else %}
+ 图标图片
+ {% endif %}
+
+
{{ attachment.upload_time }}
+
+
+
+
+
+
+ {% else %}
+
+ {% endfor %}
+
@@ -133,11 +192,11 @@
{% endif %}
-
+
{% endblock %}
\ No newline at end of file
diff --git a/templates/categories.html b/templates/categories.html
index f5c0f1b..0f03319 100644
--- a/templates/categories.html
+++ b/templates/categories.html
@@ -3,99 +3,310 @@
{% block title %}分类管理{% endblock %}
{% block content %}
+
+
+
+
+
+
添加主分类
-
-
-
-
-
-
添加子分类
-
-
- 选择主分类
- {% for main_id, cat in categories.items() %}
- {{ cat.name }}
- {% endfor %}
-
-
-
-
-
-
已存在的分类
-
- {% for main_id, cat in categories.items() %}
-
-
-
- {{ cat.name }} (ID: {{ main_id }})
- {{ cat.color }}
- {% if cat.get('private', False) %}
- 私有
- {% endif %}
-
-
-
- 编辑
-
-
- 删除
-
+
+
+
+ {% for main_id, cat in categories.items()|sort(attribute='1.weight', reverse=True) %}
+
+
+
+ {{ cat.name }} (ID: {{ main_id }})
+ {{ cat.get('weight', 0) }}
+ {% if cat.get('private', False) %}
+ 私有
+ {% endif %}
+
+
+
+ {% for sub_id, subData in cat.sub.items()|sort(attribute='1.weight', reverse=True) %}
+
+
+ {{ subData.name }}(ID: {{ sub_id }})
+ {{ subData.get('weight', 0) }}
+ {% if cat.get('sub_private', {}).get(sub_id, False) %}
+ 私有
+ {% endif %}
+
+
+
+ {% endfor %}
+
-
- {% for sub_id, subData in cat.sub.items() %}
-
-
- {{ subData.name }}(ID: {{ sub_id }})
- {{ subData.color }}
- {% if cat.get('sub_private', {}).get(sub_id, False) %}
- 私有
- {% endif %}
-
-
+
+
+
+
+
+ {% for main_id, cat in categories.items()|sort(attribute='1.weight', reverse=True) %}
+
+
+
+
+
+
+ 添加子分类
+
+
+ 编辑主分类
-
+
删除
-
- {% endfor %}
-
-
- {% endfor %}
+
+
子分类列表
+ {% for sub_id, subData in cat.sub.items()|sort(attribute='1.weight', reverse=True) %}
+
+
+
+
+ {{ subData.name }} (ID: {{ sub_id }})
+ {{ subData.get('weight', 0) }}
+ {% if cat.get('sub_private', {}).get(sub_id, False) %}
+ 私有
+ {% endif %}
+
+
+
+
+ 添加应用
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+ {% endfor %}
+
+
+
+ {% endfor %}
+
@@ -106,4 +317,15 @@
+
+
{% endblock %}
\ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
index edbe4d2..6e5eef1 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2,7 +2,7 @@
-
+
应用导航
{% if settings and settings.logo_type == 'image' and settings.logo_image %}
@@ -25,6 +25,9 @@
--bg-image: none;
--dark-bg-image: none;
}
+ * {
+ box-sizing: border-box;
+ }
body {
font-family: 'Segoe UI', system-ui, sans-serif;
max-width: 1400px;
@@ -33,6 +36,8 @@
background-color: #f8f9fa;
color: #333;
transition: background-color 0.3s ease, color 0.3s ease;
+ overflow-x: hidden;
+ width: 100%;
}
/* 新增私有卡片标记样式 */
@@ -45,7 +50,7 @@
border-style: solid;
border-width: 0 30px 30px 0;
border-color: transparent #f8961e transparent transparent;
- border-radius: 0 12px 0 0; /* 只圆角右上角 */
+ border-radius: 0 12px 0 0;
}
.private-badge::after {
@@ -152,6 +157,8 @@
margin: 20px auto;
max-width: 600px;
position: relative;
+ width: 100%;
+ padding: 0 15px;
}
.search-input {
width: 100%;
@@ -164,7 +171,7 @@
}
.search-results {
position: absolute;
- width: 100%;
+ width: calc(100% - 30px);
background: white;
border-radius: 0 0 10px 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
@@ -237,9 +244,24 @@
/* 暗黑模式下的按钮样式 */
body.dark-theme .floating-btn {
background: #444;
- color: #eee;
+ color: #e0e0e0;
}
+.floating-btn#addBtn {
+ background-color: var(--primary-color);
+ color: white;
+ display: none;
+}
+
+.floating-btn#addBtn:hover {
+ background-color: var(--hover-color);
+}
+
+body.dark-theme .floating-btn#addBtn {
+ background-color: #444;
+ color: #e0e0e0;
+}
+
/* 简洁模式卡片样式 */
.app-item.compact {
padding: 10px 15px;
@@ -330,7 +352,7 @@
color: #aaa !important;
}
- /* 修改后的筛选容器样式 - 支持横向滚动 */
+ /* 修改后的筛选容器样式 */
.filter-container {
display: flex;
flex-direction: column;
@@ -346,9 +368,14 @@
padding: 15px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s ease, color 0.3s ease;
+ margin-left: -15px;
+ margin-right: -15px;
+ padding-left: 20px;
+ padding-right: 20px;
+ width: calc(100% + 30px);
}
- /* 修改后的筛选行样式 - 支持横向滚动 */
+ /* 修改后的筛选行样式 */
.filter-row {
display: flex;
flex-wrap: nowrap;
@@ -357,10 +384,13 @@
padding-bottom: 10px;
scrollbar-width: thin;
scrollbar-color: #c2c3c9d6;
- justify-content: center; /* 默认居中 */
- padding: 0 20px; /* 添加内边距 */
+ justify-content: center;
+ padding: 0 15px;
scroll-behavior: smooth;
position: relative;
+ margin-left: -10px;
+ margin-right: -10px;
+ width: calc(100% + 20px);
}
/* 当内容超出时靠左 */
@@ -417,8 +447,8 @@ body.dark-theme .filter-row::after {
font-size: 14px;
display: flex;
align-items: center;
- white-space: nowrap; /* 禁止按钮内文字换行 */
- flex-shrink: 0; /* 禁止按钮缩小 */
+ white-space: nowrap;
+ flex-shrink: 0;
}
.filter-btn:hover {
transform: translateY(-2px);
@@ -463,7 +493,7 @@ body.dark-theme .filter-row::after {
transform: rotate(90deg);
}
- /* 修改后的二级筛选容器样式 - 支持横向滚动 */
+ /* 修改后的二级筛选容器样式 */
.secondary-filters-container {
width: 100%;
display: none;
@@ -473,10 +503,13 @@ body.dark-theme .filter-row::after {
padding-bottom: 10px;
scrollbar-width: thin;
scrollbar-color: #c2c3c9d6;
- justify-content: center; /* 默认居中 */
- padding: 0 20px; /* 添加内边距 */
+ justify-content: center;
+ padding: 0 15px;
scroll-behavior: smooth;
position: relative;
+ margin-left: -10px;
+ margin-right: -10px;
+ width: calc(100% + 20px);
}
/* 私有主分类 */
@@ -542,6 +575,7 @@ body.dark-theme .secondary-filters-container::after {
.app-list-container {
margin-top: 20px;
position: relative;
+ width: 100%;
}
.category-title {
font-size: 20px;
@@ -558,11 +592,13 @@ body.dark-theme .secondary-filters-container::after {
}
.app-group {
margin-bottom: 30px;
+ width: 100%;
}
.app-list {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 20px;
+ width: 100%;
}
@media (max-width: 1200px) {
.app-list {
@@ -578,11 +614,34 @@ body.dark-theme .secondary-filters-container::after {
.app-list {
grid-template-columns: repeat(2, 1fr);
}
+ body {
+ padding: 15px;
+ }
+ .filter-container {
+ margin-left: -15px;
+ margin-right: -15px;
+ padding-left: 20px;
+ padding-right: 20px;
+ width: calc(100% + 30px);
+ }
+ .floating-btn::after {
+ display: none;
+ }
}
@media (max-width: 576px) {
.app-list {
grid-template-columns: 1fr;
}
+ body {
+ padding: 10px;
+ }
+ .filter-container {
+ margin-left: -10px;
+ margin-right: -10px;
+ padding-left: 15px;
+ padding-right: 15px;
+ width: calc(100% + 20px);
+ }
}
.app-item {
background-color: #ffffff69;
@@ -597,6 +656,7 @@ body.dark-theme .secondary-filters-container::after {
text-decoration: none;
color: inherit;
position: relative;
+ width: 100%;
}
.app-item:hover {
transform: translateY(-5px);
@@ -737,6 +797,7 @@ body.dark-theme .secondary-filters-container::after {
border-top: 1px solid #eee;
text-align: center;
color: #777;
+ width: 100%;
}
@@ -783,10 +844,12 @@ body.dark-theme .secondary-filters-container::after {