<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>
|