十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

资产管理系统需求分析文档:YAML生成PDF与反向解析校验

资产管理系统需求分析文档:YAML生成PDF与反向解析校验 简介这份PDF文档围绕资产管理系统的需求分析展开面向软件工程课程设计、毕业设计以及企业信息化项目的前期调研人员帮助读者厘清资产管理系统从立项到落地应覆盖的功能边界与约束条件。内容以需求规格说明的方式系统梳理了基于900M外部射频识别设备与C/S模式的系统总体要求、建设目标、开发平台与语言选型并细化到用户管理、资产管理、资产查询三大功能模块以及权限分级、数据备份、资产实时核查等安全性设计同时给出高效性、安全性、可靠性、扩展性四项设计原则以及需求分析、系统设计、开发、测试、实施、维护的完整实施步骤可直接当作需求文档模板或需求梳理清单参考。资源共1个PDF文件压缩包约154KB篇幅精简便于快速通读。目前已有225人学习适合作为需求分析写作与系统设计答辩阶段的参考资料。1. 资产管理系统的需求分析文档为什么最后总是一份 PDF接手一套资产管理系统最容易被低估的交付物不是代码而是那份叫《资产管理系统需求分析文档》的 PDF。它同时扮演三个角色给业务方确认范围、给开发当接口契约、给测试当追溯源头。需求评审会开完谁也不会拿一份在线表格去当基线PDF 是唯一敢直接附在邮件和会议纪要里的格式——对方少装一个编辑器也不会排版错乱多打几次印也不会因为 Word 版本差异把表格挤飞。适合看这篇的人有三类正在做资产管理从零到一的需求分析师、被拉去兼需求的开发、以及要把这份 PDF 当输入去做 pdf 解析或一致性校验的技术同学。后面的路径是先统一「资产」这个词的口径把需求拆成可编号可追溯的条目再用可复现的方式生成 PDF然后反向解析 PDF 做校验最后映射到台账表结构和验收标准。每一步都给能直接跑的命令和参数。2. 资产管理系统的需求边界拆分与条目化编码需求文档写崩多半不是文笔问题而是「资产」这个词在各部门口径里根本不是一回事。财务说资产是固定资产卡片IT 说资产是带序列号的设备行政说资产是工位和办公家具。写需求分析文档的第一件事是把这三种口径收敛到一条主线上否则后面每一条需求都会在评审会上被重新定义一次。2.1 把资产全生命周期拆成可验收的需求主线主线通常长这样采购申请 → 入库建卡 → 领用/借用 → 调拨 → 维修保养 → 盘点 → 折旧 → 处置报废。注意这不是流程图装饰每个环节都要在需求文档里回答四个问题谁发起、谁审批、资产状态怎么变、留下哪几条记录。最省事的写法是把状态机和字段绑在一张表里评审时逐行过争议当场收敛。阶段触发角色资产状态变化必须留痕的字段常见遗漏采购申请需求部门无 → 待入库申请单号、预算科目、期望到货日未关联采购合同号入库建卡资产管理员待入库 → 在用/闲置资产编码、SN、购置日期、原值SN 允许重复领用借用部门主管闲置 → 在用使用人、部门、领用时间、归还期限借用与领用混为一谈调拨调出/调入双方主管在用A 部门→ 在用B 部门调出部门、调入部门、审批单号没有「在途」中间态维修保养资产管理员在用 → 维修中 → 在用故障描述、承修方、费用、停机天数维修期间折旧是否停计提盘点盘点小组状态不变产出盘点结果盘点批次、实盘位置、差异原因盘盈资产无来源单号折旧系统定时任务状态不变累计折旧更新折旧方法、残值率、会计期间手工调整无操作痕迹处置报废资产管理员 财务在用 → 已处置处置方式、残值回收金额、审批链报废后仍可被领用这张表本身就是需求文档的核心章节它比任何一段描述性文字都好用开发照着建状态枚举测试照着设计状态迁移用例业务方照着确认没有漏环节。2.2 需求条目编号规则与优先级矩阵PDF 一旦定稿就不方便改所以编号是 PDF、源数据文件和测试用例之间唯一的锚点。常见做法是RQ-模块-三位序号例如RQ-AST-001表示资产台账模块第一条。模块码固定两到四个大写字母序号不允许跳号复用条目作废时保留编号并标注「已废弃」这样 pdf 解析脚本做差异比对时不会把删除误判成新增。优先级建议用 MoSCoW 四档并且强制每条 Must 都要写验收方式。没有验收方式的需求条目本质上是需求分析阶段的负债。编号需求条目优先级验收方式关联状态RQ-AST-001资产编码全局唯一支持条码/二维码打印Must导入 10000 行含 3 行重复编码应拒绝 3 行并输出行号入库建卡RQ-AST-002调拨需双方主管审批后方可生效Must单边审批时资产仍归属调出部门调拨RQ-AST-003盘点支持按批次冻结账面数据Should盘点期间新增资产不计入本批次盘点RQ-AST-004折旧支持年限平均法与工作量法Must同一资产两种方法月折旧额差异符合公式折旧RQ-AST-005借用超期自动提醒使用人与部门主管Could到期前 3 天生成提醒记录领用借用RQ-AST-006处置报废后禁止任何领用出口调用Must直接调接口应返回业务异常码处置报废RQ-AST-007资产变更历史只增不改不删Must数据库层无 update/delete 权限全阶段2.3 非功能需求在资产场景里的硬约束资产系统的非功能需求很容易被写成「系统应稳定可靠」这类废话评审时没人反对上线后没人认账。改成带数字的写法才有约束力比如「盘点任务支持 500 个客户端并发提交单次提交 P95 响应时间小于 800ms」「资产变更日志保留不少于 10 年且不可物理删除」。还有几类必须写进需求文档一是数据迁移历史台账往往分散在 Excel 和多套老系统里要明确字段映射和不允许丢失的字段清单二是权限粒度资产系统常被要求到字段级比如普通员工能看资产名称但不能看原值三是导出与打印财务对 pdf 打印和 Excel 导出的表头、合计行、页脚签字栏都有固定格式要求这类格式需求不写清验收时一定返工。提示非功能需求写在正文里容易被忽略建议在需求文档中单列一节并把每条数字指标写成可测量的句子便于后续直接转成压测脚本的断言。3. 用 Python 从结构化源生成《资产管理系统需求分析文档》PDF手工在 Word 里排需求文档最大的问题是改一条需求要重新调一次表格。更稳的做法是把需求条目当成数据维护PDF 只是渲染结果。这样需求变更走的是 diff评审看的还是同一份 PDF。3.1 需求条目用 YAML 维护PDF 只做呈现# requirements.yaml —— 需求条目的唯一数据源PDF 与测试用例都由它派生 project: 资产管理系统需求分析文档 version: 1.3.0 modules: - code: AST name: 资产台账 items: - id: RQ-AST-001 title: 资产编码唯一性校验 priority: Must desc: 新增与导入资产时按资产编码做唯一约束冲突需返回逐行错误详情。 acceptance: 导入 10000 行含 3 行重复编码应成功 9997 行并输出错误行号 state: 入库建卡 - id: RQ-AST-002 title: 调拨双边审批 priority: Must desc: 调拨单需调出与调入部门主管均审批通过后资产归属才发生变更。 acceptance: 仅单边审批时资产仍归属调出部门 state: 调拨这份 YAML 的字段设计和上一节的优先级矩阵是一一对应的id是锚点acceptance是可执行的验收句state把条目挂回状态机。字段一旦定下来就别轻易改因为解析脚本和比对脚本都依赖它。3.2 用 reportlab 生成带编号表格的中文 PDF# build_req_pdf.py import yaml from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import ParagraphStyle from reportlab.lib.units import mm from reportlab.lib import colors from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle) # 注册中文字体字体必须嵌入否则在只读 pdf 阅读器里会变成方框 pdfmetrics.registerFont( TTFont(CN, /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc, subfontIndex0) ) BODY ParagraphStyle(body, fontNameCN, fontSize10.5, leading16) H1 ParagraphStyle(h1, fontNameCN, fontSize16, leading24, spaceAfter8) CELL ParagraphStyle(cell, fontNameCN, fontSize8, leading12) def build(yaml_path: str, out_pdf: str) - None: doc yaml.safe_load(open(yaml_path, encodingutf-8)) flow [Paragraph(doc[project], H1), Paragraph(版本 %s % doc[version], BODY), Spacer(1, 8 * mm)] for mod in doc[modules]: flow.append(Paragraph(%s %s % (mod[code], mod[name]), H1)) data [[编号, 需求描述, 优先级, 验收方式, 状态]] for it in mod[items]: data.append([ Paragraph(it[id], CELL), Paragraph(%s%s % (it[title], it[desc]), CELL), Paragraph(it[priority], CELL), Paragraph(it[acceptance], CELL), Paragraph(it[state], CELL), ]) # 列宽合计 174mm等于 A4 宽 210mm 减去左右各 18mm 页边距 t Table(data, colWidths[24 * mm, 60 * mm, 14 * mm, 56 * mm, 20 * mm], repeatRows1) t.setStyle(TableStyle([ (GRID, (0, 0), (-1, -1), 0.4, colors.grey), (VALIGN, (0, 0), (-1, -1), TOP), (BACKGROUND, (0, 0), (-1, 0), colors.whitesmoke), (LEFTPADDING, (0, 0), (-1, -1), 3), ])) flow [t, Spacer(1, 6 * mm)] SimpleDocTemplate( out_pdf, pagesizeA4, leftMargin18 * mm, rightMargin18 * mm, topMargin20 * mm, bottomMargin18 * mm, titledoc[project], author需求分析组, ).build(flow) if __name__ __main__: build(requirements.yaml, 资产管理系统需求分析文档.pdf)这段代码的关键点有三个。registerFont把中文字体注册进 PDF 资源池subfontIndex0用于 ttc 集合字体不写会报字体索引错误。表格单元格里用Paragraph而不是裸字符串长需求描述才能自动换行否则会横向撑破版心。repeatRows1让表头在跨页时重复出现需求条目一多必然跨页没有这行参数打出来的 PDF 第二页就没有表头评审时极易看错列。colWidths合计必须小于版心宽度A4 是 210mm 宽左右各留 18mm可用宽度 174mm这里按 2460145620 分配刚好占满。想加「负责人」一列就把验收方式列从 56mm 压到 46mm不要直接调大总宽。3.3 中文字体注册与页眉页脚怎么调页眉页脚用页面回调实现比在正文里手工插页码可靠def on_page(canvas, doc): canvas.saveState() canvas.setFont(CN, 8) canvas.drawString(18 * mm, 12 * mm, 资产管理系统需求分析文档 · 内部评审稿) canvas.drawRightString(A4[0] - 18 * mm, 12 * mm, 第 %d 页 % doc.page) canvas.restoreState() # 传参方式首页和后续页都挂同一个回调 SimpleDocTemplate(out_pdf, pagesizeA4, onFirstPageon_page, onLaterPageson_page).build(flow)canvas.saveState()与restoreState()成对出现保证字号颜色不会污染后续绘制。doc.page是 reportlab 在构建过程中自动累加的页码首页一样从 1 开始。如果需求文档要放进保密评审流程建议页眉带上版本号例如「V1.3.0 内部评审稿」避免旧版 PDF 被当成基线继续传阅。3.4 交付前检查字体嵌入、打印与归档格式生成完别直接发出去先做一次字体体检# 检查字体是否嵌入emb 列必须全为 yes pdffonts 资产管理系统需求分析文档.pdf # 把 PDF 转成图片快速翻页确认没有方框字和串行 pdftoppm -r 100 -png 资产管理系统需求分析文档.pdf /tmp/req_pagepdffonts的emb列为no时说明字体没被嵌入换一台没装该字体的机器打开就是一堆方框pdf 阅读器再强也救不回来。pdftoppm的-r是渲染分辨率检查排版用 100 就够检查小字号表格用 150。还有两个容易踩的点一是需求文档若要走印刷归档印厂会要求 pdf 转曲但内部评审完全不需要转曲转曲后反而没法再搜索文字后续 pdf 解析全部失效二是带批注的评审版和干净版要分开输出批注层会混进文本抽取结果让比对脚本误报。4. 反向解析需求分析文档 PDF 做一致性校验PDF 发出去之后真正危险的不是排版而是「源数据改过、PDF 没重新生成」。评审会上大家对着旧 PDF 讨论半天最后一开发发现源文件里那条需求已经被改成 Should 了。因此需要一条反向校验链路从 PDF 抽需求编号跟 YAML 源比对。4.1 用 pdfplumber 抽取正文与表格里的需求编号# check_req_pdf.py import re import yaml import pdfplumber ID_RE re.compile(rRQ-[A-Z]{2,4}-\d{3}) def collect_from_pdf(path: str) - dict: found {} with pdfplumber.open(path) as pdf: for page in pdf.pages: # 裁掉上下页边距避免页眉页码混进正文影响比对 bbox (0, 40, page.width, page.height - 30) text page.crop(bbox).extract_text(layoutTrue) or for rid in ID_RE.findall(text): found[rid] found.get(rid, 0) 1 # 表格线清晰时优先走表格抽取单元格边界更准 for table in page.extract_tables(): for row in table: if row and row[0] and ID_RE.fullmatch((row[0] or ).strip()): rid row[0].strip() found[rid] found.get(rid, 0) 0 # 只登记存在性 found.setdefault(rid, 0) return found def collect_from_source(path: str) - set: doc yaml.safe_load(open(path, encodingutf-8)) return {it[id] for m in doc[modules] for it in m[items]} if __name__ __main__: src collect_from_source(requirements.yaml) pdf_ids collect_from_pdf(资产管理系统需求分析文档.pdf) print(源条目数:, len(src), PDF 命中:, len(pdf_ids)) print(PDF 缺失:, sorted(src - set(pdf_ids))) print(PDF 多出疑似过期条目:, sorted(set(pdf_ids) - src))extract_text(layoutTrue)会按视觉位置保留列间距表格文字不会被压成一行代价是每行可能多出若干空格所以正则只匹配编号本身不匹配整行。page.crop传入的 bbox 是相对页面左上角的坐标上边距切 40、下边距切 30正好把页眉页脚挡在抽取范围外。两边结果取差集就是校验结论src - pdf_ids是漏进 PDF 的新需求set(pdf_ids) - src是被删掉但还留在 PDF 里的旧条目。这两类差异任一非空就说明 PDF 与源数据不同步必须重新生成后再评审。4.2 解析失败的六种典型现象与处理pdf 解析在真实文档上翻车基本集中在下面这几类。排查顺序建议先看文本层有没有再看字体最后调抽取参数。现象根因处理方式编号只能抓到一半表格无边框线行被合并成一段extract_table传{vertical_strategy: text, horizontal_strategy: text}中文全部乱码生成时未嵌入字体或字体子集异常用pdffonts确认 emb 列重新用嵌入字体生成中文变方框pdf 阅读器缺字体且文档未嵌入同上根源在生成端而非读取端数字与中文错位单元格内容换行导致列偏移加大该列colWidths或调大x_tolerance整页抽不出文字图片型扫描件没有文本层走 OCR 兜底别指望 pdf 转 word 能保住结构页眉混进正文页眉页脚参与了文本抽取用page.crop排除上下边距extract_table的x_tolerance默认值偏保守中英混排的窄列容易把「RQ-AST-001」拆成两段调到 3 到 5 之间多数情况能救回来。但如果表格本身没有线条靠调参数是治标正确做法是回到生成端把表格样式补上边框线。4.3 扫描件、歪斜纠偏与格式转换的边界线下签字回来的 PDF 大多是拍照或扫描件这时候 pdf 解析的第一道坎是文本层缺失。可行的兜底路径是先做 pdf 歪斜校正纠偏再走 OCR 识别再按编号正则抽取。纠偏之所以必要是因为倾斜超过两三度后OCR 会把同一行的编号和描述识别成两行抽取结果的顺序全乱。至于用 pdf 转 word 再解析我的建议是只在人工核对场景用。转换工具为了让版面好看会把表格拆成一堆文本框文本顺序和阅读顺序不再一致自动化脚本拿到的是一个语义已经丢失的中间产物。同理用 pdf 编辑器在成品 PDF 上直接改需求条目是最不推荐的做法改完源数据没同步下一轮比对必然失败而且改的人是看不见这次改动的历史的。注意校验脚本要固定跑在 CI 或提交钩子里人工点一下跑一次等于没跑。5. 需求条目落到资产台账表结构与追溯矩阵5.1 从需求编号映射到表字段需求文档写得再漂亮落不到字段就是空谈。映射规则很简单每条 Must 级需求至少要指向一个表字段或一条约束。资产主表的字段应当只保留需求里明确要求留痕的内容避免先建表后补需求。-- 资产主表字段顺序与 2.1 状态机表一一对应 CREATE TABLE asset ( asset_code VARCHAR(32) PRIMARY KEY, -- RQ-AST-001 全局唯一编码 sn VARCHAR(64), status VARCHAR(16) NOT NULL, -- 取值来自状态机枚举禁止自由文本 dept_id BIGINT NOT NULL, -- RQ-AST-002 调拨后由双边审批更新 user_id BIGINT, purchase_date DATE, original_value DECIMAL(14,2), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_sn (sn) -- 序列号唯一避免重复建卡 ); -- 需求追溯表把编号、字段、用例绑在一起验收时逐行核销 CREATE TABLE req_trace ( req_id VARCHAR(24) PRIMARY KEY, -- RQ-XXX-000 module VARCHAR(32), table_name VARCHAR(64), column_name VARCHAR(64), test_case VARCHAR(64), status VARCHAR(16) -- 已实现 / 待确认 / 已变更 );uk_sn这个唯一索引是有意加的需求文档里若只写了「资产编码唯一」实现阶段很容易漏掉序列号结果是同型号设备重复建卡盘点时账面数量永远对不上。status用VARCHAR而不是枚举类型是为了让状态机扩展不用改表结构但要在应用层用常量约束不能允许手写字符串。req_trace的status字段是变更管理的抓手。需求从 Must 降级成 Could、或者字段改名都先在这里留一条记录再回头改 PDF顺序反了就会丢掉变更原因。5.2 用追溯矩阵收口验收验收阶段直接查追溯表就能拉出矩阵比对着 PDF 一页页翻快得多需求编号落库位置验收用例状态RQ-AST-001asset.asset_code / uk_snTC-ASSET-IMPORT-001已实现RQ-AST-002asset.dept_id 审批流TC-ASSET-TRANSFER-002已实现RQ-AST-003盘点批次快照表TC-ASSET-STOCK-001待确认RQ-AST-006领用出口前置校验TC-ASSET-DISPOSE-003已实现RQ-AST-007变更历史 append-onlyTC-ASSET-LOG-001待确认跑校验脚本时顺手把这张表也晾一遍-- 找出已标记实现但没有验收用例的需求这类条目最容易被漏测 SELECT req_id, module, column_name FROM req_trace WHERE status 已实现 AND (test_case IS NULL OR test_case );排查口径上任何一行「验收方式」为空先别签字任何一行column_name为空但状态是「已实现」说明这条需求只做了界面没落数据属于典型的口头实现。追溯矩阵的价值不在于表格好看而在于它是唯一能同时对上 PDF、代码和测试用例的东西。本文还有配套的精品资源点击获取
返回列表