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,183 @@
import { defineComponent, ref, resolveComponent, mergeProps, unref, isRef, withCtx, createTextVNode, createVNode, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderComponent, ssrRenderList, ssrRenderAttr, ssrInterpolate } from 'vue/server-renderer';
import { message } from 'ant-design-vue';
import { a as _export_sfc, c as useHead, d as useRouter, e as useRoute } from './server.mjs';
import '../nitro/nitro.mjs';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'node:fs';
import 'node:path';
import 'node:crypto';
import 'node:url';
import 'better-sqlite3';
import 'vue-router';
import '@babel/runtime/helpers/esm/extends';
import 'stylis';
import 'dayjs';
import '../routes/renderer.mjs';
import 'vue-bundle-renderer/runtime';
import 'unhead/server';
import 'devalue';
import 'unhead/plugins';
import 'unhead/utils';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "index",
__ssrInlineRender: true,
setup(__props) {
useHead({ title: "专家资讯 - 决策咨询网" });
useRouter();
const activeType = ref(useRoute().query.type || "");
const currentPage = ref(1);
const pageSize = ref(12);
const total = ref(0);
const loading = ref(false);
const items = ref([]);
async function loadItems() {
loading.value = true;
try {
} catch (e) {
message.error("加载失败");
} finally {
loading.value = false;
}
}
function handleTypeChange() {
currentPage.value = 1;
loadItems();
}
function handlePageChange(page) {
currentPage.value = page;
loadItems();
}
return (_ctx, _push, _parent, _attrs) => {
const _component_a_radio_group = resolveComponent("a-radio-group");
const _component_a_radio_button = resolveComponent("a-radio-button");
const _component_a_spin = resolveComponent("a-spin");
const _component_a_empty = resolveComponent("a-empty");
const _component_a_pagination = resolveComponent("a-pagination");
_push(`<div${ssrRenderAttrs(mergeProps({ class: "expert-page" }, _attrs))} data-v-f62ec455><div class="page-header" data-v-f62ec455><h1 class="page-title" data-v-f62ec455>专家资讯</h1><p class="page-desc" data-v-f62ec455>汇聚各领域权威专家,提供专业视角与研究成果</p></div><div class="category-tabs" data-v-f62ec455>`);
_push(ssrRenderComponent(_component_a_radio_group, {
value: unref(activeType),
"onUpdate:value": ($event) => isRef(activeType) ? activeType.value = $event : null,
"button-style": "solid",
onChange: handleTypeChange
}, {
default: withCtx((_, _push2, _parent2, _scopeId) => {
if (_push2) {
_push2(ssrRenderComponent(_component_a_radio_button, { value: "" }, {
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
if (_push3) {
_push3(`全部`);
} else {
return [
createTextVNode("全部")
];
}
}),
_: 1
}, _parent2, _scopeId));
_push2(ssrRenderComponent(_component_a_radio_button, { value: "view" }, {
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
if (_push3) {
_push3(`专家视点`);
} else {
return [
createTextVNode("专家视点")
];
}
}),
_: 1
}, _parent2, _scopeId));
_push2(ssrRenderComponent(_component_a_radio_button, { value: "dynamic" }, {
default: withCtx((_2, _push3, _parent3, _scopeId2) => {
if (_push3) {
_push3(`专家动态`);
} else {
return [
createTextVNode("专家动态")
];
}
}),
_: 1
}, _parent2, _scopeId));
} else {
return [
createVNode(_component_a_radio_button, { value: "" }, {
default: withCtx(() => [
createTextVNode("全部")
]),
_: 1
}),
createVNode(_component_a_radio_button, { value: "view" }, {
default: withCtx(() => [
createTextVNode("专家视点")
]),
_: 1
}),
createVNode(_component_a_radio_button, { value: "dynamic" }, {
default: withCtx(() => [
createTextVNode("专家动态")
]),
_: 1
})
];
}
}),
_: 1
}, _parent));
_push(`</div><div class="expert-list" data-v-f62ec455><!--[-->`);
ssrRenderList(unref(items), (item) => {
_push(`<div class="expert-item" data-v-f62ec455>`);
if (item.avatar) {
_push(`<div class="expert-avatar" data-v-f62ec455><img${ssrRenderAttr("src", item.avatar)}${ssrRenderAttr("alt", item.expertName)} data-v-f62ec455></div>`);
} else {
_push(`<div class="expert-default-avatar" data-v-f62ec455>${ssrInterpolate(item.expertName?.charAt(0))}</div>`);
}
_push(`<div class="expert-content" data-v-f62ec455><h3 class="expert-title" data-v-f62ec455>${ssrInterpolate(item.title)}</h3><div class="expert-meta" data-v-f62ec455><span class="meta-item" data-v-f62ec455>${ssrInterpolate(item.expertName)}</span><span class="meta-item" data-v-f62ec455>${ssrInterpolate(item.expertTitle)}</span><span class="meta-item" data-v-f62ec455>${ssrInterpolate(item.publishTime)}</span></div><p class="expert-overview" data-v-f62ec455>${ssrInterpolate(item.overview)}</p></div></div>`);
});
_push(`<!--]-->`);
if (unref(loading)) {
_push(`<div class="loading-placeholder" data-v-f62ec455>`);
_push(ssrRenderComponent(_component_a_spin, { size: "large" }, null, _parent));
_push(`</div>`);
} else {
_push(`<!---->`);
}
if (!unref(loading) && unref(items).length === 0) {
_push(`<div class="empty-placeholder" data-v-f62ec455>`);
_push(ssrRenderComponent(_component_a_empty, { description: "暂无内容" }, null, _parent));
_push(`</div>`);
} else {
_push(`<!---->`);
}
_push(`</div>`);
if (unref(total) > unref(pageSize)) {
_push(`<div class="pagination-wrap" data-v-f62ec455>`);
_push(ssrRenderComponent(_component_a_pagination, {
current: unref(currentPage),
"onUpdate:current": ($event) => isRef(currentPage) ? currentPage.value = $event : null,
total: unref(total),
"page-size": unref(pageSize),
onChange: handlePageChange
}, null, _parent));
_push(`</div>`);
} else {
_push(`<!---->`);
}
_push(`</div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/expert/index.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f62ec455"]]);
export { index as default };
//# sourceMappingURL=index-DcD4r-Ko.mjs.map