someone-oa/enhance_prd.py
2025-12-11 15:21:16 +08:00

441 lines
19 KiB
Python
Raw Permalink 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.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
在现有PRD基础上补充完善内容
"""
from docx import Document
from docx.shared import Pt, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import os
def add_enhanced_sections(doc):
"""添加增强的章节内容"""
# ========== 10. 审核流程详细说明 ==========
doc.add_page_break()
doc.add_heading('10. 审核流程详细说明', 1)
doc.add_heading('10.1 审核角色定义', 2)
doc.add_paragraph('系统需支持以下审核角色:')
roles = [
('部门负责人', '审核本部门员工提交的立项申请、启动申请等,一级审核节点'),
('经营管理部', '审核立项申请、启动申请等,二级审核节点'),
('组长', '审核执业工程师提交的项目成果(初稿、对账、最终成果)'),
('总经理(王总)', '审核立项申请、启动申请、成果等,最终审核节点'),
('总经理(戚总)', '审核最终成果,最终审核节点'),
('财务', '审核开票申请'),
('出纳', '执行请款放款操作')
]
table = doc.add_table(rows=1, cols=2)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '角色'
hdr[1].text = '职责说明'
for role, desc in roles:
row = table.add_row().cells
row[0].text = role
row[1].text = desc
doc.add_heading('10.2 审核流程规则', 2)
doc.add_heading('10.2.1 立项审核流程', 3)
doc.add_paragraph('1. 申请人提交立项申请')
doc.add_paragraph('2. 系统自动流转至经营管理部(部门负责人)')
doc.add_paragraph('3. 经营管理部审核通过后,自动流转至总经理')
doc.add_paragraph('4. 总经理审核通过后,项目状态变为"已立项"')
doc.add_paragraph('5. 任一环节审核驳回,流程终止,申请人可修改后重新提交')
doc.add_paragraph('6. 审核超时处理超过3个工作日未审核系统发送提醒通知')
doc.add_heading('10.2.2 启动审核流程', 3)
doc.add_paragraph('流程与立项审核类似:经营管理部 → 总经理')
doc.add_heading('10.2.3 成果审核流程', 3)
doc.add_paragraph('1. 初稿/对账审核流程:')
doc.add_paragraph(' • 执业工程师提交成果(初稿或对账)')
doc.add_paragraph(' • 多人同时提交时,需等待所有人员提交完成')
doc.add_paragraph(' • 组长审核所有提交的成果')
doc.add_paragraph(' • 组长审核通过后,流转至领导(王总)审核')
doc.add_paragraph(' • 审核通过后,状态更新')
doc.add_paragraph('2. 最终成果审核流程:')
doc.add_paragraph(' • 执业工程师提交最终成果')
doc.add_paragraph(' • 多人同时提交时,需等待所有人员提交完成')
doc.add_paragraph(' • 组长审核所有提交的成果')
doc.add_paragraph(' • 组长审核通过后,流转至领导(王总、戚总)审核')
doc.add_paragraph(' • 审核通过后,状态更新为"最终成果已确认"')
doc.add_heading('10.2.4 审核流程配置', 3)
doc.add_paragraph('系统需支持审核流程的配置化,包括:')
items = [
'审核节点可配置(可增加或减少审核节点)',
'审核人可配置(可指定特定人员或角色)',
'审核条件可配置(如金额超过阈值需额外审核)',
'审核超时时间可配置',
'审核提醒规则可配置'
]
for item in items:
doc.add_paragraph(item, style='List Bullet')
doc.add_heading('10.3 审核记录要求', 2)
doc.add_paragraph('所有审核操作需记录以下信息:')
items = [
'审核时间',
'审核人',
'审核意见(通过/驳回)',
'审核备注(驳回原因等)',
'审核节点',
'审核顺序'
]
for item in items:
doc.add_paragraph(item, style='List Bullet')
doc.add_paragraph('审核记录不可修改,支持查询和导出。')
# ========== 11. 附件管理详细规则 ==========
doc.add_page_break()
doc.add_heading('11. 附件管理详细规则', 1)
doc.add_heading('11.1 附件类型限制', 2)
doc.add_paragraph('系统支持以下附件格式:')
formats = [
'文档类PDF、Word.doc, .docx、Excel.xls, .xlsx',
'图片类JPG、PNG、GIF',
'压缩包ZIP、RAR需解压后查看'
]
for fmt in formats:
doc.add_paragraph(fmt, style='List Bullet')
doc.add_heading('11.2 附件大小限制', 2)
doc.add_paragraph('单个附件大小限制:')
doc.add_paragraph('• 单个文件不超过50MB')
doc.add_paragraph('• 单个单据附件总大小不超过200MB')
doc.add_paragraph('• 超过限制时,系统提示并阻止上传')
doc.add_heading('11.3 附件存储规则', 2)
doc.add_paragraph('• 附件存储在服务器,支持分布式存储')
doc.add_paragraph('• 附件需定期备份,防止数据丢失')
doc.add_paragraph('• 附件命名规则项目编号_附件类型_上传时间_文件名')
doc.add_paragraph('• 附件访问权限:仅相关审核人和申请人可查看和下载')
doc.add_heading('11.4 附件下载规则', 2)
doc.add_paragraph('• 支持在线预览PDF、图片等')
doc.add_paragraph('• 支持批量下载')
doc.add_paragraph('• 下载需记录日志(谁、何时、下载了哪些附件)')
# ========== 12. 状态流转完整说明 ==========
doc.add_page_break()
doc.add_heading('12. 状态流转完整说明', 1)
doc.add_heading('12.1 项目状态定义', 2)
states = [
('待提交', '立项申请已保存但未提交'),
('待审核', '已提交,等待审核'),
('审核中', '正在审核流程中'),
('已立项', '立项审核通过'),
('投标中', '项目处于投标阶段'),
('已中标', '投标成功'),
('已签合同', '已签订合同'),
('已启动', '项目已启动执行'),
('执行中', '项目正在执行'),
('初稿已完成', '初稿已提交并审核通过'),
('对账中', '正在对账阶段'),
('对账完成', '对账已完成'),
('最终成果已完成', '最终成果已提交并审核通过'),
('已开票', '已申请开票并完成开票'),
('已回款', '款项已收到'),
('已完成', '项目全部完成'),
('已驳回', '审核被驳回'),
('已取消', '项目已取消')
]
table = doc.add_table(rows=1, cols=2)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '状态'
hdr[1].text = '说明'
for state, desc in states:
row = table.add_row().cells
row[0].text = state
row[1].text = desc
doc.add_heading('12.2 状态流转规则', 2)
doc.add_paragraph('1. 状态只能按既定流程流转,不可跳过中间状态')
doc.add_paragraph('2. 状态流转需触发相应通知')
doc.add_paragraph('3. 部分状态可回退(如"已驳回"可修改后重新提交)')
doc.add_paragraph('4. 特殊状态说明:')
doc.add_paragraph('"已立项"后可直接变为"已启动"(跳过投标和合同)')
doc.add_paragraph('"已签合同"后必须变为"已启动"才能继续后续流程')
doc.add_paragraph('"已启动"后根据项目类型进入不同的成果提交流程')
# ========== 13. 消息通知机制 ==========
doc.add_page_break()
doc.add_heading('13. 消息通知机制', 1)
doc.add_heading('13.1 通知触发条件', 2)
triggers = [
('审核待办', '有新的审核任务时,通知审核人'),
('审核结果', '审核通过或驳回时,通知申请人'),
('流程流转', '流程流转到下一节点时,通知相关人'),
('对账差异提醒', '初稿金额与对账金额差异超过阈值时,通知相关人员'),
('回款提醒', '项目达到回款条件时,提醒商务人员'),
('请款提醒', '请款申请审核通过后,提醒出纳'),
('项目状态变更', '项目状态发生重要变更时,通知相关人员'),
('系统提醒', '系统维护、升级等通知所有用户')
]
table = doc.add_table(rows=1, cols=2)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '通知类型'
hdr[1].text = '触发条件'
for trigger, condition in triggers:
row = table.add_row().cells
row[0].text = trigger
row[1].text = condition
doc.add_heading('13.2 通知方式', 2)
doc.add_paragraph('系统支持以下通知方式:')
methods = [
'站内消息(系统内消息中心)',
'邮件通知(发送至用户注册邮箱)',
'短信通知(重要通知,需配置短信接口)',
'移动端推送(移动端应用推送通知)',
'桌面提醒PC端桌面弹窗提醒'
]
for method in methods:
doc.add_paragraph(method, style='List Bullet')
doc.add_paragraph('用户可在个人设置中选择接收通知的方式。')
doc.add_heading('13.3 通知模板', 2)
doc.add_paragraph('系统需提供通知模板配置功能,支持自定义通知内容模板。')
doc.add_paragraph('示例模板:')
doc.add_paragraph('【审核待办】您有一个待审核的立项申请:项目编号{project_no},项目名称{project_name},请及时处理。')
doc.add_paragraph('【审核结果】您的立项申请({project_no})已通过/驳回,驳回原因:{reject_reason}')
# ========== 14. 数据权限详细说明 ==========
doc.add_page_break()
doc.add_heading('14. 数据权限详细说明', 1)
doc.add_heading('14.1 查看权限', 2)
doc.add_paragraph('数据查看权限分为三个层级:')
levels = [
('个人数据', '仅查看自己创建或参与的数据', '普通员工查看自己提交的申请、自己参与的项目等'),
('部门数据', '查看本部门所有数据', '部门负责人可查看本部门所有项目数据'),
('全部数据', '查看公司所有数据', '总经理、系统管理员可查看所有数据')
]
table = doc.add_table(rows=1, cols=3)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '权限层级'
hdr[1].text = '权限范围'
hdr[2].text = '适用角色'
for level, scope, role in levels:
row = table.add_row().cells
row[0].text = level
row[1].text = scope
row[2].text = role
doc.add_heading('14.2 编辑权限', 2)
doc.add_paragraph('数据编辑权限规则:')
rules = [
'申请人可编辑自己提交的未审核数据',
'审核人可编辑审核意见,但不可编辑原始申请数据',
'项目负责人可编辑自己负责的项目信息',
'执业工程师可编辑自己负责的项目成果',
'财务人员可编辑财务相关数据(开票金额、回款金额等)',
'系统管理员可编辑所有数据(需有操作日志)'
]
for rule in rules:
doc.add_paragraph(rule, style='List Bullet')
doc.add_heading('14.3 删除权限', 2)
doc.add_paragraph('删除权限严格控制:')
doc.add_paragraph('• 普通用户只能删除自己创建的草稿数据(未提交状态)')
doc.add_paragraph('• 已提交的数据不可删除,只能取消或作废')
doc.add_paragraph('• 系统管理员可删除数据,但需记录详细日志')
doc.add_paragraph('• 删除操作需二次确认,防止误操作')
# ========== 15. 异常场景处理 ==========
doc.add_page_break()
doc.add_heading('15. 异常场景处理', 1)
doc.add_heading('15.1 审核人异常', 2)
scenarios = [
('审核人离职', '管理员重新分配审核人,或由上级代为审核'),
('审核人请假', '支持设置代理审核人,或自动流转至上级'),
('审核人账号禁用', '自动流转至上级或管理员重新分配'),
('审核超时', '系统发送提醒,超过期限自动流转至上级或管理员处理')
]
table = doc.add_table(rows=1, cols=2)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '异常场景'
hdr[1].text = '处理方案'
for scenario, solution in scenarios:
row = table.add_row().cells
row[0].text = scenario
row[1].text = solution
doc.add_heading('15.2 数据异常', 2)
doc.add_paragraph('数据异常处理:')
items = [
'数据不一致:如立项金额与合同金额差异过大,系统提示并阻止操作',
'编号重复:系统自动检测并重新生成编号',
'关联数据丢失:如立项项目被删除,启动单显示关联异常,需管理员处理',
'计算错误:产值、费用计算异常时,系统记录日志并提示管理员'
]
for item in items:
doc.add_paragraph(item, style='List Bullet')
doc.add_heading('15.3 系统异常', 2)
doc.add_paragraph('系统异常恢复:')
doc.add_paragraph('• 系统宕机恢复后,自动恢复未完成的操作')
doc.add_paragraph('• 数据备份恢复:支持按时间点恢复数据')
doc.add_paragraph('• 操作日志:所有关键操作记录日志,便于问题追溯')
doc.add_paragraph('• 异常监控:系统监控异常情况,及时告警')
# ========== 16. 报表导出格式 ==========
doc.add_page_break()
doc.add_heading('16. 报表导出格式', 1)
doc.add_heading('16.1 Excel导出格式', 2)
doc.add_paragraph('Excel导出要求')
items = [
'文件格式:.xlsx',
'文件命名报表名称_导出时间.xlsx',
'工作表命名:使用中文,清晰表达内容',
'表头格式:第一行为表头,加粗显示,背景色区分',
'数据格式数字格式统一日期格式统一YYYY-MM-DD',
'列宽自适应:自动调整列宽,确保内容完整显示',
'支持分页:大数据量自动分多个工作表',
'冻结首行:导出后首行冻结,方便查看'
]
for item in items:
doc.add_paragraph(item, style='List Bullet')
doc.add_heading('16.2 PDF导出格式', 2)
doc.add_paragraph('PDF导出要求可选功能')
items = [
'文件格式:.pdf',
'页面设置A4纸张横向或纵向根据内容自动选择',
'页眉页脚:包含报表名称、导出时间、页码',
'样式统一:使用统一的字体、颜色、样式',
'支持打印导出PDF可直接打印'
]
for item in items:
doc.add_paragraph(item, style='List Bullet')
# ========== 17. 移动端详细功能 ==========
doc.add_page_break()
doc.add_heading('17. 移动端详细功能', 1)
doc.add_heading('17.1 移动端可用功能', 2)
doc.add_paragraph('移动端支持以下功能:')
available = [
('待办事项', '查看待审核事项,快速审核(通过/驳回)'),
('消息通知', '接收系统通知、审核提醒等'),
('项目查询', '查询项目基本信息、状态等(简化版)'),
('成果提交', '提交项目成果,上传附件(小文件)'),
('简单报表', '查看关键数据报表(产值、回款等汇总)'),
('个人信息', '查看个人信息、修改密码等')
]
table = doc.add_table(rows=1, cols=2)
table.style = 'Light Grid Accent 1'
hdr = table.rows[0].cells
hdr[0].text = '功能'
hdr[1].text = '说明'
for func, desc in available:
row = table.add_row().cells
row[0].text = func
row[1].text = desc
doc.add_heading('17.2 移动端不可用功能', 2)
doc.add_paragraph('以下功能仅在PC端可用')
unavailable = [
'复杂报表查询和导出(移动端仅查看简化版)',
'批量操作(批量审核、批量导出等)',
'大文件上传移动端限制单文件10MB以内',
'组织架构管理、账号管理等系统设置',
'详细的数据分析功能'
]
for item in unavailable:
doc.add_paragraph(item, style='List Bullet')
doc.add_heading('17.3 移动端界面要求', 2)
doc.add_paragraph('移动端界面需满足以下要求:')
requirements = [
'响应式设计,适配不同尺寸手机屏幕',
'操作简洁,核心功能一键直达',
'支持横屏和竖屏切换',
'网络异常时提示并支持离线查看缓存数据',
'支持手势操作(滑动、长按等)',
'性能优化,页面加载快速'
]
for req in requirements:
doc.add_paragraph(req, style='List Bullet')
# ========== 18. 系统集成要求 ==========
doc.add_page_break()
doc.add_heading('18. 系统集成要求(可选)', 1)
doc.add_paragraph('系统需考虑未来可能的集成需求:')
integrations = [
'与财务系统集成:同步财务数据',
'与OA系统集成统一待办、消息通知',
'与邮件系统集成:发送邮件通知',
'与短信平台集成:发送短信通知',
'与第三方存储集成如阿里云OSS、腾讯云COS等',
'提供API接口供其他系统调用'
]
for item in integrations:
doc.add_paragraph(item, style='List Bullet')
doc.add_paragraph('注:集成需求需在开发阶段提前规划接口设计。')
def main():
print("正在读取现有文档...")
input_file = "需求文档_详细版.docx"
if not os.path.exists(input_file):
print(f"错误:找不到文件 {input_file}")
print("请先运行 generate_detailed_prd.py 生成基础文档")
return
doc = Document(input_file)
print("正在补充完善内容...")
add_enhanced_sections(doc)
output_file = "需求文档_完整版.docx"
doc.save(output_file)
print(f"✓ 文档完善成功!")
print(f" 输入文件: {input_file}")
print(f" 输出文件: {output_file}")
print(f" 新增内容:")
print(f" - 审核流程详细说明")
print(f" - 附件管理详细规则")
print(f" - 状态流转完整说明")
print(f" - 消息通知机制")
print(f" - 数据权限详细说明")
print(f" - 异常场景处理")
print(f" - 报表导出格式")
print(f" - 移动端详细功能")
print(f" - 系统集成要求")
if __name__ == "__main__":
main()