899 lines
92 KiB
Plaintext
899 lines
92 KiB
Plaintext
import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/src/views/public/HomeView.vue?v=1");/* unplugin-vue-components disabled */import __unplugin_components_2 from "/src/components/literature/LiteraturePreviewDrawer.vue?t=1783728117686";
|
|||
|
|
import __unplugin_components_1 from "/src/components/literature/LiteratureCard.vue?t=1783728117686";
|
||
|
|
import __unplugin_components_0 from "/src/components/search/AdvancedSearchPanel.vue?t=1783728117686";
|
||
|
|
import { defineComponent as _defineComponent } from "/node_modules/.vite/deps/vue.js?v=3cfd8f60";
|
||
|
|
import { ref, computed, onMounted, onBeforeUnmount, watch } from "/node_modules/.vite/deps/vue.js?v=3cfd8f60";
|
||
|
|
import { useRouter, useRoute } from "/node_modules/.vite/deps/vue-router.js?v=3cfd8f60";
|
||
|
|
import { NButton, NEmpty, NIcon } from "/node_modules/.vite/deps/naive-ui.js?v=6ae179ec";
|
||
|
|
import { ChevronDownOutline, ChevronUpOutline, CloseCircleOutline, OptionsOutline, PersonAddOutline, RefreshOutline, SearchOutline } from "/node_modules/.vite/deps/@vicons_ionicons5.js?v=78995c2b";
|
||
|
|
import { api } from "/src/api/client.ts?t=1783728117686&v=1";
|
||
|
|
import { useAuthStore } from "/src/stores/auth.ts?t=1783728117686&v=1";
|
||
|
|
import { useToast } from "/src/composables/useToast.ts?v=1";
|
||
|
|
import { useLiteraturePreview } from "/src/composables/useLiteraturePreview.ts?v=1";
|
||
|
|
import PageSkeleton from "/src/components/common/PageSkeleton.vue?v=1";
|
||
|
|
const hotPageSize = 5;
|
||
|
|
const hotMaxPage = 6;
|
||
|
|
const _sfc_main = /* @__PURE__ */ _defineComponent({
|
||
|
|
__name: "HomeView",
|
||
|
|
setup(__props, { expose: __expose }) {
|
||
|
|
__expose();
|
||
|
|
const router = useRouter();
|
||
|
|
const route = useRoute();
|
||
|
|
const auth = useAuthStore();
|
||
|
|
const toast = useToast();
|
||
|
|
const searchParams = ref({
|
||
|
|
query: "",
|
||
|
|
field: "all",
|
||
|
|
tag_ids: [],
|
||
|
|
date_from: null,
|
||
|
|
date_to: null,
|
||
|
|
retracted: "",
|
||
|
|
negative_result: "",
|
||
|
|
precision_mode: "majr",
|
||
|
|
page: 1,
|
||
|
|
page_size: 20,
|
||
|
|
sort: "date"
|
||
|
|
});
|
||
|
|
const feedItems = ref([]);
|
||
|
|
const feedTotal = ref(0);
|
||
|
|
const loading = ref(false);
|
||
|
|
const searched = ref(false);
|
||
|
|
const platformStats = ref({ literature_total: 0, journal_total: 0, daily_avg_30d: 0 });
|
||
|
|
const statsLoading = ref(true);
|
||
|
|
const hotArticles = ref([]);
|
||
|
|
const hotPage = ref(1);
|
||
|
|
const hotTotal = ref(0);
|
||
|
|
const hotAvailablePages = computed(() => Math.min(hotMaxPage, Math.ceil(hotTotal.value / hotPageSize)));
|
||
|
|
async function loadHotArticles() {
|
||
|
|
try {
|
||
|
|
const { data } = await api.get("/public/hot-articles", { params: { page: hotPage.value, page_size: hotPageSize } });
|
||
|
|
hotArticles.value = data.items || [];
|
||
|
|
hotTotal.value = data.total || 0;
|
||
|
|
} catch (e) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function refreshHot() {
|
||
|
|
const max = Math.min(hotMaxPage, Math.ceil(hotTotal.value / hotPageSize) || 1);
|
||
|
|
hotPage.value = hotPage.value >= max ? 1 : hotPage.value + 1;
|
||
|
|
loadHotArticles();
|
||
|
|
}
|
||
|
|
async function loadStats() {
|
||
|
|
try {
|
||
|
|
const { data } = await api.get("/public/stats");
|
||
|
|
platformStats.value = data;
|
||
|
|
} catch (e) {
|
||
|
|
} finally {
|
||
|
|
statsLoading.value = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const allTags = ref([]);
|
||
|
|
const selectedTagIds = ref([]);
|
||
|
|
const showAllTags = ref(false);
|
||
|
|
const isMobile = ref(window.innerWidth < 768);
|
||
|
|
const showAdvanced = ref(false);
|
||
|
|
function onDocumentMouseDown(e) {
|
||
|
|
if (!showAdvanced.value) return;
|
||
|
|
if (!e.target?.closest(".adv-filter-panel")) {
|
||
|
|
showAdvanced.value = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const localQuery = ref("");
|
||
|
|
const { showPreview, previewPmid, openPreview: setPreviewPmid, closePreview } = useLiteraturePreview();
|
||
|
|
const saving = ref(/* @__PURE__ */ new Set());
|
||
|
|
const savedPmids = ref(/* @__PURE__ */ new Set());
|
||
|
|
const lastVisitStr = localStorage.getItem("home_last_visit");
|
||
|
|
const dividerIndex = computed(() => {
|
||
|
|
if (!lastVisitStr || !feedItems.value.length) return -1;
|
||
|
|
const lastDt = new Date(parseInt(lastVisitStr)).toLocaleDateString("sv");
|
||
|
|
const idx = feedItems.value.findIndex((item) => {
|
||
|
|
const d = item.pub_date?.slice(0, 10);
|
||
|
|
return d && d <= lastDt;
|
||
|
|
});
|
||
|
|
return idx > 0 ? idx : -1;
|
||
|
|
});
|
||
|
|
async function fetchData(resetPage = true) {
|
||
|
|
if (resetPage) searchParams.value.page = 1;
|
||
|
|
loading.value = true;
|
||
|
|
try {
|
||
|
|
const body = { page: searchParams.value.page, page_size: searchParams.value.page_size, sort: searchParams.value.sort };
|
||
|
|
if (searchParams.value.query) body.query = searchParams.value.query;
|
||
|
|
if (searchParams.value.field !== "all") body.field = searchParams.value.field;
|
||
|
|
if (searchParams.value.tag_ids.length) body.tag_ids = searchParams.value.tag_ids;
|
||
|
|
if (searchParams.value.date_from) body.date_from = searchParams.value.date_from;
|
||
|
|
if (searchParams.value.date_to) body.date_to = searchParams.value.date_to;
|
||
|
|
if (searchParams.value.retracted) body.retracted = searchParams.value.retracted;
|
||
|
|
if (searchParams.value.negative_result) body.negative_result = searchParams.value.negative_result;
|
||
|
|
if (searchParams.value.precision_mode) body.precision_mode = searchParams.value.precision_mode;
|
||
|
|
const { data } = await api.post("/features/search/advanced", body);
|
||
|
|
if (resetPage) {
|
||
|
|
feedItems.value = data.items || [];
|
||
|
|
} else {
|
||
|
|
feedItems.value.push(...data.items || []);
|
||
|
|
}
|
||
|
|
feedTotal.value = data.total || 0;
|
||
|
|
searched.value = true;
|
||
|
|
} catch (e) {
|
||
|
|
toast.apiError(e, "搜索文献失败,请重试");
|
||
|
|
} finally {
|
||
|
|
loading.value = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function toggleTag(tagId) {
|
||
|
|
const id = String(tagId);
|
||
|
|
const idx = selectedTagIds.value.indexOf(id);
|
||
|
|
if (idx >= 0) {
|
||
|
|
selectedTagIds.value.splice(idx, 1);
|
||
|
|
} else {
|
||
|
|
selectedTagIds.value.push(id);
|
||
|
|
}
|
||
|
|
searchParams.value.tag_ids = [...selectedTagIds.value];
|
||
|
|
fetchData();
|
||
|
|
}
|
||
|
|
const cancerTags = computed(() => allTags.value.filter((t) => t.tag_category === "cancer" && t.level === 2));
|
||
|
|
const hasMoreTags = computed(() => cancerTags.value.length > 7);
|
||
|
|
const visibleTags = computed(() => {
|
||
|
|
if (showAllTags.value) return cancerTags.value;
|
||
|
|
return cancerTags.value.slice(0, 7);
|
||
|
|
});
|
||
|
|
function doLocalSearch() {
|
||
|
|
showAdvanced.value = false;
|
||
|
|
searchParams.value.field = "all";
|
||
|
|
if (localQuery.value.trim()) {
|
||
|
|
searchParams.value.query = localQuery.value;
|
||
|
|
} else {
|
||
|
|
searchParams.value.query = "";
|
||
|
|
}
|
||
|
|
fetchData();
|
||
|
|
}
|
||
|
|
function clearSearch() {
|
||
|
|
localQuery.value = "";
|
||
|
|
searchParams.value = {
|
||
|
|
query: "",
|
||
|
|
field: "all",
|
||
|
|
tag_ids: [],
|
||
|
|
date_from: null,
|
||
|
|
date_to: null,
|
||
|
|
retracted: "",
|
||
|
|
negative_result: "",
|
||
|
|
precision_mode: "majr",
|
||
|
|
page: 1,
|
||
|
|
page_size: 20,
|
||
|
|
sort: "date"
|
||
|
|
};
|
||
|
|
selectedTagIds.value = [];
|
||
|
|
showAdvanced.value = false;
|
||
|
|
fetchData();
|
||
|
|
}
|
||
|
|
function handleAdvancedSearch(params) {
|
||
|
|
searchParams.value.query = params.query;
|
||
|
|
searchParams.value.field = params.field;
|
||
|
|
searchParams.value.date_from = params.date_from;
|
||
|
|
searchParams.value.date_to = params.date_to;
|
||
|
|
searchParams.value.tag_ids = params.tag_ids;
|
||
|
|
searchParams.value.retracted = params.retracted;
|
||
|
|
searchParams.value.negative_result = params.negative_result;
|
||
|
|
selectedTagIds.value = [...params.tag_ids];
|
||
|
|
showAdvanced.value = false;
|
||
|
|
fetchData();
|
||
|
|
}
|
||
|
|
async function saveLiterature(item) {
|
||
|
|
if (!auth.isAuthenticated) {
|
||
|
|
router.push("/auth/login");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (saving.value.has(item.pmid) || savedPmids.value.has(item.pmid)) return;
|
||
|
|
saving.value = new Set(saving.value).add(item.pmid);
|
||
|
|
try {
|
||
|
|
await api.post(`/literature/${item.pmid}/save`);
|
||
|
|
savedPmids.value = new Set(savedPmids.value).add(item.pmid);
|
||
|
|
toast.success("已收藏");
|
||
|
|
} catch (e) {
|
||
|
|
toast.apiError(e, "收藏文献失败,请重试");
|
||
|
|
} finally {
|
||
|
|
const s = new Set(saving.value);
|
||
|
|
s.delete(item.pmid);
|
||
|
|
saving.value = s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function openPreview(item) {
|
||
|
|
if (item.pmid) setPreviewPmid(item.pmid);
|
||
|
|
}
|
||
|
|
function goDetail(item) {
|
||
|
|
closePreview();
|
||
|
|
const q = searchParams.value.query;
|
||
|
|
router.push(q ? `/literature/${item.pmid}?q=${encodeURIComponent(q)}` : `/literature/${item.pmid}`);
|
||
|
|
}
|
||
|
|
async function loadSavedPmids() {
|
||
|
|
if (!auth.isAuthenticated) return;
|
||
|
|
try {
|
||
|
|
const { data } = await api.get("/literature/saved");
|
||
|
|
savedPmids.value = new Set((data.items || []).map((i) => i.pmid));
|
||
|
|
} catch (e) {
|
||
|
|
toast.apiError(e, "加载收藏状态失败");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const loadingMore = ref(false);
|
||
|
|
const hasMore = computed(() => feedItems.value.length < feedTotal.value);
|
||
|
|
const showScrollTop = ref(false);
|
||
|
|
function onScroll() {
|
||
|
|
showScrollTop.value = window.scrollY > window.innerHeight;
|
||
|
|
}
|
||
|
|
function scrollToTop() {
|
||
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||
|
|
}
|
||
|
|
function onResize() {
|
||
|
|
isMobile.value = window.innerWidth < 768;
|
||
|
|
}
|
||
|
|
async function loadMore() {
|
||
|
|
if (loadingMore.value || !hasMore.value) return;
|
||
|
|
loadingMore.value = true;
|
||
|
|
searchParams.value.page++;
|
||
|
|
try {
|
||
|
|
const body = { page: searchParams.value.page, page_size: searchParams.value.page_size, sort: searchParams.value.sort };
|
||
|
|
if (searchParams.value.query) body.query = searchParams.value.query;
|
||
|
|
if (searchParams.value.field !== "all") body.field = searchParams.value.field;
|
||
|
|
if (searchParams.value.tag_ids.length) body.tag_ids = searchParams.value.tag_ids;
|
||
|
|
if (searchParams.value.date_from) body.date_from = searchParams.value.date_from;
|
||
|
|
if (searchParams.value.date_to) body.date_to = searchParams.value.date_to;
|
||
|
|
if (searchParams.value.retracted) body.retracted = searchParams.value.retracted;
|
||
|
|
if (searchParams.value.negative_result) body.negative_result = searchParams.value.negative_result;
|
||
|
|
if (searchParams.value.precision_mode) body.precision_mode = searchParams.value.precision_mode;
|
||
|
|
const { data } = await api.post("/features/search/advanced", body);
|
||
|
|
feedItems.value.push(...data.items || []);
|
||
|
|
feedTotal.value = data.total || 0;
|
||
|
|
} catch (e) {
|
||
|
|
toast.apiError(e, "加载更多失败,请重试");
|
||
|
|
} finally {
|
||
|
|
loadingMore.value = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function restoreFromUrl() {
|
||
|
|
const tag = route.query.tag;
|
||
|
|
const date = route.query.date;
|
||
|
|
const q = route.query.q;
|
||
|
|
if (tag) {
|
||
|
|
const ids = tag.split(",");
|
||
|
|
selectedTagIds.value = ids;
|
||
|
|
searchParams.value.tag_ids = ids;
|
||
|
|
}
|
||
|
|
if (date) {
|
||
|
|
searchParams.value.date_from = date;
|
||
|
|
searchParams.value.date_to = date;
|
||
|
|
}
|
||
|
|
if (q) {
|
||
|
|
searchParams.value.query = q;
|
||
|
|
localQuery.value = q;
|
||
|
|
}
|
||
|
|
const p = route.query.page;
|
||
|
|
if (p) {
|
||
|
|
searchParams.value.page = parseInt(p) || 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const searchKey = computed(
|
||
|
|
() => JSON.stringify([searchParams.value.query, searchParams.value.tag_ids, searchParams.value.date_from, searchParams.value.date_to, searchParams.value.page, searchParams.value.sort])
|
||
|
|
);
|
||
|
|
watch(searchKey, () => {
|
||
|
|
const query = {};
|
||
|
|
if (searchParams.value.tag_ids.length) query.tag = searchParams.value.tag_ids.join(",");
|
||
|
|
if (searchParams.value.date_from) query.date = searchParams.value.date_from;
|
||
|
|
if (searchParams.value.query) query.q = searchParams.value.query;
|
||
|
|
router.replace({ query });
|
||
|
|
});
|
||
|
|
watch(() => route.query, (q) => {
|
||
|
|
if (q && q._t) {
|
||
|
|
clearSearch();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
onMounted(async () => {
|
||
|
|
restoreFromUrl();
|
||
|
|
loadStats();
|
||
|
|
loadHotArticles();
|
||
|
|
try {
|
||
|
|
const { data } = await api.get("/public/tags");
|
||
|
|
allTags.value = data.tags || [];
|
||
|
|
} catch (e) {
|
||
|
|
toast.apiError(e, "加载标签失败");
|
||
|
|
}
|
||
|
|
await fetchData();
|
||
|
|
await loadSavedPmids();
|
||
|
|
localStorage.setItem("home_last_visit", String(Date.now()));
|
||
|
|
window.addEventListener("scroll", onScroll);
|
||
|
|
window.addEventListener("resize", onResize);
|
||
|
|
document.addEventListener("mousedown", onDocumentMouseDown);
|
||
|
|
});
|
||
|
|
onBeforeUnmount(() => {
|
||
|
|
window.removeEventListener("scroll", onScroll);
|
||
|
|
window.removeEventListener("resize", onResize);
|
||
|
|
document.removeEventListener("mousedown", onDocumentMouseDown);
|
||
|
|
});
|
||
|
|
const __returned__ = { router, route, auth, toast, searchParams, feedItems, feedTotal, loading, searched, platformStats, statsLoading, hotArticles, hotPage, hotPageSize, hotTotal, hotMaxPage, hotAvailablePages, loadHotArticles, refreshHot, loadStats, allTags, selectedTagIds, showAllTags, isMobile, showAdvanced, onDocumentMouseDown, localQuery, showPreview, previewPmid, setPreviewPmid, closePreview, saving, savedPmids, lastVisitStr, dividerIndex, fetchData, toggleTag, cancerTags, hasMoreTags, visibleTags, doLocalSearch, clearSearch, handleAdvancedSearch, saveLiterature, openPreview, goDetail, loadSavedPmids, loadingMore, hasMore, showScrollTop, onScroll, scrollToTop, onResize, loadMore, restoreFromUrl, searchKey, get NButton() {
|
||
|
|
return NButton;
|
||
|
|
}, get NEmpty() {
|
||
|
|
return NEmpty;
|
||
|
|
}, get NIcon() {
|
||
|
|
return NIcon;
|
||
|
|
}, get ChevronDownOutline() {
|
||
|
|
return ChevronDownOutline;
|
||
|
|
}, get ChevronUpOutline() {
|
||
|
|
return ChevronUpOutline;
|
||
|
|
}, get CloseCircleOutline() {
|
||
|
|
return CloseCircleOutline;
|
||
|
|
}, get OptionsOutline() {
|
||
|
|
return OptionsOutline;
|
||
|
|
}, get PersonAddOutline() {
|
||
|
|
return PersonAddOutline;
|
||
|
|
}, get RefreshOutline() {
|
||
|
|
return RefreshOutline;
|
||
|
|
}, get SearchOutline() {
|
||
|
|
return SearchOutline;
|
||
|
|
}, PageSkeleton };
|
||
|
|
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
||
|
|
return __returned__;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
import { createElementVNode as _createElementVNode, createCommentVNode as _createCommentVNode, vModelText as _vModelText, withKeys as _withKeys, withDirectives as _withDirectives, createVNode as _createVNode, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, createTextVNode as _createTextVNode, resolveComponent as _resolveComponent, renderList as _renderList, Fragment as _Fragment, createElementBlock as _createElementBlock, toDisplayString as _toDisplayString, normalizeClass as _normalizeClass } from "/node_modules/.vite/deps/vue.js?v=3cfd8f60";
|
||
|
|
const _hoisted_1 = { class: "home" };
|
||
|
|
const _hoisted_2 = { class: "content-grid" };
|
||
|
|
const _hoisted_3 = { class: "content-grid-main" };
|
||
|
|
const _hoisted_4 = { class: "section section-toolbar" };
|
||
|
|
const _hoisted_5 = { class: "search-row" };
|
||
|
|
const _hoisted_6 = { class: "search-row-left" };
|
||
|
|
const _hoisted_7 = { class: "search-input-group" };
|
||
|
|
const _hoisted_8 = { class: "search-input-top" };
|
||
|
|
const _hoisted_9 = { class: "search-input-actions" };
|
||
|
|
const _hoisted_10 = {
|
||
|
|
key: 0,
|
||
|
|
class: "section"
|
||
|
|
};
|
||
|
|
const _hoisted_11 = { class: "tag-bar" };
|
||
|
|
const _hoisted_12 = ["onClick"];
|
||
|
|
const _hoisted_13 = {
|
||
|
|
key: 0,
|
||
|
|
class: "tag-x"
|
||
|
|
};
|
||
|
|
const _hoisted_14 = { class: "section section-list" };
|
||
|
|
const _hoisted_15 = {
|
||
|
|
key: 0,
|
||
|
|
class: "read-divider"
|
||
|
|
};
|
||
|
|
const _hoisted_16 = {
|
||
|
|
key: 0,
|
||
|
|
class: "load-more"
|
||
|
|
};
|
||
|
|
const _hoisted_17 = { class: "content-grid-side" };
|
||
|
|
const _hoisted_18 = {
|
||
|
|
key: 0,
|
||
|
|
class: "section-hot-side"
|
||
|
|
};
|
||
|
|
const _hoisted_19 = { class: "hot-header" };
|
||
|
|
const _hoisted_20 = { class: "hot-header-right" };
|
||
|
|
const _hoisted_21 = { class: "hot-page-dots" };
|
||
|
|
const _hoisted_22 = { class: "hot-list" };
|
||
|
|
const _hoisted_23 = ["href"];
|
||
|
|
const _hoisted_24 = { class: "hot-content" };
|
||
|
|
const _hoisted_25 = ["title"];
|
||
|
|
const _hoisted_26 = { class: "hot-meta" };
|
||
|
|
const _hoisted_27 = {
|
||
|
|
key: 1,
|
||
|
|
class: "sidebar-stats"
|
||
|
|
};
|
||
|
|
const _hoisted_28 = { class: "sidebar-stat-item" };
|
||
|
|
const _hoisted_29 = { class: "sidebar-stat-num" };
|
||
|
|
const _hoisted_30 = { class: "sidebar-stat-item" };
|
||
|
|
const _hoisted_31 = { class: "sidebar-stat-num" };
|
||
|
|
const _hoisted_32 = { class: "sidebar-stat-item" };
|
||
|
|
const _hoisted_33 = { class: "sidebar-stat-num" };
|
||
|
|
const _hoisted_34 = {
|
||
|
|
key: 0,
|
||
|
|
class: "section section-cta"
|
||
|
|
};
|
||
|
|
const _hoisted_35 = { class: "cta-banner" };
|
||
|
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||
|
|
const _component_AdvancedSearchPanel = __unplugin_components_0;
|
||
|
|
const _component_LiteratureCard = __unplugin_components_1;
|
||
|
|
const _component_LiteraturePreviewDrawer = __unplugin_components_2;
|
||
|
|
return _openBlock(), _createElementBlock("div", _hoisted_1, [
|
||
|
|
_cache[18] || (_cache[18] = _createElementVNode(
|
||
|
|
"h1",
|
||
|
|
{ class: "visually-hidden" },
|
||
|
|
"OncoLit 肿瘤科研文献中心——每日更新的肿瘤学文献平台",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
_createCommentVNode(" ====== 内容网格:左侧(搜索 + 标签 + 文献)+ 右侧(热榜) ====== "),
|
||
|
|
_createElementVNode("div", _hoisted_2, [
|
||
|
|
_createElementVNode("div", _hoisted_3, [
|
||
|
|
_createCommentVNode(" 搜索工具栏 "),
|
||
|
|
_createElementVNode("section", _hoisted_4, [
|
||
|
|
_createElementVNode("div", _hoisted_5, [
|
||
|
|
_createElementVNode("div", _hoisted_6, [
|
||
|
|
_createElementVNode("div", _hoisted_7, [
|
||
|
|
_createElementVNode("div", _hoisted_8, [
|
||
|
|
_withDirectives(_createElementVNode(
|
||
|
|
"input",
|
||
|
|
{
|
||
|
|
class: "search-input",
|
||
|
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.localQuery = $event),
|
||
|
|
placeholder: "搜索标题、摘要、PMID、DOI...",
|
||
|
|
onKeyup: _withKeys($setup.doLocalSearch, ["enter"])
|
||
|
|
},
|
||
|
|
null,
|
||
|
|
544
|
||
|
|
/* NEED_HYDRATION, NEED_PATCH */
|
||
|
|
), [
|
||
|
|
[_vModelText, $setup.localQuery]
|
||
|
|
]),
|
||
|
|
$setup.localQuery ? (_openBlock(), _createBlock($setup["NButton"], {
|
||
|
|
key: 0,
|
||
|
|
text: "",
|
||
|
|
size: "tiny",
|
||
|
|
onClick: $setup.clearSearch,
|
||
|
|
class: "clear-search-btn",
|
||
|
|
title: "清除搜索"
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "16" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["CloseCircleOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})) : _createCommentVNode("v-if", true)
|
||
|
|
]),
|
||
|
|
_createElementVNode("div", _hoisted_9, [
|
||
|
|
_createVNode($setup["NButton"], {
|
||
|
|
text: "",
|
||
|
|
size: "tiny",
|
||
|
|
onClick: _cache[1] || (_cache[1] = ($event) => $setup.showAdvanced = !$setup.showAdvanced),
|
||
|
|
title: $setup.showAdvanced ? "收起筛选" : "高级搜索",
|
||
|
|
class: "adv-icon-btn"
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "16" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["OptionsOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
}, 8, ["title"]),
|
||
|
|
_createVNode($setup["NButton"], {
|
||
|
|
size: "small",
|
||
|
|
type: "primary",
|
||
|
|
onClick: $setup.doLocalSearch,
|
||
|
|
class: "sky-btn search-submit-btn"
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "14" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["SearchOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_cache[5] || (_cache[5] = _createTextVNode(
|
||
|
|
"搜索 ",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
])
|
||
|
|
])
|
||
|
|
])
|
||
|
|
]),
|
||
|
|
_createVNode(_component_AdvancedSearchPanel, {
|
||
|
|
show: $setup.showAdvanced,
|
||
|
|
loading: $setup.loading,
|
||
|
|
onSearch: $setup.handleAdvancedSearch
|
||
|
|
}, null, 8, ["show", "loading"])
|
||
|
|
]),
|
||
|
|
_createCommentVNode(" 热门标签快速筛选 "),
|
||
|
|
$setup.cancerTags.length ? (_openBlock(), _createElementBlock("section", _hoisted_10, [
|
||
|
|
_createElementVNode("div", _hoisted_11, [
|
||
|
|
_cache[8] || (_cache[8] = _createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "tag-label" },
|
||
|
|
"热门",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
(_openBlock(true), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
null,
|
||
|
|
_renderList($setup.visibleTags, (t) => {
|
||
|
|
return _openBlock(), _createElementBlock("span", {
|
||
|
|
key: t.id,
|
||
|
|
class: _normalizeClass(["tag-pill", { active: $setup.selectedTagIds.includes(String(t.id)) }]),
|
||
|
|
onClick: ($event) => $setup.toggleTag(t.id)
|
||
|
|
}, [
|
||
|
|
_createTextVNode(
|
||
|
|
_toDisplayString(t.name_zh),
|
||
|
|
1
|
||
|
|
/* TEXT */
|
||
|
|
),
|
||
|
|
$setup.selectedTagIds.includes(String(t.id)) ? (_openBlock(), _createElementBlock("span", _hoisted_13, "✕")) : _createCommentVNode("v-if", true)
|
||
|
|
], 10, _hoisted_12);
|
||
|
|
}),
|
||
|
|
128
|
||
|
|
/* KEYED_FRAGMENT */
|
||
|
|
)),
|
||
|
|
$setup.hasMoreTags && !$setup.showAllTags ? (_openBlock(), _createElementBlock("span", {
|
||
|
|
key: 0,
|
||
|
|
class: "tag-expand-btn",
|
||
|
|
onClick: _cache[2] || (_cache[2] = ($event) => $setup.showAllTags = true)
|
||
|
|
}, [
|
||
|
|
_cache[6] || (_cache[6] = _createTextVNode(
|
||
|
|
"更多 ",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
_createVNode($setup["NIcon"], {
|
||
|
|
size: "13",
|
||
|
|
style: { "vertical-align": "-2px" }
|
||
|
|
}, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["ChevronDownOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
])) : _createCommentVNode("v-if", true),
|
||
|
|
$setup.showAllTags ? (_openBlock(), _createElementBlock("span", {
|
||
|
|
key: 1,
|
||
|
|
class: "tag-expand-btn",
|
||
|
|
onClick: _cache[3] || (_cache[3] = ($event) => $setup.showAllTags = false)
|
||
|
|
}, [
|
||
|
|
_cache[7] || (_cache[7] = _createTextVNode(
|
||
|
|
"收起 ",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
_createVNode($setup["NIcon"], {
|
||
|
|
size: "13",
|
||
|
|
style: { "vertical-align": "-2px" }
|
||
|
|
}, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["ChevronUpOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
])) : _createCommentVNode("v-if", true)
|
||
|
|
])
|
||
|
|
])) : _createCommentVNode("v-if", true),
|
||
|
|
_createCommentVNode(" 文献列表 "),
|
||
|
|
_createElementVNode("section", _hoisted_14, [
|
||
|
|
_createVNode($setup["PageSkeleton"], {
|
||
|
|
loading: $setup.loading && !$setup.feedItems.length
|
||
|
|
}, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
!$setup.loading && !$setup.feedItems.length ? (_openBlock(), _createBlock($setup["NEmpty"], {
|
||
|
|
key: 0,
|
||
|
|
description: "暂无文献"
|
||
|
|
})) : _createCommentVNode("v-if", true),
|
||
|
|
$setup.feedItems.length ? (_openBlock(), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
{ key: 1 },
|
||
|
|
[
|
||
|
|
(_openBlock(true), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
null,
|
||
|
|
_renderList($setup.feedItems, (item, idx) => {
|
||
|
|
return _openBlock(), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
{
|
||
|
|
key: item.id || item.pmid
|
||
|
|
},
|
||
|
|
[
|
||
|
|
idx === $setup.dividerIndex ? (_openBlock(), _createElementBlock("div", _hoisted_15, [..._cache[9] || (_cache[9] = [
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "read-divider-line" },
|
||
|
|
null,
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
),
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "read-divider-text" },
|
||
|
|
"—— 上次看到这里 ——",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
),
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "read-divider-line" },
|
||
|
|
null,
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)
|
||
|
|
])])) : _createCommentVNode("v-if", true),
|
||
|
|
_createVNode(_component_LiteratureCard, {
|
||
|
|
item,
|
||
|
|
showSave: $setup.auth.isAuthenticated,
|
||
|
|
savedPmids: $setup.savedPmids,
|
||
|
|
searchQuery: $setup.searchParams.query,
|
||
|
|
onDetail: $setup.goDetail,
|
||
|
|
onPreview: $setup.openPreview,
|
||
|
|
onSave: $setup.saveLiterature
|
||
|
|
}, null, 8, ["item", "showSave", "savedPmids", "searchQuery"])
|
||
|
|
],
|
||
|
|
64
|
||
|
|
/* STABLE_FRAGMENT */
|
||
|
|
);
|
||
|
|
}),
|
||
|
|
128
|
||
|
|
/* KEYED_FRAGMENT */
|
||
|
|
)),
|
||
|
|
$setup.hasMore ? (_openBlock(), _createElementBlock("div", _hoisted_16, [
|
||
|
|
_createVNode($setup["NButton"], {
|
||
|
|
class: "sky-btn",
|
||
|
|
loading: $setup.loadingMore,
|
||
|
|
onClick: $setup.loadMore,
|
||
|
|
size: "small"
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "14" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["ChevronDownOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_cache[10] || (_cache[10] = _createTextVNode(
|
||
|
|
"展示更多",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
}, 8, ["loading"])
|
||
|
|
])) : _createCommentVNode("v-if", true)
|
||
|
|
],
|
||
|
|
64
|
||
|
|
/* STABLE_FRAGMENT */
|
||
|
|
)) : _createCommentVNode("v-if", true)
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
}, 8, ["loading"])
|
||
|
|
])
|
||
|
|
]),
|
||
|
|
_createElementVNode("div", _hoisted_17, [
|
||
|
|
$setup.hotArticles.length ? (_openBlock(), _createElementBlock("section", _hoisted_18, [
|
||
|
|
_createElementVNode("div", _hoisted_19, [
|
||
|
|
_cache[12] || (_cache[12] = _createElementVNode(
|
||
|
|
"span",
|
||
|
|
null,
|
||
|
|
"🔥 热搜",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
_createElementVNode("div", _hoisted_20, [
|
||
|
|
_createElementVNode("span", _hoisted_21, [
|
||
|
|
(_openBlock(true), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
null,
|
||
|
|
_renderList($setup.hotAvailablePages, (p) => {
|
||
|
|
return _openBlock(), _createElementBlock(
|
||
|
|
"span",
|
||
|
|
{
|
||
|
|
key: p,
|
||
|
|
class: _normalizeClass(["hot-page-dot", { active: $setup.hotPage === p }])
|
||
|
|
},
|
||
|
|
null,
|
||
|
|
2
|
||
|
|
/* CLASS */
|
||
|
|
);
|
||
|
|
}),
|
||
|
|
128
|
||
|
|
/* KEYED_FRAGMENT */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_createVNode($setup["NButton"], {
|
||
|
|
text: "",
|
||
|
|
size: "tiny",
|
||
|
|
style: { "font-size": "12px", "color": "var(--text-muted)" },
|
||
|
|
onClick: $setup.refreshHot
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "12" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["RefreshOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_cache[11] || (_cache[11] = _createTextVNode(
|
||
|
|
"换一批 ",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
])
|
||
|
|
]),
|
||
|
|
_createElementVNode("div", _hoisted_22, [
|
||
|
|
(_openBlock(true), _createElementBlock(
|
||
|
|
_Fragment,
|
||
|
|
null,
|
||
|
|
_renderList($setup.hotArticles, (art, i) => {
|
||
|
|
return _openBlock(), _createElementBlock("a", {
|
||
|
|
key: art.id,
|
||
|
|
class: "hot-item",
|
||
|
|
href: `/literature/${art.pmid}`
|
||
|
|
}, [
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
{
|
||
|
|
class: _normalizeClass(["hot-rank", { "hot-rank-top": ($setup.hotPage - 1) * $setup.hotPageSize + i + 1 <= 3 }])
|
||
|
|
},
|
||
|
|
_toDisplayString(($setup.hotPage - 1) * $setup.hotPageSize + i + 1),
|
||
|
|
3
|
||
|
|
/* TEXT, CLASS */
|
||
|
|
),
|
||
|
|
_createElementVNode("div", _hoisted_24, [
|
||
|
|
_createElementVNode("span", {
|
||
|
|
class: "hot-title",
|
||
|
|
title: art.title
|
||
|
|
}, _toDisplayString(art.title), 9, _hoisted_25),
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
_hoisted_26,
|
||
|
|
_toDisplayString(art.journal) + " · " + _toDisplayString(art.cited_by_count ?? 0) + " 被引",
|
||
|
|
1
|
||
|
|
/* TEXT */
|
||
|
|
)
|
||
|
|
])
|
||
|
|
], 8, _hoisted_23);
|
||
|
|
}),
|
||
|
|
128
|
||
|
|
/* KEYED_FRAGMENT */
|
||
|
|
))
|
||
|
|
])
|
||
|
|
])) : _createCommentVNode("v-if", true),
|
||
|
|
!$setup.statsLoading && $setup.platformStats.literature_total > 0 ? (_openBlock(), _createElementBlock("div", _hoisted_27, [
|
||
|
|
_createElementVNode("div", _hoisted_28, [
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
_hoisted_29,
|
||
|
|
_toDisplayString($setup.platformStats.literature_total.toLocaleString()),
|
||
|
|
1
|
||
|
|
/* TEXT */
|
||
|
|
),
|
||
|
|
_cache[13] || (_cache[13] = _createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "sidebar-stat-label" },
|
||
|
|
"文献总量",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_createElementVNode("div", _hoisted_30, [
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
_hoisted_31,
|
||
|
|
_toDisplayString($setup.platformStats.journal_total),
|
||
|
|
1
|
||
|
|
/* TEXT */
|
||
|
|
),
|
||
|
|
_cache[14] || (_cache[14] = _createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "sidebar-stat-label" },
|
||
|
|
"收录期刊",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_createElementVNode("div", _hoisted_32, [
|
||
|
|
_createElementVNode(
|
||
|
|
"span",
|
||
|
|
_hoisted_33,
|
||
|
|
_toDisplayString($setup.platformStats.daily_avg_30d.toFixed(1)),
|
||
|
|
1
|
||
|
|
/* TEXT */
|
||
|
|
),
|
||
|
|
_cache[15] || (_cache[15] = _createElementVNode(
|
||
|
|
"span",
|
||
|
|
{ class: "sidebar-stat-label" },
|
||
|
|
"日均新增",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
])
|
||
|
|
])) : _createCommentVNode("v-if", true)
|
||
|
|
])
|
||
|
|
]),
|
||
|
|
_createCommentVNode(" ====== 注册引导 CTA(未登录) ====== "),
|
||
|
|
!$setup.auth.isAuthenticated && $setup.feedItems.length > 3 ? (_openBlock(), _createElementBlock("section", _hoisted_34, [
|
||
|
|
_createElementVNode("div", _hoisted_35, [
|
||
|
|
_cache[17] || (_cache[17] = _createElementVNode(
|
||
|
|
"div",
|
||
|
|
{ class: "cta-text" },
|
||
|
|
[
|
||
|
|
_createElementVNode("div", { class: "cta-title" }, "🔒 注册后获得完整功能"),
|
||
|
|
_createElementVNode("div", { class: "cta-desc" }, "收藏文献 · 设置关注领域 · 每日精准推送 · 团队共享")
|
||
|
|
],
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
)),
|
||
|
|
_createVNode($setup["NButton"], {
|
||
|
|
class: "sky-btn",
|
||
|
|
type: "primary",
|
||
|
|
size: "large",
|
||
|
|
onClick: _cache[4] || (_cache[4] = ($event) => $setup.router.push("/auth/register"))
|
||
|
|
}, {
|
||
|
|
icon: _withCtx(() => [
|
||
|
|
_createVNode($setup["NIcon"], { size: "14" }, {
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_createVNode($setup["PersonAddOutline"])
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
]),
|
||
|
|
default: _withCtx(() => [
|
||
|
|
_cache[16] || (_cache[16] = _createTextVNode(
|
||
|
|
"免费注册",
|
||
|
|
-1
|
||
|
|
/* CACHED */
|
||
|
|
))
|
||
|
|
]),
|
||
|
|
_: 1
|
||
|
|
/* STABLE */
|
||
|
|
})
|
||
|
|
])
|
||
|
|
])) : _createCommentVNode("v-if", true),
|
||
|
|
_createCommentVNode(" ====== 文献预览抽屉 ====== "),
|
||
|
|
_createVNode(_component_LiteraturePreviewDrawer, {
|
||
|
|
show: $setup.showPreview,
|
||
|
|
pmid: $setup.previewPmid,
|
||
|
|
onClose: $setup.closePreview,
|
||
|
|
onGoDetail: $setup.goDetail
|
||
|
|
}, null, 8, ["show", "pmid", "onClose"]),
|
||
|
|
_createCommentVNode(" 回到顶部 "),
|
||
|
|
$setup.showScrollTop ? (_openBlock(), _createElementBlock("button", {
|
||
|
|
key: 1,
|
||
|
|
class: "scroll-top",
|
||
|
|
onClick: $setup.scrollToTop
|
||
|
|
}, "↑")) : _createCommentVNode("v-if", true)
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
import "/src/views/public/HomeView.vue?v=1&vue&type=style&index=0&scoped=790ec39d&lang.css";
|
||
|
|
_sfc_main.__hmrId = "790ec39d";
|
||
|
|
typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main);
|
||
|
|
import.meta.hot.on("file-changed", ({ file }) => {
|
||
|
|
__VUE_HMR_RUNTIME__.CHANGED_FILE = file;
|
||
|
|
});
|
||
|
|
import.meta.hot.accept((mod) => {
|
||
|
|
if (!mod) return;
|
||
|
|
const { default: updated, _rerender_only } = mod;
|
||
|
|
if (_rerender_only) {
|
||
|
|
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render);
|
||
|
|
} else {
|
||
|
|
__VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
import _export_sfc from "/@id/__x00__plugin-vue:export-helper";
|
||
|
|
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-790ec39d"], ["__file", "D:/ClaudeCode/frontend/src/views/public/HomeView.vue"]]);
|
||
|
|
|
||
|
|
//# sourceMappingURL=data:application/json;base64,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
|