巡检
This commit is contained in:
93
src/components/mediaPreview.vue
Normal file
93
src/components/mediaPreview.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<!-- 放大后的遮罩层 -->
|
||||
<view v-if="isEnlarged" class="image-preview-overlay" @click="handleClose">
|
||||
<block v-if="getFileType(mediaUrl)=='image'">
|
||||
<image
|
||||
:src="mediaUrl"
|
||||
mode="widthFix"
|
||||
class="enlarged-image"
|
||||
/>
|
||||
</block>
|
||||
<view :class="videoClass" v-else-if="getFileType(mediaUrl)=='video'">
|
||||
<!-- object-fit="cover" -->
|
||||
<video :src="mediaUrl" controls @loadedmetadata="onVideoLoaded"></video>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,watch } from 'vue';
|
||||
import {getFileType} from '@/utils/common.js';
|
||||
const props = defineProps({
|
||||
visible:{
|
||||
type:Boolean
|
||||
},
|
||||
url:{}//图片路径
|
||||
})
|
||||
|
||||
const isEnlarged = ref(props.visible);
|
||||
const mediaUrl = ref(props.url);//http://192.168.236.184:9000/718ys-test/polling/2483ee76b28b4d43b87c13386dad90bb.jpg
|
||||
// const mediaType = ref('');//类型
|
||||
// 显示隐藏
|
||||
watch(() => props.visible, (newVal, oldVal) => {
|
||||
isEnlarged.value = newVal
|
||||
},{
|
||||
deep:true, // 深度监听
|
||||
immediate:true // 立即执行
|
||||
});
|
||||
|
||||
watch(() => props.url, (newVal, oldVal) => {
|
||||
mediaUrl.value = newVal;
|
||||
},{
|
||||
deep:true,
|
||||
immediate:true
|
||||
});
|
||||
const emit = defineEmits(['close'])
|
||||
const handleClose=()=>{
|
||||
emit('close');
|
||||
}
|
||||
|
||||
// 获取视频的宽和高
|
||||
let videoClass = ref('enlarged-image');
|
||||
const onVideoLoaded = (e) => {
|
||||
// 通过事件对象获取原始宽高[citation:3]
|
||||
let w = e.detail.width;
|
||||
let h = e.detail.height;
|
||||
// 你也可以在这里进行后续操作,比如根据宽高比调整UI
|
||||
console.log(w,h)
|
||||
if(h>w){
|
||||
videoClass.value="enlarged-image"
|
||||
}else{
|
||||
videoClass.value="enlarged-image"
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
:deep(uni-video){
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.enlarged-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.enlarged-image2 {
|
||||
width:auto;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
@@ -112,6 +112,27 @@
|
||||
"pid" : "",
|
||||
"parameters" : {}
|
||||
}
|
||||
},
|
||||
"LF-Sense-Card" : {
|
||||
"插件需要配置的参数名称, 如appid" : "",
|
||||
"__plugin_info__" : {
|
||||
"name" : "Android-NFC读卡",
|
||||
"description" : "uni-app android原生插件 用来使用nfc读取m1卡",
|
||||
"platforms" : "Android",
|
||||
"url" : "",
|
||||
"android_package_name" : "",
|
||||
"ios_bundle_id" : "",
|
||||
"isCloud" : false,
|
||||
"bought" : -1,
|
||||
"pid" : "",
|
||||
"parameters" : {
|
||||
"插件需要配置的参数名称, 如appid" : {
|
||||
"des" : "参数描述",
|
||||
"key" : "AndroidManifest.xml中添加meta-data节点!对应android:name属性值, 如GETUI_APPID",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<view class="r-l-left">
|
||||
完成进度<span class="r-gray"><span :class="{'r-red':item.groupFinishNum<item.groupNum}">{{item.groupFinishNum}}</span>/{{item.groupNum}}</span>
|
||||
</view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum).toFixed()+'%'}}</span></view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum*100).toFixed()+'%'}}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
@@ -102,7 +102,7 @@
|
||||
<view class="r-l-left">
|
||||
完成进度<span class="r-gray"><span :class="{'r-red':item.groupFinishNum<item.groupNum}">{{item.groupFinishNum}}</span>/{{item.groupNum}}</span>
|
||||
</view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum).toFixed()+'%'}}</span></view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum*100).toFixed()+'%'}}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
@@ -305,12 +305,12 @@ const handleJump = (item)=>{
|
||||
.white-bg{
|
||||
width: 670rpx;
|
||||
padding: 30rpx 40rpx 40rpx;
|
||||
margin-bottom: 0;
|
||||
margin: 0 auto !important;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
.white-bg2{
|
||||
border-radius: 0;
|
||||
margin-top:20rpx;
|
||||
border-top:20rpx solid #F5F5F5
|
||||
}
|
||||
.report-list{
|
||||
position: relative;
|
||||
|
||||
@@ -129,8 +129,8 @@
|
||||
<view>{{ item.pointName }}</view>
|
||||
</view>
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-for="(item2,index) in imgArr2" :key="index">
|
||||
<img :src="item2" />
|
||||
<view class="img-show" v-for="(item2,index) in imgArr2" :key="index" @click="showMediaPreview(item2)">
|
||||
<img :src="item2.shortUrl" />
|
||||
</view>
|
||||
<view class="img-con" @click="chooseImage(item)">
|
||||
<img :src="'static/images/polling/icon-AddPic.png'" class="img-pic" />
|
||||
@@ -145,8 +145,8 @@
|
||||
<view>{{ item.pointName }}</view>
|
||||
</view>
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-for="(item2,index) in videoArr2" :key="index">
|
||||
<video :src="item2" controls></video>
|
||||
<view class="img-show" v-for="(item2,index) in videoArr2" :key="index" @click="showMediaPreview(item2)">
|
||||
<video :src="item2.url" controls v-show="videoShow"></video>
|
||||
</view>
|
||||
<view class="img-con" @click="chooseVideo(item)">
|
||||
<img :src="'static/images/polling/icon-AddVideo.png'" class="img-pic" />
|
||||
@@ -194,6 +194,8 @@
|
||||
ref="showModel3"
|
||||
></customShowModal>
|
||||
|
||||
<!-- 图片放大 -->
|
||||
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
@@ -205,28 +207,28 @@ import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import multipleSelect from "@/components/multipleSelect.vue";
|
||||
import pollingShowModal from "@/components/pollingShowModal.vue";
|
||||
import customShowModal from "@/components/customShowModal.vue"
|
||||
import mediaPreview from "@/components/mediaPreview.vue"
|
||||
import { parseTime } from '@/utils/datetime.js';
|
||||
import { formatTaskStatus } from '@/utils/status.js';
|
||||
import { taskGroupDetail,submitResult,minioUpload } from '@/api/polling.js'
|
||||
import {compressImageUni,getMinioThumbUrl} from '@/utils/common.js'
|
||||
import {compressImageUni} from '@/utils/common.js'
|
||||
// import {uploadFileMinio} from '@/utils/minio.js'
|
||||
// #ifdef APP-PLUS
|
||||
import nfcUtil from "@/utils/nfcUtil.js"
|
||||
let m1CardModule = uni.requireNativePlugin("LF-Sense-Card-M1")
|
||||
// #endif
|
||||
|
||||
let taskId = ref(undefined);
|
||||
let groupId = ref(undefined);
|
||||
let minioObj = ref({});
|
||||
let minioObj = {};
|
||||
onLoad(option => {
|
||||
// console.log(option)
|
||||
taskId.value = option.taskId;
|
||||
groupId.value = option.groupId;
|
||||
|
||||
minioObj.value = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||
// console.log(minioObj.value)
|
||||
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||
// console.log(minioObj)
|
||||
})
|
||||
|
||||
|
||||
// 下拉刷新
|
||||
const mescrollRef = ref(null);
|
||||
const mescrollInit = (mescroll) => {
|
||||
@@ -269,21 +271,24 @@ const getList = async() => {
|
||||
}else if(item.pointType==7){
|
||||
imgArr.value=[];
|
||||
imgArr2.value=[];
|
||||
let imgList = item.resultContent.split(",");
|
||||
let imgList = item.resultContent?.split(",")||[];
|
||||
imgList.forEach(imgUrl=>{
|
||||
imgArr.value.push(imgUrl);
|
||||
let urlNew = minioObj.value.endpoint + "/thumb/"+minioObj.value.bucketName +"/"+imgUrl
|
||||
imgArr2.value.push(urlNew)
|
||||
imgArr2.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+imgUrl,
|
||||
url:minioObj.minioUrl +"/"+imgUrl,
|
||||
})
|
||||
})
|
||||
|
||||
}else if(item.pointType==8){
|
||||
videoArr.value=[];
|
||||
videoArr2.value=[]
|
||||
let videoList = item.resultContent.split(",");
|
||||
let videoList = item.resultContent?.split(",")||[];
|
||||
videoList.forEach(videoUrl=>{
|
||||
videoArr.value.push(videoUrl);
|
||||
let urlNew = minioObj.value.endpoint + "/"+minioObj.value.bucketName +"/"+videoUrl
|
||||
videoArr2.value.push(urlNew)
|
||||
videoArr2.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+videoUrl,
|
||||
url:minioObj.minioUrl +"/"+videoUrl,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -408,70 +413,32 @@ const chooseVideo = (item) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 放大视频或图片
|
||||
let isVisible= ref(false);//放大处理
|
||||
let mediaUrl= ref('');//放大地址
|
||||
let videoShow = ref(true);
|
||||
const showMediaPreview=(item)=>{
|
||||
console.log("showMediaPreview===")
|
||||
isVisible.value = true;
|
||||
videoShow.value = false;
|
||||
mediaUrl.value = item.url
|
||||
}
|
||||
const handlePreviewClose=()=>{
|
||||
isVisible.value = false;
|
||||
videoShow.value = true;
|
||||
}
|
||||
|
||||
// nfc 处理
|
||||
let discoveryCallback = null
|
||||
let cardUID = ref('');
|
||||
let cardValue = ref('');
|
||||
const initNFC = async(item) => {
|
||||
// console.log("initNFC=>",plus)
|
||||
|
||||
//这里用异步获取读取到的NFC数据
|
||||
const nfcId = await nfcUtil.listenNFCStatus();
|
||||
console.log("initNFC=>",nfcId)
|
||||
|
||||
// 确保在 App 环境
|
||||
// if (typeof plus === 'undefined') {
|
||||
// showModel3('此功能仅支持 App 端')
|
||||
// return
|
||||
// }
|
||||
|
||||
// // 检查设备是否支持NFC
|
||||
// if (!plus.nfc) {
|
||||
// showModel3('设备不支持 NFC')
|
||||
// return;
|
||||
// }
|
||||
// if (!plus.nfc.isSupportNFC()) {
|
||||
// showModel3('设备不支持 NFC')
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 检查NFC是否开启
|
||||
// plus.nfc.isNFCEnabled((enabled) => {
|
||||
// if (enabled) {
|
||||
// startDiscovery()
|
||||
// } else {
|
||||
// showModel3('请先开启设备NFC功能')
|
||||
// }
|
||||
// },(error) => {
|
||||
// console.error('检查NFC状态失败:'+error.message);
|
||||
// showModel3('检查NFC状态失败')
|
||||
// })
|
||||
}
|
||||
// 执行NFC扫描
|
||||
const startDiscovery = () => {
|
||||
// 开始监听NFC标签
|
||||
plus.nfc.startDiscovery((res) => {
|
||||
console.log('NFC监听启动成功')
|
||||
// 监听NFC标签被发现的事件
|
||||
discoveryCallback = (result) => {
|
||||
try {
|
||||
console.log("NFC监听返回=>",result)
|
||||
// 尝试读取标签ID或NDEF数据
|
||||
const tag = result.tag
|
||||
if (tag && tag.id) {
|
||||
// 将标签ID字节数组转换为十六进制字符串
|
||||
const tagId = tag.id.map(b => b.toString(16).padStart(2, '0')).join(':')
|
||||
console.log(`检测到标签,ID: ${tagId}`)
|
||||
// 此处可以处理tag.ndefMessage等数据
|
||||
} else {
|
||||
console.log( `检测到标签,但无法解析数据`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log( '处理NFC数据时出错:' + error.message)
|
||||
}
|
||||
}
|
||||
plus.nfc.addEventListener('discovered', discoveryCallback, false)
|
||||
},(err) => {
|
||||
console.log( 'NFC监听启动失败:' + err.message)
|
||||
m1CardModule.openNativeSenseCard({
|
||||
'keyA': 'TestKey',
|
||||
'sector': 0,
|
||||
'block': 0
|
||||
},ret => {
|
||||
cardUID.value = ret.uid
|
||||
cardValue.value = ret.code
|
||||
})
|
||||
}
|
||||
|
||||
@@ -576,8 +543,9 @@ const handleConfirm=()=>{
|
||||
submitResult(submitParam).then(res=>{
|
||||
subTime.value = res;
|
||||
visible.value = false;
|
||||
console.log("submitResult=>",visible.value)
|
||||
// console.log("submitResult=>",visible.value)
|
||||
showModel2('此巡检项已完成');
|
||||
uni.navigateBack();
|
||||
}).finally(() => {
|
||||
submitLoading.value = false;
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:leftFlag="true" :rightFlag="true"
|
||||
>
|
||||
<template #right>
|
||||
<view class="head-right" @click="handleQuestion">
|
||||
<view class="head-right" @click="handleQuestion" v-if="problemObj.problemStatus==1">
|
||||
<view class="btn-yellow">
|
||||
<uni-icons type="plus" size="20" color="#4C2D11"></uni-icons> 新增跟踪信息
|
||||
</view>
|
||||
@@ -56,18 +56,18 @@
|
||||
<view class="report-list">
|
||||
<block v-for="(item,index) in problemObj.listFile" :key="index">
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-if="getFileType(item)=='image'">
|
||||
<img :src="item" />
|
||||
<view class="img-show" v-if="getFileType(item)=='image'" @click="showMediaPreview(minioObj.minioUrl+'/'+item)">
|
||||
<img :src="minioObj.minioThumbUrl+'/'+item" />
|
||||
</view>
|
||||
<view class="img-show" v-else-if="getFileType(item)=='video'">
|
||||
<video :src="item" controls></video>
|
||||
<view class="img-show" v-else-if="getFileType(item)=='video'" @click="showMediaPreview(minioObj.minioUrl+'/'+item)">
|
||||
<video :src="minioObj.minioUrl+'/'+item" controls v-show="videoShow"></video>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 当天提的 增加按钮 修改和删除 -->
|
||||
<view class="btn-con" v-if="isToday">
|
||||
<view class="btn-con" v-if="isToday && problemObj.problemStatus==1">
|
||||
<button type="primary" @click="handleUpdate" size="mini" style="margin-right:50rpx;" class="btn-primary">修改</button>
|
||||
<button type="primary" @click="handleDelete" size="mini">删除</button>
|
||||
</view>
|
||||
@@ -88,11 +88,11 @@
|
||||
<view class="report-list">
|
||||
<view class="img-flex">
|
||||
<block v-for="(item,index) in item.listFile" :key="index">
|
||||
<view class="img-show" v-if="getFileType(item)=='image'">
|
||||
<img :src="item" />
|
||||
<view class="img-show" v-if="getFileType(item)=='image'" @click="showMediaPreview(minioObj.minioUrl+'/'+item)">
|
||||
<img :src="minioObj.minioThumbUrl+'/'+item" />
|
||||
</view>
|
||||
<view class="img-show" v-else-if="getFileType(item)=='video'">
|
||||
<video :src="item" controls></video>
|
||||
<view class="img-show" v-else-if="getFileType(item)=='video'" @click="showMediaPreview(minioObj.minioUrl+'/'+item)">
|
||||
<video :src="minioObj.minioUrl+'/'+item" controls v-show="videoShow"></video>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -103,24 +103,35 @@
|
||||
</view>
|
||||
</mescroll-uni>
|
||||
</view>
|
||||
<!-- 图片放大 -->
|
||||
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,onMounted,onUnmounted,nextTick,computed,reactive } from 'vue'
|
||||
import { onLoad,onHide} from '@dcloudio/uni-app';
|
||||
import { onLoad,onShow,onHide} from '@dcloudio/uni-app';
|
||||
import customHeader from '@/components/customHeader.vue';
|
||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import mediaPreview from "@/components/mediaPreview.vue"
|
||||
import { parseTime } from '@/utils/datetime.js';
|
||||
import {getFileType} from '@/utils/common.js';
|
||||
import { problemDetail } from '@/api/polling.js'
|
||||
import { problemDetail,problemDel } from '@/api/polling.js'
|
||||
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||
|
||||
let problemId=ref('');
|
||||
let problemObj = ref({});
|
||||
let isToday = ref(false)
|
||||
let isToday = ref(false);
|
||||
let minioObj = {};
|
||||
onLoad(option => {
|
||||
// console.log(option)
|
||||
problemId.value = option.problemId;
|
||||
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||
})
|
||||
|
||||
onShow(()=>{
|
||||
getList();
|
||||
})
|
||||
|
||||
// 下拉刷新
|
||||
@@ -129,7 +140,7 @@ const mescrollInit = (mescroll) => {
|
||||
mescrollRef.value = mescroll;
|
||||
};
|
||||
const downOption = ref({
|
||||
auto: true,
|
||||
auto: false,
|
||||
textInOffset: '下拉刷新',
|
||||
textOutOffset: '释放更新',
|
||||
textLoading: '刷新中...'
|
||||
@@ -150,28 +161,10 @@ const downCallback = async (mescroll) => {
|
||||
const getList = async() => {
|
||||
isToday.value = false;
|
||||
let data = await problemDetail({problemId:problemId.value});
|
||||
// let res = {
|
||||
// "code": 200,
|
||||
// "msg": "操作成功",
|
||||
// "data": {
|
||||
// groupName:'配电箱箱体和内部线路检查',
|
||||
// problemDesc:'电箱右侧箱体有锈蚀,需要及时修补;电箱前门关闭不严,缝隙过大;箱门密封条出现老化痕迹;显示屏出现若干像素坏点。',
|
||||
// planTime:new Date().getTime(),
|
||||
// realname:'张三',
|
||||
// pointName:'技术中心机房总电源,监控室消防设备阀门正常开启闭合,监控室10组灭火器压力指针处于绿色区域',
|
||||
// problemVedio:'http://192.168.236.196:9000/718ys-test/polling/rotate_2.jpg,http://192.168.236.196:9000/718ys-test/polling/mov_bbb.mp4',
|
||||
// logList:[
|
||||
// {
|
||||
// logId:1,logDesc:'配电箱箱体和内部线路检查',createTime:new Date().getTime(),modifyUserName:'张三',
|
||||
// logVedio:'http://192.168.236.196:9000/718ys-test/polling/mov_bbb.mp4,http://192.168.236.196:9000/718ys-test/polling/rotate_2.jpg,http://192.168.236.196:9000/718ys-test/polling/mov_bbb.mp4,http://192.168.236.196:9000/718ys-test/polling/rotate_2.jpg,http://192.168.236.196:9000/718ys-test/polling/mov_bbb.mp4,http://192.168.236.196:9000/718ys-test/polling/rotate_2.jpg',
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
data.list = data.pointName.split(",") || [];
|
||||
data.listFile=data.problemVedio.split(",") || [];
|
||||
data.list = data.pointName?.split(",") || [];
|
||||
data.listFile=data.problemVedio?.split(",") || [];
|
||||
data.logList.forEach(item => {
|
||||
item.listFile = item.logVedio.split(",")||[]
|
||||
item.listFile = item.logVedio?.split(",")||[]
|
||||
});
|
||||
// 判断是否当天创建的,显示按钮
|
||||
let createTime = parseTime(data.createTime,'{y}-{m}-{d}');
|
||||
@@ -182,10 +175,24 @@ const getList = async() => {
|
||||
problemObj.value = data;
|
||||
}
|
||||
|
||||
// 放大视频或图片
|
||||
let isVisible= ref(false);//放大处理
|
||||
let mediaUrl= ref('');//放大地址
|
||||
let videoShow = ref(true);
|
||||
const showMediaPreview=(url)=>{
|
||||
isVisible.value = true;
|
||||
videoShow.value = false;
|
||||
mediaUrl.value = url
|
||||
}
|
||||
const handlePreviewClose=()=>{
|
||||
isVisible.value = false;
|
||||
videoShow.value = true;
|
||||
}
|
||||
|
||||
// 跳转问题上报页面
|
||||
const handleQuestion=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/business/polling/problemLog'
|
||||
url: '/pages/business/polling/problemLog?problemId='+problemId.value
|
||||
});
|
||||
}
|
||||
|
||||
@@ -198,7 +205,15 @@ const handleUpdate=()=>{
|
||||
|
||||
// 删除
|
||||
const handleDelete=()=>{
|
||||
|
||||
showLoading("加载中...")
|
||||
problemDel({problemId:problemId.value}).then(res=>{
|
||||
// content, title = '提示',showCancel=false,succFun
|
||||
showAlert("删除成功!",'提示',false,()=>{
|
||||
uni.navigateBack()
|
||||
})
|
||||
}).finally(()=>{
|
||||
hideLoading();
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -231,7 +246,7 @@ const handleDelete=()=>{
|
||||
}
|
||||
.white-bg{
|
||||
width: 680rpx;
|
||||
padding: 15rpx 30rpx 10rpx 40rpx;
|
||||
padding: 15rpx 30rpx 50rpx 40rpx;
|
||||
margin-bottom: 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ import customHeader from '@/components/customHeader.vue'
|
||||
import customSearch from '@/components/customSearch.vue'
|
||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||
import { noticeList } from '@/api/notice.js'
|
||||
import { parseTime } from '@/utils/datetime.js'
|
||||
import { problemList } from '@/api/polling.js'
|
||||
|
||||
@@ -188,90 +187,10 @@ const getList = (pageIndex, pageSize) => {
|
||||
taskType:notictTypeCheck.value.id
|
||||
}
|
||||
let res = await problemList(param);
|
||||
// let res={
|
||||
// "code": 200,
|
||||
// "msg": "操作成功",
|
||||
// "data": {
|
||||
// list:[
|
||||
// {
|
||||
// problemDesc:'西区地下车库入口防汛物资摆放',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:1,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:0,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'西区地下车库入口防汛物资摆放',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:1,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:0,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },{
|
||||
// problemDesc:'西区地下车库入口防汛物资摆放',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:1,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:0,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// },
|
||||
// {
|
||||
// problemDesc:'监控室消防设备阀门确保正常开启闭合',
|
||||
// problemId:202512297899,
|
||||
// problemStatus:2,
|
||||
// modifyTime:new Date().getTime(),
|
||||
// count:20,
|
||||
// }
|
||||
// ],
|
||||
// recordCount:2
|
||||
// }
|
||||
// }
|
||||
|
||||
let list = res.list || [];
|
||||
|
||||
resolve({
|
||||
list,
|
||||
total: res.recordCount || 0
|
||||
// total: res.recordCount || 0
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,118 +8,167 @@
|
||||
<!-- 高度来避免头部遮挡 -->
|
||||
<view class="top-height"></view>
|
||||
|
||||
<view class="white-bg">
|
||||
<view class="red-title">问题:{{optionObj.groupName}}</view>
|
||||
<view class="report-list">
|
||||
<view class="report-pro">问题项</view>
|
||||
<view class="report-right">
|
||||
<view class="r-list" v-for="(item, index) in optionObj.list" :key="index">
|
||||
<view class="r-left">
|
||||
<view>{{String(index+1).padStart(2, '0')+'.'}}</view>
|
||||
<view>{{ item }}</view>
|
||||
<!-- 下拉刷新 -->
|
||||
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||
:down="downOption" @down="downCallback"
|
||||
:fixed="false" class="scroll-h"
|
||||
>
|
||||
<view class="white-bg">
|
||||
<view class="red-title">问题:{{optionObj.groupName}}</view>
|
||||
<view class="report-list">
|
||||
<view class="report-pro">问题项</view>
|
||||
<view class="report-right">
|
||||
<view class="r-list" v-for="(item, index) in optionObj.list" :key="index">
|
||||
<view class="r-left">
|
||||
<view>{{String(index+1).padStart(2, '0')+'.'}}</view>
|
||||
<view>{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list">
|
||||
<view class="report-pro">巡检人</view>
|
||||
<view class="report-right">{{realname}}</view>
|
||||
</view>
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list" style="display:block;">
|
||||
检查点跟踪情况描述
|
||||
<textarea class="r-input textarea" v-model="desc" auto-height
|
||||
placeholder="请输入跟踪情况描述" placeholder-class="place-input"
|
||||
></textarea>
|
||||
</view>
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list" style="display:block;">
|
||||
<view class="r-title">问题点位照片或视频 <text>*</text></view>
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-for="(item,index) in imgArr" :key="index">
|
||||
<img :src="item" />
|
||||
</view>
|
||||
<view class="img-show" v-for="(item,index) in videoArr" :key="index">
|
||||
<video :src="item" controls></video>
|
||||
</view>
|
||||
<view class="img-con" @click="chooseMedia">
|
||||
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list">
|
||||
<view class="report-pro">提交人</view>
|
||||
<view class="report-right">{{optionObj.createUserName}}</view>
|
||||
</view>
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list" style="display:block;">
|
||||
检查点跟踪情况描述
|
||||
<textarea class="r-input textarea" v-model="desc" auto-height
|
||||
placeholder="请输入跟踪情况描述" placeholder-class="place-input"
|
||||
></textarea>
|
||||
</view>
|
||||
<view class="report-border"></view>
|
||||
<view class="report-list" style="display:block;">
|
||||
<view class="r-title">问题点位照片或视频 <text>*</text></view>
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-for="(item,index) in imgArr" :key="index">
|
||||
<img :src="item" />
|
||||
</view>
|
||||
<view class="img-show" v-for="(item,index) in videoArr" :key="index">
|
||||
<video :src="item" controls></video>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="img-con" @click="chooseMedia">
|
||||
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<view class="img-con">
|
||||
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-submit">
|
||||
<button type="primary" @click="handleSubmit">提交</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-submit">
|
||||
<button type="primary" @click="handleSubmit">提交</button>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-uni>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,onMounted,onUnmounted,nextTick,computed,reactive } from 'vue'
|
||||
import { onLoad,onHide} from '@dcloudio/uni-app';
|
||||
import { onLoad,onHide, onShow} from '@dcloudio/uni-app';
|
||||
import customHeader from '@/components/customHeader.vue';
|
||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import { getUserInfo } from '@/api/auth.js'
|
||||
import { problemDetail,problemAddLog,minioUpload } from '@/api/polling.js'
|
||||
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||
import {compressImageUni} from '@/utils/common.js'
|
||||
|
||||
let id = ref('');
|
||||
let problemId = ref('');
|
||||
let realname = ref('');
|
||||
let desc = ref('');//描述
|
||||
onLoad(async option => {
|
||||
// console.log(option)
|
||||
id.value = option.id;
|
||||
problemId.value = option.problemId;
|
||||
|
||||
let userinfo = await getUserInfo({});
|
||||
realname.value = userinfo.realname
|
||||
})
|
||||
|
||||
onShow(()=>{
|
||||
getList();
|
||||
})
|
||||
|
||||
// 查询列表
|
||||
let list = ref([]);
|
||||
let optionObj = ref({})
|
||||
|
||||
// 获取数据列表
|
||||
const getList = () => {
|
||||
// let res = await noticeList();
|
||||
// 1 单选 2多选 3判断 4问答 5 读卡 6 扫码 7 拍照 8 视频 9 定位
|
||||
let res = {
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
groupName:'配电箱箱体和内部线路检查',
|
||||
planTime:new Date().getTime(),
|
||||
pointName:'技术中心机房总电源,监控室消防设备阀门正常开启闭合,监控室10组灭火器压力指针处于绿色区域',
|
||||
}
|
||||
// 下拉刷新
|
||||
const mescrollRef = ref(null);
|
||||
const mescrollInit = (mescroll) => {
|
||||
mescrollRef.value = mescroll;
|
||||
};
|
||||
const downOption = ref({
|
||||
auto: false,
|
||||
textInOffset: '下拉刷新',
|
||||
textOutOffset: '释放更新',
|
||||
textLoading: '刷新中...'
|
||||
});
|
||||
// 下拉刷新
|
||||
const downCallback = async (mescroll) => {
|
||||
try {
|
||||
getList();
|
||||
} catch (error) {
|
||||
mescroll.endErr();
|
||||
} finally {
|
||||
mescroll.endSuccess();
|
||||
}
|
||||
let data = res.data || {};
|
||||
}
|
||||
|
||||
// 获取数据列表
|
||||
const getList = async () => {
|
||||
let res = await problemDetail({problemId:problemId.value});
|
||||
let data = res || {};
|
||||
data.list = data.pointName.split(",") || [];
|
||||
optionObj.value = data;
|
||||
}
|
||||
|
||||
// 图片或视频
|
||||
let imgArr = ref([]);//视频
|
||||
let videoArr = ref([]);//视频
|
||||
const imgArr2=ref([]);
|
||||
let mediaArr = ref([]);//传给后台的地址
|
||||
let imgArr=ref([]);//图片 后台返回的
|
||||
let videoArr = ref([]);//视频 后台返回的
|
||||
const chooseMedia = () => {
|
||||
imgArr.value=[];
|
||||
videoArr.value=[];
|
||||
uni.chooseMedia({
|
||||
count: 9,
|
||||
mediaType: ['image', 'video'], // 指定可选择图片和视频
|
||||
sourceType: ['album', 'camera'],
|
||||
maxDuration: 30, // 拍摄视频最长拍摄时间
|
||||
maxDuration: 60, // 拍摄视频最长拍摄时间
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
res.tempFiles.forEach(file => {
|
||||
console.log("问题跟踪chooseMedia=>",res)
|
||||
res.tempFiles.forEach(async file => {
|
||||
console.log(`文件类型: ${file.type}, 文件路径: ${file.tempFilePath}`);
|
||||
if (file.type === 'image') {
|
||||
// 显示本地图片
|
||||
imgArr.value.push(file)
|
||||
} else if (file.type === 'video') {
|
||||
// 处理视频
|
||||
videoArr.value.push(file)
|
||||
let compressImg = file.tempFilePath;
|
||||
// 图片进行压缩
|
||||
if (file.fileType === 'image') {
|
||||
// #ifdef APP-PLUS
|
||||
// 压缩图片
|
||||
compressImg = await compressImageUni(file.tempFilePath);
|
||||
// #endif
|
||||
}
|
||||
// 执行上传
|
||||
let param = {
|
||||
filePath: compressImg,
|
||||
name: 'file',
|
||||
formData: {
|
||||
directory:'polling'
|
||||
},
|
||||
}
|
||||
minioUpload(param).then(res=>{
|
||||
let data = res.data;
|
||||
mediaArr.value.push(data.fileName);
|
||||
if (file.fileType === 'image') {// 图片
|
||||
imgArr.value.push(data.fileUrl)
|
||||
} else if (file.type === 'video') {// 视频
|
||||
videoArr.value.push(data.fileUrl)
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -127,12 +176,33 @@ const chooseMedia = () => {
|
||||
|
||||
// 提交
|
||||
const handleSubmit=()=>{
|
||||
// showModel('有未完成的巡检项');
|
||||
// showModel2('此巡检项已完成');
|
||||
let param = {
|
||||
problemId:problemId.value,
|
||||
logVedio:mediaArr.value.join(","),
|
||||
logDesc:desc.value
|
||||
}
|
||||
console.log("problemAddLog=>",param)
|
||||
problemAddLog(param).then(res=>{
|
||||
showAlert("新建问题跟踪成功!");
|
||||
uni.navigateBack();
|
||||
}).finally(()=>{
|
||||
hideLoading();
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.scroll-h{
|
||||
/* #ifdef APP-PLUS */
|
||||
height:calc(100vh - 78px) !important;
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS */
|
||||
height: calc(100vh - 58px) !important;
|
||||
/* #endif */
|
||||
}
|
||||
:deep(.mescroll-upwarp){
|
||||
display: none !important;
|
||||
}
|
||||
.white-bg{
|
||||
width: 680rpx;
|
||||
padding: 15rpx 30rpx 40rpx 40rpx;
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
<view class="report-list" style="display:block;">
|
||||
<view class="r-title">问题点位照片或视频 <text>*</text></view>
|
||||
<view class="img-flex">
|
||||
<view class="img-show" v-for="(item,index) in imgArr" :key="index">
|
||||
<img :src="item" />
|
||||
<view class="img-show" v-for="(item,index) in imgArr" :key="index" @click="showMediaPreview(item)">
|
||||
<img :src="item.shortUrl" />
|
||||
</view>
|
||||
<view class="img-show" v-for="(item,index) in videoArr" :key="index">
|
||||
<video :src="item" controls></video>
|
||||
<view class="img-show" v-for="(item,index) in videoArr" :key="index" @click="showMediaPreview(item)">
|
||||
<video :src="item.url" controls></video>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="img-con" @click="chooseMedia">
|
||||
@@ -69,33 +69,42 @@
|
||||
</view>
|
||||
</mescroll-uni>
|
||||
</view>
|
||||
|
||||
<!-- 图片放大 -->
|
||||
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,onMounted,onUnmounted,nextTick,computed,reactive } from 'vue'
|
||||
import { ref,onMounted,onUnmounted,nextTick,computed,reactive, watch } from 'vue'
|
||||
import { onLoad,onHide} from '@dcloudio/uni-app';
|
||||
import customHeader from '@/components/customHeader.vue';
|
||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import mediaPreview from "@/components/mediaPreview.vue"
|
||||
import { getUserInfo } from '@/api/auth.js'
|
||||
import { problemDetail,problemAdd,problemEdit,minioUpload } from '@/api/polling.js'
|
||||
import {compressImageUni,getMinioThumbUrl} from '@/utils/common.js'
|
||||
import {compressImageUni,getFileType} from '@/utils/common.js'
|
||||
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||
|
||||
let taskId = ref('');//任务id
|
||||
let groupId = ref('');//组id
|
||||
let problemId = ref('');//问题id
|
||||
let realname = ref('');
|
||||
let desc = ref('');//描述
|
||||
let minioObj = {};
|
||||
onLoad(async option => {
|
||||
// console.log(option)
|
||||
taskId.value = option.taskId;
|
||||
groupId.value = option.groupId;
|
||||
problemId.value = option.problemId;
|
||||
|
||||
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||
|
||||
let userinfo = await getUserInfo({});
|
||||
realname.value = userinfo.realname
|
||||
})
|
||||
|
||||
// 查询列表
|
||||
let list = ref([]);
|
||||
let optionObj = ref({})
|
||||
@@ -132,7 +141,7 @@ const getList = async () => {
|
||||
let res = await problemDetail(param);
|
||||
let data = res||{};
|
||||
|
||||
let pointIds = data.pointId.split(",");
|
||||
let pointIds = data.pointId?.split(",") || [];
|
||||
data.pointList.forEach(item2=>{
|
||||
item2.active=false;
|
||||
for (let i = 0; i < pointIds.length; i++) {
|
||||
@@ -143,6 +152,25 @@ const getList = async () => {
|
||||
}
|
||||
})
|
||||
|
||||
// 视频回显
|
||||
imgArr.value = [];
|
||||
mediaArr.value=[];
|
||||
videoArr.value=[];
|
||||
let fileList =data.problemVedio?.split(",") || [];
|
||||
fileList.forEach(item=>{
|
||||
mediaArr.value.push(item)
|
||||
if(getFileType(item)=='image'){
|
||||
imgArr.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+item,
|
||||
url:minioObj.minioUrl +"/"+item,
|
||||
})
|
||||
}else if(getFileType(item)=='video'){
|
||||
videoArr.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+item,
|
||||
url:minioObj.minioUrl +"/"+item,
|
||||
})
|
||||
}
|
||||
})
|
||||
optionObj.value = data;
|
||||
}
|
||||
|
||||
@@ -158,14 +186,14 @@ const chooseMedia = () => {
|
||||
maxDuration: 60, // 拍摄视频最长拍摄时间
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
console.log("chooseMedia=>",res)
|
||||
res.tempFiles.forEach(async file => {
|
||||
// tempFilePath
|
||||
console.log(`文件类型: ${file.fileType}, 文件路径: ${file.tempFilePath}`);
|
||||
let compressImg = file.tempFilePath;
|
||||
// 图片进行压缩
|
||||
if (file.fileType === 'image') {
|
||||
// #ifdef APP-PLUS
|
||||
// #ifdef APP-PLUS
|
||||
// 压缩图片
|
||||
compressImg = await compressImageUni(file.tempFilePath);
|
||||
// #endif
|
||||
@@ -183,9 +211,17 @@ const chooseMedia = () => {
|
||||
let data = res.data;
|
||||
mediaArr.value.push(data.fileName);
|
||||
if (file.fileType === 'image') {// 图片
|
||||
imgArr.value.push(data.fileUrl)
|
||||
// imgArr.value.push(data.fileUrl)
|
||||
imgArr.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||
url:minioObj.minioUrl +"/"+data.fileName,
|
||||
})
|
||||
} else if (file.type === 'video') {// 视频
|
||||
videoArr.value.push(data.fileUrl)
|
||||
// videoArr.value.push(data.fileUrl)
|
||||
videoArr.value.push({
|
||||
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||
url:minioObj.minioUrl +"/"+data.fileName,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -194,6 +230,21 @@ const chooseMedia = () => {
|
||||
});
|
||||
}
|
||||
|
||||
// 放大视频或图片
|
||||
let isVisible= ref(false);//放大处理
|
||||
let mediaUrl= ref('');//放大地址
|
||||
let videoShow = ref(true);
|
||||
const showMediaPreview=(item)=>{
|
||||
isVisible.value = true;
|
||||
videoShow.value = false;
|
||||
mediaUrl.value = item.url
|
||||
}
|
||||
const handlePreviewClose=()=>{
|
||||
isVisible.value = false;
|
||||
videoShow.value = true;
|
||||
}
|
||||
|
||||
|
||||
// 红点点击
|
||||
const handleRound=(item)=>{
|
||||
item.active=!item.active
|
||||
@@ -214,25 +265,26 @@ const handleSubmit=()=>{
|
||||
problemId:problemId.value,
|
||||
pointId:pointIds.join(","),
|
||||
problemVedio:mediaArr.value.join(","),
|
||||
problemDesc:optionObj.problemDesc
|
||||
problemDesc:optionObj.value.problemDesc
|
||||
}
|
||||
console.log("problemEdit=>",param)
|
||||
// console.log("problemEdit=>",param)
|
||||
problemEdit(param).then(res=>{
|
||||
showAlert("新增上报问题成功")
|
||||
showAlert("修改问题上报成功!")
|
||||
}).finally(()=>{
|
||||
hideLoading();
|
||||
})
|
||||
}else{
|
||||
let param = {
|
||||
let param = {
|
||||
taskId:taskId.value,
|
||||
groupId:groupId.value,
|
||||
pointId:pointIds.join(","),
|
||||
problemVedio:mediaArr.value.join(","),
|
||||
problemDesc:optionObj.problemDesc
|
||||
problemDesc:optionObj.value.problemDesc
|
||||
}
|
||||
console.log("problemAdd=>",param)
|
||||
// console.log("problemAdd=>",param)
|
||||
problemAdd(param).then(res=>{
|
||||
showAlert("编辑上报问题成功")
|
||||
showAlert("新建问题上报成功!");
|
||||
problemId.value = res;
|
||||
}).finally(()=>{
|
||||
hideLoading();
|
||||
})
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
<block v-for="(row,index) in list" :key="index">
|
||||
|
||||
<!-- 日期展示 parseTime(row.date,'{y}-{m}-{d} 星期{a}')-->
|
||||
<view class="date-title">{{row.day}}</view>
|
||||
<view class="date-title" v-if="activeTab==1 && row.day">{{row.day}}</view>
|
||||
<view class="bg-border" v-else></view>
|
||||
|
||||
<!-- 日常巡检 -->
|
||||
<view class="blue-title">日常巡检</view>
|
||||
@@ -99,7 +100,7 @@
|
||||
<view class="r-l-left">
|
||||
完成进度<span class="r-gray"><span :class="{'r-red':item.groupFinishNum<item.groupNum}">{{item.groupFinishNum}}</span>/{{item.groupNum}}</span>
|
||||
</view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{item.percentage}}</span></view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum*100).toFixed()+'%'}}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
@@ -547,6 +548,7 @@ const handleJump = (item)=>{
|
||||
margin-left:-40rpx;
|
||||
color:#919191;
|
||||
font-size:28rpx;
|
||||
margin-top:30rpx;
|
||||
}
|
||||
|
||||
.scroll-h{
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
<view class="bg-progress">
|
||||
<view class="progress-container">
|
||||
<circleTemplate :progress="progress"></circleTemplate>
|
||||
<span>{{ (taskObj.groupFinishNum / taskObj.groupNum).toFixed() }}%</span>
|
||||
<span>{{ (taskObj.groupFinishNum / taskObj.groupNum*100).toFixed() }}%</span>
|
||||
</view>
|
||||
<view class="polling">
|
||||
<view class="p-title p-border">巡检单号<text>{{taskObj.taskNo}}</text></view>
|
||||
<view class="p-title">完成进度<text class="p-blue">{{taskObj.groupFinishNum}}</text>/{{taskObj.groupNum}}</view>
|
||||
<view class="btn-primary">
|
||||
<button type="primary" size="mini" @click="handleConfirm">任务提交</button>
|
||||
<button type="primary" size="mini" @click="handleConfirm" :disabled="taskObj.taskStatus!=3">任务提交</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -95,13 +95,14 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref,onMounted,nextTick,computed } from 'vue'
|
||||
import { onLoad,onHide } from '@dcloudio/uni-app';
|
||||
import { onLoad,onHide, onShow } from '@dcloudio/uni-app';
|
||||
import customHeader from '@/components/customHeader.vue';
|
||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||
import circleTemplate from '@/components/circleTemplate.vue';
|
||||
import { parseTime } from '@/utils/datetime.js';
|
||||
import { formatTaskStatus } from '@/utils/status.js';
|
||||
import { taskDetail } from '@/api/polling.js'
|
||||
import { taskDetail,submitTask } from '@/api/polling.js';
|
||||
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||
|
||||
// '2025-12-29 星期五'
|
||||
let taskId = ref(undefined);
|
||||
@@ -112,6 +113,10 @@ onLoad(option => {
|
||||
taskId.value = option.id;
|
||||
})
|
||||
|
||||
onShow(async ()=>{
|
||||
let res = await getList(1, 10);
|
||||
taskObj.value = res;
|
||||
})
|
||||
|
||||
// 查询列表
|
||||
let taskObj = ref({
|
||||
@@ -134,7 +139,7 @@ const upOption = ref({
|
||||
});
|
||||
|
||||
const downOption = ref({
|
||||
auto: true,
|
||||
auto: false,
|
||||
textInOffset: '下拉刷新',
|
||||
textOutOffset: '释放更新',
|
||||
textLoading: '刷新中...'
|
||||
@@ -348,7 +353,15 @@ const getList = (pageIndex, pageSize) => {
|
||||
|
||||
// 执行提交
|
||||
const handleConfirm=()=>{
|
||||
|
||||
let param = {
|
||||
taskId:taskObj.value.taskId
|
||||
}
|
||||
showLoading("加载中...")
|
||||
submitTask(param).then(res=>{
|
||||
showAlert("任务提交成功!");
|
||||
}).finally(()=>{
|
||||
hideLoading();
|
||||
})
|
||||
}
|
||||
|
||||
// 查看详情 type 1-详情 2-问题详情
|
||||
|
||||
@@ -28,65 +28,56 @@
|
||||
<!-- 列表 -->
|
||||
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
||||
:up="upOption" :down="downOption" :fixed="false" class="scroll-h" :class="{'loading-scroll':cssFlag}">
|
||||
<view class="white-bg">
|
||||
<block v-if="list">
|
||||
<block v-if="list.length>0">
|
||||
<!-- <view class="r-title">{{ parseTime(obj.dateStr,'{y}-{m}-{d} 星期{a}')}}</view> -->
|
||||
<view class="report-list" v-for="(item, index) in list" :key="index" @click="handleDetail(item)">
|
||||
<view class="r-list" style="padding-bottom:0">
|
||||
<view class="r-name">{{ item.taskName }}</view>
|
||||
<view class="r-right">
|
||||
<!-- 任务(巡检)状态 1=未发布 2=已发布 3 进行中 4 已完成 5 已过期 -->
|
||||
<!-- 状态为3进行中时 进度>0执行中 进度=0为待执行 -->
|
||||
<block v-if="item.taskStatus==3">
|
||||
<img v-if="item.count==0" :src="'static/images/polling/icon-start.png'" class="img-w" />
|
||||
<img v-else :src="'static/images/polling/icon-pending.png'" class="img-w" />
|
||||
</block>
|
||||
<img v-else-if="item.taskStatus==4" :src="'static/images/polling/icon-complete.png'" class="img-complete" />
|
||||
<img v-else-if="item.taskStatus==5" :src="'static/images/polling/icon-Expired.png'" class="img-w" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">巡检单号<span class="r-gray">{{ item.taskId }}</span></view>
|
||||
<view class="r-l-right">类型<span class="r-gray">{{ formatTaskType(item.taskType) }}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">开始时间<span class="r-gray">{{ parseTime(item.planTime,'{y}-{m}-{d} {h}:{i}') }}</span></view>
|
||||
<view class="r-l-right">任务时长<span class="r-gray">{{ item.workHour }}小时</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">
|
||||
完成进度<span class="r-gray"><span :class="{'r-red':item.groupFinishNum<item.groupNum}">{{item.groupFinishNum}}</span>/{{item.groupNum}}</span>
|
||||
</view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum).toFixed()+'%'}}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view>任务状态
|
||||
<span class="r-gray" v-if="item.taskStatus==3">
|
||||
<block v-if="item.groupFinishNum==0">待执行</block>
|
||||
<block v-else>执行中</block>
|
||||
</span>
|
||||
<span class="r-gray" v-else>{{formatTaskStatus(item.taskStatus) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-border" v-if="index<list.length-1"></view>
|
||||
<view class="white-bg" v-if="list.length>0">
|
||||
<!-- <view class="r-title">{{ parseTime(obj.dateStr,'{y}-{m}-{d} 星期{a}')}}</view> -->
|
||||
<view class="report-list" v-for="(item, index) in list" :key="index" @click="handleDetail(item)">
|
||||
<view class="r-list" style="padding-bottom:0">
|
||||
<view class="r-name">{{ item.taskName }}</view>
|
||||
<view class="r-right">
|
||||
<!-- 任务(巡检)状态 1=未发布 2=已发布 3 进行中 4 已完成 5 已过期 -->
|
||||
<!-- 状态为3进行中时 进度>0执行中 进度=0为待执行 -->
|
||||
<block v-if="item.taskStatus==3">
|
||||
<img v-if="item.count==0" :src="'static/images/polling/icon-start.png'" class="img-w" />
|
||||
<img v-else :src="'static/images/polling/icon-pending.png'" class="img-w" />
|
||||
</block>
|
||||
<img v-else-if="item.taskStatus==4" :src="'static/images/polling/icon-complete.png'" class="img-complete" />
|
||||
<img v-else-if="item.taskStatus==5" :src="'static/images/polling/icon-Expired.png'" class="img-w" />
|
||||
</view>
|
||||
</block>
|
||||
<view v-else class="no-data">
|
||||
<img :src="'static/images/polling/pic-NoResult.png'" class="no-pic" />
|
||||
</view>
|
||||
</block>
|
||||
<view v-else class="no-data">
|
||||
<img :src="'static/images/polling/pic-NoResult.png'" class="no-pic" />
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">巡检单号<span class="r-gray">{{ item.taskId }}</span></view>
|
||||
<view class="r-l-right">类型<span class="r-gray">{{ formatTaskType(item.taskType) }}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">开始时间<span class="r-gray">{{ parseTime(item.planTime,'{y}-{m}-{d} {h}:{i}') }}</span></view>
|
||||
<view class="r-l-right">任务时长<span class="r-gray">{{ item.workHour }}小时</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view class="r-l-left">
|
||||
完成进度<span class="r-gray"><span :class="{'r-red':item.groupFinishNum<item.groupNum}">{{item.groupFinishNum}}</span>/{{item.groupNum}}</span>
|
||||
</view>
|
||||
<view class="r-l-right">完成比率<span class="r-blue">{{(item.groupFinishNum/item.groupNum*100).toFixed()+'%'}}</span></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="r-list">
|
||||
<view class="r-left">
|
||||
<view>任务状态
|
||||
<span class="r-gray" v-if="item.taskStatus==3">
|
||||
<block v-if="item.groupFinishNum==0">待执行</block>
|
||||
<block v-else>执行中</block>
|
||||
</span>
|
||||
<span class="r-gray" v-else>{{formatTaskStatus(item.taskStatus) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-border" v-if="index<list.length-1"></view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</mescroll-uni>
|
||||
</view>
|
||||
@@ -105,7 +96,6 @@ import searchDate from '@/components/searchDate.vue';
|
||||
import { parseTime,getDateRange,getDateRangeName } from '@/utils/datetime.js';
|
||||
import { taskTypeOptions,formatTaskType,formatTaskStatus } from '@/utils/status.js';
|
||||
import { taskLists } from '@/api/polling.js'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 底部日期选择
|
||||
@@ -118,7 +108,6 @@ const dateClose=()=>{
|
||||
}
|
||||
// 选完日期提交回显
|
||||
const dateConfirm=(dateObj)=>{
|
||||
console.log(dateObj)
|
||||
isShow.value = false;
|
||||
dateStr.value = dateObj.startDate + ' 至 '+dateObj.endDate;
|
||||
dateStrName.value = getDateRangeName(dateObj.lastType)
|
||||
@@ -132,7 +121,7 @@ let taskTypeIndex = ref(0);
|
||||
let taskTypeArr = ref([]);
|
||||
let dateStr = ref('');
|
||||
let dateStrName=ref('');
|
||||
onLoad(option => {
|
||||
onLoad(async option => {
|
||||
taskTypeOptions.forEach(item => {
|
||||
taskTypeArr.value.push(item.label)
|
||||
});
|
||||
@@ -143,6 +132,10 @@ onLoad(option => {
|
||||
|
||||
form.value.startDate = dateObj.startDate;
|
||||
form.value.endDate = dateObj.endDate
|
||||
|
||||
// let res = await getList(0,3);
|
||||
// cssFlag.value = false;
|
||||
// list.value = res.list;
|
||||
|
||||
})
|
||||
|
||||
@@ -155,6 +148,7 @@ const changeTaskType = (e)=>{
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
let lastId = ref('');
|
||||
let list = ref([]);
|
||||
let form = ref({
|
||||
startDate:''
|
||||
@@ -162,6 +156,7 @@ let form = ref({
|
||||
const mescrollRef = ref(null);
|
||||
const upOption = ref({
|
||||
// use: false,
|
||||
auto: true, // 禁用自动上拉
|
||||
page: { num: 0, size: 10 },
|
||||
noMoreSize: 5,
|
||||
empty: {
|
||||
@@ -183,16 +178,18 @@ let cssFlag=ref(false);//控制样式
|
||||
const mescrollInit = (mescroll) => {
|
||||
cssFlag.value = true;
|
||||
mescrollRef.value = mescroll;
|
||||
// mescrollRef.value.triggerUpScroll();
|
||||
};
|
||||
|
||||
// 下拉刷新
|
||||
const downCallback = async (mescroll) => {
|
||||
console.log("mescroll=>",mescroll)
|
||||
try {
|
||||
console.log("下拉刷新")
|
||||
const res = await getList(1, upOption.value.page.size);
|
||||
console.log("下拉刷新");
|
||||
const res = await getList(1, upOption.value.page.size,undefined);
|
||||
cssFlag.value = false;
|
||||
list.value = res.list;
|
||||
mescroll.resetUpScroll();
|
||||
mescroll.resetUpScroll()
|
||||
} catch (error) {
|
||||
mescroll.endErr();
|
||||
} finally {
|
||||
@@ -204,8 +201,8 @@ const downCallback = async (mescroll) => {
|
||||
// 上拉加载更多
|
||||
const upCallback = async (mescroll) => {
|
||||
try {
|
||||
console.log("上拉加载更多")
|
||||
let res = await getList(mescroll.num, mescroll.size);
|
||||
console.log("上拉加载更多",mescroll)
|
||||
let res = await getList(mescroll.num, mescroll.size,lastId.value);
|
||||
if (mescroll.num === 1) {
|
||||
list.value = res.list;
|
||||
} else {
|
||||
@@ -218,27 +215,32 @@ const upCallback = async (mescroll) => {
|
||||
}
|
||||
|
||||
// 获取数据列表
|
||||
const getList = (pageIndex, pageSize) => {
|
||||
const getList = (pageIndex, pageSize,last) => {
|
||||
return new Promise(async (resolve) => {
|
||||
let param = {
|
||||
pageIndex,
|
||||
// pageIndex,
|
||||
pageSize,
|
||||
timeBegin: form.value.startDate,
|
||||
timeEnd: form.value.endDate,
|
||||
lastId:last,
|
||||
taskType:taskTypeOptions[taskTypeIndex.value].value
|
||||
}
|
||||
let res = await taskLists(param);
|
||||
let data = res ||{};
|
||||
lastId.value = data.isEnd==1?undefined:data.lastId
|
||||
resolve({
|
||||
...data,
|
||||
// total: res.recordCount || 0
|
||||
total: (data.isEnd==1?0:data.lastId) || 1, //是否最后一页(1-是,0-否)
|
||||
lastId: data.isEnd==1?undefined:data.lastId
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// 执行查询
|
||||
const handleSearch=()=>{
|
||||
getList(0,10)
|
||||
const handleSearch= async ()=>{
|
||||
let res = await getList(0,10);
|
||||
cssFlag.value = false;
|
||||
list.value = res.list;
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
@@ -253,10 +255,10 @@ const handleDetail = (item,type) =>{
|
||||
<style scoped>
|
||||
.scroll-h{
|
||||
/* #ifdef APP-PLUS */
|
||||
height: calc(100vh - 108px);
|
||||
height: calc(100vh - 148px);
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS */
|
||||
height: calc(100vh - 135px);
|
||||
height: calc(100vh - 132px);
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
@@ -364,7 +366,7 @@ const handleDetail = (item,type) =>{
|
||||
width:525rpx
|
||||
}
|
||||
.r-left .r-l-left{
|
||||
width:370rpx;
|
||||
width:350rpx;
|
||||
}
|
||||
.r-left .r-l-right{
|
||||
|
||||
|
||||
@@ -283,12 +283,4 @@ export const compressImageUni = (file) => {
|
||||
console.log('压缩失败:', error);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取minio缩略图地址
|
||||
export function getMinioThumbUrl(ossObj,path){
|
||||
let baseUrl = process.env.VUE_APP_MINIO?process.env.VUE_APP_MINIO:'';
|
||||
// let replaceStr="http://"+ossObj.clientObj.url+":"+ossObj.clientObj.port+"/new-gd-manager"
|
||||
// let thumbUrl = path.replace(replaceStr,baseUrl+'/thumb/new-gd-manager');
|
||||
return {baseUrl}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
// 包路径
|
||||
const package_NdefRecord = 'android.nfc.NdefRecord';
|
||||
const package_NdefMessage = 'android.nfc.NdefMessage';
|
||||
const package_TECH_DISCOVERED = 'android.nfc.action.TECH_DISCOVERED';
|
||||
const package_Intent = 'android.content.Intent';
|
||||
const package_Activity = 'android.app.Activity';
|
||||
const package_PendingIntent = 'android.app.PendingIntent';
|
||||
const package_IntentFilter = 'android.content.IntentFilter';
|
||||
const package_NfcAdapter = 'android.nfc.NfcAdapter';
|
||||
const package_Ndef = 'android.nfc.tech.Ndef';
|
||||
const package_NdefFormatable = 'android.nfc.tech.NdefFormatable';
|
||||
const package_Parcelable = 'android.os.Parcelable';
|
||||
const package_String = 'java.lang.String';
|
||||
|
||||
let NfcAdapter;
|
||||
let NdefRecord;
|
||||
let NdefMessage;
|
||||
let readyRead = true; //开启读
|
||||
let noNFC = false;
|
||||
let techListsArray = [
|
||||
['android.nfc.tech.IsoDep'],
|
||||
['android.nfc.tech.NfcA'],
|
||||
['android.nfc.tech.NfcB'],
|
||||
['android.nfc.tech.NfcF'],
|
||||
['android.nfc.tech.Nfcf'],
|
||||
['android.nfc.tech.NfcV'],
|
||||
['android.nfc.tech.NdefFormatable'],
|
||||
['android.nfc.tech.MifareClassi'],
|
||||
['android.nfc.tech.MifareUltralight']
|
||||
];
|
||||
// 要写入的数据
|
||||
// let text = '{id:8888,name:nfc,stie:wangqin.com}';
|
||||
// let readResult = '';
|
||||
|
||||
export default {
|
||||
listenNFCStatus() {
|
||||
console.log("---------listenNFCStatus--------------")
|
||||
let that = this;
|
||||
try {
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let Intent = plus.android.importClass('android.content.Intent');
|
||||
let Activity = plus.android.importClass('android.app.Activity');
|
||||
let PendingIntent = plus.android.importClass('android.app.PendingIntent');
|
||||
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
|
||||
NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
|
||||
let nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
||||
console.log("nfcAdapter=>",nfcAdapter)
|
||||
if (nfcAdapter == null) {
|
||||
uni.showToast({
|
||||
title: '设备不支持NFC!',
|
||||
icon: 'none'
|
||||
})
|
||||
noNFC = true;
|
||||
return;
|
||||
}
|
||||
if (!nfcAdapter.isEnabled()) {
|
||||
uni.showToast({
|
||||
title: '请在系统设置中先启用NFC功能!',
|
||||
icon: 'none'
|
||||
});
|
||||
noNFC = true;
|
||||
return;
|
||||
} else {
|
||||
noNFC = false;
|
||||
}
|
||||
console.log("nfcAdapter=>noNFC=>",noNFC)
|
||||
let intent = new Intent(main, main.getClass());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
let pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);
|
||||
let ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
|
||||
ndef.addDataType("*/*");
|
||||
let intentFiltersArray = [ndef];
|
||||
|
||||
//重点部分代码
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
plus.globalEvent.addEventListener('newintent', function () {
|
||||
// 轮询调用 NFC
|
||||
// setTimeout(that.nfcRuning(resolve), 1000);
|
||||
setTimeout(() => {
|
||||
that.nfcRuning(resolve)
|
||||
}, 1000);
|
||||
});
|
||||
})
|
||||
|
||||
nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
|
||||
return promise
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
nfcRuning(resolve){
|
||||
console.log("--------------nfcRuning---------------")
|
||||
NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
|
||||
NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let intent = main.getIntent(); console.log("intent=>",intent)
|
||||
let that = this;
|
||||
if (package_TECH_DISCOVERED == intent.getAction()) {
|
||||
if (readyRead) {
|
||||
//这里通过read方法拿到NFC数据
|
||||
const id = that.read(intent);
|
||||
console.log("nfcRuning=>",id)
|
||||
// readyRead = false;
|
||||
//将数据返回出去
|
||||
resolve(id)
|
||||
}
|
||||
}
|
||||
},
|
||||
read(intent) {
|
||||
// toast('请勿移开标签正在读取数据');
|
||||
let that = this;
|
||||
// NFC id
|
||||
let bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
|
||||
let nfc_id = that.byteArrayToHexString(bytesId);
|
||||
|
||||
return nfc_id;
|
||||
},
|
||||
byteArrayToHexString(inarray){ // converts byte arrays to string
|
||||
let i, j, inn;
|
||||
let hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
|
||||
let out = "";
|
||||
|
||||
for (j = 0; j < inarray.length; ++j) {
|
||||
inn = inarray[j] & 0xff;
|
||||
i = (inn >>> 4) & 0x0f;
|
||||
out += hex[i];
|
||||
i = inn & 0x0f;
|
||||
out += hex[i];
|
||||
}
|
||||
return out;
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
function toast(content) {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user