whychdw
2020-12-04 fab2a7b8694d1c088a62eeb51668773dc49e12d1
3D机房配置
5个文件已添加
14个文件已修改
1488 ■■■■■ 已修改文件
package-lock.json 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/theme/science-black.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/common.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/apis/pageSetting/index.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/apis/pageSetting/threeHomeSetting.js 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/HdwDialog.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ThreeHome/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/BattParamsTooltip/index.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/BattParamsTooltip/index.vue 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/history.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/threeHome.vue 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/pageSetting/dialog/AddThreeHomeSetting.vue 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/pageSetting/dialog/EditThreeHomeSetting.vue 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/pageSetting/dialog/UploadPicture.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/pageSetting/threeHomeSetting.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/routes.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -1,6 +1,6 @@
{
  "name": "admin_manage",
  "version": "2.1.7",
  "version": "2.1.8",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
@@ -11472,6 +11472,11 @@
      "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz?cache=0&sync_timestamp=1595984005097&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.11.tgz",
      "integrity": "sha1-dllNh31LEiNEBuhONSdcbVFBJcU="
    },
    "vue-draggable-resizable": {
      "version": "2.2.0",
      "resolved": "https://registry.npm.taobao.org/vue-draggable-resizable/download/vue-draggable-resizable-2.2.0.tgz",
      "integrity": "sha1-60WBtt3WogxfVPmZk8hkY4JSMpY="
    },
    "vue-eslint-parser": {
      "version": "7.1.0",
      "resolved": "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-7.1.0.tgz?cache=0&sync_timestamp=1589539313907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-7.1.0.tgz",
package.json
@@ -21,6 +21,7 @@
    "qs": "^6.9.4",
    "script-loader": "^0.7.2",
    "vue": "^2.6.11",
    "vue-draggable-resizable": "^2.2.0",
    "vue-jsonp": "^0.1.8",
    "vue-layer": "^1.2.0",
    "vue-router": "^3.4.3",
public/theme/science-black.css
@@ -760,6 +760,12 @@
.science-box .box-header {
    color: #FFFD1E;
}
.science-box .box-content::before {
    border-color: #05ccd3 transparent transparent !important;
}
.science-box .box-content::after {
    border-color: #153953  transparent transparent !important;
}
.el-science-blue .baoji-group-list a {
    color: #1fcbdf !important;
src/assets/css/common.css
@@ -175,3 +175,9 @@
    left: 0;
    z-index: 0;
}
.el-science-blue .vdr {
    border: 4px dashed #0b388b;
}
.el-science-blue .handle {
    background: #1f66e7;
}
src/assets/js/apis/pageSetting/index.js
@@ -1,5 +1,7 @@
import realTime from './realTime'   // 实时页面
import threeHomeSetting from "@/assets/js/apis/pageSetting/threeHomeSetting";
export default {
    realTime
    realTime,
    threeHomeSetting
}
src/assets/js/apis/pageSetting/threeHomeSetting.js
New file
@@ -0,0 +1,83 @@
import axios from "axios";
export default {
    /**
     * 批量添加3D机房配置
     * @param data
     * @returns {AxiosPromise}
     */
    add(data) {
        return axios({
            method: 'post',
            url: 'Station3DAction!addBatch',
            data: 'json='+JSON.stringify(data)
        });
    },
    /**
     * 批量删除3D机房配置
     * @param data
     * @returns {AxiosPromise}
     */
    del(data) {
        return axios({
            method: 'post',
            url: 'Station3DAction!delete',
            data: 'json='+JSON.stringify(data)
        });
    },
    /**
     * 批量更新3D机房的配置
     * @param data
     * @returns {AxiosPromise}
     */
    update(data) {
        return axios({
            method: 'post',
            url: 'Station3DAction!updateBatch',
            data: 'json='+JSON.stringify(data)
        });
    },
    /**
     * 查询所有的配置
     * @returns {AxiosPromise}
     */
    searchAll() {
        return axios({
            method: 'post',
            url: 'Station3DAction!getAll',
            data: null
        });
    },
    /**
     * 根据设备id查询配置
     * @param data
     * @returns {AxiosPromise}
     */
    searchByDevId(data) {
        return axios({
            method: 'post',
            url: 'Station3DAction!getByDeviceId',
            data: 'json='+JSON.stringify(data)
        });
    },
    /**
     * 获取所有的图片资源
     * @returns {AxiosPromise}
     */
    searchPicture() {
        return axios({
            method: 'post',
            url: 'Station3DAction!pictureLoad',
            data: null
        });
    },
    /**
     * 上传图片资源
     */
    uploadPicture(data) {
        return axios({
            method: 'post',
            url: 'Station3DAction!uploadPicture',
            data: 'json='+JSON.stringify(data)
        });
    },
}
src/components/HdwDialog.vue
@@ -1,13 +1,54 @@
<template>
    $END$
    <div class="hdw-dialog" v-if="visible">
        <div class="hdw-dialog-close" @click="close">X</div>
        <div class="hdw-dialog-content">
            <slot></slot>
        </div>
    </div>
</template>
<script>
    export default {
        name: "HdwDialog"
        name: "HdwDialog",
        props: {
            visible: {
                type: Boolean,
                default: false,
            }
        },
        methods: {
            close() {
                this.$emit("update:visible", false);
            }
        }
    }
</script>
<style scoped>
    .hdw-dialog {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-color: #00000090;
        z-index: 100;
    }
    .hdw-dialog-close {
        position: absolute;
        top: 8px;
        right: 8px;
        cursor: pointer;
        user-select: none;
    }
    .hdw-dialog-close:hover {
        color: #FF0000;
    }
    .hdw-dialog-content {
        display: flex;
        justify-content: center; /* 水平居中 */
        align-items: center;     /* 垂直居中 */
        width: 100%;
        height: 100%;
    }
</style>
src/components/ThreeHome/index.vue
@@ -14,7 +14,7 @@
        props: {
            bg: {
                type: String,
                default: "1.png"
                default: "3.png"
            },
            activeArea: {
                type: Array,
@@ -56,7 +56,11 @@
            },
            initBg() {
                try {
                    const imageSrc = require(`@/assets/images/${this.bg}`);
                    let baseUrl= window.location.origin+"/fg_photo_3DStation/";
                    if(process.env.NODE_ENV == 'dev') {
                        baseUrl = "http://localhost:6798/fg_photo_3DStation/"
                    }
                    const imageSrc = baseUrl+this.bg;
                    const image = new Image();
                    image.src=imageSrc;
                    image.onload = (()=>{
src/main.js
@@ -24,6 +24,9 @@
import apis from './assets/js/apis'
Vue.use(VueJsonp)
import 'vue-draggable-resizable/dist/VueDraggableResizable.css';
import VueDraggableResizable from "vue-draggable-resizable";
Vue.component('vue-draggable-resizable', VueDraggableResizable);
Vue.prototype.$layer = layer(Vue);
Vue.use(ElementUI, {
src/pages/dataTest/BattParamsTooltip/index.js
@@ -0,0 +1,93 @@
export default {
    getBattParams() {
        return [
            {
                id: 1,
                name: "workState",
                type: "",
                icon: "",
                text: "电池状态:",
                value: "在线浮充",
                show: false
            },
            {
                id: 2,
                name: "onlineVol",
                type: "",
                icon: "",
                text: "在线电压:",
                value: "0.00",
                unit: "V",
                show: false
            },
            {
                id: 3,
                name: "groupVol",
                type: "",
                icon: "",
                text: "组端电压:",
                value: "0.00",
                unit: "V",
                show: false
            },
            {
                id: 4,
                name: "groupVol",
                type: "",
                icon: "",
                text: "电池电流:",
                value: "0",
                unit: "A",
                show: false
            },
            {
                id: 5,
                name: "updateTime",
                type: "",
                icon: "",
                text: "更新日期:",
                value: "1980-01-01 00:00:00",
                show: false
            },
            {
                id: 6,
                name: "testTimeLong",
                type: "",
                icon: "",
                text: "测试时长:",
                value: "00:00:00",
                show: false
            },
            {
                id: 7,
                name: "testCap",
                type: "",
                icon: "",
                text: "测试容量:",
                value: "0",
                unit: 'AH',
                show: false
            },
            {
                id: 8,
                name: "resCap",
                type: "",
                icon: "",
                text: "剩余容量:",
                value: "0",
                unit: 'AH',
                show: false
            },
            {
                id: 9,
                name: "xuhang",
                type: "",
                icon: "",
                text: "续航时长:",
                value: "——",
                show: false
            },
        ]
    }
}
src/pages/dataTest/BattParamsTooltip/index.vue
@@ -1,13 +1,160 @@
<template>
    $END$
    <div class="science-box" ref="scienceBox" :style="getStyle">
        <div class="box-content">
            <div class="box-header">
                {{batt.BattGroupName}}
            </div>
            <div class="box-body">
                <div class="table-layout">
                    <div v-for="state in stateList" :key="state.text" class="table-row" :class="state.type">
                        <div class="table-cell text-right">
                            <i v-if="state.icon" class="iconfont" :class="state.icon"></i>{{ state.text }}
                        </div>
                        <div class="table-cell">
                            {{ state.value }}{{ state.unit }}
                        </div>
                    </div>
                </div>
            </div>
            <div class="box-footer">
                <el-button type="primary" size="mini">单体信息</el-button>
                <el-button type="primary" size="mini">核容测试</el-button>
                <el-button type="primary" size="mini">停止测试</el-button>
            </div>
        </div>
    </div>
</template>
<script>
    import tools from './index'
    export default {
        name: "index"
        name: "BattParamsTooltip",
        props: {
            title: {
                type: String,
                default: ''
            },
            top: {
                type: Number,
                default: 0,
            },
            left: {
                type: Number,
                default: 0,
            },
            cssWidth: {
                type: [Number, String],
                default() {
                    return 'auto';
                }
            },
            cssHeight: {
                type: [Number, String],
                default: 'auto'
            },
            bMax: {
                type: Number,
                default: 20000,
            },
            noHeader: {
                type: Boolean,
                default: false
            },
            batt: {
                type: Object,
                default() {
                    return {}
                }
            },
        },
        data() {
            return {
                height: 0,
                stateList: tools.getBattParams()
            }
        },
        methods: {
            getInfo() {
                return {
                    width: this.$refs.scienceBox.offsetWidth,
                    height: this.$refs.scienceBox.offsetHeight+20,
                };
            }
        },
        computed: {
            getStyle() {
                let bottom = this.top+this.height;
                let realTop = bottom>(this.bMax-8)?this.bMax-8-this.height:this.top;
                return {
                    top: realTop+'px',
                    left: this.left+'px',
                    width: typeof this.cssWidth == 'number' ? this.cssWidth + 'px' : this.cssWidth,
                    height: typeof this.cssHeight == 'number' ? this.cssHeight + 'px' : this.cssHeight
                }
            }
        },
        mounted() {
            this.height = this.$refs.scienceBox.offsetHeight;
        },
    }
</script>
<style scoped>
    .science-box {
        position: absolute;
        top: 0;
        left: 0;
        box-sizing: border-box;
        border: 2Px solid #037fab;
        /* border-image: linear-gradient(#12566d, #197796, #6decff, #197796, #12566d) 9; */
        background-color: #0b388a;
        color: #FFFFFF;
        z-index: 9;
        border-radius: 6Px;
        font-size: 14Px;
    }
    .box-content {
        position: relative;
        height: 100%;
        padding-top: 6Px;
        padding-bottom: 6Px;
        padding-left: 12Px;
        padding-right: 12Px;
        /* background-image: linear-gradient(#164586, #143a6e, #0f2e5a, #07172e); */
        box-sizing: border-box;
    }
    .box-content::before {
        content: '';
        width: 0;
        height: 0;
        border: 20Px solid;
        position: absolute;
        bottom: -40Px;
        left: 100Px;
        border-color: #037fab transparent transparent;
    }
    .box-content::after {
        content: '';
        width: 0;
        height: 0;
        border: 20Px solid;
        position: absolute;
        bottom: -37Px;
        left: 100Px;
        border-color: #0b388a transparent transparent;
    }
    .box-header {
        font-size: 16px;
        text-align: center;
        font-weight: bold;
        padding-top: 6Px;
        padding-bottom: 6Px;
    }
    .box-body {
        min-width: 100Px;
    }
    .box-footer {
        text-align: right;
        padding-top: 4px;
    }
</style>
src/pages/dataTest/history.vue
@@ -741,13 +741,15 @@
            // 格式化历史信息数据
            formateHisData(data) {
                let record_time = -1; // 记录时间
                let record_num = -100;  // 记录笔数
                allData.endData = data[data.length-1];
                data.forEach(item => {
                    let mon_num = item.mon_num;
                    let testTimeLong = formatSeconds(item.test_timelong);
                    // 获取组端电压,在线电压,组端电流的信息和开辟一个单体柱状图
                    if (record_time != item.record_time) {
                    if (record_num != item.record_num) {
                        record_time = item.record_time;
                        record_num = item.record_num;
                        allData.groupVol.push([testTimeLong, item.group_vol]);
                        allData.onlineVol.push([testTimeLong, item.online_vol]);
                        allData.testCurr.push([testTimeLong, item.test_curr]);
src/pages/dataTest/threeHome.vue
@@ -1,12 +1,12 @@
<template>
    <flex-layout direction="row" :no-bg="true">
        <home-list slot="header"></home-list>
        <div class="flex-content">
            <div class="three-home-wrapper">
                <three-home
                    @handleClick="handleClick"
                    :active-area="activeArae">
                    <batt-params-tooltip v-show="group1.show" :top="group1Params.top" :left="group1Params.left" ref="group1Tooltip"></batt-params-tooltip>
                    <batt-params-tooltip v-show="group2.show" :top="group2Params.top" :left="group2Params.left" ref="group2Tooltip"></batt-params-tooltip>
                </three-home>
            </div>
            <science-box title="设备参数" :top="8" :left="8" v-show="stateListState">
@@ -26,42 +26,58 @@
</template>
<script>
    import HomeList from "@/pages/HomeList";
    import ThreeHome from "@/components/ThreeHome";
    import ScienceBox from "@/components/ScienceBox";
    import BattParamsTooltip from "@/pages/dataTest/BattParamsTooltip";
    import {
        const_61850
    } from "@/assets/js/const";
    export default {
        name: "pagesThreeHome",
        components: {
            HomeList,
            ThreeHome,
            ScienceBox
            ScienceBox,
            BattParamsTooltip,
        },
        data() {
            let stateList = const_61850.stateList;
            return {
                group1: {
                    show: false,
                    batt: {},
                    tooltipInfo: {
                        width: 0,
                        height: 0,
                    },
                    area: {
                        id: "group1",
                        groupName: "电池组1",
                        deviceId: 910001,
                        battGroupId: 10001,
                        pictureName: "呵呵",
                        positionX: 682,
                        positionY: 132,
                        length: 285,
                        width: 69,
                        positionX: 163,
                        positionY: 169,
                        length: 100,
                        width: 60,
                    }
                },
                group2: {
                    show: false,
                    batt: {},
                    tooltipInfo: {
                        width: 0,
                        height: 0,
                    },
                    area: {
                        id: "group2",
                        groupName: "电池组2",
                        deviceId: 910002,
                        battGroupId: 10002,
                        pictureName: "呵呵",
                        positionX: 310,
                        positionY: 406,
                        length: 320,
                        width: 56,
                        positionX: 288,
                        positionY: 169,
                        length: 98,
                        width: 60,
                    }
                },
                stateListShow: false,
@@ -70,7 +86,12 @@
        },
        methods: {
            handleClick(info) {
                console.log(info);
                this.group1.show = false;
                this.group2.show = false;
                this[info.id].show = true;
                this.$nextTick(()=>{
                    this.changeTooltipInfo();
                });
            },
            // 查询拓扑图状态的显示
            searchStatus() {
@@ -97,6 +118,15 @@
                }
                return result;
            },
            changeTooltipInfo() {
                // 设置宽高
                let group1Info = this.$refs.group1Tooltip.getInfo();
                this.group1.tooltipInfo = group1Info;
                // 设置宽高
                let group2Info = this.$refs.group2Tooltip.getInfo();
                this.group2.tooltipInfo = group2Info;
            }
        },
        computed: {
            activeArae() {
@@ -115,10 +145,33 @@
            stateListState() {
                return this.stateListShow && this.showStateList.length;
            },
            group1Params() {
                let group = this.group1;
                let left = group.area.positionX+group.area.length/2-group.tooltipInfo.width/2;
                let top = group.area.positionY-group.tooltipInfo.height;
                return {
                    top: top,
                    left: left
                }
            },
            group2Params() {
                let group = this.group2;
                let left = group.area.positionX+group.area.length/2-group.tooltipInfo.width/2;
                let top = group.area.positionY-group.tooltipInfo.height;
                return {
                    top: top,
                    left: left
                }
            }
        },
        mounted() {
            // 查询拓扑图状态的显示
            this.searchStatus();
            this.changeTooltipInfo();
            // 监测浏览器窗口大小改变
            window.addEventListener("resize", ()=>{
                this.changeTooltipInfo();
            });
        }
    }
</script>
src/pages/index.vue
@@ -55,6 +55,9 @@
                </div>
            </div>
        </content-box>
        <hdw-dialog :visible.sync="hdwDialog">
            <pages-three-home></pages-three-home>
        </hdw-dialog>
    </flex-layout>
</template>
@@ -67,7 +70,9 @@
    import InfoWindowTest from "../components/InfoWindowTest";
    import InfoPanel from "../components/indexPanel/InfoPanel"
    import AddPanel from "@/components/indexPanel/AddPanel";
    import HomeList from "./HomeList"
    import HomeList from "./HomeList";
    import HdwDialog from "@/components/HdwDialog";
    import PagesThreeHome from '@/pages/dataTest/threeHome';
    import {
        searchCoordinateMove,
        searchMap,
@@ -77,7 +82,7 @@
        setMapCenterPoint,
        delMapHome,
        searchMapHomeState,
        getAllMapOutlineAction
        getAllMapOutlineAction,
    } from '../assets/js/api'
    import {
        isHasPermit,
@@ -147,7 +152,9 @@
            PieChart,
            HomeList,
            cityChart,
            InfoPanel
            InfoPanel,
            HdwDialog,
            PagesThreeHome,
        },
        data() {
            let permits = this.$store.state.user.permits;
@@ -156,8 +163,9 @@
            return {
                isCanEdit: isCanEdit,
                isCanDel: isCanDel,
                hdwDialog: false,
                timer: new Timeout('index'),
                mapName: 'qingyuan',
                mapName: '',
                mapInfoX: null,
                mapInfoY: null,
                mapInfoTitle: '',
src/pages/pageSetting/dialog/AddThreeHomeSetting.vue
New file
@@ -0,0 +1,294 @@
<template>
    <div class="params-dialog">
        <el-form ref="ruleForm" size="mini" label-position="top" :model="params" :rules="rules">
            <el-row :gutter="layout.gutter">
                <el-col :span="layout.span">
                    <el-form-item label="站点名称" prop="stationName">
                        <el-select
                            size="small"
                            v-model="params.deviceId"
                            filterable
                            :filter-method="homeFilter"
                            placeholder="请选择"
                            clearable
                            @change="filterChange">
                            <el-option
                                v-for="item in homeList"
                                :key="item.id"
                                :label="item.label"
                                :value="item.id">
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="layout.span">
                    <el-form-item label="3D图片列表" prop="pictureName">
                        <el-select
                            size="small"
                            v-model="params.pictureName"
                            filterable
                            :filter-method="homeFilter"
                            placeholder="请选择"
                            clearable>
                            <el-option
                                v-for="item in pictureList"
                                :key="item.id"
                                :label="item.label"
                                :value="item.id">
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="24">
                    <three-home :bg="params.pictureName">
                        <vue-draggable-resizable
                            v-if="group1"
                            :x="0" :y="0"
                            :w="100" :h="100"
                            :parent="true"
                            @dragging="onDrag" @resizing="onResize">
                            <span class="red-color">{{battGroups[0].battGroupName}}</span>
                        </vue-draggable-resizable>
                        <vue-draggable-resizable
                                v-if="group2"
                                :x="0" :y="150"
                                :w="100" :h="100"
                                :parent="true"
                                @dragging="onGroup2Drag" @resizing="onGroup2Resize">
                            <span class="red-color">{{battGroups[1].battGroupName}}</span>
                        </vue-draggable-resizable>
                    </three-home>
                </el-col>
            </el-row>
            <div class="form-footer">
                <three-btn @click="handleOk">确定</three-btn>
                <three-btn @click="close">取消</three-btn>
            </div>
        </el-form>
    </div>
</template>
<script>
    import pinyinMatch from "pinyin-match";
    import ThreeHome from "@/components/ThreeHome/index";
    import {searchBattInfo, searchStation} from "@/assets/js/api";
    import {extend} from "@/assets/js/tools";
    export default {
        name: "AddThreeHomeSetting",
        components: {
            ThreeHome,
        },
        props: {
            visible: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                layout: {
                    span: 12,
                    gutter: 16
                },
                params: {
                    deviceId: "",
                    stationName: "",
                    pictureName: "",
                    pictureUrl: "123",
                },
                rules: {},
                group1: false,
                group2: false,
                battGroups: [
                    {
                        battGroupId: 0,
                        battGroupName: "",
                        positionX: 0,
                        positionY:0,
                        length:0,
                        width: 0
                    },
                    {
                        battGroupId: 1,
                        battGroupName: "",
                        positionX: 0,
                        positionY:150,
                        length:0,
                        width: 0
                    },
                ],
                homeList: [],
                homeListCopy: [],
                pictureList: []
            };
        },
        methods: {
            searchStations() {
                searchStation({
                    StationName1:"",
                    StationName2:"",
                    StationName5:"",
                }).then((res)=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data.map(item=>{
                            item.id = item.FBSDeviceId;
                            item.label = item.StationName;
                            return item;
                        });
                    }
                    this.homeList = data;
                    this.homeListCopy = data;
                });
            },
            homeFilter(value) {
                if (value) { //value存在
                    this.homeList = this.homeListCopy.filter((item) => {
                        if (pinyinMatch.match(item.label, value)) {
                            return true
                        }
                    })
                } else { //val为空时,还原数组
                    this.homeList = this.homeListCopy;
                }
            },
            filterChange() {
                this.searchBattInfo(this.stationInfo);
            },
            searchAllPicture() {
                this.$apis.pageSetting.threeHomeSetting.searchPicture().then(res=>{
                    let rs = JSON.parse(res.data.result);
                    let data = rs.data.map(item=>{
                        let name = item.path.substr(item.path.lastIndexOf("\\")+1);
                        return {
                            id: name,
                            label: name,
                        }
                    });
                    if(data.length != 0) {
                        this.params.pictureName = data[0].id;
                    }
                    this.pictureList = data;
                }).catch(error=>{
                });
            },
            close() {
                this.$emit("update:visible", false);
            },
            uploadPicture() {},
            handleOk() {
                if(!this.stationInfo || !this.params.pictureName) {
                    this.$layer.msg("请先选择站点或图片资源");
                    return;
                }
                this.params.stationName = this.stationInfo.StationName;
                let addInfo = [];
                if(this.group2) {
                    addInfo.push(extend({}, this.params, this.battGroups[0]));
                    addInfo.push(extend({}, this.params, this.battGroups[1]));
                }else if(this.group1){
                    addInfo.push(extend({}, this.params, this.battGroups[0]));
                }else {
                    this.$layer.msg("未检测到电池组信息")
                    return;
                }
                // 开启等待框
                let loading = this.$layer.loading();
                this.$apis.pageSetting.threeHomeSetting.add(addInfo).then(res=>{
                    let rs = JSON.parse(res.data.result);
                    if(rs.code == 1) {
                        this.close();
                        this.$layer.msg("添加成功!");
                        this.$emit("successHandle");
                    }else {
                        this.$layer.msg("添加失败!");
                    }
                    this.$layer.close(loading);
                }).catch(error=>{
                    this.$layer.close(loading);
                });
            },
            // 查询机房的信息
            searchBattInfo(stationInfo) {
                searchBattInfo(stationInfo).then((res)=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    // 查询到结果
                    if(rs.code == 1) {
                       data = rs.data;
                    }
                    this.group1 = false;
                    this.group2 = false;
                    switch (data.length) {
                        case 2:
                            this.group2 = true;
                            this.battGroups[1].battGroupId = data[1].BattGroupId;
                            this.battGroups[1].battGroupName = data[1].BattGroupName;
                        case 1:
                            this.group1 = true;
                            this.battGroups[0].battGroupId = data[0].BattGroupId;
                            this.battGroups[0].battGroupName = data[0].BattGroupName;
                            break;
                    }
                }).catch(error=>{
                    console.log(error);
                });
            },
            onDrag(x, y) {
                this.battGroups[0].positionX = x;
                this.battGroups[0].positionY = y;
            },
            onResize(x, y, width, height) {
                this.battGroups[0].positionX = x;
                this.battGroups[0].positionY = y;
                this.battGroups[0].length = width;
                this.battGroups[0].width = height;
            },
            onGroup2Drag(x, y) {
                this.battGroups[1].positionX = x;
                this.battGroups[1].positionY = y;
            },
            onGroup2Resize(x, y, width, height) {
                this.battGroups[1].positionX = x;
                this.battGroups[1].positionY = y;
                this.battGroups[1].length = width;
                this.battGroups[1].width = height;
            },
        },
        computed: {
            stationInfo() {
                let result = false;
                for(let i=0; i<this.homeList.length; i++) {
                    if(this.homeList[i].id == this.params.deviceId) {
                        result = this.homeList[i];
                        break;
                    }
                }
                return result;
            }
        },
        mounted() {
            // 查询站点
            this.searchStations();
            this.searchAllPicture();
        }
    }
</script>
<style scoped>
    .params-dialog {
        padding: 12px 12px 0 12px;
    }
    .form-footer .three-btn {
        margin-left: 12px;
    }
    .red-color {
        color: #FF0000;
    }
</style>
src/pages/pageSetting/dialog/EditThreeHomeSetting.vue
New file
@@ -0,0 +1,340 @@
<template>
    <div class="params-dialog">
        <el-form ref="ruleForm" size="mini" label-position="top" :model="params" :rules="rules">
            <el-row :gutter="layout.gutter">
                <el-col :span="layout.span">
                    <el-form-item label="站点名称" prop="stationName">
                        <el-select
                                size="small"
                                v-model="params.deviceId"
                                filterable
                                :filter-method="homeFilter"
                                placeholder="请选择"
                                clearable
                                @change="filterChange" disabled>
                            <el-option
                                    v-for="item in homeList"
                                    :key="item.id"
                                    :label="item.label"
                                    :value="item.id">
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="layout.span">
                    <el-form-item label="3D图片列表" prop="pictureName">
                        <el-select
                                size="small"
                                v-model="params.pictureName"
                                filterable
                                :filter-method="homeFilter"
                                placeholder="请选择"
                                clearable>
                            <el-option
                                    v-for="item in pictureList"
                                    :key="item.id"
                                    :label="item.label"
                                    :value="item.id">
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="24">
                    <three-home :bg="params.pictureName">
                        <vue-draggable-resizable
                                v-if="group1"
                                :x="initData[0].positionX" :y="initData[0].positionY"
                                :w="initData[0].length" :h="initData[0].width"
                                :parent="true"
                                @dragging="onDrag" @resizing="onResize">
                            <span class="red-color">{{battGroups[0].battGroupName}}</span>
                        </vue-draggable-resizable>
                        <vue-draggable-resizable
                                v-if="group2"
                                :x="initData[1].positionX" :y="initData[1].positionY"
                                :w="initData[1].length" :h="initData[1].width"
                                :parent="true"
                                @dragging="onGroup2Drag" @resizing="onGroup2Resize">
                            <span class="red-color">{{battGroups[1].battGroupName}}</span>
                        </vue-draggable-resizable>
                    </three-home>
                </el-col>
            </el-row>
            <div class="form-footer">
                <three-btn @click="handleOk">确定</three-btn>
                <three-btn @click="close">取消</three-btn>
            </div>
        </el-form>
    </div>
</template>
<script>
    import pinyinMatch from "pinyin-match";
    import ThreeHome from "@/components/ThreeHome/index";
    import {searchStation} from "@/assets/js/api";
    import {extend} from "@/assets/js/tools";
    export default {
        name: "EditThreeHomeSetting",
        components: {
            ThreeHome,
        },
        props: {
            visible: {
                type: Boolean,
                default: false
            },
            info: {
                type: Object,
                default() {
                    return {}
                }
            },
        },
        data() {
            return {
                layout: {
                    span: 12,
                    gutter: 16
                },
                params: {
                    deviceId: "",
                    stationName: "",
                    pictureName: "",
                    pictureUrl: "123",
                },
                rules: {},
                group1: false,
                group2: false,
                initData: [
                    {
                        positionX: 0,
                        positionY:0,
                        length:100,
                        width: 100
                    },
                    {
                        positionX: 0,
                        positionY:150,
                        length:100,
                        width: 100
                    },
                ],
                battGroups: [
                    {
                        id: 0,
                        battGroupId: 0,
                        battGroupName: "",
                        positionX: 0,
                        positionY:150,
                        length:100,
                        width: 100
                    },
                    {
                        id: 1,
                        battGroupId: 1,
                        battGroupName: "",
                        positionX: 0,
                        positionY:150,
                        length:100,
                        width: 100
                    },
                ],
                homeList: [],
                homeListCopy: [],
                pictureList: []
            };
        },
        methods: {
            init() {
                let info = this.info;
                this.params.deviceId = info.deviceId;
                this.params.pictureName = info.pictureName;
                this.searchByDevId();
            },
            searchByDevId() {
                this.$apis.pageSetting.threeHomeSetting.searchByDevId({
                    deviceId: this.info.deviceId,
                }).then(res=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data;
                    }
                    this.group1 = false;
                    this.group2 = false;
                    switch (data.length) {
                        case 2:
                            this.group2 = true;
                            this.battGroups[1].id = data[1].id;
                            this.battGroups[1].battGroupId = data[1].battGroupId;
                            this.battGroups[1].battGroupName = data[1].battGroupName;
                            this.battGroups[1].positionX = data[1].positionX;
                            this.battGroups[1].positionY = data[1].positionY;
                            this.battGroups[1].length = data[1].length;
                            this.battGroups[1].width = data[1].width;
                            this.initData[1].positionX = data[1].positionX;
                            this.initData[1].positionY = data[1].positionY;
                            this.initData[1].length = data[1].length;
                            this.initData[1].width = data[1].width;
                        case 1:
                            this.group1 = true;
                            this.battGroups[0].id = data[0].id;
                            this.battGroups[0].battGroupId = data[0].battGroupId;
                            this.battGroups[0].battGroupName = data[0].battGroupName;
                            this.battGroups[0].positionX = data[0].positionX;
                            this.battGroups[0].positionY = data[0].positionY;
                            this.battGroups[0].length = data[0].length;
                            this.battGroups[0].width = data[0].width;
                            this.initData[0].positionX = data[0].positionX;
                            this.initData[0].positionY = data[0].positionY;
                            this.initData[0].length = data[0].length;
                            this.initData[0].width = data[0].width;
                            break;
                    }
                }).catch(error=>{
                });
            },
            searchStations() {
                searchStation({
                    StationName1:"",
                    StationName2:"",
                    StationName5:"",
                }).then((res)=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data.map(item=>{
                            item.id = item.FBSDeviceId;
                            item.label = item.StationName;
                            return item;
                        });
                    }
                    this.homeList = data;
                    this.homeListCopy = data;
                });
            },
            homeFilter(value) {
                if (value) { //value存在
                    this.homeList = this.homeListCopy.filter((item) => {
                        if (pinyinMatch.match(item.label, value)) {
                            return true
                        }
                    })
                } else { //val为空时,还原数组
                    this.homeList = this.homeListCopy;
                }
            },
            filterChange() {
            },
            searchAllPicture() {
                this.$apis.pageSetting.threeHomeSetting.searchPicture().then(res=>{
                    let rs = JSON.parse(res.data.result);
                    let data = rs.data.map(item=>{
                        let name = item.path.substr(item.path.lastIndexOf("\\")+1);
                        return {
                            id: name,
                            label: name,
                        }
                    });
                    this.pictureList = data;
                }).catch(error=>{
                });
            },
            close() {
                this.$emit("update:visible", false);
            },
            uploadPicture() {
            },
            handleOk() {
                if(!this.stationInfo || !this.params.pictureName) {
                    this.$layer.msg("请先选择站点或图片资源");
                    return;
                }
                this.params.stationName = this.stationInfo.StationName;
                let addInfo = [];
                if(this.group2) {
                    addInfo.push(extend({}, this.params, this.battGroups[0]));
                    addInfo.push(extend({}, this.params, this.battGroups[1]));
                }else if(this.group1){
                    addInfo.push(extend({}, this.params, this.battGroups[0]));
                }else {
                    this.$layer.msg("未检测到电池组信息")
                    return;
                }
                // 开启等待框
                let loading = this.$layer.loading();
                this.$apis.pageSetting.threeHomeSetting.update(addInfo).then(res=>{
                    let rs = JSON.parse(res.data.result);
                    if(rs.code == 1) {
                        this.close();
                        this.$layer.msg("修改成功!");
                        this.$emit("successHandle");
                    }else {
                        this.$layer.msg("修改失败!");
                    }
                    this.$layer.close(loading);
                }).catch(error=>{
                    this.$layer.close(loading);
                });
            },
            onDrag(x, y) {
                this.battGroups[0].positionX = x;
                this.battGroups[0].positionY = y;
            },
            onResize(x, y, width, height) {
                this.battGroups[0].positionX = x;
                this.battGroups[0].positionY = y;
                this.battGroups[0].length = width;
                this.battGroups[0].width = height;
            },
            onGroup2Drag(x, y) {
                this.battGroups[1].positionX = x;
                this.battGroups[1].positionY = y;
            },
            onGroup2Resize(x, y, width, height) {
                this.battGroups[1].positionX = x;
                this.battGroups[1].positionY = y;
                this.battGroups[1].length = width;
                this.battGroups[1].width = height;
            },
        },
        computed: {
            stationInfo() {
                let result = false;
                for(let i=0; i<this.homeList.length; i++) {
                    if(this.homeList[i].id == this.params.deviceId) {
                        result = this.homeList[i];
                        break;
                    }
                }
                return result;
            }
        },
        mounted() {
            // 查询站点
            this.searchStations();
            this.searchAllPicture();
            this.init();
        }
    }
</script>
<style scoped>
    .params-dialog {
        padding: 12px 12px 0 12px;
    }
    .form-footer .three-btn {
        margin-left: 12px;
    }
    .red-color {
        color: #FF0000;
    }
</style>
src/pages/pageSetting/dialog/UploadPicture.vue
New file
@@ -0,0 +1,152 @@
<template>
    <div class="params-dialog">
        <el-form ref="ruleForm" size="mini" label-position="top" :model="params" :rules="rules">
            <el-row :gutter="layout.gutter">
                <el-col :span="24">
                    <el-form-item label="图片名称" prop="pictureName">
                        <el-input v-model="params.pictureName"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :sapn="24">
                    <el-upload
                        ref="uploadPicture"
                        class="upload-demo"
                        drag
                        action
                        name="fileData"
                        :http-request="uploadImg"
                        :data="params"
                        :limit="1"
                        multiple
                        list-type="picture">
                        <i class="el-icon-upload"></i>
                        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
                        <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
                    </el-upload>
                </el-col>
            </el-row>
            <div class="form-footer">
                <three-btn @click="submitUpload">确定</three-btn>
                <three-btn @click="close">取消</three-btn>
            </div>
        </el-form>
    </div>
</template>
<script>
    import {searchStation} from "@/assets/js/api";
    import pinyinMatch from "pinyin-match";
    let fileObj;
    export default {
        name: "UploadPicture",
        props: {
            visible: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                layout: {
                    span: 12,
                    gutter: 16
                },
                params: {
                    stationName: "",
                    pictureName: "",
                    fileData: ""
                },
                rules: {},
                homeList: [],
                homeListCopy: [],
            }
        },
        methods: {
            homeFilter(value) {
                if (value) { //value存在
                    this.homeList = this.homeListCopy.filter((item) => {
                        if (pinyinMatch.match(item.label, value)) {
                            return true
                        }
                    })
                } else { //val为空时,还原数组
                    this.homeList = this.homeListCopy;
                }
            },
            filterChange() {
            },
            searchStations() {
                searchStation({
                    StationName1:"",
                    StationName2:"",
                    StationName5:"",
                }).then((res)=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data.map(item=>{
                            item.id = item.FBSDeviceId;
                            item.label = item.StationName;
                            return item;
                        });
                    }
                    console.log(data);
                    this.homeList = data;
                    this.homeListCopy = data;
                });
            },
            uploadImg(fileInfo) {
                let name = fileInfo.file.name;
                this.params.pictureName = name.substring(0,name.indexOf("."));;
                this.getBase64(fileInfo.file).then(res=>{
                    this.params.fileData = res;
                });
            },
            submitUpload() {
                this.$apis.pageSetting.threeHomeSetting.uploadPicture(this.params).then(res=>{
                    let rs = JSON.parse(res.data.result);
                    this.close();
                    this.$layer.msg("上传成功");
                }).catch(error=>{
                    console.log(error);
                })
            },
            close() {
                this.$emit("update:visible", false);
            },
            getBase64(file) {
                return new Promise(function (resolve, reject) {
                    let reader = new FileReader();
                    let imgResult = "";
                    reader.readAsDataURL(file);
                    reader.onload = function () {
                        imgResult = reader.result;
                    };
                    reader.onerror = function (error) {
                        reject(error);
                    };
                    reader.onloadend = function () {
                        resolve(imgResult);
                    };
                });
            },
        },
        mounted() {
            this.searchStations();
        }
    }
</script>
<style scoped>
    .upload-demo {
        text-align: center;
    }
    .params-dialog {
        padding: 12px 12px 0 12px;
        min-width: 700px;
    }
    .form-footer .three-btn {
        margin-left: 12px;
    }
</style>
src/pages/pageSetting/threeHomeSetting.vue
New file
@@ -0,0 +1,183 @@
<template>
    <flex-layout>
        <div class="flex-page-content">
            <el-table stripe size="mini" header-row-class-name="header-primary" height="100%" :data="table.data">
                <el-table-column
                        v-for="item in table.headers" :key="item.props"
                        :prop="item.prop" :label="item.label" :min-width="item.minWidth"
                        align="center" :resizable="false"></el-table-column>
                <el-table-column label="操作" width="250" align="center" fixed="right">
                    <template slot-scope="scope">
                        <el-button @click="handleUpdate(scope.row)" type="success" size="mini">编辑</el-button>
                        <el-button type="error" size="mini" @click="handleDel(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <!-- 3D机房信息功能按钮 -->
        <div class="flex-page-footer" slot="footer" v-if="acTabs=='threeHomeInfo'">
            <div class="el-pagination-btns">
                <el-button type="primary" round size="mini" icon="el-icon-search" @click="searchData">查询</el-button>
            </div>
            <div class="el-pagination-btns">
                <el-button type="primary" round size="mini" icon="el-icon-plus" @click="handleAdd">新增站点配置</el-button>
            </div>
            <div class="el-pagination-btns">
                <el-button type="primary" round size="mini" icon="el-icon-upload" @click="handleUploadPicture">上传3D资源</el-button>
            </div>
        </div>
        <el-dialog title="新增3D机房配置" width="auto" :visible.sync="addDialog" :close-on-click-modal="false" top="0"
           class="dialog-center" :modal-append-to-body="false">
           <add-three-home-setting v-if="addDialog" :visible.sync="addDialog" @successHandle="addSuccessHandle"></add-three-home-setting>
        </el-dialog>
        <el-dialog title="更新3D机房配置" width="auto" :visible.sync="editDialog" :close-on-click-modal="false" top="0"
                   class="dialog-center" :modal-append-to-body="false">
            <edit-three-home-setting v-if="editDialog" :visible.sync="editDialog" :info="editRow" @successHandle="editSuccessHandle"></edit-three-home-setting>
        </el-dialog>
        <el-dialog title="上传图片资源" width="auto" :visible.sync="uploadDialog" :close-on-click-modal="false" top="0"
                   class="dialog-center" :modal-append-to-body="false">
            <upload-picture v-if="uploadDialog" :visible.sync="uploadDialog"></upload-picture>
        </el-dialog>
    </flex-layout>
</template>
<script>
    import AddThreeHomeSetting from "@/pages/pageSetting/dialog/AddThreeHomeSetting";
    import UploadPicture from "@/pages/pageSetting/dialog/UploadPicture";
    import EditThreeHomeSetting from "@/pages/pageSetting/dialog/EditThreeHomeSetting";
    export default {
        name: "threeHomeSetting",
        components: {
            EditThreeHomeSetting,
            AddThreeHomeSetting,
            UploadPicture
        },
        data() {
            return {
                acTabs: "threeHomeInfo",
                table: {
                    headers: [
                        {
                            prop: "stationName",
                            label: "站点名称",
                            minWidth: 360,
                        },
                        {
                            prop: "battGroupName",
                            label: "电池组名称",
                            minWidth: 180,
                        },
                        {
                            prop: "pictureName",
                            label: "3D图片名",
                            minWidth: 300,
                        },
                        {
                            prop: "positionX",
                            label: "电池组位置X",
                            minWidth: 180,
                        },
                        {
                            prop: "positionY",
                            label: "电池组位置Y",
                            minWidth: 180,
                        },
                        {
                            prop: "length",
                            label: "电池组长",
                            minWidth: 180,
                        },
                        {
                            prop: "width",
                            label: "电池组宽",
                            minWidth: 180,
                        }
                    ],
                    data: []
                },
                addDialog: false,
                editDialog: false,
                editRow: {},
                uploadDialog: false,
            }
        },
        methods: {
            handleAdd() {
                this.addDialog = true;
            },
            addSuccessHandle() {
                this.searchData();
            },
            editSuccessHandle() {
                this.searchData();
            },
            handleUpdate(row) {
                this.editRow = row;
                this.$nextTick(()=>{
                    this.editDialog = true;
                });
            },
            handleDel(row) {
                this.$confirm("确认删除", "提示", {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(()=>{
                    // 开启等待框
                    let loading = this.$layer.loading();
                    this.$apis.pageSetting.threeHomeSetting.del(row).then(res=>{
                        let rs = JSON.parse(res.data.result);
                        if(rs.code == 1) {
                            this.$layer.msg("删除成功");
                        }else {
                            this.$layer.msg("删除失败");
                        }
                        this.searchData();
                        this.$layer.close(loading);
                    }).catch(error=>{
                        console.log(error);
                        this.$layer.close(loading);
                    });
                }).catch(()=>{});
            },
            searchData() {
                this.$apis.pageSetting.threeHomeSetting.searchAll().then(res=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data;
                    }
                    // 设置表格的值
                    this.table.data = data;
                }).catch(error=>{
                    console.log(error);
                });
            },
            searchPictureData() {
                this.$apis.pageSetting.threeHomeSetting.searchPicture().then(res=>{
                    let rs = JSON.parse(res.data.result);
                    let data = [];
                    if(rs.code == 1) {
                        data = rs.data;
                    }
                    // 设置表格的值
                    console.log(rs);
                    //this.table.data = data;
                }).catch(error=>{
                    console.log(error);
                });
            },
            handleUploadPicture() {
                this.uploadDialog = true;
            },
        },
        mounted() {
            // 查询配置信息
            this.searchData();
        }
    }
</script>
<style scoped>
</style>
src/router/routes.js
@@ -286,6 +286,13 @@
        component: (resolve) => require(['../pages/pageSetting/chartMapSetting'], resolve)
    },
    {
        path: '/pageSetting/threeHomeSetting',
        meta: {
            title: '3D机房配置',
        },
        component: (resolve) => require(['../pages/pageSetting/threeHomeSetting'], resolve)
    },
    {
        path: '*',
        name: '',
        meta: {