mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-21 08:10:16 +08:00
feat: 更新工作流组件,优化界面布局,添加消息和媒体过滤功能
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { Site } from '@/api/types'
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
@@ -11,6 +13,47 @@ defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 电影/电视剧下拉框
|
||||
const typeOptions = ref([
|
||||
{
|
||||
title: '电影',
|
||||
value: '电影',
|
||||
},
|
||||
{
|
||||
title: '电视剧',
|
||||
value: '电视剧',
|
||||
},
|
||||
])
|
||||
|
||||
// 站点数据列表
|
||||
const siteList = ref<Site[]>([])
|
||||
|
||||
// 获取站点列表数据
|
||||
async function loadSites() {
|
||||
try {
|
||||
const data: Site[] = await api.get('site/rss')
|
||||
|
||||
// 过滤站点,只有启用的站点才显示
|
||||
siteList.value = data.filter(item => item.is_active)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 站点选项
|
||||
const siteOptions = computed(() => {
|
||||
return siteList.value.map(item => {
|
||||
return {
|
||||
title: item.name,
|
||||
value: item.id,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadSites()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard max-width="20rem">
|
||||
@@ -25,7 +68,25 @@ defineProps({
|
||||
<VCardSubtitle>根据关键字搜索站点种子资源</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.name" label="名称" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.year" label="年份" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VSelect v-model="data.type" label="类型" :items="typeOptions" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.season" type="number" label="季" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VSelect v-model="data.sites" label="站点" :items="siteOptions" chips multiple outlined dense />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,6 +12,41 @@ defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 电影/电视剧下拉框
|
||||
const typeOptions = ref([
|
||||
{
|
||||
title: '电影',
|
||||
value: '电影',
|
||||
},
|
||||
{
|
||||
title: '电视剧',
|
||||
value: '电视剧',
|
||||
},
|
||||
])
|
||||
|
||||
// 二级分类策略
|
||||
const mediaCategories = ref<{ [key: string]: any }>({})
|
||||
|
||||
// 调用API查询自动分类配置
|
||||
async function loadMediaCategories() {
|
||||
try {
|
||||
mediaCategories.value = await api.get('media/category')
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据选中的媒体类型,获取对应的媒体类别
|
||||
const getCategories = computed(() => {
|
||||
const default_value = [{ title: '全部', value: '' }]
|
||||
if (!mediaCategories.value || !mediaCategories.value[props.data.type ?? '']) return default_value
|
||||
return default_value.concat(mediaCategories.value[props.data.type ?? ''])
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadMediaCategories()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard max-width="20rem">
|
||||
@@ -25,7 +61,22 @@ defineProps({
|
||||
<VCardSubtitle>对媒体数据列表进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VSelect v-model="data.type" label="类型" :items="typeOptions" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VSelect v-model="data.category" label="类别" :items="getCategories" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.year" label="年份" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.vote" type="number" label="评分" outlined dense />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { FilterRuleGroup } from '@/api/types'
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
@@ -11,6 +13,115 @@ defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 质量选择框数据
|
||||
const qualityOptions = ref([
|
||||
{
|
||||
title: '全部',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
title: '蓝光原盘',
|
||||
value: 'Blu-?Ray.+VC-?1|Blu-?Ray.+AVC|UHD.+blu-?ray.+HEVC|MiniBD',
|
||||
},
|
||||
{
|
||||
title: 'Remux',
|
||||
value: 'Remux',
|
||||
},
|
||||
{
|
||||
title: 'BluRay',
|
||||
value: 'Blu-?Ray',
|
||||
},
|
||||
{
|
||||
title: 'UHD',
|
||||
value: 'UHD|UltraHD',
|
||||
},
|
||||
{
|
||||
title: 'WEB-DL',
|
||||
value: 'WEB-?DL|WEB-?RIP',
|
||||
},
|
||||
{
|
||||
title: 'HDTV',
|
||||
value: 'HDTV',
|
||||
},
|
||||
{
|
||||
title: 'H265',
|
||||
value: '[Hx].?265|HEVC',
|
||||
},
|
||||
{
|
||||
title: 'H264',
|
||||
value: '[Hx].?264|AVC',
|
||||
},
|
||||
])
|
||||
|
||||
// 分辨率选择框数据
|
||||
const resolutionOptions = ref([
|
||||
{
|
||||
title: '全部',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
title: '4k',
|
||||
value: '4K|2160p|x2160',
|
||||
},
|
||||
{
|
||||
title: '1080p',
|
||||
value: '1080[pi]|x1080',
|
||||
},
|
||||
{
|
||||
title: '720p',
|
||||
value: '720[pi]|x720',
|
||||
},
|
||||
])
|
||||
|
||||
// 特效选择框数据
|
||||
const effectOptions = ref([
|
||||
{
|
||||
title: '全部',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
title: '杜比视界',
|
||||
value: 'Dolby[\\s.]+Vision|DOVI|[\\s.]+DV[\\s.]+',
|
||||
},
|
||||
{
|
||||
title: '杜比全景声',
|
||||
value: 'Dolby[\\s.]*\\+?Atmos|Atmos',
|
||||
},
|
||||
{
|
||||
title: 'HDR',
|
||||
value: '[\\s.]+HDR[\\s.]+|HDR10|HDR10\\+',
|
||||
},
|
||||
{
|
||||
title: 'SDR',
|
||||
value: '[\\s.]+SDR[\\s.]+',
|
||||
},
|
||||
])
|
||||
|
||||
// 所有规则组列表
|
||||
const filterRuleGroups = ref<FilterRuleGroup[]>([])
|
||||
|
||||
// 加载规则组
|
||||
async function queryFilterRuleGroups() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.get('system/setting/UserFilterRuleGroups')
|
||||
filterRuleGroups.value = result.data?.value ?? []
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算过滤规则组选择框数据
|
||||
const ruleGroupsOptions = computed(() => {
|
||||
return filterRuleGroups.value.map(group => ({
|
||||
title: group.name,
|
||||
value: group.name,
|
||||
}))
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
queryFilterRuleGroups()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard max-width="20rem">
|
||||
@@ -25,7 +136,39 @@ defineProps({
|
||||
<VCardSubtitle>对资源列表数据进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="6">
|
||||
<VSelect v-model="data.quality" label="质量" :items="qualityOptions" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VSelect v-model="data.resolution" label="分辨率" :items="resolutionOptions" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VSelect v-model="data.effect" label="特效" :items="effectOptions" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="6">
|
||||
<VTextField v-model="data.size" label="大小范围" placeholder="MB" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.include" label="包含(关键字、正则式)" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.exclude" label="排除(关键字、正则式)" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VSelect
|
||||
v-model="data.rule_groups"
|
||||
chips
|
||||
multiple
|
||||
label="过滤规则组"
|
||||
:items="ruleGroupsOptions"
|
||||
outlined
|
||||
dense
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -24,8 +24,6 @@ defineProps({
|
||||
<VCardTitle>刮削文件</VCardTitle>
|
||||
<VCardSubtitle>刮削媒体信息和图片</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -22,10 +22,8 @@ defineProps({
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>发送事件</VCardTitle>
|
||||
<VCardSubtitle>发送特定事件</VCardSubtitle>
|
||||
<VCardSubtitle>发送队列中的所有事件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import { NotificationConf } from '@/api/types'
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
@@ -11,6 +13,33 @@ defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 所有消息渠道
|
||||
const notifications = ref<NotificationConf[]>([])
|
||||
|
||||
// 调用API查询通知渠道设置
|
||||
async function loadNotificationSetting() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.get('system/setting/Notifications')
|
||||
notifications.value = result.data?.value ?? []
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算消息渠道选项
|
||||
const sourceOptions = computed(() => {
|
||||
return notifications.value.map(item => {
|
||||
return {
|
||||
title: item.name,
|
||||
value: item.name,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadNotificationSetting()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard max-width="20rem">
|
||||
@@ -22,10 +51,28 @@ defineProps({
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>发送消息</VCardTitle>
|
||||
<VCardSubtitle>发送特定消息</VCardSubtitle>
|
||||
<VCardSubtitle>发送队列中的所有消息</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VSelect
|
||||
v-model="data.client"
|
||||
:items="sourceOptions"
|
||||
label="消息渠道"
|
||||
chips
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
clearable
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.userid" label="用户ID" chips multiple outlined dense clearable />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -22,10 +22,8 @@ defineProps({
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>整理文件</VCardTitle>
|
||||
<VCardSubtitle>转移和重命名文件</VCardSubtitle>
|
||||
<VCardSubtitle>整理下载队列中的文件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user