Files
hjc-web/nuxt.config.ts
T
weicw-dshsa b88c9df3b3 chore(templates): 只保留 template-07,删除其余 9 套模板
汇吉采仅使用 template-07(后端绑定 + .env.development),其余
template-01~06、08~10 为多租户 SaaS 平台时代遗留,全部删除:

- 删除 app/templates/ 下 9 套模板目录及注册表内对应配置
- 删除 public/images/template-{01,03,09,10} 图片目录
- 删除 templates/cloud-website 下 9 张模板预览图
- 三处 template-01 兜底(nuxt.config / useTemplate / default.vue)改为 07
- 清理指向已删模板的注释,README 模板系统章节同步更新

模板动态加载机制保留:新增模板 = 建目录 + 在 app/templates/index.ts 注册
2026-09-30 07:38:05 +08:00

169 lines
6.2 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 || ''
// appId 是 app_product.product_id 数字主键(如 42),不是 productCode('website')。
// 留空时下游 getSubscriptionStatus 等按空值降级,绝不回退到编码值,
// 否则 /api/app/product/detail/{productId} 会因 Integer 转换失败报错。
const appId = process.env.NUXT_PUBLIC_APP_ID || ''
const templateId = process.env.NUXT_PUBLIC_TEMPLATE_ID || 'template-07'
// 强制模板 ID:一旦设置则拥有最高优先级,覆盖应用/站点绑定(主要用于本地调试)
const forceTemplateId = process.env.NUXT_PUBLIC_FORCE_TEMPLATE_ID || ''
// 站点名称覆盖:设置后优先于后端 AppProduct / CMS 返回值(多用于本地调试或强制品牌名)
const siteName = process.env.NUXT_PUBLIC_SITE_NAME || ''
const modulesApiBase =
process.env.NUXT_PUBLIC_MODULES_API_BASE ||
'https://hjc-api.sitelnk.cn/api'
const appApiBase =
process.env.NUXT_PUBLIC_APP_API_BASE ||
'https://hjc-api.sitelnk.cn'
const fileServerBase =
process.env.NUXT_PUBLIC_FILE_SERVER_BASE ||
getOrigin(appApiBase) ||
'https://hjc-api.sitelnk.cn'
const baseDomain =
process.env.NUXT_PUBLIC_BASE_DOMAIN || 'shoplnk.cn'
// 多主域清单:子域名租户解析支持的主域(逗号分隔)。
// 默认 shoplnk.cn,sitelink.cn,wsdns.cn;baseDomain 仅作兼容保留(取第一个)。
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://hjc-api.sitelnk.cn', crossorigin: '' },
{ rel: 'dns-prefetch', href: 'https://hjc-api.sitelnk.cn' },
{ rel: 'preconnect', href: 'https://file.wsdns.cn', crossorigin: '' },
{ rel: 'dns-prefetch', href: 'https://file.wsdns.cn' },
// 思源黑体(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,
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 会在请求进入中间件前直接 403(Blocked 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
}
}
})