feat(video-sources): add visible UID import entry for submissions
fix(build): rerun rust build when web/build changes
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=../../web/build");
|
||||||
built::write_built_file().expect("Failed to acquire build-time information");
|
built::write_built_file().expect("Failed to acquire build-time information");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,8 @@
|
|||||||
let favoriteForm = { fid: '' };
|
let favoriteForm = { fid: '' };
|
||||||
let collectionForm = { sid: '', mid: '', collection_type: '2' }; // 默认为合集
|
let collectionForm = { sid: '', mid: '', collection_type: '2' }; // 默认为合集
|
||||||
let submissionForm = { upper_id: '' };
|
let submissionForm = { upper_id: '' };
|
||||||
|
let importingSubmissions = false;
|
||||||
|
let submissionImportInput: HTMLInputElement | null = null;
|
||||||
let selectedIds: Record<string, number[]> = {
|
let selectedIds: Record<string, number[]> = {
|
||||||
favorites: [],
|
favorites: [],
|
||||||
collections: [],
|
collections: [],
|
||||||
@@ -383,6 +385,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseUidLines(content: string): number[] {
|
||||||
|
return [...new Set(content.split(/\r?\n/).map((line) => line.trim()).filter((line) => /^\d+$/.test(line)))].map(
|
||||||
|
(uid) => parseInt(uid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleImportSubmissionUids(file: File | null) {
|
||||||
|
if (!file) return;
|
||||||
|
importingSubmissions = true;
|
||||||
|
try {
|
||||||
|
const content = await file.text();
|
||||||
|
const uids = parseUidLines(content);
|
||||||
|
if (uids.length === 0) {
|
||||||
|
toast.error('未在文件中识别到有效 UID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let success = 0;
|
||||||
|
let failed = 0;
|
||||||
|
for (const uid of uids) {
|
||||||
|
try {
|
||||||
|
await api.insertSubmission({ upper_id: uid });
|
||||||
|
success += 1;
|
||||||
|
} catch {
|
||||||
|
failed += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failed > 0) {
|
||||||
|
toast.warning('UID 文件导入完成(部分失败)', {
|
||||||
|
description: `成功 ${success} 条,失败 ${failed} 条`
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toast.success(`UID 文件导入成功,共 ${success} 条`);
|
||||||
|
}
|
||||||
|
loadVideoSources();
|
||||||
|
} catch (error) {
|
||||||
|
toast.error('导入 UID 文件失败', {
|
||||||
|
description: (error as ApiError).message
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
importingSubmissions = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSubmissionUidImport() {
|
||||||
|
submissionImportInput?.click();
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
setBreadcrumb([{ label: '视频源' }]);
|
setBreadcrumb([{ label: '视频源' }]);
|
||||||
@@ -451,10 +500,34 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if key === 'favorites' || key === 'collections' || key === 'submissions'}
|
{#if key === 'favorites' || key === 'collections' || key === 'submissions'}
|
||||||
<Button size="sm" onclick={() => openAddDialog(key)} class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<PlusIcon class="h-4 w-4" />
|
{#if key === 'submissions'}
|
||||||
手动添加
|
<input
|
||||||
</Button>
|
bind:this={submissionImportInput}
|
||||||
|
type="file"
|
||||||
|
accept=".txt,text/plain"
|
||||||
|
class="hidden"
|
||||||
|
disabled={importingSubmissions}
|
||||||
|
onchange={(event) => {
|
||||||
|
const file = (event.currentTarget as HTMLInputElement).files?.[0] ?? null;
|
||||||
|
handleImportSubmissionUids(file);
|
||||||
|
(event.currentTarget as HTMLInputElement).value = '';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
onclick={openSubmissionUidImport}
|
||||||
|
disabled={importingSubmissions}
|
||||||
|
>
|
||||||
|
{importingSubmissions ? '导入中...' : '导入 UID.txt'}
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
<Button size="sm" onclick={() => openAddDialog(key)} class="flex items-center gap-2">
|
||||||
|
<PlusIcon class="h-4 w-4" />
|
||||||
|
手动添加
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if sources.length > 0}
|
{#if sources.length > 0}
|
||||||
@@ -620,10 +693,21 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
{#if key === 'favorites' || key === 'collections' || key === 'submissions'}
|
{#if key === 'favorites' || key === 'collections' || key === 'submissions'}
|
||||||
<Button onclick={() => openAddDialog(key)} class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<PlusIcon class="h-4 w-4" />
|
{#if key === 'submissions'}
|
||||||
手动添加
|
<Button
|
||||||
</Button>
|
variant="outline"
|
||||||
|
onclick={openSubmissionUidImport}
|
||||||
|
disabled={importingSubmissions}
|
||||||
|
>
|
||||||
|
{importingSubmissions ? '导入中...' : '导入 UID.txt'}
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
<Button onclick={() => openAddDialog(key)} class="flex items-center gap-2">
|
||||||
|
<PlusIcon class="h-4 w-4" />
|
||||||
|
手动添加
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -839,6 +923,24 @@
|
|||||||
class="mt-1"
|
class="mt-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label for="uid-file" class="text-sm font-medium">导入 UID.txt</Label>
|
||||||
|
<Input
|
||||||
|
id="uid-file"
|
||||||
|
type="file"
|
||||||
|
accept=".txt,text/plain"
|
||||||
|
class="mt-1"
|
||||||
|
disabled={importingSubmissions}
|
||||||
|
onchange={(event) => {
|
||||||
|
const file = (event.currentTarget as HTMLInputElement).files?.[0] ?? null;
|
||||||
|
handleImportSubmissionUids(file);
|
||||||
|
(event.currentTarget as HTMLInputElement).value = '';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<p class="text-muted-foreground mt-1 text-xs">
|
||||||
|
每行一个 UID,例如:2122895527
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="mt-4 space-y-1.5">
|
<div class="mt-4 space-y-1.5">
|
||||||
|
|||||||
Reference in New Issue
Block a user