feat: 完成前端业务闭环与后端联调
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
const workspaceRoot = process.cwd()
|
||||
const referenceRoot = path.resolve(workspaceRoot, '..', 'Jiapu-App')
|
||||
const referencePagesPath = path.join(referenceRoot, 'pages.json')
|
||||
const parityDocumentPath = path.join(
|
||||
workspaceRoot,
|
||||
'docs',
|
||||
'frontend-reference-parity-2026-08-17.md'
|
||||
)
|
||||
|
||||
const stripJsonLineComments = (source) =>
|
||||
source
|
||||
.split(/\r?\n/u)
|
||||
.map((line) => {
|
||||
let inString = false
|
||||
let escaped = false
|
||||
for (let index = 0; index < line.length - 1; index += 1) {
|
||||
const character = line[index]
|
||||
if (escaped) {
|
||||
escaped = false
|
||||
continue
|
||||
}
|
||||
if (character === '\\' && inString) {
|
||||
escaped = true
|
||||
continue
|
||||
}
|
||||
if (character === '"') {
|
||||
inString = !inString
|
||||
continue
|
||||
}
|
||||
if (!inString && character === '/' && line[index + 1] === '/') {
|
||||
return line.slice(0, index)
|
||||
}
|
||||
}
|
||||
return line
|
||||
})
|
||||
.join('\n')
|
||||
|
||||
const fail = (message) => {
|
||||
console.error(`FRONTEND PARITY CHECK FAIL: ${message}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (!fs.existsSync(referencePagesPath)) {
|
||||
fail(`参考项目不存在:${referencePagesPath}`)
|
||||
}
|
||||
if (!fs.existsSync(parityDocumentPath)) {
|
||||
fail(`对比总表不存在:${parityDocumentPath}`)
|
||||
}
|
||||
|
||||
const referenceConfig = JSON.parse(
|
||||
stripJsonLineComments(fs.readFileSync(referencePagesPath, 'utf8'))
|
||||
)
|
||||
const referenceRoutes = referenceConfig.pages.map(({ path: routePath }) => routePath)
|
||||
if (referenceRoutes.length !== 78) {
|
||||
fail(`参考项目活动路由应为 78 条,实际为 ${referenceRoutes.length} 条`)
|
||||
}
|
||||
if (new Set(referenceRoutes).size !== referenceRoutes.length) {
|
||||
fail('参考项目 pages.json 存在重复活动路由')
|
||||
}
|
||||
|
||||
for (const routePath of referenceRoutes) {
|
||||
const vuePath = path.join(referenceRoot, `${routePath}.vue`)
|
||||
const nvuePath = path.join(referenceRoot, `${routePath}.nvue`)
|
||||
if (!fs.existsSync(vuePath) && !fs.existsSync(nvuePath)) {
|
||||
fail(`参考路由没有 .vue 或 .nvue 页面文件:${routePath}`)
|
||||
}
|
||||
}
|
||||
|
||||
const parityDocument = fs.readFileSync(parityDocumentPath, 'utf8')
|
||||
const documentedRouteRows = parityDocument
|
||||
.split(/\r?\n/u)
|
||||
.filter((line) => /^\| `[^`]+` \|/u.test(line))
|
||||
.map((line) => line.split('|').slice(1, -1).map((column) => column.trim()))
|
||||
const documentedRoutes = documentedRouteRows.map(([routeCell]) => routeCell.slice(1, -1))
|
||||
const allowedStatuses = new Set([
|
||||
'覆盖',
|
||||
'合并覆盖',
|
||||
'升级替代',
|
||||
'非产品页',
|
||||
'本轮补齐',
|
||||
'部分覆盖',
|
||||
'部分合并',
|
||||
'部分升级',
|
||||
'前端待后端'
|
||||
])
|
||||
|
||||
for (const columns of documentedRouteRows) {
|
||||
if (columns.length !== 5 || columns.some((column) => !column)) {
|
||||
fail(`对比总表路由行字段不完整:${columns[0] || '未知路由'}`)
|
||||
}
|
||||
if (!allowedStatuses.has(columns[3])) {
|
||||
fail(`对比总表路由状态无效:${columns[0]} -> ${columns[3]}`)
|
||||
}
|
||||
}
|
||||
|
||||
const documentedRouteCounts = new Map()
|
||||
for (const routePath of documentedRoutes) {
|
||||
documentedRouteCounts.set(
|
||||
routePath,
|
||||
(documentedRouteCounts.get(routePath) || 0) + 1
|
||||
)
|
||||
}
|
||||
|
||||
const missingRoutes = referenceRoutes.filter(
|
||||
(routePath) => !documentedRouteCounts.has(routePath)
|
||||
)
|
||||
const duplicateRoutes = [...documentedRouteCounts.entries()]
|
||||
.filter(([, count]) => count !== 1)
|
||||
.map(([routePath]) => routePath)
|
||||
const unknownRoutes = documentedRoutes.filter(
|
||||
(routePath) => !referenceRoutes.includes(routePath)
|
||||
)
|
||||
|
||||
if (missingRoutes.length) fail(`对比总表遗漏路由:${missingRoutes.join(', ')}`)
|
||||
if (duplicateRoutes.length) fail(`对比总表重复路由:${duplicateRoutes.join(', ')}`)
|
||||
if (unknownRoutes.length) fail(`对比总表包含未知路由:${unknownRoutes.join(', ')}`)
|
||||
|
||||
console.log(
|
||||
`FRONTEND PARITY CHECK PASS referenceRoutes=${referenceRoutes.length} documentedRoutes=${documentedRoutes.length}`
|
||||
)
|
||||
Reference in New Issue
Block a user