v1.0.0 bug修复更新
This commit is contained in:
229
README.md
229
README.md
@@ -1,206 +1,135 @@
|
|||||||
# PerToolBox Front - 前端界面
|
# PerToolBox Front - 前端界面
|
||||||
|
|
||||||
> 一个基于 PHP + HTML/CSS/JS 的个人工具箱前端项目,采用响应式侧边栏设计,适配多端设备。
|
> 基于 PHP 的轻量级个人工具箱前端
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 项目信息
|
## 📋 项目信息
|
||||||
|
|
||||||
|
- 项目名称:PerToolBox Front
|
||||||
|
- 项目类型:Web 前端界面
|
||||||
- 版权所有:Sea Network Technology Studio
|
- 版权所有:Sea Network Technology Studio
|
||||||
- 权利人:Canglan
|
- 权利人:Canglan
|
||||||
- 联系方式:admin@sea-studio.top
|
|
||||||
- 开源协议:AGPL v3
|
- 开源协议:AGPL v3
|
||||||
|
- 联系方式:admin@sea-studio.top
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 功能特性
|
## ✨ 功能模块
|
||||||
|
|
||||||
- 响应式侧边栏(支持手机 / PC)
|
### 🔐 用户系统
|
||||||
- 用户认证(登录 / 注册 / 验证码)
|
- 登录 / 注册
|
||||||
- 待办事项管理(CRUD)
|
|
||||||
- 便签本(CRUD)
|
### 📝 数据功能
|
||||||
- 密码生成器
|
- 待办事项
|
||||||
- 二维码生成
|
- 便签本
|
||||||
- 加密工具箱:
|
|
||||||
- Hash
|
### 🧰 工具模块
|
||||||
- Base64
|
- 密码生成器
|
||||||
- URL 编码
|
- 二维码生成
|
||||||
- AES 加密
|
- 加密工具箱
|
||||||
- JSON 校验与格式化
|
- JSON 校验器
|
||||||
- 热度统计展示
|
|
||||||
|
### 📊 展示功能
|
||||||
|
- 工具访问热度展示
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 环境要求
|
## 🎨 特性
|
||||||
|
|
||||||
- PHP >= 8.0
|
- 响应式布局(桌面 / 移动端)
|
||||||
- Nginx 或 Apache
|
- TailwindCSS(CDN)
|
||||||
|
- 无构建流程(即开即用)
|
||||||
|
- 结构清晰,易扩展
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 快速开始
|
## 🛠️ 技术栈
|
||||||
|
|
||||||
### 1. 克隆项目
|
| 技术 | 版本 |
|
||||||
|
|------|------|
|
||||||
|
| PHP | 8.0+ |
|
||||||
|
| Nginx / Apache | 最新稳定版 |
|
||||||
|
| TailwindCSS | CDN |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 配置
|
||||||
|
|
||||||
|
编辑配置文件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vim config.php
|
||||||
|
```
|
||||||
|
|
||||||
|
设置:
|
||||||
|
|
||||||
|
- API_BASE_URL=http://127.0.0.1:9999/api/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 1. 获取代码
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://hz-gitea.sea-studio.top/Sea-Studio/PerToolBoxFront.git
|
git clone https://hz-gitea.sea-studio.top/Sea-Studio/PerToolBoxFront.git
|
||||||
cd PerToolBoxFront
|
cd PerToolBoxFront
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 配置后端接口
|
### 2. 配置 API
|
||||||
|
|
||||||
编辑 config.php:
|
```bash
|
||||||
|
vim config.php
|
||||||
```php
|
|
||||||
define('API_BASE_URL', 'https://your-domain/api/v1');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 配置 Nginx
|
---
|
||||||
|
|
||||||
|
## 🌐 Nginx 配置
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name your-domain;
|
server_name toolbox.your-domain.com;
|
||||||
|
|
||||||
root /path/to/PerToolBoxFront;
|
root /www/wwwroot/PerToolBoxFront;
|
||||||
index index.php;
|
index index.php;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.php;
|
try_files $uri $uri/ /index.php?$args;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ \.php$ {
|
location ~ \.php$ {
|
||||||
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
|
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
|
||||||
fastcgi_index index.php;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:9999/api/;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 访问项目
|
|
||||||
|
|
||||||
```
|
|
||||||
http://your-domain
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 项目结构
|
## 📁 项目结构
|
||||||
|
|
||||||
```text
|
|
||||||
PerToolBoxFront/
|
PerToolBoxFront/
|
||||||
├── index.php # 首页
|
├── index.php
|
||||||
├── login.php # 登录/注册
|
├── login.php
|
||||||
├── profile.php # 个人中心
|
├── profile.php
|
||||||
├── config.php # 配置文件
|
├── config.php
|
||||||
├── header.php # 公共头部
|
├── header.php
|
||||||
├── footer.php # 公共底部
|
├── footer.php
|
||||||
├── sidebar.php # 侧边栏
|
├── sidebar.php
|
||||||
├── css/
|
├── css/
|
||||||
│ └── style.css # 样式文件
|
├── js/
|
||||||
├── js/
|
└── pages/
|
||||||
│ └── common.js # 公共脚本
|
|
||||||
└── pages/ # 功能页面
|
|
||||||
├── todos.php # 待办事项
|
|
||||||
├── notes.php # 便签
|
|
||||||
├── password.php # 密码生成
|
|
||||||
├── qrcode.php # 二维码
|
|
||||||
├── crypto.php # 加密工具
|
|
||||||
└── json.php # JSON 工具
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 后端 API 要求
|
## 📞 联系方式
|
||||||
|
|
||||||
后端服务基础路径:
|
- Git:https://hz-gitea.sea-studio.top/Sea-Studio/PerToolBoxFront
|
||||||
|
- 邮箱:admin@sea-studio.top
|
||||||
```
|
|
||||||
https://your-domain/api/v1
|
|
||||||
```
|
|
||||||
|
|
||||||
实现以下接口:
|
|
||||||
|
|
||||||
### 认证模块
|
|
||||||
|
|
||||||
- 用户注册
|
|
||||||
- 用户登录
|
|
||||||
- 验证码发送
|
|
||||||
|
|
||||||
### 数据模块
|
|
||||||
|
|
||||||
- 待办事项 CRUD
|
|
||||||
- 便签 CRUD
|
|
||||||
|
|
||||||
### 工具模块
|
|
||||||
|
|
||||||
- 密码生成
|
|
||||||
- 二维码生成
|
|
||||||
- 加密 / 解密
|
|
||||||
- JSON 处理
|
|
||||||
|
|
||||||
### 统计模块
|
|
||||||
|
|
||||||
- 热度统计接口
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 部署指南
|
|
||||||
|
|
||||||
### 后端部署
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 安装依赖
|
|
||||||
sudo dnf install -y python python-pip mysql redis nginx git # CentOS/Rocky
|
|
||||||
sudo apt install -y python python-pip mysql redis nginx git # Ubuntu/Debian
|
|
||||||
|
|
||||||
# 2. 克隆项目
|
|
||||||
git clone https://hz-gitea.sea-studio.top/Sea-Studio/PerToolBoxServer.git
|
|
||||||
cd PerToolBoxServer
|
|
||||||
|
|
||||||
# 3. 创建虚拟环境
|
|
||||||
python -m venv venv
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# 4. 安装依赖
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# 5. 配置环境变量
|
|
||||||
cp .env.example .env
|
|
||||||
# 编辑 .env 文件(数据库 / Redis / 短信服务)
|
|
||||||
|
|
||||||
# 6. 初始化数据库
|
|
||||||
mysql -u root -p < scripts/init_db.sql
|
|
||||||
|
|
||||||
# 7. 启动服务
|
|
||||||
uvicorn backend.main:app --host 0.0.0.0 --port 8000
|
|
||||||
```
|
|
||||||
|
|
||||||
### 前端部署(Linux + Nginx + PHP)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 安装依赖
|
|
||||||
sudo dnf install -y php php-fpm nginx # CentOS/Rocky
|
|
||||||
sudo apt install -y php php-fpm nginx # Ubuntu/Debian
|
|
||||||
|
|
||||||
# 2. 克隆项目
|
|
||||||
git clone https://hz-gitea.sea-studio.top/Sea-Studio/PerToolBoxFront.git
|
|
||||||
cd PerToolBoxFront
|
|
||||||
|
|
||||||
# 3. 配置 API 地址
|
|
||||||
# 编辑 config.php
|
|
||||||
|
|
||||||
# 4. 配置 Nginx
|
|
||||||
# 参考上方配置
|
|
||||||
|
|
||||||
# 5. 启动服务
|
|
||||||
sudo systemctl start php-fpm
|
|
||||||
sudo systemctl start nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 许可证
|
|
||||||
|
|
||||||
本项目基于 AGPL v3 协议开源。
|
|
||||||
@@ -14,7 +14,7 @@ define('API_BASE_URL', getenv('API_BASE_URL') ?: 'http://your-domain/api/v1');
|
|||||||
define('SITE_NAME', 'PerToolBox');
|
define('SITE_NAME', 'PerToolBox');
|
||||||
|
|
||||||
// 调试模式
|
// 调试模式
|
||||||
define('DEBUG', getenv('DEBUG') === 'true');
|
define('DEBUG', getenv('DEBUG') === 'false');
|
||||||
|
|
||||||
// 错误报告
|
// 错误报告
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
40
js/common.js
40
js/common.js
@@ -1,8 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* PerToolBox Front - 公共 JavaScript
|
* PerToolBox Front - 公共 JavaScript
|
||||||
* Copyright (C) 2024 Sea Network Technology Studio
|
|
||||||
* Author: Canglan <admin@sea-studio.top>
|
|
||||||
* License: AGPL v3
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ========== 全局变量 ==========
|
// ========== 全局变量 ==========
|
||||||
@@ -27,7 +24,10 @@ function isLoggedIn() {
|
|||||||
|
|
||||||
// ========== API 请求封装 ==========
|
// ========== API 请求封装 ==========
|
||||||
async function apiRequest(endpoint, options = {}) {
|
async function apiRequest(endpoint, options = {}) {
|
||||||
const url = endpoint.startsWith('http') ? endpoint : `${window.API_BASE}${endpoint}`;
|
// 使用 window.API_BASE,如果未定义则使用默认值
|
||||||
|
const baseUrl = window.API_BASE || '/api/v1';
|
||||||
|
const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...options.headers
|
...options.headers
|
||||||
@@ -45,7 +45,6 @@ async function apiRequest(endpoint, options = {}) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// token 失效,清除本地存储并跳转登录页
|
|
||||||
setToken(null);
|
setToken(null);
|
||||||
if (!window.location.pathname.includes('/login.php')) {
|
if (!window.location.pathname.includes('/login.php')) {
|
||||||
window.location.href = '/login.php';
|
window.location.href = '/login.php';
|
||||||
@@ -68,6 +67,7 @@ async function apiRequest(endpoint, options = {}) {
|
|||||||
async function recordUsage(toolName) {
|
async function recordUsage(toolName) {
|
||||||
try {
|
try {
|
||||||
await apiRequest(`/tool/usage?tool_name=${toolName}`, { method: 'POST' });
|
await apiRequest(`/tool/usage?tool_name=${toolName}`, { method: 'POST' });
|
||||||
|
console.log(`✅ 热度上报: ${toolName}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('热度上报失败:', error);
|
console.warn('热度上报失败:', error);
|
||||||
}
|
}
|
||||||
@@ -102,17 +102,19 @@ function updateUserUI(user) {
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
const displayName = user.username || user.phone || user.email || '用户';
|
const displayName = user.username || user.phone || user.email || '用户';
|
||||||
userInfoDiv.innerHTML = `
|
if (userInfoDiv) {
|
||||||
<div class="px-6 py-3 bg-blue-800 rounded-lg mx-4 mb-2">
|
userInfoDiv.innerHTML = `
|
||||||
<div class="text-sm text-blue-200">欢迎,</div>
|
<div class="px-6 py-3 bg-blue-800 rounded-lg mx-4 mb-2">
|
||||||
<div class="font-semibold">${escapeHtml(displayName)}</div>
|
<div class="text-sm text-blue-200">欢迎,</div>
|
||||||
</div>
|
<div class="font-semibold">${escapeHtml(displayName)}</div>
|
||||||
`;
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
if (profileLink) profileLink.style.display = 'flex';
|
if (profileLink) profileLink.style.display = 'flex';
|
||||||
if (logoutBtn) logoutBtn.style.display = 'flex';
|
if (logoutBtn) logoutBtn.style.display = 'flex';
|
||||||
if (loginLink) loginLink.style.display = 'none';
|
if (loginLink) loginLink.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
userInfoDiv.innerHTML = '';
|
if (userInfoDiv) userInfoDiv.innerHTML = '';
|
||||||
if (profileLink) profileLink.style.display = 'none';
|
if (profileLink) profileLink.style.display = 'none';
|
||||||
if (logoutBtn) logoutBtn.style.display = 'none';
|
if (logoutBtn) logoutBtn.style.display = 'none';
|
||||||
if (loginLink) loginLink.style.display = 'flex';
|
if (loginLink) loginLink.style.display = 'flex';
|
||||||
@@ -149,17 +151,6 @@ function initSidebar() {
|
|||||||
if (menuBtn) menuBtn.addEventListener('click', openSidebar);
|
if (menuBtn) menuBtn.addEventListener('click', openSidebar);
|
||||||
if (closeBtn) closeBtn.addEventListener('click', closeSidebar);
|
if (closeBtn) closeBtn.addEventListener('click', closeSidebar);
|
||||||
if (overlay) overlay.addEventListener('click', closeSidebar);
|
if (overlay) overlay.addEventListener('click', closeSidebar);
|
||||||
|
|
||||||
// 点击侧边栏内的链接后自动关闭(移动端)
|
|
||||||
if (sidebar) {
|
|
||||||
sidebar.querySelectorAll('a').forEach(link => {
|
|
||||||
link.addEventListener('click', () => {
|
|
||||||
if (window.innerWidth < 768) {
|
|
||||||
closeSidebar();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== HTML 转义 ==========
|
// ========== HTML 转义 ==========
|
||||||
@@ -186,7 +177,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
initSidebar();
|
initSidebar();
|
||||||
loadUserInfo();
|
loadUserInfo();
|
||||||
|
|
||||||
// 绑定退出按钮
|
|
||||||
const logoutBtn = document.getElementById('logoutBtn');
|
const logoutBtn = document.getElementById('logoutBtn');
|
||||||
if (logoutBtn) {
|
if (logoutBtn) {
|
||||||
logoutBtn.addEventListener('click', (e) => {
|
logoutBtn.addEventListener('click', (e) => {
|
||||||
@@ -194,4 +184,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
logout();
|
logout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user