音乐模块调整

This commit is contained in:
zhongluofeng
2026-09-15 17:17:16 +08:00
parent 4f574cb5fa
commit 8f853f7ef3
31 changed files with 3819 additions and 936 deletions
@@ -22,6 +22,7 @@ const editing = ref<Partial<FeiniuConnection> | null>(null)
const editOpen = ref(false)
const password = ref('')
const testing = ref(false)
const saving = ref(false)
function newForm() {
editing.value = { name: '', kind: 'lan', baseUrl: '', username: '', accessCode: '', insecure: false, fnId: '' }
@@ -30,46 +31,94 @@ function newForm() {
}
function editForm(c: FeiniuConnection) {
editing.value = { ...c }
// 历史数据里的 frp 等内网转发方式已并入「局域网」
editing.value = { ...c, kind: c.kind === 'fnconnect' ? 'fnconnect' : 'lan' }
password.value = ''
editOpen.value = true
}
async function save() {
if (!editing.value) return
if (!editing.value.name?.trim() || !editing.value.baseUrl?.trim()) {
toast.error('请填写名称与服务器地址')
if (!editing.value || saving.value) return
const draft = { ...editing.value }
if (!draft.name?.trim()) {
toast.error('请填写名称')
return
}
// 局域网需要服务器地址;FnConnect 需要飞牛 ID(服务器地址在登录时自动解析)
if (draft.kind === 'fnconnect') {
if (!draft.fnId?.trim()) {
toast.error('请填写飞牛 ID')
return
}
} else if (!draft.baseUrl?.trim()) {
toast.error('请填写服务器地址')
return
}
const pw = password.value
saving.value = true
try {
const id = await store.saveConnection({
id: editing.value.id || '',
name: editing.value.name.trim(),
kind: editing.value.kind || 'lan',
baseUrl: editing.value.baseUrl.trim(),
username: editing.value.username || '',
accessCode: editing.value.accessCode || '',
insecure: !!editing.value.insecure,
fnId: editing.value.fnId || ''
id: draft.id || '',
name: draft.name.trim(),
kind: draft.kind || 'lan',
baseUrl: draft.baseUrl?.trim() || '',
username: draft.username || '',
accessCode: draft.accessCode || '',
insecure: !!draft.insecure,
fnId: draft.fnId?.trim() || '',
relay: !!draft.relay
})
if (password.value) {
await store.login(id, editing.value.username || '', password.value)
}
// 先关闭对话框再登录:FnConnect 登录要先探测可达地址(可能数秒),
// 若等待其完成才关窗,观感就是「已保存但对话框卡住」。
editOpen.value = false
toast.success('已保存')
if (pw && id) {
void store
.login(id, draft.username || '', pw)
.then(() => toast.success('登录成功'))
.catch((e) => toast.error(`登录失败:${e}`))
}
} catch (e) {
toast.error(String(e))
} finally {
saving.value = false
}
}
async function test(c: FeiniuConnection) {
/** 测试当前对话框里的草案(无需先保存,新建连接也可以直接测) */
async function test() {
const d = editing.value
if (!d || testing.value) return
if (!password.value) {
toast.error('请输入密码再测试')
return
}
if (d.kind === 'fnconnect') {
if (!d.fnId?.trim()) {
toast.error('请填写飞牛 ID')
return
}
} else if (!d.baseUrl?.trim()) {
toast.error('请填写服务器地址')
return
}
testing.value = true
try {
await store.testConnection(c.id, c.username, password.value)
await store.testConnection(
{
id: d.id || '',
name: d.name?.trim() || '测试',
kind: d.kind || 'lan',
baseUrl: d.baseUrl?.trim() || '',
username: d.username || '',
accessCode: d.accessCode || '',
insecure: !!d.insecure,
fnId: d.fnId?.trim() || '',
relay: !!d.relay
},
d.username || '',
password.value
)
toast.success('连接成功')
} catch (e) {
toast.error(String(e))
@@ -93,8 +142,9 @@ async function remove(c: FeiniuConnection) {
toast.success('已删除')
}
/** kind → 展示名:局域网涵盖 frp / 内网转发等直连方式,其余为 FnConnect */
function kindLabel(k: string) {
return k === 'lan' ? '局域网' : k === 'frp' ? 'frp 域名' : 'FnConnect'
return k === 'fnconnect' ? 'FnConnect' : '局域网'
}
onMounted(() => store.refreshConnections())
@@ -122,7 +172,8 @@ onMounted(() => store.refreshConnections())
<Badge v-if="store.activeId === c.id" variant="default" class="text-[10px]">激活</Badge>
</div>
<div class="truncate text-xs text-muted-foreground">
{{ c.baseUrl }}<template v-if="c.username"> · {{ c.username }}</template>
{{ c.baseUrl }}<template v-if="c.kind === 'fnconnect' && c.relay"> · 中继</template
><template v-if="c.username"> · {{ c.username }}</template>
</div>
</div>
<div class="flex shrink-0 items-center gap-1">
@@ -167,7 +218,7 @@ onMounted(() => store.refreshConnections())
</div>
</div>
<p v-if="!store.connections.length" class="text-xs text-muted-foreground">
还没有连接新建一个并填写 NAS 地址局域网 http://192.168.x.x:5666frp 域名 FnConnect fnId
还没有连接新建一个并填写 NAS 地址局域网 http://192.168.x.x:5666frp 等内网转发同样填最终访问地址 FnConnect fnId
</p>
</div>
@@ -179,17 +230,17 @@ onMounted(() => store.refreshConnections())
<div class="flex flex-col gap-3">
<div class="space-y-1.5">
<Label>名称</Label>
<Input v-model="editing!.name" placeholder="如:家里 NAS / frp 远程 / FnConnect" />
<Input v-model="editing!.name" placeholder="如:家里 NAS / FnConnect 远程" />
</div>
<div class="space-y-1.5">
<Label>类型</Label>
<div class="flex gap-2">
<Button
v-for="k in (['lan', 'frp', 'fnconnect'] as const)"
v-for="k in (['lan', 'fnconnect'] as const)"
:key="k"
type="button"
size="sm"
:variant="editing!.kind === k ? 'default' : 'outline'"
:variant="(editing!.kind ?? 'lan') === k ? 'default' : 'outline'"
@click="editing!.kind = k"
>
{{ kindLabel(k) }}
@@ -197,15 +248,19 @@ onMounted(() => store.refreshConnections())
</div>
</div>
<div v-if="editing!.kind === 'fnconnect'" class="space-y-1.5">
<Label>FnConnect fnIdfnos.net/xxx 或裸 id</Label>
<Input v-model="editing!.fnId" placeholder="fnos.net/zy2060537" />
<Label>飞牛 ID</Label>
<Input v-model="editing!.fnId" placeholder="请输入飞牛 ID,如 abc123" />
<p class="text-xs text-muted-foreground">
保存后点登录会自动解析到可达地址服务器地址会回填
fnos.net/ 后面的那段也可直接粘贴 fnos.net/abc123
保存后点登录会自动解析到可达地址内网 / 公网 / 中继服务器地址会回填
</p>
</div>
<div v-else class="space-y-1.5">
<Label>服务器地址</Label>
<Input v-model="editing!.baseUrl" placeholder="http://192.168.1.10:5666 或 https://xxx.xxx.com" />
<Input
v-model="editing!.baseUrl"
placeholder="http://192.168.1.10:5666 或 https://xxx.xxx.comfrp 填转发后的地址)"
/>
</div>
<div class="space-y-1.5">
<Label>账号</Label>
@@ -221,17 +276,14 @@ onMounted(() => store.refreshConnections())
</div>
</div>
<DialogFooter class="gap-2">
<Button variant="outline" :disabled="testing" @click="test(editing as unknown as FeiniuConnection)">
<Button variant="outline" :disabled="testing || saving" @click="test">
<Loader2 v-if="testing" class="size-4 animate-spin" /> 测试
</Button>
<Button @click="save">保存</Button>
<Button :disabled="saving" @click="save">
<Loader2 v-if="saving" class="size-4 animate-spin" /> 保存
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<p class="text-xs text-muted-foreground">
提示上传音乐到 NAS下载到飞牛/ 上传 / 删除已改用 <strong class="font-medium">WebDAV</strong>
存储与上传分组里配置无需在此登录文件服务
</p>
</div>
</template>