智慧园区前端大屏
封装全局搜索栏组件处理
应急空间表格样式调整
封装全局表格及分页组件处理
全局组件引用位置调整
9 files modified
4 files added
1356 ■■■■ changed files
src/components/global/GlobalSearch.vue 588 ●●●●● patch | view | raw | blame | history
src/components/global/GlobalTable.vue 325 ●●●●● patch | view | raw | blame | history
src/components/global/render.js patch | view | raw | blame | history
src/components/index.js 2 ●●● patch | view | raw | blame | history
src/main.js 25 ●●●●● patch | view | raw | blame | history
src/styles/base/index.scss 4 ●●●● patch | view | raw | blame | history
src/styles/element/index.scss 72 ●●●●● patch | view | raw | blame | history
src/styles/index.scss 3 ●●●● patch | view | raw | blame | history
src/views/rs/index.vue 18 ●●●● patch | view | raw | blame | history
src/views/space/components/box/dataContent.vue 297 ●●●● patch | view | raw | blame | history
src/views/space/components/leftContainer.vue 10 ●●●●● patch | view | raw | blame | history
src/views/supplies/components/leftContainer.vue 4 ●●●● patch | view | raw | blame | history
src/views/survey/components/box/fireSource.vue 8 ●●●● patch | view | raw | blame | history
src/components/global/GlobalSearch.vue
New file
@@ -0,0 +1,588 @@
<template>
  <div class="search-bar">
    <template class="search-cont" v-for="(item, index) in options.columns">
      <div :style="{ flex: item.flex || 1, minWidth: '28%', ...item.customClass || '' }" class="search-cont"
        v-if="showCurSelect(item)">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-select :teleported="false" :size="item.size || 'small'" v-model="params[item.props]"
          :clearable="item.clearable || false" :multiple="item.multiple || false" collapse-tags
          :placeholder="item.placeholder || (item.label ? '请选择' + item.label : '请选择')"
          :style="{ flex: 1, marginLeft: $px2rem(item.label ? '15px' : '') }"
          @change="searchSelectChange($event, item)">
          <el-option v-for="selectItem in item.data" :key="selectItem.value" :label="selectItem.label"
            :value="selectItem.value">
          </el-option>
        </el-select>
      </div>
      <div :style="{ flex: item.flex || 1, minWidth: '28%', ...item.customClass || '' }" class="search-cont"
        v-if="item.type === 'input'">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-input :size="item.size || 'small'" v-model="params[item.props]" :clearable="item.clearable || false"
          :placeholder="item.placeholder || (item.label ? '请输入' + item.label : '请输入')"
          :style="{ flex: 1, marginLeft: $px2rem(item.label ? '15px' : '') }" @change="searchInputChange($event, item)">
        </el-input>
      </div>
      <div class="search-cont" v-if="item.type === 'checkbox'">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-checkbox :style="{ marginLeft: $px2rem(item.label ? '15px' : '') }"
          v-model="params[item.props]"></el-checkbox>
      </div>
      <div class="search-cont" v-if="item.type === 'datePicker'">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-date-picker :append-to-body="false" :size="item.size || 'small'" v-model="params[item.props]"
          :pickerOptions="item.pickerOptions || {}" :format="item.format || 'yyyy-MM-dd HH:mm:ss'"
          :clearable="item.clearable || false" :type="item.pickerType || 'daterange'" range-separator="至"
          start-placeholder="开始日期" end-placeholder="结束日期" :value-format="item.format || 'yyyy-MM-dd HH:mm:ss'"
          :style="{ width: $px2rem(`${item.width || '360'}px`), marginLeft: $px2rem(item.label ? '15px' : '') }"
          @change="searchDateChange($event, item)">
        </el-date-picker>
      </div>
      <!-- :picker-options="pickerOptions" -->
      <div class="search-cont" v-if="item.type === 'date' && options.quickDateBtn">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-date-picker :append-to-body="false" :size="item.size || 'small'" v-model="params[item.props]" type="date"
          :clearable="item.clearable || false" :placeholder="item.placeholder || item.label || '选择时间'"
          :style="{ width: $px2rem(`${item.width || '140'}px`), marginLeft: $px2rem(item.label ? '15px' : '') }"
          :editable="false" :disabled="currentDateType != 3" :value-format="item.format || 'yyyy-MM-dd'">
        </el-date-picker>
      </div>
      <div class="search-cont" v-if="item.type === 'year'">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-date-picker :append-to-body="false" v-model="params[item.props]" type="year"
          :placeholder="item.placeholder || '选择年'" :value-format="item.format || 'yyyy'">
        </el-date-picker>
      </div>
      <div class="search-cont" v-if="item.type === 'multiDate' && options.quickMultiDateBtn">
        <span v-show="item.label" class="search-cont-label">{{ item.label }}:</span>
        <el-date-picker :append-to-body="false" :size="item.size || 'small'" v-model="params[item.props]"
          :type="multiDateType" :key="multiDateType" :clearable="item.clearable || false"
          :placeholder="item.placeholder || item.label || '多选择时间'" :editable="false"
          :style="{ width: $px2rem(`${item.width || '180'}px`), marginLeft: $px2rem(item.label ? '15px' : '') }"
          :value-format="item.format || 'yyyy-MM-dd'">
        </el-date-picker>
      </div>
    </template>
    <div class="search-cont search-cont-btn" v-if="options.searchBtnGroup">
      <el-button v-if="options.searchBtn || false"
        :type="options.searchBtnTitleShow ? '' : options.searchType || 'primary'"
        :disabled="options.searchDisabled || false" :size="options.searchSize || 'small'" :icon="Search"
        @click="searchClick" :class="{ 'btn-h32-w76': options.searchBtnTitleShow ? false : true }">{{
          options.searchBtnTitleShow ?
            options.searchBtnTitle : '查 询'
        }}</el-button>
      <el-button v-if="options.resetBtn || false" :type="options.resetType || ''"
        :disabled="options.resetDisabled || false" :size="options.resetSize || 'small'" :icon="Refresh"
        @click="resetClick" class="btn-h32-w76 reset-btn">重
        置</el-button>
      <el-button v-if="options.exportBtn || false" :type="options.exportType || 'primary'"
        :disabled="options.exportDisabled || false" :size="options.exportSize || 'small'" :icon="Download"
        @click="exportClick" class="btn-h32-w76">导 出</el-button>
    </div>
  </div>
</template>
<script setup>
import { Search, Refresh, Download } from '@element-plus/icons-vue'
import request from 'utils/http'
import { reactive } from 'vue'
const {
  options,
  inputs,
  selects,
  button,
} = defineProps({
  options: {
    default: () => { return new Object() }
  },
  inputs: {
    default: () => { return new Array() }
  },
  selects: {
    default: () => { return new Array() }
  },
  button: {
    default: () => { return new Object() }
  }
})
const emit = defineEmits(['searchBtn', 'resetBtn', 'exportExcel', 'quickQuery'])
const params = reactive({})
const currentDateType = ref('')
const multiDateType = ref('')
const regionCode = ref('')
let pendingFlag = null
let pendingFunction = null
const showCurSelect = computed(() => (item) => {
  if ('show' in item) {
    if (item.show == false) {
      return false
    } else {
      return item.type === 'select'
    }
  } else {
    return item.type === 'select'
  }
})
/**
    * @description: 按钮查询事件
    * @return {*}
    */
const searchClick = () => {
  const flag = options.columns.some(item => item.type == 'cascader' || item.type == 'basinCascader' || item.type == 'ruleCascader')
  if (flag) {
    emit('searchBtn', getSeachCondition())
  } else {
    emit('searchBtn', { ...params })
  }
}
/**
     * @description: 按钮重置事件
     * @return {*}
     */
const resetClick = () => {
  const flag = options.columns.some(item => item.type == 'cascader' || item.type == '')
  resetParams()
  if (flag) {
    emit('resetBtn', resetSeachCondition())
  } else {
    emit('resetBtn', { ...params })
  }
}
/**
     * @description: 重置所有查询条件
     * @return {*}
     */
const resetParams = (param, type = false) => {
  options.columns.forEach(item => {
    if (item.props) {
      if (item.defaultValue) {
        params[item.props] = item.defaultValue
      } else {
        params[item.props] = ''
      }
    }
  })
  if (pendingFlag == true && type == true) {
    pendingFunction()
    pendingFlag = false
  }
}
const disposeFunction = (fun) => {
  pendingFunction = fun
  pendingFlag = true
}
const getSeachCondition = () => {
  return { ...params }
}
/**
   * @description: 重置当前搜索条件
   * @return {*}
   */
const resetSeachCondition = () => {
  return { ...this.params }
}
/**
    * @description: 按钮导出事件
    * @return {*}
    */
const exportClick = () => {
  const flag = options.columns.some(item => item.type == 'cascader')
  if (flag) {
    emit('exportExcel', getSeachCondition())
  } else {
    emit('exportExcel', { ...params })
  }
}
/**
  * @description: select公共方法
  * @param {*} e
  * @param {*} item
  * @return {*}
  */
const searchSelectChange = (e, item) => {
  if (item.quickBtnShow) {
    if (item.quickBtnShow == e) {
      options.quickMultiDateBtn = false
      options.quickDateBtn = true
    } else {
      options.quickDateBtn = false
      options.quickMultiDateBtn = true
    }
    emit('quickQuery', params)
  }
  if (item.relationUrl) {
    let cur = item.data.find(it => it.value === e)
    options.columns.forEach(curItem => {
      if (curItem.dataSource && curItem.dataSource == 'middleground' && curItem.relevanceProps && curItem.relevanceProps == item.props) {
        curItem.data = []
        params[curItem.props] = ''
        item.cb(cur.ztValue)
        if (cur[curItem.searchValue] == 'all') {
          return
        }
        let getParams = {}
        if (item.res_cd) {
          getParams = {
            res_cd: item.res_cd
          }
        }
        if (curItem.searchProps) {
          getParams[curItem.searchProps] = cur[curItem.searchValue]
        }
        request({
          url: item.relationUrl,
          method: item.method,
          apiKey: true,
          params: getParams
        }).then(res => {
          curItem[curItem.props] = ''
          if (item.customResponse) {
            curItem.data = res.data.data.map(it => {
              if (cur[curItem.searchValue] == 'sy') {
                return {
                  label: it[item.customResponse.label],
                  value: it[item.customResponse.value],
                }
              } else if (cur[curItem.searchValue] == 'wy') {
                return {
                  label: it[item.customResponse.label],
                  value: it[item.customResponse.value],
                }
              } else {
                return {
                  label: it.cd,
                  value: it.cd,
                }
              }
            })
          } else {
            curItem.data = res.data.data.map(it => {
              if (cur[curItem.searchValue] == 'sy') {
                return {
                  label: it.cd,
                  value: it.cd,
                }
              } else if (cur[curItem.searchValue] == 'wy') {
                return {
                  label: it.cd,
                  value: it.cd,
                }
              } else {
                return {
                  label: it.cd,
                  value: it.cd,
                }
              }
            })
          }
        })
      } else if (curItem.basisFlag == true && curItem.relevanceProps && curItem.relevanceProps == item.props) {
        params[curItem.props] = ''
        let getParams = {}
        if (curItem.codeFlag) {
          getParams = {
            code: curItem.basisType
          }
        }
        if (curItem.searchProps) {
          getParams[curItem.searchProps] = cur[curItem.searchValue]
        } else {
          getParams['parentId'] = cur.id
        }
        request({
          url: item.relationUrl,
          method: item.method,
          params: getParams
        }).then(res => {
          curItem.data = res.data.data.map(it => {
            return {
              label: it.dictValue,
              value: it.dictKey,
            }
          })
        })
      }
    })
  }
  // 配置changeSearch时改变值立即调用搜索
  if (item.changeSearch) {
    searchClick()
  }
}
const searchInputChange = (e, item) => {
  // 配置changeSearch时改变值立即调用搜索
  if (item.changeSearch) {
    searchClick()
  }
}
const setItemDefault = (props, defaultValue) => {
  params[props] = defaultValue
}
const searchDateChange = (e, item) => {
  // 配置changeSearch时改变值立即调用搜索
  if (item.changeSearch) {
    params.isChangeDate = true//监测预警时间改变
    searchClick()
  }
}
const $px2rem = (px) => {
  if (/%/gi.test(px)) {
    // 有百分号%,特殊处理,表述pc是一个有百分号的数,比如:90%
    return px
  } else {
    return parseFloat(px) / 192 + "rem"
  }
}
watch(
  () => options,
  (newData) => {
    if (JSON.stringify(newData) != '{}') {
      if (newData.resetParams && newData.resetParams == true) params = {}
      resetParams({}, true)
      if (newData.quickDateBtn) {
        currentDateType = newData.quickBtnDefault
      }
      if (newData.multiDateTypeDefault) {
        multiDateType = newData.multiDateTypeDefault
      }
    }
  },
  { immediate: true } // 设置immediate为true以便在组件挂载时立即检查createB的值
)
defineExpose({
  getSeachCondition
})
</script>
<script>
export default {
  name: 'GlobalSearch'
}
</script>
<style lang="scss" scoped>
.search-bar {
  padding-left: 10px;
  margin-bottom: 10px;
  display: flex;
  flex-wrap: wrap;
  .search-cont {
    margin-right: 10px;
    margin-top: 10px;
    display: flex;
    align-items: center;
    &-label {
      display: flex;
      align-items: center;
      white-space: nowrap;
      font-size: 14px;
      color: #fff;
    }
  }
  ::v-deep(.el-input) {
    .el-input__wrapper {
      background: rgba(135, 158, 199, 0.2);
      box-shadow: inset 0px 3px 7px 0px rgba(42, 138, 236, 0.949);
      border-radius: 4px 4px 4px 4px;
      border: 1px solid #4081CB;
    }
    input {
      color: #D4E8F8;
    }
  }
  ::v-deep(.el-select) {
    .el-select__wrapper {
      background: rgba(135, 158, 199, 0.2);
      box-shadow: inset 0px 3px 7px 0px rgba(42, 138, 236, 0.949);
      border-radius: 4px 4px 4px 4px;
      border: 1px solid #4081CB;
      .el-select__placeholder {
        color: #D4E8F8;
      }
    }
    .el-popper.is-light,
    .el-popper.is-light>.el-popper__arrow:before {
      background: rgba(15, 44, 75, 1);
      border: 1px solid rgba(15, 44, 75, 1);
    }
    .el-select-dropdown {
      background: rgba(15, 44, 75, 1);
      border: none;
      .el-select-dropdown__item {
        color: #D4E8F8;
      }
      .el-select-dropdown__item.is-hovering {
        color: #4ACFFF;
        background: rgba(85, 187, 248, 0.2);
      }
    }
  }
  .search-cont-btn {
    margin-top: 10px;
    ::v-deep(.el-button) {
      background: #277DFF;
      border-color: #277DFF;
      &.reset-btn {
        color: #D4E8F8;
        background: #43779B;
        border-color: #43779B;
      }
    }
  }
}
::v-deep .el-date-editor {
  width: 100%;
  color: #fff;
  background: rgba(0, 44, 71, 0.302);
  .el-input__icon {
    color: #fff;
  }
  .el-range-separator {
    color: #fff;
  }
  input {
    color: #fff;
    background: transparent;
  }
  .el-picker-panel,
  .el-time-panel__content {
    color: #D4E8F8;
    background: rgba(15, 44, 75, 1);
  }
  .el-time-panel__content {
    .el-time-spinner__item {
      color: #9eb1c1;
      &:hover {
        background: rgba(85, 187, 248, 0.2);
      }
      &.active {
        color: #D4E8F8;
      }
    }
  }
  .el-picker-panel__footer,
  .el-time-panel__footer {
    background: rgba(15, 44, 75, 1);
  }
  .el-picker-panel__footer {
    .is-plain {
      color: #D4E8F8;
      background: rgba(39, 125, 255, .6);
      border-color: rgba(39, 125, 255, .6);
    }
  }
  .el-time-panel__footer {
    .cancel {
      color: #D4E8F8;
    }
  }
  .el-icon-arrow-right {
    color: #AFBED8;
  }
  .el-date-table {
    th {
      color: #AFBED8;
      border-color: rgba(39, 125, 255, .6);
    }
  }
  .el-date-range-picker__time-header,
  .el-date-range-picker__content,
  .el-picker-panel__footer,
  .el-picker-panel__body,
  .el-picker-panel__body-wrapper,
  .el-picker-panel {
    border-color: rgba(39, 125, 255, .6);
  }
  .el-popper__arrow,
  .el-popper__arrow::after {
    border-bottom-color: rgba(39, 125, 255, .6);
  }
  td.in-range {
    div {
      background: rgba(39, 125, 255, .4) !important;
    }
  }
}
</style>
src/components/global/GlobalTable.vue
New file
@@ -0,0 +1,325 @@
<template>
  <div class="h100 flex f-d-c cur-table-box" v-loading="loading" element-loading-background="rgba(46, 81, 136, 0.9)">
    <div class="h0 flex-1 table-content" ref="TableContent">
      <el-table ref="tableData" :height="tableHeight" :row-key="rowKey" :border="border" :size="tableSize" :data="data"
        @selection-change="handleSelectionChange" @current-change="handleTableCurrentChange"
        @row-click="handleTableRowClick" @sort-change="handleSortChange" v-bind="otherConfig">
        <template v-for="(item, index) in columns">
          <!-- 选择框 -->
          <el-table-column v-if="item.selection" type="selection" width="36" :fixed="item.fixed"
            :reserve-selection="reserveSelection" align="center" header-align="center"
            :key="`selection_${index}`"></el-table-column>
          <!-- 自定义单选框 -->
          <el-table-column v-else-if="item.singleSelection" width="50" :fixed="item.fixed" align="center"
            header-align="center" :key="`singleSelection_${index}`">
            <template slot-scope="scope">
              <el-checkbox v-model="scope.row.isSingleSelected"
                @change="handleSingleSelectionChange(scope.row)"></el-checkbox>
            </template>
          </el-table-column>
          <!-- 序号 -->
          <el-table-column v-else-if="item.index" align="center" type="index" width="48" :fixed="item.fixed" label="序号"
            :index="item.indexMethod || indexMethod" :key="`index_${index}`"></el-table-column>
          <!-- 多级表头 -->
          <el-table-column v-else-if="item.multi" align="center" :label="item.label" :key="`multi_${index}`">
            <el-table-column v-for="(child, childIndex) in item.children" :key="`child_${index}_${childIndex}`"
              v-bind="child">
            </el-table-column>
          </el-table-column>
          <!-- 自定义内容 -->
          <slot v-else-if="item.slot" :name="item.slot"></slot>
          <el-table-column v-else-if="item.sortable" sortable="custom" align="center" show-overflow-tooltip
            v-bind="item" :fixed="item.fixed" :width="item.width" :key="`normal_sort${index}`"
            :render-header="tableRenderHeader"></el-table-column>
          <!-- 常规字段 -->
          <el-table-column v-else align="center" show-overflow-tooltip v-bind="item" :fixed="item.fixed"
            :width="item.width" :key="`normal_${index}`" :render-header="tableRenderHeader"></el-table-column>
        </template>
      </el-table>
    </div>
    <div v-show="isPaginationShow && pagination.total" class="pagination-content">
      <el-pagination background :page-sizes="[10, 20, 50, 100]" layout="prev, pager, next" :pager-count="5"
        :current-page.sync="pagination.current" :page-size="pagination.size" :total="pagination.total"
        @size-change="handleSizeChange" @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <!-- 自定义内容 -->
    <slot name="custom-content"></slot>
  </div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue'
const emit = defineEmits(['getData', 'changeSelection', 'changeCurrent', 'changeSingleSelection', 'rowClick', 'changeSort'])
const { columns, data, pagination, } = defineProps({
  columns: {
    type: Array,
    default: () => [],
  },
  data: {
    type: Array,
    default: () => [],
  },
  pagination: {
    type: Object,
    default: () => ({
      current: 1,
      size: 10,
      total: 0,
    }),
  },
  isPaginationShow: {
    type: Boolean,
    default: true,
  },
  tableSize: {
    type: String,
    default: 'small',
  },
  border: {
    type: Boolean,
    default: false
  },
  otherConfig: {
    type: Object,
    default: () => { },
  },
  loading: {
    type: Boolean,
    default: false,
  },
  // 支持跨页选择的两个配置项
  rowKey: {
    type: String,
    default: ''
  },
  reserveSelection: {
    type: Boolean,
    default: false
  }
})
const tableHeight = ref(0)
const TableContent = ref(null)
const tableData = ref(null)
onMounted(() => {
  window.addEventListener('resize', this.handleWindowResize)
})
onUnmounted(() => {
  window.removeEventListener('resize', this.handleWindowResize)
})
watch(
  () => data,
  (newData) => {
    if (newData) {
      nextTick(() => {
        handleWindowResize()
      })
    }
  }
)
watch(
  () => columns,
  (newColumns) => {
    if (newColumns && newColumns.length) {
      nextTick(() => {
        tableData.value.doLayout()
      })
    }
  },
  { deep: true }
)
// 切换页码
const handleCurrentChange = () => {
  emit('getData')
},
// 切换每页条数
const handleSizeChange = (value) => {
  pagination.size = value
  emit('getData')
}
// 切换选择
const handleSelectionChange = (val) => {
  emit('changeSelection', val)
}
// 单选
const handleTableCurrentChange = (currentRow) => {
  emit('changeCurrent', currentRow)
}
// 自定义单选
const handleSingleSelectionChange = (currentRow) => {
  emit('changeSingleSelection', currentRow)
}
// 点击行
const handleTableRowClick = (currentRow) => {
  emit('rowClick', currentRow)
}
// 排序
const handleSortChange = (val) => {
  emit('changeSort', val)
}
// 自定义表头渲染方法
const tableRenderHeader = (h, { column }) => {
  const span = document.createElement('span')
  span.innerText = column.label
  document.body.appendChild(span)
  const realWidth = span.getBoundingClientRect().width
  let columnWidth = realWidth + 22 // 22: 左右padding 10*2 + border预留 2
  if (column.sortable === 'custom') columnWidth += 30
  column.minWidth = columnWidth
  document.body.removeChild(span)
  return h('span', column.label)
}
// 序号列自定义方法
const indexMethod = (index) => {
  const { current, size } = this.pagination
  return (current - 1) * size + index + 1
}
// 页面缩放重新计算 table高度
const handleWindowResize = () => {
  tableHeight = TableContent.offsetHeight
}
</script>
<script>
export default {
  name: 'GlobalTable'
}
</script>
<style lang="scss" scoped>
.cur-table-box {
  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
    background-color: none;
  }
  ::-webkit-scrollbar-thumb {
    background: #4ACFFF;
    border-radius: 3px;
  }
  ::-webkit-scrollbar-track {
    background: #1D486E;
  }
}
.table-content {
  ::v-deep(.el-table) {
    &::before {
      content: none;
    }
    background: transparent !important;
    border: none;
    .el-table__header-wrapper {
      tr {
        height: 38px;
        background: rgba(35, 53, 92, 0.8) !important;
        box-sizing: border-box;
        th {
          background: transparent !important;
          border-bottom: 1px solid rgba(103, 135, 214, 1);
          .cell {
            color: #AFBED8;
          }
        }
      }
    }
    .el-table__body-wrapper {
      table {
        border-collapse: separate !important;
        border-spacing: 0 10px !important;
      }
      tr {
        height: 38px;
        background: rgba(36, 57, 110, 0.2);
        box-sizing: border-box;
        cursor: pointer;
        &:hover {
          td {
            color: #44C1EF;
            background: transparent !important;
          }
        }
        td {
          padding: 0;
          height: 38px;
          line-height: 38px;
          color: #D4E8F8;
          border-top: 1px solid rgba(110, 135, 197, 0.32);
          border-bottom: 1px solid rgba(110, 135, 197, 0.32);
          box-sizing: border-box;
        }
        td:first-child {
          border-left: 1px solid rgba(110, 135, 197, 0.32);
        }
        td:last-child {
          border-right: 1px solid rgba(110, 135, 197, 0.32);
        }
      }
    }
    .el-table__empty-block {
      background: rgba(36, 57, 110, 0.2);
      .el-table__empty-text {
        color: #D4E8F8;
      }
    }
  }
}
.pagination-content {
  margin: 10px 0;
  color: #D4E8F8;
  ::v-deep(.el-pagination) {
    .el-pagination__total {
      color: #D4E8F8;
    }
    .btn-prev,
    .btn-next {
      color: rgba(216, 235, 238, 0.8) !important;
      background: rgba(68, 193, 239, 0.1);
    }
    .el-pager {
      .btn-quickprev,
      .btn-quicknext,
      .number {
        color: rgba(216, 235, 238, 0.8) !important;
        background: rgba(68, 193, 239, 0.1);
      }
      .active {
        color: #FFFFFF;
        background: #44C1EF !important;
        opacity: 0.8;
      }
    }
  }
}
</style>
src/components/global/render.js
src/components/index.js
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2024-10-25 15:20:05
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2024-10-25 15:25:41
 * @LastEditTime: 2024-11-08 20:11:39
 * @FilePath: \bigScreen\src\components\index.js
 * @Description: 
 * 
src/main.js
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2024-10-25 10:56:27
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2024-10-31 11:01:20
 * @LastEditTime: 2024-11-08 20:11:07
 * @FilePath: \bigScreen\src\main.js
 * @Description: 
 * 
@@ -22,10 +22,14 @@
import './permission'
// 全局组件自动注册
import components from '@/components/index'
import GlobalSearch from 'components/global/GlobalSearch.vue'
// import GlobalTable from 'components/global/GlobalTable.vue'
import MapContainer from 'components/global/MapContainer.vue'
import publicBox from 'components/global/publicBox.vue'
import TitleBox from 'components/global/TitleBox.vue'
import { getElementLabelLine } from 'element-tree-line';
import 'element-tree-line/dist/style.css';
import { getElementLabelLine } from 'element-tree-line'
import 'element-tree-line/dist/style.css'
import * as DC from '@dvgis/dc-sdk'
import '@dvgis/dc-sdk/dist/dc.min.css'
@@ -34,11 +38,16 @@
const pinia = createPinia()
pinia.use(piniaPersistPlugin)
const ElementLabelLine = getElementLabelLine(h);
app.component(ElementLabelLine.name, ElementLabelLine);
const ElementLabelLine = getElementLabelLine(h)
app.component(ElementLabelLine.name, ElementLabelLine)
app.component('GlobalSearch', GlobalSearch)
// app.component('GlobalTable', GlobalTable)
app.component('MapContainer', MapContainer)
app.component('publicBox', publicBox)
app.component('TitleBox', TitleBox)
app.use(router)
app.use(ElementPlus)
app.use(pinia)
app.use(components)
app.mount('#app')
router.isReady().then(() => app.mount('#app'))
src/styles/base/index.scss
@@ -33,12 +33,12 @@
}
::-webkit-scrollbar-thumb {
  background-color: #BFBFBF;
  background: #4acfff;
  border-radius: 3px;
}
::-webkit-scrollbar-track {
  background-color: rgb(255, 255, 255);
  background: #1d486e;
}
.content-center {
src/styles/element/index.scss
New file
@@ -0,0 +1,72 @@
.el-table {
  &::before {
    content: none;
  }
  background: transparent !important;
  border: none;
  .el-table__header-wrapper {
    tr {
      height: 38px;
      background: rgba(35, 53, 92, 0.8) !important;
      box-sizing: border-box;
      th {
        background: transparent !important;
        border-bottom: 1px solid rgba(103, 135, 214, 1);
        .cell {
          color: #AFBED8;
        }
      }
    }
  }
  .el-table__body-wrapper {
    table {
      border-collapse: separate !important;
      border-spacing: 0 10px !important;
    }
    tr {
      height: 38px;
      background: rgba(36, 57, 110, 0.2);
      box-sizing: border-box;
      cursor: pointer;
      &:hover {
        td {
          color: #44C1EF;
          background: transparent !important;
        }
      }
      td {
        padding: 0;
        height: 38px;
        line-height: 38px;
        color: #D4E8F8;
        border-top: 1px solid rgba(110, 135, 197, 0.32);
        border-bottom: 1px solid rgba(110, 135, 197, 0.32);
        box-sizing: border-box;
      }
      td:first-child {
        border-left: 1px solid rgba(110, 135, 197, 0.32);
      }
      td:last-child {
        border-right: 1px solid rgba(110, 135, 197, 0.32);
      }
    }
  }
  .el-table__empty-block {
    background: rgba(36, 57, 110, 0.2);
    .el-table__empty-text {
      color: #D4E8F8;
    }
  }
}
src/styles/index.scss
@@ -1,2 +1,3 @@
@use './base/index.scss'as *;
@use './page/index.scss'as *;
@use './page/index.scss'as *;
@use './element/index.scss'as *;
src/views/rs/index.vue
@@ -2,8 +2,8 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-03-13 16:02:07
 * @FilePath: \forest-fire\src\views\statistics\index.vue
 * @LastEditTime: 2024-11-08 15:29:21
 * @FilePath: \bigScreen\src\views\rs\index.vue
 * @Description: 综合设计
 * 
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
@@ -14,17 +14,17 @@
</script>
<template>
    <div class="container page-container">
        <left-container></left-container>
  <div class="container page-container">
    <!-- <left-container></left-container> -->
        <right-container></right-container>
    </div>
    <!-- <right-container></right-container> -->
  </div>
</template>
<style lang="scss" scoped>
.container {
    position: absolute;
    width: 100%;
    height: 100%;
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>
src/views/space/components/box/dataContent.vue
@@ -2,43 +2,57 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-13 14:54:26
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-03-13 15:00:55
 * @FilePath: \forest-fire\src\views\statistics\components\box\dataContent.vue
 * @LastEditTime: 2024-11-08 20:12:10
 * @FilePath: \bigScreen\src\views\space\components\box\dataContent.vue
 * @Description: 
 * 
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
-->
<script setup>
import publicContent from "./publicContent.vue";
import { getList } from "@/api/space/space";
import { getDictionary } from "@/api/dict/dict";
import { reactive } from "vue";
const loading = ref(false);
import publicContent from "./publicContent.vue"
import { getList } from "@/api/space/space"
import { getDictionary } from "@/api/dict/dict"
import { nextTick, reactive } from "vue"
const SeachBarCondition = ref(null)
const loading = ref(false)
const TableContent = ref(null)
const curTableHeight = ref(0)
const tableData = ref([]);
const opertionData = ref([]);
// 搜索项配置
const options = reactive({
  searchBtnGroup: true,
  searchBtn: true,
  resetBtn: true,
  exportBtn: false,
  columns: [
    {
      label: "名称",
      type: 'input',
      props: 'name',
      placeholder: '请输入名称',
      changeSearch: true,
      flex: 1,
    },
    {
      label: "类型",
      type: "select",
      props: "type",
      data: [],
      changeSearch: true,
      clearable: true,
      flex: 1,
    },
  ]
})
const tableData = ref([])
const pages = {
  page: 1,
  pageSize: 10,
  total: 0,
};
function positionColor() {
  return (row) => {
    if (
      (row.X && row.X != 0) ||
      (row.lng && row.lng != 0) ||
      (row.longitude && row.longitude != 0) ||
      (row.x && row.x != 0)
    ) {
      return "#1AFA29";
    } else {
      return "#ccc";
    }
  };
}
function positionDisabled() {
function positionColor () {
  return (row) => {
    if (
      (row.X && row.X != 0) ||
@@ -46,146 +60,145 @@
      (row.longitude && row.longitude != 0) ||
      (row.x && row.x != 0)
    ) {
      return false;
      return "#1AFA29"
    } else {
      return true;
      return "#ccc"
    }
  };
  }
}
function positionDisabled () {
  return (row) => {
    if (
      (row.X && row.X != 0) ||
      (row.lng && row.lng != 0) ||
      (row.longitude && row.longitude != 0) ||
      (row.x && row.x != 0)
    ) {
      return false
    } else {
      return true
    }
  }
}
onMounted(() => {
  // 获取下拉字典信息
  getDictData("emergency_space_type");
  // 获取列表信息
  getLists();
});
// 表格样式
const tableCellStyle = ({ row, column }) => {
  return { background: "#152851", color: "#fff" };
};
// 表格表头样式
const headerCellStyle = ({ }) => {
  return {
    background: "#152851",
    color: "#fff",
  };
};
// 搜索条件
const formInline = reactive({
  name: "",
  type: "",
});
  curTableHeight.value = TableContent.value.offsetHeight
})
// 提交查询
const onSubmit = () => {
  resetPage();
  console.log("submit!");
  getLists(formInline);
};
watch(
  () => TableContent,
  (newData) => {
    console.log(newData.value?.clientHeight, 456465456)
  },
  {
    immediate: true,
    deep: true
  })
// 重置分页数据
const resetPage = () => {
  pages.page = 1;
  pages.pageSize = 10;
  pages.total = 0;
};
// 分页树改变
const handleSizeChange = (val) => {
  pages.pageSize = val;
  getLists(formInline);
};
// 分页改变
const handleCurrentChange = (val) => {
  pages.page = val;
  getLists(formInline);
};
// 重置条件
const clearBtn = () => {
  formInline.name = "";
  formInline.type = "";
  resetPage();
  getLists(formInline);
};
  pages.page = val
  getLists(SeachBarCondition.value.getSeachCondition())
}
// 获取下拉字典
function getDictData(code) {
const getDictData = (code) => {
  const param = {
    code: code,
  };
  }
  getDictionary(param).then((res) => {
    opertionData.value = res.data.data;
  });
    options.columns[1].data = res.data.data.map(item => {
      return {
        label: item.dictValue,
        value: item.dictKey
      }
    })
    searchBtn(SeachBarCondition.value.getSeachCondition())
  })
}
// 查询分页数据
function getLists(param = {}) {
  param.current = pages.page;
  param.size = pages.pageSize;
  loading.value = true;
const getLists = (param = {}) => {
  param.current = pages.page
  param.size = pages.pageSize
  loading.value = true
  getList(param)
    .then((res) => {
      const data = res.data.data;
      tableData.value = data.records;
      pages.total = data.total;
      loading.value = false;
      const data = res.data.data
      tableData.value = data.records
      pages.total = data.total
      loading.value = false
    })
    .catch((err) => {
      loading.value = false;
      console.log(err);
    });
      loading.value = false
      console.log(err)
    })
}
// 行点击
function rowClick(row) {
function rowClick (row) {
  // 读取定位飞
}
// 查看详情
function goDetail(row) { }
function goDetail (row) { }
const searchBtn = (params) => {
  resetPage()
  getLists(params)
}
const resetBtn = (params) => {
  resetPage()
  getLists(params)
}
// 重置分页数据
const resetPage = () => {
  pages.page = 1
  pages.pageSize = 10
  pages.total = 0
}
// 分页树改变
const handleSizeChange = (val) => {
  pages.pageSize = val
  getLists(SeachBarCondition.value.getSeachCondition())
}
getDictData("emergency_space_type")
</script>
<template>
  <public-content>
    <template #content>
      <div class="search-box">
        <el-form :inline="true" :model="formInline" class="demo-form-inline">
          <el-form-item label="名称">
            <el-input v-model="formInline.name" placeholder="请输入名称" clearable style="width: 350px" />
          </el-form-item>
          <el-form-item label="类型">
            <el-select v-model="formInline.type" placeholder="请选择" clearable style="width: 120px">
              <el-option v-for="item in opertionData" :label="item.dictValue" :value="item.dictKey" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button siz="default" type="primary" @click="onSubmit">查询</el-button>
            <el-button siz="default" type="" @click="clearBtn">重置</el-button>
          </el-form-item>
        </el-form>
        <el-table :data="tableData" style="width: 100%" :header-cell-style="headerCellStyle" :cell-style="tableCellStyle"
          v-loading="loading">
          <el-table-column fixed prop="name" label="名称" />
          <el-table-column prop="emergencySpaceType" label="类型" width="70" />
          <el-table-column prop="mainFuncName" label="作用" width="60" />
          <el-table-column width="60" label="操作" align="center">
            <template #default="scope">
              <el-button link type="primary" size="small" :disabled="scope.row.lng == ''" @click="rowClick(scope.row)">
                定位
              </el-button>
              <!-- <el-button link type="primary" size="small" @click="goDetail">
  <div class="w100 h0 flex-1 flex f-d-c">
    <global-search :options="options" @searchBtn="searchBtn" @resetBtn="resetBtn"
      ref="SeachBarCondition"></global-search>
    <div class="h0 flex-1 table-content" ref="TableContent">
      <el-table :data="tableData" :height="curTableHeight" style="width: 100%" v-loading="loading">
        <el-table-column prop="name" label="名称" />
        <el-table-column prop="emergencySpaceType" label="类型" width="70" />
        <el-table-column prop="mainFuncName" label="作用" width="60" />
        <el-table-column width="60" label="操作" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" :disabled="scope.row.lng == ''" @click="rowClick(scope.row)">
              定位
            </el-button>
            <!-- <el-button link type="primary" size="small" @click="goDetail">
                <i class="el-icon-document" style="color: #66b1ff"></i>详情
              </el-button> -->
            </template>
          </el-table-column>
        </el-table>
        <div class="el-page">
          <el-pagination background layout="prev, pager, next" :page-size="pages.pageSize" :total="pages.total"
            @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
      </div>
    </template>
  </public-content>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="el-page">
      <el-pagination background layout="prev, pager, next" :page-size="pages.pageSize" :total="pages.total"
        @size-change="handleSizeChange" @current-change="handleCurrentChange" size="small" />
    </div>
  </div>
</template>
<style lang="scss" scoped>
@@ -193,25 +206,17 @@
  color: #fff !important;
}
.search-box {
  ::v-deep .el-table__body-wrapper {
    background-color: #152851;
  }
}
/* 当表格没有数据时,修改表格的背景颜色 */
.el-table--empty .el-table__body {
  background-color: rgba(135, 158, 199, 0.3);
  /* 你想要的背景颜色 */
.table-content {
  flex-basis: auto;
  height: calc(100% - 40px);
}
.el-page {
  margin-top: 10px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  // margin-bottom:10px;
  width: 100%;
  height: 40px;
  line-height: 40px;
}
</style>
src/views/space/components/leftContainer.vue
@@ -2,8 +2,8 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2024-10-25 18:43:23
 * @FilePath: \bigScreen\src\views\statistics\components\leftContainer.vue
 * @LastEditTime: 2024-11-08 15:49:02
 * @FilePath: \bigScreen\src\views\space\components\leftContainer.vue
 * @Description: 
 * 
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
@@ -16,13 +16,15 @@
<template>
  <div class="left-container">
    <div class="data box">
    <div class="data box h0 flex-1">
      <title-box>
        <template #titleName>
          应急空间信息
        </template>
      </title-box>
      <data-content></data-content>
      <div class="content-box">
        <data-content></data-content>
      </div>
    </div>
    <!-- <div class="unit box">
src/views/supplies/components/leftContainer.vue
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2024-11-08 11:35:39
 * @LastEditTime: 2024-11-08 15:48:16
 * @FilePath: \bigScreen\src\views\supplies\components\leftContainer.vue
 * @Description: 
 * 
@@ -16,7 +16,7 @@
<template>
  <div class="left-container">
    <div class="data box">
    <div class="data box w100 h100">
      <data-content>
      </data-content>
    </div>
src/views/survey/components/box/fireSource.vue
@@ -70,7 +70,7 @@
})
// 获取详情
function getData() {
function getData () {
  getDetail().then(res => {
    state.parkInfo = res.data.data
    parkInfoList.forEach(item => {
@@ -131,11 +131,11 @@
}
.box-content-img {
  height: 360px;
  overflow: scroll;
  height: 380px;
  // 隐藏滚动条
  scrollbar-width: none;
  // overflow-y: auto;
  overflow-x: hidden;
  overflow-y: auto;
}
.box-content-img img {