top图和top图表格权限管理

This commit is contained in:
clay 2021-07-21 01:36:16 +08:00
parent 49dcaa80b9
commit 8f0cfe1fb3
22 changed files with 1536 additions and 723 deletions

View File

@ -0,0 +1,65 @@
import request from '@/utils/request'
// 查询top万能查询主列表
export function listTable(data) {
return request({
url: '/tool/table/list',
method: 'post',
data: data
})
}
// 导出top万能查询主
export function exportTable(data) {
return request({
url: '/tool/table/export',
method: 'post',
data: data
})
}
// 导入表
export function importTopTable(data) {
return request({
url: '/tool/table/importTopTable',
method: 'post',
params: data
})
}
// 查询top万能查询主详细
export function getTable(id) {
return request({
url: '/tool/table/' + id,
method: 'get'
})
}
// 新增top万能查询主
export function addTable(data) {
return request({
url: '/tool/table',
method: 'post',
data: data
})
}
// 修改top万能查询主
export function updateTable(data) {
return request({
url: '/tool/table',
method: 'put',
data: data
})
}
// 删除top万能查询主
export function delTable(id) {
return request({
url: '/tool/table/' + id,
method: 'delete'
})
}

View File

@ -92,19 +92,6 @@ export const constantRoutes = [
} }
] ]
}, },
{
path: '/top',
component: Layout,
hidden: true,
children: [
{
path: '/',
component: (resolve) => require(['@/views/system/top/demo-topology'], resolve),
name:'Top',
meta: {title: 'top视图'}
}
]
},
{ {
path: '/apiclass', path: '/apiclass',
component: Layout, component: Layout,

View File

@ -31,7 +31,7 @@
<el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column> <el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column> <el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="createTime" label="创建时间"></el-table-column> <el-table-column prop="createTime" label="创建时间"></el-table-column>
<el-table-column prop="updateTime" label="更新时间"></el-table-column> <!-- <el-table-column prop="updateTime" label="更新时间"></el-table-column>-->
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total>0"

View File

@ -86,7 +86,6 @@
<el-table v-loading="loading" :data="queryList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="queryList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" width="50"></el-table-column> <el-table-column type="index" width="50"></el-table-column>
<!-- <el-table-column label="id" align="center" prop="id" />-->
<el-table-column label="名称" align="center" prop="uqName" /> <el-table-column label="名称" align="center" prop="uqName" />
<el-table-column label="描述" align="center" prop="uqDescribe" /> <el-table-column label="描述" align="center" prop="uqDescribe" />
<el-table-column label="创建时间" align="center" prop="createTime"> <el-table-column label="创建时间" align="center" prop="createTime">

View File

@ -0,0 +1,119 @@
<template>
<!-- 导入表 -->
<el-dialog title="导入表" :visible.sync="visible" width="800px" top="5vh" append-to-body>
<el-form :model="queryParams" ref="queryForm" :inline="true">
<el-form-item label="表名称" prop="tableName">
<el-input
v-model="queryParams.tableName"
placeholder="请输入表名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="表描述" prop="tableComment">
<el-input
v-model="queryParams.tableComment"
placeholder="请输入表描述"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row>
<el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="createTime" label="创建时间"></el-table-column>
<!-- <el-table-column prop="updateTime" label="更新时间"></el-table-column>-->
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleImportTopTable"> </el-button>
<el-button @click="visible = false"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { listDbTable} from "@/api/tool/gen";
import {importTopTable} from '../../../api/tool/table'
export default {
data() {
return {
//
visible: false,
//
tables: [],
//
total: 0,
//
dbTableList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
tableName: undefined,
tableComment: undefined
}
};
},
methods: {
//
show() {
this.getList();
this.visible = true;
},
clickRow(row) {
this.$refs.table.toggleRowSelection(row);
},
//
handleSelectionChange(selection) {
this.tables = selection.map(item => item.tableName);
},
//
getList() {
listDbTable(this.queryParams).then(res => {
if (res.code === 200) {
this.dbTableList = res.rows;
this.total = res.total;
}
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 导入按钮操作 */
handleImportTopTable() {
importTopTable({ tables: this.tables.join(",") }).then(res => {
this.msgSuccess(res.msg);
if (res.code === 200) {
this.visible = false;
this.$emit("ok");
}
});
}
}
};
</script>

View File

@ -0,0 +1,459 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="表名" prop="tableName">
<el-input
v-model="queryParams.tableName"
placeholder="请输入表名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="更新时间">
<el-date-picker
v-model="daterangeUpdateTime"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['tool:table:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['tool:table:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['tool:table:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-upload"
size="mini"
@click="openImportTable"
v-hasPermi="['tool:gen:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['tool:table:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" align="center">
<template slot-scope="scope">
<span>{{ ((queryParams.pageInfo.pageNum - 1) * queryParams.pageInfo.pageSize + scope.$index + 1)}}</span>
</template>
</el-table-column>
<el-table-column label="表名" align="center" prop="tableName" />
<el-table-column label="表描述" align="center" prop="tableComment" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['tool:table:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['tool:table:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageInfo.pageNum"
:limit.sync="queryParams.pageInfo.pageSize"
@pagination="getList"
/>
<!-- 添加或修改top万能查询主对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="表名:" prop="tableName">
<span>{{form.tableName}}</span>
</el-form-item>
<el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择">
<el-option
v-for="item in roleOptions"
:key="item.roleId"
:label="item.roleName"
:value="item.roleId"
:disabled="item.status == 1"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="表描述" prop="tableComment">
<el-input v-model="form.tableComment" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
<el-col :span="12">
</el-col>
</el-row>
<el-divider content-position="center">top万能查询字段信息</el-divider>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">-->
<!-- <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddTopSearchColumn">添加</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteTopSearchColumn">删除</el-button>-->
<!-- </el-col>-->
</el-row>
<el-table :data="topSearchColumnList" :row-class-name="rowTopSearchColumnIndex" @selection-change="handleTopSearchColumnSelectionChange" ref="topSearchColumn">
<el-table-column label="序号" align="center" prop="index" width="50"/>
<el-table-column label="列名称" prop="columnName">
<template slot-scope="scope">
<span>{{scope.row.columnName}}</span>
</template>
</el-table-column>
<el-table-column label="列描述" prop="columnComment">
<template slot-scope="scope">
<el-input v-model="scope.row.columnComment" placeholder="请输入列描述" />
</template>
</el-table-column>
<el-table-column label="列类型" prop="columnType">
<template slot-scope="scope">
<span>{{scope.row.columnType}}</span>
</template>
</el-table-column>
<el-table-column label="是否使用" prop="isUse" align="center">
<template slot-scope="scope">
<el-checkbox :false-label="0" :true-label="1" v-model="scope.row.isUse"/>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime">
<template slot-scope="scope">
<span>{{scope.row.createTime}}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" prop="updateTime">
<template slot-scope="scope">
<span>{{scope.row.updateTime}}</span>
</template>
</el-table-column>
</el-table>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<import-top-table ref="import" @ok="handleQuery" />
</div>
</template>
<script>
import { listTable, getTable, delTable, addTable, updateTable, exportTable } from "@/api/tool/table";
import {listRole} from '../../../api/system/role'
import importTopTable from "./importTopTable";
export default {
name: "Table",
components: { importTopTable },
data() {
return {
//
loading: true,
//
ids: [],
//
checkedTopSearchColumn: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// top
tableList: [],
//
roleOptions: [],
// top
topSearchColumnList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
daterangeUpdateTime: [],
//
queryParams: {
pageInfo:{
pageNum: 1,
pageSize: 10,
},
params:{},
tableName: null,
tableComment: null,
},
//
form: {
roleIds:[]
},
//
rules: {
}
};
},
created() {
this.getList();
this.getRoleList();
},
methods: {
getRoleList(){
listRole().then(res=>{
this.roleOptions = res.rows
})
},
/** 查询top万能查询主列表 */
getList() {
this.loading = true;
this.queryParams.params={}
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
}
this.queryParams.params={}
if (null != this.daterangeUpdateTime && '' != this.daterangeUpdateTime) {
this.queryParams.params["beginUpdateTime"] = this.daterangeUpdateTime[0];
this.queryParams.params["endUpdateTime"] = this.daterangeUpdateTime[1];
}
listTable(this.queryParams).then(response => {
this.tableList = response.rows;
if(response.total!==undefined){
this.total = response.total;
}
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
tableName: null,
tableComment: null,
remark: null,
roleIds:[],
};
this.topSearchColumnList = [];
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 打开导入表弹窗 */
openImportTable() {
this.$refs.import.show();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.params={}
this.daterangeUpdateTime = [];
this.queryParams.params={}
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加top万能查询主";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getTable(id).then(response => {
this.form = response.data;
this.topSearchColumnList = response.data.topSearchColumnList;
this.open = true;
this.title = "修改top万能查询主";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.form.topSearchColumnList = this.topSearchColumnList;
if (this.form.id != null) {
updateTable(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addTable(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$confirm('是否确认删除top万能查询主编号为"' + ids + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delTable(ids);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** top万能查询字段序号 */
rowTopSearchColumnIndex({ row, rowIndex }) {
row.index = rowIndex + 1;
},
/** top万能查询字段添加按钮操作 */
handleAddTopSearchColumn() {
let obj = {};
obj.columnName = "";
obj.columnComment = "";
obj.columnType = "";
obj.isUse = "";
obj.createTime = "";
obj.updateTime = "";
this.topSearchColumnList.push(obj);
},
/** top万能查询字段删除按钮操作 */
handleDeleteTopSearchColumn() {
if (this.checkedTopSearchColumn.length == 0) {
this.$alert("请先选择要删除的top万能查询字段数据", "提示", { confirmButtonText: "确定", });
} else {
this.topSearchColumnList.splice(this.checkedTopSearchColumn[0].index - 1, 1);
}
},
/** 单选框选中数据 */
handleTopSearchColumnSelectionChange(selection) {
if (selection.length > 1) {
this.$refs.topSearchColumn.clearSelection();
this.$refs.topSearchColumn.toggleRowSelection(selection.pop());
} else {
this.checkedTopSearchColumn = selection;
}
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm('是否确认导出所有top万能查询主数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportTable(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -19,7 +19,14 @@ const isInBBox = (point, bbox) => {
return x < maxX && x > minX && y > minY && y < maxY; return x < maxX && x > minX && y > minY && y < maxY;
}; };
let vm = null;
const sendThis = (_this) => {
vm = _this;
};
export default { export default {
sendThis,
name: 'dice-er-node', name: 'dice-er-node',
options: { options: {
getDefaultCfg() { getDefaultCfg() {
@ -31,8 +38,11 @@ export default {
return { return {
itemHeight: 50, itemHeight: 50,
wheel: "scroll", wheel: "scroll",
"node:click": "click", "node:click": "onNodeClick",
// "node:mousemove": "moves", "edge:click": "onEdgeClick",
"node:contextmenu": "onNodeRightClick",
"edge:contextmenu": "onEdgeRightClick",
"canvas:click": "onCanvasClick",
}; };
}, },
scroll(e) { scroll(e) {
@ -73,7 +83,114 @@ export default {
}, },
click(e) { onNodeClick(event) {
this.shrinkage(event)
vm.currentFocus = "node";
vm.rightMenuShow = false;
this.updateVmData(event);
},
/**
* 点击连线
* @param event
*/
onEdgeClick(event) {
let clickEdge = event.item;
clickEdge.setState("selected", !clickEdge.hasState("selected"));
vm.currentFocus = "edge";
this.updateVmData(event);
},
onNodeRightClick(event) {
let graph = vm.graph;
let clickNode = event.item;
let clickNodeModel = clickNode.getModel();
let selectedNodes = graph.findAllByState("node", "selected");
let selectedNodeIds = selectedNodes.map(item => {
return item.getModel().id;
});
vm.selectedNode = clickNode;
// 如果当前点击节点是之前选中的某个节点,就进行下面的处理
if (selectedNodes.length > 1 && selectedNodeIds.indexOf(clickNodeModel.id) > -1) {
vm.rightMenuShow = true;
let rightMenu = vm.$refs.rightMenu;
rightMenu.style.left = event.clientX + "px";
rightMenu.style.top = event.clientY + "px";
} else {
// 隐藏右键菜单
vm.rightMenuShow = false;
// 先取消所有节点的选中状态
selectedNodes.forEach(node => {
node.setState("selected", false);
});
// 再添加该节点的选中状态
clickNode.setState("selected", true);
vm.currentFocus = "node";
this.updateVmData(event);
}
graph.paint();
},
/**
*
* @param event
*/
onEdgeRightClick(event) {
let graph = vm.graph;
let clickEdge = event.item;
let clickEdgeModel = clickEdge.getModel();
let selectedEdges = graph.findAllByState("edge", "selected");
// 如果当前点击节点不是之前选中的单个节点,才进行下面的处理
if (!(selectedEdges.length === 1 && clickEdgeModel.id === selectedEdges[0].getModel().id)) {
// 先取消所有节点的选中状态
graph.findAllByState("edge", "selected").forEach(edge => {
edge.setState("selected", false);
});
// 再添加该节点的选中状态
clickEdge.setState("selected", true);
vm.currentFocus = "edge";
this.updateVmData(event);
}
let point = { x: event.x, y: event.y };
},
onCanvasClick() {
vm.currentFocus = "canvas";
vm.rightMenuShow = false;
},
updateVmData(event) {
if (event.item._cfg.type === "node") {
let clickNode = event.item;
if (clickNode.hasState("selected")) {
let clickNodeModel = clickNode.getModel();
vm.selectedNode = clickNode;
let nodeAppConfig = { ...vm.nodeAppConfig };
Object.keys(nodeAppConfig).forEach(function(key) {
nodeAppConfig[key] = "";
});
vm.selectedNodeParams = {
label: clickNodeModel.label || "",
attrs:clickNodeModel.attrs,
appConfig: { ...nodeAppConfig, ...clickNodeModel.appConfig }
};
}
} else if (event.item._cfg.type === "edge") {
// 更新vm的data: selectedEdge 和 selectedEdgeParams
let clickEdge = event.item;
if (clickEdge.hasState("selected")) {
let clickEdgeModel = clickEdge.getModel();
vm.selectedEdge = clickEdge;
let edgeAppConfig = { ...vm.edgeAppConfig };
Object.keys(edgeAppConfig).forEach(function(key) {
edgeAppConfig[key] = "";
});
vm.selectedEdgeParams = {
label: clickEdgeModel.label || "",
sourceAttrs:clickEdgeModel.sourceAttrs,
targetAttrs:clickEdgeModel.targetAttrs,
appConfig: { ...edgeAppConfig, ...clickEdgeModel.appConfig }
};
}
}
},
shrinkage(e){
const { const {
graph graph
} = this; } = this;
@ -82,7 +199,7 @@ export default {
if (!item) { if (!item) {
return; return;
} }
if (shape.get("name") === "collapse") { if (shape.get("name") === "collapse") {
graph.updateItem(item, { graph.updateItem(item, {
collapsed: true, collapsed: true,
size: [300, 50], size: [300, 50],
@ -95,13 +212,12 @@ export default {
}); });
setTimeout(() => graph.layout(), 100); setTimeout(() => graph.layout(), 100);
}else { }else {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const model = item.getModel(); const model = item.getModel();
// console.log(JSON.stringify(model)); // console.log(JSON.stringify(model));
// console.log(model.style.default.fill = '#4eb922'); // console.log(model.style.default.fill = '#4eb922');
// console.log(model.style.selected.shadowColor = '#4eb922'); // console.log(model.style.selected.shadowColor = '#4eb922');
}
}
}, },
moves(e) { moves(e) {
const name = e.shape.get("name"); const name = e.shape.get("name");

View File

@ -79,33 +79,35 @@ export default {
let sourceAnchor = self.evtInfo.node.getAnchorPoints(); let sourceAnchor = self.evtInfo.node.getAnchorPoints();
let sourceNodeModel = self.evtInfo.node.getModel(); let sourceNodeModel = self.evtInfo.node.getModel();
console.log("sourceNodeModel",sourceNodeModel)
// 锚点数据 // 锚点数据
let anchorPoints = self.evtInfo.node.getAnchorPoints(); let anchorPoints = self.evtInfo.node.getAnchorPoints();
// 处理线条目标点 // 处理线条目标点
if (anchorPoints && anchorPoints.length) { if (anchorPoints && anchorPoints.length) {
// 获取距离指定坐标最近的一个锚点 // 获取距离指定坐标最近的一个锚点
// sourceAnchor = self.evtInfo.node.getLinkPoint({ sourceAnchor = self.evtInfo.node.getLinkPoint({
// x: event.x, x: event.x,
// y: event.y y: event.y
// }) })
} }
console.log(anchorPoints, sourceAnchor);
self.drawEdge.currentLine = self.graph.addItem("edge", { self.drawEdge.currentLine = self.graph.addItem("edge", {
// id: G6.Util.uniqueId(), // 这种生成id的方式有bug会重复 // id: G6.Util.uniqueId(), // 这种生成id的方式有bug会重复
id: utils.generateUUID(), id: utils.generateUUID(),
// 起始节点 // 起始节点
source: sourceNodeModel.id, source: sourceNodeModel.id,
sourceAttrs:sourceNodeModel.attrs,
sourceAnchor: sourceAnchor ? sourceAnchor.anchorIndex : "", sourceAnchor: sourceAnchor ? sourceAnchor.anchorIndex : "",
// 终止节点/位置 // 终止节点/位置
target: { target: {
x: event.x, x: event.x,
y: event.y y: event.y
}, },
type: self.graph.$C.edge.type || "top-line", type: self.graph.$C.edge.type || "top-cubic",
style: G6.Util.mix({}, themeStyle.edgeStyle.default, self.graph.$C.edge.style) style: themeStyle.edgeStyle.default|| self.graph.$C.edge.style
}); });
self.drawEdge.isMoving = true; self.drawEdge.isMoving = true;
}, },
move(event) { move(event) {
let self = this; let self = this;
if (self.drawEdge.isMoving && self.drawEdge.currentLine) { if (self.drawEdge.isMoving && self.drawEdge.currentLine) {
@ -139,7 +141,8 @@ export default {
} }
self.graph.updateItem(self.drawEdge.currentLine, { self.graph.updateItem(self.drawEdge.currentLine, {
target: targetNodeModel.id, target: targetNodeModel.id,
targetAnchor: targetAnchor ? targetAnchor.anchorIndex : "" targetAnchor: targetAnchor ? targetAnchor.anchorIndex : "",
targetAttrs:targetNodeModel.attrs,
}); });
// ************** 记录historyData的逻辑 start ************** // ************** 记录historyData的逻辑 start **************

View File

@ -5,6 +5,7 @@
*/ */
// 用来获取调用此js的vue组件实例this // 用来获取调用此js的vue组件实例this
let vm = null; let vm = null;
var hourItem = null;
const sendThis = (_this) => { const sendThis = (_this) => {
vm = _this; vm = _this;
}; };
@ -16,6 +17,7 @@ export default {
return { return {
"node:mouseover": "onNodeHover", "node:mouseover": "onNodeHover",
"node:mouseout": "onNodeOut", "node:mouseout": "onNodeOut",
"node:mouseleave":"onNodeLeave",
}; };
}, },
onNodeHover(event) { onNodeHover(event) {
@ -34,20 +36,30 @@ export default {
selectedIndex: NaN selectedIndex: NaN
}); });
} }
// console.log(item);
if (name && name.startsWith("marker")) { if (name && name.startsWith("marker")) {
hoverNode.setState(graph,"hover", true, graph); hoverNode.setState("hover", true, graph);
hourItem=hoverNode;
}else {
if (hourItem!=null){
hourItem.setState("hover", false)
}
} }
}, },
onNodeOut(event) { onNodeOut(event) {
const name = event.shape.get("name"); const name = event.shape.get("name");
console.log("out", name)
let hoverNode = event.item; let hoverNode = event.item;
if (name && name.startsWith("marker")) { if (name && name.startsWith("marker")) {
hoverNode.setState(graph,"hover", false); hoverNode.setState("hover", false);
}
if (hourItem!=null){
hourItem.setState("hover", false)
}
hoverNode.setState("hover", false);
},
onNodeLeave(event) {
if (hourItem!=null){
hourItem.setState("hover", false)
} }
// hoverNode.setState("hover", false);
} }
} }
}; };

View File

@ -6,20 +6,16 @@
import dragAddEdge from './drag-add-edge' import dragAddEdge from './drag-add-edge'
import hoverEventEdit from './hover-event-edit' import hoverEventEdit from './hover-event-edit'
import clickEventEdit from './click-event-edit'
import dragEventEdit from './drag-event-edit' import dragEventEdit from './drag-event-edit'
import keyupEventEdit from './keyup-event-edit' import keyupEventEdit from './keyup-event-edit'
import diceErNode from './dice-er-node' import diceErNode from './dice-er-node'
import diceErEdge from './dice-er-edge'
const obj = { const obj = {
// dragAddEdge, dragAddEdge,
hoverEventEdit, hoverEventEdit,
// clickEventEdit,
dragEventEdit, dragEventEdit,
keyupEventEdit, keyupEventEdit,
diceErNode, diceErNode,
diceErEdge
} }
export default { export default {

View File

@ -5,9 +5,9 @@
*/ */
export default { export default {
type: 'cc-line', type: 'top-cubic',
style: { style: {
startArrow: false, startArrow: false,
endArrow: false endArrow: true
} }
} }

View File

@ -0,0 +1,30 @@
/**
* @author: Clay
* @data: 2019/07/18
* @description: 线公共方法
*/
import utils from '../utils'
export default {
draw(cfg, group) {
const { startPoint, endPoint } = cfg
const keyShape = group.addShape('path', {
className: 'edge-shape',
attrs: {
...cfg.style,
path: [
['M', startPoint.x, startPoint.y],
['L', endPoint.x, endPoint.y]
]
},
name: 'edge-shape'
})
console.log(keyShape.attrs.endArrow = true)
return keyShape
},
setState(name, value, item) {
// 设置边状态
utils.edge.setState(name, value, item)
}
}

View File

@ -5,10 +5,10 @@
*/ */
import diceErEdge from './dice-er-edge' import topCubic from './top-cubic'
const obj = { const obj = {
diceErEdge topCubic
} }
export default function(G6) { export default function(G6) {

View File

@ -0,0 +1,14 @@
/**
* @author: Clay
* @data: 2019/07/18
* @description: 曲线
*/
import base from './base'
export default {
name: 'top-cubic',
extendName: 'cubic',
options: {
...base
}
}

View File

@ -39,7 +39,7 @@ const initGraph = {
} }
}, },
defaultEdge: { defaultEdge: {
type: 'dice-er-edge', type: 'top-cubic',
labelCfg: { labelCfg: {
position: 'center', position: 'center',
autoRotate: false autoRotate: false

View File

@ -15,6 +15,14 @@ export default {
sendThis, sendThis,
name: 'dice-er-box', name: 'dice-er-box',
options: { options: {
setState(name, value, item) {
// 设置节点状态
utils.node.setState(name, value, item)
// 设置锚点状态
// if (vm.graphMode === 'edit') {
utils.anchor.setState(name, value, item)
// }
},
draw(cfg, group) { draw(cfg, group) {
const width = 250; const width = 250;
const height = 316; const height = 316;
@ -203,8 +211,8 @@ export default {
}); });
if (!cfg.hideDot) { if (!cfg.hideDot) {
utils.anchor.erDrawLeft(group, label, 0, i * itemHeight + offsetY) // utils.anchor.erDrawLeft(group, label, 0, i * itemHeight + offsetY)
utils.anchor.erDrawLeft(group,label,width,i * itemHeight + offsetY) // utils.anchor.erDrawLeft(group,label,width,i * itemHeight + offsetY)
// listContainer.addShape("marker", { // listContainer.addShape("marker", {
// attrs: { // attrs: {
// x: 0, // x: 0,
@ -254,25 +262,20 @@ export default {
}); });
}); });
} }
// console.log(keyshape);
return keyshape; return keyshape;
}, },
getAnchorPoints() { // getAnchorPoints() {
return [ // return [
[0, 0], // [0, 0],
[1, 0], // [1, 0],
]; // ];
}, // },
setState(graph,name, value, item) { // 绘制后附加锚点
// 设置节点状态 afterDraw(cfg, group) {
// utils.node.setState(name, value, item) // 绘制锚点
// 设置锚点状态 utils.anchor.drawMark(cfg, group)
// if (vm.graphMode === 'edit') {
utils.anchor.setState(graph,name, value, item)
// }
}, },
} }
} }

View File

@ -74,15 +74,15 @@ export default {
r: 3, r: 3,
symbol: 'circle', symbol: 'circle',
lineWidth: 1, lineWidth: 1,
fill: 'white', fill: '#FFFFFF',
fillOpacity: 1, fillOpacity: 1,
stroke: '#096DD9', stroke: '#096DD9',
strokeOpacity: 1, strokeOpacity: 1,
cursor: 'crosshair' cursor: 'crosshair'
}, },
hover: { hover: {
fillOpacity: 1, fillOpacity: 0.3,
strokeOpacity: 1 strokeOpacity: 0.5
}, },
unhover: { unhover: {
fillOpacity: 0, fillOpacity: 0,

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,59 @@
import theme from '../../theme'
export default function(cfg, group) {
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
// console.log("cfg",cfg)
let { anchorPoints, width, height, id } = cfg
// console.log("基础信息",anchorPoints,"宽",width,"高",height,"节点id",id)
if (anchorPoints && anchorPoints.length) {
for (let i = 0, len = anchorPoints.length; i < len; i++) {
let [x, y] = anchorPoints[i]
// 计算Marker中心点坐标
let originX = -width / 2
let originY = -height / 2
let anchorX = x * width + originX+125
let anchorY = y * height + originY+158
// 添加锚点背景
let anchorBgShape = group.addShape('marker', {
id: id + '_anchor_bg_' + i,
attrs: {
name: 'anchorBg',
x: anchorX,
y: anchorY,
// 锚点默认样式
...themeStyle.anchorBgStyle.default
},
draggable: false,
name: 'markerBg-shape'
})
// 添加锚点Marker形状
// eslint-disable-next-line no-unused-vars
let anchorShape = group.addShape('marker', {
id: id + '_anchor_' + i,
attrs: {
name: 'anchor',
x: anchorX,
y: anchorY,
// 锚点默认样式
...themeStyle.anchorStyle.default
},
draggable: false,
name: 'marker-shape'
})
anchorShape.on('mouseenter', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.active
})
})
anchorShape.on('mouseleave', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.inactive
})
})
}
}
}

View File

@ -7,9 +7,11 @@
// import draw from './draw' // import draw from './draw'
import erDrawLeft from './er-draw-left' import erDrawLeft from './er-draw-left'
import setState from './set-state' import setState from './set-state'
import drawMark from './draw_mark'
// import update from './update' // import update from './update'
export default { export default {
setState, setState,
erDrawLeft, erDrawLeft,
drawMark,
} }

View File

@ -5,18 +5,19 @@
*/ */
import theme from '../../theme' import theme from '../../theme'
export default function(graph,name, value, item) { export default function(name, value, item) {
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体 const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
if (name === 'hover') { if (name === 'hover') {
// console.log(item)
let group = item.getContainer() let group = item.getContainer()
let children = group.get('children') let children = group.get('children')
for (let i = 0, len = children.length; i < len; i++) { for (let i = 0, len = children.length; i < len; i++) {
let child = children[i] let child = children[i]
// 处理锚点状态 // 处理锚点状态
if (child.attrs.name === 'anchorg') { // console.log(child.attrs.name)
if (child.attrs.name === 'anchorBg') {
if (value) { if (value) {
console.log(graph)
child.attr(themeStyle.anchorStyle.hover) child.attr(themeStyle.anchorStyle.hover)
} else { } else {
child.attr(themeStyle.anchorStyle.unhover) child.attr(themeStyle.anchorStyle.unhover)

View File

@ -4,6 +4,7 @@
ref="topology" ref="topology"
:graph-data="graphData" :graph-data="graphData"
:node-app-config="nodeAppConfig" :node-app-config="nodeAppConfig"
:edge-app-config="edgeAppConfig"
@doAutoRefresh="doAutoRefresh" @doAutoRefresh="doAutoRefresh"
@doManualRefresh="doManualRefresh" @doManualRefresh="doManualRefresh"
@doChangeMode="doChangeMode" @doChangeMode="doChangeMode"
@ -15,147 +16,17 @@
<script> <script>
/* 局部注册 */ /* 局部注册 */
import Topology from "./packages/topology/src/topology"; import Topology from './packages/topology/src/topology'
import { deepClone } from "./utils/index"; import { deepClone } from './utils/index'
export default { export default {
name: "DemoTopology", name: 'DemoTopology',
components: { components: {
"topology": Topology 'topology': Topology
}, },
data() { data() {
return { return {
graphData: { graphData: {"nodes":[{"id":"305bfbdd-31cc-4028-b2b1-2f504968356d","x":304.8223042174235,"y":131.0267312661499,"label":"客户端","table":"test_table","type":"dice-er-box","attrs":[{"key":"id","type":"number(6)","comment":"主键id","isUse":0},{"key":"key","type":"varchar(255)","comment":"关键字","isUse":1},{"key":"gender","type":"enum(M, F)","comment":"gender","isUse":1},{"key":"birthday","type":"date","comment":"生日","isUse":0},{"key":"hometown","type":"varchar(255)","comment":"家乡","isUse":0},{"key":"country","type":"varchar(255)","comment":"国家","isUse":1},{"key":"nation","type":"varchar(255)","comment":"nation","isUse":1},{"key":"jobId","type":"number(3)","comment":"工作id","isUse":1},{"key":"phone","type":"varchar(255)","comment":"电话","isUse":1}],"size":[55,55],"width":250,"height":316,"anchorPoints":[[0.5,0],[1,0.5],[0.5,1],[0,0.5]],"appState":{"alert":false},"labelCfg":{"position":"bottom"},"style":{"default":{"stroke":"#CED4D9","fill":"transparent","shadowBlur":10,"shadowColor":"rgba(13, 26, 38, 0.08)","lineWidth":1,"radius":4,"strokeOpacity":0.7},"selected":{"shadowColor":"#ff240b","shadowBlur":2},"unselected":{"shadowColor":""}},"selectedIndex":null,"appConfig":{},"depth":0},{"id":"be9b52e5-9c2f-4e5c-990a-afbf19dcfeed","x":-94.51187075489108,"y":127.35469287559994,"label":"防火墙","table":"test_table","type":"dice-er-box","attrs":[{"key":"id","type":"number(6)","comment":"主键id","isUse":0},{"key":"key","type":"varchar(255)","comment":"关键字","isUse":1},{"key":"gender","type":"enum(M, F)","comment":"gender","isUse":0},{"key":"birthday","type":"date","comment":"生日","isUse":1},{"key":"hometown","type":"varchar(255)","comment":"家乡","isUse":1},{"key":"country","type":"varchar(255)","comment":"国家","isUse":0},{"key":"nation","type":"varchar(255)","comment":"nation","isUse":1},{"key":"jobId","type":"number(3)","comment":"工作id","isUse":1},{"key":"phone","type":"varchar(255)","comment":"电话","isUse":1}],"size":[55,55],"width":250,"height":316,"anchorPoints":[[0.5,0],[1,0.5],[0.5,1],[0,0.5]],"appState":{"alert":false},"labelCfg":{"position":"bottom"},"style":{"default":{"stroke":"#CED4D9","fill":"transparent","shadowBlur":10,"shadowColor":"rgba(13, 26, 38, 0.08)","lineWidth":1,"radius":4,"strokeOpacity":0.7},"selected":{"shadowColor":"#ff240b","shadowBlur":2},"unselected":{"shadowColor":""}},"selectedIndex":null,"appConfig":{},"startIndex":0,"startX":0,"depth":0}],"edges":[{"id":"8bc0249e-ee5d-4dd7-84e0-e4e32c217f2a","source":"be9b52e5-9c2f-4e5c-990a-afbf19dcfeed","sourceAttrs":[{"key":"id","type":"number(6)","comment":"主键id","isUse":1},{"key":"key","type":"varchar(255)","comment":"关键字","isUse":1},{"key":"gender","type":"enum(M, F)","comment":"gender","isUse":1},{"key":"birthday","type":"date","comment":"生日","isUse":1},{"key":"hometown","type":"varchar(255)","comment":"家乡","isUse":1},{"key":"country","type":"varchar(255)","comment":"国家","isUse":1},{"key":"nation","type":"varchar(255)","comment":"nation","isUse":1},{"key":"jobId","type":"number(3)","comment":"工作id","isUse":1},{"key":"phone","type":"varchar(255)","comment":"电话","isUse":1}],"sourceAnchor":1,"target":"305bfbdd-31cc-4028-b2b1-2f504968356d","type":"top-cubic","style":{"active":{"stroke":"rgb(95, 149, 255)","lineWidth":1},"selected":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"shadowColor":"rgb(95, 149, 255)","shadowBlur":10,"text-shape":{"fontWeight":500}},"highlight":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"text-shape":{"fontWeight":500}},"inactive":{"stroke":"rgb(234, 234, 234)","lineWidth":1},"disable":{"stroke":"rgb(245, 245, 245)","lineWidth":1},"edgeStyle":{"default":{"stroke":"#e2e2e2","lineWidth":3,"lineAppendWidth":10},"selected":{"shadowColor":"#626262","shadowBlur":3}},"stroke":"#A3B1BF","lineWidth":2,"strokeOpacity":0.92,"lineAppendWidth":10},"labelCfg":{"position":"center","autoRotate":false},"startPoint":{"x":155.98812924510892,"y":285.35469287559994,"anchorIndex":1},"endPoint":{"x":304.3223042174235,"y":289.0267312661499,"anchorIndex":3},"curveOffset":[-20,20],"curvePosition":[0.5,0.5],"targetAnchor":3,"targetAttrs":[{"key":"id","type":"number(6)","comment":"主键id","isUse":1},{"key":"key","type":"varchar(255)","comment":"关键字","isUse":1},{"key":"gender","type":"enum(M, F)","comment":"gender","isUse":1},{"key":"birthday","type":"date","comment":"生日","isUse":1},{"key":"hometown","type":"varchar(255)","comment":"家乡","isUse":1},{"key":"country","type":"varchar(255)","comment":"国家","isUse":1},{"key":"nation","type":"varchar(255)","comment":"nation","isUse":1},{"key":"jobId","type":"number(3)","comment":"工作id","isUse":1},{"key":"phone","type":"varchar(255)","comment":"电话","isUse":1}],"depth":0}],"combos":[]},
nodes: [
{
"id": "info",
"label": "Employee",
"attrs": [{
"key": "id",
"type": "number(6)"
},
{
"key": "key",
"type": "varchar(255)"
},
{
"key": "gender",
"type": "enum(M, F)"
},
{
"key": "birthday",
"type": "date"
},
{
"key": "hometown",
"type": "varchar(255)"
},
{
"key": "country",
"type": "varchar(255)"
},
{
"key": "nation",
"type": "varchar(255)"
},
{
"key": "jobId",
"type": "number(3)",
"relation": [{
"key": "id",
"nodeId": "job"
}]
},
{
"key": "phone",
"type": "varchar(255)"
},
{
"key": "deptId",
"type": "number(6)",
"relation": [{
"key": "id",
"nodeId": "dept"
}]
},
{
"key": "startTime",
"type": "date"
},
{
"key": "leaveTime",
"type": "date"
}
]
},
{
"id": "job",
"label": "Job",
"attrs": [{
"key": "id",
"type": "number(3)"
},
{
"key": "title",
"type": "varchar(255)"
},
{
"key": "level",
"type": "number(3)"
}
]
},
{
"id": "dept",
"label": "Department",
"attrs": [{
"key": "id",
"type": "number(6)"
},
{
"key": "title",
"type": "varchar(255)"
},
{
"key": "desc",
"type": "text"
},
{
"key": "parent",
"type": "number(6)",
"relation": [{
"key": "id",
"nodeId": "dept"
}]
},
{
"key": "manager",
"type": "number(6)"
}
]
}
],
edges: [
{
"source": "info",
"target": "job",
"sourceKey": "jobId",
"targetKey": "id"
},
{
"source": "info",
"target": "dept",
"sourceKey": "deptId",
"targetKey": "id"
},
{
"source": "dept",
"target": "dept",
"sourceKey": "parent",
"targetKey": "id"
}
]
},
nodeTypeList: [ nodeTypeList: [
// { guid: "blue", label: "", imgSrc: require("../../assets/images/blue.svg") }, // { guid: "blue", label: "", imgSrc: require("../../assets/images/blue.svg") },
// { guid: "green", label: "绿", imgSrc: require("@/assets/images/green.svg") }, // { guid: "green", label: "绿", imgSrc: require("@/assets/images/green.svg") },
@ -163,50 +34,55 @@ export default {
], ],
// //
nodeAppConfig: { nodeAppConfig: {
ip: "节点IP", // ip: 'IP',
port: "节点端口", // port: '',
sysName: "设备名称" // sysName: ''
},
edgeAppConfig: {
associated: '查询方式',
tableComment: '主表字段',
relComment: '关联字段'
}, },
autoRefreshTimer: null autoRefreshTimer: null
}; }
}, },
mounted() { mounted() {
let graphData = deepClone(this.graphData); let graphData = deepClone(this.graphData)
this.$refs.topology.initTopo(graphData); this.$refs.topology.initTopo(graphData)
this.randomChange(); this.randomChange()
}, },
methods: { methods: {
doAutoRefresh(interval) { doAutoRefresh(interval) {
if (interval === -1) { if (interval === -1) {
clearInterval(this.autoRefreshTimer); clearInterval(this.autoRefreshTimer)
} else { } else {
clearInterval(this.autoRefreshTimer); clearInterval(this.autoRefreshTimer)
this.autoRefreshTimer = setInterval(() => { this.autoRefreshTimer = setInterval(() => {
this.randomChange(); this.randomChange()
}, interval); }, interval)
this.$once("hook:beforeDestroy", () => { this.$once('hook:beforeDestroy', () => {
clearInterval(this.autoRefreshTimer); clearInterval(this.autoRefreshTimer)
}); })
} }
}, },
doChangeMode(graphMode) { doChangeMode(graphMode) {
clearInterval(this.autoRefreshTimer); clearInterval(this.autoRefreshTimer)
let graphData = deepClone(this.graphData); let graphData = deepClone(this.graphData)
this.$refs.topology.changeGraphMode(graphData, graphMode); this.$refs.topology.changeGraphMode(graphData, graphMode)
}, },
doManualRefresh() { doManualRefresh() {
this.randomChange(); this.randomChange()
}, },
doSaveData(graphData) { doSaveData(graphData) {
console.log(JSON.stringify(graphData)); console.log(JSON.stringify(graphData))
}, },
randomChange() { randomChange() {
let graphData = deepClone(this.$refs.topology.getGraphData()); let graphData = deepClone(this.$refs.topology.getGraphData())
let { nodes } = graphData; let { nodes } = graphData
this.$refs.topology.changeGraphData(graphData); this.$refs.topology.changeGraphData(graphData)
} }
} }
}; }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>