| | |
| | | <template>
|
| | | <view class="main_app">
|
| | | <view class="head_bg"></view>
|
| | | <view class="info"> |
| | | <image v-if="true" class="icon" src="@/static/side/ic_dabiaoed.png" mode=""></image> |
| | | <image v-else class="icon" src="@/static/side/ic_dabiao.png" mode=""></image>
|
| | | <view v-if="info.status || info.status == 0" class="head_bg" :style="{
|
| | | background: `linear-gradient(180deg, ${statusM[info.status].color} 0%, rgba(247, 247, 247, 0) 100%)`
|
| | | }"></view>
|
| | | <view class="info">
|
| | | <image v-if="info.status == 2" class="icon" src="@/static/side/ic_dabiaoed.png" mode=""></image>
|
| | | <image v-if="info.status == 3" class="icon" src="@/static/side/ic_dabiao.png" mode=""></image>
|
| | | <view class="head">
|
| | | <view class="name">巡检计划</view>
|
| | | <view class="status">待开始</view>
|
| | | <view class="name">{{ info.title || info.planTitle }}</view>
|
| | | <view class="status" v-if="info.status || info.status == 0" :style="{color: statusM[info.status].color}">
|
| | | {{statusM[info.status].name}}
|
| | | </view>
|
| | | </view>
|
| | | <view class="line">
|
| | | <view class="la">任务日期:</view>
|
| | | <view class="val">2023-23-23</view>
|
| | | <view class="val" v-if="info.startDate">{{ info.startDate.slice(0, 10) }}</view>
|
| | | </view>
|
| | | <view class="line">
|
| | | <view class="la">执行时间:</view>
|
| | | <view class="val">2023-23-23</view>
|
| | | <view class="val" v-if="info.startDate && info.endDate">{{ info.startDate.slice(11,16) }} 至
|
| | | {{ info.endDate.slice(11, 16) }}
|
| | | </view>
|
| | | </view>
|
| | | <view class="line">
|
| | | <view class="la">完成情况:</view>
|
| | | <view class="val">2023-23-23</view>
|
| | | <view class="val">{{info.finishNum || 0}}/{{info.patrolNum}}</view>
|
| | | </view>
|
| | | </view>
|
| | | <view class="title">巡检点列表(1)</view>
|
| | | <view class="title">巡检点列表({{list.length}})</view>
|
| | | <view class="list">
|
| | | <view class="item" v-for="i in 10" @click="itemClick()">
|
| | | <view class="item" v-for="item in list" @click="itemClick(item)">
|
| | | <view class="icon"></view>
|
| | | <view class="content">
|
| | | <view class="head">
|
| | | <view>巡检点10</view>
|
| | | <view class="status">待巡检</view>
|
| | | <view>{{item.pointName}}</view>
|
| | | <view class="status" :class="{ gray: item.status == 1 }"> |
| | | <image v-if="item.status == 1" src="@/static/plan_ic_finish@2x.png" class="icon" mode=""></image> |
| | | <text>{{ item.status == 1 ? '已巡检' : '待巡检' }}</text> |
| | | </view>
|
| | | </view>
|
| | | <view class="desc">巡检内容最多展示两行,多的省略巡检内容最多展示两行,多的省略巡检内容最多展示两行,多的省略巡检内容最多展示两行,多的省略巡检内容最多展示两行,多的省略巡检内容最多展示两行,多的省略
|
| | | </view>
|
| | | <template v-if="item.status == 1">
|
| | | <view class="line">
|
| | | <view class="la">巡检结果:</view>
|
| | | <view class="val" :class="{ red: item.dealStatus == 1 }">{{ item.dealStatus == 0 ? '正常' : '异常' }}</view>
|
| | | </view>
|
| | | <view class="line">
|
| | | <view class="la">巡检时间:</view>
|
| | | <view class="val"> |
| | | <text>{{item.dealDate}}</text> |
| | | <text v-if="item.status == 1" class="detail">查看详情</text> |
| | | </view>
|
| | | </view>
|
| | | </template>
|
| | | <view class="desc" v-else>{{item.content}}</view>
|
| | | </view>
|
| | | </view>
|
| | | </view>
|
| | | <view class="footer"> |
| | | <view class="sub_btn">扫码巡检</view> |
| | | <view class="footer" @click="openSc" v-if="flag">
|
| | | <view class="sub_btn">扫码巡检</view>
|
| | | </view> |
| | | <!-- --> |
| | | <view class="reader-box" @click="stopScan" v-if="isScaning"> |
| | | <view class="reader" id="reader"></view> |
| | | </view>
|
| | | </view>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import {
|
| | | ywPatrolDetail,
|
| | | ywPatrolTaskRecord, |
| | | getPointRecordByCode
|
| | | } from '@/api'
|
| | | import dayjs from 'dayjs';
|
| | | import {
|
| | | Html5Qrcode
|
| | | } from 'html5-qrcode';
|
| | | export default {
|
| | | data() {
|
| | | return {
|
| | |
|
| | | id: '',
|
| | | info: {},
|
| | | list: [],
|
| | | flag: false,
|
| | | statusM: [{
|
| | | color: '#4593f7',
|
| | | name: '待开始'
|
| | | },
|
| | | {
|
| | | color: '#73e09a',
|
| | | name: '进行中'
|
| | | },
|
| | | {
|
| | | color: '#f1a93f',
|
| | | name: '已超期'
|
| | | },
|
| | | {
|
| | | color: '#b9b9b9',
|
| | | name: '已处理'
|
| | | },
|
| | | ],
|
| | | html5Qrcode: null,
|
| | | isScaning: false,
|
| | | };
|
| | | }, |
| | | methods: { |
| | | itemClick() { |
| | | uni.navigateTo({ |
| | | url: '/pages/polling/point' |
| | | }) |
| | | } |
| | | },
|
| | | onLoad(option) {
|
| | | this.id = option.id
|
| | | // this.getDetail()
|
| | | },
|
| | | onShow() {
|
| | | this.getDetail()
|
| | | },
|
| | | methods: {
|
| | | openSc() {
|
| | | this.isScaning = true;
|
| | | Html5Qrcode.getCameras().then((devices) => {
|
| | | if (devices && devices.length) {
|
| | | this.html5Qrcode = new Html5Qrcode('reader');
|
| | | this.html5Qrcode.start({
|
| | | facingMode: 'environment'
|
| | | }, {
|
| | | focusMode: 'continuous', //设置连续聚焦模式
|
| | | fps: 5, //设置扫码识别速度
|
| | | qrbox: 280 //设置二维码扫描框大小
|
| | | },
|
| | | (decodeText, decodeResult) => {
|
| | | if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容
|
| | | this.stopScan(); //关闭扫码功能
|
| | | getPointRecordByCode({
|
| | | taskId: this.id,
|
| | | pointCode: decodeText
|
| | | }).then(ress => {
|
| | | if (ress.data) {
|
| | | uni.navigateTo({
|
| | | url: '/pages/polling/point?id=' + ress.data.id
|
| | | })
|
| | | } else {
|
| | | this.showToast('未匹配到巡检点,请重新扫描')
|
| | | }
|
| | | })
|
| | | }
|
| | | },
|
| | | (err) => {
|
| | | // console.log(err); //错误信息
|
| | | }
|
| | | );
|
| | | }
|
| | | });
|
| | | },
|
| | |
|
| | | stopScan() {
|
| | | console.log('停止扫码')
|
| | | this.isScaning = false;
|
| | | if (this.html5Qrcode) {
|
| | | this.html5Qrcode.stop();
|
| | | }
|
| | | },
|
| | | itemClick(item) {
|
| | | if (!this.flag) return
|
| | | uni.navigateTo({
|
| | | url: '/pages/polling/point?id=' + item.id
|
| | | })
|
| | | },
|
| | | getDetail() {
|
| | | const {
|
| | | id
|
| | | } = this
|
| | | ywPatrolDetail(id).then(res => {
|
| | | this.info = res.data
|
| | | let time = new Date(res.data.startDate).getTime()
|
| | | console.log('res.data.startDate', new Date().getTime());
|
| | | this.flag = new Date().getTime() > time && (this.info.status == 0 || this.info.status == 1)
|
| | | })
|
| | | ywPatrolTaskRecord({
|
| | | capacity: 999,
|
| | | page: 1,
|
| | | model: {
|
| | | taskId: id
|
| | | }
|
| | | }).then(res => {
|
| | | this.list = res.data.records
|
| | | })
|
| | | },
|
| | | async startScan() {
|
| | | try {
|
| | | const video = document.getElementById('video');
|
| | | const stream = await navigator.mediaDevices.getUserMedia({
|
| | | video: {
|
| | | facingMode: "environment"
|
| | | }
|
| | | });
|
| | | video.srcObject = stream;
|
| | |
|
| | | // 使用 QrScanner 解析
|
| | | const qrScanner = new QrScanner(video, result => {
|
| | | alert(`扫描结果: ${result}`);
|
| | | qrScanner.stop(); // 停止扫码
|
| | | });
|
| | | qrScanner.start();
|
| | | } catch (err) {
|
| | | console.error('打开摄像头失败:', err);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | </script>
|
| | |
| | | padding: 30rpx;
|
| | |
|
| | | .head_bg {
|
| | | background: linear-gradient(180deg, #008BFF 0%, rgba(247, 247, 247, 0) 100%);
|
| | | // background: linear-gradient(180deg, #008BFF 0%, rgba(247, 247, 247, 0) 100%);
|
| | | height: 240rpx;
|
| | | width: 750rpx;
|
| | | position: absolute;
|
| | |
| | | padding: 30rpx 30rpx 10rpx;
|
| | | margin-bottom: 40rpx;
|
| | | background: linear-gradient(#FFFFFF 0%, #FFFFFF 48%, #F0F5FF 100%);
|
| | | position: relative; |
| | | .icon{ |
| | | position: absolute; |
| | | right: 30rpx; |
| | | bottom: 30rpx; |
| | | width: 160rpx; |
| | | height: 122rpx; |
| | | position: relative;
|
| | |
|
| | | .icon {
|
| | | position: absolute;
|
| | | right: 30rpx;
|
| | | bottom: 30rpx;
|
| | | width: 160rpx;
|
| | | height: 122rpx;
|
| | | }
|
| | |
|
| | | .head {
|
| | | display: flex;
|
| | | justify-content: space-between;
|
| | |
| | | .status {
|
| | | color: $primaryColor;
|
| | | }
|
| | | }
|
| | |
|
| | | .line {
|
| | | display: flex;
|
| | | margin-bottom: 20rpx;
|
| | |
|
| | | .la {
|
| | | color: #666666;
|
| | | .gray {
|
| | | color: gray;
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | .title {
|
| | |
| | | margin-bottom: 30rpx;
|
| | | }
|
| | |
|
| | | .list { |
| | | height: calc( 100vh - 720rpx ) ; |
| | | overflow: auto;
|
| | | .line {
|
| | | display: flex;
|
| | | margin-bottom: 20rpx;
|
| | |
|
| | | .la {
|
| | | color: #666666; |
| | | |
| | | }
|
| | | }
|
| | |
|
| | | .list {
|
| | | height: calc(100vh - 490rpx);
|
| | | overflow: auto; |
| | | padding-bottom: 160rpx;
|
| | | .item {
|
| | | width: 690rpx;
|
| | | height: 188rpx;
|
| | |
| | | display: flex;
|
| | | padding: 20rpx 30rpx 0 16rpx;
|
| | | margin-bottom: 20rpx;
|
| | |
|
| | | .line {
|
| | | margin-bottom: 10rpx; |
| | | width: 100%; |
| | | .val{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | flex: 1; |
| | | .detail{ |
| | | color: $primaryColor; |
| | | font-size: 26rpx; |
| | | } |
| | | }
|
| | | }
|
| | |
|
| | | .icon {
|
| | | width: 10rpx;
|
| | |
| | | margin-bottom: 16rpx;
|
| | |
|
| | | .status {
|
| | | offset-anchor: 28rpx;
|
| | | font-size: 28rpx;
|
| | | color: $primaryColor;
|
| | | font-weight: 400;
|
| | | font-weight: 400; |
| | | display: flex; |
| | | align-items: center; |
| | | .icon{ |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | | // border-radius: 50%; |
| | | // overflow: hidden; |
| | | background: none; |
| | | } |
| | | |
| | | }
|
| | |
|
| | | .gray {
|
| | | color: #999999;
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | | .footer{ |
| | | position: fixed; |
| | | bottom: 0rpx; |
| | | left: 0rpx; |
| | | width: 750rpx; |
| | | height: 172rpx; |
| | | background-color: #fff; |
| | | padding: 20rpx 40rpx; |
| | | .sub_btn { |
| | | |
| | | width: 670rpx; |
| | | height: 88rpx; |
| | | background: $primaryColor; |
| | | box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3); |
| | | border-radius: 44rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-weight: 500; |
| | | font-size: 32rpx; |
| | | color: #FFFFFF; |
| | | } |
| | |
|
| | | .footer {
|
| | | position: fixed;
|
| | | bottom: 0rpx;
|
| | | left: 0rpx;
|
| | | width: 750rpx;
|
| | | height: 172rpx;
|
| | | background-color: #fff;
|
| | | padding: 20rpx 40rpx;
|
| | |
|
| | | .sub_btn {
|
| | |
|
| | | width: 670rpx;
|
| | | height: 88rpx;
|
| | | background: $primaryColor;
|
| | | box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3);
|
| | | border-radius: 44rpx;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | font-weight: 500;
|
| | | font-size: 32rpx;
|
| | | color: #FFFFFF;
|
| | | }
|
| | | }
|
| | | |
| | |
|
| | | }
|
| | | |
| | | .reader-box { |
| | | position: fixed; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | } |
| | | |
| | | .reader { |
| | | width: 100%; |
| | | // width: 540rpx; |
| | | // height: 540rpx; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | } |
| | | </style> |