一个现代化的企业内部导航门户系统,用于集中管理和展示公司各类系统和资源的链接。
- 临时域名:https://eyaxltzszbal.sealosgzg.site/
- demo地址:https://www.easynav.icu
- 用户名:admin 密码:admin123
-
🔐 用户认证与授权
-
📱 响应式设计
- 支持桌面和移动设备
- 流畅的动画效果
- 现代化的 UI/UX
-
🎯 导航管理
-
🛠 管理功能
- 分组 CRUD
- 链接 CRUD
- 二级分类管理
- 排序管理
- React 18
- TypeScript
- Tailwind CSS
- Framer Motion
- React Icons
- Axios
- React Router
- Node.js
- Express
- SQLite/MySQL
- JWT
- Nodemailer
- bcrypt
- Docker
- Kubernetes
- Nginx
.
├── backend/ # 后端项目
│ ├── src/
│ │ ├── db/ # 数据库相关
│ │ ├── middleware/ # 中间件
│ │ ├── routes/ # 路由
│ │ └── utils/ # 工具函数
│ └── docs/ # 文档
├── frontend/ # 前端项目
│ ├── src/
│ │ ├── components/ # React 组件
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── services/ # API 服务
│ │ └── types/ # TypeScript 类型
└── k8s/ # Kubernetes 配置
- Node.js >= 18
- npm >= 9
- MySQL (可选,默认使用 SQLite)
# 后端
cd backend
npm install
# 前端
cd frontend
npm install
- 后端配置 (backend/.env)
PORT=3000
JWT_SECRET=your-secret-key
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-specific-password
SMTP_FROM=Company Portal <noreply@company.com>
FRONTEND_URL=http://localhost:5173
# 数据库配置
DB_TYPE=sqlite # 或 mysql
DB_NAME=database.sqlite
# MySQL 配置(如果使用 MySQL)
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=root
- 前端配置 (frontend/.env)
VITE_API_URL=http://localhost:3000/api
# 后端
cd backend
npm run dev
# 前端
cd frontend
npm run dev
- 构建镜像
# 后端
docker build -t nav-portal-backend ./backend
# 前端
docker build -t nav-portal-frontend ./frontend
- 使用 Docker Compose 启动
version: '3'
services:
frontend:
image: nav-portal-frontend
ports:
- "80:80"
depends_on:
- backend
environment:
- VITE_API_URL=http://localhost:3000/api
backend:
image: nav-portal-backend
ports:
- "3000:3000"
environment:
- JWT_SECRET=your-secret-key
- DB_TYPE=mysql
- DB_HOST=db
- DB_USER=root
- DB_PASSWORD=root
depends_on:
- db
db:
image: mysql:8
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=nav_portal
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
项目包含完整的 Kubernetes 配置文件,位于 k8s/
目录:
frontend.yaml
backend.yaml
mysql-deployment.yaml 已经删除(需要自己安装数据库信息)
ingress.yaml(或者traefik.yaml)
使用 kubectl 部署:
kubectl apply -f k8s/
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password TEXT,
is_active BOOLEAN DEFAULT FALSE,
verification_token TEXT,
wework_userid TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
modified_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE groups (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
icon TEXT NOT NULL,
sort_order INTEGER DEFAULT 100,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
modified_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE subgroups (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
group_id TEXT NOT NULL,
sort_order INTEGER DEFAULT 100,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
modified_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE links (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
subtitle TEXT NOT NULL,
url TEXT NOT NULL,
icon TEXT NOT NULL,
group_id TEXT NOT NULL,
subgroup_id TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
modified_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
POST /api/auth/register
Content-Type: application/json
{
"username": "string",
"email": "string",
"password": "string"
}
POST /api/auth/login
Content-Type: application/json
{
"username": "string",
"password": "string"
}
GET /api/auth/verify-email?token=string
GET /api/groups
Authorization: Bearer <token>
POST /api/groups
Authorization: Bearer <token>
Content-Type: application/json
{
"id": "string",
"name": "string",
"icon": "string",
"sort_order": number
}
PUT /api/groups/:id
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "string",
"icon": "string",
"sort_order": number
}
DELETE /api/groups/:id
Authorization: Bearer <token>
GET /api/links
Authorization: Bearer <token>
GET /api/links/group/:groupId
Authorization: Bearer <token>
POST /api/links
Authorization: Bearer <token>
Content-Type: application/json
{
"id": "string",
"title": "string",
"subtitle": "string",
"url": "string",
"icon": "string",
"group_id": "string",
"subgroup_id": "string"
}
PUT /api/links/:id
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "string",
"subtitle": "string",
"url": "string",
"icon": "string",
"group_id": "string",
"subgroup_id": "string"
}
DELETE /api/links/:id
Authorization: Bearer <token>
- 密码加密:使用 bcrypt 进行密码哈希
- JWT 认证:使用 JWT 进行用户认证
- CORS 保护:配置适当的 CORS 策略
- 环境变量:敏感信息通过环境变量配置
- SQL 注入防护:使用参数化查询
- XSS 防护:React 默认转义 + CSP
- 邮箱验证:新用户需要验证邮箱
- 路由懒加载
- 组件按需加载
- 图片懒加载
- 缓存静态资源
- Gzip 压缩
- Tree Shaking
- 代码分割
- 数据库索引
- 连接池
- 缓存策略
- 请求限流
- 响应压缩
- Fork 项目
- 创建特性分支
- 提交改动
- 推送到分支
- 创建 Pull Request
木兰宽松许可证