|
|
@@ -0,0 +1,774 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+from docx import Document
|
|
|
+from docx.shared import Pt, Cm, RGBColor, Inches
|
|
|
+from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_TAB_LEADER
|
|
|
+from docx.enum.table import WD_TABLE_ALIGNMENT, WD_ALIGN_VERTICAL
|
|
|
+from docx.oxml.ns import qn
|
|
|
+from docx.oxml import OxmlElement
|
|
|
+import copy
|
|
|
+
|
|
|
+doc = Document()
|
|
|
+
|
|
|
+# ── 页面设置 A4 ──────────────────────────────────────────────
|
|
|
+section = doc.sections[0]
|
|
|
+section.page_width = Cm(21)
|
|
|
+section.page_height = Cm(29.7)
|
|
|
+section.left_margin = Cm(2.5)
|
|
|
+section.right_margin = Cm(2.5)
|
|
|
+section.top_margin = Cm(2.5)
|
|
|
+section.bottom_margin = Cm(2.0)
|
|
|
+
|
|
|
+# ── 颜色常量 ────────────────────────────────────────────────
|
|
|
+C_TITLE = RGBColor(0x1e, 0x3a, 0x8a) # 深蓝
|
|
|
+C_H2 = RGBColor(0x1d, 0x4e, 0xd8) # 中蓝
|
|
|
+C_H3 = RGBColor(0x0e, 0x7a, 0x9e) # 青蓝
|
|
|
+C_LABEL = RGBColor(0x37, 0x41, 0x51) # 深灰
|
|
|
+C_BODY = RGBColor(0x1f, 0x29, 0x37) # 正文黑
|
|
|
+C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
|
|
+C_TH_BG = RGBColor(0x1e, 0x40, 0xaf)
|
|
|
+C_ROW1 = RGBColor(0xef, 0xf6, 0xff)
|
|
|
+C_ROW2 = RGBColor(0xff, 0xff, 0xff)
|
|
|
+C_BORDER = RGBColor(0xc3, 0xda, 0xf7)
|
|
|
+C_NOTE_BG= RGBColor(0xfe, 0xf9, 0xc3)
|
|
|
+C_NOTE_BD= RGBColor(0xf5, 0x9e, 0x0b)
|
|
|
+
|
|
|
+def set_cell_bg(cell, rgb: RGBColor):
|
|
|
+ tc = cell._tc
|
|
|
+ tcPr = tc.get_or_add_tcPr()
|
|
|
+ shd = OxmlElement('w:shd')
|
|
|
+ shd.set(qn('w:val'), 'clear')
|
|
|
+ shd.set(qn('w:color'), 'auto')
|
|
|
+ hex_color = '{:02X}{:02X}{:02X}'.format(rgb[0], rgb[1], rgb[2])
|
|
|
+ shd.set(qn('w:fill'), hex_color)
|
|
|
+ tcPr.append(shd)
|
|
|
+
|
|
|
+def set_cell_border(cell, top=None, bottom=None, left=None, right=None):
|
|
|
+ tc = cell._tc
|
|
|
+ tcPr = tc.get_or_add_tcPr()
|
|
|
+ tcBorders = OxmlElement('w:tcBorders')
|
|
|
+ for side, val in [('top',top),('bottom',bottom),('left',left),('right',right)]:
|
|
|
+ if val:
|
|
|
+ el = OxmlElement(f'w:{side}')
|
|
|
+ el.set(qn('w:val'), val.get('val','single'))
|
|
|
+ el.set(qn('w:sz'), str(val.get('sz',4)))
|
|
|
+ el.set(qn('w:space'), '0')
|
|
|
+ el.set(qn('w:color'), val.get('color','C3DAF7'))
|
|
|
+ tcBorders.append(el)
|
|
|
+ tcPr.append(tcBorders)
|
|
|
+
|
|
|
+def add_run(para, text, bold=False, size=None, color=None, italic=False):
|
|
|
+ run = para.add_run(text)
|
|
|
+ run.bold = bold
|
|
|
+ run.italic = italic
|
|
|
+ run.font.name = '微软雅黑'
|
|
|
+ run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
|
|
|
+ if size:
|
|
|
+ run.font.size = Pt(size)
|
|
|
+ if color:
|
|
|
+ run.font.color.rgb = color
|
|
|
+ return run
|
|
|
+
|
|
|
+def heading1(text):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(18)
|
|
|
+ para.paragraph_format.space_after = Pt(8)
|
|
|
+ para.paragraph_format.left_indent = Cm(0)
|
|
|
+ # 左侧蓝条效果通过 border
|
|
|
+ pPr = para._p.get_or_add_pPr()
|
|
|
+ pBdr = OxmlElement('w:pBdr')
|
|
|
+ left = OxmlElement('w:left')
|
|
|
+ left.set(qn('w:val'), 'single')
|
|
|
+ left.set(qn('w:sz'), '24')
|
|
|
+ left.set(qn('w:space'), '6')
|
|
|
+ left.set(qn('w:color'), '1E3A8A')
|
|
|
+ pBdr.append(left)
|
|
|
+ pPr.append(pBdr)
|
|
|
+ para.paragraph_format.left_indent = Cm(0.5)
|
|
|
+ add_run(para, text, bold=True, size=14, color=C_TITLE)
|
|
|
+ return para
|
|
|
+
|
|
|
+def heading2(text):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(10)
|
|
|
+ para.paragraph_format.space_after = Pt(4)
|
|
|
+ add_run(para, '◆ ', bold=True, size=12, color=C_H2)
|
|
|
+ add_run(para, text, bold=True, size=12, color=C_H2)
|
|
|
+ return para
|
|
|
+
|
|
|
+def heading3(text):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(6)
|
|
|
+ para.paragraph_format.space_after = Pt(3)
|
|
|
+ add_run(para, '▸ ', bold=True, size=11, color=C_H3)
|
|
|
+ add_run(para, text, bold=True, size=11, color=C_H3)
|
|
|
+ return para
|
|
|
+
|
|
|
+def body(text, indent=0):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(2)
|
|
|
+ para.paragraph_format.space_after = Pt(2)
|
|
|
+ para.paragraph_format.left_indent = Cm(indent)
|
|
|
+ para.paragraph_format.first_line_indent = Cm(0)
|
|
|
+ add_run(para, text, size=10.5, color=C_BODY)
|
|
|
+ return para
|
|
|
+
|
|
|
+def bullet(text, level=0):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(1)
|
|
|
+ para.paragraph_format.space_after = Pt(1)
|
|
|
+ indent = 0.5 + level * 0.5
|
|
|
+ para.paragraph_format.left_indent = Cm(indent)
|
|
|
+ bullets = ['●', '○', '–']
|
|
|
+ add_run(para, bullets[level] + ' ', bold=(level==0), size=10, color=C_H3)
|
|
|
+ add_run(para, text, size=10, color=C_BODY)
|
|
|
+ return para
|
|
|
+
|
|
|
+def note(text):
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(6)
|
|
|
+ para.paragraph_format.space_after = Pt(6)
|
|
|
+ para.paragraph_format.left_indent = Cm(0.5)
|
|
|
+ para.paragraph_format.right_indent = Cm(0.5)
|
|
|
+ pPr = para._p.get_or_add_pPr()
|
|
|
+ pBdr = OxmlElement('w:pBdr')
|
|
|
+ for side in ['top','bottom','left','right']:
|
|
|
+ el = OxmlElement(f'w:{side}')
|
|
|
+ el.set(qn('w:val'), 'single')
|
|
|
+ el.set(qn('w:sz'), '4' if side in ('top','bottom','right') else '18')
|
|
|
+ el.set(qn('w:space'), '4')
|
|
|
+ el.set(qn('w:color'), 'F59E0B')
|
|
|
+ pBdr.append(el)
|
|
|
+ pPr.append(pBdr)
|
|
|
+ add_run(para, '📌 注意:', bold=True, size=10, color=RGBColor(0xd9,0x77,0x06))
|
|
|
+ add_run(para, text, size=10, color=C_BODY)
|
|
|
+ return para
|
|
|
+
|
|
|
+def make_table(headers, rows, col_widths=None):
|
|
|
+ table = doc.add_table(rows=1+len(rows), cols=len(headers))
|
|
|
+ table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
|
|
+ table.style = 'Table Grid'
|
|
|
+ # 表头
|
|
|
+ hdr = table.rows[0]
|
|
|
+ for i, h in enumerate(headers):
|
|
|
+ cell = hdr.cells[i]
|
|
|
+ set_cell_bg(cell, C_TH_BG)
|
|
|
+ cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
|
|
|
+ para = cell.paragraphs[0]
|
|
|
+ para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+ add_run(para, h, bold=True, size=10, color=C_WHITE)
|
|
|
+ # 数据行
|
|
|
+ for r_idx, row in enumerate(rows):
|
|
|
+ tr = table.rows[r_idx+1]
|
|
|
+ bg = C_ROW1 if r_idx % 2 == 0 else C_ROW2
|
|
|
+ for c_idx, val in enumerate(row):
|
|
|
+ cell = tr.cells[c_idx]
|
|
|
+ set_cell_bg(cell, bg)
|
|
|
+ cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
|
|
|
+ para = cell.paragraphs[0]
|
|
|
+ para.alignment = WD_ALIGN_PARAGRAPH.LEFT
|
|
|
+ add_run(para, str(val), size=10, color=C_BODY)
|
|
|
+ # 列宽
|
|
|
+ if col_widths:
|
|
|
+ for i, w in enumerate(col_widths):
|
|
|
+ for row in table.rows:
|
|
|
+ row.cells[i].width = Cm(w)
|
|
|
+ doc.add_paragraph() # 表格后空行
|
|
|
+ return table
|
|
|
+
|
|
|
+def divider():
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(4)
|
|
|
+ para.paragraph_format.space_after = Pt(4)
|
|
|
+ pPr = para._p.get_or_add_pPr()
|
|
|
+ pBdr = OxmlElement('w:pBdr')
|
|
|
+ bottom = OxmlElement('w:bottom')
|
|
|
+ bottom.set(qn('w:val'), 'single')
|
|
|
+ bottom.set(qn('w:sz'), '6')
|
|
|
+ bottom.set(qn('w:space'), '1')
|
|
|
+ bottom.set(qn('w:color'), 'C3DAF7')
|
|
|
+ pBdr.append(bottom)
|
|
|
+ pPr.append(pBdr)
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 封面
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+doc.add_paragraph()
|
|
|
+doc.add_paragraph()
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '实验室安全智能监测与管控中心', bold=True, size=22, color=C_TITLE)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '数据可视化大屏', bold=True, size=16, color=C_H2)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '使 用 说 明 文 档', bold=True, size=14, color=C_H3)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '中国安全生产科学研究院', bold=True, size=12, color=C_LABEL)
|
|
|
+
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, 'National Institute for Occupational Safety', italic=True, size=10, color=C_LABEL)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '文档版本:V1.0 编制日期:2026年03月', size=10, color=C_LABEL)
|
|
|
+
|
|
|
+doc.add_page_break()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 目录
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '目 录', bold=True, size=14, color=C_TITLE)
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+toc_items = [
|
|
|
+ ('1', '文档概述', '3'),
|
|
|
+ ('2', '系统简介', '3'),
|
|
|
+ ('3', '运行环境与访问方式', '4'),
|
|
|
+ ('4', '整体界面布局说明', '4'),
|
|
|
+ ('5', '顶部导航栏', '5'),
|
|
|
+ ('6', '1区 — 实验室基本情况统计', '5'),
|
|
|
+ ('7', '2区 — 智能设备与实验室设备统计', '7'),
|
|
|
+ ('8', '3区 — 实时监控', '8'),
|
|
|
+ ('9', '4区 — 实验环境感知与风险预警', '10'),
|
|
|
+ ('10', '全屏预警弹窗', '11'),
|
|
|
+ ('11', '通用交互说明', '12'),
|
|
|
+ ('12', '数据说明', '12'),
|
|
|
+ ('13', '常见问题(FAQ)', '13'),
|
|
|
+]
|
|
|
+for no, title, page in toc_items:
|
|
|
+ para = doc.add_paragraph()
|
|
|
+ para.paragraph_format.space_before = Pt(3)
|
|
|
+ para.paragraph_format.space_after = Pt(3)
|
|
|
+ tab_stops = para.paragraph_format.tab_stops
|
|
|
+ tab_stops.add_tab_stop(Cm(14.5), leader=WD_TAB_LEADER.DOTS)
|
|
|
+ add_run(para, f'{no}. {title}', size=10.5, color=C_BODY)
|
|
|
+ para.add_run('\t')
|
|
|
+ add_run(para, page, size=10.5, color=C_BODY)
|
|
|
+
|
|
|
+doc.add_page_break()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 1. 文档概述
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('1. 文档概述')
|
|
|
+body('本文档为《实验室安全智能监测与管控中心》数据可视化大屏的使用说明,旨在帮助操作人员、管理人员及相关使用者快速了解系统各功能模块的展示内容、交互方式及数据含义,确保系统功能得到正确、高效的使用。')
|
|
|
+doc.add_paragraph()
|
|
|
+body('本文档适用对象:')
|
|
|
+bullet('实验室安全管理人员(日常监控运维)')
|
|
|
+bullet('院级行政管理人员(决策数据查看)')
|
|
|
+bullet('IT运维人员(系统部署与维护参考)')
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 2. 系统简介
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('2. 系统简介')
|
|
|
+body('《实验室安全智能监测与管控中心》大屏系统是面向中国安全生产科学研究院(简称"安科院")各实验室的综合安全管理可视化平台,通过数据可视化手段将实验室的安全状态、环境感知数据、设备运行状况、人员进出信息及风险预警等核心数据以直观、实时的方式呈现于大屏上,便于管理人员进行统一监控与快速决策。')
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+heading2('系统定位')
|
|
|
+make_table(
|
|
|
+ ['维度', '说明'],
|
|
|
+ [
|
|
|
+ ['系统名称', '实验室安全智能监测与管控中心'],
|
|
|
+ ['所属单位', '中国安全生产科学研究院(National Institute for Occupational Safety)'],
|
|
|
+ ['系统类型', '数据可视化大屏(单页面应用)'],
|
|
|
+ ['设计分辨率', '9600 × 2800 px(约为1920×1080的2.5倍)'],
|
|
|
+ ['视觉风格', '深蓝科幻风,边框流动效果,科技感动效图标'],
|
|
|
+ ['技术框架', 'HTML5 + CSS3 + ECharts 5.4.3(单文件内联,无需构建工具)'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 11.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('主要功能概览')
|
|
|
+bullet('实验室基本情况统计(总数、分级、状态)')
|
|
|
+bullet('实验室安全分级统计(各二级单位堆叠柱状图)')
|
|
|
+bullet('实验室人员进出数量统计及走势折线图')
|
|
|
+bullet('智能环境感知应用设备统计(在线率、设备分类)')
|
|
|
+bullet('实验室设备分类及使用统计(分类、使用率、状态)')
|
|
|
+bullet('3区固定显示实时监控(9宫格监控画面,AI危险行为检测)')
|
|
|
+bullet('实验环境安全智能感知(传感器实时数据滚动)')
|
|
|
+bullet('实验室实时风险预警(预警通知轮播)')
|
|
|
+bullet('全屏预警弹窗(超阈值自动触发,科幻警报样式)')
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 3. 运行环境与访问方式
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('3. 运行环境与访问方式')
|
|
|
+heading2('硬件环境要求')
|
|
|
+make_table(
|
|
|
+ ['项目', '最低要求', '推荐配置'],
|
|
|
+ [
|
|
|
+ ['显示屏', '1920×1080(FHD)', '超大屏/拼接屏 9600×2800 px'],
|
|
|
+ ['处理器', 'Intel i5 / 同等级别', 'Intel i7 或以上'],
|
|
|
+ ['内存', '8 GB', '16 GB 或以上'],
|
|
|
+ ['显卡', '支持硬件加速', '独立显卡(GPU加速渲染)'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 5, 6.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('软件环境要求')
|
|
|
+make_table(
|
|
|
+ ['软件', '版本要求', '说明'],
|
|
|
+ [
|
|
|
+ ['浏览器', 'Chrome 90+ / Edge 90+', '推荐使用最新版 Chrome,需支持 WebGL'],
|
|
|
+ ['ECharts CDN', '5.4.3', '通过 jsDelivr CDN 在线加载,需保证网络可达'],
|
|
|
+ ['操作系统', 'Windows 10+ / macOS 12+', '支持主流64位操作系统'],
|
|
|
+ ],
|
|
|
+ col_widths=[3, 5, 7.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('访问方式')
|
|
|
+bullet('将项目文件夹(含 index-v2.html 及 baseBg.png)部署到本地或局域网 Web 服务器。')
|
|
|
+bullet('用浏览器打开 http://[服务器IP]/index-v2.html 即可访问。')
|
|
|
+bullet('也可直接双击 index-v2.html 在浏览器中本地打开(部分资源需本地服务器访问)。')
|
|
|
+bullet('首次加载时,系统将自动请求进入全屏模式(浏览器弹出授权提示,点击"允许"即可)。')
|
|
|
+
|
|
|
+note('若 ECharts 图表未正常显示,请检查网络连接是否可访问 cdn.jsdelivr.net,或将 ECharts 替换为本地文件引用。')
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 4. 整体界面布局说明
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('4. 整体界面布局说明')
|
|
|
+body('大屏整体由顶部导航栏 + 内容区域两大部分构成,内容区域按从左到右 2:1.5:4.5:2 的比例划分为四个区域。布局示意如下:')
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+# 布局示意表
|
|
|
+table = doc.add_table(rows=3, cols=5)
|
|
|
+table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
|
|
+table.style = 'Table Grid'
|
|
|
+
|
|
|
+# 第1行:导航栏
|
|
|
+row0 = table.rows[0]
|
|
|
+row0.cells[0].merge(row0.cells[4])
|
|
|
+set_cell_bg(row0.cells[0], C_TH_BG)
|
|
|
+p = row0.cells[0].paragraphs[0]
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '顶部导航栏(时钟 | LOGO + 单位名称 + 系统大标题 | 天气)', bold=True, size=10, color=C_WHITE)
|
|
|
+
|
|
|
+# 第2行:列标题
|
|
|
+row1 = table.rows[1]
|
|
|
+for i, (txt, bg) in enumerate([
|
|
|
+ ('1区(比例2)', C_ROW1),
|
|
|
+ ('2区(比例1.5)', C_ROW2),
|
|
|
+ ('3区(比例4.5)', C_ROW1),
|
|
|
+ ('4区(比例2)', C_ROW2),
|
|
|
+]):
|
|
|
+ if i < 4:
|
|
|
+ cell = row1.cells[i]
|
|
|
+ set_cell_bg(cell, C_TH_BG if i in [0,2] else RGBColor(0x1d, 0x4e, 0xd8))
|
|
|
+ p = cell.paragraphs[0]
|
|
|
+ p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+ add_run(p, txt, bold=True, size=10, color=C_WHITE)
|
|
|
+# merge last 2 cols for col 4
|
|
|
+# Actually use 4 cols only: remove 5th
|
|
|
+row1.cells[4].merge(row1.cells[3])
|
|
|
+
|
|
|
+# 第3行:内容描述
|
|
|
+row2 = table.rows[2]
|
|
|
+contents = [
|
|
|
+ '• 基本情况统计\n• 安全分级统计\n• 人员进出走势',
|
|
|
+ '• 智能环境感知\n 应用设备统计\n• 设备分类及\n 使用统计',
|
|
|
+ '实时监控(固定显示)\n左侧:搜索/筛选/树状图\n右侧:9宫格摄像头',
|
|
|
+ '• 实验环境安全\n 智能感知\n• 实时风险预警',
|
|
|
+]
|
|
|
+bgs = [C_ROW1, C_ROW2, C_ROW1, C_ROW2]
|
|
|
+for i, (txt, bg) in enumerate(zip(contents, bgs)):
|
|
|
+ cell = row2.cells[i]
|
|
|
+ set_cell_bg(cell, bg)
|
|
|
+ cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER
|
|
|
+ p = cell.paragraphs[0]
|
|
|
+ p.alignment = WD_ALIGN_PARAGRAPH.LEFT
|
|
|
+ add_run(p, txt, size=9.5, color=C_BODY)
|
|
|
+
|
|
|
+row2.cells[4].merge(row2.cells[3])
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+body('各区域均设有科幻装饰线框(四角装饰线)、边框流动动画(border-beam)及动效图标,模块之间有呼吸感的间距,整体采用深蓝科幻主题色系。')
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 5. 顶部导航栏
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('5. 顶部导航栏')
|
|
|
+body('导航栏位于页面最顶部,横贯全宽,分为左、中、右三个区域。')
|
|
|
+
|
|
|
+make_table(
|
|
|
+ ['区域', '显示内容', '说明'],
|
|
|
+ [
|
|
|
+ ['左侧', '实时时钟(时:分:秒)\n日期及星期', '每秒自动更新,金色数字显示,字体采用等宽字体'],
|
|
|
+ ['中间', 'LOGO图标\n中国安全生产科学研究院(单位名称)\n竖向分隔线\n实验室安全智能监测与管控中心(系统大标题)', 'LOGO为蓝色方形图标,带脉冲光晕动效;\n大标题采用渐变流光动画,中英文双语单位名称显示'],
|
|
|
+ ['右侧', '城市 · 天气状况\n气温(°C) / AQI空气质量指数', '显示当前天气信息及空气质量'],
|
|
|
+ ],
|
|
|
+ col_widths=[2.5, 7, 6]
|
|
|
+)
|
|
|
+
|
|
|
+note('导航栏不含任何操作按钮,3区实时监控为固定显示,无需切换。')
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 6. 1区
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('6. 1区 — 实验室基本情况统计')
|
|
|
+body('1区位于大屏左侧,由上至下包含三个功能模块。')
|
|
|
+
|
|
|
+heading2('6.1 实验室基本情况统计')
|
|
|
+body('本模块分为上部(80%)和下部(20%)两部分:')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('上部(按左4:右6比例划分)')
|
|
|
+bullet('左侧(4):SVG圆弧仪表图形,展示实验室总数(共128间),图形中心显示总数数字,下方配分级比例色条(I级红、II级橙、III级黄、IV级蓝)。', 0)
|
|
|
+bullet('右侧(6):环形图(donut chart),展示四个安全分级(I~IV级)的占比及数量,图外标注各级名称、数量(间)、百分比;图表圆心显示总数;右侧配彩色左边框明细行。', 0)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('下部(三种状态徽章)')
|
|
|
+bullet('横向并排三个状态徽章,实时显示各状态实验室数量:', 0)
|
|
|
+bullet('使用(绿色):当前正在使用的实验室数量', 1)
|
|
|
+bullet('异常(橙色):当前处于异常告警状态的实验室数量', 1)
|
|
|
+bullet('空闲(靛蓝):当前闲置的实验室数量', 1)
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+body('分级说明:')
|
|
|
+make_table(
|
|
|
+ ['安全级别', '标识颜色', '含义', '数量(示例)'],
|
|
|
+ [
|
|
|
+ ['I 级', '红色', '危险实验室', '12 间'],
|
|
|
+ ['II 级', '橙色', '较危险实验室', '28 间'],
|
|
|
+ ['III 级', '黄色', '一般危险实验室', '45 间'],
|
|
|
+ ['IV 级', '蓝色', '较安全实验室', '43 间'],
|
|
|
+ ],
|
|
|
+ col_widths=[3, 3, 5, 4.5]
|
|
|
+)
|
|
|
+
|
|
|
+divider()
|
|
|
+heading2('6.2 实验室安全分级统计')
|
|
|
+body('本模块使用堆叠柱状图统计各二级单位实验室总数及分级数据。')
|
|
|
+bullet('X轴:各二级单位名称,单位名称下方显示该单位实验室总数。')
|
|
|
+bullet('Y轴:实验室数量(间)。')
|
|
|
+bullet('每根柱子由I~IV级叠加组成,颜色对应分级(红/橙/黄/蓝)。')
|
|
|
+bullet('图表顶部显示图例(I级、II级、III级、IV级及对应颜色)。')
|
|
|
+bullet('一屏展示6个柱子,当数据量超出时,图表每5秒自动向左滚动1个单位,循环展示所有二级单位数据。')
|
|
|
+
|
|
|
+doc.add_paragraph()
|
|
|
+note('鼠标悬停在柱状图上可显示当前单位各分级详细数量的悬浮提示框。')
|
|
|
+divider()
|
|
|
+
|
|
|
+heading2('6.3 实验室进入人数统计及走势')
|
|
|
+body('本模块展示今日实验室进入与在场人数统计,以及全天走势趋势。')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('数字翻牌器(上方)')
|
|
|
+bullet('今日进入总人数:以翻牌动画形式显示,共4位数字滚动展示,金色高亮。')
|
|
|
+bullet('当前在场实验人数:同样以翻牌动画形式显示,实时更新。')
|
|
|
+
|
|
|
+heading3('折线图(下方)')
|
|
|
+bullet('X轴:当天0~24小时,按9个时间节点显示(00:00、03:00、06:00…24:00)。')
|
|
|
+bullet('Y轴:人数(人)。')
|
|
|
+bullet('进入人数(蓝色实线+渐变填充)与在场人数(金色实线+渐变填充)双线对比展示。')
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 7. 2区
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('7. 2区 — 智能设备与实验室设备统计')
|
|
|
+body('2区位于1区右侧,由上至下包含两个功能模块。')
|
|
|
+
|
|
|
+heading2('7.1 智能环境感知应用设备统计')
|
|
|
+body('本模块统计展示布设的智能物联应用设备整体情况,分为上部统计栏和下部图表区。')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('上部统计栏')
|
|
|
+bullet('在线设备数量(绿色高亮,示例:312台)')
|
|
|
+bullet('离线设备数量(红色高亮,示例:18台)')
|
|
|
+
|
|
|
+heading3('下部图表区(左右布局)')
|
|
|
+bullet('左侧:速度仪表盘样式图表,展示设备在线率百分比(示例:94.5%),金色数字显示。')
|
|
|
+bullet('右侧:2×2网格卡片,分别显示:')
|
|
|
+bullet('电子信息铭牌(86台)', 1)
|
|
|
+bullet('化学品智能终端(44台)', 1)
|
|
|
+bullet('传感器套件(128台)', 1)
|
|
|
+bullet('智能摄像设备(72台)', 1)
|
|
|
+
|
|
|
+divider()
|
|
|
+heading2('7.2 实验室设备分类及使用统计')
|
|
|
+body('本模块按 4:2:4 比例分为上、中、下三部分:')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('上部(占4)— 设备分类环形图')
|
|
|
+bullet('使用环形图展示所有实验室设备的分类分布情况。')
|
|
|
+bullet('右侧显示图例:各设备分类的颜色圆点标识、分类名称及数量(台)。')
|
|
|
+body('设备分类示例:', indent=1)
|
|
|
+make_table(
|
|
|
+ ['分类', '数量(台)'],
|
|
|
+ [
|
|
|
+ ['检测设备', '680'],
|
|
|
+ ['分析仪器', '520'],
|
|
|
+ ['制备设备', '380'],
|
|
|
+ ['安全设备', '280'],
|
|
|
+ ['辅助设备', '240'],
|
|
|
+ ['其他', '358'],
|
|
|
+ ],
|
|
|
+ col_widths=[7, 8.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading3('中部(占2)— 汇总统计')
|
|
|
+make_table(
|
|
|
+ ['指标', '说明'],
|
|
|
+ [
|
|
|
+ ['设备总数', '所有实验室设备总数(示例:2,458台)'],
|
|
|
+ ['使用总时长', '累计设备使用时长(示例:18,620小时)'],
|
|
|
+ ['设备使用率', '当前设备使用率(示例:62.4%)'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 11.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading3('下部(占4)— 设备状态饼图')
|
|
|
+bullet('使用饼图统计各使用状态的设备数量及占比。')
|
|
|
+bullet('右侧显示四种状态的颜色圆点标识及对应数量(台)。')
|
|
|
+make_table(
|
|
|
+ ['状态', '说明', '示例数量'],
|
|
|
+ [
|
|
|
+ ['使用', '当前正在使用中的设备', '486 台'],
|
|
|
+ ['空闲', '空置未使用的设备', '1,840 台'],
|
|
|
+ ['正常', '状态正常待命的设备', '98 台'],
|
|
|
+ ['维修', '正在维修或故障设备', '34 台'],
|
|
|
+ ],
|
|
|
+ col_widths=[3, 8, 4.5]
|
|
|
+)
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 8. 3区
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('8. 3区 — 实时监控')
|
|
|
+body('3区是大屏中央最大区域(比例占4.5),固定显示实时监控视图,分为左侧面板和右侧画面区两部分,无需切换。')
|
|
|
+
|
|
|
+heading2('8.1 左侧面板(功能操作区)')
|
|
|
+make_table(
|
|
|
+ ['功能组件', '说明'],
|
|
|
+ [
|
|
|
+ ['搜索框', '可输入关键词搜索楼栋、楼层或房间名称'],
|
|
|
+ ['二级单位下拉筛选', '下拉选择框,可按化学研究所/物理研究所等单位进行筛选过滤'],
|
|
|
+ ['建筑结构树状图', '可展开/折叠的树形结构,层级为:院区 > 楼栋 > 楼层 > 房间\n点击节点可选中并高亮对应监控画面'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 11.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('8.2 右侧画面区(9宫格监控)')
|
|
|
+bullet('标题行:左侧显示当前位置面包屑导航(院区 › 楼栋名称 › 楼层),右侧显示翻页按钮(‹ / ›)及页码信息。')
|
|
|
+bullet('9宫格画面:以3×3网格排列9路摄像头画面(16:9比例),每路画面使用Canvas模拟实时视频。')
|
|
|
+bullet('第一路摄像头(AI摄像头)特殊标注:')
|
|
|
+bullet('顶部左角:绿色"🤖 AI检测"徽标', 1)
|
|
|
+bullet('顶部右角:红色 REC 录制指示灯(闪烁)', 1)
|
|
|
+bullet('画面中叠加红色危险行为检测框及标签(如"危险行为: 未佩戴防护")', 1)
|
|
|
+bullet('其余8路摄像头显示常规画面(带室内场景模拟)。')
|
|
|
+
|
|
|
+note('9宫格摄像头画面为Canvas模拟渲染,不接入真实摄像头信号,如需接入真实视频流请联系IT运维人员进行配置。')
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 9. 4区
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('9. 4区 — 实验环境感知与风险预警')
|
|
|
+body('4区位于大屏最右侧,由上至下按7:3比例划分为两个功能模块。')
|
|
|
+
|
|
|
+heading2('9.1 实验环境安全智能感知(占7)')
|
|
|
+body('本模块展示每间实验室硬件传感器的实时监测数据,区域内由下向上自动滚动展示所有实验室条目(30秒一循环,鼠标悬停自动暂停)。')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('每条实验室条目包含以下信息:')
|
|
|
+make_table(
|
|
|
+ ['信息字段', '说明', '示例'],
|
|
|
+ [
|
|
|
+ ['实验室名称', '实验室中文名称(房号)', '化学分析实验室(A301)'],
|
|
|
+ ['所属单位', '二级单位名称', '化学研究所'],
|
|
|
+ ['告警状态', '正常/告警指示图标及文字', '● 正常 / 🚨 告警(闪烁)'],
|
|
|
+ ['温度 T', '当前室内温度(°C)', '22.5°C'],
|
|
|
+ ['湿度 H', '当前室内相对湿度(%RH)', '58%'],
|
|
|
+ ['TVOC', '总挥发性有机化合物浓度(mg/m³)\n超标(>0.6)时标红闪烁', '0.82 mg/m³(红色告警)'],
|
|
|
+ ['CO₂', '二氧化碳浓度(ppm)\n超标(>700)时标红闪烁', '650 ppm'],
|
|
|
+ ['O₂', '氧气浓度(%)', '20.9%'],
|
|
|
+ ],
|
|
|
+ col_widths=[3, 7, 5.5]
|
|
|
+)
|
|
|
+
|
|
|
+body('当某传感器数值超出阈值时,该实验室条目整体高亮为红色渐变效果,并触发全屏预警弹窗(详见第10章)。')
|
|
|
+
|
|
|
+divider()
|
|
|
+heading2('9.2 实验室实时风险预警(占3)')
|
|
|
+body('本模块展示本月预警响应总数及实时预警通知轮播(22秒一循环,最新通知始终显示在最上方)。')
|
|
|
+doc.add_paragraph()
|
|
|
+heading3('顶部统计')
|
|
|
+bullet('本月预警响应总数:以琥珀色/橙黄色高亮数字显示(示例:42次)。')
|
|
|
+
|
|
|
+heading3('预警通知列表(每条包含)')
|
|
|
+make_table(
|
|
|
+ ['字段', '说明'],
|
|
|
+ [
|
|
|
+ ['实验室信息', '实验室名称(房号)- 所属二级单位'],
|
|
|
+ ['异常指标', '异常传感器类型及当前超标值'],
|
|
|
+ ['预警时间', '精确到秒的时间戳(日期-时-分-秒)'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 11.5]
|
|
|
+)
|
|
|
+
|
|
|
+note('预警区域字体采用琥珀/橙色调(#fcd34d / #fb923c),不使用红色字体,区别于传感器告警区域。')
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 10. 全屏预警弹窗
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('10. 全屏预警弹窗')
|
|
|
+body('当传感器监测数据超出设定阈值,系统将自动弹出全屏预警弹窗(系统启动约5秒后自动触发演示),以科幻电影系统报警样式呈现。')
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+heading2('弹窗布局')
|
|
|
+body('弹窗分为左右两个区域:')
|
|
|
+make_table(
|
|
|
+ ['区域', '内容', '说明'],
|
|
|
+ [
|
|
|
+ ['左侧', '告警实验室实时监控画面\n(900×700 Canvas模拟)', '带红色扫描线、噪点效果;\n叠加AI危险行为检测框;\n顶部显示摄像头编号、REC录制状态;\n底部显示实验室名称及AI检测标识'],
|
|
|
+ ['右侧', '告警详细信息', '告警实验室、所属单位、告警指标、当前值/安全阈值四项信息卡片;\n底部显示紧急疏散提示文字(闪烁动效)'],
|
|
|
+ ],
|
|
|
+ col_widths=[2, 5, 8.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('弹窗操作按钮')
|
|
|
+make_table(
|
|
|
+ ['按钮', '功能'],
|
|
|
+ [
|
|
|
+ ['稍后处理', '关闭弹窗,暂时忽略告警(后续可在4区预警列表查看)'],
|
|
|
+ ['确认处理', '关闭弹窗,标记告警已处理'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 11.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('弹窗视觉特征')
|
|
|
+bullet('全屏深红色半透明遮罩,背景模糊(backdrop-filter: blur)。')
|
|
|
+bullet('弹窗主体为深红渐变边框,红色扫描线从上到下持续扫描(1.5秒一循环)。')
|
|
|
+bullet('标题"⚡ 系统预警 · ALERT"红色字体,💥 图标快速闪烁动效。')
|
|
|
+
|
|
|
+note('弹窗为全屏展示,关闭弹窗后系统恢复正常监控状态,预警信息仍保留在4区实时风险预警列表中。')
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 11. 通用交互说明
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('11. 通用交互说明')
|
|
|
+make_table(
|
|
|
+ ['交互行为', '触发方式', '效果说明'],
|
|
|
+ [
|
|
|
+ ['全屏显示', '页面加载时自动触发', '请求浏览器进入全屏模式(F11手动切换亦可)'],
|
|
|
+ ['图表悬停提示', '鼠标悬停在图表区域', '显示详细数据悬浮提示框(Tooltip)'],
|
|
|
+ ['安全分级柱状图滚动', '自动(每5秒)', '自动向左滚动1个X轴单位,循环展示'],
|
|
|
+ ['传感器列表滚动', '自动(30秒一循环)', '由下向上平滑滚动,鼠标悬停可暂停'],
|
|
|
+ ['预警通知滚动', '自动(22秒一循环)', '由下向上平滑滚动,鼠标悬停可暂停'],
|
|
|
+ ['树状图展开/折叠', '点击监控视图左侧树状图节点', '展开或折叠对应子节点'],
|
|
|
+ ['关闭预警弹窗', '点击"确认处理"或"稍后处理"按钮', '关闭全屏预警弹窗,恢复正常显示'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 5, 6.5]
|
|
|
+)
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 12. 数据说明
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('12. 数据说明')
|
|
|
+body('当前版本大屏展示的数据均为内置模拟数据(Demo数据),用于系统功能演示。如需接入真实数据,请由IT运维人员按照以下说明进行后端数据对接。')
|
|
|
+doc.add_paragraph()
|
|
|
+
|
|
|
+heading2('传感器告警阈值(默认配置)')
|
|
|
+make_table(
|
|
|
+ ['传感器指标', '正常范围', '告警阈值', '单位'],
|
|
|
+ [
|
|
|
+ ['TVOC', '< 0.6', '≥ 0.6', 'mg/m³'],
|
|
|
+ ['CO₂', '< 700', '≥ 700', 'ppm'],
|
|
|
+ ['O₂', '19.5 ~ 23.5', '< 19.5 或 > 23.5', '%'],
|
|
|
+ ['温度', '16 ~ 28', '< 16 或 > 28', '°C'],
|
|
|
+ ['湿度', '30 ~ 80', '< 30 或 > 80', '% RH'],
|
|
|
+ ],
|
|
|
+ col_widths=[4, 4, 5, 2.5]
|
|
|
+)
|
|
|
+
|
|
|
+heading2('数据刷新说明')
|
|
|
+make_table(
|
|
|
+ ['数据模块', '刷新方式'],
|
|
|
+ [
|
|
|
+ ['实时时钟', '每秒刷新'],
|
|
|
+ ['数字翻牌器(进入人数)', '页面加载时动画计数(2秒内完成)'],
|
|
|
+ ['传感器数据列表', '页面加载时渲染(静态模拟数据)'],
|
|
|
+ ['风险预警列表', '页面加载时渲染(静态模拟数据)'],
|
|
|
+ ['ECharts图表', '页面加载时初始化渲染(静态模拟数据)'],
|
|
|
+ ['柱状图自动滚动', '每5秒自动切换1个X轴步长'],
|
|
|
+ ],
|
|
|
+ col_widths=[6, 9.5]
|
|
|
+)
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+# 13. FAQ
|
|
|
+# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
+heading1('13. 常见问题(FAQ)')
|
|
|
+
|
|
|
+faqs = [
|
|
|
+ ('Q1:打开页面后图表区域空白,没有显示图表?',
|
|
|
+ '请检查网络连接是否正常,确保可以访问 cdn.jsdelivr.net(ECharts CDN地址)。如无外网访问条件,请将 ECharts JS 文件下载至本地,并将 HTML 文件头部的 CDN 引用路径改为本地相对路径。'),
|
|
|
+ ('Q2:页面一打开就弹出了预警弹窗,如何关闭?',
|
|
|
+ '这是系统的演示效果,页面加载约5秒后会自动弹出全屏预警弹窗。点击弹窗右下角的"确认处理"或"稍后处理"按钮即可关闭。'),
|
|
|
+ ('Q3:3区实时监控画面不显示或摄像头为黑屏?',
|
|
|
+ '9宫格摄像头画面为Canvas模拟渲染,页面加载完成后自动初始化。若画面为黑屏,请刷新页面后等待3~5秒。如需接入真实摄像头,请联系IT运维人员进行后端视频流配置。'),
|
|
|
+ ('Q4:页面内容显示不完整或过小,无法正常查看?',
|
|
|
+ '本大屏设计分辨率为 9600×2800px,需配合超大屏/拼接屏使用。普通1080p显示器需通过浏览器滚动查看完整内容,或将浏览器缩放比例调整为25%~33%以适配屏幕。'),
|
|
|
+ ('Q5:9宫格监控画面是否为真实摄像头接入?',
|
|
|
+ '当前版本为Canvas模拟画面,不接入真实摄像头信号。如需接入真实CCTV/RTSP视频流,需进行后端视频推流对接开发,请联系IT运维人员处理。'),
|
|
|
+ ('Q6:传感器数据是否实时更新?',
|
|
|
+ '当前版本数据为静态模拟数据,页面加载后不会自动刷新传感器数值。如需接入真实IoT传感器数据,需配置WebSocket或轮询接口,由IT运维人员进行后端集成开发。'),
|
|
|
+ ('Q7:如何修改告警阈值?',
|
|
|
+ '当前阈值配置在 index-v2.html 的 JavaScript 代码中(LABS数组及判断逻辑),修改对应字段的判断条件即可。生产环境建议将阈值配置抽取为后端可配置参数。'),
|
|
|
+]
|
|
|
+
|
|
|
+for q, a in faqs:
|
|
|
+ p = doc.add_paragraph()
|
|
|
+ p.paragraph_format.space_before = Pt(8)
|
|
|
+ p.paragraph_format.space_after = Pt(2)
|
|
|
+ add_run(p, q, bold=True, size=11, color=C_H2)
|
|
|
+ p2 = doc.add_paragraph()
|
|
|
+ p2.paragraph_format.space_before = Pt(2)
|
|
|
+ p2.paragraph_format.space_after = Pt(6)
|
|
|
+ p2.paragraph_format.left_indent = Cm(0.5)
|
|
|
+ add_run(p2, 'A:' + a, size=10.5, color=C_BODY)
|
|
|
+
|
|
|
+divider()
|
|
|
+
|
|
|
+# ── 页脚说明 ─────────────────────────────────────────────────────
|
|
|
+doc.add_paragraph()
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '中国安全生产科学研究院 · 实验室安全智能监测与管控中心 · 使用说明文档 V1.0', size=9, color=C_LABEL)
|
|
|
+p = doc.add_paragraph()
|
|
|
+p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
|
+add_run(p, '本文档仅供内部使用,未经许可不得对外发布。', size=9, italic=True, color=C_LABEL)
|
|
|
+
|
|
|
+# ── 保存 ────────────────────────────────────────────────────────
|
|
|
+out = r'C:\Users\Administrator\lab-safety-monitor\实验室安全大屏使用说明.docx'
|
|
|
+doc.save(out)
|
|
|
+print(f'已保存:{out}')
|