#
Junjie
2026-01-12 c397643ce84b62690c814fc1dbca04a110647d1a
#
2个文件已修改
14个文件已添加
515 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/BasOutStationAreaController.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/CreateOutTaskParam.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasOutArea.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasOutStationArea.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasOutAreaMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasOutStationAreaMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasOutAreaService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasOutStationAreaService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasOutAreaServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasOutStationAreaServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/docs/WCS外部HTTP API接口V1.4.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasOutAreaMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasOutStationAreaMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basOutStationArea/basOutStationArea.js 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basOutStationArea/basOutStationArea.html 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/BasOutStationAreaController.java
New file
@@ -0,0 +1,106 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.BasOutArea;
import com.zy.asrs.entity.BasOutStationArea;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.BasOutAreaService;
import com.zy.asrs.service.BasOutStationAreaService;
import com.zy.asrs.service.BasStationService;
import com.zy.common.web.BaseController;
import com.zy.core.model.StationObjModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/basOutStationArea")
public class BasOutStationAreaController extends BaseController {
    @Autowired
    private BasOutAreaService basOutAreaService;
    @Autowired
    private BasOutStationAreaService basOutStationAreaService;
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private BasStationService basStationService;
    @RequestMapping("/data/auth")
    @ManagerAuth
    public R data() {
        Map<String, Object> data = new HashMap<>();
        List<Integer> stationIds = new ArrayList<>();
        List<BasDevp> devps = basDevpService.selectList(new EntityWrapper<BasDevp>().eq("status", 1));
        for (BasDevp devp : devps) {
            for (StationObjModel stationObjModel : devp.getOutStationList$()) {
                stationIds.add(stationObjModel.getStationId());
            }
        }
        List<BasStation> stations = stationIds.isEmpty()
                ? new ArrayList<>()
                : basStationService.selectList(new EntityWrapper<BasStation>().in("station_id", stationIds));
        data.put("stations", stations);
        List<BasOutArea> areas = basOutAreaService.selectList(new EntityWrapper<>());
        data.put("areas", areas);
        List<BasOutStationArea> relations = basOutStationAreaService.selectList(new EntityWrapper<>());
        data.put("relations", relations);
        return R.ok(data);
    }
    @RequestMapping("/save/auth")
    @ManagerAuth
    public R save(@RequestBody JSONObject payload) {
        JSONArray areas = payload.getJSONArray("areas");
        JSONArray relations = payload.getJSONArray("relations");
        basOutAreaService.delete(new EntityWrapper<>());
        basOutStationAreaService.delete(new EntityWrapper<>());
        if (areas != null && !areas.isEmpty()) {
            List<BasOutArea> areaList = new ArrayList<>();
            for (int i = 0; i < areas.size(); i++) {
                JSONObject o = areas.getJSONObject(i);
                BasOutArea a = new BasOutArea();
                a.setAreaCode(o.getString("areaCode"));
                a.setAreaName(o.getString("areaName"));
                areaList.add(a);
            }
            if (!areaList.isEmpty()) {
                basOutAreaService.insertBatch(areaList);
            }
        }
        if (relations != null && !relations.isEmpty()) {
            List<BasOutStationArea> relList = new ArrayList<>();
            for (int i = 0; i < relations.size(); i++) {
                JSONObject o = relations.getJSONObject(i);
                BasOutStationArea r = new BasOutStationArea();
                r.setStationId(o.getInteger("stationId"));
                r.setAreaCode(o.getString("areaCode"));
                relList.add(r);
            }
            if (!relList.isEmpty()) {
                basOutStationAreaService.insertBatch(relList);
            }
        }
        return R.ok();
    }
}
src/main/java/com/zy/asrs/domain/param/CreateOutTaskParam.java
@@ -8,13 +8,16 @@
    //wms任务号
    private String taskNo;
    //目标站
    private Integer staNo;
    //出库库位
    private String locNo;
    //任务优先级
    private Integer taskPri;
    //目标站
    private Integer staNo;
    //出库区域
    private String outArea;
}
src/main/java/com/zy/asrs/entity/BasOutArea.java
New file
@@ -0,0 +1,24 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("asr_bas_out_area")
public class BasOutArea implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @TableField("area_code")
    private String areaCode;
    @TableField("area_name")
    private String areaName;
}
src/main/java/com/zy/asrs/entity/BasOutStationArea.java
New file
@@ -0,0 +1,24 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("asr_bas_out_station_area")
public class BasOutStationArea implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @TableField("station_id")
    private Integer stationId;
    @TableField("area_code")
    private String areaCode;
}
src/main/java/com/zy/asrs/mapper/BasOutAreaMapper.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.BasOutArea;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface BasOutAreaMapper extends BaseMapper<BasOutArea> {
}
src/main/java/com/zy/asrs/mapper/BasOutStationAreaMapper.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.BasOutStationArea;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface BasOutStationAreaMapper extends BaseMapper<BasOutStationArea> {
}
src/main/java/com/zy/asrs/service/BasOutAreaService.java
New file
@@ -0,0 +1,7 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.BasOutArea;
public interface BasOutAreaService extends IService<BasOutArea> {
}
src/main/java/com/zy/asrs/service/BasOutStationAreaService.java
New file
@@ -0,0 +1,7 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.BasOutStationArea;
public interface BasOutStationAreaService extends IService<BasOutStationArea> {
}
src/main/java/com/zy/asrs/service/impl/BasOutAreaServiceImpl.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.BasOutArea;
import com.zy.asrs.mapper.BasOutAreaMapper;
import com.zy.asrs.service.BasOutAreaService;
import org.springframework.stereotype.Service;
@Service
public class BasOutAreaServiceImpl extends ServiceImpl<BasOutAreaMapper, BasOutArea> implements BasOutAreaService {
}
src/main/java/com/zy/asrs/service/impl/BasOutStationAreaServiceImpl.java
New file
@@ -0,0 +1,11 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.BasOutStationArea;
import com.zy.asrs.mapper.BasOutStationAreaMapper;
import com.zy.asrs.service.BasOutStationAreaService;
import org.springframework.stereotype.Service;
@Service
public class BasOutStationAreaServiceImpl extends ServiceImpl<BasOutStationAreaMapper, BasOutStationArea> implements BasOutStationAreaService {
}
src/main/java/com/zy/common/service/CommonService.java
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
@Slf4j
@Service
@@ -43,6 +44,8 @@
    private NavigateUtils navigateUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private BasOutStationAreaService basOutStationAreaService;
    /**
     * ç”Ÿæˆå·¥ä½œå·
@@ -302,7 +305,23 @@
        }
        Integer crnNo = findCrnResult.getCrnNo();
        Integer sourceStationId = this.findOutStationId(findCrnResult, param.getStaNo());
        Integer staNo = param.getStaNo();
        String outArea = param.getOutArea();
        if(Cools.isEmpty(staNo) && Cools.isEmpty(outArea)) {
            throw new CoolException("请传入出库站点或出库区域");
        }
        if(Cools.isEmpty(staNo)) {
            List<BasOutStationArea> areaList = basOutStationAreaService.selectList(new EntityWrapper<BasOutStationArea>().eq("area_code", outArea));
            if (areaList.isEmpty()) {
                throw new CoolException("出库区域不存在");
            }
            int nextInt = new Random().nextInt(areaList.size());
            BasOutStationArea basOutStationArea = areaList.get(nextInt);
            staNo = basOutStationArea.getStationId();
        }
        Integer sourceStationId = this.findOutStationId(findCrnResult, staNo);
        if (sourceStationId == null) {
            throw new CoolException("未找到输送目标站点可走行路径");
        }
@@ -318,7 +337,7 @@
        wrkMast.setIoPri(ioPri);
        wrkMast.setSourceLocNo(locMast.getLocNo()); // æºåº“位
        wrkMast.setSourceStaNo(sourceStationId);//源站
        wrkMast.setStaNo(param.getStaNo());//目标站
        wrkMast.setStaNo(staNo);//目标站
        wrkMast.setWmsWrkNo(param.getTaskNo());
        wrkMast.setBarcode(locMast.getBarcode());
        wrkMast.setAppeTime(now);
src/main/resources/docs/WCSÍⲿHTTP API½Ó¿ÚV1.4.docx
Binary files differ
src/main/resources/mapper/BasOutAreaMapper.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.BasOutAreaMapper">
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BasOutArea">
        <id column="id" property="id"/>
        <result column="area_code" property="areaCode"/>
        <result column="area_name" property="areaName"/>
    </resultMap>
</mapper>
src/main/resources/mapper/BasOutStationAreaMapper.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.BasOutStationAreaMapper">
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BasOutStationArea">
        <id column="id" property="id"/>
        <result column="station_id" property="stationId"/>
        <result column="area_code" property="areaCode"/>
    </resultMap>
</mapper>
src/main/webapp/static/js/basOutStationArea/basOutStationArea.js
New file
@@ -0,0 +1,167 @@
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;
        }
    }
});
src/main/webapp/views/basOutStationArea/basOutStationArea.html
New file
@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>出库站与出库区域绑定配置</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../../static/vue/element/element.css">
    <link rel="stylesheet" href="../../static/css/cool.css">
    <style>
        html, body { height: 100%; margin: 0; padding: 0; background-color: #f0f2f5; }
        #app { height: 100%; padding: 20px; box-sizing: border-box; display: flex; flex-direction: column; }
        .main-card { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
        .flow-container { flex: 1; display: flex; position: relative; background: #fff; border: 1px solid #ebeef5; overflow: hidden; }
        .column { width: 300px; display: flex; flex-direction: column; border-right: 1px solid #ebeef5; background-color: #fcfcfc; z-index: 10; }
        .column.right { border-right: none; border-left: 1px solid #ebeef5; position: absolute; right: 0; top: 0; bottom: 0; }
        .column-header { padding: 15px; text-align: center; font-weight: bold; background-color: #f5f7fa; border-bottom: 1px solid #ebeef5; color: #606266; }
        .list-container { flex: 1; overflow-y: auto; padding: 10px; }
        .node-item { padding: 12px; margin-bottom: 10px; background-color: #fff; border: 1px solid #dcdfe6; border-radius: 4px; cursor: grab; transition: all 0.3s; position: relative; color: #606266; font-size: 14px; display: flex; justify-content: space-between; align-items: center; }
        .node-item:hover { box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1); border-color: #409eff; }
        .node-item.active { background-color: #ecf5ff; border-color: #409eff; color: #409eff; }
        .station-node { border-left: 4px solid #67c23a; }
        .area-node { border-left: 4px solid #e6a23c; }
        .canvas-area { flex: 1; position: relative; margin-right: 300px; background-color: #fafafa; overflow: hidden; }
        svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
        svg line { stroke: #909399; stroke-width: 2; cursor: pointer; pointer-events: stroke; transition: stroke-width 0.2s, stroke 0.2s; }
        svg line:hover { stroke: #f56c6c; stroke-width: 4; }
        .toolbar { padding: 10px 0; display: flex; justify-content: space-between; align-items: center; }
        .area-toolbar { padding: 10px; border-bottom: 1px solid #ebeef5; }
    </style>
    </head>
<body>
<div id="app" v-cloak>
    <el-card class="main-card" :body-style="{ padding: '0px', display: 'flex', flexDirection: 'column', height: '100%' }">
        <div slot="header" class="clearfix">
            <span style="font-weight: bold; font-size: 16px;">出库站与出库区域绑定配置</span>
            <div style="float: right;">
                <el-button type="primary" icon="el-icon-check" size="small" @click="saveData" :loading="saving">保存配置</el-button>
                <el-button icon="el-icon-refresh" size="small" @click="loadData">刷新</el-button>
            </div>
        </div>
        <div class="toolbar" style="padding: 10px 20px; border-bottom: 1px solid #ebeef5;">
            <el-alert title="操作说明:拖拽左侧【出库站点】到右侧【出库区域】上建立绑定。点击连线可删除绑定。" type="info" show-icon :closable="false"></el-alert>
        </div>
        <div class="flow-container" ref="flowContainer">
            <div class="column">
                <div class="column-header">出库站点 ({{ stations.length }})</div>
                <div class="list-container" ref="stationList">
                    <div v-for="item in stations" :key="'s-' + item.stationId" :id="'station-' + item.stationId" class="node-item station-node" :class="{ active: isStationBound(item.stationId) }" draggable="true" @dragstart="onDragStart($event, item, 'station')" @dragend="onDragEnd">
                        <span>{{ item.stationId }}</span>
                    </div>
                </div>
            </div>
            <div class="canvas-area">
                <svg width="100%" height="100%">
                    <line v-for="(link, index) in lines" :key="index" :x1="link.x1" :y1="link.y1" :x2="link.x2" :y2="link.y2" @click="confirmDelete(index)">
                        <title>点击删除绑定: ç«™ç‚¹ {{ link.stationId }} -> åŒºåŸŸ {{ link.areaCode }}</title>
                    </line>
                    <line v-if="draggingLine" :x1="draggingLine.x1" :y1="draggingLine.y1" :x2="draggingLine.x2" :y2="draggingLine.y2" stroke="#409eff" stroke-dasharray="5,5" stroke-width="2" />
                </svg>
            </div>
            <div class="column right">
                <div class="column-header">出库区域 ({{ areas.length }})</div>
                <div class="area-toolbar">
                    <el-input size="small" placeholder="区域编码" v-model="newAreaCode" style="width: 140px; margin-right: 8px;"></el-input>
                    <el-input size="small" placeholder="区域名称" v-model="newAreaName" style="width: 140px; margin-right: 8px;"></el-input>
                    <el-button size="small" type="primary" icon="el-icon-plus" @click="addArea">新增区域</el-button>
                </div>
                <div class="list-container" ref="areaList">
                    <div v-for="item in areas" :key="'a-' + item.areaCode" :id="'area-' + item.areaCode" class="node-item area-node" :class="{ active: isAreaBound(item.areaCode) }" @dragover.prevent @drop="onDrop($event, item)">
                        <span>{{ item.areaCode }} - {{ item.areaName }}</span>
                        <el-button type="text" size="mini" @click="removeArea(item.areaCode)">删除</el-button>
                    </div>
                </div>
            </div>
        </div>
    </el-card>
</div>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
<script type="text/javascript" src="../../static/vue/element/element.js"></script>
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/basOutStationArea/basOutStationArea.js"></script>
</body>
</html>