推荐系统初始化
This commit is contained in:
238
web/src/components/dialog/EdgeAdd.vue
Normal file
238
web/src/components/dialog/EdgeAdd.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<!-- 实例节点的详细信息 -->
|
||||
<div class="node-box">
|
||||
<div class="title">添加关系</div>
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules" style="height: 600px;overflow-y: auto">
|
||||
<el-form-item label="所属关系" prop="edge">
|
||||
<el-select v-model="form.edge" >
|
||||
<el-option v-for="edge in edgeList" :key="edge.Name" :label="edge.comment"
|
||||
:value="edge.Name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="头节点" prop="srcId">
|
||||
<el-select v-model="form.srcLabel" placeholder="请选择概念" @change="form.srcId = '';srcOptions = []" filterable>
|
||||
<el-option v-for="label in labelList" :key="label.Name" :label="label.comment" :value="label.Name"></el-option>
|
||||
</el-select>
|
||||
<el-select v-model="form.srcId" filterable remote reserve-keyword placeholder="请输入关键词" :remote-method="remoteMethodSrc" @change="changeSelect"
|
||||
:loading="srcLoading">
|
||||
<el-option
|
||||
v-for="item in srcOptions"
|
||||
:key="item.vid"
|
||||
:label="item.properties.name"
|
||||
:value="item.vid">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="尾节点" prop="dstId">
|
||||
<el-select v-model="form.dstLabel" placeholder="请选择概念" @change="form.dstId = '';dstOptions = []" filterable>
|
||||
<el-option v-for="label in labelList" :key="label.Name" :label="label.comment" :value="label.Name"></el-option>
|
||||
</el-select>
|
||||
<el-select v-model="form.dstId" filterable remote reserve-keyword placeholder="请输入关键词" :remote-method="remoteMethodDst" @change="changeSelect"
|
||||
:loading="dstLoading">
|
||||
<el-option
|
||||
v-for="item in dstOptions"
|
||||
:key="item.vid"
|
||||
:label="item.properties.name"
|
||||
:value="item.vid">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-box">
|
||||
<el-button type="primary" @click="submitUpdate">保 存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import {getFirstStringProperty} from "@/utils/common";
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
form: {
|
||||
edge: '',
|
||||
srcId: '',
|
||||
dstId: '',
|
||||
srcLabel: '',
|
||||
dstLabel: ''
|
||||
},
|
||||
rules: {
|
||||
edge: [
|
||||
{required: true, message: '请选择所属关系'}
|
||||
],
|
||||
srcId: [
|
||||
{required: true, message: '请选择头节点'}
|
||||
],
|
||||
dstId: [
|
||||
{required: true, message: '请选择尾节点'}
|
||||
],
|
||||
},
|
||||
edgeList:[],
|
||||
labelList:[],
|
||||
srcOptions:[],
|
||||
dstOptions:[],
|
||||
srcLoading:false,
|
||||
dstLoading:false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
//模糊搜索
|
||||
remoteMethodSrc(query) {
|
||||
if(vm.form.srcLabel){
|
||||
if (query !== '') {
|
||||
vm.srcLoading = true;
|
||||
request({
|
||||
url: `/nebula_operate/findnodebykeyword/${vm.space}/${vm.form.srcLabel}`,
|
||||
method: 'post',
|
||||
data: {keyword:query}
|
||||
}).then(res => {
|
||||
vm.srcOptions = res.data;
|
||||
vm.srcLoading = false;
|
||||
});
|
||||
} else {
|
||||
vm.form.srcId = "";
|
||||
vm.srcOptions = [];
|
||||
}
|
||||
}else{
|
||||
vm.$message.warning("请输入头节点概念");
|
||||
}
|
||||
|
||||
},
|
||||
//模糊搜索
|
||||
remoteMethodDst(query) {
|
||||
if(vm.form.dstLabel){
|
||||
if (query !== '') {
|
||||
vm.dstLoading = true;
|
||||
request({
|
||||
url: `/nebula_operate/findnodebykeyword/${vm.space}/${vm.form.dstLabel}`,
|
||||
method: 'post',
|
||||
data: {keyword:query}
|
||||
}).then(res => {
|
||||
vm.dstOptions = res.data;
|
||||
vm.dstLoading = false;
|
||||
});
|
||||
} else {
|
||||
vm.form.dstId = "";
|
||||
vm.dstOptions = [];
|
||||
}
|
||||
}else{
|
||||
vm.$message.warning("请输入尾节点概念");
|
||||
}
|
||||
},
|
||||
changeSelect(){
|
||||
|
||||
},
|
||||
queryEdgeList() {
|
||||
request({
|
||||
url: `/nebula_operate/showedge/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.edgeList = res.data;
|
||||
});
|
||||
},
|
||||
queryTagList() { // 查询tag列表
|
||||
vm.propsInfoVisible = false;
|
||||
request({
|
||||
url: `/nebula_operate/showtag/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.labelList = res.data;
|
||||
});
|
||||
},
|
||||
createItem(space) {
|
||||
vm.space = space;
|
||||
vm.form = {
|
||||
edge: '',
|
||||
srcId: '',
|
||||
dstId: '',
|
||||
srcLabel: '',
|
||||
dstLabel: ''
|
||||
};
|
||||
vm.queryEdgeList();
|
||||
vm.queryTagList();
|
||||
},
|
||||
submitUpdate() { // 更新
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加关系
|
||||
request({
|
||||
url: `/nebula_operate/insertedgeline/${vm.space}/${vm.form.edge}`,
|
||||
method: 'post',
|
||||
data: vm.form
|
||||
}).then(res => {
|
||||
vm.$parent.findOnePathBySrcidAndDctid(vm.form.srcId,vm.form.dstId);
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.form-box {
|
||||
height: 900px;
|
||||
overflow-y: auto;
|
||||
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
|
||||
.btn-box {
|
||||
text-align: right;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.node-box .title {
|
||||
font-size: 18px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
250
web/src/components/dialog/EdgeDetail.vue
Normal file
250
web/src/components/dialog/EdgeDetail.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<!-- 实例节点关系的详细信息 -->
|
||||
<div class="node-box">
|
||||
<div class="title"> 关系属性</div>
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules" style="height: 600px;overflow-y: auto">
|
||||
<el-form-item label="类型" prop="labels">
|
||||
<el-select v-model="form.labels" :disabled="editFlag" @change="handleLabelChange">
|
||||
<el-option v-for="label in labelList" :key="label.Name" :label="label.comment"
|
||||
:value="label.Name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="头实例">
|
||||
<el-input v-model="form.start" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="尾实例">
|
||||
<el-input v-model="form.end" disabled></el-input>
|
||||
</el-form-item>
|
||||
<div class="loading-box" v-show="loading">
|
||||
<i class="el-icon-loading"></i>
|
||||
<label>查询中</label>
|
||||
</div>
|
||||
<el-form-item :label="item.comment" v-for="item in infoList" :key="item.field">
|
||||
<el-input v-model="item.value"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-box">
|
||||
<el-button type="danger" @click="removeItem" v-show="editFlag">删 除</el-button>
|
||||
<el-button type="primary" @click="submitUpdate">保 存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import {getFirstStringProperty} from "@/utils/common";
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
editFlag: false,
|
||||
labelList: [],
|
||||
selectObj: {},
|
||||
loading: false,
|
||||
form: {
|
||||
labels: '',
|
||||
start: '',
|
||||
end: '',
|
||||
},
|
||||
infoList: [],
|
||||
rules: {
|
||||
labels: [
|
||||
{required: true, message: '请选择类型'}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
queryEdgeList() {
|
||||
vm.propsInfoVisible = false;
|
||||
request({
|
||||
url: `/nebula_operate/showedge/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.labelList = res.data;
|
||||
});
|
||||
},
|
||||
createItem(space, srcId, dstId) {
|
||||
vm.editFlag = false;
|
||||
vm.space = space;
|
||||
vm.form.labels = "";
|
||||
vm.infoList = [];
|
||||
vm.selectObj.vid = null;
|
||||
vm.selectObj.srcId = srcId;
|
||||
vm.selectObj.dstId = dstId;
|
||||
vm.queryNodeForEdge(srcId, 'start');
|
||||
vm.queryNodeForEdge(dstId, 'end');
|
||||
vm.queryEdgeList();
|
||||
},
|
||||
queryDetail(space, {edgeType, srcVid, dstVid}) {
|
||||
vm.editFlag = true;
|
||||
vm.space = space;
|
||||
vm.queryEdgeList();
|
||||
vm.queryEdgeDetail(edgeType, srcVid, dstVid);
|
||||
},
|
||||
queryNodeForEdge(vid, comment) {
|
||||
request({
|
||||
url: `/nebula_operate/findnodebyid/${vm.space}/${vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.form[comment] = getFirstStringProperty(res.data.properties);
|
||||
});
|
||||
},
|
||||
queryEdgeDetail(edgeType, srcVid, dstVid) {
|
||||
vm.queryNodeForEdge(srcVid, 'start');
|
||||
vm.queryNodeForEdge(dstVid, 'end');
|
||||
vm.selectObj = {
|
||||
srcId: srcVid,
|
||||
dstId: dstVid
|
||||
};
|
||||
request({
|
||||
url: `/nebula_operate/descedge/${vm.space}/${edgeType}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res0 => {
|
||||
let map = {};
|
||||
res0.data.forEach(item => {
|
||||
map[item.field] = item.comment;
|
||||
});
|
||||
request({
|
||||
url: `/nebula_operate/findrelationbyid/${vm.space}/${edgeType}/${srcVid}/${dstVid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.form.labels = res.data.edgeName;
|
||||
vm.resolveProperties(res.data.properties, map);
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
handleLabelChange() {
|
||||
vm.loading = true;
|
||||
request({
|
||||
url: `/nebula_operate/descedge/${vm.space}/${vm.form.labels}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.loading = false;
|
||||
vm.infoList = res.data;
|
||||
});
|
||||
},
|
||||
resolveProperties(properties, map) { // 处理节点和边的属性
|
||||
let _infoList = [];
|
||||
Reflect.ownKeys(properties).forEach(key => {
|
||||
_infoList.push({
|
||||
comment: map[key],
|
||||
field: key,
|
||||
value: properties[key]
|
||||
});
|
||||
});
|
||||
vm.infoList = _infoList;
|
||||
},
|
||||
removeItem() {
|
||||
this.$confirm('此操作将永久删除选中关系, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: `/nebula_operate/deleteedgeline/${vm.space}/${vm.form.labels}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
srcId: vm.selectObj.srcId,
|
||||
dstId: vm.selectObj.dstId,
|
||||
}
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.$parent.querySpaceGraphData();
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
submitUpdate() { // 更新
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
let _ob = {};
|
||||
vm.infoList.forEach(info => {
|
||||
_ob[info.field] = info.value;
|
||||
});
|
||||
// 添加关系
|
||||
request({
|
||||
url: `/nebula_operate/insertedgeline/${vm.space}/${vm.form.labels}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
srcId: vm.selectObj.srcId,
|
||||
dstId: vm.selectObj.dstId,
|
||||
ob: _ob
|
||||
}
|
||||
}).then(res => {
|
||||
vm.$parent.querySpaceGraphData();
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.form-box {
|
||||
height: 900px;
|
||||
overflow-y: auto;
|
||||
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
|
||||
.btn-box {
|
||||
text-align: right;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.node-box .title {
|
||||
font-size: 18px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
270
web/src/components/dialog/EdgeTypeModify.vue
Normal file
270
web/src/components/dialog/EdgeTypeModify.vue
Normal file
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<!-- 边类型信息修改 -->
|
||||
<div class="node-box">
|
||||
<div class="title">{{ editFlag ? '编辑' : '新建' }}</div>
|
||||
<el-form ref="relationForm" label-width="100px" label-position="left">
|
||||
<el-form-item label="*边类型名称">
|
||||
<el-input v-model="modifyCmd.name" :disabled="editFlag"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="modifyCmd.comment"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-title">定义属性</div>
|
||||
<el-table :data="fields"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="field" label="属性名称"></el-table-column>
|
||||
<el-table-column prop="type" label="数据类型"></el-table-column>
|
||||
<!-- <el-table-column prop="Null" label="允许空值"></el-table-column>-->
|
||||
<!-- <el-table-column prop="Default" label="默认值"></el-table-column>-->
|
||||
<!-- <el-table-column prop="Comment" label="描述"></el-table-column>-->
|
||||
<el-table-column label="操作" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="modifyField(scope.row, scope.$index)">编辑</el-button>
|
||||
<el-button type="text" size="small" @click="removeField(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="add-attribute-box" @click="showAddFieldDialog('source')">添加字段</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="btn-box">
|
||||
<el-button type="danger" @click="removeEdge" v-show="editFlag">删 除</el-button>
|
||||
<el-button type="primary" @click="submitUpdateNode" >保 存</el-button>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="dialogName"
|
||||
:append-to-body="true"
|
||||
:visible.sync="fieldDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="fieldCmd" label-width="80px">
|
||||
<el-form-item label="属性名称">
|
||||
<el-input v-model="fieldCmd.field" :disabled="dialogName == '编辑属性'"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据类型">
|
||||
<el-select v-model="fieldCmd.type" style="width: 100%">
|
||||
<el-option :label="item" :value="item" v-for="item in dataType"
|
||||
:key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="允许空值">-->
|
||||
<!-- <el-switch-->
|
||||
<!-- v-model="fieldCmd.Null"-->
|
||||
<!-- active-color="#13ce66"-->
|
||||
<!-- inactive-color="#ff4949"-->
|
||||
<!-- active-value="YES"-->
|
||||
<!-- inactive-value="NO">-->
|
||||
<!-- </el-switch>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="默认值">-->
|
||||
<!-- <el-input v-model="fieldCmd.Default"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="描述">-->
|
||||
<!-- <el-input v-model="fieldCmd.Comment" type="textarea"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="fieldDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddField">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
modifyCmd: {
|
||||
name: '',
|
||||
fields: []
|
||||
},
|
||||
editFlag: false,
|
||||
fields: [],
|
||||
fieldDialogVisible: false,
|
||||
fieldCmd: {
|
||||
field: '',
|
||||
type: ''
|
||||
},
|
||||
dialogName: '添加属性',
|
||||
selectObj: {
|
||||
type: '',
|
||||
value: {}
|
||||
},
|
||||
dataType: ["INT64", "INT32", "INT16", "INT8", "FLOAT", "DOUBLE", "BOOL", "STRING", "DATE", "TIME", "DATETIME", "FIXED_STRING"],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
updateValue(space, name) {
|
||||
vm.space = space;
|
||||
vm.modifyCmd.name = name;
|
||||
if (name.length > 0) {
|
||||
vm.queryEdgeDescribe();
|
||||
request({
|
||||
url: `/nebula_operate/showcreateedge/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.modifyCmd.comment = res.data.comment;
|
||||
vm.modifyCmd = JSON.parse(JSON.stringify(vm.modifyCmd))
|
||||
});
|
||||
vm.editFlag = true;
|
||||
} else {
|
||||
vm.editFlag = false;
|
||||
vm.fields = [];
|
||||
}
|
||||
},
|
||||
queryEdgeDescribe() {
|
||||
request({
|
||||
url: `/nebula_operate/descedge/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.forEach(item => {
|
||||
item.type = item.type.toUpperCase();
|
||||
});
|
||||
vm.fields = res.data;
|
||||
});
|
||||
},
|
||||
modifyField(item, index) {
|
||||
vm.dialogName = '编辑属性';
|
||||
vm.fieldCmd = JSON.parse(JSON.stringify(item));
|
||||
vm.fieldCmd.index = index;
|
||||
vm.fieldDialogVisible = true;
|
||||
},
|
||||
removeField(item, index) {
|
||||
vm.fields.splice(index, 1);
|
||||
if (vm.editFlag) { // 编辑tag,需要提交请求
|
||||
vm.modifyCmd.fields = [item];
|
||||
request({
|
||||
url: `/nebula_operate/alterdropedge/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.fieldDialogVisible = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
showAddFieldDialog(type) {
|
||||
vm.fieldCmd = {
|
||||
field: '',
|
||||
type: '',
|
||||
null: 'YES',
|
||||
};
|
||||
vm.dialogName = '添加属性';
|
||||
vm.fieldDialogVisible = true;
|
||||
},
|
||||
submitAddField() {
|
||||
if (!vm.editFlag) { // 新建的tag,不需要即时提交
|
||||
if (vm.dialogName == '添加属性') {
|
||||
vm.fields.push(vm.fieldCmd);
|
||||
} else if (vm.dialogName == '编辑属性') {
|
||||
vm.fields[vm.fieldCmd.index] = vm.fieldCmd;
|
||||
}
|
||||
vm.fieldDialogVisible = false;
|
||||
} else {
|
||||
vm.modifyCmd.fields = [vm.fieldCmd];
|
||||
if (vm.dialogName == '添加属性') {
|
||||
request({
|
||||
url: `/nebula_operate/alteraddedge/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.fields.push(vm.fieldCmd);
|
||||
vm.fieldDialogVisible = false;
|
||||
});
|
||||
} else if (vm.dialogName == '编辑属性') {
|
||||
request({
|
||||
url: `/nebula_operate/alterchangeedge/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.fields[vm.fieldCmd.index] = vm.fieldCmd;
|
||||
vm.fieldDialogVisible = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
submitUpdateNode() { // 更新
|
||||
if(vm.modifyCmd.name.length === 0) {
|
||||
vm.$message.warning("边类型名称不能为空");
|
||||
return false;
|
||||
}
|
||||
vm.modifyCmd.fields = vm.fields;
|
||||
if (!vm.editFlag) { // 新建
|
||||
request({
|
||||
url: `/nebula_operate/createedge/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.$parent.queryEdgeList();
|
||||
});
|
||||
} else { // 编辑
|
||||
vm.$parent.queryEdgeList();
|
||||
}
|
||||
},
|
||||
removeEdge() {
|
||||
vm.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: `/nebula_operate/dropedge/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.$parent.queryEdgeList();
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.btn-box {
|
||||
text-align: right;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
144
web/src/components/dialog/GraphSpaceAdd.vue
Normal file
144
web/src/components/dialog/GraphSpaceAdd.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<el-dialog title="新建实例" :visible.sync="cmdDialogVisible" width="40%">
|
||||
<el-steps :active="active" finish-status="success" style="margin-bottom: 20px">
|
||||
<el-step title="新建实例空间"></el-step>
|
||||
<el-step title="选择本体"></el-step>
|
||||
</el-steps>
|
||||
<el-form ref="cmd" label-width="120px" :model="cmd" v-if="active == 0">
|
||||
<el-form-item label="实例空间名称:">
|
||||
<el-input v-model="cmd.name" style="width: 100%" ></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="实例空间描述:">
|
||||
<el-input v-model="cmd.comment" style="width: 100%" ></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer" v-if="active == 0">
|
||||
<el-button type="primary" @click="createSpace">下一步</el-button>
|
||||
</span>
|
||||
<el-form ref="cmd" label-width="130px" :model="cmd" v-if="active == 1">
|
||||
<el-form-item label="选择本体:">
|
||||
<el-select v-model="cmd.ontologyId" placeholder="请选择本体" style="width: 100%">
|
||||
<el-option v-for="item in ontologyList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer" v-if="active == 1">
|
||||
<el-button @click="cmdDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitModify" :loading="loading">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from "@/utils/request";
|
||||
|
||||
let data;
|
||||
var _this;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
cmd:{},
|
||||
cmdDialogVisible:false,
|
||||
spaceList:[],
|
||||
active:0,
|
||||
ontologyList:[],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
_this = this;
|
||||
},
|
||||
methods: {
|
||||
queryOntology() {
|
||||
request({
|
||||
url: `/ontology/query_list`,
|
||||
method: 'post',
|
||||
data: {EQI_sourceType: 1}
|
||||
}).then(res => {
|
||||
_this.ontologyList = res.data;
|
||||
});
|
||||
},
|
||||
openDialog() {
|
||||
_this.queryOntology();
|
||||
_this.active = 0;
|
||||
_this.cmd = {
|
||||
ontologyId:"",
|
||||
name:"",
|
||||
comment:""
|
||||
}
|
||||
_this.loading = false;
|
||||
_this.cmdDialogVisible = true;
|
||||
},
|
||||
createSpace(){
|
||||
if(!_this.cmd.name){
|
||||
_this.$message.warning("请输入实例空间名称");
|
||||
return false;
|
||||
}
|
||||
if(!_this.cmd.comment){
|
||||
_this.$message.warning("请输入实例空间描述");
|
||||
return false;
|
||||
}
|
||||
_this.active = 1;
|
||||
},
|
||||
submitModify(){
|
||||
if(!_this.cmd.ontologyId){
|
||||
_this.$message.warning("请选择本体");
|
||||
return false;
|
||||
}
|
||||
|
||||
_this.loading = true;
|
||||
this.$message({
|
||||
message: '正在初始化图空间,请等待...',
|
||||
type:"info",
|
||||
duration:20000
|
||||
});
|
||||
request({
|
||||
url: '/nebula_operate/createspace',
|
||||
method: 'post',
|
||||
data: {name:_this.cmd.name,comment:_this.cmd.comment}
|
||||
}).then(res => {
|
||||
var timer = setTimeout(function(){
|
||||
request({
|
||||
url: '/nebula_model/initgraphdatabase/'+_this.cmd.ontologyId+'/'+_this.cmd.name,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
_this.$message.success("新建实例成功");
|
||||
clearTimeout(timer);
|
||||
_this.loading = false;
|
||||
_this.cmdDialogVisible = false;
|
||||
_this.$parent.querySpaceList();
|
||||
});
|
||||
},20000)
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
187
web/src/components/dialog/GraphSpaceAdd1.vue
Normal file
187
web/src/components/dialog/GraphSpaceAdd1.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="新建知识图谱实例"
|
||||
:visible.sync="selectModelDialogVisible"
|
||||
width="40%">
|
||||
<el-steps :space="200" :active="activeStep" finish-status="success">
|
||||
<el-step title="知识图谱本体选择"></el-step>
|
||||
<el-step title="知识图谱实例命名"></el-step>
|
||||
</el-steps>
|
||||
<div v-show="activeStep == 1">
|
||||
<div>
|
||||
<el-form :inline="true" :model="modelQo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-input v-model="modelQo.LIKES_name" placeholder="请输入知识图谱本体名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="modelQo.pageNo=1;queryModelData()">搜 索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="modelResult.records" style="width: 100%" @selection-change="handleSelectionChange"
|
||||
ref="modelTable">
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="知识图谱本体"></el-table-column>
|
||||
<el-table-column prop="description" label="本体描述"></el-table-column>
|
||||
<!-- <el-table-column prop="createTime" label="创建时间"></el-table-column>-->
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination background
|
||||
@current-change="handleModelCurrentChange"
|
||||
:current-page="modelQo.pageNo"
|
||||
:page-size="modelQo.pageSize"
|
||||
layout="total, prev, pager, next"
|
||||
:total="modelResult.total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="nextStep">下一步</el-button>
|
||||
</span>
|
||||
</div>
|
||||
<div v-show="activeStep == 2">
|
||||
<el-form ref="cmd" :model="cmd" label-width="180px" :rules="cmdRules">
|
||||
<el-form-item label="知识图谱实例名称" prop="space">
|
||||
<el-input v-model="cmd.space" placeholder="请输入新建的知识图谱实例名称,英文数字下划线组合"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="知识图谱实例描述">
|
||||
<el-input v-model="cmd.spaceComment" placeholder="请输入新建的知识图谱实例描述,中文描述"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="activeStep = 1">上一步</el-button>
|
||||
<el-button type="primary" @click="gotoCreateGraphSpace">确 定</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from "@/utils/request";
|
||||
|
||||
let data;
|
||||
var _this;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectModelDialogVisible: false,
|
||||
activeStep: 1,
|
||||
selectModelId: '',
|
||||
graphSpaceName: '',
|
||||
cmd: {},
|
||||
modelQo: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
LIKES_name: '',
|
||||
EQI_sourceType:1
|
||||
},
|
||||
modelResult: {
|
||||
records: [],
|
||||
total: 0
|
||||
},
|
||||
modelSelection: [],
|
||||
cmdRules: {
|
||||
space: [
|
||||
{required: true, message: '请输入知识图谱实例名称', trigger: 'blur'},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
_this = this;
|
||||
},
|
||||
methods: {
|
||||
openDialog() {
|
||||
|
||||
_this.modelQo.pageNo = 1;
|
||||
_this.cmd = {
|
||||
space: '',
|
||||
ontologyId: '',
|
||||
spaceComment: ''
|
||||
};
|
||||
_this.activeStep = 1;
|
||||
_this.modelSelection = [];
|
||||
_this.queryModelData();
|
||||
_this.selectModelDialogVisible = true;
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
if(val.length > 0) {
|
||||
for (let i = 0; i < val.length - 1; i++) {
|
||||
this.$refs.modelTable.toggleRowSelection(val[i]);
|
||||
}
|
||||
_this.modelSelection = [val[val.length - 1]];
|
||||
} else {
|
||||
_this.modelSelection = [];
|
||||
}
|
||||
},
|
||||
nextStep() {
|
||||
if (_this.modelSelection.length == 0) {
|
||||
_this.$message.warning("请选择知识图谱本体");
|
||||
return;
|
||||
}
|
||||
_this.activeStep = 2;
|
||||
},
|
||||
queryModelData() {
|
||||
request({
|
||||
url: '/ontology/query_pages',
|
||||
method: 'post',
|
||||
data: _this.modelQo
|
||||
}).then(res => {
|
||||
_this.modelResult.records = res.data.records;
|
||||
_this.modelResult.total = res.data.total;
|
||||
});
|
||||
},
|
||||
handleModelCurrentChange(val) {
|
||||
_this.modelQo.pageNo = val;
|
||||
_this.queryModelData();
|
||||
},
|
||||
gotoCreateGraphSpace() {
|
||||
_this.$refs['cmd'].validate((valid) => {
|
||||
if (valid) {
|
||||
request({
|
||||
url: `/nebula_model/initgraphdatabase/${_this.modelSelection[0].id}/${_this.cmd.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
_this.$message.success("创建成功");
|
||||
_this.selectModelDialogVisible = false;
|
||||
_this.$parent.querySpaceList();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
201
web/src/components/dialog/IndexAdd.vue
Normal file
201
web/src/components/dialog/IndexAdd.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<!-- 边类型信息修改 -->
|
||||
<div>
|
||||
<el-dialog
|
||||
title="添加"
|
||||
:visible.sync="indexDialogVisible"
|
||||
width="60%">
|
||||
<el-form ref="fieldCmd" label-width="80px">
|
||||
<el-form-item label="索引类型">
|
||||
<el-select v-model="indexCmd.type" style="width: 100%" @change="handleIndexTypeChange">
|
||||
<el-option :label="item" :value="item" v-for="item in indexTypeList"
|
||||
:key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称">
|
||||
<el-select v-model="indexCmd.onName" style="width: 100%" @change="handleIndexOnNameChange">
|
||||
<template v-if="indexCmd.type == 'TAG'">
|
||||
<el-option :label="item.Name" :value="item.Name" v-for="item in tagList"
|
||||
:key="item.Name"></el-option>
|
||||
</template>
|
||||
<template v-if="indexCmd.type == 'EDGE'">
|
||||
<el-option :label="item.Name" :value="item.Name" v-for="item in edgeList"
|
||||
:key="item.Name"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="索引名称">
|
||||
<el-input v-model="indexCmd.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="索引属性">
|
||||
<el-tag style="margin-right: 15px"
|
||||
v-for="tagObj in indexCmd.fields"
|
||||
:key="tagObj.fieldName"
|
||||
@close="handleIndexFieldClose(tagObj)"
|
||||
closable>
|
||||
{{ tagObj.fieldName }}({{ tagObj.len }})
|
||||
</el-tag>
|
||||
<el-button @click="showAddIndexFieldDialog" type="text" size="small">添加</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="indexDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddIndex">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
title="添加索引属性"
|
||||
:append-to-body="true"
|
||||
:visible.sync="indexFieldDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="fieldCmd" label-width="140px">
|
||||
<el-form-item label="选择关联的属性">
|
||||
<el-select v-model="indexFieldCmd.fieldName" style="width: 100%">
|
||||
<el-option :label="item.Field" :value="item.Field" v-for="item in indexFields"
|
||||
:key="item.Field" v-show="filterSelected(item.Field)"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="长度">
|
||||
<el-input v-model="indexFieldCmd.len"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="indexFieldDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addFieldToIndexCmd">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
tagList: [],
|
||||
edgeList: [],
|
||||
indexDialogVisible: false,
|
||||
indexCmd: {},
|
||||
indexTypeList: ['TAG', 'EDGE'],
|
||||
indexFields: [],
|
||||
indexFieldCmd: {},
|
||||
indexFieldDialogVisible: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
showAddIndexDialog(space) {
|
||||
vm.space = space;
|
||||
vm.indexCmd = {
|
||||
space: vm.space,
|
||||
onName: '',
|
||||
name: '',
|
||||
type: 'TAG',
|
||||
fields: []
|
||||
};
|
||||
vm.queryTagList();
|
||||
vm.queryEdgeList();
|
||||
vm.indexDialogVisible = true;
|
||||
},
|
||||
queryTagList() {
|
||||
request({
|
||||
url: `/nebula_operate/showtag/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.tagList = res.data;
|
||||
});
|
||||
},
|
||||
queryEdgeList() {
|
||||
request({
|
||||
url: `/nebula_operate/showedge/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.edgeList = res.data;
|
||||
});
|
||||
},
|
||||
handleIndexTypeChange() {
|
||||
vm.indexCmd.onName = '';
|
||||
vm.indexCmd.fields = [];
|
||||
},
|
||||
handleIndexFieldClose(tagObj) {
|
||||
vm.indexCmd.fields.splice(vm.indexCmd.fields.indexOf(tagObj), 1);
|
||||
},
|
||||
handleIndexOnNameChange() {
|
||||
vm.indexCmd.fields = [];
|
||||
let url = '';
|
||||
if (vm.indexCmd.type == 'TAG') {
|
||||
url = `/nebula_operate/desctag/${vm.space}/${vm.indexCmd.onName}`;
|
||||
} else {
|
||||
url = `/nebula_operate/descedge/${vm.space}/${vm.indexCmd.onName}`;
|
||||
}
|
||||
request({
|
||||
url: url,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.indexFields = res.data;
|
||||
});
|
||||
},
|
||||
showAddIndexFieldDialog() {
|
||||
if (vm.indexCmd.onName.length == 0) {
|
||||
vm.$message.warning("请选择名称");
|
||||
return;
|
||||
}
|
||||
vm.indexFieldCmd = {
|
||||
fieldName: '',
|
||||
len: ''
|
||||
};
|
||||
vm.indexFieldDialogVisible = true;
|
||||
},
|
||||
addFieldToIndexCmd() {
|
||||
vm.indexCmd.fields.push(vm.indexFieldCmd);
|
||||
vm.indexFieldDialogVisible = false;
|
||||
},
|
||||
filterSelected(fieldName) {
|
||||
let _index = vm.indexCmd.fields.findIndex(row => {
|
||||
return row.fieldName == fieldName;
|
||||
});
|
||||
return _index < 0; // 存在了
|
||||
},
|
||||
submitAddIndex() {
|
||||
if (vm.indexCmd.onName.length == 0) {
|
||||
vm.$message.warning("请选择名称");
|
||||
return;
|
||||
}
|
||||
if (vm.indexCmd.name.length == 0) {
|
||||
vm.$message.warning("请填写索引名称");
|
||||
return;
|
||||
}
|
||||
request({
|
||||
url: `/nebula_operate/createindex/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.indexCmd
|
||||
}).then(res => {
|
||||
vm.indexDialogVisible = false;
|
||||
vm.$parent.queryIndexList();
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
224
web/src/components/dialog/NodeDetail.vue
Normal file
224
web/src/components/dialog/NodeDetail.vue
Normal file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<!-- 实例节点的详细信息 -->
|
||||
<div class="node-box">
|
||||
<div class="title">实例属性</div>
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules" style="height: 600px;overflow-y: auto">
|
||||
<el-form-item label="所属概念" prop="labels">
|
||||
<el-select v-model="form.labels" :disabled="editFlag" @change="handleLabelChange">
|
||||
<el-option v-for="label in labelList" :key="label.Name" :label="label.comment"
|
||||
:value="label.Name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="loading-box" v-show="loading">
|
||||
<i class="el-icon-loading"></i>
|
||||
<label>查询中</label>
|
||||
</div>
|
||||
<el-form-item :label="item.comment" v-for="item in infoList" :key="item.field">
|
||||
<el-input v-model="item.value"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn-box">
|
||||
<el-button type="danger" @click="removeItem" v-show="editFlag">删 除</el-button>
|
||||
<el-button type="primary" @click="submitUpdate">保 存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
import {getFirstStringProperty} from "@/utils/common";
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
editFlag: false,
|
||||
labelList: [],
|
||||
selectObj: {},
|
||||
loading: false,
|
||||
form: {
|
||||
labels: '',
|
||||
},
|
||||
infoList: [],
|
||||
rules: {
|
||||
labels: [
|
||||
{required: true, message: '请选择所属概念'}
|
||||
],
|
||||
},
|
||||
tag:""
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
queryTagList() { // 查询tag列表
|
||||
vm.propsInfoVisible = false;
|
||||
request({
|
||||
url: `/nebula_operate/showtag/${vm.space}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.labelList = res.data;
|
||||
});
|
||||
},
|
||||
createItem(space) {
|
||||
vm.editFlag = false;
|
||||
vm.space = space;
|
||||
vm.form.labels = "";
|
||||
vm.infoList = [];
|
||||
vm.selectObj.vid = null;
|
||||
vm.queryTagList();
|
||||
},
|
||||
queryDetail(space, {tag, vid}) {
|
||||
vm.editFlag = true;
|
||||
vm.space = space;
|
||||
vm.tag = tag;
|
||||
vm.queryTagList();
|
||||
vm.queryNodeDetail(tag, vid);
|
||||
},
|
||||
queryNodeDetail(tag, vid) {
|
||||
vm.selectObj = {
|
||||
vid: vid
|
||||
};
|
||||
request({
|
||||
url: `/nebula_operate/desctag/${vm.space}/${tag}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res0 => {
|
||||
let map = {};
|
||||
res0.data.forEach(item => {
|
||||
map[item.field] = item.comment;
|
||||
});
|
||||
request({
|
||||
url: `/nebula_operate/findnodebyid/${vm.space}/${tag}/${vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.form.labels = res.data.labels;
|
||||
vm.resolveProperties(res.data.properties, map);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleLabelChange() {
|
||||
vm.loading = true;
|
||||
request({
|
||||
url: `/nebula_operate/desctag/${vm.space}/${vm.form.labels}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.loading = false;
|
||||
vm.infoList = res.data;
|
||||
});
|
||||
},
|
||||
resolveProperties(properties, map) { // 处理节点和边的属性
|
||||
let _infoList = [];
|
||||
Reflect.ownKeys(properties).forEach(key => {
|
||||
_infoList.push({
|
||||
comment: map[key],
|
||||
field: key,
|
||||
value: properties[key]
|
||||
});
|
||||
});
|
||||
vm.infoList = _infoList;
|
||||
},
|
||||
removeItem() {
|
||||
this.$confirm('此操作将永久删除选中节点, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: `/nebula_operate/deletevertex/${vm.selectObj.vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.$parent.querySpaceGraphData();
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
submitUpdate() { // 更新
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
let _ob = {};
|
||||
vm.infoList.forEach(info => {
|
||||
_ob[info.field] = info.value;
|
||||
});
|
||||
// 添加节点
|
||||
request({
|
||||
url: `/nebula_operate/insertvertex/${vm.space}/${vm.form.labels}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
vid: vm.selectObj.vid,
|
||||
ob: _ob
|
||||
}
|
||||
}).then(res => {
|
||||
vm.$parent.findNodeById(vm.tag,res.data.vid);
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.form-box {
|
||||
height: 900px;
|
||||
overflow-y: auto;
|
||||
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
|
||||
.btn-box {
|
||||
text-align: right;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.node-box .title {
|
||||
font-size: 18px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
174
web/src/components/dialog/NoumenonEdgeModify.vue
Normal file
174
web/src/components/dialog/NoumenonEdgeModify.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<!-- 本体间关系信息修改 -->
|
||||
<div class="node-box">
|
||||
<div class="form-title">关系配置</div>
|
||||
<el-form ref="relationForm" label-width="100px" label-position="left">
|
||||
<el-form-item label="*关系名称">
|
||||
<el-input v-model="modifyCmd.edgeName" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="关系描述">
|
||||
<el-input v-model="modifyCmd.label"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示箭头">
|
||||
<el-radio v-model="modifyCmd.arrow" :label="true" disabled>是</el-radio>
|
||||
<el-radio v-model="modifyCmd.arrow" :label="false" disabled>否</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item label="头概念">
|
||||
<el-input v-model="modifyCmd.start" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="尾概念">
|
||||
<el-input v-model="modifyCmd.end" disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-title">关系属性(选填)</div>
|
||||
<el-table :data="fields"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="field" label="属性名"></el-table-column>
|
||||
<el-table-column prop="comment" label="描述"></el-table-column>
|
||||
<el-table-column prop="type" label="类型"></el-table-column>
|
||||
<!-- <el-table-column prop="len" label="长度"></el-table-column>-->
|
||||
<el-table-column label="操作" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="removeAttribute(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="add-attribute-box" @click="showAddAttributeDialog('source')">添加字段</div>
|
||||
<el-button type="primary" @click="submitUpdateEdge" style="float: right;margin-top: 20px">确 定</el-button>
|
||||
<el-dialog
|
||||
title="新增属性"
|
||||
:append-to-body="true"
|
||||
:visible.sync="addAttributeDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="addAttributeCmd" label-width="80px">
|
||||
<el-form-item label="属性名">
|
||||
<el-input v-model="addAttributeCmd.field"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="addAttributeCmd.comment"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="addAttributeCmd.type" style="width: 100%">
|
||||
<el-option :label="item" :value="item" v-for="item in type" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="长度">-->
|
||||
<!-- <el-input v-model="addAttributeCmd.len"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addAttributeDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddAttribute">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
modifyCmd: {
|
||||
edgeName: '',
|
||||
label: '',
|
||||
arrow: '',
|
||||
start: '',
|
||||
end: ''
|
||||
},
|
||||
fields: [],
|
||||
addAttributeDialogVisible: false,
|
||||
addAttributeCmd: {
|
||||
field: '',
|
||||
type: '',
|
||||
comment: ''
|
||||
},
|
||||
selectObj: {
|
||||
type: '',
|
||||
value: {}
|
||||
},
|
||||
type: ["INT64", "INT32", "INT16", "INT8", "FLOAT", "DOUBLE", "BOOL", "STRING", "DATE", "TIME", "DATETIME", "FIXED_STRING"],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
updateValue(edgeName, label, arrow, fields, sourceVid, targetVid) {
|
||||
vm.modifyCmd = {
|
||||
edgeName: edgeName,
|
||||
label: label,
|
||||
arrow: arrow,
|
||||
start: '',
|
||||
end: ''
|
||||
};
|
||||
vm.fields = fields || [];
|
||||
vm.queryNode(sourceVid, "start");
|
||||
vm.queryNode(targetVid, "end");
|
||||
},
|
||||
queryNode(vid, comment) {
|
||||
request({
|
||||
url: `/nebula_model/findnodebyid/${vm.ontologyId}/${vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.modifyCmd[comment] = res.data.properties.label;
|
||||
console.log(vm.modifyCmd)
|
||||
});
|
||||
},
|
||||
removeAttribute(item, index) {
|
||||
vm.fields.splice(index, 1);
|
||||
},
|
||||
showAddAttributeDialog(type) {
|
||||
vm.addAttributeCmd = {
|
||||
type: '',
|
||||
field: '',
|
||||
comment: ''
|
||||
};
|
||||
vm.addAttributeDialogVisible = true;
|
||||
vm.attributeType = type;
|
||||
},
|
||||
submitAddAttribute() {
|
||||
vm.fields.push(vm.addAttributeCmd);
|
||||
vm.addAttributeDialogVisible = false;
|
||||
},
|
||||
submitUpdateEdge() { // 更新
|
||||
vm.$parent.submitUpdateEdge(vm.modifyCmd);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
307
web/src/components/dialog/NoumenonInfo.vue
Normal file
307
web/src/components/dialog/NoumenonInfo.vue
Normal file
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<!-- 本体节点信息 -->
|
||||
<div style="display: flex">
|
||||
<div class="node-box" style="flex:1;padding-right: 20px">
|
||||
<div class="form-title">概念描述</div>
|
||||
<el-form ref="relationForm" label-width="100px" label-position="left">
|
||||
<el-form-item label="概念名">
|
||||
<el-input v-model="modifyCmd.tagName" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="概念描述">
|
||||
<el-input v-model="modifyCmd.label" @change="handleNodeCommentChange"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-title">概念属性</div>
|
||||
<el-table :data="fields"
|
||||
height="500"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="comment" label="属性描述">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.comment" v-if="scope.$index === fields.length - 1"
|
||||
@change="(fieldId) => {handleFieldSelectChange(fieldId, scope.$index)}" filterable>
|
||||
<template v-for="field in fieldList">
|
||||
<el-option :value="field.id" :label="field.comment" v-if="judgeExist(field)"
|
||||
:key="field.id"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
<label v-else>{{ scope.row.comment }}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="comment" label="描述"></el-table-column>-->
|
||||
<el-table-column prop="type" label="类型"></el-table-column>
|
||||
<el-table-column label="删除" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="removeField(scope.row,scope.$index)" type="text" size="small">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="node-box" style="flex:1;border-right: 1px solid #EBEEF5;padding-left: 20px;">
|
||||
<div class="form-title" style="margin-top: 0px">对象属性</div>
|
||||
<el-table :data="relationData"
|
||||
height="675"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="edgeName" label="关系">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.label" v-if="scope.$index === relationData.length - 1"
|
||||
@change="handleRelationSelectChange(scope.row.label,scope.row.dstId, scope.$index)" filterable>
|
||||
<template v-for="relation in relationOptions">
|
||||
<el-option :value="relation.label" :label="relation.label"
|
||||
:key="relation.label"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
<label v-else>{{ scope.row.label }}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="尾概念">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.dstId" v-if="scope.$index === relationData.length - 1"
|
||||
@change="handleRelationSelectChange(scope.row.label,scope.row.dstId, scope.$index)" filterable>
|
||||
<template v-for="node in nodeOptions">
|
||||
<el-option :value="node.ownId" :label="node.label"
|
||||
:key="node.ownId"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
<label v-else>{{nodeObj[scope.row.dstId]}}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="删除" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.native.prevent="removeRelation(scope.row,scope.$index)" type="text" size="small">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
var _ = require('lodash');
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
modifyCmd: {
|
||||
id: '',
|
||||
tagName: '',
|
||||
label: '',
|
||||
ownId:'',
|
||||
ontologyId:''
|
||||
},
|
||||
fields: [],
|
||||
fieldList: [],
|
||||
relationData:[],
|
||||
relationOptions:[],
|
||||
nodeOptions:[],
|
||||
nodeObj:{}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
updateValue(ontologyId, ownId, id) {
|
||||
vm.queryFieldList(ontologyId);
|
||||
vm.queryRelations(ontologyId);
|
||||
vm.queryNodes(ontologyId, ownId);
|
||||
vm.modifyCmd.id = id;
|
||||
vm.modifyCmd.ownId = ownId;
|
||||
vm.modifyCmd.ontologyId = ontologyId;
|
||||
vm.queryField(ontologyId, ownId)
|
||||
},
|
||||
//查询概念属性
|
||||
queryField(ontologyId,ownId){
|
||||
request({
|
||||
url: `/nebula_model/findnodebyid/${ontologyId}/${ownId}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.modifyCmd.tagName = _.get(res.data, "properties.tagName", '');
|
||||
vm.modifyCmd.label = _.get(res.data, "properties.label", '');
|
||||
let _fields = _.get(res.data, "properties.nebulafieldsnapshot", '');
|
||||
if (!_fields) {
|
||||
_fields = [];
|
||||
}
|
||||
_fields.push({
|
||||
comment: '',
|
||||
type: '',
|
||||
field:''
|
||||
});
|
||||
vm.fields = _fields;
|
||||
});
|
||||
},
|
||||
//查询对象属性列表
|
||||
queryRelationData(ontologyId,ownId){
|
||||
vm.relationData = [];
|
||||
request({
|
||||
url: `/nebula_model/findlistpathbyid/${ontologyId}/${ownId}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if(res.data){
|
||||
res.data.forEach(item => {
|
||||
vm.relationData.push({label:item.relation.properties.label,
|
||||
ontologyId:item.relation.properties.ontologyId,srcId:item.relation.srcId,dstId:item.relation.dstId});
|
||||
})
|
||||
}
|
||||
vm.relationData.push({label:"",
|
||||
ontologyId:ontologyId,srcId:ownId,dstId:""});
|
||||
});
|
||||
},
|
||||
//查询关系列表
|
||||
queryRelations(ontologyId){
|
||||
request({
|
||||
url: `/ontology-relation/query_list/${ontologyId}`,
|
||||
method: 'post',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.relationOptions = res.data;
|
||||
});
|
||||
},
|
||||
//查询尾结点列表
|
||||
queryNodes(ontologyId, ownId){
|
||||
request({
|
||||
url: `/ontology-concept/query_list/${ontologyId}`,
|
||||
method: 'post',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.forEach(item => {
|
||||
vm.nodeObj[item.ownId] = item.label
|
||||
})
|
||||
vm.nodeOptions = res.data;
|
||||
vm.queryRelationData(ontologyId,ownId);
|
||||
});
|
||||
},
|
||||
judgeExist(field) {
|
||||
let index = vm.fields.findIndex(f => {
|
||||
return f.comment === field.comment;
|
||||
});
|
||||
return index < 0;
|
||||
},
|
||||
handleFieldSelectChange(fieldId, rowIndex) { // 值属性选择框变化
|
||||
let fieldIndex = vm.fieldList.findIndex(f => {
|
||||
return f.id === fieldId;
|
||||
});
|
||||
if (fieldId >= 0) {
|
||||
vm.fields[rowIndex] = {
|
||||
comment:vm.fieldList[fieldIndex].comment,
|
||||
type: vm.fieldList[fieldIndex].type,
|
||||
field:vm.fieldList[fieldIndex].field
|
||||
};
|
||||
request({
|
||||
url: '/nebula_model/insertmodelvertex',
|
||||
method: 'post',
|
||||
data: {vid:vm.modifyCmd.ownId,ontologyId:vm.modifyCmd.ontologyId,tagName:vm.modifyCmd.tagName,label:vm.modifyCmd.label,fields:vm.fields}
|
||||
}).then(res => {
|
||||
vm.queryField(vm.modifyCmd.ontologyId, vm.modifyCmd.ownId);
|
||||
vm.$message.success("添加成功");
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
//关系、尾结点选择框变化
|
||||
handleRelationSelectChange(label,dstId,rowIndex){
|
||||
if(label && dstId){
|
||||
request({
|
||||
url: '/nebula_model/insertmodeledge',
|
||||
method: 'post',
|
||||
data: vm.relationData[rowIndex]
|
||||
}).then(res => {
|
||||
vm.relationData.push({label:"",
|
||||
ontologyId:vm.modifyCmd.ontologyId,srcId:vm.modifyCmd.ownId,dstId:""});
|
||||
vm.$message.success("添加成功");
|
||||
});
|
||||
}
|
||||
},
|
||||
removeRelation(row,index) { // 删除对象属性
|
||||
// 对接接口
|
||||
request({
|
||||
url: '/nebula_model/deletemodeledge',
|
||||
method: 'post',
|
||||
data: row
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.relationData.splice(index,1);
|
||||
vm.relationData.push({label:"",
|
||||
ontologyId:vm.modifyCmd.ontologyId,srcId:vm.modifyCmd.ownId,dstId:""});
|
||||
});
|
||||
},
|
||||
queryFieldList(ontologyId) { // 查询全部的值属性
|
||||
request({
|
||||
url: `/ontology-field/query_list/${ontologyId}`,
|
||||
method: 'post',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.fieldList = res.data;
|
||||
});
|
||||
},
|
||||
removeField(row, index) { // 删除值属性
|
||||
var newFields = JSON.parse(JSON.stringify(vm.fields));
|
||||
newFields.splice(newFields.length - 1,1);
|
||||
newFields.splice(index,1);
|
||||
// 对接接口
|
||||
request({
|
||||
url: '/nebula_model/insertmodelvertex',
|
||||
method: 'post',
|
||||
data: {vid:vm.modifyCmd.ownId,ontologyId:vm.modifyCmd.ontologyId,tagName:vm.modifyCmd.tagName,label:vm.modifyCmd.label,fields:newFields}
|
||||
}).then(res => {
|
||||
vm.queryField(vm.modifyCmd.ontologyId, vm.modifyCmd.ownId);
|
||||
vm.$message.success("删除成功");
|
||||
});
|
||||
},
|
||||
handleNodeCommentChange() { // 概念描述修改,自动保存
|
||||
request({
|
||||
url: '/ontology-concept/modify',
|
||||
method: 'post',
|
||||
data: {
|
||||
ownId: vm.modifyCmd.ownId,
|
||||
label: vm.modifyCmd.label
|
||||
}
|
||||
}).then(res => {
|
||||
vm.$message.success("概念描述修改成功");
|
||||
vm.$parent.queryTreeData();
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
142
web/src/components/dialog/NoumenonModify.vue
Normal file
142
web/src/components/dialog/NoumenonModify.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<!-- 本体节点信息修改 -->
|
||||
<div class="node-box">
|
||||
<div class="form-title">节点配置</div>
|
||||
<el-form ref="relationForm" label-width="100px" label-position="left">
|
||||
<el-form-item label="*概念名">
|
||||
<el-input v-model="modifyCmd.tagName" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="概念描述">
|
||||
<el-input v-model="modifyCmd.label"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-title">概念属性(选填)</div>
|
||||
<el-table :data="fields"
|
||||
height="500"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="field" label="属性名"></el-table-column>
|
||||
<el-table-column prop="comment" label="描述"></el-table-column>
|
||||
<el-table-column prop="type" label="类型"></el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="removeAttribute(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="add-attribute-box" @click="showAddAttributeDialog('source')">添加字段</div>
|
||||
<el-button type="primary" @click="submitUpdateNode" style="float: right;margin-top: 20px">确 定</el-button>
|
||||
<el-dialog
|
||||
title="新增属性"
|
||||
:append-to-body="true"
|
||||
:visible.sync="addAttributeDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="addAttributeCmd" label-width="80px">
|
||||
<el-form-item label="属性名称">
|
||||
<el-input v-model="addAttributeCmd.field"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="addAttributeCmd.comment"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="addAttributeCmd.type" style="width: 100%">
|
||||
<el-option :label="item" :value="item" v-for="item in dataType" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addAttributeDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddAttribute">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
modifyCmd: {
|
||||
vid: '',
|
||||
tagName: '',
|
||||
label: '',
|
||||
},
|
||||
fields: [],
|
||||
addAttributeDialogVisible: false,
|
||||
addAttributeCmd: {
|
||||
field: '',
|
||||
type: '',
|
||||
comment: ''
|
||||
},
|
||||
selectObj: {
|
||||
type: '',
|
||||
value: {}
|
||||
},
|
||||
dataType: ["INT64", "INT32", "INT16", "INT8", "FLOAT", "DOUBLE", "BOOL", "STRING", "DATE", "TIME", "DATETIME", "FIXED_STRING"],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
updateValue(tagName, label, fields) {
|
||||
vm.modifyCmd.tagName = tagName;
|
||||
vm.modifyCmd.label = label;
|
||||
vm.fields = fields;
|
||||
},
|
||||
removeAttribute(item, index) {
|
||||
vm.fields.splice(index, 1);
|
||||
},
|
||||
showAddAttributeDialog(type) {
|
||||
vm.addAttributeCmd = {
|
||||
type: '',
|
||||
field: '',
|
||||
comment: ''
|
||||
};
|
||||
vm.addAttributeDialogVisible = true;
|
||||
vm.attributeType = type;
|
||||
},
|
||||
submitAddAttribute() {
|
||||
vm.fields.push(vm.addAttributeCmd);
|
||||
vm.addAttributeDialogVisible = false;
|
||||
},
|
||||
submitUpdateNode() { // 更新
|
||||
vm.$parent.submitUpdateNode(vm.modifyCmd);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
278
web/src/components/dialog/TagModify.vue
Normal file
278
web/src/components/dialog/TagModify.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<!-- 标签信息修改 -->
|
||||
<div class="node-box">
|
||||
<div class="title"> {{ editFlag ? '编辑' : '新建' }}</div>
|
||||
<el-form ref="relationForm" label-width="100px" label-position="left">
|
||||
<el-form-item label="*标签名称">
|
||||
<el-input v-model="modifyCmd.name" :disabled="editFlag"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="modifyCmd.comment"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-title">定义属性</div>
|
||||
<el-table :data="fields"
|
||||
height="550"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column prop="comment" label="属性名称"></el-table-column>
|
||||
<el-table-column prop="type" label="数据类型"></el-table-column>
|
||||
<!-- <el-table-column prop="Null" label="允许空值"></el-table-column>-->
|
||||
<!-- <el-table-column prop="Default" label="默认值"></el-table-column>-->
|
||||
<!-- <el-table-column prop="Comment" label="描述"></el-table-column>-->
|
||||
<el-table-column label="操作" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="modifyField(scope.row, scope.$index)">编辑</el-button>
|
||||
<el-button type="text" size="small" @click="removeField(scope.row, scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="add-attribute-box" @click="showAddFieldDialog('source')">添加字段</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="btn-box">
|
||||
<el-button type="danger" @click="removeTag" v-show="editFlag">删 除</el-button>
|
||||
<el-button type="primary" @click="submitUpdateNode">保 存</el-button>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="dialogName"
|
||||
:append-to-body="true"
|
||||
:visible.sync="fieldDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="fieldCmd" label-width="80px">
|
||||
<el-form-item label="属性名称">
|
||||
<el-input v-model="fieldCmd.comment" :disabled="dialogName == '编辑属性'"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据类型">
|
||||
<el-select v-model="fieldCmd.type" style="width: 100%">
|
||||
<el-option :label="item" :value="item" v-for="item in dataType"
|
||||
:key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="允许空值">-->
|
||||
<!-- <el-switch-->
|
||||
<!-- v-model="fieldCmd.Null"-->
|
||||
<!-- active-color="#13ce66"-->
|
||||
<!-- inactive-color="#ff4949"-->
|
||||
<!-- active-value="YES"-->
|
||||
<!-- inactive-value="NO">-->
|
||||
<!-- </el-switch>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="默认值">-->
|
||||
<!-- <el-input v-model="fieldCmd.Default"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="描述">-->
|
||||
<!-- <el-input v-model="fieldCmd.Comment" type="textarea"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="fieldDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddField">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from '@/utils/request';
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
space: '',
|
||||
modifyCmd: {
|
||||
name: '',
|
||||
fields: []
|
||||
},
|
||||
editFlag: false,
|
||||
fields: [],
|
||||
fieldDialogVisible: false,
|
||||
fieldCmd: {
|
||||
field: '',
|
||||
type: ''
|
||||
},
|
||||
dialogName: '添加属性',
|
||||
selectObj: {
|
||||
type: '',
|
||||
value: {}
|
||||
},
|
||||
dataType: ["INT64", "INT32", "INT16", "INT8", "FLOAT", "DOUBLE", "BOOL", "STRING", "DATE", "TIME", "DATETIME", "FIXED_STRING"],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
updateValue(space, name) {
|
||||
vm.space = space;
|
||||
vm.modifyCmd.name = name;
|
||||
if (name.length > 0) {
|
||||
vm.queryTagDescribe();
|
||||
request({
|
||||
url: `/nebula_operate/showcreatetag/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.modifyCmd.comment = res.data.comment;
|
||||
vm.modifyCmd = JSON.parse(JSON.stringify(vm.modifyCmd))
|
||||
});
|
||||
vm.editFlag = true;
|
||||
} else {
|
||||
vm.editFlag = false;
|
||||
vm.fields = [];
|
||||
vm.modifyCmd.comment = "";
|
||||
}
|
||||
},
|
||||
queryTagDescribe() {
|
||||
request({
|
||||
url: `/nebula_operate/desctag/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.forEach(item => {
|
||||
item.type = item.type.toUpperCase()
|
||||
});
|
||||
vm.fields = res.data;
|
||||
});
|
||||
},
|
||||
modifyField(item, index) {
|
||||
vm.dialogName = '编辑属性';
|
||||
vm.fieldCmd = JSON.parse(JSON.stringify(item));
|
||||
vm.fieldCmd.index = index;
|
||||
vm.fieldDialogVisible = true;
|
||||
},
|
||||
removeField(item, index) {
|
||||
vm.fields.splice(index, 1);
|
||||
if (vm.editFlag) { // 编辑tag,需要提交请求
|
||||
vm.modifyCmd.fields = [item];
|
||||
request({
|
||||
url: `/nebula_operate/alterdroptag/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
});
|
||||
}
|
||||
},
|
||||
showAddFieldDialog(type) {
|
||||
vm.fieldCmd = {
|
||||
field: '',
|
||||
type: '',
|
||||
null: 'YES',
|
||||
};
|
||||
vm.dialogName = '添加属性';
|
||||
vm.fieldDialogVisible = true;
|
||||
},
|
||||
submitAddField() {
|
||||
if (!vm.editFlag) { // 新建的tag,不需要即时提交
|
||||
if (vm.dialogName == '添加属性') {
|
||||
vm.fields.push(vm.fieldCmd);
|
||||
} else if (vm.dialogName == '编辑属性') {
|
||||
vm.fields[vm.fieldCmd.index] = vm.fieldCmd;
|
||||
}
|
||||
vm.fieldDialogVisible = false;
|
||||
} else {
|
||||
vm.modifyCmd.fields = [vm.fieldCmd];
|
||||
if (vm.dialogName == '添加属性') {
|
||||
request({
|
||||
url: `/nebula_operate/alteraddtag/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.fields.push(vm.fieldCmd);
|
||||
console.log(vm.fields);
|
||||
vm.fieldDialogVisible = false;
|
||||
});
|
||||
} else if (vm.dialogName == '编辑属性') {
|
||||
request({
|
||||
url: `/nebula_operate/alterchangetag/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.fields[vm.fieldCmd.index] = vm.fieldCmd;
|
||||
vm.fieldDialogVisible = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
submitUpdateNode() { // 更新
|
||||
if (vm.modifyCmd.name.length === 0) {
|
||||
vm.$message.warning("标签名称不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
vm.modifyCmd.fields = vm.fields;
|
||||
if (!vm.editFlag) { // 新建
|
||||
request({
|
||||
url: `/nebula_operate/createtag/${vm.space}`,
|
||||
method: 'post',
|
||||
data: vm.modifyCmd
|
||||
}).then(res => {
|
||||
vm.$parent.queryTagList();
|
||||
});
|
||||
} else { // 编辑
|
||||
vm.$parent.queryTagList();
|
||||
}
|
||||
},
|
||||
removeTag() {
|
||||
vm.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: `/nebula_operate/droptag/${vm.space}/${vm.modifyCmd.name}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.$parent.queryTagList();
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn-box {
|
||||
text-align: right;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.node-box .title {
|
||||
font-size: 18px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
226
web/src/components/dialog/TreeGraphInfo.vue
Normal file
226
web/src/components/dialog/TreeGraphInfo.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<!-- 树形图谱 -->
|
||||
<div>
|
||||
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="树形图谱" name="first">
|
||||
<div style=""></div>
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
node-key="vid"
|
||||
:default-expanded-keys="['root']"
|
||||
:props="defaultProps"
|
||||
@node-drop="handleDrop"
|
||||
:expand-on-click-node="false"
|
||||
draggable
|
||||
:allow-drag="allowDrag"
|
||||
style="height: 650px;overflow-y: auto;">
|
||||
<span class="custom-tree-node" slot-scope="{ node, data }">
|
||||
<span>{{ node.label }}</span>
|
||||
<span class="btn-box">
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="() => appendChild(data)">
|
||||
添加子节点
|
||||
</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="() => removeNode(data)">
|
||||
删除
|
||||
</el-button>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</el-tab-pane>
|
||||
<!-- <el-tab-pane label="统计信息" name="second">-->
|
||||
<!-- </el-tab-pane>-->
|
||||
</el-tabs>
|
||||
<el-dialog
|
||||
title="添加子节点"
|
||||
:append-to-body="true"
|
||||
:visible.sync="cmdDialogVisible"
|
||||
width="40%">
|
||||
<el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd">
|
||||
<el-form-item label="子节点类名称" prop="tagName">
|
||||
<el-input v-model="cmd.tagName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="子节点类描述">
|
||||
<el-input v-model="cmd.label"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cmdDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAppendChild">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from "@/utils/request";
|
||||
import {tripletToTree} from "@/utils/common";
|
||||
|
||||
var vm;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
},
|
||||
activeName: 'first',
|
||||
ontologyId: '',
|
||||
treeData: [],
|
||||
cmdDialogVisible: false,
|
||||
cmd: {},
|
||||
rules: {
|
||||
tagName: [
|
||||
{required: true, message: '请输入子节点类名称'}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
queryTreeData(ontologyId) {
|
||||
if (vm.ontologyId === ontologyId) {
|
||||
return;
|
||||
}
|
||||
vm.refreshTree(ontologyId);
|
||||
},
|
||||
refreshTree(ontologyId) {
|
||||
if (ontologyId) {
|
||||
vm.ontologyId = ontologyId;
|
||||
}
|
||||
request({
|
||||
url: `/nebula_model/findtreebyontologyid/${vm.ontologyId}`,
|
||||
method: 'post',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
res.data.nodes.forEach(node => {
|
||||
node.label = node.properties.label || '未命名';
|
||||
});
|
||||
vm.treeData = [{
|
||||
vid: "root",
|
||||
label: '根节点',
|
||||
children: tripletToTree({
|
||||
nodes: res.data.nodes,
|
||||
relations: res.data.relations,
|
||||
idName: 'vid',
|
||||
sourceName: 'srcId',
|
||||
targetName: 'dstId'
|
||||
})
|
||||
}];
|
||||
console.log(vm.treeData);
|
||||
});
|
||||
},
|
||||
handleDrop(draggingNode, dropNode, dropType, ev) { // 树形拖拽完成时触发
|
||||
console.log("drop success");
|
||||
},
|
||||
allowDrag(draggingNode) { // judge node can be drag
|
||||
return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
|
||||
},
|
||||
destroyTree() {
|
||||
},
|
||||
appendChild(parent) {
|
||||
vm.cmdDialogVisible = true;
|
||||
vm.$nextTick(() => {
|
||||
vm.cmd = {
|
||||
tagName: '',
|
||||
label: '',
|
||||
ontologyId: vm.ontologyId,
|
||||
parentId: parent.vid
|
||||
};
|
||||
vm.$refs.cmd.resetFields();
|
||||
});
|
||||
},
|
||||
submitAppendChild() {
|
||||
this.$refs.cmd.validate((valid) => {
|
||||
if (valid) {
|
||||
request({
|
||||
url: `/nebula_model/insertchildmodelvertex/${vm.cmd.parentId}`,
|
||||
method: 'post',
|
||||
data: vm.cmd
|
||||
}).then(res => {
|
||||
vm.$message.success("添加成功");
|
||||
vm.cmdDialogVisible = false;
|
||||
vm.refreshTree();
|
||||
vm.$parent.queryTagData();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
removeNode(node) {
|
||||
this.$confirm('此操作将永久删除选中节点和关系, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
request({
|
||||
url: `/nebula_model/deletemodelvertex/${node.vid}`,
|
||||
method: 'get',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
vm.$message.success("删除成功");
|
||||
vm.refreshTree();
|
||||
vm.$parent.queryTagData();
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
handleTabClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.el-tree-node__content .btn-box {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-tree-node__content:hover .btn-box {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
</style>
|
||||
244
web/src/components/dialog/TreeGraphInfo2.vue
Normal file
244
web/src/components/dialog/TreeGraphInfo2.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<!-- 树形图谱 -->
|
||||
<el-tabs v-model="activeName" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="树形图谱" name="first">
|
||||
<div id="container"></div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="统计信息" name="second">
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import G6 from '@antv/g6';
|
||||
import request from "@/utils/request";
|
||||
import {tripletToTree} from "@/utils/common";
|
||||
|
||||
let data;
|
||||
var vm;
|
||||
var graph;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
vm = this;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
queryTreeData(ontologyId) {
|
||||
if (graph) {
|
||||
return;
|
||||
}
|
||||
request({
|
||||
url: `/nebula_model/findtreebyontologyid/${ontologyId}`,
|
||||
method: 'post',
|
||||
data: {}
|
||||
}).then(res => {
|
||||
data = {
|
||||
id: "root",
|
||||
properties: {tagName: '根节点'},
|
||||
children: tripletToTree({
|
||||
nodes: res.data.nodes,
|
||||
relations: res.data.relations,
|
||||
idName: 'vid',
|
||||
sourceName: 'srcId',
|
||||
targetName: 'dstId'
|
||||
})
|
||||
};
|
||||
vm.initTree();
|
||||
});
|
||||
|
||||
},
|
||||
destroyTree() {
|
||||
if (graph) {
|
||||
graph = null;
|
||||
document.getElementById('container').innerHTML = "";
|
||||
}
|
||||
},
|
||||
initTree() { // 初始化数据
|
||||
const container = document.getElementById('container');
|
||||
const width = container.scrollWidth;
|
||||
const height = (container.scrollHeight || 800) - 20;
|
||||
graph = new G6.TreeGraph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
modes: {
|
||||
default: [
|
||||
'drag-canvas',
|
||||
'zoom-canvas',
|
||||
{
|
||||
type: 'drag-node',
|
||||
enableDelegate: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultNode: {
|
||||
size: 25,
|
||||
anchorPoints: [
|
||||
[0, 0.5],
|
||||
[1, 0.5],
|
||||
],
|
||||
style: {
|
||||
|
||||
fill: '#68BDF6',
|
||||
stroke: '#4b4b4b',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
type: 'cubic-horizontal',
|
||||
style: {
|
||||
stroke: '#A3B1BF',
|
||||
},
|
||||
},
|
||||
nodeStateStyles: {
|
||||
closest: {
|
||||
fill: '#004f80',
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
type: 'compactBox',
|
||||
direction: 'LR',
|
||||
getId: function getId(d) {
|
||||
return d.id;
|
||||
},
|
||||
getHeight: function getHeight() {
|
||||
return 16;
|
||||
},
|
||||
getWidth: function getWidth() {
|
||||
return 16;
|
||||
},
|
||||
getVGap: function getVGap() {
|
||||
return 10;
|
||||
},
|
||||
getHGap: function getHGap() {
|
||||
return 100;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
graph.node(function (node) {
|
||||
node.tagName = (node.properties && node.properties.tagName) ? node.properties.tagName : '未命名';
|
||||
return {
|
||||
label: node.tagName,
|
||||
labelCfg: {
|
||||
offset: 10,
|
||||
position: node.children && node.children.length > 0 ? 'left' : 'right',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
graph.fitView();
|
||||
|
||||
let minDisNode;
|
||||
graph.on('node:dragstart', (e) => {
|
||||
minDisNode = undefined;
|
||||
});
|
||||
graph.on('node:drag', (e) => {
|
||||
minDisNode = undefined;
|
||||
const item = e.item;
|
||||
const model = item.getModel();
|
||||
const nodes = graph.getNodes();
|
||||
let minDis = Infinity;
|
||||
nodes.forEach((inode) => {
|
||||
graph.setItemState(inode, 'closest', false);
|
||||
const node = inode.getModel();
|
||||
if (node.id === model.id) return;
|
||||
const dis = (node.x - e.x) * (node.x - e.x) + (node.y - e.y) * (node.y - e.y);
|
||||
if (dis < minDis) {
|
||||
minDis = dis;
|
||||
minDisNode = inode;
|
||||
}
|
||||
});
|
||||
// console.log('minDis', minDis, minDisNode);
|
||||
if (minDis < 2000) graph.setItemState(minDisNode, 'closest', true);
|
||||
else minDisNode = undefined;
|
||||
});
|
||||
|
||||
graph.on('node:dragend', (e) => {
|
||||
if (!minDisNode) {
|
||||
// descriptionDiv.innerHTML = '失败,拖动的节点附近没有节点';
|
||||
return;
|
||||
}
|
||||
const item = e.item;
|
||||
const id = item.getID();
|
||||
const data = graph.findDataById(id);
|
||||
// if the minDisNode is a descent of the dragged node, return
|
||||
let isDescent = false;
|
||||
const minDisNodeId = minDisNode.getID();
|
||||
console.log('dragend', minDisNodeId, isDescent, data, id);
|
||||
|
||||
G6.Util.traverseTree(data, (d) => {
|
||||
if (d.id === minDisNodeId) isDescent = true;
|
||||
});
|
||||
if (isDescent) {
|
||||
vm.$message.error("目标节点是被拖动节点的后代");
|
||||
return;
|
||||
}
|
||||
graph.removeChild(id);
|
||||
|
||||
setTimeout(() => {
|
||||
const newParentData = graph.findDataById(minDisNodeId);
|
||||
let newChildren = newParentData.children;
|
||||
if (newChildren) newChildren.push(data);
|
||||
else newChildren = [data];
|
||||
graph.updateChildren(newChildren, minDisNodeId);
|
||||
vm.$message.success("操作成功");
|
||||
}, 600);
|
||||
});
|
||||
|
||||
if (typeof window !== 'undefined')
|
||||
window.onresize = () => {
|
||||
if (!graph || graph.get('destroyed')) return;
|
||||
if (!container || !container.scrollWidth || !container.scrollHeight) return;
|
||||
graph.changeSize(container.scrollWidth, container.scrollHeight - 20);
|
||||
};
|
||||
},
|
||||
destroyTreeGraph() {
|
||||
|
||||
},
|
||||
handleTabClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
submitUpdate() { // 更新
|
||||
vm.$parent.submitUpdateEdge(vm.modifyCmd);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.node-box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 16px;
|
||||
margin: 15px 0;
|
||||
|
||||
}
|
||||
|
||||
.add-attribute-box {
|
||||
margin-top: 10px;
|
||||
color: #409EFF;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-content > div {
|
||||
margin-bottom: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user