OncoLit: a multi-tenant oncology literature search, feed, and collaboration platform. Built with FastAPI + Vue 3 + PostgreSQL. Includes PubMed pipeline, drug approvals, AI summaries, and systematic review tools.
58 lines
2.2 KiB
Vue
58 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted, watch, nextTick } from 'vue'
|
|
import { NCard, NSkeleton, NPagination, NInput, useMessage } from 'naive-ui'
|
|
import { api } from '../../api/client'
|
|
|
|
const message = useMessage()
|
|
const journals = ref<any[]>([])
|
|
const loading = ref(true)
|
|
const page = ref(1)
|
|
const pageSize = ref(50)
|
|
const total = ref(0)
|
|
const q = ref('')
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
try {
|
|
const { data } = await api.get('/admin/journals', { params: { page: page.value, page_size: pageSize.value, q: q.value || undefined } })
|
|
journals.value = data.items || []
|
|
total.value = data.total || 0
|
|
} catch (e: any) {
|
|
message.error(e?.response?.data?.detail || '加载期刊失败')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
onMounted(load)
|
|
watch([page, pageSize], load)
|
|
|
|
async function onSearch() {
|
|
page.value = 1
|
|
await nextTick()
|
|
load()
|
|
}
|
|
|
|
const tierLabels: Record<string,string> = { '1':'🔴', '2':'🟠', '3':'🟡', '4':'⚪' }
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
|
|
<h2 style="margin:0">📰 期刊列表 ({{ total }})</h2>
|
|
<NInput v-model:value="q" placeholder="搜索期刊名称..." size="small" style="width:240px" clearable @keyup.enter="onSearch" @clear="onSearch" />
|
|
</div>
|
|
<NSkeleton v-if="loading" text :repeat="8" />
|
|
<NCard v-else size="small">
|
|
<div v-for="j in journals" :key="j.id" style="display:flex;align-items:center;padding:8px;border-bottom:1px solid var(--border-color);font-size:13px">
|
|
<span style="width:30px">{{ tierLabels[j.tier]||'' }}</span>
|
|
<span style="flex:1;font-weight:500">{{ j.name }}</span>
|
|
<span style="width:120px;font-size:11px;color:var(--text-muted)">{{ j.issn || '—' }}</span>
|
|
<span style="width:60px;text-align:right;font-weight:600" v-if="j.impact_factor">IF {{ j.impact_factor }}</span>
|
|
</div>
|
|
</NCard>
|
|
<div v-if="total > 0" style="display:flex;justify-content:center;margin-top:16px">
|
|
<NPagination v-model:page="page" :page-count="Math.ceil(total / pageSize)" :page-size="pageSize" @update:page-size="pageSize = $event; page = 1" :page-sizes="[20, 50, 100, 200]" show-size-picker />
|
|
</div>
|
|
</div>
|
|
</template>
|