feat: 首页文献列表接入显示设置 — 新增共享齿轮面板组件并复用
首页卡片原未传 displaySettings 导致除标题日期外全部字段隐藏; 新建 DisplaySettingsPopover 共享组件,首页列表顶部加「最新文献」行+齿轮按钮, 搜索页改用共享组件,两页显示设置全局同步(localStorage 持久化)。
This commit is contained in:
Vendored
+1
@@ -8,6 +8,7 @@ export {}
|
|||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AdvancedSearchPanel: typeof import('./components/search/AdvancedSearchPanel.vue')['default']
|
AdvancedSearchPanel: typeof import('./components/search/AdvancedSearchPanel.vue')['default']
|
||||||
|
DisplaySettingsPopover: typeof import('./components/literature/DisplaySettingsPopover.vue')['default']
|
||||||
LiteratureCard: typeof import('./components/literature/LiteratureCard.vue')['default']
|
LiteratureCard: typeof import('./components/literature/LiteratureCard.vue')['default']
|
||||||
LiteraturePreviewDrawer: typeof import('./components/literature/LiteraturePreviewDrawer.vue')['default']
|
LiteraturePreviewDrawer: typeof import('./components/literature/LiteraturePreviewDrawer.vue')['default']
|
||||||
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
|
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { NButton, NIcon, NPopover, NCheckbox } from 'naive-ui'
|
||||||
|
import { SettingsOutline } from '@vicons/ionicons5'
|
||||||
|
import { useDisplaySettings } from '../../composables/useDisplaySettings'
|
||||||
|
|
||||||
|
const displaySettings = useDisplaySettings()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NPopover trigger="click" placement="bottom-end" :width="200">
|
||||||
|
<template #trigger>
|
||||||
|
<NButton size="tiny" quaternary title="显示设置"><template #icon><NIcon size="14"><SettingsOutline /></NIcon></template></NButton>
|
||||||
|
</template>
|
||||||
|
<div style="font-size:13px;font-weight:600;margin-bottom:8px">显示设置</div>
|
||||||
|
<div style="display:flex;flex-direction:column;gap:4px;font-size:13px">
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showAuthors">作者</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showAffiliation">机构</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showJournal">期刊+分区</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showPmid">PMID</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showDoi">DOI</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showStudyTypes">研究类型+OA+NCT</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showTags">MeSH 标签</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showCitedBy">被引次数</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showAiSummary">AI 摘要</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showBadges">徽章</NCheckbox>
|
||||||
|
<NCheckbox v-model:checked="displaySettings.showActions">操作按钮</NCheckbox>
|
||||||
|
</div>
|
||||||
|
</NPopover>
|
||||||
|
</template>
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||||
import { useRouter, useRoute, onBeforeRouteUpdate } from 'vue-router'
|
import { useRouter, useRoute, onBeforeRouteUpdate } from 'vue-router'
|
||||||
import { useAuthStore } from '../../stores/auth'
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import { NInput, NButton, NEmpty, NSelect, NCheckboxGroup, NCheckbox, NPagination, NIcon, NRadioGroup, NRadio, NSlider, NModal, NPopover } from 'naive-ui'
|
import { NInput, NButton, NEmpty, NSelect, NCheckboxGroup, NCheckbox, NPagination, NIcon, NRadioGroup, NRadio, NSlider, NModal } from 'naive-ui'
|
||||||
import { SearchOutline, FilterOutline, EyeOffOutline, SettingsOutline } from '@vicons/ionicons5'
|
import { SearchOutline, FilterOutline, EyeOffOutline } from '@vicons/ionicons5'
|
||||||
import { api } from '../../api/client'
|
import { api } from '../../api/client'
|
||||||
import { useToast } from '../../composables/useToast'
|
import { useToast } from '../../composables/useToast'
|
||||||
import { useLiteraturePreview } from '../../composables/useLiteraturePreview'
|
import { useLiteraturePreview } from '../../composables/useLiteraturePreview'
|
||||||
@@ -13,6 +13,7 @@ import { trackAction } from '../../composables/useAnalytics'
|
|||||||
import PageSkeleton from '../../components/common/PageSkeleton.vue'
|
import PageSkeleton from '../../components/common/PageSkeleton.vue'
|
||||||
import LiteratureCard from '../../components/literature/LiteratureCard.vue'
|
import LiteratureCard from '../../components/literature/LiteratureCard.vue'
|
||||||
import LiteraturePreviewDrawer from '../../components/literature/LiteraturePreviewDrawer.vue'
|
import LiteraturePreviewDrawer from '../../components/literature/LiteraturePreviewDrawer.vue'
|
||||||
|
import DisplaySettingsPopover from '../../components/literature/DisplaySettingsPopover.vue'
|
||||||
import type { LiteratureItem, TagOption, SearchRequestBody, SavedFilter } from '../../types'
|
import type { LiteratureItem, TagOption, SearchRequestBody, SavedFilter } from '../../types'
|
||||||
|
|
||||||
const router = useRouter(); const route = useRoute()
|
const router = useRouter(); const route = useRoute()
|
||||||
@@ -903,25 +904,7 @@ const specialTags = computed(() => filterOptions.value?.special_tags || {})
|
|||||||
{label:'20条/页',value:20},
|
{label:'20条/页',value:20},
|
||||||
{label:'50条/页',value:50},
|
{label:'50条/页',value:50},
|
||||||
]" size="tiny" style="width:100px" />
|
]" size="tiny" style="width:100px" />
|
||||||
<NPopover trigger="click" placement="bottom-end" :width="200">
|
<DisplaySettingsPopover />
|
||||||
<template #trigger>
|
|
||||||
<NButton size="tiny" quaternary title="显示设置"><template #icon><NIcon size="14"><SettingsOutline /></NIcon></template></NButton>
|
|
||||||
</template>
|
|
||||||
<div style="font-size:13px;font-weight:600;margin-bottom:8px">显示设置</div>
|
|
||||||
<div style="display:flex;flex-direction:column;gap:4px;font-size:13px">
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showAuthors">作者</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showAffiliation">机构</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showJournal">期刊+分区</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showPmid">PMID</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showDoi">DOI</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showStudyTypes">研究类型+OA+NCT</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showTags">MeSH 标签</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showCitedBy">被引次数</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showAiSummary">AI 摘要</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showBadges">徽章</NCheckbox>
|
|
||||||
<NCheckbox v-model:checked="displaySettings.showActions">操作按钮</NCheckbox>
|
|
||||||
</div>
|
|
||||||
</NPopover>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ import { useAuthStore } from '../../stores/auth'
|
|||||||
import { useToast } from '../../composables/useToast'
|
import { useToast } from '../../composables/useToast'
|
||||||
import { trackAction } from '../../composables/useAnalytics'
|
import { trackAction } from '../../composables/useAnalytics'
|
||||||
import { useLiteraturePreview } from '../../composables/useLiteraturePreview'
|
import { useLiteraturePreview } from '../../composables/useLiteraturePreview'
|
||||||
|
import { useDisplaySettings } from '../../composables/useDisplaySettings'
|
||||||
import PageSkeleton from '../../components/common/PageSkeleton.vue'
|
import PageSkeleton from '../../components/common/PageSkeleton.vue'
|
||||||
|
import DisplaySettingsPopover from '../../components/literature/DisplaySettingsPopover.vue'
|
||||||
import type { LiteratureItem, TagOption } from '../../types'
|
import type { LiteratureItem, TagOption } from '../../types'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
const displaySettings = useDisplaySettings()
|
||||||
|
|
||||||
// ── 搜索状态(统一数据源) ──
|
// ── 搜索状态(统一数据源) ──
|
||||||
const searchParams = ref({
|
const searchParams = ref({
|
||||||
@@ -502,6 +505,10 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<!-- 文献列表 -->
|
<!-- 文献列表 -->
|
||||||
<section class="section section-list">
|
<section class="section section-list">
|
||||||
|
<div class="list-header">
|
||||||
|
<span>最新文献</span>
|
||||||
|
<DisplaySettingsPopover />
|
||||||
|
</div>
|
||||||
<PageSkeleton :loading="loading && !feedItems.length">
|
<PageSkeleton :loading="loading && !feedItems.length">
|
||||||
<NEmpty v-if="!loading && !feedItems.length" description="暂无文献" />
|
<NEmpty v-if="!loading && !feedItems.length" description="暂无文献" />
|
||||||
<div v-if="!loading && !feedItems.length && searched && searchParams.query" class="search-result-count" style="text-align:center;margin-top:8px">共 0 条结果</div>
|
<div v-if="!loading && !feedItems.length && searched && searchParams.query" class="search-result-count" style="text-align:center;margin-top:8px">共 0 条结果</div>
|
||||||
@@ -518,6 +525,7 @@ onBeforeUnmount(() => {
|
|||||||
:showSave="auth.isAuthenticated"
|
:showSave="auth.isAuthenticated"
|
||||||
:savedPmids="savedPmids"
|
:savedPmids="savedPmids"
|
||||||
:searchQuery="searchParams.query"
|
:searchQuery="searchParams.query"
|
||||||
|
:displaySettings="displaySettings"
|
||||||
@detail="goDetail"
|
@detail="goDetail"
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
@save="saveLiterature"
|
@save="saveLiterature"
|
||||||
@@ -620,6 +628,7 @@ onBeforeUnmount(() => {
|
|||||||
.home { max-width: 1100px; margin: 0 auto; padding: 0 24px; color: var(--text-primary); }
|
.home { max-width: 1100px; margin: 0 auto; padding: 0 24px; color: var(--text-primary); }
|
||||||
.section { padding: 3px 0; }
|
.section { padding: 3px 0; }
|
||||||
.section-list { padding-bottom: 16px; }
|
.section-list { padding-bottom: 16px; }
|
||||||
|
.list-header { display: flex; align-items: center; justify-content: space-between; font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; }
|
||||||
.section-cta { padding: 12px 0 24px; }
|
.section-cta { padding: 12px 0 24px; }
|
||||||
|
|
||||||
/* 内容网格:文献列表 + 热榜侧栏 */
|
/* 内容网格:文献列表 + 热榜侧栏 */
|
||||||
|
|||||||
Reference in New Issue
Block a user