mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-04-13 14:59:54 +08:00
配置页渲染
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
import axios from 'axios';
|
||||
import type { Config } from '#/config';
|
||||
|
||||
export const setConfig = () => axios.post('/api/v1/updateConfig');
|
||||
export async function setConfig(newConfig: Config) {
|
||||
const { data } = await axios.post('/api/v1/updateConfig', newConfig);
|
||||
return data;
|
||||
}
|
||||
|
||||
export const getConfig = () => axios.post('/api/v1/getConfig');
|
||||
export async function getConfig() {
|
||||
const { data } = await axios.get<Config>('/api/v1/getConfig');
|
||||
return data;
|
||||
}
|
||||
|
||||
8
src/components.d.ts
vendored
8
src/components.d.ts
vendored
@@ -7,6 +7,9 @@ export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
ConfigFormCol: typeof import('./components/ConfigFormCol.vue')['default']
|
||||
ConfigFormRow: typeof import('./components/ConfigFormRow.vue')['default']
|
||||
copy: typeof import('./components/ConfigFormCol copy.vue')['default']
|
||||
ElAside: typeof import('element-plus/es')['ElAside']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
@@ -16,13 +19,18 @@ declare module '@vue/runtime-core' {
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElOptions: typeof import('element-plus/es')['ElOptions']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
||||
13
src/components/ConfigFormCol.vue
Normal file
13
src/components/ConfigFormCol.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
label: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item :label="label">
|
||||
<slot></slot>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
17
src/components/ConfigFormRow.vue
Normal file
17
src/components/ConfigFormRow.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
title: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-collapse-item>
|
||||
<template #title>
|
||||
<span font-bold text-base>{{ title }}</span>
|
||||
</template>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<slot></slot>
|
||||
</el-row>
|
||||
</el-collapse-item>
|
||||
</template>
|
||||
@@ -1,12 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import AddBangumi from './components/AddBangumi.vue';
|
||||
import BangumiData from './components/BangumiData.vue';
|
||||
|
||||
const program = {
|
||||
sleep_time: 7200,
|
||||
rename_times: 20,
|
||||
webui_port: 7892,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
64
src/pages/config/components/BangumiManageItem.vue
Normal file
64
src/pages/config/components/BangumiManageItem.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { form, renameMethod, tfOptions } from '../form-data';
|
||||
|
||||
const bgmManage = computed(() => form.bangumi_manage);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="番剧管理">
|
||||
<ConfigFormCol label="启用">
|
||||
<el-select v-model="bgmManage.enable" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="历史番剧下载">
|
||||
<el-select v-model="bgmManage.eps_complete" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="重命名方法">
|
||||
<el-select v-model="bgmManage.rename_method" flex-1>
|
||||
<el-option
|
||||
v-for="opt in renameMethod"
|
||||
:key="opt"
|
||||
:label="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="下载规则中添加组名">
|
||||
<el-select v-model="bgmManage.group_tag" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="删除坏种">
|
||||
<el-select v-model="bgmManage.remove_bad_torrent" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
46
src/pages/config/components/DownloaderItem.vue
Normal file
46
src/pages/config/components/DownloaderItem.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<script lang="ts" setup>
|
||||
import { downloaderType, form, tfOptions } from '../form-data';
|
||||
|
||||
const downloader = computed(() => form.downloader);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="下载">
|
||||
<ConfigFormCol label="下载器">
|
||||
<el-select v-model="downloader.type" flex-1>
|
||||
<el-option
|
||||
v-for="opt in downloaderType"
|
||||
:key="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="host">
|
||||
<el-input v-model="downloader.host"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="path">
|
||||
<el-input v-model="downloader.path"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="username">
|
||||
<el-input v-model="downloader.username"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="password">
|
||||
<el-input v-model="downloader.password"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="ssl">
|
||||
<el-select v-model="downloader.ssl" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
20
src/pages/config/components/LogItem.vue
Normal file
20
src/pages/config/components/LogItem.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts" setup>
|
||||
import { form, tfOptions } from '../form-data';
|
||||
|
||||
const log = computed(() => form.log);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="日志">
|
||||
<ConfigFormCol label="启用debug">
|
||||
<el-select v-model="log.debug_enable" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
39
src/pages/config/components/NotificationItem.vue
Normal file
39
src/pages/config/components/NotificationItem.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<script lang="ts" setup>
|
||||
import { form, notificationType, tfOptions } from '../form-data';
|
||||
|
||||
const notification = computed(() => form.notification);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="通知">
|
||||
<ConfigFormCol label="启用">
|
||||
<el-select v-model="notification.enable" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="通知类型">
|
||||
<el-select v-model="notification.type" flex-1>
|
||||
<el-option
|
||||
v-for="opt in notificationType"
|
||||
:key="opt"
|
||||
:label="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="token">
|
||||
<el-input v-model="notification.token"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="chat_id">
|
||||
<el-input v-model="notification.chat_id" type="number"></el-input>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
21
src/pages/config/components/ProgramItem.vue
Normal file
21
src/pages/config/components/ProgramItem.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script lang="ts" setup>
|
||||
import { form } from '../form-data';
|
||||
|
||||
const program = computed(() => form.program);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="主程序">
|
||||
<ConfigFormCol label="RSS 检查间隔">
|
||||
<el-input v-model="program.sleep_time" type="number" />
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="重命名间隔">
|
||||
<el-input v-model="program.rename_times" type="number" />
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="webui端口">
|
||||
<el-input v-model="program.webui_port" type="number" />
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
47
src/pages/config/components/ProxyItem.vue
Normal file
47
src/pages/config/components/ProxyItem.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<script lang="ts" setup>
|
||||
import { form, proxyType, tfOptions } from '../form-data';
|
||||
|
||||
const proxy = computed(() => form.proxy);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="代理">
|
||||
<ConfigFormCol label="启用">
|
||||
<el-select v-model="proxy.enable" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="代理类型">
|
||||
<el-select v-model="proxy.type" flex-1>
|
||||
<el-option
|
||||
v-for="opt in proxyType"
|
||||
:key="opt"
|
||||
:label="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="host">
|
||||
<el-input v-model="proxy.host"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="port">
|
||||
<el-input v-model="proxy.port" type="number"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="username">
|
||||
<el-input v-model="proxy.username"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="password">
|
||||
<el-input v-model="proxy.password"></el-input>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
69
src/pages/config/components/RssParserItem.vue
Normal file
69
src/pages/config/components/RssParserItem.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<script lang="ts" setup>
|
||||
import { form, rssParserLang, rssParserType, tfOptions } from '../form-data';
|
||||
|
||||
const rssParser = computed(() => form.rss_parser);
|
||||
|
||||
const filter = ref('');
|
||||
watch(filter, (nv) => {
|
||||
const value = nv.split(',').filter((e) => e !== '');
|
||||
rssParser.value.filter = value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ConfigFormRow title="RSS解析">
|
||||
<ConfigFormCol label="启用">
|
||||
<el-select v-model="rssParser.enable" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="源">
|
||||
<el-select v-model="rssParser.type" flex-1>
|
||||
<el-option
|
||||
v-for="opt in rssParserType"
|
||||
:key="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="token">
|
||||
<el-input v-model="rssParser.token"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="语言">
|
||||
<el-select v-model="rssParser.language" flex-1>
|
||||
<el-option
|
||||
v-for="opt in rssParserLang"
|
||||
:key="opt"
|
||||
:value="opt"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="反代链接">
|
||||
<el-input v-model="rssParser.custom_url"></el-input>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="ssl">
|
||||
<el-select v-model="rssParser.enable_tmdb" flex-1>
|
||||
<el-option
|
||||
v-for="(opt, index) in tfOptions"
|
||||
:key="index"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</ConfigFormCol>
|
||||
|
||||
<ConfigFormCol label="筛选">
|
||||
<el-input v-model="filter" :value="rssParser.filter.join(',')"></el-input>
|
||||
</ConfigFormCol>
|
||||
</ConfigFormRow>
|
||||
</template>
|
||||
70
src/pages/config/form-data.ts
Normal file
70
src/pages/config/form-data.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type {
|
||||
Config,
|
||||
DownloaderType,
|
||||
NotificationType,
|
||||
ProxyType,
|
||||
RenameMethod,
|
||||
RssParserLang,
|
||||
RssParserType,
|
||||
} from '#/config';
|
||||
|
||||
export const form = reactive<Config>({
|
||||
data_version: 4,
|
||||
program: {
|
||||
sleep_time: 0,
|
||||
rename_times: 0,
|
||||
webui_port: 0,
|
||||
},
|
||||
downloader: {
|
||||
type: 'qbittorrent',
|
||||
host: '',
|
||||
username: '',
|
||||
password: '',
|
||||
path: '',
|
||||
ssl: false,
|
||||
},
|
||||
rss_parser: {
|
||||
enable: true,
|
||||
type: 'mikan',
|
||||
token: '',
|
||||
custom_url: '',
|
||||
enable_tmdb: false,
|
||||
filter: [],
|
||||
language: 'zh',
|
||||
},
|
||||
bangumi_manage: {
|
||||
enable: true,
|
||||
eps_complete: true,
|
||||
rename_method: 'normal',
|
||||
group_tag: true,
|
||||
remove_bad_torrent: true,
|
||||
},
|
||||
log: {
|
||||
debug_enable: false,
|
||||
},
|
||||
proxy: {
|
||||
enable: false,
|
||||
type: 'http',
|
||||
host: '',
|
||||
port: 0,
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
notification: {
|
||||
enable: false,
|
||||
type: 'telegram',
|
||||
token: '',
|
||||
chat_id: '',
|
||||
},
|
||||
});
|
||||
|
||||
export const downloaderType: DownloaderType = ['qbittorrent'];
|
||||
export const rssParserType: RssParserType = ['mikan'];
|
||||
export const rssParserLang: RssParserLang = ['zh', 'en', 'jp'];
|
||||
export const renameMethod: RenameMethod = ['normal', 'pn', 'advance', 'none'];
|
||||
export const proxyType: ProxyType = ['http', 'https', 'socks5'];
|
||||
export const notificationType: NotificationType = ['telegram', 'server-chan'];
|
||||
export const tfOptions = [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false },
|
||||
];
|
||||
@@ -1,20 +1,55 @@
|
||||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import ProgramItem from './components/ProgramItem.vue';
|
||||
import DownloaderItem from './components/DownloaderItem.vue';
|
||||
import RssParserItem from './components/RssParserItem.vue';
|
||||
import BangumiManageItem from './components/BangumiManageItem.vue';
|
||||
import LogItem from './components/LogItem.vue';
|
||||
import ProxyItem from './components/ProxyItem.vue';
|
||||
import NotificationItem from './components/NotificationItem.vue';
|
||||
|
||||
import { form } from './form-data';
|
||||
|
||||
const store = configStore();
|
||||
|
||||
watch(form, (v) => {
|
||||
console.log('🚀 ~ file: index.vue:54 ~ v:', v);
|
||||
});
|
||||
|
||||
onBeforeMount(async () => {
|
||||
await store.get();
|
||||
|
||||
if (store.config) {
|
||||
Object.keys(store.config).forEach((key) => {
|
||||
if (store.config) {
|
||||
form[key] = store.config[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="settings">
|
||||
<el-row :gutter="20">
|
||||
<!-- S 添加新番 -->
|
||||
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
||||
<AddBangumi type="new" />
|
||||
<el-col :xs="24" :sm="24">
|
||||
<el-form :model="form" label-position="right">
|
||||
<el-collapse>
|
||||
<ProgramItem />
|
||||
<DownloaderItem />
|
||||
<RssParserItem />
|
||||
<BangumiManageItem />
|
||||
<LogItem />
|
||||
<ProxyItem />
|
||||
<NotificationItem />
|
||||
</el-collapse>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<!-- E 添加新番 -->
|
||||
|
||||
<!-- S 添加旧番 -->
|
||||
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
||||
<AddBangumi type="old" />
|
||||
</el-col>
|
||||
<!-- E 添加旧番 -->
|
||||
</el-row>
|
||||
|
||||
<div flex="~ items-center justify-center" mt20>
|
||||
<el-button type="primary">保存</el-button>
|
||||
<el-button>还原</el-button>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'element-plus/es/components/message/style/css';
|
||||
import 'element-plus/es/components/message-box/style/css';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { resetRule } from '@/api/debug';
|
||||
import { appRestart } from '@/api/program';
|
||||
|
||||
const loading = ref(false);
|
||||
async function reset() {
|
||||
@@ -11,7 +12,7 @@ async function reset() {
|
||||
loading.value = false;
|
||||
if (res.data === 'Success') {
|
||||
ElMessage({
|
||||
message: '数据已重置, 建议重启容器',
|
||||
message: '数据已重置, 建议重启程序或容器',
|
||||
type: 'success',
|
||||
});
|
||||
} else {
|
||||
@@ -25,7 +26,28 @@ async function reset() {
|
||||
function restart() {
|
||||
ElMessageBox.confirm('该操作将重启程序!', {
|
||||
type: 'warning',
|
||||
});
|
||||
})
|
||||
.then(async () => {
|
||||
appRestart()
|
||||
.then(({ data }) => {
|
||||
console.log('🚀 ~ file: index.vue:33 ~ .then ~ data:', data);
|
||||
|
||||
if (data.status === 'success') {
|
||||
ElMessage({
|
||||
message: '正在重启, 请稍后刷新页面...',
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('🚀 ~ file: index.vue:41 ~ .then ~ e:', error);
|
||||
ElMessage({
|
||||
message: '操作失败, 请重试!',
|
||||
type: 'error',
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,55 +1,29 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export interface Config {
|
||||
data_version: 4;
|
||||
program: {
|
||||
sleep_time: number;
|
||||
rename_times: number;
|
||||
webui_port: number;
|
||||
};
|
||||
downloader: {
|
||||
type: 'qbittorrent';
|
||||
host: string;
|
||||
username: string;
|
||||
password: string;
|
||||
path: string;
|
||||
ssl: boolean;
|
||||
};
|
||||
rss_parser: {
|
||||
enable: boolean;
|
||||
type: string;
|
||||
token: string;
|
||||
custom_url: string;
|
||||
enable_tmdb: boolean;
|
||||
filter: Array<string>;
|
||||
language: 'zh' | 'en' | 'jp';
|
||||
};
|
||||
bangumi_manage: {
|
||||
enable: boolean;
|
||||
eps_complete: boolean;
|
||||
rename_method: 'normal' | 'pn' | 'advance' | 'none';
|
||||
group_tag: boolean;
|
||||
remove_bad_torrent: boolean;
|
||||
};
|
||||
log: {
|
||||
debug_enable: boolean;
|
||||
};
|
||||
proxy: {
|
||||
enable: boolean;
|
||||
type: 'http' | 'https';
|
||||
host: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
notification: {
|
||||
enable: boolean;
|
||||
type: 'telegram' | 'server-chan';
|
||||
token: string;
|
||||
chat_id: string;
|
||||
};
|
||||
}
|
||||
import { getConfig, setConfig } from '@/api/config';
|
||||
import type { Config } from '#/config';
|
||||
|
||||
export const configStore = defineStore('config', () => {
|
||||
const config = ref(null);
|
||||
const config = ref<Config>();
|
||||
|
||||
const get = async () => {
|
||||
config.value = await getConfig();
|
||||
};
|
||||
|
||||
get();
|
||||
|
||||
const set = (newConfig: Omit<Config, 'data_version'>) => {
|
||||
let finalConfig: Config;
|
||||
if (config.value !== undefined) {
|
||||
finalConfig = Object.assign(config.value, newConfig);
|
||||
return setConfig(finalConfig);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
config,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -12,13 +12,20 @@
|
||||
"esModuleInterop": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": false,
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"#/*": ["src/types/*"]
|
||||
"#/*": ["types/*"]
|
||||
},
|
||||
"types": ["element-plus/global"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"types/config.ts"
|
||||
],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
||||
74
types/config.ts
Normal file
74
types/config.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import type { UnionToTuple } from '#/utils';
|
||||
|
||||
export interface Config {
|
||||
data_version: 4;
|
||||
program: {
|
||||
sleep_time: number;
|
||||
rename_times: number;
|
||||
webui_port: number;
|
||||
};
|
||||
downloader: {
|
||||
type: 'qbittorrent';
|
||||
host: string;
|
||||
username: string;
|
||||
password: string;
|
||||
path: string;
|
||||
ssl: boolean;
|
||||
};
|
||||
rss_parser: {
|
||||
enable: boolean;
|
||||
type: 'mikan';
|
||||
token: string;
|
||||
custom_url: string;
|
||||
enable_tmdb: boolean;
|
||||
filter: Array<string>;
|
||||
language: 'zh' | 'en' | 'jp';
|
||||
};
|
||||
bangumi_manage: {
|
||||
enable: boolean;
|
||||
eps_complete: boolean;
|
||||
rename_method: 'normal' | 'pn' | 'advance' | 'none';
|
||||
group_tag: boolean;
|
||||
remove_bad_torrent: boolean;
|
||||
};
|
||||
log: {
|
||||
debug_enable: boolean;
|
||||
};
|
||||
proxy: {
|
||||
enable: boolean;
|
||||
type: 'http' | 'https' | 'socks5';
|
||||
host: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
notification: {
|
||||
enable: boolean;
|
||||
type: 'telegram' | 'server-chan';
|
||||
token: string;
|
||||
chat_id: string;
|
||||
};
|
||||
}
|
||||
|
||||
type getItem<T extends keyof Config> = Pick<Config, T>[T];
|
||||
|
||||
export type Program = getItem<'program'>;
|
||||
export type Downloader = getItem<'downloader'>;
|
||||
export type RssParser = getItem<'rss_parser'>;
|
||||
export type BangumiManage = getItem<'bangumi_manage'>;
|
||||
export type Log = getItem<'log'>;
|
||||
export type Proxy = getItem<'proxy'>;
|
||||
export type Notification = getItem<'notification'>;
|
||||
|
||||
/** 下载方式 */
|
||||
export type DownloaderType = UnionToTuple<Downloader['type']>;
|
||||
/** rss parser 源 */
|
||||
export type RssParserType = UnionToTuple<RssParser['type']>;
|
||||
/** rss parser 语言 */
|
||||
export type RssParserLang = UnionToTuple<RssParser['language']>;
|
||||
/** 重命名方式 */
|
||||
export type RenameMethod = UnionToTuple<BangumiManage['rename_method']>;
|
||||
/** 代理类型 */
|
||||
export type ProxyType = UnionToTuple<Proxy['type']>;
|
||||
/** 通知类型 */
|
||||
export type NotificationType = UnionToTuple<Notification['type']>;
|
||||
39
types/utils.ts
Normal file
39
types/utils.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 将联合类型转为对应的交叉函数类型
|
||||
* @template U 联合类型
|
||||
*/
|
||||
export type UnionToInterFunction<U> = (
|
||||
U extends any ? (k: () => U) => void : never
|
||||
) extends (k: infer I) => void
|
||||
? I
|
||||
: never;
|
||||
|
||||
/**
|
||||
* 获取联合类型中的最后一个类型
|
||||
* @template U 联合类型
|
||||
*/
|
||||
export type GetUnionLast<U> = UnionToInterFunction<U> extends { (): infer A }
|
||||
? A
|
||||
: never;
|
||||
|
||||
/**
|
||||
* 在元组类型中前置插入一个新的类型(元素);
|
||||
* @template Tuple 元组类型
|
||||
* @template E 新的类型
|
||||
*/
|
||||
export type Prepend<Tuple extends any[], E> = [E, ...Tuple];
|
||||
|
||||
/**
|
||||
* 联合类型转元组类型;
|
||||
* @template Union 联合类型
|
||||
* @template T 初始元组类型
|
||||
* @template Last 传入联合类型中的最后一个类型(元素),自动生成,内部使用
|
||||
*/
|
||||
export type UnionToTuple<
|
||||
Union,
|
||||
T extends any[] = [],
|
||||
Last = GetUnionLast<Union>
|
||||
> = {
|
||||
0: T;
|
||||
1: UnionToTuple<Exclude<Union, Last>, Prepend<T, Last>>;
|
||||
}[[Union] extends [never] ? 0 : 1];
|
||||
Reference in New Issue
Block a user