当前位置: 首页 > news >正文

自动生成md文件以及config.mjs文件-vitepress

效果:

config.mjs文件

import {defineConfig} from 'vitepress'
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import xml from 'highlight.js/lib/languages/xml'
import {ref} from "./cache/deps/vue.js";
// 注册语言
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('html', xml)export default defineConfig(async () => {return {markdown: {theme: 'material-theme-palenight',lineNumbers: true,math: true,container: {tipLabel: '提示',warningLabel: '警告',dangerLabel: '危险',infoLabel: "信息",detailsLabel: "详情"},},enhanceApp: {setup: (ctx) => {ctx.app.component('AdBanner', AdBanner)}},title: "平台基础管理系统PBM帮助文档",description: "系统使用说明",themeConfig: {outline: {level: [2, 3],label: '页面导航'},siteTitle: "帮助文档",logo: "../pubilc/assets/logo.png",nav: [{text: '首页',link: '/'},{text: '数据采集',items: [{text: '直报',link: 'DFS'},{text: '爬虫',link: 'DAS'},{text: '爬虫2',link: 'das2'},{text: '爬虫2',link: 'das2'},]},],
sidebar: {'DFS': {items: [{text: '表单管理平行测试',link: 'null'}]},'formManage': {items: [{text: '表单管理',collapsible: true,collapsed: false,items: [{text: '表单管理文档',link: 'testMD'},{text: '表单路径测试',link: 'testForm'},{text: '测试文档2',link: 'test2'},{text: '测试3',link: 'test3'}]}]},},footer: {message: "平台基础管理系统PBM帮助文档",copyright: '2025.5.20   @langtao'},styl: {}}}
})

前端代码:

列表:

<template><div class="app-container" style="width:100%;height:100%;"><el-aside style="padding-right: 10px; padding-left: 15px; padding-top: 0px;float:left;width:20%;background:none;"><div class="block" style="width:100%;height:100%;"><!-- <el-select v-model="xiangmuId" class="filter-item" placeholder="项目" style="width: 100%" clearable @change="handChange"><el-option v-for="item in xmList" :key="item.id" :label="item.xiangmumingcheng" :value="item.id" /></el-select> --><el-cascader ref="cascaderHandle" v-model="xiangmuId" style="width:100%;" clearable :options="xmList" :props="optionProps" :show-all-levels="false" @change="change"><template slot-scope="{ data }"><span @click="clickNode">{{ data.xiangmumingcheng }}</span></template></el-cascader><el-treeid="el-tree"ref="tree"class="filter-tree":data="data2"node-key="id":highlight-current="true":props="defaultProps":default-expanded-keys="TreeArr":expand-on-click-node="false"@node-click="handleNodeClick"@node-contextmenu="rightClick"/><div v-show="menu1Visible"><ul id="menu1" class="menu1" style="font-size:14px;"><li class="menu_item" @click="handleAdd">新增下级目录</li><li class="menu_item" @click="download()">生成md文件</li></ul></div><div v-show="menu2Visible"><ul id="menu2" class="menu2" style="font-size:14px;"><li class="menu_item" @click="handleAdd">新增下级目录</li></ul></div><div v-show="menu3Visible"><ul id="menu3" class="menu3" style="font-size:14px;"><li class="menu_item" @click="handleAdd">新增下级目录</li><li class="menu_item" @click="handleEdit">编辑目录</li><li class="menu_item" @click="add()">新增文档</li><li class="menu_item" @click="handleDisable">删除目录</li></ul></div><div v-show="menu4Visible"><ul id="menu4" class="menu4" style="font-size:14px;"><li class="menu_item" @click="handleEdit">编辑目录</li><li class="menu_item" @click="add()">新增文档</li><li class="menu_item" @click="handleDisable">删除目录</li></ul></div><div v-show="menu5Visible"><ul id="menu5" class="menu5" style="font-size:14px;"><li class="menu_item" @click="edit()">编辑文档</li><li class="menu_item" @click="remove()">删除文档</li>  </ul></div></div></el-aside><el-aside style="padding-right: 5px; padding-left: 5px; padding-top: 0px;float:left;width:80%;background:none;"><div class="filter-container" style="text-align:center;margin-top:0px;padding-bottom: 0px;"><el-button class="filter-item" icon="el-icon-s-data" type="info" @click="history()">文档历史版本</el-button><el-button class="filter-item" icon="el-icon-warning-outline" type="primary" @click="yulan()">预览</el-button></div><el-table v-show="displayVisible" v-loading="listLoading" :data="numList" :height="tableHeight4" style="width: 100%; overflow:auto;" border><el-table-column type="index" header-align="center" align="center" label="序号" width="80px" /><el-table-column header-align="center" align="left" label="操作" width="320px"><template slot-scope="scope"><el-button type="text" size="small" @click="hlfp(scope)">查看</el-button></template></el-table-column><el-table-column header-align="center" align="left" label="项目名称"><template slot-scope="scope"><span>{{ scope.row.xmName }}</span></template></el-table-column><el-table-column header-align="center" align="right" label="文档数量"><template slot-scope="scope"><span>{{ scope.row.num }}</span></template></el-table-column></el-table><div v-show="displayVisible1" style="width:100%; margin:0 auto;"><div><table class="table"><tr><td class="title-name"><strong>项目:</strong></td><td class="table-content"><span>{{ from.xmName }}</span></td><td class="title-name"><strong>文档名称:</strong></td><td class="table-content"><span>{{ from.tableName }}</span></td></tr><tr><td class="title-name"><strong>备注:</strong></td><td colspan="3" style="100%"><span>{{ from.tableDetailExplain }}</span></td></tr><tr><td class="title-name"><strong>内容:</strong></td></tr><tr><td colspan="4" style="98%"><span v-html="from.htmlData" /></td></tr></table></div></div><el-dialog :visible.sync="dialogAddVisible" width="600px" :show-close="false" append-to-body :title="'新增下级目录'"><dialog-add v-if="dialogAddVisible" ref="dialogAdd" :xiangmu="xiangmuId" :classify="classifyId" :level="treeLevel" :visible.sync="dialogAddVisible" /></el-dialog><el-dialog :visible.sync="dialogEditVisible" width="600px" :show-close="false" append-to-body :title="'编辑目录'"><dialog-edit v-if="dialogEditVisible" ref="dialogEdit" :proid="code" :level="treeLevel" :visible.sync="dialogEditVisible" /></el-dialog><el-dialog :visible.sync="addApiVisible" width="1200px" append-to-body :show-close="false" :title="'新增文档'"><add-api v-if="addApiVisible" ref="addApi" :classify="classifyId" :xiangmu="xiangmuId" :visible.sync="addApiVisible" /></el-dialog><el-dialog :visible.sync="editApiVisible" width="1200px" append-to-body :show-close="false" :title="'编辑文档'"><edit-api v-if="editApiVisible" ref="editApi" :proid="classifyId" :visible.sync="editApiVisible" /></el-dialog><el-dialog :visible.sync="historyVisible" width="1000px" append-to-body :title="'文档历史记录'"><history v-if="historyVisible" ref="history" :history="batchCode" :visible.sync="historyVisible" /></el-dialog><el-dialog :visible.sync="downloadVisible" width="400px" append-to-body :show-close="false" :title="'生成MD文件'"><download v-if="downloadVisible" ref="download" :xiangmu="xiangmuId" :classify="classifyId" :level="treeLevel2" :visible.sync="downloadVisible" /></el-dialog><el-dialog :visible.sync="yulanVisible" width="1200px" append-to-body :title="'预览'"><yulan v-if="yulanVisible" ref="yulan" :proid="xiangmuId" :visible.sync="yulanVisible" /></el-dialog></el-aside></div>
</template><script>
import { getXiangMuList } from '@/api/projectInfo'
import { getInfo, getFileList, remove } from '@/api/usersManualFile'
import { getInitialLoading, getAgainLoading, makeMD } from '@/api/configMenu'
import { disabled} from '@/api/usersManualCatalog'
import { getDictListByCode } from '@/api/dict'
import { Message, MessageBox } from 'element-ui'
import { tableHeight4 } from '@/utils/tableHeight'
import DialogAdd from './add' // eslint-disable-line no-unused-vars
import DialogEdit from './edit' // eslint-disable-line no-unused-vars
import AddApi from '../manual/addApi' // eslint-disable-line no-unused-vars
import EditApi from '../manual/editApi' // eslint-disable-line no-unused-vars
import history from '../manual/history' // eslint-disable-line no-unused-vars
import download from '../manual/downloadByXm' // eslint-disable-line no-unused-vars
import yulan from '../manual/yulan' // eslint-disable-line no-unused-varsexport default {name: 'Zzjg',components: { AddApi, EditApi,history, download, yulan, DialogAdd, DialogEdit, },mixins: [tableHeight4],provide() {return {getTreeList: this.getTreeList}},data() {return {TreeArr: [],optionProps: {value: 'id',children: 'children',label: 'xiangmumingcheng',checkStrictly: false,expandTrigger: 'hover'},IdArr: [],displayVisible: false,displayVisible1: false,listLoading: false,total: 0,xiangmuId: '',numList: [],xmList: [],userList: [],classifyId: '',batchCode: '',flag: '',DATA: null,NODE: null,objectID: null,menu1Visible: false,menu2Visible: false,menu3Visible: false,menu4Visible: false,menu4Visible2: false,menu5Visible:false,treeLevel:'',treeLevel2: '',downloadId: '',dialogAddVisible: false,dialogEditVisible: false,addApiVisible: false,editApiVisible: false,historyVisible: false,downloadVisible: false,yulanVisible: false,stateOptions: [],data: [],data2: [],from: {},queryPage: {},datas: '',img1: require('../../../assets/images/Folder-01.png'),defaultProps: {children: 'children',label: 'menuName'}}},created() {this.getList()this.getXiangMuList()this.getDictList('YW_BASE_STATUS')},methods: {getList() {this.displayVisible = truethis.displayVisible1 = falsegetFileList().then(response => {this.numList = response.datathis.listLoading = false}).catch(response => {this.listLoading = false})},// 提示框renderContent: function(h, { node, data, store }) {var text = data.nameif (data.flag === 'ML') {if (text.length > 15) {return (< span >< i > <img src={this.img1} style='width: 18px;height: 18px;margin-right:5px;padding-top:1px' /></i><el-tooltip class='item' id='tool' effect='light' popper-class='draw' visible-arrow='false' content={data.name} placement='bottom-start' ><span class='style-demo' >{data.name}</span ></el-tooltip></span>)} else {return (< span >< i > <img src={this.img1} style='width: 18px;height: 18px;margin-right:5px;padding-top:1px' /></i><span class='style-demo' >{data.name}</span ></span>)}} else {if (text.length > 15) {return (< span ><el-tooltip class='item' id='tool' effect='light' popper-class='draw' visible-arrow='false' content={data.name} placement='bottom-start' ><span class='style-demo' >{data.name}</span ></el-tooltip></span>)} else {return (< span ><span class='style-demo' >{data.name}</span ></span>)}}},hlfp(scope) {this.displayVisible = falsethis.displayVisible1 = truethis.xiangmuId = scope.row.xmId// 加载列表getInitialLoading({ xmId: scope.row.projectId }).then(response => {this.data = response.datathis.data2 = this.buildTree2(this.data)this.data2.forEach(m => {this.TreeArr.push(m.id)})this.listLoading = false}).catch(response => {this.listLoading = false})},getXiangMuList() { // 加载列表this.xmList = []getXiangMuList(this.queryPage).then(response => {this.xmList = this.buildTree(response.data)this.listLoading = false}).catch(response => {this.listLoading = false})},buildTree(data) {var rdata = []for (let i = 0; i < data.length; i++) {var e1 = data[i]if (e1.parentId === '-1') {rdata.push(e1)}for (let j = 0; j < data.length; j++) {var e2 = data[j]if (e1.parentId === e2.id) {if (!e2.children) {e2.children = []}e2.children.push(e1)}}}return rdata},clickNode($event) {$event.target.parentElement.parentElement.firstElementChild.click()this.$refs.cascaderHandle.dropDownVisible = false},change(val) {const nodesObj = this.$refs['cascaderHandle'].getCheckedNodes()this.data = []this.data2 = []if (val.length === 2) {this.displayVisible = falsethis.xiangmuId = nodesObj[0].data.idthis.getTreeList(nodesObj[0].data.id)this.displayVisible1 = true} else {this.displayVisible = truethis.displayVisible1 = false}},// handChange(e) {//   this.displayVisible = false//   this.data = []//   this.data2 = []//   if (e !== null && e !== '' && e !== 'null') {//     this.getTreeList(e)//     this.displayVisible1 = true//   }// },getTreeList(code) { // 加载列表// 加载列表getInitialLoading({ xmId: code }).then(response => {this.data = response.dataconsole.log(code,'123213')this.data2 = this.buildTree2(this.data)this.data2.forEach(m => {this.TreeArr.push(m.id)})this.listLoading = false}).catch(response => {this.listLoading = false})},buildTree2(data) {var rdata = []for (let i = 0; i < data.length; i++) {var e1 = data[i]if (e1.parentId === '-1') {rdata.push(e1)}for (let j = 0; j < data.length; j++) {var e2 = data[j]if (e1.parentId === e2.id) {if (!e2.children) {e2.children = []}e2.children.push(e1)}}}return rdata},getDictList(code) {getDictListByCode(code).then(response => {if (code === 'YW_BASE_STATUS') {this.stateOptions = response.data}})},getDicName(code, flag) {var dict = []if (flag === 'YW_BASE_STATUS') {dict = this.stateOptions}for (var i in dict) {if (dict[i].code === code) {return dict[i].name}}},// 右键点击rightClick(MouseEvent, object, Node, element) { // 鼠标右击触发事件this.DATA = objectthis.NODE = Nodeconsole.log(this.NODE,this.DATA,'123',this.NODE.level)if (this.NODE.level === 1) {this.menu1Visible = true // 显示模态窗口,跳出自定义菜单栏this.menu2Visible = false // 显示模态窗口,跳出自定义菜单栏this.menu3Visible = false var menu1 = document.querySelector('#menu1')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu1.style.display = 'block'menu1.style.left = MouseEvent.clientX - 0 + 'px'menu1.style.top = MouseEvent.clientY - 20 + 'px'} else if (this.NODE.level > 1 && this.NODE.level < 3) {if (this.NODE.data.flag === 'ML') {this.menu1Visible = false // 显示模态窗口,跳出自定义菜单栏this.menu2Visible = true // 显示模态窗口,跳出自定义菜单栏var menu2 = document.querySelector('#menu2')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu2.style.display = 'block'menu2.style.left = MouseEvent.clientX - 0 + 'px'menu2.style.top = MouseEvent.clientY - 20 + 'px'}}else if(this.NODE.level === 3){this.menu1Visible = falsethis.menu2Visible = falsethis.menu3Visible = truethis.menu4Visible = falsethis.menu4Visible2 = falsethis.menu5Visible = falsevar menu3 = document.querySelector('#menu3')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu3.style.display = 'block'menu3.style.left = MouseEvent.clientX - 0 + 'px'menu3.style.top = MouseEvent.clientY - 20 + 'px'}else if(this.NODE.level ===4){this.menu1Visible = falsethis.menu2Visible = falsethis.menu3Visible = falseif (this.NODE.data.flag === 'ML') {this.menu4Visible = truevar menu4 = document.querySelector('#menu4')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu4.style.display = 'block'menu4.style.left = MouseEvent.clientX - 0 + 'px'menu4.style.top = MouseEvent.clientY - 20 + 'px'}else{this.menu4Visible2 = truevar menu42 = document.querySelector('#menu42')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu42.style.display = 'block'menu42.style.left = MouseEvent.clientX - 0 + 'px'menu42.style.top = MouseEvent.clientY - 20 + 'px'}}else if(this.NODE.level === 5){this.menu1Visible = falsethis.menu2Visible = falsethis.menu3Visible = falsethis.menu4Visible = falsethis.menu4Visible2 = falsethis.menu5Visible = truevar menu5 = document.querySelector('#menu5')document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法menu5.style.display = 'block'menu5.style.left = MouseEvent.clientX - 0 + 'px'menu5.style.top = MouseEvent.clientY - 20 + 'px'}this.classifyId = this.NODE.data.idthis.treeLevel = this.NODE.level+1this.treeLevel2 = this.NODE.levelthis.downloadId = this.NODE.data.idconsole.log(this.downloadId,'this.downloadId')this.xiangmuId = this.NODE.data.projectId},foo() { // 取消鼠标监听事件 菜单栏this.menu1Visible = falsethis.menu2Visible = falsethis.menu3Visible = falsethis.menu4Visible = falsethis.menu4Visible2 = falsethis.menu5Visible = falsedocument.removeEventListener('click', this.foo) // 要及时关掉监听,不关掉的是一个坑,不信你试试,虽然前台显示的时候没有啥毛病,加一个alert你就知道了},handleNodeClick(data) {this.from = {}this.displayVisible1 = truethis.classifyId = data.idconsole.log(this.classifyId,'this.classifyId',this.optionProps.label)this.xiangmuId = data.projectIdthis.flag = data.flagthis.batchCode = data.codethis.parent = data.parentIdif (this.flag === 'WD') {getInfo({ code: data.id }).then(response => {this.from = response.data[0]}).catch(function() {})} else {var dataA = dataif (!this.IdArr.includes(dataA.id)) {// 树getAgainLoading({ parentId: data.id, xmId: data.projectId }).then(response => {this.data = response.datafor (let i = 0; i < this.data.length; i++) {const newChild = this.data[i]if (!dataA.children) {this.$set(dataA, 'children', [])}dataA.children.push(newChild)}this.dataId = dataA.idthis.IdArr.push(dataA.id)this.listLoading = false}).catch(response => {this.listLoading = false})}}},handleAdd() {this.dialogAddVisible = truethis.$nextTick(() => {this.$refs.dialogAdd})},handleEdit() {this.dialogEditVisible = truethis.code = this.classifyIdthis.$nextTick(() => {this.$refs.dialogEdit})},add() {if (this.parent === '-1') {Message({message: '请选择子节点!',type: 'error',duration: 5 * 1000})} else if (this.parent !== '-1' && this.flag !== 'WD') {if (this.xiangmuId !== null && this.xiangmuId !== '') {if (this.classifyId !== null && this.classifyId !== '') {this.addApiVisible = truethis.$nextTick(() => {this.$refs.addApi})} else {Message({message: '请选择节点!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}}},edit() {if (this.parent !== '-1' && this.flag === 'WD') {if (this.xiangmuId !== null && this.xiangmuId !== '') {if (this.classifyId !== null && this.classifyId !== '') {this.editApiVisible = truethis.$nextTick(() => {this.$refs.editApi})} else {Message({message: '请选择子节点!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择文档节点!',type: 'error',duration: 5 * 1000})}},history() {if (this.parent !== '-1' && this.flag === 'WD') {if (this.xiangmuId !== null && this.xiangmuId !== '') {if (this.classifyId !== null && this.classifyId !== '') {this.historyVisible = truethis.$nextTick(() => {this.$refs.history})} else {Message({message: '请选择子节点!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择文档节点!',type: 'error',duration: 5 * 1000})}},download() {if (this.xiangmuId !== null && this.xiangmuId !== '') {this.downloadVisible = truethis.$nextTick(() => {this.$refs.download})} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}},handleDisable() {MessageBox.confirm('确认删除节点', '确定', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {disabled(this.NODE.id).then(response => {Message({message: '删除节点成功',type: 'success',duration: 5 * 1000})// 重新加载表格this.getTreeList(this.xiangmuId)})})},remove() {if (this.parent !== '-1' && this.flag === 'WD') {if (this.xiangmuId !== null && this.xiangmuId !== '') {if (this.classifyId !== null && this.classifyId !== '') {MessageBox.confirm('确认删除', '确定', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {remove({ code: this.classifyId }).then(response => {Message({message: '删除成功',type: 'success',duration: 5 * 1000})// 重新加载表格this.getTreeList(this.xiangmuId)// 重新加载表格this.handleNodeClick()})})} else {Message({message: '请选择子节点!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}} else {Message({message: '请选择文档节点!',type: 'error',duration: 5 * 1000})}},yulan() {if (this.xiangmuId !== null && this.xiangmuId !== '') {this.yulanVisible = truethis.$nextTick(() => {this.$refs.yulan})} else {Message({message: '请选择项目!',type: 'error',duration: 5 * 1000})}}}
}
</script><style scoped>
.app-container{height:calc(100% - 20px) !important;width:calc(100% - 20px) !important;padding:10px 0;
}
#app-contain{height:100%;width:100%
}
.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;
}
/* 右键会选中文字,为了美观将它禁用*/
#el-tree{user-select:none;
}
#el-tree >>> .style-demo {color: #474a4d;font-size: 14px;font-family: "黑体";text-overflow: ellipsis;white-space: nowrap;overflow: hidden;
}
.menu1 {height: 60px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu2 {height: 40px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu3 {height: 120px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu4 {height: 90px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu42 {height: 80px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu5 {height: 60px;width: 120px;position: fixed;border: 1px solid #ccc;background-color: white;list-style: none;padding-left: 10px;
}
.menu_item {line-height: 20px;text-align: left;margin-top: 10px;
}
.collapse-title{font-size: 16px;color:#1196EE;
}
.table{border-collapse: separate;border-spacing: 10px 10px;
}
.title-name{width: 100px;text-align: left;vertical-align: middle;
}
.table-content{width: 450px;
}</style>

生成md文件:

<template><div class="app-container" style="width:100%;height:100%;"><div class="block" style="width:100%;height:100%;">是否要按照目录生成MD文件</div><span slot="footer" class="dialog-footer"><div style="text-align:center;margin-top:20px;"><el-button type="primary" @click="onSave">确定</el-button><el-button type="danger" class="quxiao_btn" @click="closePage()">取消</el-button></div></span></div>
</template><script>import { getTreeList, makeMD } from '@/api/configMenu'
import { Message } from 'element-ui'export default {name: 'Zzjg',props: { // 第二种方式xiangmu: {type: String,required: true},classify: {type: String,required: true},level: {type: String,required: true}},data() {return {data: [],data2: [],ids: '',defaultProps: {children: 'children',label: 'name'}}},created() {this.getTreeList()},methods: {getTreeList() { // 加载列表getTreeList({ xiangmuId: this.xiangmu }).then(response => {this.data = response.datathis.data2 = this.buildTree2(this.data)}).catch(response => {})},buildTree2(data) {var rdata = []for (let i = 0; i < data.length; i++) {var e1 = data[i]if (e1.parentId === '-1') {rdata.push(e1)}for (let j = 0; j < data.length; j++) {var e2 = data[j]if (e1.parentId === e2.id) {if (!e2.children) {e2.children = []}e2.children.push(e1)}}}return rdata},onSave() {var ids = ''var flag = ''var level = ''ids = this.classifyconsole.log(this.level,'level')const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})makeMD({ id: ids, flag: flag, level:this.level }).then(response => {var fileName = 'download.zip'// const contentDisposition = response.headers['content-disposition']//   if (contentDisposition) {//     fileName = window.decodeURI(response.headers['content-disposition'].split('=')[1], 'UTF-8')//   }const blob = new Blob([response], {type: `application/zip` // word文档为msword,pdf文档为pdf})const objectUrl = URL.createObjectURL(blob)const link = document.createElement('a')link.href = objectUrlconsole.log(objectUrl,'objectUrl')link.setAttribute('download', fileName)document.body.appendChild(link)link.click()// 释放内存window.URL.revokeObjectURL(link.href)loading.close()this.closePage()if (response.code === 20000) {Message({message: '生成成功',type: 'success',duration: 5 * 1000})loading.close()this.closePage()}}).catch(response => {loading.close()})},closePage() {this.$emit('update:visible', false)}}
}
</script>

新增方法:

<template><div class="markdown"><div style="width:100%;height:auto; margin:0 auto;"><el-form ref="form" :model="form" :rules="rules" label-width="80px" style="margin: 0 auto;width:100%;"><el-row><el-col :span="12"><el-form-item label="手册名称" prop="tableName"><el-input v-model="form.tableName" placeholder="手册名称" /></el-form-item></el-col><el-col :span="12"><el-form-item label="排序号" prop="sortNum"><el-input-number v-model="form.sortNum" :step="1" style="width:100%;text-align:left;" /></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-item label="路径" prop="link"><el-input v-model="form.link" placeholder="路径" /></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="内容" prop="sortNum"><mavon-editor ref="md" v-model="content" style="height: 400px" @change="change" @imgAdd="imgAdd" /></el-form-item></el-col></el-row></el-form><div style="text-align:center; padding-top:10px"><el-button type="primary" @click="save">保存</el-button><el-button type="danger" @click="closePage">取消</el-button></div></div></div>
</template><script>
import { Message } from 'element-ui'
import { save, getMdTemplate } from '@/api/usersManualFile'
import { upload } from '@/api/projectFile'import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'export default {name: '',components: {mavonEditor},inject: ['getTreeList'],props: { // 第二种方式xiangmu: {type: String,required: true},classify: {type: String,required: true}},data() {return {form: {sortNum: 1},rules: {sortNum: [{ required: true, message: '排序号不能为空', trigger: 'blur' }],tableName: [{ required: true, message: 'api名称不能为空', trigger: 'blur' }]},content: '',html: '',configs: {}}},created() {this.getDetailed()},methods: {getDetailed() {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})getMdTemplate().then(response => {this.content = response.dataloading.close()}).catch(function() {loading.close()})},// 将图片上传到服务器,返回地址替换到md中imgAdd(pos, $file) {const formdata = new FormData()formdata.append('image', $file)// 访问后台服务器方法upload(formdata).then(res => {if (res.code === 20000) {this.$refs.md.$img2Url(pos, res.data.abstractPath)} else {this.$message.error(res.message)}}).catch(err => {console.log(err)})},// 所有操作都会被解析重新渲染change(value, render) {this.form.htmlData = renderthis.form.markdownData = value},save() { // 新增this.$refs.form.validate(valid => {if (valid) {const loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'})this.form.xmId = this.xiangmuthis.form.classifyId = this.classifysave(this.form).then(response => {Message({message: '新增成功',type: 'success',duration: 5 * 1000})this.$emit('update:visible', false)// this.getList()this.getTreeList()loading.close()}).catch(response => {loading.close()})} else {return false}})},closePage() {this.$emit('update:visible', false)}}
}
</script>

后端生成方法:

 /*** 生成md文件** @Title: makeMD* @Description:* @author sxy* @param flag* @param ids* @return* @throws IOException*/@RequestMapping(value = "/makeMD", method = RequestMethod.POST, produces = "application/json")
//    @GetMapping(value="/makeMD", method = RequestMethod.POST, produces = "application/json")@ResponseBodypublic void makeMD(HttpServletRequest request, HttpServletResponse response, String flag, String id,Integer level)throws IOException {if (id == null || StringUtils.isBlank(id)) {
//            return ResultData.error(ResultData.PARAM_ERROR_CODE, "参数错误");}// 创建存放生成的MD文件的根目录String rootDir = uploadPath + File.separator + "md_files";File rootDirFile = new File(rootDir);if (!rootDirFile.exists()) {rootDirFile.mkdirs();}// 生成日期子目录// 生成日期时间子目录,格式为:年-月-日_时-分-秒DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");String dateSubDir = LocalDateTime.now().format(formatter);String fullDirPath = rootDir + File.separator + dateSubDir;File dateDir = new File(fullDirPath);if (!dateDir.exists()) {dateDir.mkdirs();}//md文件列表List<UsersManualFile> list = new ArrayList<>();//如果不是根节点的话,则去查找UsersManualFile表里的parent_id的数据if (level != 1) {QueryWrapper<UsersManualFile> queryWrapper = new QueryWrapper<UsersManualFile>();queryWrapper.eq("parent_id", id);list = usersManualFileMapper.selectList(queryWrapper);}else {QueryWrapper<UsersManualFile> queryWrapper = new QueryWrapper<UsersManualFile>();queryWrapper.eq("umf_xm_id", id);list = usersManualFileMapper.selectList(queryWrapper);//mjs文件列表QueryWrapper<ConfigMenu> queryWrapper2 = new QueryWrapper<ConfigMenu>();queryWrapper2.eq("project_id", id);List<ConfigMenu> configMenuList = configMenuMapper.selectList(queryWrapper2);List<ConfigMenu> navMenuList = configMenuList;if (configMenuList == null || configMenuList.size() == 0) {
//                return ResultData.error(ResultData.PARAM_ERROR_CODE, "无数据");}//动态navStringBuilder  mjsTemplateNav = new StringBuilder();mjsTemplateNav.append("      nav: [\n" +"        {\n" +"          text: '首页',\n" +"          link: '/'\n" +"        },\n");//动态sidebarStringBuilder mjsTemplateSidebar = new StringBuilder();mjsTemplateSidebar.append("sidebar: {\n");//动态navfor (ConfigMenu configMenu : configMenuList) {// 二级节点为横向菜单if ("2".equals(configMenu.getLevel())) {// 判断该菜单是否存在下拉子项boolean hasSubItems = navMenuList.stream().anyMatch(menu -> menu.getParentId().equals(configMenu.getId()));if (hasSubItems) {// 如果有下拉子项,则使用 items 格式mjsTemplateNav.append("        {\n");mjsTemplateNav.append("          text: '").append(configMenu.getMenuName()).append("',\n");mjsTemplateNav.append("          items: [\n");for (ConfigMenu subMenu : navMenuList) {if (subMenu.getParentId().equals(configMenu.getId())) {mjsTemplateNav.append("            {\n");mjsTemplateNav.append("              text: '").append(subMenu.getMenuName()).append("',\n");mjsTemplateNav.append("              link: '").append(subMenu.getLink()).append("'\n");mjsTemplateNav.append("            },\n");}}mjsTemplateNav.append("          ]\n");mjsTemplateNav.append("        },\n");} else {// 如果没有下拉子项,则使用简单格式mjsTemplateNav.append("        {\n");mjsTemplateNav.append("          text: '").append(configMenu.getMenuName()).append("',\n");mjsTemplateNav.append("          link: '").append(configMenu.getLink()).append("'\n");mjsTemplateNav.append("        },\n");}}}//动态生成sidebar// 创建一个映射,用于存储每个路径对应的菜单项Map<String, List<ConfigMenu>> pathToMenus = new HashMap<>();for (ConfigMenu configMenu : configMenuList) {if ("3".equals(configMenu.getLevel()) || "4".equals(configMenu.getLevel())) {// 如果是三级或四级菜单,检查其是否有对应的文档文件for (UsersManualFile usersManualFile : list) {if (usersManualFile.getParentId().equals(configMenu.getId())) {// 根据菜单的路径分组String path = configMenu.getLink();pathToMenus.computeIfAbsent(path, k -> new ArrayList<>()).add(configMenu);}}}}// 生成每个路径的配置for (Map.Entry<String, List<ConfigMenu>> entry : pathToMenus.entrySet()) {String path = entry.getKey();List<ConfigMenu> menus = entry.getValue();// 对菜单项进行去重List<ConfigMenu> uniqueMenus = new ArrayList<>();for (ConfigMenu menu : menus) {if (!uniqueMenus.contains(menu)) {uniqueMenus.add(menu);}}menus = uniqueMenus;mjsTemplateSidebar.append("      '").append(path).append("': {\n");mjsTemplateSidebar.append("        items: [\n");for (ConfigMenu configMenu : menus) {if ("3".equals(configMenu.getLevel())) {// 如果是三级菜单,直接添加文档项for (UsersManualFile usersManualFile : list) {if (usersManualFile.getParentId().equals(configMenu.getId())) {mjsTemplateSidebar.append("          {\n");mjsTemplateSidebar.append("            text: '").append(usersManualFile.getTableName()).append("',\n");mjsTemplateSidebar.append("            link: '").append(usersManualFile.getLink()).append("'\n");mjsTemplateSidebar.append("          },\n");}}} else if ("4".equals(configMenu.getLevel())) {// 如果是四级菜单,创建一个可折叠的项mjsTemplateSidebar.append("          {\n");mjsTemplateSidebar.append("            text: '").append(configMenu.getMenuName()).append("',\n");mjsTemplateSidebar.append("            collapsible: true,\n");mjsTemplateSidebar.append("            collapsed: false,\n");mjsTemplateSidebar.append("            items: [\n");// 查找对应的文档文件boolean hasItems = false;for (UsersManualFile usersManualFile : list) {if (usersManualFile.getParentId().equals(configMenu.getId())) {if (!hasItems) {hasItems = true;}mjsTemplateSidebar.append("              {\n");mjsTemplateSidebar.append("                text: '").append(usersManualFile.getTableName()).append("',\n");mjsTemplateSidebar.append("                link: '").append(usersManualFile.getLink()).append("'\n");mjsTemplateSidebar.append("              },\n");}}if (hasItems) {mjsTemplateSidebar.setLength(mjsTemplateSidebar.length() - 2); // 去掉最后一个逗号mjsTemplateSidebar.append("\n            ]\n");} else {mjsTemplateSidebar.append("            ]\n");}mjsTemplateSidebar.append("          },\n");}}mjsTemplateSidebar.setLength(mjsTemplateSidebar.length() - 2); // 去掉最后一个逗号mjsTemplateSidebar.append("\n        ]\n");mjsTemplateSidebar.append("      },\n");}mjsTemplateSidebar.append("    },\n");mjsTemplateNav.append("      ]\n" +"    ,\n");//根据id获取项目名称ProjectInfo projectInfo = projectInfoMapper.selectById(id);String  projectName = "";if (projectInfo != null){projectName = projectInfo.getXiangmumingcheng();}//配置mjs文件内容// 固定模板头部String mjsTemplateHeder = "import {defineConfig} from 'vitepress'\n" +"import hljs from 'highlight.js/lib/core'\n" +"import javascript from 'highlight.js/lib/languages/javascript'\n" +"import xml from 'highlight.js/lib/languages/xml'\n" +"import {ref} from \"./cache/deps/vue.js\";\n" +"// 注册语言\n" +"hljs.registerLanguage('javascript', javascript)\n" +"hljs.registerLanguage('html', xml)\n" +"\n" +"export default defineConfig(async () => {\n" +"  return {\n" +"    markdown: {\n" +"      theme: 'material-theme-palenight',\n" +"      lineNumbers: true,\n" +"      math: true,\n" +"      container: {\n" +"        tipLabel: '提示',\n" +"        warningLabel: '警告',\n" +"        dangerLabel: '危险',\n" +"        infoLabel: \"信息\",\n" +"        detailsLabel: \"详情\"\n" +"      },\n" +"\n" +"    },\n" +"    enhanceApp: {\n" +"      setup: (ctx) => {\n" +"        ctx.app.component('AdBanner', AdBanner)\n" +"      }\n" +"    },\n" +"\n" +//动态修改项目名称"    title: \""+projectName+"帮助文档\",\n" +"    description: \"系统使用说明\",\n" +"    themeConfig: {\n" +"      outline: {\n" +"        level: [2, 3],\n" +"        label: '页面导航'\n" +"      },\n" +"      siteTitle: \"帮助文档\",\n" +"      logo: \"../pubilc/assets/logo.png\",\n";//固定模板尾部String mjsTemplateTail ="      footer: {\n" +"        message: \""+projectName+"帮助文档\",\n" +"        copyright: '2025.5.20   @langtao'\n" +"      },\n" +"      styl: {\n" +"\n" +"      }\n" +"\n" +"    }\n" +"  }\n" +"})";// 写入动态生成的 .mjs 文件String mjsContent = mjsTemplateHeder+mjsTemplateNav+mjsTemplateSidebar+mjsTemplateTail;String fileName = "config" + ".mjs";String filePath = fullDirPath + File.separator + fileName;// 写入文件try (FileWriter writer = new FileWriter(filePath)) {writer.write(mjsContent);}}if (list == null || list.size() == 0) {
//            return ResultData.error(ResultData.PARAM_ERROR_CODE, "无数据");}// 存储生成的md文件的相对路径List<String> mdFilePaths = new ArrayList<>();for (UsersManualFile usersManualFile : list) {// 使用文件ID作为文件名前缀,避免文件名重复String fileNamePrefix = usersManualFile.getId().toString().substring(usersManualFile.getId().toString().length() - 8);String fileName = fileNamePrefix + "-" + usersManualFile.getTableName() + ".md";String filePath = fullDirPath + File.separator + fileName;// 写入MD内容try (FileWriter writer = new FileWriter(filePath)) {writer.write(usersManualFile.getMarkdownData());}// 添加相对路径到结果列表mdFilePaths.add("md_files/" + dateSubDir  + fileName);}// 在生成MD文件和MJS文件后,将文件夹压缩成ZIPString zipPath = fullDirPath + ".zip";FileOutputStream fos = new FileOutputStream(zipPath);ZipOutputStream zos = new ZipOutputStream(fos);// 添加文件夹到ZIPaddFolderToZip(fullDirPath, fullDirPath, zos);// 关闭流zos.close();fos.close();// 设置响应头,以便前端下载response.setHeader("Content-Disposition", "attachment; filename=" + dateSubDir + ".zip");response.setHeader("Content-Type", "application/octet-stream");// 将ZIP文件发送给前端FileInputStream fis = new FileInputStream(zipPath);IOUtils.copy(fis, response.getOutputStream());response.getOutputStream().flush();fis.close();// 删除临时文件
//        deleteDir(new File(fullDirPath));
//        new File(zipPath).delete();//        return ResultData.success("ok", response);}/*** 将文件夹添加到ZIP压缩包中*/private void addFolderToZip(String srcFolder, String baseFolder, ZipOutputStream zos) throws IOException {File folder = new File(srcFolder);for (File file : folder.listFiles()) {if (file.isFile()) {FileInputStream fis = new FileInputStream(file);String entryName = file.getAbsolutePath().substring(baseFolder.length() + 1);ZipEntry entry = new ZipEntry(entryName);zos.putNextEntry(entry);IOUtils.copy(fis, zos);zos.closeEntry();fis.close();} else if (file.isDirectory()) {addFolderToZip(file.getAbsolutePath(), baseFolder, zos);}}}/*** 删除文件夹及其内容*/private void deleteDir(File dir) {if (dir.isDirectory()) {for (File child : dir.listFiles()) {deleteDir(child);}}dir.delete();}

相关文章:

  • Docker部署Zookeeper集群
  • 技术服务业-首套运营商网络路由5G SA测试专网搭建完成并对外提供服务
  • 分布式缓存:缓存的三种读写模式及分类
  • Flume的大概简单介绍
  • AGV(自动导引车)通信协议及通信链路性能需求分析
  • 移远三款主流5G模块RM500U,RM520N,RG200U比较
  • RK3588 Opencv-ffmpeg-rkmpp-rkrga编译与测试
  • EasyRTC音视频实时通话WebP2P技术赋能的全场景实时通信解决方案
  • 力扣-最大连续一的个数
  • 力扣-将x减到0的最小操作数
  • 【时时三省】(C语言基础)对被调用函数的声明和函数原型
  • [特殊字符] GUNION SDK 接口调用方式说明(静态库 vs 动态库)
  • C/C++的OpenCV 进行图像梯度提取
  • 并发容器(Collections)
  • bi软件是什么?bi软件是做什么用的?
  • 量化研究---bigquant策略交易api研究
  • 30个性能优化方案
  • Python在自动驾驶中的多传感器融合——让智能汽车“看得更清楚”
  • Ubantu安装 Jenkins LTS
  • VR全景制作方法都有哪些?需要注意什么?
  • 描述网站开发的过程/磁力搜索器 磁力猫
  • 网站短信验证怎么做/网站seo外包靠谱吗
  • 焊接加工订单网/百度seo优
  • 申请公司注册需要多少钱/沈阳百度推广优化
  • 单位网站建设收费标准/市场推广方案
  • wordpress编辑分类/沈阳seo关键字优化