217 lines
14 KiB
JavaScript
217 lines
14 KiB
JavaScript
const fs = require('fs')
|
||
const path = require('path')
|
||
const { modules } = require('./capture-full-manual-pages')
|
||
|
||
const root = path.resolve(__dirname, '..', '..')
|
||
const outputPath = path.join(__dirname, 'full-page-catalog.json')
|
||
|
||
const purposes = {
|
||
'设备信息维护': '维护设备名称、公司编码、生产用名、规格型号、设备类型、使用部门、数量、状态及维修记录,为工艺能力、工位绑定和设备数据查询提供设备主数据。',
|
||
'设备数据': '按工位查看设备运行数据及当前采集状态,用于现场设备状态监控和生产运行判断。',
|
||
'设备历史数据': '按设备、工位和时间范围追溯历史采集值,用于故障分析、运行复盘和数据导出。',
|
||
'实时数据': '查看设备最新实时采集值和更新时间,快速判断设备连接及当前运行状态。',
|
||
'设计任务': '建立、分派和维护设计任务,记录项目、物料、设计要求、计划时间、可见人员、批示、附件及完成状态。',
|
||
'设计报工': '由设计人员对被授权的设计任务执行开始、结束和说明登记,形成设计工时与进度记录。',
|
||
'设计工时校验': '由授权人员复核设计报工的开始时间、结束时间、计算工时和备注,形成已校验状态。',
|
||
'设计工时报表': '按作业者或任务汇总设计工时,支持条件查询、树形展开和结果导出。',
|
||
'工序管理': '维护工艺分类、工序名称、简称及工艺要求,为标准工艺和生产工艺编制提供基础工序字典。',
|
||
'制定标准工艺': '按物料建立可复用的标准工艺路线,维护工序顺序、设备、工时和工艺要求。',
|
||
'生产工艺': '根据生产订单和物料生成、编辑、复制并启用本次生产工艺,可将工艺任务下发到计划排产。',
|
||
'工艺查询': '按物料、订单等条件查看已维护的工艺路线及工序明细,供生产、计划和质量人员核对。',
|
||
'工艺任务': '查询待编制或待下发工艺的生产订单任务,进入对应工艺处理流程。',
|
||
'图纸维护': '维护物料对应的零件图纸及版本,支持上传、查看、替换、下载和删除记录查询。',
|
||
'工艺维护': '维护工艺相关图纸及名称,使工序和工艺路线能够关联正确的技术文件。',
|
||
'查看图纸': '以只读方式按物料、图号等条件查找和预览零件图纸。',
|
||
'采购图纸查询': '供采购场景按物料或图号查询所需图纸,支持只读预览和下载。',
|
||
'机加件排产': '对待排产机加工序选择工位、指派数量并维护计划开始、完成和最晚开始时间,批量形成机加计划。',
|
||
'装配件排产': '对装配任务选择工位、人员和计划时间,形成装配执行任务。',
|
||
'机加件已排产': '查询已形成计划的机加任务,并按订单、物料、工序、工位和日期核对排产结果。',
|
||
'机加件未排产': '汇总尚未完成排产的机加工序,定位缺少工位、数量或计划时间的任务。',
|
||
'优先装配': '维护需要优先处理的装配订单或任务,为装配排产和现场执行提供优先级依据。',
|
||
'计划用表': '以计划人员使用的综合表格查看订单、物料、工艺、计划时间和任务状态。',
|
||
'装配未排产': '查询尚未形成装配计划的任务,支持按订单、物料和日期范围筛选。',
|
||
'生产订单关闭': '查询可关闭或已关闭的生产订单,并执行订单关闭状态维护。',
|
||
'工位任务汇总': '按工位汇总计划任务、数量、时间和状态,用于检查工位负荷及任务分布。',
|
||
'装配已排产': '查询已排产装配任务及其工位、人员、数量和计划时间。',
|
||
'系统类装配任务': '维护和查看系统类产品的装配任务、工位分配及计划执行状态。',
|
||
'阀类装配任务': '维护和查看阀类产品的装配任务、工位分配及计划执行状态。',
|
||
'及时齐套跟踪结果': '汇总物料齐套跟踪结果,展示任务是否按计划具备投产或装配条件。',
|
||
'生产计划跟踪': '综合查看生产订单从计划、工艺、排产到执行的进度与状态。',
|
||
'加工中心': '供机加现场查询本人或工位任务,并执行开工、暂停、报工、收料、自检、异常和图纸查看等生产操作。',
|
||
'过程异常管控': '集中查询和处理生产过程中登记的异常,跟踪异常类型、责任、状态和处理结果。',
|
||
'工时校验': '对生产报工形成的工时记录进行核对和校验,修正异常时长并保留校验状态。',
|
||
'外协管理': '管理生产外协任务的发料、收料、数量和状态,连接内部生产订单与外协执行。',
|
||
'人员绑定': '将人员与工位、设备或生产资源建立绑定关系,决定现场任务和报工的人员范围。',
|
||
'装配中心': '供装配现场执行开始、结束、送检、收验、领料、自检、异常和图纸查看等操作。',
|
||
'班次管理': '维护班次名称、班次类型及工作时间,为人员、设备和工时计算提供班次基础数据。',
|
||
'工时报表': '按项目、人员、任务或设备汇总生产工时,并支持日期过滤和 Excel 导出。',
|
||
'加急件管理': '登记和跟踪加急生产任务,维护加急数量、状态及相关订单信息。',
|
||
'拣配任务': '查看和处理生产物料拣配任务,跟踪拣配数量和完成状态。',
|
||
'采购外协管理': '跟踪采购外协任务的订单、发料、到货、收料和完成情况。',
|
||
'工时查询': '按人员、订单、物料、工序和日期查询生产工时明细。',
|
||
'机加正在进行中': '实时查看正在机加执行的人员、设备、任务及开始时间。',
|
||
'装配状态': '实时查看装配任务的当前执行、送检、收验和完成状态。',
|
||
'外协报表': '按订单、供应商、物料和日期汇总外协发料、收料及完成数据。',
|
||
'工时修正': '对满足权限和状态条件的生产工时记录进行修正,并保留修改依据。',
|
||
'物料机器人': '查询 AGV 物料搬运任务的起点、终点、状态和时间,并在授权情况下处理任务状态。',
|
||
'手续确认报表': '汇总订单或任务相关手续的确认状态,供生产和发货前核查。',
|
||
'发货通知列表': '查询发货通知及其订单、物料、数量、状态和关联文件,供生产与销售协同。',
|
||
'结算工时': '按任务和人员结算可计入的生产工时,形成结算口径的工时结果。',
|
||
'机加及时开工': '对比机加计划开始时间与实际开工状态,识别未按时开工任务。',
|
||
'外协及时开工': '对比外协计划与实际执行状态,识别未按时开始的外协任务。',
|
||
'加急任务列表': '集中展示加急任务、当前环节和完成状态,提示相关人员优先处理。',
|
||
'装配及时送检': '对比装配计划和实际送检时间,识别未按时送检任务。',
|
||
'终检': '处理产品最终检验任务,登记检验数量、合格数量、不合格数量和检验结果。',
|
||
'采购入库检': '处理采购物料入库前检验,关联采购到货、物料和质量标准。',
|
||
'销售退货检': '处理销售退货物料的质量检验并记录判定结果。',
|
||
'原材料退库检': '处理原材料退库前检验,记录质量状态和处置依据。',
|
||
'序检收检': '处理工序间送检和收检任务,连接生产报工与后续工序放行。',
|
||
'质量检验标准': '查询和维护物料、工序对应的检验项目、标准和判定要求。',
|
||
'其他入库检': '处理非采购等其他来源的入库检验任务。',
|
||
'质检明细': '按订单、物料、检验类型和日期查询质量检验记录明细。',
|
||
'不合格品处置': '登记不合格品的评审、返工、让步、报废等处置结论并跟踪状态。',
|
||
'质检报工': '由检验人员执行开始、结束、送检和收验等质量任务操作并形成质检工时。',
|
||
'测试装配任务': '处理测试类装配和检验任务,记录执行数量、状态及结果。',
|
||
'及时检验报表': '统计检验任务是否按计划及时完成,支持责任和日期维度分析。',
|
||
'产品合格率(工位)': '按工位汇总检验数量、合格数量和合格率,用于质量绩效分析。',
|
||
'销售订单状态': '综合展示销售订单对应生产订单的计划、齐套、拣配、发料、装配、入库和发货状态。'
|
||
}
|
||
|
||
const moduleRelations = {
|
||
'设备管理': '上游使用系统工位、部门和设备主数据;设备能力和采集数据向工艺编制、计划排产、生产监控、异常分析提供设备依据。',
|
||
'研发管理': '上游使用人员、角色、项目、物料和附件;设计任务依次形成设计报工、工时校验和工时报表,并可为工艺、生产和项目跟踪提供设计进度。',
|
||
'工艺管理': '上游接收 SAP/MES 生产订单、物料、图纸和设备信息;输出标准工艺、生产工艺和工艺任务,供计划排产、生产执行与质量检验使用。',
|
||
'计划排产': '上游接收生产订单、物料、工艺路线、工位和人员;输出机加及装配任务、计划时间和优先级,供生产中心、异常提醒和齐套跟踪使用。',
|
||
'生产管理': '上游接收已排产任务、工艺、人员、工位和物料;执行结果形成报工、工时、异常、外协、送检和发货协同数据,向质量、报表和销售状态反馈。',
|
||
'异常提醒': '读取计划时间、实际开工、外协执行、加急标识和送检时间进行差异判断;结果供计划与生产人员跟进,不单独改变原业务单据。',
|
||
'质量管理': '上游接收采购到货、生产送检、退货、物料和质量标准;检验及处置结果反馈生产状态、库存入库、不合格品处理和质量统计。',
|
||
'销售订单管理': '汇总 SAP/MES 销售订单、生产订单、计划、齐套、拣配、发料、装配、入库和发货数据,形成面向订单的全流程状态视图。'
|
||
}
|
||
|
||
function normalizeText(value) {
|
||
return String(value || '')
|
||
.replace(/<!--[\s\S]*?-->/g, '')
|
||
.replace(/<[^>]+>/g, '')
|
||
.replace(/\{\{[^}]+\}\}/g, '')
|
||
.replace(/ /g, ' ')
|
||
.replace(/\s+/g, ' ')
|
||
.trim()
|
||
}
|
||
|
||
function unique(values, limit = 60) {
|
||
return [...new Set(values.map(normalizeText).filter(value => value && value.length <= 40))].slice(0, limit)
|
||
}
|
||
|
||
function extractSearchFields(template) {
|
||
const firstTable = template.search(/<el-table\b/i)
|
||
const prefix = firstTable >= 0 ? template.slice(0, firstTable) : template.slice(0, 12000)
|
||
const labels = []
|
||
const labelPatterns = [
|
||
/<el-form-item\b[^>]*\blabel=["']([^"']+)["'][^>]*>/gi,
|
||
/<span\b[^>]*>([^<]{1,40})<\/span>/gi,
|
||
/<label\b[^>]*>([^<]{1,40})<\/label>/gi
|
||
]
|
||
for (const pattern of labelPatterns) {
|
||
let match
|
||
while ((match = pattern.exec(prefix))) {
|
||
const label = normalizeText(match[1]).replace(/[::]$/, '')
|
||
if (label && !/^(至|表单|日程|首页)$/.test(label)) labels.push(label)
|
||
}
|
||
}
|
||
const placeholders = []
|
||
const placeholderPattern = /\bplaceholder=["']([^"']+)["']/gi
|
||
let match
|
||
while ((match = placeholderPattern.exec(prefix))) {
|
||
const value = normalizeText(match[1]).replace(/^(请输入|请选择|输入|选择)/, '')
|
||
if (value && value.length <= 30) placeholders.push(value)
|
||
}
|
||
return unique([...labels, ...placeholders], 30)
|
||
}
|
||
|
||
function extractButtons(template) {
|
||
const values = []
|
||
const pattern = /<(?:el-button|button)\b[^>]*>([\s\S]*?)<\/(?:el-button|button)>/gi
|
||
let match
|
||
while ((match = pattern.exec(template))) {
|
||
const value = normalizeText(match[1])
|
||
if (value && value.length <= 24) values.push(value)
|
||
}
|
||
return unique(values, 30)
|
||
}
|
||
|
||
function extractAttributes(template, tag, attribute, limit) {
|
||
const values = []
|
||
const pattern = new RegExp(`<${tag}\\b[^>]*\\b${attribute}=["']([^"']+)["'][^>]*>`, 'gi')
|
||
let match
|
||
while ((match = pattern.exec(template))) values.push(match[1])
|
||
return unique(values, limit)
|
||
}
|
||
|
||
function extractProcedures(source, importedSources) {
|
||
const read = []
|
||
const write = []
|
||
const directPattern = /CreateData\s*\(\s*["'](11|12)["']\s*,\s*["'`]([^"'`$]+)["'`]/g
|
||
let match
|
||
while ((match = directPattern.exec(source))) {
|
||
(match[1] === '11' ? read : write).push(match[2])
|
||
}
|
||
const apiPattern = /\bname\s*:\s*["'`]([^"'`$]+)["'`]/g
|
||
for (const apiSource of importedSources) {
|
||
while ((match = apiPattern.exec(apiSource))) {
|
||
if (/查询|获取|列表|状态|select/i.test(match[1])) read.push(match[1])
|
||
else write.push(match[1])
|
||
}
|
||
}
|
||
return { read: unique(read, 20), write: unique(write, 20) }
|
||
}
|
||
|
||
function readImportedApiSources(source) {
|
||
const sources = []
|
||
const pattern = /from\s+["']@\/api\/([^"']+)["']/g
|
||
let match
|
||
while ((match = pattern.exec(source))) {
|
||
const apiPath = path.join(root, 'src', 'api', `${match[1]}.js`)
|
||
if (fs.existsSync(apiPath)) sources.push(fs.readFileSync(apiPath, 'utf8'))
|
||
}
|
||
return sources
|
||
}
|
||
|
||
const catalog = []
|
||
let sequence = 0
|
||
for (let moduleIndex = 0; moduleIndex < modules.length; moduleIndex++) {
|
||
const module = modules[moduleIndex]
|
||
for (let pageIndex = 0; pageIndex < module.pages.length; pageIndex++) {
|
||
sequence++
|
||
const [title, route, relativeSource] = module.pages[pageIndex]
|
||
const sourcePath = path.join(root, 'src', 'views', relativeSource)
|
||
const source = fs.readFileSync(sourcePath, 'utf8')
|
||
const templateStart = source.indexOf('<template>')
|
||
const templateEnd = source.lastIndexOf('</template>')
|
||
const template = templateStart >= 0 && templateEnd > templateStart
|
||
? source.slice(templateStart + '<template>'.length, templateEnd)
|
||
: source
|
||
const procedures = extractProcedures(source, readImportedApiSources(source))
|
||
catalog.push({
|
||
sequence,
|
||
moduleIndex: moduleIndex + 1,
|
||
pageIndex: pageIndex + 1,
|
||
module: module.title,
|
||
title,
|
||
route,
|
||
source: relativeSource,
|
||
screenshot: `${String(moduleIndex + 1).padStart(2, '0')}-${String(pageIndex + 1).padStart(2, '0')}-${module.key}.png`,
|
||
purpose: purposes[title] || `用于处理${title}相关业务。`,
|
||
moduleRelation: moduleRelations[module.title],
|
||
searchFields: extractSearchFields(template),
|
||
tabs: extractAttributes(template, 'el-tab-pane', 'label', 20),
|
||
tableColumns: extractAttributes(template, 'el-table-column', 'label', 40),
|
||
buttons: extractButtons(template),
|
||
readProcedures: procedures.read,
|
||
writeProcedures: procedures.write
|
||
})
|
||
}
|
||
}
|
||
|
||
fs.writeFileSync(outputPath, JSON.stringify(catalog, null, 2), 'utf8')
|
||
console.log(`Generated ${catalog.length} page records: ${outputPath}`)
|