Newer
Older
smartwell_front / src / views / mobile / record / search.vue
<!--
  Description: h5-运维记录查询
  Author: 李亚光
  Date: 2025-01-02
 -->
<script lang="ts" setup name="H5OperationRecord">
import dayjs from 'dayjs'
import { showToast } from 'vant'
import { getDictByCode } from '@/api/system/dict'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { getDeptTreeList } from '@/api/system/dept'
import useUserStore from '@/store/modules/user'
import { exportOperationList, getOperationListPage } from '@/api/mobile/record'
import { showLoadingToast, closeToast } from 'vant'
import { exportFile } from '@/utils/exportUtils'
import { keepSearchParams } from '@/utils/keepQuery'
import { debounce } from 'lodash-es'
const list = ref<any>([])
const total = ref(0)
const loading = ref(true)
const userInfo = useUserStore()
const searchQuery = ref({
  repairType: '',
  deviceType: '',
  userId: '',
  timeType: '', // 时间类型  1 近7日 2近30日 3 自定义时间
  beginTime: '',
  endTime: '',
  deptid: '',
  offset: 1,
  limit: 10,
})
const searchQueryForNames = ref({
  repairTypeName: '运维类型',
  deviceTypeName: '设备类型',
  deptName: '',
})
// 运维类型
const showRepairType = ref(false)
const pickerRepairType = ref([])
// 选择运维类型
const selectRepairType = () => {
  showRepairType.value = true
}
// 确认运维类型
const onConfirmRepairType = ({ selectedValues, selectedOptions }: any) => {
  searchQuery.value.repairType = selectedOptions[0]?.value
  searchQueryForNames.value.repairTypeName = selectedOptions[0]?.text === '全部' ? '运维类型' : selectedOptions[0]?.text
  pickerRepairType.value = selectedValues
  showRepairType.value = false
}
// 管理单位
const showDept = ref(false)
const loadingDept = ref(false)
const allDeptList = ref<{ name: string; id: string; pid: string }[]>([]) // 管理单位
const groupDeptList = ref<{ text: string; value: string; pValue: string }[]>([]) // 集团
const unitDeptList = ref<{ text: string; value: string; pValue: string }[]>([]) // 单位
const divisionDeptList = ref<{ text: string; value: string; pValue: string }[]>([]) // 部门
const teamDeptList = ref<{ text: string; value: string; pValue: string }[]>([]) // 班组
const areaDeptList = ref<{ text: string; value: string; pValue: string }[]>([]) // 片区
// 选择管理单位
const selectDept = () => {
  showDept.value = true
}
const deptActiveTab = ref(0)
const deptTabs = ref<string[]>(['集团'])
// 选择集团
const pickerGroupDept = ref<string[]>([])  // 选中的集团
const pickerUnitDept = ref<string[]>([])  // 选中的单位
const pickerDivisionDept = ref<string[]>([])  // 选中的部门
const pickerTeamDept = ref<string[]>([])  // 选中的班组
const pickerAreaDept = ref<string[]>([])  // 选中的片区
// 集团选项变化
const changeGroupDept = ({ selectedValues, selectedOptions }: any) => {
  // 清空 单位 部门 班组
  unitDeptList.value = []
  divisionDeptList.value = []
  teamDeptList.value = []
  areaDeptList.value = []
  pickerUnitDept.value = []
  pickerDivisionDept.value = []
  pickerTeamDept.value = []
  pickerAreaDept.value = []
  if (!selectedOptions[0].text.includes('全部')) {
    // 填充单位
    unitDeptList.value = allDeptList.value.filter(item => item.pid === selectedValues[0]).map((item: { name: string; id: string; pid: string }) => ({ text: item.name, value: item.id, pValue: item.pid }))
    unitDeptList.value.unshift({ text: '全部', value: selectedOptions[0].value, pValue: selectedOptions[0].pValue })
    pickerUnitDept.value = [selectedOptions[0].value as string]
    deptTabs.value = ['集团', '单位']
  }
  else {
    deptTabs.value = ['集团']
  }
}
// 点击集团直接确定选项
const clickGroupDept = ({ selectedValues, selectedOptions }: any) => {
  if (!selectedOptions[0].text.includes('全部')) {
    changeGroupDept({ selectedValues, selectedOptions })
    deptTabs.value = ['集团', '单位']
    setTimeout(() => {
      deptActiveTab.value = 1
    }, 300)
  }
  else {
    deptTabs.value = ['集团']
  }
}
// 单位选项变化
const changeUnitDept = ({ selectedValues, selectedOptions }: any) => {
  // 清空 部门 班组
  divisionDeptList.value = []
  teamDeptList.value = []
  areaDeptList.value = []
  pickerDivisionDept.value = []
  pickerTeamDept.value = []
  pickerAreaDept.value = []
  if (!selectedOptions[0].text.includes('全部')) {
    // 填充 部门
    divisionDeptList.value = allDeptList.value.filter(item => item.pid === selectedValues[0]).map((item: { name: string; id: string; pid: string }) => ({ text: item.name, value: item.id, pValue: item.pid }))
    divisionDeptList.value.unshift({ text: '全部', value: selectedOptions[0].value, pValue: selectedOptions[0].pValue })
    pickerDivisionDept.value = [selectedOptions[0].value as string]
    deptTabs.value = ['集团', '单位', '部门']
  }
  else {
    deptTabs.value = ['集团', '单位']
  }
}
// 点击单位直接确定选项
const clickUnitDept = ({ selectedValues, selectedOptions }: any) => {
  if (selectedOptions[0].text.includes('全部')) {
    deptTabs.value = ['集团', '单位']
    // showDept.value = false
    // 确定
    // searchQuery.value.deptid = selectedOptions[0].value
    // searchQueryForNames.value.deptName = allDeptList.value.filter(item => item.id === selectedOptions[0].value)[0].name
  }
  else {
    changeUnitDept({ selectedValues, selectedOptions })
    deptTabs.value = ['集团', '单位', '部门']
    setTimeout(() => {
      deptActiveTab.value = 2
    }, 300)
  }
}
// 部门选项变化
const changeDivisionDept = ({ selectedValues, selectedOptions }: any) => {
  // 清空 班组
  teamDeptList.value = []
  areaDeptList.value = []
  pickerTeamDept.value = []
  pickerAreaDept.value = []
  if (!selectedOptions[0].text.includes('全部')) {
    // 填充 班组
    teamDeptList.value = allDeptList.value.filter(item => item.pid === selectedValues[0]).map((item: { name: string; id: string; pid: string }) => ({ text: item.name, value: item.id, pValue: item.pid }))
    teamDeptList.value.unshift({ text: '全部', value: selectedOptions[0].value, pValue: selectedOptions[0].pValue })
    pickerTeamDept.value = [selectedOptions[0].value as string]
    deptTabs.value = ['集团', '单位', '部门', '班组']
  }
  else {
    deptTabs.value = ['集团', '单位', '部门']
  }
}
// 点击部门直接确定选项
const clickDivisionDept = ({ selectedValues, selectedOptions }: any) => {
  if (selectedOptions[0].text.includes('全部')) {
    deptTabs.value = ['集团', '单位', '部门']
  }
  else {
    changeDivisionDept({ selectedValues, selectedOptions })
    deptTabs.value = ['集团', '单位', '部门', '班组']
    setTimeout(() => {
      deptActiveTab.value = 3
    }, 300)
  }
}
// 班组选项变化
const changeTeamDept = ({ selectedValues, selectedOptions }: any) => {
  areaDeptList.value = []
  pickerAreaDept.value = []
  if (!selectedOptions[0].text.includes('全部')) {
    // 填充 片区
    areaDeptList.value = allDeptList.value.filter(item => item.pid === selectedValues[0]).map((item: { name: string; id: string; pid: string }) => ({ text: item.name, value: item.id, pValue: item.pid }))
    areaDeptList.value.unshift({ text: '全部', value: selectedOptions[0].value, pValue: selectedOptions[0].pValue })
    pickerAreaDept.value = [selectedOptions[0].value as string]
    deptTabs.value = ['集团', '单位', '部门', '班组', '片区']
  }
  else {
    deptTabs.value = ['集团', '单位', '部门', '班组']
  }
}
// 点击班组
const clickTeamDept = ({ selectedValues, selectedOptions }: any) => {
  if (selectedOptions[0].text.includes('全部')) {
    deptTabs.value = ['集团', '单位', '部门', '班组']
  }
  else {
    changeTeamDept({ selectedValues, selectedOptions })
    deptTabs.value = ['集团', '单位', '部门', '班组', '片区']
    setTimeout(() => {
      deptActiveTab.value = 4
    }, 300)
  }
}
// 确认管理单位
const onConfirmDept = (data: any[]) => {
  const dict = {
    0: pickerGroupDept,
    1: pickerUnitDept,
    2: pickerDivisionDept,
    3: pickerTeamDept,
    4: pickerAreaDept
  } as { [key: string]: any }
  data.forEach((item: any, index: number) => {
    dict[index].value = item.selectedValues
  })
  searchQuery.value.deptid = data[deptTabs.value.length - 1].selectedValues
  if (!searchQuery.value.deptid[0]) {
    searchQueryForNames.value.deptName = ''
    showDept.value = false
    return
  }
  searchQueryForNames.value.deptName = allDeptList.value.filter(item => item.id === data[deptTabs.value.length - 1].selectedValues[0])[0].name
  showDept.value = false
}
// 设备类型
const showDeviceType = ref(false)
const pickerDeviceType = ref([])
// 选择设备类型
const selectDeviceType = () => {
  showDeviceType.value = true
}
// 确认设备类型
const onConfirmDeviceType = ({ selectedValues, selectedOptions }: any) => {
  searchQuery.value.deviceType = selectedOptions[0]?.value
  searchQueryForNames.value.deviceTypeName = selectedOptions[0]?.text === '全部' ? '设备类型' : selectedOptions[0]?.text
  pickerDeviceType.value = selectedValues
  showDeviceType.value = false
}
// 按钮类选择
const searchBtn = (type: string) => {
  // 仅看本人
  if (type === 'self') {
    searchQuery.value.userId = searchQuery.value.userId ? '' : userInfo.id
  }
  //  近7日
  else if (type === 'week') {
    if (searchQuery.value.timeType === '1') {
      searchQuery.value.timeType = ''
      searchQuery.value.beginTime = ''
      searchQuery.value.endTime = ''
    }
    else {
      searchQuery.value.timeType = '1'
      searchQuery.value.beginTime = dayjs().subtract(7, 'day').format('YYYY-MM-DD')
      searchQuery.value.endTime = dayjs().format('YYYY-MM-DD')
    }
  }
  //  近30日
  else if (type === 'month') {
    if (searchQuery.value.timeType === '2') {
      searchQuery.value.timeType = ''
      searchQuery.value.beginTime = ''
      searchQuery.value.endTime = ''
    }
    else {
      searchQuery.value.timeType = '2'
      searchQuery.value.beginTime = dayjs().subtract(1, 'month').format('YYYY-MM-DD')
      searchQuery.value.endTime = dayjs().format('YYYY-MM-DD')
    }
  }
}
// 自定义日期
const showDate = ref(false)
// 默认开始日期
const startDate = ref<string[]>([])
// 默认结束日期
const endDate = ref<string[]>([])
startDate.value = dayjs().subtract(1, 'month').format('YYYY-MM-DD').split('-')
endDate.value = dayjs().format('YYYY-MM-DD').split('-')
// 结束日期的最大日期限制
// const endMaxDate = ref(new Date(2025, 5, 1))
// 选择日期
const selectDate = () => {
  showDate.value = true
}
// 确认日期选择
const onConfirmDate = () => {
  // 先判断结束日期是否在开始日期之前
  if (new Date(endDate.value.join('-')).getTime() - new Date(startDate.value.join('-')).getTime() < 0) {
    showToast('请选择正确时间范围');
    return
  }
  searchQuery.value.timeType = '3'
  searchQuery.value.beginTime = startDate.value.join('-')
  searchQuery.value.endTime = endDate.value.join('-')
  showDate.value = false
}
// 取消日期选择
const onCancelDate = () => {
  showDate.value = false
}
// 清空自定义日期
const cancelDate = () => {
  searchQuery.value.timeType = ''
  searchQuery.value.beginTime = ''
  searchQuery.value.endTime = ''
}
const repairTypeList = ref<{ text: string; value: string }[]>([]) // 运维类型
const deviceTypeList = ref<{ text: string; value: string }[]>([]) // 设备类型

// 获取字典
const fetchDict = async () => {
  // 运维类型
  getDictByCode('repairType').then(res => {
    repairTypeList.value = res.data.map((item: { id: string; name: string; value: string }) => ({ text: item.name, value: item.value }))
    repairTypeList.value.unshift({ text: '全部', value: '' })
  })
  // 设备类型
  getDeviceTypeListPage({ offset: 1, limit: 9999 }).then(res => {
    deviceTypeList.value = res.data.rows.map((item: any) => ({ text: item.typeName, value: item.id }))
    deviceTypeList.value.unshift({ text: '全部', value: '' })
  })
  // 获取管理单位
  loadingDept.value = true
  getDeptTreeList().then(res => {
    allDeptList.value = res.data
    groupDeptList.value = res.data.filter((item: { name: string; id: string; pid: string }) => item.pid === '0').map((item: { name: string; id: string; pid: string }) => ({
      text: item.name, value: item.id, pValue: item.pid
    }))
    groupDeptList.value.unshift({ text: '全部', value: '', pValue: '' })
    loadingDept.value = false
  }).catch(() => {
    loadingDept.value = false
  })
}
fetchDict()
// 计算滚动区域高度
const scrollHeight = ref(0)
const calcHeight = () => {
  // 公共头部高度40
  // 边距安全 30
  // 导出按钮
  const exportBtnHeight = document.getElementById('export-btn-log')?.offsetHeight || 0
  // 查询头部
  const searchHeaderHeight = document.getElementById('search-area-log')?.offsetHeight || 0
  scrollHeight.value = window.innerHeight - 40 - exportBtnHeight - searchHeaderHeight - 30
}
const search = ref({})  // 查询条件 给导出使用
const fetchData = () => {
  const obj = {
    deviceType: searchQuery.value.deviceType,
    offset: searchQuery.value.offset,
    limit: 10,
    repairType: searchQuery.value.repairType,
    deptid: searchQuery.value.deptid ? searchQuery.value.deptid[0] : '',
    repairPerson: searchQuery.value.userId ? userInfo.name : '',
    begTime: searchQuery.value.beginTime,
    endTime: searchQuery.value.endTime,
  }
  search.value = obj
  getOperationListPage(obj).then(res => {
    total.value = res.data.total
    list.value = [...list.value, ...(res.data.rows || [])]
    list.value = list.value.map((item: any) => ({ ...item, repairTime: item.repairTime ? dayjs().format('YYYY-MM-DD') : '' }))
    loading.value = false
  })
}
watch([() => searchQuery.value.beginTime, () => searchQuery.value.deptid, () => searchQuery.value.deviceType, () => searchQuery.value.endTime,
() => searchQuery.value.repairType, () => searchQuery.value.timeType, () => searchQuery.value.userId
], () => {
  list.value = []
  searchQuery.value.offset = 1
  loading.value = true
  fetchData()
}, {
  deep: true,
})
onMounted(() => {
  calcHeight()
  loading.value = true
  fetchData()
})
window.addEventListener('resize', () => {
  calcHeight()
})
onBeforeUnmount(() => {
  window.addEventListener('resize', () => { })
})
// 查看详情
const $router = useRouter()
const detail = (event: any, row: any) => {
  if (event.target.innerHTML === ('收起') || event.target.innerHTML === ('展开')) {
    return
  }
  $router.push({
    name: 'RecordDetail',
    query: {
      row: JSON.stringify(row)
    }
  })
}
// 导出运维记录
const exportLog = () => {
  const toast = showLoadingToast({
    duration: 0,
    forbidClick: true,
    message: '加载中...',
  })
  exportOperationList(search.value).then(res => {
    exportFile(res.data, '运维记录')
    closeToast()
  })
}
// 页面缓存
onBeforeRouteLeave((to: any) => {
  keepSearchParams(to.path, 'H5OperationRecord')
})
onActivated(() => {
  if (!($router.options.history.state.forward as string || '').includes('detail')) {
    fetchData()
  }
})
// 滚动条
const scrollbarRef = ref()
const handleScroll = (a) => {
  // 判断滚动条是否滚动到底部
  const scrollbarContainer = scrollbarRef.value.$el.querySelector('.el-scrollbar__wrap')
  const isScrolledToBottom = scrollbarContainer.scrollHeight - scrollbarContainer.scrollTop <= scrollbarContainer.clientHeight + 50
  if (isScrolledToBottom) {
    if (list.value.length === total.value) {
      return
    }
    // debounce(() => {
    loading.value = true
    searchQuery.value.offset += 1
    fetchData()
    // }, 200)

  }
}
</script>

<template>
  <div style="position: relative;">
    <!-- 查询条件 -->
    <div id="search-area-log" class="search-area">
      <!-- 运维类型选择 -->
      <van-popup v-model:show="showRepairType" destroy-on-close position="bottom">
        <van-picker :columns="repairTypeList" :model-value="pickerRepairType" @confirm="onConfirmRepairType"
          @cancel="showRepairType = false" />
      </van-popup>
      <!-- 管理单位 -->
      <van-popup v-model:show="showDept" destroy-on-close position="bottom">
        <!-- 树形选择 -->
        <!-- , '班组' -->
        <van-picker-group v-model:active-tab="deptActiveTab" title="管理单位" :tabs="deptTabs" @confirm="onConfirmDept"
          @cancel="showDept = false">
          <!-- 集团 -->
          <van-picker v-show="deptTabs.includes('集团')" :loading="loadingDept" :swipe-duration="500"
            :columns="groupDeptList" :model-value="pickerGroupDept" @change="changeGroupDept"
            @click-option="clickGroupDept" />
          <!-- 单位 -->
          <van-picker v-show="deptTabs.includes('单位')" :swipe-duration="500" :columns="unitDeptList"
            :model-value="pickerUnitDept" @change="changeUnitDept" @click-option="clickUnitDept" />
          <!-- 部门 -->
          <van-picker v-show="deptTabs.includes('部门')" :swipe-duration="500" :columns="divisionDeptList"
            :model-value="pickerDivisionDept" @change="changeDivisionDept" @click-option="clickDivisionDept" />
          <!-- 班组 -->
          <van-picker v-show="deptTabs.includes('班组')" :swipe-duration="500" :columns="teamDeptList"
            :model-value="pickerTeamDept" @change="changeTeamDept" @click-option="clickTeamDept" />
          <!-- 片区 -->
          <van-picker v-show="deptTabs.includes('片区')" :swipe-duration="500" :columns="areaDeptList"
            :model-value="pickerAreaDept" />
        </van-picker-group>
      </van-popup>
      <!-- 设备类型选择 -->
      <van-popup v-model:show="showDeviceType" destroy-on-close position="bottom">
        <van-picker :columns="deviceTypeList" :model-value="pickerDeviceType" @confirm="onConfirmDeviceType"
          @cancel="showDeviceType = false" />
      </van-popup>
      <!-- 开始结束日期 -->
      <van-popup v-model:show="showDate" destroy-on-close position="bottom">
        <van-picker-group title="预约日期" :tabs="['开始日期', '结束日期']" @confirm="onConfirmDate" @cancel="onCancelDate">
          <van-date-picker v-model="startDate" />
          <van-date-picker v-model="endDate" />
        </van-picker-group>
      </van-popup>
      <div class="search-container-top">
        <div class="search-item" @click="selectRepairType">
          <span class="value" :class="searchQueryForNames.repairTypeName === '运维类型' ? '' : 'active'">{{
            searchQueryForNames.repairTypeName }}</span>
          <van-icon name="arrow-down" class="icon" />
        </div>

        <div class="search-item" @click="selectDept">
          <span class="value" :class="searchQueryForNames.deptName === '' ? '' : 'active'">
            {{ searchQueryForNames.deptName === '' ? '管理单位' : searchQueryForNames.deptName }}
          </span>
          <van-icon name="arrow-down" class="icon" />
        </div>
        <div class="search-item" @click="selectDeviceType">
          <span class="value" :class="searchQueryForNames.deviceTypeName === '设备类型' ? '' : 'active'">{{
            searchQueryForNames.deviceTypeName }}</span>
          <van-icon name="arrow-down" class="icon" />
        </div>

        <div class="search-btn" @click="searchBtn('self')" :class="searchQuery.userId ? 'active-btn' : ''">
          仅看本人
        </div>
      </div>
      <div class="search-container-bottom">
        <div class="search-btn" @click="searchBtn('week')" :class="searchQuery.timeType === '1' ? 'active-btn' : ''">
          近7日
        </div>
        <div class="search-btn" @click="searchBtn('month')" :class="searchQuery.timeType === '2' ? 'active-btn' : ''">
          近30日
        </div>
        <div class="date" :class="searchQuery.timeType === '3' ? 'active-btn' : ''">
          <span @click="selectDate" style="text-align: center;flex: 1;">
            <!-- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> -->
            {{ searchQuery.timeType === '3' ? searchQuery.beginTime : '开始时间' }}
          </span>
          <span @click="selectDate">至</span>
          <!-- <span> -->
          <span @click="selectDate" style="text-align: center;flex: 1;">{{ searchQuery.timeType === '3' ?
            searchQuery.endTime : '结束时间' }}</span>
          <!-- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> -->
          <!-- </span> -->
          <van-icon v-if="searchQuery.timeType === '3'" class="icon" name="close" size="1.2rem" @click="cancelDate" />
        </div>
      </div>
    </div>
    <!-- 查询结果 -->
    <div v-loading="loading" class="search-result">
      <el-scrollbar ref="scrollbarRef" :max-height="`${scrollHeight}px`" @scroll="handleScroll">
        <lazy-component v-if="list.length">
          <div v-for="(item, index) in list" :key="index" class="result-item" :class="index !== 0 ? 'top-border' : ''"
            @click="(event) => detail(event, item)">
            <div class="devcode"> {{ item.devcode }}</div>
            <div class="cell">
              <div class="title">设备类型</div>
              <div class="value">
                <van-text-ellipsis :rows="1" :content="item.deviceTypeName" expand-text="展开" collapse-text="收起" />
              </div>
            </div>
            <div class="cell">
              <div class="title">运维类型</div>
              <div class="value">
                <van-text-ellipsis :rows="1" :content="item.repairType" expand-text="展开" collapse-text="收起" />
              </div>
            </div>
            <div class="cell">
              <div class="title">安装位置</div>
              <div class="value">{{ item.ledgerNumber }}</div>
            </div>
            <div class="cell">
              <div class="title">管理单位</div>
              <div class="value">
                <van-text-ellipsis :rows="1" :content="item.deptName" expand-text="展开" collapse-text="收起" />
              </div>
            </div>
            <div class="cell">
              <div class="title">运维时间</div>
              <div class="value">{{ item.repairTime }}</div>
            </div>
          </div>
        </lazy-component>
        <div class="to-top">
          <van-back-top />
        </div>
        <van-empty v-if="!list.length" description="暂无数据" />
      </el-scrollbar>

    </div>
    <!-- 导出按钮 -->
    <div id="export-btn-log" class="export-btn">
      <el-button type="primary" style="width: 96%;" @click="exportLog">导出运维记录</el-button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.to-top {
  ::v-deep(.van-back-top) {
    opacity: 0.4 !important;
  }
}

$primary: #0D76D4;
$--van-primary-color: #0D76D4;

::v-deep(.van-picker-column__item--selected) {
  color: $primary !important;
}

.active {
  color: $primary !important;
}

.active-btn {
  color: $primary !important;
  border: 1px solid $primary !important;
}

.search-area {
  background-color: #fff;
  margin: 6px;
  font-size: 1rem;
  border-radius: 8px;
  font-weight: 400;
}

.search-container-top {
  width: 100%;
  display: flex;
  padding: 6px;
  // padding-left: 0;
  // padding-right: 0;
  justify-content: space-around;
  color: #555;

  .search-item {
    width: 26%;
    text-align: center;
    padding: 4px;
    display: flex;
    // justify-content: space-between;
    align-items: center;
    vertical-align: middle;

    .value {
      width: 100%;

      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .icon {
      // display: inline-block;
      // width: 20px;
      // height: 20px;
      vertical-align: middle;
      margin-left: 6px;
      // background: url('@/assets/icons/search-down.svg') no-repeat center center / cover;
    }
  }

  .search-btn {
    width: 20%;
    padding: 4px;
    text-align: center;
    background-color: #fff;
    border-radius: 16px;
    border: 1px solid #e4e7ed;
    white-space: nowrap;
    /* 确保文本在一行内显示 */
    overflow: hidden;

    /* 超出容器部分隐藏 */
    text-overflow: ellipsis;

    /* 文字溢出显示省略号 */

  }
}

.search-container-bottom {
  width: 100%;
  display: flex;
  padding: 6px;
  // padding-left: 0;
  // padding-right: 0;
  padding-top: 0;
  color: #555;
  justify-content: space-around;

  .search-btn {
    width: 18%;
    padding: 4px;
    text-align: center;
    background-color: #fff;
    border-radius: 16px;
    border: 1px solid #e4e7ed;
  }

  .date {
    width: 62%;
    background-color: #fff;
    border-radius: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 5px;
    border: 1px solid #e4e7ed;

    vertical-align: middle;

    .icon {
      vertical-align: middle;
    }
  }
}

.search-result {
  background-color: #fff;
  margin: 6px;
  font-size: 0.8rem;
  border-radius: 8px;
  color: #444;
  padding: 14px;
  padding-bottom: 0px;

  // height: 600px;
  .top-border {
    border-top: 1px solid #e4e7ed;
    // margin-top: 8px;
  }

  .result-item {
    padding: 4px;

    // box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, .04), 0px 8px 20px rgba(0, 0, 0, .08);
    .devcode {
      font-weight: 700;
      font-size: 1.1rem;
    }

    .cell {
      display: flex;
      justify-content: space-between;
      padding-top: 6px;
      padding-bottom: 6px;
      padding-right: 14px;

      .value {
        color: #888;
        width: 80%;
        text-align: right;
        font-size: 1rem;
      }

      .title {
        width: 20%;
        white-space: nowrap;
        font-weight: 500;
        font-size: 1rem;
      }

      .title,
      .value {
        white-space: nowrap;
        // overflow: hidden;
        // text-overflow: ellipsis;
      }
    }


  }
}

.export-btn {
  width: 100%;
  position: fixed;
  bottom: 0;
  display: flex;
  justify-content: center;

  ::v-deep(.el-button) {
    font-size: 18px;
  }
}
</style>