2025-07-25 13:28:47 +08:00
< template >
< div class = "editor-container" >
2025-10-11 11:08:42 +08:00
<!-- < router-link to = "/WangG2" > Wang2 2 页面 < / router-link >
< router-link to = "/WangG3" > Wang3 3 页面 < / router-link > -- >
<!-- < router-link to = "/WangG4" > Wang34 4 页面 < / router-link > -- >
2025-09-15 09:58:52 +08:00
<!-- 左侧操作框 -- >
2025-10-11 11:08:42 +08:00
<!-- < div class = "leftDiv" v -if = ' isLoadXml ' :style = "{'maxHeight':leftHeight+'px','minHeight':'100px'}" > -- >
<!-- < a href = "/#/wangG2" target = "_blank" > asdasda < / a > -- >
< div class = "leftDiv" v -if = ' isLoadXml ' >
2025-09-15 09:58:52 +08:00
< div id = 'navMain' >
<!-- 操作栏 -- >
< div class = "operation-buttons" >
<!-- 节点搜索框 -- >
2025-10-11 11:08:42 +08:00
< div style = "margin:5px auto;" >
2025-09-15 09:58:52 +08:00
< el-input
placeholder = "输入节点名称搜索"
v - model = "searchText"
class = "search-input"
clearable
@ clear = "handleSearchClear"
@ keyup . enter = "handleSearch" >
< el-button slot = "append" icon = "el-icon-search" @click ="handleSearch" > < / el -button >
< / el-input >
< / div >
<!-- 操作栏按钮 -- >
2025-10-11 11:08:42 +08:00
< div style = "display:flex;margin-bottom: 5px;" >
< div style = "width:25%;height:30px;" class = "iconImgDiv" @click ="showAddDialog('create')" title = '新建' v -if = ' isLoadXml ' > < img class = 'iconImg' title = '新建' src = "../assets/img/addIcon.png" alt = "" > < / div >
< div style = "width:25%;height:30px;" class = "iconImgDiv" @click ="showAddDialog('edit')" title = '编辑' v -if = ' currentNode ' > < img class = 'iconImg' title = '编辑' src = "../assets/img/editIcon.png" alt = "" > < / div >
< div style = "width:25%;height:30px;" class = "iconImgDiv" @click ="saveNowDmcClick" title = '保存' v -if = ' currentNode ' > < img class = 'iconImg' title = '保存' src = "../assets/img/saveIcon.png" alt = "" > < / div >
< div style = "width:25%;height:30px;" class = "iconImgDiv" @click ="deleteDialog" title = '删除' v -if = ' currentNode ' > < img class = 'iconImg' title = '删除' src = "../assets/img/delIcon.png" alt = "" > < / div >
< / div >
2025-09-15 09:58:52 +08:00
< / div >
2025-10-11 11:08:42 +08:00
<!-- 'maxHeight' : leftHeight + 'px' , -- >
< div class = "tree-container" :style = "{'minHeight':'100px'}" >
< div class = "navTitle" >
< p @ click = 'clearNodeState' :title = "getBookName" > { { getBookName } } < / p >
< img @ click = 'editBookName' class = 'iconImgMulu' title = '编辑书名' src = "../assets/img/bianji.png" alt = "" >
< / div >
<!-- 目录结构树 -- >
< el-tree
class = "elTree elTreeMain gd"
2025-09-15 09:58:52 +08:00
ref = "tree"
: data = "treeData"
node - key = "id"
icon - class = "el-icon-arrow-right"
: default - expand - all = "true"
: props = "defaultProps"
2025-10-11 11:08:42 +08:00
: filter - node - method = "filterNode"
@ node - click = "handleNodeClick"
@ node - drag - end = "handleDragEnd"
@ node - contextmenu = "handleNodeContextMenu"
: expand - on - click - node = "false"
: highlight - current = "true"
draggable
2025-09-15 09:58:52 +08:00
>
2025-10-11 11:08:42 +08:00
<!-- 节点自定义渲染插槽 -- >
< span slot -scope = " { data } " >
<!-- ( 1 ) 原有节点图标 + 名称渲染逻辑 -- >
< template v-if = "data.children && data.children.length > 0" >
<!-- 父节点 ( 有子节点 ) -- >
< div >
< i class = "el-icon-folder" : style = "'font-size: 14px; padding: 0 5px 0 5px'" / >
< i class = "el-icon-warning changeState" @click.stop ="handleModify(data)" v-if = "showModifyBtn && hasMinorVersion01(data)" :style="'font-size: 14px; padding: 0 5px 0 5px'" />
< span : title = "data.id + '-' + data.name" : class = "{ 'highlight': isHighlight(data) }" >
{ { data . name } }
< / span >
<!-- ( 关键 ) 条件显示 【 修改 】 : 检查状态开启 + 当前节点 / 子节点有minorVersion : 01 -- >
<!-- < span
class = "modify-btn"
v - if = "showModifyBtn && hasMinorVersion01(data)"
@ click . stop = "handleModify(data)"
>
【 修改 】
< / span > -- >
< / div >
< / template >
< template v-else >
<!-- 叶子节点 ( 无子节点 ) -- >
< div style = "margin-left: 0px;" >
< i class = "leaf-node-line" > < / i >
< i class = "el-icon-document" : style = "'padding: 0 5px 0 5px'" > < / i >
<!-- < svg viewBox = "64 64 896 896" data -icon = " deployment -unit " width = "1em" height = "1em" fill = "currentColor" aria -hidden = " true " focusable = "false" class = "" >
< path d = "M888.3 693.2c-42.5-24.6-94.3-18-129.2 12.8l-53-30.7V523.6c0-15.7-8.4-30.3-22-38.1l-136-78.3v-67.1c44.2-15 76-56.8 76-106.1 0-61.9-50.1-112-112-112s-112 50.1-112 112c0 49.3 31.8 91.1 76 106.1v67.1l-136 78.3c-13.6 7.8-22 22.4-22 38.1v151.6l-53 30.7c-34.9-30.8-86.8-37.4-129.2-12.8-53.5 31-71.7 99.4-41 152.9 30.8 53.5 98.9 71.9 152.2 41 42.5-24.6 62.7-73 53.6-118.8l48.7-28.3 140.6 81c6.8 3.9 14.4 5.9 22 5.9s15.2-2 22-5.9L674.5 740l48.7 28.3c-9.1 45.7 11.2 94.2 53.6 118.8 53.3 30.9 121.5 12.6 152.2-41 30.8-53.6 12.6-122-40.7-152.9zm-673 138.4a47.6 47.6 0 0 1-65.2-17.6c-13.2-22.9-5.4-52.3 17.5-65.5a47.6 47.6 0 0 1 65.2 17.6c13.2 22.9 5.4 52.3-17.5 65.5zM522 463.8zM464 234a48.01 48.01 0 0 1 96 0 48.01 48.01 0 0 1-96 0zm170 446.2l-122 70.3-122-70.3V539.8l122-70.3 122 70.3v140.4zm239.9 133.9c-13.2 22.9-42.4 30.8-65.2 17.6-22.8-13.2-30.7-42.6-17.5-65.5s42.4-30.8 65.2-17.6c22.9 13.2 30.7 42.5 17.5 65.5z" > < / path >
< / svg > -- >
<!-- < i : style = "'font-size: 13px; padding: 0 5px 0 5px'" >
< / i > -- >
< i class = "el-icon-warning changeState" @click.stop ="handleModify(data)" v-if = "showModifyBtn && hasMinorVersion01(data)" :style="'font-size: 14px; padding: 0 5px 0 5px'" />
< span : title = "data.id + '-' + data.name" : class = "{ 'highlight': isHighlight(data) }" >
{ { data . name } }
< / span >
<!-- ( 关键 ) 叶子节点同样条件显示 【 修改 】 -- >
<!-- < span
class = "modify-btn"
v - if = "showModifyBtn && hasMinorVersion01(data)"
@ click . stop = "handleModify(data)"
>
【 修改 】
< / span > -- >
< / div >
< / template >
2025-09-15 09:58:52 +08:00
< / span >
2025-10-11 11:08:42 +08:00
< / el-tree >
2025-09-15 09:58:52 +08:00
< / div >
< / div >
<!-- < div id = 'nav' >
< nav-temp / >
< / div > -- >
< / div >
2025-10-11 11:08:42 +08:00
<!-- 右侧容器 -- >
2025-09-15 09:58:52 +08:00
< div class = "rightDiv" >
2025-10-11 11:08:42 +08:00
< div class = "bName" :title = "getBookName" > { { getBookName } } < / div >
<!-- 编辑框 -- >
<!-- : style = "{height:editorHeight+'px'}" -- >
<!-- : class = "{ editor2Opacity: dialogVisibleNav||dialogVisibleNavDel|| dialogVisible||dialogVisibleImg||dialogVisibleRight||dialogVisibleTips||dialogVisibleBland||dialogVisibleHistory||dialogVisibleTips2||editBookNameDialog }" -- >
< div id = "editor" v -show = ' currentNode ' : class = "{ editor2Opacity: dialogVisibleNav||dialogVisibleNavDel|| dialogVisible||dialogVisibleImg||dialogVisibleRight||dialogVisibleTips||dialogVisibleBland||dialogVisibleHistory||dialogVisibleTips2||editBookNameDialog }" ref = "editor" > < / div >
<!-- 提示信息 -- >
<!-- < div class = "paAutoStyle" v-show = "!currentNode && isLoadXml" > 请打开所要编辑的的章节目录 < / div >
< div class = "paAutoStyle" v-show = "!isLoadXml" > 请加载所要编辑的文档目录 < / div > - - >
2025-09-15 09:58:52 +08:00
< / div >
2025-10-11 11:08:42 +08:00
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
<!-- 历史弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "历史版本"
: visible . sync = "dialogVisibleHistory"
width = '80%'
class = "custom-dialog"
: before - close = "handleClose" >
< div class = "attribute-selection" v -if = ' historyData ' >
< div class = 'zyBox' style = "text-align: left;" v-for = "(item,index) in historyData" :key="index" >
< p > 版本名称 : { { item . Name } } < / p >
< p > 修改时间 : { { timeChange ( item . CreationTime ) } } < / p >
< p > 文件路径 : { { item . Path } } < / p >
< el-button @ click = 'lookHistoryFile(item.Path)' > 查看历史版本 < / el-button >
2025-07-28 17:01:13 +08:00
< / div >
2025-09-15 09:58:52 +08:00
< / div >
< div class = "attribute-selection" v -if = ' historyData.length = = 0 ' >
暂无历史版本
< / div >
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="dialogVisibleHistory = false" > 关闭 < / el -button >
<!-- < el-button type = "primary" @click ="catalogueAnalysis(treeData)" > 选择绑定资源 < / el -button > -- >
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 绑定资源弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "绑定资源"
class = "custom-dialog"
: visible . sync = "dialogVisibleBland"
width = "50%"
: before - close = "handleClose" >
< div class = "attribute-selection" v-if = "currentNode&¤tNode.attributes.length > 0" >
< p > 已绑资源 : < / p >
<!-- 属性展示区域 -- >
< div v -if = ' currentNode ' class = 'bindMain' >
< div class = "zyBox" v-for = "(item,index) in currentNode.attributes" :key="index" >
< p > { { item } } < / p >
< el-button type = "danger" size = "mini" @click ="deleteAttr(item,index)" :disabled = "!currentNode" > 删除 < / el-button >
< / div >
< / div >
< / div >
< div v-else > 暂未绑定资源 < / div >
< span slot = "footer" class = "dialog-footer" >
< el-button @ click = 'saveAttributes' > 选择绑定资源 < / el-button >
< el-button @click ="dialogVisibleBland = false" > 关闭 < / el -button >
<!-- < el-button type = "primary" @click ="catalogueAnalysis(treeData)" > 选择绑定资源 < / el -button > -- >
< / span >
2025-10-11 11:08:42 +08:00
< / el-dialog >
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
<!-- 新建 , 编辑目录弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
2025-10-11 11:08:42 +08:00
: title = "navIsAdd=='create'?'新建章节':'编辑章节'"
2025-09-15 09:58:52 +08:00
: visible . sync = "dialogVisibleNav"
width = "80%"
class = "custom-dialog"
: before - close = "handleClose"
>
2025-10-11 11:08:42 +08:00
< el-form label -position = " left " label -width = " 120px " :model = "form" :rules = "rules" ref = "form" >
<!-- 按钮区域 -- >
< div style = "margin-bottom: 15px;" >
< el-button type = "info" icon = "el-icon-folder-opened" v -if = ' navIsAdd = = " create " ' @click ="loadFileBtn" > 加载文件 < / el -button >
< el-button type = "info" icon = "el-icon-data-analysis" v -if = ' showView ' @click ="viewLoadDMFile" > 预览文件 < / el -button >
< / div >
<!-- 两列布局容器 -- >
< el-row :gutter = "20" >
<!-- 第一列 -- >
< el-col :span = "24" >
< div class = "colStyle colStyle1" >
< img title = '章节名称' src = "../assets/img/wenjian.png" >
< span > 章节名称 < / span >
< / div >
< el-input v-model = "form.name" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第二列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '责任合作单位' src = "../assets/img/danwei.png" >
< span > 责任合作单位 < / span >
< / div >
< el-input v-model = "form.contributor" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第一列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '创作单位' src = "../assets/img/hezuodanwei.png" >
< span > 创作单位 < / span >
< / div >
< el-input v-model = "form.creator" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第二列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '适用性信息' src = "../assets/img/xinxi.png" >
< span > 适用性信息 < / span >
< / div >
< el-input v-model = "form.applicabilityInformation" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第一列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '质量验证' src = "../assets/img/xinxi.png" >
< span > 质量验证 < / span >
< / div >
< el-input v-model = "form.qualityVerification" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第二列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '权限' src = "../assets/img/quanxian.png" >
< span > 权限 < / span >
< / div >
<!-- < el-input v-model = "form.permission" autocomplete="off" > < / el -input > -- >
< el-select v-model = "form.permission" style="width:100%;" placeholder="请选择" >
< el-option
v - for = "item in optionsPermission"
: key = "item.value"
: label = "item.label"
: value = "item.value" >
< / el-option >
< / el-select >
< / el-col >
<!-- 第一列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '版本信息' src = "../assets/img/jurassic_version.png" >
< span > 版本信息 < / span >
< / div >
< el-input v-model = "form.version" disabled autocomplete="off" > < / el -input >
< / el-col >
<!-- 第二列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '发布时间' src = "../assets/img/fabushijian.png" >
< span > 发布时间 < / span >
< / div >
< el-date-picker
style = "width:100%;"
v - model = "form.date"
type = "date"
placeholder = "选择日期" >
< / el-date-picker >
<!-- < el-input v-model = "form.date" autocomplete="off" > < / el -input > -- >
< / el-col >
<!-- 第一列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '语言' src = "../assets/img/duoyuyan.png" >
< span > 语言 < / span >
< / div >
< el-input v-model = "form.language" autocomplete="off" > < / el -input >
< / el-col >
<!-- 第二列 -- >
< el-col :span = "12" >
< div class = "colStyle" >
< img title = '密级' src = "../assets/img/miji.png" >
< span > 密级 < / span >
< / div >
< el-select v-model = "form.level" style="width:100%;" placeholder="请选择" >
< el-option
v - for = "item in optionsLevel"
: key = "item.value"
: label = "item.label"
: value = "item.value" >
< / el-option >
< / el-select >
<!-- < el-input v-model = "form.level" autocomplete="off" > < / el -input > -- >
< / el-col >
<!-- 单独占满一行的表单项 -- >
< el-col :span = "12" v -if = ' showView ' >
< div class = "colStyle" >
< img title = '使用加载数据' src = "../assets/img/xinxi.png" >
< span > 使用加载数据 < / span >
< / div >
< div >
< el-select v-model = "isLoadOldDmc" style="width:100%;" placeholder="请选择" >
< el-option
v - for = "item in options2"
: key = "item.value"
: label = "item.label"
: value = "item.value" >
< / el-option >
< / el-select >
<!-- < el-radio v-model = "isLoadOldDmc" label="1" > 使用 < / el -radio > -- >
<!-- < el-radio v-model = "isLoadOldDmc" label="2" > 不使用 < / el -radio > -- >
< / div >
< / el-col >
< / el-row >
< / el-form >
< span slot = "footer" class = "dialog-footer" >
2025-09-15 09:58:52 +08:00
< el-button @click ="dialogVisibleNav = false" > 取 消 < / el -button >
2025-10-11 11:08:42 +08:00
< el-button type = "primary" v -if = ' navIsAdd = = " create " & & isLoadOldDmc = = " 1 " ' @click ="confirmAdd(false)" > 确 定 < / el -button >
< el-button v -if = ' navIsAdd = = " create " & & isLoadOldDmc = = " 2 " ' type = "primary" @click ="confirmAdd(true)" > 确 定 < / el -button >
< el-button v -if = ' navIsAdd = = " edit " ' type = "primary" @click ="confirmEdit()" > 确 定 < / el -button >
2025-09-15 09:58:52 +08:00
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 删除目录确认弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "删除章节"
: visible . sync = "dialogVisibleNavDel"
2025-10-11 11:08:42 +08:00
width = "50%"
2025-09-15 09:58:52 +08:00
class = "custom-dialog"
>
< div >
是否确定删除 【 { { currentNode ? currentNode . name : '' } } 】 ?
< / div >
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="dialogVisibleNavDel = false" > 取 消 < / el -button >
< el-button type = "primary" @click ="deleteNode" > 确 定 < / el -button >
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 删除资源确认弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "删除资源"
: visible . sync = "dialogVisibleAttrDel"
2025-10-11 11:08:42 +08:00
width = "50%"
2025-09-15 09:58:52 +08:00
class = "custom-dialog"
>
< div >
是否确定删除 【 { { nowAttr . name } } 】 的绑定 ?
< / div >
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="dialogVisibleAttrDel = false" > 取 消 < / el -button >
< el-button type = "primary" @click ="deleteAttrSure" > 确 定 < / el -button >
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 操作目录时候未保存提示 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "提示"
: visible . sync = "dialogVisibleTips"
2025-10-11 11:08:42 +08:00
width = "50%"
2025-09-15 09:58:52 +08:00
class = "custom-dialog"
: before - close = "handleClose2" >
2025-10-11 11:08:42 +08:00
< span > 是否保存当前编辑内容 < / span >
2025-09-15 09:58:52 +08:00
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="saveNowDmc('noSave')" > 不保存 < / el -button >
< el-button type = "primary" @click ="saveNowDmc('save')" > 保存 < / el -button >
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 切换目录时候未保存提示 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "提示"
: visible . sync = "dialogVisibleTips2"
2025-10-11 11:08:42 +08:00
width = "50%"
2025-09-15 09:58:52 +08:00
class = "custom-dialog"
: before - close = "saveNowDmc2" >
2025-10-11 11:08:42 +08:00
< span > 是否保存当前编辑内容 < / span >
2025-09-15 09:58:52 +08:00
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="saveNowDmc2('noSave')" > 不保存 < / el -button >
< el-button type = "primary" @click ="saveNowDmc2('save')" > 保存 < / el -button >
< / span >
< / el-dialog >
2025-10-11 11:08:42 +08:00
<!-- 邮件弹窗 -- >
2025-09-15 09:58:52 +08:00
< div
v - if = "contextMenuVisible"
class = "custom-context-menu"
: style = "{ left: contextMenuLeft + 'px', top: contextMenuTop + 'px' }"
2025-10-11 11:08:42 +08:00
>
< div class = 'nowRightHint' :title = "nowRightHint" > { { nowRightHint } } < / div >
< div class = "menu-item" @click ="handleMenuClick('a')" > < img title = '编辑章节' src = "../assets/img/bianji1.png" > < span > 编辑章节 < / span > < / div >
< div class = "menu-item" @click ="handleMenuClick('b')" > < img title = '绑定资源' src = "../assets/img/bangdingziyuanchi.png" > < span > 绑定资源 < / span > < / div >
< div class = "menu-item" @click ="handleMenuClick('c')" > < img title = '版本定稿' src = "../assets/img/dinggao.png" > < span > 版本定稿 < / span > < / div >
< div class = "menu-item" @click ="handleMenuClick('d')" > < img title = '历史版本' src = "../assets/img/gaojisousuo.png" > < span > 历史版本 < / span > < / div >
< div class = "menu-item" @click ="handleMenuClick('e')" > < img title = '删除章节' src = "../assets/img/shanchu-copy.png" > < span > 删除章节 < / span > < / div >
<!-- < div class = "menu-divider" > < / div > -- >
<!-- < div class = "menu-item" @click ="contextMenuVisible = false" > 关闭 < / div > - - >
2025-09-15 09:58:52 +08:00
< / div >
2025-10-11 11:08:42 +08:00
<!-- 文件预览弹窗 -- >
2025-09-15 09:58:52 +08:00
< el-dialog
title = "文件预览"
: visible . sync = "maskViewShow"
width = "90%"
class = "custom-dialog viewDialog"
: before - close = "handleCloseMask"
>
2025-10-11 11:08:42 +08:00
< el-descriptions class = "margin-top" v -if = ' viewXml ' title = "章节信息" :column = "3" border >
< template slot = "extra" >
< el-button @ click = 'dmcTable' type = "primary" size = "small" > { { dmcHint ? "收起" : "展开" } } < / el-button >
< / template >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
章节名称
< / template >
{ { rdfDescriptions [ 0 ] . children [ 0 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
创作单位
< / template >
{ { rdfDescriptions [ 0 ] . children [ 1 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
权限
< / template >
{ { formatOther ( 'permission' , rdfDescriptions [ 0 ] . children [ 2 ] . text ) . label } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
合作单位
< / template >
{ { rdfDescriptions [ 0 ] . children [ 5 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
版本号
< / template >
{ { rdfDescriptions [ 0 ] . children [ 6 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
密级
< / template >
{ { formatOther ( 'level' , this . rdfDescriptions [ 0 ] . children [ 7 ] . text ) . label } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
发布日期
< / template >
{ { formatDate ( rdfDescriptions [ 0 ] . children [ 8 ] . text ) } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
适用性信息
< / template >
{ { rdfDescriptions [ 0 ] . children [ 9 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
质量验证
< / template >
{ { rdfDescriptions [ 0 ] . children [ 10 ] . text } }
< / el-descriptions-item >
< el-descriptions-item v -if = ' dmcHint ' >
< template slot = "label" >
语言
< / template >
{ { rdfDescriptions [ 0 ] . children [ 14 ] . text } }
< / el-descriptions-item >
< / el-descriptions >
2025-09-15 09:58:52 +08:00
< div class = "loadContent" v-html = "neirong" >
< / div >
2025-10-11 11:08:42 +08:00
< / el-dialog >
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
< el-dialog
title = "修改书名"
: visible . sync = "editBookNameDialog"
width = "60%"
class = "custom-dialog viewDialog2"
: before - close = "handleCloseEditBookName"
>
< el-input v-model = "getBookName" autocomplete="off" > < / el -input >
< span slot = "footer" class = "dialog-footer" >
< el-button @click ="editBookFun(false)" > 取消 < / el -button >
< el-button type = "primary" @click ="editBookFun(true)" > 修改 < / el -button >
< / span >
< / el-dialog >
2025-09-15 09:58:52 +08:00
2025-07-25 13:28:47 +08:00
< / div >
< / template >
< script >
2025-09-15 09:58:52 +08:00
import WangEditor from 'wangeditor' ;
2025-10-11 11:08:42 +08:00
import brImg from '../assets/img/br.png' ;
import '../assets/css/style.css'
2025-07-25 13:28:47 +08:00
export default {
name : 'RichTextEditor' ,
2025-09-15 09:58:52 +08:00
components : {
} ,
2025-07-25 13:28:47 +08:00
data ( ) {
return {
2025-10-11 11:08:42 +08:00
minLevel : '' ,
maxLevel : '' ,
maxPermission : '' ,
minPermission : '' ,
nowRightHint : '' ,
dmcHint : false ,
rdfDescriptions : [ ] ,
editBookNameDialog : false ,
getBookName : '' ,
getBookNameDf : '' ,
pickerOptions : {
disabledDate ( time ) {
return time . getTime ( ) > Date . now ( ) ;
} ,
shortcuts : [ {
text : '今天' ,
onClick ( picker ) {
picker . $emit ( 'pick' , new Date ( ) ) ;
}
} , {
text : '昨天' ,
onClick ( picker ) {
const date = new Date ( ) ;
date . setTime ( date . getTime ( ) - 3600 * 1000 * 24 ) ;
picker . $emit ( 'pick' , date ) ;
}
} , {
text : '一周前' ,
onClick ( picker ) {
const date = new Date ( ) ;
date . setTime ( date . getTime ( ) - 3600 * 1000 * 24 * 7 ) ;
picker . $emit ( 'pick' , date ) ;
}
} ]
} ,
optionList : [
{
label : '使用' ,
value : "1"
} ,
{
label : '不使用' ,
value : "2"
}
] ,
optionsPermission : [
{ label : '一级' , value : '1' } ,
{ label : '二级' , value : '2' } ,
{ label : '三级' , value : '3' } ,
{ label : '四级' , value : '4' } ,
{ label : '五级' , value : '5' } ,
{ label : '六级' , value : '6' } ,
{ label : '七级' , value : '7' } ,
{ label : '八级' , value : '8' } ,
{ label : '九级' , value : '9' } ,
{ label : '十级' , value : '10' } ,
] ,
optionsLevel : [
{ value : '1' , label : '公开' } ,
{ value : '2' , label : '秘密' } ,
{ value : '3' , label : '机密' } ,
{ value : '4' , label : '绝密' }
] ,
brImg : brImg ,
imgUrlJg : require ( '../assets/img/jgIcon.png' ) , //警告Icon
imgUrlJs : require ( '../assets/img/jsIcon.png' ) , //警示Icon
editorHeight : '' , //编辑器高度
historyVsPath : '' , //查看历史文件路径
leftHeight : '0' , //左边容器高度
2025-09-15 09:58:52 +08:00
isLoadXml : false , //是否加载DMC
neirong : '' , //预览内容
isLoadOldDmc : "1" , // 初始值需与 options 中的 value 类型一致
2025-10-11 11:08:42 +08:00
options2 : [
{
value : "1" ,
label : "使用" ,
} ,
{
value : "2" ,
label : "不使用" ,
}
] ,
2025-09-15 09:58:52 +08:00
showView : false , //是否显加载原文档
2025-10-11 11:08:42 +08:00
tempDivData1 : '' , //模板文件容器
viewLis : '' , //预览时候端口号
viewXml : '' , //预览时候的XML内容
maskViewShow : false , //文件预览弹窗是否显示
2025-09-15 09:58:52 +08:00
// 屏幕整体尺寸(设备屏幕尺寸)
screenWidth : 0 ,
screenHeight : 0 ,
// 浏览器窗口尺寸
windowW : 0 ,
windowH : 0 ,
// 用于防抖的定时器
resizeTimer : null ,
// 保存对新窗口的引用
wangG2Window : null ,
// 用于检查窗口状态的定时器
2025-10-11 11:08:42 +08:00
checkWindowTimer : null ,
2025-09-15 09:58:52 +08:00
showModifyBtn : false , // 控制是否显示【修改】的开关( 按钮点击后设为true)
2025-10-11 11:08:42 +08:00
mId : '' , //当前最大ID
2025-09-15 09:58:52 +08:00
loadFileDMC : '' , //加载的DMC文件里面的content内容
loadFileXML : '' , //加载的DMC文件内容
historyData : [ ] , //历史版本列表信息
contextMenuVisible : false , // 右键菜单是否可见
contextMenuLeft : 0 , // 右键菜单left位置
contextMenuTop : 0 , // 右键菜单top位置
contextMenuNode : null , // 右键点击的节点数据
2025-10-11 11:08:42 +08:00
nowAttr : { //当前操作的资源
name : '' ,
index : ''
} ,
2025-09-15 09:58:52 +08:00
dialogVisibleAttrDel : false , //删除弹窗
2025-10-11 11:08:42 +08:00
dialogVisibleTips2 : false , //切换目录时候未保存提示弹窗是否显示
dialogVisibleTips : false , //操作目录时候未保存提示弹窗是否显示
2025-09-15 09:58:52 +08:00
contentXmlStr : '' , //当前富文本字符串
getDmName : '' , //当前DM文件名。
isNavEdit : false , //是否在目录编辑状态。
allImgType : //暂定当前的图片类型
new Set ( [
"bmp" , "jpg" , "jpeg" , "png" , "tif" , "gif" , "pcx" , "tga" , "exif" , "fpx" , "svg" , "psd" , "cdr" , "pcd" , "dxf" , "ufo" , "eps" , "ai" , "raw" , "WMF" , "webp" , "avif" , "apng"
] ) ,
allMusicType : new Set ( [ //暂定当前的音频类型
"mp3" , "aac" , "wav" , "flac" , "alac" , "wma"
] ) ,
allVideoType : new Set ( [ //暂定当前的视频类型
"mp4" , "avi" , "mkv" , "mov" , "flv" , "wmv" , "webm" , "mpeg"
] ) ,
otherType : new Set ( [ 'wrl' , 'jltf' ] ) ,
lisenPath : '' , //当前内置服务器端口
//目录
domNameStr : [ //拼接文档名
'DMC-' , 'test2' , '-A-P4-20-00-00A-' , 'A-A_000_00' , '_zh_cn'
] ,
lastClick : '' , //上一次点击的目录id
nowClick : '' , //当前点击的目录id
nowMaxId : '' , //最大文档id
catalogueString : '' , //目录字符串
navIsAdd : '' , //判断当前目录操作类型
searchText : '' , //搜索目录章节
dialogVisibleNav : false , //目录弹窗
dialogVisibleRight : false , //右键绑定弹窗
dialogVisibleBland : false , //绑定源弹窗
dialogVisibleHistory : false , //历史版本弹窗
dialogVisibleNavDel : false , //删除弹窗
selectedAttributes : [ ] , // 当前选中的属性
treeData : [ //基础目录数据
// { id: '00001', name: '根节点1根节点1根节点1根节点1根节点1根节点1', children: [
// {
// id: '00003', name: '根节点3根节点3根节点3根节点3根节点3', children: [{
// id: '00004', name: '根节点4根节点4根节点4根节点4根节点4', children: [],
// attributes: [] // 示例:已绑定的属性
// }]
// }
// ], attributes: [] // 示例:已绑定的属性
// },
// { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
// {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
// {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
// {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
// {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: []}
// ] }]}
// ] }]}
// ] }]}
// ] }
] ,
treeData2 : [
{
id : '00001' ,
name : '装备概况' ,
attributes : [ '金' , '木' , '水' ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [
{
id : '00002' ,
name : '方舱概述' ,
attributes : [ ] ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [
{
id : '00003' ,
name : '功能介绍' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00004' ,
name : '规格介绍' ,
attributes : [ '水' ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
}
]
} ,
{
id : '00005' ,
name : '舱体' ,
attributes : [ '火' , '土' ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00006' ,
name : '机身转运小车' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00007' ,
name : '无人机部件存储装置' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00008' ,
name : '机身转运小车' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00009' ,
name : '附件及工具' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [
{
id : '00010' ,
name : '灭火器' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00011' ,
name : '应急灯' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00012' ,
name : '土木工具' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00013' ,
name : '机械工具' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
}
]
}
]
} ,
{
id : '00013' ,
name : '使用说明' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [
{
id : '00014' ,
name : '无人机出舱' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00015' ,
name : '无人机入舱' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
} ,
{
id : '00016' ,
name : '灭火器使用' ,
attributes : [ ] ,
formMes : { } ,
lagreVersion : '001' ,
minorVersion : '01' ,
children : [ ]
}
]
}
2025-10-11 11:08:42 +08:00
] ,
2025-09-15 09:58:52 +08:00
defaultProps : { //树结构
children : 'children' ,
label : 'name'
} ,
currentNode : null , //当前节点
form : { //默认目录信息
name : '' ,
version : '000' ,
date : '' ,
language : '' ,
2025-10-11 11:08:42 +08:00
level : '1' ,
2025-09-15 09:58:52 +08:00
contributor : '' ,
2025-10-11 11:08:42 +08:00
creator : '四威高科' ,
2025-09-15 09:58:52 +08:00
applicabilityInformation : '' ,
qualityVerification : '' ,
2025-10-11 11:08:42 +08:00
permission : '1'
2025-09-15 09:58:52 +08:00
// version:'001',
// date:'2046-12-12',
// language:'zn_cn',
// level:'公开',
// contributor:'责任合作单位',
// creator:'创作单位',
// applicabilityInformation:'适用性信息',
// qualityVerification:'质量验证',
// permission:'10'
} ,
2025-10-11 11:08:42 +08:00
rules : { //规则
2025-09-15 09:58:52 +08:00
name : [
{ required : true , message : '请输入节点名称' , trigger : 'blur' } ,
{ min : 1 , max : 40 , message : '长度在 1 到 40 个字符' , trigger : 'blur' }
]
} ,
//弹窗
dialogVisible : false , //自定义弹窗
idLength : 10 , //暂无用
contextMenu : { //暂无用
visible : false ,
x : 0 ,
y : 0 ,
selectedElement : null ,
selectedParam : ''
} ,
isContextMenuEnabled : false , //暂无用
itemParams : { } , //暂无用
// 存储元素的参数 {elementId: param}
// 模拟弹框参数
//查看图片begin
dialogVisibleImg : false , //暂无用
images : [ //暂无用
'https://ww2.sinaimg.cn/mw690/007ut4Uhly1hx4v37mpxcj30u017cgrv.jpg' ,
'https://example.com/image2.jpg'
] ,
currentImage : '' , //暂无用
scale : 1 , //暂无用
rotation : 0 , //暂无用
isDragging : false , //暂无用
startX : 0 , //暂无用
startY : 0 , //暂无用
translateX : 0 , //暂无用
translateY : 0 , //暂无用
containerHeight : '90vh' , //暂无用 动态控制高度
//查看图片end
oldSelector : [ //基础标签模块
'div' , 'code' , 'hr' , 'br' , 'h1,h2,h3,h4' , 'p' , 'img' , 'table' , 'a' , 'ul' , 'ol' , 'blockquote' , 'pre' ,
] ,
newSelector : [ //替换后的标签模块
'pDiv' , 'pCode' , 'pHr' , 'pBr' , 'pTitle' , 'pDiv' , 'pImg' , 'pTable' , 'pA' , 'pUl' , 'pOl' , 'pBlockquote' , 'pPre' ,
] ,
tempDivData : { //当前富文本str
innerHTML : '五'
} ,
colors : '' , //暂无用
val1 : '' , //暂无用
val2 : '' , //暂无用
message : '' , //暂无用
2025-10-11 11:08:42 +08:00
editor : null , //编辑器
editorContent : '' , //富文本内容
2025-07-28 17:01:13 +08:00
}
} ,
2025-10-11 11:08:42 +08:00
computed : {
2025-07-25 13:28:47 +08:00
} ,
mounted ( ) {
2025-09-15 09:58:52 +08:00
// 初始化尺寸
this . getWindowSize ( )
// 绑定 resize 事件
window . addEventListener ( 'resize' , this . handleResize )
2025-10-11 11:08:42 +08:00
// // 确保DOM已加载
// this.$nextTick(() => {
// this.initEditor()
// })
2025-09-15 09:58:52 +08:00
this . $nextTick ( ( ) => {
2025-10-11 11:08:42 +08:00
// 初始时如果容器不可见,等待 currentNode 变化后再初始化
if ( this . currentNode ) {
this . initEditor ( ) ;
}
} ) ;
2025-09-15 09:58:52 +08:00
2025-07-25 13:28:47 +08:00
console . log ( 'chrome对象是否存在:' , ! ! window . chrome ) ;
2025-10-11 11:08:42 +08:00
console . log ( 'webview对象是否存在:' , ! ! window . chrome ? . webview ) ;
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
window . removeEventListener ( 'SelectFilePathSend' , this . handleFilePathSend ) ;
// 再绑定新的监听器
window . addEventListener ( 'SelectFilePathSend' , this . handleFilePathSend ) ;
window . addEventListener ( 'SelectFilePathSend' , this . SendLisentPathFun ) ;
2025-07-25 13:28:47 +08:00
} ,
beforeDestroy ( ) {
// 销毁编辑器
if ( this . editor ) {
this . editor . destroy ( )
}
2025-09-15 09:58:52 +08:00
// 清理定时器
if ( this . checkWindowTimer ) {
clearInterval ( this . checkWindowTimer )
}
console . log ( '监听器开始移除:' , Date . now ( ) ) // 打印移除时间戳
window . removeEventListener ( 'resize' , this . handleResize )
window . removeEventListener ( 'FrontLoadDM' , this . FrontLoadDM _g1 )
window . removeEventListener ( 'handleMessageFromDotNet' , this . fun1 )
window . removeEventListener ( 'SelectFilePathSend' , this . SendLisentPathFun )
2025-07-25 13:28:47 +08:00
} ,
2025-09-15 09:58:52 +08:00
methods : {
//清除节点选中
clearNodeState ( ) {
2025-10-11 11:08:42 +08:00
this . currentNode = '' ;
2025-09-15 09:58:52 +08:00
// 通过ref获取el-tree实例
const tree = this . $refs . tree ;
if ( tree ) {
// 取消当前选中状态
tree . setCurrentKey ( null ) ;
// 如果需要清除所有节点的选中状态(包括多选情况)
// 先获取所有选中的节点
const selectedNodes = tree . getCheckedNodes ( ) ;
// 取消所有节点的选中状态
selectedNodes . forEach ( node => {
tree . setChecked ( node . id , false ) ;
} ) ;
// 可选: 触发节点点击事件的回调, 传递null表示无选中节点
// this.handleNodeClick(null);
}
} ,
// 测试接收数据
fun1 ( e ) {
console . log ( "方法1" , e , e . detail )
} ,
// 获取服务端口地址
SendLisentPathFun ( e ) {
console . log ( '服务端口地址信息1:' , e , e . detail )
this . lisenPath = e . detail ;
} ,
2025-10-11 11:08:42 +08:00
FrontLoadDM _g2 ( e ) {
// 加载目录
console . log ( 'FrontLoadProjectNew111 参数接收:' )
this . isLoadXml = true ;
this . currentNode = '' ;
//获取目录字段拼接,暂不用
// this.extractDmCode(e.detail)
// 去除首尾的双引号
let processed = e . detail . trim ( ) ;
// 检查并去除开头的双引号
if ( processed . startsWith ( '"' ) ) {
processed = processed . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( processed . endsWith ( '"' ) ) {
processed = processed . substring ( 0 , processed . length - 1 ) ;
}
// this.outputXml = processed;
this . generateTreeData ( processed ) ;
// this.parseXml(processed);
// this.parseToTreeData(processed)
} ,
2025-09-15 09:58:52 +08:00
//接收富文本内容信息
FrontLoadDM _g1 ( e ) {
console . log ( "加载文档数据 1111" )
console . log ( 'FrontLoadDM 参数接收111:' , e , e . detail )
// this.editorShow = true;
let xmlContent = e . detail . trim ( ) ;
if ( xmlContent . startsWith ( '"' ) ) {
xmlContent = xmlContent . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( xmlContent . endsWith ( '"' ) ) {
xmlContent = xmlContent . substring ( 0 , xmlContent . length - 1 ) ;
}
// console.log("xmlContent",xmlContent)
const parser = new DOMParser ( )
const xmlDoc = parser . parseFromString ( xmlContent , "text/xml" )
console . log ( "xmlDoc" , xmlDoc )
const contentNodes = xmlDoc . getElementsByTagName ( 'content' ) [ 0 ] ;
console . log ( "xmlDoc.getElementsByTagName('content')" , xmlDoc . getElementsByTagName ( 'content' ) )
console . log ( "contentNodes" , contentNodes )
const rdfDescription = xmlDoc . querySelector ( 'rdf\\:Description, Description' ) ;
if ( rdfDescription ) {
// 填充表单数据 - 映射关系: form字段 -> XML标签
this . form = {
name : this . getNodeValue ( rdfDescription , 'dc\\:title, title' ) ,
version : this . getNodeValue ( rdfDescription , 'dc\\:version, version' ) ,
date : this . getNodeValue ( rdfDescription , 'dc\\:date, date' ) ,
language : this . getNodeValue ( rdfDescription , 'dc\\:language, language' ) ,
level : this . getNodeValue ( rdfDescription , 'dc\\:level, level' ) ,
contributor : this . getNodeValue ( rdfDescription , 'dc\\:contributor, contributor' ) ,
creator : this . getNodeValue ( rdfDescription , 'dc\\:creator, creator' ) ,
applicabilityInformation : this . getNodeValue ( rdfDescription , 'dc\\:applicabilityInformation, applicabilityInformation' ) ,
qualityVerification : this . getNodeValue ( rdfDescription , 'dc\\:qualityVerification, qualityVerification' ) ,
permission : this . getNodeValue ( rdfDescription , 'dc\\:permission, permission' )
} ;
console . log ( 'XML解析成功' , this . form ) ;
} else {
this . form = {
name : '' ,
2025-10-11 11:08:42 +08:00
version : '000' ,
2025-09-15 09:58:52 +08:00
date : '' ,
language : '' ,
2025-10-11 11:08:42 +08:00
level : '1' ,
2025-09-15 09:58:52 +08:00
contributor : '' ,
2025-10-11 11:08:42 +08:00
creator : '四威高科' ,
2025-09-15 09:58:52 +08:00
applicabilityInformation : '' ,
qualityVerification : '' ,
} ;
console . log ( "目录解析不成功 置空" , this . form )
}
if ( contentNodes ) {
console . log ( "处理前" , contentNodes . innerHTML )
let htmlContent = this . convertXmlContentToHtml ( contentNodes . innerHTML )
let htmlContent2 = this . completeModel3DTags ( htmlContent )
console . log ( "处理后" , htmlContent2 )
const htmlContent3 = this . replaceModel3dToImg ( htmlContent2 ) ;
// this.editor.txt.html(htmlContent)
//处理过后再导入
// this.restoreContent(htmlContent)
this . restoreContentXh ( htmlContent3 )
}
} ,
//测试发送给后端信息
2025-07-25 13:28:47 +08:00
sendMessageToHost ( ) {
2025-09-15 09:58:52 +08:00
//调用后端 sendToDotNet
2025-07-25 13:28:47 +08:00
this . $sendToDotNet ( this . val1 , this . val2 ) ;
2025-10-11 11:08:42 +08:00
} ,
2025-09-15 09:58:52 +08:00
initEditor ( ) { //初始化编辑器配置
2025-07-25 13:28:47 +08:00
this . editor = new WangEditor ( this . $refs . editor )
2025-10-11 11:08:42 +08:00
const editorEl = this . $refs . editor ;
if ( ! editorEl ) {
console . warn ( '编辑器容器不存在' ) ;
return ;
}
2025-07-25 13:28:47 +08:00
// 配置编辑器
this . editor . config . uploadImgShowBase64 = true // 使用 base64 保存图片
this . editor . config . onchange = ( html ) => {
2025-09-15 09:58:52 +08:00
this . editorContent = html ;
2025-07-25 13:28:47 +08:00
}
let dm = this . editor . config . menus ;
console . log ( "默认菜单" , dm )
2025-09-15 09:58:52 +08:00
2025-07-25 13:28:47 +08:00
2025-07-28 17:01:13 +08:00
// 启用颜色选择功能
this . editor . config . colors = [
'#000000' , '#ffffff' , '#eeeef1' ,
'#ff0000' , '#ff5e5e' , '#ffbbbb' ,
'#0033ff' , '#0055ff' , '#3d7eff' ,
'red' , "#096" , "#9cf"
]
2025-07-25 13:28:47 +08:00
// 完全自定义菜单
this . editor . config . menus = [
'image' , // 图片
'video' , // 视频
2025-09-15 09:58:52 +08:00
// 'head', // 标题
2025-07-25 13:28:47 +08:00
'bold' , // 粗体
2025-09-15 09:58:52 +08:00
'fontSize' , //字号
2025-07-25 13:28:47 +08:00
// 'fontName',//字体
'italic' , // 斜体
'underline' , // 下划线
'strikeThrough' , // 删除线
// 'line',//行高
'lineHeight' , //
2025-07-28 17:01:13 +08:00
'foreColor' , // 文字颜色
'backColor' , // 背景颜色
2025-09-15 09:58:52 +08:00
'link' , // 链接
2025-07-25 13:28:47 +08:00
'list' , // 列表
// 'todo',//
'justify' , // 对齐方式
2025-09-15 09:58:52 +08:00
'quote' , // 引用
2025-07-25 13:28:47 +08:00
// 'emoticon',//表情
'table' , // 表格
2025-09-15 09:58:52 +08:00
'code' , // 代码
2025-07-25 13:28:47 +08:00
'splitLine' , //分割线
'undo' , // 撤销
2025-07-28 17:01:13 +08:00
'redo' , // 重做
2025-07-25 13:28:47 +08:00
]
2025-09-15 09:58:52 +08:00
console . log ( "自定义菜单" , this . editor . config )
// 自定义处理拖拽事件
this . editor . config . customUpload = true
// 监听拖拽事件
this . editor . config . uploadImgShowBase64 = false
this . editor . config . uploadVideoShowBase64 = false
this . editor . config . uploadAudioShowBase64 = false
// 设置自定义拖拽处理
// this.setupDragHandler()
// 保存原始的创建方法
const originalCreate = this . editor . create
// 重写创建方法,在创建完成后立即添加按钮
this . editor . create = ( ) => {
// 执行原始创建方法
originalCreate . call ( this . editor )
// 尝试获取工具栏
// 📌🔖
//
2025-10-11 11:08:42 +08:00
this . addCustomButton ( '警示' , '<img src="' + this . imgUrlJs + '" alt="按钮图标" style="width: 20px; height: 20px; object-fit: contain;">' , 1 ) // 第一个按钮, 弹出123, 使用图钉图标
2025-09-15 09:58:52 +08:00
this . addCustomButton ( '警告' , '<img src="' + this . imgUrlJg + '" alt="按钮图标" style="width: 20px; height: 20px; object-fit: contain;">' , 2 ) // 第一个按钮, 弹出123, 使用图钉图标
}
2025-07-25 13:28:47 +08:00
// 创建编辑器
this . editor . create ( ) ;
2025-09-15 09:58:52 +08:00
// 特别注意:需要在编辑器创建完成后绑定事件
this . $nextTick ( ( ) => {
console . log ( "初始化 setupDragHandler" )
this . setupDragHandler ( )
} )
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// this.editor2 = new WangEditor(this.$refs.editor2)
// // 配置编辑器
// this.editor2.config.uploadImgShowBase64 = true // 使用 base64 保存图片
// this.editor2.config.onchange = (html) => {
// console.log("22222",html)
// // this.editorContent2 = html
// }
// this.editor2.create()
2025-07-25 13:28:47 +08:00
2025-10-11 11:08:42 +08:00
} ,
//编辑书名
editBookName ( ) {
console . log ( "编辑书名" )
const getBookNameDf = this . getBookName ;
this . getBookNameDf = getBookNameDf ;
this . editBookNameDialog = true ;
} ,
editBookFun ( type ) {
if ( type ) {
this . catalogueAnalysis ( this . treeData ) ;
this . editBookNameDialog = false ;
} else {
this . getBookName = this . getBookNameDf ;
this . editBookNameDialog = false ;
}
} ,
2025-09-15 09:58:52 +08:00
// 通用的添加自定义按钮方法,接收两个参数:提示内容和图标
addCustomButton ( alertContent , icon , type ) {
let toolbarElem = null
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 方式1: 通过编辑器内部属性获取工具栏
if ( this . editor . $toolbarElem && this . editor . $toolbarElem [ 0 ] ) {
toolbarElem = this . editor . $toolbarElem [ 0 ]
console . log ( '通过$toolbarElem获取到工具栏' )
}
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 方式2: 直接通过容器查找
if ( ! toolbarElem ) {
toolbarElem = this . $refs . editor . querySelector ( '.w-e-toolbar' )
if ( toolbarElem ) {
console . log ( '通过容器查询获取到工具栏' )
}
}
// 方式3: 全局查找
if ( ! toolbarElem ) {
toolbarElem = document . querySelector ( '.w-e-toolbar' )
if ( toolbarElem ) {
console . log ( '通过全局查询获取到工具栏' )
}
}
// 如果还是找不到工具栏,直接创建一个简单的按钮放在编辑器上方
if ( ! toolbarElem ) {
console . warn ( '仍然未找到工具栏,创建独立按钮' )
this . createFallbackButton ( alertContent , icon , type )
return
}
// 查找或创建菜单容器
let menuBar = toolbarElem . querySelector ( '.w-e-menu-bar' )
if ( ! menuBar ) {
menuBar = document . createElement ( 'div' )
menuBar . className = 'w-e-menu-bar'
menuBar . style . cssText = 'padding: 5px; border-bottom: 1px solid #e8e8e8;'
toolbarElem . appendChild ( menuBar )
}
// 创建自定义按钮
const customBtn = document . createElement ( 'div' )
customBtn . className = 'w-e-menu'
customBtn . style . cssText = `
width : 32 px ;
height : 32 px ;
display : inline - flex ;
align - items : center ;
justify - content : center ;
cursor : pointer ;
margin : 0 2 px ;
background : # fff ;
border - radius : 2 px ;
color : # 333 ;
font - size : 18 px ;
`
customBtn . innerHTML = icon
customBtn . title = ` ${ alertContent } `
// 绑定点击事件,使用传入的提示内容
customBtn . onclick = ( ) => {
console . log ( "点击了111" , type )
switch ( type ) {
case 1 :
case '1' :
2025-10-11 11:08:42 +08:00
// this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style='
// padding: 20px;
// margin: 20px;
// background-image:url("`+this.brImg+`");
// '><p class='teshu' style="border-radius: 4px;padding: 10px;border: 3px solid #000;"></p></div>
// <p data-we-empty-p=""><br></p>`)
// this.editor.cmd.do('insertHTML', `<p class='jg'>[[]]</p>`)
// this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style='margin: 10px auto;
// padding: 10px;
// border: 10px solid;
// background:#fff;
// border-image: linear-gradient(45deg,
// #ffcc00 0%, #ffcc00 10%,
// #000000 10%, #000000 20%,
// #ffcc00 20%, #ffcc00 30%,
// #000000 30%, #000000 40%,
// #ffcc00 40%, #ffcc00 50%,
// #000000 50%, #000000 60%,
// #ffcc00 60%, #ffcc00 70%,
// #000000 70%, #000000 80%,
// #ffcc00 80%, #ffcc00 90%,
// #000000 90%, #000000 100%
// ) 1;' class='teshu2'></div><p data-we-empty-p=""><br></p>`)
this . editor . cmd . do ( 'insertHTML' , ` <p data-we-empty-p=""><br></p><div style='margin: 10px auto;
padding : 10 px ;
background : # fff ; ' class=' teshu2 borderStyle _yellow ' > < / div > < p data -we -empty -p = " " > < br > < / p > ` )
2025-09-15 09:58:52 +08:00
break ;
case 2 :
case '2' :
2025-10-11 11:08:42 +08:00
// this.editor.cmd.do('insertHTML', `<p class='js'><<>></p>`)
// this.editor.cmd.do('insertHTML', `<div class='jg' style='border:1px solid red;padding:10px;'></div>`)
// this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style="margin: 50px auto;
// padding: 20px;
// border: 12px solid;
// background:#fff;
// border-image: linear-gradient(-45deg,
// #ff0000 0%, #ff0000 10%,
// #000000 10%, #000000 20%,
// #ff0000 20%, #ff0000 30%,
// #000000 30%, #000000 40%,
// #ff0000 40%, #ff0000 50%,
// #000000 50%, #000000 60%,
// #ff0000 60%, #ff0000 70%,
// #000000 70%, #000000 80%,
// #ff0000 80%, #ff0000 90%,
// #000000 90%, #000000 100%
// ) 1;" class='teshu'></div><p data-we-empty-p=""><br></p>`)
this . editor . cmd . do ( 'insertHTML' , ` <p data-we-empty-p=""><br></p><div style="margin: 10px auto;
padding : 10 px ;
background : # fff ; " class='teshu borderStyle_red'></div><p data-we-empty-p=" " > < br > < / p > ` )
2025-09-15 09:58:52 +08:00
break ;
2025-07-25 13:28:47 +08:00
}
2025-09-15 09:58:52 +08:00
}
// 添加悬停效果
customBtn . onmouseover = ( ) => {
customBtn . style . background = '#f0f0f0'
}
customBtn . onmouseout = ( ) => {
customBtn . style . background = '#fff'
}
// 添加到菜单最前面
menuBar . insertBefore ( customBtn , menuBar . firstChild )
console . log ( ` 自定义按钮(弹出 ${ alertContent } )已成功添加到菜单栏 ` )
} ,
// 备用方案:如果找不到工具栏,直接在编辑器上方创建一个按钮
createFallbackButton ( alertContent , icon , type ) {
const fallbackBtn = document . createElement ( 'div' )
fallbackBtn . style . cssText = `
padding : 8 px 15 px ;
background : # 409 eff ;
color : white ;
border - radius : 4 px ;
cursor : pointer ;
display : inline - block ;
margin : 0 5 px 10 px 0 ;
`
fallbackBtn . innerHTML = ` ${ icon } 点击弹出 ${ alertContent } `
fallbackBtn . onclick = ( ) => {
console . log ( "点击了222" , type )
switch ( type ) {
case 1 :
2025-10-11 11:08:42 +08:00
this . editor . cmd . do ( 'insertHTML' , ` <p class="fine-stripe-border1"><div></div></p> ` )
2025-09-15 09:58:52 +08:00
break ;
case 2 :
2025-10-11 11:08:42 +08:00
this . editor . cmd . do ( 'insertHTML' , ` <p class="fine-stripe-border2"><div></div></p> ` )
2025-09-15 09:58:52 +08:00
break ;
2025-07-25 13:28:47 +08:00
}
2025-09-15 09:58:52 +08:00
}
// 添加到编辑器容器的最前面
this . $refs . editor . insertBefore ( fallbackBtn , this . $refs . editor . firstChild )
console . log ( ` 已创建备用按钮(弹出 ${ alertContent } ) ` )
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
setupDragHandler ( ) {
console . log ( "进入setupDragHandler" )
const editor = this . editor
const editorContainer = editor . $textElem . elems [ 0 ]
let that = this ;
// console.log("进入参数",editor,editorContainer)
// // 阻止默认拖拽行为
editorContainer . addEventListener ( 'dragover' , ( e ) => {
// console.log("进入 dragover",e)
e . preventDefault ( )
e . stopPropagation ( )
2025-07-25 13:28:47 +08:00
} )
2025-09-15 09:58:52 +08:00
editorContainer . addEventListener ( 'drop' , ( e ) => {
// console.log("进入 drop",)
e . preventDefault ( )
e . stopPropagation ( )
that . $sendToDotNet ( 'GetMaterialPath' ) ;
// // 检查拖拽的文件类型
// const items = e.dataTransfer.items
// for (let i = 0; i < items.length; i++) {
// const item = items[i]
// if (item.kind === 'file') {
// const file = item.getAsFile()
// const fileType = file.type.split('/')[0]
// // 根据文件类型显示不同的提示
// switch(fileType) {
// case 'image':
// alert('检测到图片文件,已阻止上传')
// break
// case 'video':
// alert('检测到视频文件,已阻止上传')
// break
// case 'audio':
// alert('检测到音频文件,已阻止上传')
// break
// default:
// alert(`检测到${fileType}类型文件,已阻止上传`)
// }
// }
// }
2025-07-25 13:28:47 +08:00
} )
2025-09-15 09:58:52 +08:00
} ,
// 上传图片
insertImage ( src ) {
2025-10-11 11:08:42 +08:00
if ( ! this . editor ) {
console . error ( '编辑器未初始化,无法插入图片' ) ;
return ;
} else {
// src = 'http://localhost:54610/a1.jpg';
// const imgUrl = 'http://youneed.top:10017/uploads/1.jpg'
// const imgUrl = 'https://ww2.sinaimg.cn/mw690/007ut4Uhly1hx4v37mpxcj30u017cgrv.jpg';
if ( src ) {
const imgUrl = src ? src : 'http://localhost:5432/DM_Material/a1.jpg' ;
console . log ( "地址" , src , imgUrl )
this . editor . cmd . do ( 'insertHTML' , ` <img src=" ${ imgUrl } " style="width: 100%;" alt="图片"> ` )
}
}
2025-09-15 09:58:52 +08:00
} ,
// 上传3D资源模拟占位
insert3d ( imgUrl ) {
2025-10-11 11:08:42 +08:00
this . editor . cmd . do ( 'insertHTML' , ` <img src=" ${ imgUrl } " class='model3d' style="width: 100%;" alt="图片"><p data-we-empty-p=""><br></p> ` )
2025-09-15 09:58:52 +08:00
// this.editor.cmd.do('insertHTML', `<div>3D模型<model3d src="http://www.baidu.com" controls="controls" style="max-width: 100%"></model3d></div>`)
} ,
//上传3D资源模设置标识
replacemodel3dImages ( htmlString ) {
if ( ! htmlString ) return '' ;
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
const regex = /<img([^>]*?)class="model3d"([^>]*?)\/?>/gi ;
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
return htmlString . replace ( regex , ( match , prefix , suffix ) => {
const attributes = ( prefix || '' ) + ( suffix || '' ) ;
return ` <model3d class="model3d" ${ attributes } ></model3d> ` ;
} ) ;
2025-07-25 13:28:47 +08:00
} ,
2025-09-15 09:58:52 +08:00
//解析3d资源标识
modelToImg ( htmlString ) {
// 匹配<model3d>标签且class中包含model3d
const regex = /<model3d([^>]*?)class="([^"]*?)model3d([^"]*?)"([^>]*?)>/gi ;
// 替换标签名,保留所有属性
return htmlString . replace ( regex , '<img$1class="$2model3d$3"$4>' ) ;
} ,
// // 插入视频
// insertVideo() {
// // const videoUrl = 'http://youneed.top:10017/uploads/video.mp4'
// const videoUrl = 'https://r1.realme.net/general/20250530/17485780109181ed6767541a64e7d90626e0a3fd1aaae.mp4?type=video/mp4';
// const videoId = `video-${Date.now()}`
// // 创建视频HTML
// const videoHtml = `
// <div class="video-wrapper" data-video-id="${videoId}">
// <video controls width="50%" style='margin:auto' data-video-id="${videoId}">
// <source src="${videoUrl}" type="video/mp4">
// </video>
// <div class="video-controls" style='display:none;'>
// <span class="video-delete" data-video-id="${videoId}">× 删除</span>
// </div>
// </div>
// <p><br></p>
// `
// // 使用编辑器命令插入
// this.editor.cmd.do('insertHTML', videoHtml)
// // 添加删除事件监听
// this.$nextTick(() => {
// const btn = document.querySelector(`button[data-video-id="${videoId}"]`)
// if (btn) {
// btn.onclick = (e) => {
// e.preventDefault()
// this.deleteVideoById(videoId)
// }
// }
// })
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// },
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// // 根据ID删除视频( 修正版)
// deleteVideoById(videoId) {
// const container = document.querySelector(`.video-container[data-video-id="${videoId}"]`)
// if (container) {
// container.remove()
// this.editor.txt.html(this.editor.txt.html()) // 刷新编辑器
// }
// },
2025-10-11 11:08:42 +08:00
dmcTable ( ) {
if ( this . dmcHint ) {
this . dmcHint = false ;
} else {
this . dmcHint = true ;
}
} ,
formatOther ( type , data ) {
let textStr = null ;
console . log ( "内容" , type , data )
switch ( type ) {
case "level" :
textStr = this . optionsLevel . find ( item => {
return item . value === data ;
} ) ;
break ;
case "permission" :
textStr = this . optionsPermission . find ( item => {
return item . value === data ;
} ) ;
break ;
}
console . log ( '内容' , data , textStr )
return textStr ;
} ,
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
formatDate ( dateStr ) {
if ( ! dateStr ) return "" ;
try {
// 将字符串转换为Date对象
const date = new Date ( dateStr ) ;
// 获取年、月、日
const year = date . getFullYear ( ) ;
// 月份从0开始, 需要+1, 并用padStart补零确保两位数
const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , "0" ) ;
// 日期补零确保两位数
const day = String ( date . getDate ( ) ) . padStart ( 2 , "0" ) ;
// 返回格式化后的字符串( 格式: YYYY-MM-DD)
return ` ${ year } - ${ month } - ${ day } ` ;
} catch ( error ) {
console . error ( "日期格式化失败:" , error ) ;
return "无效日期" ;
}
} ,
parseRdfDescriptions ( ) {
try {
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( this . viewXml , 'text/xml' ) ;
// 定义RDF命名空间( 关键: 必须与XML中的命名空间一致)
const nsResolver = ( prefix ) => {
const ns = {
'rdf' : 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
// 可以添加其他需要的命名空间
} ;
return ns [ prefix ] || null ;
} ;
// 使用XPath查询所有rdf:Description元素
const xpathResult = xmlDoc . evaluate (
'//rdf:Description' ,
xmlDoc ,
nsResolver ,
XPathResult . ORDERED _NODE _ITERATOR _TYPE ,
null
) ;
this . rdfDescriptions = [ ] ;
let currentNode ;
// 遍历所有找到的rdf:Description节点
while ( ( currentNode = xpathResult . iterateNext ( ) ) ) {
// 获取节点内的所有内容(包括子节点和文本)
const content = {
attributes : { } ,
children : [ ] ,
innerXML : currentNode . innerHTML // 完整的内部XML
} ;
// 获取所有属性
if ( currentNode . attributes ) {
for ( let i = 0 ; i < currentNode . attributes . length ; i ++ ) {
const attr = currentNode . attributes [ i ] ;
content . attributes [ attr . name ] = attr . value ;
}
}
// 获取所有子节点文本内容
if ( currentNode . children && currentNode . children . length > 0 ) {
for ( let i = 0 ; i < currentNode . children . length ; i ++ ) {
const child = currentNode . children [ i ] ;
content . children . push ( {
tag : child . tagName ,
text : child . textContent ,
attributes : Array . from ( child . attributes ) . reduce ( ( attrs , attr ) => {
attrs [ attr . name ] = attr . value ;
return attrs ;
} , { } )
} ) ;
}
} else {
// 如果没有子节点,直接获取文本内容
content . text = currentNode . textContent ;
}
this . rdfDescriptions . push ( content ) ;
}
console . log ( '所有rdf:Description内容: ' , this . rdfDescriptions ) ;
} catch ( error ) {
console . error ( '解析XML出错: ' , error ) ;
}
} ,
2025-09-15 09:58:52 +08:00
// 插入视频
insertVideo ( src ) {
2025-10-11 11:08:42 +08:00
if ( ! this . editor ) {
console . error ( '编辑器未初始化,无法插入插入视频' ) ;
return ;
} else {
// const videoUrl = src?src:'https://r1.realme.net/general/20250530/17485780109181ed6767541a64e7d90626e0a3fd1aaae.mp4?type=video/mp4'
const videoUrl = src ? src : 'http://localhost:5432/DM_Material/video.mp4'
// 使用 editor.cmd.do 执行插入操作,支持撤销/重做
this . editor . cmd . do ( 'insertHTML' , ` <p data-we-empty-p=""><div><video src=" ${ videoUrl } " style="width: 100%;" controls="controls" style="max-width: 100%"></video></div><p data-we-empty-p=""><br></p><p data-we-empty-p=""><br></p></p> ` )
}
2025-09-15 09:58:52 +08:00
// 或者使用更简单的插入方式
// this.editor.txt.append(`<video src="${videoUrl}" controls="controls" style="max-width: 100%"></video>`)
2025-07-25 13:28:47 +08:00
} ,
2025-09-15 09:58:52 +08:00
// 插入音频
insertAudio ( src ) {
2025-10-11 11:08:42 +08:00
if ( ! this . editor ) {
console . error ( '编辑器未初始化,无法插入音频' ) ;
return ;
} else {
// let audioUrl = 'https://m801.music.126.net/20250805103535/df94bdfa3bc8c3a07de64531c4925895/jdymusic/obj/wo3DlMOGwrbDjj7DisKw/14096444542/bafc/a068/39f8/9a9e06e5634410b5e7e81df24749e656.mp3?vuutv=6WGmbU7+iXWmpSMnJs8FQEYWEieNRcA9S4YcUYOjmx36NJRHK0ASi7jhIJz0R9gxcmMcAUDn9rf1k08lFtqC9TQYcOlc8ZofqvCCJho3eeBGH/hwnjUlaQHe2GQFyJ32rhYAydM3bCBfIg+ZnpfZTw==';
let audioUrl = src ? src : 'http://localhost:5432/DM_Material/music.mp3' ;
// 使用预设音频URL
// const audioHtml = `
// <div class="audio-container" style="margin: 10px 0;">
// <audio controls src="${audioUrl}" style="width: 100%;"></audio>
// <div style="text-align: center; color: #999; font-size: 12px;">音频文件</div>
// </div>
// `;
const audioHtml = `
< p data -we -empty -p = " " > < audio controls src = "${audioUrl}" style = "width: 100%;" > < / audio > < / p > < p data -we -empty -p = " " > < br > < / p > < p data -we -empty -p = " " > < br > < / p > < p data -we -empty -p = " " > < br > < / p >
` ;
// 插入到编辑器
this . editor . cmd . do ( 'insertHTML' , audioHtml ) ;
}
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 或者使用更简单的方式
// this.editor.txt.append(audioHtml)
} ,
//循环处理标签
xh ( oldSt , newSt , type , saveId ) {
let times = oldSt . length ;
// const ht1 = this.tempDivData.innerHTML;
// console.log("3d转换之后2",ht1)
for ( let i = 0 ; i < times ; i + + ) {
const headings = this . tempDivData . querySelectorAll ( oldSt [ i ] )
headings . forEach ( heading => {
const dmTitle = document . createElement ( newSt [ i ] )
heading . parentNode . insertBefore ( dmTitle , heading )
console . log ( "内容替换" , dmTitle , heading )
dmTitle . appendChild ( heading )
} )
}
this . createXmlSt ( type , saveId ) ;
} ,
// 先清除已有的ID, 确保干净的基础
removeAllIds ( htmlString ) {
// 创建临时容器解析HTML
const tempContainer = document . createElement ( 'div' ) ;
tempContainer . innerHTML = htmlString ;
// 递归移除所有元素的id属性
const removeIdsFromElement = ( element ) => {
if ( ! element || element . nodeType !== 1 ) return ;
// 移除当前元素的id
element . removeAttribute ( 'id' ) ;
// 递归处理子元素
Array . from ( element . children ) . forEach ( child => {
removeIdsFromElement ( child ) ;
} ) ;
} ;
// 处理所有子元素
Array . from ( tempContainer . children ) . forEach ( child => {
removeIdsFromElement ( child ) ;
} ) ;
return tempContainer . innerHTML ;
} ,
// 删除Colgroup
removeColgroup ( str ) {
// 1. 校验入参( 防止传入null/undefined导致报错)
if ( ! str || typeof str !== 'string' ) {
console . warn ( '传入的内容不是有效字符串' ) ;
return str ; // 入参无效时,直接返回原内容
}
// 2. 定义正则( 匹配colgroup标签, 不区分大小写、全局匹配)
const colgroupReg = /<colgroup[\s\S]*?<\/colgroup>/gi ;
// 3. 判断是否包含colgroup标签
const hasColgroupTag = colgroupReg . test ( str ) ;
// 4. 处理逻辑:包含则移除,不包含则返回原字符串
let processedStr ;
if ( hasColgroupTag ) {
processedStr = str . replace ( colgroupReg , '' ) ;
console . log ( '检测到colgroup标签, 已移除' ) ;
} else {
processedStr = str ; // 关键: 不包含时返回原字符串, 而非null
console . log ( '未检测到colgroup标签, 返回原字符串' ) ;
}
// 5. 打印日志(便于调试)
console . log ( '解析前:' , str ) ;
console . log ( '解析后:' , processedStr ) ;
return processedStr ;
} ,
/ * *
* 为HTML字符串中的所有标签添加唯一ID
* @ param { string } htmlString - 原始HTML字符串
* @ returns { string } 处理后的HTML字符串
* /
addUniqueIds ( htmlString ) {
// 先清除已有的ID, 确保干净的基础
const cleanHtml = this . removeAllIds ( htmlString ) ;
console . log ( "当前的所有html内容2" , cleanHtml )
const tempContainer = document . createElement ( 'div' ) ;
tempContainer . innerHTML = cleanHtml ;
const usedIds = new Set ( ) ;
// 生成唯一ID
const generateUniqueId = ( tagName , content = '' ) => {
const pureTagName = tagName . toLowerCase ( ) . replace ( /^p/ , '' ) ;
const semanticSuffix = content . trim ( )
. replace ( /\s+/g , '_' )
. replace ( /[^a-z0-9-]/g , '' )
. slice ( 0 , 10 ) ;
console . log ( '循环数据semanticSuffix' , semanticSuffix )
let baseId = pureTagName + ( semanticSuffix ? ` id_ ${ semanticSuffix } ` : 'id' ) ;
let finalId = baseId ;
let counter = 1 ;
2025-10-11 11:08:42 +08:00
// console.log('循环数据counter',counter)
// console.log('循环数据baseId',baseId)
2025-09-15 09:58:52 +08:00
while ( usedIds . has ( finalId ) ) {
finalId = ` ${ baseId } _ ${ counter } ` ;
counter ++ ;
}
usedIds . add ( finalId ) ;
return finalId ;
} ;
// 递归添加ID
const addIdsToElement = ( element ) => {
if ( ! element || element . nodeType !== 1 ) return ;
const elementText = element . textContent || '' ;
const elementId = generateUniqueId ( element . tagName , elementText ) ;
element . setAttribute ( 'id' , elementId ) ;
Array . from ( element . children ) . forEach ( child => {
addIdsToElement ( child ) ;
} ) ;
} ;
// 处理所有元素
Array . from ( tempContainer . children ) . forEach ( child => {
addIdsToElement ( child ) ;
} ) ;
return tempContainer . innerHTML ;
} ,
/ * *
* 完整处理流程 : 清除现有ID - > 添加新的唯一ID
* @ param { string } originalHtml - 原始HTML字符串
* /
processHtmlWithIds ( originalHtml ) {
console . log ( "当前的所有html内容1" , originalHtml )
let processedHtml = this . addUniqueIds ( originalHtml ) ;
console . log ( "添加完的富文本" , processedHtml )
return processedHtml ;
} ,
// 创建XML字符串
createXmlSt ( type , saveId ) {
let desStr = this . form ;
// if(type||this.isNavEdit){
// desStr = this.form;
// this.isNavEdit = false;
// }else{
// desStr = '';
// }
console . log ( "当前" , this . navIsAdd )
// const ht3 = this.tempDivData.innerHTML;
// console.log("3d转换之后3",ht3)
switch ( this . navIsAdd ) {
case "create" :
this . tempDivData . innerHTML = '' ;
break ;
case "edit" :
// this.tempDivData.innerHTML = this.tempDivData.innerHTML;
break ;
case "other" :
// this.tempDivData.innerHTML = this.tempDivData.innerHTML;
this . navIsAdd = 'create' ;
break ;
default :
// this.tempDivData.innerHTML = '';
break ;
}
// this.tempDivData.innerHTML = this.navIsAdd?"":this.tempDivData.innerHTML;
this . tempDivData . innerHTML = this . clearNbsp ( this . tempDivData . innerHTML )
// const ht4 = this.tempDivData.innerHTML;
// console.log("3d转换之后4",ht4)
console . log ( "当前的所有html内容3" , this . tempDivData . innerHTML )
let newDST = this . processHtmlWithIds ( this . tempDivData . innerHTML )
// const ht5 = this.tempDivData.innerHTML;
// console.log("3d转换之后5",ht5)
console . log ( "结果cleanedStr 然后赋值" , this . tempDivData . innerHTML )
console . log ( "加ID后的" , newDST )
//去掉table里面的东西
2025-10-11 11:08:42 +08:00
if ( newDST ) {
newDST = this . removeColgroup ( newDST )
} else {
newDST = '' ;
}
2025-09-15 09:58:52 +08:00
// const ht6 = this.tempDivData.innerHTML;
// console.log("3d转换之后6",ht6)
if ( this . loadFileDMC ) {
newDST = this . loadFileDMC ;
}
console . log ( "解析出来后的" , newDST )
const xmlString = ` <?xml version="1.0" encoding="UTF-8"?>
2025-10-11 11:08:42 +08:00
< dmodule xmlns :xlink = "http://www.w3.org/1999/xlink" xmlns :rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns :dc = "http://www.purl.org/dc/elements/1.1/" >
2025-09-15 09:58:52 +08:00
< rdf : Description >
< dc : title > ` +desStr.name+ ` < / d c : t i t l e >
< dc : creator > ` +desStr.creator+ ` < / d c : c r e a t o r >
< dc : permission > ` +desStr.permission+ ` < / d c : p e r m i s s i o n >
< dc : subject / >
< dc : publisher > ` +desStr.creator+ ` < / d c : p u b l i s h e r >
< dc : contributor > ` +desStr.contributor+ ` < / d c : c o n t r i b u t o r >
< dc : version > ` +desStr.version+ ` < / d c : v e r s i o n >
< dc : level > ` +desStr.level+ ` < / d c : l e v e l >
< dc : date > ` +desStr.date+ ` < / d c : d a t e >
< dc : applicabilityInformation > ` +desStr.applicabilityInformation+ ` < / d c : a p p l i c a b i l i t y I n f o r m a t i o n >
< dc : qualityVerification > ` +desStr.qualityVerification+ ` < / d c : q u a l i t y V e r i f i c a t i o n >
< dc : type > text < / d c : t y p e >
< dc : format > text / xml < / d c : f o r m a t >
< dc : identifier > ` +this.getDmName+ ` < / d c : i d e n t i f i e r >
< dc : language > ` +desStr.language+ ` < / d c : l a n g u a g e >
< dc : rights > 01 < / d c : r i g h t s >
< / r d f : D e s c r i p t i o n >
< identAndStatusSection >
< dmAddress >
< dmIdent >
< dmCode
modelIdentCode = "EXAMPLE01"
systemDiffCode = "A1"
systemCode = "SYS"
subSystemCode = "A"
subSubSystemCode = "B"
assyCode = "AS01"
disassyCode = "DS"
disassyCodeVariant = "001"
infoCode = "INF"
infoCodeVariant = "1"
itemLocationCode = "A"
/ >
< language languageIsoCode = "en" countryIsoCode = "US" / >
< issueInfo issueNumber = "001" inWork = "01" / >
< / dmIdent >
< dmAddressItems >
< issueDate year = "2023" month = "06" day = "15" / >
< dmTitle >
< techName > Example Technical Document < / techName >
< / dmTitle >
< / dmAddressItems >
< / dmAddress >
< dmStatus >
< security securityClassification = "01" / >
< responsiblePartnerCompany enterpriseCode = "COMP001" >
< enterpriseName > Example Company < / enterpriseName >
< / responsiblePartnerCompany >
< originator > John Doe < / originator >
< brexDmRef > BREX001 < / brexDmRef >
< qualityAssurance > QA passed < / qualityAssurance >
< / dmStatus >
< / identAndStatusSection >
< content > `
+ newDST +
` </content>
< / dmodule > `
// this.tempDivData.innerHTML
// ${this.convertHtmlToXmlContent(this.editorContent)}
console . log ( "${tempDiv.innerHTML}" , this . tempDivData . innerHTML )
console . log ( "${tempDiv}" , this . tempDivData )
let xmlData = this . fixHrTagsInContent ( this . fixBrTagsInContent ( this . fixImgTagsInContent ( xmlString , false ) , false ) , false ) ;
2025-10-11 11:08:42 +08:00
console . log ( "存储最终1" , this . tempDivData )
console . log ( "存储最终2" , xmlString )
console . log ( "存储最终3" , xmlData )
2025-09-15 09:58:52 +08:00
//存富文本信息
// const ht7 = this.tempDivData.innerHTML;
// console.log("3d转换之后7",ht7)
// const ht8 = xmlData;
// console.log("3d转换之后8",ht8)
// xmlData = this.replacemodel3dImages(xmlData);
if ( type ) {
console . log ( "存富文本内容时候1" , type , this . nowMaxId , xmlData )
this . $sendToDotNet ( 'SaveFile' , 'DMC' , this . nowMaxId , xmlData , '000' ) ;
} else {
console . log ( "存富文本内容时候2" , type , saveId , this . currentNode , xmlData )
this . $sendToDotNet ( 'SaveFile' , 'DMC' , saveId ? saveId : this . currentNode . id , xmlData , this . currentNode . lagreVersion ) ;
this . lastClick = this . currentNode . id ;
}
2025-10-11 11:08:42 +08:00
this . contentXmlStr = this . editor . txt . html ( ) ;
2025-09-15 09:58:52 +08:00
if ( this . navIsAdd == 'create' ) {
// this.currentNode = '';
// this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.nowMaxId+this.domNameStr[3]+this.domNameStr[4];
// console.log("新建目录以后调到新的DMC",this.getDmName)
// this.loadFWBFile(this.getDmName);
}
// this.successTips('目录保存完成')
// 处理content标签内的img标签
// this.xmlDownload(xmlData)
// this.xmlDownload(this.fixImgTagsInContent(xmlString, false))
} ,
// 创建XML文件然后下载
xmlDownload ( xmlString ) {
// Create download link
const blob = new Blob ( [ xmlString ] , { type : 'text/xml' } )
const url = URL . createObjectURL ( blob )
const a = document . createElement ( 'a' )
a . href = url
a . download = 'document.xml'
document . body . appendChild ( a )
a . click ( )
document . body . removeChild ( a )
URL . revokeObjectURL ( url )
} ,
// // XML文件标签剔除
// restoreContent(html) {
// console.log("XML初始内容: ",html)
// if (html) {
// const tempDiv = document.createElement('div')
// tempDiv.innerHTML = html
// // 处理所有dmTitle标签
// const dmTitles = tempDiv.querySelectorAll('dmTitle')
// dmTitles.forEach(dmTitle => {
// // 获取dmTitle的子节点
// const children = Array.from(dmTitle.childNodes)
// // 在dmTitle之前插入所有子节点
// children.forEach(child => {
// dmTitle.parentNode.insertBefore(child.cloneNode(true), dmTitle)
// })
// // 移除dmTitle
// dmTitle.parentNode.removeChild(dmTitle)
// })
// console.log('内容还原完成! dmTitle标签已被移除')
// console.log("tempDiv.innerHTML",tempDiv.innerHTML)
// this.editor.txt.html(tempDiv.innerHTML)
// }else{
// console.log("空白文档")
// this.editor.txt.html('')
// }
// this.editor.txt.html(tempDiv.innerHTML)
// },
//删除视频
deleteAllVideos ( ) {
const videoWrappers = document . querySelectorAll ( '.video-wrapper' )
if ( videoWrappers . length === 0 ) {
console . log ( '没有找到可删除的视频' )
return
}
videoWrappers . forEach ( wrapper => {
wrapper . remove ( )
} )
// 删除可能残留的空段落
const editor = this . $refs . editor
const paragraphs = editor . querySelectorAll ( 'p' )
paragraphs . forEach ( p => {
if ( p . textContent . trim ( ) === '' && p . children . length === 0 ) {
p . remove ( )
}
} )
// 使用正确的方式通知内容变更
if ( this . editor . txt ) {
this . editor . txt . html ( this . editor . txt . html ( ) ) // 强制更新编辑器内容
}
console . log ( ` 已删除 ${ videoWrappers . length } 个视频 ` )
} ,
// 加载所有内容到 main 容器
loadAllContent ( ) {
const mainContainer = document . getElementById ( 'main' )
mainContainer . innerHTML = this . editorContent ;
console . log ( "this.editorContent" , this . editorContent )
// 为main容器中的标题添加ID
this . addHeadingIds ( mainContainer )
} ,
// 为标题元素添加ID
addHeadingIds ( container ) {
const headings = container . querySelectorAll ( 'h1, h2, h3, h4, h5, h6' )
headings . forEach ( ( heading , index ) => {
if ( ! heading . id ) {
heading . id = ` heading- ${ index } - ${ Date . now ( ) } `
console . log ( "Date.now" , Date . now ( ) )
}
} )
} ,
// 生成带锚点的目录
generateTOC ( ) {
const navContainer = document . getElementById ( 'nav' )
navContainer . innerHTML = '' // 清空原有目录
// 确保main容器已加载内容
// if (!document.getElementById('main').innerHTML) {
this . loadAllContent ( )
// }
const mainContainer = document . getElementById ( 'main' )
const headings = mainContainer . querySelectorAll ( 'h1, h2, h3, h4, h5, h6' )
console . log ( "headings.length" , headings . length )
if ( headings . length === 0 ) {
2025-07-25 13:28:47 +08:00
navContainer . innerHTML = '<p>没有找到标题元素,无法生成目录。</p>'
return
}
const tocList = document . createElement ( 'ul' )
tocList . style . listStyleType = 'none'
tocList . style . paddingLeft = '0'
headings . forEach ( heading => {
2025-09-15 09:58:52 +08:00
console . log ( "heading" , )
2025-07-25 13:28:47 +08:00
const level = parseInt ( heading . tagName . substring ( 1 ) )
const listItem = document . createElement ( 'li' )
2025-09-15 09:58:52 +08:00
listItem . style . marginLeft = ` ${ ( level - 1 ) * 1.2 } rem ` ;
listItem . style . marginBottom = '5px' ;
let fontSize = '12px'
switch ( level ) {
case 1 :
fontSize = '30px'
break ;
case 2 :
fontSize = '26px'
break ;
case 3 :
fontSize = '22px'
break ;
case 4 :
fontSize = '18px'
break ;
case 5 :
fontSize = '20px'
break ;
}
listItem . style . fontSize = fontSize ;
2025-07-25 13:28:47 +08:00
const link = document . createElement ( 'a' )
link . href = ` # ${ heading . id } `
link . textContent = heading . textContent
link . style . textDecoration = 'none'
link . style . color = '#333'
// 添加平滑滚动效果
link . addEventListener ( 'click' , ( e ) => {
e . preventDefault ( )
document . getElementById ( heading . id ) . scrollIntoView ( {
behavior : 'smooth'
} )
} )
listItem . appendChild ( link )
2025-09-15 09:58:52 +08:00
tocList . appendChild ( listItem )
2025-07-25 13:28:47 +08:00
} )
const tocContainer = document . createElement ( 'div' )
tocContainer . style . border = '1px solid #ddd'
tocContainer . style . padding = '15px'
tocContainer . style . marginBottom = '20px'
tocContainer . style . background = '#f9f9f9'
tocContainer . style . borderRadius = '4px'
const tocTitle = document . createElement ( 'h2' )
tocTitle . textContent = '目录'
tocTitle . style . marginTop = '0'
tocContainer . appendChild ( tocTitle )
tocContainer . appendChild ( tocList )
navContainer . appendChild ( tocContainer )
2025-07-28 17:01:13 +08:00
} ,
2025-09-15 09:58:52 +08:00
// 处理所有标题元素的ID
processHeadingIds ( ) {
if ( ! this . editor ) return
// 获取当前时间戳( 简化版, 只取后8位)
const timestamp = Date . now ( ) . toString ( ) . slice ( - 8 ) ;
let timestamps = parseInt ( Date . now ( ) . toString ( ) . slice ( - 8 ) ) ;
console . log ( "时间戳" , timestamp , timestamps )
// 获取编辑器内容
const editorHtml = this . editor . txt . html ( )
if ( ! editorHtml ) return
// 创建一个临时div来操作DOM
const tempDiv = document . createElement ( 'div' )
tempDiv . innerHTML = editorHtml
// 获取所有标题元素
const headings = tempDiv . querySelectorAll ( 'h1, h2, h3, h4, h5, h6' )
headings . forEach ( ( heading , index ) => {
console . log ( "index" , index )
// 生成3个随机字母 + 时间戳后8位
// const newId = `heading-${randomLetters}-${timestamp}`
const randomLetters = this . getRandomLetters ( this . idLength )
// const newId = `${heading.id}${randomLetters}${timestamps}`
timestamps ++ ;
console . log ( "timestamp" , timestamps )
const newId = ` ${ randomLetters } `
if ( heading . id . length < this .idLength ) {
heading . id = newId
}
} )
// 将修改后的HTML设置回编辑器
this . editor . txt . html ( tempDiv . innerHTML ) ;
setTimeout ( ( ) => {
this . generateTOC ( )
} , 200 ) ;
} ,
// 生成随机字母
getRandomLetter ( ) {
const letters = 'abcdefghijklmnopqrstuvwxyz1234567890'
return letters . charAt ( Math . floor ( Math . random ( ) * letters . length ) )
} ,
// 生成随机字母组合
getRandomLetters ( length ) {
let result = ''
for ( let i = 0 ; i < length ; i ++ ) {
result += this . getRandomLetter ( )
}
return result
} ,
2025-10-11 11:08:42 +08:00
2025-07-28 17:01:13 +08:00
// XML特殊字符转义
escapeXml ( unsafe ) {
return unsafe . replace ( /[<>&'"]/g , ( c ) => {
switch ( c ) {
case '<' : return '<' ;
case '>' : return '>' ;
case '&' : return '&' ;
case '\'' : return ''' ;
case '"' : return '"' ;
default : return c ;
}
} ) ;
} ,
2025-10-11 11:08:42 +08:00
2025-07-28 17:01:13 +08:00
// 从S1000D XML导入
handleS1000DUpload ( event ) {
const file = event . target . files [ 0 ] ;
if ( ! file ) return ;
const reader = new FileReader ( ) ;
reader . onload = ( e ) => {
const xmlString = e . target . result ;
const html = this . extractContentFromS1000D ( xmlString ) ;
2025-09-15 09:58:52 +08:00
// const parser = new DOMParser();
// const xmlDoc = parser.parseFromString(html, 'text/xml');
// 获取 content 元素
const contentElement = html . querySelector ( 'content' ) ;
console . log ( "contentElement" , contentElement )
if ( contentElement ) {
// 提取 content 内部的所有子节点并转换为字符串
let innerHtml = '' ;
Array . from ( contentElement . childNodes ) . forEach ( node => {
innerHtml += new XMLSerializer ( ) . serializeToString ( node ) ;
} ) ;
console . log ( "innerHtml" , innerHtml )
this . editor . txt . html ( innerHtml )
2025-10-11 11:08:42 +08:00
}
2025-07-28 17:01:13 +08:00
// 重置input值, 允许重复选择同一文件
event . target . value = '' ;
} ;
reader . readAsText ( file ) ;
} ,
// 从S1000D XML提取内容
extractContentFromS1000D ( xmlString ) {
try {
// 简单提取description内容
const descriptionMatch = xmlString . match ( /<description>([\s\S]*?)<\/description>/i ) ;
if ( ! descriptionMatch || ! descriptionMatch [ 1 ] ) {
throw new Error ( '未找到description内容' ) ;
}
// 反转义XML特殊字符
let content = descriptionMatch [ 1 ]
. replace ( /</g , '<' )
. replace ( />/g , '>' )
. replace ( /&/g , '&' )
. replace ( /'/g , "'" )
. replace ( /"/g , '"' ) ;
// 移除可能的多余空格和换行
content = content . trim ( ) ;
return content ;
} catch ( e ) {
console . error ( 'S1000D导入错误:' , e ) ;
alert ( ` 导入S1000D XML失败: ${ e . message } ` ) ;
return '' ;
}
} ,
2025-09-15 09:58:52 +08:00
rgbToHex ( r , g , b ) { //色号转换
console . log ( "colors" , this . colors )
return ` # ${ [ r , g , b ] . map ( x => x . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) } ` ;
2025-10-11 11:08:42 +08:00
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
//保存内容到XML
generateXml ( type , saveId ) {
this . dataXmlProcessing ( type , saveId ) ;
} ,
//测试 保存目录到XML
navXml ( ) {
const xmlString = ` <?xml version="1.0" encoding="UTF-8"?>
< dmodule xmlns :xlink = "http://www.w3.org/1999/xlink" xmlns :rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
< identAndStatusSection >
< dmAddress >
< dmIdent >
< dmCode
modelIdentCode = "EXAMPLE01"
systemDiffCode = "A1"
systemCode = "SYS"
subSystemCode = "A"
subSubSystemCode = "B"
assyCode = "AS01"
disassyCode = "DS"
disassyCodeVariant = "001"
infoCode = "INF"
infoCodeVariant = "1"
itemLocationCode = "A"
/ >
< language languageIsoCode = "en" countryIsoCode = "US" / >
< issueInfo issueNumber = "001" inWork = "01" / >
< / dmIdent >
< dmAddressItems >
< issueDate year = "2023" month = "06" day = "15" / >
< dmTitle >
< techName > Example Technical Document < / techName >
< / dmTitle >
< / dmAddressItems >
< / dmAddress >
< dmStatus >
< security securityClassification = "01" / >
< responsiblePartnerCompany enterpriseCode = "COMP001" >
< enterpriseName > Example Company < / enterpriseName >
< / responsiblePartnerCompany >
< originator > John Doe < / originator >
< brexDmRef > BREX001 < / brexDmRef >
< qualityAssurance > QA passed < / qualityAssurance >
< / dmStatus >
< / identAndStatusSection >
< content > < infoCode > `
+ JSON . stringify ( this . treeData ) +
` </infoCode></content>
< / dmodule > ` ;
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
const blob = new Blob ( [ xmlString ] , { type : 'text/xml' } )
const url = URL . createObjectURL ( blob )
const a = document . createElement ( 'a' )
a . href = url
a . download = 'mulu.xml'
document . body . appendChild ( a )
a . click ( )
document . body . removeChild ( a )
URL . revokeObjectURL ( url )
} ,
//测试 加载XML
loadXml ( ) {
this . $refs . fileInput . click ( )
} ,
//测试 选择文件
handleFileUpload ( event ) {
const file = event . target . files [ 0 ]
if ( ! file ) return
const reader = new FileReader ( )
reader . onload = ( e ) => {
const xmlContent = e . target . result
// console.log("xmlContent",xmlContent)
const parser = new DOMParser ( )
const xmlDoc = parser . parseFromString ( xmlContent , "text/xml" )
console . log ( "xmlDoc" , xmlDoc )
const contentNodes = xmlDoc . getElementsByTagName ( 'content' ) [ 0 ] ;
console . log ( "xmlDoc.getElementsByTagName('content')" , xmlDoc . getElementsByTagName ( 'content' ) )
console . log ( "contentNodes" , contentNodes )
if ( contentNodes ) {
const htmlContent = this . convertXmlContentToHtml ( contentNodes . innerHTML )
// this.editor.txt.html(htmlContent)
//处理过后再导入
// this.restoreContent(htmlContent)
this . restoreContentXh ( htmlContent )
}
2025-07-25 13:28:47 +08:00
}
2025-09-15 09:58:52 +08:00
reader . readAsText ( file )
} ,
completeModel3DTags ( htmlString ) {
// 处理自闭合的model3d标签, 替换为完整的闭合标签
return htmlString . replace ( /<model3d([^>]*?)\/>/g , ( match , attributes ) => {
// 返回带有相同属性的完整闭合标签
return ` <model3d ${ attributes } ></model3d> ` ;
} ) ;
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 解析xml里面 content内容
convertXmlContentToHtml ( xmlContent ) {
return xmlContent
. replace ( /<para>/g , '<p>' )
. replace ( /<\/para>/g , '</p>' )
. replace ( /<emphasis emphasisType="bold">/g , '<strong>' )
. replace ( /<\/emphasis>/g , '</strong>' )
. replace ( /<emphasis emphasisType="italic">/g , '<em>' )
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
/ * *
* 修复content标签内的img标签闭合符
* @ param { string } inputStr 输入HTML
* @ param { boolean } useSlash 是否使用自闭合
* @ returns { string } 修正后的HTML
* /
fixImgTagsInContent ( inputStr , useSlash ) {
const contentRegex = /<content>([\s\S]*?)<\/content>/g
return inputStr . replace ( contentRegex , ( contentMatch , innerContent ) => {
const fixedInnerContent = innerContent . replace (
/<img\b([^>]*)>/g ,
( imgMatch , imgAttributes ) => {
// 已有闭合符则不处理
if ( imgMatch . endsWith ( '/>' ) || imgMatch . includes ( '</img>' ) ) {
return imgMatch
}
// 根据参数决定闭合方式
return useSlash
? ` <img ${ imgAttributes } /> `
: ` <img ${ imgAttributes } ></img> `
}
)
return ` <content> ${ fixedInnerContent } </content> `
} )
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 检测hr标签是否闭合
fixHrTagsInContent ( inputStr , useSlash ) {
const contentRegex = /<content>([\s\S]*?)<\/content>/g
return inputStr . replace ( contentRegex , ( contentMatch , innerContent ) => {
const fixedInnerContent = innerContent . replace (
/<hr\b([^>]*)>/g ,
( imgMatch ) => {
// 已有闭合符则不处理
if ( imgMatch . endsWith ( '/>' ) || imgMatch . includes ( '</hr>' ) ) {
return imgMatch
}
// 根据参数决定闭合方式
return useSlash
? ` <hr/> `
: ` <hr></hr> `
}
)
return ` <content> ${ fixedInnerContent } </content> `
} )
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// 检测br标签是否闭合
fixBrTagsInContent ( inputStr , useSlash ) {
const contentRegex = /<content>([\s\S]*?)<\/content>/g
return inputStr . replace ( contentRegex , ( contentMatch , innerContent ) => {
const fixedInnerContent = innerContent . replace (
/<br\b([^>]*)>/g ,
( imgMatch , imgAttributes ) => {
// 已有闭合符则不处理
if ( imgMatch . endsWith ( '/>' ) || imgMatch . includes ( '</br>' ) ) {
return imgMatch
}
// 根据参数决定闭合方式
return useSlash
? ` <br ${ imgAttributes } /> `
: ` <br ${ imgAttributes } ></br> `
}
)
return ` <content> ${ fixedInnerContent } </content> `
} )
} ,
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
//富文本内容打标签
dataXmlProcessing ( type , saveId ) {
let html = this . editor . txt . html ( )
console . log ( '保存内容' , html ) ;
// 正则表达式: 匹配img、audio、video标签的src属性
// 支持三种标签:<img ...>、<audio ...>、<video ...>
// 捕获组1: 标签名和src="之前的部分
// 捕获组2: 提取文件名(最后一个/后面的内容)
// 捕获组3: 保留"及之后的部分
const reg = /(<(img|audio|video)[^>]+src=")[^"]+\/([^"]+)("[^>]*>)/gi ;
// 替换为: src="文件名"
let html _1 = html . replace ( reg , '$1$3$4' ) ;
console . log ( '解析地址:' , html _1 )
2025-07-25 13:28:47 +08:00
2025-09-15 09:58:52 +08:00
// const reg2 = /(<(img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi;
// let jc = 'http://localhost:5432/';
// // 替换为: src="基础URL+文件名"
// // 这里假设原路径可能包含DM_Material目录, 如果不需要可以去掉
// let html_2 = html_1.replace(reg2, `$1${jc}$3$4`);
// console.log('还原地址:',html_2)
this . tempDivData = document . createElement ( 'div' )
html _1 = this . replacemodel3dImages ( html _1 ) ;
// const ht1 = html_1;
// console.log("3d转换之后1",ht1)
this . tempDivData . innerHTML = html _1 ;
this . xh ( this . oldSelector , this . newSelector , type , saveId ) ;
} ,
// XML文件标签剔除
restoreContentXh ( html ) {
console . log ( "XML初始内容: " , html )
if ( html ) {
this . tempDivData = document . createElement ( 'div' )
this . tempDivData . innerHTML = html
let times = this . oldSelector . length ;
for ( let i = 0 ; i < times ; i + + ) {
// 处理所有dmTitle标签
const dmTitles = this . tempDivData . querySelectorAll ( this . newSelector [ i ] )
dmTitles . forEach ( dmTitle => {
// 获取dmTitle的子节点
const children = Array . from ( dmTitle . childNodes )
console . log ( "剔除标签:" , dmTitles , children )
// 在dmTitle之前插入所有子节点
children . forEach ( child => {
dmTitle . parentNode . insertBefore ( child . cloneNode ( true ) , dmTitle )
} )
// 移除dmTitle
dmTitle . parentNode . removeChild ( dmTitle )
console . log ( "剔除标签移除:" , dmTitle , '替换成' , dmTitle )
} )
}
console . log ( '内容还原完成! dmTitle标签已被移除' )
console . log ( "tempDiv.innerHTML" , this . tempDivData . innerHTML )
const reg2 = /(<(img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi ;
let jc = this . lisenPath ;
// 检查并去除开头的双引号
if ( jc . startsWith ( '"' ) ) {
jc = jc . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( jc . endsWith ( '"' ) ) {
jc = jc . substring ( 0 , jc . length - 1 ) ;
}
// 替换为: src="基础URL+文件名"
// 这里假设原路径可能包含DM_Material目录, 如果不需要可以去掉
let html _2 = this . tempDivData . innerHTML . replace ( reg2 , ` $ 1 ${ jc } $ 3 $ 4 ` ) ;
// html_2 = this.modelToImg(html_2);
console . log ( '还原地址:' , html _2 )
this . editor . txt . html ( html _2 )
this . contentXmlStr = this . editor . txt . html ( ) ;
} else {
console . log ( "空白文档" )
this . editor . txt . html ( '' )
this . contentXmlStr = this . editor . txt . html ( ) ;
}
} ,
// XML文件标签剔除
restoreContentXh2 ( html ) {
console . log ( "XML初始内容: " , html )
if ( html ) {
this . tempDivData1 = document . createElement ( 'div' )
this . tempDivData1 . innerHTML = html
let times = this . oldSelector . length ;
for ( let i = 0 ; i < times ; i + + ) {
// 处理所有dmTitle标签
const dmTitles = this . tempDivData1 . querySelectorAll ( this . newSelector [ i ] )
dmTitles . forEach ( dmTitle => {
// 获取dmTitle的子节点
const children = Array . from ( dmTitle . childNodes )
console . log ( "剔除标签:" , dmTitles , children )
// 在dmTitle之前插入所有子节点
children . forEach ( child => {
dmTitle . parentNode . insertBefore ( child . cloneNode ( true ) , dmTitle )
} )
// 移除dmTitle
dmTitle . parentNode . removeChild ( dmTitle )
console . log ( "剔除标签移除:" , dmTitle , '替换成' , dmTitle )
} )
}
console . log ( '内容还原完成! dmTitle标签已被移除' )
console . log ( "tempDiv.innerHTML" , this . tempDivData1 . innerHTML )
const reg2 = /(<(model3d|img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi ;
let jc = this . viewLis ;
// 检查并去除开头的双引号
if ( jc . startsWith ( '"' ) ) {
jc = jc . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( jc . endsWith ( '"' ) ) {
jc = jc . substring ( 0 , jc . length - 1 ) ;
}
if ( ! this . dialogVisibleNav ) {
jc = jc + this . historyVsPath + '/' ;
}
// 替换为: src="基础URL+文件名"
// 这里假设原路径可能包含DM_Material目录, 如果不需要可以去掉
2025-10-11 11:08:42 +08:00
let html _2 = this . tempDivData1 . innerHTML . replace ( reg2 , ` $ 1 ${ jc } $ 3 $ 4 ` ) ;
2025-09-15 09:58:52 +08:00
// html_2 = this.modelToImg(html_2);
2025-10-11 11:08:42 +08:00
console . log ( "大豪科技等哈时间" , this . viewLis )
console . log ( '加载还原地址:' , html _2 )
let processedL = this . hintFun ( html _2 )
this . neirong = this . modelToImg ( processedL ) ;
2025-09-15 09:58:52 +08:00
// document.getElementsByClassName("loadContent")[0].innerHTML=html_2;
// document.getElementsByClassName("loadContent1")[0].innerHTML=html_2;
2025-10-11 11:08:42 +08:00
// console.log('加载还原地址:',html_3)
2025-09-15 09:58:52 +08:00
// this.editor.txt.html(html_2)
// this.contentXmlStr = this.editor.txt.html();
} else {
console . log ( "空白文档" )
// this.editor.txt.html('')
// this.contentXmlStr = this.editor.txt.html();
}
} ,
2025-10-11 11:08:42 +08:00
hintFun ( html _2 ) {
let html = html _2 ;
// 先定义所有需要用到的变量,确保初始化顺序
// 需要移除的class
// const classesToRemove = ['borderStyle_yellow', 'borderStyle_red'];
// // 处理class属性 - 先替换指定class
// html = html.replace(/class="([^"]*)"/g, (match, classValues) => {
// let newClassValues = classValues;
// // 在替换函数内部定义class映射, 确保在使用前初始化
// const classMappings = {
// 'teshu': 'testBo',
// 'teshu2': 'testBo2'
// };
// // 替换class
// Object.keys(classMappings).forEach(oldClass => {
// const newClass = classMappings[oldClass];
// const regex = new RegExp(`\\b${oldClass}\\b`, 'g');
// newClassValues = newClassValues.replace(regex, newClass);
// });
// // 移除不需要的class
// classesToRemove.forEach(classToRemove => {
// const regex = new RegExp(`\\b${classToRemove}\\b\\s*`, 'g');
// newClassValues = newClassValues.replace(regex, '').trim();
// });
// return `class="${newClassValues}"`;
// });
// 定义需要替换的class映射关系
const classMappings = {
'teshu' : 'testBo' ,
'teshu2' : 'testBo2'
} ;
// 使用正则表达式匹配class属性并替换相应的值
// 这个正则表达式会匹配class属性中的各个class名称
html = html . replace ( /class="([^"]*)"/g , ( match , classValues ) => {
let newClassValues = classValues ;
// 遍历替换映射, 替换每个需要替换的class
Object . keys ( classMappings ) . forEach ( oldClass => {
const newClass = classMappings [ oldClass ] ;
// 使用单词边界确保只替换完整的class名称
const regex = new RegExp ( ` \\ b ${ oldClass } \\ b ` , 'g' ) ;
newClassValues = newClassValues . replace ( regex , newClass ) ;
} ) ;
return ` class=" ${ newClassValues } " ` ;
} ) ;
const regex = / ( < d i v \ s + [ ^ > ] * c l a s s = " [ ^ " ] * ( t e s t B o 2 | t e s t B o ) [ ^ " ] * " [ ^ > ] * > ) ( . * ? ) ( < \ / d i v > ) / g i s ;
html = html . replace ( regex , ( match , startTag , className , content , endTag ) => {
// 验证捕获的className
console . log ( '捕获的class名称:' , className ) ;
// 定义不同class对应的边框样式
let borderStyle ;
if ( className === 'testBo2' ) {
borderStyle = '3px solid #ffcc00' ; // testBo的边框样式(深黄色)
} else if ( className === 'testBo' ) {
borderStyle = '3px solid red' ; // testBo2的边框样式(红色)
}
// 包裹div的完整样式
const wrapperStyle = ` background:#fff;padding: 10px;border: ${ borderStyle } ;border-radius: 8px; ` ;
// 包裹内容
const wrappedContent = ` <div style=' ${ wrapperStyle } '> ${ content } </div> ` ;
// 返回处理后的标签
return ` ${ startTag } ${ wrappedContent } ${ endTag } ` ;
} ) ;
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
return html ;
// const regex = /\s*class\s*=\s*"teshu"\s*/gi;
// const regex2 = /\s*class\s*=\s*"teshu2"\s*/gi;
// // 将匹配到的class替换为class="testBo"
// const styleRegex = /(<div[^>]*?)style\s*=\s*"[^"]*?"\s*([^>]*?class\s*=\s*"teshu"[^>]*?>)/gi;
// html_2 = html_2.replace(styleRegex, '$1$2');
// const styleRegex2 = /(<div[^>]*?)style\s*=\s*"[^"]*?"\s*([^>]*?class\s*=\s*"teshu2"[^>]*?>)/gi;
// html_2 = html_2.replace(styleRegex2, '$1$2');
// let html_3 = html_2.replace(regex, ' class="testBo"');
// let html_4 = html_3.replace(regex2, ' class="testBo2"');
// // let html_4 = html_3;
// // 正则表达式匹配class="testBo"的div标签
// // 匹配模式:<div class="testBo"[属性...]>内容</div>
// const regex1 = /(<div\s+class="testBo"[^>]*>)(.*?)(<\/div>)/gi;
// const regex22 = /(<div\s+class="testBo2"[^>]*>)(.*?)(<\/div>)/gi;
// // 替换匹配到的内容
// // 在原内容外层包裹<div style='background:#fff'>...</div>
// let processed = html_4.replace(regex22, (match, startTag, content, endTag) => {
// return `${startTag}<div style='background:#fff;padding: 10px;
// border: 3px solid #000;
// border-radius: 8px;
// '>${content}</div>${endTag}`;
// });
// console.log("预览数据processed",processed)
// let processedL = processed.replace(regex1, (match, startTag, content, endTag) => {
// return `${startTag}<div style='background:#fff;padding: 10px;
// border: 3px solid #000;
// border-radius: 8px;
// '>${content}</div>${endTag}`;
// });
// console.log("预览数据processedL",processedL)
// return processedL
} ,
2025-09-15 09:58:52 +08:00
//处理 3d模型标签
replaceModel3dToImg ( htmlString ) {
// 创建临时DOM元素处理HTML
const tempDiv = document . createElement ( 'div' ) ;
tempDiv . innerHTML = htmlString ;
// 查找所有model3d标签
const model3dElements = tempDiv . querySelectorAll ( 'model3d' ) ;
model3dElements . forEach ( model3d => {
// 创建新的img元素
const img = document . createElement ( 'img' ) ;
// 复制所有属性
Array . from ( model3d . attributes ) . forEach ( attr => {
img . setAttribute ( attr . name , attr . value ) ;
} ) ;
// 替换元素
model3d . parentNode . replaceChild ( img , model3d ) ;
} ) ;
return tempDiv . innerHTML ;
} ,
//判断富文本内容是否更改
dmcIsChange ( ) {
2025-10-11 11:08:42 +08:00
if ( this . editor ) { //初始化时候
console . log ( "this.editor.txt.html()" , this . editor . txt . html ( ) )
console . log ( "this.contentXmlStr" , this . contentXmlStr )
console . log ( "验证结果" , this . editor . txt . html ( ) == this . contentXmlStr )
return this . editor . txt . html ( ) == this . contentXmlStr ;
} else {
return true
}
2025-09-15 09:58:52 +08:00
} ,
//测试 启用右键功能
enableContextMenu ( ) {
console . log ( "进入isContextMenuEnabled" , this . isContextMenuEnabled )
if ( this . isContextMenuEnabled ) return ;
this . isContextMenuEnabled = true ;
// 获取#nav下的所有li元素
const tocItems = document . querySelectorAll ( '.elTree .el-tree-node__content' ) ;
// 为每个li元素绑定右键事件
tocItems . forEach ( ( item , index ) => {
// 为元素设置唯一ID
const elementId = ` toc-item- ${ index } ` ;
item . id = elementId ;
// 初始化参数存储
if ( ! this . itemParams [ elementId ] ) {
this . $set ( this . itemParams , elementId , '' ) ;
}
item . addEventListener ( 'contextmenu' , ( e ) => {
e . preventDefault ( ) ;
this . showContextMenu ( e , item ) ;
} ) ;
item . addEventListener ( 'click' , ( e ) => {
console . log ( "左键" , e , item )
this . dialogVisible = true ;
} ) ;
} ) ;
// alert('右键菜单功能已启用!');
} ,
//测试 显示右键菜单
showContextMenu ( e , element ) {
console . log ( "ID" , element )
// 获取该 <a> 元素
// const linkElement = element.querySelector('#toc-item-0 a');
// 提取 # 后面的参数
// const hashValue = linkElement.getAttribute('href');
// const hashValue2 = hashValue.split('#')[1];
// console.log(hashValue,hashValue2);
if ( ! this . isContextMenuEnabled ) return ;
// 设置右键菜单位置和当前选中元素
this . contextMenu = {
visible : true ,
x : e . clientX ,
y : e . clientY ,
selectedElement : element ,
selectedParam : this . itemParams [ element . id ] || ''
}
// 点击其他地方关闭菜单
document . addEventListener ( 'click' , this . closeContextMenu , { once : true } ) ;
} ,
//测试 关闭右键菜单
closeContextMenu ( ) {
this . contextMenu . visible = false ;
} ,
//测试 选择右键菜单选项
selectMenuOption ( option ) {
if ( this . contextMenu . selectedElement ) {
const element = this . contextMenu . selectedElement ;
// 更新元素的参数
this . $set ( this . itemParams , element . id , option ) ;
// 在元素上显示参数(可选)
const paramSpan = element . querySelector ( '.param-display' ) ;
if ( paramSpan ) {
paramSpan . textContent = ` ( ${ option } ) ` ;
} else {
const span = document . createElement ( 'span' ) ;
span . className = 'param-display' ;
span . style . cssText = 'color: #f00; margin-left: 10px;' ;
span . textContent = ` ( ${ option } ) ` ;
element . appendChild ( span ) ;
}
this . closeContextMenu ( ) ;
}
} ,
// 新增方法: 打印nav内容
logTocItems ( ) {
const navElement = document . getElementById ( 'nav' ) ;
if ( ! navElement ) {
console . error ( '未找到ID为"nav"的容器' ) ;
return ;
}
// 获取nav内的HTML内容
const navHtml = navElement . innerHTML ;
// 获取nav内的文本内容
const navText = navElement . innerText || navElement . textContent ;
// 获取结构化数据(包括参数)
const structuredData = this . getStructuredNavData ( ) ;
console . log ( '====== nav的HTML内容 ======' ) ;
console . log ( navHtml ) ;
console . log ( '====== nav的文本内容 ======' ) ;
console . log ( navText ) ;
console . log ( '====== nav的结构化数据 ======' ) ;
console . log ( structuredData ) ;
} ,
// 获取结构化数据
getStructuredNavData ( ) {
const items = document . querySelectorAll ( '#nav ul li' ) ;
return Array . from ( items ) . map ( item => {
return {
id : item . id ,
text : item . innerText . trim ( ) ,
html : item . innerHTML ,
param : this . itemParams [ item . id ] || '未设置'
} ;
} ) ;
} ,
//测试 查看图片
openDialog ( ) {
// this.imageStyle();
const imgItems = document . querySelectorAll ( '#main img' ) ;
console . log ( "imgItems" , imgItems )
imgItems . forEach ( ( item , index ) => {
item . addEventListener ( 'click' , ( e ) => {
console . log ( "左键" , e , item , index , item . src )
// 通过选择器获取
// let imgSrc = e.src;
this . scale = 1 ;
this . rotation = 0 ;
this . currentImage = item . src ;
this . dialogVisibleImg = true ;
} ) ;
} ) ;
// this.currentImage = this.images[index]
// this.dialogVisible = true
// this.reset() // 每次打开重置状态
} ,
//测试 放大
zoomIn ( ) {
console . log ( "放大" )
this . scale = 1.1 * this . scale
} ,
//测试 缩小
zoomOut ( ) {
if ( this . scale > 0.5 ) {
this . scale -= 0.2
}
} ,
//测试 旋转
rotate ( ) {
this . rotation += 90
} ,
//测试 重置
reset ( ) {
this . scale = 1
this . rotation = 0
this . translateX = 0
this . translateY = 0
} ,
//测试 开始拖动
startDrag ( e ) {
this . isDragging = true
this . startX = e . type === 'mousedown' ? e . clientX : e . touches [ 0 ] . clientX
this . startY = e . type === 'mousedown' ? e . clientY : e . touches [ 0 ] . clientY
document . addEventListener ( 'mousemove' , this . dragImage )
document . addEventListener ( 'touchmove' , this . dragImage )
document . addEventListener ( 'mouseup' , this . endDrag )
document . addEventListener ( 'touchend' , this . endDrag )
} ,
//测试 拖动图片
dragImage ( e ) {
if ( ! this . isDragging ) return
const clientX = e . type === 'mousemove' ? e . clientX : e . touches [ 0 ] . clientX
const clientY = e . type === 'mousemove' ? e . clientY : e . touches [ 0 ] . clientY
this . translateX += ( clientX - this . startX ) / this . scale
this . translateY += ( clientY - this . startY ) / this . scale
this . startX = clientX
this . startY = clientY
} ,
//测试 停止拖动
endDrag ( ) {
this . isDragging = false
document . removeEventListener ( 'mousemove' , this . dragImage )
document . removeEventListener ( 'touchmove' , this . dragImage )
document . removeEventListener ( 'mouseup' , this . endDrag )
document . removeEventListener ( 'touchend' , this . endDrag )
} ,
//测试 图片样式
imageStyle ( ) {
return {
transform : `
scale ( $ { this . scale } )
rotate ( $ { this . rotation } deg )
translate ( $ { this . translateX } px , $ { this . translateY } px )
` ,
cursor : this . isDragging ? 'grabbing' : 'grab'
}
} ,
gengxin ( ) {
2025-10-11 11:08:42 +08:00
if ( this . currentNode ) {
const element = document . querySelector ( '.w-e-toolbar' )
const container = document . querySelector ( '.w-e-text-container' ) ;
const rightDivHeight = document . querySelector ( ".rightDiv" ) . scrollHeight ;
container . style . height = ( rightDivHeight - element . scrollHeight - 86 ) + 'px' ;
console . log ( "内容高度" , ( rightDivHeight - element . scrollHeight - 86 ) + 'px' )
}
// const heightPx = (window.innerHeight - 240) + 'px';
// console.log("富文本框高度",heightPx)
// document.getElementsByClassName('w-e-text-container')[0].style.height =heightPx;
// document.getElementsByClassName('w-e-text-container')[1].style.height = (window.innerHeight - 240) + 'px' ;
2025-09-15 09:58:52 +08:00
} ,
//获取屏幕尺寸
getWindowSize ( ) {
// this.windowW = window.innerWidth
// this.windowH = window.innerHeigh
// t
this . leftHeight = window . innerHeight - 200 ;
2025-10-11 11:08:42 +08:00
this . editorHeight = window . innerHeight - 250 ;
if ( this . currentNode ) {
const element = document . querySelector ( '.w-e-toolbar' )
const container = document . querySelector ( '.w-e-text-container' ) ;
const rightDivHeight = document . querySelector ( ".rightDiv" ) . scrollHeight ;
container . style . height = ( rightDivHeight - element . scrollHeight - 86 ) + 'px' ;
console . log ( "内容高度" , ( rightDivHeight - element . scrollHeight - 86 ) + 'px' )
}
2025-09-15 09:58:52 +08:00
} ,
// 尺寸变化时的处理函数
handleResize ( ) {
// 使用节流优化性能(频繁触发时限制执行频率)
if ( this . resizeTimer ) clearTimeout ( this . resizeTimer )
this . resizeTimer = setTimeout ( ( ) => {
this . getWindowSize ( )
console . log ( '窗口尺寸变化:' , this . windowW , this . windowH )
// 在这里可以添加尺寸变化后的业务逻辑
// 例如:调整组件布局、重新计算元素位置等
} , 100 ) // 100ms 节流延迟,可根据需求调整
} ,
// 加载XML文件 dmc
loadFileBtn ( ) {
this . $sendToDotNet ( 'GetExistenceDMContent' )
} ,
// 获取屏幕和窗口尺寸
getScreenSize ( ) {
// 屏幕整体尺寸(设备的屏幕尺寸)
this . screenWidth = window . screen . width ;
this . screenHeight = window . screen . height ;
// 浏览器窗口尺寸(可视区域尺寸)
this . windowW = window . innerWidth ;
this . windowH = window . innerHeight ;
console . log ( "屏幕变化的尺寸" , window . screen . width , window . screen . height , window . innerWidth , window . innerHeight )
// 可以在这里添加需要根据尺寸执行的逻辑
this . handleSizeChange ( ) ;
} ,
// 处理窗口大小变化(使用防抖优化性能)
// handleResize() {
// // 清除之前的定时器
// if (this.resizeTimer) {
// clearTimeout(this.resizeTimer);
// }
// // 防抖: 50ms后再执行, 避免频繁触发
// this.resizeTimer = setTimeout(() => {
// this.getScreenSize();
// this.resizeTimer = null;
// }, 50);
// },
// 根据尺寸变化执行的逻辑
handleSizeChange ( ) {
// 这里可以添加尺寸变化时需要执行的操作
console . log ( '尺寸变化:' , {
screenWidth : this . screenWidth ,
screenHeight : this . screenHeight ,
windowWidth : this . windowW ,
windowHeight : this . windowH
} ) ;
} ,
//预览加载的XML
viewLoadDMFile ( ) {
this . maskViewShow = true ;
// this.draggableVis = true;
// localStorage.setItem("fileName",'dassad')
this . $sendToDotNet ( 'DMPreview' , 'UserLocalDMPreview' )
} ,
//解析加载的DMC
parseXmlDmc ( ) {
try {
// 解析XML字符串
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( this . loadFileXML , "text/xml" ) ;
// 检查解析错误
const errorNode = xmlDoc . querySelector ( "parsererror" ) ;
if ( errorNode ) {
throw new Error ( "XML解析错误: " + errorNode . textContent ) ;
}
// 提取content标签内容
this . extractContent ( xmlDoc ) ;
// 解析rdf:Description
this . parseRdfDescription ( xmlDoc ) ;
} catch ( error ) {
console . error ( "解析失败:" , error ) ;
// alert("解析XML失败: " + error.message);
}
} ,
//解析新建目录时候的DMC文件
parseXmlDmc _loadFile ( ) {
try {
// 解析XML字符串
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( this . viewXml , "text/xml" ) ;
2025-10-11 11:08:42 +08:00
console . log ( "得到的1" , xmlDoc )
2025-09-15 09:58:52 +08:00
// 检查解析错误
const errorNode = xmlDoc . querySelector ( "parsererror" ) ;
2025-10-11 11:08:42 +08:00
console . log ( "得到的2" , errorNode )
2025-09-15 09:58:52 +08:00
if ( errorNode ) {
throw new Error ( "XML解析错误: " + errorNode . textContent ) ;
}
// 提取content标签内容
this . extractContent2 ( xmlDoc ) ;
} catch ( error ) {
console . error ( "解析失败:" , error ) ;
// alert("解析XML失败: " + error.message);
}
} ,
//验证是否修改过的dmc文件
handleCheckVersion ( ) {
this . showModifyBtn = true ;
// 可选: 若需高亮有01版本的节点, 可在此处触发树重渲染
this . $nextTick ( ( ) => {
this . $refs . tree . updateKeyChildren ( ) ; // 强制树更新节点
} ) ;
} ,
// 3. 递归判断: 当前节点或其所有子节点是否存在minorVersion: '01'
hasMinorVersion01 ( node ) {
// 边界条件: 节点不存在则返回false
if ( ! node ) return false ;
// 第一步: 检查当前节点是否为01版本
if ( node . minorVersion === '01' ) {
return true ;
}
// 第二步:若有子节点,递归检查所有子节点
if ( node . children && node . children . length > 0 ) {
// 只要有一个子节点满足, 就返回true
return node . children . some ( child => this . hasMinorVersion01 ( child ) ) ;
}
// 第三步: 无子孙节点且当前节点不是01版本, 返回false
return false ;
} ,
// 4. 【修改】文字点击事件(可根据需求扩展修改逻辑)
handleModify ( node ) {
console . log ( '当前需要修改的节点:' , node ) ;
// 示例:可打开修改弹窗、跳转修改页面等
// this.$emit('openModifyDialog', node);
} ,
// 提取content标签内的内容
extractContent ( xmlDoc ) {
const contentNodes = xmlDoc . getElementsByTagName ( "content" ) ;
if ( contentNodes . length === 0 ) {
this . contentResult = "未找到content标签" ;
return ;
}
const contentNode = contentNodes [ 0 ] ;
let contentHtml = "" ;
// 序列化content节点的所有子节点
for ( let i = 0 ; i < contentNode . childNodes . length ; i ++ ) {
const child = contentNode . childNodes [ i ] ;
// 忽略空文本节点
if ( child . nodeType === 1 || ( child . nodeType === 3 && child . textContent . trim ( ) ) ) {
contentHtml += new XMLSerializer ( ) . serializeToString ( child ) ;
}
}
this . loadFileDMC = contentHtml . trim ( ) ;
console . log ( "解析出来DMC内容" , contentHtml )
console . log ( "解析出来DMC内容" , contentHtml . trim ( ) )
// this.contentResult = contentHtml.trim();
} ,
// 提取新建目录时候的DMC文件中content标签内的内容
extractContent2 ( xmlDoc ) {
const contentNodes = xmlDoc . getElementsByTagName ( "content" ) ;
if ( contentNodes . length === 0 ) {
this . contentResult = "未找到content标签" ;
return ;
}
const contentNode = contentNodes [ 0 ] ;
let contentHtml = "" ;
// 序列化content节点的所有子节点
for ( let i = 0 ; i < contentNode . childNodes . length ; i ++ ) {
const child = contentNode . childNodes [ i ] ;
// 忽略空文本节点
if ( child . nodeType === 1 || ( child . nodeType === 3 && child . textContent . trim ( ) ) ) {
contentHtml += new XMLSerializer ( ) . serializeToString ( child ) ;
}
}
2025-10-11 11:08:42 +08:00
// this.viewXmlContent = contentHtml.trim();
2025-09-15 09:58:52 +08:00
console . log ( "加载解析出来DMC内容" , contentHtml )
console . log ( "加载解析出来DMC内容" , contentHtml . trim ( ) )
2025-10-11 11:08:42 +08:00
this . restoreContentXh2 ( contentHtml . trim ( ) )
2025-09-15 09:58:52 +08:00
// this.contentResult = contentHtml.trim();
} ,
// 解析rdf:Description为对象
parseRdfDescription ( xmlDoc ) {
const rdfObj = { } ;
const rdfNamespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" ;
const rdfNode = xmlDoc . getElementsByTagNameNS ( rdfNamespace , "Description" ) [ 0 ] ;
if ( ! rdfNode ) {
// this.rdfResult = { error: "未找到rdf:Description标签" };
return ;
}
// 解析dc命名空间下的所有子节点
2025-10-11 11:08:42 +08:00
const dcNamespace = "http://www.purl.org/dc/elements/1.1/" ;
2025-09-15 09:58:52 +08:00
const dcNodes = rdfNode . getElementsByTagNameNS ( dcNamespace , "*" ) ;
Array . from ( dcNodes ) . forEach ( node => {
const key = node . localName ; // 获取不带命名空间前缀的标签名
const value = node . textContent . trim ( ) || "" ; // 处理空标签
rdfObj [ key ] = value ;
} ) ;
console . log ( "解析出来DMC目录内容" , rdfObj )
// this.rdfResult = rdfObj;
for ( let key in this . form ) {
this . form [ key ] = rdfObj [ key ] ? rdfObj [ key ] : '' ;
}
this . form . name = rdfObj . title ;
this . form . version = '000' ;
} ,
//转换时间值
timeChange ( isoTime ) {
const date = new Date ( isoTime ) ;
// 3. 提取时间组件(注意:月份从 0 开始,需 +1; 数字不足 2 位时补 0)
const year = date . getFullYear ( ) ; // 年份: 2025
const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , "0" ) ; // 月份: 09( getMonth() 返回 8, +1 后补 0)
const day = String ( date . getDate ( ) ) . padStart ( 2 , "0" ) ; // 日期: 01
const hours = String ( date . getHours ( ) ) . padStart ( 2 , "0" ) ; // 小时: 16( 24小时制)
const minutes = String ( date . getMinutes ( ) ) . padStart ( 2 , "0" ) ; // 分钟: 39
const seconds = String ( date . getSeconds ( ) ) . padStart ( 2 , "0" ) ; // 秒: 07
// 4. 拼接成正常时间格式
const normalTime = ` ${ year } - ${ month } - ${ day } ${ hours } : ${ minutes } : ${ seconds } ` ;
return normalTime ;
} ,
// 关闭预览弹窗
handleCloseMask ( ) {
this . maskViewShow = false ;
2025-10-11 11:08:42 +08:00
} ,
// 关闭修改书名弹窗
handleCloseEditBookName ( ) {
this . getBookName = this . getBookNameDf ;
this . editBookNameDialog = false ;
2025-09-15 09:58:52 +08:00
} ,
//关闭弹窗节点
handleClose ( type ) {
2025-10-11 11:08:42 +08:00
this . loadFileDMC = '' ;
2025-09-15 09:58:52 +08:00
console . log ( '点' , type ) ;
this . dialogVisibleHistory = false ;
this . dialogVisibleNav = false ;
this . dialogVisibleRight = false ;
this . dialogVisibleTips = false ;
this . dialogVisibleTips2 = false ;
this . dialogVisibleBland = false ;
this . dialogVisibleBland = false ;
this . currentNode = null ;
this . clearNodeState ( ) ;
} ,
handleClose2 ( ) {
this . dialogVisibleHistory = false ;
this . dialogVisibleNav = false ;
this . dialogVisibleRight = false ;
this . dialogVisibleTips = false ;
this . dialogVisibleTips2 = false ;
this . dialogVisibleBland = false ;
this . dialogVisibleBland = false ;
} ,
//测试 保存当前目录信息
saveNowDmcClick ( ) {
const targetNode = this . findNodeById ( this . treeData , this . currentNode . id ) ;
targetNode . minorVersion = '01' ;
const aaa = this . editor . txt . html ( ) ;
console . log ( "当前的所有html内容4" , aaa )
this . catalogueAnalysis ( this . treeData ) ;
this . generateXml ( false , this . currentNode . id ) ;
// this.$sendToDotNet('RefreshTree');
this . contentXmlStr = this . editor . txt . html ( ) ;
} ,
//保存当前DMC信息
saveNowDmc2 ( type ) {
console . log ( "保存时候点击" , this . lastClick )
if ( type == 'save' ) {
console . log ( "保存时候点击 this.currentNode" , this . currentNode , this . currentNode . minorVersion )
// if(this.currentNode.minorVersion == '00'){
const targetNode = this . findNodeById ( this . treeData , this . lastClick ) ;
targetNode . minorVersion = '01' ;
// }
console . log ( "保存时候点击 treedata" , this . treeData )
this . catalogueAnalysis ( this . treeData ) ;
this . generateXml ( false , this . lastClick ) ;
this . contentXmlStr = this . editor . txt . html ( ) ;
// const targetNode = this.findNodeById(this.treeData, this.lastClick);
// if (targetNode) {
// targetNode.minorVersion = '01';
// }
// this.catalogueAnalysis(this.treeData);
} else if ( type == 'noSave' ) {
this . getDmName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + this . lastClick + this . domNameStr [ 3 ] + this . domNameStr [ 4 ] ;
console . log ( "加载富文本的文件名" , this . getDmName )
this . loadFWBFile ( this . getDmName ) ;
console . log ( "不保存" )
}
this . dialogVisibleTips2 = false ;
console . log ( "saveNowDmc2" , type )
} ,
//保存当前DMC信息
saveNowDmc ( type ) {
if ( type == 'save' ) {
this . navIsAdd = 'other'
this . generateXml ( false ) ;
this . dialogVisibleTips = false ;
this . dialogVisibleNav = true ;
} else if ( type == 'noSave' ) {
this . getDmName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + this . lastClick + this . domNameStr [ 3 ] + this . domNameStr [ 4 ] ;
this . loadFWBFile ( this . getDmName ) ;
this . dialogVisibleTips = false ;
this . dialogVisibleNav = true ;
}
2025-10-11 11:08:42 +08:00
this . loadFileDMC = '' ;
2025-09-15 09:58:52 +08:00
this . clearFormData ( ) ;
this . showView = false ;
this . $sendToDotNet ( 'CancelUserHistoy' )
} ,
//测试 绑定资源弹窗显示
showBand ( ) {
this . dialogVisibleRight = false ;
this . dialogVisibleBland = true ;
} ,
//测试 历史版本展示
showHistory ( ) {
this . dialogVisibleRight = false ;
this . dialogVisibleHistory = true ;
this . getDmName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + this . currentNode . id + this . domNameStr [ 3 ] + this . domNameStr [ 4 ] ;
console . log ( "历史版本查询时候的名字" , this . getDmName )
console . log ( "历史版本查询时候的domNameStr" , this . domNameStr )
console . log ( "历史版本查询时候的currentNode" , this . currentNode )
this . $sendToDotNet ( "GetHistoryVesions" , this . getDmName )
} ,
//版本定稿
finalVersion ( ) {
console . log ( "定版时候的参数" , this . currentNode )
const newStr = 'A-A_' + this . currentNode . lagreVersion + '_00' ;
// let versionName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+this.domNameStr[3]+this.domNameStr[4]+'.xml';
const versionName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + this . currentNode . id + newStr + this . domNameStr [ 4 ] + '.xml' ;
// this.currentNode.minorVersion = '00';
const targetNode = this . findNodeById ( this . treeData , this . currentNode . id ) ;
targetNode . minorVersion = '00' ;
2025-10-11 11:08:42 +08:00
// targetNode.lagreVersion = this.currentNode.lagreVersion
const num = parseInt ( this . currentNode . lagreVersion , 10 ) ;
// 3. 加1运算
const newNum = num + 1 ;
// 4. 格式化为3位带前导零的字符串
this . form . version = String ( newNum ) . padStart ( 3 , "0" ) ;
2025-09-15 09:58:52 +08:00
2025-10-11 11:08:42 +08:00
console . log ( "定稿时候逇form" , this . form )
2025-09-15 09:58:52 +08:00
this . catalogueAnalysis ( this . treeData ) ;
2025-10-11 11:08:42 +08:00
this . generateXml ( false ) ;
2025-09-15 09:58:52 +08:00
this . $sendToDotNet ( "CreatVersion" , versionName )
} ,
//显示新建弹窗
showAddDialog ( type ) {
console . log ( "点击新建" , type )
this . $sendToDotNet ( "CancelPriview" )
this . navIsAdd = type ;
if ( type == "create" ) {
this . form . name = '' ;
this . isLoadOldDmc = '2' ,
this . clearFormData ( ) ;
} else {
this . form . name = this . currentNode . name ;
}
if ( this . dmcIsChange ( ) ) {
this . dialogVisibleNav = true ;
2025-10-11 11:08:42 +08:00
this . loadFileDMC = '' ;
2025-09-15 09:58:52 +08:00
this . showView = false ;
} else {
this . dialogVisibleTips = true ;
}
// this.$sendToDotNet('CancelUserHistoy')
this . dialogVisibleRight = false ;
} ,
//截取路径信息
removeQuotationMarks ( data ) {
const result = data . replace ( /^"|"$/g , '' ) ;
return result ;
} ,
//目录节点点击
handleNodeClick ( data ) {
this . currentNode = data ;
2025-10-11 11:08:42 +08:00
this . navIsAdd = '' ;
2025-09-15 09:58:52 +08:00
console . log ( "这一次点击的节点信息" , data ) ;
console . log ( "上一次点击的时候的ID" , this . lastClick )
console . log ( "这一次点击的时候的ID" , this . nowClick )
if ( this . lastClick == this . nowClick . id ) {
this . nowClick = data ;
this . lastClick = data . id ;
// this.generateXml(false);
// this.catalogueAnalysis(this.treeData);
} else {
console . log ( "中中中中中" , this . lastClick , this . dmcIsChange ( ) )
if ( this . lastClick && ! this . dmcIsChange ( ) ) {
this . dialogVisibleTips2 = true ;
console . log ( "dialogVisibleTips2出现" )
console . log ( "恢复成上一次点击" , this . lastClick )
// this.$refs.tree.setCheckedKeys([this.lastClick]);
// 确保DOM更新后再重置状态
this . $nextTick ( ( ) => {
this . $refs . tree . setCheckedKeys ( [ this . lastClick ] ) ;
this . $refs . tree . setCurrentKey ( this . lastClick ) ;
} ) ;
} else {
const target = this . domNameStr [ 3 ] ;
// 假设需要替换的格式是 "前缀_xxx_yy", 其中xxx是3位, yy是2位
// 先找到最后两个下划线的位置
const lastUnderlineIndex = target . lastIndexOf ( '_' ) ;
const secondLastUnderlineIndex = target . lastIndexOf ( '_' , lastUnderlineIndex - 1 ) ;
if ( lastUnderlineIndex > - 1 && secondLastUnderlineIndex > - 1 ) {
// 截取前缀部分(到第二个下划线)
const prefix = target . substring ( 0 , secondLastUnderlineIndex + 1 ) ;
// 截取中间部分( 3位) 和末尾部分( 2位) , 并用新值替换
// const newValue = `${prefix}${data.lagreVersion}_${data.minorVersion}`;
const newValue = ` ${ prefix } ${ data . lagreVersion } _00 ` ;
// 更新数组
this . domNameStr . splice ( 3 , 1 , newValue ) ;
this . replaced = true ;
}
console . log ( "点击时候的节点data" , data . id )
this . getDmName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + data . id + this . domNameStr [ 3 ] + this . domNameStr [ 4 ] ;
console . log ( "加载富文本的文件名" , this . getDmName )
this . loadFWBFile ( this . getDmName ) ;
this . lastClick = data . id ;
}
// if(this.lastClick){
// if(!this.dmcIsChange()){
// this.navIsAdd = 'edit';
// this.generateXml(false,this.lastClick);
// }
// }
// this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+data.id+this.domNameStr[3]+this.domNameStr[4];
// console.log("加载富文本的文件名",this.getDmName)
// this.loadFWBFile(this.getDmName);
}
console . log ( "当前节点点击" , data ) ;
2025-10-11 11:08:42 +08:00
this . getWindowSize ( ) ;
this . gengxin ( ) ;
2025-09-15 09:58:52 +08:00
// this.$sendToDotNet('GetFilePath','PMC',data.id,'');
} ,
2025-10-11 11:08:42 +08:00
zy ( dataStr ) {
try {
// 1. 清理字符串
const cleaned = dataStr . replace ( /;$/g , '' ) ;
// 2. 转义双引号
const escaped = cleaned . replace ( /"/g , '\\"' ) ;
// 3. 解码 Unicode
let unicodeDecoded = JSON . parse ( ` " ${ escaped } " ` ) ;
// 4. 处理反斜杠
let a = unicodeDecoded . replace ( /\\\\/g , "\\" )
return a ;
} catch ( e ) {
// 捕获解析错误,避免页面崩溃
console . error ( "字符串解析失败:" , e ) ;
return "解析错误" ;
}
} ,
2025-09-15 09:58:52 +08:00
//确认新建目录
confirmAdd ( type ) {
if ( type ) {
this . loadFileDMC = '' ;
} else {
this . $sendToDotNet ( 'CopyToWorkDire' ) ;
}
this . $refs . form . validate ( ( valid ) => {
if ( ! valid ) return
// if(!this.dmcIsChange()){
// }else{
// }
const newNode = {
id : this . queryMaxId ( ) ,
maxId : this . mId ,
name : this . form . name ,
attributes : [ ] ,
formMes : this . form ,
lagreVersion : this . form . version , //大版本
minorVersion : '00' , //临时版本
children : [ ]
}
console . log ( "新建章节目录时候的参数" , newNode )
this . nowMaxId = newNode . id ;
if ( this . currentNode ) {
if ( ! this . currentNode . children ) {
this . $set ( this . currentNode , 'children' , [ ] )
}
this . currentNode . children . push ( newNode )
} else {
this . treeData . push ( newNode )
}
this . dialogVisibleNav = false
this . $nextTick ( ( ) => {
this . $refs . tree . setCurrentKey ( newNode . id )
2025-10-11 11:08:42 +08:00
// this.currentNode = newNode;
this . currentNode = '' ;
2025-09-15 09:58:52 +08:00
this . catalogueAnalysis ( this . treeData ) ;
// this.$sendToDotNet('SaveFile','PMC',newNode.id,JSON.stringify(this.currentNode));
//创建目录时候同时创建一个空DM文件
2025-10-11 11:08:42 +08:00
this . generateXml ( true ) ;
2025-09-15 09:58:52 +08:00
} )
} )
} ,
//编辑目录时候点击确认进行保存
confirmEdit ( ) {
this . currentNode . name = this . form . name ;
console . log ( "点击编辑确定" , this . currentNode , this . treeData )
this . currentNode . minorVersion = '01' ;
this . catalogueAnalysis ( this . treeData ) ;
this . isNavEdit = true ;
this . dialogVisibleNav = false ;
this . generateXml ( false , this . treeData . id )
// let targetNode = this.findNodeById(this.treeData,this.currentNode.id);
// if (targetNode) {
// // 替换attributes
// // targetNode.name = ...this.currentNode.name];
// // this.hasReplaced = true;
// console.log('替换成功,新的节点数据:', targetNode);
// } else {
// console.warn('未找到节点');
// }
// console.log('获取当前节点',this.currentNode)
} ,
// 删除时候的二次确认弹窗
deleteDialog ( ) {
console . log ( "currentNode.children" , this . currentNode )
this . dialogVisibleNavDel = true ;
} ,
// 删除绑定资源按钮
deleteAttr ( name , index ) {
this . nowAttr = {
name : name ,
index : index ,
}
this . dialogVisibleAttrDel = true ;
} ,
// 删除绑定资源二次确定
deleteAttrSure ( ) {
this . currentNode . attributes . splice ( this . nowAttr . index , 1 ) ;
this . catalogueAnalysis ( this . treeData ) ;
this . dialogVisibleAttrDel = false ;
} ,
//删除节点时候判断是否有子节点。
deleteNode ( ) {
if ( this . currentNode . children && this . currentNode . children . length > 0 ) {
this . $message ( {
type : 'warning' ,
message : '该节点包含子节点,不能删除!'
} )
} else {
let isDel = this . deleteNodeFromTree ( this . treeData , this . currentNode . id )
2025-10-11 11:08:42 +08:00
console . log ( "删除是否成功" , isDel , this . currentNode )
2025-09-15 09:58:52 +08:00
// this.currentNode = null;
const fileId = this . currentNode . id ;
this . catalogueAnalysis ( this . treeData ) ;
this . dialogVisibleNavDel = false ;
// this.$sendToDotNet('RefreshTree');
console . log ( '删除RMDMfile fileId' , fileId )
2025-10-11 11:08:42 +08:00
this . $sendToDotNet ( 'RMDMfile' , 'DMC' , fileId , this . currentNode . lagreVersion )
this . currentNode = '' ;
2025-09-15 09:58:52 +08:00
// this.$message({
// type: 'success',
// message: '删除成功!'
// })
}
} ,
// 更新指定节点的版本号
updateNodeVersion ( id , vs ) {
const targetNode = this . findNodeById ( this . treeData2 , id ) ;
if ( targetNode ) {
targetNode . lagreVersion = vs ;
}
} ,
//删除节点
deleteNodeFromTree ( nodes , id ) {
for ( let i = 0 ; i < nodes . length ; i ++ ) {
if ( nodes [ i ] . id === id ) {
nodes . splice ( i , 1 )
return true
}
if ( nodes [ i ] . children && nodes [ i ] . children . length > 0 ) {
if ( this . deleteNodeFromTree ( nodes [ i ] . children , id ) ) {
return true
}
}
}
return false
} ,
//重置输入框
resetForm ( ) {
this . $refs . form . resetFields ( )
} ,
// 搜索相关方法
handleSearch ( ) {
if ( ! this . searchText . trim ( ) ) {
this . $refs . tree . filter ( this . searchText ) ;
// 搜索内容为空时,重置所有节点的可见性
this . resetTreeVisibility ( this . treeData )
} else {
this . $refs . tree . filter ( this . searchText )
}
} ,
//清除搜索
handleSearchClear ( ) {
this . searchText = '' ;
// 清空搜索时重置所有节点的可见性
this . $refs . tree . filter ( '' ) ;
this . resetTreeVisibility ( this . treeData )
} ,
//重置目录节点信息
resetTreeVisibility ( nodes ) {
nodes . forEach ( node => {
// 重置节点的可见性
node . visible = true
if ( node . children && node . children . length > 0 ) {
this . resetTreeVisibility ( node . children )
}
} )
// 强制刷新树组件
this . $refs . tree . updateKeyChildren ( )
} ,
//目录节点信息
filterNode ( value , data ) {
if ( ! value ) return true ; // 空值时显示所有节点
// 这里假设你要搜索的是节点的name属性
return data . name . toLowerCase ( ) . includes ( value . toLowerCase ( ) ) ;
} ,
//筛选后高亮class
isHighlight ( data ) {
return this . searchText && data . name . toLowerCase ( ) . includes ( this . searchText . toLowerCase ( ) )
} ,
// 保存属性
saveAttributes ( ) {
console . log ( "this.currentNode.id" , this . currentNode . id )
this . $sendToDotNet ( 'GetFilePath' , 'PMC' , this . currentNode . id , '' ) ;
// if (this.currentNode) {
// // 保存选中的属性到当前节点
// this.currentNode.attributes = [...this.selectedAttributes];
// // 刷新树结构
// this.$refs.tree.setCurrentKey(this.currentNode.id);
// }
// this.dialogVisibleRight = false;
} ,
//查询最大ID值
queryMaxId ( ) {
// maxId = '00001'
console . log ( "初始化ID" , this . treeData )
// if(this.treeData[0]){
let maxId = this . mId ? this . mId : '00001' ;
const length = maxId . length ;
// 将字符串转换为数字并加1
const number = parseInt ( maxId , 10 ) + 1 ;
// 格式化数字为指定长度的字符串,不足的前面补零
maxId = number . toString ( ) . padStart ( length , '0' ) ;
// }
this . mId = maxId ;
return maxId ;
// let maxId = 0;
// let treeData = this.treeData;
// // 递归遍历函数
// const traverse = (nodes) => {
// if (!nodes || nodes.length === 0) return;
// nodes.forEach(node => {
// // 比较当前节点ID与最大值
// if (node.id > maxId) {
// maxId = node.id;
// }
// // 递归处理子节点
// traverse(node.children);
// });
// };
// // 开始遍历
// traverse(treeData);
// console.log("当前数据最大ID",maxId)
// const length = maxId.length;
// // 将字符串转换为数字并加1
// const number = parseInt(maxId, 10) + 1;
// // 格式化数字为指定长度的字符串,不足的前面补零
// maxId = number.toString().padStart(length, '0');
// if(maxId == 1){
// maxId = '00001'
// }
// return maxId;
} ,
//解析XML目录( 暂时不用)
extractDmCode ( xmlString ) {
// 1. 解析 XML 字符串
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( xmlString , "text/xml" ) ;
// 2. 获取所有 dmCode 节点
const dmCodeNodes = xmlDoc . getElementsByTagName ( "dmCode" ) ;
const issueInfoNodes = xmlDoc . getElementsByTagName ( "issueInfo" ) ;
const languageNodes = xmlDoc . getElementsByTagName ( "language" ) ;
// 3. 遍历节点,提取属性
let dmCodeList = Array . from ( dmCodeNodes ) . map ( node => {
const attributes = { } ;
// 遍历节点的所有属性
for ( let i = 0 ; i < node . attributes . length ; i ++ ) {
const attr = node . attributes [ i ] ;
attributes [ attr . name ] = attr . value ;
}
return attributes ;
} ) ;
let issueInfoList = Array . from ( issueInfoNodes ) . map ( node => {
const attributes = { } ;
// 遍历节点的所有属性
for ( let i = 0 ; i < node . attributes . length ; i ++ ) {
const attr = node . attributes [ i ] ;
attributes [ attr . name ] = attr . value ;
}
return attributes ;
} ) ;
let languageList = Array . from ( languageNodes ) . map ( node => {
const attributes = { } ;
// 遍历节点的所有属性
for ( let i = 0 ; i < node . attributes . length ; i ++ ) {
const attr = node . attributes [ i ] ;
attributes [ attr . name ] = attr . value ;
}
return attributes ;
} ) ;
// 处理函数:将对象按指定字段集拼接成字符串
let dmCodeTitle = [ 'modelIdentCode' , 'systemDiffCode' , 'systemCode' , 'subSystemCode' , 'subSubSystemCode' , 'disassyCode' , 'disassyCodeVariant' , 'infoCode' , 'infoCodeVariant' , 'itemLocationCode' ]
let issueInfoTitle = [ 'issueNumber' , 'inWork' ] ;
let languageTitle = [ 'languageIsoCode' , 'countryIsoCode' ]
// 处理三组数据
let dmCodeResult = this . joinFields ( dmCodeList , dmCodeTitle , '-' ) ;
let issueInfoResult = this . joinFields ( issueInfoList , issueInfoTitle , '_' ) ;
let languageResult = this . joinFields ( languageList , languageTitle , '_' ) ;
console . log ( "参数 dmCodeResult" , dmCodeResult )
console . log ( "参数 issueInfoResult" , issueInfoResult )
console . log ( "参数 languageResult" , languageResult )
// let dmCodeResult2 = [];
let newList = [ ] ;
for ( let i = 0 ; i < dmCodeResult .length ; i + + ) {
// let strA = dmCodeResult[0]+'_'+dmCodeResult[0]
let str = dmCodeResult [ i ] + "-" + issueInfoResult [ i ] + "-" + languageResult [ i ]
newList . push ( str ) ;
}
console . log ( "结果" , newList )
} ,
//解析目录节点数据
generateTreeData ( xmlContent ) {
console . log ( "加载XML解析内容 初始化内容" , xmlContent )
// 1. 解析XML
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( xmlContent , "text/xml" ) ;
console . log ( "加载XML解析内容 初始化XML" , xmlDoc )
// 2. 获取根节点( content下的所有pmEntry)
const contentNode = xmlDoc . querySelector ( "content" ) ;
console . log ( "加载XML解析内容 content" , contentNode )
const rootPmEntries = contentNode ? Array . from ( contentNode . children ) . filter ( node => node . tagName === "pmEntry" ) : [ ] ;
2025-10-11 11:08:42 +08:00
let getBookName = xmlDoc . getElementsByTagName ( 'pmTitle' ) ;
this . getBookName = getBookName [ 0 ] . textContent ;
console . log ( "得到的书名" , this . getBookName )
2025-09-15 09:58:52 +08:00
// 3. 递归处理节点,构建树形结构
this . treeData = this . parsePmEntries ( rootPmEntries ) ;
this . handleCheckVersion ( ) ;
// console.log("")
console . log ( "重新解析结果" , this . treeData )
// if(this.treeData.length>0){
// this.clearNodeState();
// }
// this.enableContextMenu();//绑定右键
// 获取最大ID
const simpleParaNode = xmlDoc . querySelector ( "simplePara" ) ;
console . log ( "加载XML解析内容 id" , simpleParaNode )
const maxId = simpleParaNode . getAttribute ( "maxId" ) || "00001" ;
console . log ( "当前目录最大ID" , maxId )
this . mId = maxId ;
2025-10-11 11:08:42 +08:00
const issueInfoNode = xmlDoc . querySelector ( "issueInfo" ) ;
this . minLevel = issueInfoNode . getAttribute ( "minLevel" )
this . maxLevel = issueInfoNode . getAttribute ( "maxLevel" )
this . maxPermission = issueInfoNode . getAttribute ( "maxPermission" )
this . minPermission = issueInfoNode . getAttribute ( "minPermission" )
console . log ( "版本号上各种参数" , this . minLevel , this . maxLevel , this . minPermission , this . maxPermission )
2025-09-15 09:58:52 +08:00
} ,
/ * *
* 递归解析pmEntry节点列表 , 生成树形数据
* @ param { NodeList } pmEntries - pmEntry节点列表
* @ param { Object } parent - 父节点 ( 用于处理嵌套关系 )
* @ returns { Array } 树形结构数组
* /
parsePmEntries ( pmEntries , parent = null ) {
const treeNodes = [ ] ;
console . log ( "parent" , parent )
pmEntries . forEach ( entry => {
// const lagreVersion = parent.getAttribute("lagreVersion") || "";
// const minorVersion = parent.getAttribute("minorVersion") || "";
// console.log("数循环结果 大版本",lagreVersion)
// console.log("数循环结果 小版本",minorVersion)
// a. 提取当前节点的id、name、attributes
const titleNode = entry . querySelector ( "pmEntryTitle" ) || entry . querySelector ( "techName" ) ;
if ( ! titleNode ) return ; // 跳过无标题的节点
const id = titleNode . getAttribute ( "id" ) ;
const name = titleNode . textContent . trim ( ) ;
const attributesStr = titleNode . getAttribute ( "attributes" ) || "" ;
const lagreVersion = titleNode . getAttribute ( "lagreVersion" ) || "000" ;
const minorVersion = titleNode . getAttribute ( "minorVersion" ) || "00" ;
// const maxID = titleNode.getAttribute("maxId") || "00001";
const attributes = attributesStr ? attributesStr . split ( "," ) . map ( item => item . trim ( ) ) : [ ] ;
// b. 创建节点基本结构
const node = {
id ,
name ,
// maxId:maxID,
attributes ,
formMes : { } , // 固定空对象
children : [ ] ,
lagreVersion : lagreVersion , //大版本
minorVersion : minorVersion , //临时版本
} ;
// c. 处理子节点( 当前pmEntry下的子pmEntry)
const childEntries = Array . from ( entry . children ) . filter ( child => child . tagName === "pmEntry" ) ;
if ( childEntries . length > 0 ) {
node . children = this . parsePmEntries ( childEntries , node ) ;
}
treeNodes . push ( node ) ;
} ) ;
return treeNodes ;
} ,
//测试 解析xml 暂未使用
parseXml ( xmlInput ) {
this . errorMessage = '' ;
this . parsedData = [ ] ;
try {
// 创建DOMParser实例
const parser = new DOMParser ( ) ;
const xmlDoc = parser . parseFromString ( xmlInput , "text/xml" ) ;
console . log ( "xmlDoc" , xmlDoc )
// 检查XML解析错误
const parserError = xmlDoc . getElementsByTagName ( "parsererror" ) [ 0 ] ;
if ( parserError ) {
throw new Error ( "XML格式错误: " + parserError . textContent ) ;
}
// 获取所有顶级pmEntry节点
const pmEntries = xmlDoc . querySelectorAll ( 'content > pmEntry' ) ;
let parsedData = [ ] ;
// 解析每个pmEntry
pmEntries . forEach ( pmEntry => {
const entryData = this . parsePmEntry ( pmEntry ) ;
if ( entryData ) {
parsedData . push ( entryData ) ;
}
} ) ;
parsedData . map ( ( res ) => {
if ( res . infoCode ) {
return res . is = res . infoCode , res . name = res . title ;
}
} )
this . treeData = parsedData ;
console . log ( "parsedData" , parsedData )
} catch ( error ) {
this . errorMessage = "解析失败: " + error . message ;
console . error ( "XML解析错误:" , error ) ;
}
} ,
/ * *
* 获取指定节点的值
* @ param { Element } parentNode - 父节点
* @ param { string } selector - 节点选择器
* @ returns { string } 节点值
* /
getNodeValue ( parentNode , selector ) {
const node = parentNode . querySelector ( selector ) ;
return node ? node . textContent . trim ( ) : '' ;
} ,
//格式化数据提取节点内容
parsePmEntry ( pmEntryElement ) {
// 获取pmEntryTitle
const titleElement = pmEntryElement . querySelector ( 'pmEntryTitle' ) ;
if ( ! titleElement ) return null ;
const title = titleElement . textContent . trim ( ) ;
const result = {
title ,
children : [ ] ,
subItems : [ ]
} ;
// 获取当前pmEntry下的所有子节点
const childNodes = Array . from ( pmEntryElement . childNodes ) ;
// 查找子pmEntry和dmRef节点
childNodes . forEach ( node => {
if ( node . nodeType !== 1 ) return ; // 只处理元素节点
if ( node . tagName === 'pmEntry' ) {
// 递归解析子pmEntry
const childData = this . parsePmEntry ( node ) ;
if ( childData ) {
result . children . push ( childData ) ;
}
} else if ( node . tagName === 'dmRef' ) {
// 解析dmRef中的infoCode
const dmCode = node . querySelector ( 'dmRefIdent > dmCode' ) ;
if ( dmCode && dmCode . hasAttribute ( 'infoCode' ) ) {
result . subItems . push ( {
infoCode : dmCode . getAttribute ( 'infoCode' )
} ) ;
}
}
} ) ;
// 如果没有子节点但有subItems, 设置当前节点的infoCode为第一个subItem的infoCode
if ( result . children . length === 0 && result . subItems . length > 0 ) {
result . infoCode = result . subItems [ 0 ] . infoCode ;
}
return result ;
} ,
// 处理数据信息
joinFields ( dataList , fields ) {
return dataList . map ( item => {
return fields . map ( field => item [ field ] ) . join ( '_' ) ;
} ) ;
} ,
//处理目录节点信息
catalogueAnalysis ( treeData ) {
console . log ( "处理每个节点信息 treeData" , treeData )
// 递归处理每个节点, 跟踪路径用于生成infoName
const processNode = ( node , path = [ ] , level = 0 ) => {
let nodeStr = '' ;
console . log ( "处理每个节点信息 node" , node )
// 每个节点都用pmEntry标签包裹
nodeStr += '<pmEntry>\n' ;
// 计算当前节点的路径, 用于生成infoName
const currentPath = [ ... path , node . name ] ;
// 如果有子节点, 添加pmEntryTitle标签
if ( node . children && node . children . length > 0 ) {
nodeStr += ` \ t<pmEntryTitle attributes=' ${ node . attributes } ' lagreVersion=" ${ node . lagreVersion } " minorVersion=" ${ node . minorVersion } " id=" ${ node . id } "> ${ node . name } </pmEntryTitle> \ n ` ;
// 递归处理子节点
node . children . forEach ( ( child , index ) => {
console . log ( "index" , index )
// 递归处理子节点, 传入当前路径( 移除了未使用的infoCode和issueDate参数)
nodeStr += processNode ( child , currentPath , level + 1 ) ;
} ) ;
} else {
// 没有子节点的节点用dmRef标签包裹
nodeStr += '\t<dmRef>\n' ;
// 添加dmRefIdent部分, 包含动态生成的dmCode
nodeStr += ` \ t \ t<dmRefIdent> \ n ` ;
nodeStr += ` \ t \ t \ t<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode=" ${ getInfoCode ( level ) } " disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode=" ${ getSubSubSystemCode ( level ) } " subSystemCode=" ${ getSubSystemCode ( level ) } " systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/> \ n ` ;
nodeStr += ` \ t \ t \ t<issueInfo issueNumber="001" inWork="01"/> \ n ` ;
nodeStr += ` \ t \ t \ t<language languageIsoCode="zh" countryIsoCode="CN"/> \ n ` ;
nodeStr += ` \ t \ t</dmRefIdent> \ n ` ;
// 添加dmRefAddressItems标签
nodeStr += ` \ t \ t<dmRefAddressItems> \ n ` ;
// 添加dmTitle标签, 包含techName和infoName
nodeStr += ` \ t \ t \ t<dmTitle> \ n ` ;
nodeStr += ` \ t \ t \ t \ t<techName attributes=' ${ node . attributes } ' lagreVersion=" ${ node . lagreVersion } " minorVersion=" ${ node . minorVersion } " id=" ${ node . id } "> ${ node . name } </techName> \ n ` ;
nodeStr += ` \ t \ t \ t \ t<infoName> ${ currentPath . join ( '-' ) } </infoName> \ n ` ;
nodeStr += ` \ t \ t \ t</dmTitle> \ n ` ;
// 添加issueDate标签
nodeStr += ` \ t \ t \ t<issueDate year="2024" month="06" day=" ${ getIssueDay ( level ) } "/> \ n ` ;
// 闭合dmRefAddressItems标签
nodeStr += ` \ t \ t</dmRefAddressItems> \ n ` ;
// 闭合dmRef标签
nodeStr += ` \ t</dmRef> \ n ` ;
}
// 闭合当前节点的pmEntry标签
nodeStr += '</pmEntry>\n' ;
return nodeStr ;
} ;
// 根据层级和索引生成infoCode
const getInfoCode = ( level , index = 0 ) => {
if ( level === 1 && index === 0 ) return "042" ;
if ( level === 1 && index === 1 ) return "041" ;
return "040" ;
} ;
// 根据层级生成subSystemCode
const getSubSystemCode = ( level ) => {
if ( level === 0 ) return "0" ;
if ( level === 1 ) return "1" ;
if ( level === 2 ) return "3" ;
return "0" ;
} ;
// 根据层级生成subSubSystemCode
const getSubSubSystemCode = ( level , index = 0 ) => {
if ( level === 1 ) return "1" ;
if ( level === 2 ) return index + 1 ;
return "0" ;
} ;
// 根据层级生成issueDay
const getIssueDay = ( level ) => {
return level === 1 ? "13" : "12" ;
} ;
// 处理所有根节点
let result = '' ;
treeData . forEach ( node => {
result += processNode ( node ) ;
} ) ;
2025-10-11 11:08:42 +08:00
// console.log('catalogueString 目录字符串',result);
2025-09-15 09:58:52 +08:00
this . catalogueString = result ;
this . saveNav ( ) ;
// console.log(this.treeData)
} ,
//生成目录节点XML信息 并保存目录pmc
saveNav ( ) {
2025-10-11 11:08:42 +08:00
let a1 = this . form . permission ; //2
let a2 = this . form . level ; //2
// let minP = this.minPermission;//1
let maxP = this . maxPermission ; //5
// let minL = this.minLevel;//1
let maxL = this . maxLevel ; //5
if ( a1 > maxP ) {
maxP = a1 ;
}
if ( a2 > maxL ) {
maxL = a2 ;
}
2025-09-15 09:58:52 +08:00
let xmlStr = ` <?xml version="1.0" encoding="UTF-8" standalone="no"?>
< ! DOCTYPE pm [
] >
< pm xsi :noNamespaceSchemaLocation = "http://www.s1000d.org/S1000D_4-1/xml_schema_flat/pm.xsd" xmlns :xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns :rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns :dc = "http://www.purl.org/dc/elements/1.1/" xmlns :xlink = "http://www.w3.org/1999/xlink" >
< identAndStatusSection >
< pmAddress >
< pmIdent >
< pmCode modelIdentCode = "YSC001" pmIssuer = "732380192B" pmNumber = "00001" pmVolume = "00" / >
< language countryIsoCode = "CN" languageIsoCode = "zh" / >
2025-10-11 11:08:42 +08:00
< issueInfo minLevel = "1" maxLevel = "`+maxL+`" maxPermission = "`+maxP+`" minPermission = "1" issueNumber = "000" inWork = "01" / >
2025-09-15 09:58:52 +08:00
< / pmIdent >
< pmAddressItems >
< issueDate year = "2024" month = "06" day = "24" / >
2025-10-11 11:08:42 +08:00
< pmTitle > ` +this.getBookName+ ` < / pmTitle >
2025-09-15 09:58:52 +08:00
< / pmAddressItems >
< / pmAddress >
< pmStatus issueType = "new" >
< security securityClassification = "01" / >
< responsiblePartnerCompany enterpriseCode = " " / >
< originator / >
< applic >
< displayText >
< simplePara maxId = '`+this.mId+`' > A0304 - 1 A无人机系统地面运输方舱 < / simplePara >
< / displayText >
< / applic >
< brexDmRef >
< dmRef xlink :type = "simple" xlink :actuate = "onRequest" xlink :show = "replace" xlink :href = "URN:S1000D:DMC-S1000D-E-04-10-0301-00A-022A-D" >
< dmRefIdent >
< dmCode modelIdentCode = "YSC001" systemDiffCode = "A" systemCode = "P4" subSystemCode = "0" subSubSystemCode = "0" assyCode = "00" disassyCode = "00" disassyCodeVariant = "A" infoCode = "022" infoCodeVariant = "A" itemLocationCode = "A" / >
< / dmRefIdent >
< / dmRef >
< / brexDmRef >
< qualityAssurance >
< unverified / >
< / qualityAssurance >
< / pmStatus >
< / identAndStatusSection >
< content > `
+ this . catalogueString +
` </content>
< / pm > `
2025-10-11 11:08:42 +08:00
// console.log("传递字符串",this.catalogueString)
// console.log("存时候",xmlStr)
2025-09-15 09:58:52 +08:00
this . $sendToDotNet ( 'SaveFile' , 'PMC' , '' , xmlStr ) ;
2025-10-11 11:08:42 +08:00
// if(this.dialogVisibleNav){
// this.dialogVisibleNav = false;
// this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+this.domNameStr[3]+this.domNameStr[4];
// console.log("加载富文本的文件名997",this.getDmName)
// setTimeout(() => {
// this.loadFWBFile(this.getDmName);
// console.log("加载富文本的文件名997")
// }, 500);
// }
2025-09-15 09:58:52 +08:00
} ,
//测试 加载目录
jzml ( ) {
let a = ` <!DOCTYPE pm [
] >
< pm xsi :noNamespaceSchemaLocation = "http://www.s1000d.org/S1000D_4-1/xml_schema_flat/pm.xsd" xmlns :xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns :rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns :dc = "http://www.purl.org/dc/elements/1.1/" xmlns :xlink = "http://www.w3.org/1999/xlink" >
< identAndStatusSection >
< pmAddress >
< pmIdent >
< pmCode modelIdentCode = "YSC001" pmIssuer = "732380192B" pmNumber = "00001" pmVolume = "00" / >
< language countryIsoCode = "CN" languageIsoCode = "zh" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< / pmIdent >
< pmAddressItems >
< issueDate year = "2024" month = "06" day = "24" / >
< pmTitle > 无人机系统地面运输方舱使用维护说明书 < / pmTitle >
< / pmAddressItems >
< / pmAddress >
< pmStatus issueType = "new" >
< security securityClassification = "01" / >
< responsiblePartnerCompany enterpriseCode = " " / >
< originator / >
< applic >
< displayText >
< simplePara > A0304 - 1 A无人机系统地面运输方舱 < / simplePara >
< / displayText >
< / applic >
< brexDmRef >
< dmRef xlink :type = "simple" xlink :actuate = "onRequest" xlink :show = "replace" xlink :href = "URN:S1000D:DMC-S1000D-E-04-10-0301-00A-022A-D" >
< dmRefIdent >
< dmCode modelIdentCode = "YSC001" systemDiffCode = "A" systemCode = "P4" subSystemCode = "0" subSubSystemCode = "0" assyCode = "00" disassyCode = "00" disassyCodeVariant = "A" infoCode = "022" infoCodeVariant = "A" itemLocationCode = "A" / >
< / dmRefIdent >
< / dmRef >
< / brexDmRef >
< qualityAssurance >
< unverified / >
< / qualityAssurance >
< / pmStatus >
< / identAndStatusSection >
< content > < pmEntry >
< pmEntryTitle > 装备概况 < / pmEntryTitle >
< pmEntry >
< pmEntryTitle > 方舱概述 < / pmEntryTitle >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00003" > 无人机系统 < / techName >
< infoName > 装备概况 - 方舱概述 - 功能介绍 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00004" > 无人机系统 < / techName >
< infoName > 装备概况 - 方舱概述 - 规格介绍 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = '["金","木","水"]' id = "00005" > 无人机系统 < / techName >
< infoName > 装备概况 - 舱体 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00006" > 无人机系统 < / techName >
< infoName > 装备概况 - 机身转运小车 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00007" > 无人机系统 < / techName >
< infoName > 装备概况 - 无人机部件存储装置 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00008" > 无人机系统 < / techName >
< infoName > 装备概况 - 机身转运小车 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< pmEntryTitle > 附件及工具 < / pmEntryTitle >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00010" > 无人机系统 < / techName >
< infoName > 装备概况 - 附件及工具 - 灭火器 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00011" > 无人机系统 < / techName >
< infoName > 装备概况 - 附件及工具 - 应急灯 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00012" > 无人机系统 < / techName >
< infoName > 装备概况 - 附件及工具 - 土木工具 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "040" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "3" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00013" > 无人机系统 < / techName >
< infoName > 装备概况 - 附件及工具 - 机械工具 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "12" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< / pmEntry >
< / pmEntry >
< pmEntry >
< pmEntryTitle > 使用说明 < / pmEntryTitle >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00014" > 无人机系统 < / techName >
< infoName > 使用说明 - 无人机出舱 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00015" > 无人机系统 < / techName >
< infoName > 使用说明 - 无人机入舱 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< pmEntry >
< dmRef >
< dmRefIdent >
< dmCode itemLocationCode = "A" infoCodeVariant = "A" infoCode = "042" disassyCodeVariant = "A" disassyCode = "00" assyCode = "00" subSubSystemCode = "1" subSystemCode = "1" systemCode = "P4" systemDiffCode = "A" modelIdentCode = "YSC001" / >
< issueInfo issueNumber = "000" inWork = "01" / >
< language languageIsoCode = "zh" countryIsoCode = "CN" / >
< / dmRefIdent >
< dmRefAddressItems >
< dmTitle >
< techName attributes = "[]" id = "00016" > 无人机系统 < / techName >
< infoName > 使用说明 - 灭火器使用 < / infoName >
< / dmTitle >
< issueDate year = "2024" month = "06" day = "13" / >
< / dmRefAddressItems >
< / dmRef >
< / pmEntry >
< / pmEntry >
< / content >
< / pm > `
this . parseToTreeData ( a ) ;
} ,
//清除新建目录弹窗内容信息。
clearFormData ( ) {
this . form = {
name : '' ,
version : '000' ,
date : '' ,
language : '' ,
2025-10-11 11:08:42 +08:00
level : '1' ,
2025-09-15 09:58:52 +08:00
contributor : '' ,
2025-10-11 11:08:42 +08:00
creator : '四威高科' ,
2025-09-15 09:58:52 +08:00
applicabilityInformation : '' ,
qualityVerification : '' ,
2025-10-11 11:08:42 +08:00
permission : '1'
2025-09-15 09:58:52 +08:00
}
} ,
//测试 格式化目录信息
parseToTreeData ( xmlString ) {
// 创建DOMParser实例
const parser = new DOMParser ( ) ;
// 解析XML字符串
const xmlDoc = parser . parseFromString ( xmlString , 'text/xml' ) ;
// 获取根节点下的所有pmEntry节点( 顶级节点)
const rootPmEntries = xmlDoc . querySelectorAll ( 'content > pmEntry' ) ;
// 递归解析节点的函数
const parseNode = ( xmlNode ) => {
// 检查是否有pmEntryTitle子节点
const titleNode = xmlNode . querySelector ( 'pmEntryTitle' ) ;
if ( titleNode ) {
// 有标题节点,说明是父节点
const node = {
id : '' , // 后续会从子节点中查找合适的id
name : titleNode . textContent . trim ( ) ,
children : [ ] ,
attributes : [ ]
} ;
// 修复选择器错误:使用更兼容的方式获取直接子节点
const childNodes = xmlNode . childNodes ;
const childPmEntries = [ ] ;
// 遍历所有子节点, 筛选出直接子pmEntry元素
for ( let i = 0 ; i < childNodes . length ; i ++ ) {
const child = childNodes [ i ] ;
// 检查是否是元素节点且标签名为pmEntry
if ( child . nodeType === 1 && child . tagName === 'pmEntry' ) {
childPmEntries . push ( child ) ;
}
}
// 递归解析每个子节点
childPmEntries . forEach ( childEntry => {
const childNode = parseNode ( childEntry ) ;
if ( childNode ) {
node . children . push ( childNode ) ;
}
} ) ;
// 为父节点生成合适的id
if ( ! node . id && node . children . length > 0 ) {
// 取第一个子节点id的前缀并生成父节点id
const firstChildId = node . children [ 0 ] . id ;
// 简单处理: 取前面的数字部分并减1( 根据实际情况调整)
node . id = ( parseInt ( firstChildId , 10 ) - 1 ) . toString ( ) . padStart ( firstChildId . length , '0' ) ;
}
return node ;
} else {
// 没有标题节点, 说明是叶子节点, 从dmRef中获取信息
const dmRef = xmlNode . querySelector ( 'dmRef' ) ;
if ( ! dmRef ) return null ;
// 获取techName节点中的id和内容
const techNameNode = dmRef . querySelector ( 'techName' ) ;
const id = techNameNode . getAttribute ( 'id' ) ;
const attributes = techNameNode . getAttribute ( 'attributes' ) ;
// 从infoName获取名称路径
const infoNameNode = dmRef . querySelector ( 'infoName' ) ;
const infoName = infoNameNode . textContent . trim ( ) ;
// 取最后一部分作为名称
const nameParts = infoName . split ( '-' ) ;
const name = nameParts [ nameParts . length - 1 ] ;
return {
id ,
name ,
children : [ ] ,
attributes : attributes
} ;
}
} ;
// 解析所有顶级节点
const treeData = [ ] ;
rootPmEntries . forEach ( entry => {
const node = parseNode ( entry ) ;
if ( node ) {
treeData . push ( node ) ;
}
} ) ;
console . log ( "打印" , treeData )
console . log ( "打印String" , JSON . stringify ( treeData ) )
this . treeData = treeData ;
} ,
//和后台交互 加载需要读取的dmc
loadFWBFile ( dmName ) {
// this.$sendToDotNet('LoadDM','DMC--A-P4-20-00-00A-00001A-A_000_01_zh_cn');
console . log ( "需要读取的富文本:" , dmName )
this . $sendToDotNet ( 'LoadDM' , 'DMC' , dmName ) ;
// this.$sendToDotNet('GetFilePath','PMC',data.id,'');
} ,
//和后台交互 查看历史版本
lookHistoryFile ( path ) {
let newPath = path + '\\' + this . getLastPartOfPath ( path ) + '.xml' ;
this . historyVsPath = path ;
console . log ( "发送路径" , newPath )
this . $sendToDotNet ( 'DMPreview' , 'HistoryDMPreview' , newPath )
// this.$sendToDotNet('GetHistoryDMContent',newPath);
// localStorage.setItem('filePath',newPath);
// const url = this.$router.resolve({ name: 'WangG2' }).href
// // 打开新窗口,可指定窗口大小和位置
// window.open(
// url,
// '_blank',
// 'width=800,height=600,top=100,left=100'
// )
} ,
//清除 NBSP str
clearNbsp ( originalStr ) {
const cleanedStr = originalStr . replace ( / /g , '' ) ;
console . log ( "结果cleanedStr" , cleanedStr )
return cleanedStr ;
} ,
//测试 测试拼接地址;
ceshi ( ) {
this . lisenPath = '"http://localhost:61980/"' ;
let e = {
detail : '"\\1.jpg"'
}
const parsedA = this . lisenPath . replace ( /"/g , '' ) ;
const parsedB = e . detail . replace ( /"/g , '' ) ;
// 2. 处理转义字符(如斜杠)
const processedA = parsedA . replace ( /\\/g , '' ) ;
const processedB = parsedB . replace ( /\\/g , '' ) ;
// 3. 确保基础URL以斜杠结尾
let baseUrl = processedA ;
if ( baseUrl && ! baseUrl . endsWith ( '/' ) ) {
baseUrl += '/' ;
}
this . insertImage ( baseUrl + processedB )
} ,
//判断拖拽进富文本的文件类型;
isImageSuffix ( a ) {
let type = '' ;
// 检查参数是否为字符串
if ( typeof a !== 'string' ) {
return false ;
}
// 转换为小写后判断(忽略大小写)
const lowerCaseA = a . toLowerCase ( ) ;
if ( this . allImgType . has ( lowerCaseA ) ) {
type = 'img' ;
} else if ( this . allMusicType . has ( lowerCaseA ) ) {
type = 'music' ;
} else if ( this . allVideoType . has ( lowerCaseA ) ) {
type = 'video' ;
} else if ( this . otherType . has ( lowerCaseA ) ) {
type = '3d'
} else {
type = 'other'
}
return type ;
} ,
//解析字符串信息
parseSpecialString ( str ) {
return str . replace ( /['"\\]/g , '' )
// 处理步骤:移除引号 → 替换转义反斜杠 → 解析Unicode
// return str
// .replace(/^"|"$/g, '')
// .replace(/\\\\/g, '\\')
// .replace(/\\\\/g, '\\')
// .replace(/""/g, '')
// .replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
} ,
//根据ID查询节点 已经需要替换的内容信息
replaceAttributes ( ) {
// 找到treeData中id为xx节点
const targetNode = this . findNodeById ( this . treeData , this . currentNode . id ) ;
if ( targetNode ) {
// 替换attributes
targetNode . attributes = [ ... this . currentNode . attributes ] ;
// this.hasReplaced = true;
console . log ( '替换成功, 新的attributes:' , targetNode . attributes ) ;
}
this . catalogueAnalysis ( this . treeData ) ;
} ,
/ * *
* 查找树形结构中指定id的节点
* @ param { Array } nodes - 节点数组
* @ param { string } id - 要查找的节点id
* @ returns { Object | null } 找到的节点或null
* /
findNodeById ( nodes , id ) {
// 遍历节点数组
for ( const node of nodes ) {
// 找到目标节点
if ( node . id === id ) {
return node ;
}
// 递归查找子节点
if ( node . children && node . children . length > 0 ) {
const found = this . findNodeById ( node . children , id ) ;
if ( found ) {
return found ;
}
}
}
return null ;
} ,
//成功信息 暂未使用
successTips ( msg ) {
this . $message ( {
message : msg ,
type : 'success'
} ) ;
} ,
2025-10-11 11:08:42 +08:00
//目录节点拖拽结束后
handleDragEnd ( ) {
//拖拽完成后保存目录节点。
this . catalogueAnalysis ( this . treeData )
} ,
2025-09-15 09:58:52 +08:00
// 处理节点右键点击
// 处理节点右键点击
handleNodeContextMenu ( event , data , node , component ) {
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
console . log ( "node" , node )
console . log ( "component" , component )
this . navIsAdd = '' ;
this . contextMenuNode = data ;
this . currentNode = data ;
2025-10-11 11:08:42 +08:00
this . nowRightHint = data . name ;
2025-09-15 09:58:52 +08:00
console . log ( "右键以后赋值:" , this . currentNode , data )
this . getDmName = this . domNameStr [ 0 ] + this . domNameStr [ 1 ] + this . domNameStr [ 2 ] + data . id + this . domNameStr [ 3 ] + this . domNameStr [ 4 ] ;
console . log ( "删除的DM名字" , this . getDmName )
// return;
// 获取鼠标位置
let clientX = event . clientX ;
let clientY = event . clientY ;
// 预估菜单高度(可根据实际菜单内容调整)
const menuHeight = 200 ; // 包含4个选项+分隔线+关闭按钮的大概高度
const windowHeight = window . innerHeight ;
// 计算菜单底部位置
const menuBottom = clientY + menuHeight ;
// 如果菜单底部超出窗口高度,向上调整位置
if ( menuBottom > windowHeight ) {
// 调整后的位置 = 鼠标Y - 菜单高度(确保菜单顶部不超出窗口顶部)
clientY = Math . max ( 0 , clientY - menuHeight ) ;
}
// 设置调整后的菜单位置
this . contextMenuLeft = clientX ;
this . contextMenuTop = clientY ;
this . contextMenuVisible = true ;
// 点击其他区域关闭菜单 - 修复版
const handleClickOutside = ( e ) => {
// 先判断菜单元素是否存在
const menuElement = document . querySelector ( '.custom-context-menu' ) ;
if ( ! menuElement ) {
// 元素不存在时直接移除监听
document . removeEventListener ( 'click' , handleClickOutside ) ;
return ;
}
// 元素存在再判断点击位置
if ( ! menuElement . contains ( e . target ) ) {
this . contextMenuVisible = false ;
document . removeEventListener ( 'click' , handleClickOutside ) ;
}
} ;
// 确保移除之前可能存在的监听,避免重复绑定
setTimeout ( ( ) => {
document . removeEventListener ( 'click' , handleClickOutside ) ;
document . addEventListener ( 'click' , handleClickOutside ) ;
} , 0 ) ;
}
,
// 处理菜单选项点击
handleMenuClick ( option ) {
console . log ( '选择了选项:' , option , ',节点数据:' , this . contextMenuNode ) ;
// 根据选项执行对应操作
switch ( option ) {
case 'a' :
this . showAddDialog ( 'edit' ) ;
// 处理选项a逻辑
break ;
case 'b' :
this . showBand ( ) ;
// 处理选项b逻辑
break ;
case 'c' :
this . finalVersion ( ) ;
// 处理选项b逻辑
break ;
case 'd' :
this . showHistory ( ) ;
// 处理选项c逻辑
break ;
case 'e' :
// 处理选项d逻辑
this . deleteDialog ( ) ;
break ;
}
// 关闭菜单
this . contextMenuVisible = false ;
} ,
// 复用路径截取函数
getLastPartOfPath ( path ) {
if ( ! path || typeof path !== 'string' ) return '' ;
const lastBackslashIndex = path . lastIndexOf ( '\\' ) ;
return lastBackslashIndex === - 1 ? path : path . slice ( lastBackslashIndex + 1 ) ;
} ,
//转译 多个反斜杠
fixJsonEscapes ( str ) {
// 步骤1: 先将所有单个\转义为\\(基础转义修复)
let fixed = str . replace ( /(?<!\\)\\/g , '\\\\' ) ;
// // 步骤2: 将所有实际换行符( \n) 替换为字符串\\n
// fixed = fixed.replace(/\n/g, '\\n');
// // 步骤3: 处理可能存在的\r( 回车符)
// fixed = fixed.replace(/\r/g, '\\r');
return fixed ;
} ,
//测试 新开一个浏览器窗口
openWangG2InNewWindow ( sendStr ) {
let str = "[{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_000_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_000_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:39:07.0578892+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_001_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_001_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:41:46.4181541+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_002_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_002_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:42:06.7153697+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_003_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_003_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:42:25.8314261+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_004_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_004_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:51:02.3778949+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_005_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_005_00_zh_cn\",\"CreationTime\":\"2025-09-02T15:59:19.5476416+08:00\"}]"
// let strb = JSON.parse(str);
console . log ( "解析的结果" , str )
// // 获取wangG2页面的路由路径
const wangG2Url = this . $router . resolve ( { name : 'WangG2' } ) . href
// // 打开新窗口,可指定窗口大小和位置
// window.open(
// url,
// '_blank',
// 'width=800,height=600,top=100,left=100'
// )
// 打开新窗口, 假设wangG2.vue的路由路径是/wangG2
// const wangG2Url = this.$router.resolve({ path: '/wangG2' }).href;
// 打开新窗口并设置尺寸
this . wangG2Window = window . open (
wangG2Url ,
'WangG2Window' ,
'width=800,height=600,left=200,top=100'
) ;
// 检查窗口是否被浏览器拦截
if ( ! this . wangG2Window ) {
this . $message . error ( '窗口被浏览器拦截,请允许弹出窗口' ) ;
return ;
}
// 定时检查窗口是否加载完成并发送数据
this . checkWindowTimer = setInterval ( ( ) => {
// 窗口已关闭
if ( this . wangG2Window . closed ) {
clearInterval ( this . checkWindowTimer ) ;
this . $message . info ( 'wangG2窗口已关闭' ) ;
return ;
}
try {
// 尝试发送消息,确保窗口已加载
this . wangG2Window . postMessage (
{
type : 'INIT_DATA' ,
// payload: this.dataToSend,
payload : sendStr ,
sender : 'MainPage'
} ,
window . location . origin // 限制只发送到同源地址
) ;
// 发送成功后清除定时器
clearInterval ( this . checkWindowTimer ) ;
this . $message . success ( '数据已发送到wangG2窗口' ) ;
} catch ( error ) {
// 窗口未加载完成时会抛出错误,继续等待
console . log ( '等待wangG2窗口加载...' ) ;
}
} , 100 ) ;
} ,
// 将处理逻辑提取为单独的方法,便于绑定和解绑
handleFilePathSend ( e ) {
const newStr = this . parseSpecialString ( e . detail ) ;
console . log ( '路径接收:' , this . currentNode , e , e . detail , newStr ) ;
// 访问 currentNode 前先判断是否存在,避免 null 错误
if ( this . currentNode && this . currentNode . attributes ) {
this . currentNode . attributes . push ( newStr ) ;
this . replaceAttributes ( ) ;
console . log ( "当前节点" , this . currentNode , this . treeData ) ;
} else {
console . warn ( 'currentNode 不存在或无 attributes 属性' ) ;
}
} ,
} ,
watch : {
// 监听新建目录的弹窗状态
dialogVisibleNav ( newVal , oldVal ) {
console . log ( "弹窗" , newVal , oldVal )
if ( newVal == true ) {
this . loadFileDMC = '' ;
}
2025-10-11 11:08:42 +08:00
} ,
currentNode ( newVal ) {
if ( newVal ) {
this . $nextTick ( ( ) => {
// 先销毁旧编辑器
if ( this . editor ) {
this . editor . destroy ( ) ;
}
// 初始化新编辑器
this . initEditor ( ) ;
} ) ;
} else {
// 节点为空时销毁编辑器
if ( this . editor ) {
this . editor . destroy ( ) ;
this . editor = null ;
}
}
2025-09-15 09:58:52 +08:00
}
} ,
created ( ) {
// let that = this;
// 方式1: 直接访问全局变量
this . $watch (
( ) => this . $dotNetMessage ,
( newMsg ) => {
console . log ( '收到消息:' , newMsg )
}
)
//和后台交互 获取对应的DMC的历史版本列表
window . addEventListener ( 'GetHistoryVesions' , ( e ) => {
if ( e . detail ) {
const aa = this . fixJsonEscapes ( e . detail ) ;
console . log ( "1第一次接收历史版本信息this.historyData" , e . detail , aa )
this . historyData = JSON . parse ( aa ) ;
console . log ( "1第二次接收历史版本信息this.historyData" , this . historyData )
}
} )
//和后台交互 暂未使用
window . addEventListener ( 'GetHistoryDMContent' , ( e ) => {
console . log ( 'GetHistoryDMContent接收历史版本信息XML:' , e . detail )
} )
//和后台交互 新建章节目录时候点击加载DMC文件
window . addEventListener ( 'GetExistenceDMContent' , ( e ) => {
// console.log('接收历史版本DMC的XML内容:',e, e.detail)
if ( e . detail ) {
this . isLoadOldDmc = '2' ;
this . showView = true ;
this . loadFileXML = e . detail ;
if ( this . loadFileXML . startsWith ( '"' ) ) {
this . loadFileXML = this . loadFileXML . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( this . loadFileXML . endsWith ( '"' ) ) {
this . loadFileXML = this . loadFileXML . substring ( 0 , this . loadFileXML . length - 1 ) ;
}
this . parseXmlDmc ( ) ;
}
} )
2025-10-11 11:08:42 +08:00
//和后台交互 接收富文本XML
window . addEventListener ( 'FrontLoadProjectNew' , this . FrontLoadDM _g2 )
2025-09-15 09:58:52 +08:00
//和后台交互 接收目录XML
2025-10-11 11:08:42 +08:00
// window.addEventListener('FrontLoadProjectNew', (e) => {
// })
2025-09-15 09:58:52 +08:00
//和后台交互 单独获取DM的文文件(暂未使用)
window . addEventListener ( 'GetDMDta' , ( e ) => {
// 加载目录
console . log ( 'GetDMDta 参数接收:' , e , e . detail )
} )
//和后台交互 接收富文本XML
window . addEventListener ( 'FrontLoadDM' , this . FrontLoadDM _g1 )
//和后台交互 获取文件地址
window . addEventListener ( 'SendResourcePath' , ( e ) => {
console . log ( '拖拽文件地址:' , e , e . detail )
2025-10-11 11:08:42 +08:00
let newData = this . zy ( e . detail ) ;
2025-09-15 09:58:52 +08:00
// 1. 去除双引号
2025-10-11 11:08:42 +08:00
const parsedA = this . lisenPath . replace ( /"/g , '' ) ;
const parsedB = newData . replace ( /"/g , '' ) ;
2025-09-15 09:58:52 +08:00
// 2. 处理转义字符(如斜杠)
const processedA = parsedA . replace ( /\\/g , '' ) ;
2025-10-11 11:08:42 +08:00
// const processedB = parsedB.replace(/\\/g, '');
const processedB = parsedB . replace ( /\\\\/g , "\\" ) ;
console . log ( "processedB" , processedB , parsedB )
2025-09-15 09:58:52 +08:00
// 3. 确保基础URL以斜杠结尾
let baseUrl = processedA ;
if ( baseUrl && ! baseUrl . endsWith ( '/' ) ) {
baseUrl += '/' ;
}
const cleanedFile = parsedB . replace ( /\\/g , '' ) ;
// 2. 提取后缀名
const lastDotIndex = cleanedFile . lastIndexOf ( '.' ) ;
const suffix = cleanedFile . substring ( lastDotIndex + 1 ) . toLowerCase ( ) ;
// allImgType allMusicType allVideoType
console . log ( "后缀" , suffix )
switch ( this . isImageSuffix ( suffix ) ) {
case 'img' :
this . insertImage ( baseUrl + processedB )
// this.insertImage( baseUrl + '/zw.jpg')
break ;
case 'music' :
this . insertAudio ( baseUrl + processedB )
break ;
case 'video' :
this . insertVideo ( baseUrl + processedB )
break ;
case '3d' :
this . insert3d ( baseUrl + '/zw.jpg' )
break ;
default :
this . $message ( {
message : '当前文件不支持' ,
type : 'warning'
} ) ;
break ;
}
} )
2025-10-11 11:08:42 +08:00
console . log ( '监听器开始注册11: ' , Date . now ( ) ) // 打印注册时间戳
2025-09-15 09:58:52 +08:00
//和后台交互 获取文件地址
window . addEventListener ( 'SendLisentPath' , this . SendLisentPathFun )
//和后台交互 获取项目名
window . addEventListener ( 'SendProjectName' , ( e ) => {
this . domNameStr [ 1 ] = this . removeQuotationMarks ( e . detail ) ;
console . log ( '获取项目文件夹名子:' , this . domNameStr , e , e . detail )
} )
2025-10-11 11:08:42 +08:00
2025-09-15 09:58:52 +08:00
//和后台交互 定稿之后获取最新的dm名称
window . addEventListener ( 'SendNewVersionDMFileName' , ( e ) => {
console . log ( "定稿以后的信息" , e . detail )
let str = this . removeQuotationMarks ( e . detail ) ;
console . log ( "定稿以后的 str" , str )
const firstUnderline = str . indexOf ( '_' ) ;
console . log ( "定稿以后的 firstUnderline" , firstUnderline )
const secondUnderline = str . indexOf ( '_' , firstUnderline + 1 ) ;
console . log ( "节点属性" , this . currentNode )
console . log ( "定稿以后的secondUnderline" , secondUnderline )
if ( this . currentNode ) {
this . currentNode . lagreVersion = str . substring (
firstUnderline + 1 ,
secondUnderline
) ;
this . updateNodeVersion ( this . currentNode . id , this . currentNode . lagreVersion )
console . log ( "定稿以后的currentNode" , this . currentNode )
console . log ( "定稿以后的树" , this . treeData )
this . catalogueAnalysis ( this . treeData ) ;
}
} )
//和后台交互 获取加载时候的DMC文件预览服务器端口号
window . addEventListener ( 'handPrePath' , ( e ) => {
if ( e ) {
this . viewLis = e . detail ;
}
} )
//和后台交互 获取加载时候的DMC文件具体内容
window . addEventListener ( 'handreContent' , ( e ) => {
if ( e ) {
this . maskViewShow = true ;
this . viewXml = e . detail ;
if ( this . viewLis . startsWith ( '"' ) ) {
this . viewXml = this . viewXml . substring ( 1 ) ;
}
// 检查并去除结尾的双引号
if ( this . viewXml . endsWith ( '"' ) ) {
this . viewXml = this . viewXml . substring ( 0 , this . viewXml . length - 1 ) ;
}
2025-10-11 11:08:42 +08:00
console . log ( "得到的0" , this . viewXml )
this . parseRdfDescriptions ( this . viewXml )
2025-09-15 09:58:52 +08:00
this . parseXmlDmc _loadFile ( ) ;
}
} )
// window.addEventListener('handleMessageFromDotNet', this.fun1)
} ,
}
2025-10-11 11:08:42 +08:00
< / script >