From 046f1de193dd38e7153ecaf72eed5797b28d1c2c Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 08 Nov 2024 20:16:59 +0800
Subject: [PATCH] 封装全局搜索栏组件处理 应急空间表格样式调整 封装全局表格及分页组件处理 全局组件引用位置调整

---
 src/components/global/GlobalTable.vue           |  325 ++++++++++++++
 src/views/survey/components/box/fireSource.vue  |    8 
 src/styles/base/index.scss                      |    4 
 src/components/index.js                         |    2 
 src/views/supplies/components/leftContainer.vue |    4 
 src/main.js                                     |   25 
 src/views/space/components/leftContainer.vue    |   10 
 src/components/global/render.js                 |    0 
 src/views/rs/index.vue                          |   18 
 src/components/global/GlobalSearch.vue          |  588 +++++++++++++++++++++++++
 src/styles/index.scss                           |    3 
 src/styles/element/index.scss                   |   72 +++
 src/views/space/components/box/dataContent.vue  |  297 ++++++------
 13 files changed, 1,179 insertions(+), 177 deletions(-)

diff --git a/src/components/global/GlobalSearch.vue b/src/components/global/GlobalSearch.vue
new file mode 100644
index 0000000..475dfb8
--- /dev/null
+++ b/src/components/global/GlobalSearch.vue
@@ -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>
\ No newline at end of file
diff --git a/src/components/global/GlobalTable.vue b/src/components/global/GlobalTable.vue
new file mode 100644
index 0000000..f74740b
--- /dev/null
+++ b/src/components/global/GlobalTable.vue
@@ -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>
\ No newline at end of file
diff --git a/src/components/global/render.js b/src/components/global/render.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/components/global/render.js
diff --git a/src/components/index.js b/src/components/index.js
index 59cae0f..3101eb5 100644
--- a/src/components/index.js
+++ b/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: 
  * 
diff --git a/src/main.js b/src/main.js
index 689bcb1..441dda3 100644
--- a/src/main.js
+++ b/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'))
\ No newline at end of file
diff --git a/src/styles/base/index.scss b/src/styles/base/index.scss
index 5027faf..119d9d1 100644
--- a/src/styles/base/index.scss
+++ b/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 {
diff --git a/src/styles/element/index.scss b/src/styles/element/index.scss
new file mode 100644
index 0000000..4aa04ef
--- /dev/null
+++ b/src/styles/element/index.scss
@@ -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;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 355b4b0..e4f81d6 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -1,2 +1,3 @@
 @use './base/index.scss'as *;
-@use './page/index.scss'as *;
\ No newline at end of file
+@use './page/index.scss'as *;
+@use './element/index.scss'as *;
\ No newline at end of file
diff --git a/src/views/rs/index.vue b/src/views/rs/index.vue
index f341db6..787a174 100644
--- a/src/views/rs/index.vue
+++ b/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>
\ No newline at end of file
diff --git a/src/views/space/components/box/dataContent.vue b/src/views/space/components/box/dataContent.vue
index e8a71c9..0ef86eb 100644
--- a/src/views/space/components/box/dataContent.vue
+++ b/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>
diff --git a/src/views/space/components/leftContainer.vue b/src/views/space/components/leftContainer.vue
index 8d05e9b..e1d9633 100644
--- a/src/views/space/components/leftContainer.vue
+++ b/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">
diff --git a/src/views/supplies/components/leftContainer.vue b/src/views/supplies/components/leftContainer.vue
index 9aeac42..7542968 100644
--- a/src/views/supplies/components/leftContainer.vue
+++ b/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>
diff --git a/src/views/survey/components/box/fireSource.vue b/src/views/survey/components/box/fireSource.vue
index 6de2786..e3225ee 100644
--- a/src/views/survey/components/box/fireSource.vue
+++ b/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 {

--
Gitblit v1.9.3