Browse Source

自动脚本

zxm
hanyuqing 8 months ago
parent
commit
f2d5d9450e
  1. 23
      gyxtp/src/api/api/doc.js
  2. 657
      gyxtp/src/view/create.vue
  3. 285
      gyxtp/src/view/docInfo.vue
  4. 169
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ZhyFileManageController.java
  5. 177
      ruoyi-api/src/main/java/com/ruoyi/api/WebSocketServerHandler.java
  6. 19
      ruoyi-api/src/main/java/com/ruoyi/api/WebSocketService.java
  7. 8
      ruoyi-api/src/main/java/com/ruoyi/api/Websocket.java
  8. 25
      ruoyi-api/src/main/java/com/ruoyi/api/WebsocketServerConfig.java
  9. 523
      ruoyi-api/src/main/java/com/ruoyi/api/controller/DocApiController.java
  10. 16
      ruoyi-api/src/main/java/com/ruoyi/api/controller/TestXiaoTuPuController.java
  11. 4
      ruoyi-api/src/main/java/com/ruoyi/api/service/impl/GraphServiceImpl.java
  12. 3
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/Test1Mapper.java
  13. 2
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WordSplitter.java
  14. 15
      ruoyi-system/src/main/resources/mapper/system/Test1Mapper.xml
  15. 116
      ruoyi-ui/src/views/system/fileManage/index.vue

23
gyxtp/src/api/api/doc.js

@ -81,9 +81,28 @@ export const getTitle = () => {
}
});
};
export const build = (params) => {
export const getTitleByGroup = () => {
return request({
url: '/api/doc/build',
url: '/api/doc/getTitleByGroup',
method: 'get',
headers:{
'token':localStorage.getItem('token')
}
});
};
export const buildOne = (params) => {
return request({
url: '/api/doc/buildOne',
method: 'post',
data: params,
headers:{
'token':localStorage.getItem('token')
}
});
};
export const buildTwo = (params) => {
return request({
url: '/api/doc/buildTwo',
method: 'post',
data: params,
headers:{

657
gyxtp/src/view/create.vue

@ -11,156 +11,297 @@
style="position: absolute;height: 3vw;width: 3vw;font-size: 2vw;border-radius: 0 50% 50% 0;z-index: 1000;bottom:49%;left:0vw;">
<img src="../assets/img2/open2.png" style="width: 60%;object-fit: contain;margin-top: 1.8vw;">
</div>
<div class="rightInfo">
<div class="">
<!-- <div class="m-4">-->
<!-- <el-cascader v-model="value" :options="options" @change="handleChange" />-->
<!-- </div>-->
<!-- <el-tree-->
<!-- style="max-width: 600px"-->
<!-- :data="treeDataWithRoot"-->
<!-- :props="defaultProps"-->
<!-- accordion-->
<!-- @node-click="handleNodeClick"-->
<!-- />-->
<div class="searchInfo">
<!-- <treeselect v-model="nodeTreeData" :multiple="true" :options="options" placeholder="请选择相关的知识点"-->
<!-- style="width: 15%;">-->
<!-- </treeselect>-->
<div>
<div>
<!-- <span>战略方向</span>-->
<el-select class="mainSelect" v-model="value1" clearable filterable placeholder="请选择战略方向">
<el-option
v-for="item in level1"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div>
<!-- <span>作战行动</span>-->
<el-select class="mainSelect" v-model="value2" clearable filterable placeholder="请选择作战行动">
<el-option
v-for="item in level2"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div>
<!-- <span>武器平台</span>-->
<el-select class="mainSelect" v-model="value3" clearable filterable placeholder="请选择武器平台">
<el-option
v-for="item in level3"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div>
<!-- <span>模型方法</span>-->
<el-select class="mainSelect" v-model="value4" clearable filterable placeholder="请选择模型方法">
<el-option
v-for="item in level4"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div>
<!-- <span>指标</span>-->
<el-select class="mainSelect" v-model="value5" clearable filterable placeholder="请选择指标">
<el-option
v-for="item in level5"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div>
<!-- <span>环境要素</span>-->
<el-select class="mainSelect" v-model="value6" clearable filterable placeholder="请选择环境要素">
<el-option
v-for="item in level6"
:key="item.id"
:label="item.docTitle"
:value="item.id">
</el-option>
</el-select>
</div>
<div class="rightInfo">
<div class="">
<div class="searchInfo">
<div>
<el-cascader
v-model="selected1"
:options="cascadeOptions1"
:props="cascaderProps"
@change="handleChange1"
placeholder="请选择方向类"
style="width: 100%; max-width: 300px;"
/>
</div>
<div>
<div style="width: 600px;margin-bottom: 20px;display: flex;align-items: center; "
v-for="(item, index) in searchItems1">
<div class="input"
:key="index"
:id="'item-' + index">
<!-- 标签 -->
<el-tag
style="margin-right: 10px"
v-for="tag in item.tags"
:key="tag"
closable
@close="removeTag(0,index, tag)"
>
{{ tag }}
</el-tag>
<!-- 输入框 -->
<input
v-model="item.inputValue"
placeholder="请输入要检索的关键字"
class="input-new-tag"
@keyup.enter="addTag(0,index)"
ref="saveTagInput"
/>
</div>
<el-button @click="addItem(0)">添加</el-button>
<el-button v-if="index!=0" @click="removeItem(0,index)">删除</el-button>
</div>
</div>
</div>
<div>
<div style="width: 600px;margin-bottom: 20px;display: flex;align-items: center; "
v-for="(item, index) in searchItems">
<div class="input"
:key="index"
:id="'item-' + index">
<!-- 标签 -->
<el-tag
style="margin-right: 10px"
v-for="tag in item.tags"
:key="tag"
closable
@close="removeTag(index, tag)"
>
{{ tag }}
</el-tag>
<!-- 输入框 -->
<input
v-model="item.inputValue"
placeholder="请输入要检索的关键字"
class="input-new-tag"
@keyup.enter="addTag(index)"
ref="saveTagInput"
/>
<div class="searchInfo">
<div>
<el-cascader
v-model="selected2"
:options="cascadeOptions2"
:props="cascaderProps"
@change="handleChange2"
placeholder="请选择业务系统类"
style="width: 100%; max-width: 300px;"
/>
</div>
<div>
<div style="width: 600px;margin-bottom: 20px;display: flex;align-items: center; "
v-for="(item, index) in searchItems2">
<div class="input"
:key="index"
:id="'item-' + index">
<!-- 标签 -->
<el-tag
style="margin-right: 10px"
v-for="tag in item.tags"
:key="tag"
closable
@close="removeTag(1,index, tag)"
>
{{ tag }}
</el-tag>
<!-- 输入框 -->
<input
v-model="item.inputValue"
placeholder="请输入要检索的关键字"
class="input-new-tag"
@keyup.enter="addTag(1,index)"
ref="saveTagInput"
/>
</div>
<el-button @click="addItem(1)">添加</el-button>
<el-button v-if="index!=0" @click="removeItem(1,index)">删除</el-button>
</div>
</div>
</div>
<el-button @click="addItem">添加</el-button>
<el-button v-if="index!=0" @click="remove">删除</el-button>
</div>
<div class="searchInfo">
<div>
<el-cascader
v-model="selected3"
:options="cascadeOptions3"
:props="cascaderProps"
@change="handleChange3"
placeholder="请选择模型方法类"
style="width: 100%; max-width: 300px;"
/>
</div>
<div>
<div style="width: 600px;margin-bottom: 20px;display: flex;align-items: center; "
v-for="(item, index) in searchItems3">
<div class="input"
:key="index"
:id="'item-' + index">
<!-- 标签 -->
<el-tag
style="margin-right: 10px"
v-for="tag in item.tags"
:key="tag"
closable
@close="removeTag(2,index, tag)"
>
{{ tag }}
</el-tag>
<!-- <button @click="addItem">添加</button>-->
<!-- <el-input-tag v-model="dynamicTags" clearable placeholder="Please input" />-->
<el-button @click="build" style="margin-left: 200px">构建</el-button>
<!-- <img-->
<!-- src="../assets/img2/photo.png" @click="openPhoto"-->
<!-- style="position: absolute;right: 29%;top: 53.5%;height: 28%;object-fit: contain;cursor: pointer;"-->
<!-- alt=""-->
<!-- />-->
<!-- <div class="searchQuan" @click="goSearch" v-if="type=='word'" style="cursor: pointer;">-->
<!-- <img-->
<!-- src="../assets/img2/search.png"-->
<!-- style="height: 100%;object-fit: contain;"-->
<!-- alt=""-->
<!-- />-->
<!-- </div>-->
<!-- <div class="searchQuan" @click="goSearchPhoto" v-if="type=='photo'">-->
<!-- <img-->
<!-- src="../assets/img2/search.png"-->
<!-- style="height: 100%;object-fit: contain;"-->
<!-- alt=""-->
<!-- />-->
<!-- </div>-->
<!-- 输入框 -->
<input
v-model="item.inputValue"
placeholder="请输入要检索的关键字"
class="input-new-tag"
@keyup.enter="addTag(2,index)"
ref="saveTagInput"
/>
</div>
<el-button @click="addItem(2)">添加</el-button>
<el-button v-if="index!=0" @click="removeItem(2,index)">删除</el-button>
</div>
</div>
</div>
<el-button @click="build" style="margin-left: 200px">构建</el-button>
</div>
</div>
</div>
</div>
<!-- <div class="rightInfo">-->
<!-- <div class="">-->
<!--&lt;!&ndash; <div class="m-4">&ndash;&gt;-->
<!--&lt;!&ndash; <el-cascader v-model="value" :options="options" @change="handleChange" />&ndash;&gt;-->
<!--&lt;!&ndash; </div>&ndash;&gt;-->
<!--&lt;!&ndash; <el-tree&ndash;&gt;-->
<!--&lt;!&ndash; style="max-width: 600px"&ndash;&gt;-->
<!--&lt;!&ndash; :data="treeDataWithRoot"&ndash;&gt;-->
<!--&lt;!&ndash; :props="defaultProps"&ndash;&gt;-->
<!--&lt;!&ndash; accordion&ndash;&gt;-->
<!--&lt;!&ndash; @node-click="handleNodeClick"&ndash;&gt;-->
<!--&lt;!&ndash; />&ndash;&gt;-->
<!-- <div class="searchInfo">-->
<!--&lt;!&ndash; <treeselect v-model="nodeTreeData" :multiple="true" :options="options" placeholder="请选择相关的知识点"&ndash;&gt;-->
<!--&lt;!&ndash; style="width: 15%;">&ndash;&gt;-->
<!--&lt;!&ndash; </treeselect>&ndash;&gt;-->
<!-- <div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>战略方向</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value1" clearable filterable placeholder="请选择一级节点">-->
<!-- <el-option-->
<!-- v-for="item in level1"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>作战行动</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value2" clearable filterable placeholder="请选择二级节点">-->
<!-- <el-option-->
<!-- v-for="item in level2"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>武器平台</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value3" clearable filterable placeholder="请选择三级节点">-->
<!-- <el-option-->
<!-- v-for="item in level3"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>模型方法</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value4" clearable filterable placeholder="请选择四级节点">-->
<!-- <el-option-->
<!-- v-for="item in level4"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>指标</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value5" clearable filterable placeholder="请选择五级节点">-->
<!-- <el-option-->
<!-- v-for="item in level5"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div>-->
<!--&lt;!&ndash; <span>环境要素</span>&ndash;&gt;-->
<!-- <el-select class="mainSelect" v-model="value6" clearable filterable placeholder="请选择六级节点">-->
<!-- <el-option-->
<!-- v-for="item in level6"-->
<!-- :key="item.id"-->
<!-- :label="item.docTitle"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div>-->
<!-- <div style="width: 600px;margin-bottom: 20px;display: flex;align-items: center; "-->
<!-- v-for="(item, index) in searchItems">-->
<!-- <div class="input"-->
<!-- :key="index"-->
<!-- :id="'item-' + index">-->
<!-- &lt;!&ndash; 标签 &ndash;&gt;-->
<!-- <el-tag-->
<!-- style="margin-right: 10px"-->
<!-- v-for="tag in item.tags"-->
<!-- :key="tag"-->
<!-- closable-->
<!-- @close="removeTag(index, tag)"-->
<!-- >-->
<!-- {{ tag }}-->
<!-- </el-tag>-->
<!-- &lt;!&ndash; 输入框 &ndash;&gt;-->
<!-- <input-->
<!-- v-model="item.inputValue"-->
<!-- placeholder="请输入要检索的关键字"-->
<!-- class="input-new-tag"-->
<!-- @keyup.enter="addTag(index)"-->
<!-- ref="saveTagInput"-->
<!-- />-->
<!-- </div>-->
<!-- <el-button @click="addItem">添加</el-button>-->
<!-- <el-button v-if="index!=0" @click="remove">删除</el-button>-->
<!-- </div>-->
<!--&lt;!&ndash; <button @click="addItem">添加</button>&ndash;&gt;-->
<!--&lt;!&ndash; <el-input-tag v-model="dynamicTags" clearable placeholder="Please input" />&ndash;&gt;-->
<!-- <el-button @click="build" style="margin-left: 200px">构建</el-button>-->
<!--&lt;!&ndash; <img&ndash;&gt;-->
<!--&lt;!&ndash; src="../assets/img2/photo.png" @click="openPhoto"&ndash;&gt;-->
<!--&lt;!&ndash; style="position: absolute;right: 29%;top: 53.5%;height: 28%;object-fit: contain;cursor: pointer;"&ndash;&gt;-->
<!--&lt;!&ndash; alt=""&ndash;&gt;-->
<!--&lt;!&ndash; />&ndash;&gt;-->
<!--&lt;!&ndash; <div class="searchQuan" @click="goSearch" v-if="type=='word'" style="cursor: pointer;">&ndash;&gt;-->
<!--&lt;!&ndash; <img&ndash;&gt;-->
<!--&lt;!&ndash; src="../assets/img2/search.png"&ndash;&gt;-->
<!--&lt;!&ndash; style="height: 100%;object-fit: contain;"&ndash;&gt;-->
<!--&lt;!&ndash; alt=""&ndash;&gt;-->
<!--&lt;!&ndash; />&ndash;&gt;-->
<!--&lt;!&ndash; </div>&ndash;&gt;-->
<!--&lt;!&ndash; <div class="searchQuan" @click="goSearchPhoto" v-if="type=='photo'">&ndash;&gt;-->
<!--&lt;!&ndash; <img&ndash;&gt;-->
<!--&lt;!&ndash; src="../assets/img2/search.png"&ndash;&gt;-->
<!--&lt;!&ndash; style="height: 100%;object-fit: contain;"&ndash;&gt;-->
<!--&lt;!&ndash; alt=""&ndash;&gt;-->
<!--&lt;!&ndash; />&ndash;&gt;-->
<!--&lt;!&ndash; </div>&ndash;&gt;-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
</template>
<script>
import HeaderInfo from '../components/UseAll/headerInfo'
import leftInfo from "../components/UseAll/leftInfo";
import {build, getAllHistory, getAllHistory1, getTitle} from "../api/api/doc";
import {build, buildTwo, getAllHistory, getAllHistory1, getAllTitle, getTitle, getTitleByGroup} from "../api/api/doc";
import Treeselect from 'vue3-treeselect'
import {Button} from "view-ui-plus";
import {Plus} from '@element-plus/icons-vue'
@ -209,39 +350,196 @@ export default {
value4:"",
value5:"",
value6:"",
searchItems:[{
searchItems3:[{
tags: [],
inputValue: ''
}],
searchItems1:[{
tags: [],
inputValue: ''
}],
searchItems2:[{
tags: [],
inputValue: ''
}]
}],
selected1: [],
selectedIds1:[],
cascadeOptions1: [],
selected2: [],
selectedIds2:[],
cascadeOptions2: [],
selected3: [],
cascadeOptions3: [],
selectedIds3:[],
//
cascaderProps: {
multiple: true,
value: 'id', // `id` value
label: 'docTitle', // `docTitle` label
children: 'children', // `children` children
disabled: 'disabled' //
},
};
},
methods: {
handleChange1(value) {
console.log(this.selected1)
console.log('完整选中路径:', value)
// const selectedId = value.length > 0 ? value[value.length - 1] : null
// this.loadDocContent(selectedId)
this.selectedIds1 = value.map(path => path[path.length - 1])
console.log('选中的 children 的 id:', this.selectedIds1)
},
handleChange2(value) {
console.log('完整选中路径:', value)
// const selectedId = value.length > 0 ? value[value.length - 1] : null
// this.loadDocContent(selectedId)
this.selectedIds2 = value.map(path => path[path.length - 1])
console.log('选中的 children 的 id:', this.selectedIds2)
},
handleChange3(value) {
console.log('完整选中路径:', value)
// const selectedId = value.length > 0 ? value[value.length - 1] : null
// this.loadDocContent(selectedId)
this.selectedIds3 = value.map(path => path[path.length - 1])
console.log('选中的 children 的 id:', this.selectedIds3)
},
getTitleByGroup(){
getTitleByGroup().then(res=>{
console.log(res)
this.cascadeOptions1 = [
{
id: res.g01.id,
docTitle: res.g01.name,
children: res.g01.children
},
{
id: res.g02.id,
docTitle: res.g02.name,
children: res.g02.children
},
{
id: res.g03.id,
docTitle: res.g03.name,
children: res.g03.children
},
{
id: res.g04.id,
docTitle: res.g04.name,
children: res.g04.children
},
]
this.cascadeOptions2 = [
{
id: res.g11.id,
docTitle: res.g11.name,
children: res.g11.children
},
{
id: res.g12.id,
docTitle: res.g12.name,
children: res.g12.children
},
{
id: res.g13.id,
docTitle: res.g13.name,
children: res.g13.children
},
{
id: res.g14.id,
docTitle: res.g14.name,
children: res.g14.children
},
]
this.cascadeOptions3 = [
{
id: res.g21.id,
docTitle: res.g21.name,
children: res.g21.children
},
{
id: res.g22.id,
docTitle: res.g22.name,
children: res.g22.children
},
]
});
},
// build(){
// let data={
// l1:this.value1,
// l2:this.value2,
// l3:this.value3,
// l4:this.value4,
// l5:this.value5,
// l6:this.value6,
// searchItems:this.searchItems
// }
// build(data).then(res=>{
//
// })
// },
build(){
let data={
l1:this.value1,
l2:this.value2,
l3:this.value3,
l4:this.value4,
l5:this.value5,
l6:this.value6,
searchItems:this.searchItems
group0:{
selected:this.selected1,
searchItems:this.searchItems1
},
group1:{
selected:this.selected2,
searchItems:this.searchItems2
},
group2:{
selected:this.selected3,
searchItems:this.searchItems3
},
}
build(data).then(res=>{
buildTwo(data).then(res=>{
})
},
//
addItem() {
this.searchItems.push({
tags: [], //
inputValue: '' //
})
},
addItem(group) {
if(group==0){
this.searchItems1.push({
tags: [], //
inputValue: '' //
})
}else if(group==1){
this.searchItems2.push({
tags: [], //
inputValue: '' //
})
}else if(group==2){
this.searchItems3.push({
tags: [], //
inputValue: '' //
})
}
},
removeItem(group, index) {
if (group === 0) {
this.searchItems1.splice(index, 1);
} else if (group === 1) {
this.searchItems2.splice(index, 1);
} else if (group === 2) {
this.searchItems3.splice(index, 1);
}
},
//
addTag(index) {
const item = this.searchItems[index]
addTag(group,index) {
let item = this.searchItems1[index]
if(group==0){
item = this.searchItems1[index]
}else if(group==1){
item = this.searchItems2[index]
}else if(group==2){
item = this.searchItems3[index]
}
if (item.inputValue && !item.tags.includes(item.inputValue)) {
item.tags.push(item.inputValue)
item.inputValue = ''
@ -249,8 +547,15 @@ export default {
},
//
removeTag(moduleIndex, tag) {
const item = this.searchItems[moduleIndex]
removeTag(group,moduleIndex, tag) {
let item = this.searchItems1[moduleIndex]
if(group==0){
item = this.searchItems1[moduleIndex]
}else if(group==1){
item = this.searchItems2[moduleIndex]
}else if(group==2){
item = this.searchItems3[moduleIndex]
}
item.tags.splice(item.tags.indexOf(tag), 1)
},
getAll(){
@ -353,6 +658,23 @@ export default {
mounted() {
this.getInfoInit();
this.getAll();
this.getTitleByGroup()
// WebSocket
this.socket = new WebSocket('ws://localhost:10031/api/ws?userId=123'); //
//
this.socket.addEventListener('open', (event) => {
console.log('WebSocket 连接已建立');
this.messages.push('已连接到服务端');
});
//
this.socket.addEventListener('message', (event) => {
console.log('收到消息:', event.data);
this.messages.push(event.data);
});
}
};
// import vHeader from "../components/Header";
@ -375,12 +697,12 @@ export default {
}
.input-new-tag {
padding: 8px 12px;
padding: 0px 12px;
border:none;
border-radius: 4px;
font-size: 14px;
outline: none;
height: 33px;
height: 30px;
margin-left: 0.5vw;
}
@ -417,28 +739,29 @@ export default {
}
.input {
width: 400px;
margin-left: 1vw;
height: 50px;
width: 350px;
margin-left: 3vw;
height: 30px;
border-radius: 2vw;
background-color: rgba(255, 255, 255, 0.65);
border: 2px solid #0776ff;
text-indent: 1vw;
font-size: 1.2vw;
margin-right: 15px;
}
.searchInfo {
margin-top: 14%;
margin-top: 8%;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.input::placeholder {
height: 50px;
line-height: 50px;
height: 30px;
line-height: 30px;
font-size: 1vw;
padding-left: 1vw;
color: #9e9e9e;

285
gyxtp/src/view/docInfo.vue

@ -59,10 +59,10 @@
<div class="huiBlock"></div>
<div class="huiTitle">关系图谱</div>
</div>
<div class="oneTitle" @click="chooseInfo=5">
<div class="huiBlock"></div>
<div class="huiTitle">学习资源</div>
</div>
<!-- <div class="oneTitle" @click="chooseInfo=5">-->
<!-- <div class="huiBlock"></div>-->
<!-- <div class="huiTitle">学习资源</div>-->
<!-- </div>-->
<div class="oneTitle" @click="chooseInfo=2">
<div class="huiBlock"></div>
<div class="huiTitle">图片视频</div>
@ -79,10 +79,10 @@
<div class="huiBlock"></div>
<div class="huiTitle">关系图谱</div>
</div>
<div class="oneTitle" @click="chooseInfo=5">
<div class="huiBlock"></div>
<div class="huiTitle">学习资源</div>
</div>
<!-- <div class="oneTitle" @click="chooseInfo=5">-->
<!-- <div class="huiBlock"></div>-->
<!-- <div class="huiTitle">学习资源</div>-->
<!-- </div>-->
<div class="oneTitle" style="background-color: #e4e4e4;">
<div class="chengBlock"></div>
<div class="chengTitle">图片视频</div>
@ -100,10 +100,10 @@
<div class="chengBlock"></div>
<div class="chengTitle">关系图谱</div>
</div>
<div class="oneTitle" @click="chooseInfo=5">
<div class="huiBlock"></div>
<div class="huiTitle">学习资源</div>
</div>
<!-- <div class="oneTitle" @click="chooseInfo=5">-->
<!-- <div class="huiBlock"></div>-->
<!-- <div class="huiTitle">学习资源</div>-->
<!-- </div>-->
<div class="oneTitle" @click="chooseInfo=2">
<div class="huiBlock"></div>
<div class="huiTitle">图片视频</div>
@ -121,10 +121,10 @@
<div class="huiBlock"></div>
<div class="huiTitle">关系图谱</div>
</div>
<div class="oneTitle" style="background-color: #e4e4e4;">
<div class="chengBlock"></div>
<div class="chengTitle">学习资源</div>
</div>
<!-- <div class="oneTitle" style="background-color: #e4e4e4;">-->
<!-- <div class="chengBlock"></div>-->
<!-- <div class="chengTitle">学习资源</div>-->
<!-- </div>-->
<div class="oneTitle" @click="chooseInfo=2">
<div class="huiBlock"></div>
<div class="huiTitle">图片视频</div>
@ -187,17 +187,17 @@
<div class="yuanwen" v-html="contentInfo.content"></div>
</div>
<div class="videoInfo" v-if="chooseInfo==2 && haveImg==true">
<div class="videoInfoList">
<div class="shipin">
<div class="sInfo">
<div class="scontent">视频:</div>
</div>
</div>
<div class="videoBox" v-for="(video, index) in videoUrls" :key="index">
<Video1 style="width: 100%; height: 100%; border-radius: 2vw;object-fit: cover; " :src="video"
:second="3"/>
</div>
</div>
<!-- <div class="videoInfoList">-->
<!-- <div class="shipin">-->
<!-- <div class="sInfo">-->
<!-- <div class="scontent">视频:</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="videoBox" v-for="(video, index) in videoUrls" :key="index">-->
<!-- <Video1 style="width: 100%; height: 100%; border-radius: 2vw;object-fit: cover; " :src="video"-->
<!-- :second="3"/>-->
<!-- </div>-->
<!-- </div>-->
<div class="imgInfoList">
<div class="shipin">
<div class="sInfo">
@ -216,7 +216,7 @@
<div class="videoInfo" v-if="chooseInfo==2 && haveImg==false">
<div
style="font-size: 2vw;width: 20vw;height: 8vw;text-align: center;line-height: 8vw;margin: 0 auto;margin-top: 10vw;">
暂无图片视频资源
暂无图片资源
</div>
</div>
@ -230,8 +230,9 @@
:on-node-click="onNodeClick"
:on-line-click="onLineClick"
>
<!-- @mouseenter="showNodeTips(node)" @mouseout="overMouse"-->
<template #node="{node}">
<div class="my-node-1" @mouseenter="showNodeTips(node)" @mouseout="overMouse">
<div class="my-node-1" >
<div v-if="node.data.label==0"
style="line-height: 70px;font-size: 60px;margin-top: 10px;">
{{ node.text }}
@ -545,15 +546,22 @@ export default {
setTimeout(() => {
this.g_loading = false;
const graphInstance = this.$refs.graphRef.getInstance();
this.stopForceIfNeed();
graphInstance.setJsonData(data);
if (this.useBigData) {
graphInstance.setZoom(60);
} else {
graphInstance.setZoom(80);
const graphRef = this.$refs.graphRef;
if (!graphRef) {
console.warn('GraphComponent 未渲染,无法初始化');
return;
}
const graphInstance = graphRef.getInstance();
if(graphInstance!=null){
this.stopForceIfNeed();
graphInstance.setJsonData(data);
if (this.useBigData) {
graphInstance.setZoom(60);
} else {
graphInstance.setZoom(80);
}
}
}, 1000);
setTimeout(() => {
this.changeSelected();
@ -563,46 +571,27 @@ export default {
},
async stopForceIfNeed() {
const graphInstance = this.$refs.graphRef.getInstance();
const graphRef = this.$refs.graphRef;
if (!graphRef) {
console.warn('GraphComponent 未渲染,无法初始化');
return;
}
const graphInstance = graphRef.getInstance();
await graphInstance.stopAutoLayout();
},
overMouse() {
this.addInfo = true;
},
showNodeTips(nodeObject) {
if (this.addInfo) {
let params = {
id: this.$route.query.docId,
oldId: nodeObject.data.docId,
};
this.haveLine = 0;
for (let l = 0; l < this.linksNew.length; l++) {
if (this.linksNew[l].from == nodeObject.data.id) {
this.haveLine = 1;
break;
}
}
if (this.haveLine == 0) {
getInfoTestAdd(params).then((res) => {
if (res.data.node != null) {
this.g_loading = true;
this.zhengl1(res.data);
this.addInfo = false;
} else {
this.g_loading = false;
}
})
}
}
},
async changeSelected() {
var docId = this.$route.query.docId;
for (let b = 0; b < this.nodesNew.length; b++) {
if (this.nodesNew[b].docId == docId) {
const graphInstance = this.$refs.graphRef.getInstance();
const graphRef = this.$refs.graphRef;
if (!graphRef) {
console.warn('GraphComponent 未渲染,无法初始化');
return;
}
const graphInstance = graphRef.getInstance();
await graphInstance.focusNodeById(this.nodesNew[b].id);
graphInstance.setZoom(60);
}
@ -633,10 +622,10 @@ export default {
let docId = {
docId: res.data.id
}
getDifficult(docId).then((res) => {
this.difficultValue = res.data.difficult + ''
this.docUrl = res.data.docUrl
})
// getDifficult(docId).then((res) => {
// this.difficultValue = res.data.difficult + ''
// this.docUrl = res.data.docUrl
// })
this.title = res.data.docTitle;
this.level = res.data.docLevel;
//
@ -690,10 +679,10 @@ export default {
let docId = {
docId: res.data.id
}
getDifficult(docId).then((res) => {
this.difficultValue = res.data.difficult + ''
this.docUrl = res.data.docUrl
})
// getDifficult(docId).then((res) => {
// this.difficultValue = res.data.difficult + ''
// this.docUrl = res.data.docUrl
// })
this.title = res.data.docTitle;
this.level = res.data.docLevel;
//
@ -1044,146 +1033,10 @@ export default {
})
}
this.showGraph();
},
zhengl1(data) {
var nodeList = data.node;
var lineList = data.links;
for (let a = 0; a < nodeList.length; a++) {
if (nodeList[a].docLeve == "leve0") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
data: {
docId: nodeList[a].docId,
label: 0,
},
width: 300,
height: 300,
color: 'rgba(227,203,0,0.73)',
fontColor: '#000000',
className: 'testNode'
})
}
if (nodeList[a].docLeve == "leve1") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 1,
},
docId: nodeList[a].docId,
width: 260,
height: 260,
color: '#2f2fe6'
})
}
if (nodeList[a].docLeve == "leve2") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 2,
},
docId: nodeList[a].docId,
width: 230,
height: 230,
color: '#ff8a00'
})
}
if (nodeList[a].docLeve == "leve3") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 3,
},
docId: nodeList[a].docId,
width: 200,
height: 200,
color: 'rgba(30,255,0,0.73)'
})
}
if (nodeList[a].docLeve == "leve4") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 4,
},
docId: nodeList[a].docId,
width: 170,
height: 170,
color: 'rgba(248,143,248,0.84)'
})
}
if (nodeList[a].docLeve == "leve5") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 5,
},
docId: nodeList[a].docId,
width: 140,
height: 140,
color: '#419aff'
})
}
if (nodeList[a].docLeve == "leve6") {
this.nodesNew.push({
id: nodeList[a].uuid,
text: nodeList[a].docTitle,
fontColor: '#000000',
data: {
docId: nodeList[a].docId,
label: 6,
},
docId: nodeList[a].docId,
width: 110,
height: 100,
color: '#00e4ff'
})
}
}
for (let b = 0; b < lineList.length; b++) {
this.haveLine = 0;
for (let g = 0; g < this.linksNew.length; g++) {
if (this.linksNew[g].uuid == lineList[b].uuid) {
this.haveLine = 1;
break;
}
}
if (this.haveLine == 0) {
this.linksNew.push({
from: lineList[b].sourceid,
to: lineList[b].targetid,
text: lineList[b].name,
uuid: lineList[b].uuid,
color: '#000000',
lineWidth: 2
})
}
this.$nextTick(() => {
this.showGraph(); // DOM
});
}
this.showGraph();
},
goOtherInfo(data) {
@ -1987,7 +1840,7 @@ margin-top: 0.2vw;
.oneImg {
flex: 0 0 calc((80% - 10px) / 3);
height: 12vw;
height: 30vw;
/* 间隙为5px */
margin: 1vw 5px 5px 0;
}

169
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/ZhyFileManageController.java

@ -147,13 +147,10 @@ public class ZhyFileManageController extends BaseController {
}
@PostMapping("/insertRelationByFile")
public AjaxResult insertRelationByFile(MultipartFile file) throws IOException {
// 1. 校验文件是否为空
if (file.isEmpty()) {
return AjaxResult.error("上传的文件为空");
}
// 2. 校验是否为 CSV 文件
String fileName = file.getOriginalFilename();
if (fileName == null || !fileName.toLowerCase().endsWith(".csv")) {
@ -313,75 +310,27 @@ public class ZhyFileManageController extends BaseController {
"云边端协同调度系统",
"知识模型管理系统"
};
// o[p[[[[=
String[] strs22 = {
"多源观测数据融合模型库",
"多源数据融合模型库",
"传感器误差校正模型库",
"数据插值与同化模型库",
"时空对齐与配准模型库",
"数据质量控制模型库",
"中尺度气象数值模式库",
"海洋环流数值模式库",
"海浪数值模式库",
"耦合气象海洋模式库",
"集合预报与不确定性分析模型库",
"短临快速更新模式库",
"三维地理信息渲染模型库",
"动态环境场可视化模型库",
"多层态势叠加模型库",
"虚拟现实与增强现实交互模型库",
"环境态势演化预测模型库",
"舰艇航行安全风险模型库",
"飞行器飞行安全风险模型库",
"雷达探测效能衰减模型库",
"声呐探测效能模型库",
"导弹打击精度环境修正模型库",
"水面舰艇综合效能影响模型库",
"武器系统环境适应性评估模型库",
"两栖登陆作战风险评估模型库",
"空降空投环境风险模型库",
"海上编队机动风险模型库",
"潜艇隐蔽行动风险模型库",
"航空飞行颠簸积冰风险模型库",
"舰载机起降安全风险模型库",
"蛙人特种作战环境风险模型库",
"情报模板生成模型库",
"关键信息提取模型库",
"多级分发策略模型库",
"用户画像与需求匹配模型库",
"自动摘要与图件生成模型库",
"雷达回波环境干扰识别模型库",
"声呐信号噪声抑制模型库",
"光学图像云雾去除模型库",
"海杂波抑制模型库",
"多源传感器数据融合识别模型库",
"航线环境优化模型库",
"作战窗口评估模型库",
"兵力部署环境匹配模型库",
"任务可行性环境判据模型库",
"动态重规划环境响应模型库",
"小样本信息扩散模型库",
"贝叶斯推理推演模型库",
"马尔科夫决策过程模型库",
"演化博弈推演模型库",
"高维稀疏数据聚类模型库",
"模糊逻辑推理评估模型库",
"台风路径预测模型库",
"寒潮强度预警模型库",
"强对流识别模型库",
"海浪极值预警模型库",
"内波发生概率模型库",
"雷暴区识别与规避模型库",
"计算任务分解模型库",
"边缘节点负载均衡模型库",
"带宽自适应调度模型库",
"数据缓存与预取模型库",
"服务优先级分配模型库",
"模型元数据管理模型库",
"版本控制与更新模型库",
"模型性能评估模型库",
"模型服务接口注册模型库",
"知识图谱构建与推理模型库"
"气象海洋数值预报模型库",
"时空协同同化模型库",
"战场环境可视化模型库",
"装备环境适应性评估模型库",
"作战风险预测模型库",
"目标识别与干扰抑制模型库",
"智能任务规划支持模型库",
"小样本智能推演模型库",
"极端环境预警模型库",
"动态态势演化模型库",
"决策知识推理模型库",
"资源协同调度模型库",
"情报自动生成模型库",
"海洋动力过程模型库",
"环境影响修正模型库",
"风险智能评估模型库",
"模型全生命周期管理库",
"多模态交互渲染模型库"
};
String[] strs2 = { "快速机降作战",
"海上机动作战",
@ -417,7 +366,74 @@ public class ZhyFileManageController extends BaseController {
"深水炸弹", "航空炸弹", "多功能干扰火箭", "火控雷达", "伞降",
"舰载声呐", "机载声纳",
};
String[] strs33 = {
"三维建模规则库",
"元数据定义规则库",
"信息提取规则库",
"任务划分规则库",
"任务可行性评估规则库",
"任务分配规则库",
"任务调整规则库",
"信号传播模型规则库",
"初始条件设置规则库",
"内波生成机制规则库",
"历史数据分析规则库",
"实时渲染规则库",
"实时数据获取规则库",
"动态数据处理规则库",
"关系抽取规则库",
"多源数据匹配规则库",
"快速同化算法规则库",
"情景模拟规则库",
"样本特征提取规则库",
"水文条件评估规则库",
"海洋动力学方程规则库",
"波浪传播规则库",
"波浪生成机制规则库",
"物理过程参数化规则库",
"用户交互规则库",
"环境变化监测规则库",
"环境因素分类规则库",
"环境适应性修正规则库",
"环境影响修正模型库",
"电磁环境影响修正规则库",
"目标识别规则库",
"气象模式接口规则库",
"模糊集定义规则库",
"模板设计规则库",
"海洋模式接口规则库",
"耦合机制规则库",
"图层管理规则库",
"图像增强规则库",
"声波传播模型规则库",
"噪声抑制算法规则库",
"噪声特征提取规则库",
"风险规避规则库",
"风险因子识别规则库",
"雷达回波环境干扰识别规则库",
"雷达探测效能衰减模型库",
"预测模型选择规则库",
"航行环境评估规则库",
"飞行环境评估规则库",
"避碰规则库",
"透明度控制规则库",
"适应性测试规则库",
"版本控制规则库",
"杂波特征提取规则库",
"杂波抑制算法规则库",
"战术应用规则库",
"数据一致性校验规则库",
"数据预处理规则库",
"数据同化方法规则库",
"数据清洗规则库",
"带宽分配规则库",
"强度评估规则库",
"强对流特征提取规则库",
"实体识别规则库"
};
String[] strs44 = {
"基础地理数据",
"气象观测数据",
"海洋环境数据",
@ -453,7 +469,7 @@ public class ZhyFileManageController extends BaseController {
"效用分析决策方法",
"模糊逻辑推理评估方法"
};
String[] strs44 = {
String[] strs55 = {
"地形数据",
"水文数据",
"重要的岛屿港口",
@ -593,6 +609,15 @@ public class ZhyFileManageController extends BaseController {
zhyDoc.setDocUrl( url +"\\wordSplitter" + "\\" + zhyDoc.getDocLevel()+zhyDoc.getDocTitle() + ".txt");
nodeList.add(zhyDoc);
}
for(int i=0;i<strs55.length;i++){
ZhyDoc zhyDoc=new ZhyDoc();
zhyDoc.setDocTitle(strs55[i]);
zhyDoc.setDocLevel(5l);
zhyDoc.setGroupId(1l);
zhyDoc.setFileId(zhyFileManage.getId());
zhyDoc.setDocUrl( url +"\\wordSplitter" + "\\" + zhyDoc.getDocLevel()+zhyDoc.getDocTitle() + ".txt");
nodeList.add(zhyDoc);
}
for(int i=0;i<strs111.length;i++){
ZhyDoc zhyDoc=new ZhyDoc();
zhyDoc.setDocTitle(strs111[i]);
@ -616,7 +641,7 @@ public class ZhyFileManageController extends BaseController {
List<ZhyDoc> list = test1Mapper.selectAllDoc();
for (int i = 0; i < list.size(); i++) {
list.get(i).setDocParentId(0l);
if(list.get(i).getDocLevel()==4l){
if(list.get(i).getDocLevel()==5l){
if(list.get(i).getDocTitle().equals("地形数据")
|list.get(i).getDocTitle().equals("水文数据")
|list.get(i).getDocTitle().equals("重要的岛屿港口")

177
ruoyi-api/src/main/java/com/ruoyi/api/WebSocketServerHandler.java

@ -0,0 +1,177 @@
// 文件路径:src/main/java/com/ruoyi/api/WebSocketServerHandler.java
package com.ruoyi.api;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* WebSocket 服务处理器
* 支持 userId 建立连接发送消息广播查询在线用户
*/
@Component
public class WebSocketServerHandler implements WebSocketHandler {
// 存储 userId -> WebSocketSession 映射(线程安全)
private static final Map<String, WebSocketSession> userSessionMap = new ConcurrentHashMap<>();
// 存储 session -> userId 映射(便于断开时清理)
private static final Map<String, String> sessionToUserMap = new ConcurrentHashMap<>();
/**
* 广播消息给所有在线用户
*/
public static void broadcastMessage(String message) {
Objects.requireNonNull(message, "消息内容不能为空");
userSessionMap.forEach((userId, session) -> {
if (session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
System.err.println("广播消息失败 - 用户: " + userId + ", 错误: " + e.getMessage());
// 清理失效连接
cleanupSession(session, userId);
}
}
});
}
/**
* 发送消息给指定用户
*/
public static void sendMessageToUser(String userId, String message) {
Objects.requireNonNull(userId, "userId 不能为空");
Objects.requireNonNull(message, "消息内容不能为空");
WebSocketSession session = userSessionMap.get(userId);
if (session != null && session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
System.err.println("发送消息失败 - 用户: " + userId + ", 错误: " + e.getMessage());
cleanupSession(session, userId);
}
} else {
System.out.println("⚠️ 用户未连接或已断开: userId=" + userId);
}
}
/**
* 获取当前在线用户数
*/
public static int getOnlineUserCount() {
return userSessionMap.size();
}
/**
* 获取所有在线用户 ID
*/
public static Set<String> getOnlineUserIds() {
return new HashSet<>(userSessionMap.keySet());
}
/**
* WebSocketSession 中提取 userId
*/
private String extractUserId(WebSocketSession session) {
URI uri = session.getUri();
if (uri == null) return null;
String query = uri.getQuery(); // 格式: userId=123&token=abc
if (query == null || query.isEmpty()) return null;
return Arrays.stream(query.split("&"))
.map(param -> param.split("=", 2))
.filter(arr -> arr.length == 2)
.filter(arr -> "userId".equals(arr[0]))
.map(arr -> arr[1])
.findFirst()
.orElse(null);
}
/**
* 清理失效的 session
*/
private static void cleanupSession(WebSocketSession session, String userId) {
userSessionMap.remove(userId);
sessionToUserMap.remove(session.getId());
try {
if (session.isOpen()) {
session.close();
}
} catch (IOException e) {
System.err.println("关闭 session 失败: " + e.getMessage());
}
}
// ========================================
// WebSocket 回调方法
// ========================================
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String userId = extractUserId(session);
if (userId == null || userId.trim().isEmpty()) {
System.err.println("❌ 连接拒绝 - 缺少 userId: " + session.getId());
session.close(CloseStatus.NOT_ACCEPTABLE.withReason("Missing userId"));
return;
}
// 防止重复连接(可选)
if (userSessionMap.containsKey(userId)) {
System.out.println("🔄 用户重新连接: userId=" + userId);
WebSocketSession oldSession = userSessionMap.get(userId);
if (oldSession.isOpen()) {
try {
oldSession.close();
} catch (IOException e) {
System.err.println("关闭旧连接失败: " + e.getMessage());
}
}
}
// 保存映射
userSessionMap.put(userId, session);
sessionToUserMap.put(session.getId(), userId);
// 记录日志
System.out.println("✅ 新用户连接: userId=" + userId + ", sessionId=" + session.getId());
// 可选:发送欢迎消息
session.sendMessage(new TextMessage("{\"type\":\"welcome\",\"msg\":\"欢迎, " + userId + "!\"}"));
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String userId = sessionToUserMap.get(session.getId());
System.out.println(message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
String userId = sessionToUserMap.get(session.getId());
System.err.println("❌ 传输错误 - 用户: " + userId + ", sessionId: " + session.getId() + ", 错误: " + exception.getMessage());
cleanupSession(session, userId);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
String userId = sessionToUserMap.get(session.getId());
if (userId != null) {
userSessionMap.remove(userId);
sessionToUserMap.remove(session.getId());
System.out.println("⏹️ 用户断开: userId=" + userId + ", 原因: " + closeStatus.getReason());
}
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}

19
ruoyi-api/src/main/java/com/ruoyi/api/WebSocketService.java

@ -0,0 +1,19 @@
// com.ruoyi.api.WebSocketService.java
package com.ruoyi.api;
import org.springframework.stereotype.Service;
@Service // 让它成为 Spring Bean
public class WebSocketService {
/**
* 广播消息给所有客户端
*/
public void broadcast(String message) {
WebSocketServerHandler.broadcastMessage(message);
}
public void sendToUser(String userId, String message) {
WebSocketServerHandler.sendMessageToUser(userId, message);
}
}

8
ruoyi-api/src/main/java/com/ruoyi/api/Websocket.java

@ -43,10 +43,10 @@ public class Websocket {
* 静态方法启动 WebSocket 连接可由外部调用
*/
public static synchronized void start(String url) {
if (isConnected || (manager != null)) {
log.info("WebSocket 已连接,无需重复启动");
return;
}
// if (isConnected || (manager != null)) {
// log.info("WebSocket 已连接,无需重复启动");
// return;
// }
log.info("🚀 正在启动 WebSocket 客户端,连接地址: {}", url);

25
ruoyi-api/src/main/java/com/ruoyi/api/WebsocketServerConfig.java

@ -0,0 +1,25 @@
package com.ruoyi.api;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebsocketServerConfig implements WebSocketConfigurer {
private final WebSocketServerHandler webSocketHandler;
public WebsocketServerConfig(WebSocketServerHandler webSocketHandler) {
this.webSocketHandler = webSocketHandler;
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
System.out.println("websocket服务正在创建");
registry.addHandler(webSocketHandler, "/api/ws") // 客户端连接的路径
.setAllowedOrigins("*"); // 允许跨域
}
}

523
ruoyi-api/src/main/java/com/ruoyi/api/controller/DocApiController.java

@ -42,6 +42,9 @@ import com.ruoyi.api.util.PythonApiClient;
@RequestMapping("/api/doc")
public class DocApiController extends BaseController {
static boolean flag=false;
static String url="";
@Autowired
LuceneUtil luceneUtil;
@ -910,58 +913,40 @@ public class DocApiController extends BaseController {
}
// @GetMapping("/getAllTitle")
// public List<Map<String, Object>> getAllTitle(HttpServletRequest request) {
// String token = request.getHeader("Token");
// if (token == null || token.trim().isEmpty()) {
// return Collections.emptyList();
// }
//
// try {
// token = tokenService.parseToken(token).get("login_user_key", String.class);
// reushToken.DeletToken(token);
//
// LoginUser loginUser = redisCache.getCacheObject("login_tokens:" + token);
// if (loginUser == null) {
// return Collections.emptyList();
// }
//
// // 从根节点(parentId = 0)开始构建级联数据
// return buildCascaderTree(0L, 6); // 最多6层
// } catch (Exception e) {
// e.printStackTrace();
// return Collections.emptyList();
// }
// }
// private List<Map<String, Object>> buildCascaderTree(Long parentId, int maxLevel) {
// // 超过最大层级或无子节点则返回 null
// if (maxLevel <= 0) return null;
//
// ZhyDocApi doc = new ZhyDocApi();
// doc.setDocParentId(parentId);
// List<ZhyDocApi> children = zhyDocApiMapper.selectAllDocByPLeve(doc);
//
// if (children.isEmpty()) {
// return null;
// }
//
// List<Map<String, Object>> result = new ArrayList<>();
// for (ZhyDocApi item : children) {
// Map<String, Object> node = new LinkedHashMap<>(); // 保持插入顺序
// node.put("id", item.getId().toString());
// node.put("label", item.getDocTitle()); // 请根据实际字段名替换 getDocTitle()
//
// // 递归构建子节点
// List<Map<String, Object>> childNodes = buildCascaderTree(item.getId(), maxLevel - 1);
// if (childNodes != null && !childNodes.isEmpty()) {
// node.put("children", childNodes);
// }
//
// result.add(node);
// }
//
// return result;
// }
@GetMapping("/getAllTree")
public List<Map<String, Object>> getAllTree(HttpServletRequest request) {
// 从根节点(parentId = 0)开始构建级联数据
return buildCascaderTree(0L, 4); // 最多6层
}
private List<Map<String, Object>> buildCascaderTree(Long parentId, int maxLevel) {
// 超过最大层级或无子节点则返回 null
if (maxLevel <= 0) return null;
ZhyDocApi doc = new ZhyDocApi();
doc.setDocParentId(parentId);
List<ZhyDocApi> children = zhyDocApiMapper.selectAllDocByPLeve(doc);
if (children.isEmpty()) {
return null;
}
List<Map<String, Object>> result = new ArrayList<>();
for (ZhyDocApi item : children) {
Map<String, Object> node = new LinkedHashMap<>(); // 保持插入顺序
node.put("id", item.getId().toString());
node.put("label", item.getDocTitle()); // 请根据实际字段名替换 getDocTitle()
// 递归构建子节点
List<Map<String, Object>> childNodes = buildCascaderTree(item.getId(), maxLevel - 1);
if (childNodes != null && !childNodes.isEmpty()) {
node.put("children", childNodes);
}
result.add(node);
}
return result;
}
@GetMapping("/getAllTitle")
public List<ZhyDocApi> getAllTitle(HttpServletRequest request) {
String token = request.getHeader("Token");
@ -1094,118 +1079,356 @@ public class DocApiController extends BaseController {
}
}
@GetMapping("/getTitleByGroup")
public Map getTitleByGroup(HttpServletRequest request) {
String token = request.getHeader("Token");
if (!token.equals("")) {
token = tokenService.parseToken(token).get("login_user_key", String.class);
reushToken.DeletToken(token);
LoginUser loginUser1 = redisCache.getCacheObject("login_tokens:" + token);
if (loginUser1 != null) {
//查询所有一级标题
List<ZhyDoc> g01=test1Mapper.selectDocByLevelByGroup(0l,1l);
List<ZhyDoc> g02=test1Mapper.selectDocByLevelByGroup(0l,2l);
List<ZhyDoc> g03=test1Mapper.selectDocByLevelByGroup(0l,3l);
List<ZhyDoc> g04=test1Mapper.selectDocByLevelByGroup(0l,4l);
List<ZhyDoc> g11=test1Mapper.selectDocByLevelByGroup(1l,1l);
List<ZhyDoc> g12=test1Mapper.selectDocByLevelByGroup(1l,2l);
List<ZhyDoc> g13=test1Mapper.selectDocByLevelByGroup(1l,3l);
List<ZhyDoc> g14=test1Mapper.selectDocByLevelByGroup(1l,4l);
List<ZhyDoc> g21=test1Mapper.selectDocByLevelByGroup(2l,1l);
List<ZhyDoc> g22=test1Mapper.selectDocByLevelByGroup(2l,2l);
Map mapAll=new HashMap<>();
Map map01=new HashMap<>();
map01.put("id",1);
map01.put("name","方向");
map01.put("children",g01);
Map map02=new HashMap<>();
map02.put("id",2);
map02.put("name","作战");
map02.put("children",g02);
Map map03=new HashMap<>();
map03.put("id",3);
map03.put("name","装备");
map03.put("children",g03);
Map map04=new HashMap<>();
map04.put("id",4);
map04.put("name","环境");
map04.put("children",g04);
Map map11=new HashMap<>();
map11.put("id",1);
map11.put("name","业务系统");
map11.put("children",g11);
Map map12=new HashMap<>();
map12.put("id",2);
map12.put("name","模型库");
map12.put("children",g12);
Map map13=new HashMap<>();
map13.put("id",3);
map13.put("name","规则库");
map13.put("children",g13);
Map map14=new HashMap<>();
map14.put("id",4);
map14.put("name","大类数据");
map14.put("children",g14);
Map map21=new HashMap<>();
map21.put("id",1);
map21.put("name","模型方法");
map21.put("children",g21);
Map map22=new HashMap<>();
map22.put("id",2);
map22.put("name","指标");
map22.put("children",g22);
mapAll.put("g01",map01);
mapAll.put("g02",map02);
mapAll.put("g03",map03);
mapAll.put("g04",map04);
mapAll.put("g11",map11);
mapAll.put("g12",map12);
mapAll.put("g13",map13);
mapAll.put("g14",map14);
mapAll.put("g21",map21);
mapAll.put("g22",map22);
return mapAll;
} else {
return null;
}
} else {
return null;
}
}
@Autowired
BuildService buildService;
@PostMapping("/build")
public void build(HttpServletRequest request,@RequestBody Map data) {
@PostMapping("/buildOne")
public void buildOne(HttpServletRequest request,@RequestBody Map data) {
Map thesis =new HashMap<>();
thesis.put("url","D:\\\\project\\\\gyx\\\\tupudata\\\\thesis\\\\thesis_results_20250821_124104.csv");
thesis.put("url1","D:\\\\project\\\\gyx\\\\tupudata\\\\thesis\\\\html_results_20250821_124440");
buildService.create(thesis);
if (!data.get("l1").equals("")){
Long l1 = Long.valueOf(String.valueOf(data.get("l1")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l1);
data.put("l1",doc.getDocTitle());
}else {
Integer l1=null;
}
if (!data.get("l2").equals("")){
Long l2 = Long.valueOf(String.valueOf(data.get("l2")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l2);
data.put("l2",doc.getDocTitle());
}else{
Integer l2=null;
}
if (!data.get("l3").equals("")){
Long l3 = Long.valueOf(String.valueOf(data.get("l3")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l3);
data.put("l3",doc.getDocTitle());
}else {
Integer l3=null;
}
if (!data.get("l4").equals("")){
Long l4 = Long.valueOf(String.valueOf(data.get("l4")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l4);
data.put("l4",doc.getDocTitle());
}else {
Integer l4=null;
}
if (!data.get("l5").equals("")){
Long l5 = Long.valueOf(String.valueOf(data.get("l5")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l5);
data.put("l5",doc.getDocTitle());
}else {
Integer l5=null;
}
// String token = request.getHeader("Token");
// if (!token.equals("")) {
// token = tokenService.parseToken(token).get("login_user_key", String.class);
// reushToken.DeletToken(token);
// LoginUser loginUser1 = redisCache.getCacheObject("login_tokens:" + token);
// if (loginUser1 != null) {
//
//
// if (!data.get("l1").equals("")){
// Long l1 = Long.valueOf(String.valueOf(data.get("l1")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l1);
// data.put("l1",doc.getDocTitle());
// }else {
// Integer l1=null;
// }
// if (!data.get("l2").equals("")){
// Long l2 = Long.valueOf(String.valueOf(data.get("l2")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l2);
// data.put("l2",doc.getDocTitle());
// }else{
// Integer l2=null;
// }
// if (!data.get("l3").equals("")){
// Long l3 = Long.valueOf(String.valueOf(data.get("l3")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l3);
// data.put("l3",doc.getDocTitle());
// }else {
// Integer l3=null;
// }
// if (!data.get("l4").equals("")){
// Long l4 = Long.valueOf(String.valueOf(data.get("l4")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l4);
// data.put("l4",doc.getDocTitle());
// }else {
// Integer l4=null;
// }
//
// if (!data.get("l5").equals("")){
// Long l5 = Long.valueOf(String.valueOf(data.get("l5")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l5);
// data.put("l5",doc.getDocTitle());
// }else {
// Integer l5=null;
// }
//
// if (!data.get("l6").equals("")){
// Long l6 = Long.valueOf(String.valueOf(data.get("l6")));
// ZhyDoc doc=test1Mapper.selectDocByIdId(l6);
// data.put("l6",doc.getDocTitle());
// }else {
// Integer l6=null;
// }
//
// Websocket.start();
// Gson gson = new Gson();
// String json = gson.toJson(data);
// Websocket.sendMessage(json);
//
//// 前端返回状态
//// // 2. 提取 searchItems(它是一个 List<Map<String, Object>>)
//// Object searchItemsObj = data.get("searchItems");
////
//// if (searchItemsObj instanceof List) {
//// List<?> searchItems = (List<?>) searchItemsObj;
////
//// for (int i = 0; i < searchItems.size(); i++) {
//// Object itemObj = searchItems.get(i);
////
//// if (itemObj instanceof Map) {
//// Map<String, Object> item = (Map<String, Object>) itemObj;
////
//// // 提取 tags(List<String>)
//// Object tagsObj = item.get("tags");
//// if (tagsObj instanceof List) {
//// List<?> tags = (List<?>) tagsObj;
//// System.out.println("模块 " + i + " 的标签: " + tags);
//// }
////
//// }
//// }
//// }
//// // ✅ 关键:把整个 data 传给 Python 处理
//// try {
//// String pythonResult = PythonApiClient.callPython(data);
//// System.out.println("Python 返回: " + pythonResult);
////
//// // ✅ 你可以把结果返回给前端,或存入数据库
////// return ResponseEntity.ok().body("{\"status\":\"success\",\"python_result\":" + pythonResult + "}");
////
//// } catch (IOException e) {
//// e.printStackTrace();
////// return ResponseEntity.status(500).body("{\"error\":\"调用Python失败: " + e.getMessage() + "\"}");
//// }
// } else {
if (!data.get("l6").equals("")){
Long l6 = Long.valueOf(String.valueOf(data.get("l6")));
ZhyDoc doc=test1Mapper.selectDocByIdId(l6);
data.put("l6",doc.getDocTitle());
}else {
Integer l6=null;
}
Websocket.start();
Gson gson = new Gson();
String json = gson.toJson(data);
Websocket.sendMessage(json);
}
@PostMapping("/buildTwo")
public void buildTwo(HttpServletRequest request,@RequestBody Map<String, Object> data) {
System.out.println(data);
// 存储结果:group -> type -> List<Long>(ID 列表)
Map<String, Map<Object, List<Long>>> groupedResult = new HashMap<>();
// 存储每个 group 的 searchItems(可选)
Map<String, List<Map<String, Object>>> searchItemsMap = new HashMap<>();
// 遍历每个 group
for (Map.Entry<String, Object> entry : data.entrySet()) {
String groupName = entry.getKey();
Object groupObj = entry.getValue();
if (!(groupObj instanceof Map)) {
System.out.println("无效 group 数据: " + groupName);
continue;
}
Map<String, Object> group = (Map<String, Object>) groupObj;
// ===== 1. 处理 selected:按 type 分组,ID 存为 Long =====
Object selectedObj = group.get("selected");
Map<Object, List<Long>> typeToIds = new HashMap<>();
if (selectedObj instanceof List) {
for (Object item : (List<?>) selectedObj) {
if (item instanceof List) {
List<?> pair = (List<?>) item;
if (pair.size() >= 2) {
Object type = pair.get(0); // type(如 1, 2)
Object idObj = pair.get(1); // ID 值
// 转为 Long
Long id = convertToLong(idObj);
if (id != null) {
typeToIds.computeIfAbsent(type, k -> new ArrayList<>()).add(id);
}
}
}
}
}
// 保存该 group 的分组结果
groupedResult.put(groupName, typeToIds);
// ===== 2. 提取 searchItems(可选)=====
Object searchItemsObj = group.get("searchItems");
List<Map<String, Object>> searchItems = new ArrayList<>();
if (searchItemsObj instanceof List) {
for (Object item : (List<?>) searchItemsObj) {
if (item instanceof Map) {
searchItems.add((Map<String, Object>) item);
}
}
}
searchItemsMap.put(groupName, searchItems);
}
// ===== 输出结果 =====
// 打印每个 group 的分组结果
// System.out.println("=== 每个 Group 按 Type 分组的 ID(Long) ===");
// for (Map.Entry<String, Map<Object, List<Long>>> entry : groupedResult.entrySet()) {
// String groupName = entry.getKey();
// Map<Object, List<Long>> map = entry.getValue();
// System.out.println("Group: " + groupName);
// map.forEach((type, ids) -> System.out.println(" Type " + type + " -> " + ids));
// }
//
// // 打印 searchItems(可选)
// System.out.println("\n=== 每个 Group 的 searchItems ===");
// for (Map.Entry<String, List<Map<String, Object>>> entry : searchItemsMap.entrySet()) {
// String groupName = entry.getKey();
// List<Map<String, Object>> items = entry.getValue();
// System.out.println("Group: " + groupName);
// for (Map<String, Object> item : items) {
// List<?> tags = (List<?>) item.get("tags");
// Object inputValue = item.get("inputValue");
// System.out.println(" tags: " + (tags != null ? tags : "[]") +
// ", inputValue: '" + (inputValue != null ? inputValue : "") + "'");
// }
// } else {
//
// }
List<Map<String, Object>> group0SearchItems = searchItemsMap.get("group0");
List<Map<String, Object>> group1SearchItems = searchItemsMap.get("group1");
List<Map<String, Object>> group2SearchItems = searchItemsMap.get("group2");
// 直接获取,即使 key 不存在也不会报错
//获取第一组的数据节点
List<Long> group0_type1 = getIdsByGroupAndType(groupedResult, "group0", 1);
List<Long> group0_type2 = getIdsByGroupAndType(groupedResult, "group0", 2);
List<Long> group0_type3 = getIdsByGroupAndType(groupedResult, "group0", 3);
List<Long> group0_type4 = getIdsByGroupAndType(groupedResult, "group0", 4);
List<ZhyDoc> g01=new ArrayList<>();
List<ZhyDoc> g02=new ArrayList<>();
List<ZhyDoc> g03=new ArrayList<>();
List<ZhyDoc> g04=new ArrayList<>();
if(group0_type1.size()>0){
g01=test1Mapper.selectDocByIds(group0_type1);
}
if(group0_type2.size()>0){
g02=test1Mapper.selectDocByIds(group0_type2);
}
if(group0_type3.size()>0){
g03=test1Mapper.selectDocByIds(group0_type3);
}
if(group0_type4.size()>0){
g04=test1Mapper.selectDocByIds(group0_type4);
}
for(int i=0;i<g01.size();i++){
ZhyDoc doc1=g01.get(i);
for(int j=0;j<g02.size();j++){
ZhyDoc doc2=g02.get(j);
//websocket python
//websocket vue
String[] keywords = new String[]{doc1.getDocTitle(), doc2.getDocTitle()};
Map map =new HashMap();
map.put("keywords",keywords);
map.put("searchItems",group0SearchItems);
sendPython(map);
}
}
List<Long> group1_type1 = getIdsByGroupAndType(groupedResult, "group1", 1);
List<Long> group2_type1 = getIdsByGroupAndType(groupedResult, "group2", 1);
System.out.println("group0_type1 = " + group0_type1); // [79804]
System.out.println("group1_type1 = " + group1_type1); // [79824]
System.out.println("group2_type1 = " + group2_type1); // [79812]
System.out.println(group0SearchItems+"0");
System.out.println(group1SearchItems+"1");
System.out.println(group2SearchItems+"2");
//构建定时图谱
//定时去跑这个脚本
//获取所有的节点信息,包括名称、group分组
//按照group每组去跑脚本
//根据group下的分成不同等级的标题去循环跑
//跑一遍写入返回地址,然后java处理,然后进行构建
//跑csv的时候如果urls时空不要写入csv
//先跑csv和顺道构建图谱
//构建完之后跑pdf
//然后再跑下一组数据group
//如果中间抛出异常就等待20分钟
//构建完图谱的时候,立刻写入mysql日志
//格式大概是节点1名称、节点2名称、节点1id、节点2id、文献名称、文献id,日志时间、日志事件
//如果中途嘎了java等待,然后20分钟去访问mysql时间最后一条数据
}
public List<Long> getIdsByGroupAndType(
Map<String, Map<Object, List<Long>>> result,
String groupName,
Object type
) {
return result.getOrDefault(groupName, Collections.emptyMap())
.getOrDefault(type, Collections.emptyList());
}
private Long convertToLong(Object obj) {
if (obj == null) return null;
if (obj instanceof Long) {
return (Long) obj;
} else if (obj instanceof Integer) {
return ((Integer) obj).longValue();
} else if (obj instanceof String) {
try {
return Long.parseLong((String) obj);
} catch (NumberFormatException e) {
return null;
}
} else {
return null;
}
}
private void sendPython(Map data){
Websocket.start();
Gson gson = new Gson();
String json = gson.toJson(data);
Websocket.sendMessage(json);
}
@PostMapping("/getDocOne")
public ZhyDocApi getDocOne(HttpServletRequest request, @RequestBody ZhyDocApi zhyDocApi) {
String token = request.getHeader("Token");

16
ruoyi-api/src/main/java/com/ruoyi/api/controller/TestXiaoTuPuController.java

@ -1,6 +1,7 @@
package com.ruoyi.api.controller;
import com.google.gson.GsonBuilder;
import com.ruoyi.api.WebSocketService;
import com.ruoyi.api.service.impl.PointService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.utils.Neo4jUtil;
@ -26,6 +27,19 @@ public class TestXiaoTuPuController extends BaseController {
@Autowired
PointService pointService;
@Autowired
WebSocketService webSocketService;
@GetMapping("testsocket")
public void testsocket(){
webSocketService.sendToUser("123","wahahaooo");
}
private static final Gson gson = new GsonBuilder().create();
private static final Type LIST_MAP_TYPE = new TypeToken<List<Map<String, Object>>>(){}.getType();
@ -39,6 +53,8 @@ public class TestXiaoTuPuController extends BaseController {
neo4jUtil.excuteCypherSql(cypher);
}
@GetMapping("test2")
public void test2() {
try {

4
ruoyi-api/src/main/java/com/ruoyi/api/service/impl/GraphServiceImpl.java

@ -474,7 +474,7 @@ public class GraphServiceImpl implements GraphService {
}
aa.put("source",graphRelation.get(b).get("sourceid"));
aa.put("target",graphRelation.get(b).get("targetid"));
// aa.put("relate",graphRelation.get(b).get("name"));
aa.put("relate",graphRelation.get(b).get("name"));
graphRelationNew.add(aa);
}
// === 开始去重合并 ===
@ -605,7 +605,7 @@ public class GraphServiceImpl implements GraphService {
aa.put("source",graphRelation.get(b).get("sourceid"));
aa.put("target",graphRelation.get(b).get("targetid"));
// aa.put("relate",graphRelation.get(b).get("name"));
aa.put("relate",graphRelation.get(b).get("name"));
graphRelationNew.add(aa);
}

3
ruoyi-system/src/main/java/com/ruoyi/system/mapper/Test1Mapper.java

@ -17,6 +17,7 @@ public interface Test1Mapper {
List<ZhyDoc> selectAllDocListP(Long docLevel);
ZhyDoc selectDocByTitleAndLevel(@Param("docTitle") String docTitle,@Param("docLevel") Long docLevel);
List<ZhyDoc> selectDocByLevelByGroup(@Param("groupId") Long groupId,@Param("docLevel") Long docLevel);
ZhyDoc selectDocByTitle(@Param("docTitle") String docTitle);
@ -38,6 +39,8 @@ public interface Test1Mapper {
ZhyDoc selectDocByIdId(Long id);
List<ZhyDoc> selectDocByIds(@Param("ids")List<Long> ids);
int updateDocById(ZhyDoc zhyDoc);
int updateParentId(List<ZhyDoc> list);
int updateParentId1(@Param("docTitle") String docTitle,@Param("docLevel") Long docLevel,@Param("docParentId") Long docParentId);

2
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WordSplitter.java

@ -1391,7 +1391,7 @@ public class WordSplitter {
}
// ========================
// 三级标题:X.X.X 格式(最具体,优先匹配)
// 三级标题:X.X.X 格式(最具体,优先匹配)
// ========================
if(text.indexOf("。")==-1){
Pattern p3 = Pattern.compile("^([0-9]+\\.[0-9]+\\.[0-9]+)\\s*(.*)", Pattern.DOTALL);

15
ruoyi-system/src/main/resources/mapper/system/Test1Mapper.xml

@ -44,7 +44,11 @@
<result property="difficult" column="difficult"/>
</resultMap>
<select id="selectDocByLevelByGroup" resultMap="ZhyDocResult">
select *
from zhy_doc
where doc_level = #{docLevel} and group_id=#{groupId}
</select>
<select id="selectAllDoc" resultMap="ZhyDocResult"> select * from zhy_doc where isgraph = 0</select>
<select id="selectAllDoc1" resultMap="ZhyDocResult"> select * from zhy_doc </select>
<select id="selectAllDocOver" resultMap="ZhyDocResult">
@ -104,6 +108,7 @@ select * from zhy_doc where isgraph = 0 and file_id = #{fileId}
</foreach>
</update>
<!-- <update id="updateDocById" >-->
<!-- update zhy_doc-->
<!-- set doc_title = #{docTitle} , doc_url = #{docUrl},-->
@ -185,6 +190,14 @@ select * from zhy_doc where isgraph = 0 and file_id = #{fileId}
where id = #{id}
</select>
<select id="selectDocByIds" resultMap="ZhyDocResult">
SELECT *
FROM zhy_doc
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 获取第一级标题 -->
<select id="getOneHeader" resultMap="ZhyDocResult">

116
ruoyi-ui/src/views/system/fileManage/index.vue

@ -264,7 +264,7 @@
<p v-if="isInputInvalid1" class="error-message">{{ inputErrorMessage }}</p>
<div style="margin-top: 10px;">与上级文章关系</div>
<el-input v-model="relaTion" oninput="this.value = this.value.replace(/[^(\u4e00-\u9fa5A-Za-z)]/g, '')"
placeholder="仅限汉字或字母"></el-input>
placeholder="仅限汉字或字母,不填写默认为相关"></el-input>
<span v-if="isInputInvalid" class="error-message">{{ inputErrorMessage1 }}</span>
<div slot="footer" class="dialog-footer">
<el-button v-loading="oprnIno1" type="primary" @click="submitFileForm1"> </el-button>
@ -305,45 +305,45 @@
</el-form-item>
<el-form-item style="position: relative ;" label="与上级关系">
<el-input v-model="relationName" oninput="this.value = this.value.replace(/[^(\u4e00-\u9fa5A-Za-z)]/g, '')"
placeholder="仅限汉字或字母">
placeholder="仅限汉字或字母,不填写默认为相关">
</el-input>
</el-form-item>
<el-form-item label="上传视频" prop="courseUrl">
<el-upload
class="avatar-uploader el-upload--text"
multiple
:headers="videoUpload.headers"
:action="videoUpload.url"
:file-list="videoFileList"
:show-file-list="false"
accept=".mp4"
:on-success="handleVideoSuccess"
:before-upload="beforeUploadVideo"
:on-progress="uploadVideoProcess"
:on-remove="handleVideoRemove"
>
<div v-if="!videoFlag && showVideoPath" style="display: flex; flex-wrap: wrap; gap: 10px;">
<div v-for="(url, index) in showVideoPath.split(',')" :key="url"
style="position: relative; flex: 1 1 calc(33.333% - 20px); min-width: 200px; margin-bottom: 10px;">
<video :src="`${videoUpload.url2}${url}`" style="width:90%; height: auto;border-radius: 0.5vw;" class="avatar video-avatar" controls>
您的浏览器不支持视频播放
</video>
<img
src="../../../assets/images/delete.png"
@click.stop="handleVideoRemove(videoFileList[index])"
style="width: 35px; height: 35px;position: absolute; top: 5px; left: 5px; cursor: pointer; z-index: 999;"
alt="删除"
/>
</div>
</div>
<el-progress :stroke-width="10" class="progressType" v-if="videoFlag"
type="circle" :percentage="videoUploadPercent" style="margin-top:30px;"></el-progress>
<el-button style="z-index: 999;" class="video-btn" slot="trigger" size="small" type="primary">点击上传视频</el-button>
</el-upload>
</el-form-item>
<!-- <el-form-item label="上传视频" prop="courseUrl">-->
<!-- <el-upload-->
<!-- class="avatar-uploader el-upload&#45;&#45;text"-->
<!-- multiple-->
<!-- :headers="videoUpload.headers"-->
<!-- :action="videoUpload.url"-->
<!-- :file-list="videoFileList"-->
<!-- :show-file-list="false"-->
<!-- accept=".mp4"-->
<!-- :on-success="handleVideoSuccess"-->
<!-- :before-upload="beforeUploadVideo"-->
<!-- :on-progress="uploadVideoProcess"-->
<!-- :on-remove="handleVideoRemove"-->
<!-- >-->
<!-- <div v-if="!videoFlag && showVideoPath" style="display: flex; flex-wrap: wrap; gap: 10px;">-->
<!-- <div v-for="(url, index) in showVideoPath.split(',')" :key="url"-->
<!-- style="position: relative; flex: 1 1 calc(33.333% - 20px); min-width: 200px; margin-bottom: 10px;">-->
<!-- <video :src="`${videoUpload.url2}${url}`" style="width:90%; height: auto;border-radius: 0.5vw;" class="avatar video-avatar" controls>-->
<!-- 您的浏览器不支持视频播放-->
<!-- </video>-->
<!-- <img-->
<!-- src="../../../assets/images/delete.png"-->
<!-- @click.stop="handleVideoRemove(videoFileList[index])"-->
<!-- style="width: 35px; height: 35px;position: absolute; top: 5px; left: 5px; cursor: pointer; z-index: 999;"-->
<!-- alt="删除"-->
<!-- />-->
<!-- </div>-->
<!-- </div>-->
<!-- <el-progress :stroke-width="10" class="progressType" v-if="videoFlag"-->
<!-- type="circle" :percentage="videoUploadPercent" style="margin-top:30px;"></el-progress>-->
<!-- <el-button style="z-index: 999;" class="video-btn" slot="trigger" size="small" type="primary">点击上传视频</el-button>-->
<!-- </el-upload>-->
<!-- </el-form-item>-->
<el-form-item label="上传图片" prop="courseUrl">
<el-upload
:action="uploadImgUrl"
@ -357,27 +357,27 @@
</el-upload>
</el-form-item>
<el-form-item label="上传文件" prop="courseUrl">
<el-upload
v-model="diaForm.list"
:limit="5"
:on-exceed="handleExceed"
:on-preview="handlePreview"
:before-upload="beforeAvatarUpload"
:on-remove="handleRemoveFile"
:headers="reqHeaders"
:on-success="onUploadSuccess"
action="http://localhost:10031/common/upload"
:file-list="resultFileList"
list-type="picture"
class="upload-files"
accept=".png,.jpeg,.gif,.pdf,.jpg,.JPG">
<div class="upfile-btn">
<d2-icon name="document-upload" class="document-upload" />
<div>点击上传+拖拽上传</div>
</div>
</el-upload>
</el-form-item>
<!-- <el-form-item label="上传文件" prop="courseUrl">-->
<!-- <el-upload-->
<!-- v-model="diaForm.list"-->
<!-- :limit="5"-->
<!-- :on-exceed="handleExceed"-->
<!-- :on-preview="handlePreview"-->
<!-- :before-upload="beforeAvatarUpload"-->
<!-- :on-remove="handleRemoveFile"-->
<!-- :headers="reqHeaders"-->
<!-- :on-success="onUploadSuccess"-->
<!-- action="http://localhost:10031/common/upload"-->
<!-- :file-list="resultFileList"-->
<!-- list-type="picture"-->
<!-- class="upload-files"-->
<!-- accept=".png,.jpeg,.gif,.pdf,.jpg,.JPG">-->
<!-- <div class="upfile-btn">-->
<!-- <d2-icon name="document-upload" class="document-upload" />-->
<!-- <div>点击上传+拖拽上传</div>-->
<!-- </div>-->
<!-- </el-upload>-->
<!-- </el-form-item>-->
@ -415,7 +415,7 @@
</el-form-item>
<el-form-item style="position: relative ;" label="与上级关系">
<el-input v-model="relaTion" oninput="this.value = this.value.replace(/[^(\u4e00-\u9fa5A-Za-z)]/g, '')"
placeholder="仅限汉字或字母"></el-input>
placeholder="仅限汉字或字母,不填写默认为相关"></el-input>
</el-form-item>
<el-form-item style="position: relative ;" label="知识内容">
<Editor v-if="addTxt" v-model="TxtValue"></Editor>

Loading…
Cancel
Save