Diagram.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <template>
  2. <div>
  3. <el-row>
  4. <!-- 模板树 -->
  5. <el-col :span="6" >
  6. <div style="height: 100vh;overflow: scroll;">
  7. <el-tree :data="diagrams" :props="{children: 'children', label: nodeLabel, value: 'id'}"
  8. @node-click="open"
  9. default-expand-all
  10. :expand-on-click-node="false">
  11. <span class="custom-tree-node" slot-scope="{ node, data }">
  12. <span>{{ node.label}}</span>
  13. <span style="padding-left: 10px;">
  14. <el-button type="text" size="mini" icon="el-icon-plus" @click="() => newDiagram(node)"
  15. v-if="data.objType == 'folder' && data.type == 'type'">
  16. 创建系统图
  17. </el-button>
  18. <el-popconfirm title="确定删除?" v-if="data.objType != 'folder'" @confirm="() => delDiagram(node)">
  19. <el-button slot="reference" type="text" size="mini" icon="el-icon-remove">删除</el-button>
  20. </el-popconfirm>
  21. </span>
  22. </span>
  23. </el-tree>
  24. </div>
  25. </el-col>
  26. <!-- 编辑区 -->
  27. <el-col :span="18" style="border-left: 1px solid #f4f4f4">
  28. <!-- 工具条 -->
  29. <div ref="header" style="padding: 2px;border-bottom: 1px solid #f4f4f4">
  30. <span class="editor-title">{{currentDiagram.name}}</span>
  31. <el-button-group>
  32. <el-button size="mini" @click="() => prjEnv()">项目环境</el-button>
  33. </el-button-group>
  34. <el-button-group>
  35. <el-button size="mini" @click="() => chooseTemplate()" :disabled="state == -1">选择模板</el-button>
  36. <el-button size="mini" @click="() => loadData()" :disabled="state == -1">加载数据</el-button>
  37. </el-button-group>
  38. <el-button-group>
  39. <el-button size="mini" @click="() => {}" :disabled="state != 1">上移/左移</el-button>
  40. <el-button size="mini" @click="() => {}" :disabled="state != 1">下移/右移</el-button>
  41. </el-button-group>
  42. &nbsp;
  43. <el-button-group>
  44. <el-button size="mini" @click="() => changeConState()" :disabled="state == -1">{{conButtonText}}</el-button>
  45. </el-button-group>
  46. &nbsp;
  47. <el-button-group>
  48. <el-button size="mini" @click="() => save()" :disabled="state == -1">保存</el-button>
  49. </el-button-group>
  50. <!--选中信息-->
  51. <div class="info">
  52. <span>{{selectionInfo}}</span>
  53. <span style="margin-left: 30px;color: #a3a3a3;">{{dynInfo}}</span>
  54. </div>
  55. </div>
  56. <!-- 编辑界面 -->
  57. <div ref="editor" :style="editorStyle">
  58. </div>
  59. </el-col>
  60. </el-row>
  61. <!-- 编辑项目环境对话框 -->
  62. <el-dialog title="项目环境" :visible.sync="dlgEnvVisible">
  63. <el-form :model="propsData" label-width="100px">
  64. <el-form-item label="项目Id">
  65. <el-autocomplete
  66. class="inline-input"
  67. v-model="propsData.projectId"
  68. :fetch-suggestions="getPrjIds"></el-autocomplete>
  69. </el-form-item>
  70. <el-form-item label="系统实例Id">
  71. <el-input v-model="propsData.systemId"></el-input>
  72. </el-form-item>
  73. <el-form-item label="集团编码">
  74. <el-input v-model="propsData.groupCode"></el-input>
  75. </el-form-item>
  76. </el-form>
  77. <div slot="footer" class="dialog-footer">
  78. <el-button @click="dlgEnvVisible = false">取 消</el-button>
  79. <el-button type="primary" @click='modifyEnv'>确 定</el-button>
  80. </div>
  81. </el-dialog>
  82. <!-- 选择模板对话框 -->
  83. <el-dialog title="系统图模板" :visible.sync="dlgTemplateVisible">
  84. <el-form :model="propsData" label-width="100px">
  85. <el-form-item label="选择模板">
  86. <el-select
  87. v-model="propsData.templateId"
  88. style="width: 600px;"
  89. >
  90. <el-option
  91. v-for="item in templateOptions"
  92. :key="item.id"
  93. :label="item.name"
  94. :value="item.id">
  95. </el-option>
  96. </el-select>
  97. </el-form-item>
  98. </el-form>
  99. <div slot="footer" class="dialog-footer">
  100. <el-button @click="dlgTemplateVisible = false">取 消</el-button>
  101. <el-button type="primary" @click='modifyTemplate'>确 定</el-button>
  102. </div>
  103. </el-dialog>
  104. </div>
  105. </template>
  106. <script lang="ts">
  107. import {
  108. Component,
  109. Prop,
  110. Vue,
  111. Watch
  112. } from "vue-property-decorator";
  113. import {DiagramEditor} from '@/lib/DiagramEditor';
  114. import {Template} from '@/lib/DiagramModel';
  115. @Component({})
  116. export default class DiagramTemplate extends Vue {
  117. projectId = 'Pj1101080665';
  118. systemId = '';
  119. groupCode = '';
  120. editorStyle = {
  121. width: "100%",
  122. height: "",
  123. "overflow": "scroll"
  124. };
  125. diagrams = [];
  126. currentDiagram:any = {};
  127. editor:DiagramEditor = null;
  128. state = -1; //编辑状态(-1:关闭; 0:打开; 1:容器编辑中; 2:绘制干管)
  129. dlgEnvVisible = false;
  130. dlgTemplateVisible = false;
  131. propsData: any = {};
  132. templateOptions:any[] = [];
  133. selectionInfo = '~';
  134. dynInfo = '';
  135. conButtonText = '隐藏容器';
  136. mounted() {
  137. this.onWindowresize();
  138. this.editor = new DiagramEditor(this.$refs.editor);
  139. this.editor.setEditorPart(this);
  140. this.loadDiagrams();
  141. }
  142. loadDiagrams(){
  143. this['$axios'].get(this['$common'].url + "diagram0/getDiagrams" + this.buildUrlParams())
  144. .then(res => {
  145. this.diagrams = res.data.data;
  146. })
  147. .catch(err => {
  148. //console.log(err);
  149. });
  150. }
  151. buildUrlParams(){
  152. var str = "?projectId=" + this.projectId;
  153. if(this.systemId)
  154. str += '&systemId=' + this.systemId;
  155. if(this.groupCode)
  156. str += '&groupCode=' + this.groupCode;
  157. return str;
  158. }
  159. //系统图模板树的节点显示
  160. nodeLabel(data, node) {
  161. if(data.objType == 'folder') //文件夹
  162. return data.name;
  163. else //图
  164. return '[系统图] ' + data.name;
  165. }
  166. prjEnv() {
  167. this.propsData = {projectId: this.projectId, systemId: this.systemId, groupCode: this.groupCode};
  168. this.dlgEnvVisible = true;
  169. }
  170. getPrjIds(queryString, cb){
  171. const list = [
  172. { "value": "Pj1101080665", "code": "JDKJ" },
  173. { "value": "Pj1101050036", "code": "JM" },
  174. { "value": "Pj1101050031", "code": "YT" }
  175. ];
  176. cb(list);
  177. }
  178. modifyEnv() {
  179. const reload = this.projectId != this.propsData.projectId;
  180. this.projectId = this.propsData.projectId;
  181. this.systemId = this.propsData.systemId;
  182. this.groupCode = this.propsData.groupCode;
  183. this.dlgEnvVisible = false;
  184. if(reload) {
  185. this.loadDiagrams();
  186. this.open(new Object());
  187. }
  188. }
  189. //新建模板文件
  190. newDiagram(node){
  191. this.$prompt('请输入系统图名称', '提示', {
  192. confirmButtonText: '确定',
  193. cancelButtonText: '取消',
  194. type: 'info',
  195. inputValidator: val => {return val != null}
  196. }).then(instance => {
  197. const params:any = {name: instance['value'], type: node.data.id};
  198. this['$axios'].post(this['$common'].url + "diagram0/newDiagram" + this.buildUrlParams(), params)
  199. .then(res => {
  200. const root = res.data;
  201. if(root.result == 'success') {
  202. const newObj = root.data;
  203. node.data.children.push(newObj);
  204. this.$message({
  205. type: 'success',
  206. message: '操作成功!'
  207. });
  208. this.open(newObj);
  209. }
  210. })
  211. .catch(err => {
  212. console.log(err);
  213. });
  214. }).catch(() => {
  215. });
  216. }
  217. //删除模板
  218. delDiagram(node){
  219. const params:any = {id: node.data.id};
  220. this['$axios'].post(this['$common'].url + "diagram0/delDiagram", params)
  221. .then(res => {
  222. const root = res.data;
  223. if(root.data == true) {
  224. const parent = node.parent;
  225. const children = parent.data.children || parent.data;
  226. const index = children.findIndex(d => d.id === node.data.id);
  227. children.splice(index, 1);
  228. this.$message({
  229. type: 'success',
  230. message: '操作成功!'
  231. });
  232. this.open({});
  233. }
  234. })
  235. .catch(err => {
  236. console.log(err);
  237. });
  238. }
  239. //在编辑器中打开模板文件
  240. open(data){
  241. if(data.objType == 'folder') //文件夹
  242. return;
  243. if(this.currentDiagram != data) {
  244. this.currentDiagram = data;
  245. this.selectionInfo = '~';
  246. this.dynInfo = '';
  247. this.editor.show(this.currentDiagram);
  248. if(!this.currentDiagram.id) //编辑对象为空
  249. this.state = -1;
  250. else {
  251. this.onSelectionChange();
  252. }
  253. }
  254. }
  255. chooseTemplate() {
  256. this.templateOptions = [];
  257. this['$axios'].get(this['$common'].url + "template/getTemplatesByType?diagramType=" + this.currentDiagram.type)
  258. .then(res => {
  259. this.templateOptions = res.data.data;
  260. })
  261. .catch(err => {
  262. //console.log(err);
  263. });
  264. const props:any = new Object();
  265. props.templateId = this.currentDiagram.templateId;
  266. this.propsData = props;
  267. this.dlgTemplateVisible = true;
  268. }
  269. modifyTemplate() {
  270. const tId = this.propsData.templateId;
  271. this.currentDiagram.templateId = tId;
  272. this.dlgTemplateVisible = false;
  273. this.editor.redraw();
  274. const params:any = {diagramId: this.currentDiagram.id, templateId: this.propsData.templateId};
  275. //this.propsData = {id: params.newCompId}; //方便后续选中操作
  276. this.callAction('setTemplate', params);
  277. }
  278. loadData() {
  279. const params:any = {diagramId: this.currentDiagram.id};
  280. //this.propsData = {id: params.newCompId}; //方便后续选中操作
  281. this.callAction('loadData', params);
  282. }
  283. created(){
  284. //window.addEventListener('resize', this.onWindowresize);
  285. }
  286. onWindowresize(){
  287. this.editorStyle.height = (window.innerHeight - this.$refs.header['offsetHeight']) + 'px';
  288. }
  289. //选中组件的事件触发
  290. onSelectionChange(){
  291. this.state = this.editor.getState();
  292. if(this.editor)
  293. this.selectionInfo = this.editor.buildSelInfo();
  294. }
  295. //调用服务端编辑操作,返回新的系统图对象,然后刷新
  296. callAction(action, params) {
  297. this['$axios'].post(this['$common'].url + 'diagram0/' + action, params)
  298. .then(res => {
  299. const root = res.data;
  300. if(root.result == 'success') {
  301. //记录之前的选中对象id
  302. // var selId = this.propsData.id;
  303. // if(!selId) {
  304. // const sel:any = this.editor.getSelComp();
  305. // if(sel)
  306. // selId = sel.id;
  307. // }
  308. const newObj = root.data;
  309. if(newObj == null)
  310. return;
  311. for(const i in newObj) {
  312. this.currentDiagram[i] = newObj[i];
  313. }
  314. // this.$message({
  315. // type: 'success',
  316. // message: '操作成功!'
  317. // });
  318. if(this.dlgTemplateVisible)
  319. this.dlgTemplateVisible = false;
  320. this.propsData = {};
  321. this.editor.show(this.currentDiagram);
  322. //this.editor.setSelComp(this.editor.getCompById(selId));
  323. }
  324. })
  325. .catch(err => {
  326. console.log(err);
  327. });
  328. }
  329. changeConState(){
  330. this.editor.showContainer = !this.editor.showContainer;
  331. this.editor.redraw();
  332. this.conButtonText = this.editor.showContainer ? '隐藏容器' : '显示容器';
  333. }
  334. save(){
  335. Template.clearParent(this.currentDiagram.template);
  336. const params:any = {diagram: this.currentDiagram};
  337. this.callAction("saveDiagram", params)
  338. }
  339. //切换编辑状态
  340. changeState(state) {
  341. this.state = state;
  342. this.editor.setState(state);
  343. }
  344. }
  345. </script>
  346. <style>
  347. .panel {
  348. padding: 30px;
  349. }
  350. .custom-tree-node {
  351. /* flex: 1;
  352. display: flex; */
  353. align-items: center;
  354. justify-content: space-between;
  355. font-size: 14px;
  356. padding-right: 20px;
  357. }
  358. .editor-title {
  359. font-size: 14px;
  360. font-weight: bold;
  361. padding:0 10px;
  362. }
  363. .info {
  364. font-size: 12px;
  365. padding:0 10px;
  366. }
  367. .el-dialog-div{
  368. height: 60vh;
  369. overflow: auto;
  370. }
  371. </style>