From c1bb66cc9dc7d2abbc202f37e88a5bdfb6497cf3 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 28 Apr 2024 13:40:49 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E6=8F=92=E4=BB=B6=E8=BF=87=E6=BB=A4=20&?= =?UTF-8?q?=20=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/types.ts | 2 + src/components/cards/PluginAppCard.vue | 13 +- src/views/plugin/PluginCardListView.vue | 135 +++++++++++++++++++-- src/views/setting/AccountSettingSearch.vue | 4 +- 4 files changed, 141 insertions(+), 13 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index e202dcbb..985cd64a 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -407,6 +407,8 @@ export interface Plugin { plugin_desc?: string // 插件图标 plugin_icon?: string + // 插件标签,多个以,分隔 + plugin_label?: string // 插件版本 plugin_version?: string // 插件作者 diff --git a/src/components/cards/PluginAppCard.vue b/src/components/cards/PluginAppCard.vue index 8db903a4..7ef73dfc 100644 --- a/src/components/cards/PluginAppCard.vue +++ b/src/components/cards/PluginAppCard.vue @@ -43,6 +43,12 @@ const imageLoadError = ref(false) // 更新日志弹窗 const releaseDialog = ref(false) +// 计算插件标签 +const pluginLabels = computed(() => { + if (!props.plugin?.plugin_label) return [] + return props.plugin.plugin_label.split(',') +}) + // 图片加载完成 async function imageLoaded() { isImageLoaded.value = true @@ -183,7 +189,12 @@ const dropdownItems = ref([ v{{ props.plugin?.plugin_version }} - {{ props.plugin?.plugin_desc }} +
{{ props.plugin?.plugin_desc }}
+
+ + {{ label }} + +
diff --git a/src/views/plugin/PluginCardListView.vue b/src/views/plugin/PluginCardListView.vue index 7636ef39..c0230cb4 100644 --- a/src/views/plugin/PluginCardListView.vue +++ b/src/views/plugin/PluginCardListView.vue @@ -7,6 +7,7 @@ import PluginAppCard from '@/components/cards/PluginAppCard.vue' import PluginCard from '@/components/cards/PluginCard.vue' import noImage from '@images/logos/plugin.png' import { useDisplay } from 'vuetify' +import { isNullOrEmptyObject } from '@/@core/utils' // 显示器宽度 const display = useDisplay() @@ -17,6 +18,9 @@ const dataList = ref([]) // 未安装插件列表 const uninstalledList = ref([]) +// 插件市场插件列表 +const marketList = ref([]) + // 是否刷新过 const isRefreshed = ref(false) @@ -50,6 +54,41 @@ const progressDialog = ref(false) // 进度框文本 const progressText = ref('正在安装插件...') +// 过滤表单 +const filterForm = reactive({ + // 名称 + name: [] as string[], + // 作者 + author: [] as string[], + // 标签 + label: [] as string[], + // 插件库 + repo: [] as string[], +}) + +// 名称过滤项 +const nameFilterOptions = ref([]) +// 作者过滤项 +const authorFilterOptions = ref([]) +// 标签过滤项 +const labelFilterOptions = ref([]) +// 插件库过滤项 +const repoFilterOptions = ref([]) + +// 初始化过滤选项 +function initOptions(item: Plugin) { + const optionValue = (options: Array, value: string | undefined) => { + value && !options.includes(value) && options.push(value) + } + const optionMutipleValue = (options: Array, value: string | undefined) => { + value && value.split(',').forEach(v => !options.includes(v) && options.push(v)) + } + optionValue(nameFilterOptions.value, item.plugin_name) + optionValue(authorFilterOptions.value, item.plugin_author) + optionMutipleValue(labelFilterOptions.value, item.plugin_label) + optionValue(repoFilterOptions.value, item.repo_url) +} + // 关闭插件市场窗口 function pluginDialogClose() { PluginAppDialog.value = false @@ -123,7 +162,11 @@ function pluginIcon(item: Plugin) { const filterPlugins = computed(() => { const all_list = [...dataList.value, ...uninstalledList.value] return all_list.filter((item: Plugin) => { - return item.plugin_name?.includes(keyword.value) || item.plugin_desc?.includes(keyword.value) + // 需要忽略大小写 + return ( + item.plugin_name?.toLowerCase().includes(keyword.value.toLowerCase()) || + item.plugin_desc?.toLowerCase().includes(keyword.value.toLowerCase()) + ) }) }) @@ -167,6 +210,11 @@ async function fetchUninstalledPlugins() { } } } + // 更新插件市场列表 + // 排除已安装且有更新的,上面的问题在于“本地存在未安装的旧版本插件且云端有更新时”不会在插件市场展示 + marketList.value = uninstalledList.value.filter(item => !(item.has_update && item.installed)) + // 初始化过滤选项 + marketList.value.forEach(initOptions) } catch (error) { console.error(error) } @@ -189,11 +237,32 @@ function refreshData() { // 对uninstalledList进行排序,按PluginStatistics倒序 const sortedUninstalledList = computed(() => { - //const list = uninstalledList.value.filter(item => !item.has_update) - // 排除已安装且有更新的,上面的问题在于“本地存在未安装的旧版本插件且云端有更新时”不会在插件市场展示 - const list = uninstalledList.value.filter(item => !(item.has_update && item.installed)) - if (PluginStatistics.value.length === 0) return list - return list.sort((a, b) => { + // 匹配过滤函数 + const match = (filter: Array, value: string | undefined) => + filter.length === 0 || (value && filter.includes(value)) + const matchMultiple = (filter: Array, value: string | undefined) => + filter.length === 0 || (value && value.split(',').some(v => filter.includes(v))) + + // 过滤后的数据列表 + const ret_list: Plugin[] = [] + + // 过滤 + marketList.value.forEach(value => { + if (value) { + if ( + match(filterForm.name, value.plugin_name) && + match(filterForm.author, value.plugin_author) && + matchMultiple(filterForm.label, value.plugin_label) && + match(filterForm.repo, value.repo_url) + ) { + ret_list.push(value) + } + } + }) + + // 按照统计数据排序 + if (isNullOrEmptyObject(PluginStatistics.value)) return ret_list + return ret_list.sort((a, b) => { return PluginStatistics.value[b.id || '0'] - PluginStatistics.value[a.id || '0'] }) }) @@ -236,15 +305,12 @@ onBeforeMount(() => { :z-index="1010" transition="dialog-bottom-transition" > - - +
插件市场 - - @@ -254,6 +320,55 @@ onBeforeMount(() => {
+ +
+ + + + + + + + + + + + + + +
{ chips :items="mediaSourcesDict" label="当前使用数据源" - hint="选中多项时会同时展示来自不同数据源的搜索结果" + hint="选中多项时会同时展示来自不同数据源的搜索结果,选择的数据源顺序将会搜索结果的排序" />