|
|
@@ -1,612 +0,0 @@
|
|
|
-<template>
|
|
|
- <wrapper
|
|
|
- fill
|
|
|
- margin
|
|
|
- background
|
|
|
- >
|
|
|
- <el-tabs
|
|
|
- v-model="activeName"
|
|
|
- v-loading="videoOption.loading"
|
|
|
- class="c-tabs video"
|
|
|
- @tab-click="handleClick"
|
|
|
- >
|
|
|
- <el-tab-pane
|
|
|
- label="人流量监测"
|
|
|
- name="first"
|
|
|
- >
|
|
|
- <div class="has-padding">
|
|
|
- <div class="l-flex--row c-table__header">
|
|
|
- <div class="l-flex__auto c-sibling-item">
|
|
|
- <button
|
|
|
- v-if="canEdit"
|
|
|
- class="o-button"
|
|
|
- @click="addbtn"
|
|
|
- >
|
|
|
- <i class="o-button__icon el-icon-circle-plus-outline" />新增
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- <search-input
|
|
|
- v-model.trim="searchname"
|
|
|
- class="l-flex__none c-sibling-item"
|
|
|
- placeholder="搜索"
|
|
|
- @search="search"
|
|
|
- />
|
|
|
- <button
|
|
|
- class="l-flex__none c-sibling-item o-button"
|
|
|
- @click="search"
|
|
|
- >
|
|
|
- 搜索
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- <el-row
|
|
|
- v-if="videoOption.list.length"
|
|
|
- :gutter="16"
|
|
|
- class="rowheight"
|
|
|
- >
|
|
|
- <el-col
|
|
|
- v-for="(video, index) in videoOption.list"
|
|
|
- :key="index"
|
|
|
- :span="8"
|
|
|
- class="cameraRow"
|
|
|
- >
|
|
|
- <div
|
|
|
- ref="videoB"
|
|
|
- class="o-video bg-purple"
|
|
|
- :style="{ height: videoheight }"
|
|
|
- @click="toDetail(video)"
|
|
|
- >
|
|
|
- <video
|
|
|
- :ref="video.deviceId"
|
|
|
- style="width: 100%;"
|
|
|
- class="video"
|
|
|
- muted
|
|
|
- autoplay
|
|
|
- :poster="require('@/assets//video-post.png')"
|
|
|
- />
|
|
|
- <div
|
|
|
- v-show="!video.online"
|
|
|
- class="offLine"
|
|
|
- >
|
|
|
- 设备离线
|
|
|
- </div>
|
|
|
- <div class="o-video_buttom l-flex--row">
|
|
|
- <div class="l-flex__auto">{{ video.name }}</div>
|
|
|
- <template v-if="canEdit">
|
|
|
- <img
|
|
|
- class="o-video_edit"
|
|
|
- :src="imgUrl.edit"
|
|
|
- @click.stop="editbtn(video)"
|
|
|
- >
|
|
|
- <img
|
|
|
- class="o-video_delete"
|
|
|
- :src="imgUrl.delete"
|
|
|
- @click.stop="deletebtn(video)"
|
|
|
- >
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <div
|
|
|
- v-if="!videoOption.list.length"
|
|
|
- class="empty"
|
|
|
- >无摄像头数据</div>
|
|
|
- <pagination
|
|
|
- :total="videoOption.totalCount"
|
|
|
- :page-sizes="[6]"
|
|
|
- :page.sync="videoOption.params.pageNum"
|
|
|
- :limit.sync="videoOption.params.pageSize"
|
|
|
- @pagination="getCamera"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </el-tab-pane>
|
|
|
- <!-- <el-tab-pane label="视频回传" name="second">
|
|
|
- <div class="has-padding">
|
|
|
- <div class="l-flex--row c-table__header">
|
|
|
- <div class="l-flex__auto c-sibling-item">
|
|
|
- <el-checkbox-group v-model="checkList" @change="chechChange">
|
|
|
- <el-checkbox label="视频回采"></el-checkbox>
|
|
|
- <el-checkbox label="模拟终端"></el-checkbox>
|
|
|
- </el-checkbox-group>
|
|
|
- </div>
|
|
|
- <div class="l-flex__none c-sibling-item">
|
|
|
- <img
|
|
|
- class="c-sibling-item"
|
|
|
- @click="rowChange(24)"
|
|
|
- :src="require('@/assets/icon_one_normal.png')"
|
|
|
- alt=""
|
|
|
- />
|
|
|
- <img
|
|
|
- class="c-sibling-item"
|
|
|
- @click="rowChange(12)"
|
|
|
- :src="require('@/assets/icon_four_normal.png')"
|
|
|
- alt=""
|
|
|
- />
|
|
|
- <img
|
|
|
- class="c-sibling-item"
|
|
|
- @click="rowChange(8)"
|
|
|
- :src="require('@/assets/icon_nine_focus.png')"
|
|
|
- alt=""
|
|
|
- />
|
|
|
- </div>
|
|
|
- <button
|
|
|
- class="l-flex__none c-sibling-item o-button"
|
|
|
- @click="search"
|
|
|
- >
|
|
|
- <i class="o-button__icon el-icon-full-screen" />
|
|
|
- 全屏
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- <el-row :gutter="16" class="rowheight">
|
|
|
- <el-col
|
|
|
- :span="rowNum"
|
|
|
- v-for="(item, index) in returnList.list"
|
|
|
- :key="index"
|
|
|
- class="cameraRow"
|
|
|
- >
|
|
|
- <div class="return_item bg-purple"
|
|
|
- ref="returnB"
|
|
|
- :style="{ height: returnheight }">
|
|
|
- <div class="o-video_buttom l-flex--row">
|
|
|
- <div class="l-flex__auto">{{ item.name }}</div>
|
|
|
- <img
|
|
|
- :src="require('@/assets/icon_address.png')"
|
|
|
- class="o-video_edit"
|
|
|
- />
|
|
|
- <div class="return_local">{{ item.name }}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
- </el-tab-pane> -->
|
|
|
- </el-tabs>
|
|
|
- <!-- 新增和编辑 -->
|
|
|
- <el-dialog
|
|
|
- :title="dialogTitle"
|
|
|
- :visible.sync="adding"
|
|
|
- custom-class="c-dialog"
|
|
|
- :close-on-click-modal="false"
|
|
|
- >
|
|
|
- <el-form
|
|
|
- ref="cameraForm"
|
|
|
- :model="camera"
|
|
|
- :rules="cameraRules"
|
|
|
- label-width="100px"
|
|
|
- class="c-form"
|
|
|
- >
|
|
|
- <el-form-item
|
|
|
- label="设备名称"
|
|
|
- prop="name"
|
|
|
- >
|
|
|
- <el-input
|
|
|
- v-model.number="camera.name"
|
|
|
- maxlength="50"
|
|
|
- show-word-limit
|
|
|
- class="c-form__item c-form__item_padding"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- label="ID"
|
|
|
- prop="deviceId"
|
|
|
- >
|
|
|
- <el-input
|
|
|
- v-model.number="camera.deviceId"
|
|
|
- maxlength="50"
|
|
|
- :disabled="isEdit"
|
|
|
- class="c-form__item"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- label="用户名"
|
|
|
- prop="username"
|
|
|
- >
|
|
|
- <el-input
|
|
|
- v-model.number="camera.username"
|
|
|
- maxlength="50"
|
|
|
- :disabled="isEdit"
|
|
|
- class="c-form__item"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- v-if="!isEdit"
|
|
|
- label="密码"
|
|
|
- prop="password"
|
|
|
- >
|
|
|
- <el-input
|
|
|
- v-model.number="camera.password"
|
|
|
- maxlength="50"
|
|
|
- type="password"
|
|
|
- autocomplete="off"
|
|
|
- class="c-form__item"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- label="备注"
|
|
|
- prop="remark"
|
|
|
- >
|
|
|
- <el-input
|
|
|
- v-model.number="camera.remark"
|
|
|
- type="textarea"
|
|
|
- maxlength="500"
|
|
|
- class="c-form__item"
|
|
|
- show-word-limit
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <template #footer>
|
|
|
- <button
|
|
|
- class="o-button"
|
|
|
- @click="add('cameraForm')"
|
|
|
- >
|
|
|
- 确定
|
|
|
- </button>
|
|
|
- <button
|
|
|
- class="o-button cancel"
|
|
|
- @click="handleCloseAddDialog('cameraForm')"
|
|
|
- >
|
|
|
- 取消
|
|
|
- </button>
|
|
|
- </template>
|
|
|
- </el-dialog>
|
|
|
- <el-dialog
|
|
|
- title
|
|
|
- :fullscreen="true"
|
|
|
- :visible="detailing"
|
|
|
- :close-on-click-modal="false"
|
|
|
- class="fulldialog"
|
|
|
- >
|
|
|
- <detail
|
|
|
- v-if="detailing"
|
|
|
- :detailobj="editOption"
|
|
|
- @closeDetail="closeDetail"
|
|
|
- />
|
|
|
- </el-dialog>
|
|
|
- </wrapper>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import flvjs from 'flv.js'
|
|
|
-import {
|
|
|
- getCamera,
|
|
|
- addCamera,
|
|
|
- updateCamera,
|
|
|
- deleteCamera
|
|
|
-} from '@/api/camera'
|
|
|
-import { createListOptions } from '@/utils'
|
|
|
-import Detail from './components/Detail'
|
|
|
-
|
|
|
-const CAMERA_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${process.env.VUE_APP_GATEWAY || location.host}${process.env.VUE_APP_CAMERA_PROXY}`
|
|
|
-
|
|
|
-export default {
|
|
|
- name: 'Camera',
|
|
|
- components: {
|
|
|
- Detail
|
|
|
- },
|
|
|
- data () {
|
|
|
- return {
|
|
|
- activeName: 'first',
|
|
|
- searchname: '',
|
|
|
- imgUrl: {
|
|
|
- edit: require('@/assets/icon_edit.png'),
|
|
|
- delete: require('@/assets/icon_delete.png')
|
|
|
- },
|
|
|
- videoOption: createListOptions({
|
|
|
- pageSize: 6
|
|
|
- }),
|
|
|
- dialogTitle: '新增',
|
|
|
- adding: false,
|
|
|
- camera: {
|
|
|
- name: '',
|
|
|
- deviceId: '',
|
|
|
- username: '',
|
|
|
- password: '',
|
|
|
- remark: ''
|
|
|
- },
|
|
|
- cameraRules: {
|
|
|
- name: [{ required: true, message: '请填写设备名称', trigger: 'blur' }],
|
|
|
- deviceId: [{ required: true, message: '请填写ID', trigger: 'blur' }],
|
|
|
- username: [
|
|
|
- { required: true, message: '请填写用户名', trigger: 'blur' }
|
|
|
- ],
|
|
|
- password: [{ required: true, message: '请填写密码', trigger: 'blur' }]
|
|
|
- },
|
|
|
- isEdit: true,
|
|
|
- editOption: {},
|
|
|
- detailing: false,
|
|
|
- videoheight: '',
|
|
|
- playerList: {},
|
|
|
-
|
|
|
- checkList: [],
|
|
|
- returnList: createListOptions({
|
|
|
- pageSize: 9
|
|
|
- }),
|
|
|
- returnheight: 0,
|
|
|
- rowNum: 8
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- canEdit () {
|
|
|
- return this.accessSet.has(this.Access.MANAGE_DEVICES)
|
|
|
- }
|
|
|
- },
|
|
|
- created () {
|
|
|
- this.getCamera()
|
|
|
- },
|
|
|
- beforeDestroy () {
|
|
|
- this.destroyPlayer()
|
|
|
- },
|
|
|
- methods: {
|
|
|
- rowChange (num) {
|
|
|
- this.rowNum = num
|
|
|
- this.$nextTick(() => {
|
|
|
- this.returnheight = (this.$refs.returnB[0].clientWidth * 9) / 16 + 'px'
|
|
|
- })
|
|
|
- },
|
|
|
- chechChange (val) {
|
|
|
- console.log(val)
|
|
|
- },
|
|
|
- destroyPlayer () {
|
|
|
- for (const key in this.playerList) {
|
|
|
- if (Object.hasOwnProperty.call(this.playerList, key)) {
|
|
|
- // const element = object[key];
|
|
|
- if (this.playerList[key]) {
|
|
|
- this.playerList[key].pause()
|
|
|
- this.playerList[key].unload()
|
|
|
- this.playerList[key].detachMediaElement()
|
|
|
- this.playerList[key].destroy()
|
|
|
- this.playerList[key] = null
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- handleClick () {},
|
|
|
- search () {
|
|
|
- this.getCamera()
|
|
|
- },
|
|
|
- getCamera () {
|
|
|
- const options = this.videoOption
|
|
|
- options.error = false
|
|
|
- options.loading = true
|
|
|
- options.params.name = this.searchname
|
|
|
- getCamera(options.params)
|
|
|
- .then(
|
|
|
- ({ data, totalCount }) => {
|
|
|
- options.totalCount = totalCount
|
|
|
- options.list = data
|
|
|
- // for (let i = 0; i < 34; i++) {
|
|
|
- // data.push({
|
|
|
- // deviceId: Math.random(),
|
|
|
- // })
|
|
|
- // }
|
|
|
- this.$nextTick(() => {
|
|
|
- this.videoheight =
|
|
|
- (this.$refs.videoB[0].clientWidth * 9) / 16 + 'px'
|
|
|
- this.destroyPlayer()
|
|
|
- for (let i = 0; i < data.length; i++) {
|
|
|
- if (options.list[i].online) {
|
|
|
- this.getflv(options.list[i].deviceId)
|
|
|
- }
|
|
|
- // getOnline(options.list[i].deviceId).then(({ data }) => {
|
|
|
- // options.list[i].online = data
|
|
|
- // if (data) {
|
|
|
- // this.getflv(options.list[i].deviceId)
|
|
|
- // }
|
|
|
- // })
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- () => {
|
|
|
- options.error = true
|
|
|
- options.list = []
|
|
|
- }
|
|
|
- )
|
|
|
- .finally(() => {
|
|
|
- options.loading = false
|
|
|
- })
|
|
|
- },
|
|
|
- addCamera () {
|
|
|
- addCamera({
|
|
|
- name: this.camera.name,
|
|
|
- deviceId: this.camera.deviceId,
|
|
|
- username: this.camera.username,
|
|
|
- password: this.camera.password,
|
|
|
- remark: this.camera.remark
|
|
|
- }).then(() => {
|
|
|
- this.handleCloseAddDialog('cameraForm')
|
|
|
- this.getCamera()
|
|
|
- })
|
|
|
- },
|
|
|
- addbtn () {
|
|
|
- this.camera = {
|
|
|
- name: '',
|
|
|
- deviceId: '',
|
|
|
- username: '',
|
|
|
- password: '',
|
|
|
- remark: ''
|
|
|
- }
|
|
|
- this.dialogTitle = '新增'
|
|
|
- this.isEdit = false
|
|
|
- this.adding = true
|
|
|
- },
|
|
|
- add (formName) {
|
|
|
- this.$refs[formName].validate((valid) => {
|
|
|
- if (valid) {
|
|
|
- if (this.isEdit) {
|
|
|
- this.edit(this.editOption)
|
|
|
- } else {
|
|
|
- this.addCamera()
|
|
|
- }
|
|
|
- } else {
|
|
|
- console.log('error submit!!')
|
|
|
- return false
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- handleCloseAddDialog (formName) {
|
|
|
- this.adding = false
|
|
|
- this.$refs[formName].resetFields()
|
|
|
- },
|
|
|
- editbtn (item) {
|
|
|
- this.adding = true
|
|
|
- this.isEdit = true
|
|
|
- this.dialogTitle = '编辑'
|
|
|
-
|
|
|
- this.editOption = item
|
|
|
- this.camera = {
|
|
|
- name: item.name,
|
|
|
- deviceId: item.deviceId,
|
|
|
- username: item.username,
|
|
|
- remark: item.remark
|
|
|
- }
|
|
|
- },
|
|
|
- edit (item) {
|
|
|
- updateCamera({
|
|
|
- id: item.id,
|
|
|
- name: this.camera.name,
|
|
|
- deviceId: item.deviceId,
|
|
|
- username: this.camera.username,
|
|
|
- password: this.camera.password,
|
|
|
- remark: this.camera.remark
|
|
|
- }).then(() => {
|
|
|
- this.handleCloseAddDialog('cameraForm')
|
|
|
- this.getCamera()
|
|
|
- })
|
|
|
- },
|
|
|
- deletebtn (item) {
|
|
|
- const videoOption = this.videoOption
|
|
|
- deleteCamera({ id: item.id, name: item.name }).then(() => {
|
|
|
- if (videoOption.list.length === 1 && videoOption.params.pageNum > 1) {
|
|
|
- videoOption.params.pageNum -= 1
|
|
|
- }
|
|
|
- this.getCamera()
|
|
|
- })
|
|
|
- },
|
|
|
- getflv (deviceId) {
|
|
|
- if (flvjs.isSupported()) {
|
|
|
- // 创建一个flvjs实例
|
|
|
- this.playerList[deviceId] = flvjs.createPlayer({
|
|
|
- type: 'flv',
|
|
|
- isLive: true,
|
|
|
- hasAudio: false,
|
|
|
- url: `${CAMERA_URL}/${deviceId}?authorization=${this.$keycloak.token}`
|
|
|
- })
|
|
|
- this.playerList[deviceId].on('error', (e) => {
|
|
|
- console.log(e)
|
|
|
- })
|
|
|
- // 将实例挂载到video元素上面
|
|
|
- this.playerList[deviceId].attachMediaElement(this.$refs[deviceId][0])
|
|
|
- // player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
|
|
|
- try {
|
|
|
- // 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了
|
|
|
- this.playerList[deviceId].load()
|
|
|
- this.playerList[deviceId].play()
|
|
|
- } catch (error) {
|
|
|
- console.log('连接websocker异常:' + error)
|
|
|
- console.log(error)
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- toDetail (item) {
|
|
|
- if (item.online) {
|
|
|
- this.detailing = true
|
|
|
- this.editOption = item
|
|
|
- this.destroyPlayer()
|
|
|
- }
|
|
|
- },
|
|
|
- closeDetail () {
|
|
|
- this.detailing = false
|
|
|
- this.getCamera()
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-//所有控件
|
|
|
-video::-webkit-media-controls-enclosure {
|
|
|
- display: none;
|
|
|
-}
|
|
|
-.has-padding {
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-.rowheight {
|
|
|
- // height: calc(100% - 40px);
|
|
|
- overflow: auto;
|
|
|
-}
|
|
|
-.c-tabs {
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-.cameraRow {
|
|
|
- margin-bottom: 16px;
|
|
|
-}
|
|
|
-.o-video {
|
|
|
- // height: 190px;
|
|
|
- background-color: #edf0f6;
|
|
|
- position: relative;
|
|
|
- overflow: hidden;
|
|
|
- &_buttom {
|
|
|
- position: absolute;
|
|
|
- bottom: 0px;
|
|
|
- width: 100%;
|
|
|
- height: 58px;
|
|
|
- background-image: linear-gradient(0deg, rgba(6, 11, 18, 0.9), transparent);
|
|
|
- border-radius: 0px 0px 4px 4px;
|
|
|
- color: #fff;
|
|
|
- padding: 0 16px;
|
|
|
- }
|
|
|
- img {
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- &_edit {
|
|
|
- margin-right: 16px;
|
|
|
- }
|
|
|
- .offLine {
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: 50%;
|
|
|
- color: #ff0000;
|
|
|
- text-align: center;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- }
|
|
|
-}
|
|
|
-.return {
|
|
|
- &_item {
|
|
|
- background-color: #aaa;
|
|
|
- width: 100%;
|
|
|
- height: 150px;
|
|
|
- position: relative;
|
|
|
- }
|
|
|
- &_local {
|
|
|
- font-size: 12px;
|
|
|
- }
|
|
|
-}
|
|
|
-.empty {
|
|
|
- color: #aaa;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-</style>
|
|
|
-<style lang="scss">
|
|
|
-.fulldialog {
|
|
|
- .el-dialog__header {
|
|
|
- display: none;
|
|
|
- }
|
|
|
- .el-dialog__body {
|
|
|
- padding: 0;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-}
|
|
|
-.video {
|
|
|
- .el-tabs__content {
|
|
|
- height: calc(100% - 40px);
|
|
|
- }
|
|
|
- .el-tab-pane {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-}
|
|
|
-.c-form__item_padding{
|
|
|
- .el-input__inner{
|
|
|
- padding-right: 50px;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|