ZZJ
2021-11-09 ccee429d379e0108b7445f72ade8d97c110a6fb3
src/pages/gb28181/index/App.vue
@@ -1,195 +1,186 @@
<template>
  <div class="s-basic-setting" @contextmenu.prevent="toOpenMenuList">
    <el-menu
      :default-openeds="openeds"
      background-color="#fff"
      text-color="#303133"
      active-text-color="#409EFF"
      style="height: 100%;"
      class="menu-css"
      @open="menuOpen"
      @close="menuClose"
    >
      <el-submenu index="0">
        <template slot="title">
          <b class="tree-font">国际ID</b>
        </template>
        <el-menu-item-group class="item-group">
          <!-- GB28181设置 -->
          <el-form
            :model="gb28181"
            :rules="rules"
            label-width="130px"
            class="alarmSetting"
            ref="gb28181"
          >
            <!-- <el-form-item label="国际服务器IP" prop="ServerIp">
                  <ip-input :ip="gb28181.ServerIp" @on-blur="gb28181.ServerIp = arguments[0]"></ip-input>
            </el-form-item>-->
            <div style="text-align: left;margin-bottom: 16px;">
              <el-radio-group v-model="gb28181.idType">
                <el-radio :label="0">输入已有ID</el-radio>
                <el-radio :label="1">生成新的ID</el-radio>
              </el-radio-group>
            </div>
            <el-form-item label="所在地">
              <el-select
                v-model="locationCity.province"
                @change="changeProvince"
                size="small"
                placeholder="请选择省份"
                :disabled="gb28181.idType === 0"
              >
                <el-option
                  v-for="item in locationCity.provinceOptions"
                  :key="item.id"
                  :label="item.name"
                  size="small"
                  :value="item.id"
                ></el-option>
              </el-select>
              <el-select
                class="ml10 mr10"
                v-model="locationCity.city"
                :disabled="!locationCity.province"
                @change="changeCity"
                size="small"
                placeholder="请选择城市"
              >
                <el-option
                  v-for="item in locationCity.cityOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                ></el-option>
              </el-select>
              <el-select
                v-model="locationCity.county"
                :disabled="!locationCity.city"
                size="small"
                placeholder="请选择区县"
              >
                <el-option
                  v-for="item in locationCity.countyOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                ></el-option>
              </el-select>
              <el-button
                type="text"
                style="position: absolute"
                v-show="gb28181.idType === 1"
                @click="newGBID"
                >生成ID</el-button
              >
            </el-form-item>
            <!-- <el-form-item label="国际服务器端口" prop="GbServerPort">
                  <el-input v-model.number="gb28181.ServerPort" placeholder="请输入" size="small"></el-input>
            </el-form-item>-->
            <el-form-item label="国标ID">
              <el-input
                v-model="gb28181.PublicId"
                placeholder="请输入"
                size="small"
                :disabled="gb28181.idType === 1"
              ></el-input>
            </el-form-item>
            <el-form-item label="国标端口" prop="ServerPort">
              <el-input
                v-model.number="gb28181.GbServerPort"
                placeholder="请输入"
                size="small"
              ></el-input>
            </el-form-item>
            <el-form-item label="开启鉴权">
              <el-switch v-model="gb28181.IsAuth"></el-switch>
            </el-form-item>
            <el-form-item label="鉴权密码" v-show="gb28181.IsAuth">
              <el-input
                v-model="gb28181.Password"
                placeholder="请输入"
                size="small"
              ></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitGB28281" size="small"
                >保存</el-button
              >
            </el-form-item>
          </el-form>
        </el-menu-item-group>
      </el-submenu>
      <el-submenu index="1">
        <template slot="title">
          <b class="tree-font">接入平台列表</b>
        </template>
        <el-menu-item-group class="item-group">
          <div>
            <el-table
              :data="tableList"
              border
              fit
              highlight-current-row
              style="width: 100%; color:#000"
              :header-cell-style="{ background: '#f8f8f8', color: '#222222', height:'30px'  }"
  <div class="s-system-manage">
    <div class="s-basic-setting">
      <el-tabs
        id="e-basic-setting"
        v-model="activeName"
        v-loading="loading"
        :element-loading-text="loadingText"
        type="border-card"
        @tab-click="hanleTabClick"
      >
        <el-tab-pane label="国标ID" name="gb28181">
          <div style="width: 775px">
            <!-- GB28181设置 -->
            <el-form
              :model="gb28181"
              :rules="rules"
              label-width="130px"
              class="alarmSetting"
              ref="gb28181"
            >
              <el-table-column
                type="index"
                label="序号"
                align="center"
                width="50"
              ></el-table-column>
              <el-table-column
                prop="name"
                label="名称"
                align="center"
              ></el-table-column>
              <el-table-column
                prop="id"
                label="ID"
                align="center"
              ></el-table-column>
              <el-table-column
                prop="ip"
                label="IP"
                align="center"
              ></el-table-column>
              <el-table-column
                prop="status"
                label="状态"
                align="center"
              ></el-table-column>
              <el-table-column
                prop="mark"
                label="备注"
                align="center"
              ></el-table-column>
            </el-table>
              <!-- <el-form-item label="国际服务器IP" prop="ServerIp">
                  <ip-input :ip="gb28181.ServerIp" @on-blur="gb28181.ServerIp = arguments[0]"></ip-input>
              </el-form-item>-->
              <div style="text-align: left;margin-bottom: 16px;">
                <el-radio-group v-model="gb28181.idType">
                  <el-radio :label="0">输入已有ID</el-radio>
                  <el-radio :label="1">生成新的ID</el-radio>
                </el-radio-group>
              </div>
              <el-form-item label="所在地">
                <el-select
                  v-model="locationCity.province"
                  @change="changeProvince"
                  size="small"
                  placeholder="请选择省份"
                  :disabled="gb28181.idType === 0"
                >
                  <el-option
                    v-for="item in locationCity.provinceOptions"
                    :key="item.id"
                    :label="item.name"
                    size="small"
                    :value="item.id"
                  ></el-option>
                </el-select>
                <el-select
                  class="ml10 mr10"
                  v-model="locationCity.city"
                  :disabled="!locationCity.province"
                  @change="changeCity"
                  size="small"
                  placeholder="请选择城市"
                >
                  <el-option
                    v-for="item in locationCity.cityOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  ></el-option>
                </el-select>
                <el-select
                  v-model="locationCity.county"
                  :disabled="!locationCity.city"
                  size="small"
                  placeholder="请选择区县"
                >
                  <el-option
                    v-for="item in locationCity.countyOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  ></el-option>
                </el-select>
                <el-button
                  type="text"
                  style="position: absolute"
                  v-show="gb28181.idType === 1"
                  @click="newGBID"
                >生成ID</el-button>
              </el-form-item>
              <!-- <el-form-item label="国际服务器端口" prop="GbServerPort">
                  <el-input v-model.number="gb28181.ServerPort" placeholder="请输入" size="small"></el-input>
              </el-form-item>-->
              <el-form-item label="国标ID">
                <el-input
                  v-model="gb28181.PublicId"
                  placeholder="请输入"
                  size="small"
                  :disabled="gb28181.idType === 1"
                ></el-input>
              </el-form-item>
              <el-form-item label="国标端口" prop="GbServerPort">
                <el-input v-model.number="gb28181.GbServerPort" placeholder="请输入" size="small"></el-input>
              </el-form-item>
              <el-form-item label="开启鉴权" style="text-align: left">
                <el-switch v-model="gb28181.IsAuth"></el-switch>
              </el-form-item>
              <el-form-item label="鉴权密码">
                <el-input
                  v-model="gb28181.Password"
                  placeholder="请输入"
                  size="small"
                  :disabled="!gb28181.IsAuth"
                ></el-input>
              </el-form-item>
              <el-form-item style="float: right">
                <el-button type="primary" @click="submitGB28281" size="small">保存</el-button>
              </el-form-item>
            </el-form>
          </div>
        </el-menu-item-group>
      </el-submenu>
      <el-submenu index="2">
        <template slot="title">
          <b class="tree-font">国际摄像机</b>
        </template>
        <el-menu-item-group class="item-group">
          <div>
            <div>
              <el-button type="primary" size="small">刷新</el-button>
        </el-tab-pane>
        <el-tab-pane label="接入平台列表" name="subordinates">
          <el-table
            :data="subDevTable"
            border
            fit
            highlight-current-row
            style="width: 100%; color:#000"
            :header-cell-style="{ background: '#f8f8f8', color: '#222222', height:'30px'  }"
          >
            <el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
            <el-table-column prop="name" label="名称" align="center"></el-table-column>
            <el-table-column prop="publicid" label="ID" align="center"></el-table-column>
            <el-table-column prop="ip" label="IP" align="center"></el-table-column>
            <el-table-column prop="status" label="状态" align="center">
              <template slot-scope="scope">
                <span
                  :style="scope.row.alive ? `color:#047d19` : 'color:#f11a1a;' "
                >{{scope.row.alive ? "在线": "离线"}}</span>
              </template>
            </el-table-column>
            <el-table-column prop="corp" label="备注" align="center"></el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="国标摄像机" name="cameras">
          <div style="text-align:left">
            <el-button type="primary" size="small" @click="updateCamerasFromVideosvr">刷新</el-button>
          </div>
          <div class="camera-title">
            <b>国标摄像机配置</b>
            <span>(最多勾选500路摄像机)</span>
          </div>
          <tree-menu
            ref="tree"
            app="gb28181"
            treeName="localTree"
            :node="TreeDataPool.treeData"
            :height="treeHeight"
            :setting="treeSettings"
            style="width:600px;min-height:500px"
          />
          <div class="base-image" v-loading="TreeDataPool.baseImageLoading">
            <span>{{TreeDataPool.cameraNameForBaseImage}}</span>
            <div class="camera-image" v-show="TreeDataPool.cameraNameForBaseImage.length">
              <img
                :src="'data:image/png;base64,' + TreeDataPool.gb28181CameraBaseImage"
                width="450px"
                alt
              />
            </div>
          </div>
        </el-menu-item-group>
      </el-submenu>
    </el-menu>
          <el-divider></el-divider>
          <span class="camera-seleted-text">
            已选择 (
            <b>{{TreeDataPool.gb28181CheckedCount}}</b>
            / {{TreeDataPool.gb28181ChildNodeCount}} ) 路
          </span>
          <el-button type="primary" size="small" @click="saveChecked">保存</el-button>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>
@@ -198,27 +189,42 @@
  getGB28181Config,
  saveGB28181Config,
  getGb28181AreaList,
  newGb28181ID
  newGb28181ID,
  getAllSubServer,
  saveGb28181CamTree
} from './api'
import TreeMenu from "@/components/giantTree/index";
import { isPort, isIPv4 } from '@/scripts/validate'
import bus from '@/plugin/bus'
export default {
  name: 'Gb28181Setting',
  components: {
    TreeMenu
  },
  directives: {
    focus: {
      inserted: function(el) {
      inserted: function (el) {
        el.querySelector('input').focus()
      }
    }
  },
  data() {
    return {
      activeName: "gb28181",
      treeHeight: 750,
      loading: false,
      loadingText: "",
      openeds: ['0'],
      gb28181: {},
      tableList: [],
      subDevTable: [],
      idType: 1,
      treeSettings: {
        check: {
          enable: true
        }
      },
      rules: {
        ip: [
          {
@@ -264,18 +270,80 @@
    }
  },
  mounted() {
    //this.$nextTick(()=>{
    this.initGB28181Conf()
    //})
    this.TreeDataPool.multiple = true;
    // 记录目录是否折叠
    let foldList = localStorage.getItem("ztree_fold_list")
    if (foldList) {
      this.TreeDataPool.foldNodeList = JSON.parse(foldList)
    }
    this.initGB28181Conf();
  },
  methods: {
    hanleTabClick(tab, event) {
      if (this.activeName == "subordinates") {
        getAllSubServer().then(rsp => {
          if (rsp && rsp.success) {
            this.subDevTable = rsp.data;
          }
        })
      } else if (this.activeName == "cameras") {
        this.getCamerasFromVideosvr();
      }
    },
    async getCamerasFromVideosvr() {
      this.loading = true;
      await this.TreeDataPool.fetchVideosvrCameras(false);
      this.loading = false;
    },
    async updateCamerasFromVideosvr() {
      this.loading = true;
      await this.TreeDataPool.fetchVideosvrCameras(true);
      this.loading = false;
    },
    saveChecked() {
      localStorage.setItem('ztree_fold_list', JSON.stringify(this.TreeDataPool.foldNodeList))
      if (this.TreeDataPool.gb28181CheckedCount > 500) {
        this.$message({
          type: "warning",
          message: "最多仅支持选择500路摄像机. 请重新选择"
        })
        return;
      }
      this.loading = true;
      let treeData = this.TreeDataPool.newTreeByChecked(this.TreeDataPool.activeTreeData)
      saveGb28181CamTree({ checkedMenus: treeData }).then(rsp => {
        if (rsp && rsp.success) {
          this.$message({
            type: "success",
            message: "保存成功"
          })
        }
        this.loading = false;
      }).catch(err => {
        this.$message({
          type: "error",
          message: "保存失败"
        })
        this.loading = false;
      })
    },
    initGB28181Conf() {
      getGB28181Config().then(rsp => {
        if (rsp && rsp.success) {
          this.gb28181 = rsp.data
          //this.gb28181.idType = 0;
          this.$set(this.gb28181, 'idType', 0)
          this.$refs['gb28181'].resetFields();
        }
      })
      getGb28181AreaList().then(rsp => {
@@ -328,254 +396,148 @@
        }
      })
    },
    menuOpen(){
    },
    menuClose(){
    },
    toOpenMenuList(e){
      debugger
      let t = e.clientY - this.$el.offsetTop+30;
      let l = e.clientX-this.$el.offsetLeft;
    menuOpen() {
      window.parent.postMessage({source:location.href.split('/')[location.href.split('/').length-1], trigger: 'contextmenu', menuT:t, menuL:l},"*");
    },
    menuClose() {
    },
    toOpenMenuList(e) {
      let t = e.clientY - this.$el.offsetTop + 30;
      let l = e.clientX - this.$el.offsetLeft;
      window.parent.postMessage({ source: location.href.split('/')[location.href.split('/').length - 1], trigger: 'contextmenu', menuT: t, menuL: l }, "*");
      return false;
    }
  }
}
</script>
<style lang="scss">
.s-basic-setting {
.s-system-manage {
  width: 100% !important;
  min-width: 1067px;
  height: 100%;
  padding: 20px;
  box-sizing: border-box;
  .item-group {
    padding: 0 15px;
    margin-bottom: 15px;
  }
  .el-form {
    .el-form-item {
      text-align: left;
      margin-bottom: 16px;
      &:last-of-type {
        width: 490px;
      }
      .el-button {
        float: right;
      }
      .el-select {
        margin-right: 10px;
      }
      .el-form-item__content {
        text-align: left;
        input {
          max-width: 360px;
        }
        .el-date-editor.el-input,
        .el-date-editor.el-input__inner {
          width: 216px;
        }
        .el-checkbox__label {
          padding-left: 5px;
        }
      }
      .el-form-item__label {
        text-align: left;
      }
      &.el-form-item.is-required:not(.is-no-asterisk)
        > .el-form-item__label:before {
        margin-left: -9px;
      }
    }
  }
  .alarmSetting {
    .el-input {
      width: 100%;
      // padding-right: 10px;
    }
    .el-select {
      max-width: 113px;
    }
    .el-slider {
      width: calc(100% - 120px);
      display: inline-block;
      padding-right: 30px;
      box-sizing: border-box;
      vertical-align: middle;
    }
    .el-input-number {
      width: 100px;
      display: inline-block;
      .el-input {
        width: 100%;
      }
    }
  padding: 10px;
  background-color: #f8f9fb;
  .s-system-manage-breadcrumb {
    height: 5%;
    box-sizing: border-box;
    border: 1px solid #e4e7ed;
    box-shadow: #e4e7ed 0px 0px 9px inset;
    box-shadow: #e4e7ed 0px 0px 9px inset;
    border-radius: 5px;
  }
  .time-type {
    height: 25px;
    width: 413px;
    line-height: 28px;
    padding: 3px 23px;
    font-size: 14px;
    font-weight: 600;
    background-color: #e4e6ed;
  }
  #e-basic-setting {
  .el-tabs--border-card {
    border: 0px solid #dcdfe6;
    -webkit-box-shadow: none;
    box-shadow: none;
    .el-tabs__header {
      border: 0px solid #dcdfe6;
      .el-tabs__item {
        padding: 5px 50px;
        height: 50px;
        font-family: PingFangSC-Regular;
        font-size: 14px;
        font-size: 15px;
        color: #222222;
        text-align: center;
        border: 0px solid transparent;
      }
      .el-tabs__item:nth-child(2) {
        padding-left: 50px;
        padding-left: 50px !important;
      }
      .el-tabs__item:last-child {
        padding-right: 50px;
        padding-right: 50px !important;
      }
      .el-tabs__item.is-active {
        color: #ff7733;
        font-weight: bold;
        color: #3d68e1;
        // border-right-color: #fff;
        // border-left-color: #fff;
      }
      .el-tabs__item:not(.is-disabled):hover {
        color: #ff7733;
      }
    }
    .el-tabs__active-bar {
      background-color: #ff7733;
    }
    .xiangqin-label {
      text-align: left;
      width: 85px;
      font-size: 14px;
      line-height: 30px;
    }
    .xiangqing-info {
      text-align: left;
      font-size: 14px;
      line-height: 30px;
    }
  }
  #cut_min_duration {
    .el-slider__bar {
      background-color: #3d68e1;
    }
    .el-slider__button {
      width: 10px;
      height: 10px;
      border: 4px solid #3d68e1;
    }
  }
  #cut_max_duration {
    .el-slider__bar {
      background-color: #ff9e6e;
    }
    .el-slider__button {
      width: 10px;
      height: 10px;
      border: 4px solid #ff9e6e;
    }
  }
  .menu-css,
  .el-menu {
    border-right: none;
    list-style: none;
    position: relative;
    margin: 0;
    padding-left: 0;
    background-color: #ffffff;
    .el-submenu__title {
      height: 35px;
      line-height: 35px;
      font-size: 14px;
      color: #303133;
      padding: 0 20px;
      list-style: none;
      cursor: pointer;
      position: relative;
      -webkit-transition: border-color 0.3s, background-color 0.3s, color 0.3s;
      transition: border-color 0.3s, background-color 0.3s, color 0.3s;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      white-space: nowrap;
    }
    .tree-font {
      font-family: PingFangSC-Medium;
      font-size: 14px;
      color: #222222;
      text-align: left;
    }
    li {
      text-align: left;
      .el-submenu__title {
        // border-bottom: solid 1px #e6e6e6;
        padding-left: 10px !important;
        background-color: #e4e6ed !important;
        border-radius: 2px;
        .el-submenu__icon-arrow {
          position: absolute;
          top: 50%;
          right: auto;
          left: 135px;
          margin-top: -7px;
          -webkit-transition: -webkit-transform 0.3s;
          transition: -webkit-transform 0.3s;
          transition: transform 0.3s;
          transition: transform 0.3s, -webkit-transform 0.3s;
          font-size: 12px;
        }
        color: #3d68e1;
      }
    }
  }
  .save-btn {
    text-align: right;
    position: relative;
    right: 40px;
  .el-tabs__header {
    margin-bottom: 0;
  }
}
</style>
<style lang="scss" scoped>
.menu-css,
.el-menu {
  border-right: none;
  list-style: none;
  position: relative;
  margin: 0;
  padding-left: 0;
  background-color: #ffffff;
  .el-tabs__content {
    height: calc(100% - 64px);
    box-sizing: border-box;
    overflow-y: auto;
    padding: 20px 40px !important;
    background: #fff;
    .el-tab-pane {
      width: 100%;
      .s-title {
        text-align: left;
        padding: 15px 0px;
        font-size: 16px;
      }
    }
  }
  .tree-font {
    font-family: PingFangSC-Medium;
  .s-table {
    border: 1px solid #e8e8e9;
    margin-top: 40px;
  }
  .ui-top-title {
    padding-bottom: 10px;
    /* border-bottom: 1px solid #ebebeb; */
    position: relative;
    text-align: left;
    padding-left: 15px;
    font-size: 16px;
    font-weight: bold;
  }
  .ui-top-title:before {
    content: " ";
    border-left: 4px solid #f53d3d;
    display: inline-block;
    height: 16px;
    position: absolute;
    top: 50%;
    left: 0;
    margin-top: -13px;
  }
  .el-button--text {
    color: #3d68e1;
    text-decoration: underline;
  }
  .camera-title {
    text-align: left;
    padding: 0px 10px;
    margin: 5px 0px;
    height: 33px;
    background-color: #e4e2e2;
    line-height: 33px;
    font-size: 14px;
    color: #222222;
    text-align: left;
  }
  li {
    text-align: left;
    .el-submenu__title {
      .el-submenu__icon-arrow {
        position: absolute;
        top: 50%;
        right: 0;
        margin-top: -7px;
        -webkit-transition: -webkit-transform 0.3s;
        transition: -webkit-transform 0.3s;
        transition: transform 0.3s;
        transition: transform 0.3s, -webkit-transform 0.3s;
        font-size: 12px;
      }
  .camera-seleted-text {
    margin-right: 20px;
    .b {
      color: #3d68e1;
    }
  }
  .base-image {
    position: absolute;
    top: 18%;
    left: 57%;
    width: 450px;
    .camera-image {
      background-color: black;
      height: 254px;
    }
  }
}