| <template> | 
|     <div class="box1"> | 
|         <!--    设备+日期   --> | 
|         <div class="box_list"> | 
|             <div class="box_list_item" @click="open"> | 
|                 <div class="box_list_item_left"> | 
|                     <span>检验设备</span><span>*</span> | 
|                 </div> | 
|                 <div class="box_list_item_right"> | 
|                     <span :style="form.equipmentName ? 'color: #000' : ''">{{ form.equipmentName ? form.equipmentName : '点击选择巡检设备' }}</span> | 
|                     <van-icon name="arrow" size="18" color="#999999" /> | 
|                 </div> | 
|             </div> | 
|             <div class="box_list_code" @click.stop="openCode"> | 
|                 <div class="boxs"> | 
|                     <img src="@/assets/icon/jianyan_ic_saoma@2x.png" alt="" /> | 
|                     <span>扫描设备</span> | 
|                 </div> | 
|             </div> | 
|             <div class="box_list_item" @click="openTime"> | 
|                 <div class="box_list_item_left"> | 
|                     <span>巡检时间</span><span>*</span> | 
|                 </div> | 
|                 <div class="box_list_item_right"> | 
|                     <span class="black">{{form.time}}</span> | 
|                     <van-icon name="arrow" size="18" color="#999999" /> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|         <!--    状态+图片/视频   --> | 
|         <div class="box_list1"> | 
|             <div class="box_list1_item"> | 
|                 <div class="box_list1_item_left"> | 
|                     <span>设备状态</span><span>*</span> | 
|                 </div> | 
|                 <div class="box_list1_item_right"> | 
|                     <div class="box_list1_item_right_item" :class="{'active': item.active}" v-for="(item, index) in status" :key="index" @click="changeItem(index, item.id)">{{item.name}}</div> | 
|                 </div> | 
|             </div> | 
|             <div class="box_list1_club"> | 
|                 <div class="box_list1_club_label">巡检现场照片<span v-show="form.status == '1'">*</span></div> | 
|                 <div class="box_list1_club_list"> | 
|                     <div class="box_list1_club_list_item" @click="uploadFile"> | 
|                         <div class="type"> | 
|                             <img class="type_img" src="@/assets/icon/btn_upload@2x.png" alt="" /> | 
|                         </div> | 
|                     </div> | 
|                     <div class="box_list1_club_list_item" v-for="(item, index) in form.files" :key="index" @click="seeBigFile(index)"> | 
|                         <img class="close" src="@/assets/icon/ic_delete@2x.png" @click.stop="dele(index)" /> | 
|                         <img class="play" src="@/assets/icon/ic_play@2x.png" v-if="item.type === 1" /> | 
|                         <div class="type"> | 
|                             <video :src="item.url" v-if="item.type === 1"></video> | 
|                             <img v-else class="type_img" :src="item.url" alt="" /> | 
|                         </div> | 
|                     </div> | 
|                     <div class="box_list1_club_list_item1"></div> | 
|                     <div class="box_list1_club_list_item1"></div> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|         <div class="box_list2"> | 
|             <div class="box_list2_label">备注</div> | 
|             <textarea name="" id="" v-model="form.remarks" cols="20" rows="5" maxlength="300" placeholder="请详细描述巡检情况"></textarea> | 
|         </div> | 
|         <div class="box_footer"> | 
|             <button class="box_footer_submit" v-preventReClick @click="submit">提交</button> | 
|         </div> | 
|         <!--    设备弹框    --> | 
|         <van-popup v-model:show="show" position="bottom" round :style="{ height: '50%' }"> | 
|             <van-search v-model="value" @blur="changeValue" placeholder="请输入搜索关键词" /> | 
|             <van-picker | 
|                 title="请选择设备" | 
|                 :columns="value ? data : columns" | 
|                 @confirm="onConfirm" | 
|                 @cancel="onCancel" | 
|             /> | 
|         </van-popup> | 
|         <!--    时间选择    --> | 
|         <van-popup v-model:show="showTime" position="bottom" round :style="{ height: '40%' }"> | 
|             <van-datetime-picker | 
|                 v-model="currentDate" | 
|                 type="datetime" | 
|                 title="选择完整时间" | 
|                 @cancel="closeTime" | 
|                 @confirm="queding" | 
|                 :min-date="minDate" | 
|                 :max-date="maxDate" | 
|             /> | 
|         </van-popup> | 
|         <!--    扫一扫    --> | 
|         <v-ScanCode | 
|             :openCode="openCodea" | 
|             :infos="['请扫描设备码']" | 
|             @closePopup="closePopupa" | 
|             @onDecode="onDecodea" /> | 
|         <!--    上传     --> | 
|         <input type="file" hidden accept="video/mp4,image/png,image/jpeg,image/jpg" multiple @change="upFile" ref="upload" /> | 
|         <!--    大图预览     --> | 
|         <v-Preview v-if="isOpen" :list="form.files" :index="index" @close="close" /> | 
|     </div> | 
| </template> | 
|   | 
| <script setup lang="ts"> | 
|     import { ref, watch, onMounted, reactive } from 'vue' | 
|     import { setTime, judgmentType, sizeTostr } from '@/utils/utils' | 
|     import { queryListByCode, uploadFiles } from '@/apis/index' | 
|     import { saveBean, getDeviceByCondition, getsbInfo } from '@/apis/QualityAPI' | 
|     import { getBarcodeContent } from '@/apis/WorkOrderAPI' | 
|     import { QRCodeType } from '@/enum' | 
|     import { Toast } from 'vant' | 
|     import { useRouter } from 'vue-router' | 
|     import vPreview from '@/components/common/Preview.vue' | 
|   | 
|     const router = useRouter() | 
|   | 
|     let upload: any = ref(null) | 
|   | 
|     // 打开大图默认展示下标 | 
|     let index = ref<number>(0) | 
|   | 
|     let isOpen = ref<boolean>(false) | 
|   | 
|     // 弹框显示隐藏 | 
|     let show = ref<boolean>(false) | 
|   | 
|     // 文件上传路劲 | 
|     let path = ref<string>('') | 
|   | 
|     // 弹框显示隐藏时间选择器 | 
|     let showTime = ref<boolean>(false) | 
|   | 
|     // 扫一扫显示/隐藏 | 
|     let openCodea = ref<boolean>(false) | 
|   | 
|     // 搜索值 | 
|     let value = ref<string>('') | 
|   | 
|     // 筛选数据 | 
|     let data = ref<Array<any>>([]) | 
|   | 
|     // 设备列表 | 
|     let columns = ref<Array<object>>([]) | 
|   | 
|     // 设备状态 | 
|     let status = ref([ | 
|         { name: '正常', active: true, id: '0' }, | 
|         { name: '异常', active: false, id: '1' } | 
|     ]) | 
|   | 
|     const currentDate = ref(new Date()); | 
|   | 
|     const minDate = new Date(2020, 0, 1) | 
|   | 
|     const maxDate = new Date(2025, 10, 1) | 
|   | 
|     // 提交数据 | 
|     const form = reactive<{ equipmentId: string, equipmentName: string, time: string, status: string, files: Array<object>, remarks: string }>({ | 
|         equipmentId: '',    // 设备id | 
|         equipmentName: '',  //设备名称 | 
|         time: '',   // 巡检时间 | 
|         status: '0',     // 设备状态 | 
|         files: [],      // 巡检图片/视频 | 
|         remarks: ''     // 备注 | 
|     }) | 
|   | 
|     // 提交检验 | 
|     const submit = () => { | 
|         if (!form.equipmentId) return Toast.fail({ message: '设备不能为空' }) | 
|         if (!form.time) return Toast.fail({ message: '时间不能为空' }) | 
|         if (!form.status) return Toast.fail({ message: '状态不能为空' }) | 
|         if (form.status == '1') { | 
|             if (form.files.length === 0) return Toast.fail({ message: '现场照片不能为空' }) | 
|         } | 
|         saveBean({ | 
|             checkDate: form.time, | 
|             content: form.remarks, | 
|             deviceId: form.equipmentId, | 
|             status: form.status, | 
|             multiFilesSaveBeans: form.files | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 Toast.success({ message: "提交成功", duration: 2000, forbidClick: true }) | 
|                 setTimeout(() => { | 
|                     router.go(-1) | 
|                 }, 2000) | 
|             } | 
|         }) | 
|     } | 
|   | 
|     // 查看大图/视频 | 
|     const seeBigFile = (i: number): void => { | 
|         index.value = i | 
|         isOpen.value = true | 
|     } | 
|   | 
|     // 删除指定文件 | 
|     const dele = (i: number): void => { | 
|         form.files.splice(i, 1) | 
|     } | 
|   | 
|     // 获取当前用户下所有设备 | 
|     const getSB = () => { | 
|         getDeviceByCondition({}) | 
|             .then(res => { | 
|                 if (res.code === 200 && res.data && res.data.length > 0) { | 
|                     columns.value = [] | 
|                     res.data.forEach((item: any) => { | 
|                         columns.value.push({ text: item.name, id: item.id }) | 
|                     }) | 
|                 } | 
|             }) | 
|     } | 
|   | 
|     // 打开视频/图片大图预览 | 
|     const openPreview = () => { | 
|         isOpen.value = true | 
|     } | 
|   | 
|     // 关闭查看大图/视频组件 | 
|     const close = () => { | 
|         isOpen.value = false | 
|     } | 
|   | 
|     // 获取文件 | 
|     const upFile = async (e: any) => { | 
|         if (form.files.length + e.target.files.length > 9) { | 
|             Toast.fail({ message: '最多只能上传9个图片/视频' }) | 
|             upload.value.value = '' | 
|             return | 
|         } | 
|         for (let i = 0; i < e.target.files.length; i++) { | 
|             let type: string = e.target.files[i].type | 
|             let index = type.indexOf('/') | 
|             let data = type.substring(index + 1, type.length) | 
|             const format = new FormData() | 
|             format.append('file', e.target.files[i]) | 
|             format.append('folder', path.value) | 
|             let res = await uploadFiles(format) | 
|             if (res.code === 200) { | 
|                 form.files.push({ | 
|                     fileUrl: res.data.imgaddr, | 
|                     filename: res.data.imgname, | 
|                     filesize: e.target.files[i].size, | 
|                     type: judgmentType(data.toLowerCase()) ? 0 : 1, | 
|                     url: res.data.url | 
|                 }) | 
|             } | 
|         } | 
|         upload.value.value = '' | 
|     } | 
|   | 
|     // 点击上传 | 
|     const uploadFile = () => { | 
|         upload.value.click() | 
|     } | 
|   | 
|     // 关闭时间选择器 | 
|     const closeTime = () => { | 
|         showTime.value = false | 
|     } | 
|   | 
|     // 确认选择日期 | 
|     const queding = (val: any): void => { | 
|         form.time = setTime(val, '-') | 
|         showTime.value = false | 
|     } | 
|   | 
|     // 打开时间选择器 | 
|     const openTime = () => { | 
|         showTime.value = true | 
|     } | 
|   | 
|     // 扫码回调 | 
|     const onDecodea = (data: string[]): void => { | 
|         openCodea.value = false | 
|         getBarcodeContent({ | 
|             barcode: data[0] | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 if (res.data.barcodeType === QRCodeType.SB) { | 
|                     getsbInfo(res.data.id) | 
|                         .then(res => { | 
|                             if (res.code === 200) { | 
|                                 form.equipmentId = res.data.id | 
|                                 form.equipmentName = res.data.name | 
|                             } | 
|                         }) | 
|                 } else { | 
|                     Toast.fail({ message: '请扫描正确的设备码' }) | 
|                 } | 
|             } | 
|         }) | 
|     } | 
|   | 
|     // 打开扫一扫 | 
|     const openCode = (): void => { | 
|         openCodea.value = true | 
|     } | 
|   | 
|     // 关闭扫一扫 | 
|     const closePopupa = (): void => { | 
|         openCodea.value = false | 
|     } | 
|   | 
|     // 模糊搜索 | 
|     const changeValue = (val: any): void => { | 
|         data.value = [] | 
|         let { _value } = val.target | 
|         if (!_value) return | 
|         columns.value.forEach((item: any) => { | 
|             if (item.text.indexOf(_value) !== -1) { | 
|                 data.value.push(item) | 
|             } | 
|         }) | 
|     } | 
|   | 
|     // 关闭弹框 | 
|     const onCancel = (): void => { | 
|         show.value = false | 
|     } | 
|   | 
|     // 确认选择设备 | 
|     const onConfirm = (value: any): void => { | 
|         form.equipmentId = value.id | 
|         form.equipmentName = value.text | 
|         show.value = false | 
|     } | 
|   | 
|     // 打开设备弹框 | 
|     const open = (): void => { | 
|         show.value = true | 
|     } | 
|   | 
|     // 改变状态 | 
|     const changeItem = (i: number, id: string): void => { | 
|         status.value.forEach((item: any, index: number) => { | 
|             item.active = index === i; | 
|         }) | 
|         form.status = id | 
|     } | 
|   | 
|     // 监听设备弹框关闭 | 
|     watch(() => show.value, (news, old) => { | 
|         if (!news) { | 
|             value.value = '' | 
|             data.value = [] | 
|         } | 
|     }) | 
|   | 
|     // 获取字典纸 | 
|     const getqueryListByCode = () => { | 
|         queryListByCode({ | 
|             dicCode: 'FOLDER', | 
|             label: 'DEVICE_CHECK' | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 path.value = res.data[0].code | 
|             } | 
|         }) | 
|     } | 
|   | 
|     onMounted(() => { | 
|         getSB() | 
|         getqueryListByCode() | 
|         form.time = setTime(new Date(), '-') | 
|     }) | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
| .box1 { | 
|     width: 100%; | 
|     height: 100%; | 
|     position: absolute; | 
|     background: #F7F7F7; | 
|     .box_list { | 
|         padding: 30px 30px 0 30px; | 
|         background: white; | 
|         display: flex; | 
|         flex-direction: column; | 
|         .box_list_code { | 
|             margin: 20px 0; | 
|             .boxs { | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: flex-end; | 
|                 img { | 
|                     width: 28px; | 
|                     height: 28px; | 
|                     margin-right: 12px; | 
|                 } | 
|                 span { | 
|                     font-size: 28px; | 
|                     font-weight: 400; | 
|                     color: $nav-color; | 
|                 } | 
|             } | 
|         } | 
|         .box_list_item { | 
|             height: 98px; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: space-between; | 
|             border-bottom: 1PX solid #E5E5E5; | 
|             &:last-child { | 
|                 border: none; | 
|             } | 
|             .box_list_item_left { | 
|                 span { | 
|                     font-size: 30px; | 
|                     font-weight: 400; | 
|                     &:first-child { | 
|                         color: #222222; | 
|                     } | 
|                     &:last-child { | 
|                         color: #DE5243; | 
|                         margin-left: 8px; | 
|                     } | 
|                 } | 
|             } | 
|             .box_list_item_right { | 
|                 .black { | 
|                     color: black; | 
|                 } | 
|                 span { | 
|                     font-size: 28px; | 
|                     font-weight: 400; | 
|                     color: #999999; | 
|                     margin-right: 10px; | 
|                 } | 
|             } | 
|         } | 
|     } | 
|     .box_list1 { | 
|         padding: 30px; | 
|         background: white; | 
|         margin-top: 20px; | 
|         .box_list1_item { | 
|             height: 98px; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: space-between; | 
|             border-bottom: 1PX solid #E5E5E5; | 
|             &:last-child { | 
|                 border: none; | 
|             } | 
|             .box_list1_item_left { | 
|                 span { | 
|                     font-size: 30px; | 
|                     font-weight: 400; | 
|                     color: #222222; | 
|                     &:last-child { | 
|                         font-size: 30px; | 
|                         font-weight: 400; | 
|                         color: #DE5243; | 
|                         margin-left: 4px; | 
|                     } | 
|                 } | 
|             } | 
|             .box_list1_item_right { | 
|                 display: flex; | 
|                 align-items: center; | 
|                 .active { | 
|                     color: white !important; | 
|                     background: $nav-color !important; | 
|                 } | 
|                 .box_list1_item_right_item { | 
|                     padding: 18px 32px; | 
|                     background: #F2F2F2; | 
|                     display: flex; | 
|                     align-items: center; | 
|                     justify-content: center; | 
|                     font-size: 26px; | 
|                     font-weight: 400; | 
|                     color: #333333; | 
|                     margin-left: 20px; | 
|                     border-radius: 8px; | 
|                 } | 
|             } | 
|         } | 
|         .box_list1_club { | 
|             display: flex; | 
|             flex-direction: column; | 
|             margin-top: 36px; | 
|             .box_list1_club_label { | 
|                 font-size: 30px; | 
|                 font-weight: 400; | 
|                 color: #222222; | 
|                 margin-bottom: 32px; | 
|                 span { | 
|                     font-size: 30px; | 
|                     font-weight: 400; | 
|                     color: #DE5243; | 
|                     margin-left: 4px; | 
|                 } | 
|             } | 
|             .box_list1_club_list { | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: space-between; | 
|                 flex-wrap: wrap; | 
|                 .box_list1_club_list_item1 { | 
|                     width: 170px; | 
|                     height: 0; | 
|                 } | 
|                 .box_list1_club_list_item { | 
|                     width: 150px; | 
|                     height: 150px; | 
|                     border-radius: 8px; | 
|                     position: relative; | 
|                     margin-right: 22px; | 
|                     margin-bottom: 22px; | 
|                     .type { | 
|                         width: 100%; | 
|                         height: 100%; | 
|                         display: flex; | 
|                         align-items: center; | 
|                         justify-content: center; | 
|                         overflow: hidden; | 
|                         position: absolute; | 
|                         top: 0; | 
|                         left: 0; | 
|                         .type_img { | 
|                             width: 100%; | 
|                             height: 100%; | 
|                         } | 
|                         video { | 
|                             height: 100%; | 
|                             z-index: 1; | 
|                         } | 
|                     } | 
|                     .play { | 
|                         position: absolute; | 
|                         left: 50%; | 
|                         top: 50%; | 
|                         width: 56px; | 
|                         height: 56px; | 
|                         z-index: 9; | 
|                         transform: translate(-50%, -50%); | 
|                     } | 
|                     .close { | 
|                         position: absolute; | 
|                         right: -16px; | 
|                         top: -16px; | 
|                         width: 32px; | 
|                         height: 32px; | 
|                         z-index: 9; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     } | 
|     .box_list2 { | 
|         padding: 30px; | 
|         background: white; | 
|         margin-top: 20px; | 
|         display: flex; | 
|         flex-direction: column; | 
|         .box_list2_label { | 
|             font-size: 30px; | 
|             font-weight: 400; | 
|             color: #222222; | 
|             margin-bottom: 32px; | 
|         } | 
|         textarea { | 
|             border: none; | 
|             font-size: 28px; | 
|         } | 
|         textarea::-webkit-input-placeholder{ | 
|             font-size: 28px; | 
|             font-weight: 400; | 
|             color: #B2B2B2; | 
|         } | 
|     } | 
|     .box_footer { | 
|         width: 100%; | 
|         padding: 0 30px 68px 30px; | 
|         box-sizing: border-box; | 
|         position: fixed; | 
|         bottom: 0; | 
|         left: 0; | 
|         background: #F7F7F7; | 
|         .box_footer_submit { | 
|             width: 100%; | 
|             height: 88px; | 
|             background: #4275FC; | 
|             box-shadow: 0 0 12px 0 rgba(0,0,0,0.0800); | 
|             border-radius: 8px; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: center; | 
|             font-size: 30px; | 
|             font-weight: 500; | 
|             color: #FFFFFF; | 
|             border: none; | 
|         } | 
|     } | 
| } | 
| </style> |