关于加强安全生产的通知
+一、总体要求
+1.1 具体要求
+正文内容。
+diff --git a/docs/team/cases_intent.md b/docs/team/cases_intent.md index 852d688..b52bc44 100644 --- a/docs/team/cases_intent.md +++ b/docs/team/cases_intent.md @@ -18,7 +18,11 @@ route(text, has_attachments, has_active_artifact) -> "qa" | "docgen" | "edit" | ### 3. docgen(写文档意图) 条件:text 含任一 WRITE_VERB 且含任一 DOC_TYPE -- WRITE_VERB = [写, 撰写, 拟, 起草, 编制, 生成, 编写, 拟定, 草拟, 制定] +- WRITE_VERB = [写, 撰写, 拟, 起草, 编制, 生成, 编写, 拟定, 草拟, 制定, 总结, 概括, 归纳](r4 #52 新增后三词) +- 动词自指保护(r4 #52 新增):规则 3 判定时,若 text 命中的 DOC_TYPE 恰好等于命中的 WRITE_VERB 本身 + (如「总结一下植物光合作用的过程」——「总结」既是动词又是文档类型词),不算写文档意图, + 继续向下判定。「写一篇总结」(动词=写,类型=总结)与「总结这篇论文」(动词=总结,类型=论文) + 不受影响。 - DOC_TYPE = [论文, 报告, 通知, 通告, 公告, 请示, 批复, 函, 申请书, 申请, 申报书, 标书, 合同, 协议, 方案, 计划, 总结, 汇报, 讲话稿, 致辞, 证明, 纪要, 简报, 材料, 说明书, 指南, 文档, 申报材料, 工作总结, 调研报告, 可行性报告, 项目书, 策划书, 演讲稿, 新闻稿, 文案, 简历, 制度, 规定, 办法, 细则, 章程, 声明, 邀请函, 感谢信, 慰问信, 介绍信, 推荐信, 倡议书, 述职报告, 开题报告, 结题报告, 实验报告, 分析报告, 会议纪要] - 明确排除(不属于 DOC_TYPE,防误判):介绍, 内容, 代码, 诗, 作业, 问题, 建议, 想法 @@ -28,7 +32,7 @@ route(text, has_attachments, has_active_artifact) -> "qa" | "docgen" | "edit" | ### 5. 其余一律 "qa"(漏判安全原则:不命中绝不进 docgen) -## 用例表(30 条,前后端实现与测试共用同一张表) +## 用例表(34 条,前后端实现与测试共用同一张表) | # | 输入 text | 附件 | 活动文档 | 期望 | |---|---|---|---|---| @@ -62,6 +66,10 @@ route(text, has_attachments, has_active_artifact) -> "qa" | "docgen" | "edit" | | 28 | 帮我写个会议通知模板 | 否 | 是 | docgen | | 29 | 给这个通知加个结尾 | 否 | 是 | edit | | 30 | 增加一段关于风险的描述 | 否 | 是 | edit | +| 31 | 帮我总结论文 | 是 | 否 | docgen | +| 32 | 总结一下植物光合作用的过程 | 否 | 否 | qa | +| 33 | 概括一下这个通知 | 是 | 是 | docgen | +| 34 | 归纳这篇文章 | 是 | 否 | docgen | ## 一致性要求 - dev1 的 sdk/app/services/docgen/intent.py 与 dev3 的 ui/src/intent.js 必须按本表逐条通过 diff --git a/sdk/app/routers/docgen.py b/sdk/app/routers/docgen.py index 40405d1..9e8c236 100644 --- a/sdk/app/routers/docgen.py +++ b/sdk/app/routers/docgen.py @@ -983,7 +983,11 @@ async def export_artifact( html, _rendered_css = render_html( markdown, title=title, key=key, letterhead=letterhead ) - data = await docx_from_html_document(html, title) + # 缺陷 #47a(2026-09-11):css 一并传给 DOCX 转换, + # 红头/标题样式与预览/PDF 同源;frozen_css 优先(同 PDF 路径) + data = await docx_from_html_document( + html, title, css=frozen_css or _rendered_css + ) except Exception as exc: logger.warning( "docgen: HTML→DOCX 转换失败(%s),回退 md2docx 旧路径", exc diff --git a/sdk/app/routers/test_docgen_api.py b/sdk/app/routers/test_docgen_api.py index eebbf85..43a2a2c 100644 --- a/sdk/app/routers/test_docgen_api.py +++ b/sdk/app/routers/test_docgen_api.py @@ -108,7 +108,7 @@ def _reset_mocks(monkeypatch): async def rebuild_ok(): return {"rebuilt": True} - async def docx_html_ok(html: str, title: str): + async def docx_html_ok(html: str, title: str, css: str = ""): return b"DOCX-HTML-BYTES" def render_ok(markdown, *, title, key="document", letterhead=""): diff --git a/sdk/app/services/docgen/converter.py b/sdk/app/services/docgen/converter.py index 83f9f4b..d1c9dfe 100644 --- a/sdk/app/services/docgen/converter.py +++ b/sdk/app/services/docgen/converter.py @@ -31,13 +31,17 @@ async def pdf_from_markdown(markdown: str, title: str) -> bytes: return await anyio.to_thread.run_sync(_pdf_bytes, markdown, title) -async def docx_from_html_document(html: str, title: str) -> bytes: - """HTML → docx(缺陷 #47a,2026-09-10):与 converter 其它函数同签名, - html2docx 是 CPU 同步转换,to_thread 避免阻塞事件循环。""" +async def docx_from_html_document(html: str, title: str, css: str = "") -> bytes: + """HTML → docx(缺陷 #47a,2026-09-10/11):与 converter 其它函数同签名, + html2docx 是 CPU 同步转换,to_thread 避免阻塞事件循环。 + + css:render_html 返回的模板 CSS(缺陷 #47a 同源解析,2026-09-11)。 + 为空时 html2docx 只解析 html 内嵌 ", "html.parser") + for decl in _declarations(wrapped.style): + block = merged.setdefault(decl["selector"], {}) + block.update(decl["block"]) + return merged + + +def letterhead_style(styles: dict[str, dict[str, str]]) -> tuple[_ColorRGB, float]: + """红头样式:(rgb 颜色, 字号 pt)。解析不到时回退历史常量。""" + block = styles.get(".doc-letterhead") or {} + color = parse_rgb(block.get("color", "")) or _LEGACY_LETTERHEAD_COLOR + size = parse_size_pt(block.get("font-size", "")) + if size is None: + size = _LEGACY_LETTERHEAD_SIZE_PT + return color, size + + +def heading_sizes(styles: dict[str, dict[str, str]]) -> dict[int, float]: + """h1-h3 字号(pt):解析 h1.doc-title、h2、h3 声明;缺失回落历史常量。""" + h1 = styles.get("h1.doc-title") or styles.get("h1") or {} + h2 = styles.get("h2") or {} + h3 = styles.get("h3") or {} + parsed = { + 1: parse_size_pt(h1.get("font-size", "")), + 2: parse_size_pt(h2.get("font-size", "")), + 3: parse_size_pt(h3.get("font-size", "")), + } + return { + level: parsed[level] if parsed[level] is not None else _LEGACY_HEADING_SIZES_PT[level] + for level in (1, 2, 3) + } diff --git a/sdk/app/services/docgen/intent.py b/sdk/app/services/docgen/intent.py index 3d0db8b..a0c8dc4 100644 --- a/sdk/app/services/docgen/intent.py +++ b/sdk/app/services/docgen/intent.py @@ -20,7 +20,8 @@ FORMAT_WORD = ["pdf", "docx", "doc", "word"] # 英文不区分大小写(conta EDIT_WORD = ["改", "修改", "调整", "删", "删除", "加一段", "补充", "润色", "缩写", "扩写", "重写", "改写", "优化", "加个", "增加一段"] -WRITE_VERB = ["写", "撰写", "拟", "起草", "编制", "生成", "编写", "拟定", "草拟", "制定"] +WRITE_VERB = ["写", "撰写", "拟", "起草", "编制", "生成", "编写", "拟定", "草拟", "制定", + "总结", "概括", "归纳"] # r4 #52(2026-09-11) DOC_TYPE = [ "论文", "报告", "通知", "通告", "公告", "请示", "批复", "函", "申请书", @@ -71,8 +72,16 @@ def route(text: str, has_attachments: bool, has_active_artifact: bool) -> str: return "edit" # 3. docgen:写类动词 + 文档类型词 - if _contains_any(text, WRITE_VERB) and _has_doc_type(text): - return "docgen" + # r4 #52(2026-09-11)动词自指保护:当唯一命中的 DOC_TYPE 恰好等于 + # 命中的动词本身(如「总结一下植物光合作用的过程」——「总结」既是动词 + # 又是文档类型词),不视为写文档意图(继续向下判定)。「写一篇总结」 + # (动词=写,类型=总结)与「总结这篇论文」(动词=总结,类型=论文) + # 不受影响。规则详见 docs/team/cases_intent.md 用例 31-34。 + _matched_verbs = [w for w in WRITE_VERB if w in text] + _matched_types = [w for w in DOC_TYPE if w in text] + if _matched_verbs and _matched_types and _has_doc_type(text): + if set(_matched_types) != set(_matched_verbs): + return "docgen" # 4. docgen:附件信号(拖入文件 + 写类动词) if has_attachments and _contains_any(text, WRITE_VERB): diff --git a/sdk/app/services/test_docgen_html2docx.py b/sdk/app/services/test_docgen_html2docx.py index 4e3fd53..d2b2183 100644 --- a/sdk/app/services/test_docgen_html2docx.py +++ b/sdk/app/services/test_docgen_html2docx.py @@ -127,6 +127,96 @@ def test_bold_italic_code_runs(tmp_path): assert code_found +# --------------------------------------------------------------------------- +# 缺陷 #47a(2026-09-11):红头/标题样式从 render_html 产物解析(css 参数) +# --------------------------------------------------------------------------- + +HTML_OFFICIAL_STYLED = """
+正文内容。
+