const fs = require('fs')
const path = require('path')
const http = require('http')
const Prerenderer = require('@prerenderer/prerenderer')
const PuppeteerRenderer = require('@prerenderer/renderer-puppeteer')
const staticDir = path.join(__dirname, '../dist')
const API_TARGET = process.env.PRERENDER_API_TARGET || 'http://121.41.91.44:8080'
const ROUTE_REQUIREMENTS = {
'/': ['hm-banner__title', 'hm-ai-tab', 'hm-logo-item', 'organization-jsonld', 'website-jsonld'],
'/home': ['hm-banner__title', 'hm-ai-tab', 'hm-logo-item', 'organization-jsonld', 'website-jsonld'],
'/product/version-selection': ['db-hero__title', 'version-selection-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-hr': ['od-banner-main-title', 'organization-product-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-recruitment': ['od-banner-main-title', 'organization-product-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-attendance': ['od-banner-main-title', 'organization-product-jsonld', 'breadcrumb-jsonld'],
'/product/dingtalk-payroll': ['od-banner-main-title', 'organization-product-jsonld', 'breadcrumb-jsonld'],
'/product/dingtalk-yida': ['bd-banner-main-title', 'business-product-jsonld', 'breadcrumb-jsonld'],
'/product/teambition': ['bd-banner-main-title', 'business-product-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-finance': ['bd-banner-main-title', 'business-product-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-contract': ['bd-banner-main-title', 'business-product-jsonld', 'breadcrumb-jsonld'],
'/product/intelligent-marketing': ['bd-banner-main-title', 'business-product-jsonld', 'breadcrumb-jsonld'],
'/ai/qwen-office': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai/deap': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai/ai-table': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai/ai-memo': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai/ai-search': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai/dingtalk-a1': ['ot-hero__title', 'ai-product-jsonld', 'breadcrumb-jsonld'],
'/ai': ['ot-hero__title', 'ot-mod--block', 'service-jsonld', 'breadcrumb-jsonld'],
'/digital-base': ['db-hero__title', 'db-cat-tab', 'service-jsonld', 'breadcrumb-jsonld'],
'/organization-digital': ['od-banner-main-title', 'od-mod--product', 'service-jsonld', 'breadcrumb-jsonld'],
'/business-digital': ['bd-banner-main-title', 'bd-mod--product', 'service-jsonld', 'breadcrumb-jsonld'],
'/solutions': ['banner-kicker', 'solution-section', 'service-jsonld', 'breadcrumb-jsonld'],
'/cases': ['cases-hero__title', 'cases-mod'],
'/super-service': ['ss-banner__title', 'ss-tab-btn', 'service-jsonld', 'breadcrumb-jsonld'],
'/fde': ['fde-hero', 'fde-heading', 'breadcrumb-jsonld'],
'/about': ['about-banner__title', 'about-contact-card__name'],
'/contact': ['consult-info__title', 'consult-card__title'],
'/privacy-policy': ['privacy-page__hero', 'privacy-page__content', 'breadcrumb-jsonld'],
'/news': ['news-hero', 'news-list-wrap', 'breadcrumb-jsonld']
}
const ROUTE_READY_SELECTORS = {
'/': '.hm-ai-tab',
'/home': '.hm-ai-tab',
'/product/version-selection': '.db-page',
'/product/intelligent-hr': '.od-page',
'/product/intelligent-recruitment': '.od-page',
'/product/intelligent-attendance': '.od-page',
'/product/dingtalk-payroll': '.od-page',
'/product/dingtalk-yida': '.bd-page',
'/product/teambition': '.bd-page',
'/product/intelligent-finance': '.bd-page',
'/product/intelligent-contract': '.bd-page',
'/product/intelligent-marketing': '.bd-page',
'/ai/qwen-office': '.ot-page',
'/ai/deap': '.ot-page',
'/ai/ai-table': '.ot-page',
'/ai/ai-memo': '.ot-page',
'/ai/ai-search': '.ot-page',
'/ai/dingtalk-a1': '.ot-page',
'/ai': '.ot-mod--block',
'/digital-base': '.db-cat-tab',
'/organization-digital': '.od-mod--product',
'/business-digital': '.bd-mod--product',
'/solutions': '.solution-section',
'/cases': '.cases-mod',
'/super-service': '.ss-tab-btn',
'/fde': '.fde-hero',
'/about': '.about-contact-card__name',
'/contact': '.consult-card__title',
'/privacy-policy': '.privacy-page__content',
'/news': '.news-list-wrap'
}
const PRERENDER_ROUTES = process.env.PRERENDER_ROUTES
? process.env.PRERENDER_ROUTES.split(',').map((route) => route.trim()).filter(Boolean)
: [
'/',
'/home',
'/product/version-selection',
'/product/intelligent-hr',
'/product/intelligent-recruitment',
'/product/intelligent-attendance',
'/product/dingtalk-payroll',
'/product/dingtalk-yida',
'/product/teambition',
'/product/intelligent-finance',
'/product/intelligent-contract',
'/product/intelligent-marketing',
'/ai/qwen-office',
'/ai/deap',
'/ai/ai-table',
'/ai/ai-memo',
'/ai/ai-search',
'/ai/dingtalk-a1',
'/ai',
'/digital-base',
'/organization-digital',
'/business-digital',
'/solutions',
'/cases',
'/super-service',
'/fde',
'/about',
'/contact',
'/privacy-policy',
'/news'
]
function fetchPublishedArticles() {
const url = new URL('/prod-api/api/article/list?pageNum=1&pageSize=1000', API_TARGET)
return new Promise((resolve, reject) => {
const request = http.get(url, response => {
let body = ''
response.setEncoding('utf8')
response.on('data', chunk => { body += chunk })
response.on('end', () => {
if (response.statusCode !== 200) return reject(new Error(`文章 API 返回 ${response.statusCode}`))
try { const parsed = JSON.parse(body); resolve(Array.isArray(parsed.rows) ? parsed.rows : []) } catch (error) { reject(error) }
})
})
request.setTimeout(30000, () => request.destroy(new Error('文章 API 请求超时')))
request.on('error', reject)
})
}
function writeSitemap(articles) {
const staticRoutes = ['home', 'product/version-selection', 'product/intelligent-hr', 'product/intelligent-recruitment', 'product/intelligent-attendance', 'product/dingtalk-payroll', 'product/dingtalk-yida', 'product/teambition', 'product/intelligent-finance', 'product/intelligent-contract', 'product/intelligent-marketing', 'ai', 'ai/qwen-office', 'ai/deap', 'ai/ai-table', 'ai/ai-memo', 'ai/ai-search', 'ai/dingtalk-a1', 'fde', 'digital-base', 'organization-digital', 'business-digital', 'solutions', 'cases', 'super-service', 'about', 'contact', 'privacy-policy', 'news']
const urls = [...staticRoutes.map(route => `${route}/`), ...articles.map(article => `news/${article.slug}/`)]
const xml = ['', '