feat:优先级规则支持拖动排序

This commit is contained in:
jxxghp
2024-05-14 11:32:28 +08:00
parent d501bf7506
commit 6ea106b25d
3 changed files with 129 additions and 291 deletions
+4 -24
View File
@@ -9,23 +9,13 @@ const props = defineProps({
}) })
// 定义触发的自定义事件 // 定义触发的自定义事件
const emit = defineEmits(['close', 'changed', 'levelup', 'leveldown']) const emit = defineEmits(['close', 'changed'])
// 按钮点击 // 按钮点击
function onClose() { function onClose() {
emit('close') emit('close')
} }
// 上升优先级
function onLevelUp() {
emit('levelup', props.pri)
}
// 下降优先级
function onLevelDown() {
emit('leveldown', props.pri)
}
// 选项变化 // 选项变化
function filtersChanged(value: string[]) { function filtersChanged(value: string[]) {
emit('changed', props.pri, value) emit('changed', props.pri, value)
@@ -76,18 +66,9 @@ const selectFilterOptions = ref<{ [key: string]: string }[]>([
<template> <template>
<VCard variant="tonal" :width="props.width" :height="props.height"> <VCard variant="tonal" :width="props.width" :height="props.height">
<span class="absolute top-3 right-14"> <span class="absolute top-3 right-12">
<IconBtn <IconBtn>
v-if="props.pri !== '1'" <VIcon class="cursor-move" icon="mdi-drag" />
@click.stop="onLevelUp"
>
<VIcon icon="mdi-arrow-up" />
</IconBtn>
<IconBtn
v-if="props.pri !== props.maxpri"
@click.stop="onLevelDown"
>
<VIcon icon="mdi-arrow-down" />
</IconBtn> </IconBtn>
</span> </span>
<DialogCloseBtn @click="onClose" /> <DialogCloseBtn @click="onClose" />
@@ -96,7 +77,6 @@ const selectFilterOptions = ref<{ [key: string]: string }[]>([
<VRow> <VRow>
<VCol> <VCol>
<VSelect <VSelect
:key="props.pri"
v-model="props.rules" v-model="props.rules"
variant="underlined" variant="underlined"
:items="selectFilterOptions" :items="selectFilterOptions"
+25 -49
View File
@@ -1,5 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import draggable from 'vuedraggable'
import api from '@/api' import api from '@/api'
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue' import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
import type { Site } from '@/api/types' import type { Site } from '@/api/types'
@@ -170,42 +171,12 @@ async function saveSelectedSites() {
} }
} }
// 上调优先级 // 根据列表的拖动顺序更新优先级
function onLevelUp(pri: string) { function dragOrderEnd() {
// 找到当前卡片 filterCards.value = filterCards.value.map((card, index) => {
const card = filterCards.value.find(card => card.pri === pri) card.pri = (index + 1).toString()
if (!card) return return card
})
// 找到当前卡片的上一张卡片
const prevCard = filterCards.value.find(card => card.pri === (parseInt(pri) - 1).toString())
if (!prevCard) return
// 交换两张卡片的优先级
const temp = card.pri
card.pri = prevCard.pri
prevCard.pri = temp
// 卡片重新按优先级排序
filterCards.value.sort((a, b) => parseInt(a.pri) - parseInt(b.pri))
}
// 下调优先级
function onLevelDown(pri: string) {
// 找到当前卡片
const card = filterCards.value.find(card => card.pri === pri)
if (!card) return
// 找到当前卡片的下一张卡片
const nextCard = filterCards.value.find(card => card.pri === (parseInt(pri) + 1).toString())
if (!nextCard) return
// 交换两张卡片的优先级
const temp = card.pri
card.pri = nextCard.pri
nextCard.pri = temp
// 卡片重新按优先级排序
filterCards.value.sort((a, b) => parseInt(a.pri) - parseInt(b.pri))
} }
// 查询包含与排除规则 // 查询包含与排除规则
@@ -380,19 +351,24 @@ onMounted(() => {
</template> </template>
<VCardSubtitle> 设置在搜索时默认使用的优先级排序未在优先级中的资源将不在搜索结果中显示 </VCardSubtitle> <VCardSubtitle> 设置在搜索时默认使用的优先级排序未在优先级中的资源将不在搜索结果中显示 </VCardSubtitle>
<VCardItem> <VCardItem>
<div class="grid gap-3 grid-filterrule-card"> <draggable
<FilterRuleCard v-model="filterCards"
v-for="(card, index) in filterCards" handle=".cursor-move"
:key="index" item-key="pri"
:pri="card.pri" tag="div"
:maxpri="filterCards.length.toString()" @end="dragOrderEnd"
:rules="card.rules" :component-data="{ 'class': 'grid gap-3 grid-filterrule-card' }"
@changed="updateFilterCardValue" >
@close="filterCardClose(card.pri)" <template #item="{ element }">
@leveldown="onLevelDown" <FilterRuleCard
@levelup="onLevelUp" :pri="element.pri"
/> :maxpri="filterCards.length.toString()"
</div> :rules="element.rules"
@changed="updateFilterCardValue"
@close="filterCardClose(element.pri)"
/>
</template>
</draggable>
</VCardItem> </VCardItem>
<VCardItem> <VCardItem>
<VBtn type="submit" class="me-2" @click="saveCustomFilters()"> 保存 </VBtn> <VBtn type="submit" class="me-2" @click="saveCustomFilters()"> 保存 </VBtn>
+100 -218
View File
@@ -1,5 +1,6 @@
<script lang='ts' setup> <script lang="ts" setup>
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import draggable from 'vuedraggable'
import api from '@/api' import api from '@/api'
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue' import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
import type { Site } from '@/api/types' import type { Site } from '@/api/types'
@@ -42,7 +43,7 @@ const defaultFilterRules = ref({
movie_size: '', movie_size: '',
tv_size: '', tv_size: '',
min_seeders: 0, min_seeders: 0,
min_seeders_time: 0 min_seeders_time: 0,
}) })
// 订阅模式选择项 // 订阅模式选择项
@@ -80,8 +81,7 @@ async function querySelectedRssSites() {
const result: { [key: string]: any } = await api.get('system/setting/RssSites') const result: { [key: string]: any } = await api.get('system/setting/RssSites')
selectedRssSites.value = result.data?.value ?? [] selectedRssSites.value = result.data?.value ?? []
} } catch (error) {
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -89,31 +89,23 @@ async function querySelectedRssSites() {
// 保存用户选中的订阅站点 // 保存用户选中的订阅站点
async function saveSelectedRssSites() { async function saveSelectedRssSites() {
try { try {
const result1: { [key: string]: any } = await api.post( const result1: { [key: string]: any } = await api.post('system/setting/RssSites', selectedRssSites.value)
'system/setting/RssSites',
selectedRssSites.value)
const result2: { [key: string]: any } = await api.post( const result2: { [key: string]: any } = await api.post(
'system/setting/SUBSCRIBE_SEARCH', 'system/setting/SUBSCRIBE_SEARCH',
enableIntervalSearch.value ? 'True' : 'False', enableIntervalSearch.value ? 'True' : 'False',
) )
const result3: { [key: string]: any } = await api.post( const result3: { [key: string]: any } = await api.post('system/setting/SUBSCRIBE_MODE', selectedSubscribeMode.value)
'system/setting/SUBSCRIBE_MODE',
selectedSubscribeMode.value,
)
const result4: { [key: string]: any } = await api.post( const result4: { [key: string]: any } = await api.post(
'system/setting/SUBSCRIBE_RSS_INTERVAL', 'system/setting/SUBSCRIBE_RSS_INTERVAL',
selectedRssInterval.value, selectedRssInterval.value,
) )
if (result1.success && result2.success && result3.success && result4.success) if (result1.success && result2.success && result3.success && result4.success) $toast.success('订阅站点保存成功')
$toast.success('订阅站点保存成功') else $toast.error('订阅站点保存失败!')
else } catch (error) {
$toast.error('订阅站点保存失败!')
}
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -129,18 +121,14 @@ async function querySites() {
// 查询订阅搜索开关 // 查询订阅搜索开关
const result: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_SEARCH') const result: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_SEARCH')
if (result.success) if (result.success) enableIntervalSearch.value = result.data?.value
enableIntervalSearch.value = result.data?.value
// 查询订阅模式 // 查询订阅模式
const result2: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_MODE') const result2: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_MODE')
if (result2.success) if (result2.success) selectedSubscribeMode.value = result2.data?.value
selectedSubscribeMode.value = result2.data?.value
// 查询站点RSS周期 // 查询站点RSS周期
const result3: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_RSS_INTERVAL') const result3: { [key: string]: any } = await api.get('system/setting/SUBSCRIBE_RSS_INTERVAL')
if (result3.success) if (result3.success) selectedRssInterval.value = result3.data?.value
selectedRssInterval.value = result3.data?.value } catch (error) {
}
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -162,8 +150,7 @@ async function queryCustomFilters(ruleType: string) {
} }
}) })
} }
} } catch (error) {
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -182,35 +169,27 @@ async function saveCustomFilters(ruleType: string) {
.join('>') .join('>')
} }
// 保存 // 保存
const result: { [key: string]: any } = await api.post( const result: { [key: string]: any } = await api.post(`system/setting/${ruleType}`, value)
`system/setting/${ruleType}`,
value,
)
const msg = ruleType === 'SubscribeFilterRules' ? '订阅优先级' : '洗版优先级' const msg = ruleType === 'SubscribeFilterRules' ? '订阅优先级' : '洗版优先级'
if (result.success) if (result.success) $toast.success(`${msg}保存成功`)
$toast.success(`${msg}保存成功`) else $toast.error(`${msg}保存失败!`)
else } catch (error) {
$toast.error(`${msg}保存失败!`)
}
catch (error) {
console.log(error) console.log(error)
} }
} }
// 更新规则卡片的值 // 更新规则卡片的值
function updateFilterCardValue(pri: string, rules: string[]) { function updateSubscribeFilterCardValue(pri: string, rules: string[]) {
const card = subscribeFilterCards.value.find(card => card.pri === pri) const card = subscribeFilterCards.value.find(card => card.pri === pri)
if (card) if (card) card.rules = rules
card.rules = rules
} }
// 更新洗版规则卡片的值 // 更新洗版规则卡片的值
function updateFilterCardValue2(pri: string, rules: string[]) { function updateBestVersionFilterCardValue(pri: string, rules: string[]) {
const card = bestVersionFilterCards.value.find(card => card.pri === pri) const card = bestVersionFilterCards.value.find(card => card.pri === pri)
if (card) if (card) card.rules = rules
card.rules = rules
} }
// 移除卡片 // 移除卡片
@@ -223,10 +202,8 @@ function filterCardClose(ruleType: string, pri: string) {
return card return card
}) })
// 更新 subscribeFilterCards.value // 更新 subscribeFilterCards.value
if (ruleType === 'SubscribeFilterRules') if (ruleType === 'SubscribeFilterRules') subscribeFilterCards.value = updatedCards
subscribeFilterCards.value = updatedCards else bestVersionFilterCards.value = updatedCards
else
bestVersionFilterCards.value = updatedCards
} }
// 增加卡片 // 增加卡片
@@ -242,58 +219,22 @@ function addFilterCard(ruleType: string) {
cards.value.push(newCard) cards.value.push(newCard)
} }
// 上调优先级 // 根据列表的拖动顺序更新优先级
function onLevelUp(filterCards: FilterCard[], pri: string) { function dragOrderEnd(ruleType: string) {
// 找到当前卡片 ;(ruleType === 'SubscribeFilterRules' ? subscribeFilterCards.value : bestVersionFilterCards.value).map(
const card = filterCards.find(card => card.pri === pri) (card, index) => {
if (!card) card.pri = (index + 1).toString()
return return card
},
// 找到当前卡片的上一张卡片 )
const prevCard = filterCards.find(card => card.pri === (parseInt(pri) - 1).toString())
if (!prevCard)
return
// 交换两张卡片的优先级
const temp = card.pri
card.pri = prevCard.pri
prevCard.pri = temp
// 卡片重新按优先级排序
filterCards.sort((a, b) => parseInt(a.pri) - parseInt(b.pri))
}
// 下调优先级
function onLevelDown(filterCards: FilterCard[], pri: string) {
// 找到当前卡片
const card = filterCards.find(card => card.pri === pri)
if (!card)
return
// 找到当前卡片的下一张卡片
const nextCard = filterCards.find(card => card.pri === (parseInt(pri) + 1).toString())
if (!nextCard)
return
// 交换两张卡片的优先级
const temp = card.pri
card.pri = nextCard.pri
nextCard.pri = temp
// 卡片重新按优先级排序
filterCards.sort((a, b) => parseInt(a.pri) - parseInt(b.pri))
} }
// 查询包含与排除规则 // 查询包含与排除规则
async function queryDefaultFilter() { async function queryDefaultFilter() {
try { try {
const result: { [key: string]: any } = await api.get( const result: { [key: string]: any } = await api.get('system/setting/DefaultFilterRules')
'system/setting/DefaultFilterRules', if (result.data?.value) defaultFilterRules.value = result.data?.value
) } catch (error) {
if (result.data?.value)
defaultFilterRules.value = result.data?.value
}
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -301,16 +242,10 @@ async function queryDefaultFilter() {
// 保存包含与排除规则 // 保存包含与排除规则
async function saveDefaultFilter() { async function saveDefaultFilter() {
try { try {
const result: { [key: string]: any } = await api.post( const result: { [key: string]: any } = await api.post('system/setting/DefaultFilterRules', defaultFilterRules.value)
'system/setting/DefaultFilterRules', if (result.success) $toast.success('默认包含/排除规则保存成功')
defaultFilterRules.value, else $toast.error('默认包含/排除规则保存失败!')
) } catch (error) {
if (result.success)
$toast.success('默认包含/排除规则保存成功')
else
$toast.error('默认包含/排除规则保存失败!')
}
catch (error) {
console.log(error) console.log(error)
} }
} }
@@ -318,13 +253,10 @@ async function saveDefaultFilter() {
// 分享规则 // 分享规则
function shareRules(ruleType: string) { function shareRules(ruleType: string) {
let filterCards: Ref<FilterCard[]> let filterCards: Ref<FilterCard[]>
if (ruleType === 'SubscribeFilterRules') if (ruleType === 'SubscribeFilterRules') filterCards = subscribeFilterCards
filterCards = subscribeFilterCards else filterCards = bestVersionFilterCards
else
filterCards = bestVersionFilterCards
// 有值才处理 // 有值才处理
if (filterCards.value.length === 0) if (filterCards.value.length === 0) return
return
// 将卡片规则接装为字符串 // 将卡片规则接装为字符串
const value = filterCards.value const value = filterCards.value
@@ -336,8 +268,7 @@ function shareRules(ruleType: string) {
try { try {
copyToClipboard(value) copyToClipboard(value)
$toast.success('优先级规则已复制到剪贴板') $toast.success('优先级规则已复制到剪贴板')
} } catch (error) {
catch (error) {
$toast.error('优先级规则复制失败!') $toast.error('优先级规则复制失败!')
} }
} }
@@ -351,20 +282,14 @@ async function importRules(ruleType: string) {
// 监听导入代码变化 // 监听导入代码变化
watchEffect(() => { watchEffect(() => {
if (!importCodeString.value) if (!importCodeString.value) return
return if (!currentRuleType.value) return
if (!currentRuleType.value)
return
// 导入代码需要以空格开头和结束,没有则拼接 // 导入代码需要以空格开头和结束,没有则拼接
if (!importCodeString.value.startsWith(' ')) if (!importCodeString.value.startsWith(' ')) importCodeString.value = ` ${importCodeString.value}`
importCodeString.value = ` ${importCodeString.value}` if (!importCodeString.value.endsWith(' ')) importCodeString.value = `${importCodeString.value} `
if (!importCodeString.value.endsWith(' '))
importCodeString.value = `${importCodeString.value} `
let filterCards: Ref<FilterCard[]> let filterCards: Ref<FilterCard[]>
if (currentRuleType.value === 'SubscribeFilterRules') if (currentRuleType.value === 'SubscribeFilterRules') filterCards = subscribeFilterCards
filterCards = subscribeFilterCards else filterCards = bestVersionFilterCards
else
filterCards = bestVersionFilterCards
// 将导入的代码转换为规则卡片 // 将导入的代码转换为规则卡片
const groups = importCodeString.value.split('>') const groups = importCodeString.value.split('>')
filterCards.value = groups.map((group: string, index: number) => { filterCards.value = groups.map((group: string, index: number) => {
@@ -435,9 +360,7 @@ onMounted(() => {
</VForm> </VForm>
</VCardText> </VCardText>
<VCardItem> <VCardItem>
<VBtn type="submit" @click="saveSelectedRssSites"> <VBtn type="submit" @click="saveSelectedRssSites"> 保存 </VBtn>
保存
</VBtn>
</VCardItem> </VCardItem>
</VCard> </VCard>
</VCol> </VCol>
@@ -446,24 +369,15 @@ onMounted(() => {
<template #append> <template #append>
<IconBtn> <IconBtn>
<VIcon icon="mdi-dots-vertical" /> <VIcon icon="mdi-dots-vertical" />
<VMenu <VMenu activator="parent" close-on-content-click>
activator="parent"
close-on-content-click
>
<VList> <VList>
<VListItem <VListItem variant="plain" @click="shareRules('SubscribeFilterRules')">
variant="plain"
@click="shareRules('SubscribeFilterRules')"
>
<template #prepend> <template #prepend>
<VIcon icon="mdi-share" /> <VIcon icon="mdi-share" />
</template> </template>
<VListItemTitle>分享</VListItemTitle> <VListItemTitle>分享</VListItemTitle>
</VListItem> </VListItem>
<VListItem <VListItem variant="plain" @click="importRules('SubscribeFilterRules')">
variant="plain"
@click="importRules('SubscribeFilterRules')"
>
<template #prepend> <template #prepend>
<VIcon icon="mdi-import" /> <VIcon icon="mdi-import" />
</template> </template>
@@ -475,33 +389,28 @@ onMounted(() => {
</template> </template>
<VCardSubtitle> 设置在正常订阅时默认使用的优先级未在优先级中的资源将不会自动下载</VCardSubtitle> <VCardSubtitle> 设置在正常订阅时默认使用的优先级未在优先级中的资源将不会自动下载</VCardSubtitle>
<VCardItem> <VCardItem>
<div class="grid gap-3 grid-filterrule-card"> <draggable
<FilterRuleCard v-model="subscribeFilterCards"
v-for="(card, index) in subscribeFilterCards" handle=".cursor-move"
:key="index" item-key="pri"
:pri="card.pri" tag="div"
:maxpri="subscribeFilterCards.length.toString()" @end="dragOrderEnd('SubscribeFilterRules')"
:rules="card.rules" :component-data="{ 'class': 'grid gap-3 grid-filterrule-card' }"
@changed="updateFilterCardValue" >
@close="filterCardClose('SubscribeFilterRules', card.pri)" <template #item="{ element }">
@leveldown="onLevelDown(subscribeFilterCards, card.pri)" <FilterRuleCard
@levelup="onLevelUp(subscribeFilterCards, card.pri)" :pri="element.pri"
/> :maxpri="subscribeFilterCards.length.toString()"
</div> :rules="element.rules"
@changed="updateSubscribeFilterCardValue"
@close="filterCardClose('SubscribeFilterRules', element.pri)"
/>
</template>
</draggable>
</VCardItem> </VCardItem>
<VCardItem> <VCardItem>
<VBtn <VBtn type="submit" class="me-2" @click="saveCustomFilters('SubscribeFilterRules')"> 保存 </VBtn>
type="submit" <VBtn color="success" variant="tonal" @click="addFilterCard('SubscribeFilterRules')">
class="me-2"
@click="saveCustomFilters('SubscribeFilterRules')"
>
保存
</VBtn>
<VBtn
color="success"
variant="tonal"
@click="addFilterCard('SubscribeFilterRules')"
>
<VIcon icon="mdi-plus" /> <VIcon icon="mdi-plus" />
</VBtn> </VBtn>
</VCardItem> </VCardItem>
@@ -512,24 +421,15 @@ onMounted(() => {
<template #append> <template #append>
<IconBtn> <IconBtn>
<VIcon icon="mdi-dots-vertical" /> <VIcon icon="mdi-dots-vertical" />
<VMenu <VMenu activator="parent" close-on-content-click>
activator="parent"
close-on-content-click
>
<VList> <VList>
<VListItem <VListItem variant="plain" @click="shareRules('BestVersionFilterRules')">
variant="plain"
@click="shareRules('BestVersionFilterRules')"
>
<template #prepend> <template #prepend>
<VIcon icon="mdi-share" /> <VIcon icon="mdi-share" />
</template> </template>
<VListItemTitle>分享</VListItemTitle> <VListItemTitle>分享</VListItemTitle>
</VListItem> </VListItem>
<VListItem <VListItem variant="plain" @click="importRules('BestVersionFilterRules')">
variant="plain"
@click="importRules('BestVersionFilterRules')"
>
<template #prepend> <template #prepend>
<VIcon icon="mdi-import" /> <VIcon icon="mdi-import" />
</template> </template>
@@ -541,33 +441,28 @@ onMounted(() => {
</template> </template>
<VCardSubtitle> 设置在订阅洗版时使用的优先级匹配优先级1时洗版完成</VCardSubtitle> <VCardSubtitle> 设置在订阅洗版时使用的优先级匹配优先级1时洗版完成</VCardSubtitle>
<VCardItem> <VCardItem>
<div class="grid gap-3 grid-filterrule-card"> <draggable
<FilterRuleCard v-model="bestVersionFilterCards"
v-for="(card, index) in bestVersionFilterCards" handle=".cursor-move"
:key="index" item-key="pri"
:pri="card.pri" tag="div"
:maxpri="bestVersionFilterCards.length.toString()" @end="dragOrderEnd('BestVersionFilterRules')"
:rules="card.rules" :component-data="{ 'class': 'grid gap-3 grid-filterrule-card' }"
@changed="updateFilterCardValue2" >
@close="filterCardClose('BestVersionFilterRules', card.pri)" <template #item="{ element }">
@leveldown="onLevelDown(bestVersionFilterCards, card.pri)" <FilterRuleCard
@levelup="onLevelUp(bestVersionFilterCards, card.pri)" :pri="element.pri"
/> :maxpri="bestVersionFilterCards.length.toString()"
</div> :rules="element.rules"
@changed="updateBestVersionFilterCardValue"
@close="filterCardClose('BestVersionFilterRules', element.pri)"
/>
</template>
</draggable>
</VCardItem> </VCardItem>
<VCardItem> <VCardItem>
<VBtn <VBtn type="submit" class="me-2" @click="saveCustomFilters('BestVersionFilterRules')"> 保存 </VBtn>
type="submit" <VBtn color="success" variant="tonal" @click="addFilterCard('BestVersionFilterRules')">
class="me-2"
@click="saveCustomFilters('BestVersionFilterRules')"
>
保存
</VBtn>
<VBtn
color="success"
variant="tonal"
@click="addFilterCard('BestVersionFilterRules')"
>
<VIcon icon="mdi-plus" /> <VIcon icon="mdi-plus" />
</VBtn> </VBtn>
</VCardItem> </VCardItem>
@@ -635,30 +530,17 @@ onMounted(() => {
</VForm> </VForm>
</VCardText> </VCardText>
<VCardItem> <VCardItem>
<VBtn <VBtn type="submit" @click="saveDefaultFilter"> 保存 </VBtn>
type="submit"
@click="saveDefaultFilter"
>
保存
</VBtn>
</VCardItem> </VCardItem>
</VCard> </VCard>
</VCol> </VCol>
</VRow> </VRow>
<VDialog <VDialog v-model="importCodeDialog" width="60rem" scrollable>
v-model="importCodeDialog" <ImportCodeDialog v-model="importCodeString" title="导入优先级规则" @close="importCodeDialog = false" />
width="60rem"
scrollable
>
<ImportCodeDialog
v-model="importCodeString"
title="导入优先级规则"
@close="importCodeDialog = false"
/>
</VDialog> </VDialog>
</template> </template>
<style lang='scss'> <style lang="scss">
.grid-filterrule-card { .grid-filterrule-card {
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
padding-block-end: 1rem; padding-block-end: 1rem;