mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-26 01:51:41 +08:00
Refactor site import/export feature with improved toast notifications
Co-authored-by: jxxghp <jxxghp@live.cn>
This commit is contained in:
@@ -1,161 +0,0 @@
|
||||
# 站点批量导入导出功能实现总结
|
||||
|
||||
## 功能概述
|
||||
|
||||
成功实现了站点批量导入和批量导出功能,在站点列表页面右上角添加了导入和导出操作按钮,方便用户快速备份和恢复站点配置。
|
||||
|
||||
## 实现的功能
|
||||
|
||||
### 1. 批量导出功能
|
||||
- **位置**: 站点列表页面右上角
|
||||
- **按钮**: "批量导出"按钮(绿色图标)
|
||||
- **功能**:
|
||||
- 自动获取所有站点数据
|
||||
- 导出为JSON格式文件
|
||||
- 文件名格式: `sites_export_YYYY-MM-DD.json`
|
||||
- 包含站点的所有配置信息(除ID外)
|
||||
- 自动下载到用户本地
|
||||
|
||||
### 2. 批量导入功能
|
||||
- **位置**: 站点列表页面右上角
|
||||
- **按钮**: "批量导入"按钮(蓝色图标)
|
||||
- **功能**:
|
||||
- 支持JSON格式文件导入
|
||||
- 支持拖拽上传和文件选择
|
||||
- 导入前数据预览和验证
|
||||
- 实时导入进度显示
|
||||
- 详细的导入结果反馈
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 1. 前端组件
|
||||
- **SiteCardListView.vue**: 主页面组件,添加了导入导出按钮
|
||||
- **SiteImportDialog.vue**: 新建的导入对话框组件
|
||||
- **导出功能**: 直接在SiteCardListView中实现
|
||||
|
||||
### 2. 后端接口
|
||||
- **导出**: 使用现有的 `GET /site/` 接口获取所有站点数据
|
||||
- **导入**: 使用现有的 `POST /site/` 接口批量创建站点
|
||||
|
||||
### 3. 数据验证
|
||||
- 验证必填字段: `name`, `domain`, `url`
|
||||
- 自动移除ID字段避免冲突
|
||||
- 显示数据预览和验证结果
|
||||
|
||||
### 4. 用户体验
|
||||
- 拖拽上传支持
|
||||
- 实时进度显示
|
||||
- 详细的错误提示
|
||||
- 多语言支持(中文、英文、繁体中文)
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── views/site/
|
||||
│ └── SiteCardListView.vue # 主页面,添加了导入导出按钮
|
||||
├── components/dialog/
|
||||
│ └── SiteImportDialog.vue # 新建的导入对话框组件
|
||||
├── locales/
|
||||
│ ├── zh-CN.ts # 简体中文翻译
|
||||
│ ├── en-US.ts # 英文翻译
|
||||
│ └── zh-TW.ts # 繁体中文翻译
|
||||
└── test_sites_export.json # 测试用的导出文件
|
||||
```
|
||||
|
||||
## 国际化支持
|
||||
|
||||
### 中文(简体)
|
||||
- 批量导入/导出
|
||||
- 数据预览
|
||||
- 错误提示
|
||||
- 进度显示
|
||||
|
||||
### 英文
|
||||
- Batch Import/Export
|
||||
- Data Preview
|
||||
- Error Messages
|
||||
- Progress Display
|
||||
|
||||
### 繁体中文
|
||||
- 批量導入/導出
|
||||
- 數據預覽
|
||||
- 錯誤提示
|
||||
- 進度顯示
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 导出站点配置
|
||||
1. 进入站点管理页面
|
||||
2. 点击右上角的"批量导出"按钮
|
||||
3. 浏览器自动下载JSON配置文件
|
||||
|
||||
### 导入站点配置
|
||||
1. 进入站点管理页面
|
||||
2. 点击右上角的"批量导入"按钮
|
||||
3. 选择或拖拽JSON文件
|
||||
4. 查看数据预览
|
||||
5. 点击"开始导入"
|
||||
6. 等待导入完成
|
||||
|
||||
## 文件格式
|
||||
|
||||
导出的JSON文件包含以下字段:
|
||||
```json
|
||||
{
|
||||
"name": "站点名称",
|
||||
"domain": "站点域名",
|
||||
"url": "站点地址",
|
||||
"rss": "RSS地址",
|
||||
"downloader": "下载器",
|
||||
"cookie": "Cookie信息",
|
||||
"apikey": "API密钥",
|
||||
"token": "访问令牌",
|
||||
"ua": "User-Agent",
|
||||
"proxy": false,
|
||||
"filter": "过滤规则",
|
||||
"render": false,
|
||||
"public": 0,
|
||||
"note": "备注信息",
|
||||
"timeout": 30,
|
||||
"limit_interval": 0,
|
||||
"limit_count": 0,
|
||||
"limit_seconds": 0,
|
||||
"is_active": true,
|
||||
"pri": 1
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
- 文件格式验证
|
||||
- 数据完整性检查
|
||||
- 网络错误处理
|
||||
- 导入失败统计
|
||||
- 用户友好的错误提示
|
||||
|
||||
## 测试
|
||||
|
||||
- 提供了 `test_sites_export.json` 测试文件
|
||||
- 支持各种边界情况测试
|
||||
- 多语言界面测试
|
||||
- 拖拽上传功能测试
|
||||
|
||||
## 构建状态
|
||||
|
||||
✅ 项目构建成功
|
||||
✅ 所有组件正常工作
|
||||
✅ 国际化完整
|
||||
✅ 错误处理完善
|
||||
✅ 用户体验良好
|
||||
|
||||
## 总结
|
||||
|
||||
成功实现了完整的站点批量导入导出功能,包括:
|
||||
- 直观的用户界面
|
||||
- 完善的数据验证
|
||||
- 良好的错误处理
|
||||
- 完整的多语言支持
|
||||
- 优秀的用户体验
|
||||
|
||||
该功能可以帮助用户快速备份和恢复站点配置,提高工作效率。
|
||||
@@ -1,95 +0,0 @@
|
||||
# 站点批量导入导出功能
|
||||
|
||||
## 功能概述
|
||||
|
||||
在站点管理页面新增了批量导入和批量导出功能,方便用户快速备份和恢复站点配置。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 批量导出
|
||||
- 点击站点列表页面右上角的"批量导出"按钮
|
||||
- 自动导出所有站点的配置信息为JSON格式
|
||||
- 文件名格式:`sites_export_YYYY-MM-DD.json`
|
||||
- 包含站点的所有配置信息(除ID外)
|
||||
|
||||
### 批量导入
|
||||
- 点击站点列表页面右上角的"批量导入"按钮
|
||||
- 支持JSON格式的站点配置文件
|
||||
- 支持拖拽上传和文件选择
|
||||
- 导入前会显示数据预览
|
||||
- 自动验证数据有效性
|
||||
- 显示导入进度和结果
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 导出站点配置
|
||||
1. 进入站点管理页面
|
||||
2. 点击右上角的"批量导出"按钮
|
||||
3. 浏览器会自动下载JSON格式的配置文件
|
||||
|
||||
### 导入站点配置
|
||||
1. 进入站点管理页面
|
||||
2. 点击右上角的"批量导入"按钮
|
||||
3. 选择JSON格式的站点配置文件
|
||||
4. 查看数据预览,确认无误后点击"开始导入"
|
||||
5. 等待导入完成,查看导入结果
|
||||
|
||||
## 文件格式
|
||||
|
||||
导出的JSON文件格式如下:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "站点名称",
|
||||
"domain": "站点域名",
|
||||
"url": "站点地址",
|
||||
"rss": "RSS地址",
|
||||
"downloader": "下载器",
|
||||
"cookie": "Cookie信息",
|
||||
"apikey": "API密钥",
|
||||
"token": "访问令牌",
|
||||
"ua": "User-Agent",
|
||||
"proxy": false,
|
||||
"filter": "过滤规则",
|
||||
"render": false,
|
||||
"public": 0,
|
||||
"note": "备注信息",
|
||||
"timeout": 30,
|
||||
"limit_interval": 0,
|
||||
"limit_count": 0,
|
||||
"limit_seconds": 0,
|
||||
"is_active": true,
|
||||
"pri": 1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 数据验证
|
||||
|
||||
导入时会自动验证以下必填字段:
|
||||
- `name`: 站点名称
|
||||
- `domain`: 站点域名
|
||||
- `url`: 站点地址
|
||||
|
||||
如果数据无效,会在预览中标记出来,并显示错误提示。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 导入时会自动移除原数据中的ID字段,避免冲突
|
||||
2. 导入过程中会显示进度条和实时状态
|
||||
3. 如果部分数据导入失败,会显示详细的成功和失败数量
|
||||
4. 导入完成后会自动刷新站点列表
|
||||
5. 支持的文件格式:JSON文件(.json)
|
||||
|
||||
## 测试文件
|
||||
|
||||
项目根目录下提供了 `test_sites_export.json` 测试文件,可用于测试导入功能。
|
||||
|
||||
## 技术实现
|
||||
|
||||
- 使用现有的站点新增接口 `POST /site/` 进行批量导入
|
||||
- 使用现有的站点查询接口 `GET /site/` 进行数据导出
|
||||
- 前端使用Vue 3 + Vuetify 3实现用户界面
|
||||
- 支持拖拽上传和文件选择
|
||||
- 实时进度显示和错误处理
|
||||
@@ -12,6 +12,9 @@ const { t } = useI18n()
|
||||
// 显示器宽度
|
||||
const display = useDisplay()
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
// 输入参数
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@@ -23,8 +26,7 @@ const props = defineProps({
|
||||
// 注册事件
|
||||
const emit = defineEmits(['update:modelValue', 'import-success'])
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
|
||||
// 是否拖拽中
|
||||
const isDragging = ref(false)
|
||||
|
||||
@@ -11,10 +11,14 @@ import { useDisplay } from 'vuetify'
|
||||
import { useDynamicButton } from '@/composables/useDynamicButton'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { usePWA } from '@/composables/usePWA'
|
||||
import { useToast } from 'vue-toastification'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
// 路由
|
||||
const route = useRoute()
|
||||
|
||||
@@ -260,15 +264,9 @@ async function exportSites() {
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
// 显示成功提示
|
||||
const { t } = useI18n()
|
||||
const { useToast } = await import('vue-toastification')
|
||||
const $toast = useToast()
|
||||
$toast.success(t('site.messages.exportSuccess'))
|
||||
} catch (error) {
|
||||
console.error('Export sites failed:', error)
|
||||
const { t } = useI18n()
|
||||
const { useToast } = await import('vue-toastification')
|
||||
const $toast = useToast()
|
||||
$toast.error(t('site.messages.exportFailed'))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "测试站点1",
|
||||
"domain": "test1.example.com",
|
||||
"url": "https://test1.example.com",
|
||||
"rss": "https://test1.example.com/rss",
|
||||
"downloader": "",
|
||||
"cookie": "",
|
||||
"apikey": "",
|
||||
"token": "",
|
||||
"ua": "",
|
||||
"proxy": false,
|
||||
"filter": "",
|
||||
"render": false,
|
||||
"public": 0,
|
||||
"note": "测试站点1",
|
||||
"timeout": 30,
|
||||
"limit_interval": 0,
|
||||
"limit_count": 0,
|
||||
"limit_seconds": 0,
|
||||
"is_active": true,
|
||||
"pri": 1
|
||||
},
|
||||
{
|
||||
"name": "测试站点2",
|
||||
"domain": "test2.example.com",
|
||||
"url": "https://test2.example.com",
|
||||
"rss": "https://test2.example.com/rss",
|
||||
"downloader": "",
|
||||
"cookie": "",
|
||||
"apikey": "",
|
||||
"token": "",
|
||||
"ua": "",
|
||||
"proxy": false,
|
||||
"filter": "",
|
||||
"render": false,
|
||||
"public": 0,
|
||||
"note": "测试站点2",
|
||||
"timeout": 30,
|
||||
"limit_interval": 0,
|
||||
"limit_count": 0,
|
||||
"limit_seconds": 0,
|
||||
"is_active": true,
|
||||
"pri": 2
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user