feat: 视频预览/数据看板/下载配置 三项业务功能

- 新增视频预览:VideoPlayer 组件、VideoController/DyCollectVideoService/Repository、VideoPageRequestDTO 对应后端改动
- 新增数据看板:workplace/statics.vue、RecordTable、相关 store/http/axios 改动
- 新增下载配置:DownloadConfigService、ConfigController、AppSet.vue、AppConfig
- 其他:DyHttpClientService / 同步 Job(Collect, Favorit) / Cookie 表 / CommonService / ServiceExtension 的配套调整
- 仓库卫生:.gitignore 追加 feiniu 过滤;运维脚本归档到 docs/scripts/
This commit is contained in:
yuming
2026-04-25 00:22:33 +08:00
parent ca530312d0
commit b328e82eb2
27 changed files with 3602 additions and 348 deletions
+89 -1
View File
@@ -16,6 +16,47 @@
<a-alert message="每次扫描行数,第一次同步完成后,可以适当调高提高效率" type="success" />
</a-form-item>
<a-divider orientation="left">下载配置</a-divider>
<a-alert message="默认情况下,系统不会自动下载视频,避免占用过多存储空间。如需下载,请配置以下选项。" type="info" style="margin-bottom: 16px;" />
<a-form-item label="启用自动下载">
<a-switch v-model:checked="formState.EnableAutoDownload" />
<a-alert message="关闭后,系统只同步视频信息到数据库,不会下载视频文件" type="warning" style="margin-top: 8px;" />
</a-form-item>
<a-form-item label="下载时间范围(天)" v-if="formState.EnableAutoDownload">
<a-input-number v-model:value="formState.DownloadDaysRange" :min="0" :max="3650" style="width: 200px;" />
<a-alert message="0表示不限制时间,只下载指定天数内的视频(例如:30表示只下载最近30天的视频)" type="success" style="margin-top: 8px;" />
</a-form-item>
<a-form-item label="下载喜欢的视频" v-if="formState.EnableAutoDownload">
<a-switch v-model:checked="formState.DownloadFavorite" />
</a-form-item>
<a-form-item label="下载收藏的视频" v-if="formState.EnableAutoDownload">
<a-switch v-model:checked="formState.DownloadCollect" />
</a-form-item>
<a-form-item label="作者白名单" v-if="formState.EnableAutoDownload">
<a-textarea
v-model:value="formState.AuthorWhitelist"
placeholder="每行一个作者名称或ID,留空则不限制&#10;例如:&#10;作者1&#10;作者2&#10;MS4wLjABAAAA..."
:rows="4"
style="width: 500px;"
/>
<a-alert message="配置后,只有白名单中的作者视频才会被下载。留空则不限制。" type="success" style="margin-top: 8px;" />
</a-form-item>
<a-form-item label="作者黑名单" v-if="formState.EnableAutoDownload">
<a-textarea
v-model:value="formState.AuthorBlacklist"
placeholder="每行一个作者名称或ID,留空则不限制&#10;例如:&#10;作者1&#10;作者2&#10;MS4wLjABAAAA..."
:rows="4"
style="width: 500px;"
/>
<a-alert message="配置后,黑名单中的作者视频不会被下载。留空则不限制。" type="success" style="margin-top: 8px;" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 10, offset: 3 }">
<a-space>
<a-button type="primary" @click="onUpdate" v-if="componentDisabled">修改配置</a-button>
@@ -43,11 +84,23 @@ interface FormState {
Cron: string;
Id: string;
BatchCount: number;
EnableAutoDownload?: boolean;
DownloadDaysRange?: number;
AuthorWhitelist?: string;
AuthorBlacklist?: string;
DownloadFavorite?: boolean;
DownloadCollect?: boolean;
}
const formState: UnwrapRef<FormState> = reactive({
Cron: '30',
Id: '0',
BatchCount: 10,
EnableAutoDownload: false,
DownloadDaysRange: 0,
AuthorWhitelist: '',
AuthorBlacklist: '',
DownloadFavorite: false,
DownloadCollect: false,
});
const rules: Record<string, Rule[]> = {
@@ -62,6 +115,21 @@ const getConfig = () => {
formState.Cron = res.data.cron;
formState.Id = res.data.id;
formState.BatchCount = res.data.batchCount;
// 下载配置
formState.EnableAutoDownload = res.data.enableAutoDownload ?? false;
formState.DownloadDaysRange = res.data.downloadDaysRange ?? 0;
try {
formState.AuthorWhitelist = res.data.authorWhitelist ? JSON.parse(res.data.authorWhitelist).join('\n') : '';
} catch {
formState.AuthorWhitelist = '';
}
try {
formState.AuthorBlacklist = res.data.authorBlacklist ? JSON.parse(res.data.authorBlacklist).join('\n') : '';
} catch {
formState.AuthorBlacklist = '';
}
formState.DownloadFavorite = res.data.downloadFavorite ?? false;
formState.DownloadCollect = res.data.downloadCollect ?? false;
} else {
message.error(res.erro, 8);
}
@@ -79,12 +147,32 @@ const onSubmit = () => {
.validate()
.then(() => {
console.log('values', formState, toRaw(formState));
// 处理作者白名单和黑名单,转换为JSON数组
const submitData = { ...toRaw(formState) };
if (submitData.AuthorWhitelist) {
const whitelist = submitData.AuthorWhitelist.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
submitData.AuthorWhitelist = whitelist.length > 0 ? JSON.stringify(whitelist) : '';
} else {
submitData.AuthorWhitelist = '';
}
if (submitData.AuthorBlacklist) {
const blacklist = submitData.AuthorBlacklist.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
submitData.AuthorBlacklist = blacklist.length > 0 ? JSON.stringify(blacklist) : '';
} else {
submitData.AuthorBlacklist = '';
}
useApiStore()
.apiUpdateConfig(toRaw(formState))
.apiUpdateConfig(submitData)
.then((res) => {
if (res.code === 0) {
message.success('配置修改生效,同步任务将按照新的规则执行');
componentDisabled.value = true;
getConfig(); // 重新加载配置
} else {
message.error(res.erro, 8);
}