Newer
Older
operation_web / src / components / ConfigManager / SiteManagement.vue
<template>
  <div id="pagetwo" class="page-data">
    <!--搜素框-->
    <div class="page-filter">
      <page-filter
        :query.sync="siteFilterInfo.query"
        :filter-list="siteFilterInfo.list"
        @handleClick="handleClick"
      />
    </div>
    <div class="page-content">
      <!--表格-->
      <div class="h-100">
        <page-table
          tabIndex
          pagination
          :api-url="siteTableInfo.url"
          :refresh="siteTableInfo.refresh"
          :data.sync="siteTableInfo.data"
          :query="siteFilterInfo.query"
          :page-query="siteTableInfo.pageQuery"
          :list-type-info="listTypeInfo"
          :init-curpage="siteTableInfo.initCurpage"
          :field-list="siteTableInfo.fieldList"
          :handle="siteTableInfo.handle"
          @handleClick="handleClick"
        >
          <!-- 自定义插槽显示状态 -->
          <template v-slot:col-equips="scope">
            <el-button type="text" size="small" @click="handleClick('look',scope.row)">查看设备</el-button>
          </template>
        </page-table>
      </div>
    </div>

    <!-- 新增/修改的弹出框 -->
    <el-dialog
      :visible.sync="yzaddflag"
      width="1000px"
      true
      :title="title"
      @close="closedialog('ruleForm')"
    >
      <div>
        <el-form
          :model="ruleForm"
          :rules="rules"
          ref="ruleForm"
          label-width="110px"
        >
          <el-form-item label="站点名称" prop="stName" style="width: 100%">
            <el-input
              size="small"
              v-model="ruleForm.stName"
              class="selectInput"
            ></el-input>
            <span
              >站点名称命名规则 "[项目名称]"
              +安装位置关键标识,例如[武昌]湖北大学东门监测站点</span
            >
          </el-form-item>
          <el-form-item label="站点类型" prop="stationType">
            <el-select
              class="selectInput"
              size="small"
              v-model="ruleForm.stationType"
              placeholder="请选择站点类型"
            >
              <el-option
                class="selectOption"
                v-for="item in siteTypeList"
                :key="item.code"
                :label="item.name"
                :value="item.code"
              ></el-option>
            </el-select>
            <span>按实际设备类型选择站点类型</span>
          </el-form-item>
          <el-form-item label="所属项目" prop="platformCode">
            <el-select
              class="selectInput"
              size="small"
              filterable
              v-model="ruleForm.platformCode"
              placeholder="请选择所属项目"
            >
              <el-option
                class="selectOption"
                v-for="item in projectList"
                :key="item.id"
                :label="item.key"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="所属区域" prop="area">
            <el-cascader
              ref="cascader"
              popper-class="form-cascader"
              class="selectInput"
              v-model="ruleForm.area"
              :options="syscityList"
              filterable
              placeholder="请选择所属区域"
              :props="syscityListProps"
              @change="handleChange"
              @visible-change="visiblechange"
            ></el-cascader>
          </el-form-item>
          <el-form-item label="站点安装定位" required>
            <el-col :span="7">
              <el-form-item prop="coordinateSystem"
                ><el-input
                  size="small"
                  v-model="ruleForm.coordinateSystem"
                ></el-input
              ></el-form-item>
            </el-col>
            <el-col :span="1">&nbsp;经度</el-col>
            <el-col :span="5">
              <el-form-item prop="lon"
                ><el-input size="small" v-model="ruleForm.lon"></el-input
              ></el-form-item>
            </el-col>
            <el-col :span="1">&nbsp;纬度</el-col>
            <el-col :span="5">
              <el-form-item prop="lat"
                ><el-input size="small" v-model="ruleForm.lat"></el-input
              ></el-form-item>
            </el-col>
          </el-form-item>
          <el-form-item label="站点安装位置" prop="address">
            <el-input
              size="small"
              v-model="ruleForm.address"
              class="selectInput"
            ></el-input>
            <span
              >按实际安装位置填写,可填入地图定位软件显示的中文名或自行输入</span
            >
          </el-form-item>
          <el-form-item label="安装负责人" prop="person" style="width: 100%">
            <el-input
              size="small"
              v-model="ruleForm.person"
              class="selectInput"
            ></el-input>
            <span>填写安装负责人</span>
          </el-form-item>

          <el-form-item label="现场安装图片" prop="height">
            <!-- 点击上传按钮 -->
            <el-upload
              v-loading="loading"
              element-loading-text="正在上传图片..."
              element-loading-spinner="el-icon-loading"
              element-loading-background="rgba(255, 255, 255, 0.3)"
              :auto-upload="false"
              multiple
              action="#"
              :on-change="fileChange"
            >
              <i class="el-icon-plus">添加图片</i>
            </el-upload>
            <!-- 渲染服务器返回给我们的图片列表 -->
            <div class="imglist">
              <div
                class="imgbox"
                v-for="(item, index) in ruleForm.fileList"
                :key="index"
              >
                <img
                  class="imgtype"
                  :src="item.fileAbbreviatedCloudStorageKey"
                  @click="handlePictureCardPreview(item)"
                />
                <span class="deleteSpan" @click="deleteImg(item.fileNo)"
                  ><span class="deletex">x</span></span
                >
              </div>
            </div>
            <!-- 点击图片预览大图的效果 -->
            <el-dialog :visible.sync="dialogVisible" append-to-body>
              <img width="100%" :src="dialogImageUrl" alt="" />
            </el-dialog>
          </el-form-item>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="resetField('ruleForm')">取消</el-button>
        <el-button type="primary" @click="saveOru('ruleForm')">保存</el-button>
      </span>
    </el-dialog>
    <!--关联设备弹窗-->
    <page-dialog
      class="page-data-dialog"
      :title="dialogInfo.title[dialogInfo.type]"
      :visible.sync="dialogInfo.visible"
      width="80%"
      :bt-loading="dialogInfo.btLoading"
      :bt-list="dialogInfo.btList"
      @handleClick="handleClick"
    >
      <template v-if="dialogInfo.type === 'look'">
        <div class="page-filter">
          <el-form :inline="true" :model="deviceRelatedQuery" ref="deviceRelatedQuery" size="medium">
            <el-form-item label="">
              <el-input v-model="deviceRelatedQuery.searchStr" placeholder="请输入设备编号/厂家" clearable></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="el-icon-search" size="medium" @click="handleClick('deviceSearch')">查询</el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="page-content">
          <el-row :gutter="20" class="h-100">
            <el-col :span="10" class="h-100 flex flex-d">
              <div class="table-title">未关联设备列表</div>
              <page-table
                class="flex-1"
                checkBox
                pagination
                type="unRelated"
                :api-url="deviceTableInfo.url"
                :refresh="deviceTableInfo.refresh"
                :data.sync="unRelatedDeviceTableInfo.data"
                :query="unRelatedDeviceTableInfo.query"
                :init-curpage="deviceTableInfo.initCurpage"
                :field-list="deviceTableInfo.fieldList"
                @handleClick="handleClick"
                @handleEvent="handleEvent"
              />
            </el-col>
            <el-col :span="4" class="h-100">
              <div class="btn-group">
                <el-button
                  type="primary"
                  size="small"
                  icon="el-icon-d-arrow-right"
                  :disabled="isCanInsertDevice"
                  @click="handleClick('insert')"
                  >添加</el-button
                >
                <el-button
                  type="primary"
                  size="small"
                  icon="el-icon-d-arrow-left"
                  :disabled="isCanRemoveDevice"
                  @click="handleClick('remove')"
                  >移除</el-button
                >
              </div>
            </el-col>
            <el-col :span="10" class="h-100 flex flex-d">
              <div class="table-title">已关联设备列表</div>
              <page-table
                class="flex-1"
                checkBox
                pagination
                type="isRelated"
                :api-url="deviceTableInfo.url"
                :refresh="deviceTableInfo.refresh"
                :data.sync="isRelatedDeviceTableInfo.data"
                :query="isRelatedDeviceTableInfo.query"
                :init-curpage="deviceTableInfo.initCurpage"
                :field-list="deviceTableInfo.fieldList"
                @handleClick="handleClick"
                @handleEvent="handleEvent"
              />
            </el-col>
          </el-row>
        </div>
      </template>
    </page-dialog>
  </div>
</template>
<script>
import axios from "axios";
import { mapGetters } from "vuex";
export default {
  data() {
    return {
      //站点搜索相关
      siteFilterInfo: {
        query: {
          searchStr: "",
          startDate: "",
          endDate: ""
        },
        list: [
          {type: "input", label: "站点名称/编号", value: "searchStr", hideLabel: true },
          {type: "date", label: "开始时间", value: "startDate", dateType: "date", datePickerOptions: "pickerOptionsStart", hideLabel: true},
          {type: "date", label: "结束时间", value: "endDate", dateType: "date", datePickerOptions: "pickerOptionsEnd", hideLabel: true},
          {type: "button", label: "查询", btType: "primary", icon: "el-icon-search", event: "search", show: true},
          {type: "button", label: "添加站点", btType: "primary", icon: "el-icon-circle-plus-outline", event: "create", show: true, has: "m11-2-1"}
        ]
      },
      //站点表格相关
      siteTableInfo: {
        url: this.nozzle.listExtend, //接口地址
        refresh: 1,
        initCurpage: 1,
        data: [],
        fieldList: [
          { label: "站点编号", value: "stCode", minWidth: 120, tooltip: true },
          { label: "站点名称", value: "stName", minWidth: 120, tooltip: true },
          { label: "站点类型", value: "stationTypeName", width: 120 },
          { label: "站点安装时间", value: "createTime", minWidth: 120, tooltip: true },
          { label: "安装人", value: "person", width: 100 },
          { label: "关联设备", value: "equips", width: 100, type: "slot" },
          { label: "首次数据接入时间", value: "tt", minWidth: 150, tooltip: true },
        ],
        handle: {
          fixed: "right",
          label: "操作",
          width: "80",
          btList: [
            { label: "修改", size: "small", type: "text", event: "update", show: true, has: 'm11-2-2' }
          ]
        }
      },
      //列表相关
      listTypeInfo: {},
      loadingdelet: undefined,
      loading: false,
      timer: null,
      dialogImageUrl: "",
      dialogVisible: false,
      title: "站点管理",
      siteTypeList: [], //弹框里面站点类型列表
      yzaddflag: false,
      ruleForm: {
        id: "", //站点ID
        stName: "", //站点名称
        stCode: "", //站点编号
        tt: "",
        area: "", //所属区域
        constructionStatus: "",
        faultStatus: "",
        taskStatus: "",
        platformCode: "",
        lat: "", //维度
        lon: "", //经度
        isPush: "",
        createTime: "",
        coordinateSystem: "",
        status: "",
        offlineTime: "",
        stationType: "", //站点类型
        // stationTypeName: "", //站点名称
        coordinateSystem: "", //坐标系(经纬度所对应的的坐标系)
        address: "", //站点安装位置
        person: "", //安装负责人
        fileList: [] //现场安装图片
      },
      rules: {
        area: [
          {
            required: true,
            message: "请选择所属区域",
            trigger: "change"
          }
        ],
        stationType: [
          {
            required: true,
            message: "请选择站点类型",
            trigger: "change"
          }
        ],
        platformCode: [
          {
            required: true,
            message: "请选择所属项目",
            trigger: "change"
          }
        ],
        stName: [
          {
            required: true,
            message: "请填写站点名称",
            trigger: "blur"
          }
        ],
        lon: [
          {
            required: true,
            message: "请填写经度",
            trigger: "blur"
          }
        ],
        lat: [
          {
            required: true,
            message: "请填写纬度",
            trigger: "blur"
          }
        ],
        coordinateSystem: [
          {
            required: true,
            message: "请填写站点坐标系",
            trigger: "blur"
          }
        ],
        address: [
          {
            required: true,
            message: "请填写站点安装位置",
            trigger: "blur"
          }
        ],
        person: [
          {
            required: true,
            message: "请填写安装负责人",
            trigger: "blur"
          }
        ]
      },
      value: [],
      // 站点管理/所属区域数组
      syscityList: [],
      syscityListProps: { checkStrictly: true, value: "id", label: "name" },
      //当前用户权限内的项目数据
      projectList: [],
      //弹窗相关
      dialogInfo: {
        title: {
          look: ''
        },
        width: "60%",
        visible: false,
        btLoading: false,
        type: "",
        btList: [
          { label: "关闭", type: "", icon: "", event: "close", show: true }
        ]
      },
      //设备表格通用相关
      deviceTableInfo: {
        url: this.nozzle.sysEquipRelatedList, //接口地址
        refresh: 1,
        initCurpage: 1,
        fieldList: [
          { label: "设备编号", value: "equipNo", minWidth: 100, tooltip: true },
          { label: "设备厂家", value: "equipFactory", minWidth: 150, tooltip: true },
        ]
      },
      //已关联设备表格相关
      isRelatedDeviceTableInfo: {
        data: [],
        query: {
          sign: ""
        },
        selectList: []
      },
      //未关联设备表格相关
      unRelatedDeviceTableInfo: {
        data: [],
        query: {
          sign: "unbound"
        },
        selectList: []
      },
      //设备关联过滤相关
      deviceRelatedQuery: {
        searchStr: "",
        siteCode: ""
      }
    };
  },
  mounted() {
    this.siteTableInfo.refresh = Math.random();
    this.getsityType();
    this.getCurrentUserProject(); //获取当前用户所绑定的项目
  },
  computed: {
    //移除按钮是否可点击
    isCanRemoveDevice() {
      return this.isRelatedDeviceTableInfo.selectList.length ? false : true;
    },
    //添加按钮是否可点击
    isCanInsertDevice() {
      return this.unRelatedDeviceTableInfo.selectList.length ? false : true;
    },
    ...mapGetters(["allDept", "allRole", "allCity"])
  },
  watch: {
    "ruleForm.area": {
      handler(newVal, oldVal) {
        if (this.$refs.cascader) {
          let children = this.$refs.cascader.getCheckedNodes();
          if (
            children.length &&
            children[0].children &&
            children[0].children.length < 1
          ) {
            this.$refs.cascader.dropDownVisible = false;
          }
        }
      },
      deep: true // 深度监听
    },
    dialogVisible: {
      handler(newVal, oldval) {
        if (oldval) {
          this.dialogImageUrl = "";
        }
      }
    },
    "dialogInfo.visible"(val) {
      if (!val) {
        this.deviceTableInfo.data = [];
        this.deviceRelatedQuery.searchStr = "";
        this.dialogInfo.btLoading = false;
      }
    },
    "deviceRelatedQuery.searchStr"(val) {
      Object.assign(this.isRelatedDeviceTableInfo.query, this.deviceRelatedQuery);
      Object.assign(this.unRelatedDeviceTableInfo.query, this.deviceRelatedQuery);
    }
  },
  methods: {
    //上传头像
    fileChange(file) {
      this.loading = true;
      const isLt1M = file.size / 1024 / 1024 < 1;
      if (file.raw.type != "image/jpeg" && file.raw.type != "image/png") {
        this.loading = false;
        this.$message.error("上传图片只能是JPG或PNG格式!");
        return;
      }
      if (!isLt1M) {
        this.loading = false;
        this.$message.error("上传图片大小不能超过 1MB!");
        return;
      }
      var formdata = new FormData();
      formdata.append("files", file.raw);
      formdata.append("siteNo", this.ruleForm.stCode);
      formdata.append("username", "admin");
      let config = {
        headers: { "Content-Type": "multipart/form-data" }
      };
      axios.post(this.nozzle.upload, formdata, config).then(res => {
        if (res.data.code == 1) {
          this.loading = false;
          this.$message({
            message: "上传图片成功!",
            type: "success"
          });
          this.ruleForm.fileList.push(res.data.data[0]);
          this.siteTableInfo.refresh = Math.random();
        }
      })
      .catch(res => {
        this.loading = false;
        this.$message({
          message: "服务器问题!请重试!",
          type: "warning"
        });
      });
    },
    // 删除图片按钮
    deleteImg(fileNo) {
      this.$confirm("此操作将永久删除该图片文件,无法撤回!是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          let fileNos = [];
          fileNos.push(fileNo);
          const loadingdelet = this.$loading({
            lock: true,
            text: "正在删除....",
            spinner: "el-icon-loading",
            background: "rgba(0, 0, 0, 0.7)"
          });
          this.$http
            .post(this.nozzle.delete, {
              data: {
                siteNo: this.ruleForm.stCode,
                fileNos: fileNos
              }
            })
            .then(res => {
              loadingdelet.close();
              if(res.data.code === 1) {
                this.siteTableInfo.refresh = Math.random();
              }
              this.$message({
                type: res.data.code === 1 ? "success" : "error",
                message: res.data.msg
              });
              this.ruleForm.fileList = this.ruleForm.fileList.filter(item => {
                return item.fileNo != fileNo;
              });
            })
            .catch(res => {
              loadingdelet.close();
              this.$message({
                type: "info",
                message: "删除失败,请重试!"
              });
            });
        })
        .catch(() => {
          loadingdelet.close();
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },
    // 点击图片显示图片预览大图
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.fileCloudStorageKey;
      this.dialogVisible = true;
    },
    // 弹框提交表单按钮
    saveOru(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.$http.post(this.nozzle.saveOrupdate, {
            data: this.ruleForm
          })
          .then(res => {
            if(res.data.code === 1) {
              this.siteTableInfo.refresh = Math.random();
              this.yzaddflag = false;
            }
            this.$message({
              message: res.data.msg,
              type: res.data.code === 1 ? 'success' : 'error',
              showClose: true,
            })
          });
        }
      });
    },
    // 弹框取消表单按钮
    resetField(formName) {
      this.yzaddflag = false;
      this.$refs[formName].resetFields();
    },
    visiblechange(visible) {
      let that = this;
      if (visible) {
        this.timer = setInterval(() => {
          NodeList.prototype.forEach = Array.prototype.forEach;
          document.querySelectorAll(".el-cascader-node__label").forEach(el => {
            el.onclick = function() {
              if (this.previousElementSibling)
                this.previousElementSibling.click();
            };
            el.ondblclick = function() {
              if(Array.isArray(that.$refs.cascader)) {
                that.$refs.cascader[0].dropDownVisible = false;
              }else{
                that.$refs.cascader.dropDownVisible = false;
              }
            };
          });
        }, 1000);
      } else {
        clearInterval(this.timer);
      }
    },
    //获取站点类型列表
    async getsityType() {
      const { data } = await this.$http.post(this.nozzle.sityType, {
        data: {
          siteType: "site_type"
        }
      });
      this.siteTypeList = data.data;
    },
    //获取当前用户所绑定的项目
    getCurrentUserProject() {
      this.$http
        .post(this.nozzle.sysPlatformList, {
          current: 0,
          size: 0,
          data: { searchStr: "", startDate: "", endDate: "" }
        })
        .then(res => {
          if (res.data.code === 1) {
            this.projectList = res.data.data.list.map(item => {
              return {
                id: item.id,
                key: item.name,
                value: item.platformCode
              };
            });
          }
        });
    },
    //表格checkbox选择事件
    handleEvent(event, data) {
      switch (event) {
        case "isRelated":
          this.isRelatedDeviceTableInfo.selectList = data;
          break;
        case "unRelated":
          this.unRelatedDeviceTableInfo.selectList = data;
          break;
      }
    },
    //点击事件
    handleClick(event, data, index){
      switch(event) {
        //站点搜索
        case "search":
          this.siteTableInfo.initCurpage = Math.random();
          this.siteTableInfo.refresh = Math.random();
          break;
        //添加站点
        case "create":
          this.yzaddflag = true;
          this.title = "新增站点";
          this.syscityList = this.removeEmptyChild(this.allCity);
          break;
        //编辑站点
        case "update":
          this.title = "修改站点";
          for (let key in data) {
            if (key === "stationType") {
              data[key] = data[key].toString();
            }
            this.ruleForm[key] = data[key];
          }
          this.syscityList = this.removeEmptyChild(this.allCity);
          this.yzaddflag = true;
          break;
        //查看关联设备
        case "look":
          this.dialogInfo.type = event;
          this.deviceRelatedQuery.siteCode = data.stCode;
          this.dialogInfo.visible = true;
          setTimeout(() => {
            Object.assign(this.isRelatedDeviceTableInfo.query, this.deviceRelatedQuery);
            Object.assign(this.unRelatedDeviceTableInfo.query, this.deviceRelatedQuery);
            this.deviceTableInfo.refresh = Math.random();
          }, 0);
          break;
        //关联设备搜索
        case "deviceSearch":
          this.deviceTableInfo.initCurpage = Math.random();
          this.deviceTableInfo.refresh = Math.random();
          break;
        //添加设备到站点
        case "insert":
          const insertEquipNoArr = this.unRelatedDeviceTableInfo.selectList.map( item => item.equipNo);
          const insertData = {
            siteCode: this.unRelatedDeviceTableInfo.query.siteCode,
            equipNos: insertEquipNoArr
          };
          this.$http.post(this.nozzle.sysEquipInsertBatch, { data: insertData }).then(res => {
            if (res.data.code === 1) {
              this.deviceRelatedQuery.searchStr = "";
              this.deviceTableInfo.refresh = Math.random();
              this.deviceTableInfo.initCurpage = Math.random();
            }
            this.$message({
              message: res.data.msg,
              type: res.data.code === 1 ? "success" : "error",
              showClose: true
            });
          });
          break;
        //解绑设备与站点
        case "remove":
          const removeEquipNoArr = this.isRelatedDeviceTableInfo.selectList.map(item => item.equipNo);
          const removeData = {
            siteCode: this.isRelatedDeviceTableInfo.query.siteCode,
            equipNos: removeEquipNoArr
          };
          this.$http.post(this.nozzle.sysEquipRemoveBatch, { data: removeData }).then(res => {
            if (res.data.code === 1) {
              this.deviceRelatedQuery.searchStr = "";
              this.deviceTableInfo.refresh = Math.random();
              this.deviceTableInfo.initCurpage = Math.random();
            }
            this.$message({
              message: res.data.msg,
              type: res.data.code === 1 ? "success" : "error",
              showClose: true
            });
          }).catch(e =>{console.log(e)});
          break;
        //关闭
        case "close":
          setTimeout(() => {
            this.dialogInfo.visible = false;
          }, 0);
          break;
      }
    },
    // 关闭弹框后做的操作
    closedialog(formName) {
      this.$refs["ruleForm"].resetFields();
      this.ruleForm = {
        id: "", //站点ID
        stName: "", //站点名称
        stCode: "", //站点编号
        tt: "",
        area: "", //所属区域
        constructionStatus: "",
        faultStatus: "",
        taskStatus: "",
        platformCode: "",
        lat: "", //维度
        lon: "", //经度
        isPush: "",
        createTime: "",
        coordinateSystem: "",
        status: "",
        offlineTime: "",
        stationType: "", //站点类型
        // stationTypeName: "",
        coordinateSystem: "", //坐标系(经纬度所对应的的坐标系)
        address: "", //站点安装位置
        person: "", //安装负责人
        fileList: [] //现场安装图片
      };
      this.$refs.cascader.$refs.panel.activePath = [];
      this.$refs.cascader.$refs.panel.clearCheckedNodes();
    },
    handleChange(value) {
      // 取选中数组的最后一项的id
      this.ruleForm.area = value.slice(-1)[0];
    },
    //将空的children置为undefined,避免在没有下一级数据的情况下显示暂无数据
    removeEmptyChild(arr) {
      arr.forEach(item => {
        if (!item.children || item.children.length < 1) {
          item.children = undefined;
        } else {
          this.removeEmptyChild(item.children);
        }
      });
      return arr;
    }
  },
  destroyed() {
    clearInterval(this.timer);
  }
};
</script>
<style lang="scss" scoped>
.imgtype {
  width: 150px;
  height: 100px;
}
/deep/ .el-upload-list {
  display: none;
}
.imgbox {
  display: inline-block;
  margin: 0 20px 20px 0;
  position: relative;
}
.deleteSpan {
  position: absolute;
  display: inline-block;
  right: -6px;
  top: -8px;
  cursor: pointer;
  background: var(--white);
  color: var(--white);
  width: 15px;
  height: 15px;
  border-radius: 13px;
  text-align: center;
}
.deletex {
  color: var(--black);
  position: absolute;
  top: -12px;
  left: 4px;
}
.form {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 50px;
  text-align: left;
  color: var(--white);
  font-size: 14px;
  box-sizing: border-box;
  padding-left: 10px;
}
.form .el-input {
  width: 200px;
  margin: 0 10px;
}
.title, .table-title{
  @include hl(30px,30px);
  color: #409EFF;
  text-align: center;
  font-size: 16px;
  margin-bottom: 10px;
}
.tableSection {
  padding: 10px;
  background: rgba(270, 255, 255, 0.05);
}
/deep/ .el-dialog .el-dialog__body {
  text-align: left;
  padding-bottom: 0;
}
.el-dialog .selectInput {
  width: 30% !important;
}
.el-dialog .selectInput .el-select-dropdown__empty {
  width: 100% !important;
}
.btn-group {
  height: 100%;
  @include fdaj(center, center);
  /deep/ .el-button + .el-button {
    margin-left: 0;
    margin-top: 10px;
  }
}
</style>