完成基础开发
This commit is contained in:
260
frontend/src/components/AddTorrentDialog.vue
Normal file
260
frontend/src/components/AddTorrentDialog.vue
Normal file
@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="添加种子"
|
||||
v-model="visible"
|
||||
width="600px"
|
||||
@close="resetForm"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="客户端" prop="clientId">
|
||||
<el-select v-model="form.clientId" placeholder="选择客户端" style="width: 100%">
|
||||
<el-option
|
||||
v-for="client in connectedClients"
|
||||
:key="client.id"
|
||||
:label="client.name"
|
||||
:value="client.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="添加方式">
|
||||
<el-radio-group v-model="addMethod">
|
||||
<el-radio value="file">种子文件</el-radio>
|
||||
<el-radio value="magnet">磁力链接</el-radio>
|
||||
<el-radio value="url">种子URL</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 种子文件上传 -->
|
||||
<el-form-item v-if="addMethod === 'file'" label="种子文件" prop="torrentFile">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:show-file-list="true"
|
||||
:limit="1"
|
||||
accept=".torrent"
|
||||
:on-change="handleFileChange"
|
||||
:on-remove="handleFileRemove"
|
||||
>
|
||||
<el-button type="primary">选择文件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 .torrent 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 磁力链接 -->
|
||||
<el-form-item v-if="addMethod === 'magnet'" label="磁力链接" prop="magnetLink">
|
||||
<el-input
|
||||
v-model="form.magnetLink"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="magnet:?xt=urn:btih:..."
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 种子URL -->
|
||||
<el-form-item v-if="addMethod === 'url'" label="种子URL" prop="torrentUrl">
|
||||
<el-input
|
||||
v-model="form.torrentUrl"
|
||||
placeholder="https://example.com/torrent.torrent"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 可选设置 -->
|
||||
<el-divider content-position="left">可选设置</el-divider>
|
||||
|
||||
<el-form-item label="分类">
|
||||
<el-input v-model="form.category" placeholder="种子分类" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="标签">
|
||||
<el-input v-model="form.tags" placeholder="用逗号分隔多个标签" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="保存路径">
|
||||
<el-input v-model="form.savePath" placeholder="自定义保存路径" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="添加后暂停">
|
||||
<el-switch v-model="form.paused" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="submitting">
|
||||
添加种子
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useClientsStore } from '@/stores/clients'
|
||||
import { torrentsApi } from '@/api/torrents'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits(['update:modelValue', 'success'])
|
||||
|
||||
// Stores
|
||||
const clientsStore = useClientsStore()
|
||||
|
||||
// 响应式数据
|
||||
const visible = ref(false)
|
||||
const addMethod = ref('file')
|
||||
const submitting = ref(false)
|
||||
const formRef = ref()
|
||||
const uploadRef = ref()
|
||||
|
||||
const form = ref({
|
||||
clientId: '',
|
||||
torrentFile: null,
|
||||
magnetLink: '',
|
||||
torrentUrl: '',
|
||||
category: '',
|
||||
tags: '',
|
||||
savePath: '',
|
||||
paused: false
|
||||
})
|
||||
|
||||
const rules = {
|
||||
clientId: [
|
||||
{ required: true, message: '请选择客户端', trigger: 'change' }
|
||||
],
|
||||
torrentFile: [
|
||||
{ required: true, message: '请选择种子文件', trigger: 'change' }
|
||||
],
|
||||
magnetLink: [
|
||||
{ required: true, message: '请输入磁力链接', trigger: 'blur' },
|
||||
{ pattern: /^magnet:/, message: '请输入有效的磁力链接', trigger: 'blur' }
|
||||
],
|
||||
torrentUrl: [
|
||||
{ required: true, message: '请输入种子URL', trigger: 'blur' },
|
||||
{ type: 'url', message: '请输入有效的URL', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 计算属性
|
||||
const connectedClients = computed(() => clientsStore.connectedClients)
|
||||
|
||||
// 监听 modelValue 变化
|
||||
watch(() => props.modelValue, (newVal) => {
|
||||
visible.value = newVal
|
||||
})
|
||||
|
||||
watch(visible, (newVal) => {
|
||||
emit('update:modelValue', newVal)
|
||||
})
|
||||
|
||||
// 监听添加方式变化,重置验证
|
||||
watch(addMethod, () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate()
|
||||
}
|
||||
})
|
||||
|
||||
// 方法
|
||||
const handleFileChange = (file) => {
|
||||
form.value.torrentFile = file.raw
|
||||
}
|
||||
|
||||
const handleFileRemove = () => {
|
||||
form.value.torrentFile = null
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
try {
|
||||
// 根据添加方式验证不同字段
|
||||
const fieldsToValidate = ['clientId']
|
||||
if (addMethod.value === 'file') fieldsToValidate.push('torrentFile')
|
||||
if (addMethod.value === 'magnet') fieldsToValidate.push('magnetLink')
|
||||
if (addMethod.value === 'url') fieldsToValidate.push('torrentUrl')
|
||||
|
||||
await formRef.value.validateField(fieldsToValidate)
|
||||
|
||||
submitting.value = true
|
||||
|
||||
const options = {
|
||||
category: form.value.category,
|
||||
tags: form.value.tags,
|
||||
savePath: form.value.savePath,
|
||||
paused: form.value.paused
|
||||
}
|
||||
|
||||
let response
|
||||
if (addMethod.value === 'file') {
|
||||
response = await torrentsApi.addTorrentFile(form.value.clientId, form.value.torrentFile, options)
|
||||
} else if (addMethod.value === 'magnet') {
|
||||
response = await torrentsApi.addMagnetLink(form.value.clientId, form.value.magnetLink, options)
|
||||
} else if (addMethod.value === 'url') {
|
||||
response = await torrentsApi.addTorrentUrl(form.value.clientId, form.value.torrentUrl, options)
|
||||
}
|
||||
|
||||
if (response.success) {
|
||||
ElMessage.success(response.message || '种子添加成功')
|
||||
visible.value = false
|
||||
emit('success')
|
||||
} else {
|
||||
ElMessage.error(response.error || '添加失败')
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
ElMessage.error(`添加种子失败: ${error.message}`)
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.value = {
|
||||
clientId: '',
|
||||
torrentFile: null,
|
||||
magnetLink: '',
|
||||
torrentUrl: '',
|
||||
category: '',
|
||||
tags: '',
|
||||
savePath: '',
|
||||
paused: false
|
||||
}
|
||||
addMethod.value = 'file'
|
||||
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
if (uploadRef.value) {
|
||||
uploadRef.value.clearFiles()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-divider {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.el-upload__tip {
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user