feat(api): 添加多路由代理处理实现

- 新增api目录下多个接口路径代理处理文件,支持动态拼接目标URL
- 根据环境变量选择不同的后端服务地址(如dev和生产环境)
- 统一添加TenantId和Authorization请求头传递租户及身份信息
- 实现请求参数及搜索参数的完整转发
- 引入better-sqlite3及node内建模块支持服务端功能
- 新增专家详情页面,实现文章、成果及预约咨询功能展示
- 页面实现加载骨架屏、标签页切换及空状态提示优化体验
This commit is contained in:
2026-04-28 13:50:27 +08:00
parent 3edf4f0124
commit 528fe28ffc
399 changed files with 53320 additions and 0 deletions

View File

@@ -0,0 +1,372 @@
import { defineComponent, ref, computed, watch, resolveComponent, mergeProps, withCtx, unref, createVNode, createBlock, toDisplayString, openBlock, Fragment, renderList, isRef, createCommentVNode, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderStyle, ssrInterpolate, ssrRenderComponent, ssrRenderList, ssrRenderClass, ssrRenderAttr } from 'vue/server-renderer';
import { message } from 'ant-design-vue';
import { a as _export_sfc, e as useRoute, d as useRouter } from './server.mjs';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "ArticleListPage",
__ssrInlineRender: true,
props: {
config: {}
},
setup(__props) {
const props = __props;
const route = useRoute();
const router = useRouter();
const activeType = ref(route.query.type || "");
const currentPage = ref(1);
const pageSize = ref(12);
const total = ref(0);
const loading = ref(false);
const articles = ref([]);
const currentCategoryLabel = computed(() => {
if (!activeType.value) return "全部文章";
const found = props.config.categories.find((c) => c.type === activeType.value);
return found?.label || "全部文章";
});
function getCategoryLabel(type) {
const found = props.config.categories.find((c) => c.type === type);
return found?.label || type;
}
function selectType(type) {
activeType.value = type;
currentPage.value = 1;
router.replace({ query: type ? { type } : {} });
loadArticles();
}
async function loadArticles() {
loading.value = true;
try {
total.value = 35;
articles.value = Array.from({ length: Math.min(pageSize.value, 35 - (currentPage.value - 1) * pageSize.value) }, (_, i) => ({
id: (currentPage.value - 1) * pageSize.value + i + 1,
title: `${currentCategoryLabel.value}文章标题 ${(currentPage.value - 1) * pageSize.value + i + 1}:广西政策研究成果发布`,
overview: "摘要内容:本文就广西经济社会发展中的若干重大问题进行深入研究,提出了切实可行的政策建议和对策措施,为相关决策提供参考依据...",
image: `https://picsum.photos/200/130?random=${(currentPage.value - 1) * pageSize.value + i + 1}`,
source: "广西决策咨询中心",
publishTime: `2024-12-${String(20 - i).padStart(2, "0")}`,
views: Math.floor(Math.random() * 2e3) + 100,
type: activeType.value || props.config.categories[i % props.config.categories.length]?.type
}));
} catch (e) {
message.error("加载失败");
} finally {
loading.value = false;
}
}
function handlePageChange(page) {
currentPage.value = page;
loadArticles();
(void 0).scrollTo({ top: 0, behavior: "smooth" });
}
function handleView(article) {
router.push(`/article/${article.id}`);
}
watch(() => route.query.type, (newType) => {
activeType.value = newType || "";
currentPage.value = 1;
loadArticles();
});
return (_ctx, _push, _parent, _attrs) => {
const _component_a_row = resolveComponent("a-row");
const _component_a_col = resolveComponent("a-col");
const _component_a_skeleton = resolveComponent("a-skeleton");
const _component_a_empty = resolveComponent("a-empty");
const _component_a_pagination = resolveComponent("a-pagination");
_push(`<div${ssrRenderAttrs(mergeProps({ class: "list-page" }, _attrs))} data-v-adab0af3><div class="page-banner" style="${ssrRenderStyle({ background: __props.config.bannerGradient })}" data-v-adab0af3><div class="mx-auto max-w-screen-xl px-4" data-v-adab0af3><h1 class="banner-title" data-v-adab0af3>${ssrInterpolate(__props.config.title)}</h1><p class="banner-desc" data-v-adab0af3>${ssrInterpolate(__props.config.desc)}</p></div></div><div class="mx-auto max-w-screen-xl px-4 py-8" data-v-adab0af3>`);
_push(ssrRenderComponent(_component_a_row, { gutter: [32, 0] }, {
default: withCtx((_, _push2, _parent2, _scopeId) => {
if (_push2) {
_push2(ssrRenderComponent(_component_a_col, {
xs: 24,
lg: 5,
class: "mb-6 lg:mb-0"
}, {
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
if (_push3) {
_push3(`<div class="category-sidebar" data-v-adab0af3${_scopeId2}><div class="category-sidebar-title" data-v-adab0af3${_scopeId2}>${ssrInterpolate(__props.config.title)}</div><!--[-->`);
ssrRenderList(__props.config.categories, (cat) => {
_push3(`<div class="${ssrRenderClass([{ active: unref(activeType) === cat.type }, "category-item"])}" data-v-adab0af3${_scopeId2}>${ssrInterpolate(cat.label)}</div>`);
});
_push3(`<!--]--></div>`);
} else {
return [
createVNode("div", { class: "category-sidebar" }, [
createVNode("div", { class: "category-sidebar-title" }, toDisplayString(__props.config.title), 1),
(openBlock(true), createBlock(Fragment, null, renderList(__props.config.categories, (cat) => {
return openBlock(), createBlock("div", {
key: cat.type,
class: ["category-item", { active: unref(activeType) === cat.type }],
onClick: ($event) => selectType(cat.type)
}, toDisplayString(cat.label), 11, ["onClick"]);
}), 128))
])
];
}
}),
_: 1
}, _parent2, _scopeId));
_push2(ssrRenderComponent(_component_a_col, {
xs: 24,
lg: 19
}, {
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
if (_push3) {
_push3(`<div class="category-breadcrumb" data-v-adab0af3${_scopeId2}><span class="category-name" data-v-adab0af3${_scopeId2}>${ssrInterpolate(unref(currentCategoryLabel))}</span><span class="article-count" data-v-adab0af3${_scopeId2}>共 ${ssrInterpolate(unref(total))} 篇文章</span></div>`);
if (unref(loading)) {
_push3(`<div class="loading-state" data-v-adab0af3${_scopeId2}><!--[-->`);
ssrRenderList(5, (i) => {
_push3(ssrRenderComponent(_component_a_skeleton, {
key: i,
active: "",
paragraph: { rows: 2 },
style: { "margin-bottom": "16px" }
}, null, _parent3, _scopeId2));
});
_push3(`<!--]--></div>`);
} else {
_push3(`<div data-v-adab0af3${_scopeId2}><div class="article-list" data-v-adab0af3${_scopeId2}><!--[-->`);
ssrRenderList(unref(articles), (article) => {
_push3(`<div class="article-item" data-v-adab0af3${_scopeId2}>`);
if (article.image) {
_push3(`<div class="article-thumb" data-v-adab0af3${_scopeId2}><img${ssrRenderAttr("src", article.image)}${ssrRenderAttr("alt", article.title)} data-v-adab0af3${_scopeId2}></div>`);
} else {
_push3(`<!---->`);
}
_push3(`<div class="article-main" data-v-adab0af3${_scopeId2}><h3 class="article-title" data-v-adab0af3${_scopeId2}>${ssrInterpolate(article.title)}</h3><p class="article-overview" data-v-adab0af3${_scopeId2}>${ssrInterpolate(article.overview)}</p><div class="article-meta" data-v-adab0af3${_scopeId2}>`);
if (article.type) {
_push3(`<span class="meta-tag" data-v-adab0af3${_scopeId2}>${ssrInterpolate(getCategoryLabel(article.type))}</span>`);
} else {
_push3(`<!---->`);
}
_push3(`<span class="meta-item" data-v-adab0af3${_scopeId2}>${ssrInterpolate(article.source)}</span><span class="meta-item" data-v-adab0af3${_scopeId2}>${ssrInterpolate(article.publishTime)}</span>`);
if (article.views) {
_push3(`<span class="meta-item" data-v-adab0af3${_scopeId2}>👁 ${ssrInterpolate(article.views)}</span>`);
} else {
_push3(`<!---->`);
}
_push3(`</div></div></div>`);
});
_push3(`<!--]--></div>`);
if (unref(articles).length === 0) {
_push3(`<div class="empty-state" data-v-adab0af3${_scopeId2}>`);
_push3(ssrRenderComponent(_component_a_empty, { description: "暂无内容" }, null, _parent3, _scopeId2));
_push3(`</div>`);
} else {
_push3(`<!---->`);
}
if (unref(total) > unref(pageSize)) {
_push3(`<div class="pagination-wrap" data-v-adab0af3${_scopeId2}>`);
_push3(ssrRenderComponent(_component_a_pagination, {
current: unref(currentPage),
"onUpdate:current": ($event) => isRef(currentPage) ? currentPage.value = $event : null,
total: unref(total),
"page-size": unref(pageSize),
"show-quick-jumper": "",
onChange: handlePageChange
}, null, _parent3, _scopeId2));
_push3(`</div>`);
} else {
_push3(`<!---->`);
}
_push3(`</div>`);
}
} else {
return [
createVNode("div", { class: "category-breadcrumb" }, [
createVNode("span", { class: "category-name" }, toDisplayString(unref(currentCategoryLabel)), 1),
createVNode("span", { class: "article-count" }, "共 " + toDisplayString(unref(total)) + " 篇文章", 1)
]),
unref(loading) ? (openBlock(), createBlock("div", {
key: 0,
class: "loading-state"
}, [
(openBlock(), createBlock(Fragment, null, renderList(5, (i) => {
return createVNode(_component_a_skeleton, {
key: i,
active: "",
paragraph: { rows: 2 },
style: { "margin-bottom": "16px" }
});
}), 64))
])) : (openBlock(), createBlock("div", { key: 1 }, [
createVNode("div", { class: "article-list" }, [
(openBlock(true), createBlock(Fragment, null, renderList(unref(articles), (article) => {
return openBlock(), createBlock("div", {
key: article.id,
class: "article-item",
onClick: ($event) => handleView(article)
}, [
article.image ? (openBlock(), createBlock("div", {
key: 0,
class: "article-thumb"
}, [
createVNode("img", {
src: article.image,
alt: article.title
}, null, 8, ["src", "alt"])
])) : createCommentVNode("", true),
createVNode("div", { class: "article-main" }, [
createVNode("h3", { class: "article-title" }, toDisplayString(article.title), 1),
createVNode("p", { class: "article-overview" }, toDisplayString(article.overview), 1),
createVNode("div", { class: "article-meta" }, [
article.type ? (openBlock(), createBlock("span", {
key: 0,
class: "meta-tag"
}, toDisplayString(getCategoryLabel(article.type)), 1)) : createCommentVNode("", true),
createVNode("span", { class: "meta-item" }, toDisplayString(article.source), 1),
createVNode("span", { class: "meta-item" }, toDisplayString(article.publishTime), 1),
article.views ? (openBlock(), createBlock("span", {
key: 1,
class: "meta-item"
}, "👁 " + toDisplayString(article.views), 1)) : createCommentVNode("", true)
])
])
], 8, ["onClick"]);
}), 128))
]),
unref(articles).length === 0 ? (openBlock(), createBlock("div", {
key: 0,
class: "empty-state"
}, [
createVNode(_component_a_empty, { description: "暂无内容" })
])) : createCommentVNode("", true),
unref(total) > unref(pageSize) ? (openBlock(), createBlock("div", {
key: 1,
class: "pagination-wrap"
}, [
createVNode(_component_a_pagination, {
current: unref(currentPage),
"onUpdate:current": ($event) => isRef(currentPage) ? currentPage.value = $event : null,
total: unref(total),
"page-size": unref(pageSize),
"show-quick-jumper": "",
onChange: handlePageChange
}, null, 8, ["current", "onUpdate:current", "total", "page-size"])
])) : createCommentVNode("", true)
]))
];
}
}),
_: 1
}, _parent2, _scopeId));
} else {
return [
createVNode(_component_a_col, {
xs: 24,
lg: 5,
class: "mb-6 lg:mb-0"
}, {
default: withCtx(() => [
createVNode("div", { class: "category-sidebar" }, [
createVNode("div", { class: "category-sidebar-title" }, toDisplayString(__props.config.title), 1),
(openBlock(true), createBlock(Fragment, null, renderList(__props.config.categories, (cat) => {
return openBlock(), createBlock("div", {
key: cat.type,
class: ["category-item", { active: unref(activeType) === cat.type }],
onClick: ($event) => selectType(cat.type)
}, toDisplayString(cat.label), 11, ["onClick"]);
}), 128))
])
]),
_: 1
}),
createVNode(_component_a_col, {
xs: 24,
lg: 19
}, {
default: withCtx(() => [
createVNode("div", { class: "category-breadcrumb" }, [
createVNode("span", { class: "category-name" }, toDisplayString(unref(currentCategoryLabel)), 1),
createVNode("span", { class: "article-count" }, "共 " + toDisplayString(unref(total)) + " 篇文章", 1)
]),
unref(loading) ? (openBlock(), createBlock("div", {
key: 0,
class: "loading-state"
}, [
(openBlock(), createBlock(Fragment, null, renderList(5, (i) => {
return createVNode(_component_a_skeleton, {
key: i,
active: "",
paragraph: { rows: 2 },
style: { "margin-bottom": "16px" }
});
}), 64))
])) : (openBlock(), createBlock("div", { key: 1 }, [
createVNode("div", { class: "article-list" }, [
(openBlock(true), createBlock(Fragment, null, renderList(unref(articles), (article) => {
return openBlock(), createBlock("div", {
key: article.id,
class: "article-item",
onClick: ($event) => handleView(article)
}, [
article.image ? (openBlock(), createBlock("div", {
key: 0,
class: "article-thumb"
}, [
createVNode("img", {
src: article.image,
alt: article.title
}, null, 8, ["src", "alt"])
])) : createCommentVNode("", true),
createVNode("div", { class: "article-main" }, [
createVNode("h3", { class: "article-title" }, toDisplayString(article.title), 1),
createVNode("p", { class: "article-overview" }, toDisplayString(article.overview), 1),
createVNode("div", { class: "article-meta" }, [
article.type ? (openBlock(), createBlock("span", {
key: 0,
class: "meta-tag"
}, toDisplayString(getCategoryLabel(article.type)), 1)) : createCommentVNode("", true),
createVNode("span", { class: "meta-item" }, toDisplayString(article.source), 1),
createVNode("span", { class: "meta-item" }, toDisplayString(article.publishTime), 1),
article.views ? (openBlock(), createBlock("span", {
key: 1,
class: "meta-item"
}, "👁 " + toDisplayString(article.views), 1)) : createCommentVNode("", true)
])
])
], 8, ["onClick"]);
}), 128))
]),
unref(articles).length === 0 ? (openBlock(), createBlock("div", {
key: 0,
class: "empty-state"
}, [
createVNode(_component_a_empty, { description: "暂无内容" })
])) : createCommentVNode("", true),
unref(total) > unref(pageSize) ? (openBlock(), createBlock("div", {
key: 1,
class: "pagination-wrap"
}, [
createVNode(_component_a_pagination, {
current: unref(currentPage),
"onUpdate:current": ($event) => isRef(currentPage) ? currentPage.value = $event : null,
total: unref(total),
"page-size": unref(pageSize),
"show-quick-jumper": "",
onChange: handlePageChange
}, null, 8, ["current", "onUpdate:current", "total", "page-size"])
])) : createCommentVNode("", true)
]))
]),
_: 1
})
];
}
}),
_: 1
}, _parent));
_push(`</div></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/ArticleListPage.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const __nuxt_component_0 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main, [["__scopeId", "data-v-adab0af3"]]), { __name: "ArticleListPage" });
export { __nuxt_component_0 as _ };
//# sourceMappingURL=ArticleListPage-Di4R26TI.mjs.map