diff --git a/122-06A0014-B01001_发动机-维修手册_content_list.json b/122-06A0014-B01001_发动机-维修手册_content_list.json deleted file mode 100644 index 5cadc38..0000000 --- a/122-06A0014-B01001_发动机-维修手册_content_list.json +++ /dev/null @@ -1,9700 +0,0 @@ -[ - { - "type": "text", - "text": "船舶主发动机 JY 级维修手册", - "text_level": 1, - "bbox": [ - 166, - 379, - 833, - 519 - ], - "page_idx": 0, - "id": 1 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT1 ", - "bbox": [ - 435, - 916, - 603, - 928 - ], - "page_idx": 0, - "id": 2 - }, - { - "type": "text", - "text": "目次", - "text_level": 1, - "bbox": [ - 472, - 148, - 527, - 168 - ], - "page_idx": 1, - "id": 3 - }, - { - "type": "text", - "text": "1 安全警告. 3 \n1.1 警告.. .3 \n1.2 注意.. .3 \n2 概述... .4 \n2.1 主要功能.. .4 \n2.2 工作条件.. .4 \n2.2.1 正常运行条件.. 4 \n2.2.2 非正常运行条件. .5 \n3 组成、技术特征及接口.. .5 \n3.1 组成...... .5 \n3.2 工作原理.. .6 \n3.3 技术指标.. 11 \n3.4 接口关系.. .13 \n3.5 布置情况.. .14 \n4 维修工作指导... .15 \n4.1 维修项目索引表.. .15 \n4.2 常见故障表... .16 \n4.3 维修项目表... .17 \n5 器材保障.... .47 \n5.1 保障设施、保障设备(工具)信息汇总表. .47 \n5.2 消耗材料信息汇总表... .52 \n6 维修安全防护及注意事项汇总表.. .53 \n6.1 安全防护... .53 \n6.2 注意事项... .54", - "bbox": [ - 144, - 173, - 855, - 644 - ], - "page_idx": 1, - "id": 4 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT2 ", - "bbox": [ - 415, - 928, - 583, - 941 - ], - "page_idx": 1, - "id": 5 - }, - { - "type": "text", - "text": "1 安全警告", - "text_level": 1, - "bbox": [ - 151, - 96, - 336, - 126 - ], - "page_idx": 2, - "id": 6 - }, - { - "type": "text", - "text": "本章用于提示船舶主发动机在运行、检查及维修过程中可能存在的危险因素,明确最低安全防护要求及违规操作可能造成的后果。所有参与运行与维修的人员必须严格遵守本章规定。", - "bbox": [ - 149, - 193, - 850, - 260 - ], - "page_idx": 2, - "id": 7 - }, - { - "type": "text", - "text": "1.1 警告", - "text_level": 1, - "bbox": [ - 151, - 274, - 255, - 297 - ], - "page_idx": 2, - "id": 8 - }, - { - "type": "text", - "text": "1) 主发动机属于高温、高压、高转动惯量设备,维修作业前必须完全停车、盘车确认、挂牌隔离。", - "bbox": [ - 147, - 335, - 857, - 379 - ], - "page_idx": 2, - "id": 9 - }, - { - "type": "text", - "text": "2) 严禁在主机带压、带温、带电状态下进行任何拆卸作业,否则可能造成人员伤亡。", - "bbox": [ - 147, - 386, - 850, - 429 - ], - "page_idx": 2, - "id": 10 - }, - { - "type": "text", - "text": "3) 燃油系统、高压油泵及喷油器为高压精密部件,误操作可能导致高压喷射伤害。", - "bbox": [ - 147, - 436, - 850, - 479 - ], - "page_idx": 2, - "id": 11 - }, - { - "type": "text", - "text": "4) 吊装曲轴、活塞、气缸盖等重件时,必须使用额定载荷合格的吊具并设置专人指挥。", - "bbox": [ - 149, - 485, - 850, - 529 - ], - "page_idx": 2, - "id": 12 - }, - { - "type": "text", - "text": "1.2 注意", - "text_level": 1, - "bbox": [ - 151, - 543, - 255, - 565 - ], - "page_idx": 2, - "id": 13 - }, - { - "type": "text", - "text": "1) 所有更换件必须使用原厂或等同技术条件的认可备件。", - "bbox": [ - 188, - 605, - 695, - 623 - ], - "page_idx": 2, - "id": 14 - }, - { - "type": "text", - "text": "2) 防冻液含碱。请避免接触皮肤和眼睛,以免造成 人身伤害。", - "bbox": [ - 186, - 630, - 746, - 648 - ], - "page_idx": 2, - "id": 15 - }, - { - "type": "text", - "text": "3) 为自身安全考虑,请佩带防护设备:头盔、面罩、安全靴、防护镜、厚手套、护耳等。", - "bbox": [ - 146, - 655, - 850, - 695 - ], - "page_idx": 2, - "id": 16 - }, - { - "type": "text", - "text": "4) 如果发动机周围环境中存在疑似燃烧介质(如燃油、润滑油或液化石油汽)泄漏或排放,请不要启动或继续运行发动机。", - "bbox": [ - 146, - 702, - 850, - 745 - ], - "page_idx": 2, - "id": 17 - }, - { - "type": "text", - "text": "5) 拆装过程中严禁敲击精密偶件(如喷油嘴、柱塞偶件)。", - "bbox": [ - 189, - 752, - 715, - 770 - ], - "page_idx": 2, - "id": 18 - }, - { - "type": "text", - "text": "6) 所有密封件(O形圈、金属密封环)拆装必换。", - "bbox": [ - 186, - 776, - 630, - 794 - ], - "page_idx": 2, - "id": 19 - }, - { - "type": "text", - "text": "7) 紧固件必须按规定力矩和顺序紧固。", - "bbox": [ - 186, - 801, - 536, - 819 - ], - "page_idx": 2, - "id": 20 - }, - { - "type": "text", - "text": "8) 起吊时应使用固定在发电机组上的吊耳。请始终检查起吊设备是否处于良好状态和有足够的起吊能力(发动机以及安装的各种附件的重量)。为安全起见,应使用可调节的梁式吊具。所有吊链和缆绳应彼此平行并尽可能与发动机顶部垂直。请注意安装在发动机上的辅助设备会改变发动机的重心。因此,为了保持平衡和确保安全起见,可能需要使用专门的起吊设备。切勿在悬挂于起重设备上且没有任何支撑的发动机上进行工作。重要事项!发动机只能水平起吊。", - "bbox": [ - 149, - 825, - 852, - 892 - ], - "page_idx": 2, - "id": 21 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 2, - "id": 22 - }, - { - "type": "text", - "text": "", - "bbox": [ - 147, - 90, - 850, - 183 - ], - "page_idx": 3, - "id": 23 - }, - { - "type": "text", - "text": "2 概述", - "text_level": 1, - "bbox": [ - 147, - 193, - 263, - 224 - ], - "page_idx": 3, - "id": 24 - }, - { - "type": "text", - "text": "2.1 主要功能", - "text_level": 1, - "bbox": [ - 149, - 298, - 310, - 322 - ], - "page_idx": 3, - "id": 25 - }, - { - "type": "text", - "text": "船舶主发动机为低速二冲程船用推进柴油机,是船舶推进系统的核心动力装置,其主要功能是将燃油化学能转化为机械能,通过曲轴输出转矩,驱动推进轴系和螺旋桨,实现船舶航行。", - "bbox": [ - 147, - 360, - 852, - 428 - ], - "page_idx": 3, - "id": 26 - }, - { - "type": "text", - "text": "发动机主要由以下子系统组成:", - "bbox": [ - 189, - 434, - 462, - 451 - ], - "page_idx": 3, - "id": 27 - }, - { - "type": "text", - "text": "1) 机座与机架组件:承载与结构支撑; \n2) 曲柄连杆机构:实现往复—旋转运动转换; \n3) 燃烧室部件:完成燃烧做功; \n4) 排气阀驱动系统:控制废气排放; \n5) 燃油喷射系统:完成燃油定时、定量喷射; \n6) 扫气与增压系统:提高换气效率与功率密度。", - "bbox": [ - 193, - 457, - 628, - 606 - ], - "page_idx": 3, - "id": 28 - }, - { - "type": "text", - "text": "2.2 工作条件", - "text_level": 1, - "bbox": [ - 149, - 621, - 310, - 645 - ], - "page_idx": 3, - "id": 29 - }, - { - "type": "text", - "text": "2.2.1 正常运行条件", - "text_level": 1, - "bbox": [ - 149, - 692, - 381, - 714 - ], - "page_idx": 3, - "id": 30 - }, - { - "type": "text", - "text": "1)环境条件长期纵倾: $\\pm 5 ^ { \\circ }$ ;横倾: $\\pm 1 5 ^ { \\circ }$ °; \n短期纵摇: $\\pm 1 0 ^ { \\circ }$ °( $5 { \\sim } 8 \\ \\textrm { s } )$ );横摇:± $4 5 ^ { \\circ }$ ( $( 8 \\sim 1 3 ~ \\mathrm { ~ s ~ } )$ ); \n环境温度: $+ 5 \\mathrm { ~ \\small ~ \\displaystyle ~ \\int ~ } \\sim \\mathrm { ~ \\small ~ \\displaystyle ~ + 5 5 ~ \\mathrm { ~ \\small ~ \\displaystyle ~ C ~ } ~ }$ ; \n相对湿度: $\\leqslant 9 3 \\%$ ( $4 0 \\textrm { ‰}$ )。", - "bbox": [ - 188, - 752, - 715, - 869 - ], - "page_idx": 3, - "id": 31 - }, - { - "type": "text", - "text": "2)能源条件", - "bbox": [ - 188, - 876, - 304, - 894 - ], - "page_idx": 3, - "id": 32 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 3, - "id": 33 - }, - { - "type": "table", - "img_path": "images/c355a19982798077fbb5e367b87027f5b1286e4fded2ad87f76b70907ffae553.jpg", - "table_caption": [ - "表2.1 冷水机组正常使用时的能源条件" - ], - "table_footnote": [], - "table_body": "
序号项目船舶主发动机
1.燃油船用重油/轻柴油(符合ISO 标准)
2.润滑油主机系统油(厂家指定牌号)
3.冷却介质淡水/海水冷却系统
4.控制电源AC 380V/50 Hz
", - "bbox": [ - 137, - 109, - 858, - 203 - ], - "page_idx": 4, - "id": 34 - }, - { - "type": "text", - "text": "2.2.2 非正常运行条件", - "text_level": 1, - "bbox": [ - 149, - 224, - 401, - 248 - ], - "page_idx": 4, - "id": 35 - }, - { - "type": "table", - "img_path": "images/8c192eeca369324fd1e1ec2d0b8eab90cecf10dd4654421d3972bc2da6ef8a59.jpg", - "table_caption": [ - "表2.2 非正常输入条件及产生后果" - ], - "table_footnote": [], - "table_body": "
序号项目非正常输入条件可能产生后果
1.润滑油系统润滑油压力过低主轴承、连杆轴承润滑失效,导致轴承烧损,严重时引发曲轴抱死
2.冷却系统冷却水中断或流量不足气缸套、活塞、气缸盖温度急剧升高,发生热变形或热咬死
3.燃油系统燃油污染(水分、杂质超标)喷油器偶件、高压油泵柱塞偶件异常磨损,喷油雾化恶化
4.扫气系统扫气压力不足气缸换气不良,燃烧恶化,排气温度升高
5.增压系统涡轮增压器效率下降或失效主机功率下降,燃油消耗率上升
6.电控系统控制信号异常或供电不稳启停、保护、报警功能异常,存在误操作风险
", - "bbox": [ - 137, - 305, - 860, - 519 - ], - "page_idx": 4, - "id": 36 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 4, - "id": 37 - }, - { - "type": "table", - "img_path": "images/7a4db648aa24b5e07fb8160907607ef10b5165ca595cf5ba1348ac57d7df4c04.jpg", - "table_caption": [ - "表2.3 设备故障非正常输出条件及可能产生后果" - ], - "table_footnote": [], - "table_body": "
序号故障非正常输出条件可能产生后果
1.主轴承或连杆轴承损坏曲轴输出扭矩不稳定,振动和噪声显著增大推进轴系振动加剧,可能引发轴系对中破坏,影响推进系统安全
2.气缸套或活塞严重磨损单缸功率下降,缸间功率不均主机运行不平稳,长期运行可能导致曲轴疲劳损伤
3.排气阀密封失效排气温度异常升高,排气背压增大涡轮增压器过热,降低增压系统使用寿命
4.喷油器雾化不良燃烧延迟,燃烧不完全,排烟恶化排气系统积碳增加,空冷器、涡轮效率下降
5.冷却系统效率降低主机整体热负荷增大,温度报警频繁附属设备(冷却泵、换热器)超负荷运行,可靠性下降
6.润滑油系统故障润滑油温度升高、油质劣化加快加速各运动副磨损,缩短主发动机大修周期
7.主发动机功率异常波动推进功率输出不稳定船舶航速控制困难,影响操纵性能和航行安全
8.主机紧急停机推进动力瞬间中断对船舶航行安全造成直接影响,可能引发次生事故
", - "bbox": [ - 132, - 109, - 865, - 388 - ], - "page_idx": 5, - "id": 38 - }, - { - "type": "text", - "text": "3 组成、技术特征及接口", - "text_level": 1, - "bbox": [ - 146, - 392, - 557, - 424 - ], - "page_idx": 5, - "id": 39 - }, - { - "type": "text", - "text": "3.1 组成", - "text_level": 1, - "bbox": [ - 149, - 498, - 257, - 520 - ], - "page_idx": 5, - "id": 40 - }, - { - "type": "text", - "text": "船舶主发动机主要由机座与机架组件、曲柄连杆机构、燃烧室部件、排气阀驱动系统、燃油喷射系统、扫气与增压系统等组成,设备组成图见图 3.1,各组成部分的功能及数量见表3.1。", - "bbox": [ - 149, - 558, - 848, - 627 - ], - "page_idx": 5, - "id": 41 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 5, - "id": 42 - }, - { - "type": "image", - "img_path": "images/171aea58f3d26119162df4d3205d10e8063b313a42a02e53f6262dd999aeabc8.jpg", - "image_caption": [ - "图3.1 船舶主发动机组成图" - ], - "image_footnote": [], - "bbox": [ - 240, - 108, - 761, - 442 - ], - "page_idx": 6, - "id": 43 - }, - { - "type": "table", - "img_path": "images/b0db3dfb6c04f161e20d160458d6a8e52d262898fe26cae548d91a04804d2314.jpg", - "table_caption": [ - "表3.1 船舶主发动机组成部分" - ], - "table_footnote": [], - "table_body": "
序号组成部分功能数量
1机座与机架组件承重与结构支撑1
2曲柄连杆机构动力转换1
3燃烧室部件燃烧做功1
4排气阀驱动系统排气控制1
5燃油喷射系统喷油控制1
6扫气与增压系统换气增压1
", - "bbox": [ - 139, - 485, - 858, - 620 - ], - "page_idx": 6, - "id": 44 - }, - { - "type": "text", - "text": "3.2 工作原理", - "text_level": 1, - "bbox": [ - 147, - 627, - 310, - 650 - ], - "page_idx": 6, - "id": 45 - }, - { - "type": "text", - "text": "主发动机为低速二冲程柴油机。燃油经燃油供给单元加压后,由高压油泵按曲轴角度控制,通过喷油器喷入气缸内,与压缩空气混合燃烧。燃烧产生的高温高压推动活塞下行,经活塞杆、连杆带动曲轴旋转输出功率。废气经排气阀排出,扫气系统向气缸内补充新鲜空气,完成工作循环。", - "bbox": [ - 147, - 688, - 852, - 781 - ], - "page_idx": 6, - "id": 46 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 6, - "id": 47 - }, - { - "type": "image", - "img_path": "images/7b93c6cd0b97ceb2852104f53b5b26ecd268040953c0bd5a9e430ab75d6f4c87.jpg", - "image_caption": [ - "船舶主发动机工作原理", - "图3.2 船舶主发动机组成图" - ], - "image_footnote": [], - "bbox": [ - 161, - 128, - 826, - 419 - ], - "page_idx": 7, - "id": 48 - }, - { - "type": "text", - "text": "机座与机架组件用于称重与结构支持,其整体图如图3.3所示。", - "bbox": [ - 188, - 443, - 744, - 461 - ], - "page_idx": 7, - "id": 49 - }, - { - "type": "image", - "img_path": "images/d044a3416e3c9ebb48db4ede46c4fe67a379c0ade5a6b3f0f914d0ee07dd3ac7.jpg", - "image_caption": [ - "图3.3 机座与机架组件整体图" - ], - "image_footnote": [], - "bbox": [ - 152, - 498, - 838, - 795 - ], - "page_idx": 7, - "id": 50 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 7, - "id": 51 - }, - { - "type": "image", - "img_path": "images/b0a392fc003700febc001175e8cbc7c57e8a9b1eb88072b4e62f03dd9f7aa4ce.jpg", - "image_caption": [ - "图3.4 曲柄连杆机构工作原理图" - ], - "image_footnote": [], - "bbox": [ - 163, - 96, - 847, - 476 - ], - "page_idx": 8, - "id": 52 - }, - { - "type": "text", - "text": "曲柄连杆机构的作用是提供燃烧场所,把燃料燃烧后产生的气体作用在活塞顶上的膨胀压力转变为曲轴旋转的转矩,不断输出动力。将气体的压力变为曲轴的转矩,将活塞的往复运动变为曲轴的旋转运动,把燃烧作用在活塞顶上的力转变为曲轴的转矩,以向工作机械输出机械能。", - "bbox": [ - 147, - 502, - 850, - 594 - ], - "page_idx": 8, - "id": 53 - }, - { - "type": "image", - "img_path": "images/b8aed03bc813b595d82bc8c1c67944dc6841d2f850b4ba6b891a464420551873.jpg", - "image_caption": [ - "图3.5 燃烧室部件工作原理图" - ], - "image_footnote": [], - "bbox": [ - 267, - 613, - 736, - 788 - ], - "page_idx": 8, - "id": 54 - }, - { - "type": "text", - "text": "图3.5是燃烧室部件的工作原理图,燃烧过程组成部分主要有:初始段、燃烧段、稀释段。在初始段,燃料喷射到回流区,混合比接近化学当量比,要求确保火焰稳定。在燃烧段,加入二次空气,促进燃料完全燃烧。在稀释段,加入空气与废气混合,降低温度,使燃烧室排气管温度分布,与汽轮机、喷口导向叶片相适应。", - "bbox": [ - 147, - 833, - 850, - 900 - ], - "page_idx": 8, - "id": 55 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 8, - "id": 56 - }, - { - "type": "discarded", - "text": "", - "bbox": [ - 811, - 458, - 848, - 478 - ], - "page_idx": 8, - "id": 57 - }, - { - "type": "text", - "text": "", - "bbox": [ - 147, - 91, - 848, - 134 - ], - "page_idx": 9, - "id": 58 - }, - { - "type": "image", - "img_path": "images/a0d4cbddaa06e49278a94439ff43b574c222473044c191cb42cfc08411f5bf81.jpg", - "image_caption": [ - "图3.6 排气阀驱动系统工作原理图" - ], - "image_footnote": [], - "bbox": [ - 287, - 153, - 726, - 468 - ], - "page_idx": 9, - "id": 59 - }, - { - "type": "text", - "text": "船舶柴油机排气阀驱动系统原理主要是利用 机械连杆、凸轮轴和液压/气动装置,结合发动机的转速和气缸压力信号,通过精确的凸轮机构控制排气阀的开启时机与开启度,将燃烧后的废气顺畅排出,以实现高效换气,其核心是カム(凸轮)与挺杆/摇臂的配合动作,实现气门与气缸盖的精确密封与打开。", - "bbox": [ - 147, - 498, - 852, - 588 - ], - "page_idx": 9, - "id": 60 - }, - { - "type": "text", - "text": "核心原理与步骤 ", - "bbox": [ - 188, - 594, - 336, - 612 - ], - "page_idx": 9, - "id": 61 - }, - { - "type": "text", - "text": "动力源:曲轴通过正时齿轮(或链条)带动凸轮轴旋转,提供驱动动力。", - "bbox": [ - 188, - 619, - 826, - 637 - ], - "page_idx": 9, - "id": 62 - }, - { - "type": "text", - "text": "凸轮驱动:凸轮轴上特定的凸轮轮廓,在旋转时顶起与其配合的挺杆或摇臂。", - "bbox": [ - 142, - 643, - 848, - 684 - ], - "page_idx": 9, - "id": 63 - }, - { - "type": "text", - "text": "传递运动:挺杆/摇臂将凸轮的旋转运动转化为直线往复运动,传递给排气阀。", - "bbox": [ - 146, - 692, - 848, - 733 - ], - "page_idx": 9, - "id": 64 - }, - { - "type": "text", - "text": "阀门启闭:排气阀在弹簧(或液压)的弹力作用下,由凸轮顶开,并在凸轮离开后关闭,完成排气过程。", - "bbox": [ - 147, - 740, - 848, - 783 - ], - "page_idx": 9, - "id": 65 - }, - { - "type": "text", - "text": "精确控制:凸轮的形状和位置是经过精心设计,确保排气阀在活塞到达排气行程末端时准时开启,并在进入压缩行程前完全关闭,实现高效换气。", - "bbox": [ - 147, - 789, - 848, - 832 - ], - "page_idx": 9, - "id": 66 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 9, - "id": 67 - }, - { - "type": "image", - "img_path": "images/1512b1e9716b2d1617a6ed49f0fb99d87fa0944d1cc6916d1c9f1a5e30e74653.jpg", - "image_caption": [ - "图3.7 燃油喷射系统工作原理图" - ], - "image_footnote": [], - "bbox": [ - 201, - 102, - 800, - 367 - ], - "page_idx": 10, - "id": 68 - }, - { - "type": "text", - "text": "如图3.7中船舶柴油机燃油喷射系统原理,核心在于高压将柴油雾化喷入高温高压的压燃气缸中,利用压强和温度自燃,无需火花塞点火,主要包括供油、增压、喷射、点火燃烧几个环节,系统通常由低压供油(油箱->低压油泵->滤清器),高压输送(高压油泵->油轨/柱塞),精密喷射(喷油器->气缸),以及电子控制单元(ECU)组成,实现精确控制燃油量、喷油正时和压力,满足不同工况下的动力和排放要求。", - "bbox": [ - 147, - 410, - 855, - 550 - ], - "page_idx": 10, - "id": 69 - }, - { - "type": "image", - "img_path": "images/13ca99936db8079f936aa3d2ce9b1f06947ba673b0715c73f599588a5735542f.jpg", - "image_caption": [ - "图3.8 扫气与增压系统工作原理图" - ], - "image_footnote": [], - "bbox": [ - 245, - 569, - 784, - 821 - ], - "page_idx": 10, - "id": 70 - }, - { - "type": "text", - "text": "船舶柴油机扫气与增压系统原理核心在于废气涡轮增压和扫气过程配合,利用发动机排出的高温高压废气驱动涡轮,带动同轴压气机将新鲜空气高压送入气缸,增加空气密度,允许喷入更多燃油,从而大幅提高功率,而扫气过程则负责用压缩空气将气缸内的余热废气排出,实现进排气的高效混合与置换。", - "bbox": [ - 147, - 856, - 850, - 897 - ], - "page_idx": 10, - "id": 71 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 10, - "id": 72 - }, - { - "type": "text", - "text": "", - "bbox": [ - 149, - 91, - 852, - 134 - ], - "page_idx": 11, - "id": 73 - }, - { - "type": "text", - "text": "增压系统原理(废气涡轮增压)能量回收:柴油机排出的约 $7 0 0 { - } 9 0 0 ^ { \\circ } \\mathrm { ~ C ~ }$ 的高温废气进入增压器的涡轮端,驱动涡轮高速旋转。空气压缩:涡轮通过主轴带动同轴的压气机(离心式)高速旋转,将新鲜空气吸入并压缩,压力升高(2-3个大气压)。进气增密:增压后的高密度、高压力空气被送入气缸,填满气缸,为喷入更多燃油创造条件。功率提升:更多的燃油在更多空气中燃烧,产生更大的热能和压力,有效提高柴油机功率。", - "bbox": [ - 147, - 140, - 855, - 280 - ], - "page_idx": 11, - "id": 74 - }, - { - "type": "text", - "text": "扫气系统原理(二冲程柴油机常见)扫气方式:在二冲程柴油机中,活塞下行至排气口打开后,气缸内的废气依靠自身压力排出,同时扫气箱(或增压箱)中的新鲜空气通过扫气口进入气缸,将剩余废气“扫”出。扫气作用:将气缸内的废气排出,为下一次进气做准备。利用扫气空气的压力,提高气缸内的初始空气密度,提升换气效率。增压器与扫气结合:增压器压气机提供的增压空气,直接送入扫气箱,再由扫气口进入气缸,实现增压与扫气的联动,形成高效的进排气过程。", - "bbox": [ - 149, - 286, - 852, - 451 - ], - "page_idx": 11, - "id": 75 - }, - { - "type": "text", - "text": "3.3 技术指标", - "text_level": 1, - "bbox": [ - 149, - 466, - 310, - 488 - ], - "page_idx": 11, - "id": 76 - }, - { - "type": "text", - "text": "船舶主发动机的基本指标参见表3.2。", - "bbox": [ - 189, - 527, - 517, - 545 - ], - "page_idx": 11, - "id": 77 - }, - { - "type": "table", - "img_path": "images/b8129b2d58f664243ef00ba48170235a94425adcd1139e80815045a9ed1f716b.jpg", - "table_caption": [ - "表3.2 船舶主发动机基本参数" - ], - "table_footnote": [], - "table_body": "
指标名称参数值
1、功能特性
类型低速、二冲程、直列六缸、涡轮增压、不可逆转式船用柴油机
燃油类型重质燃料油(HF0),黏度 ≤ 700 cSt@ 50°C
启动方式压缩空气启动(3.0MPa)
额定转速127 r/min
气缸数6
缸径× 行程500 mm × 2200 mm
平均有效压力(BMEP)≈ 1.85 MPa
2、能力限制
最大持续功率(MCR)8,520 kW (@ 127 r/min)
最小稳定运行转速20% MCR(约 25r/min)
排气温度(正常工况)≤ 420℃
扫气压力0.32 MPa
3、额定输出
指标名称参数值
输出功率8,520 kW(≈ 11,580 HP)
输出扭矩~ 640 kN·m
燃油消耗率(ISO条件)≤172 g/kWh
滑油消耗率≤0.6 g/kWh
4、环境特性
工作环境温度-25℃~ +50 ℃
冷却水进口温度≤ 36℃
相对湿度≤95%(无凝露)
单位散热量(总)≈ 1,800 kW(含缸套水、活塞冷却、润滑油等)
外形尺寸与重量
整机外形尺寸(L×W×H)≈ 11,200 mm × 4,500 mm × 6,800 mm
总干重(不含滑油、冷却水)≈ 210,000 kg
5、外形尺寸、重量
重量焊接机座组件(0101)18,500 kg
A型机架组件(0102)12,400 kg
曲轴组件(0201)28,000 kg
飞轮(020103)3,500 kg
涡轮增压器(0601)2,100 kg
空冷器(0602)850kg
辅助鼓风机(0603,单台)120 kg(共2台)
6、其它指标
设计寿命≥ 25 年(或 200,000小时)
关键寿命件更换周期气缸套:30,000~40,000 h;活塞环:15,000~25,000 h;排气阀:20,000 h
控制系统电子控制燃油喷射(ME-C 系统)
安全保护超速、滑油低压、冷却水高温、曲轴箱油雾浓度等自动停机保护
", - "bbox": [ - 137, - 569, - 860, - 901 - ], - "page_idx": 11, - "id": 78 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 11, - "id": 79 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 139, - 87, - 860, - 781 - ], - "page_idx": 12, - "id": 80 - }, - { - "type": "text", - "text": "3.4 接口关系", - "text_level": 1, - "bbox": [ - 147, - 815, - 310, - 838 - ], - "page_idx": 12, - "id": 81 - }, - { - "type": "text", - "text": "船舶主推进柴油机作为全船核心动力装置,通过多种能源、信息及机械接", - "bbox": [ - 184, - 877, - 850, - 896 - ], - "page_idx": 12, - "id": 82 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 588, - 928 - ], - "page_idx": 12, - "id": 83 - }, - { - "type": "text", - "text": "口与舰船平台(JC)及其他子系统实现集成。其主要接口包括安装接口、能源供给/排出接口(燃油、滑油、冷却水、扫气空气、排气)、以及监测与控制信息接口。", - "bbox": [ - 149, - 91, - 850, - 158 - ], - "page_idx": 13, - "id": 84 - }, - { - "type": "text", - "text": "1) 安装接口", - "text_level": 1, - "bbox": [ - 189, - 166, - 312, - 183 - ], - "page_idx": 13, - "id": 85 - }, - { - "type": "text", - "text": "主发动机通过 焊接机座组件(0101) 安装于船体基座上,由 48 根${ \\tt M } 4 8 \\times 3 2 0$ 地脚螺栓(010103) 固定,确保运行中承受交变载荷与振动。推力由 推力轴承座(010102) 传递至船体结构,实现轴系推力的有效支撑。", - "bbox": [ - 147, - 190, - 852, - 256 - ], - "page_idx": 13, - "id": 86 - }, - { - "type": "text", - "text": "2) 能源接口", - "text_level": 1, - "bbox": [ - 188, - 262, - 312, - 280 - ], - "page_idx": 13, - "id": 87 - }, - { - "type": "text", - "text": "燃油系统:由 燃油供给单元(0501) 接收来自日用油柜的低压燃油,经高压油泵(0503) 加压后通过 高压油管(040202 / 0503 高压油路) 输送至喷油器组件(0502),实现缸内定时定量喷射。", - "bbox": [ - 149, - 287, - 852, - 354 - ], - "page_idx": 13, - "id": 88 - }, - { - "type": "text", - "text": "滑油系统:外部滑油泵提供压力滑油,经机座内部油道分配至 主轴承(010101)、曲轴主轴颈(020102)、连杆大端轴承(020201) 等关键摩擦副,并润滑 涡轮增压器轴承组件(060103)。", - "bbox": [ - 151, - 360, - 855, - 428 - ], - "page_idx": 13, - "id": 89 - }, - { - "type": "text", - "text": "冷却水系统:高温淡水回路流经 气缸套冷却水套(030303) 和 气缸盖,低温海水通过 空冷器(0602) 对增压扫气空气进行冷却。", - "bbox": [ - 151, - 434, - 843, - 476 - ], - "page_idx": 13, - "id": 90 - }, - { - "type": "text", - "text": "扫气与排气系统:扫气空气由 辅助鼓风机(0603) 或 涡轮增压器(0601) 提供,经 空冷器(0602) 冷却后进入 气缸套扫气口;", - "bbox": [ - 156, - 482, - 848, - 525 - ], - "page_idx": 13, - "id": 91 - }, - { - "type": "text", - "text": "燃烧废气驱动 涡轮增压器涡轮转子轴(060101) 后,经排气管排至烟囱。", - "bbox": [ - 181, - 531, - 847, - 549 - ], - "page_idx": 13, - "id": 92 - }, - { - "type": "text", - "text": "启动与安全系统:启动阀(030102) 接入压缩空气启动管路,用于主机启动;安全阀(030103) 与 示功阀(030104) 分别用于超压保护与燃烧状态检测。", - "bbox": [ - 147, - 556, - 850, - 621 - ], - "page_idx": 13, - "id": 93 - }, - { - "type": "text", - "text": "3) 信息与监测接口", - "text_level": 1, - "bbox": [ - 188, - 630, - 374, - 648 - ], - "page_idx": 13, - "id": 94 - }, - { - "type": "text", - "text": "各缸配置 示功阀(030104),支持机械式或电子式示功仪接入,用于燃烧分析;注油器接头(030302) 可连接智能注油监控系统,实现气缸油按需供给;主轴承、增压器等关键部位预留温度、振动传感器安装孔位,支持状态监测系统(CMS)数据采集;控制系统通过 CAN 或 Modbus 通信接口与主机遥控系统、机舱自动化系统交互,传输转速、负荷、故障代码等信息。", - "bbox": [ - 149, - 653, - 858, - 770 - ], - "page_idx": 13, - "id": 95 - }, - { - "type": "text", - "text": "3.5 布置情况", - "text_level": 1, - "bbox": [ - 149, - 783, - 309, - 806 - ], - "page_idx": 13, - "id": 96 - }, - { - "type": "text", - "text": "全船共配置 1 台 船舶主推进柴油机,配套系统按功能分区布置如下:船舶主推进柴油机整体布置于主机舱中部偏后位置,沿船体纵向中心线安", - "bbox": [ - 186, - 845, - 850, - 889 - ], - "page_idx": 13, - "id": 97 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 13, - "id": 98 - }, - { - "type": "text", - "text": "装,输出端通过推力轴承与中间轴相连,最终驱动螺旋桨。该布置确保轴系对中良好、重心居中,有利于船舶稳性与振动控制。", - "bbox": [ - 147, - 91, - 850, - 134 - ], - "page_idx": 14, - "id": 99 - }, - { - "type": "text", - "text": "船舶主发动机布置情况见表3.3。", - "bbox": [ - 188, - 140, - 477, - 159 - ], - "page_idx": 14, - "id": 100 - }, - { - "type": "table", - "img_path": "images/c986f8d4de156a5102888d0ab6e9cfbd824ae4a478067b6b26cd098603b79a79.jpg", - "table_caption": [ - "表3.3 船舶主发动机布置情况" - ], - "table_footnote": [], - "table_body": "
序号设备名称位置信息
1船舶主推进柴油机 (整机)主机舱中部,沿船体纵舶线安装
2焊接机座组件(0101)固定于主机舱船体基座上
3A型机架组件(0102)安装于焊接机座上方
4曲轴组件(0201)位于机座主轴承座内,纵向贯穿主机
5连杆组件(0202)连接曲轴与活塞,每缸1套,共6套
6气缸盖组件(0301)安装于气缸套顶部,共6个
7活塞与活塞杆组件(0302)位于气缸套内,每缸1套,共6套
8气缸套组件(0303)嵌入机架水腔中,共6套
9排气阀组件(0401)安装于气缸盖顶部,每缸1套
10液压驱动器(0402)布置于气缸盖侧上方,与排气阀联动
11燃油供给单元(0501)主机前端右侧平台
12高压油泵(0503)安装于凸轮轴箱体上,每缸1台
13喷油器组件(0502)插入气缸盖中心孔,每缸3支(共18支)
14涡轮增压器(0601)主机排气总管上方,垂直安装
15空冷器(0602)增压器下游,固定于机架顶部
16辅助鼓风机(0603)机舱两侧应急风机平台,共2台
17启动阀(030102)集成于气缸盖,连接启动空气管路
18安全阀(030103)安装于气缸盖测压口
19示功阀(030104)位于气缸盖示功通道接口处
20活塞杆填料函(030206)安装于十字头导板下方密封区域
", - "bbox": [ - 137, - 181, - 858, - 624 - ], - "page_idx": 14, - "id": 101 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 14, - "id": 102 - }, - { - "type": "text", - "text": "4 维修工作指导", - "text_level": 1, - "bbox": [ - 149, - 96, - 400, - 126 - ], - "page_idx": 15, - "id": 103 - }, - { - "type": "text", - "text": "4.1 维修项目索引表", - "text_level": 1, - "bbox": [ - 149, - 200, - 391, - 224 - ], - "page_idx": 15, - "id": 104 - }, - { - "type": "table", - "img_path": "images/1bf4257762737ba05bd8af011f2bac7e9db56c3cc2903660b84076e2b4b2f640.jpg", - "table_caption": [ - "表4.1 船舶主发动机维修项目索引表" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别顶购
MT00101机座与机架组件保养机座与机架组件1MJY级20
MT0020101焊接机座组件检查主轴承座安装状态6M/2000hJY级22
MT0030201曲轴组件检测曲轴主轴颈跳动量1A/8000hJY级24
MT004020201连杆大端轴承更换连杆大端轴承2A/12000hJY级26
MT005020203连杆小端轴承更换连杆小端轴承2A/12000hJY级29
MT006030201活塞头拆检活塞头磨损情况1A/8000hJY级31
MT0070302031号压缩环更换1号压缩环1A/8000hJY级33
MT0080302042-4号活塞环更换2-4号活塞环1A/8000hJY级35
MT009030301气缸套检测气缸套内径磨损量1A/8000hJY级37
MT010030301气缸套更换气缸套4A/32000hJY级40
MT011040102阀杆检查排气阀杆密封面磨损6M/4000hJY级43
MT012040103阀座更换排气阀座2A/16000hJY级45
MT013050201喷油嘴偶件更换喷油嘴偶件6M/4000hJY级47
MT014050301柱塞偶件更换高压油泵柱塞偶件1A/8000hJY级49
MT015060103轴承组件更换涡轮增压器轴承组件2A/16000hZJ级52
MT016060201管束芯体清洗空冷器管束芯体3MZJ级54
MT017020201连杆大端轴承修复连杆大端轴承异常磨损1UZJ级57
MT018030201活塞头修复活塞头部烧蚀1UZJ级59
维修项目编号组成编码名称维修项目维修间隔期维修级别页购
MT0190502喷油器组件排除喷油器雾化不良故障1UZJ级61
MT02001机座与机架组件排除主机功率异常波动故障1UZJ级63
", - "bbox": [ - 109, - 275, - 889, - 900 - ], - "page_idx": 15, - "id": 105 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 15, - "id": 106 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 109, - 90, - 889, - 199 - ], - "page_idx": 16, - "id": 107 - }, - { - "type": "text", - "text": "4.2 常见故障表", - "text_level": 1, - "bbox": [ - 149, - 205, - 337, - 228 - ], - "page_idx": 16, - "id": 108 - }, - { - "type": "table", - "img_path": "images/6014ee15a31de57d71704ff096f47b11185f92108ab14d81dcc4ef9c6b1f971c.jpg", - "table_caption": [ - "表4.2 船舶主发动机常见故障表" - ], - "table_footnote": [], - "table_body": "
序号故障现象故障原因维修项目
1机座与机架组件运行中振动异常增大主轴承或连杆大端轴承磨损执行以下维修项目:MT004更换连杆大端轴承MT017 修复连杆大端轴承异常磨损
曲轴主轴颈跳动超差执行以下维修项目:MT003 检测曲轴主轴颈跳动量
2气缸套排气温度异常升高排气阀密封面磨损或阀座烧蚀执行以下维修项目:MT011 检查排气阀杆密封面磨损MT012更换排气阀座
涡轮增压器轴承损坏执行以下维修项目:MT015 更换涡轮增压器轴承组件
3扫气箱内发现润滑油泄漏活塞杆填料函密封失效执行以下维修项目:MT001保养机座与机架组件
4轴承组件启动困难或压缩压力不足缸盖密封环老化失效执行以下维修项目:MT001保养机座与机架组件
6机座与机架组件功率输出不稳定喷油器工作不一致执行以下维修项目:MT019 排除喷油器雾化不良故障
调速系统响应异常执行以下维修项目:MT020 排除主机功率异常波动故障
7空冷器后扫气温度持续偏高空冷器管束芯体结垢或堵塞执行以下维修项目:MT016 清洗空冷器管束芯体
8机座与机架组件润滑油消耗异常增加活塞环磨损或断裂执行以下维修项目:MT007更换1号压缩环MT008更换2-4号活塞环
活塞杆填料函磨损执行以下维修项目:MT001保养机座与机架组件
9高压燃油管路附近有油渍高压油管接头密封失效执行以下维修项目:MT014 更换高压油泵柱塞偶件
10轴承组件紧急停机润滑油压力骤降执行以下维修项目:MT001保养机座与机架组件
多缸燃烧严重失衡执行以下维修项目:MT020 排除主机功率异常波动故障
", - "bbox": [ - 137, - 284, - 860, - 846 - ], - "page_idx": 16, - "id": 109 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 16, - "id": 110 - }, - { - "type": "text", - "text": "4.3 维修项目表", - "text_level": 1, - "bbox": [ - 151, - 98, - 337, - 122 - ], - "page_idx": 17, - "id": 111 - }, - { - "type": "text", - "text": "本节主要填写各维修项目的修理表,包括预防性、恢复性维修、故障排查项目。", - "bbox": [ - 147, - 161, - 850, - 203 - ], - "page_idx": 17, - "id": 112 - }, - { - "type": "table", - "img_path": "images/e034f319e6109091e41a7281631ed10b6b3bdc573fc5ba2c494a9a513cd2f968.jpg", - "table_caption": [ - "表 4.3 MT001 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT00101机座与机架组件保养机座与机架组件1MJY级
", - "bbox": [ - 141, - 228, - 857, - 288 - ], - "page_idx": 17, - "id": 113 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 288, - 257, - 302 - ], - "page_idx": 17, - "id": 114 - }, - { - "type": "text", - "text": "1.保养作业前,必须在主机控制面板悬挂“禁止启动”红色警示牌; \n2.机油排放区域应铺设防滑吸油垫,并设置围挡防止油液外溢。", - "bbox": [ - 179, - 302, - 727, - 331 - ], - "page_idx": 17, - "id": 115 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 147, - 332, - 257, - 346 - ], - "page_idx": 17, - "id": 116 - }, - { - "type": "text", - "text": "1.保养前确认主机已停机至少 2 小时,确保系统无残余压力与高温; \n2.排放热机油时佩戴耐高温手套及护目镜,防止烫伤。", - "bbox": [ - 183, - 346, - 704, - 374 - ], - "page_idx": 17, - "id": 117 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 375, - 645, - 390 - ], - "page_idx": 17, - "id": 118 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 390, - 386, - 403 - ], - "page_idx": 17, - "id": 119 - }, - { - "type": "table", - "img_path": "images/a1e12f7790ed1261d1b7b71545949885fcbbdf69631388b6115de18a09d8f673.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1液压升降平台HLP-30001台用于接近主机上部
2扭矩扳手TB-200N·m1把精度±3%
3机油滤清器专用拆装工具OEM-DIESEL-FIT1套厂家配套
4工业吸油泵VAC-0IL501台防爆型
", - "bbox": [ - 149, - 403, - 843, - 537 - ], - "page_idx": 17, - "id": 120 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 537, - 248, - 551 - ], - "page_idx": 17, - "id": 121 - }, - { - "type": "table", - "img_path": "images/3676466cb4a6e56febd88671b8e139f73a02992a844d77f4e2b2cf40378b4703.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1高压燃油泵HD-45A2个原厂件
2涡轮增压器TC-80B1个耐高温氟橡胶
", - "bbox": [ - 151, - 551, - 842, - 608 - ], - "page_idx": 17, - "id": 122 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 149, - 609, - 248, - 623 - ], - "page_idx": 17, - "id": 123 - }, - { - "type": "table", - "img_path": "images/7af14d27d7954302d0ed0b2926a290d2f529e8b4e819972e9a55b2f3c0eb8e80.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1柴油机专用润滑油Shell Mysella S5N8050L符合MAN 97101标准
2无纺布抹布Industrial Grade5张不掉屑
3清洗剂CRC Brakleen1罐用于清洁滤座
", - "bbox": [ - 149, - 623, - 843, - 719 - ], - "page_idx": 17, - "id": 124 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 719, - 247, - 733 - ], - "page_idx": 17, - "id": 125 - }, - { - "type": "table", - "img_path": "images/ad7d8e016903908df4e336256192ca2638d26bc58c269d27f7ee49bbbb996490.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师主导保养流程
2电气专业1技师监控主机ECU状态
", - "bbox": [ - 149, - 733, - 843, - 810 - ], - "page_idx": 17, - "id": 126 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 813, - 275, - 827 - ], - "page_idx": 17, - "id": 127 - }, - { - "type": "text", - "text": "保养前检查与准备", - "bbox": [ - 151, - 829, - 292, - 843 - ], - "page_idx": 17, - "id": 128 - }, - { - "type": "text", - "text": "1)确认主机已停机冷却,滑油温度 ${ \\leqslant } 5 0 ^ { \\circ } \\mathrm { C }$ ;", - "bbox": [ - 189, - 844, - 527, - 857 - ], - "page_idx": 17, - "id": 129 - }, - { - "type": "text", - "text": "2)断开主机启动电源,并在集控室操作屏挂“保养中”标识;", - "bbox": [ - 181, - 858, - 660, - 873 - ], - "page_idx": 17, - "id": 130 - }, - { - "type": "text", - "text": "3)准备接油盘置于主机油底壳下方,容量 ${ \\geqslant } 6 0 \\mathrm { ~ L ~ }$ 。", - "bbox": [ - 176, - 872, - 583, - 887 - ], - "page_idx": 17, - "id": 131 - }, - { - "type": "text", - "text": "执行保养作业", - "bbox": [ - 147, - 887, - 257, - 901 - ], - "page_idx": 17, - "id": 132 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 17, - "id": 133 - }, - { - "type": "text", - "text": "1)排放旧机油 ", - "bbox": [ - 184, - 93, - 302, - 107 - ], - "page_idx": 18, - "id": 134 - }, - { - "type": "text", - "text": "(1)旋松油底壳放油螺塞(扭矩释放后手动旋出),完全排空旧油;", - "bbox": [ - 189, - 107, - 714, - 121 - ], - "page_idx": 18, - "id": 135 - }, - { - "type": "image", - "img_path": "images/f9d69cc29d95df45a8e8dbc3336555c2ae99ff3983e9d7790633b89557b2ffb7.jpg", - "image_caption": [ - "图 MT001.1 旋松螺塞" - ], - "image_footnote": [], - "bbox": [ - 317, - 123, - 680, - 306 - ], - "page_idx": 18, - "id": 136 - }, - { - "type": "text", - "text": "(2)检查排出机油中是否有金属屑,若有则记录并上报异常。", - "bbox": [ - 191, - 323, - 662, - 337 - ], - "page_idx": 18, - "id": 137 - }, - { - "type": "image", - "img_path": "images/d9e42a82eaf3199b5396a34c1e1949943a9971c468fedc2ee7c75b15951c45fb.jpg", - "image_caption": [ - "图 MT001.2 检查" - ], - "image_footnote": [], - "bbox": [ - 342, - 338, - 655, - 524 - ], - "page_idx": 18, - "id": 138 - }, - { - "type": "text", - "text": "2)更换机油滤芯", - "bbox": [ - 184, - 556, - 321, - 569 - ], - "page_idx": 18, - "id": 139 - }, - { - "type": "text", - "text": "(1)使用专用工具拆下旧滤芯,清洁滤座密封面,无残留胶圈;", - "bbox": [ - 191, - 569, - 677, - 583 - ], - "page_idx": 18, - "id": 140 - }, - { - "type": "image", - "img_path": "images/5cded84d3bbdf89c141e40e8e3cb530c12042e51a956ac023d0424f47d0fcdbb.jpg", - "image_caption": [ - "图 MT001.3 拆卸" - ], - "image_footnote": [], - "bbox": [ - 295, - 583, - 702, - 843 - ], - "page_idx": 18, - "id": 141 - }, - { - "type": "text", - "text": "(2)在新滤芯密封圈涂少量新机油,手工旋紧至贴合后再用扭矩扳手加力 $\\underline { { 1 5 \\mathrm { ~ N ~ } } } \\cdot \\underline { { \\mathrm { ~ m ~ } } }$ ;", - "bbox": [ - 186, - 858, - 838, - 873 - ], - "page_idx": 18, - "id": 142 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 18, - "id": 143 - }, - { - "type": "image", - "img_path": "images/d08060324c963b2b8c22008a816db11536a3493f3c76fedbe9eff80e56ec02c9.jpg", - "image_caption": [ - "图MT001.4 滤芯安装扭矩示意图" - ], - "image_footnote": [], - "bbox": [ - 309, - 91, - 689, - 305 - ], - "page_idx": 19, - "id": 144 - }, - { - "type": "text", - "text": "3)加注新机油 ", - "bbox": [ - 184, - 322, - 302, - 336 - ], - "page_idx": 19, - "id": 145 - }, - { - "type": "text", - "text": "(1)通过加油口注入 Shell Mysella S5 N80 润滑油至标尺“MAX”线;", - "bbox": [ - 184, - 336, - 731, - 349 - ], - "page_idx": 19, - "id": 146 - }, - { - "type": "image", - "img_path": "images/97168b01ab476d2f3907da0894787852a1ca5c28765a741d56a35fce3d0be5a0.jpg", - "image_caption": [ - "图MT001.5 滤芯安装扭矩示意图" - ], - "image_footnote": [], - "bbox": [ - 314, - 351, - 682, - 695 - ], - "page_idx": 19, - "id": 147 - }, - { - "type": "text", - "text": "(2)静置10分钟后复查油位,补充至标准范围。", - "bbox": [ - 193, - 711, - 563, - 725 - ], - "page_idx": 19, - "id": 148 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 19, - "id": 149 - }, - { - "type": "image", - "img_path": "images/6d64bdc2fb9a69f985a45e602e34b65e435ad5d09fd87dea43d6e7f4d9907ca4.jpg", - "image_caption": [ - "图 MT001.6 油位检查" - ], - "image_footnote": [], - "bbox": [ - 147, - 90, - 850, - 336 - ], - "page_idx": 20, - "id": 150 - }, - { - "type": "text", - "text": "恢复与清理", - "bbox": [ - 149, - 350, - 242, - 366 - ], - "page_idx": 20, - "id": 151 - }, - { - "type": "text", - "text": "1)安装放油螺塞(新密封圈),扭矩: $4 5 \\mathrm { ~ N ~ } \\cdot \\mathrm { ~ m ~ }$ ;", - "bbox": [ - 183, - 366, - 564, - 380 - ], - "page_idx": 20, - "id": 152 - }, - { - "type": "image", - "img_path": "images/dd7bfa673ce36a4db6f104ae1bf8ddcf11340b66b2e6125b01e802c1c06ce99c.jpg", - "image_caption": [ - "图 MT001.7 安装放油螺塞" - ], - "image_footnote": [], - "bbox": [ - 326, - 379, - 673, - 703 - ], - "page_idx": 20, - "id": 153 - }, - { - "type": "text", - "text": "2)清理作业区域油污,回收废油至指定容器;", - "bbox": [ - 186, - 719, - 536, - 733 - ], - "page_idx": 20, - "id": 154 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 20, - "id": 155 - }, - { - "type": "image", - "img_path": "images/5ab01d367d4051cddcd3ac8e2c0c9784711e4e71c3b59b544adb083d1c6c0d78.jpg", - "image_caption": [ - "图 MT001.8 油污清理" - ], - "image_footnote": [], - "bbox": [ - 337, - 92, - 660, - 393 - ], - "page_idx": 21, - "id": 156 - }, - { - "type": "text", - "text": "3)拆除“禁止启动”牌,通知集控室保养完成。", - "bbox": [ - 183, - 411, - 556, - 425 - ], - "page_idx": 21, - "id": 157 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 428, - 223, - 442 - ], - "page_idx": 21, - "id": 158 - }, - { - "type": "text", - "text": "1.启动主机后运行10分钟,滑油压力稳定在 $0 . 4 5 \\small { \\sim } 0 . 6 0 ~ \\mathrm { M P } $ a(额定转速下)", - "bbox": [ - 191, - 442, - 781, - 456 - ], - "page_idx": 21, - "id": 159 - }, - { - "type": "text", - "text": "2.滤芯座及放油口无渗漏,目视检查无油迹;", - "bbox": [ - 186, - 457, - 527, - 470 - ], - "page_idx": 21, - "id": 160 - }, - { - "type": "text", - "text": "3.滑油取样检测粘度变化率 $\\leqslant 5 \\%$ ,无水分及金属颗粒超标。", - "bbox": [ - 154, - 472, - 648, - 485 - ], - "page_idx": 21, - "id": 161 - }, - { - "type": "table", - "img_path": "images/42b949ba85a6b13f6a0d96d994d3b991eeea1e264ba529ca9fe30083a09395f9.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:2/2版本号:
", - "bbox": [ - 196, - 486, - 635, - 501 - ], - "page_idx": 21, - "id": 162 - }, - { - "type": "table", - "img_path": "images/1a9244537edbb84905d97f3d781a940e98fc8abecce121feb7683c520f0c3a29.jpg", - "table_caption": [ - "表 4.4 MT002 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT0020101焊接机座组件检查主轴承座安装状态6M/200hJY级
", - "bbox": [ - 141, - 548, - 858, - 607 - ], - "page_idx": 21, - "id": 163 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 608, - 257, - 621 - ], - "page_idx": 21, - "id": 164 - }, - { - "type": "text", - "text": "1.检查前必须锁定曲轴转动机构,并在飞轮处加装机械止动销;", - "bbox": [ - 181, - 623, - 673, - 637 - ], - "page_idx": 21, - "id": 165 - }, - { - "type": "text", - "text": "2.作业区域设置激光对中仪警戒区,非相关人员禁止入内。", - "bbox": [ - 181, - 631, - 642, - 650 - ], - "page_idx": 21, - "id": 166 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 652, - 257, - 665 - ], - "page_idx": 21, - "id": 167 - }, - { - "type": "text", - "text": "1.禁止在主机运转或盘车未锁定状态下进行测量;", - "bbox": [ - 188, - 667, - 561, - 680 - ], - "page_idx": 21, - "id": 168 - }, - { - "type": "text", - "text": "2.使用塞尺或千分表时,手指不得置于轴承盖与机座结合面之间。", - "bbox": [ - 186, - 681, - 687, - 694 - ], - "page_idx": 21, - "id": 169 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 695, - 647, - 708 - ], - "page_idx": 21, - "id": 170 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 709, - 388, - 722 - ], - "page_idx": 21, - "id": 171 - }, - { - "type": "table", - "img_path": "images/a3b6ac05ec9ae27bc90cbb939a1f9989f4688eb25fdc5007aaeb507f6f095f36.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1激光对中仪SKF TKSA 711套用于轴承同轴度检测
2塞尺组0.02 -1.00 mm1套精度±0.005mm
3液压拉伸器HYTORC AVANTI-101台用于地脚螺栓预紧
4内径千分尺200 -300 mm1把校验有效期内
", - "bbox": [ - 149, - 722, - 843, - 857 - ], - "page_idx": 21, - "id": 172 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 149, - 857, - 248, - 871 - ], - "page_idx": 21, - "id": 173 - }, - { - "type": "table", - "img_path": "images/b0996e078301b3950195ab1e7868fd4b293428e66a0ae0c665105058346bb770.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1排气阀PV-1001
", - "bbox": [ - 147, - 870, - 840, - 890 - ], - "page_idx": 21, - "id": 174 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 21, - "id": 175 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 144, - 91, - 848, - 112 - ], - "page_idx": 22, - "id": 176 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 149, - 112, - 247, - 127 - ], - "page_idx": 22, - "id": 177 - }, - { - "type": "table", - "img_path": "images/10188fa82d4eadaf22075b5da2d3b07a5901fd534acdf7949dc6304464792b5e.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1清洁酒精AR Grade100mL
2防锈纸VCI-2002张
", - "bbox": [ - 149, - 126, - 843, - 184 - ], - "page_idx": 22, - "id": 178 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 185, - 247, - 199 - ], - "page_idx": 22, - "id": 179 - }, - { - "type": "table", - "img_path": "images/a9f37325110e4928be587f29dd04a3c866d4e827a3bfbdd1605922cbd4f9fc35.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+工程师
", - "bbox": [ - 147, - 198, - 847, - 239 - ], - "page_idx": 22, - "id": 180 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 241, - 275, - 256 - ], - "page_idx": 22, - "id": 181 - }, - { - "type": "text", - "text": "前提条件确认", - "bbox": [ - 147, - 278, - 257, - 292 - ], - "page_idx": 22, - "id": 182 - }, - { - "type": "text", - "text": "1)主机停机 $\\geqslant 4$ 小时,环境温度 $1 5 - 3 5 \\mathrm { ^ \\circ C }$ ;", - "bbox": [ - 186, - 297, - 537, - 311 - ], - "page_idx": 22, - "id": 183 - }, - { - "type": "text", - "text": "2)所有主轴承盖地脚螺栓处于规定预紧力(参考值: $8 5 0 ~ \\mathrm { ~ k N } )$ )。", - "bbox": [ - 161, - 316, - 675, - 330 - ], - "page_idx": 22, - "id": 184 - }, - { - "type": "text", - "text": "检查主轴承座安装状态 ", - "bbox": [ - 151, - 351, - 331, - 367 - ], - "page_idx": 22, - "id": 185 - }, - { - "type": "text", - "text": "1)清洁与目视检查", - "bbox": [ - 184, - 370, - 337, - 386 - ], - "page_idx": 22, - "id": 186 - }, - { - "type": "text", - "text": "(1)清除轴承座与机座结合面油污、锈迹;", - "bbox": [ - 193, - 388, - 521, - 404 - ], - "page_idx": 22, - "id": 187 - }, - { - "type": "image", - "img_path": "images/b3a60b9ef3959dbb3a1a851c5b565419c45e2bd40babc64fa67ddddf9290939f.jpg", - "image_caption": [ - "图 MT002.1 换油前清洗" - ], - "image_footnote": [], - "bbox": [ - 347, - 405, - 650, - 687 - ], - "page_idx": 22, - "id": 188 - }, - { - "type": "text", - "text": "(2)目视检查有无裂纹、变形或螺栓松动迹象。", - "bbox": [ - 194, - 719, - 554, - 733 - ], - "page_idx": 22, - "id": 189 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 22, - "id": 190 - }, - { - "type": "image", - "img_path": "images/4110aaa61ad20a5c735a3c5aee23aeab49aa98a98201da69ef359a87917ecdd7.jpg", - "image_caption": [ - "图 MT002.2 检查" - ], - "image_footnote": [], - "bbox": [ - 331, - 92, - 667, - 409 - ], - "page_idx": 23, - "id": 191 - }, - { - "type": "text", - "text": "2)间隙测量", - "bbox": [ - 184, - 442, - 284, - 457 - ], - "page_idx": 23, - "id": 192 - }, - { - "type": "text", - "text": "(1)使用塞尺沿圆周8点测量轴承座与机座结合面间隙;", - "bbox": [ - 191, - 461, - 625, - 476 - ], - "page_idx": 23, - "id": 193 - }, - { - "type": "image", - "img_path": "images/de705ccddcc55a4e2159aa667354ce64bb5af2365fc6f25cbc5656cd300eaab3.jpg", - "image_caption": [ - "图 MT002.3 塞尺测量" - ], - "image_footnote": [], - "bbox": [ - 147, - 479, - 850, - 829 - ], - "page_idx": 23, - "id": 194 - }, - { - "type": "text", - "text": "(3)任一点间隙 $\\leqslant 0 . 0 5 \\ \\mathrm { ~ m m }$ ,否则判定为安装不良。", - "bbox": [ - 156, - 847, - 556, - 862 - ], - "page_idx": 23, - "id": 195 - }, - { - "type": "text", - "text": "3)同轴度检测 ", - "bbox": [ - 183, - 866, - 302, - 881 - ], - "page_idx": 23, - "id": 196 - }, - { - "type": "text", - "text": "(1)安装激光对中仪于相邻两主轴承中心孔;", - "bbox": [ - 191, - 884, - 537, - 900 - ], - "page_idx": 23, - "id": 197 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 23, - "id": 198 - }, - { - "type": "image", - "img_path": "images/79f8a89ce837fee7aa0ce58859f4dd9bc4e9b42bf08dc448f6180d638e0079e6.jpg", - "image_caption": [ - "图 MT002.4 激光对中仪" - ], - "image_footnote": [], - "bbox": [ - 315, - 92, - 680, - 307 - ], - "page_idx": 24, - "id": 199 - }, - { - "type": "text", - "text": "(2)测量轴线偏移量,允许值: ${ \\leqslant } 0 . 0 8 ~ \\mathrm { m m / m }$ 。", - "bbox": [ - 157, - 331, - 512, - 347 - ], - "page_idx": 24, - "id": 200 - }, - { - "type": "image", - "img_path": "images/6606fdb7446a1fd5ab1267af58db192cc196e81e3f6571c7060059f9df530545.jpg", - "image_caption": [ - "图 MT002.5 测量轴线偏移量" - ], - "image_footnote": [], - "bbox": [ - 332, - 347, - 668, - 663 - ], - "page_idx": 24, - "id": 201 - }, - { - "type": "text", - "text": "判定与处理", - "text_level": 1, - "bbox": [ - 149, - 717, - 242, - 732 - ], - "page_idx": 24, - "id": 202 - }, - { - "type": "text", - "text": "1)若所有测量值合格,则记录数据并结束检查;", - "bbox": [ - 147, - 736, - 524, - 751 - ], - "page_idx": 24, - "id": 203 - }, - { - "type": "text", - "text": "2)若任一指标超差,标记异常轴承座编号,进入MTxxx(修复程序)。", - "bbox": [ - 176, - 753, - 727, - 769 - ], - "page_idx": 24, - "id": 204 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 771, - 223, - 785 - ], - "page_idx": 24, - "id": 205 - }, - { - "type": "text", - "text": "1.主轴承座与机座结合面间隙 $\\leqslant 0 . 0 5 \\ \\mathrm { ~ m m }$ (全周); \n2.相邻主轴承同轴度偏差 ${ \\leqslant } 0 . 0 8 ~ \\mathrm { m m / m }$ ; \n3.地脚螺栓预紧力在设计值 ± $5 \\%$ 范围内。", - "bbox": [ - 183, - 785, - 579, - 828 - ], - "page_idx": 24, - "id": 206 - }, - { - "type": "table", - "img_path": "images/1a1f9715387fc59593dece1362687c5e5d0af82a78f2000f13ef021d192eb827.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1版本号:1
", - "bbox": [ - 193, - 829, - 658, - 846 - ], - "page_idx": 24, - "id": 207 - }, - { - "type": "table", - "img_path": "images/9073e4c743244f4a4a79c194a7911bde5d5b098373cba8ae09278a24d4bfa6c7.jpg", - "table_caption": [ - "表 4.5 MT003 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT0030201曲轴组件检测曲轴主轴颈跳动量1A/8000hJY级
", - "bbox": [ - 137, - 877, - 847, - 908 - ], - "page_idx": 24, - "id": 208 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 24, - "id": 209 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 136, - 91, - 862, - 121 - ], - "page_idx": 25, - "id": 210 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 151, - 122, - 257, - 135 - ], - "page_idx": 25, - "id": 211 - }, - { - "type": "text", - "text": "1.曲轴检测前必须在盘车机构处加装机械锁止装置,并悬挂“禁止盘车”警示牌; \n2.检测区域设置防滑平台,千分表支架须稳固固定,防止倾倒伤人。", - "bbox": [ - 183, - 136, - 820, - 165 - ], - "page_idx": 25, - "id": 212 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 166, - 258, - 179 - ], - "page_idx": 25, - "id": 213 - }, - { - "type": "text", - "text": "1.禁止在曲轴未完全支撑状态下进行测量操作;", - "bbox": [ - 186, - 180, - 544, - 193 - ], - "page_idx": 25, - "id": 214 - }, - { - "type": "text", - "text": "2.使用磁力表座时,确认其吸附面清洁无油,防止滑脱。", - "bbox": [ - 163, - 195, - 620, - 208 - ], - "page_idx": 25, - "id": 215 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 146, - 209, - 645, - 223 - ], - "page_idx": 25, - "id": 216 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 224, - 386, - 237 - ], - "page_idx": 25, - "id": 217 - }, - { - "type": "table", - "img_path": "images/27ca3e3c89bc2dcbe439eded35c4444a4e45672229a59f57f4ca369490be99e8.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1精密千分表Mitutoyo 543-791D1套分辨率0.001mm
2磁力表座Starrett 16B1个带万向关节
3V型支撑架Custom-Crank-V3002组承重≥500kg
4盘车手轮OEM-MAN-BW-PCW1个原厂配套
", - "bbox": [ - 149, - 236, - 843, - 351 - ], - "page_idx": 25, - "id": 218 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 353, - 250, - 366 - ], - "page_idx": 25, - "id": 219 - }, - { - "type": "table", - "img_path": "images/fbb32f870d536af92563956fb80e0d43597b6bfafd0c49e3d302c818a475be3c.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1排气阀PV-1001
", - "bbox": [ - 151, - 366, - 847, - 405 - ], - "page_idx": 25, - "id": 220 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 406, - 248, - 419 - ], - "page_idx": 25, - "id": 221 - }, - { - "type": "table", - "img_path": "images/e795efa47e7adeb126a42323388644deb99f32b5a335832b2256de35cbc4e898.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1工业酒精≥99.5%50 mL清洁轴颈表面
2无绒擦拭布Kimwipe EX-L3张防刮伤轴面
", - "bbox": [ - 149, - 419, - 843, - 476 - ], - "page_idx": 25, - "id": 222 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 478, - 247, - 492 - ], - "page_idx": 25, - "id": 223 - }, - { - "type": "table", - "img_path": "images/7f8a257438ed37a8c2315e6045aa3ebe9c0654b1826edcf33a4ef3cfff9f2c00.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+工程师总工复刻数据
", - "bbox": [ - 146, - 491, - 847, - 531 - ], - "page_idx": 25, - "id": 224 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 533, - 275, - 549 - ], - "page_idx": 25, - "id": 225 - }, - { - "type": "text", - "text": "检测前提条件确认 ", - "bbox": [ - 149, - 570, - 292, - 586 - ], - "page_idx": 25, - "id": 226 - }, - { - "type": "text", - "text": "1)主机已停机 ${ \\geqslant } 6$ 小时,曲轴温度 ${ \\leqslant } 4 0 ^ { \\circ } \\mathrm { C }$ ; \n2)所有主轴承盖已按规范扭矩紧固,且无拆卸记录; \n3)曲轴自由端与输出端已用V型架可靠支撑,无悬空。", - "bbox": [ - 178, - 589, - 608, - 642 - ], - "page_idx": 25, - "id": 227 - }, - { - "type": "text", - "text": "执行跳动量检测 ", - "bbox": [ - 147, - 663, - 277, - 678 - ], - "page_idx": 25, - "id": 228 - }, - { - "type": "text", - "text": "1)准备测量点", - "bbox": [ - 184, - 682, - 302, - 696 - ], - "page_idx": 25, - "id": 229 - }, - { - "type": "text", - "text": "(1)清洁各主轴颈表面至无油膜、锈斑;", - "bbox": [ - 194, - 700, - 502, - 715 - ], - "page_idx": 25, - "id": 230 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 25, - "id": 231 - }, - { - "type": "image", - "img_path": "images/ec05d9c869db8120239d85dbbeb436ed5c8ca4e8863ee8df95e8bd8dd4a3cc6a.jpg", - "image_caption": [ - "图 MT003.1 清洁" - ], - "image_footnote": [], - "bbox": [ - 147, - 90, - 850, - 369 - ], - "page_idx": 26, - "id": 232 - }, - { - "type": "text", - "text": "(3)在每道主轴颈圆周标记 $0 ^ { \\circ }$ 、90°、 $1 8 0 ^ { \\circ }$ 、 $2 7 0 ^ { \\circ }$ 四个测量基准点。 ", - "bbox": [ - 156, - 387, - 710, - 401 - ], - "page_idx": 26, - "id": 233 - }, - { - "type": "image", - "img_path": "images/5ad57e2c7e213c243145f5c84e623a5f7d4d5393d65a149a44e7eb9c838e18e5.jpg", - "image_caption": [ - "图 MT003.2 标记测量基准点" - ], - "image_footnote": [], - "bbox": [ - 349, - 405, - 650, - 780 - ], - "page_idx": 26, - "id": 234 - }, - { - "type": "text", - "text": "2)安装千分表", - "bbox": [ - 184, - 809, - 304, - 825 - ], - "page_idx": 26, - "id": 235 - }, - { - "type": "text", - "text": "(1)将磁力表座固定于稳固基座,千分表测头垂直抵住第一道主轴颈最高点;", - "bbox": [ - 188, - 827, - 786, - 844 - ], - "page_idx": 26, - "id": 236 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 26, - "id": 237 - }, - { - "type": "image", - "img_path": "images/d707987d6bb8abb80be09833d4e324c7b5a860cf153a6059ed2de27074d2a054.jpg", - "image_caption": [ - "图 MT003.3 千分尺" - ], - "image_footnote": [], - "bbox": [ - 381, - 130, - 618, - 260 - ], - "page_idx": 27, - "id": 238 - }, - { - "type": "text", - "text": "(2)预压千分表 $0 . 3 \\mathrm { \\ m m }$ ,归零。", - "bbox": [ - 193, - 313, - 438, - 328 - ], - "page_idx": 27, - "id": 239 - }, - { - "type": "text", - "text": "3)盘车测量", - "bbox": [ - 183, - 331, - 284, - 346 - ], - "page_idx": 27, - "id": 240 - }, - { - "type": "text", - "text": "(1)缓慢盘动曲轴一周( $3 6 0 ^ { \\circ }$ ),记录千分表最大与最小读数;", - "bbox": [ - 193, - 349, - 689, - 365 - ], - "page_idx": 27, - "id": 241 - }, - { - "type": "text", - "text": "(2)跳动量 $=$ 最大值 - 最小值;", - "bbox": [ - 194, - 369, - 450, - 384 - ], - "page_idx": 27, - "id": 242 - }, - { - "type": "text", - "text": "(3)重复上述步骤,依次测量其余主轴颈。", - "bbox": [ - 194, - 387, - 522, - 403 - ], - "page_idx": 27, - "id": 243 - }, - { - "type": "text", - "text": "数据判定", - "bbox": [ - 149, - 424, - 223, - 439 - ], - "page_idx": 27, - "id": 244 - }, - { - "type": "text", - "text": "1)若任一主轴颈跳动量 $\\leqslant 0 . 0 5 \\ \\mathrm { ~ m m }$ ,则判定合格;", - "bbox": [ - 147, - 443, - 539, - 458 - ], - "page_idx": 27, - "id": 245 - }, - { - "type": "image", - "img_path": "images/6034b75846df17df7f5ccdbbb3df99746b720a4c69ec283de060a2320558fece.jpg", - "image_caption": [ - "图MT003.1 曲轴主轴颈跳动测量布置图" - ], - "image_footnote": [], - "bbox": [ - 363, - 463, - 625, - 646 - ], - "page_idx": 27, - "id": 246 - }, - { - "type": "text", - "text": "2)若跳动量 $> 0 . 0 5 \\ \\mathrm { \\ m m }$ 且 $\\leqslant 0 . 1 0 \\ \\mathrm { ~ m m }$ ,记录并安排下次缩短检测周期;", - "bbox": [ - 176, - 681, - 734, - 695 - ], - "page_idx": 27, - "id": 247 - }, - { - "type": "text", - "text": "3)若跳动量 $> 0 . 1 0 \\ \\mathrm { \\ m m }$ ,立即停机,启动曲轴校直或更换程序。", - "bbox": [ - 184, - 699, - 662, - 713 - ], - "page_idx": 27, - "id": 248 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 715, - 223, - 730 - ], - "page_idx": 27, - "id": 249 - }, - { - "type": "text", - "text": "1.所有主轴颈径向跳动量 $\\leqslant 0 . 0 5 \\ \\mathrm { ~ m m }$ ; \n2.测量原始数据完整记录于《曲轴状态检测报告》; \n3.千分表校验标签在有效期内,测量环境温度波动 $\\leqslant \\pm 2 ^ { \\circ } \\mathrm { C }$ \n1.拆装连杆前必须锁定曲轴位置,并在气缸顶部加盖防异物落入盖板; \n2.吊装连杆组件时使用专用吊具,下方设置警戒区。", - "bbox": [ - 183, - 730, - 645, - 772 - ], - "page_idx": 27, - "id": 250 - }, - { - "type": "table", - "img_path": "images/3c2335367bc1d44f76898d0efb63e9aa7270c0ec24f302fae70214c6d0cb337a.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1
", - "bbox": [ - 198, - 774, - 638, - 789 - ], - "page_idx": 27, - "id": 251 - }, - { - "type": "table", - "img_path": "images/81751393b14e1a48a70960d1b861cdfef6ddf9fc2ec559bb0ca497737c2e6ba0.jpg", - "table_caption": [ - "表 4.6 MT004 维修项目" - ], - "table_footnote": [ - "安全防护要求" - ], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT004020201连杆大端轴承更换连杆大端轴承2A/12000hJT级
", - "bbox": [ - 139, - 835, - 855, - 882 - ], - "page_idx": 27, - "id": 252 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 27, - "id": 253 - }, - { - "type": "text", - "text": "", - "bbox": [ - 169, - 92, - 776, - 121 - ], - "page_idx": 28, - "id": 254 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 151, - 122, - 257, - 136 - ], - "page_idx": 28, - "id": 255 - }, - { - "type": "text", - "text": "1.禁止使用锤击方式拆卸轴承盖,防止损伤连杆体;", - "bbox": [ - 184, - 136, - 581, - 151 - ], - "page_idx": 28, - "id": 256 - }, - { - "type": "text", - "text": "2.新轴承安装前确认瓦背无毛刺、涂层完整。", - "bbox": [ - 184, - 151, - 529, - 164 - ], - "page_idx": 28, - "id": 257 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 165, - 643, - 179 - ], - "page_idx": 28, - "id": 258 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 180, - 386, - 193 - ], - "page_idx": 28, - "id": 259 - }, - { - "type": "table", - "img_path": "images/1c7cd01b0106ebb9dbeaaa71a974748e0f01cc478e6cd45546a43de9a04144fd.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1液压拉伸器HYTORC RS-201套
2扭矩扳手Norbar 1500N·m1把精度±2%
3轴承安装导向套OEM-MAN-BW-BG-041个
4内窥镜GE Mentor VisualiQ1台
", - "bbox": [ - 149, - 193, - 842, - 307 - ], - "page_idx": 28, - "id": 260 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 149, - 309, - 248, - 323 - ], - "page_idx": 28, - "id": 261 - }, - { - "type": "table", - "img_path": "images/2781ea1f1ecc2e1899550dae39aeb957d668c21922d9a6433df9a0971a85f268.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1连杆大端轴承上瓦MAN 5L35MC-BRG-UP1副原厂高锡合金
2连杆大端轴承下瓦MAN 5L35MC-BRG-DN1副
3连杆螺栓M30×2.0 Grade12.92根一次性使用,强制更换
", - "bbox": [ - 151, - 322, - 842, - 418 - ], - "page_idx": 28, - "id": 262 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 419, - 248, - 434 - ], - "page_idx": 28, - "id": 263 - }, - { - "type": "table", - "img_path": "images/961b950923494e5988b0637e5782d9899a5a6bc6d2905e1c923510fbb066ad69.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1轴承装配润滑脂Kluber Isoflex LDS18 Special A10g仅涂瓦背
2螺纹锁固胶Loctite 2701少量用于螺栓螺纹(如适用)
3清洗剂Brulin 815GD200mL清洁连杆结合面
", - "bbox": [ - 149, - 432, - 842, - 546 - ], - "page_idx": 28, - "id": 264 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 548, - 247, - 562 - ], - "page_idx": 28, - "id": 265 - }, - { - "type": "table", - "img_path": "images/a3d72f067d00e9b344e05fc05c4560e52c56db2a4e3de8481203216777ce55db.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业3总工+2x工程师总工监督关键步骤
", - "bbox": [ - 149, - 561, - 843, - 619 - ], - "page_idx": 28, - "id": 266 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 621, - 275, - 637 - ], - "page_idx": 28, - "id": 267 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 149, - 658, - 257, - 674 - ], - "page_idx": 28, - "id": 268 - }, - { - "type": "text", - "text": "1)主机已完成停机冷却,滑油系统泄压;", - "bbox": [ - 184, - 677, - 502, - 692 - ], - "page_idx": 28, - "id": 269 - }, - { - "type": "text", - "text": "2)确认本次为计划性更换(运行时间 $\\geqslant 1 2 0 0 0 \\mathrm { ~ h ~ }$ 或 2A 级检修);", - "bbox": [ - 183, - 696, - 704, - 711 - ], - "page_idx": 28, - "id": 270 - }, - { - "type": "text", - "text": "3)新轴承与螺栓已核对型号、批次,无运输损伤。", - "bbox": [ - 183, - 714, - 569, - 730 - ], - "page_idx": 28, - "id": 271 - }, - { - "type": "text", - "text": "拆卸旧轴承 ", - "bbox": [ - 147, - 751, - 240, - 766 - ], - "page_idx": 28, - "id": 272 - }, - { - "type": "text", - "text": "1)拆连杆盖 ", - "bbox": [ - 184, - 770, - 284, - 784 - ], - "page_idx": 28, - "id": 273 - }, - { - "type": "text", - "text": "(1)使用液压拉伸器逐步释放连杆螺栓预紧力(分三次卸载);", - "bbox": [ - 193, - 788, - 678, - 803 - ], - "page_idx": 28, - "id": 274 - }, - { - "type": "text", - "text": "(2)取下螺栓及连杆大端盖,放置于专用托架。", - "bbox": [ - 193, - 807, - 557, - 822 - ], - "page_idx": 28, - "id": 275 - }, - { - "type": "text", - "text": "2)取出旧轴承 ", - "bbox": [ - 183, - 826, - 302, - 840 - ], - "page_idx": 28, - "id": 276 - }, - { - "type": "text", - "text": "(1)轻敲连杆体侧面,使下瓦自然脱落;", - "bbox": [ - 194, - 845, - 500, - 859 - ], - "page_idx": 28, - "id": 277 - }, - { - "type": "text", - "text": "(2)用塑料撬棒取出上瓦,禁止使用金属工具接触轴颈。", - "bbox": [ - 191, - 863, - 628, - 878 - ], - "page_idx": 28, - "id": 278 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 28, - "id": 279 - }, - { - "type": "text", - "text": "安装新轴承", - "text_level": 1, - "bbox": [ - 149, - 95, - 240, - 109 - ], - "page_idx": 29, - "id": 280 - }, - { - "type": "text", - "text": "1)清洁与检查", - "bbox": [ - 184, - 114, - 302, - 128 - ], - "page_idx": 29, - "id": 281 - }, - { - "type": "text", - "text": "(1)用清洗剂彻底清洁连杆体与盖的瓦槽,无油污、毛刺;", - "bbox": [ - 193, - 131, - 643, - 147 - ], - "page_idx": 29, - "id": 282 - }, - { - "type": "text", - "text": "(2)目视检查新瓦背面涂层均匀,无裂纹。", - "bbox": [ - 193, - 151, - 521, - 166 - ], - "page_idx": 29, - "id": 283 - }, - { - "type": "text", - "text": "2)装配 ", - "bbox": [ - 183, - 170, - 250, - 184 - ], - "page_idx": 29, - "id": 284 - }, - { - "type": "text", - "text": "(1)在瓦背薄涂 Klüber 润滑脂,将上瓦嵌入连杆体,定位唇对准槽口;", - "bbox": [ - 193, - 187, - 739, - 203 - ], - "page_idx": 29, - "id": 285 - }, - { - "type": "text", - "text": "(2)将下瓦装入连杆盖,同样对准定位;", - "bbox": [ - 196, - 206, - 502, - 221 - ], - "page_idx": 29, - "id": 286 - }, - { - "type": "text", - "text": "(3)使用导向套引导连杆盖就位,避免瓦片移位。", - "bbox": [ - 193, - 224, - 574, - 240 - ], - "page_idx": 29, - "id": 287 - }, - { - "type": "text", - "text": "3)紧固螺栓 ", - "bbox": [ - 183, - 243, - 284, - 258 - ], - "page_idx": 29, - "id": 288 - }, - { - "type": "text", - "text": "(1)安装新连杆螺栓,手工旋入到底;", - "bbox": [ - 194, - 262, - 485, - 277 - ], - "page_idx": 29, - "id": 289 - }, - { - "type": "text", - "text": "(2)按三阶段拧紧: $\\textcircled{1}$ $3 0 0 \\mathrm { ~ N ~ } \\bullet \\mathrm { ~ m ~ } \\mathrm { ~ \\textcircled { 2 } ~ 6 0 0 ~ ~ N ~ } \\bullet \\mathrm { ~ m ~ } \\mathrm { ~ \\textcircled { 3 } ~ }$ 拉伸至 $1 2 0 0 \\mathrm { ~ N ~ } \\cdot \\mathrm { ~ m ~ }$ (参考值);", - "bbox": [ - 149, - 280, - 848, - 313 - ], - "page_idx": 29, - "id": 290 - }, - { - "type": "text", - "text": "(3)最终用角度法复核(如适用)。", - "bbox": [ - 193, - 317, - 468, - 332 - ], - "page_idx": 29, - "id": 291 - }, - { - "type": "image", - "img_path": "images/8e09cfa5b43ae695a4e82679fe54dba2b5b6a6167e5328d43e6e16fc0c70181f.jpg", - "image_caption": [ - "图MT004.1 连杆大端轴承结构分解图" - ], - "image_footnote": [], - "bbox": [ - 218, - 338, - 778, - 486 - ], - "page_idx": 29, - "id": 292 - }, - { - "type": "text", - "text": "恢复与验证 ", - "bbox": [ - 149, - 536, - 240, - 550 - ], - "page_idx": 29, - "id": 293 - }, - { - "type": "text", - "text": "1)盘车两圈,确认无卡滞;", - "bbox": [ - 184, - 554, - 396, - 569 - ], - "page_idx": 29, - "id": 294 - }, - { - "type": "text", - "text": "2)安装气缸防异物盖,清理工具与废弃物。", - "bbox": [ - 181, - 573, - 522, - 588 - ], - "page_idx": 29, - "id": 295 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 590, - 223, - 604 - ], - "page_idx": 29, - "id": 296 - }, - { - "type": "text", - "text": "1.新轴承瓦背与瓦槽贴合面积 ${ \\geqslant } 9 5 \\%$ ,无翘曲; \n2.连杆螺栓最终预紧力在设计值 ±3% 范围内; \n3.盘车阻力矩变化平稳,无突变(参考值:≤ $1 5 \\%$ 波动)。", - "bbox": [ - 184, - 605, - 633, - 648 - ], - "page_idx": 29, - "id": 297 - }, - { - "type": "table", - "img_path": "images/afacf5e3c5d49b6cd31973b728295f74b8622f9ac968773841a69a71d78d821b.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1版本号:1
", - "bbox": [ - 149, - 648, - 847, - 664 - ], - "page_idx": 29, - "id": 298 - }, - { - "type": "table", - "img_path": "images/5077350b2e19de6ac8417e5855276f7071cc5e484da4f8a78a3030165ce541d8.jpg", - "table_caption": [ - "表 4.7 MT005 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT005020203连杆小段轴承更换连杆小段轴承2A/12000hJY级
", - "bbox": [ - 141, - 709, - 855, - 756 - ], - "page_idx": 29, - "id": 299 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 149, - 756, - 257, - 770 - ], - "page_idx": 29, - "id": 300 - }, - { - "type": "text", - "text": "1.拆装活塞连杆组件前,必须在曲轴输出端加装机械止动装置; \n2.吊装活塞-连杆总成时使用专用吊环,下方设置软质承接垫。", - "bbox": [ - 184, - 770, - 667, - 799 - ], - "page_idx": 29, - "id": 301 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 151, - 800, - 257, - 813 - ], - "page_idx": 29, - "id": 302 - }, - { - "type": "text", - "text": "1.禁止在未拆除缸头及缸套冷却水的情况下强行抽出活塞; \n2.加热连杆小端进行热装时,操作人员须佩戴隔热面罩及手套。", - "bbox": [ - 181, - 814, - 672, - 841 - ], - "page_idx": 29, - "id": 303 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 29, - "id": 304 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 146, - 92, - 647, - 108 - ], - "page_idx": 30, - "id": 305 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 108, - 388, - 121 - ], - "page_idx": 30, - "id": 306 - }, - { - "type": "table", - "img_path": "images/62e4a2ca7990b4dc2651bbed90931fed812a721d1747cf987236a950e6346539.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1活塞吊装专用吊具OEM-MAN-BW-PST-051套带缓冲橡胶夹头
2感应加热器EFD InductionMinac 161台温控精度±5℃
3内径千分尺40-50mm1把校验有效期内
4铜棒与塑料锤Φ20×300mm各1把
", - "bbox": [ - 149, - 121, - 842, - 235 - ], - "page_idx": 30, - "id": 307 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 236, - 250, - 250 - ], - "page_idx": 30, - "id": 308 - }, - { - "type": "table", - "img_path": "images/9037b038915559794e971355b78e9646d37d1ef29322f5639244ebff634e3665.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1连杆小端衬套(上)MAN 5L35MC-BUSH-UP1件锡青铜基
2连杆小端衬套(下)MAN 5L35MC-BUSH-DN1件
3活塞销卡簧Φ50×2.5mm2个不锈钢,一次性
", - "bbox": [ - 149, - 249, - 843, - 365 - ], - "page_idx": 30, - "id": 309 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 365, - 248, - 379 - ], - "page_idx": 30, - "id": 310 - }, - { - "type": "table", - "img_path": "images/a1deae5e59aa14cc00b2977a23b2559864c05e72ad93e7f50340ae7d495dd0e1.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1高温装配润滑脂Molycote G-10525g
2清洗剂Brulin 815GD150mL
3耐高温标记笔Markal 900°F1支
", - "bbox": [ - 149, - 378, - 842, - 456 - ], - "page_idx": 30, - "id": 311 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 456, - 247, - 470 - ], - "page_idx": 30, - "id": 312 - }, - { - "type": "table", - "img_path": "images/a1d30848f9b6bb936a81c7d0cc1bace9066aa42f88ec515556bc903a0cafd1c9.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师+技师工程师主导热装
", - "bbox": [ - 147, - 469, - 845, - 510 - ], - "page_idx": 30, - "id": 313 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 149, - 512, - 275, - 527 - ], - "page_idx": 30, - "id": 314 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 149, - 542, - 257, - 557 - ], - "page_idx": 30, - "id": 315 - }, - { - "type": "text", - "text": "1)主机已完成2A级检修停机程序,气缸已冷却至 $\\leqslant 5 0 ^ { \\circ } \\mathrm { C }$ ;", - "bbox": [ - 183, - 560, - 643, - 574 - ], - "page_idx": 30, - "id": 316 - }, - { - "type": "text", - "text": "2)确认运行时间 $\\geqslant 1 2 0 0 0 \\mathrm { ~ h ~ }$ 或上次更换后已超周期", - "bbox": [ - 184, - 577, - 588, - 592 - ], - "page_idx": 30, - "id": 317 - }, - { - "type": "text", - "text": "3)新衬套尺寸经复测符合图纸公差(过盈量: $0 . \\ 0 3 { \\sim } 0 . \\ 0 6 \\ \\ \\mathrm { m m } )$ )。", - "bbox": [ - 181, - 596, - 690, - 612 - ], - "page_idx": 30, - "id": 318 - }, - { - "type": "text", - "text": "拆卸旧衬套 ", - "bbox": [ - 149, - 633, - 242, - 649 - ], - "page_idx": 30, - "id": 319 - }, - { - "type": "text", - "text": "1)抽出活塞-连杆总成", - "bbox": [ - 184, - 652, - 364, - 667 - ], - "page_idx": 30, - "id": 320 - }, - { - "type": "text", - "text": "(1)拆除缸头、喷油器及冷却水管路;", - "bbox": [ - 194, - 670, - 485, - 686 - ], - "page_idx": 30, - "id": 321 - }, - { - "type": "text", - "text": "(2)使用吊具将活塞缓慢抽出,避免刮伤缸套。", - "bbox": [ - 194, - 689, - 556, - 703 - ], - "page_idx": 30, - "id": 322 - }, - { - "type": "text", - "text": "2)压出旧衬套 ", - "bbox": [ - 184, - 708, - 302, - 722 - ], - "page_idx": 30, - "id": 323 - }, - { - "type": "text", - "text": "(1)用专用液压压床或铜棒轻敲,从连杆小端一侧推出旧衬套;", - "bbox": [ - 191, - 726, - 682, - 741 - ], - "page_idx": 30, - "id": 324 - }, - { - "type": "text", - "text": "(2)检查座孔有无拉伤、变形,若有则需镗孔修复(参见 MTxxx)。", - "bbox": [ - 193, - 745, - 710, - 760 - ], - "page_idx": 30, - "id": 325 - }, - { - "type": "text", - "text": "安装新衬套", - "text_level": 1, - "bbox": [ - 149, - 782, - 242, - 796 - ], - "page_idx": 30, - "id": 326 - }, - { - "type": "text", - "text": "1)清洁与预装检查", - "bbox": [ - 184, - 800, - 337, - 815 - ], - "page_idx": 30, - "id": 327 - }, - { - "type": "text", - "text": "(1)用清洗剂彻底清洁连杆小端座孔,吹干;", - "bbox": [ - 194, - 819, - 534, - 834 - ], - "page_idx": 30, - "id": 328 - }, - { - "type": "text", - "text": "(2)测量座孔内径,记录作为过盈量计算依据。", - "bbox": [ - 193, - 838, - 557, - 853 - ], - "page_idx": 30, - "id": 329 - }, - { - "type": "text", - "text": "2)热装新衬套 ", - "bbox": [ - 184, - 857, - 302, - 870 - ], - "page_idx": 30, - "id": 330 - }, - { - "type": "text", - "text": "(1)将新衬套放入感应加热器,加热至 $1 8 0 \\pm 1 0 ^ { \\circ } \\mathrm { C }$ (用红外测温仪监控);", - "bbox": [ - 191, - 875, - 766, - 890 - ], - "page_idx": 30, - "id": 331 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 30, - "id": 332 - }, - { - "type": "table", - "img_path": "images/68d2ad1e3c2dc30824179c5f9e19403b705914d073ba9686ba0e6371eb060c46.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
(2)迅速将热衬套套入连杆小端,确保完全到位; (3)自然冷却至室温,禁止强制冷却。 3)精铰与研配(如需要) (1)若图纸要求配合间隙为0.04~0.08mm,则进行精铰; (2)使用研磨膏手工研配活塞销,接触面积≥70%。
组装活塞销与卡簧 1)在衬套内孔涂MolycoteG-1052 润滑脂; 2)将活塞销推入衬套,两端装入新卡簧,确认完全嵌入槽内。
验收标准 1.衬套与座孔过盈配合牢固,无松动或轴向位移; 2.活塞销转动灵活,轴向窜动量≤0.15 mm;
3.卡簧两端完全嵌入槽内,无翘起或断裂。 页码:1/1 版本号:1
", - "bbox": [ - 147, - 91, - 855, - 338 - ], - "page_idx": 31, - "id": 333 - }, - { - "type": "table", - "img_path": "images/b1afb5703711fb5cf11af09c9870ba78606b221542c21f6903a791d9c7527b41.jpg", - "table_caption": [ - "表 4.8 MT006 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT006030201活塞头拆检活塞头磨损情况1A/8000hJY级
", - "bbox": [ - 141, - 380, - 857, - 439 - ], - "page_idx": 31, - "id": 334 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 441, - 257, - 454 - ], - "page_idx": 31, - "id": 335 - }, - { - "type": "text", - "text": "1.拆检前必须隔离燃油、滑油及冷却水系统,并挂牌上锁(LOTO); \n2.缸内作业时使用防爆照明灯,电压 ≤24 V。", - "bbox": [ - 179, - 455, - 724, - 483 - ], - "page_idx": 31, - "id": 336 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 483, - 257, - 498 - ], - "page_idx": 31, - "id": 337 - }, - { - "type": "text", - "text": "1.抽出活塞时防止活塞环弹出伤人,应使用环压缩器; \n2.检查燃烧面时佩戴防颗粒物口罩,避免吸入积碳粉尘。", - "bbox": [ - 171, - 498, - 620, - 526 - ], - "page_idx": 31, - "id": 338 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 527, - 645, - 542 - ], - "page_idx": 31, - "id": 339 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 542, - 386, - 556 - ], - "page_idx": 31, - "id": 340 - }, - { - "type": "table", - "img_path": "images/be37f537e7434a702da213fe318b298c1fce64022e699ffabc888d78dfd594db.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1活塞环压缩器OEM-MAN-BW-RCC-061个适配Φ350mm活塞
2内窥镜GE Mentor VisualiQ1台
3深度规0-150mm1把
4放大镜10X with scale1个
", - "bbox": [ - 149, - 555, - 842, - 688 - ], - "page_idx": 31, - "id": 341 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 689, - 248, - 703 - ], - "page_idx": 31, - "id": 342 - }, - { - "type": "table", - "img_path": "images/b26c7a64d3c76f73c9f93771647ebee74fc03669eaaf225356dab1d320859c2d.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
本项目为检查类,无备件消耗
", - "bbox": [ - 151, - 702, - 842, - 760 - ], - "page_idx": 31, - "id": 343 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 760, - 248, - 775 - ], - "page_idx": 31, - "id": 344 - }, - { - "type": "table", - "img_path": "images/47acc8a58dfe0ef1a542131607817a79b6c3118133f60f56f6d5f33e757aa882.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1积碳清洗剂CRC Carbon CleanPro200mL环保型
2无纺布Industrial Grade5张
3防锈油CRC 3-3650mL
4)人力人员
序号专业人数技能等级备注
", - "bbox": [ - 146, - 774, - 843, - 907 - ], - "page_idx": 31, - "id": 345 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 31, - "id": 346 - }, - { - "type": "table", - "img_path": "images/0195ca1debc1da6471095742394b5b7dc3ab423fc175559fa66e2c173c78bcb6.jpg", - "table_caption": [ - "表 4.9 MT007 维修项目" - ], - "table_footnote": [], - "table_body": "
1机械专业2工程师+技师工程师判定磨损 等级
修理步骤及工艺
拆检前提确认 1)主机已完成1A级停机程序,缸内温度≤60℃; 2)已通过内窥镜初步确认无严重烧蚀或裂纹。
抽出活塞组件 1)拆除缸头、喷油器、排气阀等上部附件;
", - "bbox": [ - 142, - 82, - 857, - 670 - ], - "page_idx": 32, - "id": 347 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 762, - 257, - 776 - ], - "page_idx": 32, - "id": 348 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 147, - 806, - 257, - 819 - ], - "page_idx": 32, - "id": 349 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 32, - "id": 350 - }, - { - "type": "table", - "img_path": "images/fc3b875159bdd828240a44cb0371d60256bbea9eb8193633b46c1e464b3cc351.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
1活塞环压缩器OEM-MAN-BW-RCC-061个适配Φ350mm活塞
2环口间隙测量规Feeler Gauge Set1套0.05 -1.00mm
3环槽清洁刮刀Custom-Piston-Groove-Scraper1把铜质刃口
4扭矩扳手20 -100 N·m1把
", - "bbox": [ - 147, - 91, - 843, - 225 - ], - "page_idx": 33, - "id": 351 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 227, - 250, - 241 - ], - "page_idx": 33, - "id": 352 - }, - { - "type": "table", - "img_path": "images/608957d9fd1e5eb607507a6ba8f8bea32f81e800a3d392981793d1eedad60f64.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1第一道压缩环MAN 5L35MC-RING-11件梯形截面,表面镀铬
", - "bbox": [ - 151, - 240, - 843, - 297 - ], - "page_idx": 33, - "id": 353 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 298, - 248, - 312 - ], - "page_idx": 33, - "id": 354 - }, - { - "type": "table", - "img_path": "images/d258cd482e52295c63e29d1dbe9b82f50b79050ec647ddd338edd9510997890d.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1二硫化钼润滑膏Molycote BR2 Plus5g
2无绒布Kimwipe EX-L3张
3清洗剂Brulin 815GD100mL
", - "bbox": [ - 149, - 311, - 843, - 388 - ], - "page_idx": 33, - "id": 355 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 390, - 248, - 404 - ], - "page_idx": 33, - "id": 356 - }, - { - "type": "table", - "img_path": "images/6f27bb976da9587112a1690cce76cd1a25f286b7a5123e809dd30287c1851dcd.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师+技师工程师复刻还口间隙
", - "bbox": [ - 149, - 403, - 843, - 461 - ], - "page_idx": 33, - "id": 357 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 463, - 275, - 479 - ], - "page_idx": 33, - "id": 358 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 149, - 500, - 257, - 516 - ], - "page_idx": 33, - "id": 359 - }, - { - "type": "text", - "text": "1)活塞已按 $\\mathrm { M T 0 0 6 }$ 完成拆检,确认第一道环槽侧隙 $> 0 . 3 5 ~ \\mathrm { \\ m m }$ 或环断裂;", - "bbox": [ - 184, - 519, - 746, - 535 - ], - "page_idx": 33, - "id": 360 - }, - { - "type": "text", - "text": "2)新压缩环型号、批次与主机匹配,且在有效储存期内。", - "bbox": [ - 183, - 537, - 623, - 552 - ], - "page_idx": 33, - "id": 361 - }, - { - "type": "text", - "text": "拆卸旧1号压缩环1)用铜质刮刀清除环槽内积碳,避免损伤槽底;", - "bbox": [ - 184, - 556, - 700, - 571 - ], - "page_idx": 33, - "id": 362 - }, - { - "type": "text", - "text": "2)用手轻扩环口,将旧环从活塞顶部取出,禁止强行拉扯。", - "bbox": [ - 184, - 575, - 636, - 590 - ], - "page_idx": 33, - "id": 363 - }, - { - "type": "text", - "text": "安装新1号压缩环", - "bbox": [ - 149, - 612, - 290, - 627 - ], - "page_idx": 33, - "id": 364 - }, - { - "type": "text", - "text": "1)预处理", - "bbox": [ - 184, - 631, - 267, - 645 - ], - "page_idx": 33, - "id": 365 - }, - { - "type": "text", - "text": "(1)用无绒布清洁新环内外表面及活塞环槽;", - "bbox": [ - 194, - 649, - 537, - 664 - ], - "page_idx": 33, - "id": 366 - }, - { - "type": "text", - "text": "(2)在环外圆薄涂 Molycote BR2 Plus 润滑膏。", - "bbox": [ - 194, - 669, - 554, - 683 - ], - "page_idx": 33, - "id": 367 - }, - { - "type": "text", - "text": "2)装配 ", - "bbox": [ - 183, - 687, - 250, - 701 - ], - "page_idx": 33, - "id": 368 - }, - { - "type": "text", - "text": "(1)确认环上有“TOP”标记,安装时朝向活塞顶; \n(2)将环放入环槽,用手压平,确保无翘曲; \n(3)用活塞环压缩器收紧所有环,缓慢将活塞推入缸套。", - "bbox": [ - 191, - 705, - 628, - 757 - ], - "page_idx": 33, - "id": 369 - }, - { - "type": "text", - "text": "环口间隙检查(关键步骤)", - "text_level": 1, - "bbox": [ - 149, - 778, - 354, - 794 - ], - "page_idx": 33, - "id": 370 - }, - { - "type": "text", - "text": "1)将新环平放于缸套下部未磨损区域; \n2)用塞尺测量环口间隙,标准值: $0 . 6 0 { \\sim } 0 . 8 0 \\ \\mathrm { m m } ;$ ; \n3)若间隙 $\\langle 0 , 6 0 \\ \\mathrm { \\ m m }$ ,修锉环口端面;若 $> 0 . 8 0 \\ \\mathrm { \\ m m }$ ,更换新环。", - "bbox": [ - 183, - 797, - 682, - 851 - ], - "page_idx": 33, - "id": 371 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 33, - "id": 372 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 92, - 223, - 107 - ], - "page_idx": 34, - "id": 373 - }, - { - "type": "text", - "text": "1.1号压缩环正确安装,“TOP”标记朝上,无反装; \n2.环口间隙在 0.60~0.80 mm 范围内; \n3.环在槽内转动灵活,无卡滞,侧隙 $0 . 1 5 { \\sim } 0 . 3 5 ~ \\mathrm { m m } _ { \\circ }$ ", - "bbox": [ - 183, - 108, - 594, - 149 - ], - "page_idx": 34, - "id": 374 - }, - { - "type": "text", - "text": "版本号:1", - "bbox": [ - 551, - 152, - 633, - 166 - ], - "page_idx": 34, - "id": 375 - }, - { - "type": "table", - "img_path": "images/50d757ebd97a09f145dcd83bfd45b0db0e97655d028fe221aec6520034911460.jpg", - "table_caption": [ - "表 4.10 MT008 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT0080302042-4号活塞环更换2-4号活塞环1A/8000hJY级
", - "bbox": [ - 141, - 212, - 855, - 259 - ], - "page_idx": 34, - "id": 376 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 149, - 259, - 257, - 273 - ], - "page_idx": 34, - "id": 377 - }, - { - "type": "text", - "text": "1.多环同时更换时,应按顺序摆放旧环,防止混淆安装位置; \n2.缸套内壁涂抹润滑油前,确认无砂粒或金属屑残留。", - "bbox": [ - 184, - 273, - 690, - 302 - ], - "page_idx": 34, - "id": 378 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 302, - 257, - 316 - ], - "page_idx": 34, - "id": 379 - }, - { - "type": "text", - "text": "1.不同环型(刮油环、锥面环)不得互换位置;", - "bbox": [ - 189, - 316, - 542, - 330 - ], - "page_idx": 34, - "id": 380 - }, - { - "type": "text", - "text": "2.安装刮油环时,确保弹簧胀圈接口与环体开口错开180°。", - "bbox": [ - 179, - 331, - 652, - 344 - ], - "page_idx": 34, - "id": 381 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 146, - 346, - 645, - 360 - ], - "page_idx": 34, - "id": 382 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 360, - 388, - 374 - ], - "page_idx": 34, - "id": 383 - }, - { - "type": "table", - "img_path": "images/be480a0461de2f2734e46ccee896b86310814d14373b4470bbd6d269722beb97.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1活塞环压缩器OEM-MAN-BW-RCC-061个同MT007
2环口定位夹具Custom-Ring-Aligner1套控制各环开口相位
3放大镜(带LED)5× with light1个检查环体缺陷
", - "bbox": [ - 149, - 374, - 842, - 451 - ], - "page_idx": 34, - "id": 384 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 149, - 453, - 248, - 467 - ], - "page_idx": 34, - "id": 385 - }, - { - "type": "table", - "img_path": "images/91ac68d398c1b873dfc6dab8a8164e0479c9a5c5a7bb1fe450f2be15c83532ab.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1第二道压缩环MAN 5L35MC-RING-21件锥面环
2第三道刮油环(组合式)MAN 5L35MC-RING-31套含轨环+弹簧胀圈
3第四道刮油环(组合式)MAN 5L35MC-RING-41套同上
", - "bbox": [ - 151, - 466, - 842, - 558 - ], - "page_idx": 34, - "id": 386 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 149, - 560, - 248, - 574 - ], - "page_idx": 34, - "id": 387 - }, - { - "type": "table", - "img_path": "images/fa7836adb05e9d9d1387c4473ea317cccb3cc5b7830202435091bd9bb96e0455.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1二硫化钼润滑膏Molycote BR2 Plus10g涂所有环外圆
2缸套润滑机油Shell Mysella S5N8050 mL涂缸壁
3标记笔(耐油)Markal Oil-Resistant1支标记环开口位置
", - "bbox": [ - 149, - 573, - 843, - 667 - ], - "page_idx": 34, - "id": 388 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 667, - 247, - 681 - ], - "page_idx": 34, - "id": 389 - }, - { - "type": "table", - "img_path": "images/87cec9a9091d826279629615ba898b8767ac0f32c842cfc265cc4f26c05ef8da.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师+技师工程师监督相位布置
", - "bbox": [ - 149, - 680, - 843, - 730 - ], - "page_idx": 34, - "id": 390 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 732, - 275, - 747 - ], - "page_idx": 34, - "id": 391 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 149, - 769, - 257, - 784 - ], - "page_idx": 34, - "id": 392 - }, - { - "type": "text", - "text": "1)已完成 $\\mathbb { M T } 0 0 6$ 活塞拆检,确认 2-4 号环磨损超限或断裂;", - "bbox": [ - 183, - 788, - 640, - 802 - ], - "page_idx": 34, - "id": 393 - }, - { - "type": "text", - "text": "2)新环套装齐全,各环类型与图纸一致(RING-2 为锥面, $\\mathrm { R I N G } { - } 3 / 4$ 为组合刮油环)。", - "bbox": [ - 149, - 806, - 847, - 840 - ], - "page_idx": 34, - "id": 394 - }, - { - "type": "text", - "text": "拆卸旧环 ", - "bbox": [ - 149, - 863, - 223, - 877 - ], - "page_idx": 34, - "id": 395 - }, - { - "type": "text", - "text": "1)依次取出 2-4 号旧环,按顺序放置于标记托盘;", - "bbox": [ - 184, - 881, - 571, - 896 - ], - "page_idx": 34, - "id": 396 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 34, - "id": 397 - }, - { - "type": "text", - "text": "2)彻底清洁各环槽,确保无残留弹簧片或积碳。", - "bbox": [ - 181, - 95, - 556, - 110 - ], - "page_idx": 35, - "id": 398 - }, - { - "type": "text", - "text": "安装新环", - "bbox": [ - 149, - 131, - 223, - 146 - ], - "page_idx": 35, - "id": 399 - }, - { - "type": "text", - "text": "1)逐环装配 ", - "bbox": [ - 184, - 151, - 285, - 165 - ], - "page_idx": 35, - "id": 400 - }, - { - "type": "text", - "text": "(1)第二道环(锥面环):“TOP”标记朝上,开口位置与 1 号环错开 $1 2 0 ^ { \\circ }$ ;", - "bbox": [ - 194, - 168, - 789, - 184 - ], - "page_idx": 35, - "id": 401 - }, - { - "type": "text", - "text": "(2)第三、四道刮油环:先装下轨环 $\\twoheadrightarrow$ 弹簧胀圈 $\\twoheadrightarrow$ 上轨环,胀圈接口与环体开口相位差 $1 8 0 ^ { \\circ }$ °;", - "bbox": [ - 154, - 187, - 847, - 221 - ], - "page_idx": 35, - "id": 402 - }, - { - "type": "text", - "text": "(3)各环开口相位布置如下:- 1 号环: $0 ^ { \\circ }$ - 2 号环: $1 2 0 ^ { \\circ }$ - 3 号环: $2 4 0 ^ { \\circ }$ °- 4 号环: $6 0 ^ { \\circ }$ °", - "bbox": [ - 184, - 224, - 415, - 313 - ], - "page_idx": 35, - "id": 403 - }, - { - "type": "text", - "text": "2)润滑与压缩 ", - "bbox": [ - 183, - 318, - 302, - 332 - ], - "page_idx": 35, - "id": 404 - }, - { - "type": "text", - "text": "(1)在所有新环外圆涂 Molycote BR2 Plus; \n(2)在缸套内壁薄涂 Shell Mysella S5 N80 机油; \n(3)使用环压缩器收紧活塞环,垂直推入缸套,避免倾斜。", - "bbox": [ - 191, - 336, - 645, - 388 - ], - "page_idx": 35, - "id": 405 - }, - { - "type": "text", - "text": "验证 ", - "bbox": [ - 149, - 411, - 186, - 425 - ], - "page_idx": 35, - "id": 406 - }, - { - "type": "text", - "text": "1)盘车两圈,确认无异常阻力; \n2)抽查一道环口位置是否符合相位要求。", - "bbox": [ - 178, - 429, - 504, - 462 - ], - "page_idx": 35, - "id": 407 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 464, - 223, - 479 - ], - "page_idx": 35, - "id": 408 - }, - { - "type": "text", - "text": "1.各环类型、位置、方向正确,无混装;", - "bbox": [ - 186, - 479, - 492, - 493 - ], - "page_idx": 35, - "id": 409 - }, - { - "type": "text", - "text": "2.刮油环弹簧胀圈接口与环体开口错开 $1 8 0 ^ { \\circ }$ ;", - "bbox": [ - 186, - 494, - 537, - 507 - ], - "page_idx": 35, - "id": 410 - }, - { - "type": "text", - "text": "3.所有环口相位偏差 ≤±10°;", - "bbox": [ - 186, - 508, - 431, - 521 - ], - "page_idx": 35, - "id": 411 - }, - { - "type": "text", - "text": "4.盘车力矩平稳,无突增。", - "bbox": [ - 184, - 521, - 388, - 535 - ], - "page_idx": 35, - "id": 412 - }, - { - "type": "table", - "img_path": "images/f9582db5bcab3823baf9a0a7f20706b238c7712b99d239d18969ab50e95e974f.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1版本号:1
", - "bbox": [ - 196, - 536, - 642, - 551 - ], - "page_idx": 35, - "id": 413 - }, - { - "type": "table", - "img_path": "images/20a785f24c4b9aba9c4874852b7970416485301ea17075226560d8e815ab44fe.jpg", - "table_caption": [ - "表 4.11 MT009 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT009030301气缸套检测气缸套内径磨损量1A/8000hJY级
", - "bbox": [ - 141, - 596, - 855, - 657 - ], - "page_idx": 35, - "id": 414 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 658, - 257, - 671 - ], - "page_idx": 35, - "id": 415 - }, - { - "type": "text", - "text": "1.检测前必须在主机控制面板悬挂“禁止盘车”和“禁止启动”双警示牌; \n2.缸口作业区域设置防坠落围栏,工具系防坠绳。", - "bbox": [ - 183, - 671, - 759, - 700 - ], - "page_idx": 35, - "id": 416 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 701, - 257, - 714 - ], - "page_idx": 35, - "id": 417 - }, - { - "type": "text", - "text": "1.禁止在气缸冷却水未排空状态下进行内径测量;", - "bbox": [ - 188, - 717, - 561, - 730 - ], - "page_idx": 35, - "id": 418 - }, - { - "type": "text", - "text": "2.使用内径千分尺时,手部不得置于测量杆与缸壁之间,防止夹伤", - "bbox": [ - 183, - 730, - 694, - 744 - ], - "page_idx": 35, - "id": 419 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 146, - 745, - 647, - 758 - ], - "page_idx": 35, - "id": 420 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 759, - 388, - 772 - ], - "page_idx": 35, - "id": 421 - }, - { - "type": "table", - "img_path": "images/f155d1dcb62c655c931320e338976c850f5fdd9ec43287a3c9d3248b3692d754.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1内径千分尺(三点式)Mitutoyo 204-304 mm1套分辨率0.001mm
2缸套磨损测量记录仪Custom-Bore-Wear-Log1台自动生成磨损曲线
3防爆LED手电Streamlight 880401个24V安全电压
4清洁气枪Industrial Air BlowGun1把压力≤0.5 MPa
", - "bbox": [ - 149, - 772, - 842, - 895 - ], - "page_idx": 35, - "id": 422 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 35, - "id": 423 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 92, - 250, - 107 - ], - "page_idx": 36, - "id": 424 - }, - { - "type": "table", - "img_path": "images/e2f6440c8af9f1d0eee6f6422133073d9e5ecac5186dfec8a1d23b8f3edfc38c.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
本项目为检测类,无备件消耗
", - "bbox": [ - 151, - 107, - 842, - 155 - ], - "page_idx": 36, - "id": 425 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 156, - 247, - 171 - ], - "page_idx": 36, - "id": 426 - }, - { - "type": "table", - "img_path": "images/036fb7c6498a0cbce7976c247a858f76dbddca69590a9cdd5f25a1c16d8f86d5.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1工业酒精≥99.5%100mL清洁测量接触面
2无绒布Kimwipe EX-L5张防刮伤缸壁
3防锈纸VCI-2002张测量后临时覆盖
", - "bbox": [ - 149, - 170, - 842, - 234 - ], - "page_idx": 36, - "id": 427 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 235, - 247, - 248 - ], - "page_idx": 36, - "id": 428 - }, - { - "type": "table", - "img_path": "images/f81b4685b1c24ab0b988fb6a7641d823d6e18adaca19e28edb8ce164a3b9c6ec.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+工程师总工审核磨损趋势
", - "bbox": [ - 147, - 248, - 843, - 298 - ], - "page_idx": 36, - "id": 429 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 300, - 275, - 315 - ], - "page_idx": 36, - "id": 430 - }, - { - "type": "text", - "text": "检测前提确认 ", - "bbox": [ - 184, - 318, - 292, - 334 - ], - "page_idx": 36, - "id": 431 - }, - { - "type": "text", - "text": "1)主机已停机 ${ \\geqslant } 6$ 小时,缸套温度 $\\leqslant 5 0 ^ { \\circ } \\mathrm { C }$ ;", - "bbox": [ - 186, - 337, - 537, - 353 - ], - "page_idx": 36, - "id": 432 - }, - { - "type": "text", - "text": "2)活塞已按 $\\mathrm { M T 0 0 6 }$ 抽出,缸套内部无积碳遮挡;", - "bbox": [ - 186, - 356, - 549, - 370 - ], - "page_idx": 36, - "id": 433 - }, - { - "type": "text", - "text": "3)冷却水系统已隔离并排空。执行内径磨损测量", - "bbox": [ - 183, - 374, - 416, - 409 - ], - "page_idx": 36, - "id": 434 - }, - { - "type": "text", - "text": "1)清洁缸套 ", - "bbox": [ - 184, - 412, - 285, - 426 - ], - "page_idx": 36, - "id": 435 - }, - { - "type": "text", - "text": "(1)用气枪吹净缸套上部浮尘;", - "bbox": [ - 194, - 430, - 433, - 445 - ], - "page_idx": 36, - "id": 436 - }, - { - "type": "text", - "text": "(2)用酒精和无绒布擦拭测量区域(距上止点下 $2 0 \\ \\mathrm { \\ m m }$ 至下止点上 $2 0 \\ \\mathrm { \\ m m }$ )。", - "bbox": [ - 191, - 449, - 781, - 463 - ], - "page_idx": 36, - "id": 437 - }, - { - "type": "text", - "text": "2)设定测量截面与角度", - "bbox": [ - 183, - 467, - 373, - 482 - ], - "page_idx": 36, - "id": 438 - }, - { - "type": "text", - "text": "(1)沿轴向选取5个截面:- A: 上止点下 $2 0 \\ \\mathrm { \\ m m }$ - B: 上止点下 $1 0 0 ~ \\mathrm { { m m } }$ - C: 行程中点- D: 下止点上 $1 0 0 ~ \\mathrm { { m m } }$ - E: 下止点上 $2 0 \\ \\mathrm { \\ m m }$ ", - "bbox": [ - 183, - 486, - 394, - 593 - ], - "page_idx": 36, - "id": 439 - }, - { - "type": "text", - "text": "(2)每个截面在 $0 ^ { \\circ }$ 、 $9 0 ^ { \\circ }$ 、 $1 8 0 ^ { \\circ }$ 、 $2 7 0 ^ { \\circ }$ 四个方向测量内径。 ", - "bbox": [ - 189, - 598, - 675, - 612 - ], - "page_idx": 36, - "id": 440 - }, - { - "type": "text", - "text": "3)测量与记录", - "bbox": [ - 183, - 617, - 302, - 631 - ], - "page_idx": 36, - "id": 441 - }, - { - "type": "text", - "text": "(1)将三点式内径千分尺调零后置入截面,缓慢旋转获取最大读数;", - "bbox": [ - 191, - 634, - 712, - 649 - ], - "page_idx": 36, - "id": 442 - }, - { - "type": "text", - "text": "(2)记录各点实测值,计算圆度(同一截面最大–最小)与锥度(A–E差值)。数据判定", - "bbox": [ - 179, - 653, - 810, - 687 - ], - "page_idx": 36, - "id": 443 - }, - { - "type": "text", - "text": "1)若所有截面圆度 ${ \\leqslant } 0 . 0 8 \\ \\mathrm { \\ m m }$ 且锥度 ${ \\leqslant } 0 . 1 2 \\ \\mathrm { ~ m m }$ ,则判定合格;", - "bbox": [ - 184, - 690, - 690, - 705 - ], - "page_idx": 36, - "id": 444 - }, - { - "type": "text", - "text": "2)若任一指标超限但未达更换阈值,缩短下次检测周期至 $4 0 0 0 \\mathrm { ~ h ~ }$ ;", - "bbox": [ - 181, - 708, - 705, - 724 - ], - "page_idx": 36, - "id": 445 - }, - { - "type": "text", - "text": "3)若锥度 $> 0 . 2 0 \\ \\mathrm { \\ m m }$ 或局部拉伤深度 $> 0 . 3 ~ \\mathrm { \\ m m }$ ,启动 $\\mathrm { M T 0 1 0 }$ (更换气缸套)。", - "bbox": [ - 183, - 727, - 779, - 741 - ], - "page_idx": 36, - "id": 446 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 763, - 223, - 777 - ], - "page_idx": 36, - "id": 447 - }, - { - "type": "text", - "text": "1.圆度 $\\leqslant 0 . 0 8 \\ \\mathrm { m m }$ ,锥度 ${ \\leqslant } 0 . 1 2 \\ \\mathrm { ~ m m }$ ; \n2.测量原始数据完整录入《缸套磨损档案》,包含时间、温度、操作人; \n3.千分尺校验标签在有效期内,环境温度波动 $\\leqslant \\pm 3 ^ { \\circ } \\mathrm { C }$ 。", - "bbox": [ - 183, - 777, - 746, - 820 - ], - "page_idx": 36, - "id": 448 - }, - { - "type": "table", - "img_path": "images/2bf2e7bb1f1e9737d4c0a6be309cd5aadda3d1ee9e140cb7df9fb72db19ba45d.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1
", - "bbox": [ - 196, - 820, - 635, - 837 - ], - "page_idx": 36, - "id": 449 - }, - { - "type": "table", - "img_path": "images/12865913eed4bd99a2b25c607e1c5d3c56377c80c84a132b4d52c3005f4a72df.jpg", - "table_caption": [ - "图 $\\mathrm { M T 0 0 9 . ~ 1 }$ 气缸套磨损测量截面位置图(略)", - "表 4.12 MT010 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项组成编码名称维修项目维修间隔期维修级别
目编号
MT010030301气缸套更换气缸套4A/32000hJY级
", - "bbox": [ - 139, - 883, - 847, - 900 - ], - "page_idx": 36, - "id": 450 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 36, - "id": 451 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 137, - 91, - 858, - 122 - ], - "page_idx": 37, - "id": 452 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 151, - 123, - 257, - 136 - ], - "page_idx": 37, - "id": 453 - }, - { - "type": "text", - "text": "1.吊装新/旧缸套时使用专用吊耳,下方设置软质承接平台;", - "bbox": [ - 184, - 137, - 648, - 151 - ], - "page_idx": 37, - "id": 454 - }, - { - "type": "text", - "text": "2.缸体水腔开口处加盖防水布,防止异物或水分进入曲轴箱。", - "bbox": [ - 184, - 152, - 645, - 166 - ], - "page_idx": 37, - "id": 455 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 166, - 258, - 179 - ], - "page_idx": 37, - "id": 456 - }, - { - "type": "text", - "text": "1.禁止用火焰直接加热缸体以拆卸旧套,防止热应力裂纹;", - "bbox": [ - 171, - 181, - 635, - 195 - ], - "page_idx": 37, - "id": 457 - }, - { - "type": "text", - "text": "2.新缸套压装过程中,操作人员不得站在压机正下方。", - "bbox": [ - 169, - 195, - 605, - 209 - ], - "page_idx": 37, - "id": 458 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 210, - 645, - 224 - ], - "page_idx": 37, - "id": 459 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 224, - 388, - 237 - ], - "page_idx": 37, - "id": 460 - }, - { - "type": "table", - "img_path": "images/cafaa5373270b6f39ce1b873c303534d0e6294ebcd27a1c474f7214c9007b3e3.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1液压压装机HYDRA-PRESS-50T1台带压力与位移监控
2缸套拔出器OEM-MAN-BW-LINER-PULL1套螺纹顶压式
3冷却水腔密封测试仪LeakTest-CT3001台0.3 MPa 保压
4深度规0-300 mm1把测量缸套凸肩高度
", - "bbox": [ - 149, - 237, - 842, - 378 - ], - "page_idx": 37, - "id": 461 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 379, - 248, - 393 - ], - "page_idx": 37, - "id": 462 - }, - { - "type": "table", - "img_path": "images/d4547222a1b8e3041c2bc650501819a27ec8468c7796f69439fd06d73ad6b690.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1气缸套总成MAN 5L35MC-LINER-ASSY1件含0形圈、定位销
2缸套水封0形圈VitonΦ380×5.02个耐高温氟橡胶
3缸套油封环NBRΦ352×3.01个下部密封
", - "bbox": [ - 151, - 392, - 842, - 470 - ], - "page_idx": 37, - "id": 463 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 149, - 472, - 248, - 485 - ], - "page_idx": 37, - "id": 464 - }, - { - "type": "table", - "img_path": "images/bf0e1f7ba49e5b658a478d17318b16adb95090b1e4ad78448e0b9a2ae69a9167.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1装配润滑脂Kluber Isoflex LDS18 Special A20g涂缸套外壁
2密封胶Loctite 518少量水腔法兰面(如适用)
3清洗剂Brulin 815GD300mL清洁缸体座孔
", - "bbox": [ - 149, - 485, - 842, - 579 - ], - "page_idx": 37, - "id": 465 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 579, - 247, - 593 - ], - "page_idx": 37, - "id": 466 - }, - { - "type": "table", - "img_path": "images/d6e9c5fd43c4b4c3032c0d87af9974af19c6124c71d7de9260e1b524681de3ac.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业3总工+2×工程师总工监督压装对中
", - "bbox": [ - 149, - 592, - 843, - 642 - ], - "page_idx": 37, - "id": 467 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 644, - 275, - 658 - ], - "page_idx": 37, - "id": 468 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 184, - 663, - 292, - 677 - ], - "page_idx": 37, - "id": 469 - }, - { - "type": "text", - "text": "1)MT009检测结果确认缸套磨损超限(锥度 $> 0 . 2 0 \\ \\mathrm { \\ m m }$ 或裂纹);", - "bbox": [ - 184, - 681, - 690, - 696 - ], - "page_idx": 37, - "id": 470 - }, - { - "type": "text", - "text": "2)新缸套已核对尺寸、材质证书,O 形圈无老化。", - "bbox": [ - 183, - 700, - 568, - 715 - ], - "page_idx": 37, - "id": 471 - }, - { - "type": "text", - "text": "拆卸旧缸套 ", - "bbox": [ - 183, - 719, - 275, - 733 - ], - "page_idx": 37, - "id": 472 - }, - { - "type": "text", - "text": "1)拆除缸头、活塞、冷却水管路;", - "bbox": [ - 186, - 737, - 448, - 751 - ], - "page_idx": 37, - "id": 473 - }, - { - "type": "text", - "text": "2)安装缸套拔出器,均匀施力将旧套缓慢顶出;", - "bbox": [ - 186, - 756, - 556, - 771 - ], - "page_idx": 37, - "id": 474 - }, - { - "type": "text", - "text": "3)检查缸体座孔有无腐蚀、变形,若有则需镗孔修复。 安装新缸套 ", - "bbox": [ - 183, - 774, - 610, - 808 - ], - "page_idx": 37, - "id": 475 - }, - { - "type": "text", - "text": "1)准备 ", - "bbox": [ - 184, - 812, - 248, - 826 - ], - "page_idx": 37, - "id": 476 - }, - { - "type": "text", - "text": "(1)清洁缸体座孔及新缸套外壁,无毛刺、油污;", - "bbox": [ - 196, - 829, - 571, - 845 - ], - "page_idx": 37, - "id": 477 - }, - { - "type": "text", - "text": "(2)在新缸套外壁薄涂Klüber润滑脂;", - "bbox": [ - 193, - 848, - 494, - 864 - ], - "page_idx": 37, - "id": 478 - }, - { - "type": "text", - "text": "(3)将O形圈装入缸体水封槽,涂少量硅脂。", - "bbox": [ - 191, - 868, - 536, - 882 - ], - "page_idx": 37, - "id": 479 - }, - { - "type": "text", - "text": "2)压装", - "bbox": [ - 183, - 885, - 250, - 900 - ], - "page_idx": 37, - "id": 480 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 37, - "id": 481 - }, - { - "type": "table", - "img_path": "images/c21284c91c848bdd80ce8ccb53611422d233f441105d912b62d5a184bc59e851.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
(1)将新缸套垂直放入座孔,使用导向套对中; (2)启动液压压机,以≤5mm/min 速度压入,监控压力曲线; (3)压装到位后,测量缸套上平面凸肩高度,标准值:3.5±0.2 mm。 3)密封测试 (1)封闭水腔进出口,注入0.3MPa压缩空气; (2)保压10分钟,压降≤0.01MPa 判定密封合格。
攵标准 1.缸套凸肩高度 3.3~3.7 mm; 2.水腔0.3MPa保压10分钟无泄漏; 3.缸套内径圆度≤0.03mm(出厂状态)。
", - "bbox": [ - 176, - 91, - 857, - 336 - ], - "page_idx": 38, - "id": 482 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 260, - 223, - 274 - ], - "page_idx": 38, - "id": 483 - }, - { - "type": "table", - "img_path": "images/e04f4c8d84b74a582b38f8d1cd3ef7c6f6802a8c26e96210a2afb52a95482ce2.jpg", - "table_caption": [ - "表 4.13 MT011 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT011040102阀杆检查排气阀杆密封面磨损6M/4000hJY级
", - "bbox": [ - 141, - 380, - 857, - 439 - ], - "page_idx": 38, - "id": 484 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 441, - 257, - 454 - ], - "page_idx": 38, - "id": 485 - }, - { - "type": "text", - "text": "1.拆检前必须隔离气缸启动空气系统,并在阀杆驱动机构处加装机械锁; \n2.高温阀杆冷却前禁止直接接触,作业区设置“高温部件”警示标识。", - "bbox": [ - 178, - 455, - 741, - 483 - ], - "page_idx": 38, - "id": 486 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 483, - 257, - 498 - ], - "page_idx": 38, - "id": 487 - }, - { - "type": "text", - "text": "1.禁止使用砂轮或电动工具打磨阀杆密封面;", - "bbox": [ - 186, - 499, - 529, - 511 - ], - "page_idx": 38, - "id": 488 - }, - { - "type": "text", - "text": "2.检查时佩戴耐高温手套及护目镜,防止热辐射或碎屑伤害。", - "bbox": [ - 166, - 513, - 655, - 526 - ], - "page_idx": 38, - "id": 489 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 527, - 647, - 542 - ], - "page_idx": 38, - "id": 490 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 542, - 386, - 555 - ], - "page_idx": 38, - "id": 491 - }, - { - "type": "table", - "img_path": "images/cc15c78b018c296eb398e8b295caebb3216394523568a8a946ead4c802fa568a.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1排气阀专用吊具OEM-MAN-BW-VALVE-HOOK1套带隔热手柄
2红外测温仪Fluke 62 Max+1台测量阀杆温度
3密封面检测平板Optical Flat λ/101块用于着色法检查
4着色剂套装Dykem Steel Blue +Developer1套检查接触印痕
", - "bbox": [ - 149, - 555, - 842, - 682 - ], - "page_idx": 38, - "id": 492 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 682, - 250, - 696 - ], - "page_idx": 38, - "id": 493 - }, - { - "type": "table", - "img_path": "images/16aaca33785d9284f5269b49e5f02ba1028e5c4c96068791a0754f1b16d68c89.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
本项目为检查类,无备件消耗(但可能触发MT012)
", - "bbox": [ - 151, - 695, - 842, - 772 - ], - "page_idx": 38, - "id": 494 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 774, - 248, - 788 - ], - "page_idx": 38, - "id": 495 - }, - { - "type": "table", - "img_path": "images/9d2f8bb40dd63ba0f5f3927ecf253d6acb84c5a061291923c8073beb68415959.jpg", - "table_caption": [ - "4)人力人员" - ], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1高温清洁剂CRC Brakleen HT100 mL清除积碳
2无绒布Kimwipe EX-L5张防刮伤密封面
3防锈油CRC 3-3630mL检查后临时防护
", - "bbox": [ - 149, - 787, - 842, - 852 - ], - "page_idx": 38, - "id": 496 - }, - { - "type": "table", - "img_path": "images/1078b0e3d7f60232c8d0838e6666ca4497eed5b13e4b2abebd4c507f9c88a922.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师+技师工程师判定磨损
", - "bbox": [ - 144, - 865, - 842, - 901 - ], - "page_idx": 38, - "id": 497 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 38, - "id": 498 - }, - { - "type": "table", - "img_path": "images/ac37ff4a7dbef9e7a283adb2a17a8b10ecdc144a1ae890e205dc8a3f131bcdac.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
等级
", - "bbox": [ - 141, - 91, - 855, - 108 - ], - "page_idx": 39, - "id": 499 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 149, - 110, - 277, - 126 - ], - "page_idx": 39, - "id": 500 - }, - { - "type": "table", - "img_path": "images/939f6f62ed5805f3b673e67477c25c176ab318bcc380877f902f09fa573c2b22.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
修理步骤及工艺 检查前提确认 1)主机已停机≥4小时,排气阀杆温度≤80℃(用红外测温仪确认); 2)启动空气系统已隔离并泄压。
拆卸排气阀组件 1)拆除阀杆驱动弹簧及锁紧螺母; 2)使用专用吊具缓慢吊出排气阀总成,放置于耐热支架。
检查阀杆密封面 1)清洁
(1)用高温清洁剂软化密封面积碳; (2)用铜刷清除残留物,禁用钢丝刷。 2)着色法检测
(1)在阀座密封面上均匀涂抹Dykem着色剂; (2)将阀杆轻压旋转180°后提起;
(3)观察阀杆密封面印痕: -合格:连续环带,宽度≥1.5 mm,无断点; -轻微磨损:环带不连续但无凹坑;
-严重磨损:有沟槽、凹坑或烧蚀斑。 判定与处置 1)若印痕连续且宽度≥1.5mm,清洁后回装;
2)若存在局部凹坑或烧蚀,标记该阀,启动MT012(更换排气阀座); 3)记录检查结果于《排气阀状态档案》。 验收标准 阀杆密封面差色印痕为连续环带 宽度
", - "bbox": [ - 146, - 118, - 857, - 541 - ], - "page_idx": 39, - "id": 501 - }, - { - "type": "text", - "text": "1.阀杆密封面着色印痕为连续环带,宽度 $\\geqslant 1 . 5 ~ \\mathrm { ~ m m }$ ", - "bbox": [ - 181, - 532, - 586, - 545 - ], - "page_idx": 39, - "id": 502 - }, - { - "type": "text", - "text": "2.无可见裂纹、凹坑、烧蚀或局部熔融;", - "bbox": [ - 186, - 546, - 494, - 560 - ], - "page_idx": 39, - "id": 503 - }, - { - "type": "text", - "text": "3.回装后阀杆动作灵活,无卡滞。", - "bbox": [ - 184, - 561, - 442, - 574 - ], - "page_idx": 39, - "id": 504 - }, - { - "type": "table", - "img_path": "images/6174b21b95afbe2c4b0a3f7f019a77266842a2919830c35ea5c029a850aa35b2.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1版本号:1
", - "bbox": [ - 196, - 575, - 665, - 592 - ], - "page_idx": 39, - "id": 505 - }, - { - "type": "table", - "img_path": "images/9ee20348e14141c14e85450a1b099eb859d1f620658a4d860f6061fa42237ac9.jpg", - "table_caption": [ - "表 4.14 MT012 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT012040103阀座更换排气阀座2A/16000hJY级
", - "bbox": [ - 141, - 638, - 855, - 683 - ], - "page_idx": 39, - "id": 506 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 149, - 684, - 257, - 697 - ], - "page_idx": 39, - "id": 507 - }, - { - "type": "text", - "text": "1.镗削或更换阀座时,气缸内部必须完全隔离,并加盖防异物盖; \n2.使用便携式镗床时,设备接地良好,操作区设置警戒线。", - "bbox": [ - 184, - 697, - 700, - 726 - ], - "page_idx": 39, - "id": 508 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 727, - 257, - 740 - ], - "page_idx": 39, - "id": 509 - }, - { - "type": "text", - "text": "1.禁止在未冷却的缸盖上进行阀座更换作业; \n2.新阀座压装或焊接后,必须进行无损检测(PT/UT)。", - "bbox": [ - 173, - 741, - 611, - 769 - ], - "page_idx": 39, - "id": 510 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 146, - 770, - 645, - 784 - ], - "page_idx": 39, - "id": 511 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 784, - 388, - 799 - ], - "page_idx": 39, - "id": 512 - }, - { - "type": "table", - "img_path": "images/063ba79f97ea9cdea8fec42cd06c3bf7858bc43cbc4d7e63c5bec2e70c1c6b2e.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1便携式阀座镗床SUNNEN SV-201台带角度调节
2液压阀座压装机HYDRA-SEAT-PRESS1台用于过盈配合座
3渗透探伤套装Magnaflux ZL-27A1套PT检测裂纹
4角度规0-90°Protractor1把检查密封锥角
", - "bbox": [ - 149, - 799, - 842, - 878 - ], - "page_idx": 39, - "id": 513 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 878, - 248, - 892 - ], - "page_idx": 39, - "id": 514 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 39, - "id": 515 - }, - { - "type": "table", - "img_path": "images/db3a2f05f1acaa2ef4b54ebda8b62f8f0604a0272264ff862f9614f7ee9dbd98.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1排气阀座MAN 5L35MC-EXH-SEAT1件Stellite合金堆焊
2定位销(如适用)Φ8×20mm1个不锈钢
", - "bbox": [ - 147, - 91, - 843, - 156 - ], - "page_idx": 40, - "id": 516 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 156, - 248, - 171 - ], - "page_idx": 40, - "id": 517 - }, - { - "type": "table", - "img_path": "images/cf4203e009fc837d904bd899b53e5c652a02ca5102c605a0561a6909bd24f35e.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1高温镍基焊条ENiCrFe-31根用于焊接固定(如需要)
2清洗剂Brulin 815GD150 mL清洁阀座孔
3研磨膏(细)Clover Leaf Green20g配合研磨
", - "bbox": [ - 149, - 171, - 843, - 249 - ], - "page_idx": 40, - "id": 518 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 249, - 247, - 263 - ], - "page_idx": 40, - "id": 519 - }, - { - "type": "table", - "img_path": "images/f5d8d8e970f46602a772c79bb8dfd11124bc2ba145111a5b79ad99d639f802a9.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+工程师总工批准焊接/压装方案
", - "bbox": [ - 147, - 263, - 843, - 312 - ], - "page_idx": 40, - "id": 520 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 315, - 277, - 330 - ], - "page_idx": 40, - "id": 521 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 184, - 334, - 292, - 349 - ], - "page_idx": 40, - "id": 522 - }, - { - "type": "text", - "text": "1)MT011检查确认阀座密封面烧蚀、裂纹或锥面变形;", - "bbox": [ - 184, - 353, - 603, - 367 - ], - "page_idx": 40, - "id": 523 - }, - { - "type": "text", - "text": "2)新阀座材质、锥角(通常 $4 5 ^ { \\circ }$ )与原设计一致。", - "bbox": [ - 183, - 370, - 578, - 386 - ], - "page_idx": 40, - "id": 524 - }, - { - "type": "text", - "text": "拆卸旧阀座", - "bbox": [ - 184, - 390, - 275, - 404 - ], - "page_idx": 40, - "id": 525 - }, - { - "type": "text", - "text": "1)若为压装式:使用液压拉拔器缓慢取出;", - "bbox": [ - 184, - 409, - 519, - 423 - ], - "page_idx": 40, - "id": 526 - }, - { - "type": "text", - "text": "2)若为焊接式:用碳弧气刨或专用铣刀去除旧座,避免损伤缸盖基体。安装新阀座", - "bbox": [ - 181, - 426, - 736, - 460 - ], - "page_idx": 40, - "id": 527 - }, - { - "type": "text", - "text": "1)准备阀座孔 ", - "bbox": [ - 184, - 463, - 302, - 479 - ], - "page_idx": 40, - "id": 528 - }, - { - "type": "text", - "text": "(1)清洁孔内油污、毛刺,测量内径;", - "bbox": [ - 196, - 482, - 485, - 498 - ], - "page_idx": 40, - "id": 529 - }, - { - "type": "text", - "text": "(2)若为压装,确保过盈量 $0 . 0 5 { \\sim } 0 . 0 8 \\ \\mathrm { m m } .$ ", - "bbox": [ - 194, - 500, - 537, - 516 - ], - "page_idx": 40, - "id": 530 - }, - { - "type": "text", - "text": "2)安装方式选择", - "bbox": [ - 183, - 520, - 319, - 535 - ], - "page_idx": 40, - "id": 531 - }, - { - "type": "text", - "text": "(1)压装法:将新阀座冷却至 $- 4 0 ^ { \\circ } \\mathrm { C }$ (干冰),快速压入预热至 $8 0 ^ { \\circ } \\mathrm { C }$ 的缸盖孔;", - "bbox": [ - 189, - 538, - 806, - 552 - ], - "page_idx": 40, - "id": 532 - }, - { - "type": "text", - "text": "(2)焊接法:采用 TIG 焊沿阀座底部周向点焊固定,焊后缓冷。", - "bbox": [ - 191, - 556, - 680, - 571 - ], - "page_idx": 40, - "id": 533 - }, - { - "type": "text", - "text": "3)密封面精加工", - "bbox": [ - 183, - 575, - 319, - 589 - ], - "page_idx": 40, - "id": 534 - }, - { - "type": "text", - "text": "(1)使用便携镗床修整密封锥面,角度 $4 5 ^ { \\circ } \\ \\pm 0 . 5 ^ { \\circ }$ °;", - "bbox": [ - 193, - 594, - 603, - 608 - ], - "page_idx": 40, - "id": 535 - }, - { - "type": "text", - "text": "(2)表面粗糙度 $\\mathrm { { R a } ~ } \\leqslant 1 . 6 \\ \\mathrm { ~ \\mu ~ m ~ } .$ 。", - "bbox": [ - 194, - 612, - 442, - 627 - ], - "page_idx": 40, - "id": 536 - }, - { - "type": "text", - "text": "研配与检测", - "bbox": [ - 184, - 631, - 275, - 645 - ], - "page_idx": 40, - "id": 537 - }, - { - "type": "text", - "text": "1)与对应阀杆进行手工研磨,着色印痕连续宽度 $\\geqslant 1 . 8 \\mathrm { ~ m m }$ ;", - "bbox": [ - 184, - 649, - 652, - 664 - ], - "page_idx": 40, - "id": 538 - }, - { - "type": "text", - "text": "2)对焊接区域进行PT探伤,无裂纹、气孔; \n3)记录安装参数(温度、压力、角度)。", - "bbox": [ - 181, - 668, - 529, - 701 - ], - "page_idx": 40, - "id": 539 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 703, - 223, - 718 - ], - "page_idx": 40, - "id": 540 - }, - { - "type": "text", - "text": "1 阀座与阀杆着色印痕连续,宽度 $\\geqslant 1 . 8 \\mathrm { ~ m m }$ ;", - "bbox": [ - 188, - 719, - 532, - 732 - ], - "page_idx": 40, - "id": 541 - }, - { - "type": "text", - "text": "2.PT探伤无缺陷(适用于焊接阀座);", - "bbox": [ - 184, - 733, - 480, - 746 - ], - "page_idx": 40, - "id": 542 - }, - { - "type": "text", - "text": "3.密封面锥角 45°±0.5°,Ra ≤1.6 μm;", - "bbox": [ - 188, - 747, - 527, - 760 - ], - "page_idx": 40, - "id": 543 - }, - { - "type": "table", - "img_path": "images/06cb0da637ebcbb897b5c887b1800fe2ec9eb50753911516c110c4c34be69f43.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
页码:1/1版本号:1
", - "bbox": [ - 193, - 775, - 657, - 790 - ], - "page_idx": 40, - "id": 544 - }, - { - "type": "table", - "img_path": "images/4f04ee74720242cb378f9b0c3db0da4aaa23f8e73c71baf1ca08a99e0b7c6972.jpg", - "table_caption": [ - "表 4.15 MT013 维修项目" - ], - "table_footnote": [ - "安全防护要求" - ], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT013050201喷油嘴偶件更换喷油嘴偶件6M/4000hJY级
", - "bbox": [ - 139, - 837, - 857, - 883 - ], - "page_idx": 40, - "id": 545 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 40, - "id": 546 - }, - { - "type": "text", - "text": "1.拆卸喷油器前必须泄放高压燃油系统压力,并在燃油泵出口加装盲板; \n2.高压油管接口处悬挂“高压危险”警示牌,作业区禁止明火", - "bbox": [ - 174, - 92, - 788, - 121 - ], - "page_idx": 41, - "id": 547 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 151, - 122, - 257, - 136 - ], - "page_idx": 41, - "id": 548 - }, - { - "type": "text", - "text": "1.禁止用金属工具敲击喷油嘴,防止针阀卡死或密封面损 ", - "bbox": [ - 176, - 136, - 628, - 149 - ], - "page_idx": 41, - "id": 549 - }, - { - "type": "text", - "text": "2.新偶件拆封后立即安装,避免暴露于潮湿或粉尘环境。", - "bbox": [ - 178, - 151, - 620, - 164 - ], - "page_idx": 41, - "id": 550 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 152, - 165, - 645, - 179 - ], - "page_idx": 41, - "id": 551 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 180, - 386, - 193 - ], - "page_idx": 41, - "id": 552 - }, - { - "type": "table", - "img_path": "images/292095136cab5dc27d81f0b4ba1402e834fb7c40dcd3bab73e8975df2efe6dae.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
房号名称规格/型号数量及单位备注
1喷油器专用拆装扳手OEM-MAN-BW-INJ-WRENCH1把防滑齿设计
2高压燃油压力表0-20 MPa1个校验有效期内
3喷油雾化测试台Bosch EPS 8151台可测开启压力与雾化角
4扭矩扳手40 -200 N·m1把用于喷油器压紧螺母
", - "bbox": [ - 149, - 193, - 842, - 334 - ], - "page_idx": 41, - "id": 553 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 149, - 335, - 250, - 349 - ], - "page_idx": 41, - "id": 554 - }, - { - "type": "table", - "img_path": "images/d3d4aa32fbd08847a8cb3917dcd985e788dfc8ca2a9ef5cec39eb64b4bcb35b5.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1喷油嘴偶件(针阀+阀体)MAN 5L35MC-INJ-NOZZLE-KIT1套原厂高精度配对
2喷油器铜密封垫Φ18×2.0 mm1个退火紫铜,一次性
", - "bbox": [ - 149, - 348, - 847, - 425 - ], - "page_idx": 41, - "id": 555 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 426, - 248, - 441 - ], - "page_idx": 41, - "id": 556 - }, - { - "type": "table", - "img_path": "images/727a977b7ebfd76e314509e4099e28dc06c5ee4011df5d58d3cdefb909a5183a.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1清洁柴油ISO 4020 Grade A200 mL用于冲洗油道
2无绒布Kimwipe EX-L5张擦拭偶件表面
3高温润滑脂Molycote G-1052少量涂压紧螺纹
", - "bbox": [ - 151, - 439, - 843, - 505 - ], - "page_idx": 41, - "id": 557 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 506, - 247, - 519 - ], - "page_idx": 41, - "id": 558 - }, - { - "type": "table", - "img_path": "images/f0e3aaed2f7051bdcd81ee0ed344573e3cf91ac036480e4afde0555edc2af85b.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2工程师 + 技师工程师操作测试台
", - "bbox": [ - 147, - 519, - 845, - 568 - ], - "page_idx": 41, - "id": 559 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 570, - 277, - 586 - ], - "page_idx": 41, - "id": 560 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 184, - 589, - 292, - 605 - ], - "page_idx": 41, - "id": 561 - }, - { - "type": "text", - "text": "1)主机运行中出现单缸排温异常升高或冒黑烟;", - "bbox": [ - 184, - 608, - 556, - 623 - ], - "page_idx": 41, - "id": 562 - }, - { - "type": "text", - "text": "2)或按计划周期( $\\geq 4 0 0 0 \\mathrm { ~ h ~ } )$ )执行预防性更换;", - "bbox": [ - 184, - 627, - 554, - 642 - ], - "page_idx": 41, - "id": 563 - }, - { - "type": "text", - "text": "3)新喷油嘴偶件包装完好,配对编号一致。拆卸旧喷油器", - "bbox": [ - 183, - 645, - 524, - 678 - ], - "page_idx": 41, - "id": 564 - }, - { - "type": "text", - "text": "1)关闭该缸高压油泵进油阀,泄放残余压力;", - "bbox": [ - 186, - 682, - 536, - 697 - ], - "page_idx": 41, - "id": 565 - }, - { - "type": "text", - "text": "2)用专用扳手松开喷油器压紧螺母(扭矩释放后手动旋出);", - "bbox": [ - 183, - 701, - 662, - 717 - ], - "page_idx": 41, - "id": 566 - }, - { - "type": "text", - "text": "3)垂直取出喷油器总成,防止针阀意外伸出。更换喷油嘴偶件", - "bbox": [ - 183, - 719, - 539, - 753 - ], - "page_idx": 41, - "id": 567 - }, - { - "type": "text", - "text": "1)分解旧喷油器", - "bbox": [ - 184, - 757, - 319, - 771 - ], - "page_idx": 41, - "id": 568 - }, - { - "type": "text", - "text": "(1)在清洁工作台上拆下旧喷油嘴;", - "bbox": [ - 196, - 775, - 468, - 790 - ], - "page_idx": 41, - "id": 569 - }, - { - "type": "text", - "text": "(2)检查是否有咬死、积碳或滴漏。", - "bbox": [ - 194, - 794, - 468, - 809 - ], - "page_idx": 41, - "id": 570 - }, - { - "type": "text", - "text": "2)安装新偶件", - "bbox": [ - 183, - 813, - 302, - 827 - ], - "page_idx": 41, - "id": 571 - }, - { - "type": "text", - "text": "(1)用清洁柴油冲洗新偶件内部通道;", - "bbox": [ - 196, - 831, - 485, - 846 - ], - "page_idx": 41, - "id": 572 - }, - { - "type": "text", - "text": "(2)将新喷油嘴旋入喷油器本体,手工拧紧至贴合;", - "bbox": [ - 191, - 850, - 593, - 864 - ], - "page_idx": 41, - "id": 573 - }, - { - "type": "text", - "text": "(3)更换新铜密封垫,安装喷油器至缸盖,压紧螺母扭矩: $1 2 0 \\mathrm { ~ N ~ } { \\cdot } \\mathrm { ~ m ~ }$ 功能测试", - "bbox": [ - 186, - 868, - 731, - 902 - ], - "page_idx": 41, - "id": 574 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 41, - "id": 575 - }, - { - "type": "table", - "img_path": "images/05667a22ac884de789213ba4cf6269a6892a0d12ce8102aac78c2613476d7f38.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
验收标准1.喷油开启压力27.5~28.5 MPa;2.雾化均匀,呈锥形无偏射、无油线;3.安装后无燃油泄漏,主机运行单缸排温偏差≤±15℃。
页码:1/1版本号:1
", - "bbox": [ - 147, - 92, - 857, - 260 - ], - "page_idx": 42, - "id": 576 - }, - { - "type": "table", - "img_path": "images/ce4136fa88c64d10a14906b0ecf41e24f33f6f2ed9853c5cfafe66a994ce5164.jpg", - "table_caption": [ - "表 4.16 MT014 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT014050301柱塞偶件更换高压油泵柱塞偶件1A/8000hJY级
", - "bbox": [ - 141, - 306, - 857, - 366 - ], - "page_idx": 42, - "id": 577 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 366, - 257, - 380 - ], - "page_idx": 42, - "id": 578 - }, - { - "type": "text", - "text": "1.拆卸高压油泵前必须隔离燃油系统,并挂牌上锁(LOTO); \n2.柱塞偶件存放于专用防尘盒内,避免磕碰精密配合面。", - "bbox": [ - 181, - 380, - 653, - 409 - ], - "page_idx": 42, - "id": 579 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 151, - 410, - 257, - 424 - ], - "page_idx": 42, - "id": 580 - }, - { - "type": "text", - "text": "1.禁止互换不同泵体的柱塞偶件,必须成对使用原厂配对件; \n2.安装时确保柱塞斜槽与齿条啮合正确,防止供油相位错误。", - "bbox": [ - 168, - 424, - 652, - 451 - ], - "page_idx": 42, - "id": 581 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 453, - 645, - 467 - ], - "page_idx": 42, - "id": 582 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 149, - 468, - 386, - 481 - ], - "page_idx": 42, - "id": 583 - }, - { - "type": "table", - "img_path": "images/7a19b44cd821b43ac6b1634d678b122c2d7b86797db5863f3a9ab6671d39ab0c.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
房号名称规格/型号数量及单位备注
1柱塞偶件安装导向套OEM-MAN-BW-PLUNGER-GUIDE1个防止划伤
2供油定时检测仪AVL 5451台测量喷油始点
3精密塞尺0.02-1.00mm1套检查齿条间隙
4扭矩扳手30 -150 N·m1把用于泵体检修盖
", - "bbox": [ - 149, - 481, - 842, - 607 - ], - "page_idx": 42, - "id": 584 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 608, - 250, - 623 - ], - "page_idx": 42, - "id": 585 - }, - { - "type": "table", - "img_path": "images/fa6fa147fcdd631afc13a68024a772e9f792436362f8a990b4e6b35923fcdfb4.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1柱塞+套筒偶件MAN 5L35MC-PLUNGER-KIT1套配对编号一致
2出油阀组件MAN5L35MC-DV-ASSY1套含弹簧、阀座
", - "bbox": [ - 149, - 621, - 842, - 686 - ], - "page_idx": 42, - "id": 586 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 686, - 248, - 700 - ], - "page_idx": 42, - "id": 587 - }, - { - "type": "table", - "img_path": "images/f2cf564617441e6675913b5207ff753774f88d0a9e16193f5f360f49f189a3c5.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1高压泵专用润滑油Shell Tellus S4 VX32100 mL用于偶件润滑
2密封胶Loctite 577少量泵体结合面(如适用)
3清洗柴油ISO 4020 Grade A300mL冲洗油道
", - "bbox": [ - 149, - 699, - 843, - 793 - ], - "page_idx": 42, - "id": 588 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 793, - 247, - 807 - ], - "page_idx": 42, - "id": 589 - }, - { - "type": "table", - "img_path": "images/eff5d6b713b7dc99a3114bd185462ba7944a107fc5b666cb26537a74fb5c3551.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+工程师总工确认供油定时
", - "bbox": [ - 144, - 806, - 847, - 856 - ], - "page_idx": 42, - "id": 590 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 858, - 275, - 873 - ], - "page_idx": 42, - "id": 591 - }, - { - "type": "text", - "text": "更换前提确认 ", - "bbox": [ - 183, - 877, - 292, - 892 - ], - "page_idx": 42, - "id": 592 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 42, - "id": 593 - }, - { - "type": "table", - "img_path": "images/f8426d78141ec9050f8d18a1de11ad42f809fc518438f8a12c3914233519c638.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
1)主机出现供油不足、单缸功率下降或高压油泵异响; 2)或运行时间≥8000h,执行计划性更换; 3)新偶件配对编号与泵体匹配,无运输损伤。 拆卸高压油泵 1)拆除进出油管、齿条连接机构; 2)松开泵体检修盖螺栓,取出柱塞偶件及出油阀。 安装新柱塞偶件 1)清洁与检查 (1)用清洗柴油彻底冲洗泵体内腔; (2)检查齿条移动是否灵活,间隙0.10~0.20 mm。 2)装配 (1)在新柱塞表面涂 Shel1 Tellus S4VX32润滑油; (2)使用导向套将柱塞缓慢插入套筒,旋转使其斜槽对准调节齿条; (3)安装出油阀组件,确保弹簧预紧到位。 3)回装泵体 (1)安装检修盖,螺栓按对角线顺序拧紧至80 N·m;
供油定时校验 1)启动主机至额定转速,用AVL545检测喷油始点; 2)标准值:上止点前 12.5°±0.5°CA;
验收标准 1.柱塞偶件运动灵活,无卡滞或泄漏; 2.供油始点为上止点前 12.0°~13.0°CA;
3.主机各缸排温差≤±20℃,无功率波动。
", - "bbox": [ - 137, - 92, - 857, - 564 - ], - "page_idx": 43, - "id": 594 - }, - { - "type": "table", - "img_path": "images/1380375ec83855ef0c725a67875bcb6c28df4274c50b6d14d395ef45b53de8da.jpg", - "table_caption": [ - "表 4.17 MT015 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT015060103轴承组件更换涡轮增压器轴承组件2A/16000hZJ级
", - "bbox": [ - 139, - 602, - 857, - 662 - ], - "page_idx": 43, - "id": 595 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 663, - 257, - 676 - ], - "page_idx": 43, - "id": 596 - }, - { - "type": "text", - "text": "1.拆卸增压器前必须隔离排气与进气管路,并加装盲板;", - "bbox": [ - 188, - 677, - 616, - 692 - ], - "page_idx": 43, - "id": 597 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 147, - 707, - 257, - 720 - ], - "page_idx": 43, - "id": 598 - }, - { - "type": "text", - "text": "1.禁止用手直接转动增压器转子判断轴承状态,应使用专用盘车工具; \n2.新轴承安装前确认无油脂污染或保持架变形。", - "bbox": [ - 183, - 720, - 722, - 749 - ], - "page_idx": 43, - "id": 599 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 750, - 643, - 764 - ], - "page_idx": 43, - "id": 600 - }, - { - "type": "table", - "img_path": "images/f0cfd1368c14a4ea1c2c4bfb00a2c93bb917435a1ff8320fe07e704e2c52998f.jpg", - "table_caption": [ - "1)保障设施、保障设备(工具)" - ], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1涡轮增压器专用拆装台Custom-Turbo-Bench1台带V型支撑
2感应加热器EFD Minac 101台温控±5℃
3动平衡检测仪Schenck BALANCERV1台G2.5级精度
4扭矩扳手10-80N·m1把用于壳体螺栓
", - "bbox": [ - 149, - 777, - 842, - 872 - ], - "page_idx": 43, - "id": 601 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 872, - 248, - 885 - ], - "page_idx": 43, - "id": 602 - }, - { - "type": "table", - "img_path": "images/e017efd1b02d4383540089011786ea42042512b1ba65ab026e035b52b3898055.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1径向轴承(主轴)MAN TCA77-BRG-RAD1套铜铅合金
2止推轴承组件MAN TCA77-BRG-THRUST1套含瓦片+垫片组
3轴封环Carbon SealΦ60×32个石墨基
", - "bbox": [ - 149, - 884, - 840, - 906 - ], - "page_idx": 43, - "id": 603 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 588, - 928 - ], - "page_idx": 43, - "id": 604 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 147, - 91, - 843, - 166 - ], - "page_idx": 44, - "id": 605 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 167, - 248, - 181 - ], - "page_idx": 44, - "id": 606 - }, - { - "type": "table", - "img_path": "images/85793420abab01cba35f1eb41c891a5d664ce1e795f046ba39ab1c55880e4978.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1高温润滑脂Kluber Isoflex LDS18 Special A15g仅涂轴承外圈
2清洗剂Brulin 815GD200 mL清洁轴承座
3密封胶Loctite 518少量壳体结合面
", - "bbox": [ - 149, - 179, - 843, - 259 - ], - "page_idx": 44, - "id": 607 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 260, - 247, - 273 - ], - "page_idx": 44, - "id": 608 - }, - { - "type": "table", - "img_path": "images/70711bbdc89824a055acc876a90e69d2a995e0b2eb08aac4288158c97f0ed1a9.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2高级+中级高级主导装配
2电子专业1中级监测振动传感器(如适用)
", - "bbox": [ - 147, - 273, - 845, - 337 - ], - "page_idx": 44, - "id": 609 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 340, - 277, - 355 - ], - "page_idx": 44, - "id": 610 - }, - { - "type": "table", - "img_path": "images/e577f613b490a322a52cde7450472ed7bb3e5fa2a5aaff058b6c6bb088ea9582.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
更换前提确认 1)主机运行中增压器振动值>4.5mm/s(RMS); 2)或按计划周期≥16000h 执行预防性更换; 3)新轴承组件包装完好,无运输损伤。 拆卸增压器总成 1)断开进排气法兰、滑油进出口管路; 2)使用吊车将增压器整体吊离支架,放置于专用工作台。 分解与更换轴承 1)分解 (1)拆除两端轴承盖,取出转子总成;
2)清洁与检查 (1)清洁轴承座孔,测量内径,记录磨损量; (2)检查转子轴颈有无拉伤、椭圆(允许圆度≤0.02mm)。 3)热装新轴承 (1)将径向轴承加热至120±5℃; (2)迅速套入主轴,自然冷却; (3)安装止推轴承,调整垫片组使轴向间隙0.10~0.15 mm。
1)按对称顺序拧紧壳体螺栓(扭矩:50N·m); 2)手动盘车,确认转子转动灵活无卡滞; 3)若条件允许,进行低速动平衡测试(残余不平衡≤2g·mm)。 验收标准 1.转子轴向间隙0.10~0.15 mm; 2.手动盘车无卡滞,旋转阻力均匀;
3.回装后空载试运行30分钟,振动值≤3.0mm/s。 页码:1/1 版本号:1
", - "bbox": [ - 141, - 350, - 858, - 848 - ], - "page_idx": 44, - "id": 611 - }, - { - "type": "table", - "img_path": "images/e7800b7a14fc1280b124189992ff9bb968bb83f7c09cc02b75c4141182549d65.jpg", - "table_caption": [ - "表 4.18 MT016 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项组成编码名称维修项目维修间隔期维修级别
目编号
MT016060201管束芯体清洗空冷器管束芯体3MZJ级
", - "bbox": [ - 137, - 877, - 845, - 895 - ], - "page_idx": 44, - "id": 612 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 44, - "id": 613 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 141, - 91, - 857, - 136 - ], - "page_idx": 45, - "id": 614 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 149, - 137, - 257, - 151 - ], - "page_idx": 45, - "id": 615 - }, - { - "type": "text", - "text": "1.清洗前必须隔离海水/淡水侧管路,并排空内部介质;", - "bbox": [ - 184, - 152, - 605, - 165 - ], - "page_idx": 45, - "id": 616 - }, - { - "type": "text", - "text": "2.高压水枪作业时佩戴防护面罩及防水服。", - "bbox": [ - 183, - 166, - 512, - 179 - ], - "page_idx": 45, - "id": 617 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 147, - 180, - 257, - 195 - ], - "page_idx": 45, - "id": 618 - }, - { - "type": "text", - "text": "1.禁止使用酸性清洗剂,防止腐蚀铝制或铜镍合金管束;", - "bbox": [ - 181, - 195, - 613, - 209 - ], - "page_idx": 45, - "id": 619 - }, - { - "type": "text", - "text": "2.清洗压力不得超过 5 MPa,防止翅片倒伏或管子破裂。", - "bbox": [ - 178, - 210, - 613, - 222 - ], - "page_idx": 45, - "id": 620 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 224, - 645, - 237 - ], - "page_idx": 45, - "id": 621 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 239, - 388, - 252 - ], - "page_idx": 45, - "id": 622 - }, - { - "type": "table", - "img_path": "images/1aa5a62b00f965b38c9d3772278d4ea180b448be8032a896fd0cb7ceb87c2be6.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1高压清洗机Kärcher HD 7/15-41台压力0-5MPa可调
2管束专用清洗喷头Rotating Nozzle3mm2个自旋式
3风压干燥机Industrial AirDryer1台0.6 MPa
4泄漏测试装置Air/Water LeakTester1套0.4 MPa保压
", - "bbox": [ - 149, - 252, - 842, - 388 - ], - "page_idx": 45, - "id": 623 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 403, - 250, - 417 - ], - "page_idx": 45, - "id": 624 - }, - { - "type": "table", - "img_path": "images/551db6c91d2ead2ec7efef38a3c39136327549a0f2a35157404f1bba25ed6c81.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
本项目为清洗 类,无备件消耗 (但可能触发堵 管修复
", - "bbox": [ - 151, - 417, - 842, - 494 - ], - "page_idx": 45, - "id": 625 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 508, - 250, - 523 - ], - "page_idx": 45, - "id": 626 - }, - { - "type": "table", - "img_path": "images/6ee2e398326152142d38525cbc86f89c5a125242c2ce50d1d1ae312eea00453c.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1中性清洗剂Alconox Detojet2kgpH=9.5,环保型
2软化水Deionized Water200 L配制清洗液
3防锈剂CRC 3-36100 mL清洗后喷涂
", - "bbox": [ - 151, - 521, - 842, - 594 - ], - "page_idx": 45, - "id": 627 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 607, - 247, - 621 - ], - "page_idx": 45, - "id": 628 - }, - { - "type": "table", - "img_path": "images/69c884d086a4869a23e2d6623830e0fd8ddce7c76448f4287bc8e03d36243dc4.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2中级+初级中级操作高压设备
", - "bbox": [ - 147, - 621, - 843, - 670 - ], - "page_idx": 45, - "id": 629 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 149, - 674, - 275, - 688 - ], - "page_idx": 45, - "id": 630 - }, - { - "type": "text", - "text": "清洗前提确认 ", - "bbox": [ - 183, - 693, - 292, - 707 - ], - "page_idx": 45, - "id": 631 - }, - { - "type": "text", - "text": "1)主机扫气温度差(进/出空冷器) ${ } \\mathrm { > } 1 5 \\mathrm { ‰}$ ,或压降 $\\gamma 1 . 5 \\mathrm { \\ k P a }$ ;", - "bbox": [ - 184, - 711, - 670, - 726 - ], - "page_idx": 45, - "id": 632 - }, - { - "type": "text", - "text": "2)空冷器已从系统中隔离并排空。", - "bbox": [ - 184, - 730, - 452, - 744 - ], - "page_idx": 45, - "id": 633 - }, - { - "type": "text", - "text": "1)用低压水冲洗空冷器外表面,去除盐结晶与油污;", - "bbox": [ - 183, - 766, - 588, - 782 - ], - "page_idx": 45, - "id": 634 - }, - { - "type": "text", - "text": "2)拆除端盖,检查管口堵塞情况。 管束芯体清洗 ", - "bbox": [ - 183, - 784, - 452, - 819 - ], - "page_idx": 45, - "id": 635 - }, - { - "type": "text", - "text": "1)配制清洗液 ", - "bbox": [ - 184, - 822, - 304, - 837 - ], - "page_idx": 45, - "id": 636 - }, - { - "type": "text", - "text": "(1)将 Alconox Detojet 按 $2 \\%$ 浓度溶于软化水;", - "bbox": [ - 196, - 840, - 556, - 856 - ], - "page_idx": 45, - "id": 637 - }, - { - "type": "text", - "text": "(2)水温控制在 $4 0 \\pm 5 ^ { \\circ } \\mathrm { C }$ 。", - "bbox": [ - 193, - 859, - 398, - 875 - ], - "page_idx": 45, - "id": 638 - }, - { - "type": "text", - "text": "2)高压冲洗 ", - "bbox": [ - 183, - 878, - 284, - 892 - ], - "page_idx": 45, - "id": 639 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 45, - "id": 640 - }, - { - "type": "table", - "img_path": "images/80d3d0d903db2ba34b6b57f6011e619385f3e9c695331772646b6ff45a441ddb.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
(1)将旋转喷头插入每根管子,以3.5MPa 压力冲洗; (2)水流方向与正常流向一致,单管冲洗时间≥15 秒; (3)重点清洗迎风面及底部积垢区。 3)漂洗与干燥 (1)用清水彻底漂洗至pH=7; 清洗前提确认 1)主机扫气温度差(进/出空冷器)>15℃,或压降>1.5 kPa; 2)空冷器已从系统中隔离并排空。 外部清洁 1)用低压水冲洗空冷器外表面,去除盐结晶与油污; 2)拆除端盖,检查管口堵塞情况。 管束芯体清洗 1)配制清洗液 (1)将Alconox Detojet 按2%浓度溶于软化水; (2)水温控制在 40±5℃。 2)高压冲洗 (1)将旋转喷头插入每根管子,以3.5 MPa压力冲洗; (2)水流方向与正常流向一致,单管冲洗时间≥15 秒; (3)重点清洗迎风面及底部积垢区。 3)漂洗与干燥 (1)用清水彻底漂洗至pH=7; (2)用0.6MPa压缩空气吹干管内残留水分。 泄漏测试与防护
1)对淡水侧加压至0.4 MPa,保压10分钟,压降≤0.01 MPa; 2)在翅片表面薄喷CRC 3-36 防锈剂。 验收标准 1.空冷器淡水侧压降≤1.0kPa(额定流量下);
2.扫气温差恢复至≤10℃; 3.泄漏测试无渗漏,翅片无大面积倒伏。
页码:1/1 版本号:1
", - "bbox": [ - 139, - 87, - 857, - 640 - ], - "page_idx": 46, - "id": 641 - }, - { - "type": "table", - "img_path": "images/958cd6534611bb7596bcfb5d54c930b427a9603303112caa1bf6ce97758cdfde.jpg", - "table_caption": [ - "表 4.19 MT017 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
T017030200连杆大端轴承修复连杆大端轴承异常磨损故障触发ZJ级
安全防护要求1.着火后必须立即停机、切断燃油与启动空气,并启动CO2灭火系统(如已动作需确认复位);2.进入扫气箱前执行受限空间作业许可,检测02≥19.5%、CH4<1%LEL。
安全注意事项1.禁止在未冷却(>60℃)的扫气箱内使用电动工具;2.残留油泥可能自燃,清理时持续喷雾降温。
保障设施、保障设备(工具)、备件、消耗材料、人力人员需求1)保障设施、保障设备(工具)序号 名称 规格/型号 数量及单位 备注1 防爆型扫气箱清洗 SCB-CLEANB0T-X1 1台 自动高压水射流
序号名称规格/型号数量及单位备注
1防爆型扫气箱清洗SCB-CLEANB0T-X11台自动高压水射流
机器人
2内窥镜(防爆)GE Mentor VisualiQ-Ex1台检查缸套下部
3红外热像仪FLIR T8601台检测局部热点
4可燃气体检测仪MSA Altair 5X1台多气体复合
", - "bbox": [ - 139, - 675, - 858, - 903 - ], - "page_idx": 46, - "id": 642 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 46, - "id": 643 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 147, - 91, - 843, - 167 - ], - "page_idx": 47, - "id": 644 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 167, - 250, - 181 - ], - "page_idx": 47, - "id": 645 - }, - { - "type": "table", - "img_path": "images/5e1b20867d972d77846d321d26a8653c580c19862732c2bf95638a4868bf51ed.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1全套活塞环组MAN 5L35MC-RING-SET1套含1-4号环
2活塞头(如需更换)MAN 5L35MC-PISTON-HEAD1件铸钢整体式
3扫气口密封条Viton Strip 5×10mm若干更换烧损件
", - "bbox": [ - 149, - 180, - 842, - 288 - ], - "page_idx": 47, - "id": 646 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 149, - 288, - 248, - 303 - ], - "page_idx": 47, - "id": 647 - }, - { - "type": "table", - "img_path": "images/d3fb4772b73d6e18bcfa80cd3e364be60557af584cd2bf17975ab4cc302d4f42.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1生物降解清洗剂Envirox SC-905L清除碳化油泥
2耐高温防火毯Fiberglass Mat1200°C2m局部隔热防护
3防锈剂CRC 3-36200mL修复后防护
", - "bbox": [ - 149, - 302, - 842, - 381 - ], - "page_idx": 47, - "id": 648 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 149, - 381, - 247, - 395 - ], - "page_idx": 47, - "id": 649 - }, - { - "type": "table", - "img_path": "images/0a79591db75fc541a17cd0d8ca470da0080e8d6c683a21cf440ca587e5205de4.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业3总工+2×工程师总工主导故障分析
2安全监督1高级安全员全程监护受限空间作业
", - "bbox": [ - 147, - 395, - 843, - 474 - ], - "page_idx": 47, - "id": 650 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 476, - 275, - 491 - ], - "page_idx": 47, - "id": 651 - }, - { - "type": "text", - "text": "故障确认与隔离 ", - "bbox": [ - 184, - 495, - 310, - 510 - ], - "page_idx": 47, - "id": 652 - }, - { - "type": "text", - "text": "1)确认故障现象:扫气箱高温报警、排烟管冒黑烟、单缸排温骤升后骤降;2)停机后盘车检查,发现某缸活塞环断裂、扫气口积碳严重; \n3)隔离该缸燃油、启动空气、冷却水。 \n扫气箱清理与检查 \n1)打开扫气箱人孔,通风 $\\geqslant 3 0$ 分钟; \n2)用清洗机器人清除底部碳化油泥(重点:着火点周边); \n3)目视 $^ +$ 内窥镜检查: \n缸套下部有无拉伤; \n扫气口边缘是否熔融变形; \n曲轴箱油雾浓度是否异常。 \n活塞组件修复 \n1)抽出故障缸活塞,确认1号环断裂、环槽烧蚀; \n2)若活塞头无裂纹,仅更换全套活塞环(执行 $\\mathsf { M T 0 0 7 + M T 0 0 8 }$ ); \n3)若活塞头火力岸熔损 $\\gamma 2 \\ m \\mathrm { m }$ ,启动 $\\mathrm { M T 0 1 8 }$ 。 \n系统恢复与验证 \n1)回装活塞,按标准扭矩紧固缸头; \n2)手动盘车两圈,确认无卡滞; \n3)空载试运行30分钟,监测: \n扫气温度 ${ \\leqslant } 6 0 ^ { \\circ } \\mathrm { C }$ ; \n无异常振动或异响。", - "bbox": [ - 178, - 512, - 855, - 883 - ], - "page_idx": 47, - "id": 653 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 47, - "id": 654 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 92, - 223, - 107 - ], - "page_idx": 48, - "id": 655 - }, - { - "type": "text", - "text": "1.扫气箱内部无残留碳渣、油泥,表面干燥清洁; \n2.新活塞环安装正确,环口相位符合MT008要求; \n3.主机空载运行30分钟,扫气温度稳定 ${ \\leqslant } 6 0 ^ { \\circ } \\mathrm { C }$ ,无复燃风险。", - "bbox": [ - 183, - 108, - 660, - 149 - ], - "page_idx": 48, - "id": 656 - }, - { - "type": "table", - "img_path": "images/79943d32993c830ed7107cb8ac416572f1a2a67b0a7105459056fa918bb9abc9.jpg", - "table_caption": [ - "表 4.20 MT018 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT018030201活塞头修复活塞头部烧蚀熔损故障触发ZJ级
", - "bbox": [ - 141, - 212, - 857, - 273 - ], - "page_idx": 48, - "id": 657 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 149, - 273, - 257, - 286 - ], - "page_idx": 48, - "id": 658 - }, - { - "type": "text", - "text": "1.修复作业区设置防火挡板,配备干粉灭火器( $\\geqslant 2$ 具);", - "bbox": [ - 186, - 287, - 633, - 300 - ], - "page_idx": 48, - "id": 659 - }, - { - "type": "text", - "text": "2.焊接/堆焊操作需办理动火作业许可证。", - "bbox": [ - 164, - 302, - 857, - 316 - ], - "page_idx": 48, - "id": 660 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 317, - 258, - 330 - ], - "page_idx": 48, - "id": 661 - }, - { - "type": "text", - "text": "1.禁止对深度裂纹(>3 mm)的活塞头进行堆焊修复,必须更换; \n2.热处理后必须缓冷,防止二次裂纹。", - "bbox": [ - 183, - 331, - 682, - 359 - ], - "page_idx": 48, - "id": 662 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 360, - 647, - 374 - ], - "page_idx": 48, - "id": 663 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 374, - 388, - 387 - ], - "page_idx": 48, - "id": 664 - }, - { - "type": "table", - "img_path": "images/860de36bdd774768dd1b6097d2e95cb8e8b0a6214457a29b9f6648aad30e390d.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称规格/型号数量及单位备注
1等离子堆焊机PLASMAD 50001台自动送粉
2热处理炉Box Furnace 800°C1台控温±10℃
3超声波探伤仪Olympus Epoch 6501台检测内部缺陷
4三维扫描仪FARO Arm Quantum1台修复前后形貌比对
", - "bbox": [ - 151, - 387, - 842, - 481 - ], - "page_idx": 48, - "id": 665 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 483, - 250, - 498 - ], - "page_idx": 48, - "id": 666 - }, - { - "type": "table", - "img_path": "images/bd4a9be006ec4087a6d60a17a97be288f3e7ebd41363d5801e12bf5aa4b6626f.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
本项目为修复类,通常不消耗新活塞(除非报废)
", - "bbox": [ - 149, - 499, - 842, - 576 - ], - "page_idx": 48, - "id": 667 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 577, - 248, - 592 - ], - "page_idx": 48, - "id": 668 - }, - { - "type": "table", - "img_path": "images/1d865426d01d0cacb2f6a5524d7082558d26d1e80430494828968dee6dcbdd43.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1镍基合金焊粉INCONEL 625300g耐高温抗烧蚀
2渗透探伤剂Magnaflux ZL-27A1套PT检测裂纹
3保温棉Ceramic FiberBlanket2 kg焊后包裹缓冷
", - "bbox": [ - 151, - 590, - 842, - 670 - ], - "page_idx": 48, - "id": 669 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 149, - 670, - 247, - 684 - ], - "page_idx": 48, - "id": 670 - }, - { - "type": "table", - "img_path": "images/e44bfe73c8b53a1058feb5276194bc55dd0dbc4418b68d631f12c3921f14a9e4.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2总工+高级技师总工批准修复方案
2焊接专业1高级焊工(ASMEIX认证)执行堆焊
", - "bbox": [ - 149, - 684, - 843, - 763 - ], - "page_idx": 48, - "id": 671 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 765, - 275, - 780 - ], - "page_idx": 48, - "id": 672 - }, - { - "type": "text", - "text": "损伤评估 ", - "bbox": [ - 184, - 784, - 258, - 799 - ], - "page_idx": 48, - "id": 673 - }, - { - "type": "text", - "text": "1)通过 $\\mathbb { M T } 0 0 6$ 或 MT017 拆检,确认活塞顶存在:局部熔坑(深度 ${ < } 3 ~ \\mathrm { \\ m m }$ );火力岸微裂纹(长度 $\\mathrm { < 1 0 m m }$ ,深度 $\\angle 2 ~ \\mathrm { m m } ,$ );", - "bbox": [ - 184, - 802, - 554, - 856 - ], - "page_idx": 48, - "id": 674 - }, - { - "type": "text", - "text": "2)超声波探伤确认无内部裂纹延伸至销孔或冷却腔。预处理", - "bbox": [ - 181, - 858, - 625, - 891 - ], - "page_idx": 48, - "id": 675 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 48, - "id": 676 - }, - { - "type": "table", - "img_path": "images/ec8f64eea3194c7616a1adce7c03f409613a98260d8cf3a21aacad3fe4c419fb.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
1)用PT渗透法标记所有表面裂纹; 2)用碳弧气刨或铣刀将熔损区域加工成U型坡口(R≥3mm); 3)放入热处理炉预热至250℃,保温2小时。 堆焊修复
1)采用等离子堆焊,使用INCONEL625 焊粉,层间温度控制在 200-300℃; 2)堆焊高度超出原轮廓1.5mm,预留机加工余量; 3)焊后立即用陶瓷纤维棉包裹,随炉缓冷至≤50℃。
后处理与验证 1)机加工恢复活塞顶原始轮廓(参照三维扫描模型);
2)再次PT探伤,确认无新裂纹; 3)测量重量,与标准活塞偏差≤±50g,否则配重。
攵标准 1.修复区域无裂纹、气孔、未熔合等缺陷(PT/UT合格);
2.活塞顶几何尺寸符合图纸公差(±0.2mm);
3.重量偏差≤±50g,冷却腔密封性测试0.3MPa保压10分钟无泄漏。
页码:1/1 版本号:1
", - "bbox": [ - 174, - 92, - 855, - 372 - ], - "page_idx": 49, - "id": 677 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 297, - 223, - 311 - ], - "page_idx": 49, - "id": 678 - }, - { - "type": "table", - "img_path": "images/06797c95110c29319dc6e26bb8d9e9777a682e6c59e437c060abb0fd4d4ab7e9.jpg", - "table_caption": [ - "表 4.21 MT019 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT0190502喷油器组件排除喷油器雾化不良故障1UZJ级
", - "bbox": [ - 141, - 418, - 857, - 478 - ], - "page_idx": 49, - "id": 679 - }, - { - "type": "text", - "text": "安全防护要求", - "text_level": 1, - "bbox": [ - 147, - 478, - 257, - 492 - ], - "page_idx": 49, - "id": 680 - }, - { - "type": "text", - "text": "1.拆卸喷油器前必须泄放高压燃油系统压力,并在燃油泵出口加装盲板; \n2.高压油管接口区域设置“高压危险”警示标识,禁止明火作业。", - "bbox": [ - 181, - 492, - 757, - 520 - ], - "page_idx": 49, - "id": 681 - }, - { - "type": "text", - "text": "安全注意事项", - "text_level": 1, - "bbox": [ - 149, - 521, - 257, - 535 - ], - "page_idx": 49, - "id": 682 - }, - { - "type": "text", - "text": "1.拆卸喷油器前必须泄放高压燃油系统压力,并在燃油泵出口加装盲板; \n2.高压油管接口区域设置“高压危险”警示标识,禁止明火作业。", - "bbox": [ - 176, - 535, - 742, - 563 - ], - "page_idx": 49, - "id": 683 - }, - { - "type": "text", - "text": "保障设施、保障设备(工具)、备件、消耗材料、人力人员需求", - "bbox": [ - 147, - 564, - 645, - 579 - ], - "page_idx": 49, - "id": 684 - }, - { - "type": "text", - "text": "1)保障设施、保障设备(工具)", - "bbox": [ - 151, - 579, - 386, - 592 - ], - "page_idx": 49, - "id": 685 - }, - { - "type": "table", - "img_path": "images/7502a2df53202b3d1b01b8ce1782fdb7684b412c6bb61872289b0455039cbcbd.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
房号名称规格/型号数量及单位备注
1喷油器专用拆装扳手OEM-MAN-BW-INJ-WRENCH1把防滑齿设计
2喷油雾化测试台Bosch EPS 815 或等效1台可调压、可视窗
3扭矩扳手40 -200 N·m1把用于压紧螺母回装
", - "bbox": [ - 149, - 592, - 842, - 718 - ], - "page_idx": 49, - "id": 686 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 719, - 248, - 733 - ], - "page_idx": 49, - "id": 687 - }, - { - "type": "table", - "img_path": "images/5e9ac8edf3f1bba7cedd831083566fb88e97233973a0256c3036b13832bdd681.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1喷油嘴偶件MAN 5L35MC-INJ-N0ZZLE-KIT1套原厂配对
2铜密封垫Φ18×2.0 mm1个退火紫铜,一次性
", - "bbox": [ - 151, - 731, - 847, - 810 - ], - "page_idx": 49, - "id": 688 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 810, - 248, - 825 - ], - "page_idx": 49, - "id": 689 - }, - { - "type": "table", - "img_path": "images/48f66387086a6f0cbe2dd7dbda2ee99233433b6972d19657a97ca1e13e28e42b.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1清洁柴油ISO 4020 Grade A200 mL冲洗油道
2无绒布Kimwipe EX-L5张擦拭精密表面
3高温润滑脂Molycote G-1052少量涂压紧螺纹
", - "bbox": [ - 149, - 824, - 843, - 889 - ], - "page_idx": 49, - "id": 690 - }, - { - "type": "text", - "text": "4)人力人员", - "text_level": 1, - "bbox": [ - 147, - 890, - 248, - 904 - ], - "page_idx": 49, - "id": 691 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 49, - "id": 692 - }, - { - "type": "table", - "img_path": "images/dc74a03dc026cb0b449829673b138abc09e2326a5ea235905b3f1c87c8b8de9e.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2高级+中级高级主导测试判 定
修理步骤及工艺 故障确认
1)主机运行中出现: 单缸排温异常升高(>平均值 +50℃); 排烟冒黑烟或有未燃柴油味; 高压油管脉动减弱。 2)初步判断为该缸喷油器雾化不良。 拆卸与初步检查
1)关闭该缸高压油泵进油阀,手动盘车泄压; 2)用专用扳手拆下喷油器,检查外部有无燃油泄漏痕迹; 3)目视喷孔:若有积碳堵塞或变形,标记待测。 雾化性能测试
1)在Bosch EPS 815 测试台上安装喷油器; 2)逐步升压至28MPa,观察: 合格:雾锥均匀、无油线、无滴漏,开启压力28.0±0.5 MPa; 雾化不良表现:
(1)喷射断续; (2)雾锥偏斜或呈柱状;
(3)停喷后滴漏 >1滴/分钟。 3)若不合格,分解更换喷油嘴偶件。 回装与验证 1)更换新铜密封垫,安装喷油器,压紧螺母扭矩:120N·m;
2)启动主机,观察该缸排温是否恢复正常(偏差≤±20℃); 3)运行30分钟无泄漏、无黑烟。
验收标准 1.喷油开启压力27.5~28.5 MPa;
2.雾化锥角150°±5°,无偏射、无滴漏;
3.主机运行后单缸排温偏差≤±20℃,无黑烟。
页码:1/1 版本号:1
", - "bbox": [ - 141, - 83, - 857, - 671 - ], - "page_idx": 50, - "id": 693 - }, - { - "type": "table", - "img_path": "images/e7000b2c932098a619493e13de9c4ed190c60e0218ec8829f1f215192ab28920.jpg", - "table_caption": [ - "表 4.22 MT020 维修项目" - ], - "table_footnote": [], - "table_body": "
维修项目编号组成编码名称维修项目维修间隔期维修级别
MT02001机座与机架组件排除主机功率异常波动故障1UZJ级
安全防护要求1.故障排查期间,主机控制模式切换至“本地手动”,防止自动加载干扰;2.数据采集接线须由持证电工完成,符合船用防爆规范。
安全注意事项1.禁止在功率剧烈波动时强行维持高负荷运行;2.调整调速器前必须双人确认,防止飞车风险。
保障设施、保障设备(工具)、备件、消耗材料、人力人员需求1)保障设施、保障设备(工具)序号 名称 规格/型号 数量及单位 备注
序号名称规格/型号数量及单位备注
1主机监控系统(PMS)Integrated BridgeSystem1套读取实时功率曲线
2调速器性能测试仪Woodward TestBench1台检测响应滞后
3燃油黏度计MarconiViscotester1台测 HFO黏度
4多通道数据记录仪DataTaker DT801套同步录负荷/转速
", - "bbox": [ - 139, - 707, - 858, - 906 - ], - "page_idx": 50, - "id": 694 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 50, - "id": 695 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 147, - 91, - 842, - 210 - ], - "page_idx": 51, - "id": 696 - }, - { - "type": "text", - "text": "2)备品备件", - "bbox": [ - 147, - 210, - 250, - 224 - ], - "page_idx": 51, - "id": 697 - }, - { - "type": "table", - "img_path": "images/f4e7bc70642ce4f4d9253108a1bca54baa5b0b6004462d9b005dd04dde7ce371.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
名称规格/型号消耗数量备注
1调速器伺服阀滤芯OEM-GOV-FILTER1个如堵塞
2燃油温度传感器PT100,0-200°C1个如漂移
", - "bbox": [ - 151, - 224, - 842, - 273 - ], - "page_idx": 51, - "id": 698 - }, - { - "type": "text", - "text": "3)消耗材料", - "bbox": [ - 147, - 274, - 248, - 288 - ], - "page_idx": 51, - "id": 699 - }, - { - "type": "table", - "img_path": "images/aacb051160432a6a1adcfc3c96fd30ff09833e62cc89e57cfc2ec4dc803fe860.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号名称牌号/品级/规格消耗数量备注
1标准测试燃油ISO8217RMG380300L用于稳定测试
2密封胶Loctite 577少量传感器安装
", - "bbox": [ - 149, - 287, - 842, - 337 - ], - "page_idx": 51, - "id": 700 - }, - { - "type": "text", - "text": "4)人力人员", - "bbox": [ - 147, - 337, - 247, - 351 - ], - "page_idx": 51, - "id": 701 - }, - { - "type": "table", - "img_path": "images/12ee8e09901e962ba0b8dc1875045bd2a76f67664d19242ffc3c9c2216e7cff1.jpg", - "table_caption": [], - "table_footnote": [], - "table_body": "
序号专业人数技能等级备注
1机械专业2高级+中级高级主导系统分析
2自动化专业1中级负责调速器信号检测
", - "bbox": [ - 147, - 350, - 843, - 430 - ], - "page_idx": 51, - "id": 702 - }, - { - "type": "text", - "text": "修理步骤及工艺", - "text_level": 1, - "bbox": [ - 147, - 432, - 275, - 447 - ], - "page_idx": 51, - "id": 703 - }, - { - "type": "text", - "text": "故障特征识别 ", - "bbox": [ - 184, - 451, - 294, - 466 - ], - "page_idx": 51, - "id": 704 - }, - { - "type": "text", - "text": "1)确认现象:主机在恒定指令下,输出功率周期性波动( $\\pm 5 \\%$ 以上),伴随转速摆动;2)排除电网负载突变(如侧推启停)等外部干扰。分系统排查", - "bbox": [ - 144, - 469, - 852, - 541 - ], - "page_idx": 51, - "id": 705 - }, - { - "type": "text", - "text": "1)燃油系统检查", - "bbox": [ - 184, - 544, - 321, - 558 - ], - "page_idx": 51, - "id": 706 - }, - { - "type": "text", - "text": "(1)测燃油黏度:若 $\\mathrm { > } 1 5$ cSt( $1 5 0 \\mathrm { { ‰} }$ ),则加热不足 $\\twoheadrightarrow$ 检查黏度计/加热器;", - "bbox": [ - 189, - 562, - 801, - 577 - ], - "page_idx": 51, - "id": 707 - }, - { - "type": "text", - "text": "(2)检查燃油滤器压差,若 $> 0 . 1 5 \\ \\mathrm { \\ m P a }$ $\\twoheadrightarrow$ 清洗或更换。", - "bbox": [ - 193, - 581, - 630, - 595 - ], - "page_idx": 51, - "id": 708 - }, - { - "type": "text", - "text": "2)调速系统检查", - "bbox": [ - 183, - 600, - 321, - 614 - ], - "page_idx": 51, - "id": 709 - }, - { - "type": "text", - "text": "(1)用测试仪检测调速器输出信号是否滞后或振荡;", - "bbox": [ - 191, - 618, - 589, - 633 - ], - "page_idx": 51, - "id": 710 - }, - { - "type": "text", - "text": "(2)检查伺服阀滤芯是否堵塞(常见原因)。", - "bbox": [ - 194, - 637, - 537, - 651 - ], - "page_idx": 51, - "id": 711 - }, - { - "type": "text", - "text": "3)各缸一致性检查", - "bbox": [ - 183, - 656, - 337, - 670 - ], - "page_idx": 51, - "id": 712 - }, - { - "type": "text", - "text": "(1)对比各缸排温、高压油管脉动,排除单缸供油不稳(可能触发MT019)。针对性处置", - "bbox": [ - 188, - 674, - 781, - 707 - ], - "page_idx": 51, - "id": 713 - }, - { - "type": "text", - "text": "1)若燃油黏度异常 $\\twoheadrightarrow$ 校准黏度控制器,清洗加热器;", - "bbox": [ - 184, - 711, - 610, - 726 - ], - "page_idx": 51, - "id": 714 - }, - { - "type": "text", - "text": "2)若调速器响应迟滞 $\\twoheadrightarrow$ 更换伺服阀滤芯,清洗内部油路;", - "bbox": [ - 183, - 730, - 645, - 744 - ], - "page_idx": 51, - "id": 715 - }, - { - "type": "text", - "text": "验证运行", - "bbox": [ - 184, - 766, - 257, - 781 - ], - "page_idx": 51, - "id": 716 - }, - { - "type": "text", - "text": "1)在 $8 5 \\%$ MCR恒定负荷下运行60分钟; \n2)记录功率波动幅度,要求 $\\leqslant \\pm 2 \\%$ ", - "bbox": [ - 184, - 784, - 489, - 819 - ], - "page_idx": 51, - "id": 717 - }, - { - "type": "text", - "text": "验收标准", - "text_level": 1, - "bbox": [ - 147, - 820, - 223, - 834 - ], - "page_idx": 51, - "id": 718 - }, - { - "type": "text", - "text": "1.主机在恒定负荷指令下,功率波动幅度 $\\leqslant \\pm 2 \\%$ ", - "bbox": [ - 186, - 835, - 569, - 848 - ], - "page_idx": 51, - "id": 719 - }, - { - "type": "text", - "text": "2.转速稳定性 ≤±1 rpm(额定转速下);", - "bbox": [ - 186, - 850, - 509, - 863 - ], - "page_idx": 51, - "id": 720 - }, - { - "type": "text", - "text": "3.燃油黏度控制在设定值 ±1 cSt 范围内", - "bbox": [ - 186, - 864, - 512, - 877 - ], - "page_idx": 51, - "id": 721 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 51, - "id": 722 - }, - { - "type": "text", - "text": "5 器材保障 ", - "text_level": 1, - "bbox": [ - 147, - 96, - 326, - 126 - ], - "page_idx": 52, - "id": 723 - }, - { - "type": "text", - "text": "5.1 保障设施、保障设备(工具)信息汇总表", - "text_level": 1, - "bbox": [ - 147, - 199, - 655, - 224 - ], - "page_idx": 52, - "id": 724 - }, - { - "type": "table", - "img_path": "images/e46ef3132fafcd0925928b0bc87f73eeb582dc166fbbae564979d071423964bb.jpg", - "table_caption": [ - "表5.1 船舶主发动机工具信息汇总表" - ], - "table_footnote": [], - "table_body": "
衣J.1动机工其信总
名称规格/型号生产单位通用/专用体积参考价元)存放位置备注
1液压升降平台HLP-3000OEM 或市场品专用120045085,000主机车间东侧工具架A区用于接近主机上部
2扭矩扳手TB-200N·mOEM 或市场品通用32.51,200工具柜B-02精度±3%
3机油滤清器专用拆装工具OEM-DIESEL-FITOEM专用53.82,500主机备件柜M-07厂家配套
4工业吸油泵VAC-0IL50OEM 或市场品专用25186,800油料间防爆柜防爆型
5激光对中仪SKF TKSA 71SKF专用84.298,000精密仪器室C-01轴承同轴度检测
6塞尺组0.02 -1.00 mm市品通用0.80.6180量具盒D-05精度±0.005mm
7液压拉伸器HYTORCAVANTI-10 /RS-20HYTORC专用302242,000螺栓工具架E区用于地脚螺栓/连杆螺栓
8内径千分尺200-300 mm /40-50mmMitutoyo 等通用21.43,600量具柜F-03校验有效期内
9精密千分表 Mitutoyo 543-791DMitutoyo专用1.20.94,200精密仪器室C-02分辨率0.001mm
10磁力表座Starrett 16BStarrett通用1.51.81,500量具柜F-04带万向关节
名称规格/型号生产单位通用/专用参考价(元)存放位置备注
11V型支撑架Custom-Crank-V3000EM专用8012018,000曲轴检修平台旁承重500kg
12盘车手轮OEM-MAN-BW-PCW0EM专用15125,500主机附件箱G-01原厂配套
13内窥镜GE MentorVisual iQ/iQ-ExGE专用63.575,000探伤设备柜H-02防爆型用手故
14轴承安装导向套0EM-MAN-BW-BG-040EM专用45.23,800轴承装配区I-03防止瓦片移位
15活塞吊装专用常具OEM-MAN-BW-PST-05OEM专用202812,000吊具架J-01带缓冲橡胶夹头
16盛加EFD InductionMinac 16/Minac 10EFD专用453568,000热装工具区K-02±5℃
17铜棒与塑料锤Φ20×300 mm市品通用22.1150普通工具箱L-05用于轻敲装配
18活塞环压缩器OEM-MAN-BW-RCC-060EM专用86.54,200活塞维修台M-03适配350
19环槽清洁刮刀Custom-Piston-Groove-ScraperOEM专用0.50.4320活塞工具盒N-01铜质加
20环口定位夹具Custom-Ring-Aligner0EM专用32.31,800活塞维修台M-04控制环开□相位
21缸套拔出器OEM-MAN-BW-LINER-PULLOEM专用25329,500缸体检修区0-02螺纹顶压式
22液压压装机HYDRA-PRESS-50TOEM 或市品专用600800180,000压装工位P区带压监控
23冷却水腔密封测试仪LeakTest-CT300OEM专用181528,000密封测试台Q-010.3MPa保压
24深度规0-150mm/市品通用10.7600量具柜F-05
名称规格/型号生产单位通用/专用参考价(元)存放位置备注
0-300mm
25放大镜(带LED)5×/10×withscale/light市品通用0.60.3220检验工具盒R-01印痕
26防爆LED手电Streamlight88040Streamlight专用0.40.51,100防爆工具柜S-0124V安全电压
27清洁气枪IndustrialAir Blow Gun市品通用1.20.9180气动工具架T-02压力≤0.5MPa
28排气阀OEM-MAN-BW-VALVE-H0OKOEM专用12166,200阀件吊装区U-01带隔
29红外测温仪Fluke 62 Max+Fluke通用0.80.352,400电子仪表柜V-03测量高温部件
30密封面检测平板Optical Flatx/10市品专用10815,000精密测量台W-01
31便携式阀座床SUNNEN SV-20SUNNEN专用9075130,000阀维修区X-01带角调
32液压阀座压装机HYDRA-SEAT-PRESSOEM专用12018078,000阀维修区X-02过盈配合
33角度规0-90°Protractor市品通用1.51.2300量具柜F-06检查锥角
34喷油器专用拆装扳手OEM-MAN-BW-INJ-WRENCHOEM专用43.62,800喷油器工具箱Y-01防滑
35高压燃压力表0 -20 MPa市品通用0.90.8950仪表校验柜Z-02校验有效期内
36喷油雾化测试台Bosch EPS 815Bosch专用200220220,000喷油器测试室AA-01测开角
37柱塞偶件安装导向套OEM-MAN-BW-PLUNGER-GUIDEOEM专用21.71,600喷油泵维修台AB-02防划伤
38供油定时检测仪AVL 545AVL专用151285,000燃油系统测试区AC-01测喷油始点
39涡轮增Custom-Turbo-0EM专用30040095,000增压器维修带V型
名称规格/型号生产单位通用/专用参考价(元)存放位置备注
压器专用拆装台Bench区AD-01支撑
40动平衡检测仪SchenckBALANCER VSchenck专用500600680,000平衡实验室AE-01G2.5级精度
41高压清洗机Karcher HD7/15-4Karcher通用806532,000清洗站 AF-01压力0-5MPa可调
42管束专用清洗喷头RotatingNozzle 3mmOEM专用0.30.25800清洗配件柜AG-01自旋式
43风压干燥机IndustrialAir Dryer市品通用1209025,000空压站AH-010.6MPa
44泄漏测试装置Air/WaterLeak Tester0EM专用252036,000密封测试台Q-020.4MPa保压
45防爆型扫气箱清洗机人SCB-CLEANBOT-X1OEM专用150130420,000机器人存放区AI-01自动高压水射流
46红外热像仪FLIR T860FLIR专用52.1120,000电气检测室AJ-01检测热点
47可燃气体检测仪 MSA Altair 5XMSA专用10.78,500安全设备柜AK-01多气体复合
48等离子堆焊机PLASMAD 5000OEM专用400350580,000焊接修复区AL-01自动送粉
49热处理Box Furnace800°C0EM专用10001200320,000热处理间 AM-01控温±10℃
50超声波探伤仪Olympus Epoch6500lympus专用63.295,000探伤设备柜H-03检测内部缺陷
51三维扫描仪FARO ArmQuantumFARO专用3025750,000测绘室AN-01修复形貌比对
52主机监控系统(PMS)IntegratedBridge System船厂集成专用1,200,000集控室A0-01读取功率曲线
53调速器性能测试仪Woodward TestBenchWoodward专用180200480,000调速器测试间AP-01检测应滞后
房号名称规格/型号生产单位通用/专用参考价(元)存放位置备注
54燃油黏度计MarconiViscotesterMarconi专用12942,000燃油化验室AQ-01测HFO黏度
55多通道数据记录仪DataTakerDT80DataTaker通用32.418,000数据采集柜AR-01同步录负荷/转速
", - "bbox": [ - 57, - 271, - 942, - 901 - ], - "page_idx": 52, - "id": 725 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 52, - "id": 726 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 58, - 90, - 942, - 904 - ], - "page_idx": 53, - "id": 727 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 915, - 588, - 928 - ], - "page_idx": 53, - "id": 728 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 58, - 92, - 942, - 904 - ], - "page_idx": 54, - "id": 729 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 915, - 588, - 928 - ], - "page_idx": 54, - "id": 730 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 58, - 89, - 942, - 898 - ], - "page_idx": 55, - "id": 731 - }, - { - "type": "discarded", - "text": "PAGE $\\setminus ^ { * }$ MERGEFORMAT36 ", - "bbox": [ - 410, - 915, - 588, - 928 - ], - "page_idx": 55, - "id": 732 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 58, - 90, - 942, - 255 - ], - "page_idx": 56, - "id": 733 - }, - { - "type": "text", - "text": "5.2 消耗材料信息汇总表", - "text_level": 1, - "bbox": [ - 149, - 290, - 443, - 315 - ], - "page_idx": 56, - "id": 734 - }, - { - "type": "table", - "img_path": "images/3167312fb32cb036b229886d618108a21084e655a0a75bc830aca8be08918108.jpg", - "table_caption": [ - "表5.2 船舶主发动机消耗材料信息汇总表" - ], - "table_footnote": [], - "table_body": "
名称牌号/品级/规格生产单位备注
1柴油机专用润滑油Shell Mysella S5 N80Shell符合MAN 97101标准
2无纺布抹布Industrial Grade市场品不掉屑
3清洗剂CRC Brakleen /Brulin815GD / CRC Carbon CleanProCRC/Brulin多用途清洁
4主机油滤芯MAN B&W 5L35MC-FIL-01MAN原厂件
5机油放油螺塞密封圈Viton Φ22×2.5市场品耐高温氟橡胶
6清洁酒精AR Grade / ≥99.5%市场品
7防锈纸VCI-200市场品
8无绒擦拭布Kimwipe EX-LKimberly-Clark防刮伤
9轴承装配润滑脂Kluber Isoflex LDS 18Special AKluber仅涂瓦背
10螺纹锁固胶Loctite 2701Henkel用于螺栓(如适用)
11高温装配润滑脂Molycote G-1052Dow Corning活塞销/螺纹
12积碳清洗剂CRC Carbon Clean ProCRC环保型
13防锈油CRC 3-36CRC临时防护
14二硫化钼润滑膏Molycote BR2 PlusDow Corning涂活塞环外圆
15缸套润滑机油Shell Mysella S5 N80Shell同主滑油
16耐油标记笔Markal Oil-ResistantMarkal标记环开口
17耐高温标记笔Markal 900° FMarkal高温环境
18装配润滑脂Kluber Isoflex LDS 18Kluber缸套外壁
Special A
19密封胶Loctite 518 / 577Henkel水腔/泵体法兰
20高温镍基焊条ENiCrFe-3市场品阀座焊接
21研磨膏 (细)Clover Leaf GreenClover阀座研配
22清洁柴油ISO 4020 Grade A市场品冲洗油道
23高压泵专用润滑油Shell Tellus S4 VX 32Shell偶件润滑
24中性清洗剂Alconox DetojetAlconoxpH=9.5,环保
25软化水Deionized Water市场品配清洗液
26生物降解清洗剂Envirox SC-90Envirox清除碳化油泥
27耐高温防火毯Fiberglass Mat 1200° C市场品局部隔热
28镍基合金焊粉INCONEL 625Special Metals堆焊修复
29渗透探伤剂Magnaflux ZL-27AMagnafluxPT检测裂纹
30保温棉Ceramic Fiber Blanket市场品焊后缓冷
31标准测试燃油ISO 8217 RMG380市场品稳定测试用
", - "bbox": [ - 136, - 369, - 862, - 901 - ], - "page_idx": 56, - "id": 735 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 56, - "id": 736 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 136, - 91, - 862, - 450 - ], - "page_idx": 57, - "id": 737 - }, - { - "type": "text", - "text": "6 维修安全防护及注意事项汇总表", - "text_level": 1, - "bbox": [ - 146, - 473, - 707, - 505 - ], - "page_idx": 57, - "id": 738 - }, - { - "type": "text", - "text": "以表格的形式汇总 3.3节中该设备维修项目表中各维修项目开展期间的安全防护要求及安全注意事项。", - "bbox": [ - 151, - 570, - 848, - 613 - ], - "page_idx": 57, - "id": 739 - }, - { - "type": "text", - "text": "6.1 安全防护", - "text_level": 1, - "bbox": [ - 149, - 627, - 309, - 650 - ], - "page_idx": 57, - "id": 740 - }, - { - "type": "text", - "text": "将3.3节中该设备维修项目表中各维修项目开展期间的安全防护要求汇总后填写下表6.1中。主要反映该维修项目的实施过程中应开展的安全防护要求,如需做好的安全防护措施及不同工作状态下应在设备周围或设备上悬挂的标志。", - "bbox": [ - 147, - 688, - 858, - 756 - ], - "page_idx": 57, - "id": 741 - }, - { - "type": "table", - "img_path": "images/a3e22e4d09d116e45791e06d0b2e111fb2f032b62e9a73d025595d2520521a98.jpg", - "table_caption": [ - "表6.1 船舶主发动机维修期间安全防护要求" - ], - "table_footnote": [], - "table_body": "
序号维修项目安全防护要求备注
1MT001保养机座与机架组件1.主机控制面板悬挂“禁止启动”红色警示牌2.机油排放区铺设防滑吸油垫并设围挡防止误启与油污扩散
2MT002检查主轴承座1.锁定曲轴转动机构,飞轮加装机械止动销防止转动伤人
2.设置激光对中仪警戒区
3MT003 检测曲轴跳动1.盘车机构加装机械锁止装置,挂“禁止盘车”牌2.设置防滑平台,千分表支架稳固防止测量中曲轴转动
4MT004 更换连杆大端轴承1.锁定曲轴位置,气缸顶部加盖防异物盖板2.吊装时设警戒区防止异物落入/坠落
5MT005 更换连杆小端轴承1.曲轴输出端加装机械止动装置2.吊装活塞总成下方设软质承接垫防止活塞坠落损坏
6MT006 拆检活塞头1.隔离燃油/滑油/冷却水系统,LOTO挂牌上锁2.缸内作业使用24V防爆照明防爆防误启
7MT007/008更换活塞环1.铺设防滑垫,设工具防坠网2.气缸口加盖防护罩防止工具/异物落入
8MT009 检测缸套磨损1.悬挂“禁止盘车”和“禁止启动”双警示牌2.缸口设防坠落围栏,工具系防坠绳高空/旋转风险
9MT010 更换气缸套1.吊装缸套用专用吊耳,下方设软质平台2.缸体水腔加盖防水布防水防砸
10MT011 检查排气阀杆1.隔离启动空气系统,阀杆驱动处加机械锁2.设“高温部件”警示标识防高温/误动作
11MT012 更换排气阀座1.气缸内部完全隔离并加盖防异物盖2.便携镗床接地,设警戒线防金属屑/电击
12MT013/019 更换/排除喷油器1.泄放高压燃油压力,燃油泵出口加盲板2.高压油管区挂“高压危险”牌,禁明火防燃防爆
13MT014 更换柱塞偶件隔离燃油系统,LOTO挂牌上锁防燃油泄漏
14MT015 更换增压器轴承1.隔离进排气管路,加装盲板2.转子吊装用平衡吊具,设软垫防气体倒流/坠落
15MT016 清洗空冷器1.隔离海水/淡水侧并排空2.高压水枪作业戴面罩及防水服防高压水伤人
16MT017 修复连杆异常磨损1.着火后停机、断油、启动COz系统2.进入扫气箱前办受限空间许可,检测气体防复燃/室息
17MT018 修复活塞烧蚀1.作业区设防火挡板,配干粉灭火器≥2具2.焊接需办理动火许可证防火灾
18MT020 排除功率波动1.主机切至“本地手动”模式2.数据接线由持证电工完成,符合防爆规范防飞车/电火花
", - "bbox": [ - 139, - 781, - 860, - 902 - ], - "page_idx": 57, - "id": 742 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 588, - 928 - ], - "page_idx": 57, - "id": 743 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 139, - 97, - 860, - 881 - ], - "page_idx": 58, - "id": 744 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 411, - 916, - 586, - 928 - ], - "page_idx": 58, - "id": 745 - }, - { - "type": "text", - "text": "6.2 注意事项", - "text_level": 1, - "bbox": [ - 149, - 98, - 304, - 122 - ], - "page_idx": 59, - "id": 746 - }, - { - "type": "text", - "text": "将3.3节中该设备维修项目表中各维修项目开展期间的安全注意事项汇总后填写下表6.2中。主要反映该维修项目的实施过程中应注意的安全事项。", - "bbox": [ - 149, - 160, - 850, - 204 - ], - "page_idx": 59, - "id": 747 - }, - { - "type": "table", - "img_path": "images/fd7a1088afb8e968f2ba681807dad6e6b7df3d4acfe2abdf4a3875da06a7dda6.jpg", - "table_caption": [ - "表6.2 船舶主发动机维修期间注意事项" - ], - "table_footnote": [], - "table_body": "
序号维修项目注意事项备注
1MT0011.保养前确认主机停机≥2小时,无残余压力与高温2.排放热机油时戴耐高温手套及护目镜防烫伤
2MT0021.禁止主机运转或盘车未锁定时测量2.使用塞尺时手指不得置于结合面间防夹伤
3MT0031.曲轴未完全支撑不得测量2.磁力表座吸附面须清洁无油防滑脱
4MT0041.禁用锤击拆卸轴承盖2.新轴承瓦背无毛刺、涂层完整防损伤
5MT0051.未拆冷却水管不得强行抽活塞2.热装时戴隔热面罩及手套防烫/变形
6MT0061.抽活塞防活塞环弹出(用环压缩器)2.检查燃烧面戴防颗粒口罩防吸入积碳
7MT007/0081.禁用螺丝刀撬活塞环2.确认“TOP”标记朝上;刮油环胀圈接口错开180°防划伤/装反
8MT0091.冷却水未排空不得测量2.手不得置于千分尺与缸壁间防夹伤
9MT0101.禁用火焰加热缸体2.压装时人员不得站压机正下方防裂纹/砸伤
10MT0111.禁用砂轮打磨阀杆密封面2.戴耐高温手套及护目镜防碎屑/热辐射
11MT0121.缸盖未冷却不得作业2.新阀座安装后须PT/UT无损检测防热应力/裂纹
12MT013/0191.禁用金属工具敲击喷油嘴2.新偶件拆封后立即安装防卡死/污染
13MT0141.禁止互换不同泵体的柱塞偶件2.确保斜槽与齿条合正确防相位错误
14MT0151.禁用手直接转增压器转子2.新轴承无油脂污染或保持架变形防误判/失效
15MT0161.禁用酸性清洗剂2.清洗压力≤5MPa防腐蚀/翅片倒伏
16MT0171.扫气箱>60℃禁用电动工具2.油泥清理时持续喷雾降温防自燃
17MT0181.深度裂纹>3m不得堆焊,须更换2.热处理后必须缓冷防二次裂纹
18MT0201.功率剧烈波动时禁止维持高负荷防飞车
2.调整调速器须双人确认
", - "bbox": [ - 137, - 224, - 860, - 901 - ], - "page_idx": 59, - "id": 748 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 588, - 928 - ], - "page_idx": 59, - "id": 749 - }, - { - "type": "table", - "img_path": "", - "table_caption": [], - "table_footnote": [], - "bbox": [ - 139, - 90, - 860, - 135 - ], - "page_idx": 60, - "id": 750 - }, - { - "type": "discarded", - "text": "PAGE \\\\* MERGEFORMAT36 ", - "bbox": [ - 410, - 916, - 586, - 928 - ], - "page_idx": 60, - "id": 751 - } -] \ No newline at end of file diff --git a/__pycache__/app copy.cpython-311.pyc b/__pycache__/app copy.cpython-311.pyc deleted file mode 100644 index 01bb8fa..0000000 Binary files a/__pycache__/app copy.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc deleted file mode 100644 index 5dcf630..0000000 Binary files a/__pycache__/app.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000..1cb5ae1 Binary files /dev/null and b/__pycache__/app.cpython-312.pyc differ diff --git a/__pycache__/app_v2.cpython-311.pyc b/__pycache__/app_v2.cpython-311.pyc deleted file mode 100644 index 9e94045..0000000 Binary files a/__pycache__/app_v2.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/checkpointer_config.cpython-311.pyc b/__pycache__/checkpointer_config.cpython-311.pyc deleted file mode 100644 index bea7a07..0000000 Binary files a/__pycache__/checkpointer_config.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/checkpointer_config.cpython-312.pyc b/__pycache__/checkpointer_config.cpython-312.pyc new file mode 100644 index 0000000..f3aebef Binary files /dev/null and b/__pycache__/checkpointer_config.cpython-312.pyc differ diff --git a/__pycache__/chunk_text.cpython-311.pyc b/__pycache__/chunk_text.cpython-311.pyc deleted file mode 100644 index cb20ad3..0000000 Binary files a/__pycache__/chunk_text.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/chunk_text.cpython-312.pyc b/__pycache__/chunk_text.cpython-312.pyc new file mode 100644 index 0000000..cc86682 Binary files /dev/null and b/__pycache__/chunk_text.cpython-312.pyc differ diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc deleted file mode 100644 index c331b81..0000000 Binary files a/__pycache__/config.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/config.cpython-312.pyc b/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000..b612c7a Binary files /dev/null and b/__pycache__/config.cpython-312.pyc differ diff --git a/__pycache__/doc2pdf.cpython-311.pyc b/__pycache__/doc2pdf.cpython-311.pyc deleted file mode 100644 index 3fad918..0000000 Binary files a/__pycache__/doc2pdf.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/doc2pdf.cpython-312.pyc b/__pycache__/doc2pdf.cpython-312.pyc new file mode 100644 index 0000000..22333ba Binary files /dev/null and b/__pycache__/doc2pdf.cpython-312.pyc differ diff --git a/__pycache__/documents_prompt.cpython-311.pyc b/__pycache__/documents_prompt.cpython-312.pyc similarity index 95% rename from __pycache__/documents_prompt.cpython-311.pyc rename to __pycache__/documents_prompt.cpython-312.pyc index 3db2df7..5be96eb 100644 Binary files a/__pycache__/documents_prompt.cpython-311.pyc and b/__pycache__/documents_prompt.cpython-312.pyc differ diff --git a/__pycache__/documents_prompt.cpython-313.pyc b/__pycache__/documents_prompt.cpython-313.pyc new file mode 100644 index 0000000..866aea5 Binary files /dev/null and b/__pycache__/documents_prompt.cpython-313.pyc differ diff --git a/__pycache__/filename_proceess_and_kgquery.cpython-311.pyc b/__pycache__/filename_proceess_and_kgquery.cpython-311.pyc deleted file mode 100644 index 5b78b12..0000000 Binary files a/__pycache__/filename_proceess_and_kgquery.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/fileparse_util.cpython-311.pyc b/__pycache__/fileparse_util.cpython-311.pyc deleted file mode 100644 index 92d8822..0000000 Binary files a/__pycache__/fileparse_util.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/fileparse_util.cpython-312.pyc b/__pycache__/fileparse_util.cpython-312.pyc new file mode 100644 index 0000000..54878be Binary files /dev/null and b/__pycache__/fileparse_util.cpython-312.pyc differ diff --git a/__pycache__/main_agent.cpython-311.pyc b/__pycache__/main_agent.cpython-311.pyc deleted file mode 100644 index 459ff54..0000000 Binary files a/__pycache__/main_agent.cpython-311.pyc and /dev/null differ diff --git a/__pycache__/main_agent.cpython-312.pyc b/__pycache__/main_agent.cpython-312.pyc new file mode 100644 index 0000000..92e82cf Binary files /dev/null and b/__pycache__/main_agent.cpython-312.pyc differ diff --git a/__pycache__/prompts.cpython-311.pyc b/__pycache__/prompts.cpython-312.pyc similarity index 98% rename from __pycache__/prompts.cpython-311.pyc rename to __pycache__/prompts.cpython-312.pyc index 9737151..484628f 100644 Binary files a/__pycache__/prompts.cpython-311.pyc and b/__pycache__/prompts.cpython-312.pyc differ diff --git a/__pycache__/workflow_registry.cpython-311.pyc b/__pycache__/workflow_registry.cpython-312.pyc similarity index 92% rename from __pycache__/workflow_registry.cpython-311.pyc rename to __pycache__/workflow_registry.cpython-312.pyc index 4b28ff8..3ca32f4 100644 Binary files a/__pycache__/workflow_registry.cpython-311.pyc and b/__pycache__/workflow_registry.cpython-312.pyc differ diff --git a/apitest.py b/apitest.py deleted file mode 100644 index 94bc713..0000000 --- a/apitest.py +++ /dev/null @@ -1,18 +0,0 @@ -import base64 -import requests - -url = "http://192.168.0.46:59085/split_image" -image_path = r"E:\ZKYNLP\aidocproject\audiotransaction\gwdoc\船舶图片.png" - -with open(image_path, "rb") as f: - image_base64 = base64.b64encode(f.read()).decode("utf-8") - -payload = { - "content": "船舶主发动机为低速二冲程船用推进柴油机,是船舶推进系统的核心动力装置,其主要功能是将燃油化学能转化为机械能,通过曲轴输出转矩,驱动推进轴系和螺旋桨,实现船舶航行。![图片](/api/v1/knowledge/files/images/船舶图片.png)", - "filename": "船舶图片.png", - "image_base64": image_base64, -} - -resp = requests.post(url, json=payload, timeout=120) -print(resp.status_code) -print(resp.json()) \ No newline at end of file diff --git a/app.py b/app.py index aaa2fdf..b2416cb 100644 --- a/app.py +++ b/app.py @@ -15,7 +15,7 @@ try: except ImportError: from langchain.prompts import FewShotPromptTemplate, PromptTemplate from openai.types.chat import ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionMessageParam -from chunk_text import get_chunk_bbox, split_text_preserve_sentences, data_replace, chunk_check,merge_short_slices,find_and_read_content_list,process_pdf_file,process_other_file,safe_original_filename,image_base64_to_data_url,extract_image_text,prepare_split_image +from chunk_text import get_chunk_bbox, split_text_preserve_sentences, data_replace, chunk_check,merge_short_slices,find_and_read_content_list,process_pdf_file,process_other_file from fastapi.responses import JSONResponse, StreamingResponse import requests from pathlib import PurePath, Path as PathLib @@ -63,20 +63,14 @@ from doc2pdf import Doc2PDF from workflow_registry import WORKFLOW_CONFIG, VALID_ROUTE_FLAGS from main_agent import extract_conversation_title from workflows.history_manager import filter_image_urls, preprocess_from_request -from config import VLM_CONCURRENCY, set_request_user_config +from config import set_request_user_config from checkpointer_config import ( CheckpointerManager, checkpointer_manager ) app = FastAPI(max_request_size=1024 * 1024 * 10) -# =============== PDF 文件目录配置 =============== -# 创建 PDF 文件目录(用于存储生成的 PDF 等文件) -PDF_DIR = os.path.join(os.path.dirname(__file__), "created_pdf") -# 创建 word 文件目录(用于存储生成的 word 等文件) -WORD_DIR = os.path.join(os.path.dirname(__file__), "created_word") -os.makedirs(PDF_DIR, exist_ok=True) -VLM_SEMAPHORE = asyncio.Semaphore(max(1, VLM_CONCURRENCY)) -converter = None + +converter = Doc2PDF() DATA_DIR = "/app/files" load_dotenv() @@ -99,13 +93,6 @@ STREAM_RESPONSE_HEADERS = { } -def get_doc_converter() -> Doc2PDF: - global converter - if converter is None: - converter = Doc2PDF() - return converter - - def llm_text_stream_response(content) -> StreamingResponse: return StreamingResponse( content, @@ -117,16 +104,20 @@ def llm_text_stream_response(content) -> StreamingResponse: @app.on_event("startup") async def startup_event(): """应用启动时初始化""" - try: - await checkpointer_manager.setup() - # 初始化智能体使用统计表 - from tools.agent_usage_statistics import init_agent_usage_table - await init_agent_usage_table() - logger.info("应用启动完成,PostgreSQL Checkpointer 已配置") - except Exception as e: - logger.warning(f"Checkpointer 初始化失败,非 Agent 接口仍可使用: {e}") + await checkpointer_manager.setup() + # 初始化智能体使用统计表 + from tools.agent_usage_statistics import init_agent_usage_table + await init_agent_usage_table() + logger.info("应用启动完成,PostgreSQL Checkpointer 已配置") +# =============== PDF 文件目录配置 =============== +# 创建 PDF 文件目录(用于存储生成的 PDF 等文件) +PDF_DIR = os.path.join(os.path.dirname(__file__), "created_pdf") +# 创建 word 文件目录(用于存储生成的 word 等文件) +WORD_DIR = os.path.join(os.path.dirname(__file__), "created_word") +os.makedirs(PDF_DIR, exist_ok=True) + class RewriteRequest(BaseModel): rewrite_type: Optional[str] = None content: Optional[str] = None @@ -1518,75 +1509,6 @@ class RequestWrapper(BaseModel): pdf_contents: List[PdfContentItem] -class Base64ImageRequest(BaseModel): - content: Optional[str] = Field( - None, - description="Optional text around the image, for example: 图3.1 船舶主发动机组成图(images/test.jpg)", - ) - filename: str = Field(..., description="Original image filename, for example test.png") - image_base64: str = Field(..., description="Base64 image content, with or without data:image/... prefix") - - -async def analyze_image_with_vlm(image_bytes: bytes, suffix: str) -> str: - image_url = image_base64_to_data_url(image_bytes, suffix) - async with VLM_SEMAPHORE: - return await model_api.OpenaiAPI.open_api_vl_without_thinking(image_url) - - -@app.post("/split_image") -async def image_base64(request_data: Base64ImageRequest): - filename = safe_original_filename(request_data.filename) - suffix = PathLib(filename).suffix.lower() - if suffix not in {".jpg", ".jpeg", ".png", ".bmp", ".webp", ".gif", ".tif", ".tiff"}: - raise HTTPException(status_code=400, detail="Unsupported image type") - - image_bytes, processed_suffix = prepare_split_image(request_data.image_base64, suffix) - if not image_bytes: - raise HTTPException(status_code=400, detail="decoded image is empty") - - temp_path = None - try: - with tempfile.NamedTemporaryFile(delete=False, suffix=processed_suffix) as tmp: - tmp.write(image_bytes) - temp_path = PathLib(tmp.name) - - ocr_data = await extract_image_text(temp_path) - try: - temp_path.unlink() - except Exception as e: - logger.warning(f"Failed to delete temp image {temp_path}: {e}") - finally: - temp_path = None - - content = (request_data.content or "").strip() - ocr_full_text = (ocr_data.get("full_text") or "").strip() - - if not content and not ocr_full_text: - vlm_text = await analyze_image_with_vlm(image_bytes, processed_suffix) - image_content = "图片文本描述为:" + (vlm_text or "").strip() - elif content and ocr_full_text: - image_content = f"图片上下文内容为:{content}, {ocr_full_text}" - elif content: - image_content = "图片上下文内容为:" + content - else: - image_content = ocr_full_text - image_content = "图片文件名为:" + filename + ",图片相关内容为:" + image_content - return JSONResponse( - { - "code": 200, - "message": "ok", - "data": { - "image_content": image_content, - "filename": filename, - }, - } - ) - finally: - if temp_path and temp_path.exists(): - try: - temp_path.unlink() - except Exception as e: - logger.warning(f"Failed to delete temp image {temp_path}: {e}") @app.post("/split_content_list") @@ -1668,7 +1590,7 @@ async def split_result( logger.info(f"转换 DOCX -> PDF: {filename}") # 执行转换 - get_doc_converter().convert(str(temp_input_path), output_dir=str(DATA_DIR)) + converter.convert(str(temp_input_path), output_dir=str(DATA_DIR)) # ? 使用临时文件的基础名查找 PDF temp_base_name = temp_input_path.stem # 如 tmp2bb0l4cn diff --git a/app_v2.py b/app_v2.py deleted file mode 100644 index 526700f..0000000 --- a/app_v2.py +++ /dev/null @@ -1,2994 +0,0 @@ -from filename_proceess_and_kgquery import build_graph_from_paths, fetch_graph_sample, node_to_json, rel_to_json -from graph_search.operation_graph_search import operation_graph_search -from graph_search.fault_graph_search import fault_graph_reason_and_projects -from contextlib import asynccontextmanager -from langchain_community.graphs import Neo4jGraph -from neo4j import GraphDatabase -from neo4j.exceptions import Neo4jError -from fastapi.concurrency import run_in_threadpool -from io import BytesIO -import aiofiles -import hashlib -import logging -import random -import os -import re -import tempfile -import mimetypes -import time -import asyncio -from fastapi import FastAPI, File, Path, UploadFile, HTTPException, Form, Request, Header, Body, BackgroundTasks -from fastapi.responses import JSONResponse, StreamingResponse -from modelsAPI.model_api import OpenaiAPI -from fastapi.middleware.cors import CORSMiddleware -from pydantic import BaseModel, Field -from dotenv import load_dotenv -from pathlib import PurePath, Path as PathLib -import httpx -import pdfplumber -from typing import List, Optional, Dict -from collections import defaultdict -from fuzzywuzzy import fuzz, process -from collections import defaultdict, Counter -from kg_build.filter_node_relation import filter_node_relationship -from kg_build.kg_save import MilitaryKnowledgeGraph -from kgbuild.table_html_extract import extract_operation_tables, extract_repair_tables_keep_first, extract_tables -from kgbuild.entity_rela_reset import create_extraction_prompt -from filename_proceess_and_kgquery import get_entity,build_tree -from typing import List, Dict, Optional, Union, Any, Tuple -from pydantic import BaseModel -from dataprocess import _split_markdown -import uuid -import json -from fileparse_util import process_document -# import hanlp -from itertools import groupby -import requests -from datetime import datetime -from excel_process import transform_excel_json, read_excel_with_merged_cells, dataframe_to_row_json, json_to_markdown -import traceback -import signal -import threading -from multiprocessing import Process, Queue -import asyncio -from fastapi.staticfiles import StaticFiles -from extract_text_node_relation import get_md_node_relation, check_filename_ocr, process_file_content -from concurrent.futures import ThreadPoolExecutor -import base64 -from extract_excel_node_relation import get_excel_node_relation -from doc2pdf import Doc2PDF -from chunk_text import get_chunk_bbox, split_text_preserve_sentences, data_replace, chunk_check,merge_short_slices,find_and_read_content_list,process_pdf_file,process_other_file,safe_original_filename,image_base64_to_data_url,extract_image_text,prepare_split_image -from filename_proceess_and_kgquery import get_entity -from kg_build.extract_filtertext import get_filtertext_node_relation -import os -import logging -import sys -import asyncio -from time import sleep -from graph_search.Hybrid_graphsearch import ( - retrieve_entities, - query_with_cypher, - fetch_relations_among_results, - format_relations, - LocalBgeM3Embeddings, -) -from neo4j import AsyncGraphDatabase, GraphDatabase -from graph_search.cypher_excute import excute_cypher -if sys.platform == "win32": - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) -from contextlib import asynccontextmanager -import mimetypes -from default_ontology_config import ( - ONTOLOGY as ontology, - ONTOLOGY_DESCRIPTION as Ontology_DESCRIPTION, - NODE_TYPES as node_types, - RELATIONSHIPS as relationships, - RELATIONSHIP_TYPES as relationship_types, - # 也可以导入便捷函数 - get_ontology_config, - get_ontology_list, - get_ontology_description, - get_node_types, - get_relationships, - get_relationship_types, -) -from config import NEO4J_CONFIG,URL,API_URLS,API_OTHER_URLS,VLM_CONCURRENCY -converter = Doc2PDF() -DATA_DIR = "/app/files" -# ================== 全局资源容器 ================== -# 用一个字典持有重资源,避免每次请求都重建 -_resources: Dict[str, Any] = { - "sync_driver": None, - "async_driver": None, - "embedder": None, -} - -# 图谱检索和索引生成 -try: - from graph_search.graph_service import GraphService - from neo4j_indexing import build_hybrid_indexes - INDEXING_AVAILABLE = True - GRAPH_AVAILABLE = True -except ImportError as e: - INDEXING_AVAILABLE = False - GRAPH_AVAILABLE = False - - -kg_running_tasks: Dict[str, dict] = {} -_neo4j_indexing_lock = asyncio.Lock() - - -def setup_logging(): - fmt = "%(asctime)s - %(levelname)s - %(name)s - %(message)s" - handlers = [ - logging.StreamHandler(), - logging.FileHandler("app.log", encoding="utf-8"), - ] - logging.basicConfig(level=logging.INFO, format=fmt, handlers=handlers, force=True) - logging.disable(logging.NOTSET) - for name in list(logging.root.manager.loggerDict.keys()): - lg = logging.getLogger(name) - lg.disabled = False - lg.setLevel(logging.NOTSET) # ← 加这行,强制清除所有子 logger 的独立 level - for name in ("uvicorn", "uvicorn.error", "uvicorn.access"): - uv_logger = logging.getLogger(name) - uv_logger.handlers = list(handlers) - uv_logger.propagate = False - -@asynccontextmanager -async def lifespan(app): - setup_logging() - """应用启动时初始化驱动和 embedder,关闭时释放。""" - logger.info("[lifespan] 初始化 Neo4j 驱动与 embedder ...") - - # 同步驱动(HybridCypherRetriever 用) - _resources["sync_driver"] = GraphDatabase.driver(NEO4J_URI, auth=("neo4j", "zdht123@")) - - # 异步驱动(fulltext 检索 + Cypher 执行用) - _resources["async_driver"] = AsyncGraphDatabase.driver(NEO4J_URI, auth=("neo4j", "zdht123@")) - - # embedder - _resources["embedder"] = LocalBgeM3Embeddings( - base_url=os.getenv("LOCAL_EMBEDDING_BASE"), - api_key=os.getenv("LOCAL_API_KEY"), - ) - - logger.info("[lifespan] 初始化完成") - try: - yield - finally: - logger.info("[lifespan] 释放资源 ...") - if _resources["sync_driver"] is not None: - _resources["sync_driver"].close() - if _resources["async_driver"] is not None: - await _resources["async_driver"].close() - logger.info("[lifespan] 资源已释放") - yield - - -app = FastAPI(max_request_size=1024 * 1024 * 10, lifespan=lifespan) -VLM_SEMAPHORE = asyncio.Semaphore(max(1, VLM_CONCURRENCY)) - -setup_logging() -logger = logging.getLogger(__name__) - -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], # Allow all origins - allow_credentials=True, - allow_methods=["*"], # Allow all HTTP methods - allow_headers=["*"], # Allow all headers -) - - - - - -app.mount("/upload", StaticFiles(directory="/app/files/uploads_v1"), name="upload") -app.mount("/files", StaticFiles(directory="/app/files"), name="files") - - -""" -图查询接口 -""" - -load_dotenv() -# ===== 本地 Neo4j 强制配置 ===== -# NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687") -# NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687") -NEO4J_URI = NEO4J_CONFIG["uri"] -NEO4J_USER = NEO4J_CONFIG["username"] -NEO4J_PASSWORD = NEO4J_CONFIG["password"] # 不设默认值,强制要求提供 -NEO4J_DATABASE =NEO4J_CONFIG["database"] -indexing_url = URL['indexing_url'] # 根据实际部署调整 -PREFIX_URL = URL['prefix_url'] -API_URLS = API_URLS -API_other_URLS = API_OTHER_URLS - -_api_url_inflight = [0] * len(API_URLS) -_api_url_lock = threading.Lock() - - -def get_api_url(task_id: str = "") -> tuple: - """返回 (analyze_url, contentlist_url),选当前 inflight 最少的实例。""" - with _api_url_lock: - idx = _api_url_inflight.index(min(_api_url_inflight)) - _api_url_inflight[idx] += 1 - base = API_URLS[idx] - return base, base.replace("/analyze-pdf", "/analyze-otherfile") - - -def release_api_url(url: str): - with _api_url_lock: - if url in API_URLS: - idx = API_URLS.index(url) - _api_url_inflight[idx] = max(0, _api_url_inflight[idx] - 1) - - -# 可选:如果密码未设置,抛出明确错误 -if NEO4J_PASSWORD is None: - raise ValueError("Environment variable 'NEO4J_PASSWORD' is required.") - -driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD), database=NEO4J_DATABASE) - -DEFAULT_ONTOLOGY: list = ontology - -DEFAULT_ONTOLOGY_DESCRIPTION: dict = Ontology_DESCRIPTION - -DEFAULT_NODE_TYPES: dict = node_types - -DEFAULT_RELATIONSHIPS: list = relationships - -DEFAULT_RELATIONSHIP_TYPES: dict = relationship_types - - -# ============================================================ -# 2. 合并工具函数 -# 规则: -# - dict → 以默认值为底,用户值 key 已存在则合并 value list; -# key 不存在则直接新增 -# ============================================================ - - -def _merge_list(default: list, user: list | None) -> list: - """去重合并两个列表,保持默认顺序,用户新增项追加到末尾。""" - if not user: - return list(default) - merged = list(default) - for item in user: - if item not in merged: - merged.append(item) - return merged - - -def _merge_dict_of_lists(default: dict, user: dict | None) -> dict: - """ - 合并两个 {key: list} 结构的字典。 - - key 存在于 default:合并 list(去重),用户值追加到末尾 - - key 只存在于 user:直接新增 - """ - if not user: - return {k: list(v) for k, v in default.items()} - merged = {k: list(v) for k, v in default.items()} - for key, val in user.items(): - if key in merged: - for item in val: - if item not in merged[key]: - merged[key].append(item) - else: - merged[key] = list(val) - return merged - - -def _load_registry_config(): - """每次调用都从 entity_registry.json 读取最新注册的实体类型,无需重启生效。""" - try: - import importlib - import entity_registry as _reg - - importlib.reload(_reg) # 强制重新读文件 - return _reg.get_ontology_list(), _reg.get_ontology_description(), _reg.get_node_types() - except Exception: - return [], {}, {} - - -def build_kg_config( - user_ontology: list | None, - user_ontology_desc: dict | None, - user_relationships: list | None, - user_node_types: dict | None, - user_relationship_types: dict | None, -) -> dict: - """ - 将用户传入的参数与全局默认值合并,返回最终执行配置。 - 任何字段未传(None)时直接使用默认值;传了则合并。 - registry 中的新类型每次请求动态合并,无需重启。 - """ - reg_list, reg_desc, reg_nodes = _load_registry_config() - ontology = _merge_list(DEFAULT_ONTOLOGY, reg_list) - ontology_desc = {**reg_desc, **DEFAULT_ONTOLOGY_DESCRIPTION} # 手写配置优先 - node_types = {**reg_nodes, **DEFAULT_NODE_TYPES} # 手写配置优先 - - return { - "ontology": _merge_list(ontology, user_ontology), - "ontology_description": _merge_dict_of_lists(ontology_desc, user_ontology_desc), - "relationships": _merge_list(DEFAULT_RELATIONSHIPS, user_relationships), - "node_types": _merge_dict_of_lists(node_types, user_node_types), - "relationship_types": _merge_dict_of_lists(DEFAULT_RELATIONSHIP_TYPES, user_relationship_types), - } - - -# ============================================================ -# 3. 修改后的 Pydantic 模型 -# 所有字段改为 Optional(默认 None),表示"用户未传" -# 真正的默认值由 build_kg_config() 在运行时合并产生 -# ============================================================ - - -class FileContent(BaseModel): - """单个文件""" - - file_name: str - - # 修改:改为可选,默认为空字符串 - markdown_content: str = Field(default="", description="Markdown格式的内容") - - # 修改:改为可选,默认为空列表 - # 注意:List[Dict[str, Any]] 不能直接赋值 default=[],需要用 Field 或 default_factory 防止引用共享 - content_middle: List[Dict[str, Any]] = Field(default_factory=list, description="中间处理结果") - file_base64: str = Field(default="", description="文件内容的Base64编码字符串", validate_default=True) - - -class KGRequest(BaseModel): - task_id: str - files: Union[FileContent, List[FileContent]] - - # 全部改为 Optional[...] = None,不再在模型层携带默认值 - ontology: Optional[List[str]] = None - Ontology_DESCRIPTION: Optional[Dict[str, List[str]]] = None - relationships: Optional[List[str]] = None - node_types: Optional[Dict[str, List[str]]] = None - relationship_types: Optional[Dict[str, List[str]]] = None - - -class FileContentReset(BaseModel): - """单个文件""" - - file_name: str # 保留文件名(可用于日志或调试) - markdown_content: str - - -class resetRequest(BaseModel): - files: Union[FileContentReset, List[FileContentReset]] - - ontology: Optional[List[str]] = None - Ontology_DESCRIPTION: Optional[Dict[str, List[str]]] = None - relationships: Optional[List[str]] = None - node_types: Optional[Dict[str, List[str]]] = None - relationship_types: Optional[Dict[str, List[str]]] = None - - -def clear_database(): - graph = Neo4jGraph( - refresh_schema=False, url=NEO4J_URI, username=NEO4J_USER, password=NEO4J_PASSWORD, database=NEO4J_DATABASE - ) - # 清空数据库内容 - graph.query("MATCH (n) DETACH DELETE n") - - -# ========================= -# 接口:head / tail / 查询,并返回最短路径。node+depth查询 -# ======================== - - -def add_node_style(node): - node_type = node.get("labels", []) - if node_type and len(node_type) > 0: - node_type = node_type[0] - else: - node_type = "" - - if node_type == "舰艇": - node["color"] = "#F89A64" - node["size"] = 86 - elif node_type == "系统": - node["color"] = "#C25C21" - node["size"] = 86 - elif node_type == "子系统": - node["color"] = "#7D2D00" - node["size"] = 86 - elif node_type == "设备": - node["color"] = "#540702C1" - node["size"] = 86 - elif node_type in [ - "功能", - "环境条件", - "接口", - "安全警告", - "调试", - "器材保障", - "图册", - "设计单位", - "维修项目", - "操作项目", - ]: - node["color"] = "#2261DF" - node["size"] = 52 - else: - node["color"] = "#68C3FF" - node["size"] = 53 - - return node - - -def add_link_style(link, nodes_dict): - source_id = link.get("source") - target_id = link.get("target") - - source_type = "" - target_type = "" - - if source_id and source_id in nodes_dict: - source_labels = nodes_dict[source_id].get("labels", []) - if source_labels and len(source_labels) > 0: - source_type = source_labels[0] - - if target_id and target_id in nodes_dict: - target_labels = nodes_dict[target_id].get("labels", []) - if target_labels and len(target_labels) > 0: - target_type = target_labels[0] - - hierarchy_types = ["舰艇", "系统", "子系统", "设备"] - if source_type in hierarchy_types and target_type in hierarchy_types: - link["color"] = "#F59E0B" - else: - link["color"] = "#FFFFFF" - - return link - - -def apply_styles(graph_data): - nodes = graph_data.get("nodes", []) - links = graph_data.get("links", []) - - nodes_dict = {n.get("id"): n for n in nodes if n.get("id")} - - for node in nodes: - add_node_style(node) - - for link in links: - add_link_style(link, nodes_dict) - - return graph_data - - -class GraphQueryRequest(BaseModel): - filename: Optional[str] = None - queryview: Optional[str] = None - querylink: Optional[str] = None - head: Optional[str] = None - tail: Optional[str] = None - node: Optional[str] = None - source_node: Optional[str] = None - # 在这里设置默认值为 1 - depth: Optional[int] = 1 - simple_graphData_copy: Optional[Dict[str, Any]] = None - - -@app.post("/api/v2/neo4j/query") -async def graph_query(request: GraphQueryRequest): - """ - 返回结构: - { - "message": str, - "simple_graphData": {...}, # 200节点采样(带 level 属性) - "graphData": {...}, # 查询结果图(头尾路径 / 节点展开等) - "short_routes": {...} # 最短路径(仅头尾模式有效) - } - """ - filename = request.filename - queryview = request.queryview - querylink = request.querylink - head = request.head - tail = request.tail - node = request.node - depth = request.depth - source_node = request.source_node - simple_graphData_copy = request.simple_graphData_copy - - simple_graphData = {"nodes": [], "links": []} - - logger.info("Fetching graph sample") - try: - # 只有当没有特定查询意图(头、尾、节点、文件名、视图)时,才加载全量采样 - if not any([filename, queryview, head, tail, node]): - simple_graphData = await run_in_threadpool(fetch_graph_sample, driver) - # # 处理外部传入的 copy 数据 (如果存在) - if simple_graphData_copy: - # 注意:这里假设传入的结构是 {"simple_graphData_copy": {...}} - # 如果传入的就是图数据本身,请调整 key 的访问方式 - data_source = simple_graphData_copy.get("simple_graphData_copy", simple_graphData_copy) - - # 删除 labels 字段(如果存在) - data_source.pop("labels", None) - - # 删除 nodes 中每个 node 的 color 字段 - for n in data_source.get("nodes", []): - if isinstance(n, dict): - n.pop("color", None) - - # 更新 simple_graphData 为处理后的数据 - simple_graphData = data_source - - except Exception: - logger.exception("Neo4j sample query error") - # 可以选择继续执行(使用空图),或者抛出错误 - # 这里选择继续执行,simple_graphData 保持为空或默认值 - simple_graphData = {"nodes": [], "links": []} - - def db_task(): - try: - with driver.session() as session: - # 默认返回值 - res = { - "graphData": {"nodes": [], "links": []}, - "short_routes": {"nodes": [], "links": []}, - "message": "", - } - - # =============================== - # 情况 1: 头尾节点都有 - # =============================== - if head and tail: - logger.info(f"Mode: HEAD + TAIL | {head} -> {tail}") - h_exists = session.run("MATCH (h {名称: $head}) RETURN h", head=head).single() - t_exists = session.run("MATCH (t {名称: $tail}) RETURN t", tail=tail).single() - - if h_exists and t_exists: - res["message"] = "头节点和尾节点展开成功" - if not h_exists and not t_exists: - res["message"] = "头节点和尾节点均不存在" - res["graphData"] = {"nodes": [], "links": []} - return res - elif not h_exists: - res["message"] = "头节点不存在" - # 返回存在的尾节点(如果存在) - nodes_list = [] - if t_exists: - nodes_list.append(node_to_json(t_exists["t"])) - res["graphData"] = {"nodes": nodes_list, "links": []} - return res - elif not t_exists: - res["message"] = "尾节点不存在" - nodes_list = [node_to_json(h_exists["h"])] - res["graphData"] = {"nodes": nodes_list, "links": []} - return res - - # 两者都存在,查路径 - sp_paths = list( - session.run( - """ - MATCH path = allShortestPaths((h {名称: $head})-[*1..10]->(t {名称: $tail})) - RETURN path AS p - """, - head=head, - tail=tail, - ) - ) - - all_paths = list( - session.run( - """ - MATCH path = (h {名称: $head})-[*1..10]->(t {名称: $tail}) - UNWIND nodes(path) AS x - WITH path, COUNT(DISTINCT x) AS nodeCount - WHERE nodeCount = LENGTH(path) + 1 - RETURN path AS p - """, - head=head, - tail=tail, - ) - ) - - if not sp_paths and not all_paths: - # 无连接,返回两个孤立节点 - nodes_list = [node_to_json(h_exists["h"]), node_to_json(t_exists["t"])] - res["graphData"] = {"nodes": nodes_list, "links": []} - res["short_routes"] = {"nodes": [], "links": []} - else: - res["graphData"] = build_graph_from_paths(all_paths) - res["short_routes"] = build_graph_from_paths(sp_paths) - # === 新增:为 graphData 中每个节点计算 level(最大无向跳数,≤3)=== - nodes_list = res["graphData"]["nodes"] - if not nodes_list: - return res - - # 确保每个节点都有 "名称" - valid_nodes = [n for n in nodes_list if "name" in n and n["name"]] - node_names = [n["name"] for n in valid_nodes] - name_to_node = {n["name"]: n for n in valid_nodes} - for name in node_names: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH path = (start)-[*1]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - name=name, - ).single() - - if result: - level = min(result["max_level"], 3) - name_to_node[name]["level"] = level - else: - name_to_node[name]["level"] = 0 - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - - apply_styles(res["graphData"]) - apply_styles(res["short_routes"]) - return res - - # =============================== - # 情况 2: 单节点查询 - # =============================== - elif node: - logger.info(f"Mode: NODE (1-hop only) | {node}") - # === 只查询 1 跳关系 === - paths = session.run( - """ - MATCH path = (n {名称: $node})-[*1]-(m) - UNWIND nodes(path) AS x - WITH path, COUNT(DISTINCT x) AS nodeCount - WHERE nodeCount = LENGTH(path) + 1 - RETURN path AS p - """, - node=node, - ) - - # 构建图 - graph = build_graph_from_paths(paths) - - # ============================== - # ✅ 新增:节点类型过滤(核心) - # ============================== - FILTER_TYPES = { - "功能", - "环境条件", - "组成", - "技术指标参数", - "接口", - "安全警告", - "操作使用", - "维修工作", - "调试", - "器材保障", - "图册", - "试验鉴定", - "设计单位", - "组成部件", - "无人机", - "无人机性能", - "外部设备", - "维修", - "操作", - "故障", - "舰艇", - "系统", - "子系统", - "设备", - } - - nodes = graph.get("nodes", []) - links = graph.get("links", []) - - # 👉 1. 过滤节点(注意字段名) - filtered_nodes = [ - n - for n in nodes - if n.get("labels")[0] in FILTER_TYPES # ⚠️ type 要和你的结构一致 - ] - - # 👉 2. 保留合法节点ID - valid_ids = {n["id"] for n in filtered_nodes} - - # 👉 3. 过滤边(避免“断边”) - filtered_links = [l for l in links if l.get("source") in valid_ids and l.get("target") in valid_ids] - - # 👉 4. 回写 graph - graph["nodes"] = filtered_nodes - graph["links"] = filtered_links - - # ============================== - - center_node_result = session.run("MATCH (n {名称: $node}) RETURN n", node=node).single() - - center_node_json = None - if center_node_result: - center_node_json = node_to_json(center_node_result["n"]) - - short_routes = {"nodes": [center_node_json] if center_node_json else [], "links": []} - - res["short_routes"] = short_routes - res["graphData"] = graph - - # === level 计算 === - nodes_list = graph.get("nodes", []) - if not nodes_list: - res["message"] = "未查询到相关节点" - return res - - valid_nodes = [n for n in nodes_list if n.get("name")] - name_to_node = {n["name"]: n for n in valid_nodes} - - for name in name_to_node: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH (start)-[*1]-(end) - WHERE start <> end - RETURN COUNT(end) AS cnt - """, - name=name, - ).single() - - level = 1 if result and result["cnt"] > 0 else 0 - name_to_node[name]["level"] = level - - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - - apply_styles(graph) - apply_styles(short_routes) - res["message"] = "节点展开成功" - return res - # =============================== - # 情况 3: 有simple_graphData_copy和source_node - # =============================== - elif simple_graphData_copy and source_node: - logger.info(f"Mode: SIMPLE_GRAPHDATA_COPY + SOURCE_NODE | source_node={source_node}") - - data_source = simple_graphData_copy.get("simple_graphData_copy", simple_graphData_copy) - data_source.pop("labels", None) - for n in data_source.get("nodes", []): - if isinstance(n, dict): - n.pop("color", None) - - existing_nodes = {n["id"]: n for n in data_source.get("nodes", []) if n.get("id")} - existing_links = {l["id"]: l for l in data_source.get("links", []) if l.get("id")} - - s_exists = session.run("MATCH (s {名称: $source_node}) RETURN s", source_node=source_node).single() - if not s_exists: - res["message"] = "source_node 节点不存在" - res["short_routes"] = { - "nodes": list(existing_nodes.values()), - "links": list(existing_links.values()), - } - res["graphData"] = { - "nodes": list(existing_nodes.values()), - "links": list(existing_links.values()), - } - return res - - source_node_json = node_to_json(s_exists["s"]) - source_id = s_exists["s"].element_id - if source_id not in existing_nodes: - existing_nodes[source_id] = source_node_json - - paths = session.run( - """ - MATCH path = (s {名称: $source_node})-[*1]-(m) - RETURN path - """, - source_node=source_node, - ) - - for p_rec in paths: - path = p_rec["path"] - for n in path.nodes: - nid = n.element_id - if nid not in existing_nodes: - existing_nodes[nid] = node_to_json(n) - for rel in path.relationships: - rid = rel.element_id - if rid not in existing_links: - existing_links[rid] = rel_to_json(rel) - - short_routes_data = simple_graphData_copy.get("simple_graphData_copy", simple_graphData_copy) - short_routes_nodes = list(short_routes_data.get("nodes", [])) - short_routes_links = list(short_routes_data.get("links", [])) - - graph_data = {"nodes": list(existing_nodes.values()), "links": list(existing_links.values())} - - FILTER_TYPES = { - "功能", - "环境条件", - "组成", - "技术指标参数", - "接口", - "安全警告", - "操作使用", - "维修工作", - "调试", - "器材保障", - "图册", - "试验鉴定", - "设计单位", - "组成部件", - "无人机", - "无人机性能", - "外部设备", - "维修", - "操作", - "故障", - "舰艇", - "系统", - "子系统", - "设备", - } - - nodes = graph_data.get("nodes", []) - links = graph_data.get("links", []) - - filtered_nodes = [ - n for n in nodes if n.get("labels") and len(n["labels"]) > 0 and n["labels"][0] in FILTER_TYPES - ] - - valid_ids = {n["id"] for n in filtered_nodes} - - filtered_links = [l for l in links if l.get("source") in valid_ids and l.get("target") in valid_ids] - - graph_data["nodes"] = filtered_nodes - graph_data["links"] = filtered_links - - short_routes = {"nodes": short_routes_nodes, "links": short_routes_links} - - valid_nodes = [n for n in graph_data["nodes"] if n.get("name")] - name_to_node = {n["name"]: n for n in valid_nodes if n.get("name")} - for name in name_to_node: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH path = (start)-[*1]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - name=name, - ).single() - level = min(result["max_level"], 3) if result else 0 - name_to_node[name]["level"] = level - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - - apply_styles(graph_data) - apply_styles(short_routes) - res["graphData"] = graph_data - res["short_routes"] = short_routes - res["message"] = f"查询节点成功!" - return res - # =============================== - # 情况 4: 只有头节点(有向,最多3跳) - # =============================== - elif head: - logger.info(f"Mode: HEAD ONLY | {head}") - h_exists = session.run("MATCH (h {名称: $head}) RETURN h", head=head).single() - if not h_exists: - res["message"] = "头节点不存在" - return res - - paths = session.run( - """ - MATCH path = (h {名称: $head})-[*1]->(n) - UNWIND nodes(path) AS x - WITH path, COUNT(DISTINCT x) AS nodeCount - WHERE nodeCount = LENGTH(path) + 1 - RETURN path AS p - """, - head=head, - ) - paths = list(paths) - if not paths: - # 3. 如果没有有向路径,返回单个节点信息 - res["graphData"] = {"nodes": [node_to_json(h_exists["h"])], "links": []} - else: - res["graphData"] = build_graph_from_paths(paths) - # === 新增:为 graphData 中每个节点计算 level(最大无向跳数,≤3)=== - nodes_list = res["graphData"]["nodes"] - if not nodes_list: - return res - - # 确保每个节点都有 "名称" - valid_nodes = [n for n in nodes_list if "name" in n and n["name"]] - node_names = [n["name"] for n in valid_nodes] - name_to_node = {n["name"]: n for n in valid_nodes} - - for name in node_names: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH path = (start)-[*1]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - name=name, - ).single() - - if result: - level = min(result["max_level"], 3) - name_to_node[name]["level"] = level - else: - name_to_node[name]["level"] = 0 - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - apply_styles(res["graphData"]) - res["message"] = "头节点展开成功" - return res - - # =============================== - # 情况 5: 只有尾节点(应查入边!即 ←) - # =============================== - elif tail: - logger.info(f"Mode: TAIL ONLY | {tail}") - t_exists = session.run("MATCH (t {名称: $tail}) RETURN t", tail=tail).single() - if not t_exists: - res["message"] = "尾节点不存在" - return res - - # 注意:尾节点作为终点,应查找指向它的路径(←) - paths = session.run( - """ - MATCH path = (n)-[*1]->(t {名称: $tail}) - UNWIND nodes(path) AS x - WITH path, COUNT(DISTINCT x) AS nodeCount - WHERE nodeCount = LENGTH(path) + 1 - RETURN path AS p - """, - tail=tail, - ) - paths = list(paths) - if not paths: - # 3. 如果没有有向路径,返回单个节点信息 - res["graphData"] = {"nodes": [node_to_json(t_exists["t"])], "links": []} - else: - res["graphData"] = build_graph_from_paths(paths) - # === 新增:为 graphData 中每个节点计算 level(最大无向跳数,≤3)=== - nodes_list = res["graphData"]["nodes"] - if not nodes_list: - return res - - # 确保每个节点都有 "名称" - valid_nodes = [n for n in nodes_list if "name" in n and n["name"]] - node_names = [n["name"] for n in valid_nodes] - name_to_node = {n["name"]: n for n in valid_nodes} - - for name in node_names: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH path = (start)-[*1]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - name=name, - ).single() - - if result: - level = min(result["max_level"], 3) - name_to_node[name]["level"] = level - else: - name_to_node[name]["level"] = 0 - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - apply_styles(res["graphData"]) - res["message"] = "尾节点展开成功" - return res - # =============================== - # 情况 6: 查询节点展开 - # =============================== - elif queryview: - logger.info(f"Mode: QUERYVIEW + QUERYLINK | nodes={queryview}, links={querylink}") - - node_ids = [x.strip() for x in queryview.split(",") if x.strip()] - if querylink: - link_ids = [x.strip() for x in querylink.split(",") if x.strip()] - else: - link_ids = [] - - if not node_ids and not link_ids: - res["message"] = "queryview 和 querylink 均为空" - return res - - graph_data_nodes = {} - graph_data_links = {} - - if node_ids: - nodes_result = session.run("MATCH (n) WHERE elementId(n) IN $ids RETURN n", ids=node_ids) - for rec in nodes_result: - n = rec["n"] - nid = n.element_id - if nid not in graph_data_nodes: - graph_data_nodes[nid] = node_to_json(n) - - if link_ids: - rels_result = session.run( - """ - MATCH ()-[r]->() - WHERE elementId(r) IN $link_ids - RETURN r, elementId(startNode(r)) AS start_id, elementId(endNode(r)) AS end_id - """, - link_ids=link_ids, - ) - - for record in rels_result: - rel = record["r"] - rid = rel.element_id - if rid not in graph_data_links: - graph_data_links[rid] = rel_to_json(rel) - - start_id = record["start_id"] - end_id = record["end_id"] - - if start_id not in graph_data_nodes: - node_result = session.run( - "MATCH (n) WHERE elementId(n) = $id RETURN n", id=start_id - ).single() - if node_result: - graph_data_nodes[start_id] = node_to_json(node_result["n"]) - - if end_id not in graph_data_nodes: - node_result = session.run( - "MATCH (n) WHERE elementId(n) = $id RETURN n", id=end_id - ).single() - if node_result: - graph_data_nodes[end_id] = node_to_json(node_result["n"]) - - graph_data = {"nodes": list(graph_data_nodes.values()), "links": list(graph_data_links.values())} - - short_routes = {"nodes": list(graph_data_nodes.values()), "links": list(graph_data_links.values())} - - valid_nodes = [n for n in graph_data["nodes"] if n.get("name")] - name_to_node = {n["name"]: n for n in valid_nodes if n.get("name")} - for name in name_to_node: - try: - result = session.run( - """ - MATCH (start {名称: $name}) - OPTIONAL MATCH path = (start)-[*1]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - name=name, - ).single() - level = min(result["max_level"], 3) if result else 0 - name_to_node[name]["level"] = level - except Exception as e: - logger.warning(f"Failed to compute level for {name}: {e}") - name_to_node[name]["level"] = 0 - - apply_styles(graph_data) - apply_styles(short_routes) - res["graphData"] = graph_data - res["short_routes"] = short_routes - res["message"] = f"查询拓展加载成功!" - return res - - # =============================== - # 情况 7: 按文件名检索所有匹配节点 - # =============================== - elif filename: - logger.info(f"Mode: FILENAME SEARCH | filename={filename}") - try: - search_pattern = f'"filename": "{filename}"' - result = session.run( - """ - MATCH (n) - WHERE n.knowledge_source IS NOT NULL - AND n.knowledge_source CONTAINS $search_pattern - RETURN n - """, - search_pattern=search_pattern, - ) - - nodes_list = [] - node_ids = [] - - # ========= 查询节点 ========= - for record in result: - n = record["n"] - node_json = node_to_json(n) - - # 使用 elementId 作为前端 graph 的唯一 id - eid = n.element_id - node_json["id"] = eid - node_ids.append(eid) - - identifier = node_json.get("name") or node_json.get("名称") - if identifier: - try: - level_result = session.run( - """ - MATCH (start {名称: $id}) - OPTIONAL MATCH path = (start)-[*1..3]-(end) - WHERE start <> end - RETURN coalesce(max(length(path)), 0) AS max_level - """, - id=identifier, - ).single() - level = min(level_result["max_level"], 3) if level_result else 0 - node_json["level"] = level - except Exception as e: - logger.warning(f"Level calc failed for {identifier}: {e}") - node_json["level"] = 0 - else: - node_json["level"] = 0 - - nodes_list.append(node_json) - - # ========= 查询节点之间的边 ========= - links_list = [] - if node_ids: - rel_result = session.run( - """ - MATCH (a)-[r]->(b) - WHERE elementId(a) IN $ids - AND elementId(b) IN $ids - RETURN r, - elementId(a) AS source, - elementId(b) AS target - """, - ids=node_ids, - ) - - for record in rel_result: - r = record["r"] - link_json = rel_to_json(r) # 你已有的方法 - - # # 确保 source / target 正确 - # link_json["source"] = record["source"] - # link_json["target"] = record["target"] - - links_list.append(link_json) - - # ========= 返回结果 ========= - if nodes_list: - graph_data = {"nodes": nodes_list, "links": links_list} - apply_styles(graph_data) - res["graphData"] = graph_data - res["message"] = ( - f"找到 {len(nodes_list)} 个关联文件名 '{filename}' 的节点,{len(links_list)} 条关系" - ) - else: - res["graphData"] = {"nodes": [], "links": []} - res["message"] = f"未找到关联文件名 '{filename}' 的节点" - - return res - - except Exception as e: - logger.exception("Filename search error") - res["message"] = f"按文件名查询节点时出错: {str(e)}" - return res - - # =============================== - # 兜底:无任何输入 - # =============================== - else: - res["message"] = "查询成功!" - return res - - except Exception as e: - logger.exception("Internal db_task error") - return { - "graphData": {"nodes": [], "links": []}, - "short_routes": {"nodes": [], "links": []}, - "message": f"数据库查询异常: {str(e)}", - } - - # 执行数据库任务 - query_result = await run_in_threadpool(db_task) - - # 组装最终响应 - if head or tail: - return { - "message": query_result["message"], - "simple_graphData": query_result["graphData"], - "graphData": query_result["graphData"], - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - } - if node and depth: - return { - "message": query_result["message"], - "simple_graphData": query_result["graphData"], - "graphData": query_result["graphData"], - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - } - if simple_graphData_copy and source_node: - return { - "message": query_result["message"], - "simple_graphData": query_result["graphData"], - "graphData": query_result["graphData"], - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - } - if queryview: - return { - "message": query_result["message"], - "simple_graphData": query_result["graphData"], - "graphData": query_result["graphData"], - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - } - if filename: - return { - "message": query_result["message"], - "simple_graphData": query_result["graphData"], - "graphData": query_result["graphData"], - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - } - else: - apply_styles(simple_graphData) - tree_graphData = build_tree(simple_graphData["nodes"], simple_graphData["links"]) - return { - "message": query_result["message"], - "simple_graphData": simple_graphData, - "graphData": simple_graphData, - "short_routes": query_result.get("short_routes", {"nodes": [], "links": []}), - "tree_graphData": tree_graphData - } - - -class FuzzyNodeOnlyRequest(BaseModel): - node: str - limit: Optional[int] = 20 - - -@app.post("/api/v2/neo4j/fuzzy_query") -async def fuzzy_node_only(request: FuzzyNodeOnlyRequest): - """ - 节点名称模糊匹配(仅返回节点,不返回关系) - """ - - keyword = request.node.strip() - limit = request.limit or 50 - - if not keyword: - raise HTTPException(status_code=400, detail="keyword 不能为空") - - def db_task(): - try: - with driver.session() as session: - logger.info(f"Mode: FUZZY NODE ONLY | keyword='{keyword}', limit={limit}") - - result = session.run( - """ - MATCH (n) - WHERE n.名称 CONTAINS $kw - RETURN n - LIMIT $limit - """, - kw=keyword, - limit=limit, - ) - - nodes_list = [] - - for record in result: - n = record["n"] - node_json = node_to_json(n) - - # 统一前端使用 elementId 作为 id - node_json["id"] = n.element_id - - nodes_list.append(node_json) - - if nodes_list: - return {"message": f"模糊匹配 '{keyword}' 成功,找到 {len(nodes_list)} 个节点", "nodes": nodes_list} - else: - return {"message": f"未找到名称包含 '{keyword}' 的节点", "nodes": []} - - except Exception as e: - logger.exception("Fuzzy node only query error") - return {"message": f"节点模糊查询异常: {str(e)}", "nodes": []} - - return await run_in_threadpool(db_task) - - -class ExpandQueryRequest(BaseModel): - node: str - - -@app.post("/api/v2/neo4j/expand") -async def expand_node(request: ExpandQueryRequest): - """ - 无向节点拓展: - 仅返回指定节点 1 跳范围内的所有无向关联及节点信息。 - """ - node_name = request.node - if not node_name: - raise HTTPException(status_code=400, detail="Node name is required") - - logger.info(f"Expanding node: {node_name} | depth=1 (undirected)") - - def db_task_expand(): - try: - with driver.session() as session: - # 1. 执行 1 跳无向查询 - # 使用 -[r]- 表示无向,匹配起点 node_name 的所有直接邻居 - cypher_query = """ - MATCH path = (n {名称: $name})-[r]-(m) - RETURN path AS p - """ - result = session.run(cypher_query, name=node_name) - - # 将结果转为列表,以便多次处理或判断 - records = list(result) - - if not records: - logger.info(f"No connections found for node: {node_name}") - return {"nodes": [], "links": []} - - # 使用 build_graph_from_paths 解析路径(内部已过滤 Searchable) - return build_graph_from_paths(records) - - except Exception as e: - logger.exception("Neo4j expansion query error") - raise e - - # 执行数据库任务 - try: - related_data = await run_in_threadpool(db_task_expand) - except Exception as e: - raise HTTPException(status_code=500, detail=f"Expansion failed: {str(e)}") - - return {"message": "200", "related_graphData": related_data} - - -def _sync_kg_build_task( - task_id: str, files_data: List[dict], kg_config: dict, result_queue: Queue, cancel_flag_path: str -): - """子进程中执行知识图谱构建(并发版:最多 4 个文件同时处理)""" - - logging.basicConfig(level=logging.INFO) - logger = logging.getLogger(__name__) - - complete_files = [] - _complete_files_lock = threading.Lock() # 保护 complete_files 和 result_queue - _kg_lock = threading.Lock() # 保护 Neo4j 入库(kg.process_data / filter_node_relationship) - - def check_cancelled(): - return os.path.exists(cancel_flag_path) - - # 配置加载 - NEO4J_URI = kg_config["neo4j_uri"] - NEO4J_USER = kg_config["neo4j_user"] - NEO4J_PASSWORD = kg_config["neo4j_password"] - DATA_DIR = "/app/files" - Ontology = kg_config["ontology"] - Ontology_DESC = kg_config["ontology_description"] - relationships = kg_config["relationships"] - node_types = kg_config["node_types"] - relationship_types = kg_config["relationship_types"] - - kg = MilitaryKnowledgeGraph(uri=NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD), Ontology=Ontology) - - # ---- 单文件处理函数(供线程池调用) ---- - def _process_single_file(idx: int, file_data: dict): - """处理单个文件:OCR/提取 → 入库。线程安全。""" - entities = [] - relations = [] - filename_entity = [] - filename_relation = [] - lower_entity_device = None - lower_entity_type = None - file_name = file_data.get("file_name") or f"unknown_{idx}" - _t_file_start = time.time() - - try: - if check_cancelled(): - raise InterruptedError("任务已取消") - - file_name = file_data["file_name"] - file_base64 = file_data["file_base64"] - - logger.info(f"[线程] 处理文件: {file_name}") - - # --- 1. 文件名相关的简单实体提取 --- - try: - final_result = get_entity(file_name) - filename_entity = final_result.get("entities", []) - print(f"文件名实体提取结果: {filename_entity}") - filename_relation = final_result.get("relationships", []) - print(f"文件名关系提取结果: {filename_relation}") - lower_entity = final_result.get("low_level") - - for ins in filename_entity: - if ins.get("properties", {}).get("名称") == lower_entity: - lower_entity_device = ins["properties"].get("名称") - lower_entity_type = ins["type"] - break - except Exception as e: - logger.warning(f"文件名实体提取失败: {e}") - filename_entity = [] - filename_relation = [] - - # --- 2. 保存文件到磁盘 --- - os.makedirs(DATA_DIR, exist_ok=True) - FILE_PATH = os.path.join(DATA_DIR, file_name) - file_binary = base64.b64decode(file_base64) - with open(FILE_PATH, "wb") as f: - f.write(file_binary) - logger.info(f"? 已保存文件: {FILE_PATH}") - - content_middle = file_data.get("content_middle") or [] - - check_result = check_filename_ocr(file_name) - print("#####################################") - print(check_result) - if content_middle: - # --- 3a. 已有预解析内容,直接抽取,跳过 MinerU --- - logger.info(f"文件 {file_name} 使用预解析内容,跳过 MinerU") - _t_extract_start = time.time() - - async def run_extraction_with_content(): - return await get_md_node_relation( - content_list=content_middle, - input_pdf_path=FILE_PATH, - Ontology=Ontology, - Ontology_DESCRIPTION=Ontology_DESC, - Relationships=relationships, - RELATIONSHIP_TYPES=relationship_types, - NODE_TYPES=node_types, - PREFIX_URL=PREFIX_URL, - device=lower_entity_device, - device_type=lower_entity_type, - ) - - entities, relations = asyncio.run(run_extraction_with_content()) - - elif check_result == "ocr_true": - logger.info(f"文件 {file_name} 需要 OCR 处理") - - # --- 3b. 调用 MinerU 进行 OCR(get_api_url 轮询不同实例) --- - _t_extract_start = time.time() - entities, relations = process_file_content( - file_name=file_name, - file_path=FILE_PATH, - task_id=task_id, - data_dir=DATA_DIR, - ontology=Ontology, - ontology_desc=Ontology_DESC, - relationships=relationships, - node_types=node_types, - relationship_types=relationship_types, - prefix_url=PREFIX_URL, - api_url=file_data["api_url"], - check_cancelled_callback=check_cancelled, - device=lower_entity_device, - device_type=lower_entity_type, - ) - - elif check_result == "ocr_false": - logger.info(f"文件 {file_name} 不需要 OCR 处理,调用 get_filtertext_node_relation") - _t_extract_start = time.time() - - async def run_filtertext(): - return await get_filtertext_node_relation( - input_pdf_path=FILE_PATH, data=[], prefix_url=PREFIX_URL, device=lower_entity_device - ) - - try: - filter_result = asyncio.run(run_filtertext()) - - if isinstance(filter_result, tuple) and len(filter_result) >= 2: - entities, relations = filter_result[0], filter_result[1] - logger.info(f"get_filtertext_node_relation 返回: 实体 {len(entities)}, 关系 {len(relations)}") - else: - logger.error( - f"get_filtertext_node_relation 返回格式异常: {type(filter_result)}, 值: {filter_result}" - ) - entities, relations = [], [] - - except Exception as e: - logger.error(f"get_filtertext_node_relation 调用失败: {e}") - logger.error(traceback.format_exc()) - entities, relations = [], [] - else: - logger.warning(f"未知的 check_result: {check_result},默认使用空值") - _t_extract_start = time.time() - entities, relations = [], [] - - _t_extract_cost = time.time() - _t_extract_start - logger.info(f"[计时][{file_name}] OCR/抽取耗时: {_t_extract_cost:.1f}s") - - # --- 4. 后续合并与入库逻辑 --- - all_entity = entities + filename_entity - all_relation = relations + filename_relation - - all_entity_new = [ins for ins in all_entity if ins.get("properties", {}).get("名称")] - - # 生成 Embedding - _t_embed_start = time.time() - for entity in all_entity_new: - name = entity["properties"].get("名称") - if "未知" in name: - continue - if name: - try: - embedding_vector = OpenaiAPI.generate_embedding(name) - entity["properties"]["embedding"] = embedding_vector - except Exception as e: - logger.warning(f"生成 embedding 失败 for {name}: {e}") - - _t_embed_cost = time.time() - _t_embed_start - logger.info(f"[计时][{file_name}] Embedding耗时: {_t_embed_cost:.1f}s (实体数: {len(all_entity_new)})") - - merged_output_data = {"entities": all_entity_new, "relationships": all_relation} - - # 调试输出 - debug_path = f"/app/output_{task_id}_{idx}.json" - try: - with open(debug_path, "w", encoding="utf-8") as f: - json.dump(merged_output_data, f, ensure_ascii=False, indent=2) - except Exception as e: - logger.warning(f"保存调试文件失败: {e}") - - # 入库(加锁,Neo4j 写操作串行化,避免并发冲突) - _t_lock_wait_start = time.time() - with _kg_lock: - _t_lock_wait_cost = time.time() - _t_lock_wait_start - logger.info(f"[计时][{file_name}] 等锁耗时: {_t_lock_wait_cost:.1f}s") - - _t_filter_start = time.time() - try: - filter_data = filter_node_relationship( - URI=NEO4J_URI, - USERNAME=NEO4J_USER, - PASSWORD=NEO4J_PASSWORD, - merged_output_data=merged_output_data, - ) - except Exception as e: - logger.error(f"过滤节点关系失败: {e}") - raise - _t_filter_cost = time.time() - _t_filter_start - logger.info(f"[计时][{file_name}] filter去重耗时: {_t_filter_cost:.1f}s") - - _t_write_start = time.time() - entity_count, rel_count = kg.process_data(filter_data) - _t_write_cost = time.time() - _t_write_start - logger.info( - f"[计时][{file_name}] Neo4j写入耗时: {_t_write_cost:.1f}s (实体: {entity_count}, 关系: {rel_count})" - ) - - # 建立索引 - try: - data = { - "neo4j_uri": NEO4J_URI, - "neo4j_username": NEO4J_USER, - "neo4j_password": NEO4J_PASSWORD, - "force_refresh": True, - } - requests.post(indexing_url, json=data, timeout=30) - except Exception as e: - logger.warning(f"建立索引失败: {e}") - - _t_file_total = time.time() - _t_file_start - logger.info( - f"[计时][{file_name}] ===总耗时: {_t_file_total:.1f}s === " - f"(抽取:{_t_extract_cost:.1f}s embed:{_t_embed_cost:.1f}s " - f"等锁:{_t_lock_wait_cost:.1f}s filter:{_t_filter_cost:.1f}s 写入:{_t_write_cost:.1f}s)" - ) - - # 记录结果(加锁) - with _complete_files_lock: - file_result = { - "file_name": file_name, - "status": "success", - "entity_count": entity_count, - "relation_count": rel_count, - } - complete_files.append(file_result) - - result_queue.put( - { - "code": 200, - "type": "progress", - "file_index": idx, - "total_files": len(files_data), - "file_name": file_name, - "status": "success", - "entity_count": entity_count, - "relation_count": rel_count, - "complete_files": complete_files.copy(), - } - ) - - except InterruptedError: - with _complete_files_lock: - complete_files.append({"file_name": file_name, "status": "cancelled"}) - raise - - except Exception as e: - error_msg = f"[{task_id}] 文件 {file_name} 处理失败: {str(e)}" - logger.error(error_msg) - logger.error(traceback.format_exc()) - - with _complete_files_lock: - file_result = {"file_name": file_name, "status": "failed", "error": str(e)} - complete_files.append(file_result) - - result_queue.put( - { - "code": 200, - "type": "progress", - "file_index": idx, - "total_files": len(files_data), - "file_name": file_name, - "status": "failed", - "error": str(e), - "complete_files": complete_files.copy(), - } - ) - - # ---- 并发执行 ---- - # 预解析文件不经过 MinerU,并发数不受 API_URLS 限制 - # 需要 MinerU 的文件受 API_URLS 实例数约束,取两者中较大值保证并发 - _files_need_mineru = sum(1 for fd in files_data if not (fd.get("content_middle") or [])) - CONCURRENT_WORKERS = ( - max(len(API_URLS), min(len(files_data), 100)) if _files_need_mineru == 0 else max(len(API_URLS), 1) - ) - logger.info(f"[{task_id}] 并发数: {CONCURRENT_WORKERS},需MinerU文件: {_files_need_mineru}/{len(files_data)}") - cancelled = False - - with ThreadPoolExecutor(max_workers=CONCURRENT_WORKERS) as executor: - futures = {executor.submit(_process_single_file, idx, fd): (idx, fd) for idx, fd in enumerate(files_data)} - - for future in futures: - try: - future.result() # 等待完成,异常已在内部处理 - except InterruptedError: - cancelled = True - # 取消尚未开始的任务 - for f in futures: - f.cancel() - break - except Exception: - pass # 已在 _process_single_file 内部处理并汇报 - - if cancelled: - result_queue.put( - {"code": 200, "status": "cancelled", "message": "任务已取消", "complete_files": complete_files} - ) - return - - # 所有文件处理完成 - result_queue.put( - {"code": 200, "type": "completed", "status": "success", "message": "构建完成", "complete_files": complete_files} - ) - - -@app.post("/kg_build") -async def kg_build(request: KGRequest): - task_id = request.task_id - - if task_id in kg_running_tasks: - existing = kg_running_tasks[task_id] - if existing.get("process") and existing["process"].is_alive(): - return {"code": 400, "message": f"任务 {task_id} 已在运行中"} - - files = request.files if isinstance(request.files, list) else [request.files] - files_data = [] - for i, f in enumerate(files): - _api, _cache = get_api_url(f"{task_id}_{i}") # 哈希取模,多 worker 进程安全 - logger.info(f"[{task_id}] 文件 {f.file_name} → MinerU {_api}") - files_data.append( - { - "file_name": f.file_name, - "markdown_content": f.markdown_content, - "file_base64": f.file_base64, - "content_middle": f.content_middle, - "api_url": _api, - "get_contentlist_url": _cache, - } - ) - - logger.info(f"[{task_id}] 开始构建知识图谱,文件数量: {len(files_data)}") - - # ★ 关键改动:合并默认值与用户传入值 - merged = build_kg_config( - user_ontology=request.ontology, - user_ontology_desc=request.Ontology_DESCRIPTION, - user_relationships=request.relationships, - user_node_types=request.node_types, - user_relationship_types=request.relationship_types, - ) - - kg_config = { - "neo4j_uri": NEO4J_URI, - "neo4j_user": NEO4J_USER, - "neo4j_password": NEO4J_PASSWORD, - "data_dir": DATA_DIR, - **merged, # ontology / ontology_description / relationships / node_types / relationship_types - } - - # 持久化配置缓存(使用合并后的值) - try: - cache_dir = DATA_DIR if os.path.isdir(DATA_DIR) else os.path.dirname(__file__) - os.makedirs(cache_dir, exist_ok=True) - cache_path = os.path.join(cache_dir, "kg_config_cache.json") - async with aiofiles.open(cache_path, "w", encoding="utf-8") as f: - await f.write(json.dumps( - { - "ontology": kg_config["ontology"], - "ontology_description": kg_config["ontology_description"], - "relationships": kg_config["relationships"], - "node_types": kg_config["node_types"], - "relationship_types": kg_config["relationship_types"], - "updated_at": datetime.utcnow().isoformat() + "Z", - }, - ensure_ascii=False, - indent=2, - )) - logger.info(f"已保存 kg_build 配置缓存: {cache_path}") - except Exception as e: - logger.warning(f"保存 kg_build 配置缓存失败: {e}") - - # 后续进程启动逻辑保持不变 ... - cancel_flag_path = f"/tmp/kg_cancel_{task_id}" - if os.path.exists(cancel_flag_path): - os.remove(cancel_flag_path) - - result_queue = Queue() - proc = Process( - target=_sync_kg_build_task, - args=(task_id, files_data, kg_config, result_queue, cancel_flag_path), - daemon=True, - ) - proc.start() - - # 记录任务(用于取消) - task_data = { - "process": proc, - "result_queue": result_queue, - "cancel_flag_path": cancel_flag_path, - "status": "processing", - } - kg_running_tasks[task_id] = task_data - - # 流式返回生成器 - async def event_generator(): - """生成器:实时返回每个文件的处理进度""" - timeout = 3600 # 2小时超时 - start = time.time() - - try: - while True: - # 超时检查 - if time.time() - start > timeout: - proc.terminate() - proc.join(timeout=5) - if proc.is_alive(): - proc.kill() - kg_running_tasks.pop(task_id, None) - yield ( - json.dumps( - {"code": 500, "type": "error", "message": "任务执行超时", "complete_files": []}, - ensure_ascii=False, - ) - + "\n" - ) - return - - # 检查是否有结果 - try: - # 非阻塞获取队列消息 - while not result_queue.empty(): - result = result_queue.get_nowait() - yield json.dumps(result, ensure_ascii=False) + "\n" - - # 如果是完成或错误消息,结束生成器 - if result.get("type") in ["completed", "error", "cancelled"]: - kg_running_tasks.pop(task_id, None) - return - except Exception as e: - logger.warning(f"[{task_id}] Queue读取异常: {e}") - - # 检查进程是否还活着 - if not proc.is_alive(): - # 进程结束,读取剩余消息 - while not result_queue.empty(): - result = result_queue.get_nowait() - yield json.dumps(result, ensure_ascii=False) + "\n" - - # 如果队列为空但进程异常退出 - if result_queue.empty(): - yield ( - json.dumps( - { - "code": 500, - "type": "error", - "message": f"进程异常退出: {proc.exitcode}", - "complete_files": [], - }, - ensure_ascii=False, - ) - + "\n" - ) - - kg_running_tasks.pop(task_id, None) - return - - # 短暂休眠,避免CPU空转 - await asyncio.sleep(0.3) - - except Exception as e: - kg_running_tasks.pop(task_id, None) - logger.error(f"[{task_id}] 流式返回异常: {str(e)}") - yield ( - json.dumps({"code": 500, "type": "error", "message": str(e), "complete_files": []}, ensure_ascii=False) - + "\n" - ) - - return StreamingResponse(event_generator(), media_type="application/x-ndjson") - - -# ==================== kg_task_cancel 接口 ==================== - - -@app.post("/kg_task_cancel/{task_id}") -async def kg_task_cancel(task_id: str): - """取消知识图谱构建任务""" - task = kg_running_tasks.get(task_id) - if not task: - raise HTTPException(status_code=404, detail=f"任务 {task_id} 不存在") - - proc = task.get("process") - if not proc or not proc.is_alive(): - return {"code": 400, "message": "任务已结束", "status": task.get("status")} - - cancel_flag_path = task.get("cancel_flag_path") - - try: - # 1. 设置取消标志 - async with aiofiles.open(cancel_flag_path, "w") as f: - await f.write(str(time.time())) - - await asyncio.sleep(3) - - # 2. 强制终止 - if proc.is_alive(): - os.kill(proc.pid, signal.SIGTERM) - proc.join(timeout=5) - if proc.is_alive(): - os.kill(proc.pid, signal.SIGKILL) - proc.join() - - task["status"] = "cancelled" - - if os.path.exists(cancel_flag_path): - os.remove(cancel_flag_path) - - kg_running_tasks.pop(task_id, None) - - logger.info(f"[{task_id}] 任务已取消") - return {"code": 200, "message": "任务已取消", "task_id": task_id} - - except Exception as e: - return {"code": 500, "message": f"取消失败: {str(e)}"} - - -@app.post("/ontology_reset") -async def ontology_reset(request: resetRequest): - # ★ 关键改动:合并默认值与用户传入值 - merged = build_kg_config( - user_ontology=request.ontology, - user_ontology_desc=request.Ontology_DESCRIPTION, - user_relationships=request.relationships, - user_node_types=request.node_types, - user_relationship_types=request.relationship_types, - ) - - Ontology = merged["ontology"] - Ontology_DESC = merged["ontology_description"] - relationships = merged["relationships"] - node_types = merged["node_types"] - relationship_types = merged["relationship_types"] - - files = request.files if isinstance(request.files, list) else [request.files] - logger.info(f"开始本体衍生,文件数量: {len(files)}") - - async def event_generator(): - total_files = len(files) - for file_idx, file in enumerate(files): - markdown_content = file.markdown_content - file_name = file.file_name - new_filename = re.sub(r"^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}_", "", file_name) - - wx_tables, cleaned_wx_content = extract_repair_tables_keep_first(content=markdown_content) - opration_tables, cleaned_opration_content = extract_operation_tables(cleaned_wx_content) - nromaltabel, contexts, cleaned_normal_content = extract_tables(cleaned_opration_content) - - content, headers = _split_markdown(cleaned_normal_content, chunk_size=15000, chunk_overlap=500) - total_chunks = len(content) - - for chunk_idx, ins in enumerate(content): - final_prompt = create_extraction_prompt( - text=ins, - ontology=Ontology, - Ontology_DESCRIPTION=Ontology_DESC, - relationships=relationships, - relationship_types=relationship_types, - node_types=node_types, - ) - final_prompt = create_extraction_prompt( - text=ins, - ontology=Ontology, - Ontology_DESCRIPTION=Ontology_DESCRIPTION, - relationships=relationships, - relationship_types=relationship_types, - node_types=node_types, - ) - - res_str = await OpenaiAPI.openai_chat_aysnc(final_prompt) - - # 处理 API 调用失败 - if res_str is None: - error_msg = { - "code": 500, - "error": "API调用失败", - "file_index": file_idx, - "total_files": total_files, - "chunk_index": chunk_idx, - "total_chunks": total_chunks, - "file_name": new_filename, - } - yield json.dumps(error_msg, ensure_ascii=False) + "\n" - continue - - # 尝试解析 JSON - try: - res = json.loads(res_str) - except json.JSONDecodeError as e: - error_msg = { - "code": 500, - "error": f"JSON解析失败: {str(e)}", - "raw_response": repr(res_str), - "file_index": file_idx, - "total_files": total_files, - "chunk_index": chunk_idx, - "total_chunks": total_chunks, - "file_name": new_filename, - } - yield json.dumps(error_msg, ensure_ascii=False) + "\n" - continue - - new_entities = res.get("new_entities", []) - logger.info(f"new_entities: {new_entities}") - new_relationships = res.get("new_relationships", []) - logger.info(f"new_relationships: {new_relationships}") - - # 简化逻辑:file_index 就是当前文件索引(从0开始) - result = { - "code": 200, - "file_index": file_idx, - "total_files": total_files, - "chunk_index": chunk_idx, - "total_chunks": total_chunks, - "new_entities": new_entities, - "new_relationships": new_relationships, - "file_name": new_filename, - } - logger.info(f"衍生本体如下:{result}") - - # 流式返回(JSON Lines) - yield json.dumps(result, ensure_ascii=False) + "\n" - - # 当前文件所有chunk处理完毕后,发送文件完成标记 - yield ( - json.dumps( - { - "code": 200, - "status": "file_completed", - "file_index": file_idx, - "total_files": total_files, - "file_name": new_filename, - "message": f"文件 {new_filename} 处理完成", - }, - ensure_ascii=False, - ) - + "\n" - ) - - # 最后发送全部完成标记 - yield ( - json.dumps({"code": 200, "status": "completed", "message": "所有文件本体衍生完毕"}, ensure_ascii=False) - + "\n" - ) - logger.info("所有文件本体衍生完毕") - - return StreamingResponse(event_generator(), media_type="application/x-ndjson") - - -class PdfContentItem(BaseModel): - page_idx: int - bbox: Optional[str] = None - text: Optional[str] = None - text_level: Optional[int] = None - img_path: Optional[str] = None - table_body: Optional[str] = None - - -class RequestWrapper(BaseModel): - pdf_contents: List[PdfContentItem] - - -class Base64ImageRequest(BaseModel): - content: Optional[str] = Field( - None, - description="Optional text around the image, for example: 图3.1 船舶主发动机组成图(images/test.jpg)", - ) - filename: str = Field(..., description="Original image filename, for example test.png") - image_base64: str = Field(..., description="Base64 image content, with or without data:image/... prefix") - - -async def analyze_image_with_vlm(image_bytes: bytes, suffix: str) -> str: - image_url = image_base64_to_data_url(image_bytes, suffix) - async with VLM_SEMAPHORE: - return await OpenaiAPI.open_api_vl_without_thinking(image_url) - - -@app.post("/split_image") -async def image_base64(request_data: Base64ImageRequest): - filename = safe_original_filename(request_data.filename) - suffix = PathLib(filename).suffix.lower() - if suffix not in {".jpg", ".jpeg", ".png", ".bmp", ".webp", ".gif", ".tif", ".tiff"}: - raise HTTPException(status_code=400, detail="Unsupported image type") - - image_bytes, processed_suffix = prepare_split_image(request_data.image_base64, suffix) - if not image_bytes: - raise HTTPException(status_code=400, detail="decoded image is empty") - - temp_path = None - try: - with tempfile.NamedTemporaryFile(delete=False, suffix=processed_suffix) as tmp: - tmp.write(image_bytes) - temp_path = PathLib(tmp.name) - - ocr_data = await extract_image_text(temp_path) - try: - temp_path.unlink() - except Exception as e: - logger.warning(f"Failed to delete temp image {temp_path}: {e}") - finally: - temp_path = None - - content = (request_data.content or "").strip() - ocr_full_text = (ocr_data.get("full_text") or "").strip() - - if not content and not ocr_full_text: - vlm_text = await analyze_image_with_vlm(image_bytes, processed_suffix) - image_content = "图片文本描述为:" + (vlm_text or "").strip() - elif content and ocr_full_text: - image_content = f"图片上下文内容为:{content}, {ocr_full_text}" - elif content: - image_content = "图片上下文内容为:" + content - else: - image_content = ocr_full_text - - image_content = "图片文件名为:" + filename + ",图片相关内容为:" + image_content - return JSONResponse( - { - "code": 200, - "message": "ok", - "data": { - "image_content": image_content, - "filename": filename, - }, - } - ) - finally: - if temp_path and temp_path.exists(): - try: - temp_path.unlink() - except Exception as e: - logger.warning(f"Failed to delete temp image {temp_path}: {e}") - - - -@app.post("/split_content_list") -async def split_content_list(request_data: RequestWrapper): - pdf_contents = request_data.pdf_contents - processed_list = [] - - for item in pdf_contents: - # 将 Pydantic 模型转换为字典,方便修改 - item_dict = item.model_dump() - - # --- 核心逻辑:判断并添加 type 字段 --- - item_type = None - - # 1. 如果 text 非空 -> type: "text" - if item.text: - item_type = "text" - - # 2. 如果 table_body 非空 -> type: "table" - # 注意:如果 text 和 table_body 都有,根据代码顺序,table 会覆盖 text。 - # 如果你的业务逻辑是互斥的或需要优先级,请调整此处顺序。 - elif item.table_body: - item_type = "table" - - # 3. 如果 img_path 非空 且 table_body 为空 -> type: "image" - # 注意:上面用了 elif 判断 table_body,所以到这里 table_body 肯定为空, - # 但为了逻辑清晰,显式写出条件。 - elif item.img_path and not item.table_body: - item_type = "image" - - # 如果匹配到了类型,写入字典 - if item_type: - item_dict["type"] = item_type - - processed_list.append(item_dict) - slices = get_chunk_bbox(processed_list) - slices_check = chunk_check(slices, 8000) - - return {"code": 200, "message": "ok", "data": {"slices": slices_check}} - - -@app.post("/split_result") -async def split_result( - file: UploadFile = File(...), - image_prefix: str = Form("/api/v1/knowledge/files/images/"), -): - if not file.filename: - raise HTTPException(status_code=400, detail="File name is missing") - - chunk_size = 1024 - chunk_overlap = 100 - - filename = file.filename - suffix = PathLib(filename).suffix.lower() # 获取文件后缀 - temp_input_path: Optional[PathLib] = None - converted_pdf_path: Optional[PathLib] = None - logger.info("调用知识切分接口") - - try: - # ? 创建临时文件时指定后缀名 - with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp_in: - content = await file.read() - logger.info(f"文件大小:{len(content)}") - logger.info(f"前10字节:{content[:10]}") - # if not content.startwith(b"%PDF"): - # logger.error("不是合法PDF") - # raise HTTPException(status_code=400,detail="Uploaded file is not a valid PDF") - tmp_in.write(content) - temp_input_path = PathLib(tmp_in.name) - # 2. 根据文件类型处理 - if suffix == ".pdf": - logger.info("调用pdf切分方式") - - result_data = await process_pdf_file(temp_input_path, image_prefix,filename) - if result_data is None: - raise HTTPException(status_code=502, detail="PDF processing failed") - elif suffix == ".docx": - logger.info("调用docx切分方式") - logger.info(f"转换 DOCX -> PDF: {filename}") - - # 执行转换 - converter.convert(str(temp_input_path), output_dir=str(DATA_DIR)) - - # ? 使用临时文件的基础名查找 PDF - temp_base_name = temp_input_path.stem # 如 tmp2bb0l4cn - converted_pdf_path = PathLib(DATA_DIR) / f"{temp_base_name}.pdf" - - if not converted_pdf_path.exists(): - raise HTTPException(status_code=500, detail=f"PDF 转换失败: {converted_pdf_path}") - - result_data = await process_pdf_file(converted_pdf_path, image_prefix) - if result_data is None: - raise HTTPException(status_code=502, detail="DOCX to PDF processing failed") - - elif suffix in (".txt", ".md"): - logger.info("调用txt切分方式") - - # 直接读取文本内容 - async with aiofiles.open(temp_input_path, "r", encoding="utf-8", errors="ignore") as f: - text_content = await f.read() - contents = split_text_preserve_sentences(text_content) - # 构造统一结构(无 images) - slices = [] - for ins in contents: - slices.append({"content": ins, "positions": []}) - result_data = {"slices": slices, "images": {}} - elif suffix in [".xlsx"]: - # converter.convert(str(temp_input_path), output_dir=str(DATA_DIR)) - # temp_base_name = temp_input_path.stem # 如 tmp2bb0l4cn - # converted_pdf_path = PathLib(DATA_DIR) / f"{temp_base_name}.pdf" - # if not converted_pdf_path.exists(): - # raise HTTPException(status_code=500, detail=f"PDF 转换失败: {converted_pdf_path}") - logger.info("调用xlsx切分方式") - - result_data = await process_other_file(temp_input_path, image_prefix,filename) - if result_data is None: - raise HTTPException(status_code=502, detail="DOCX parse failed") - elif suffix in [".ppt", ".pptx"]: - logger.info("调用 PPT/PPTX 切分方式") - - # 1. 判断是否为旧版 .ppt 格式,如果是,则先进行转换 - if suffix == ".ppt": - logger.info(f"检测到旧版 PPT 文件,正在转换为 PPTX: {temp_input_path}") - try: - # 定义 LibreOffice 转换命令 - command = [ - 'libreoffice', - '--headless', # 无头模式,不弹出图形界面 - '--convert-to', 'pptx', - '--outdir', os.path.dirname(temp_input_path), - temp_input_path - ] - - # 2. 使用 run_in_executor 将阻塞的同步转换操作放入线程池,避免阻塞异步事件循环 - loop = asyncio.get_event_loop() - result = await loop.run_in_executor( - None, - lambda: subprocess.run(command, capture_output=True, text=True) - ) - - # 3. 检查转换是否成功 - if result.returncode != 0: - logger.error(f"PPT 转换失败: {result.stderr}") - raise HTTPException(status_code=500, detail="PPT to PPTX conversion failed") - - # 4. 转换成功后,更新输入路径为新生成的 .pptx 文件路径 - temp_input_path = os.path.splitext(temp_input_path)[0] + ".pptx" - logger.info(f"PPT 转换成功,新文件路径: {temp_input_path}") - - except Exception as e: - logger.exception(f"PPT 转换过程发生异常: {e}") - raise HTTPException(status_code=500, detail=f"PPT conversion error: {str(e)}") - - # 5. 无论是原本就是 .pptx,还是刚刚转换完成的 .pptx,都统一走后续处理逻辑 - result_data = await process_other_file(temp_input_path, image_prefix, filename) - if result_data is None: - raise HTTPException(status_code=502, detail="PPTX parse failed") - else: - raise HTTPException( - status_code=400, detail="Unsupported file type. Only PDF, DOCX, TXT, and MD are supported." - ) - - return JSONResponse({"code": 200, "message": "ok", "data": result_data}) - - except requests.RequestException as e: - logger.error(f"Split service request failed: {e}") - raise HTTPException(status_code=502, detail=f"Split service error: {str(e)}") - except Exception as e: - logger.error(f"Internal error: {e}") - raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") - finally: - # 清理临时文件 - for path in [temp_input_path, converted_pdf_path]: - if path and path.exists(): - try: - path.unlink() - except Exception as e: - logger.warning(f"Failed to delete temp file {path}: {e}") - - -# ========== ========== ========== ========== ========== ========== -# 图谱检索接口 -# ========== ========== ========== ========== ========== ========== - -class GraphSearchRequest(BaseModel): - """图谱检索请求模型""" - - query: Optional[str] = None - top_k: Optional[int] = 10 # 图谱检索返回结果数量 - graph_timeout: Optional[float] = 2.0 - entry_nodes: Optional[Dict[str, Any]] = None - - -@app.post("/search_graph——1") -async def search_graph(request: GraphSearchRequest, background_tasks: BackgroundTasks): - """ - ========== ========== ========== ========== ========== ========== - 纯图谱检索 - - 请求参数: - - query: 用户查询文本(必填) - - top_k: 返回用于展示的路径数量(默认10) - - graph_timeout: 图谱检索超时时间,秒(默认2.0,暂未使用) - - entry_nodes: 入口节点信息(可选,不提供则从查询中提取) - - ========== ========== ========== ========== ========== ========== - """ - - start_time = time.time() - query = request.query - - # ========== 参数验证 ========== - if not query or not query.strip(): - raise HTTPException(status_code=400, detail="查询文本不能为空") - - query = query.strip() - - logger.info(f"[search_graph] 图谱检索请求: query='{query}', top_k={request.top_k}") - - try: - # ========== 检查依赖是否可用 ========== - if not GRAPH_AVAILABLE: - raise HTTPException( - status_code=503, - detail="图谱检索功能依赖未安装,请安装: pip install neo4j langchain langchain-community neo4j-graphrag jieba", - ) - - # ========== 初始化图谱服务(复用app.py的neo4j driver) ========== - # 注意:传入app.py中创建的driver,实现连接复用 - graph_service = GraphService(driver=driver) - - # ========== 执行图谱检索(简单版本:只判断统计/非统计) ========== - # 说明: - # - 直接调用 GraphService.search,自动判断统计/非统计查询类型 - # - query_type="auto" 会自动识别统计类查询(如"多少"、"比例"等)和明细类查询 - result = await graph_service.search( - query=query, - entry_nodes=request.entry_nodes, - top_k=request.top_k, - max_attempts=3, - query_type="auto", # 自动判断统计/非统计 - ) - - # ========== 确保返回格式一致 ========== - if not isinstance(result, dict): - result = { - "code": 200, - "message": "success", - "data": result if isinstance(result, (list, dict)) else ([] if isinstance(result, list) else {}), - "meta": {"elapsed_ms": round((time.time() - start_time) * 1000, 2)}, - } - - # 确保data存在,可以是列表或字典(新格式:包含 nodes、links、results 的对象) - if "data" not in result: - result["data"] = {} - # 注意:不再强制转换为列表,支持新的对象格式 - - # 统计结果数量(兼容新旧格式) - if isinstance(result.get("data"), list): - result_count = len(result["data"]) - elif isinstance(result.get("data"), dict): - # 新格式:统计 results 数组的长度 - result_count = len(result["data"].get("results", [])) - else: - result_count = 0 - - logger.info(f"[search_graph] 图谱检索完成: 返回 {result_count} 条结果") - return result - - except HTTPException: - raise - except Exception as e: - elapsed = time.time() - start_time - logger.error(f"[search_graph] 图谱检索失败 (耗时: {elapsed * 1000:.2f}ms): {e}", exc_info=True) - return { - "code": 500, - "message": "图谱检索失败", - "data": [], - "meta": {"elapsed_ms": round(elapsed * 1000, 2), "error": str(e), "query_type": "error"}, - } - - - -# ========== ========== ========== ========== ========== ========== -# Neo4j 索引创建接口 -# ========== ========== ========== ========== ========== ========== - - -class Neo4jIndexingRequest(BaseModel): - """Neo4j索引创建请求模型""" - - neo4j_uri: Optional[str] = None # 可选,如果不提供则从环境变量获取 - neo4j_username: Optional[str] = None # 可选,如果不提供则从环境变量获取 - neo4j_password: Optional[str] = None # 可选,如果不提供则从环境变量获取 - force_refresh: Optional[bool] = ( - False # 是否强制刷新所有索引(True=清空重建,False=增量更新,只处理新节点或缺失的索引) - ) -@app.post("/neo4j_indexing") -async def neo4j_indexing(request: Neo4jIndexingRequest): - """ - Neo4j知识图谱混合索引创建接口 - - 当前版本: - 只创建 Searchable 混合索引体系: - - 1. searchable_vector - - embedding语义检索 - - 2. searchable_name_fulltext - - 名称关键词检索 - - 3. searchable_fulltext - - 内容关键词检索 - """ - - start_time = time.time() - - logger.info("[neo4j_indexing] 收到索引创建请求") - - - # ============================== - # 防止并发创建索引 - # ============================== - - if _neo4j_indexing_lock.locked(): - logger.warning( - "[neo4j_indexing] 已有任务执行,拒绝请求" - ) - return JSONResponse( - status_code=409, - content={ - "code":409, - "message":"已有Neo4j索引创建任务正在执行", - "data":None - } - ) - async with _neo4j_indexing_lock: - try: - if not INDEXING_AVAILABLE: - raise HTTPException(status_code=503,detail="Neo4j索引模块不可用") - kwargs = { - "drop_old": True, - } - # 如果接口传入连接参数,则覆盖 - if request.neo4j_uri: - kwargs["uri"] = request.neo4j_uri - if request.neo4j_username: - kwargs["user"] = request.neo4j_username - if request.neo4j_password: - kwargs["password"] = request.neo4j_password - - result = await asyncio.to_thread(build_hybrid_indexes,**kwargs) - elapsed = time.time()-start_time - if result.get("success"): - logger.info( - f"[neo4j_indexing] 创建成功 " - f"耗时:{elapsed:.2f}s") - return { - "code":200, - "message":"success", - "data":{ - "success":True, - "message": - result.get("message","混合索引创建完成"), - "searchable_added": - result.get("searchable_added",0), - "elapsed_seconds": - round(elapsed,2) - } - } - else: - logger.error( - f"[neo4j_indexing] 创建失败:" - f"{result.get('message')}" - ) - return { - "code":207, - "message":"partial success", - "data":{ - "success":False, - "message": - result.get("message","未知错误"), - "searchable_added":0, - "elapsed_seconds":round(elapsed,2) - } - } - - except HTTPException: - raise - - except Exception as e: - elapsed=time.time()-start_time - error_msg=f"索引创建失败:{str(e)}" - logger.error(error_msg,exc_info=True) - return { - "code":500, - "message":"索引创建失败", - "data":{ - "success":False, - "message":error_msg, - "elapsed_seconds": - round(elapsed,2) - } - } - -# ========== ========== ========== ========== ========== ========== -# Neo4j 索引创建接口结束 -# ========== ========== ========== ========== ========== ========== - - -# ========== ========== ========== ========== ========== ========== -# fault 图谱检索接口 -# ========== ========== ========== ========== ========== ========== - - -class FaultGraphSearchRequest(BaseModel): - """Fault 图谱检索请求模型""" - - ship_number: Optional[str] = None - device_name: Optional[str] = None - fault_symptom: Optional[str] = None - - -@app.post("/fault_graph_search") -async def fault_graph_search(request: FaultGraphSearchRequest): - result = await fault_graph_reason_and_projects(request.ship_number, request.device_name, request.fault_symptom) - return result - - -# ========== ========== ========== ========== ========== ========== -# fault 图谱检索接口结束 -# ========== ========== ========== ========== ========== ========== - -# ========== ========== ========== ========== ========== ========== -# operation 图谱检索接口 -# ========== ========== ========== ========== ========== ========== - - -class OperationGraphSearchRequest(BaseModel): - """Operation 图谱检索请求模型""" - - ship_number: Optional[str] = None - device_name: Optional[str] = None - operation_item: Optional[str] = None - - -@app.post("/operation_graph_search") -async def operation_graph_search_endpoint(request: OperationGraphSearchRequest): - result = await operation_graph_search(request.ship_number, request.device_name, request.operation_item) - return result - - -# ========== ========== ========== ========== ========== ========== -# operation 图谱检索接口结束 -# ========== ========== ========== ========== ========== ========== - - -# ========== ========== ========== ========== ========== ========== -# 设备到系统反向检索接口 -# ========== ========== ========== ========== ========== ========== -from graph_search.device_to_system import find_system_by_device - -class DeviceToSystemRequest(BaseModel): - """设备到系统反向检索请求模型""" - device_name: Optional[str] = None - min_hops: Optional[int] = 2 - max_hops: Optional[int] = 8 - top_k: Optional[int] = 10 - -@app.post("/device_to_system") -async def device_to_system_endpoint(request: DeviceToSystemRequest): - """ - ========== ========== ========== ========== ========== ========== - 设备到系统反向检索接口 - - 功能:根据设备名称,使用混合检索找到设备节点,然后反向遍历找到对应的系统节点 - - 请求参数: - - device_name: 设备名称(必填) - - min_hops: 最小跳数(默认2级) - - max_hops: 最大跳数(默认8级) - - top_k: 混合检索返回的候选节点数量(默认10) - - 返回格式: - { - "success": true/false, - "device": {设备节点信息}, - "systems": [系统节点列表], - "graph": {节点和边的图谱数据}, - "meta": {元数据} - } - ========== ========== ========== ========== ========== ========== - """ - result = await find_system_by_device( - request.device_name, - min_hops=request.min_hops or 2, - max_hops=request.max_hops or 8, - top_k=request.top_k or 10, - driver=driver - ) - return result - -# ========== ========== ========== ========== ========== ========== -# 设备到系统反向检索接口结束 -# ========== ========== ========== ========== ========== ========== - -# ========== ========== ========== ========== ========== ========== -# 图册检索接口 -# ========== ========== ========== ========== ========== ========== -from graph_search.atlas_retrieval import find_atlas_by_nodes - -class AtlasRetrievalRequest(BaseModel): - """图册检索请求模型""" - node_names: Optional[List[str]] = None - top_k: Optional[int] = 10 - -@app.post("/atlas_retrieval") -async def atlas_retrieval_endpoint(request: AtlasRetrievalRequest): - """ - ========== ========== ========== ========== ========== ========== - 图册检索接口 - - 功能:根据节点名称(可以是系统、子系统或设备),使用混合检索匹配节点 - 然后找到一跳关系的图册节点,提取图册名称和PDF URL - - 请求参数: - - node_names: 节点名称列表(可以是系统、子系统或设备,必填) - - top_k: 混合检索返回的候选节点数量(默认10) - - 返回格式(层级结构): - { - "success": true/false, - "data": { - "节点名称1": { - "图册名称1": ["PDF_URL1", "PDF_URL2"], - "图册名称2": ["PDF_URL3"] - }, - "节点名称2": { - ... - } - } - } - ========== ========== ========== ========== ========== ========== - """ - result = await find_atlas_by_nodes( - node_names=request.node_names, - top_k=request.top_k or 10, - driver=driver - ) - return result - -# ========== ========== ========== ========== ========== ========== -# 图册检索接口结束 -# ========== ========== ========== ========== ========== ========== - - -# ====================================================== -# 处理excel解析请求 -# ====================================================== - - -@app.post("/api/v2/parse/excel") -async def parse_excel(file: UploadFile = File(...), sheet_name: Optional[str] = Form(None)): - """ - 解析Excel文件的API端点 - - Args: - file (UploadFile): 上传的Excel文件 - sheet_name (Optional[str]): 工作表名称 - - Returns: - JSONResponse: 解析结果 - """ - start_time = datetime.now() - try: - logger.info(f"Received request to parse Excel file: {file.filename}, sheet: {sheet_name}") - - # if not file.filename.endswith(".xlsx"): - # logger.warning(f"Invalid file type: {file.filename}") - # raise HTTPException(status_code=400, detail="仅支持 .xlsx 文件") - - # with tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") as tmp: - # tmp.write(await file.read()) - # tmp_path = tmp.name - # logger.info(f"Saved uploaded file to temporary path: {tmp_path}") - allowed_extensions = {".xlsx", ".xls"} - - # 获取文件扩展名,并转为小写 - file_ext = os.path.splitext(file.filename)[1].lower() - - if file_ext not in allowed_extensions: - logger.warning(f"Invalid file type: {file.filename}") - raise HTTPException(status_code=400, detail="仅支持 .xls 和 .xlsx 文件") - - with tempfile.NamedTemporaryFile(delete=False, suffix=file_ext) as tmp: - tmp.write(await file.read()) - tmp_path = tmp.name - logger.info(f"Saved uploaded file to temporary path: {tmp_path}") - - try: - df = read_excel_with_merged_cells(tmp_path, sheet_name) - rows = dataframe_to_row_json(df) - result = transform_excel_json(rows) - with open("output.json", "w", encoding="utf-8") as f: - json.dump(result, f, ensure_ascii=False, indent=2) - md_text = json_to_markdown(result) - with open("output.md", "w", encoding="utf-8") as f: - f.write(md_text) - processing_time = (datetime.now() - start_time).total_seconds() - logger.info(f"Successfully processed file in {processing_time:.2f}s, result length: {len(result)}") - - return JSONResponse( - { - "message": "success", - "data": result, - "markdown": md_text, - "processing_time": processing_time, - "row_count": len(result), - } - ) - - except Exception as e: - logger.error(f"Error processing Excel file: {e}") - logger.error(traceback.format_exc()) - raise HTTPException(status_code=500, detail=f"处理Excel文件时发生错误: {str(e)}") - - finally: - if os.path.exists(tmp_path): - os.remove(tmp_path) - logger.info(f"Removed temporary file: {tmp_path}") - - except HTTPException: - # 重新抛出HTTP异常,不记录为错误 - logger.warning(f"HTTP Exception: {traceback.format_exc()}") - raise - except Exception as e: - logger.error(f"Unexpected error in parse_excel: {e}") - logger.error(traceback.format_exc()) - raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}") - - -# ================== 请求模型 ================== -class CypherQueryRequest(BaseModel): - """Cypher 图谱问答请求模型""" - - query: Optional[str] = None - use_rerank: Optional[bool] = False - top_k: Optional[int] = 70 - fulltext_top_k: Optional[int] = 15 - rerank_top_k: Optional[int] = 15 - hops: Optional[int] = 3 - verbose: Optional[bool] = False # 接口默认关闭冗长日志 - -@app.post("/search_graph") -async def search_graph(request: CypherQueryRequest): - """ - Cypher 图谱问答接口 - """ - start_time = time.time() - query = request.query - - # 1. 基础校验 - if not query or not query.strip(): - raise HTTPException(status_code=400, detail="查询文本不能为空") - - query = query.strip() - logger.info(f"[query_cypher] 请求: query='{query}', use_rerank={getattr(request, 'use_rerank', False)}") - - # ========== 检查资源是否就绪 ========== - sync_driver = _resources.get("sync_driver") - async_driver = _resources.get("async_driver") - embedder = _resources.get("embedder") - - if sync_driver is None or async_driver is None or embedder is None: - raise HTTPException(status_code=503, detail="图谱服务未初始化,请稍后重试") - - # 初始化变量,防止 except 中引用未定义变量 - final_cypher = "" - elapsed_ms = 0.0 - nodes = [] - links = [] - text_results = "" - - try: - # ========== ① 实体检索 ========== - retrieval = await retrieve_entities( - query=query, - sync_driver=sync_driver, - async_driver=async_driver, - embedder=embedder, - hybrid_top_k=getattr(request, 'top_k', 40), - fulltext_top_k=getattr(request, 'fulltext_top_k', 15), - rerank_top_k=getattr(request, 'rerank_top_k', 15), - use_rerank=getattr(request, 'use_rerank', False), - hops=getattr(request, 'hops', 3), - verbose=getattr(request, 'verbose', False), - ) - # ========== ② 增加已提取实体的一跳关系提取 ========== - relations = await fetch_relations_among_results( - search_results=retrieval["search_results"], - async_driver=async_driver, - verbose=True, - ) - formatted_relations = format_relations(relations) - retrieval["formatted_relations"] = formatted_relations - - # ========== ② Cypher 生成 + 修复 + 查询 ========== - result = await query_with_cypher( - query=query, - retrieval_result=retrieval, - driver=async_driver, - verbose=getattr(request, 'verbose', False), - ) - - # ========== ③ 执行 Cypher 获取原始数据 ========== - final_cypher = result.get("final_cypher", result.get("original_cypher", "")) - - # 如果 Cypher 生成失败或为空 - if not final_cypher: - elapsed_ms = round((time.time() - start_time) * 1000, 2) - return { - "code": 200, - "message": "success", - "data": { - "nodes": [], - "links": [], - "results": "未能生成有效的 Cypher 查询语句" - }, - "meta": { - "elapsed_ms": elapsed_ms, - "result_count": 0, - "cypher": "", - "query_classification": result.get("query_classification") - } - } - - logger.info(f"[query_cypher] 准备执行 Cypher: {final_cypher}") - - # 执行 Cypher - excute_result = None - try: - # 假设 excute_cypher 是异步的,传入 async_driver - excute_result = await excute_cypher(async_driver, final_cypher) - except Exception as e: - logger.error(f"[query_cypher] excute_cypher 调用失败: {e},尝试降级为直接执行") - # 降级方案:直接使用 async_driver 执行原始 Cypher - try: - records, _, _ = await async_driver.execute_query(final_cypher) - # 将 Record 转换为 dict - excute_result = [r.data() for r in records] - except Exception as e2: - logger.error(f"[query_cypher] 降级执行也失败: {e2}") - excute_result = [] - - logger.info(f"[query_cypher] 执行结果类型: {type(excute_result)}") - - # ========== ④ 数据处理与格式化 (健壮性核心) ========== - - # A. 尝试从 result (LLM/GraphService 输出) 中提取结构化图数据 - # 优先使用 query_with_cypher 返回的可能存在的图结构 - if isinstance(result.get("data"), dict): - graph_data = result["data"] - nodes = graph_data.get("nodes", []) - links = graph_data.get("links", []) - text_results = graph_data.get("results", "") - - # B. 如果 result 中没有图数据,则处理 excute_result - # 注意:这里需要兼容 excute_result 的不同返回格式 - if not nodes and not links: - if isinstance(excute_result, dict): - # 情况1: excute_result 已经是格式化好的 {'data': {'nodes':..., 'links':..., 'results':...}} - if "data" in excute_result and isinstance(excute_result["data"], dict): - data_part = excute_result["data"] - nodes = data_part.get("nodes", []) - links = data_part.get("links", []) - # results 可能是字符串或列表 - res_val = data_part.get("results", "") - if isinstance(res_val, list): - text_results = json.dumps(res_val, ensure_ascii=False, indent=2) - else: - text_results = str(res_val) - # 情况2: excute_result 是 {'data': [rows]} 这种普通数据库返回 - elif "data" in excute_result and isinstance(excute_result["data"], list): - rows_data = excute_result["data"] - if rows_data: - text_results = json.dumps(rows_data[:50], ensure_ascii=False, indent=2) - else: - text_results = "查询无结果" - else: - # 其他字典结构,直接序列化 - text_results = json.dumps(excute_result, ensure_ascii=False, indent=2)[:2000] - - elif isinstance(excute_result, list): - # 情况3: 直接返回列表 - if excute_result: - text_results = json.dumps(excute_result[:50], ensure_ascii=False, indent=2) - else: - text_results = "查询无结果" - else: - text_results = str(excute_result) if excute_result else "查询无结果" - - # C. 计算耗时 - elapsed_ms = round((time.time() - start_time) * 1000, 2) - - # D. 构建 Meta - # 计算 result_count - count_val = 0 - if nodes: - count_val = len(nodes) - elif links: - count_val = len(links) - elif isinstance(excute_result, list): - count_val = len(excute_result) - elif isinstance(excute_result, dict) and "data" in excute_result and isinstance(excute_result["data"], list): - count_val = len(excute_result["data"]) - - meta = { - "elapsed_ms": elapsed_ms, - "result_count": count_val, - "cypher": final_cypher, - "query_type": "graph_search" if (nodes or links) else "cypher_query" - } - - if result.get("query_classification"): - meta["query_classification"] = result.get("query_classification") - - # ========== ⑤ 最终返回 ========== - return { - "code": 200, - "message": "success", - "data": { - "nodes": nodes, - "links": links, - "results": text_results, - }, - "meta": meta, - } - - except HTTPException: - raise - except Exception as e: - # 确保 elapsed_ms 有值 - if elapsed_ms == 0.0: - elapsed_ms = round((time.time() - start_time) * 1000, 2) - - logger.exception(f"[query_cypher] Critical Error: {str(e)}") - return { - "code": 500, - "message": f"Query failed: {str(e)}", - "data": { - "nodes": [], - "links": [], - "results": "" - }, - "meta": { - "elapsed_ms": elapsed_ms, - "result_count": 0, - "cypher": final_cypher, - "error": str(e) - } - } - - -# 接口:读取 kg_build 配置缓存 -@app.get("/kg_config_cache") -async def get_kg_config_cache(): - """返回最近一次通过 `/kg_build` 保存的配置缓存(kg_config_cache.json)。""" - try: - cache_path = os.path.join(DATA_DIR, "kg_config_cache.json") - if not os.path.exists(cache_path): - # 回退到代码目录中的缓存文件(如果 DATA_DIR 不可写或不存在) - cache_path = os.path.join(os.path.dirname(__file__), "kg_config_cache.json") - - if not os.path.exists(cache_path): - return JSONResponse({"code": 404, "message": "kg_config_cache.json 未找到", "data": None}, status_code=404) - - async with aiofiles.open(cache_path, "r", encoding="utf-8") as f: - raw = await f.read() - try: - data = json.loads(raw) - except Exception as e: - return JSONResponse({"code": 500, "message": f"解析缓存文件失败: {e}", "data": None}, status_code=500) - - return {"code": 200, "message": "success", "data": data} - except Exception as e: - return JSONResponse({"code": 500, "message": str(e), "data": None}, status_code=500) - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host="0.0.0.0", port=9085) diff --git a/chunk_text.py b/chunk_text.py index cb8668e..1b9a366 100644 --- a/chunk_text.py +++ b/chunk_text.py @@ -8,293 +8,20 @@ import re from typing import List, Dict, Optional, Union, Any, Tuple # 指定 JSON 文件路径 # file_path = '/storage01/home/hdf/project/wxkgrag/kgextract/output/122-06A0014-B01001_发动机-维修手册_content_list.json' -try: - from filename_proceess_and_kgquery import get_entity -except ImportError: - get_entity = None -from pathlib import PurePath, PurePosixPath, Path as PathLib +from pathlib import PurePath, Path as PathLib from fastapi import FastAPI, File, Path, UploadFile, HTTPException, Form, Request, Header, Body from fileparse_util import process_document -from io import BytesIO -from urllib.parse import unquote, urlparse -import asyncio -import base64 -import binascii import threading import aiofiles import httpx import logging -from rapidocr_onnxruntime import RapidOCR -from PIL import Image, ImageOps, UnidentifiedImageError -from config import ( - API_URLS, - IMAGE_DIR, - MAX_SPLIT_IMAGE_BASE64_CHARS, - MAX_SPLIT_IMAGE_BYTES, - MAX_SPLIT_IMAGE_INPUT_BYTES, - OCR_CONCURRENCY, - SPLIT_IMAGE_COMPRESS_THRESHOLD_BYTES, - SPLIT_IMAGE_JPEG_QUALITY, - SPLIT_IMAGE_MAX_DIMENSION, -) -try: - from config import SHIP_MODEL_NAME -except ImportError: - SHIP_MODEL_NAME = "" +from config import API_URLS logger = logging.getLogger(__name__) -ocr_engine = RapidOCR() -OCR_SEMAPHORE = asyncio.Semaphore(max(1, OCR_CONCURRENCY)) -_ocr_thread_lock = threading.Lock() -_image_ocr_cache: Dict[str, str] = {} -_image_ocr_cache_lock = threading.Lock() _api_url_inflight = [0] * len(API_URLS) _api_url_lock = threading.Lock() - -def _image_mime_type(suffix: str) -> str: - return { - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".bmp": "image/bmp", - ".webp": "image/webp", - ".gif": "image/gif", - ".tif": "image/tiff", - ".tiff": "image/tiff", - }.get((suffix or "").lower(), "image/png") - - -def _image_save_format(suffix: str) -> tuple[str, dict]: - suffix = (suffix or "").lower() - if suffix in {".jpg", ".jpeg"}: - return "JPEG", {"quality": SPLIT_IMAGE_JPEG_QUALITY, "optimize": True} - if suffix == ".webp": - return "WEBP", {"quality": SPLIT_IMAGE_JPEG_QUALITY, "method": 6} - if suffix == ".png": - return "PNG", {"optimize": True, "compress_level": 9} - if suffix in {".tif", ".tiff"}: - return "TIFF", {"compression": "tiff_lzw"} - if suffix == ".gif": - return "GIF", {"optimize": True} - if suffix == ".bmp": - return "BMP", {} - return "PNG", {"optimize": True, "compress_level": 9} - - -def _compression_suffix(suffix: str) -> str: - suffix = (suffix or "").lower() - if suffix in {".jpg", ".jpeg", ".png", ".webp"}: - return suffix - if suffix in {".bmp", ".gif", ".tif", ".tiff"}: - return ".png" - return ".png" - - -def _save_image_to_bytes(img: Image.Image, suffix: str) -> bytes: - image_format, save_options = _image_save_format(suffix) - if image_format in {"JPEG", "WEBP", "BMP"} and img.mode not in {"RGB", "L"}: - img = img.convert("RGB") - elif image_format in {"PNG", "TIFF", "GIF"} and img.mode not in {"RGB", "RGBA", "L", "P"}: - img = img.convert("RGBA") - - output = BytesIO() - img.save(output, format=image_format, **save_options) - return output.getvalue() - - -def _save_image_as_jpeg(img: Image.Image) -> bytes: - if img.mode not in {"RGB", "L"}: - img = img.convert("RGB") - last_bytes = b"" - for quality in (SPLIT_IMAGE_JPEG_QUALITY, 82, 74): - output = BytesIO() - img.save(output, format="JPEG", quality=quality, optimize=True) - last_bytes = output.getvalue() - if len(last_bytes) <= MAX_SPLIT_IMAGE_BYTES: - break - return last_bytes - - -def compress_image_bytes(image_bytes: bytes, suffix: str = "") -> tuple[bytes, str]: - if not image_bytes: - raise HTTPException(status_code=400, detail="decoded image is empty") - if len(image_bytes) > MAX_SPLIT_IMAGE_INPUT_BYTES: - raise HTTPException(status_code=413, detail="image input is too large") - - suffix = (suffix or "").lower() - try: - with Image.open(BytesIO(image_bytes)) as img: - img = ImageOps.exif_transpose(img) - max_side = max(img.size) - should_resize = SPLIT_IMAGE_MAX_DIMENSION > 0 and max_side > SPLIT_IMAGE_MAX_DIMENSION - should_reencode = len(image_bytes) > SPLIT_IMAGE_COMPRESS_THRESHOLD_BYTES - - if not should_resize and not should_reencode: - if len(image_bytes) > MAX_SPLIT_IMAGE_BYTES: - raise HTTPException(status_code=413, detail="image is too large") - return image_bytes, suffix - - if should_resize: - scale = SPLIT_IMAGE_MAX_DIMENSION / max_side - new_size = ( - max(1, int(img.width * scale)), - max(1, int(img.height * scale)), - ) - resample = getattr(getattr(Image, "Resampling", Image), "LANCZOS") - img = img.resize(new_size, resample) - - compressed_suffix = _compression_suffix(suffix) - compressed_bytes = _save_image_to_bytes(img, compressed_suffix) - - if len(compressed_bytes) > MAX_SPLIT_IMAGE_BYTES: - compressed_bytes = _save_image_as_jpeg(img) - compressed_suffix = ".jpg" - except UnidentifiedImageError as exc: - raise HTTPException(status_code=400, detail="image content is not a supported image") from exc - except HTTPException: - raise - except Exception as exc: - logger.warning(f"Failed to compress image, using original bytes: {exc}") - compressed_bytes = image_bytes - compressed_suffix = suffix - - if len(compressed_bytes) >= len(image_bytes) and len(image_bytes) <= MAX_SPLIT_IMAGE_BYTES: - return image_bytes, suffix - if len(compressed_bytes) > MAX_SPLIT_IMAGE_BYTES: - raise HTTPException(status_code=413, detail="image is too large after compression") - return compressed_bytes, compressed_suffix - - -def prepare_split_image(image_base64: str, suffix: str = "") -> tuple[bytes, str]: - raw = (image_base64 or "").strip() - if not raw: - raise HTTPException(status_code=400, detail="image_base64 is empty") - - if "," in raw and raw.split(",", 1)[0].lower().startswith("data:image"): - raw = raw.split(",", 1)[1] - - raw = "".join(raw.split()) - if len(raw) > MAX_SPLIT_IMAGE_BASE64_CHARS: - raise HTTPException(status_code=413, detail="image_base64 is too large") - - try: - image_bytes = base64.b64decode(raw, validate=True) - except (binascii.Error, ValueError) as exc: - raise HTTPException(status_code=400, detail="image_base64 is not valid base64") from exc - - return compress_image_bytes(image_bytes, suffix) - - -def decode_base64_image(image_base64: str, suffix: str = "") -> bytes: - image_bytes, _ = prepare_split_image(image_base64, suffix) - return image_bytes - - -def safe_original_filename(filename: str) -> str: - name = os.path.basename((filename or "").strip()) - if not name: - raise HTTPException(status_code=400, detail="filename is empty") - safe_name = re.sub(r"[^\w.\-\u4e00-\u9fff]+", "_", name).strip("._") - if not safe_name: - raise HTTPException(status_code=400, detail="filename is invalid") - return safe_name - - -def _strip_markdown_image_path(img_path: str) -> str: - value = (img_path or "").strip() - match = re.match(r"!\[[^\]]*\]\((.*?)\)", value) - return match.group(1).strip() if match else value - - -def resolve_local_image_path(img_path: str) -> Optional[PathLib]: - value = _strip_markdown_image_path(str(img_path or "")) - if not value: - return None - - parsed_path = unquote(urlparse(value).path or value) - marker = "/images/" - if marker in parsed_path: - relative_path = parsed_path.split(marker, 1)[1] - else: - normalized = parsed_path.replace("\\", "/").lstrip("/") - if normalized.startswith("images/"): - relative_path = normalized.split("/", 1)[1] - else: - relative_path = normalized - - relative_path = relative_path.replace("\\", "/").lstrip("/") - if not relative_path: - return None - - image_root = PathLib(IMAGE_DIR).resolve() - local_path = (image_root / PurePosixPath(relative_path)).resolve() - try: - local_path.relative_to(image_root) - except ValueError: - logger.warning(f"Image path is outside IMAGE_DIR and will be ignored: {img_path}") - return None - - return local_path if local_path.is_file() else None - - -def extract_image_text_sync(image_path: Union[str, PathLib]) -> dict: - resolved_path = str(PathLib(image_path).resolve()) - with _image_ocr_cache_lock: - cached_text = _image_ocr_cache.get(resolved_path) - if cached_text is not None: - return {"texts": [], "full_text": cached_text, "elapse": None} - - with _ocr_thread_lock: - ocr_result, elapse = ocr_engine(resolved_path) - - texts = [item[1] for item in (ocr_result or [])] - full_text = "图片包含的文字内容为:" + ",".join(texts) if texts else "" - with _image_ocr_cache_lock: - _image_ocr_cache[resolved_path] = full_text - return { - "texts": texts, - "full_text": full_text, - "elapse": elapse, - } - - -def build_image_markdown_with_ocr(markdown_image: str, local_image_path: Optional[PathLib]) -> str: - if "图片包含的文字内容为:" in markdown_image: - return markdown_image - if not local_image_path: - return markdown_image - - try: - ocr_data = extract_image_text_sync(local_image_path) - except Exception as exc: - logger.warning(f"Failed to OCR local image {local_image_path}: {exc}") - return markdown_image - - ocr_full_text = (ocr_data.get("full_text") or "").strip() - if not ocr_full_text: - return markdown_image - return f"{markdown_image}\n{ocr_full_text}" - - -def image_base64_to_data_url(image_base64: Union[str, bytes], suffix: str) -> str: - if isinstance(image_base64, bytes): - raw = base64.b64encode(image_base64).decode("ascii") - else: - raw = (image_base64 or "").strip() - if "," in raw and raw.split(",", 1)[0].lower().startswith("data:image"): - raw = raw.split(",", 1)[1] - raw = "".join(raw.split()) - - mime_type = _image_mime_type(suffix) - return f"data:{mime_type};base64,{raw}" - - -async def extract_image_text(image_path: PathLib) -> dict: - async with OCR_SEMAPHORE: - return await asyncio.to_thread(extract_image_text_sync, image_path) - def format_entity_text(data): # 1. 定义实体类型与属性的映射关系 # 格式: '实体类型': [ ('前缀1', '属性1'), ('前缀2', '属性2') ] @@ -982,35 +709,18 @@ def data_replace(data, prefix): 遍历 data 列表,若元素包含 'img_path' 字段,则移除前缀 'images/' 并拼接新前缀。 使用 pathlib 安全处理路径。 """ + from pathlib import PurePosixPath for ins in data: if isinstance(ins, dict) and "img_path" in ins: img_path = ins["img_path"] - if isinstance(img_path, list): - ins["img_path"] = "\n".join( - data_replace([{"img_path": str(item)}], prefix)[0]["img_path"] - for item in img_path - if str(item).strip() - ) - continue - - img_path = str(img_path) - if img_path.strip().startswith("!["): - local_image_path = resolve_local_image_path(img_path) - ins["img_path"] = build_image_markdown_with_ocr(img_path, local_image_path) - continue - p = PurePosixPath(img_path) # 如果以 images/ 开头,去掉第一级目录 if p.parts and p.parts[0] == "images": relative_path = str(PurePosixPath(*p.parts[1:])) - markdown_image = f"![图片]({prefix}{relative_path})" - local_image_path = resolve_local_image_path(relative_path) - ins["img_path"] = build_image_markdown_with_ocr(markdown_image, local_image_path) + ins["img_path"] = f"![图片]({prefix}{relative_path})" else: # 否则保留原路径(或按需处理) - markdown_image = f"![图片]({prefix}{img_path})" - local_image_path = resolve_local_image_path(img_path) - ins["img_path"] = build_image_markdown_with_ocr(markdown_image, local_image_path) + ins["img_path"] = f"![图片]({prefix}{img_path})" return data def filter_content_bbox(data, max_length=3000): @@ -1246,42 +956,6 @@ def merge_short_slices(slices, min_length=30,filename="122-06A0014-B01003_雷达 "positions": pending_positions }) - try: - final_result = get_entity(filename) - xinghao = find_ship_info_by_hull(SHIP_MODEL_NAME, final_result) - if xinghao is None: # 确保 xinghao 为 None 时不会报错 - xinghao = {"model_name": "", "ship_name": ""} - print("未找到匹配的舰船信息") - - # 安全处理 xinghao 为 None 的情况 - model_name = "" - if xinghao and 'model_name' in xinghao: - model_name = xinghao['model_name'] - - other_data = format_entity_text(final_result) - logger.info(f"文件名实体提取成功: {other_data}") - except Exception as e: - logger.warning(f"文件名实体提取失败: {e}") - other_data = "" - model_name = "" # 确保异常时 model_name 有定义 - - # 将提取的信息(如舰艇名、型号)注入到每个切片的开头 - for ins in result: - content = ins['content'] - # 如果没有提取到有效数据,则跳过注入 - - newline_idx = content.find('\n') - info = other_data - if model_name: - info += f',型号为{model_name}' - suffix = f'({info})' - - # 将信息插入到第一行末尾 - if newline_idx == -1: - ins['content'] = content + suffix - else: - ins['content'] = content[:newline_idx] + suffix + content[newline_idx:] - return result def find_and_read_content_list(directory, original_filename, encoding='utf-8'): """ @@ -1324,7 +998,8 @@ async def process_pdf_file(pdf_path: Path, image_prefix: str,filename:str) -> Op slices_check = chunk_check(slices, 8000) slices_check = merge_short_slices(slices_check, min_length=30,filename=filename) return {"slices": slices_check, "images": images} - + else: + return {"slices": [], "images": {}} api_url = get_api_url() try: async with aiofiles.open(pdf_path, "rb") as f: @@ -1346,9 +1021,8 @@ async def process_pdf_file(pdf_path: Path, image_prefix: str,filename:str) -> Op slices = get_chunk_bbox(replaced_content_list) slices_check = chunk_check(slices, 8000) slices_check = merge_short_slices(slices_check, min_length=30,filename=filename) - print(11111111111111111111111111111111111111) - print(len(images)) - return {"slices": slices_check, "images": images} + + return {"slices": [], "images": {}} except json.JSONDecodeError: logger.error("❌ 响应不是有效的 JSON 格式") @@ -1370,49 +1044,10 @@ async def process_other_file(pdf_path: Path, image_prefix: str, filename: str) - replaced_content_list = data_replace(content_list, image_prefix) slices = get_chunk_bbox(replaced_content_list) slices_check = chunk_check(slices, 8000) + slices_check = merge_short_slices(slices_check, min_length=30,filename=filename) return {"slices": slices_check, "images": images} - - api_url = get_api_url() - analyze_other_url = api_url.replace("/analyze-pdf", "/analyze-otherfile") - - mime_type, _ = mimetypes.guess_type(pdf_path.name) - content_type = mime_type or "application/octet-stream" - - try: - async with aiofiles.open(pdf_path, "rb") as f: - file_content = await f.read() - - files = {"file": (pdf_path.name, file_content, content_type)} - - async with httpx.AsyncClient(timeout=60 * 20) as client: - response = await client.post(analyze_other_url, files=files) - - if response.status_code != 200: - logger.error(f"❌ Office 文件 API 请求失败,状态码: {response.status_code}, 响应: {response.text}") - return None - - result = response.json() - data = result.get("data", {}) - content_list = data.get("content_list", []) - images = data.get("images", {}) - - # 后续的数据替换与切片处理逻辑 - replaced_content_list = data_replace(content_list, image_prefix) - slices = get_chunk_bbox(replaced_content_list) - slices_check = chunk_check(slices, 8000) - - return {"slices": slices_check, "images": images} - - except json.JSONDecodeError: - error_text = response.text if 'response' in locals() else "请求未到达服务器" - logger.error(f"❌ 响应不是有效的 JSON 格式: {error_text}") + else: return {"slices": [], "images": {}} - except Exception as e: - logger.error(f"处理 Office 文件时出错: {e}", exc_info=True) - return None - finally: - release_api_url(api_url) - if __name__ == "__main__": filepath = r"E:\ZKYNLP\Hjunproject\project0506\kgrag\122-06A0014-B01001_发动机-维修手册_content_list.json" diff --git a/config.py b/config.py index e530812..17bb047 100644 --- a/config.py +++ b/config.py @@ -228,18 +228,3 @@ API_URLS = [ #"http://192.168.0.111:9980/analyze-pdf", # "http://192.168.0.111:9975/analyze-pdf", ] -# ==================== 切片图片处理配置 ==================== -MAX_SPLIT_IMAGE_INPUT_BYTES = 50 * 1024 * 1024 -MAX_SPLIT_IMAGE_BYTES = 10 * 1024 * 1024 -MAX_SPLIT_IMAGE_BASE64_CHARS = (MAX_SPLIT_IMAGE_INPUT_BYTES * 4 // 3) + 4096 -SPLIT_IMAGE_COMPRESS_THRESHOLD_BYTES = MAX_SPLIT_IMAGE_BYTES -SPLIT_IMAGE_MAX_DIMENSION = 4096 -SPLIT_IMAGE_JPEG_QUALITY = 88 -OCR_CONCURRENCY = 1 -VLM_CONCURRENCY = 2 - -SHIP_MODEL_NAME = "/app/ship_xinghao.json" -TREE_JSON_PATH = "/app/tree_data.json" -# ==================== mineru和kgrag目录映射地址 ==================== -SEARCH_DIR ="/app/mineru_output" -IMAGE_DIR = "/app/mineru_output/images" diff --git a/filename_proceess_and_kgquery.py b/filename_proceess_and_kgquery.py deleted file mode 100644 index 017ee65..0000000 --- a/filename_proceess_and_kgquery.py +++ /dev/null @@ -1,857 +0,0 @@ -""" -PDF 用户上传接口(FastAPI) -- 处理文件名和其对应关系 -""" - -from typing import Dict, Tuple -import os -import re -from typing import Dict -from fastapi import FastAPI, HTTPException -import logging -import json -from modelsAPI.model_api import OpenaiAPI -from openai import OpenAI -from typing import Dict, List, Any -from config import TREE_JSON_PATH - -app = FastAPI(title="PDF Upload Service") -logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(name)s | %(message)s") -logger = logging.getLogger("filename_neo4j_process") - - -# ========================= -# 图方法 -# ========================= - - -def node_to_json(node): - props = dict(node) - # ks_raw = props.get("knowledge_source") - # knowledge_source = json.loads(ks_raw) if ks_raw else [] - - ks_raw = props.get("knowledge_source") - knowledge_source = [] - - if ks_raw and isinstance(ks_raw, str): - try: - ks_list = json.loads(ks_raw) - if isinstance(ks_list, list): - for ks in ks_list: - if isinstance(ks, dict): - ks.pop("info", None) - knowledge_source.append(ks) - except (json.JSONDecodeError, TypeError): - # 解析失败或类型错误时,保持 knowledge_source 为空列表 - pass - - name = props.get("名称") - props.pop("embedding", None) - props.pop("knowledge_source", None) - props.pop("name", None) # 现在安全地移除 - props.pop("fulltext", None) - if "last_updated" in props: - props["最后更新时间"] = props.pop("last_updated") - - if "created_at" in props: - props["创建时间"] = props.pop("created_at") - return { - "id": node.element_id, - "name": name, # 使用提前保存的值 - "labels": list(node.labels), - "knowledge_source": knowledge_source, - "properties": props, - } - - -def rel_to_json(rel): - props = dict(rel) - props.pop("embedding", None) - props.pop("fact_timeline", None) - return {"id": rel.element_id, "label": rel.type, "source": rel.start_node.element_id, "target": rel.end_node.element_id, "properties": props} - - -def is_simple_path(path): - """ - 判断是否为无环路径(simple path) - """ - seen = set() - for n in path.nodes: - nid = n.element_id - if nid in seen: - return False - seen.add(nid) - return True - -def build_tree(nodes: List[Dict], links: List[Dict]) -> List[Dict]: - """ - 按照固定层级构建树:舰船(根) -> 舰艇 -> 系统 -> 子系统 - 不再依赖 links 的连线,直接根据 labels 归类,彻底避免环状数据导致的死循环。 - 默认只展开第一艘舰艇的系统/子系统,其它舰艇 children 置空(前端可点击按需加载)。 - """ - - # 1. 辅助函数:判断标签是否包含关键字 - def has_label(node, keyword): - labels = node.get("labels", []) - if isinstance(labels, list): - return any(keyword in lbl for lbl in labels) - return False - - # 2. 辅助函数:构建标准的树节点格式 - def make_node(node_data): - return { - "id": node_data["id"], - "name": node_data.get("name", ""), - "labels": node_data.get("labels", []), - - "properties": node_data.get("properties", {}), - "color": node_data.get("color"), - "size": node_data.get("size"), - "children": [] - } - - # 3. 将节点按层级分类存储到字典中,方便快速查找 - fleet_roots = {} # 第零层:舰船/舰号(父根节点) - ships = {} # 第一层:舰艇 - systems = {} # 第二层:系统(不含子系统) - sub_systems = {} # 第三层:子系统 - - for node in nodes: - # 注意:判断逻辑要互斥,防止"子系统"被误判为"系统" - if has_label(node, "舰船") or has_label(node, "舰号"): - fleet_roots[node["id"]] = make_node(node) - elif has_label(node, "舰艇"): - ships[node["id"]] = make_node(node) - elif has_label(node, "子系统"): - sub_systems[node["id"]] = make_node(node) - elif has_label(node, "系统"): - systems[node["id"]] = make_node(node) - else: - pass - - # 4. 组装系统 -> 子系统、舰艇 -> 系统 关系(先把完整子树挂好) - for link in links: - if link.get("label") != "包含": - continue - - src_id = link["source"] - tgt_id = link["target"] - - if src_id in ships and tgt_id in systems: - ships[src_id]["children"].append(systems[tgt_id]) - elif src_id in systems and tgt_id in sub_systems: - systems[src_id]["children"].append(sub_systems[tgt_id]) - elif src_id in ships and tgt_id in sub_systems: - ships[src_id]["children"].append(sub_systems[tgt_id]) - - # 5. 所有舰艇 children 全部保留,仅用 collapsed 标记默认折叠状态。 - # 前端读取 collapsed=False 的舰艇默认展开,其它折叠; - # 用户点击折叠的舰艇时,前端切换 collapsed 即可展示子树。 - # 只保留名称包含 "122" 的舰艇(隐藏 JZ贱 等其它分支) - #sorted_ships = sorted( - # (s for s in ships.values() if "122" in s.get("name", "")), - # key=lambda s: s.get("name", ""), - #) - sorted_ships = sorted(ships.values(), key=lambda s: s.get("name", "")) - for idx, ship in enumerate(sorted_ships): - ship["collapsed"] = (idx != 0) - - # 6. 挂载到舰船根节点;如果数据里没有舰船根,就创建一个虚拟根 - if fleet_roots: - # 取第一个舰船根节点作为父(一般场景下只有一个) - root = next(iter(fleet_roots.values())) - root["children"] = sorted_ships - return [root] - else: - virtual_root = { - "id": "__fleet_root__", - "name": "舰号", - "labels": ["舰船"], - "properties": {}, - "color": None, - "size": None, - "children": sorted_ships, - } - return [virtual_root] -def build_tree1(nodes: List[Dict], links: List[Dict]) -> List[Dict]: - """ - 从 nodes + links 构建树结构。 - - 根节点:label 包含 '舰艇' 的节点 - - 父子关系:links 中 label == '包含' 的边 (source -> target) - - 支持多棵树(多个舰艇根节点) - """ - - # 1. 建立 id -> node 的映射 - node_map: Dict[str, Dict] = {n["id"]: n for n in nodes} - - # 2. 建立 父id -> [子id列表] 的邻接表(只处理"包含"关系) - children_map: Dict[str, List[str]] = {n["id"]: [] for n in nodes} - parent_map: Dict[str, str] = {} # 子id -> 父id,用于识别根节点 - - for link in links: - if link.get("label") == "包含": - src = link["source"] - tgt = link["target"] - if src in children_map: - children_map[src].append(tgt) - if tgt not in parent_map: - parent_map[tgt] = src - - # 3. 递归构建子树 - def build_subtree(node_id: str, ancestors: set = None) -> Dict[str, Any]: - if ancestors is None: - ancestors = set() - if node_id in ancestors: - return None - ancestors.add(node_id) - node = node_map[node_id] - subtree = {"id": node_id, "name": node.get("name", ""), "labels": node.get("labels", []), "properties": node.get("properties", {}), "color": node.get("color"), "size": node.get("size"), "children": []} - current_ancestors = ancestors | {node_id} - for child_id in children_map.get(node_id, []): - child = build_subtree(child_id, current_ancestors) - if child is not None: - subtree["children"].append(child) - return subtree - - # def build_subtree(node_id: str) -> Dict[str, Any]: - # node = node_map[node_id] - # subtree = { - # "id": node_id, - # "name": node.get("name", ""), - # "labels": node.get("labels", []), - # "properties": node.get("properties", {}), - # "color": node.get("color"), - # "size": node.get("size"), - # "children": [] - # } - # for child_id in children_map.get(node_id, []): - # subtree["children"].append(build_subtree(child_id)) - # return subtree - - # 4. 找出所有根节点:label 包含 '舰艇',且没有父节点 - roots = [n["id"] for n in nodes if "舰艇" in n.get("labels", []) and n["id"] not in parent_map] - - # 5. 为每棵树构建结构,并打上树编号 - forest = [] - for i, root_id in enumerate(roots): - tree = build_subtree(root_id) - tree["tree_index"] = i # 区分不同树 - forest.append(tree) - - return forest - - -def _filter_searchable(graph: dict) -> dict: - """剥掉节点的 Searchable 标签;若剥完后 labels 为空则整体移除该节点及其关联边""" - for n in graph["nodes"]: - n["labels"] = [l for l in n.get("labels", []) if l != "Searchable"] - valid_ids = {n["id"] for n in graph["nodes"] if n["labels"]} - return { - "nodes": [n for n in graph["nodes"] if n["id"] in valid_ids], - "links": [ - l for l in graph["links"] - if l["source"] in valid_ids and l["target"] in valid_ids - ], - } - - -def build_graph_from_paths(paths): - """ - 核心公共方法 - 从 Neo4j 路径结果构建 graphData - """ - node_map: Dict[str, dict] = {} - link_map: Dict[str, dict] = {} - - def add_edge(rel): - s = rel.start_node - t = rel.end_node - - if s.element_id not in node_map: - node_map[s.element_id] = node_to_json(s) - - if t.element_id not in node_map: - node_map[t.element_id] = node_to_json(t) - - if rel.element_id not in link_map: - link_map[rel.element_id] = rel_to_json(rel) - - for record in paths: - p = record["p"] - - if not is_simple_path(p): - continue - - for r in p.relationships: - add_edge(r) - - return _filter_searchable({"nodes": list(node_map.values()), "links": list(link_map.values())}) - - -# def fetch_graph_sample(driver,limit: int = 200): -# """提取采样逻辑为可复用函数""" -# with driver.session() as session: -# result = session.run(""" -# MATCH (n) -# WITH n -# ORDER BY elementId(n) ASC -# LIMIT $limit -# MATCH (n)-[rel]->(m) -# RETURN n, rel, m -# """, limit=limit) - -# node_map, link_map = {}, {} -# for rec in result: -# n, r, m = rec["n"], rec["rel"], rec["m"] -# node_map[n.element_id] = node_to_json(n) -# node_map[m.element_id] = node_to_json(m) -# link_map[r.element_id] = rel_to_json(r) - -# return { -# "nodes": list(node_map.values()), -# "links": list(link_map.values()) -# } - -# def fetch_graph_sample(driver, limit: int = 200): -# """ -# 获取采样数据: -# 1. 选取前 $limit 个种子节点(Level 0 或 1,取决于业务定义,这里定义种子为 Level 0)。 -# 2. 对每个节点向下探索最多 3 跳。 -# 3. 每个节点对象中增加 level 字段,表示其距离种子节点的深度。 -# """ -# with driver.session() as session: -# # Cypher 逻辑: -# # - 选出种子节点 n -# # - 匹配 1-3 跳路径 -# # - 返回种子节点 n,路径 path,以及该路径的长度(即层级) -# result = session.run(""" -# MATCH (n) -# WITH n ORDER BY elementId(n) ASC LIMIT $limit -# OPTIONAL MATCH path = (n)-[*1..3]-(m) -# UNWIND nodes(path) AS x -# WITH n, path, m, COUNT(DISTINCT x) AS nodeCount -# WHERE path IS NULL OR nodeCount = LENGTH(path) + 1 -# RETURN n, path, LENGTH(path) AS depth -# """, limit=limit) - -# node_map, link_map = {}, {} - -# for rec in result: -# seed_node = rec["n"] -# path = rec["path"] -# depth = rec["depth"] or 0 # 如果没有路径,深度为 0 - -# # 1. 处理种子节点 (Level 0) -# if seed_node.element_id not in node_map: -# node_data = node_to_json(seed_node) -# node_data["level"] = 0 # 种子节点设为 0 层 -# node_map[seed_node.element_id] = node_data - -# # 2. 如果存在路径,解析路径中的所有节点和关系 -# if path: -# # 路径中的节点处理 -# # path.nodes 包含了从起始到终点的所有节点 -# for i, node in enumerate(path.nodes): -# if node.element_id not in node_map: -# node_data = node_to_json(node) -# # 层级即为该节点在当前路径中的索引 -# node_data["level"] = i -# node_map[node.element_id] = node_data -# else: -# # 如果节点已存在,保留最小的 level (即最靠近种子的距离) -# node_map[node.element_id]["level"] = min(node_map[node.element_id].get("level", 3), i) - -# # 路径中的关系处理 -# for rel in path.relationships: -# if rel.element_id not in link_map: -# link_map[rel.element_id] = rel_to_json(rel) - -# return { -# "nodes": list(node_map.values()), -# "links": list(link_map.values()) -# } - - -# def fetch_graph_sample(driver, limit=200, max_depth=3): -# with driver.session() as session: -# result = session.run(""" -# MATCH (c) -# WITH c ORDER BY elementId(c) ASC LIMIT $limit - -# MATCH path = (c)-[*0..3]-(n) -# WITH n, MIN(length(path)) AS dist -# OPTIONAL MATCH (n)-[r]-(m) - -# RETURN n, dist, r, m -# """, limit=limit) - -# node_map, link_map = {}, {} - -# for rec in result: -# n = rec["n"] -# dist = rec["dist"] -# r = rec["r"] -# m = rec["m"] - -# # ---- 节点 ---- -# nid = n.element_id -# if nid not in node_map: -# node_data = node_to_json(n) -# node_data["level"] = min(dist, 3) if dist is not None else 0 -# node_map[nid] = node_data - -# # ---- 边 ---- -# if r and m: -# mid = m.element_id -# if mid not in node_map: -# node_map[mid] = node_to_json(m) - -# link_map.setdefault(r.element_id, rel_to_json(r)) - -# return { -# "nodes": list(node_map.values()), -# "links": list(link_map.values()) -# } - -def fetch_graph_sample(driver): - """ - 查询所有舰艇及其关联的系统和子系统 - 路径结构:(舰艇) -> (系统) -> (子系统) - """ - - with driver.session() as session: - # ========================= - # 统一查询:舰艇 -> 系统 -> 子系统 - # ========================= - # 逻辑说明: - # 1. MATCH (ship:舰艇):选中所有舰艇 - # 2. -[*1..3]->(target):查找深度为 1 到 3 的路径 - # - 深度 1:舰艇 -> 系统 - # - 深度 2:舰艇 -> 系统 -> 子系统 - # 3. WHERE target:系统 OR target:子系统:确保终点是我们关心的节点类型 - # (防止查询出其他无关的深层节点) - - query = """ - MATCH path = (ship:舰艇)-[*1..3]->(target) - WHERE target:系统 OR target:子系统 - RETURN path - """ - - result = session.run(query) - - # ========================= - # 解析 paths - # ========================= - all_nodes = {} - all_links = {} - - for record in result: - path = record["path"] - - # 解析节点 - for node in path.nodes: - # 兼容 ID 获取 - node_key = node.element_id if hasattr(node, 'element_id') else node.id - if node_key not in all_nodes: - all_nodes[node_key] = node_to_json(node) - - # 解析关系 - for rel in path.relationships: - rel_key = rel.element_id if hasattr(rel, 'element_id') else rel.id - if rel_key not in all_links: - all_links[rel_key] = rel_to_json(rel) - - return _filter_searchable({ - "nodes": list(all_nodes.values()), - "links": list(all_links.values()) - }) -def fetch_graph_sample1(driver): - """ - 查找路径: - 1. 优先:舰艇 -> 子系统 - 2. fallback:舰艇 -> 系统 - - 注意:根据数据库实际结构,使用 Label (:舰艇, :子系统) 进行匹配, - 而不是 WHERE category = '...' - """ - - # 定义采样数量 - SAMPLE_LIMIT = 400 - - with driver.session() as session: - # ========================= - # 第一阶段:舰艇 -> 子系统 - # ========================= - # 修改点:直接使用 (:舰艇) 和 (:子系统) 标签匹配,去掉 WHERE 子句 - result = session.run( - """ - MATCH (ship:舰艇) - WITH ship LIMIT $limit - - MATCH path = (ship)-[*1..3]->(sub:子系统) - RETURN path - """, - limit=SAMPLE_LIMIT, - ) - - paths = [record["path"] for record in result] - - # ========================= - # fallback:舰艇 -> 系统 - # ========================= - if not paths: - # 修改点:直接使用 (:舰艇) 和 (:系统) 标签匹配 - result = session.run( - """ - MATCH (ship:舰艇) - WITH ship LIMIT $limit - - MATCH path = (ship)-[*1..2]->(sys:系统) - RETURN path - """, - limit=SAMPLE_LIMIT, - ) - - paths = [record["path"] for record in result] - - # ========================= - # 解析 paths - # ========================= - all_nodes = {} - all_links = {} - - for path in paths: - # 节点 - for node in path.nodes: - # 兼容 Neo4j 5.x (element_id) 和 4.x (id) - node_key = node.element_id if hasattr(node, "element_id") else node.id - if node_key not in all_nodes: - all_nodes[node_key] = node_to_json(node) - - # 关系 - for rel in path.relationships: - rel_key = rel.element_id if hasattr(rel, "element_id") else rel.id - if rel_key not in all_links: - all_links[rel_key] = rel_to_json(rel) - - return {"nodes": list(all_nodes.values()), "links": list(all_links.values())} - - -# ============================= -# 文件名处理方法 -# ============================= - -# BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -# TREE_JSON_PATH = os.path.join(BASE_DIR, "tree_data.json") - - -def _load_tree_data() -> Dict: - # 注意:实际运行时请确保 result.json 存在,此处仅为代码结构展示 - if not os.path.exists(TREE_JSON_PATH): - return {} - with open(TREE_JSON_PATH, "r", encoding="utf-8") as f: - return json.load(f) - - -def _resolve_ship_root(data: Dict, ship_code: str) -> Dict: - raw = data.get(ship_code) - if not isinstance(raw, dict): - return {} - - # 结构 1:直接是节点 {"code","name","children"} - if {"code", "name", "children"}.issubset(raw.keys()): - return raw - - # 结构 2:包装层 {"101": {...root node...}} - if ship_code in raw and isinstance(raw[ship_code], dict): - node = raw[ship_code] - if {"code", "name", "children"}.issubset(node.keys()): - return node - - # 兜底:取第一个 node-like 值 - for value in raw.values(): - if isinstance(value, dict) and {"code", "name", "children"}.issubset(value.keys()): - return value - - return {} - - -def _longest_common_substring_len(a: str, b: str) -> int: - if not a or not b: - return 0 - # 优化:确保 a 是较短的字符串以节省空间(可选),原逻辑保持不动也没问题 - dp = [0] * (len(b) + 1) - best = 0 - for i in range(1, len(a) + 1): - prev = 0 - for j in range(1, len(b) + 1): - temp = dp[j] - if a[i - 1] == b[j - 1]: - dp[j] = prev + 1 - if dp[j] > best: - best = dp[j] - else: - dp[j] = 0 - prev = temp - return best - - -def _match_level4_tool(filename_text: str, device_node: Dict) -> Tuple[str, str]: - """ - 匹配 Level 4 零件。 - 规则:如果文件名与 Level 3 (设备名) 的最大共同字符串长度 >= 与任何 Level 4 (零件名) 的长度, - 则只匹配到 Level 3,返回空。 - 只有当 Level 4 的匹配度严格高于 Level 3 时,才返回 Level 4 信息。 - """ - children = device_node.get("children") or {} - - # 1. 计算文件名与当前设备 (Level 3) 名称的匹配度 - device_name = str(device_node.get("name") or "") - level3_score = _longest_common_substring_len(filename_text, device_name) - - best_name = "" - best_code = "" - best_score = 0 # 记录 Level 4 中的最佳得分 - - # 2. 遍历 Level 4 子节点 - for child in children.values(): - tool_name = str(child.get("name") or "") - tool_code = str(child.get("code") or "") - - score = _longest_common_substring_len(filename_text, tool_name) - - # 关键修改:只有当 Level 4 的得分严格大于 Level 3 的得分时,才视为有效匹配 - # 并且要比当前找到的其他 Level 4 更好 - if score > level3_score and score > best_score: - best_score = score - best_name = tool_name - best_code = tool_code - - # 如果没有找到比 Level 3 匹配度更高的 Level 4,则返回空 - if best_score <= level3_score: - return "", "" - - return best_name, best_code - - -def process_filename(filename: str) -> Dict[str, str]: - name, _ = os.path.splitext(os.path.basename(filename)) - parts = re.split(r"[_-]", name) - - xian_number = "" - level_1_system_name = "" - level_2_system_name = "" - device_name = "" - tool_name = "" - tool_code = "" - - if not parts: - return {} - - xian_number_code = parts[0].strip() - level1_code = "" - level2_code = "" - device_code = "" - - if len(parts) > 1: - part = parts[1].strip() - # 防止索引越界 - if len(part) < 2: - return {} - - level1_code = part[:2] - level2_code = part[2:4] if len(part) > 2 else "" - device_code = part[4:] if len(part) > 4 else "" - # 若 parts[2] 存在,则用 parts[2] 作为 device_code(支持 122-06A0014-B01001_发动机 格式) - if len(parts) > 2: - device_code_alt = parts[2].strip() - if device_code_alt: - device_code = device_code_alt - - data = _load_tree_data() - root = _resolve_ship_root(data, xian_number_code) - if not root: - return {} - - xian_number = root.get("name", "") - - # 一级 - s1 = root.get("children", {}).get(level1_code) - if s1: - level_1_system_name = s1.get("name", "") - - # 二级 - s2 = s1.get("children", {}).get(level2_code) - if s2: - level_2_system_name = s2.get("name", "") - - # 三级设备 - device = s2.get("children", {}).get(device_code) - if device: - device_name = device.get("name", "") - # 若存在 level4,匹配与文件名最大相同字符串的零件 - # 内部已包含逻辑:如果设备名匹配度更高,则不返回零件 - tool_name, tool_code = _match_level4_tool(name, device) - - return { - "Xian_Number": xian_number, - "Xian_Number_code": xian_number_code, - "Level_1_System_Name": level_1_system_name, - "level1_code": level1_code, - "Level_2_System_Name": level_2_system_name, - "level2_code": level2_code, - "Device_Name": device_name, - "device_code": device_code, - "tool_name": tool_name, - "tool_code": tool_code, - } - - -def get_entity(filename): - result = process_filename(filename) - entities = [] - relationships = [] - low_level = "" - - if result: - xian_number = result.get("Xian_Number") - xian_number_code = result.get("Xian_Number_code") - level_1_system_name = result.get("Level_1_System_Name") - level1_code = result.get("level1_code") - level_2_system_name = result.get("Level_2_System_Name") - level2_code = result.get("level2_code") - device_name = result.get("Device_Name") - device_code = result.get("device_code") - tool_name = result.get("tool_name") - tool_code = result.get("tool_code") - - if xian_number: - entities.append( - { - "type": "舰艇", - "properties": { - "名称": xian_number, - "舷号": xian_number_code, - }, - } - ) - low_level = xian_number - - if level_1_system_name: - entities.append( - { - "type": "系统", - "properties": { - "名称": level_1_system_name, - "系统编码": level1_code, - }, - } - ) - low_level = level_1_system_name - - if xian_number and level_1_system_name: - relationships.append( - { - "type": "包含", - "from_entity": xian_number, - "to_entity": level_1_system_name, - } - ) - - if level_2_system_name: - entities.append( - { - "type": "子系统", - "properties": { - "名称": level_2_system_name, - "子系统编码": level2_code, - }, - } - ) - low_level = level_2_system_name - - if level_1_system_name and level_2_system_name: - relationships.append( - { - "type": "包含", - "from_entity": level_1_system_name, - "to_entity": level_2_system_name, - } - ) - - if device_name: - entities.append( - { - "type": "设备", - "properties": { - "名称": device_name, - "设备编码": device_code, - }, - } - ) - low_level = device_name - - if level_2_system_name and device_name: - relationships.append( - { - "type": "包含", - "from_entity": level_2_system_name, - "to_entity": device_name, - } - ) - - if tool_name: - entities.append( - { - "type": "零件", - "properties": { - "名称": tool_name, - "零件编码": tool_code, - }, - } - ) - low_level = tool_name - - if device_name and tool_name: - relationships.append( - { - "type": "包含", - "from_entity": device_name, - "to_entity": tool_name, - } - ) - - final_result = { - "entities": entities, - "relationships": relationships, - "low_level": low_level, - } - - return final_result - - -# 示例测试逻辑(非必须,仅供验证) -if __name__ == "__main__": - # 阀控蓄电池脉冲式快速充电装置 - test_list = [ - "163-06A0015-B01001_发动机-维修手册.pdf", - - ] - for i in test_list: - result = get_entity(i) - lower_entity = result.get("low_level") - print(result) - print(lower_entity) - #from neo4j import GraphDatabase - - #NEO4J_URI = "bolt://192.168.0.111:7687" - #NEO4J_USER = os.getenv("NEO4J_USER", "neo4j") - #NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD","zdht123@") # 不设默认值,强制要求提供 - #NEO4J_DATABASE = os.getenv("NEO4J_DATABASE", "neo4j") - #driver = GraphDatabase.driver( - # NEO4J_URI, - # auth=(NEO4J_USER, NEO4J_PASSWORD), - # database=NEO4J_DATABASE - #) - #res = fetch_graph_sample(driver) - #print(res) diff --git a/fileparse_util.py b/fileparse_util.py index 26e9ffc..723d7cb 100644 --- a/fileparse_util.py +++ b/fileparse_util.py @@ -5,7 +5,7 @@ import asyncio import logging from typing import Optional, Tuple, Dict import aiofiles # pip install aiofiles -from config import SEARCH_DIR,IMAGE_DIR + logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -103,6 +103,7 @@ async def encode_images_to_base64( async def process_document( input_file_name: str, + search_dir: Optional[str] = "/app/mineru_output", local_image_dir: Optional[str] = None, concurrency: int = 32, ) -> Optional[Tuple[list, Dict[str, str]]]: @@ -119,7 +120,6 @@ async def process_document( 成功: (content_list, images_dict) 失败: None """ - search_dir = SEARCH_DIR content, content_path = await find_and_read_content_list(search_dir, input_file_name) if content is None: logger.error("❌ 未找到指定的 _content_list.json 文件。") diff --git a/jpgextract.py b/jpgextract.py deleted file mode 100644 index 9820d24..0000000 --- a/jpgextract.py +++ /dev/null @@ -1,14 +0,0 @@ -from rapidocr_onnxruntime import RapidOCR - -engine = RapidOCR() -ocr_result, elapse = engine(r"E:\ZKYNLP\aidocproject\audiotransaction\gwdoc\图片.png") - -texts = [item[1] for item in (ocr_result or [])] -full_text = "图片包含的文字内容为:"+",".join(texts) - - - -print("\n合并文本:") -print(full_text) - -print("\n耗时:", elapse) diff --git a/modelsAPI/__pycache__/__init__.cpython-311.pyc b/modelsAPI/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 9f49d21..0000000 Binary files a/modelsAPI/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/modelsAPI/__pycache__/model_api.cpython-311.pyc b/modelsAPI/__pycache__/model_api.cpython-311.pyc deleted file mode 100644 index 2fe9e70..0000000 Binary files a/modelsAPI/__pycache__/model_api.cpython-311.pyc and /dev/null differ diff --git a/modelsAPI/model_api.py b/modelsAPI/model_api.py index bed5d6e..e55e56b 100644 --- a/modelsAPI/model_api.py +++ b/modelsAPI/model_api.py @@ -5,6 +5,7 @@ import os import numpy as np from openai import OpenAI from config import LLM_CONFIG, EMBEDDING_CONFIG +from neo4j_graphrag.embeddings.base import Embedder from openai import AsyncOpenAI @@ -140,7 +141,7 @@ class OpenaiAPI: # 2. 构建强约束的 System Prompt # 核心目标:禁止思考标签,禁止废话,只给结果 system_prompt = ( - "你是一个视觉分析专家。你的任务是从图片中识别内容并进行描述。\n" + "你是一个工业视觉分析专家。你的任务是从图片中识别设备并诊断故障。\n" "【严格约束】\n" "1. 绝对禁止输出 , , 等任何思考过程标签。\n" "2. 绝对禁止输出'好的'、'根据图片'、'分析如下'等开场白或结束语。\n" @@ -150,7 +151,10 @@ class OpenaiAPI: # 3. 构建针对性的 User Prompt default_task = ( "请分析这张图片,描述图片内容,重点关注以下信息\n" - "1. 图片整体阐述了什么主题,描述了哪些内容\n" + "1. 设备识别:图中是什么设备?型号或标签是否可见?\n" + "2. 状态评估:仪表盘数值是否在正常区间?指示灯颜色是什么?\n" + "3. 异常检测:是否存在漏油、生锈、电缆破损、螺丝松动或烟雾?\n" + "4. 环境风险:周围是否有杂物堆放或安全隐患?\n" "请用专业、客观、简短的语言描述。" ) @@ -181,7 +185,7 @@ class OpenaiAPI: kwargs["extra_body"] = {"chat_template_kwargs": {"enable_thinking": False}} try: - print(f"🚀 正在调用 {model} 进行图片内容分析...") + print(f"🚀 正在调用 {model} 进行设备故障分析...") response = await client.chat.completions.create(**kwargs) raw_content = response.choices[0].message.content or "" @@ -190,7 +194,7 @@ class OpenaiAPI: except Exception as e: import traceback - error_msg = f"❌ 图片内容分析失败:{str(e)}\n{traceback.format_exc()}" + error_msg = f"❌ 设备故障分析失败:{str(e)}\n{traceback.format_exc()}" print(error_msg) return f"Error: {str(e)}" @@ -349,7 +353,24 @@ class OpenaiAPI: return 0.5 * jaccard + 0.5 * len_penalty +class LocalBgeM3Embeddings(Embedder): + def __init__(self, base_url: str, api_key: str, model_name: str = "bge-m3"): + self.base_url = base_url + self.api_key = api_key + self.model_name = model_name + def embed_query(self, text: str) -> List[float]: + return self.embed_documents([text])[0] + + def embed_documents(self, texts: List[str]) -> List[List[float]]: + url = self.base_url + with httpx.Client(timeout=60) as client: + response = client.post( + url, + json={"model": self.model_name, "input": texts}, + headers={"Authorization": f"Bearer {self.api_key}"}, + ) + return [item["embedding"] for item in response.json()["data"]] if __name__ == "__main__": diff --git a/received_images/88095d35078c40adb36984cb5090527d/图片.png b/received_images/88095d35078c40adb36984cb5090527d/图片.png deleted file mode 100644 index 268f4d8..0000000 Binary files a/received_images/88095d35078c40adb36984cb5090527d/图片.png and /dev/null differ diff --git a/test.png b/test.png deleted file mode 100644 index 65130cf..0000000 Binary files a/test.png and /dev/null differ diff --git a/test2.jpg b/test2.jpg deleted file mode 100644 index e89439b..0000000 Binary files a/test2.jpg and /dev/null differ diff --git a/tools/__pycache__/__init__.cpython-311.pyc b/tools/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 987c21c..0000000 Binary files a/tools/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/fault_record_db.cpython-311.pyc b/tools/__pycache__/fault_record_db.cpython-311.pyc deleted file mode 100644 index 40f8e4a..0000000 Binary files a/tools/__pycache__/fault_record_db.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/fault_statistics.cpython-311.pyc b/tools/__pycache__/fault_statistics.cpython-311.pyc deleted file mode 100644 index 2cb87c5..0000000 Binary files a/tools/__pycache__/fault_statistics.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/function_tool.cpython-311.pyc b/tools/__pycache__/function_tool.cpython-311.pyc deleted file mode 100644 index 1b67576..0000000 Binary files a/tools/__pycache__/function_tool.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/graph_tools.cpython-311.pyc b/tools/__pycache__/graph_tools.cpython-311.pyc deleted file mode 100644 index 07cbc65..0000000 Binary files a/tools/__pycache__/graph_tools.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/rag_tools.cpython-311.pyc b/tools/__pycache__/rag_tools.cpython-311.pyc deleted file mode 100644 index c26b31b..0000000 Binary files a/tools/__pycache__/rag_tools.cpython-311.pyc and /dev/null differ diff --git a/tools/__pycache__/vlm_tools.cpython-311.pyc b/tools/__pycache__/vlm_tools.cpython-311.pyc deleted file mode 100644 index b4a64f7..0000000 Binary files a/tools/__pycache__/vlm_tools.cpython-311.pyc and /dev/null differ diff --git a/utils/__pycache__/__init__.cpython-311.pyc b/utils/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 201355b..0000000 Binary files a/utils/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/utils/__pycache__/function_tracker.cpython-311.pyc b/utils/__pycache__/function_tracker.cpython-311.pyc deleted file mode 100644 index c62eef0..0000000 Binary files a/utils/__pycache__/function_tracker.cpython-311.pyc and /dev/null differ diff --git a/utils/__pycache__/image_utils.cpython-311.pyc b/utils/__pycache__/image_utils.cpython-311.pyc deleted file mode 100644 index 35d1951..0000000 Binary files a/utils/__pycache__/image_utils.cpython-311.pyc and /dev/null differ diff --git a/utils/__pycache__/intent_matcher.cpython-311.pyc b/utils/__pycache__/intent_matcher.cpython-311.pyc deleted file mode 100644 index 3ec07b9..0000000 Binary files a/utils/__pycache__/intent_matcher.cpython-311.pyc and /dev/null differ diff --git a/utils/__pycache__/word_generator.cpython-311.pyc b/utils/__pycache__/word_generator.cpython-311.pyc deleted file mode 100644 index a53ac51..0000000 Binary files a/utils/__pycache__/word_generator.cpython-311.pyc and /dev/null differ diff --git a/workflows/__pycache__/__init__.cpython-311.pyc b/workflows/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 0f156f6..0000000 Binary files a/workflows/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/workflows/__pycache__/history_manager.cpython-311.pyc b/workflows/__pycache__/history_manager.cpython-311.pyc deleted file mode 100644 index f72067f..0000000 Binary files a/workflows/__pycache__/history_manager.cpython-311.pyc and /dev/null differ diff --git a/workflows/__pycache__/workflow_baike.cpython-311.pyc b/workflows/__pycache__/workflow_baike.cpython-311.pyc deleted file mode 100644 index affe960..0000000 Binary files a/workflows/__pycache__/workflow_baike.cpython-311.pyc and /dev/null differ diff --git a/workflows/__pycache__/workflow_fault_diagnosis.cpython-311.pyc b/workflows/__pycache__/workflow_fault_diagnosis.cpython-311.pyc deleted file mode 100644 index 1bd323c..0000000 Binary files a/workflows/__pycache__/workflow_fault_diagnosis.cpython-311.pyc and /dev/null differ diff --git a/workflows/__pycache__/workflow_utils.cpython-311.pyc b/workflows/__pycache__/workflow_utils.cpython-311.pyc deleted file mode 100644 index 0ec044c..0000000 Binary files a/workflows/__pycache__/workflow_utils.cpython-311.pyc and /dev/null differ diff --git a/船舶图片.png b/船舶图片.png deleted file mode 100644 index 268f4d8..0000000 Binary files a/船舶图片.png and /dev/null differ