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

514 lines
23 KiB
Python
Raw 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 -*-
"""
生成OA系统项目报价文档
"""
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from datetime import datetime, timedelta
from docx.oxml.ns import qn
def set_chinese_font(run, font_name='宋体'):
"""设置中文字体"""
run.font.name = font_name
run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
def add_section_title(doc, text, level=1):
"""添加章节标题"""
heading = doc.add_heading(text, level=level)
return heading
def add_formatted_paragraph(doc, text, bold=False, align=None):
"""添加格式化的段落"""
p = doc.add_paragraph()
if align == 'center':
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
elif align == 'right':
p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
run = p.add_run(text)
if bold:
run.bold = True
set_chinese_font(run)
return p
def add_table_with_header(doc, headers, data, style='Light Grid Accent 1'):
"""创建带表头的表格"""
table = doc.add_table(rows=1, cols=len(headers))
table.style = style
# 添加表头
hdr_cells = table.rows[0].cells
for i, header in enumerate(headers):
hdr_cells[i].text = header
# 表头加粗
for paragraph in hdr_cells[i].paragraphs:
for run in paragraph.runs:
run.bold = True
set_chinese_font(run)
# 添加数据行
for row_data in data:
row_cells = table.add_row().cells
for i, cell_data in enumerate(row_data):
row_cells[i].text = str(cell_data)
# 设置中文字体
for paragraph in row_cells[i].paragraphs:
for run in paragraph.runs:
set_chinese_font(run)
return table
def generate_quotation():
"""生成报价文档"""
doc = Document()
# 设置文档样式
style = doc.styles['Normal']
font = style.font
font.name = '宋体'
font.size = Pt(12)
# ========== 文档封面 ==========
# 标题
title = doc.add_heading('OA系统开发项目报价书', 0)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 副标题
subtitle = doc.add_paragraph()
subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = subtitle.add_run('(产品需求文档 v1.0')
run.font.size = Pt(14)
set_chinese_font(run)
# 添加空白行
for _ in range(5):
doc.add_paragraph()
# 公司信息
company_info = doc.add_paragraph()
company_info.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = company_info.add_run('项目报价单位:[您的公司名称]')
run.font.size = Pt(14)
run.bold = True
set_chinese_font(run)
doc.add_paragraph()
date_para = doc.add_paragraph()
date_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = date_para.add_run(f'报价日期:{datetime.now().strftime("%Y年%m月%d")}')
run.font.size = Pt(12)
set_chinese_font(run)
doc.add_page_break()
# ========== 1. 项目概述 ==========
add_section_title(doc, '一、项目概述', 1)
add_section_title(doc, '1.1 项目背景', 2)
doc.add_paragraph('随着贵公司业务发展项目管理流程日趋复杂需要一套完整的OA系统来支撑从商机立项到项目完成、财务结算的全流程管理。系统需支持项目过程跟踪、状态管理、产值统计与回款管理等核心业务实现项目管理数字化、流程化、可视化管理。')
add_section_title(doc, '1.2 项目目标', 2)
objectives = [
'实现项目全生命周期在线管理,从立项到回款全流程数字化',
'建立项目状态可视化跟踪机制,实时掌握项目进展',
'支持产值与财务数据统计,为管理决策提供数据支撑',
'建立规范的审核流程,确保关键环节可追溯',
'支持PC端与移动端提升使用便捷性',
'提升项目管理效率,降低管理成本'
]
for obj in objectives:
p = doc.add_paragraph(obj, style='List Bullet')
set_chinese_font(p.runs[0])
add_section_title(doc, '1.3 交付范围', 2)
doc.add_paragraph('本报价包含以下交付内容:')
deliverables = [
'OA系统PC端完整功能开发',
'OA系统移动端应用开发支持iOS和Android',
'系统部署和上线',
'系统使用培训不少于2次',
'系统使用文档(用户手册、管理员手册)',
'系统质保期内的维护和技术支持(详见质保条款)'
]
for item in deliverables:
p = doc.add_paragraph(item, style='List Bullet')
set_chinese_font(p.runs[0])
doc.add_page_break()
# ========== 2. 功能清单 ==========
add_section_title(doc, '二、功能清单', 1)
add_section_title(doc, '2.1 商机(立项)管理模块', 2)
functions_1 = [
('立项申请', '商务人员在线提交项目立项申请,包含项目基本信息、客户信息、服务内容等'),
('审核流程', '经营管理部及总经理依次审核立项申请,支持审核通过/驳回'),
('项目编号', '系统自动生成项目编号(年份+序号),确保唯一性'),
('投标管理', '项目状态管理,支持投标状态更新和投标附件上传'),
('合同管理', '合同状态管理和合同附件上传'),
('项目查询', '多条件组合查询项目,支持按编号、名称、状态等查询,支持导出')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_1)
add_section_title(doc, '2.2 项目过程管理模块', 2)
functions_2 = [
('项目启动', '项目启动申请,关联立项项目,分配执业工程师和工作内容'),
('启动审核', '经营管理部和总经理审核启动申请'),
('启动编号', '系统自动生成启动编号(立项编号+类型+序号)'),
('成果管理', '执业工程师提交项目成果(初稿、对账、最终成果)'),
('成果审核', '组长和领导依次审核项目成果'),
('差异提醒', '初稿与对账金额差异过大时自动提醒'),
('进度查询', '实时查询项目执行进度,支持多条件筛选'),
('费用计算', '根据标准文件自动计算项目费用支持6种项目类型')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_2)
add_section_title(doc, '2.3 财务管理模块', 2)
functions_3 = [
('开票申请', '商务人员提交开票申请'),
('开票管理', '财务人员开票并填写开票金额,上传开票附件'),
('回款管理', '记录回款金额,更新回款状态'),
('请款申请', '商务人员提交请款申请'),
('请款审核', '总经理审核请款申请'),
('付款管理', '出纳确认付款,更新付款状态')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_3)
add_section_title(doc, '2.4 报表管理模块', 2)
functions_4 = [
('项目明细表', '展示项目从立项到回款的所有明细信息,支持查询和导出'),
('项目汇总表', '按状态、负责人等维度汇总项目数量和金额'),
('产值明细表', '按执业者展示完成产值明细,自动计算产值分配'),
('产值汇总表', '按执业者统计指定时间段的产值完成情况'),
('应收账款汇总表', '按客户单位汇总应收账款'),
('应收账款明细表', '按客户单位展示多个项目的应收账款明细'),
('应付账款明细表', '展示请款申请的应付账款明细'),
('应付账款汇总表', '汇总所有请款金额')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_4)
add_section_title(doc, '2.5 系统设置模块', 2)
functions_5 = [
('组织架构管理', '自定义部门层级结构,支持多级部门'),
('账号管理', '用户账号的创建、编辑、禁用等管理'),
('角色权限', '基于角色的权限控制RBAC可配置功能权限和数据权限'),
('审核流程配置', '可配置审核流程节点和审核人'),
('系统参数配置', '系统参数、计算公式等可配置化管理')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_5)
add_section_title(doc, '2.6 通用功能', 2)
functions_6 = [
('消息通知', '站内消息、邮件、短信、移动端推送等多种通知方式'),
('附件管理', '支持多种格式文件上传、下载、在线预览'),
('操作日志', '记录所有关键操作日志,支持查询和导出'),
('数据权限', '三级数据权限控制(个人/部门/全部)'),
('移动端支持', 'iOS和Android移动应用支持待办审核、消息通知等')
]
table = add_table_with_header(doc, ['功能点', '功能描述'], functions_6)
doc.add_page_break()
# ========== 3. 技术方案 ==========
add_section_title(doc, '三、技术方案', 1)
add_section_title(doc, '3.1 技术架构', 2)
doc.add_paragraph('采用前后端分离架构,确保系统的可维护性和可扩展性。')
tech_stack = [
('前端技术', 'Vue.js 3.x + Element PlusPC端Vue Native/React Native移动端'),
('后端技术', 'Java Spring Boot / Python Django根据实际情况选择'),
('数据库', 'MySQL 8.0主数据库Redis缓存'),
('文件存储', '本地存储或云存储阿里云OSS/腾讯云COS'),
('消息队列', 'RabbitMQ或Redis用于异步任务和消息通知'),
('部署方式', 'Docker容器化部署支持集群部署')
]
table = add_table_with_header(doc, ['技术栈', '技术选型'], tech_stack)
add_section_title(doc, '3.2 性能指标', 2)
performance = [
('响应时间', '常规操作响应时间≤2秒复杂查询≤5秒'),
('并发支持', '支持至少50个用户同时在线使用'),
('数据容量', '支持至少10万条项目记录'),
('可用性', '系统可用性≥99%(排除计划内维护)'),
('安全标准', '符合网络安全等级保护要求')
]
table = add_table_with_header(doc, ['性能指标', '指标值'], performance)
doc.add_page_break()
# ========== 4. 项目周期 ==========
add_section_title(doc, '四、项目周期', 1)
doc.add_paragraph('项目预计总周期16周约4个月')
add_section_title(doc, '4.1 项目阶段划分', 2)
phases = [
('需求分析', '2周', '需求调研、需求确认、原型设计确认'),
('系统设计', '2周', '数据库设计、接口设计、UI设计'),
('开发阶段', '8周', '后端开发4周、PC前端开发3周、移动端开发3周并行'),
('测试阶段', '2周', '功能测试、性能测试、安全测试、用户验收测试'),
('部署上线', '1周', '系统部署、数据迁移、上线试运行'),
('培训交付', '1周', '用户培训、文档交付、正式验收')
]
table = add_table_with_header(doc, ['项目阶段', '周期', '主要工作'], phases)
add_section_title(doc, '4.2 里程碑节点', 2)
milestones = [
('M1', '需求确认', '需求文档确认签字', '第2周末'),
('M2', '原型确认', '原型设计确认签字', '第3周末'),
('M3', '设计评审', '数据库和接口设计评审通过', '第4周末'),
('M4', '开发完成', '所有功能开发完成,提交测试', '第12周末'),
('M5', '测试完成', '测试通过,准备上线', '第14周末'),
('M6', '正式验收', '项目正式验收,交付使用', '第16周末')
]
table = add_table_with_header(doc, ['里程碑', '节点名称', '交付物', '时间节点'], milestones)
doc.add_page_break()
# ========== 5. 项目费用 ==========
add_section_title(doc, '五、项目费用', 1)
doc.add_paragraph('项目总费用说明:以下费用包含所有开发、实施、培训、质保期维护等费用。')
add_section_title(doc, '5.1 费用明细', 2)
# 费用明细表
cost_details = [
('需求分析与设计', '需求调研、原型设计、数据库设计、接口设计', '3周', '¥XX,XXX', '15%'),
('PC端开发', '后端开发、PC前端开发、接口开发', '8周', '¥XX,XXX', '40%'),
('移动端开发', 'iOS和Android应用开发', '3周', '¥XX,XXX', '15%'),
('测试与优化', '功能测试、性能测试、安全测试、bug修复', '2周', '¥XX,XXX', '10%'),
('部署与培训', '系统部署、数据迁移、用户培训、文档编写', '2周', '¥XX,XXX', '10%'),
('项目管理', '项目协调、进度管理、质量管控', '全程', '¥XX,XXX', '10%')
]
table = add_table_with_header(doc, ['工作内容', '说明', '工期', '费用', '占比'], cost_details)
add_section_title(doc, '5.2 费用汇总', 2)
# 费用汇总
total_cost = [
('开发费用', '包含需求、设计、开发、测试、部署等所有费用', '¥XXX,XXX', '80%'),
('质保期维护', '12个月质保期内的bug修复、技术支持和系统优化', '¥XX,XXX', '10%'),
('培训费用', '用户培训、管理员培训不少于2次', '¥XX,XXX', '5%'),
('文档费用', '用户手册、管理员手册、技术文档', '¥XX,XXX', '5%'),
('项目总价', '(含税)', '¥XXX,XXX', '100%')
]
table = add_table_with_header(doc, ['费用项目', '说明', '金额', '占比'], total_cost)
add_section_title(doc, '5.3 付款方式', 2)
doc.add_paragraph('建议付款方式(可协商调整):')
payment_terms = [
('首付款', '合同签订后3个工作日内', '30%', '¥XXX,XXX'),
('进度款1', '原型设计确认后', '20%', '¥XX,XXX'),
('进度款2', '开发完成并提交测试后', '30%', '¥XXX,XXX'),
('验收款', '项目验收通过后', '15%', '¥XX,XXX'),
('质保金', '质保期结束后', '5%', '¥XX,XXX')
]
table = add_table_with_header(doc, ['付款节点', '付款条件', '付款比例', '金额'], payment_terms)
doc.add_paragraph()
doc.add_paragraph('注:以上费用均为含税价格,发票类型为【增值税专用发票/普通发票】。')
doc.add_page_break()
# ========== 6. 交付物清单 ==========
add_section_title(doc, '六、交付物清单', 1)
deliverables_list = [
('源代码', '完整的系统源代码(含注释),包含前端、后端、移动端', '电子版'),
('部署包', '可直接部署的系统安装包和部署脚本', '电子版'),
('数据库脚本', '数据库初始化脚本和升级脚本', '电子版'),
('接口文档', '完整的RESTful API接口文档Swagger格式', '电子版'),
('数据库设计文档', '数据库表结构设计文档', '电子版+纸质版'),
('系统架构文档', '系统技术架构设计文档', '电子版+纸质版'),
('用户操作手册', 'PC端和移动端用户操作手册', '电子版+纸质版'),
('管理员手册', '系统管理员配置和维护手册', '电子版+纸质版'),
('测试报告', '功能测试、性能测试、安全测试报告', '电子版+纸质版'),
('培训材料', '培训PPT和相关培训资料', '电子版')
]
table = add_table_with_header(doc, ['交付物', '说明', '交付形式'], deliverables_list)
doc.add_page_break()
# ========== 7. 质量保证 ==========
add_section_title(doc, '七、质量保证', 1)
add_section_title(doc, '7.1 开发质量标准', 2)
quality_standards = [
'代码规范:遵循行业代码规范,代码注释完整,便于维护',
'测试覆盖单元测试覆盖率≥70%关键功能测试覆盖率100%',
'性能标准:满足性能指标要求,通过性能压力测试',
'安全标准:通过安全测试,无高危安全漏洞',
'兼容性:支持主流浏览器和移动设备,兼容性测试通过'
]
for standard in quality_standards:
p = doc.add_paragraph(standard, style='List Bullet')
set_chinese_font(p.runs[0])
add_section_title(doc, '7.2 质保服务', 2)
doc.add_paragraph('质保期自项目验收通过之日起12个月。')
doc.add_paragraph('质保期内服务内容:')
warranty_services = [
'免费修复系统运行中发现的bug和缺陷',
'免费技术支持(工作日工作时间)',
'免费系统优化(性能优化、安全加固等)',
'免费提供系统版本升级(功能增强需另行协商)',
'7×24小时紧急技术支持系统故障'
]
for service in warranty_services:
p = doc.add_paragraph(service, style='List Bullet')
set_chinese_font(p.runs[0])
add_section_title(doc, '7.3 验收标准', 2)
doc.add_paragraph('项目验收需满足以下条件:')
acceptance_criteria = [
'所有功能需求已实现,功能测试通过',
'性能指标达到要求,性能测试通过',
'安全测试通过,无高危漏洞',
'兼容性测试通过,支持指定浏览器和设备',
'用户培训已完成,用户能够独立操作系统',
'所有交付物已提交,文档完整'
]
for criterion in acceptance_criteria:
p = doc.add_paragraph(criterion, style='List Bullet')
set_chinese_font(p.runs[0])
doc.add_page_break()
# ========== 8. 服务支持 ==========
add_section_title(doc, '八、服务支持', 1)
add_section_title(doc, '8.1 技术支持', 2)
support_services = [
('服务时间', '工作日9:00-18:00\n紧急情况7×24小时'),
('支持方式', '电话支持、远程协助、现场支持(必要时)'),
('响应时间', '一般问题4小时内响应\n紧急问题1小时内响应\n系统故障30分钟内响应'),
('支持内容', '系统使用咨询、bug修复、系统优化、技术培训')
]
table = add_table_with_header(doc, ['服务项目', '服务内容'], support_services)
add_section_title(doc, '8.2 培训服务', 2)
training_services = [
('培训对象', '系统管理员、业务用户(商务、财务、执业工程师等)'),
('培训方式', '现场培训、在线培训、录播视频'),
('培训次数', '不少于2次集中培训后续可安排补充培训'),
('培训内容', '系统功能介绍、操作演示、常见问题解答'),
('培训材料', '提供培训PPT、操作视频、FAQ文档')
]
table = add_table_with_header(doc, ['培训项目', '说明'], training_services)
doc.add_page_break()
# ========== 9. 风险说明 ==========
add_section_title(doc, '九、风险说明', 1)
doc.add_paragraph('项目执行过程中可能存在的风险及应对措施:')
risks = [
('需求变更风险', '项目执行过程中需求可能发生变更', '建立需求变更流程,变更需双方确认,可能影响工期和费用'),
('技术风险', '新技术应用或技术难点可能影响进度', '提前进行技术预研,预留技术攻关时间'),
('数据风险', '数据迁移或数据质量问题', '提前进行数据梳理,制定详细的数据迁移方案'),
('人员风险', '关键人员变动可能影响项目进度', '建立知识文档,确保知识传承'),
('时间风险', '项目进度可能因各种原因延期', '制定详细的项目计划,定期跟踪进度,及时调整')
]
table = add_table_with_header(doc, ['风险类型', '风险描述', '应对措施'], risks)
doc.add_page_break()
# ========== 10. 其他条款 ==========
add_section_title(doc, '十、其他条款', 1)
add_section_title(doc, '10.1 知识产权', 2)
doc.add_paragraph('• 系统源代码的知识产权归【甲方/双方共有】(需协商确定)')
doc.add_paragraph('• 系统使用权归甲方所有')
doc.add_paragraph('• 乙方不得将甲方数据泄露给第三方')
add_section_title(doc, '10.2 保密条款', 2)
doc.add_paragraph('双方对项目过程中涉及的商业机密、技术资料等负有保密义务保密期限为【3年】。')
add_section_title(doc, '10.3 违约责任', 2)
doc.add_paragraph('• 如因乙方原因导致项目延期每延期1周扣除合同总额的1%作为违约金')
doc.add_paragraph('• 如因甲方原因导致项目延期,工期相应顺延')
doc.add_paragraph('• 如因不可抗力导致项目延期,双方协商解决')
add_section_title(doc, '10.4 合同生效', 2)
doc.add_paragraph('本合同经双方签字盖章后生效,合同一式两份,双方各执一份。')
# ========== 11. 联系方式 ==========
doc.add_page_break()
add_section_title(doc, '十一、联系方式', 1)
contact_info = [
('项目负责人', '[姓名]', '[电话]', '[邮箱]'),
('技术负责人', '[姓名]', '[电话]', '[邮箱]'),
('商务联系人', '[姓名]', '[电话]', '[邮箱]'),
('公司地址', '[详细地址]', '', ''),
('公司网站', '[网址]', '', '')
]
table = add_table_with_header(doc, ['联系人', '姓名', '电话', '邮箱'], contact_info)
# ========== 结尾 ==========
doc.add_page_break()
doc.add_paragraph()
doc.add_paragraph()
end_para = doc.add_paragraph()
end_para.alignment = WD_ALIGN_PARAGRAPH.RIGHT
run = end_para.add_run('[您的公司名称]')
run.bold = True
set_chinese_font(run)
date_para = doc.add_paragraph()
date_para.alignment = WD_ALIGN_PARAGRAPH.RIGHT
run = date_para.add_run(datetime.now().strftime("%Y年%m月%d"))
set_chinese_font(run)
return doc
def main():
print("正在生成项目报价文档...")
doc = generate_quotation()
output_file = "项目报价文档.docx"
doc.save(output_file)
print(f"✓ 报价文档生成成功!")
print(f" 文件路径: {output_file}")
print()
print("注意:")
print(" 1. 文档中的费用金额需要根据实际情况填写标注为¥XX,XXX的地方")
print(" 2. 需要填写公司名称、联系方式等信息(标注为[XXX]的地方)")
print(" 3. 付款方式、合同条款等可根据实际情况调整")
print(" 4. 建议根据实际工作量和技术难度调整项目周期和费用")
if __name__ == "__main__":
main()