This commit is contained in:
xuli
2025-11-28 16:42:57 +08:00
parent c8ad7a076c
commit 5d2472eac5
16 changed files with 770 additions and 521 deletions

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

View File

@@ -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" : ""
}
}
}
}
}
},

View File

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

View File

@@ -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;
})

View File

@@ -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;
}

View File

@@ -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
});
});

View File

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

View File

@@ -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();
})

View File

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

View File

@@ -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-问题详情

View File

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

View File

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

View File

@@ -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'
})
}