<template>
|
<el-container>
|
<el-aside style="width:333px;">
|
<basic-container>
|
<div ref="TreeBox" style="height: calc(100vh - 144px);!important;">
|
<div class="headerCon">
|
<el-button v-if="permissionList.addBtn" icon="el-icon-plus" plain size="small" type="primary" @click="addClickHandler">创建
|
</el-button>
|
<el-button v-if="permissionList.editBtn" icon="el-icon-edit" plain size="small" type="primary" @click="editClickHandler">修改
|
</el-button>
|
<el-button v-if="permissionList.delBtn" icon="el-icon-delete" plain size="small" type="danger" @click="delClickHandler">删除
|
</el-button>
|
<el-button v-if="permissionList.importBtn" icon="el-icon-upload2" plain size="small" type="primary" @click="uploadClickHandler">导入
|
</el-button>
|
<el-button v-if="permissionList.exportBtn" icon="el-icon-download" plain size="small" type="primary" @click="exportClickHandler">导出
|
</el-button>
|
<el-button v-if="permissionList.viewTheScopeBtn" icon="el-icon-view" plain size="small" type="primary" @click="checkViewClickHandler">查看使用范围
|
</el-button>
|
</div>
|
<!-- 左侧树 -->
|
<div style="height: calc(100vh - 300px);">
|
<avue-tree ref="tree" :data="treeData" :option="treeOption" @node-click="nodeClick">
|
<span slot-scope="{ node, data }" class="el-tree-node__label">
|
<span>
|
<i class="el-icon-s-promotion"></i>
|
{{ (node || {}).label }}
|
</span>
|
</span>
|
</avue-tree>
|
</div>
|
</div>
|
</basic-container>
|
</el-aside>
|
<el-main>
|
<basic-container>
|
<CycleFlow
|
:key="Reload"
|
ref="vueFlowchartEditor"
|
:chart-data="nodesEdgesData"
|
:chart-data-node-items="flowChartNodeItems"
|
:rowData="rowData"
|
:type="type"
|
class="cycle_flow"
|
@save-data="save"
|
@reset-tree="handleResetTree"
|
@handler-save="handlerSave"
|
/>
|
</basic-container>
|
</el-main>
|
<upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="导入"
|
@updata="getTableList"></upload-file>
|
|
<el-dialog
|
v-dialogDrag
|
v-loading="checkViewLoading"
|
:visible.sync="checkViewVisible"
|
append-to-body="true"
|
class="avue-dialog"
|
title="查看使用范围"
|
width="60%"
|
>
|
<avue-crud
|
ref="checkViewCrud"
|
:data="checkViewData"
|
:option="checkViewOption"
|
@search-change="checkHandleSearch"
|
@search-reset="checkHandleReset"
|
>
|
|
</avue-crud>
|
</el-dialog>
|
</el-container>
|
</template>
|
|
<script>
|
import {
|
gridLifeCycle,
|
getLCEventKeys,
|
addLifeCycle,
|
updateLifeCycle,
|
deleteLifeCycles,
|
exportLifeCycles,
|
getUsedLifeCycleList
|
} from '@/api/modeling/lifeCycle/api';
|
import {gridStatus} from '@/api/modeling/statusPool/api'
|
import CycleFlow from "@/components/flow-cycle/flowchartEditor.vue";
|
import func from "@/util/func";
|
import basicOption from "@/util/basic-option";
|
import {mapGetters} from "vuex";
|
|
export default {
|
name: "index",
|
components: {CycleFlow},
|
data() {
|
return {
|
checkViewOption: {
|
...basicOption,
|
addBtn: false,
|
menu: false,
|
searchMenuSpan: 8,
|
refreshBtn: false,
|
selection: false,
|
header:false,
|
column: [
|
{
|
label: '名称',
|
prop: 'lifeCycleName',
|
sortable: true,
|
},
|
{
|
label: '来源',
|
prop: 'source',
|
sortable: true,
|
search: true
|
},
|
{
|
label: '说明',
|
prop: 'desc',
|
}
|
]
|
},
|
checkViewData: [],
|
checkViewDataSearch: [],
|
checkViewVisible: false,
|
checkViewLoading: false,
|
tipList: [
|
"名称、标签、起始状态不能为空,且名称只能为英文字符",
|
"注意配置连接线起始状态以及目标状态名称",
|
],
|
upFileType: ['xls', 'xlsx'],
|
fileUrl: 'api/lifeCycleController/importLifeCycles',
|
eventList: [],
|
Reload: Math.random(),
|
flowKey: null,
|
visible: false,
|
type: 'edit',
|
nodesEdgesData: {},
|
flowChartNodeItems: [], // 流程节点数据
|
rowData: {},
|
treeData: [],
|
treeOption: {
|
height: 'auto',
|
defaultExpandAll: false,
|
menu: false,
|
addBtn: false,
|
props: {
|
label: 'id',
|
value: 'id',
|
children: 'children'
|
}
|
},
|
}
|
},
|
computed:{
|
...mapGetters(["permission"]),
|
permissionList() {
|
return {
|
addBtn: this.vaildData(this.permission[this.$route.query.id].ADD, false),
|
delBtn: this.vaildData(this.permission[this.$route.query.id].DELETE, false),
|
editBtn: this.vaildData(this.permission[this.$route.query.id].EDIT, false),
|
exportBtn: this.vaildData(this.permission[this.$route.query.id].EXPORT, false),
|
importBtn: this.vaildData(this.permission[this.$route.query.id].IMPORT, false),
|
viewTheScopeBtn: this.vaildData(this.permission[this.$route.query.id].viewTheScope, false),
|
};
|
},
|
},
|
created() {
|
this.createdHandler();
|
},
|
methods: {
|
// 左侧树查询
|
getTreeList() {
|
gridLifeCycle().then(res => {
|
const data = res.data.data;
|
this.treeData = data;
|
}).catch(err => {
|
this.$message.error(err)
|
});
|
},
|
|
// 生命周期状态查询
|
getStatusList() {
|
gridStatus().then(res => {
|
const data = res.data.data.map(item => {
|
return {
|
id: item.id,
|
name: item.name
|
}
|
})
|
this.flowChartNodeItems = data;
|
}).catch(err => {
|
this.$message.error(err)
|
});
|
},
|
|
// 跃迁事件查询
|
getEventsSelect() {
|
getLCEventKeys().then(res => {
|
const data = res.data.data;
|
this.eventList = data;
|
}).catch(err => {
|
this.$message.error(err)
|
});
|
},
|
|
// 刷新整个页面数据
|
createdHandler() {
|
this.getTreeList(); // 树查询
|
this.getStatusList(); // tag状态池查询
|
this.getEventsSelect(); // 跃迁事件查询
|
},
|
|
// 行点击
|
nodeClick(row) {
|
console.log(row);
|
this.nodesEdgesData = {
|
nodes: this.transformNodeData(row.bounds),
|
edges: this.transformEdgeData(row.lines)
|
};
|
this.rowData = {...row, eventList: {...this.eventList}};
|
this.$store.dispatch('updateMethodBtn', false);
|
this.Reload = Math.random(); // 刷新flow图表
|
},
|
|
// node节点数据转换
|
transformNodeData(nodes) {
|
return nodes.map(item => ({
|
...item,
|
label: item.name,
|
id: item.name,
|
color: '#1890FF',
|
shape: "flow-rect",
|
x: Number(item.cellx),
|
y: Number(item.celly),
|
width: Number(item.cellw),
|
height: Number(item.cellh)
|
}));
|
},
|
|
// line连接线数据转换
|
transformEdgeData(edges) {
|
return edges.map(item => ({
|
...item,
|
events: item.events.map(item => item.oid), // 跃迁事件下拉框绑定,在FlowchartEditor组件onAfterItemSelected方法里查找到对应连接线的信息
|
label: item.name, // 用于右侧详细信息名称
|
source: item.sourceLifeStatus,
|
target: item.targetLifeStatus
|
}));
|
},
|
|
// 创建按钮
|
addClickHandler() {
|
this.$store.dispatch('updateMethodBtn', true);
|
this.handleResetTree();
|
this.$store.dispatch('typeChange', 'add');
|
},
|
|
// 修改按钮
|
editClickHandler() {
|
if (func.isEmptyObject(this.rowData)) {
|
this.$message.error('请至少选择一条数据');
|
return;
|
}
|
this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
|
this.$store.dispatch('editNodesStatus', true);
|
this.$store.dispatch('typeChange', 'edit');
|
},
|
|
// 删除按钮
|
delClickHandler() {
|
if (func.isEmptyObject(this.rowData)) {
|
this.$message.error('请至少选择一条数据');
|
return;
|
}
|
const {id, oid, ts} = this.rowData;
|
|
const data = [{id, oid, ts}];
|
deleteLifeCycles(data).then(res => {
|
if (res.data.code === 200) {
|
this.$message.success(res.data.obj);
|
this.handleResetTree();
|
this.createdHandler();
|
this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
|
}
|
});
|
},
|
|
// 导出按钮
|
exportClickHandler(){
|
if (func.isEmptyObject(this.rowData)) {
|
this.$message.error('请至少选择一条数据');
|
return;
|
}
|
exportLifeCycles({lcNames:this.rowData.id}).then(res => {
|
func.downloadFileByBlobHandler(res);
|
this.$message.success('导出成功');
|
}).catch(err => {
|
this.$message.error(err);
|
})
|
},
|
|
// 导入按钮
|
uploadClickHandler(){
|
this.$refs.upload.visible = true;
|
},
|
|
// 查看使用范围按钮
|
checkViewClickHandler(){
|
if (func.isEmptyObject(this.rowData)) {
|
this.$message.error('请至少选择一条数据');
|
return;
|
}
|
|
getUsedLifeCycleList({lifeCycleName:this.rowData.id}).then(res => {
|
if (res.data.code === 200) {
|
this.checkViewVisible = true;
|
this.checkViewData = res.data.data;
|
this.checkViewDataSearch = res.data.data;
|
}
|
})
|
},
|
|
// 查看使用范围查询
|
checkHandleSearch(params, done) {
|
const {source} = params;
|
|
if (!params.source) {
|
this.checkViewData = this.checkViewDataSearch;
|
return done();
|
}
|
|
this.checkViewData = this.checkViewData.filter(item => {
|
return item.source && item.source.includes(source);
|
});
|
|
done();
|
|
},
|
|
// 查看使用范围重置
|
checkHandleReset() {
|
this.checkViewData = this.checkViewDataSearch;
|
},
|
|
// 子组件回调保存
|
async handlerSave() {
|
const newRowData = await this.$refs.vueFlowchartEditor.getNewRowData();
|
if (!newRowData) {
|
return;
|
}
|
|
const flowData = await this.$refs.vueFlowchartEditor.getFlowData() || {};
|
|
const nodes = flowData.nodes || [];
|
const edges = flowData.edges || [];
|
|
// 检查是否绘制了至少一个图形
|
if (nodes.length <= 0) {
|
this.$message.error('请至少绘制一个图形!');
|
return;
|
}
|
|
// 检查是否绘制了连接线
|
if (nodes.length > 1 && !edges.length) {
|
this.$message.error('请检查是否绘制连接线!');
|
return;
|
}
|
|
// 检查所有连接线的名称是否填写
|
const hasValidLabels = edges.every(item => item.label && item.label.trim() !== "");
|
if (!hasValidLabels) {
|
this.$message.error('请检查是否有连接线名称未填写!');
|
return;
|
}
|
|
// 检查是否有遗漏的连接线
|
if (edges.length + 1 < nodes.length) {
|
this.$message.error('请检查是否全部绘制连接线!');
|
return;
|
}
|
|
|
let params = {...newRowData, ...flowData};
|
const transformedData = {
|
id: params.id,
|
name: params.name,
|
startStatus: params.startStatus,
|
startStatusName: params.startStatusName,
|
description: params.description,
|
ts:params.ts,
|
oid:params.oid,
|
bounds: params.nodes.map(node => ({
|
name: node.id,
|
cellx: String(node.x),
|
celly: String(node.y),
|
cellw: String(node.width),
|
cellh: String(node.height),
|
})),
|
lines: !params.edges ? [] : params.edges.map(edge => ({
|
sourceLifeStatus: edge.source,
|
targetLifeStatus: edge.target,
|
saveEventList: edge.saveEventList,
|
name: edge.label
|
}))
|
};
|
const getFunction = Object.keys(this.rowData).length > 0 ? () => updateLifeCycle(transformedData)
|
: () => addLifeCycle(transformedData);
|
|
getFunction().then(res => {
|
console.log(res);
|
if (res.data.code === 200) {
|
this.$message.success(res.data.obj);
|
this.createdHandler();
|
// this.handleResetTree();
|
this.rowData = {};
|
this.$store.dispatch('updateMethodBtn', Object.keys(this.rowData).length > 0);
|
}
|
});
|
},
|
|
// 重置树和图表
|
handleResetTree() {
|
this.$refs.tree.setCurrentKey(null);
|
this.rowData = {};
|
this.nodesEdgesData = {};
|
this.Reload = Math.random();
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
::v-deep {
|
.el-scrollbar__wrap {
|
overflow: auto !important;
|
}
|
}
|
</style>
|