Newer
Older
smartwell_front / src / views / mobile / device / add.vue
liyaguang on 9 Jan 9 KB ‘设备运维’
<!--
  Description: h5-新装设备
  Author: 李亚光
  Date: 2024-12-27
 -->
<script lang="ts" setup name="H5DeviceAdd">
import dayjs from 'dayjs'
import { Toast, showImagePreview } from 'vant'
import { getProductListPage } from '@/api/home/device/product'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { showToast, showLoadingToast, closeToast, showConfirmDialog } from 'vant'
import { getWellListPage } from '@/api/home/well/well'
import { getStationListPage } from '@/api/home/station/station'
const deciceInfo = ref({
  productId: '',
  productName: '',
  devcode: '',
  tagNumber: '',
  watchObject: '',
  installDate: '',
  photo: []
})

// 产品相关
const showProduct = ref(false)
const productValue = ref([])
const productColumns = ref([])
const onConfirm = ({ selectedValues, selectedOptions }) => {
  deciceInfo.value.productId = selectedOptions[0]?.value
  deciceInfo.value.productName = selectedOptions[0]?.text
  productValue.value = selectedValues
  showProduct.value = false
}
// 安装位置 -- 闸井/场站
const searchForWell = ref(false)
const searchForInput = ref('')
const resultForWell = ref(false)
// 搜索安装位置
const searchTagNumber = (action: string) => {
  if (!action) {
    return true
  }
  showLoadingToast({
    duration: 0,
    message: '加载中...',
    forbidClick: true,
    loadingType: 'spinner',
  });
  // 搜索场站或闸井
  (deciceInfo.value.watchObject === '1' ? getWellListPage : getStationListPage)({ offset: 1, limit: 1, tagNumber: searchForInput.value }).then(res => {
    closeToast()
    searchForWell.value = false
    let message = ''
    if (!res.data.rows.length) {
      message = `未找到位号为 ${searchForInput.value} ${deciceInfo.value.watchObject === '1' ? '闸井' : '场站'} ,请确认位号后重新搜索`
    }
    else {
      // 判断位置
      // 存在同类设备
      // 正常
    }
    // 展示查询结果
    showConfirmDialog({
      title: '搜索位置',
      message: '123123123232121'
    })
      .then(() => {

      })
      .catch(() => {

      })
  })

}
// 选择安装位置
const selectTagNumber = () => {
  if (!deciceInfo.value.productId) {
    showToast('请先选择产品')
    return
  }
  //1闸井 2场站 3管线
  if (deciceInfo.value.watchObject == '1' || deciceInfo.value.watchObject == '2') {
    searchForWell.value = true
    searchForInput.value = ''
  }
  // else {

  // }
}
// const

// 安装日期
const showDatePicker = ref(false)
const pickerValueInstallDate = ref<string[]>([])
// 默认日期
pickerValueInstallDate.value = dayjs().format('YYYY-MM-DD').split('-')
deciceInfo.value.installDate = pickerValueInstallDate.value.join('-')
const onConfirmInstallDate = ({ selectedValues }) => {
  deciceInfo.value.installDate = selectedValues.join('-')
  pickerValueInstallDate.value = selectedValues
  showDatePicker.value = false
}
// 现场照片
// const showCamera = ref(false)
// 拍照
const takePictures = () => {
  if(deciceInfo.value.photo.length >= 3) {
    showToast('最多上传三张照片')
    return
  }
  // 调用摄像头
  const camera = document.getElementById('camera-photo')
  camera?.click()
}
const fileRef = ref() // 文件上传input,获取input的引用
const onFileChange = (event: any) => {
  // 原生上传
  if (event.target.files?.length !== 0) {
    const file = event.target.files[0]
    const reader = new FileReader() // 实例化FileReader
    reader.readAsDataURL(file)
    // 读取成功以后执行的方法
    reader.onload = (e) => {
      deciceInfo.value.photo.push(e.target.result)
      // let img = new Image()
      // // base64
      // img.src = e.target.result
      // console.log(img.src, 'img.src')
      // img.onload = () => {
      //   imagetoCanvas(img) //Image 对象转变为一个 Canvas 类型对象,i为遍历的下标
      // }
    }
  }
}
// 删除图片
const deletePhoto = (index: number) => {
  deciceInfo.value.photo.splice(index, 1)
}
// 预览图片
const previewPhoto = (index: number) => {
  showImagePreview({
    images: deciceInfo.value.photo,
    startPosition: index
  })
}
// 关闭摄像头
// const closeCamera = () => {
//   showCamera.value = false
// }
// 获取字典
const deviceTypeList = ref<any[]>([]) // 设备类型列表
const fetchDict = () => {
  getProductListPage({ offset: 1, limit: 9999 }).then(res => {
    console.log(res.data.rows, '产品列表')
    productColumns.value = res.data.rows.map((item: any) => ({
      text: `${item.productName}-${item.productCode}`,
      value: item.id,
      deviceType: item.deviceType,
    }))
  })
  getDeviceTypeListPage({ limit: 9999, offset: 1 }).then((res) => {
    deviceTypeList.value = res.data.rows
  })
}
fetchDict()
// 监听产品变化,判断该设备的 监测对象
watch(() => deciceInfo.value.productId, (newVal) => {
  if (newVal) {
    const select = productColumns.value.filter((item: any) => item.value === newVal) as any
    const watchObject = deviceTypeList.value.filter((item: any) => item.id === select[0].deviceType)
    deciceInfo.value.watchObject = watchObject[0].watchObject

  }
  else {
    deciceInfo.value.tagNumber = ''
    deciceInfo.value.watchObject = ''
  }
})
const empty = ref('')
</script>

<template>
  <div class="device-container">
    <!-- 设备信息 -->
    <div class="device-info">
      <span class="title">设备信息</span>
      <van-form>
        <van-cell-group>
          <!-- 产品 -->
          <van-field v-model="deciceInfo.productName" is-link readonly label="产品" name="productId" placeholder="选择产品"
            required @click="showProduct = true" input-align="right">
          </van-field>
          <van-popup v-model:show="showProduct" destroy-on-close position="bottom">
            <van-picker :columns="productColumns" title="产品" :model-value="productValue" @confirm="onConfirm"
              @cancel="showProduct = false" />
          </van-popup>
          <!-- 设备编号 -->
          <van-field v-model="deciceInfo.devcode" label="设备编号" name="devcode" placeholder="输入设备编号" required input-align="right" />
          <!-- 安装位置 -->
          <van-field v-model="deciceInfo.tagNumber" is-link readonly label="安装位置" name="tagNumber" placeholder="去搜索"
            required @click="selectTagNumber" input-align="right" />
          <!-- 安装位置  闸井/场站查询-->
          <van-dialog v-model:show="searchForWell" title="搜索位置" confirm-button-text="搜索" :closeOnClickOverlay="true"
            :before-close="searchTagNumber">
            <van-field v-model="searchForInput" placeholder="请输入安装位号" />
          </van-dialog>
          <!-- 安装日期 -->
          <van-field v-model="deciceInfo.installDate" is-link readonly name="installDate" label="安装日期"
            placeholder="点击选择时间" @click="showDatePicker = true" required input-align="right" />
          <van-popup v-model:show="showDatePicker" destroy-on-close position="bottom">
            <van-date-picker :model-value="pickerValueInstallDate" @confirm="onConfirmInstallDate"
              @cancel="showDatePicker = false" />
          </van-popup>
          <!-- 现场照片 -->
          <van-field v-model="empty" readonly name="photo" label="现场照片" required input-align="center">
            <template #input>
              <!-- 展示照片 -->
              <div v-for="(item, index) in deciceInfo.photo" :key="index" class="show-photo">
                <div class="del_d">
                  <div class="del" @click="deletePhoto(index)"></div>
                </div>
                <img :src="item" alt="" srcset="" width="30px" height="30px" @click="previewPhoto(index)">
              </div>
            </template>
            <template #right-icon>
              <div class="camera" @click="takePictures" />
            </template>
          </van-field>

          <!-- 照相组件 -->
          <input ref="fileRef" style="display: none;opacity: 0;" multiple id="camera-photo" type="file" accept="image/*"
            @change="onFileChange">
        </van-cell-group>
      </van-form>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.show-photo{
  position: relative;
  margin-left: 10px;
}
.del_d {
  position: absolute;
  width: 16px;
  height: 16px;
  background: red;
  border-radius: 50%;
  top: -10px;
  right: -10px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;

  .del {
    width: 10px;
    height: 3px;
    background: white;
  }
}

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

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

.device-container {
  width: 100%;
  height: calc(100vh - 40px);
  overflow: hidden;

  .device-info {
    background-color: #fff;
    width: 96%;
    margin: 0 auto;
    margin-top: 1vh;
    border-radius: 6px;
    padding: 4px;

    .title {
      font-weight: 700;
      font-size: 1.2rem;
      padding-left: 0.5rem;
      margin-top: 0.5rem;
    }

    ::v-deep(.van-cell__title) {
      font-weight: 700;
      font-size: 1rem;
    }
    ::v-deep(.van-cell__value) {
      // font-weight: 700;
      font-size: 1rem;
    }
  }
}

.camera {
  width: 24px;
  height: 24px;
  background: url('@/assets/icons/icon-camera.svg') no-repeat center center / cover;
}
</style>