推荐系统初始化

This commit is contained in:
2023-05-09 17:53:58 +08:00
commit 9f8c374ac2
406 changed files with 68905 additions and 0 deletions

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>