Newer
Older
smartwell_front / src / views / mobile / operation / index.vue
liyaguang on 9 Jan 9 KB ‘设备运维’
<!--
  Description: 设备运维
  Author: 李亚光
  Date: 2024-01-03
 -->
<script lang="ts" setup name="H5DeviceOperation">
import dayjs from 'dayjs'
import { showToast, showImagePreview } from 'vant'
import { getDictByCode } from '@/api/system/dict'
import { getDeviceListPage } from '@/api/home/device/device'
import useUserStore from '@/store/modules/user'
const $router = useRouter()
const userInfo = useUserStore()
const baseInfo = ref({
  repairType: '',
  repairTypeName: '',
  devcode: '',
  tagNumber: '',
  position: '',
  repairDate: '',
  repairPerson: '',
  repairContent: '',
  photo: []
})
baseInfo.value.repairPerson = userInfo.name
const disabledPosition = ref(true) // 是否禁用安装位置
const isRequiredPhoto = ref(true) // 是否必传照片
watch(() => baseInfo.value.repairTypeName, (newVal) => {
  disabledPosition.value = true
  isRequiredPhoto.value = true
  // 设备回装支持更改安装位置
  // 拆下返厂可不传现场照片
  if (newVal) {
    if (newVal.includes('回装')) {
      disabledPosition.value = false
    }
    else if (newVal.includes('返厂')) {
      isRequiredPhoto.value = false
    }
  }
}, {
  deep: true
})
// 运维类型
const showRepairType = ref(false)
const repairTypeValue = ref([])
const onConfirmRepairType = ({ selectedValues, selectedOptions }) => {
  baseInfo.value.repairType = selectedOptions[0]?.value
  baseInfo.value.repairTypeName = selectedOptions[0]?.text
  repairTypeValue.value = selectedValues
  showRepairType.value = false
}
// 根据设备编号查询设备信息
const searchDeviceInfo = () => {
  if (!baseInfo.value.devcode) {
    return
  }
  getDeviceListPage({ offset: 1, limit: 1, devCode: baseInfo.value.devcode }).then(res => {
    if (res.data.rows.length && res.data.rows[0]?.devcode === baseInfo.value.devcode) {
      baseInfo.value.tagNumber = res.data.rows[0].tagNumber
      baseInfo.value.position = res.data.rows[0].position
    }
    else {
      baseInfo.value.tagNumber = ''
      baseInfo.value.position = ''
      showToast('未查询到设备信息,请检查设备编号是否正确')
    }
  })
}

// 运维日期
const showDatePicker = ref(false)
const pickerValueRepairDate = ref<string[]>([])
pickerValueRepairDate.value = dayjs().format('YYYY-MM-DD').split('-')
baseInfo.value.repairDate = pickerValueRepairDate.value.join('-')
const onConfirmRepairDate = ({ selectedValues }) => {
  baseInfo.value.repairDate = selectedValues.join('-')
  pickerValueRepairDate.value = selectedValues
  showDatePicker.value = false
}

// 现场照片
// const showCamera = ref(false)
// 拍照
const takePictures = () => {
  if (baseInfo.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) => {
      baseInfo.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) => {
  baseInfo.value.photo.splice(index, 1)
}
// 预览图片
const previewPhoto = (index: number) => {
  showImagePreview({
    images: baseInfo.value.photo,
    startPosition: index
  })
}

// 获取字典
const repairTypeColumns = ref<{ text: string; value: string }[]>([]) // 运维类型
const fetchDict = () => {
  getDictByCode('repairType').then(res => {
    repairTypeColumns.value = res.data.filter((item: { id: string; name: string; value: string }) => !item.name.includes('新装')).map((item: { id: string; name: string; value: string }) => ({ text: item.name, value: item.value }))
  })
}
fetchDict()

// 查看设备数据
const deviceData = () => {
  if (!baseInfo.value.devcode) {
    showToast('设备编号不能为空')
    return
  }
  $router.push({
    name: 'OperationData',
    // query: {
    //   row: JSON.stringify(baseInfo.value)
    // }
  })
}
// 保存
const save = () => {
  $router.push({
    name: 'OperationDataSuccess',
    query: {
      row: JSON.stringify(baseInfo.value)
    }
  })
}
</script>

<template>
  <div class="device-container">
    <!-- 设备信息 -->
    <div class="device-info">
      <van-form>
        <van-cell-group>
          <!-- 运维类型 -->
          <van-field v-model="baseInfo.repairTypeName" label="运维类型" is-link readonly name="repairType"
            placeholder="选择运维类型" required @click="showRepairType = true" input-align="right" />
          <van-popup v-model:show="showRepairType" destroy-on-close position="bottom">
            <van-picker :columns="repairTypeColumns" title="运维类型" :model-value="repairTypeValue"
              @confirm="onConfirmRepairType" @cancel="showRepairType = false" />
          </van-popup>
          <!-- 设备编号 -->
          <van-field v-model="baseInfo.devcode" label="设备编号" name="devcode" placeholder="输入设备编号" required
            input-align="right" @blur="searchDeviceInfo" />
          <!-- 安装位置 -->
          <van-field v-model="baseInfo.tagNumber" :readonly="disabledPosition" label="安装位置" name="tagNumber"
            placeholder="安装位置" required input-align="right" />
          <!-- 详细位置 -->
          <van-field v-model="baseInfo.position" :readonly="disabledPosition" label="详细位置" name="position"
            placeholder="详细位置" required input-align="right" />
          <!-- 运维日期 -->
          <van-field v-model="baseInfo.repairDate" is-link label="运维日期" name="repairDate" required placeholder="选择运维日期"
            @click="showDatePicker = true" input-align="right" />
          <van-popup v-model:show="showDatePicker" destroy-on-close position="bottom">
            <van-date-picker :model-value="pickerValueRepairDate" @confirm="onConfirmRepairDate"
              @cancel="showDatePicker = false" />
          </van-popup>
          <!-- 运维人员 -->
          <van-field v-model="baseInfo.repairPerson" label="运维人员" name="repairPerson" placeholder="输入运维人员" required
            input-align="right" />
          <!-- 运维内容 -->
          <van-field v-model="baseInfo.repairContent" label="运维内容" name="repairContent" placeholder="输入运维内容" required
            input-align="right" />
          <!-- 现场照片 -->
          <van-field readonly name="photo" label="现场照片" :required="isRequiredPhoto" input-align="center">
            <template #input>
              <div v-for="(item, index) in baseInfo.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>
  <!-- 按钮 -->
  <div class="btn-container">
    <el-button type="primary" style="width: 48%;" @click="save">保存</el-button>
    <el-button type="primary" plain style="width: 48%;" @click="deviceData">查看设备数据</el-button>
  </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;
  position: relative;

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

.btn-container {
  position: absolute;
  width: 96%;
  bottom: 1vh;
  display: flex;
  justify-content: space-around;
  // margin: 0 auto;
  left: 50%;
  transform: translateX(-50%);

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