var app = new Vue({ el: '#app', data: { stations: [], areas: [], relations: [], lines: [], draggingItem: null, draggingLine: null, saving: false, newAreaCode: '', newAreaName: '' }, mounted: function() { this.loadData(); window.addEventListener('resize', this.updateLines); this.$nextTick(function() { if (this.$refs.stationList) this.$refs.stationList.addEventListener('scroll', this.updateLines); if (this.$refs.areaList) this.$refs.areaList.addEventListener('scroll', this.updateLines); }.bind(this)); }, beforeDestroy: function() { window.removeEventListener('resize', this.updateLines); }, methods: { loadData: function() { var that = this; var loading = this.$loading({ lock: true, text: '加载数据中...', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' }); $.ajax({ url: baseUrl + '/basOutStationArea/data/auth', headers: { 'token': localStorage.getItem('token') }, method: 'GET', success: function(res) { loading.close(); if (res.code === 200) { that.stations = res.data.stations || []; that.areas = res.data.areas || []; that.relations = res.data.relations || []; that.$nextTick(function() { that.updateLines(); }); } else if (res.code === 403) { top.location.href = baseUrl + "/"; } else { that.$message.error('加载数据失败: ' + res.msg); } }, error: function() { loading.close(); that.$message.error('加载请求异常'); } }); }, saveData: function() { var that = this; this.saving = true; var payload = { areas: this.areas, relations: this.relations }; $.ajax({ url: baseUrl + '/basOutStationArea/save/auth', type: 'POST', headers: { 'token': localStorage.getItem('token') }, contentType: 'application/json', data: JSON.stringify(payload), success: function (res) { that.saving = false; if (res.code === 200) { that.$message.success('保存成功'); that.loadData(); } else { that.$message.error('保存失败: ' + res.msg); } }, error: function () { that.saving = false; that.$message.error('保存请求异常'); } }); }, addArea: function() { var code = (this.newAreaCode || '').trim(); var name = (this.newAreaName || '').trim(); if (!code || !name) { this.$message.warning('请输入区域编码和名称'); return; } var exists = this.areas.some(function(a) { return a.areaCode === code; }); if (exists) { this.$message.warning('区域已存在'); return; } this.areas.push({ areaCode: code, areaName: name }); this.newAreaCode = ''; this.newAreaName = ''; this.$nextTick(this.updateLines); }, removeArea: function(areaCode) { this.areas = this.areas.filter(function(a) { return a.areaCode !== areaCode; }); this.relations = this.relations.filter(function(r) { return r.areaCode !== areaCode; }); this.$nextTick(this.updateLines); }, isStationBound: function(stationId) { return this.relations.some(function(r) { return r.stationId == stationId; }); }, isAreaBound: function(areaCode) { return this.relations.some(function(r) { return r.areaCode == areaCode; }); }, onDragStart: function(event, item, type) { this.draggingItem = { item: item, type: type }; event.dataTransfer.effectAllowed = 'link'; }, onDragEnd: function() { this.draggingItem = null; this.draggingLine = null; }, onDrop: function(event, targetArea) { if (!this.draggingItem || this.draggingItem.type !== 'station') return; var station = this.draggingItem.item; var exists = this.relations.some(function(r) { return r.stationId == station.stationId && r.areaCode == targetArea.areaCode; }); if (exists) { this.$message.warning('该绑定已存在'); return; } this.relations.push({ stationId: station.stationId, areaCode: targetArea.areaCode }); this.$message.success('已建立绑定: 站点 ' + station.stationId + ' -> 区域 ' + (targetArea.areaName || targetArea.areaCode)); this.$nextTick(this.updateLines); }, confirmDelete: function(index) { var rel = this.lines[index] && this.lines[index].relation; if (!rel) return; this.relations = this.relations.filter(function(r) { return !(r.stationId == rel.stationId && r.areaCode == rel.areaCode); }); this.$nextTick(this.updateLines); }, updateLines: function() { var svg = document.querySelector('svg'); if (!svg) return; var svgRect = svg.getBoundingClientRect(); var newLines = []; this.relations.forEach(function(rel) { var sDom = document.getElementById('station-' + rel.stationId); var aDom = document.getElementById('area-' + rel.areaCode); if (sDom && aDom) { var sRect = sDom.getBoundingClientRect(); var aRect = aDom.getBoundingClientRect(); var x1 = sRect.right - svgRect.left; var y1 = sRect.top + sRect.height / 2 - svgRect.top; var x2 = aRect.left - svgRect.left; var y2 = aRect.top + aRect.height / 2 - svgRect.top; newLines.push({ x1: x1, y1: y1, x2: x2, y2: y2, relation: rel, stationId: rel.stationId, areaCode: rel.areaCode }); } }); this.lines = newLines; } } });