新增说明文件
This commit is contained in:
260
NGINX_API.md
Normal file
260
NGINX_API.md
Normal file
@@ -0,0 +1,260 @@
|
||||
# Nginx 服务 API 说明
|
||||
|
||||
## 功能说明
|
||||
|
||||
1. **应用启动时自动检测 nginx 状态**
|
||||
- 启动应用时会自动调用 `OnStartup()` 检测 nginx 是否在运行
|
||||
- 如果检测到 nginx 进程,会自动设置 `Running = true`
|
||||
- 不会自动启动或停止 nginx
|
||||
|
||||
2. **应用关闭时保持 nginx 运行**
|
||||
- 关闭应用时调用 `OnShutdown()`,但不会停止 nginx
|
||||
- nginx 进程继续在后台运行
|
||||
- 下次启动应用时会自动检测到运行状态
|
||||
|
||||
## 前端可调用方法
|
||||
|
||||
### 进程管理
|
||||
|
||||
#### 启动 Nginx
|
||||
```typescript
|
||||
import { App } from '../bindings/go-site-clone'
|
||||
|
||||
try {
|
||||
await App.StartNginx()
|
||||
console.log('Nginx 启动成功')
|
||||
} catch (error) {
|
||||
console.error('Nginx 启动失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 停止 Nginx
|
||||
```typescript
|
||||
try {
|
||||
await App.StopNginx()
|
||||
console.log('Nginx 停止成功')
|
||||
} catch (error) {
|
||||
console.error('Nginx 停止失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 重启 Nginx
|
||||
```typescript
|
||||
try {
|
||||
await App.RestartNginx()
|
||||
console.log('Nginx 重启成功')
|
||||
} catch (error) {
|
||||
console.error('Nginx 重启失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 重载配置
|
||||
```typescript
|
||||
try {
|
||||
await App.ReloadNginx()
|
||||
console.log('Nginx 配置重载成功')
|
||||
} catch (error) {
|
||||
console.error('Nginx 配置重载失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 检查状态
|
||||
```typescript
|
||||
try {
|
||||
const running = await App.CheckNginxStatus()
|
||||
console.log('Nginx 运行状态:', running)
|
||||
} catch (error) {
|
||||
console.error('检查状态失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 测试配置
|
||||
```typescript
|
||||
try {
|
||||
await App.TestNginxConfig()
|
||||
console.log('配置文件有效')
|
||||
} catch (error) {
|
||||
console.error('配置文件测试失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
### 站点管理
|
||||
|
||||
#### 添加站点
|
||||
```typescript
|
||||
const siteConfig = {
|
||||
name: 'example.com',
|
||||
domains: ['example.com', '127.0.0.1'],
|
||||
port: 80,
|
||||
path: '/www/example.com',
|
||||
index: 'index.html',
|
||||
enabled: true
|
||||
}
|
||||
|
||||
try {
|
||||
await App.AddNginxSite(siteConfig)
|
||||
console.log('站点添加成功')
|
||||
} catch (error) {
|
||||
console.error('站点添加失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 删除站点
|
||||
```typescript
|
||||
try {
|
||||
await App.DeleteNginxSite('example.com')
|
||||
console.log('站点删除成功')
|
||||
} catch (error) {
|
||||
console.error('站点删除失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 更新站点
|
||||
```typescript
|
||||
const updatedConfig = {
|
||||
name: 'example.com',
|
||||
domains: ['example.com', 'www.example.com'],
|
||||
port: 8080,
|
||||
path: '/www/example.com',
|
||||
index: 'index.html',
|
||||
enabled: true
|
||||
}
|
||||
|
||||
try {
|
||||
await App.UpdateNginxSite(updatedConfig)
|
||||
console.log('站点更新成功')
|
||||
} catch (error) {
|
||||
console.error('站点更新失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取所有站点
|
||||
```typescript
|
||||
try {
|
||||
const sites = await App.GetAllNginxSites()
|
||||
console.log('站点列表:', sites)
|
||||
} catch (error) {
|
||||
console.error('获取站点列表失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 启用站点
|
||||
```typescript
|
||||
try {
|
||||
await App.EnableNginxSite('example.com')
|
||||
console.log('站点启用成功')
|
||||
} catch (error) {
|
||||
console.error('站点启用失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 禁用站点
|
||||
```typescript
|
||||
try {
|
||||
await App.DisableNginxSite('example.com')
|
||||
console.log('站点禁用成功')
|
||||
} catch (error) {
|
||||
console.error('站点禁用失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
#### 获取访问日志(最后100行)
|
||||
```typescript
|
||||
try {
|
||||
const logs = await App.GetNginxAccessLog(100)
|
||||
console.log('访问日志:', logs)
|
||||
} catch (error) {
|
||||
console.error('获取访问日志失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取错误日志(最后100行)
|
||||
```typescript
|
||||
try {
|
||||
const logs = await App.GetNginxErrorLog(100)
|
||||
console.log('错误日志:', logs)
|
||||
} catch (error) {
|
||||
console.error('获取错误日志失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
#### 清空日志
|
||||
```typescript
|
||||
try {
|
||||
await App.ClearNginxLogs()
|
||||
console.log('日志清空成功')
|
||||
} catch (error) {
|
||||
console.error('日志清空失败:', error)
|
||||
}
|
||||
```
|
||||
|
||||
## 数据结构
|
||||
|
||||
### NginxSiteConfig
|
||||
```typescript
|
||||
interface NginxSiteConfig {
|
||||
ID: string // 站点唯一ID(可选)
|
||||
name: string // 站点名称
|
||||
domains: string[] // 域名列表
|
||||
port: number // 监听端口
|
||||
path: string // 网站根目录路径
|
||||
index: string // 默认首页文件
|
||||
enabled: boolean // 是否启用
|
||||
}
|
||||
```
|
||||
|
||||
## 工作流程示例
|
||||
|
||||
### 页面初始化时检查 nginx 状态
|
||||
```typescript
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { App } from '../bindings/go-site-clone'
|
||||
|
||||
const nginxRunning = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
nginxRunning.value = await App.CheckNginxStatus()
|
||||
} catch (error) {
|
||||
console.error('检查 nginx 状态失败:', error)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 完整的站点托管流程
|
||||
```typescript
|
||||
// 1. 检查 nginx 状态
|
||||
const running = await App.CheckNginxStatus()
|
||||
|
||||
// 2. 如果未运行,启动 nginx
|
||||
if (!running) {
|
||||
await App.StartNginx()
|
||||
}
|
||||
|
||||
// 3. 添加站点配置
|
||||
await App.AddNginxSite({
|
||||
name: 'mysite.com',
|
||||
domains: ['mysite.com', '127.0.0.1'],
|
||||
port: 80,
|
||||
path: '/www/mysite.com',
|
||||
index: 'index.html',
|
||||
enabled: true
|
||||
})
|
||||
|
||||
// 4. 重载配置使其生效
|
||||
await App.ReloadNginx()
|
||||
|
||||
// 5. 验证站点已添加
|
||||
const sites = await App.GetAllNginxSites()
|
||||
console.log('当前托管站点:', sites)
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **Windows 路径处理**:路径会自动转换为 nginx 兼容格式(斜杠)
|
||||
2. **配置文件位置**:站点配置保存在 `plugin/nginx/conf/hosts/` 目录
|
||||
3. **禁用站点**:禁用的站点配置会移动到 `plugin/nginx/conf/hosts.disabled/` 目录
|
||||
4. **自动重载**:添加、删除、更新站点时,如果 nginx 正在运行会自动重载配置
|
||||
5. **持久化运行**:应用关闭后 nginx 继续运行,重新打开应用会自动检测状态
|
||||
275
STORAGE.md
Normal file
275
STORAGE.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# BBolt 本地化存储方案实施文档
|
||||
|
||||
## 概述
|
||||
|
||||
本项目已成功集成 BBolt 嵌入式数据库,实现高效的本地化持久化存储。BBolt 是纯 Go 实现的键值数据库,单文件存储,无需安装额外依赖。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 数据库文件
|
||||
- **位置**: `data/site-clone.db`
|
||||
- **格式**: BBolt 数据库文件(二进制)
|
||||
- **特点**: 单文件、可复制、可备份
|
||||
|
||||
### Bucket 结构
|
||||
|
||||
```
|
||||
site-clone.db
|
||||
├── sites/ # 站点配置数据
|
||||
│ ├── example.com → {NginxSiteConfig + 时间戳}
|
||||
│ └── test.com → {NginxSiteConfig + 时间戳}
|
||||
├── download_records/ # 下载记录
|
||||
│ ├── 1234567890 → {DownloadRecord}
|
||||
│ └── 1234567891 → {DownloadRecord}
|
||||
├── access_logs/ # 访问日志(预留)
|
||||
└── settings/ # 系统设置(预留)
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 站点配置管理
|
||||
|
||||
#### 数据结构
|
||||
```go
|
||||
type NginxSiteConfig struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Domains []string `json:"domains"`
|
||||
Port int `json:"port"`
|
||||
Path string `json:"path"`
|
||||
Index string `json:"index"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type SiteRecord struct {
|
||||
NginxSiteConfig
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 可用方法
|
||||
- `AddSite(site)` - 添加站点配置
|
||||
- `GetSite(name)` - 获取单个站点
|
||||
- `GetAllSites()` - 获取所有站点
|
||||
- `UpdateSite(site)` - 更新站点配置
|
||||
- `DeleteSite(name)` - 删除站点配置
|
||||
- `UpdateSiteStatus(name, enabled)` - 更新启用状态
|
||||
- `GetSitesByStatus(enabled)` - 按状态筛选站点
|
||||
- `SiteExists(name)` - 检查站点是否存在
|
||||
|
||||
### 2. 下载记录管理
|
||||
|
||||
#### 数据结构
|
||||
```go
|
||||
type DownloadRecord struct {
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
SiteName string `json:"site_name"`
|
||||
Status string `json:"status"` // success, failed, processing
|
||||
TotalFiles int `json:"total_files"`
|
||||
Downloaded int `json:"downloaded"`
|
||||
CSSCount int `json:"css_count"`
|
||||
ScriptCount int `json:"script_count"`
|
||||
ImageCount int `json:"image_count"`
|
||||
VideoCount int `json:"video_count"`
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
EndTime time.Time `json:"end_time"`
|
||||
Duration int64 `json:"duration"`
|
||||
}
|
||||
```
|
||||
|
||||
#### 可用方法
|
||||
- `AddDownloadRecord(record)` - 添加下载记录
|
||||
- `GetDownloadRecord(id)` - 获取单条记录
|
||||
- `GetAllDownloadRecords()` - 获取所有记录
|
||||
- `UpdateDownloadRecord(record)` - 更新记录
|
||||
- `DeleteDownloadRecord(id)` - 删除记录
|
||||
- `GetDownloadRecordsBySite(name)` - 按站点筛选
|
||||
- `GetDownloadRecordsByStatus(status)` - 按状态筛选
|
||||
- `GetRecentDownloadRecords(limit)` - 获取最近 N 条
|
||||
- `GetDownloadStats()` - 获取统计信息
|
||||
- `ClearOldDownloadRecords(days)` - 清理旧记录
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 前端调用示例
|
||||
|
||||
#### 1. 添加站点配置
|
||||
```typescript
|
||||
import { App } from "../../../bindings/go-site-clone";
|
||||
|
||||
// 添加站点
|
||||
await App.AddNginxSite({
|
||||
name: "example.com",
|
||||
domains: ["example.com", "127.0.0.1"],
|
||||
port: 8080,
|
||||
path: "www/example.com",
|
||||
index: "index.html",
|
||||
enabled: true
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. 获取站点列表
|
||||
```typescript
|
||||
// 获取所有站点
|
||||
const sites = await App.GetAllNginxSites();
|
||||
console.log("站点列表:", sites);
|
||||
```
|
||||
|
||||
#### 3. 添加下载记录
|
||||
```typescript
|
||||
// 开始下载时创建记录
|
||||
const record = {
|
||||
id: "", // 自动生成
|
||||
url: "https://example.com",
|
||||
site_name: "example.com",
|
||||
status: "processing",
|
||||
total_files: 100,
|
||||
downloaded: 0,
|
||||
start_time: new Date()
|
||||
};
|
||||
await App.AddDownloadRecord(record);
|
||||
```
|
||||
|
||||
#### 4. 获取下载统计
|
||||
```typescript
|
||||
// 获取统计信息
|
||||
const stats = await App.GetDownloadStats();
|
||||
console.log("下载统计:", stats);
|
||||
// 输出: { total: 10, success: 8, failed: 1, processing: 1, total_files: 1234 }
|
||||
```
|
||||
|
||||
### 后端使用示例
|
||||
|
||||
#### 在其他服务中使用存储
|
||||
```go
|
||||
// 在 app.go 中
|
||||
func (a *App) SomeMethod() {
|
||||
// 使用站点存储
|
||||
sites, err := a.store.GetAllSites()
|
||||
if err != nil {
|
||||
log.Printf("获取站点失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 使用下载记录
|
||||
records, err := a.store.GetRecentDownloadRecords(10)
|
||||
if err != nil {
|
||||
log.Printf("获取记录失败: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 数据同步机制
|
||||
|
||||
### 双重存储
|
||||
系统同时维护两种存储:
|
||||
1. **BBolt 数据库**: 用于快速查询和持久化
|
||||
2. **Nginx 配置文件**: 用于 nginx 实际运行
|
||||
|
||||
### 同步策略
|
||||
- **添加站点**: 先保存数据库 → 生成配置文件
|
||||
- **删除站点**: 先删除配置文件 → 删除数据库记录
|
||||
- **更新站点**: 同步更新数据库和配置文件
|
||||
- **查询站点**: 优先从数据库读取 → 如果为空则从配置文件迁移
|
||||
|
||||
## 数据备份
|
||||
|
||||
### 备份方法
|
||||
```typescript
|
||||
// 前端调用备份
|
||||
await App.BackupDatabase("backups/site-clone-backup.db");
|
||||
```
|
||||
|
||||
### 手动备份
|
||||
直接复制 `data/site-clone.db` 文件即可
|
||||
|
||||
### 恢复数据
|
||||
将备份文件复制回 `data/site-clone.db` 即可
|
||||
|
||||
## 性能特点
|
||||
|
||||
### 优势
|
||||
- ✅ **读取速度快**: 索引查询,O(log n) 复杂度
|
||||
- ✅ **写入安全**: ACID 事务支持
|
||||
- ✅ **并发读取**: 支持多个 goroutine 并发读
|
||||
- ✅ **内存占用小**: 仅加载必要数据
|
||||
- ✅ **文件紧凑**: 自动压缩和优化
|
||||
|
||||
### 适用场景
|
||||
- ✅ 站点数量: < 10,000
|
||||
- ✅ 下载记录: < 100,000
|
||||
- ✅ 并发读取: 高
|
||||
- ✅ 并发写入: 中等
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. 数据库初始化
|
||||
应用启动时自动初始化,无需手动操作
|
||||
|
||||
### 2. 错误处理
|
||||
所有存储操作都会返回 error,建议:
|
||||
- 数据库操作失败时记录日志
|
||||
- 关键操作失败时提示用户
|
||||
- 不要因存储失败而中断主流程
|
||||
|
||||
### 3. 数据迁移
|
||||
首次启动时,系统会自动从 nginx 配置文件迁移数据到数据库
|
||||
|
||||
### 4. 并发安全
|
||||
BBolt 支持:
|
||||
- ✅ 多个并发读取
|
||||
- ⚠️ 同时只能有一个写入(已内部处理)
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 未来可添加的功能
|
||||
1. **访问日志存储**: 记录每个站点的访问日志
|
||||
2. **系统设置**: 存储用户配置和偏好
|
||||
3. **定时任务**: 记录定时下载任务
|
||||
4. **缓存管理**: 存储页面缓存信息
|
||||
5. **用户数据**: 多用户支持(如需要)
|
||||
|
||||
### 添加新 Bucket 示例
|
||||
```go
|
||||
// 在 storage/store.go 添加
|
||||
var BucketCustom = []byte("custom_data")
|
||||
|
||||
// 在 NewStore 中初始化
|
||||
buckets := [][]byte{BucketSites, BucketDownload, BucketLogs, BucketSettings, BucketCustom}
|
||||
```
|
||||
|
||||
## 维护建议
|
||||
|
||||
### 定期维护
|
||||
1. **清理旧记录**: 定期清理超过 30 天的下载记录
|
||||
```go
|
||||
deleted, _ := store.ClearOldDownloadRecords(30)
|
||||
```
|
||||
|
||||
2. **备份数据库**: 建议每周自动备份
|
||||
```go
|
||||
store.Backup("backups/weekly-backup.db")
|
||||
```
|
||||
|
||||
3. **监控大小**: 数据库文件超过 100MB 时考虑归档
|
||||
|
||||
### 故障恢复
|
||||
如果数据库损坏:
|
||||
1. 删除 `data/site-clone.db`
|
||||
2. 重启应用
|
||||
3. 系统会从 nginx 配置文件重建数据库
|
||||
|
||||
## 总结
|
||||
|
||||
BBolt 存储方案为项目提供了:
|
||||
- 🎯 **高性能**: 快速的键值存储
|
||||
- 🔒 **高可靠**: ACID 事务保证
|
||||
- 📦 **易维护**: 单文件、易备份
|
||||
- 🚀 **易扩展**: 简单的 Bucket 模型
|
||||
- 💪 **零依赖**: 纯 Go 实现,无需外部数据库
|
||||
|
||||
完美满足本地化、便携式存储需求!
|
||||
207
STORAGE_QUICK_START.md
Normal file
207
STORAGE_QUICK_START.md
Normal file
@@ -0,0 +1,207 @@
|
||||
# BBolt 存储快速开始
|
||||
|
||||
## 🚀 已完成的工作
|
||||
|
||||
✅ 安装 BBolt 依赖 (`go.etcd.io/bbolt@latest`)
|
||||
✅ 创建存储服务基础架构 (`storage/store.go`)
|
||||
✅ 实现站点数据 CRUD (`storage/site_store.go`)
|
||||
✅ 实现下载记录管理 (`storage/download_store.go`)
|
||||
✅ 集成到应用主服务 (`app.go`)
|
||||
✅ 更新类型定义 (`types/site_config.go`)
|
||||
✅ 修复前端类型绑定 (`webpage.vue`)
|
||||
|
||||
## 📁 新增文件
|
||||
|
||||
```
|
||||
go-site-clone/
|
||||
├── storage/ # 存储层(新增)
|
||||
│ ├── store.go # BBolt 核心封装
|
||||
│ ├── site_store.go # 站点配置存储
|
||||
│ └── download_store.go # 下载记录存储
|
||||
├── types/
|
||||
│ └── site_config.go # 站点配置类型定义(新增)
|
||||
├── data/ # 数据目录(运行时自动创建)
|
||||
│ └── site-clone.db # BBolt 数据库文件
|
||||
└── STORAGE.md # 存储方案文档(新增)
|
||||
```
|
||||
|
||||
## 🎯 核心功能
|
||||
|
||||
### 1. 自动初始化
|
||||
应用启动时自动创建数据库和必要的 buckets:
|
||||
- `sites` - 站点配置
|
||||
- `download_records` - 下载记录
|
||||
- `access_logs` - 访问日志(预留)
|
||||
- `settings` - 系统设置(预留)
|
||||
|
||||
### 2. 双重存储
|
||||
- **数据库**: BBolt 存储(快速查询)
|
||||
- **配置文件**: Nginx conf 文件(运行时使用)
|
||||
- 自动同步两者状态
|
||||
|
||||
### 3. 数据持久化
|
||||
- 站点配置自动保存
|
||||
- 下载记录自动记录
|
||||
- 支持数据查询和统计
|
||||
|
||||
## 🔧 使用方法
|
||||
|
||||
### 前端调用示例
|
||||
|
||||
```typescript
|
||||
import { App } from "../../../bindings/go-site-clone";
|
||||
|
||||
// 1. 添加站点
|
||||
await App.AddNginxSite({
|
||||
ID: "",
|
||||
Name: "example.com",
|
||||
Domains: ["example.com", "127.0.0.1"],
|
||||
Port: 8080,
|
||||
Path: "www/example.com",
|
||||
Index: "index.html",
|
||||
Enabled: true
|
||||
});
|
||||
|
||||
// 2. 获取所有站点
|
||||
const sites = await App.GetAllNginxSites();
|
||||
|
||||
// 3. 删除站点
|
||||
await App.DeleteNginxSite("example.com");
|
||||
|
||||
// 4. 添加下载记录
|
||||
await App.AddDownloadRecord({
|
||||
id: "",
|
||||
url: "https://example.com",
|
||||
site_name: "example.com",
|
||||
status: "processing",
|
||||
total_files: 100,
|
||||
downloaded: 0
|
||||
});
|
||||
|
||||
// 5. 获取下载统计
|
||||
const stats = await App.GetDownloadStats();
|
||||
```
|
||||
|
||||
## 📊 可用 API
|
||||
|
||||
### 站点管理
|
||||
- `AddNginxSite(site)` - 添加站点
|
||||
- `GetAllNginxSites()` - 获取所有站点
|
||||
- `UpdateNginxSite(site)` - 更新站点
|
||||
- `DeleteNginxSite(name)` - 删除站点
|
||||
- `EnableNginxSite(name)` - 启用站点
|
||||
- `DisableNginxSite(name)` - 禁用站点
|
||||
|
||||
### 下载记录
|
||||
- `AddDownloadRecord(record)` - 添加记录
|
||||
- `GetAllDownloadRecords()` - 获取所有记录
|
||||
- `GetRecentDownloadRecords(limit)` - 获取最近记录
|
||||
- `GetDownloadStats()` - 获取统计信息
|
||||
- `DeleteDownloadRecord(id)` - 删除记录
|
||||
- `ClearOldDownloadRecords(days)` - 清理旧记录
|
||||
|
||||
### 数据备份
|
||||
- `BackupDatabase(path)` - 备份数据库
|
||||
|
||||
## 🎨 数据结构
|
||||
|
||||
### 站点配置
|
||||
```go
|
||||
type NginxSiteConfig struct {
|
||||
ID string // 唯一标识
|
||||
Name string // 站点名称
|
||||
Domains []string // 域名列表
|
||||
Port int // 端口号
|
||||
Path string // 文件路径
|
||||
Index string // 默认首页
|
||||
Enabled bool // 是否启用
|
||||
}
|
||||
```
|
||||
|
||||
### 下载记录
|
||||
```go
|
||||
type DownloadRecord struct {
|
||||
ID string // 记录ID
|
||||
URL string // 下载URL
|
||||
SiteName string // 站点名称
|
||||
Status string // 状态: success/failed/processing
|
||||
TotalFiles int // 总文件数
|
||||
Downloaded int // 已下载数
|
||||
CSSCount int // CSS 数量
|
||||
ScriptCount int // JS 数量
|
||||
ImageCount int // 图片数量
|
||||
VideoCount int // 视频数量
|
||||
ErrorMsg string // 错误信息
|
||||
StartTime time.Time // 开始时间
|
||||
EndTime time.Time // 结束时间
|
||||
Duration int64 // 耗时(秒)
|
||||
}
|
||||
```
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
### 1. 错误处理
|
||||
```typescript
|
||||
try {
|
||||
await App.AddNginxSite(siteConfig);
|
||||
message.success('添加成功');
|
||||
} catch (error) {
|
||||
message.error('添加失败: ' + error.message);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 数据同步
|
||||
添加、更新、删除站点时,系统会自动:
|
||||
- 更新数据库
|
||||
- 生成/更新/删除 nginx 配置文件
|
||||
- 如果 nginx 运行中,自动重载配置
|
||||
|
||||
### 3. 定期备份
|
||||
```typescript
|
||||
// 建议定期备份数据库
|
||||
const backupPath = `backups/backup-${Date.now()}.db`;
|
||||
await App.BackupDatabase(backupPath);
|
||||
```
|
||||
|
||||
### 4. 清理旧数据
|
||||
```typescript
|
||||
// 清理 30 天前的下载记录
|
||||
const deleted = await App.ClearOldDownloadRecords(30);
|
||||
console.log(`清理了 ${deleted} 条记录`);
|
||||
```
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
1. **数据库位置**: `data/site-clone.db`(自动创建)
|
||||
2. **备份方式**: 直接复制 db 文件或使用 API
|
||||
3. **并发安全**: BBolt 内部处理,无需担心
|
||||
4. **性能**: 适合 < 10,000 站点,< 100,000 记录
|
||||
5. **迁移**: 首次运行自动从 nginx 配置迁移
|
||||
|
||||
## 🔍 调试
|
||||
|
||||
### 查看数据库内容
|
||||
可以使用 bbolt 命令行工具:
|
||||
```bash
|
||||
go install go.etcd.io/bbolt/cmd/bbolt@latest
|
||||
bbolt dump data/site-clone.db
|
||||
```
|
||||
|
||||
### 数据库统计
|
||||
```bash
|
||||
bbolt stats data/site-clone.db
|
||||
```
|
||||
|
||||
## 📚 更多信息
|
||||
|
||||
详细文档请查看 [STORAGE.md](./STORAGE.md)
|
||||
|
||||
## ✅ 验证安装
|
||||
|
||||
运行应用后检查:
|
||||
1. `data/` 目录是否创建
|
||||
2. `data/site-clone.db` 文件是否存在
|
||||
3. 添加站点后,数据库中是否有记录
|
||||
4. 控制台是否显示 "数据库初始化成功"
|
||||
|
||||
完成!🎉
|
||||
Reference in New Issue
Block a user