Newer
Older
smartwell_front / src / views / mobile / record / search.vue
liyaguang on 3 Jan 14 KB 信息查询/运维记录
<!--
  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 useUserStore from '@/store/modules/user'
const list = ref([
  {
    devcode: '24102708',
    devTypeName: '燃气智能监测终端',
    repairType: '新装',
    tagNumber: 'N57C114',
    position: '示范区联络线中压A闸9',
    address: '百环花园调压站南侧',
    repairDate: '2024-11-30',
    deptName: '第一分公司/运维一所'
  },
  {
    devcode: '322024010010',
    devTypeName: '燃气智能监测终端(一体化)',
    tagNumber: 'cprl001',
    position: '92301部队中压A闸1',
    address: '西环里35号院2号楼南',
    repairDate: '2024-01-30',
    deptName: '第一分公司/运维一所',
    repairType: '新装',
  },
  {
    devcode: '341524019XX1',
    devTypeName: '管网哨兵',
    tagNumber: 'GX_33101',
    position: '北新中压A闸6',
    address: '北京市海淀区街道1',
    repairDate: '2024-11-18',
    deptName: '第一分公司/运维一所',
    repairType: '新装',
  },
  {
    devcode: '211424152117',
    devTypeName: '智能警示桩',
    tagNumber: 'NCX_0001',
    position: '东辰小区中压A闸1',
    address: '北京市西城区复外大街与三里河路交叉口(地铁1号线地铁站木樨地站北侧)三里河3区',
    repairDate: '2024-11-26',
    deptName: '第一分公司/运维一所',
    repairType: '新装',
  },
  {
    devcode: 'YT20240913',
    devTypeName: '场站监测云台',
    tagNumber: 'N53A888',
    position: '定辛庄小学中压A闸1T',
    address: '眼镜城',
    repairDate: '2024-09-13',
    deptName: '第一分公司/运维一所',
    repairType: '新装',
  },
])
const userInfo = useUserStore()
const searchQuery = ref({
  repairType: '',
  deviceType: '',
  userId: '',
  timeType: '', // 时间类型  1 近7日 2近30日 3 自定义时间
  beginTime: '',
  endTime: '',
})
const searchQueryForNames = ref({
  repairTypeName: '运维类型',
  deviceTypeName: '设备类型',
})
// 运维类型
const showRepairType = ref(false)
const pickerRepairType = ref([])
// 选择运维类型
const selectRepairType = () => {
  showRepairType.value = true
}
// 确认运维类型
const onConfirmRepairType = ({ selectedValues, selectedOptions }) => {
  searchQuery.value.repairType = selectedOptions[0]?.value
  searchQueryForNames.value.repairTypeName = selectedOptions[0]?.text === '全部' ? '运维类型' : selectedOptions[0]?.text
  pickerRepairType.value = selectedValues
  showRepairType.value = false
}
// 设备类型
const showDeviceType = ref(false)
const pickerDeviceType = ref([])
// 选择设备类型
const selectDeviceType = () => {
  showDeviceType.value = true
}
// 确认设备类型
const onConfirmDeviceType = ({ selectedValues, selectedOptions }) => {
  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
  }
  // console.log('确认日期')
  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: '' })
  })
}
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
}
onMounted(() => {
  calcHeight()
})
window.addEventListener('resize', () => {
  calcHeight()
})
// 查看详情
const $router = useRouter()
const detail = (row: any) => {
  $router.push({
    name: 'RecordDetail'
  })
}
</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="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">
          <span class="value">管理单位</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">
            <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
            {{ searchQuery.timeType === '3' ? searchQuery.beginTime : '开始时间' }}
          </span>
          <span @click="selectDate">至</span>
          <span>
            <span @click="selectDate">{{ 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 class="search-result">
      <el-scrollbar :max-height="`${scrollHeight}px`">
        <lazy-component>
          <div v-for="(item, index) in list" :key="index" class="result-item" :class="index !== 0 ? 'top-border' : ''"
            @click="detail(item)">
            <div class="devcode"> {{ item.devcode }}</div>
            <div class="cell">
              <div class="title">设备类型</div>
              <div class="value">
                <van-text-ellipsis :rows="1" :content="item.devTypeName" 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.tagNumber }}</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.repairDate }}</div>
            </div>
          </div>
        </lazy-component>
        <!-- <div class="to-top">
          <van-back-top />
        </div> -->
      </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: 0.8rem;
  border-radius: 8px;
}

.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;
  }
}

.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:bottom;
    .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.3rem;
    }

    .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: 1.05rem;
      }

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

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


  }
}

.export-btn {
  width: 100%;
  position: fixed;
  bottom: 0;
  display: flex;
  justify-content: center;
}
</style>