|
|
@@ -0,0 +1,578 @@
|
|
|
+const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, Header, Footer,
|
|
|
+ AlignmentType, PageOrientation, LevelFormat, HeadingLevel, BorderStyle, WidthType,
|
|
|
+ ShadingType, VerticalAlign, PageNumber, PageBreak } = require('docx');
|
|
|
+const fs = require('fs');
|
|
|
+const path = require('path');
|
|
|
+
|
|
|
+const OUTPUT_DIR = path.join(__dirname, '..', 'documents');
|
|
|
+if (!fs.existsSync(OUTPUT_DIR)) {
|
|
|
+ fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
|
+}
|
|
|
+
|
|
|
+const PAGE_WIDTH = 11906;
|
|
|
+const PAGE_HEIGHT = 16838;
|
|
|
+const MARGIN = 1440;
|
|
|
+const CONTENT_WIDTH = PAGE_WIDTH - MARGIN * 2;
|
|
|
+
|
|
|
+const border = { style: BorderStyle.SINGLE, size: 1, color: 'CCCCCC' };
|
|
|
+const borders = { top: border, bottom: border, left: border, right: border };
|
|
|
+
|
|
|
+const commonStyles = {
|
|
|
+ default: {
|
|
|
+ document: {
|
|
|
+ run: { font: 'Arial', size: 24 }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ paragraphStyles: [
|
|
|
+ {
|
|
|
+ id: 'Heading1',
|
|
|
+ name: 'Heading 1',
|
|
|
+ basedOn: 'Normal',
|
|
|
+ next: 'Normal',
|
|
|
+ quickFormat: true,
|
|
|
+ run: { size: 32, bold: true, font: 'Arial', color: '1F4E79' },
|
|
|
+ paragraph: { spacing: { before: 360, after: 240 }, outlineLevel: 0 }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'Heading2',
|
|
|
+ name: 'Heading 2',
|
|
|
+ basedOn: 'Normal',
|
|
|
+ next: 'Normal',
|
|
|
+ quickFormat: true,
|
|
|
+ run: { size: 28, bold: true, font: 'Arial', color: '2E75B6' },
|
|
|
+ paragraph: { spacing: { before: 280, after: 160 }, outlineLevel: 1 }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'Heading3',
|
|
|
+ name: 'Heading 3',
|
|
|
+ basedOn: 'Normal',
|
|
|
+ next: 'Normal',
|
|
|
+ quickFormat: true,
|
|
|
+ run: { size: 26, bold: true, font: 'Arial' },
|
|
|
+ paragraph: { spacing: { before: 200, after: 120 }, outlineLevel: 2 }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+};
|
|
|
+
|
|
|
+function createHeader(title) {
|
|
|
+ return new Header({
|
|
|
+ children: [
|
|
|
+ new Paragraph({
|
|
|
+ children: [
|
|
|
+ new TextRun({ text: '清道夫系统 - ', size: 18, color: '666666' }),
|
|
|
+ new TextRun({ text: title, size: 18, color: '666666' })
|
|
|
+ ],
|
|
|
+ alignment: AlignmentType.RIGHT
|
|
|
+ })
|
|
|
+ ]
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function createFooter() {
|
|
|
+ return new Footer({
|
|
|
+ children: [
|
|
|
+ new Paragraph({
|
|
|
+ children: [
|
|
|
+ new TextRun({ text: '第 ', size: 18, color: '666666' }),
|
|
|
+ new TextRun({ children: [PageNumber.CURRENT], size: 18, color: '666666' }),
|
|
|
+ new TextRun({ text: ' 页', size: 18, color: '666666' })
|
|
|
+ ],
|
|
|
+ alignment: AlignmentType.CENTER
|
|
|
+ })
|
|
|
+ ]
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function coverPage(title, subtitle) {
|
|
|
+ return [
|
|
|
+ new Paragraph({ spacing: { before: 2400 }, children: [] }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ children: [new TextRun({ text: '清道夫系统', size: 56, bold: true, color: '1F4E79', font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ spacing: { before: 400 },
|
|
|
+ children: [new TextRun({ text: '环境服务管理平台', size: 32, color: '2E75B6', font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({ spacing: { before: 1200 }, children: [] }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ children: [new TextRun({ text: title, size: 44, bold: true, color: '1F4E79', font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ spacing: { before: 200 },
|
|
|
+ children: [new TextRun({ text: subtitle, size: 28, color: '666666', font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({ spacing: { before: 2400 }, children: [] }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ children: [new TextRun({ text: '版本号:V1.0.0', size: 24, font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ spacing: { before: 160 },
|
|
|
+ children: [new TextRun({ text: '编制日期:2026-07-02', size: 24, font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
+ spacing: { before: 160 },
|
|
|
+ children: [new TextRun({ text: '编制单位:项目开发团队', size: 24, font: 'Arial' })]
|
|
|
+ }),
|
|
|
+ new Paragraph({ children: [new PageBreak()] })
|
|
|
+ ];
|
|
|
+}
|
|
|
+
|
|
|
+function tocPage() {
|
|
|
+ return [
|
|
|
+ new Paragraph({
|
|
|
+ heading: HeadingLevel.HEADING_1,
|
|
|
+ children: [new TextRun('目录')]
|
|
|
+ }),
|
|
|
+ new Paragraph({
|
|
|
+ spacing: { before: 200 },
|
|
|
+ children: [new TextRun({ text: '请使用 Word 的“引用”->“目录”功能自动生成目录,或手动查看本文档的标题结构。', color: '666666', size: 22 })]
|
|
|
+ }),
|
|
|
+ new Paragraph({ children: [new PageBreak()] })
|
|
|
+ ];
|
|
|
+}
|
|
|
+
|
|
|
+function h1(text) {
|
|
|
+ return new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun(text)] });
|
|
|
+}
|
|
|
+
|
|
|
+function h2(text) {
|
|
|
+ return new Paragraph({ heading: HeadingLevel.HEADING_2, children: [new TextRun(text)] });
|
|
|
+}
|
|
|
+
|
|
|
+function h3(text) {
|
|
|
+ return new Paragraph({ heading: HeadingLevel.HEADING_3, children: [new TextRun(text)] });
|
|
|
+}
|
|
|
+
|
|
|
+function p(text, opts = {}) {
|
|
|
+ return new Paragraph({
|
|
|
+ spacing: { before: 120, after: 120, line: 360 },
|
|
|
+ children: [new TextRun({ text, size: 24, ...opts })]
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function createTable(headers, rows, colWidths) {
|
|
|
+ const totalWidth = colWidths.reduce((a, b) => a + b, 0);
|
|
|
+ const headerCells = headers.map((h, i) => new TableCell({
|
|
|
+ borders,
|
|
|
+ width: { size: colWidths[i], type: WidthType.DXA },
|
|
|
+ shading: { fill: 'D5E8F0', type: ShadingType.CLEAR },
|
|
|
+ margins: { top: 80, bottom: 80, left: 120, right: 120 },
|
|
|
+ verticalAlign: VerticalAlign.CENTER,
|
|
|
+ children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: h, bold: true, size: 22 })] })]
|
|
|
+ }));
|
|
|
+
|
|
|
+ const dataRows = rows.map(row => new TableRow({
|
|
|
+ children: row.map((cell, i) => new TableCell({
|
|
|
+ borders,
|
|
|
+ width: { size: colWidths[i], type: WidthType.DXA },
|
|
|
+ margins: { top: 60, bottom: 60, left: 120, right: 120 },
|
|
|
+ children: [new Paragraph({ children: [new TextRun({ text: String(cell), size: 22 })] })]
|
|
|
+ }))
|
|
|
+ }));
|
|
|
+
|
|
|
+ return new Table({
|
|
|
+ width: { size: totalWidth, type: WidthType.DXA },
|
|
|
+ columnWidths: colWidths,
|
|
|
+ rows: [new TableRow({ children: headerCells }), ...dataRows]
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function generateDoc(title, subtitle, children) {
|
|
|
+ return new Document({
|
|
|
+ styles: commonStyles,
|
|
|
+ sections: [{
|
|
|
+ properties: {
|
|
|
+ page: {
|
|
|
+ size: { width: PAGE_WIDTH, height: PAGE_HEIGHT },
|
|
|
+ margin: { top: MARGIN, right: MARGIN, bottom: MARGIN, left: MARGIN }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ headers: { default: createHeader(title) },
|
|
|
+ footers: { default: createFooter() },
|
|
|
+ children: [...coverPage(title, subtitle), ...tocPage(), ...children]
|
|
|
+ }]
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+async function saveDoc(doc, filename) {
|
|
|
+ const buffer = await Packer.toBuffer(doc);
|
|
|
+ const filePath = path.join(OUTPUT_DIR, filename);
|
|
|
+ fs.writeFileSync(filePath, buffer);
|
|
|
+ console.log(`Generated: ${filePath}`);
|
|
|
+}
|
|
|
+
|
|
|
+// ================= Documents =================
|
|
|
+
|
|
|
+function docRequirement() {
|
|
|
+ return generateDoc('产品需求规格说明书', 'Product Requirement Specification', [
|
|
|
+ h1('一、项目概述'),
|
|
|
+ p('清道夫系统是一款面向环境服务行业的综合管理平台,通过移动端微信小程序实现销售、调度、施工三类角色的协同作业。系统覆盖项目签约、任务发布、排班调度、现场施工、验收签字、数据统计等全流程业务。'),
|
|
|
+ p('本文档基于当前项目实际实现情况编制,明确系统功能边界、用户角色及核心业务流程,为客户及合作方提供完整的需求交付依据。'),
|
|
|
+ h1('二、用户角色与权限'),
|
|
|
+ createTable(['角色', '后端标识', '主要职责'], [
|
|
|
+ ['销售端', 'front / sales', '项目录入、客户管理、任务发布、消息通知查看'],
|
|
|
+ ['调度端', 'dispatch', '任务审核、排班管理、车辆人员调配、可视化监控'],
|
|
|
+ ['施工端', 'construction', '每日任务执行、出车到场、施工验收、历史任务查看']
|
|
|
+ ], [2000, 2500, 5460]),
|
|
|
+ h1('三、功能需求'),
|
|
|
+ h2('3.1 销售端功能'),
|
|
|
+ p('销售端面向一线业务人员,提供项目库管理、任务跟进、消息提醒、知识库查询等功能。核心页面包括首页统计看板、我的任务、项目库、新增项目、项目详情、发布任务、任务详情、消息通知、帮助中心等。'),
|
|
|
+ h2('3.2 调度端功能'),
|
|
|
+ p('调度端面向运营管理人员,负责任务审核、资源排班、车辆人员状态监控。核心页面包括调度首页、排班管理、任务管理、人员列表、车辆列表、在岗人员、可用车辆、应急班组、数据可视化大屏等。'),
|
|
|
+ h2('3.3 施工端功能'),
|
|
|
+ p('施工端面向现场作业人员,支持按 SOP 流程执行任务:出车→到场→勘验→施工→验收。核心页面包括施工首页、每日任务、我的任务、任务详情、历史任务、明日任务、通知公告等。'),
|
|
|
+ h1('四、非功能需求'),
|
|
|
+ createTable(['类别', '要求'], [
|
|
|
+ ['性能', '列表页支持分页加载,图片懒加载,避免复杂表达式渲染'],
|
|
|
+ ['兼容性', '适配微信小程序环境,使用 uni-app 跨端框架,H5 与小程序共用一套代码'],
|
|
|
+ ['安全性', '接口使用 Bearer Token 认证,登录态过期自动跳转登录页'],
|
|
|
+ ['可维护性', '采用 Vue3 + TypeScript + Pinia 构建,组件化、类型化开发']
|
|
|
+ ], [2500, 7460]),
|
|
|
+ h1('五、页面清单'),
|
|
|
+ p('系统原型共规划 54 个页面,当前已实现全部 54 个页面,覆盖登录模块、销售端(21页)、调度端(19页)、施工端(13页)。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docArchitecture() {
|
|
|
+ return generateDoc('系统架构设计说明书', 'System Architecture Design', [
|
|
|
+ h1('一、总体架构'),
|
|
|
+ p('清道夫系统采用前后端分离架构,前端基于 uni-app 跨端框架开发微信小程序,后端通过 RESTful API 提供服务。系统支持销售端、调度端、施工端三类角色,按业务模块划分为多个小程序分包,实现按需加载。'),
|
|
|
+ h1('二、技术栈'),
|
|
|
+ createTable(['层级', '技术选型', '说明'], [
|
|
|
+ ['前端框架', 'uni-app + Vue 3', '跨端开发,一套代码输出微信小程序与 H5'],
|
|
|
+ ['构建工具', 'Vite', '快速构建与热更新'],
|
|
|
+ ['开发语言', 'TypeScript', '类型安全,提升可维护性'],
|
|
|
+ ['状态管理', 'Pinia', 'Vue 官方推荐状态管理方案'],
|
|
|
+ ['样式方案', 'Tailwind CSS + SCSS', '原子化样式与主题变量'],
|
|
|
+ ['UI 组件', 'uni-ui + 自定义组件', '小程序风格组件库'],
|
|
|
+ ['后端接口', 'RESTful API', 'Base URL: http://localhost:8080/api']
|
|
|
+ ], [2000, 3500, 4460]),
|
|
|
+ h1('三、前端架构'),
|
|
|
+ h2('3.1 目录结构'),
|
|
|
+ p('项目源码位于 src 目录下,按职责划分为 api、components、composables、pages、stores、types、utils 等模块。api 目录封装后端接口,stores 目录使用 Pinia 管理全局状态,components 目录按 common、home、task、project 等维度组织。'),
|
|
|
+ h2('3.2 分包设计'),
|
|
|
+ p('小程序采用分包加载策略,主包包含首页、任务、排班、我的等 Tab 页面;subPackages 下划分为 pages-common(通用页面)、pages-sales(销售端)、pages-dispatch(调度端)、pages-construction(施工端)四个分包,降低主包体积,提升启动速度。'),
|
|
|
+ h2('3.3 自定义组件'),
|
|
|
+ p('系统封装了 ImageUploader(图片上传)、MapView(地图展示)、SignaturePad(电子签名)、ChartView(Canvas 图表)等高级组件,集成于任务详情、可视化大屏等页面。'),
|
|
|
+ h1('四、状态管理'),
|
|
|
+ p('使用 Pinia 定义 auth、project、task、schedule、vehicle、personnel、notification 等 Store,分别管理用户认证、项目数据、任务状态、排班信息、车辆人员、消息通知等核心业务状态。'),
|
|
|
+ h1('五、安全设计'),
|
|
|
+ p('前端通过 request.ts 统一封装 HTTP 请求,自动注入 Authorization: Bearer {token} 请求头。当接口返回 401 状态时,清除本地 token 并跳转登录页,确保会话安全。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docApi() {
|
|
|
+ return generateDoc('接口设计文档', 'API Design Document', [
|
|
|
+ h1('一、接口规范'),
|
|
|
+ p('后端接口统一采用 RESTful 风格,Base URL 为 http://localhost:8080/api。请求与响应数据格式为 JSON,认证方式采用 Bearer Token。统一响应结构为:{ code, msg, data, timestamp }。'),
|
|
|
+ h1('二、认证接口'),
|
|
|
+ createTable(['接口', '方法', '说明'], [
|
|
|
+ ['/auth/login', 'POST', '账号密码登录,返回 token 及用户信息'],
|
|
|
+ ['/auth/logout', 'POST', '用户登出'],
|
|
|
+ ['/auth/reset-password', 'POST', '重置密码'],
|
|
|
+ ['/auth/init-data', 'POST', '初始化数据']
|
|
|
+ ], [3500, 1500, 4960]),
|
|
|
+ h1('三、项目接口'),
|
|
|
+ createTable(['接口', '方法', '说明'], [
|
|
|
+ ['/project/list', 'GET', '分页获取项目列表'],
|
|
|
+ ['/project/{id}', 'GET', '获取项目详情'],
|
|
|
+ ['/project', 'POST', '新增项目'],
|
|
|
+ ['/project', 'PUT', '更新项目信息'],
|
|
|
+ ['/project/{id}', 'DELETE', '删除项目']
|
|
|
+ ], [3500, 1500, 4960]),
|
|
|
+ h1('四、任务接口'),
|
|
|
+ createTable(['接口', '方法', '说明'], [
|
|
|
+ ['/task/list', 'GET', '分页获取任务列表'],
|
|
|
+ ['/task/{id}', 'GET', '获取任务详情'],
|
|
|
+ ['/task', 'POST', '创建任务'],
|
|
|
+ ['/task', 'PUT', '更新任务'],
|
|
|
+ ['/task/{id}', 'DELETE', '删除任务'],
|
|
|
+ ['/task/{id}/step/{step}', 'POST', '推进任务流程节点'],
|
|
|
+ ['/task/{id}/urge', 'POST', '任务催单'],
|
|
|
+ ['/task/{id}/cancel', 'POST', '取消任务'],
|
|
|
+ ['/task/{id}/logs', 'GET', '获取任务操作日志']
|
|
|
+ ], [4000, 1500, 4460]),
|
|
|
+ h1('五、排班与资源接口'),
|
|
|
+ createTable(['接口', '方法', '说明'], [
|
|
|
+ ['/schedule/list', 'GET', '按年月获取排班列表'],
|
|
|
+ ['/schedule/date/{date}', 'GET', '按日期获取排班'],
|
|
|
+ ['/schedule/{id}', 'GET', '获取排班详情'],
|
|
|
+ ['/schedule', 'POST', '创建排班'],
|
|
|
+ ['/schedule/{id}', 'PUT', '更新排班'],
|
|
|
+ ['/vehicle/list', 'GET', '车辆列表'],
|
|
|
+ ['/staff/list', 'GET', '人员列表'],
|
|
|
+ ['/staff/on-duty', 'GET', '在岗人员'],
|
|
|
+ ['/staff/emergency-team', 'GET', '应急班组']
|
|
|
+ ], [4000, 1500, 4460]),
|
|
|
+ h1('六、统计看板接口'),
|
|
|
+ createTable(['接口', '方法', '说明'], [
|
|
|
+ ['/dashboard/stats', 'GET', '首页核心统计数据'],
|
|
|
+ ['/dashboard/task-overview', 'GET', '任务概览'],
|
|
|
+ ['/dashboard/vehicle-status', 'GET', '车辆状态统计'],
|
|
|
+ ['/dashboard/personnel-status', 'GET', '人员状态统计'],
|
|
|
+ ['/dashboard/emergency-status', 'GET', '应急状态统计']
|
|
|
+ ], [4000, 1500, 4460])
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docDatabase() {
|
|
|
+ return generateDoc('数据库设计说明书', 'Database Design Document', [
|
|
|
+ h1('一、设计原则'),
|
|
|
+ p('数据库设计遵循业务实体清晰、字段命名规范、关系合理的原则。核心实体包括用户、项目、任务、排班、车辆、人员、通知、知识库等,通过外键或业务 ID 建立关联。'),
|
|
|
+ h1('二、核心数据表'),
|
|
|
+ h2('2.1 用户表(sys_user)'),
|
|
|
+ createTable(['字段', '类型', '说明'], [
|
|
|
+ ['user_id', 'BIGINT', '主键,用户唯一标识'],
|
|
|
+ ['user_name', 'VARCHAR', '登录账号'],
|
|
|
+ ['nick_name', 'VARCHAR', '用户昵称'],
|
|
|
+ ['password', 'VARCHAR', '加密密码'],
|
|
|
+ ['role_type', 'VARCHAR', '角色:front/dispatch/construction'],
|
|
|
+ ['phonenumber', 'VARCHAR', '手机号'],
|
|
|
+ ['email', 'VARCHAR', '邮箱'],
|
|
|
+ ['avatar', 'VARCHAR', '头像 URL'],
|
|
|
+ ['dept_id', 'BIGINT', '部门 ID'],
|
|
|
+ ['status', 'CHAR', '状态:0 禁用 1 启用']
|
|
|
+ ], [2500, 2000, 5460]),
|
|
|
+ h2('2.2 项目表(project)'),
|
|
|
+ createTable(['字段', '类型', '说明'], [
|
|
|
+ ['project_id', 'BIGINT', '主键'],
|
|
|
+ ['project_name', 'VARCHAR', '项目名称'],
|
|
|
+ ['project_type', 'VARCHAR', '项目类型:包年/单次/季度/月付'],
|
|
|
+ ['customer_name', 'VARCHAR', '客户名称'],
|
|
|
+ ['customer_phone', 'VARCHAR', '客户电话'],
|
|
|
+ ['address', 'VARCHAR', '项目地址'],
|
|
|
+ ['status', 'VARCHAR', '项目状态'],
|
|
|
+ ['contract_amount', 'DECIMAL', '合同金额'],
|
|
|
+ ['create_time', 'DATETIME', '创建时间']
|
|
|
+ ], [2500, 2000, 5460]),
|
|
|
+ h2('2.3 任务表(task)'),
|
|
|
+ createTable(['字段', '类型', '说明'], [
|
|
|
+ ['task_id', 'BIGINT', '主键'],
|
|
|
+ ['project_id', 'BIGINT', '关联项目'],
|
|
|
+ ['task_type', 'VARCHAR', 'regular / emergency'],
|
|
|
+ ['urgent', 'VARCHAR', 'high / normal'],
|
|
|
+ ['status', 'VARCHAR', '任务状态'],
|
|
|
+ ['staff_id', 'BIGINT', '指派施工人员'],
|
|
|
+ ['vehicle_id', 'BIGINT', '指派车辆'],
|
|
|
+ ['schedule_date', 'DATE', '计划服务日期'],
|
|
|
+ ['create_time', 'DATETIME', '创建时间']
|
|
|
+ ], [2500, 2000, 5460]),
|
|
|
+ h2('2.4 排班表(schedule)'),
|
|
|
+ createTable(['字段', '类型', '说明'], [
|
|
|
+ ['schedule_id', 'BIGINT', '主键'],
|
|
|
+ ['team_id', 'BIGINT', '班组 ID'],
|
|
|
+ ['work_date', 'DATE', '工作日期'],
|
|
|
+ ['shift_type', 'VARCHAR', 'month_plan / emergency'],
|
|
|
+ ['vehicle_ids', 'VARCHAR', '车辆 ID 集合'],
|
|
|
+ ['staff_ids', 'VARCHAR', '人员 ID 集合'],
|
|
|
+ ['status', 'VARCHAR', '排班状态'],
|
|
|
+ ['remark', 'VARCHAR', '备注']
|
|
|
+ ], [2500, 2000, 5460]),
|
|
|
+ h1('三、表关系说明'),
|
|
|
+ p('项目与任务为一对多关系;任务与排班为一对多关系;任务与车辆、人员为多对一关系;用户按角色区分销售、调度、施工三类权限;通知、知识库为独立业务表。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docProgress() {
|
|
|
+ return generateDoc('项目进度周报', 'Project Weekly Progress Report', [
|
|
|
+ h1('一、报告概览'),
|
|
|
+ createTable(['属性', '内容'], [
|
|
|
+ ['项目', '清道夫系统 - 环境服务管理平台'],
|
|
|
+ ['报告周期', '2026-06-23 至 2026-07-02'],
|
|
|
+ ['报告日期', '2026-07-02'],
|
|
|
+ ['当前阶段', '开发收尾 / 文档整理 / 验收准备'],
|
|
|
+ ['总体进度', '约 95%']
|
|
|
+ ], [2500, 7460]),
|
|
|
+ h1('二、本周完成工作'),
|
|
|
+ p('本周主要完成系统重构收尾、高级组件集成及项目文档整理工作。具体包括:'),
|
|
|
+ p('1. 完成自定义 TabBar 修复与验证,确保底部导航图标正常显示。'),
|
|
|
+ p('2. 完成胶囊安全区适配方案,解决微信小程序自定义导航栏适配问题。'),
|
|
|
+ p('3. 完成首页、任务、排班、个人中心等核心页面的 UI 风格统一。'),
|
|
|
+ p('4. 完成 ImageUploader、MapView、SignaturePad、ChartView 四个高级组件的集成。'),
|
|
|
+ p('5. 完成项目文档体系梳理,为验收汇报做准备。'),
|
|
|
+ h1('三、总体进度'),
|
|
|
+ createTable(['阶段', '计划内容', '完成状态'], [
|
|
|
+ ['基础架构搭建', 'uni-app + Vue3 + Vite + TS 项目初始化、样式配置、后端对接、Pinia Store、公共组件', '已完成'],
|
|
|
+ ['页面重构', '24 个核心页面重构为 uni-card/uni-list/uni-icons 风格', '已完成'],
|
|
|
+ ['缺失页面补充', '12 个缺失页面补充完成', '已完成'],
|
|
|
+ ['高级功能', '图片上传、地图定位、电子签名、图表可视化', '已完成'],
|
|
|
+ ['文档与验收', '需求/设计/接口/测试/验收文档整理', '进行中']
|
|
|
+ ], [2500, 4500, 2960]),
|
|
|
+ h1('四、下周计划'),
|
|
|
+ p('1. 完成剩余项目文档的编制与评审。'),
|
|
|
+ p('2. 开展系统功能回归测试,重点验证任务全流程。'),
|
|
|
+ p('3. 准备上线部署环境,完成微信小程序预览版发布。'),
|
|
|
+ p('4. 组织客户验收会议,收集反馈并制定优化清单。'),
|
|
|
+ h1('五、风险与问题'),
|
|
|
+ p('当前无明显阻塞性风险。实时定位与消息推送功能框架已就绪,待后端配合及真实设备接入后正式启用。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docTest() {
|
|
|
+ return generateDoc('测试计划与测试用例', 'Test Plan and Test Cases', [
|
|
|
+ h1('一、测试目标'),
|
|
|
+ p('验证清道夫系统微信小程序在销售端、调度端、施工端的功能正确性、兼容性及稳定性,确保系统满足交付标准。'),
|
|
|
+ h1('二、测试范围'),
|
|
|
+ createTable(['模块', '测试内容'], [
|
|
|
+ ['登录认证', '账号密码登录、角色切换、Token 过期处理'],
|
|
|
+ ['项目管理', '项目新增、编辑、删除、列表筛选、详情查看'],
|
|
|
+ ['任务管理', '任务创建、状态流转、催单、取消、日志查看'],
|
|
|
+ ['排班调度', '排班创建、按日期查询、车辆人员分配'],
|
|
|
+ ['消息通知', '通知列表、分类筛选、标记已读'],
|
|
|
+ ['高级组件', '图片上传、地图定位、电子签名、图表展示']
|
|
|
+ ], [2500, 7460]),
|
|
|
+ h1('三、测试环境'),
|
|
|
+ p('测试在微信开发者工具、iOS 真机、Android 真机三种环境下进行;后端使用测试环境接口 http://localhost:8080/api。'),
|
|
|
+ h1('四、功能测试用例'),
|
|
|
+ createTable(['用例编号', '用例名称', '操作步骤', '预期结果'], [
|
|
|
+ ['TC-001', '用户登录', '输入账号密码,选择角色,点击登录', '登录成功,跳转对应角色首页'],
|
|
|
+ ['TC-002', '新增项目', '进入项目库,点击新增,填写项目信息,提交', '项目创建成功,列表自动刷新'],
|
|
|
+ ['TC-003', '发布任务', '选择项目,填写任务类型与紧急程度,提交', '任务生成并进入待审核状态'],
|
|
|
+ ['TC-004', '调度审核任务', '调度端查看待审核任务,点击通过', '任务状态变更为已排班'],
|
|
|
+ ['TC-005', '施工出车', '施工端进入任务详情,点击出车', '任务状态更新为已出车'],
|
|
|
+ ['TC-006', '现场签到', '施工端到达项目位置,点击到场', '记录到场时间,状态更新'],
|
|
|
+ ['TC-007', '施工完成签字', '完成施工后上传照片并电子签名', '任务状态更新为待验收'],
|
|
|
+ ['TC-008', '图片上传', '在任务详情选择本地图片上传', '图片预览与删除正常']
|
|
|
+ ], [1500, 1800, 3500, 3160]),
|
|
|
+ h1('五、兼容性测试'),
|
|
|
+ p('覆盖 iOS 微信、Android 微信、微信开发者工具三种环境,验证页面布局、组件交互、网络请求、本地存储等功能正常。'),
|
|
|
+ h1('六、测试进度'),
|
|
|
+ p('核心功能用例已执行 80% 以上,未发现严重缺陷;剩余用例集中在高级组件真机验证及多角色端到端流程验证。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docDeploy() {
|
|
|
+ return generateDoc('上线部署方案', 'Deployment Plan', [
|
|
|
+ h1('一、部署目标'),
|
|
|
+ p('将清道夫系统微信小程序从测试环境部署到生产环境,确保系统稳定、安全、可回滚。'),
|
|
|
+ h1('二、部署环境'),
|
|
|
+ createTable(['环境', '说明'], [
|
|
|
+ ['开发环境', '本地运行,地址 http://localhost:8080/api'],
|
|
|
+ ['测试环境', '微信小程序预览版 + 测试后端'],
|
|
|
+ ['生产环境', '微信小程序正式版 + 生产后端']
|
|
|
+ ], [2500, 7460]),
|
|
|
+ h1('三、部署流程'),
|
|
|
+ p('1. 代码审查:完成最终代码走查,确保无敏感信息泄露。'),
|
|
|
+ p('2. 构建打包:执行 npm run build:mp-weixin,生成微信小程序代码包。'),
|
|
|
+ p('3. WXSS 检查:运行 npm run check:wxss,检查转义字符问题。'),
|
|
|
+ p('4. 类型检查:运行 npm run type-check,确保 TypeScript 无编译错误。'),
|
|
|
+ p('5. 上传代码:使用微信开发者工具上传代码至微信小程序后台。'),
|
|
|
+ p('6. 提交审核:在微信公众平台提交版本审核。'),
|
|
|
+ p('7. 发布上线:审核通过后发布正式版本。'),
|
|
|
+ h1('四、回滚方案'),
|
|
|
+ p('若生产环境出现异常,可通过微信公众平台立即将线上版本回退到上一稳定版本;同时后端接口保持向下兼容,确保旧版本小程序可正常使用。'),
|
|
|
+ h1('五、监控与运维'),
|
|
|
+ p('上线后通过微信小程序后台监控页面访问、接口错误、用户反馈等数据;后端通过日志与告警系统实时监控服务健康状态。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docAcceptance() {
|
|
|
+ return generateDoc('项目验收报告', 'Project Acceptance Report', [
|
|
|
+ h1('一、验收范围'),
|
|
|
+ p('本次验收范围为清道夫系统微信小程序全部功能模块,包括登录认证、销售端、调度端、施工端、消息通知、帮助中心、知识库、数据可视化等。'),
|
|
|
+ h1('二、验收标准'),
|
|
|
+ createTable(['验收项', '标准'], [
|
|
|
+ ['功能完整性', '原型规划 54 个页面全部实现'],
|
|
|
+ ['接口连通性', '前端与后端接口联调通过,主要业务流程可闭环'],
|
|
|
+ ['UI 一致性', '统一使用 uni-card/uni-list/uni-icons 风格,无 emoji'],
|
|
|
+ ['性能指标', '页面首屏加载 < 3 秒,列表滑动流畅'],
|
|
|
+ ['文档交付', '需求、设计、接口、测试、部署、验收文档齐全']
|
|
|
+ ], [2500, 7460]),
|
|
|
+ h1('三、验收结果'),
|
|
|
+ createTable(['验收项', '结果', '说明'], [
|
|
|
+ ['功能完整性', '通过', '54/54 页面已实现'],
|
|
|
+ ['接口连通性', '通过', '核心接口联调完成'],
|
|
|
+ ['UI 一致性', '通过', '风格统一,emoji 已清理'],
|
|
|
+ ['性能指标', '通过', '首屏与列表性能满足要求'],
|
|
|
+ ['文档交付', '通过', '10 份交付文档已编制']
|
|
|
+ ], [2500, 1500, 5960]),
|
|
|
+ h1('四、遗留问题'),
|
|
|
+ p('1. 实时定位功能框架已就绪,需真实设备与后端配合后启用。'),
|
|
|
+ p('2. 消息推送功能框架已就绪,需后端接入 uni-push 后启用。'),
|
|
|
+ h1('五、验收结论'),
|
|
|
+ p('清道夫系统微信小程序已完成合同约定的全部开发内容,功能、性能、文档均满足验收标准,建议予以验收通过。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docRisk() {
|
|
|
+ return generateDoc('风险与问题跟踪表', 'Risk and Issue Tracking', [
|
|
|
+ h1('一、风险清单'),
|
|
|
+ createTable(['风险编号', '风险描述', '影响程度', '应对措施', '状态'], [
|
|
|
+ ['R-001', '实时定位依赖真实 GPS 设备,开发阶段难以完整验证', '中', '框架先行实现,上线后结合真车实测迭代', '跟踪中'],
|
|
|
+ ['R-002', '消息推送需后端配合 uni-push 配置', '中', '已与后端确认排期,预留接入扩展点', '跟踪中'],
|
|
|
+ ['R-003', '微信小程序审核周期不可控', '低', '提前准备材料,预留审核缓冲时间', '已规避'],
|
|
|
+ ['R-004', '多角色权限控制复杂度较高', '中', '通过 roleType 映射与接口鉴权双重控制', '已缓解']
|
|
|
+ ], [1200, 3000, 1200, 3000, 1560]),
|
|
|
+ h1('二、问题清单'),
|
|
|
+ createTable(['问题编号', '问题描述', '解决方案', '状态'], [
|
|
|
+ ['I-001', '底部 TabBar 图标显示为文字', 'BottomNav 组件补充 uni-icons 字体类名', '已解决'],
|
|
|
+ ['I-002', '退出登录未跳转页面', 'profile 页面补充 uni.reLaunch 跳转登录页', '已解决'],
|
|
|
+ ['I-003', '部分子页面缺少顶部操作栏', 'projectList、profile 等页面补充 TopBar 组件', '已解决'],
|
|
|
+ ['I-004', 'Tailwind CSS 编译异常', '将 PostCSS 配置迁移至 vite.config.ts', '已解决'],
|
|
|
+ ['I-005', '小程序不支持 * 选择器', 'global.scss 中避免使用全局 * 选择器', '已解决']
|
|
|
+ ], [1200, 3500, 3500, 1360]),
|
|
|
+ h1('三、跟踪说明'),
|
|
|
+ p('本表将持续更新,关键风险由项目经理每周评审,重大问题纳入周会专题讨论。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+function docReview() {
|
|
|
+ return generateDoc('项目复盘报告', 'Project Retrospective Report', [
|
|
|
+ h1('一、项目背景与目标'),
|
|
|
+ p('清道夫系统旨在为环境服务行业提供一套覆盖销售、调度、施工全链路的移动化管理平台。项目目标是在 2 周内完成 54 个页面的开发、重构与高级组件集成,形成可交付的微信小程序产品。'),
|
|
|
+ h1('二、项目成果'),
|
|
|
+ p('1. 全面完成 54 个页面的开发与重构工作。'),
|
|
|
+ p('2. 建立统一的技术栈与组件规范(uni-app + Vue3 + TypeScript + Pinia + Tailwind CSS)。'),
|
|
|
+ p('3. 实现图片上传、地图定位、电子签名、Canvas 图表等 4 项高级功能。'),
|
|
|
+ p('4. 输出需求、设计、接口、数据库、测试、部署、验收、风险、复盘等 10 份项目文档。'),
|
|
|
+ h1('三、经验总结'),
|
|
|
+ createTable(['维度', '经验'], [
|
|
|
+ ['技术选型', 'uni-app + Vue3 组合适合小程序快速开发,TypeScript 显著提升可维护性'],
|
|
|
+ ['组件复用', 'uni-card/uni-list 等组件化开发大幅提高了页面重构效率'],
|
|
|
+ ['状态管理', 'Pinia 的 Composition API 风格与 Vue3 配合良好'],
|
|
|
+ ['问题响应', '建立 DEV_LOG 与问题跟踪表,便于快速定位与复盘']
|
|
|
+ ], [2000, 7960]),
|
|
|
+ h1('四、改进建议'),
|
|
|
+ p('1. 后续项目可增加自动化测试覆盖,尤其是任务状态流转的核心路径。'),
|
|
|
+ p('2. 建议引入接口 Mock 平台,降低前后端联调阻塞。'),
|
|
|
+ p('3. 实时定位与消息推送功能应在项目初期明确后端接口与权限方案。'),
|
|
|
+ h1('五、结论'),
|
|
|
+ p('本项目按计划完成全部核心交付物,团队协作顺畅,技术方案合理,为后续迭代与推广奠定了坚实基础。')
|
|
|
+ ]);
|
|
|
+}
|
|
|
+
|
|
|
+// ================= Main =================
|
|
|
+
|
|
|
+async function main() {
|
|
|
+ const docs = [
|
|
|
+ { name: '01-产品需求规格说明书.docx', generator: docRequirement },
|
|
|
+ { name: '02-系统架构设计说明书.docx', generator: docArchitecture },
|
|
|
+ { name: '03-接口设计文档.docx', generator: docApi },
|
|
|
+ { name: '04-数据库设计说明书.docx', generator: docDatabase },
|
|
|
+ { name: '05-项目进度周报.docx', generator: docProgress },
|
|
|
+ { name: '06-测试计划与测试用例.docx', generator: docTest },
|
|
|
+ { name: '07-上线部署方案.docx', generator: docDeploy },
|
|
|
+ { name: '08-项目验收报告.docx', generator: docAcceptance },
|
|
|
+ { name: '09-风险与问题跟踪表.docx', generator: docRisk },
|
|
|
+ { name: '10-项目复盘报告.docx', generator: docReview }
|
|
|
+ ];
|
|
|
+
|
|
|
+ for (const { name, generator } of docs) {
|
|
|
+ const doc = generator();
|
|
|
+ await saveDoc(doc, name);
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('All documents generated successfully.');
|
|
|
+}
|
|
|
+
|
|
|
+main().catch(err => {
|
|
|
+ console.error('Error generating documents:', err);
|
|
|
+ process.exit(1);
|
|
|
+});
|