Files
hjc-web/nuxt.config.ts
T
gxwebsoft 2b69686795 feat(app): 添加多模板关于我们页面及相关路由和404页面
- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
2026-09-08 12:13:44 +08:00

170 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
function getOrigin(url: string) {
try {
return new URL(url).origin
} catch {
return ''
}
}
/**
* 解析布尔型环境变量:'true'→true'false'→false,其余→null(交由后台配置决定)。
*/
function toBool(v?: string): boolean | null {
if (v === 'true') return true
if (v === 'false') return false
return null
}
const tenantId = process.env.NUXT_PUBLIC_TENANT_ID || ''
const appId = process.env.NUXT_PUBLIC_APP_ID || 'website'
const templateId = process.env.NUXT_PUBLIC_TEMPLATE_ID || 'template-01'
// 强制模板 ID:一旦设置则拥有最高优先级,覆盖应用/站点绑定(主要用于本地调试)
const forceTemplateId = process.env.NUXT_PUBLIC_FORCE_TEMPLATE_ID || ''
// 站点名称覆盖:设置后优先于后端 AppProduct / CMS 返回值(多用于本地调试或强制品牌名)
const siteName = process.env.NUXT_PUBLIC_SITE_NAME || ''
const serverApiBase =
process.env.NUXT_PUBLIC_SERVER_API_BASE ||
'https://server.websoft.top/api'
const modulesApiBase =
process.env.NUXT_PUBLIC_MODULES_API_BASE ||
'https://cms-api.websoft.top/api'
const appApiBase =
process.env.NUXT_PUBLIC_APP_API_BASE ||
'https://websopy-api.websoft.top'
const fileServerBase =
process.env.NUXT_PUBLIC_FILE_SERVER_BASE ||
getOrigin(serverApiBase) ||
'https://server.websoft.top'
const baseDomain =
process.env.NUXT_PUBLIC_BASE_DOMAIN || 'shoplnk.cn'
// 多主域清单:子域名租户解析支持的主域(逗号分隔)。
// 默认 shoplnk.cn,sitelink.cn,wsdns.cnbaseDomain 仅作兼容保留(取第一个)。
const baseDomains = (
process.env.NUXT_PUBLIC_BASE_DOMAINS ||
'shoplnk.cn,sitelink.cn,wsdns.cn'
).split(',').map(s => s.trim()).filter(Boolean)
// 子域名前缀白名单:仅这些前缀 + 数字租户号 + 主域 会被识别为平台子域名租户
const subdomainPrefixes = (
process.env.NUXT_PUBLIC_SUBDOMAIN_PREFIXES ||
'site,shop,store,mp,app,oa'
).split(',').map(s => s.trim()).filter(Boolean)
// 联系电话覆盖:当后端 phone 被脱敏时,作为兜底显示
const phone = process.env.NUXT_PUBLIC_PHONE || ''
const WATCH_IGNORED = [
'**/.git/**',
'**/node_modules/**',
'**/.nuxt/**',
'**/.output/**',
'**/dist/**',
'**/coverage/**',
'**/.cache/**',
'**/.workbuddy/**'
]
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: true },
modules: ['@nuxtjs/tailwindcss', '@ant-design-vue/nuxt'],
app: {
head: {
htmlAttrs: { lang: 'zh-CN' },
titleTemplate: '%s',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'robots', content: 'index,follow' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
// 提前与内容/接口源站建立连接,降低首字节与图片加载延迟
{ rel: 'preconnect', href: 'https://server.websoft.top', crossorigin: '' },
{ rel: 'preconnect', href: 'https://cms-api.websoft.top', crossorigin: '' },
{ rel: 'dns-prefetch', href: 'https://server.websoft.top' },
{ rel: 'dns-prefetch', href: 'https://cms-api.websoft.top' },
// 思源黑体(Noto Sans SC,SIL 开源许可,版权无忧)网页字体,全站统一字体
{ rel: 'preconnect', href: 'https://fonts.googleapis.cn' },
{ rel: 'preconnect', href: 'https://fonts.gstatic.cn', crossorigin: '' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.cn/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap' }
],
// 首屏绘制前注入 .js 类,配合 animations.css 的 `.js [data-reveal]`
// 规则实现「无 JS 时内容可见、有 JS 时先隐藏再由滚动揭示」,杜绝 SSR 闪烁
script: [
{
innerHTML:
"document.documentElement.classList.add('js')",
tagPosition: 'head'
}
]
}
},
tailwindcss: {
cssPath: '~/assets/css/tailwind.css',
configPath: 'tailwind.config.cjs'
},
experimental: { appManifest: false },
// 全局 SSR,保证 SEO
routeRules: {
'/renewal': { ssr: true }
},
runtimeConfig: {
// 仅服务端可见
subscriptionCacheTtl: Number(process.env.NUXT_SUBSCRIPTION_CACHE_TTL || 60),
public: {
tenantId,
appId,
templateId,
forceTemplateId,
siteName,
serverApiBase,
modulesApiBase,
appApiBase,
fileServerBase,
baseDomain,
baseDomains,
subdomainPrefixes,
phone,
// 微信二维码覆盖:设置后优先于 CMS 返回的 wxQrcode(用于本地调试或强制指定二维码)
// ⚠️ 不要写硬编码默认图!必须保持空字符串,让 Footer 从 siteInfo.config.wxQrcode / siteInfo.qrCode 读取后台上传
wxQrcode: process.env.NUXT_PUBLIC_WX_QRCODE || '',
// 在线留言滑块验证码开关覆盖(可选):
// 默认 null → 由后台「网站设置」setting.requireCaptcha 决定;
// 设 true/false 可在不改后台的情况下强制开/关(仅部署级覆盖,后台显式配置优先)。
contactCaptcha: toBool(process.env.NUXT_PUBLIC_CONTACT_CAPTCHA)
}
},
css: ['~/assets/css/tailwind.css', '~/assets/css/animations.css'],
vite: {
server: {
// 本地开发允许用自定义域名(如 cz-hro.shoplnk.cn)访问,
// 否则 Vite 会在请求进入中间件前直接 403Blocked request. This host is not allowed
// 以 "." 开头的条目表示允许该域名及其所有子域。
// 注意:这里只是放宽 Vite 的 host 校验,真正「是否解析为合法租户」仍由
// tenant 中间件按白名单前缀 + 主域清单判断;非白名单子域不会命中租户。
allowedHosts: ['.shoplnk.cn', '.sitelink.cn', '.wsdns.cn', 'localhost', '127.0.0.1'],
watch: {
ignored: WATCH_IGNORED
}
},
optimizeDeps: {
include: ['dayjs']
}
},
nitro: {
watchOptions: {
ignored: WATCH_IGNORED
}
},
watchers: {
chokidar: {
ignored: WATCH_IGNORED
}
}
})