Browse Source

巡检

master
wwp 3 weeks ago
parent
commit
d9411709c2
11 changed files with 2240 additions and 556 deletions
  1. +533
    -0
      monitorMobile/components/DomVideoPlayer/DomVideoPlayer.vue
  2. +18
    -0
      monitorMobile/pages.json
  3. +600
    -0
      monitorMobile/pages/earlyWarning/components/inspectionCenter.vue
  4. +641
    -0
      monitorMobile/pages/earlyWarning/components/warningInfo.vue
  5. +292
    -0
      monitorMobile/pages/earlyWarning/detail.vue
  6. +78
    -0
      monitorMobile/pages/earlyWarning/handlingSuggestions.vue
  7. +14
    -556
      monitorMobile/pages/earlyWarning/index.vue
  8. +64
    -0
      monitorMobile/pages/earlyWarning/processingResults.vue
  9. BIN
      monitorMobile/static/image/earlyWarning/falid.png
  10. BIN
      monitorMobile/static/image/earlyWarning/school.png
  11. BIN
      monitorMobile/static/image/earlyWarning/success.png

+ 533
- 0
monitorMobile/components/DomVideoPlayer/DomVideoPlayer.vue View File

@@ -0,0 +1,533 @@
<!-- eslint-disable -->
<template>
<view
class="player-wrapper"
:id="videoWrapperId"
:parentId="id"
:randomNum="randomNum"
:change:randomNum="domVideoPlayer.randomNumChange"
:viewportProps="viewportProps"
:change:viewportProps="domVideoPlayer.viewportChange"
:videoSrc="videoSrc"
:change:videoSrc="domVideoPlayer.initVideoPlayer"
:command="eventCommand"
:change:command="domVideoPlayer.triggerCommand"
:func="renderFunc"
:change:func="domVideoPlayer.triggerFunc"
/>
</template>

<script>
export default {
props: {
src: {
type: String,
default: ''
},
autoplay: {
type: Boolean,
default: false
},
loop: {
type: Boolean,
default: false
},
controls: {
type: Boolean,
default: false
},
objectFit: {
type: String,
default: 'contain'
},
muted: {
type: Boolean,
default: false
},
playbackRate: {
type: Number,
default: 1
},
isLoading: {
type: Boolean,
default: false
},
poster: {
type: String,
default: ''
},
id: {
type: String,
default: ''
}
},
data() {
return {
randomNum: Math.floor(Math.random() * 100000000),
videoSrc: '',
// 父组件向子组件传递的事件指令(video的原生事件)
eventCommand: null,
// 父组件传递过来的,对 renderjs 层的函数执行(对视频控制的自定义事件)
renderFunc: {
name: null,
params: null
},
// 提供给父组件进行获取的视频属性
currentTime: 0,
duration: 0,
playing: false
}
},
watch: {
// 监听视频资源地址更新
src: {
handler(val) {
if (!val) return
setTimeout(() => {
this.videoSrc = val
}, 0)
},
immediate: true
}
},
computed: {
videoWrapperId() {
return `video-wrapper-${this.randomNum}`
},
// 聚合视图层的所有数据变化,传给renderjs的渲染层
viewportProps() {
return {
autoplay: this.autoplay,
muted: this.muted,
controls: this.controls,
loop: this.loop,
objectFit: this.objectFit,
poster: this.poster,
isLoading: this.isLoading,
playbackRate: this.playbackRate
}
}
},
// 方法
methods: {
// 传递事件指令给父组件
eventEmit({ event, data }) {
this.$emit(event, data)
},
// 修改view视图层的data数据
setViewData({ key, value }) {
key && this.$set(this, key, value)
},
// 重置事件指令
resetEventCommand() {
this.eventCommand = null
},
// 播放指令
play() {
this.eventCommand = 'play'
},
// 暂停指令
pause() {
this.eventCommand = 'pause'
},
// 重置自定义函数指令
resetFunc() {
this.renderFunc = {
name: null,
params: null
}
},
// 自定义函数 - 移除视频
remove(params) {
this.renderFunc = {
name: 'removeHandler',
params
}
},
// 自定义函数 - 全屏播放
fullScreen(params) {
this.renderFunc = {
name: 'fullScreenHandler',
params
}
},
// 自定义函数 - 跳转到指定时间点
toSeek(sec, isDelay = false) {
this.renderFunc = {
name: 'toSeekHandler',
params: { sec, isDelay }
}
}
}
}
</script>


<script module="domVideoPlayer" lang="renderjs">
const PLAYER_ID = 'DOM_VIDEO_PLAYER'
export default {
data() {
return {
num: '',
videoEl: null,
loadingEl: null,
// 延迟生效的函数
delayFunc: null,
renderProps: {}
}
},
computed: {
playerId() {
return `${PLAYER_ID}_${this.num}`
},
wrapperId() {
return `video-wrapper-${this.num}`
}
},
methods: {
isApple() {
const ua = navigator.userAgent.toLowerCase()
return ua.indexOf('iphone') !== -1 || ua.indexOf('ipad') !== -1
},
async initVideoPlayer(src) {
this.delayFunc = null
await this.$nextTick()
if (!src) return
if (this.videoEl) {
// 切换视频源
if (!this.isApple() && this.loadingEl) {
this.loadingEl.style.display = 'block'
}
this.videoEl.src = src
return
}

const videoEl = document.createElement('video')
this.videoEl = videoEl
// 开始监听视频相关事件
this.listenVideoEvent()

const { autoplay, muted, controls, loop, playbackRate, objectFit, poster } = this.renderProps
videoEl.src = src
videoEl.autoplay = autoplay
videoEl.controls = controls
videoEl.loop = loop
videoEl.muted = muted
videoEl.playbackRate = playbackRate
videoEl.id = this.playerId
// videoEl.setAttribute('x5-video-player-type', 'h5')
videoEl.setAttribute('preload', 'auto')
videoEl.setAttribute('playsinline', true)
videoEl.setAttribute('webkit-playsinline', true)
videoEl.setAttribute('crossorigin', 'anonymous')
videoEl.setAttribute('controlslist', 'nodownload')
videoEl.setAttribute('disablePictureInPicture', true)
videoEl.style.objectFit = objectFit
poster && (videoEl.poster = poster)
videoEl.style.width = '100%'
videoEl.style.height = '100%'

// 插入视频元素
// document.getElementById(this.wrapperId).appendChild(videoEl)
const playerWrapper = document.getElementById(this.wrapperId)
playerWrapper.insertBefore(videoEl, playerWrapper.firstChild)

// 插入loading 元素(遮挡安卓的默认加载过程中的黑色播放按钮)
this.createLoading()
},
// 创建 loading
createLoading() {
const { isLoading } = this.renderProps
if (!this.isApple() && isLoading) {
const loadingEl = document.createElement('div')
this.loadingEl = loadingEl
loadingEl.className = 'loading-wrapper'
loadingEl.style.position = 'absolute'
loadingEl.style.top = '0'
loadingEl.style.left = '0'
loadingEl.style.zIndex = '1'
loadingEl.style.width = '100%'
loadingEl.style.height = '100%'
loadingEl.style.backgroundColor = 'black'
document.getElementById(this.wrapperId).appendChild(loadingEl)

// 创建 loading 动画
const animationEl = document.createElement('div')
animationEl.className = 'loading'
animationEl.style.zIndex = '2'
animationEl.style.position = 'absolute'
animationEl.style.top = '50%'
animationEl.style.left = '50%'
animationEl.style.marginTop = '-15px'
animationEl.style.marginLeft = '-15px'
animationEl.style.width = '30px'
animationEl.style.height = '30px'
animationEl.style.border = '2px solid #FFF'
animationEl.style.borderTopColor = 'rgba(255, 255, 255, 0.2)'
animationEl.style.borderRightColor = 'rgba(255, 255, 255, 0.2)'
animationEl.style.borderBottomColor = 'rgba(255, 255, 255, 0.2)'
animationEl.style.borderRadius = '100%'
animationEl.style.animation = 'circle infinite 0.75s linear'
loadingEl.appendChild(animationEl)

// 创建 loading 动画所需的 keyframes
const style = document.createElement('style')
const keyframes = `
@keyframes circle {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
`
style.type = 'text/css'
if (style.styleSheet) {
style.styleSheet.cssText = keyframes
} else {
style.appendChild(document.createTextNode(keyframes))
}
document.head.appendChild(style)
}
},
// 监听视频相关事件
listenVideoEvent() {
// 播放事件监听
const playHandler = () => {
this.$ownerInstance.callMethod('eventEmit', { event: 'play' })
this.$ownerInstance.callMethod('setViewData', {
key: 'playing',
value: true
})

if (this.loadingEl) {
this.loadingEl.style.display = 'none'
}
}
this.videoEl.removeEventListener('play', playHandler)
this.videoEl.addEventListener('play', playHandler)

// 暂停事件监听
const pauseHandler = () => {
this.$ownerInstance.callMethod('eventEmit', { event: 'pause' })
this.$ownerInstance.callMethod('setViewData', {
key: 'playing',
value: false
})
}
this.videoEl.removeEventListener('pause', pauseHandler)
this.videoEl.addEventListener('pause', pauseHandler)

// 结束事件监听
const endedHandler = () => {
this.$ownerInstance.callMethod('eventEmit', { event: 'ended' })
this.$ownerInstance.callMethod('resetEventCommand')
}
this.videoEl.removeEventListener('ended', endedHandler)
this.videoEl.addEventListener('ended', endedHandler)

// 加载完成事件监听
const canPlayHandler = () => {
this.$ownerInstance.callMethod('eventEmit', { event: 'canplay' })
this.execDelayFunc()
}
this.videoEl.removeEventListener('canplay', canPlayHandler)
this.videoEl.addEventListener('canplay', canPlayHandler)

// 加载失败事件监听
const errorHandler = (e) => {
if (this.loadingEl) {
this.loadingEl.style.display = 'block'
}
this.$ownerInstance.callMethod('eventEmit', { event: 'error' })
}
this.videoEl.removeEventListener('error', errorHandler)
this.videoEl.addEventListener('error', errorHandler)

// loadedmetadata 事件监听
const loadedMetadataHandler = () => {
this.$ownerInstance.callMethod('eventEmit', { event: 'loadedmetadata' })
// 获取视频的长度
const duration = this.videoEl.duration
this.$ownerInstance.callMethod('eventEmit', {
event: 'durationchange',
data: duration
})

this.$ownerInstance.callMethod('setViewData', {
key: 'duration',
value: duration
})

// 加载首帧视频 模拟出封面图
this.loadFirstFrame()
}
this.videoEl.removeEventListener('loadedmetadata', loadedMetadataHandler)
this.videoEl.addEventListener('loadedmetadata', loadedMetadataHandler)

// 播放进度监听
const timeupdateHandler = (e) => {
const currentTime = e.target.currentTime
this.$ownerInstance.callMethod('eventEmit', {
event: 'timeupdate',
data: currentTime
})

this.$ownerInstance.callMethod('setViewData', {
key: 'currentTime',
value: currentTime
})

}
this.videoEl.removeEventListener('timeupdate', timeupdateHandler)
this.videoEl.addEventListener('timeupdate', timeupdateHandler)

// 倍速播放监听
const ratechangeHandler = (e) => {
const playbackRate = e.target.playbackRate
this.$ownerInstance.callMethod('eventEmit', {
event: 'ratechange',
data: playbackRate
})
}
this.videoEl.removeEventListener('ratechange', ratechangeHandler)
this.videoEl.addEventListener('ratechange', ratechangeHandler)

// 全屏事件监听
if (this.isApple()) {
const webkitbeginfullscreenHandler = () => {
const presentationMode = this.videoEl.webkitPresentationMode
let isFullScreen = null
if (presentationMode === 'fullscreen') {
isFullScreen = true
} else {
isFullScreen = false
}
this.$ownerInstance.callMethod('eventEmit', {
event: 'fullscreenchange',
data: isFullScreen
})
}
this.videoEl.removeEventListener('webkitpresentationmodechanged', webkitbeginfullscreenHandler)
this.videoEl.addEventListener('webkitpresentationmodechanged', webkitbeginfullscreenHandler)
} else {
const fullscreenchangeHandler = () => {
let isFullScreen = null
if (document.fullscreenElement) {
isFullScreen = true
} else {
isFullScreen = false
}
this.$ownerInstance.callMethod('eventEmit', {
event: 'fullscreenchange',
data: isFullScreen
})
}
document.removeEventListener('fullscreenchange', fullscreenchangeHandler)
document.addEventListener('fullscreenchange', fullscreenchangeHandler)
}
},
// 加载首帧视频,模拟出封面图
loadFirstFrame() {
let { autoplay, muted } = this.renderProps
if (this.isApple()) {
this.videoEl.play()
if (!autoplay) {
this.videoEl.pause()
}
} else {
// optimize: timeout 延迟调用是为了规避控制台的`https://goo.gl/LdLk22`这个报错
/**
* 原因:chromium 内核中,谷歌协议规定,视频不允许在非静音状态下进行自动播放
* 解决:在自动播放时,先将视频静音,然后延迟调用 play 方法,播放视频
* 说明:iOS 的 Safari 内核不会有这个,仅在 Android 设备出现,即使有这个报错也不影响的,所以不介意控制台报错的话是可以删掉这个 timeout 的
*/
this.videoEl.muted = true
setTimeout(() => {
this.videoEl.play()
this.videoEl.muted = muted
if (!autoplay) {
setTimeout(() => {
this.videoEl.pause()
}, 100)
}
}, 10)
}
},
triggerCommand(eventType) {
if (eventType) {
this.$ownerInstance.callMethod('resetEventCommand')
this.videoEl && this.videoEl[eventType]()
}
},
triggerFunc(func) {
const { name, params } = func || {}
if (name) {
this[name](params)
this.$ownerInstance.callMethod('resetFunc')
}
},
removeHandler() {
if (this.videoEl) {
this.videoEl.pause()
this.videoEl.src = ''
this.$ownerInstance.callMethod('setViewData', {
key: 'videoSrc',
value: ''
})
this.videoEl.load()
}
},
fullScreenHandler() {
if (this.isApple()) {
this.videoEl.webkitEnterFullscreen()
} else {
this.videoEl.requestFullscreen()
}
},
toSeekHandler({ sec, isDelay }) {
const func = () => {
if (this.videoEl) {
this.videoEl.currentTime = sec
}
}

// 延迟执行
if (isDelay) {
this.delayFunc = func
} else {
func()
}
},
// 执行延迟函数
execDelayFunc() {
this.delayFunc && this.delayFunc()
this.delayFunc = null
},
viewportChange(props) {
this.renderProps = props
const { autoplay, muted, controls, loop, playbackRate } = props
if (this.videoEl) {
this.videoEl.autoplay = autoplay
this.videoEl.controls = controls
this.videoEl.loop = loop
this.videoEl.muted = muted
this.videoEl.playbackRate = playbackRate
}
},
randomNumChange(val) {
this.num = val
}
}
}
</script>

<style scoped>
.player-wrapper {
overflow: hidden;
height: 100%;
padding: 0;
position: relative;
}
</style>

+ 18
- 0
monitorMobile/pages.json View File

@@ -110,6 +110,24 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "pages/earlyWarning/detail",
"style": {
"navigationBarTitleText": "查看详情"
}
},
{
"path": "pages/earlyWarning/handlingSuggestions",
"style": {
"navigationBarTitleText": "处理意见"
}
},
{
"path": "pages/earlyWarning/processingResults",
"style": {
"navigationBarTitleText": "处理结果"
}
},
// 我的 // 我的
{ {
"path": "pages/my/index", "path": "pages/my/index",


+ 600
- 0
monitorMobile/pages/earlyWarning/components/inspectionCenter.vue View File

@@ -0,0 +1,600 @@
<template>
<view class="inspectionCenter">
<view class="searchBox">
<view class="searchLine">
<view class="leftSearchBox">
<view class="searchLabel">
筛选条件:
</view>
<view class="searchValue">

</view>
</view>
<view class="searchShow" @click="openSearch">
<image v-show="isShowSearch==false" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screen.png" mode="">
</image>
<image v-show="isShowSearch" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screenActive.png" mode="">
</image>
</view>
</view>
<view @click="isShowSearch=false" class="searchDialog" v-if="isShowSearch">
<view class="content" @click.stop="isSelect">
<u-row justify="space-between" gutter="10">
<u-col span="7">
<view class="demo-layout" @click="toOpen">
<view class="left-layout">
<text>{{searchForm.alarmType}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>

<!-- <jp-select-plus ref="selectPlus" :isShow="false" color="#2388FF" placeholder="请选择"
isSearch v-model="va3" :list="listc"></jp-select-plus> -->
</u-col>
<u-col span="5">
<view class="demo-layout" @click="toOpenSelect">
<view class="left-layout">
<text>{{searchForm.warnHand}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>
</u-col>
</u-row>
<u-row style="margin-top:10px;" justify="space-between" gutter="10">
<u-col span="12">
<uni-datetime-picker v-model="searchForm.tick" type="datetimerange">
<view class="demo-layout">
<view class="startBox">
{{searchForm.StartTick}}
</view>
<text>至</text>
<view class="endBox">
{{searchForm.EndTick}}
</view>
<view class="timeIcon">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/calendar.png" mode=""></image>
</view>
</view>
</uni-datetime-picker>

</u-col>
</u-row>
<view class="btnBox">
<view class="leftBtn">
重置
</view>
<view class="rightBtn">
确认
</view>
</view>
</view>
</view>

</view>
<view class="tableBox">
<u-empty marginTop="100rpx" :show="false" mode="warnList" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
<u-list-item v-for="(item, index) in warnList" :key="index">
<view class="liBox">
<view class="topCard">
<view class="pic">
<image src="@/static/image/earlyWarning/warnBack.png" mode="aspectFill"></image>
<view class="resolvingPower">
2560*1440
</view>
</view>
<view class="rightCard">
<view class="firstCard">
<view class="schoolName">
摄像头ID:SXT001
</view>
</view>
<view class="secondCard">

<view class="txt">
摄像头名称:厨房(良景)
</view>
</view>
<view class="thirdCard">

<view class="txt">
设备IP:192.168.10.130
</view>
</view>
</view>
</view>

<view class="btoCard">
<view class="leftBox btoBox">
<image src="@/static/image/earlyWarning/school.png" mode=""></image>
<view class="txt">
所属学校:演示学校
</view>
</view>
<view class="rightBox btoBox" @click="deleteClick">
<view class="txt">
播放
</view>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
</view>
<u-modal :show="showDelete" :title="deleteTitle" :showCancelButton="true" @confirm="confirmDelete"
@cancel="cancelDelete">
<view class="slot-content">
<text style="text-align: center;">是否确定删除该预警吗?</text>
</view>
</u-modal>
<selectSearch ref="selectSearchBox" :cellVisible="false" :value.sync="searchForm.alarmType"
:options="[{value:1,label:'qinshi1'},{value:2,label:'qinshi2'}]" title="预警类型" search-place-holder="预警类型" />
<selectRadio ref="selectRadioBox" :cellVisible="false" :value.sync="searchForm.warnHand"
:options="[{value:1,label:'loudong1'},{value:2,label:'loudong2'}]" title="楼栋" />
</view>
</template>

<script>
import selectRadio from "@/components/selectRadio.vue"
import selectSearch from "@/components/selectSearch.vue"
export default {
components: {
selectRadio,
selectSearch,

},
data() {
return {
showDelete: false,
deleteTitle: '提示',
deleteContent: '是否确定删除该预警吗?',
isShowSearch: false,
searchForm: {
alarmType: '警告类型',
warnHand: '处理状态',
tick: [],
StartTick: '开始时间',
EndTick: '结束时间',
},
warnList: [{
warnHand: 1
}, {
warnHand: 0
}, {
warnHand: 1
}, {
warnHand: 1
}, {
warnHand: 1
}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
listc: [{
code: 1,
name: 'dasda'
}, {
code: 2,
name: 'dasda'
},
{
code: 3,
name: 'dasda'
},
{
code: 4,
name: 'dasda'
},
{
code: 5,
name: 'dasda'
},
{
code: 6,
name: 'dasda'
},
{
code: 7,
name: 'dasda'
},
{
code: 8,
name: 'dasda'
},
{
code: 9,
name: 'dasda'
},
{
code: 10,
name: 'dasda'
},
{
code: 11,
name: 'dasda'
},
{
code: 12,
name: 'dasda'
},
{
code: 13,
name: '你好'
}
]
}
},
watch: {
"searchForm.tick"() {
console.log('日期时间:', this.searchForm.tick);

if (this.searchForm.tick && this.searchForm.tick.length > 0) {
this.searchForm.StartTick = this.searchForm.tick[0]
this.searchForm.EndTick = this.searchForm.tick[1]
}

},
},
filters: {
// statusChange(val) {
// switch (val) {
// case 'todo':
// return '我的待办'
// break;
// case 'send':
// return '由我发起'
// break;
// case 'done':
// return '我的已办'
// break;
// default:

// }
// },
},
onLoad() {
// 隐藏导航栏
this.loadmore()
},
methods: {
cancelDelete() {
this.showDelete = false;
},
deleteClick() {
this.showDelete = true;
},
confirmDelete() {
this.showDelete = false;
},
// 跳转处理页面
toHandle(row) {
if (row.warnHand == 1) {
uni.navigateTo({
url: '/pages/earlyWarning/handlingSuggestions'
});
}

},
// 跳转详情页面
toDetail(row) {
uni.navigateTo({
url: '/pages/earlyWarning/detail'
});
},
// 预警类型弹框筛选
toOpen() {
this.$refs.selectSearchBox.show = true;
},
// 处理情况筛选
toOpenSelect() {
this.$refs.selectRadioBox.show = true;
},
// 打开筛选框
openSearch() {
this.isShowSearch = !this.isShowSearch;
},
isSelect() {

},
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.warnList.push({}, {})
}
// 获取到的总条数>=接口总条数
if (this.warnList.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
}
}
}
</script>

<style lang="scss" scoped>
// .contentBox {
// height: calc(100% - 375rpx);
.inspectionCenter {
width: 100%;
height: 100%;

.u-modal__title {
color: #000000;
}
}

.searchBox {
// height: calc(100% - 360rpx);
position: relative;

.searchLine {
height: 88rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
background: #fff;

.leftSearchBox {
display: flex;
align-items: center;
width: calc(100% - 40px);

.searchLabel {
flex-shrink: 1;
color: #333333;
width: 80px;
}

.searchValue {
width: calc(100% - 60px);
margin-left: 10px;
color: #2388FF;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
}

.searchDialog {
position: absolute;
z-index: 990;
top: 89rpx;
width: 100%;
height: calc(100vh - 375rpx - 100rpx);
font-size: 26rpx;
background: rgba(0, 0, 0, 0.2);

.content {
background: #FFFFFF;
padding: 15px;
box-sizing: border-box;

.demo-layout {
height: 80rpx;
border-radius: 8rpx;
background: #F5F5F5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;

.left-layout {
color: #777777;
}

.right-layout {}

.startBox {
color: #777777;
}

text {
color: #777777;
}

.endBox {
color: #777777;
}

.timeIcon {}
}
}

.btnBox {
display: flex;
align-items: center;
margin-top: 15px;

.leftBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #BABABA;
border-radius: 12rpx;
color: #333333;
text-align: center;

}

.rightBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #2388FF;
border-radius: 12rpx;
color: #fff;
text-align: center;
background: #2388FF;
margin-left: 15rpx;
}
}
}
}

.tableBox {
height: 100%;
padding: 10px;
box-sizing: border-box;
// height: 600px;
padding-bottom: 50px;


.liBox {
background: #fff;
padding: 20px 15px;
box-sizing: border-box;
border-radius: 20px;
margin-bottom: 10px;

.topCard {
display: flex;

.pic {
position: relative;

image {
width: 310rpx;
height: 220rpx;
border-radius: 4px;
}

.resolvingPower {
position: absolute;
top: 15rpx;
right: 15rpx;
background: #000000;
color: #fff;
padding: 8rpx;
box-sizing: border-box;
font-size: 20rpx;
border-radius: 4rpx;
}
}

.rightCard {
margin-left: 20rpx;
margin-top: 15rpx;

.firstCard {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 60rpx;

.schoolName {
font-size: 32rpx;
font-weight: 700;
color: #333333;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}

.statusBox {
width: 140rpx;
flex-shrink: 1;
text-align: center;
height: 50rpx;
line-height: 50rpx;
font-size: 28rpx;
border-radius: 8rpx;
color: #fff;
}

.handle {
background: rgba(15, 175, 118, 0.1);
color: #0FAF76;
}

.nohandle {
background: rgba(239, 45, 45, 0.1);
color: rgba(239, 45, 45, 1);
}
}

.secondCard,
.thirdCard {
display: flex;
align-items: center;
margin-top: 18rpx;

.txt {
font-size: 28rpx;
color: #333333;
}
}
}
}

.midCard {
font-size: 28rpx;

.midContent {
margin-top: 18rpx;
}
}

.btoCard {
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin-top: 30rpx;
padding: 18px 0 0 0;
display: flex;
justify-content: space-between;
align-items: center;

.btoBox {
// width: 33.3%;
display: flex;
justify-content: center;
align-items: center;
position: relative;

image {
width: 40rpx;
height: 40rpx;
margin-right: 15rpx;
}
}

.rightBox {
width: 180rpx;
height: 74rpx;
background: #2388FF;
color: #fff;
border-radius: 80rpx;
}
}
}

}

// }
</style>

+ 641
- 0
monitorMobile/pages/earlyWarning/components/warningInfo.vue View File

@@ -0,0 +1,641 @@
<template>
<view class="warningInfo">
<view class="searchBox">
<view class="searchLine">
<view class="leftSearchBox">
<view class="searchLabel">
筛选条件:
</view>
<view class="searchValue">

</view>
</view>
<view class="searchShow" @click="openSearch">
<image v-show="isShowSearch==false" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screen.png" mode="">
</image>
<image v-show="isShowSearch" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screenActive.png" mode="">
</image>
</view>
</view>
<view @click="isShowSearch=false" class="searchDialog" v-if="isShowSearch">
<view class="content" @click.stop="isSelect">
<u-row justify="space-between" gutter="10">
<u-col span="7">
<view class="demo-layout" @click="toOpen">
<view class="left-layout">
<text>{{searchForm.alarmType}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>

<!-- <jp-select-plus ref="selectPlus" :isShow="false" color="#2388FF" placeholder="请选择"
isSearch v-model="va3" :list="listc"></jp-select-plus> -->
</u-col>
<u-col span="5">
<view class="demo-layout" @click="toOpenSelect">
<view class="left-layout">
<text>{{searchForm.warnHand}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>
</u-col>
</u-row>
<u-row style="margin-top:10px;" justify="space-between" gutter="10">
<u-col span="12">
<uni-datetime-picker v-model="searchForm.tick" type="datetimerange">
<view class="demo-layout">
<view class="startBox">
{{searchForm.StartTick}}
</view>
<text>至</text>
<view class="endBox">
{{searchForm.EndTick}}
</view>
<view class="timeIcon">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/calendar.png" mode=""></image>
</view>
</view>
</uni-datetime-picker>

</u-col>
</u-row>
<view class="btnBox">
<view class="leftBtn">
重置
</view>
<view class="rightBtn">
确认
</view>
</view>
</view>
</view>

</view>
<view class="tableBox">
<u-empty marginTop="100rpx" :show="false" mode="warnList" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
<u-list-item v-for="(item, index) in warnList" :key="index">
<view class="liBox">
<view class="topCard">
<view class="pic">
<image src="@/static/image/earlyWarning/warnBack.png" mode="aspectFill"></image>
</view>
<view class="rightCard">
<view class="firstCard">
<view class="schoolName">
学校名称学校名称学校名称学校名称
</view>
<view class="statusBox" :class="[item.warnHand == 1?'handle':'nohandle']">
{{item.warnHand == 1 ? '已处理' : '未处理'}}
</view>
</view>
<view class="secondCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnType.png" mode=""></image>
<view class="txt">
警告类型:周界入侵
</view>
</view>
<view class="thirdCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnVideo.png" mode=""></image>
<view class="txt">
警告摄像头:厨房(良景)
</view>
</view>
</view>
</view>
<view class="midCard">
<u-row>
<u-col span="6">
<view class="midContent">
姓名:杨云
</view>
</u-col>
<u-col span="6">
<view class="midContent">
系部:安环部
</view>
</u-col>
</u-row>
<u-row>
<u-col span="6">
<view class="midContent">
专业:环艺
</view>
</u-col>
<u-col span="6">
<view class="midContent">
班级:第二班
</view>
</u-col>
</u-row>
<u-row>
<u-col span="12">
<view class="midContent">
时间:2024-08-15 11:59:12
</view>
</u-col>
</u-row>
</view>
<view class="btoCard">
<view class="leftBox btoBox" @click="toDetail(item)">
<image src="@/static/image/earlyWarning/detail.png" mode=""></image>
<view class="txt">
查看
</view>
</view>
<view class="midBox btoBox" @click="toHandle(item)">
<image v-if="item.warnHand == 1" src="@/static/image/earlyWarning/handle.png" mode="">
</image>
<image v-if="item.warnHand == 0" src="@/static/image/earlyWarning/handleDisabled.png"
mode=""></image>
<view :class="[item.warnHand == 1?'txt':'disabled']">
处理
</view>
</view>
<view class="rightBox btoBox" @click="deleteClick">
<image src="@/static/image/earlyWarning/delete.png" mode=""></image>
<view class="txt">
删除
</view>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
</view>
<u-modal :show="showDelete" :title="deleteTitle" :showCancelButton="true" @confirm="confirmDelete"
@cancel="cancelDelete">
<view class="slot-content">
<text style="text-align: center;">是否确定删除该预警吗?</text>
</view>
</u-modal>
<selectSearch ref="selectSearchBox" :cellVisible="false" :value.sync="searchForm.alarmType"
:options="[{value:1,label:'qinshi1'},{value:2,label:'qinshi2'}]" title="预警类型" search-place-holder="预警类型" />
<selectRadio ref="selectRadioBox" :cellVisible="false" :value.sync="searchForm.warnHand"
:options="[{value:1,label:'loudong1'},{value:2,label:'loudong2'}]" title="楼栋" />
</view>
</template>

<script>
import selectRadio from "@/components/selectRadio.vue"
import selectSearch from "@/components/selectSearch.vue"
export default {
components: {
selectRadio,
selectSearch
},
data() {
return {
showDelete: false,
deleteTitle: '提示',
deleteContent: '是否确定删除该预警吗?',
isShowSearch: false,
searchForm: {
alarmType: '警告类型',
warnHand: '处理状态',
tick: [],
StartTick: '开始时间',
EndTick: '结束时间',
},
warnList: [{
warnHand: 1
}, {
warnHand: 0
}, {
warnHand: 1
}, {
warnHand: 1
}, {
warnHand: 1
}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
listc: [{
code: 1,
name: 'dasda'
}, {
code: 2,
name: 'dasda'
},
{
code: 3,
name: 'dasda'
},
{
code: 4,
name: 'dasda'
},
{
code: 5,
name: 'dasda'
},
{
code: 6,
name: 'dasda'
},
{
code: 7,
name: 'dasda'
},
{
code: 8,
name: 'dasda'
},
{
code: 9,
name: 'dasda'
},
{
code: 10,
name: 'dasda'
},
{
code: 11,
name: 'dasda'
},
{
code: 12,
name: 'dasda'
},
{
code: 13,
name: '你好'
}
]
}
},
watch: {
"searchForm.tick"() {
console.log('日期时间:', this.searchForm.tick);

if (this.searchForm.tick && this.searchForm.tick.length > 0) {
this.searchForm.StartTick = this.searchForm.tick[0]
this.searchForm.EndTick = this.searchForm.tick[1]
}

},
},
filters: {
// statusChange(val) {
// switch (val) {
// case 'todo':
// return '我的待办'
// break;
// case 'send':
// return '由我发起'
// break;
// case 'done':
// return '我的已办'
// break;
// default:

// }
// },
},
onLoad() {
// 隐藏导航栏
this.loadmore()
},
methods: {
cancelDelete() {
this.showDelete = false;
},
deleteClick() {
this.showDelete = true;
},
confirmDelete() {
this.showDelete = false;
},
// 跳转处理页面
toHandle(row) {
if (row.warnHand == 1) {
uni.navigateTo({
url: '/pages/earlyWarning/handlingSuggestions'
});
}

},
// 跳转详情页面
toDetail(row) {
uni.navigateTo({
url: '/pages/earlyWarning/detail'
});
},
// 预警类型弹框筛选
toOpen() {
this.$refs.selectSearchBox.show = true;
},
// 处理情况筛选
toOpenSelect() {
this.$refs.selectRadioBox.show = true;
},
// 打开筛选框
openSearch() {
this.isShowSearch = !this.isShowSearch;
},
isSelect() {

},
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.warnList.push({}, {})
}
// 获取到的总条数>=接口总条数
if (this.warnList.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
}
}
}
</script>

<style lang="scss" scoped>
// .contentBox {
// height: calc(100% - 375rpx);
.warningInfo {
width: 100%;
height: 100%;
.u-modal__title {
color: #000000;
}
}

.searchBox {
// height: calc(100% - 360rpx);
position: relative;

.searchLine {
height: 88rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
background: #fff;

.leftSearchBox {
display: flex;
align-items: center;
width: calc(100% - 40px);

.searchLabel {
flex-shrink: 1;
color: #333333;
width: 80px;
}

.searchValue {
width: calc(100% - 60px);
margin-left: 10px;
color: #2388FF;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
}

.searchDialog {
position: absolute;
z-index: 990;
top: 89rpx;
width: 100%;
height: calc(100vh - 375rpx - 100rpx);
font-size: 26rpx;
background: rgba(0, 0, 0, 0.2);

.content {
background: #FFFFFF;
padding: 15px;
box-sizing: border-box;

.demo-layout {
height: 80rpx;
border-radius: 8rpx;
background: #F5F5F5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;

.left-layout {
color: #777777;
}

.right-layout {}

.startBox {
color: #777777;
}

text {
color: #777777;
}

.endBox {
color: #777777;
}

.timeIcon {}
}
}

.btnBox {
display: flex;
align-items: center;
margin-top: 15px;

.leftBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #BABABA;
border-radius: 12rpx;
color: #333333;
text-align: center;

}

.rightBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #2388FF;
border-radius: 12rpx;
color: #fff;
text-align: center;
background: #2388FF;
margin-left: 15rpx;
}
}
}
}

.tableBox {
height: 100%;
padding: 10px;
box-sizing: border-box;
// height: 600px;
padding-bottom: 50px;


.liBox {
background: #fff;
padding: 20px 15px;
box-sizing: border-box;
border-radius: 20px;
margin-bottom: 10px;

.topCard {
display: flex;

.pic {

image {
width: 160rpx;
height: 160rpx;
border-radius: 4px;
}
}

.rightCard {
margin-left: 20rpx;

.firstCard {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;

.schoolName {
font-size: 32rpx;
font-weight: 700;
color: #333333;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}

.statusBox {
width: 140rpx;
flex-shrink: 1;
text-align: center;
height: 50rpx;
line-height: 50rpx;
font-size: 28rpx;
border-radius: 8rpx;
color: #fff;
}

.handle {
background: rgba(15, 175, 118, 0.1);
color: #0FAF76;
}

.nohandle {
background: rgba(239, 45, 45, 0.1);
color: rgba(239, 45, 45, 1);
}
}

.secondCard,
.thirdCard {
display: flex;
align-items: center;
margin-top: 18rpx;

.txt {
font-size: 28rpx;
margin-left: 10rpx;
color: #333333;
}
}
}
}

.midCard {
font-size: 28rpx;

.midContent {
margin-top: 18rpx;
}
}

.btoCard {
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin-top: 30rpx;
padding: 18px 0 0 0;
display: flex;
justify-content: center;
align-items: center;

.btoBox {
width: 33.3%;
display: flex;
justify-content: center;
align-items: center;
position: relative;

image {
width: 40rpx;
height: 40rpx;
margin-right: 15rpx;
}
}

.btoBox:not(:last-child)::before {
content: '';
display: block;
width: 1px;
height: 100%;
background: rgba(0, 0, 0, 0.1);
position: absolute;
right: 0px;
}

.midBox {
.txt {
color: #333333;
}

.disabled {
color: #777777;
}
}
}
}

}

// }
</style>

+ 292
- 0
monitorMobile/pages/earlyWarning/detail.vue View File

@@ -0,0 +1,292 @@
<template>
<view class="warningDetail">
<view class="title cli">
周界入侵-2024-08-20 18:01:41
</view>
<image style="width: 100%;" src="../../static/image/add.png" mode="widthFix"></image>
<view class="cli">
<view class="labelBox">
所属学校:
</view>
<view class="valueBox">
演示学校
</view>
</view>
<view class="cli">
<view class="labelBox">
班级:
</view>
<view class="valueBox">
暂无数据
</view>
</view>
<view class="cli">
<view class="labelBox">
告警摄像头:
</view>
<view class="valueBox">
演示学校
</view>
</view>
<view class="cli">
<view class="labelBox">
告警类型:
</view>
<view class="valueBox">
演示学校
</view>
</view>
<view class="cli">
<view class="labelBox">
告警时间:
</view>
<view class="valueBox">
2024-8-24 16:42:13
</view>
</view>
<view class="cli">
<view class="labelBox">
复核视频:
</view>
<view class="valueBox">
<text style="color: #2388FF;" @click="seeVideo">查看视频</text>
<text>暂无数据</text>
</view>
</view>
<view class="cli2">
<view class="labelBox">
备注信息:
</view>
<view class="valueBox">
11111111111111111111111111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa撒大大飒飒水水水水水水顶顶顶顶顶反对
</view>
</view>

<view class="cli2">
<view class="labelBox">
处理意见:
</view>
<view class="valueBox">
11111111111111111111111111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa撒大大飒飒水水水水水水顶顶顶顶顶反对
</view>
</view>
<u-popup :show="showVideo" :closeable="true" @close="close" @open="open" mode="center">
<!-- <view class="">
视频
</view> -->

<view class="poupBox">
<view style="width: 750rpx;height: 400rpx;">
<DomVideoPlayer ref="domVideoPlayer" object-fit='contain' :controls="controls" :autoplay="autoplay"
:loop="loop" :src="src" :playback-rate="playbackRate" :is-loading="isLoading" @play="onPlay"
@pause="onPause" @ended="onEnded" @durationchange="onDurationChange" @timeupdate="onTimeUpdate"
@ratechange="onRateChange" @fullscreenchange="onFullscreenChange" />
</view>
</view>
</u-popup>
</view>
</template>

<script>
import DomVideoPlayer from '@/components/DomVideoPlayer/DomVideoPlayer.vue'
// 将xx秒转为 xx:xx 分秒格式
const formatSec2Time = (time) => {
const min = Math.floor(time / 60)
const sec = Math.floor(time % 60)
return `${min}:${sec < 10 ? '0' + sec : sec}`
}
export default {
components: {
DomVideoPlayer
},
data() {
return {
value1: '',
showVideo: false,
// 视频参数
src: '',
// src: 'http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240708/video/wander/SXT001__quanjiang__DEMO00001_video_wm_1720400435638.mp4?Expires=1724745909&OSSAccessKeyId=STS.NV49VEGSbWMNi7Wp4e76VrWKk&Signature=wXTdiWQHGNp%2FtbtezUBmD%2Fziy1E%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5WBcuzxqoxD4I%2BlaxHmlDQwO7l6nZLgiTz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4zIJb0D10s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKRpnrU0rgxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39ax%2Bf3elrfsIeBqAAaamZEcVMZBN29tT2k9jMRQfJjNJzZRtx5Z4sYbOwDoRAq%2F4qEv07jBx5PUAAB3q9IqDapPoeUw8Yccvlo9q5VG8AsY%2BZkidTAw%2B7s7%2BTKuJC93tJfdSUYdycPZ%2BZneA%2BlZqpdvfhTtZCteGsdnoQU4H7x%2B9ph9K%2Bg3HGMQrtuFdIAA%3D',
playing: false,
loop: false,
controls: true,
autoplay: false,
isLoading: true,
playbackRate: 1,
currentTime: 0,
duration: 0,
}
},
computed: {
// 播放进度
// progress() {
// const percent = this.currentTime / this.duration * 100
// return percent.toFixed(2) + '%'
// },
// // 显示当前时间
// showPlayTime() {
// const curr = formatSec2Time(this.currentTime)
// const dur = formatSec2Time(this.duration)
// return `${curr} / ${dur}`
// },
},
methods: {
seeVideo() {
this.showVideo = true;
},
open() {
// console.log('open');
setTimeout(() => {
this.src =
'http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240708/video/wander/SXT001__quanjiang__DEMO00001_video_wm_1720400435638.mp4?Expires=1724748181&OSSAccessKeyId=STS.NTwCzwCtwDDYeE7RAhHue5mDb&Signature=qY%2F82lk1K9VJEX95ImeNH9wMHiw%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5fCCMDDrqtW84ayZ2OGtkE9RPpJ2qjvgDz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4z1YIkL10s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKQmwS5Se2k%2BwM10kxsnMbhsSH5O0sXx5M%2B5TxBoZB5p9PtUj15fgYQDR12uT0nToulHQz7%2BX6zfLqvSrfsIeBqAAUdgBEBn%2BksEpfpynILn8V8z3O5GaZcm3NmplGe%2F2XtD9%2FbnSWWTEzR1JJ45DnANEEIGzfjd6UvxpIcrk5Ggr0I52UqVdGUhcovTegZXYeBMsXYze8OLsu0UOhtpHsy8nCCJzpNnrwUBZOfUdZtwsCYHC4Bs8BRQ9JORs4ECvUnyIAA%3D'
}, 3000)
},
close() {
this.showVideo = false;
// console.log('close');
},
// 播放 - 事件
onPlay() {
console.log('onPlay')
this.playing = true
},
// 暂停 - 事件
onPause() {
console.log('onPause')
this.playing = false
},
// 播放完毕 - 事件
onEnded() {
console.log('onEnded')
this.playing = false
},
// 总时长变化 - 事件
onDurationChange(e) {
console.log('onDurationChange', e)
this.duration = e
},
// 播放时间更新 - 事件
onTimeUpdate(e) {
// console.log('onTimeUpdate', e)
this.currentTime = e
},
// 倍速变化 - 事件
onRateChange(e) {
console.log('onRateChange', e)
this.playbackRate = e
},
// 进入/退出全屏 - 事件
onFullscreenChange(e) {
console.log('onFullScreenChange', e)
},

// // 切换播放/暂停 - 函数
// doPlaying() {
// const domVideoPlayer = this.$refs.domVideoPlayer
// if (domVideoPlayer.playing) {
// this.doPause()
// } else {
// this.doPlay()
// }
// },
// // 播放 - 函数
// doPlay() {
// const domVideoPlayer = this.$refs.domVideoPlayer
// domVideoPlayer.play()
// },
// // 暂停 - 函数
// doPause() {
// const domVideoPlayer = this.$refs.domVideoPlayer
// domVideoPlayer.pause()
// },
// // 快退/快进 - 函数
// doSeek(time) {
// const domVideoPlayer = this.$refs.domVideoPlayer
// time += domVideoPlayer.currentTime
// domVideoPlayer.toSeek(time)
// },
// // 全屏播放 - 函数
// doFullScreen() {
// const domVideoPlayer = this.$refs.domVideoPlayer
// domVideoPlayer.fullScreen()
// },
// // 移除视频 - 函数
// doRemove() {
// this.src = ''
// const domVideoPlayer = this.$refs.domVideoPlayer
// domVideoPlayer.remove()
// },
// // 更换src - 函数
// doUpdateSrc() {
// this.src = 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/create-schema2code-video.mp4'
// },
// doUpdateSrcToSeek() {
// // 切换视频
// this.src = 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/create-schema2code-video.mp4'
// setTimeout(() => {
// const domVideoPlayer = this.$refs.domVideoPlayer
// // 视频加载完后,延迟调用toSeek()方法,跳转到第60s位置
// domVideoPlayer.toSeek(60, true)
// }, 100)
// },
// // 切换倍速 - 函数
// switchRate() {
// this.playbackRate = this.playbackRate === 1 ? 2 : 1
// },
// // 切换视频控制栏 - 函数
// switchControls() {
// this.controls = !this.controls
// },
}
}
</script>

<style lang="scss" scoped>
.warningDetail {
height: 100%;
background: #fff;

.title {
font-size: 30rpx;
}

.cli {
font-size: 30rpx;
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;

.labelBox {
color: #333333;
}

.valueBox {
color: #333333;
font-weight: 700;
}
}

.cli2 {
font-size: 30rpx;
padding: 20rpx 30rpx;

.labelBox {
color: #333333;
}

.valueBox {
margin-top: 20rpx;
color: #333333;
font-weight: 700;
min-height: 100rpx;
word-break: break-all;
}
}

.poupBox {
width: 100%;
padding: 80rpx 20rpx 20rpx 20rpx;
box-sizing: border-box;
}
}
</style>

+ 78
- 0
monitorMobile/pages/earlyWarning/handlingSuggestions.vue View File

@@ -0,0 +1,78 @@
<template>
<view class="handlingSuggestions">
<view class="formBox">
<u-form :model="form" ref="uForm" labelPosition="top" labelWidth="100">
<u-form-item label="处理意见" prop="remark" required>
<u--textarea v-model="form.remark" placeholder="请输入处理意见"></u--textarea>
</u-form-item>
</u-form>
</view>

<view class="btn">
<u-button shape="circle" type="primary" @click="submit">确定</u-button>
<u-button style="margin-top: 30rpx;" shape="circle" :plain="true" :hairline="true">取消</u-button>
</view>

</view>
</template>

<script>
export default {

data() {
return {
form: {
remark: '',
},
rules: {
remark: [{
required: true,
message: '请输入处理意见',
// 可以单个或者同时写两个触发验证方式
trigger: 'blur,change'
}]
}
}
},
methods: {
submit() {
uni.navigateTo({
url: '/pages/earlyWarning/processingResults'
});
this.$refs.uForm.validate(valid => {
if (valid) {
console.log('验证通过');
} else {
console.log('验证失败');
}
});
}
},
onReady() {
this.$refs.uForm.setRules(this.rules);
},
}
</script>

<style lang="scss" scoped>
.handlingSuggestions {
height: 100%;
position: relative;
.formBox {
background: #fff;
padding: 20rpx 30rpx;
box-sizing: border-box;
}
.btn {
width: 100%;
position: absolute;
bottom: 50rpx;
padding: 20rpx 30rpx;
box-sizing: border-box;
.u-button--primary {
background: #2388FF;
}
}
}
</style>

+ 14
- 556
monitorMobile/pages/earlyWarning/index.vue View File

@@ -18,197 +18,27 @@
</view> </view>
</u-popup> </u-popup>
</view> </view>
<view class="contentBox" v-if="isActive == '1'">
<view class="searchBox">
<view class="searchLine">
<view class="leftSearchBox">
<view class="searchLabel">
筛选条件:
</view>
<view class="searchValue">
111111111111111111111111111111111111111111111111111111111111111111111111
</view>
</view>
<view class="searchShow" @click="openSearch">
<image v-show="isShowSearch==false" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screen.png" mode="">
</image>
<image v-show="isShowSearch" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screenActive.png" mode="">
</image>
</view>
</view>
<view @click="isShowSearch=false" class="searchDialog" v-if="isShowSearch">
<view class="content" @click.stop="isSelect">
<u-row justify="space-between" gutter="10">
<u-col span="7">
<view class="demo-layout" @click="toOpen">
<view class="left-layout">
<text>{{searchForm.alarmType}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>

<!-- <jp-select-plus ref="selectPlus" :isShow="false" color="#2388FF" placeholder="请选择"
isSearch v-model="va3" :list="listc"></jp-select-plus> -->
</u-col>
<u-col span="5">
<view class="demo-layout">
<view class="left-layout">
<text>{{searchForm.warnHand}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>
</u-col>
</u-row>
<u-row style="margin-top:10px;" justify="space-between" gutter="10">
<u-col span="12">
<uni-datetime-picker v-model="searchForm.tick" type="datetimerange">
<view class="demo-layout">
<view class="startBox">
{{searchForm.StartTick}}
</view>
<text>至</text>
<view class="endBox">
{{searchForm.EndTick}}
</view>
<view class="timeIcon">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/calendar.png" mode=""></image>
</view>
</view>
</uni-datetime-picker>
<view class="contentBox">
<warningInfo v-if="isActive == '1'"></warningInfo>
<inspectionCenter v-else></inspectionCenter>
</view>


</u-col>
</u-row>
<view class="btnBox">
<view class="leftBtn">
重置
</view>
<view class="rightBtn">
确认
</view>
</view>
</view>
</view>


</view>
<view class="tableBox">
<u-empty marginTop="100rpx" :show="false" mode="warnList" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
<u-list-item v-for="(item, index) in warnList" :key="index">
<view class="liBox">
<view class="topCard">
<view class="pic">
<image src="@/static/image/earlyWarning/warnBack.png" mode=""></image>
</view>
<view class="rightCard">
<view class="firstCard">
<view class="schoolName">
学校名称学校名称学校名称学校名称
</view>
<view class="statusBox" :class="[item.warnHand == 1?'handle':'nohandle']">
{{item.warnHand == 1 ? '已处理' : '未处理'}}
</view>
</view>
<view class="secondCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnType.png" mode=""></image>
<view class="txt">
警告类型:周界入侵
</view>
</view>
<view class="thirdCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnVideo.png" mode=""></image>
<view class="txt">
警告摄像头:厨房(良景)
</view>
</view>
</view>
</view>
<view class="midCard">
<u-row>
<u-col span="6">
<view class="midContent">
姓名:杨云
</view>
</u-col>
<u-col span="6">
<view class="midContent">
系部:安环部
</view>
</u-col>
</u-row>
<u-row>
<u-col span="6">
<view class="midContent">
专业:环艺
</view>
</u-col>
<u-col span="6">
<view class="midContent">
班级:第二班
</view>
</u-col>
</u-row>
<u-row>
<u-col span="12">
<view class="midContent">
时间:2024-08-15 11:59:12
</view>
</u-col>
</u-row>
</view>
<view class="btoCard">
<view class="leftBox btoBox">
<image src="@/static/image/earlyWarning/detail.png" mode=""></image>
<view class="txt">
查看
</view>
</view>
<view class="midBox btoBox">
<image v-if="item.warnHand == 1" src="@/static/image/earlyWarning/handle.png"
mode=""></image>
<image v-if="item.warnHand == 0"
src="@/static/image/earlyWarning/handleDisabled.png" mode=""></image>
<view :class="[item.warnHand == 1?'txt':'disabled']">
处理
</view>
</view>
<view class="rightBox btoBox">
<image src="@/static/image/earlyWarning/delete.png" mode=""></image>
<view class="txt">
删除
</view>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
</view>
</view>
</view> </view>
</template> </template>


<script> <script>
import warningInfo from "./components/warningInfo.vue"
import inspectionCenter from "./components/inspectionCenter.vue"
export default { export default {
components: {
warningInfo,
inspectionCenter
},
data() { data() {
return { return {
searchForm: {
alarmType: '警告类型',
warnHand: '处理状态',
tick: [],
StartTick: '开始时间',
EndTick: '结束时间',
},

showSelectModel: false, showSelectModel: false,
modelObj: { modelObj: {
name: '预警信息', name: '预警信息',
@@ -226,102 +56,10 @@
imgUrl: require(`@/static/image/earlyWarning/majorBack.png`) imgUrl: require(`@/static/image/earlyWarning/majorBack.png`)
} }
], ],
isShowSearch: false,
warnList: [{
warnHand: 0
}, {}, {}, {}, {}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
listc: [{
code: 1,
name: 'dasda'
}, {
code: 2,
name: 'dasda'
},
{
code: 3,
name: 'dasda'
},
{
code: 4,
name: 'dasda'
},
{
code: 5,
name: 'dasda'
},
{
code: 6,
name: 'dasda'
},
{
code: 7,
name: 'dasda'
},
{
code: 8,
name: 'dasda'
},
{
code: 9,
name: 'dasda'
},
{
code: 10,
name: 'dasda'
},
{
code: 11,
name: 'dasda'
},
{
code: 12,
name: 'dasda'
},
{
code: 13,
name: '你好'
}
]
}
},
watch: {
"searchForm.tick"() {
console.log('日期时间:', this.searchForm.tick);
if(this.searchForm.tick && this.searchForm.tick.length>0) {
this.searchForm.StartTick = this.searchForm.tick[0]
this.searchForm.EndTick = this.searchForm.tick[1]
}
},
},
filters: {
// statusChange(val) {
// switch (val) {
// case 'todo':
// return '我的待办'
// break;
// case 'send':
// return '由我发起'
// break;
// case 'done':
// return '我的已办'
// break;
// default:


// }
// },
},
onLoad() {
// 隐藏导航栏
this.loadmore()
}
}, },
methods: { methods: {
toOpen() {
this.$refs.selectPlus.open()
},
open() { open() {
// console.log('open'); // console.log('open');
}, },
@@ -346,32 +84,7 @@
// break; // break;
// } // }
}, },
// 打开筛选框
openSearch() {
this.isShowSearch = !this.isShowSearch;

},
isSelect() {

},
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.warnList.push({}, {})
}
// 获取到的总条数>=接口总条数
if (this.warnList.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
}
} }
} }
</script> </script>
@@ -430,261 +143,6 @@


.contentBox { .contentBox {
height: calc(100% - 375rpx); height: calc(100% - 375rpx);

.searchBox {
// height: calc(100% - 360rpx);
position: relative;

.searchLine {
height: 88rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
background: #fff;

.leftSearchBox {
display: flex;
align-items: center;
width: calc(100% - 40px);

.searchLabel {
flex-shrink: 1;
color: #333333;
width: 80px;
}

.searchValue {
width: calc(100% - 60px);
margin-left: 10px;
color: #2388FF;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
}

.searchDialog {
position: absolute;
z-index: 990;
top: 89rpx;
width: 100%;
height: calc(100vh - 375rpx - 100rpx);
font-size: 26rpx;
background: rgba(0, 0, 0, 0.2);

.content {
background: #FFFFFF;
padding: 15px;
box-sizing: border-box;

.demo-layout {
height: 80rpx;
border-radius: 8rpx;
background: #F5F5F5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;

.left-layout {
color: #777777;
}

.right-layout {}

.startBox {
color: #777777;
}

text {
color: #777777;
}

.endBox {
color: #777777;
}

.timeIcon {}
}
}

.btnBox {
display: flex;
align-items: center;
margin-top: 15px;

.leftBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #BABABA;
border-radius: 12rpx;
color: #333333;
text-align: center;

}

.rightBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #2388FF;
border-radius: 12rpx;
color: #fff;
text-align: center;
background: #2388FF;
margin-left: 15rpx;
}
}
}
}

.tableBox {
height: 100%;
padding: 10px;
box-sizing: border-box;
// height: 600px;
padding-bottom: 50px;


.liBox {
background: #fff;
padding: 20px 15px;
box-sizing: border-box;
border-radius: 20px;
margin-bottom: 10px;

.topCard {
display: flex;

.pic {

image {
width: 160rpx;
height: 160rpx;
border-radius: 4px;
}
}

.rightCard {
margin-left: 20rpx;

.firstCard {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;

.schoolName {
font-size: 32rpx;
color: #333333;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}

.statusBox {
width: 140rpx;
flex-shrink: 1;
text-align: center;
height: 50rpx;
line-height: 50rpx;
font-size: 28rpx;
border-radius: 8rpx;
color: #fff;
}

.handle {
background: rgba(15, 175, 118, 0.1);
color: #0FAF76;
}

.nohandle {
background: rgba(239, 45, 45, 0.1);
color: rgba(239, 45, 45, 1);
}
}

.secondCard,
.thirdCard {
display: flex;
align-items: center;
margin-top: 18rpx;

.txt {
font-size: 28rpx;
margin-left: 10rpx;
color: #333333;
}
}
}
}

.midCard {
font-size: 28rpx;

.midContent {
margin-top: 18rpx;
}
}

.btoCard {
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin-top: 30rpx;
padding: 18px 0 0 0;
display: flex;
justify-content: center;
align-items: center;

.btoBox {
width: 33.3%;
display: flex;
justify-content: center;
align-items: center;
position: relative;

image {
width: 40rpx;
height: 40rpx;
margin-right: 15rpx;
}
}

.btoBox:not(:last-child)::before {
content: '';
display: block;
width: 1px;
height: 100%;
background: rgba(0, 0, 0, 0.1);
position: absolute;
right: 0px;
}

.midBox {
.txt {
color: #333333;
}

.disabled {
color: #777777;
}
}
}
}

}
} }
} }
</style> </style>

+ 64
- 0
monitorMobile/pages/earlyWarning/processingResults.vue View File

@@ -0,0 +1,64 @@
<template>
<view class="processingResults">
<view class="tips" v-if="callBackType == 'success'">
<image class="auto" src="@/static/image/earlyWarning/success.png" mode=""></image>
<view class="title auto">
提交成功
</view>
<u-button class="auto" style="width: 60%" shape="circle" type="primary" @click="back">知道了</u-button>
</view>
<view class="tips" v-else>
<image class="auto" src="@/static/image/earlyWarning/falid.png" mode=""></image>
<view class="title auto">
提交失败
</view>
<u-button class="auto" style="width: 60%" shape="circle" type="primary" @click="back">重新提交</u-button>
</view>
</view>
</template>

<script>
export default {
data() {
return {
callBackType: 'success'
}
},
methods: {
back() {
uni.switchTab({
url: '/pages/earlyWarning/index'
});
}
}
}
</script>

<style lang="scss" scoped>
.processingResults {
width: 100%;
height: 100%;
background: #fff;
.tips {
width: 100%;
text-align: center;
margin-top: 200rpx;
image {
width: 300rpx;
height: 268rpx;
margin: 0 auto;
}
.auto {
margin: 0 auto;
}
.title {
text-align: center;
color: #333333;
font-weight: 700;
margin: 20rpx 0 120rpx 0;
}
}
}
</style>

BIN
monitorMobile/static/image/earlyWarning/falid.png View File

Before After
Width: 300  |  Height: 268  |  Size: 56 KiB

BIN
monitorMobile/static/image/earlyWarning/school.png View File

Before After
Width: 36  |  Height: 36  |  Size: 616 B

BIN
monitorMobile/static/image/earlyWarning/success.png View File

Before After
Width: 300  |  Height: 268  |  Size: 67 KiB

Loading…
Cancel
Save