| | |
| | | "progressMsg": "" |
| | | }, |
| | | { |
| | | "id": "a9c4a1ad-0137-4137-acf3-fc293d6c295e", |
| | | "name": "长春", |
| | | "package": "changchunTrack", |
| | | "type": "2", |
| | | "url": "/view/changchunTrack/", |
| | | "title": "长春", |
| | | "width": 1328, |
| | | "height": 690, |
| | | "iconBlob": "", |
| | | "icon": "../../images/app-mid/monitor.png", |
| | | "version": "1.0.0", |
| | | "create_time": "2020-10-09 14:00:01", |
| | | "create_by": "", |
| | | "update_time": "", |
| | | "update_by": "", |
| | | "isDelete": 0, |
| | | "isDefault": true, |
| | | "remoteVersion": "", |
| | | "installed": true, |
| | | "isUpgrade": false, |
| | | "progressMsg": "" |
| | | }, |
| | | { |
| | | "id": "7dea48a4-8294-4914-85d8-c2bbd4caf553", |
| | | "name": "应用中心", |
| | | "package": "algorithmManage", |
| | |
| | | } |
| | | |
| | | //获取商城所有应用(已激活) |
| | | export const findAllApp = () => request({ |
| | | url: '/data/api-v/app/findAllApp', |
| | | method: 'get' |
| | | }); |
| | | // export const findAllApp = () => request({ |
| | | // url: '/data/api-v/app/findAllApp', |
| | | // method: 'get' |
| | | // }); |
| | | |
| | | export const getAppDetail = (query:any) => request({ |
| | | url: '/data/api-v/app/detail', |
| | |
| | | import request from "@/scripts/httpRequest"; |
| | | import qs from "qs"; |
| | | |
| | | export const checkCameraConnet = (query: any) => { |
| | | return request({ |
| | | url: "/data/api-v/area/localmenu", |
| | | method: "get", |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | export const createCamera = (camera: any) => { |
| | | return request({ |
| | |
| | | }) |
| | | } |
| | | |
| | | export const getActiveQrCode = (query: any) => { |
| | | return request({ |
| | | url: "/version/offline/qrcode", |
| | | method: "get", |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export const getSN = (query: any) => { |
| | | return request({ |
| | | url: "/version/sn", |
| | | method: "get", |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | export const cancelAuthorization = (query: any) => { |
| | | return request({ |
| | | url: "/version/cancelAuthorization", |
| | | method: "post", |
| | | data: qs.stringify(query), |
| | | responseType: "blob" |
| | | }) |
| | | } |
| | | |
| | | export const activateVersion = (query: any) => { |
| | | return request({ |
| | | url: "/version/authorization", |
| | | method: "post", |
| | | data: qs.stringify(query) |
| | | }) |
| | | } |
| | | export const uploadKey = (data: any) => { |
| | | return request({ |
| | | url: "/version/authorization/upload", |
| | | method: "post", |
| | | data |
| | | }) |
| | | } |
| | |
| | | url: "/playState", |
| | | method: "get" |
| | | }); |
| | | }; |
| | | }; |
| | | |
| | | export const showAllCameras = () => { |
| | | return request({ |
| | | url: "/data/api-v/cameraCompose/showAll", |
| | | method: "get" |
| | | }); |
| | | }; |
| | | |
| | |
| | | |
| | | item.appendChild(btn); |
| | | } |
| | | |
| | | // 添加摄像机按钮 |
| | | if (item && !item.querySelector('.iconshishishipin') && treeNode.isParent && !this.readonly && !this.gb28181) { |
| | | const btn = document.createElement('i'); |
| | |
| | | }, |
| | | watch: { |
| | | rtspUrl: function (newVal, oldVal) { |
| | | console.log("new rstp:::", newVal); |
| | | if (newVal !== oldVal) { |
| | | if (this.wfs.config) { |
| | | this.wfs.destroy(); |
| | |
| | | } |
| | | |
| | | onMediaSourceClose() { |
| | | console.log('media source closed'); |
| | | // console.log('media source closed'); |
| | | } |
| | | |
| | | onMediaSourceEnded() { |
| | |
| | | if (Object.keys(sourceBuffer).length) { |
| | | if (this.media.error) { |
| | | this.segments = []; |
| | | console.log( |
| | | 'trying to append although a media error occured, flush segment and abort' |
| | | ); |
| | | // console.log( |
| | | // 'trying to append although a media error occured, flush segment and abort' |
| | | // ); |
| | | return; |
| | | } |
| | | if (this.appending) { |
| | |
| | | } catch (err) { |
| | | // in case any error occured while appending, put back segment in segments table |
| | | segments.unshift(segment); |
| | | var event = { type: ErrorTypes.MEDIA_ERROR }; |
| | | if (err.code !== 22) { |
| | | if (this.appendError) { |
| | | this.appendError++; |
| | | } else { |
| | | this.appendError = 1; |
| | | } |
| | | event.details = ErrorDetails.BUFFER_APPEND_ERROR; |
| | | event.frag = this.fragCurrent; |
| | | if (this.appendError > wfs.config.appendErrorMaxRetry) { |
| | | segments = []; |
| | | event.fatal = true; |
| | | return; |
| | | } else { |
| | | event.fatal = false; |
| | | } |
| | | } else { |
| | | this.segments = []; |
| | | event.details = ErrorDetails.BUFFER_FULL_ERROR; |
| | | return; |
| | | } |
| | | // var event = { type: ErrorTypes.MEDIA_ERROR }; |
| | | // if (err.code !== 22) { |
| | | // if (this.appendError) { |
| | | // this.appendError++; |
| | | // } else { |
| | | // this.appendError = 1; |
| | | // } |
| | | // event.details = ErrorDetails.BUFFER_APPEND_ERROR; |
| | | // event.frag = this.fragCurrent; |
| | | // if (this.appendError > wfs.config.appendErrorMaxRetry) { |
| | | // segments = []; |
| | | // event.fatal = true; |
| | | // return; |
| | | // } else { |
| | | // event.fatal = false; |
| | | // } |
| | | // } else { |
| | | // this.segments = []; |
| | | // event.details = ErrorDetails.BUFFER_FULL_ERROR; |
| | | // return; |
| | | // } |
| | | } |
| | | } |
| | | } |
| | |
| | | this.client = data.websocket |
| | | this.client.onopen = this.initSocketClient.bind(this) |
| | | this.client.onclose = function (e) { |
| | | console.log('Websocket Disconnected!') |
| | | // console.log('Websocket Disconnected!') |
| | | this.disconnected = true; |
| | | // console.log(this) |
| | | // this.close = true; |
| | |
| | | }) |
| | | this.client.disconnected = false |
| | | // console.log(this) |
| | | console.log('Websocket Open!') |
| | | // console.log('Websocket Open!') |
| | | } |
| | | |
| | | receiveSocketMessage(event) { |
| | |
| | | });
|
| | | setTimeout(() => {
|
| | | this.getAllSdk();
|
| | | debugger
|
| | | window.parent.postMessage(
|
| | | {
|
| | | msg: "AppUpdate",
|
| | |
| | | app.installLoading = false;
|
| | | }
|
| | | // _this.getAllApps();
|
| | | debugger
|
| | |
|
| | | window.parent.postMessage(
|
| | | {
|
| | | msg: "AppUpdate",
|
| | |
| | |
|
| | | this.appUpgreading = true;
|
| | | }
|
| | | |
| | |
|
| | | if (obj.upgradeDone) {
|
| | | this.$notify({
|
| | | this.$notify({
|
| | | type: "success",
|
| | | message:1 ? "算法安装成功" : "算法升级成功",
|
| | | message: 1 ? "算法安装成功" : "算法升级成功",
|
| | | });
|
| | | }
|
| | | |
| | |
|
| | | item.installed ? iArry.push(obj) : sArry.push(obj);
|
| | | item.isUpgrade && nArry.push(obj);
|
| | | });
|
| | |
| | | if (res && res.success) {
|
| | | app.unloadLoading = false;
|
| | | _this.getAllApps();
|
| | | debugger
|
| | |
|
| | | window.parent.postMessage(
|
| | | {
|
| | | msg: "AppUpdate",
|
| | |
| | | type: "success",
|
| | | });
|
| | | _this.getAllSdk();
|
| | | debugger
|
| | |
|
| | | window.parent.postMessage(
|
| | | {
|
| | | msg: "AppUpdate",
|
| | |
| | | // type: "success",
|
| | | // message: typ == 1 ? "算法安装成功" : "算法升级成功",
|
| | | // });
|
| | | // window.parent.postMessage(
|
| | | // { msg: `refreshDesk?` },
|
| | | // "*"
|
| | | // );
|
| | | window.parent.postMessage(
|
| | | {
|
| | | msg: "AppUpdate",
|
| | | },
|
| | | "*"
|
| | | );
|
| | | {
|
| | | msg: "AppUpdate",
|
| | | },
|
| | | "*"
|
| | | );
|
| | | })
|
| | | .catch((err) => {
|
| | | this.$notify({
|
| | |
| | | message: "摄像机添加失败!" |
| | | }); |
| | | } |
| | | }).catch((err) => { |
| | | this.$notify({ |
| | | type: "error", |
| | | message: err.msg |
| | | }); |
| | | }); |
| | | } |
| | | } |
| | |
| | | <script> |
| | | import { |
| | | saveCameraScene, |
| | | getCameraSceneRule, |
| | | deleteCameraScene |
| | | } from '@/api/scene' |
| | | import RuleEditor from "@/components/subComponents/RuleEditor"; |
| | |
| | | } |
| | | |
| | | onMediaSourceClose() { |
| | | console.log('media source closed'); |
| | | // console.log('media source closed'); |
| | | } |
| | | |
| | | onMediaSourceEnded() { |
| | |
| | | this.client = data.websocket |
| | | this.client.onopen = this.initSocketClient.bind(this) |
| | | this.client.onclose = function (e) { |
| | | console.log('Websocket Disconnected!') |
| | | // console.log('Websocket Disconnected!') |
| | | this.disconnected = true; |
| | | // console.log(this) |
| | | // this.close = true; |
| | |
| | | :class="guid === 1 ? 'video-main-box' : 'video-main-box-side'" |
| | | v-if="visibilityState" |
| | | > |
| | | <video-item |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | |
| | | guid === 1 ? 'onlyActiveItem' : '' |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></video-item> |
| | | ></VideoItem> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="monitoring-task" ref="monitorTask"> |
| | | <video-task ref="taskview" @addToBase="toAdd"></video-task> |
| | | <VideoTask ref="taskview" @addToBase="toAdd"></VideoTask> |
| | | </div> |
| | | </div> |
| | | <div class="monitoring-photo"> |
| New file |
| | |
| | | <template> |
| | | <transition name="slideLeft"> |
| | | <div |
| | | class="left-tree-box" |
| | | :style="`height:${height}px;animation-duration: 0.7s`" |
| | | v-show="TreeDataPool.showTreeBox" |
| | | v-loading="menuLoading" |
| | | > |
| | | <el-tabs v-model="TreeDataPool.treeActiveName" type="border-card" @tab-click="handleClick"> |
| | | <el-tab-pane label="摄像机" name="camera" :style="`height:${height - 56}px;`" v-if="showCam"> |
| | | <el-menu |
| | | :default-openeds="openeds" |
| | | background-color="#fff" |
| | | text-color="#303133" |
| | | active-text-color="#409EFF" |
| | | style="height: 100%;" |
| | | class="el-menu-vertical-demo" |
| | | unique-opened |
| | | @open="menuOpen" |
| | | @close="menuClose" |
| | | > |
| | | <li class="navTopSelect"> |
| | | <el-select |
| | | v-model="TreeDataPool.searchCamType" |
| | | placeholder="请选择" |
| | | @change="searchAreaData" |
| | | > |
| | | <el-option |
| | | v-for="item in searchTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | <span style="display: inline-block;padding: 0px 3px;"></span> |
| | | <el-input |
| | | v-model="TreeDataPool.searchInput" |
| | | placeholder="搜索" |
| | | clearable |
| | | @input="querySearchAsync('camera')" |
| | | > |
| | | <i |
| | | class="el-icon-search el-input__icon" |
| | | style="color:#DCDFE6" |
| | | slot="prefix" |
| | | @click="searchAreaData" |
| | | ></i> |
| | | </el-input> |
| | | <!-- <div class="tree-close"> |
| | | <el-tooltip content="收起目录树" placement="bottom" popper-class="atooltip"> |
| | | <i |
| | | class="el-icon-s-fold" |
| | | style="color: #3D68E1;line-height: 22px;font-size: 27px;" |
| | | @click="closeTree" |
| | | ></i> |
| | | </el-tooltip> |
| | | </div>--> |
| | | </li> |
| | | |
| | | <div class="tree-edit area-add" v-show="!TreeDataPool.readonly"> |
| | | <el-tooltip content="添加区域" placement="bottom" popper-class="atooltip"> |
| | | <button @click="addNode($event)"> |
| | | <i class="iconfont iconhebingxingzhuang"></i> |
| | | </button> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 添加设备图标 --> |
| | | <div class="tree-edit camera-add" v-show="!TreeDataPool.readonly"> |
| | | <el-tooltip content="添加设备" placement="bottom" popper-class="atooltip"> |
| | | <button @click="addCamera('0')"> |
| | | <!-- <i class="el-icon-video-camera"></i> --> |
| | | <span class="iconfont iconshishishipin" style="font-size:14px;"></span> |
| | | </button> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 导入设备 --> |
| | | <div class="tree-edit import-btn" v-show="!TreeDataPool.readonly"> |
| | | <el-tooltip content="导入设备" placement="bottom" popper-class="atooltip"> |
| | | <button @click="importCameras('0')"> |
| | | <!-- <i class="el-icon-video-camera"></i> --> |
| | | <span class="iconfont icondaoru" style="font-size:16px;"></span> |
| | | </button> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 树操作锁 --> |
| | | <div class="tree-edit tree-lock" v-show="showLock"> |
| | | <button @click="lockSwitch"> |
| | | <i v-if="TreeDataPool.readonly" class="el-icon-lock"></i> |
| | | <i v-else class="el-icon-unlock"></i> |
| | | </button> |
| | | </div> |
| | | |
| | | <!-- 主菜单 --> |
| | | <el-submenu index="0"> |
| | | <template slot="title"> |
| | | <!-- <i class="iconfont iconjiankongshexiangji"></i> --> |
| | | <span |
| | | class="iconfont iconjiankongshexiangji" |
| | | style="padding-right:10px;font-size:13px;" |
| | | ></span> |
| | | <b class="tree-font">摄像机</b> |
| | | </template> |
| | | <el-menu-item-group class="item-group"> |
| | | <tree-menu |
| | | ref="tree" |
| | | :app="appName" |
| | | :treeName="'localTree'" |
| | | :node="TreeDataPool.treeData" |
| | | :height="height" |
| | | @addDevice="addCamera" |
| | | @import="importCameras" |
| | | /> |
| | | </el-menu-item-group> |
| | | </el-submenu> |
| | | </el-menu> |
| | | </el-tab-pane> |
| | | <el-tab-pane |
| | | label="集群" |
| | | name="cluster" |
| | | :style="`height:${height - 56}px;`" |
| | | v-if="showCluster" |
| | | > |
| | | <div class="local-vedio-area"> |
| | | <!-- 搜索 --> |
| | | <div class="navTopSelect"> |
| | | <div class="search-input flex-box"> |
| | | <el-select |
| | | v-model="TreeDataPool.searchCamType" |
| | | placeholder="请选择" |
| | | @change="searchClusterData" |
| | | > |
| | | <el-option |
| | | v-for="item in searchTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | <span style="display: inline-block;padding: 0px 3px;"></span> |
| | | <el-input |
| | | v-model="TreeDataPool.searchInput" |
| | | placeholder="搜索" |
| | | clearable |
| | | @input="querySearchAsync('cluster')" |
| | | > |
| | | <i |
| | | class="el-icon-search el-input__icon" |
| | | style="color:#DCDFE6" |
| | | slot="prefix" |
| | | @click="searchClusterData" |
| | | ></i> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | <div class="top-menu" style="margin:0 0 10px;text-align:left;"> |
| | | <span class="iconfont iconjiqun" style="font-size:20px;"></span> |
| | | <span style="font-size:14px; margin-left: 5px;font-weight: 600;">{{clusterName}}</span> |
| | | </div> |
| | | <div class="cluster-list"> |
| | | <tree-menu |
| | | ref="tree" |
| | | :app="appName" |
| | | :treeName="'localTree'" |
| | | :node="TreeDataPool.clusterData" |
| | | :height="height" |
| | | @addDevice="addCamera" |
| | | @import="importCameras" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="数据栈" name="dataStack" v-if="showDataStack"> |
| | | <div class="local-vedio-area"> |
| | | <!-- 搜索 --> |
| | | <div class="search-input"> |
| | | <!-- <span style="display: inline-block;padding: 0px 3px;"></span> --> |
| | | <el-select |
| | | v-model="DataStackPool.searchType" |
| | | placeholder="请选择" |
| | | size="small" |
| | | style="width: 134px;height: 34px;margin-left: 10px;" |
| | | @change="searchDataStack" |
| | | > |
| | | <el-option |
| | | v-for="item in DataStackPool.searchOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | <span style="display: inline-block;padding: 0px 3px;"></span> |
| | | <el-input |
| | | v-model="DataStackPool.searchInput" |
| | | placeholder="请输入" |
| | | size="small" |
| | | clearable |
| | | @input="querySearchAsync('dir')" |
| | | :style="'width:148px;'" |
| | | > |
| | | <i |
| | | class="el-icon-search el-input__icon" |
| | | style="color:black" |
| | | slot="prefix" |
| | | @click="searchDataStack" |
| | | ></i> |
| | | </el-input> |
| | | <!-- 隐藏树按钮 --> |
| | | <!-- <div class="dev-tree-close"> |
| | | <i |
| | | class="el-icon-s-fold" |
| | | style="color: #3D68E1;line-height: 22px;font-size: 27px;" |
| | | @click="closeTree" |
| | | ></i> |
| | | </div>--> |
| | | </div> |
| | | |
| | | <!-- 本地视频源列表 --> |
| | | <div class="dev-vedio-list"> |
| | | <!-- 添加文件夹图标 --> |
| | | <div class="tree-edit area-add" v-show="!DataStackPool.readonly"> |
| | | <el-tooltip content="添加文件夹" placement="bottom" popper-class="atooltip"> |
| | | <button @click="addDir($event)"> |
| | | <i class="iconfont iconhebingxingzhuang"></i> |
| | | </button> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 文件夹操作锁 --> |
| | | <div class="tree-edit tree-lock" v-show="showLock"> |
| | | <button @click="dataStackLockSwitch"> |
| | | <i v-if="DataStackPool.readonly" class="el-icon-lock"></i> |
| | | <i v-else class="el-icon-unlock"></i> |
| | | </button> |
| | | </div> |
| | | <LocalVedioList :dataList="TreeDataPool.localVedioList"></LocalVedioList> |
| | | </div> |
| | | </div> |
| | | <file-upload v-show="fileUploadBox" @close="fileUploadBox= false" /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- 导入设备组件 事件触发 --> |
| | | <el-upload |
| | | class="upload-btn" |
| | | action="https://jsonplaceholder.typicode.com/posts/" |
| | | accept=".xlsx" |
| | | :on-exceed="exceed" |
| | | :limit="10" |
| | | :on-remove="remove" |
| | | :http-request="uploadFile" |
| | | :show-file-list="false" |
| | | > |
| | | <button ref="import-btn" v-show="false"></button> |
| | | </el-upload> |
| | | </div> |
| | | </transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import { |
| | | show, |
| | | changeEnable, |
| | | deleteLocalFile, |
| | | updateStatus |
| | | } from "@/api/localVedio"; |
| | | |
| | | import { |
| | | createCamera, |
| | | } from "@/api/camera"; |
| | | |
| | | import bus from "@/plugin/bus" |
| | | // import TreeMenu from "@/components/treeMenu/index"; |
| | | import TreeMenu from "@/components/giantTree/index"; |
| | | import LocalVedioList from '@/components/subComponents/LocalVedioList'; |
| | | import FileUpload from '@/components/subComponents/FileUpload/index'; |
| | | import XLSX from 'xlsx' |
| | | import { findCluster } from "@/api/clusterManage"; |
| | | |
| | | export default { |
| | | components: { |
| | | TreeMenu, |
| | | LocalVedioList, |
| | | FileUpload |
| | | }, |
| | | props: { |
| | | appName: { |
| | | type: String, |
| | | default: "Video" |
| | | }, |
| | | edit: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | height: { |
| | | type: Number, |
| | | default: 0 |
| | | } |
| | | }, |
| | | |
| | | computed: { |
| | | showTab() { |
| | | return true; |
| | | }, |
| | | showCam() { |
| | | return this.appName === "Camera" || this.appName === 'Cluster' || (this.appName === "Search" && (this.buttonAuthority.indexOf("search:camera") >= 0 || this.isAdmin)); |
| | | }, |
| | | showCluster() { |
| | | return this.appName === "Cluster"; |
| | | }, |
| | | // 数据栈配置必须显示。 检索通过权限控制显示, 未安装数据栈也不显示 |
| | | showDataStack() { |
| | | if (this.appName === "DataStack") { |
| | | return true; |
| | | } |
| | | |
| | | if (this.appName === "Search") { |
| | | // 未安装数据栈配置 |
| | | if (this.installedApps.indexOf("dataStack") >= 0) { |
| | | if (this.isAdmin) { |
| | | return true; |
| | | } |
| | | |
| | | if (this.buttonAuthority.indexOf("search:stack") >= 0) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | showLock() { |
| | | return this.edit; |
| | | }, |
| | | openeds() { |
| | | let arry = []; |
| | | for (let i = 0; i < this.TreeDataPool.openeds.length; i++) { |
| | | if (this.TreeDataPool.openeds[i]) { |
| | | arry.push(i + ""); |
| | | // 默认展开一颗有数据的树 |
| | | break; |
| | | } |
| | | } |
| | | return arry; |
| | | }, |
| | | isAdmin() { |
| | | if ( |
| | | sessionStorage.getItem("userInfo") && |
| | | sessionStorage.getItem("userInfo") !== "" |
| | | ) { |
| | | let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username; |
| | | return loginName === "superadmin" || loginName === "basic"; |
| | | } |
| | | return false; |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | dataStack: "videoMonitor:dataStack", |
| | | buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [], |
| | | installedApps: sessionStorage.getItem("apps") || [], |
| | | loginName: JSON.parse(sessionStorage.getItem("userInfo")).username || "用户名", |
| | | searchTypeOptions: [ |
| | | { |
| | | value: 0, |
| | | label: "全部摄像机" |
| | | }, |
| | | { |
| | | value: 1, |
| | | label: "分析摄像机" |
| | | }, |
| | | { |
| | | value: 2, |
| | | label: "监控摄像机" |
| | | }, |
| | | { |
| | | value: 3, |
| | | label: "联动摄像机" |
| | | } |
| | | ], |
| | | timeout: null, |
| | | fileUploadBox: false, |
| | | loadingGBTree: false, |
| | | importAreaId: "", |
| | | menuLoading: false, |
| | | clusterName: '' |
| | | }; |
| | | }, |
| | | created() { |
| | | if (this.showCam) { |
| | | this.TreeDataPool.treeActiveName = "camera" |
| | | this.TreeDataPool.fetchTreeData(); |
| | | |
| | | } else { |
| | | this.TreeDataPool.treeActiveName = "dataStack" |
| | | this.DataStackPool.fetchFiles(); |
| | | |
| | | } |
| | | if (this.showCluster) { |
| | | this.TreeDataPool.treeActiveName = "cluster" |
| | | this.TreeDataPool.fetchClusterTree(); |
| | | findCluster().then(res => { |
| | | if (res.success) { |
| | | this.clusterName = res.data.clusterName; |
| | | } |
| | | |
| | | }) |
| | | } |
| | | }, |
| | | methods: { |
| | | searchAreaData() { |
| | | this.TreeDataPool.fetchTreeData(); |
| | | }, |
| | | searchDataStack() { |
| | | this.DataStackPool.fetchFiles(); |
| | | }, |
| | | searchClusterData() { |
| | | this.TreeDataPool.fetchClusterTree(); |
| | | }, |
| | | lockSwitch() { |
| | | this.TreeDataPool.readonly = !this.TreeDataPool.readonly; |
| | | }, |
| | | gbLockSwitch() { |
| | | this.TreeDataPool.gbReadonly = !this.TreeDataPool.gbReadonly; |
| | | }, |
| | | dataStackLockSwitch() { |
| | | this.DataStackPool.readonly = !this.DataStackPool.readonly; |
| | | }, |
| | | closeTree() { |
| | | this.TreeDataPool.showTreeBox = false; |
| | | bus.$emit('refreshCompareImg') |
| | | }, |
| | | addNode(event) { |
| | | this.$refs.tree.addNode(event, { id: 0 }); |
| | | }, |
| | | addCamera(node) { |
| | | bus.$emit("addCameraOnTree", node); |
| | | }, |
| | | addDir(node) { |
| | | bus.$emit("addDirOnTree", node); |
| | | }, |
| | | menuOpen(index) { |
| | | this.TreeDataPool.openeds[index] = true; |
| | | }, |
| | | menuClose(index) { |
| | | this.TreeDataPool.openeds[index] = false; |
| | | }, |
| | | refreshGB() { |
| | | // 防止重复刷新 |
| | | if (this.loadingGBTree) { |
| | | return; |
| | | } |
| | | |
| | | // 国标摄像机数据是国标服务分批推送的,请求刷新列表后,需要等待约1分钟的时间后端才能同步完数据。 |
| | | this.TreeDataPool.refreshGB28181(); |
| | | this.loadingGBTree = true; |
| | | setTimeout(() => { |
| | | this.TreeDataPool.fetchGbTree(); |
| | | this.loadingGBTree = false; |
| | | }, 1000 * 60); |
| | | }, |
| | | querySearchAsync(type) { |
| | | clearTimeout(this.timeout); |
| | | this.timeout = setTimeout(() => { |
| | | if (type === "camera") { |
| | | this.TreeDataPool.fetchTreeData(); |
| | | } |
| | | if (type === "cluster") { |
| | | this.TreeDataPool.fetchClusterTree(); |
| | | } |
| | | if (type === "dir") { |
| | | this.DataStackPool.fetchFiles(); |
| | | } |
| | | }, 500); |
| | | }, |
| | | handleClick(event) { |
| | | if (event.name == 'dataStack') { |
| | | this.DataStackPool.fetchFiles(); |
| | | this.DataStackPool.clean(); |
| | | this.TreeDataPool.clean(); |
| | | } |
| | | this.TreeDataPool.treeActiveName = event.name |
| | | console.log("当前激活name:", this.TreeDataPool.treeActiveName) |
| | | }, |
| | | async changeEnable() { |
| | | if (this.PollData.localVideo === 0) { |
| | | this.$notify({ |
| | | title: "失败", |
| | | type: "warning", |
| | | message: "开启本地数据视频分析处理,需先为本地数据手动设置算力资源!" |
| | | }) |
| | | return false; |
| | | } |
| | | let res = await changeEnable({ |
| | | enable: this.TreeDataPool.vedioAnaliyseSwitch |
| | | }) |
| | | if (res && res.success) { |
| | | console.log(res, '切换本地文件分析开关') |
| | | } |
| | | }, |
| | | getCheckedFiles() { |
| | | let list1 = this.TreeDataPool.localVedioList.filter(i => { |
| | | return i.checkStatus |
| | | }) |
| | | return list1 |
| | | }, |
| | | async stopVedio(status) { |
| | | // let list1 = this.getCheckedFiles(); |
| | | if (this.TreeDataPool.checkedLocalVedio.length == 0) { |
| | | this.$notify({ |
| | | type: "warning", |
| | | message: "请先选择需要停止的视频!" |
| | | }); |
| | | // this.$notify({ |
| | | // type:"info", |
| | | // message:"请先选择需要停止的视频!" |
| | | // }) |
| | | return false; |
| | | } |
| | | let res = await updateStatus({ |
| | | ids: this.TreeDataPool.checkedLocalVedio.map(i => { |
| | | return i.id |
| | | }), |
| | | status: status |
| | | }) |
| | | if (res && res.success) { |
| | | console.log(res, '开启暂停参数') |
| | | } |
| | | }, |
| | | async deleteLocalFiles() { |
| | | let list1 = this.getCheckedFiles(); |
| | | console.log(list1, '已勾选的视频') |
| | | if (list1.length == 0) { |
| | | return false |
| | | } |
| | | let res = await deleteLocalFile({ |
| | | ids: list1.map(i => { return i.id }) |
| | | }) |
| | | if (res && res.success) { |
| | | this.$notify({ |
| | | type: 'success', |
| | | message: '删除成功!!' |
| | | }) |
| | | } else { |
| | | this.$notify({ |
| | | type: "error", |
| | | message: "删除失败!" |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | refrash(current, pageSize) { |
| | | this.TreeDataPool.localCurrentPage = current; |
| | | }, |
| | | |
| | | importCameras(area) { |
| | | this.importAreaId = area |
| | | this.$refs["import-btn"].click() |
| | | }, |
| | | |
| | | async uploadFile(params) { |
| | | const _file = params.file; |
| | | const fileReader = new FileReader(); |
| | | fileReader.onload = (ev) => { |
| | | this.menuLoading = true; |
| | | try { |
| | | const data = ev.target.result; |
| | | const workbook = XLSX.read(data, { |
| | | type: 'binary' |
| | | }); |
| | | |
| | | for (let sheet in workbook.Sheets) { |
| | | //循环读取每个文件 |
| | | const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]); |
| | | //若当前sheet没有数据,则continue |
| | | if (sheetArray.length == 0) { |
| | | continue; |
| | | } |
| | | |
| | | let succeed = 0; |
| | | let failed = 0; |
| | | let promiseArr = []; |
| | | for (let item in sheetArray) { |
| | | let camera = this.newCamera(); |
| | | camera.areaid = this.importAreaId; |
| | | camera.name = String(sheetArray[item].name); |
| | | camera.rtsp = String(sheetArray[item].rtsp); |
| | | camera.addr = String(sheetArray[item].addr); |
| | | |
| | | promiseArr.push(createCamera(camera)); |
| | | } |
| | | let _this = this; |
| | | Promise.allSettled(promiseArr).then(res => { |
| | | res.forEach(item => { |
| | | if (item.status === 'fulfilled') { |
| | | succeed++; |
| | | } else { |
| | | failed++; |
| | | } |
| | | }); |
| | | _this.menuLoading = false; |
| | | _this.$message({ |
| | | type: "success", |
| | | message: "操作完成, 导入成功:" + succeed + "个 失败:" + failed + "个" |
| | | }) |
| | | _this.TreeDataPool.fetchTreeData(); |
| | | }).catch(e => { |
| | | console.log(e) |
| | | }); |
| | | |
| | | } |
| | | } catch (e) { |
| | | this.menuLoading = false |
| | | this.$message.warning('文件类型不正确!'); |
| | | } |
| | | }; |
| | | fileReader.readAsBinaryString(_file); |
| | | }, |
| | | exceed() { |
| | | this.$message.error("最多只能上传1个xls文件"); |
| | | }, |
| | | //删除文件 |
| | | remove() { |
| | | |
| | | }, |
| | | newCamera() { |
| | | return { |
| | | latitude: 0, |
| | | rtsp: "", |
| | | longitude: 0, |
| | | name: "", |
| | | addr: "", |
| | | areaid: "", |
| | | reserved: "", |
| | | run_type: -1, |
| | | username: "", |
| | | password: "", |
| | | sensors: [] |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .left-tree-box { |
| | | float: left; |
| | | width: 100%; |
| | | .el-tabs__nav-prev, |
| | | .el-tabs__nav-next { |
| | | display: none; |
| | | } |
| | | .el-tabs--border-card { |
| | | border: none; |
| | | box-shadow: none; |
| | | .el-tabs__header { |
| | | display: none; |
| | | border-bottom: none; |
| | | //margin: 0 0 15px; |
| | | } |
| | | .el-tabs__content { |
| | | padding: 0; |
| | | width: 100%; |
| | | } |
| | | } |
| | | ul { |
| | | li { |
| | | .el-menu-item-group__title { |
| | | padding: none; |
| | | } |
| | | } |
| | | .el-submenu__title, |
| | | .el-menu-item { |
| | | padding-left: 10px !important; |
| | | color: #222222 !important; |
| | | font-size: 17px !important; |
| | | height: 35px; |
| | | line-height: 35px; |
| | | .el-submenu__icon-arrow { |
| | | font-size: 12px !important; |
| | | padding-right: 2px !important; |
| | | right: 0; |
| | | //right: unset; |
| | | } |
| | | i { |
| | | padding-right: 10px !important; |
| | | font-size: 24px !important; |
| | | color: #666666 !important; |
| | | } |
| | | } |
| | | } |
| | | .navTopSelect { |
| | | display: flex; |
| | | text-align: left; |
| | | |
| | | .el-input__icon { |
| | | line-height: 34px; |
| | | } |
| | | // padding: 24px 0px; |
| | | // padding-top: 24px; |
| | | padding-bottom: 12px; |
| | | input:nth-child(1) { |
| | | height: 34px; |
| | | box-shadow: 0 2px 11px -6px rgba(95, 95, 95, 0.5); |
| | | } |
| | | input:nth-child(2) { |
| | | height: 34px; |
| | | width: 103px; |
| | | box-shadow: 0 2px 11px -6px rgba(95, 95, 95, 0.5); |
| | | } |
| | | } |
| | | .isCollapse { |
| | | font-size: 20px; |
| | | padding: 0px 5px; |
| | | } |
| | | // .el-input__inner:focus { |
| | | // outline: none; |
| | | // border-color: #3D68E1; |
| | | // } |
| | | .el-menu { |
| | | border-right: none; |
| | | } |
| | | .el-menu-vertical-demo:not(.el-menu--collapse) { |
| | | .fontFamily, |
| | | .el-submenu__title .fontFamily, |
| | | .el-submenu__title .fontFamily { |
| | | padding-right: 20px; |
| | | font-size: 22px; |
| | | } |
| | | .el-menu { |
| | | // border-right: solid 1px #e6e6e6; |
| | | border-right: none; |
| | | } |
| | | } |
| | | .el-menu-vertical-demo:hover { |
| | | overflow-y: hidden; |
| | | overflow-x: hidden; |
| | | } |
| | | .tree-anchor .fontFamily { |
| | | font-size: 16px !important; |
| | | color: #2074ef; |
| | | padding-right: 0px !important; |
| | | } |
| | | .el-submenu__title, |
| | | .el-menu-item { |
| | | text-align: left; |
| | | } |
| | | |
| | | .item-group { |
| | | margin-left: 33px; |
| | | margin-top: -12px; |
| | | } |
| | | .el-tabs__item { |
| | | padding: 0 10px; |
| | | height: 40px; |
| | | -webkit-box-sizing: border-box; |
| | | box-sizing: border-box; |
| | | line-height: 40px; |
| | | display: inline-block; |
| | | list-style: none; |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | position: relative; |
| | | } |
| | | |
| | | .local-vedio-area { |
| | | float: left; |
| | | width: 300px; |
| | | .tree-edit-btn { |
| | | width: 100%; |
| | | height: 40px; |
| | | text-align: left; |
| | | margin-top: -8px; |
| | | i { |
| | | font-size: 20px; |
| | | margin: 0px 17px; |
| | | } |
| | | .el-button { |
| | | margin-left: 0px; |
| | | } |
| | | } |
| | | .search-input { |
| | | padding-top: 8px; |
| | | padding-bottom: 12px; |
| | | text-align: left; |
| | | .dev-tree-close { |
| | | width: 10%; |
| | | margin-left: 10px; |
| | | font-size: 20px; |
| | | display: inline-block; |
| | | color: #9ea0a0; |
| | | vertical-align: middle; |
| | | cursor: pointer; |
| | | } |
| | | .dev-switch-close { |
| | | text-align: left; |
| | | margin-left: 15px; |
| | | margin-top: 10px; |
| | | span { |
| | | font-size: 15px; |
| | | } |
| | | } |
| | | } |
| | | .dev-vedio-list { |
| | | padding: 0 15px; |
| | | box-sizing: border-box; |
| | | // height: calc(100vh - 80px); |
| | | //max-height: 740px; |
| | | // overflow-x: hidden; |
| | | overflow: auto; |
| | | |
| | | } |
| | | .dev-vedio-list::-webkit-scrollbar { |
| | | /*滚动条整体样式*/ |
| | | width: 4px; /*高宽分别对应横竖滚动条的尺寸*/ |
| | | height: 4px; |
| | | } |
| | | } |
| | | } |
| | | .tree-close { |
| | | width: 10%; |
| | | margin-left: 10px; |
| | | font-size: 20px; |
| | | display: inline-block; |
| | | color: #9ea0a0; |
| | | vertical-align: middle; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .tree-edit { |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | position: absolute; |
| | | top: 56px; |
| | | cursor: pointer; |
| | | button { |
| | | border: 0px; |
| | | color: #3d68e1; |
| | | |
| | | background-color: transparent; |
| | | cursor: pointer; |
| | | outline: none; |
| | | } |
| | | button:hover { |
| | | color: #2249b4; |
| | | } |
| | | } |
| | | .tree-lock { |
| | | left: 235px; |
| | | button { |
| | | color: #000; |
| | | } |
| | | } |
| | | |
| | | .gb-lock { |
| | | left: 231px; |
| | | top: -27px; |
| | | button { |
| | | color: #000; |
| | | } |
| | | } |
| | | .area-add { |
| | | left: 100px; |
| | | } |
| | | .camera-add { |
| | | left: 128px; |
| | | } |
| | | |
| | | .import-btn { |
| | | left: 156px; |
| | | } |
| | | .tree-font { |
| | | font-family: PingFangSC-Medium; |
| | | font-size: 14px; |
| | | color: #222222; |
| | | } |
| | | |
| | | .gb-refresh { |
| | | top: -27px; |
| | | left: 113px; |
| | | } |
| | | .paginationClass { |
| | | width: 100%; |
| | | height: 60px; |
| | | .el-pagination { |
| | | max-width: 300px; |
| | | white-space: nowrap; |
| | | padding: 0; |
| | | color: #303133; |
| | | font-weight: bold; |
| | | } |
| | | .el-pagination__jump { |
| | | margin-left: 0px; |
| | | font-weight: normal; |
| | | color: #606266; |
| | | } |
| | | } |
| | | .flex-box { |
| | | display: flex; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div |
| | | :style="'width:' + vWidth + ';height:' + vHeight" |
| | | class="video-box" |
| | | @click.stop.prevent="_click" |
| | | @mouseenter.stop.prevent="videoMouseEnter($event)" |
| | | @mouseleave="videoMouseLeave($event)" |
| | | > |
| | | <div |
| | | class="video-box-top" |
| | | v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null" |
| | | > |
| | | <b>{{ videoItem.name }}</b> |
| | | <span @click="deleteVideo(videoIndex)">×</span> |
| | | </div> |
| | | <div style="position:relative;width:100%;height: 100%;background:#272727;"> |
| | | <div class="circle"> |
| | | <p class="p1" @mousedown="ptCtrl('up')" @mouseup="ptStop"></p> |
| | | <p class="p2" @mousedown="ptCtrl('right')" @mouseup="ptStop"></p> |
| | | <div class="mid" @mouseup="ptStop"> |
| | | <span class="mid_1" @mousedown="ptCtrl('zoomin')"> |
| | | <i class="el-icon-plus"></i> |
| | | </span> |
| | | <span class="mid_2" @mousedown="ptCtrl('zoomout')" @mouseup="ptStop"> |
| | | <i class="el-icon-minus"></i> |
| | | </span> |
| | | </div> |
| | | <p class="p3" @mousedown="ptCtrl('down')" @mouseup="ptStop"></p> |
| | | <p class="p4" @mousedown="ptCtrl('left')" @mouseup="ptStop"></p> |
| | | </div> |
| | | <camera-player |
| | | :cameraName="videoItem.name" |
| | | :cameraID="videoItem.id" |
| | | :rtspUrl="videoItem.rtsp" |
| | | :isRunning="videoItem.isRunning" |
| | | :isGb="videoItem.cameraType === 1" |
| | | :showArea="showArea" |
| | | v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && TreeDataPool.treeActiveName==='camera'" |
| | | ></camera-player> |
| | | |
| | | <video |
| | | v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && TreeDataPool.treeActiveName==='dataStack'" |
| | | :src="videoItem.rtsp" |
| | | autoplay="autoplay" |
| | | poster="/images/cameraVideo/video-poster.png" |
| | | controls |
| | | >您的浏览器不支持 video 标签。</video> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { ptzControl } from "@/api/camera" |
| | | |
| | | import CameraPlayer from "@/components/player"; |
| | | |
| | | export default { |
| | | components: { |
| | | CameraPlayer |
| | | }, |
| | | props: { |
| | | videoGuid: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | videoIndex: null, |
| | | starW: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | starH:{ |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | videoItem: { |
| | | type: [Object, String], |
| | | default: null |
| | | }, |
| | | showArea: Boolean, |
| | | }, |
| | | data() { |
| | | return { |
| | | timer: '', |
| | | mouseDown: false, |
| | | videoDataItem: null |
| | | } |
| | | }, |
| | | computed: { |
| | | vWidth() { |
| | | if (this.starW!=0) { |
| | | return this.starW |
| | | |
| | | } |
| | | let per = (1 / this.videoGuid) * 100 + "%"; |
| | | return `calc(${per} - 4px)`; |
| | | }, |
| | | |
| | | vHeight() { |
| | | if (this.starH!=0) { |
| | | return this.starH |
| | | } |
| | | let per = (1 / this.videoGuid) * 100 + "%"; |
| | | return `calc(${per} - 4px)`; |
| | | } |
| | | }, |
| | | methods: { |
| | | _click() { |
| | | this.$emit("click"); |
| | | }, |
| | | ptCtrl(type) { |
| | | // 当前只支持国标摄像机 |
| | | // console.log(type, 'ptCtrl') |
| | | if (this.videoItem.cameraType != 1) { |
| | | return |
| | | } |
| | | this.mouseDown = true; |
| | | let params = { |
| | | cameraId: this.videoItem.id, |
| | | cameraType: this.videoItem.cameraType, |
| | | PTZType: type |
| | | } |
| | | ptzControl(params).then(rsp => { |
| | | // console.log(rsp) |
| | | }) |
| | | let that = this |
| | | this.timer = setTimeout(() => { |
| | | that.ptStop() |
| | | }, 5000) |
| | | }, |
| | | ptStop() { |
| | | // 当前只支持国标摄像机 |
| | | if (this.videoItem.cameraType != 1) { |
| | | return |
| | | } |
| | | let params = { |
| | | cameraId: this.videoItem.id, |
| | | cameraType: this.videoItem.cameraType, |
| | | PTZType: "stop" |
| | | } |
| | | if (this.mouseDown) { |
| | | this.mouseDown = false |
| | | ptzControl(params).then(rsp => { |
| | | // console.log(rsp) |
| | | }) |
| | | } |
| | | }, |
| | | deleteVideo(index) { |
| | | let video = this.TreeDataPool.videoArr; |
| | | video[index].isPlaying = false; |
| | | this.TreeDataPool.setVideoArr(index, undefined, this); |
| | | }, |
| | | videoMouseEnter(e) { |
| | | let target = e.target; |
| | | if (target.children.length > 1) { |
| | | target.children[0].style.display = "block"; |
| | | target.children[1].children[0].style.display = "block"; |
| | | } |
| | | }, |
| | | videoMouseLeave(e) { |
| | | let videoBoxTop = document.getElementsByClassName("video-box-top"); |
| | | let circle = document.getElementsByClassName("circle"); |
| | | for (let i = 0; i < videoBoxTop.length; i++) { |
| | | videoBoxTop[i].style.display = "none"; |
| | | } |
| | | for (let i = 0; i < circle.length; i++) { |
| | | circle[i].style.display = "none"; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .side-border { |
| | | border-right: 1px solid #cacaca; |
| | | border-bottom: 1px solid #cacaca; |
| | | } |
| | | .video-box { |
| | | float: left; |
| | | box-sizing: border-box; |
| | | padding-left: 1px; |
| | | padding-bottom: 1px; |
| | | position: relative; |
| | | margin: 0px 4px 4px 0px; |
| | | background-color: #cacaca; |
| | | .video-box-top { |
| | | color: white; |
| | | display: none; |
| | | width: 100%; |
| | | height: 32px; |
| | | line-height: 32px; |
| | | padding: 0px 20px; |
| | | box-sizing: border-box; |
| | | background: #27293190; |
| | | position: absolute; |
| | | top: 0px; |
| | | z-index: 2; |
| | | b { |
| | | float: left; |
| | | } |
| | | span { |
| | | float: right; |
| | | font-size: 22px; |
| | | font-weight: 900; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .circle { |
| | | height: 60px; |
| | | width: 60px; |
| | | border-radius: 50%; |
| | | background: rgba(0, 0, 0, 0.29); |
| | | position: absolute; |
| | | z-index: 1; |
| | | top: 40px; |
| | | right: 10px; |
| | | display: none; |
| | | p { |
| | | position: relative; |
| | | cursor: pointer; |
| | | } |
| | | .p1 { |
| | | width: 0px; |
| | | height: 0px; |
| | | border: 8px solid; |
| | | border-bottom-color: rgba(0, 0, 0, 0.6); |
| | | border-left-color: transparent; |
| | | border-top-color: transparent; |
| | | border-right-color: transparent; |
| | | left: 22px; |
| | | top: -2px; |
| | | } |
| | | .p2 { |
| | | width: 0px; |
| | | height: 0px; |
| | | border: 8px solid; |
| | | border-bottom-color: transparent; |
| | | border-left-color: rgba(0, 0, 0, 0.6); |
| | | border-top-color: transparent; |
| | | border-right-color: transparent; |
| | | left: 46px; |
| | | top: 7px; |
| | | } |
| | | .p3 { |
| | | width: 0px; |
| | | height: 0px; |
| | | border: 8px solid; |
| | | border-bottom-color: transparent; |
| | | border-left-color: transparent; |
| | | border-top-color: rgba(0, 0, 0, 0.6); |
| | | border-right-color: transparent; |
| | | left: 23px; |
| | | top: -8px; |
| | | } |
| | | .p4 { |
| | | width: 0px; |
| | | height: 0px; |
| | | border: 8px solid; |
| | | border-bottom-color: transparent; |
| | | border-left-color: transparent; |
| | | border-top-color: transparent; |
| | | border-right-color: rgba(0, 0, 0, 0.6); |
| | | left: -2px; |
| | | top: -49px; |
| | | } |
| | | .mid { |
| | | width: 24px; |
| | | height: 24px; |
| | | border-radius: 50%; |
| | | position: relative; |
| | | font-size: 5px; |
| | | top: -13px; |
| | | left: 18px; |
| | | background: rgba(0, 0, 0, 0.6); |
| | | span { |
| | | height: 24px; |
| | | float: left; |
| | | line-height: 24px; |
| | | text-align: center; |
| | | box-sizing: border-box; |
| | | cursor: pointer; |
| | | font-weight: 900; |
| | | color: rgba($color: rgb(97, 97, 97), $alpha: 0.4); |
| | | } |
| | | span:hover { |
| | | color: #fff; |
| | | // background-color: #409eff; |
| | | } |
| | | .mid_1 { |
| | | width: 50%; |
| | | height: 24px; |
| | | border-top-left-radius: 50%; |
| | | border-bottom-left-radius: 50%; |
| | | } |
| | | .mid_1:hover { |
| | | background: #fff; |
| | | color: #222222; |
| | | } |
| | | .mid_2 { |
| | | border-top-right-radius: 50%; |
| | | border-bottom-right-radius: 50%; |
| | | width: 50%; |
| | | height: 24px; |
| | | } |
| | | .mid_2:hover { |
| | | background: #fff; |
| | | color: #222222; |
| | | } |
| | | } |
| | | .mid2 { |
| | | width: 18px; |
| | | height: 18px; |
| | | } |
| | | .p1:hover { |
| | | border-bottom-color: #fff; |
| | | } |
| | | .p2:hover { |
| | | border-left-color: #fff; |
| | | } |
| | | .p3:hover { |
| | | border-top-color: #fff; |
| | | } |
| | | .p4:hover { |
| | | border-right-color: #fff; |
| | | } |
| | | } |
| | | |
| | | .video-js, |
| | | .vjs-custom-skin { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .video-play { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | bottom: 0px; |
| | | right: 0px; |
| | | margin: auto; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="column"> |
| | | <div class="column-left" > |
| | | <div class="resize-bar"></div> |
| | | <div class="resize-line"></div> |
| | | <div class="resize-save"> |
| | | <left-nav :appName="'Camera'" :height="screenHeight - 40"></left-nav> |
| | | </div> |
| | | </div> |
| | | <div class="column-right" > |
| | | <right-side /> |
| | | </div> |
| | | <card-window></card-window> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | // import LeftNav from "@/components/LeftNav"; |
| | | import LeftNav from "../components/LeftNav"; |
| | | import RightSide from "./Video"; |
| | | import CardWindow from "@/components/cardWindow"; |
| | | |
| | | export default { |
| | | name: "CameraVideo", |
| | | components: { |
| | | LeftNav, |
| | | RightSide, |
| | | CardWindow |
| | | }, |
| | | data() { |
| | | return { |
| | | screenHeight: 0, |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.screenHeight = document.documentElement.clientHeight - 20; |
| | | window.onresize = () => { |
| | | return (() => { |
| | | this.screenHeight = document.documentElement.clientHeight - 20; |
| | | })(); |
| | | }; |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | |
| | | .column { |
| | | overflow: hidden; |
| | | // min-width: 1399px; |
| | | // height: 100%; |
| | | } |
| | | .column-left { |
| | | background-color: #fff; |
| | | position: relative; |
| | | float: left; |
| | | height: 100vh; |
| | | //height: inherit; |
| | | } |
| | | .column-right { |
| | | height: 100vh; |
| | | background-color: #eee; |
| | | box-sizing: border-box; |
| | | //overflow: hidden; |
| | | overflow-x: auto; |
| | | overflow-y: auto; |
| | | } |
| | | .resize-save { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 5px; |
| | | bottom: 0; |
| | | left: 0; |
| | | padding: 14px; |
| | | overflow-x: hidden; |
| | | } |
| | | .resize-bar { |
| | | width: 310px; |
| | | height: inherit; |
| | | resize: horizontal; |
| | | cursor: ew-resize; |
| | | opacity: 0; |
| | | overflow: scroll; |
| | | max-width: 500px; //设定最大拉伸长度 |
| | | min-width: 33px; //设定最小宽度 |
| | | } |
| | | /* 拖拽线 */ |
| | | .resize-line { |
| | | position: absolute; |
| | | right: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | border-right: 2px solid #efefef; |
| | | border-left: 1px solid #e0e0e0; |
| | | pointer-events: none; |
| | | } |
| | | .resize-bar:hover ~ .resize-line, |
| | | .resize-bar:active ~ .resize-line { |
| | | border-left: 1px dashed skyblue; |
| | | } |
| | | .resize-bar::-webkit-scrollbar { |
| | | width: 200px; |
| | | height: inherit; |
| | | } |
| | | |
| | | /* Firefox只有下面一小块区域可以拉伸 */ |
| | | @supports (-moz-user-select: none) { |
| | | .resize-bar:hover ~ .resize-line, |
| | | .resize-bar:active ~ .resize-line { |
| | | border-left: 1px solid #bbb; |
| | | } |
| | | .resize-bar:hover ~ .resize-line::after, |
| | | .resize-bar:active ~ .resize-line::after { |
| | | content: ""; |
| | | position: absolute; |
| | | width: 16px; |
| | | height: 16px; |
| | | bottom: 0; |
| | | right: -8px; |
| | | // background: url(./resize.svg); |
| | | background-size: 100% 100%; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div style="width: 100%; height: 100%"> |
| | | <div class="monitoring-right" ref="videoRight"> |
| | | <div class="main-top"> |
| | | <div class="monitoring-video" ref="monitorVideo"> |
| | | <!-- <div class="monitoring-video-guid"> |
| | | <span |
| | | :class="guid === 1 ? 'iconfont icongongge1 activegongge':'iconfont icongongge1'" |
| | | @click="setGuid(1)" |
| | | ></span> |
| | | <span |
| | | :class="guid === 2 ? 'iconfont icongongge activegongge':'iconfont icongongge'" |
| | | @click="setGuid(2)" |
| | | ></span> |
| | | <span |
| | | :class="guid === 3 ? 'iconfont icongongge2 activegongge':'iconfont icongongge2'" |
| | | @click="setGuid(3)" |
| | | ></span> |
| | | <el-tooltip v-if="TreeDataPool.selectedNode.id" :content="`${showArea?'隐藏区域':'查看区域'}`" placement="bottom" popper-class="atooltip"> |
| | | <span :class="showArea?'activegongge':''" class="iconfont iconquyu" @click="toggleShowArea"></span> |
| | | </el-tooltip> |
| | | </div> --> |
| | | <div class="fixedRatioBox"> |
| | | <!-- :class="guid==1?'video-main-box':'video-main-box-side'" --> |
| | | <div |
| | | class="video-main-box-side" |
| | | v-if="visibilityState && allVideoNum == 5" |
| | | > |
| | | <!-- :videoIndex="index" --> |
| | | <VideoItem |
| | | :videoGuid="guid" |
| | | :starW="`calc(66.66% - 4px)`" |
| | | :starH="`calc(66.66% - 4px)`" |
| | | :videoItem="centerVideo" |
| | | :showArea="showArea" |
| | | class="activeItem" |
| | | ></VideoItem> |
| | | <!-- <VideoItem |
| | | :videoGuid="guid" |
| | | :starW="`calc(66.66% - 4px)`" |
| | | :starH="`calc(66.66% - 4px)`" |
| | | :videoItem="nextVideo" |
| | | :showArea="showArea" |
| | | class="activeItem" |
| | | ></VideoItem> --> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | |
| | | <div |
| | | class="video-main-box-side" |
| | | v-if="visibilityState && allVideoNum == 7" |
| | | > |
| | | <VideoItem |
| | | :videoGuid="guid" |
| | | :starW="`calc(74.99% - 4px)`" |
| | | :starH="`calc(74.99% - 4px)`" |
| | | :videoItem="centerVideo" |
| | | :showArea="showArea" |
| | | class="activeItem" |
| | | ></VideoItem> |
| | | |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | |
| | | <div |
| | | class="video-main-box-side" |
| | | v-if="visibilityState && allVideoNum == 12" |
| | | > |
| | | <div style="width: 100%; height: 25%"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(0, 4)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(24.99% - 4px)`" |
| | | :starH="`calc(100% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <div style="width: 25%; height: 50%; float: left"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(4, 6)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(100% - 4px)`" |
| | | :starH="`calc(50% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <VideoItem |
| | | :videoGuid="guid" |
| | | :starW="`calc(50% - 4px)`" |
| | | :starH="`calc(50% - 4px)`" |
| | | :videoItem="centerVideo" |
| | | :showArea="showArea" |
| | | class="activeItem" |
| | | ></VideoItem> |
| | | <div style="width: 25%; height: 50%; float: left"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(6, 8)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(100% - 4px)`" |
| | | :starH="`calc(50% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <div style="width: 100%; height: 25%"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(8)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(24.99% - 4px)`" |
| | | :starH="`calc(100% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | </div> |
| | | |
| | | <div |
| | | class="video-main-box-side" |
| | | v-if="visibilityState && allVideoNum == 16" |
| | | > |
| | | <div style="width: 100%; height: 20%"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(0, 5)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(19.99% - 4px)`" |
| | | :starH="`calc(100% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <div style="width: 20%; height: 60%; float: left"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(5, 8)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(100% - 4px)`" |
| | | :starH="`calc(33.33% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <VideoItem |
| | | :videoGuid="guid" |
| | | :starW="`calc(60% - 4px)`" |
| | | :starH="`calc(60% - 4px)`" |
| | | :videoItem="centerVideo" |
| | | :showArea="showArea" |
| | | class="activeItem" |
| | | ></VideoItem> |
| | | <div style="width: 20%; height: 60%; float: left"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(8, 11)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(100% - 4px)`" |
| | | :starH="`calc(33.33% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | <div style="width: 100%; height: 20%; float: left"> |
| | | <VideoItem |
| | | v-for="(item, index) in TreeDataPool.videoArr.slice(11)" |
| | | :key="index" |
| | | :videoGuid="guid" |
| | | :videoIndex="index" |
| | | :starW="`calc(19.99% - 4px)`" |
| | | :starH="`calc(100% - 4px)`" |
| | | :videoItem="item" |
| | | :showArea="showArea" |
| | | :class="[ |
| | | TreeDataPool.activeVideoIndex === index + 1 |
| | | ? 'activeItem' |
| | | : '', |
| | | guid === 1 ? 'onlyActiveItem' : '', |
| | | ]" |
| | | @click="videoItemClick(index)" |
| | | ></VideoItem> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import VideoItem from "../components/VideoItem"; |
| | | import { getCameraPlayList, showAllCameras } from "@/api/trackCamera"; |
| | | |
| | | export default { |
| | | name: "Video", |
| | | components: { |
| | | VideoItem, |
| | | }, |
| | | data() { |
| | | return { |
| | | guid: 3, |
| | | center: "", |
| | | defaultHeight: 432, |
| | | defaultWidth: 600, |
| | | track: false, |
| | | traceCache: {}, |
| | | traceTimer: null, |
| | | tracePubUrl: `${location.protocol === "https" ? "wss" : "ws"}://${ |
| | | location.host |
| | | }/track`, |
| | | websocket: null, |
| | | visibilityState: true, |
| | | showArea: false, |
| | | videoNum2Play: 0, |
| | | centerVideo: null, |
| | | nextVideo: null, |
| | | list2TakeTurn: [], |
| | | timer: null, |
| | | centerIndex: 0, |
| | | |
| | | }; |
| | | }, |
| | | created() { |
| | | this.TreeDataPool.activeVideoIndex = sessionStorage.activeIndex |
| | | ? Number(sessionStorage.activeIndex) |
| | | : this.TreeDataPool.activeVideoIndex; |
| | | this.getActiveIndex(); |
| | | this.TreeDataPool.readonly = true; |
| | | this.TreeDataPool.gbReadonly = true; |
| | | this.TreeDataPool.multiple = false; |
| | | }, |
| | | mounted() { |
| | | document.addEventListener("visibilitychange", this.visibilitychange, false); |
| | | this.$nextTick(() => { |
| | | window.addEventListener("resize", this.resizeMonitorTask); |
| | | //this.getRightWidth(); |
| | | this.resizeMonitorTask(); |
| | | }); |
| | | this.getCenter(); |
| | | this.blackAngWhite(); |
| | | this.VideoPhotoData.queryTagList(); |
| | | showAllCameras().then((res) => { |
| | | this.videoNum2Play = res.data.length; |
| | | res.data.forEach((info, i) => { |
| | | let camera = this.TreeDataPool.getCameraInfoById(info.cameraId); |
| | | this.TreeDataPool.setVideoArr(i, camera, this); |
| | | if (info.status == 1) { |
| | | this.list2TakeTurn.push(info); |
| | | } |
| | | }); |
| | | if (this.list2TakeTurn.length == 0 && res.data.length) { |
| | | |
| | | this.list2TakeTurn.push(res.data[0]); |
| | | } |
| | | this.handleSwitch(); |
| | | this.list2TakeTurn.forEach((item) => {}); |
| | | }); |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener("resize", this.getRightWidth); |
| | | this.CardList.details = []; |
| | | window.clearInterval(this.trackTimer); |
| | | if (this.websocket) { |
| | | this.websocket.close(); |
| | | } |
| | | }, |
| | | watch: { |
| | | "TreeDataPool.videoArr": function (newArry) { |
| | | console.log("newArry", newArry); |
| | | const cameras = this.filterNodes(newArry); |
| | | this.getActiveIndex(); |
| | | // this.$refs.taskview.showTasks(cameras); |
| | | // this.$refs.photoview.showCapture(cameras); |
| | | }, |
| | | "VideoPhotoData.selectBlacks": function (value) { |
| | | this.blackAngWhite(); |
| | | }, |
| | | "VideoPhotoData.selectWhites": function (value) { |
| | | this.blackAngWhite(); |
| | | }, |
| | | "TreeDataPool.showTreeBox"(value) { |
| | | this.getRightWidth(); |
| | | }, |
| | | }, |
| | | methods: { |
| | | handleSwitch() { |
| | | if (this.list2TakeTurn.length == 1) { |
| | | this.centerVideo = this.list2TakeTurn[0]; |
| | | return; |
| | | } |
| | | |
| | | let that = this; |
| | | that.centerVideo = that.list2TakeTurn[that.centerIndex]; |
| | | that.nextVideo=that.list2TakeTurn[that.nextIndex] |
| | | that.centerIndex++; |
| | | if (that.centerIndex == that.list2TakeTurn.length) { |
| | | that.centerIndex = 0; |
| | | |
| | | } |
| | | this.timer = setInterval(() => { |
| | | that.centerVideo = that.list2TakeTurn[that.centerIndex]; |
| | | that.nextVideo=that.list2TakeTurn[that.nextIndex] |
| | | that.centerIndex++; |
| | | if (that.centerIndex == that.list2TakeTurn.length) { |
| | | that.centerIndex = 0; |
| | | } |
| | | }, 12000); |
| | | }, |
| | | initTrackWebsocket() { |
| | | if (typeof WebSocket === "undefined") { |
| | | alert("您的浏览器不支持socket"); |
| | | } else { |
| | | // 实例化socket |
| | | this.websocket = new WebSocket(this.tracePubUrl); |
| | | // 监听socket消息 |
| | | this.websocket.onopen = this.websocketonopen; |
| | | this.websocket.onmessage = this.recvieTrackMessage; |
| | | } |
| | | }, |
| | | websocketonopen() { |
| | | //连接建立之后执行send方法发送数据 |
| | | this.websocket.send("sub"); |
| | | }, |
| | | tracking() { |
| | | getCameraPlayList().then((data) => { |
| | | if (data && data.length) { |
| | | data.forEach((ins) => { |
| | | let newCamera = this.TreeDataPool.getCameraInfoById( |
| | | ins.NewCameraId |
| | | ); |
| | | if (!newCamera) { |
| | | console.log("未查找到摄像机:", ins.NewCameraId); |
| | | return; |
| | | } |
| | | if (ins.IsNew) { |
| | | this.newPlayerInViewBox(newCamera); |
| | | } else { |
| | | this.replacePlayer(newCamera, ins.OldCameraId); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | recvieTrackMessage(e) { |
| | | let dataJson = JSON.parse(e.data); |
| | | let cache = this.traceCache; |
| | | let camera = dataJson.camera; |
| | | let person = dataJson.person; |
| | | let create = false; |
| | | |
| | | // 如果是已经在播放的摄像机, 直接返回 |
| | | if (cache[camera]) { |
| | | cache[camera][person] = 10; |
| | | return; |
| | | } |
| | | |
| | | cache[camera] = {}; |
| | | cache[camera][person] = 10; |
| | | |
| | | // 查询播放该人的上一个摄像机 |
| | | for (var cam in cache) { |
| | | if (cam === camera) { |
| | | continue; |
| | | } |
| | | |
| | | if (cache[cam][person]) { |
| | | // 找到上一个摄像机, 判断摄像机里是否还有其他人, 有:新开播放器 没有:切换 |
| | | console.log("last camera:", cam, Object.keys(cache[cam]).length); |
| | | if (Object.keys(cache[cam]).length > 2) { |
| | | delete cache[cam][person]; |
| | | this.newPlayerInViewBox(camera); |
| | | return; |
| | | } else { |
| | | this.replacePlayer(camera, cam); |
| | | delete cache[cam]; |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 未发现播放记录 |
| | | this.newPlayerInViewBox(camera); |
| | | }, |
| | | newPlayerInViewBox(id) { |
| | | // 新增播放窗口 |
| | | let camera = this.TreeDataPool.getCameraInfoById(id); |
| | | let emptyIndex = -1; |
| | | let exist = false; |
| | | for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) { |
| | | // eslint-disable-next-line |
| | | if ( |
| | | this.TreeDataPool.videoArr[i] === "" || |
| | | this.TreeDataPool.videoArr[i] === undefined |
| | | ) { |
| | | if (emptyIndex === -1) { |
| | | emptyIndex = i; |
| | | } |
| | | } else { |
| | | if (this.TreeDataPool.videoArr[i].id === camera.id) { |
| | | exist = true; |
| | | } |
| | | } |
| | | } |
| | | if (!exist && emptyIndex !== -1) { |
| | | this.TreeDataPool.setVideoArr(emptyIndex, camera, this); |
| | | } |
| | | }, |
| | | replacePlayer(id, oldCameraId) { |
| | | let camera = this.TreeDataPool.getCameraInfoById(id); |
| | | // 替换播放器 |
| | | for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) { |
| | | // eslint-disable-next-line |
| | | if ( |
| | | this.TreeDataPool.videoArr[i] && |
| | | this.TreeDataPool.videoArr[i] !== undefined && |
| | | this.TreeDataPool.videoArr[i] !== "" |
| | | ) { |
| | | if (this.TreeDataPool.videoArr[i].id === oldCameraId) { |
| | | this.TreeDataPool.setVideoArr(i, camera, this); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | closePlayer(id) { |
| | | for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) { |
| | | // eslint-disable-next-line |
| | | if ( |
| | | this.TreeDataPool.videoArr[i] && |
| | | this.TreeDataPool.videoArr[i] !== undefined && |
| | | this.TreeDataPool.videoArr[i] !== "" |
| | | ) { |
| | | if (this.TreeDataPool.videoArr[i].id === id) { |
| | | this.TreeDataPool.setVideoArr(i, undefined, this); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | visibilitychange() { |
| | | switch (document.visibilityState) { |
| | | case "hidden": |
| | | this.visibilityState = false; |
| | | break; |
| | | case "visible": |
| | | this.visibilityState = true; |
| | | break; |
| | | } |
| | | }, |
| | | blackAngWhite() { |
| | | if (this.VideoPhotoData.selectBlacks.length > 0) { |
| | | for (let i = 0; i < this.VideoPhotoData.whiteList.length; i++) { |
| | | this.$set(this.VideoPhotoData.whiteList[i], "disabled", true); |
| | | } |
| | | } |
| | | if (this.VideoPhotoData.selectBlacks.length == 0) { |
| | | for (let i = 0; i < this.VideoPhotoData.whiteList.length; i++) { |
| | | this.$set(this.VideoPhotoData.whiteList[i], "disabled", false); |
| | | } |
| | | } |
| | | if (this.VideoPhotoData.selectWhites.length > 0) { |
| | | for (let i = 0; i < this.VideoPhotoData.blackList.length; i++) { |
| | | this.$set(this.VideoPhotoData.blackList[i], "disabled", true); |
| | | } |
| | | } |
| | | if (this.VideoPhotoData.selectWhites.length == 0) { |
| | | for (let i = 0; i < this.VideoPhotoData.blackList.length; i++) { |
| | | this.$set(this.VideoPhotoData.blackList[i], "disabled", false); |
| | | } |
| | | } |
| | | }, |
| | | closeWindow(index) { |
| | | this.CardList.addBaseList.splice(index, 1); |
| | | }, |
| | | getVideoHeight() { |
| | | let h = this.$refs.monitorVideo.offsetHeight; |
| | | // this.$refs.monitorTask.style.height = h + "px"; |
| | | }, |
| | | resizeMonitorTask() { |
| | | this.getRightWidth(); |
| | | this.getVideoHeight(); |
| | | }, |
| | | getRightWidth() { |
| | | let w = this.$refs.videoRight.offsetWidth; |
| | | // this.$refs.monitorTask.style.width =w - this.$refs.monitorVideo.offsetWidth - 40 + "px"; |
| | | }, |
| | | filterNodes(selectArry) { |
| | | let nodes = []; |
| | | selectArry.forEach((i) => { |
| | | if (i && nodes.indexOf(i.id) < 0) { |
| | | nodes.push(i.id); |
| | | } |
| | | }); |
| | | return nodes; |
| | | }, |
| | | videoItemClick(index) { |
| | | this.TreeDataPool.activeVideoIndex = index; |
| | | this.TreeDataPool.activeForceChoose = true; |
| | | }, |
| | | toAdd(item) { |
| | | this.CardList.addBaseList.push(item); |
| | | }, |
| | | getCenter() { |
| | | this.center = { |
| | | x: document.documentElement.clientWidth / 2 - 250, |
| | | y: document.documentElement.clientHeight / 2 - 200, |
| | | }; |
| | | }, |
| | | resizeWidth(w) { |
| | | this.defaultWidth = w; |
| | | }, |
| | | resizeHeight(h) { |
| | | this.defaultHeight = h; |
| | | }, |
| | | saveAddBase(item, index) { |
| | | if ( |
| | | this.VideoPhotoData.selectBlacks.length === 0 && |
| | | this.VideoPhotoData.selectWhites.length === 0 |
| | | ) { |
| | | this.$notify({ |
| | | title: "注意", |
| | | message: "请选择要添加的底库", |
| | | type: "warning", |
| | | }); |
| | | return; |
| | | } |
| | | let res = this.VideoPhotoData.addBase(item); |
| | | res.then((data) => { |
| | | console.log("then", data); |
| | | if (data.success) { |
| | | this.$notify({ |
| | | title: "成功", |
| | | message: data.data, |
| | | type: "success", |
| | | }); |
| | | } else { |
| | | this.$notify({ |
| | | title: "失败", |
| | | message: data.data, |
| | | type: "error", |
| | | }); |
| | | } |
| | | this.CardList.addBaseList.splice(index, 1); |
| | | this.VideoPhotoData.selectBlacks = []; |
| | | this.VideoPhotoData.selectWhites = []; |
| | | }); |
| | | }, |
| | | getActiveIndex() { |
| | | this.TreeDataPool.videoArr.length = this.allVideoNum; |
| | | let nullVideoIndex = ""; |
| | | for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) { |
| | | // eslint-disable-next-line |
| | | if ( |
| | | this.TreeDataPool.videoArr[i] === "" || |
| | | this.TreeDataPool.videoArr[i] === undefined |
| | | ) { |
| | | nullVideoIndex = i; |
| | | } else { |
| | | nullVideoIndex = ""; |
| | | } |
| | | } |
| | | if ( |
| | | this.TreeDataPool.activeVideoIndex !== "" && |
| | | this.TreeDataPool.activeVideoIndex < |
| | | this.TreeDataPool.videoArr.length - 1 |
| | | ) { |
| | | return this.TreeDataPool.activeVideoIndex; |
| | | } else { |
| | | if (nullVideoIndex === "") { |
| | | this.TreeDataPool.activeVideoIndex = |
| | | this.TreeDataPool.videoArr.length - 1; |
| | | } else { |
| | | this.TreeDataPool.activeVideoIndex = nullVideoIndex; |
| | | } |
| | | } |
| | | }, |
| | | setGuid(value) { |
| | | clearTimeout(this.trackTimer); |
| | | if (value < this.guid && this.TreeDataPool.activeVideoIndex > value) { |
| | | // eslint-disable-next-line |
| | | for ( |
| | | let i = this.TreeDataPool.activeVideoIndex - 1; |
| | | i < this.TreeDataPool.videoArr.length; |
| | | i++ |
| | | ) { |
| | | // eslint-disable-next-line |
| | | if ( |
| | | this.TreeDataPool.videoArr[i] && |
| | | this.TreeDataPool.videoArr[i]["isPlaying"] |
| | | ) { |
| | | this.TreeDataPool.videoArr[i]["isPlaying"] = false; |
| | | } |
| | | } |
| | | } |
| | | this.guid = value; |
| | | sessionStorage.guid = this.guid; |
| | | sessionStorage.activeIndex = this.TreeDataPool.activeVideoIndex; |
| | | this.getActiveIndex(); |
| | | }, |
| | | toggleShowArea() { |
| | | this.showArea = !this.showArea; |
| | | }, |
| | | }, |
| | | destroyed() { |
| | | window.removeEventListener("resize", this.getRightWidth); |
| | | // this.CardList.details = []; |
| | | this.CardList.addBaseList = []; |
| | | this.VideoPhotoData.selectBlacks = []; |
| | | this.VideoPhotoData.selectWhites = []; |
| | | }, |
| | | computed: { |
| | | allVideoNum() { |
| | | if (this.videoNum2Play <= 5) { |
| | | this.guid = 3; |
| | | return 5; |
| | | } else if (this.videoNum2Play <= 7) { |
| | | this.guid = 4; |
| | | return 7; |
| | | } else if (this.videoNum2Play <= 12) { |
| | | this.guid = 4; |
| | | return 12; |
| | | } else if (this.videoNum2Play <= 16) { |
| | | this.guid = 5; |
| | | return 16; |
| | | } |
| | | }, |
| | | nextIndex(){ |
| | | if (this.centerIndex==this.list2TakeTurn.length-1) { |
| | | return 0 |
| | | } |
| | | return this.centerIndex+1 |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .monitoring-right { |
| | | width: 100%; |
| | | height: 100%; |
| | | // min-width: 981px; |
| | | //float: right; |
| | | box-sizing: border-box; |
| | | padding: 10px; |
| | | background-color: #e9ebf2; |
| | | .main-top { |
| | | margin-bottom: 14px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | | .monitoring-video { |
| | | width: 100%; |
| | | // min-width: 740px; |
| | | // max-width: 1208px; |
| | | // height: 98%; |
| | | //float: left; |
| | | box-sizing: border-box; |
| | | // box-shadow: #e4e7ed 0px 0px 9px inset; |
| | | border-radius: 5px; |
| | | .activeItem { |
| | | border: 3px solid #ff7733; |
| | | position: relative; |
| | | top: -1px; |
| | | left: -1px; |
| | | // width: calc(100% + 2px) !important; |
| | | // height: calc(100% + 2px) !important; |
| | | } |
| | | .onlyActiveItem { |
| | | width: calc(100% + 2px) !important; |
| | | height: calc(100% + 2px) !important; |
| | | } |
| | | .video-main-box { |
| | | background-color: #fff; |
| | | box-sizing: border-box; |
| | | border: 1px solid #cacaca; |
| | | } |
| | | .video-main-box-side { |
| | | border-top: 1px solid #cacaca; |
| | | border-left: 1px solid #cacaca; |
| | | box-sizing: border-box; |
| | | background-color: #fff; |
| | | } |
| | | .monitoring-video-guid { |
| | | text-align: right; |
| | | padding-bottom: 10px; |
| | | .activegongge { |
| | | color: #3d68e1; |
| | | } |
| | | span { |
| | | font-size: 20px; |
| | | color: #cacaca; |
| | | padding-left: 12px; |
| | | cursor: pointer; |
| | | } |
| | | .area-trigger { |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | .fixedRatioBox { |
| | | padding-top: 55.3%; |
| | | box-sizing: border-box; |
| | | position: relative; |
| | | > div { |
| | | width: 100%; |
| | | height: 100%; |
| | | position: absolute; |
| | | top: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | import Vue from 'vue'; |
| | | import App from './App.vue'; |
| | | |
| | | import ElementUI from 'element-ui'; |
| | | import 'element-ui/lib/theme-chalk/index.css'; |
| | | // import "@/assets/css/element-variables.scss"; |
| | | |
| | | import VueAwesomeSwiper from "vue-awesome-swiper"; |
| | | import "swiper/dist/css/swiper.css"; |
| | | import * as VueWindow from "@hscmap/vue-window"; |
| | | |
| | | import Mixin from "./mixins"; |
| | | |
| | | |
| | | import preview from 'vue-photo-preview' |
| | | import 'vue-photo-preview/dist/skin.css' |
| | | Vue.use(preview) |
| | | |
| | | Vue.use(ElementUI) |
| | | Vue.use(VueAwesomeSwiper as any); |
| | | Vue.use(VueWindow); |
| | | |
| | | Vue.mixin(Mixin); |
| | | |
| | | new Vue({ |
| | | el: '#app', |
| | | render: h => h(App) |
| | | }) |
| New file |
| | |
| | | import TreeDataPool from "@/Pool/TreeData"; |
| | | import DataStackPool from "@/Pool/dataStack" |
| | | import CardList from "@/Pool/CardList"; |
| | | import VideoPhotoData from "@/Pool/VideoPhotoData"; |
| | | import VideoTaskData from "@/Pool/VideoTaskData"; |
| | | import VideoCaptrue from "@/Pool/VideoCapture"; |
| | | |
| | | /* eslint-disable */ |
| | | const onlyTreeDataPool = new TreeDataPool |
| | | const onlyDataStack = new DataStackPool |
| | | const onlyCardList = new CardList |
| | | const onlyVideoPhotoData = new VideoPhotoData |
| | | const onlyVideoTaskData = new VideoTaskData |
| | | const onlyVideoCaptrue = new VideoCaptrue |
| | | |
| | | const mixin = { |
| | | data() { |
| | | return { |
| | | TreeDataPool: onlyTreeDataPool, |
| | | DataStackPool: onlyDataStack, |
| | | CardList: onlyCardList, |
| | | VideoPhotoData: onlyVideoPhotoData, |
| | | VideoTaskData: onlyVideoTaskData, |
| | | VideoCaptrue: onlyVideoCaptrue, |
| | | |
| | | }; |
| | | }, |
| | | }; |
| | | export default mixin; |
| | |
| | | }, 1000); |
| | | window.addEventListener('message', (e) => { |
| | | if (e.data.msg == 'AppUpdate') { |
| | | debugger |
| | | this.showApps(); |
| | | } |
| | | // if (e.data.msg && e.data.msg.indexOf("refreshDesk")>-1) { |
| | | // this.showApps(); |
| | | // } |
| | | }); |
| | | }, |
| | | methods: { |
| | |
| | | } |
| | | }, |
| | | mounted() { |
| | | console.log(document.querySelectorAll('iframe')) |
| | | window.addEventListener('message', (d) => { |
| | | let { source, trigger, menuT, menuL } = d.data; |
| | | if (trigger == 'contextmenu') { |
| | |
| | | <template> |
| | | <div class="desktop"> |
| | | <d-frame v-for="item in this.$store.state.desktop.frames" :data="item" :key="item.id"></d-frame> |
| | | <safari :data="$store.state.desktop.safari" v-if="$store.state.desktop.safari.active"></safari> |
| | | <d-frame |
| | | v-for="item in this.$store.state.desktop.frames" |
| | | :data="item" |
| | | :key="item.id" |
| | | ></d-frame> |
| | | <safari |
| | | :data="$store.state.desktop.safari" |
| | | v-if="$store.state.desktop.safari.active" |
| | | ></safari> |
| | | |
| | | <div class="warn-tag" v-if="showFreeVersion"> |
| | | <span class="text" |
| | | >试用版尚未激活,仅支持部分功能使用,如需使用全部功能,请尽快激活系统。</span |
| | | > |
| | | <span class="go-to" @click="gotoActive">前往激活</span> |
| | | <span class="icon iconfont" @click="showFreeVersion = false" |
| | | ></span |
| | | > |
| | | </div> |
| | | |
| | | <el-dialog title="激活SmartAI" :visible.sync="dialogVisible" width="40%"> |
| | | <div class="ver"><span class="ver-text">版本:</span>{{ version }}</div> |
| | | <div class="ver"> |
| | | <span class="ver-text">状态:</span>{{ versionState }} |
| | | </div> |
| | | <el-divider></el-divider> |
| | | <div class="info"> |
| | | 如果还没有产品密钥,你可以使用手机扫码或前往此链接 |
| | | <a href="http://os.smartai.com:7004" target="_blank" |
| | | >http://os.smartai.com:7004</a |
| | | > |
| | | 购买。 |
| | | </div> |
| | | |
| | | <!-- <img class="qr-code-img" src="/images/desktop/weather.png" /> --> |
| | | <!-- <img class="qr-code-img" src="http://192.168.8.10:7009/version/offline/qrcode" /> --> |
| | | <img |
| | | class="qr-code-img" |
| | | src="http://192.168.20.189:7009/version/offline/qrcode" |
| | | /> |
| | | |
| | | <el-divider></el-divider> |
| | | |
| | | <div class="ask"> |
| | | 如果你具有SmartAI提供的产品密钥,请在此处输入激活SmartAI。 |
| | | </div> |
| | | |
| | | <div class="validate"> |
| | | <form id="myForm"> |
| | | <!-- <el-input |
| | | class="single-input" |
| | | size="small" |
| | | ref="secrectKey" |
| | | :maxlength="4" |
| | | v-model="secrectKey" |
| | | placeholder="" |
| | | @input="onInput(1)" |
| | | ></el-input |
| | | >- |
| | | <el-input |
| | | class="single-input" |
| | | size="small" |
| | | ref="input2" |
| | | :maxlength="4" |
| | | v-model="input2" |
| | | placeholder="" |
| | | @input="onInput(2)" |
| | | ></el-input |
| | | >- |
| | | <el-input |
| | | class="single-input" |
| | | size="small" |
| | | ref="input3" |
| | | :maxlength="4" |
| | | v-model="input3" |
| | | placeholder="" |
| | | @input="onInput(3)" |
| | | ></el-input> |
| | | - |
| | | <el-input |
| | | class="single-input" |
| | | size="small" |
| | | ref="input4" |
| | | :maxlength="4" |
| | | v-model="input4" |
| | | placeholder="" |
| | | @input="onInput(4)" |
| | | ></el-input |
| | | >- |
| | | <el-input |
| | | class="single-input" |
| | | size="small" |
| | | ref="input5" |
| | | :maxlength="4" |
| | | v-model="input5" |
| | | placeholder="" |
| | | @input="onInput(5)" |
| | | ></el-input> --> |
| | | |
| | | <el-input |
| | | type="textarea" |
| | | autosize |
| | | style="width: 480px" |
| | | placeholder="将产品密钥粘贴在此处" |
| | | v-model="secrectKey" |
| | | > |
| | | </el-input> |
| | | </form> |
| | | |
| | | <el-upload |
| | | class="upload-demo" |
| | | action |
| | | :http-request="uploadKey" |
| | | :limit="1" |
| | | :show-file-list="false" |
| | | > |
| | | <el-button size="small" type="primary">导入产品密钥文件</el-button> |
| | | |
| | | <!-- <div class="el-upload__tip" slot="tip"></div> --> |
| | | </el-upload> |
| | | </div> |
| | | |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">继续试用</el-button> |
| | | <el-button type="primary" @click="activateVersion">激活</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import DFrame from './DFrame'; |
| | | import Safari from './Safari'; |
| | | |
| | | import DFrame from "./DFrame"; |
| | | import Safari from "./Safari"; |
| | | import { |
| | | getActiveQrCode, |
| | | getSN, |
| | | activateVersion, |
| | | uploadKey, |
| | | } from "@/api/system"; |
| | | export default { |
| | | name: "Desktop", |
| | | components: { |
| | | DFrame, Safari |
| | | } |
| | | } |
| | | DFrame, |
| | | Safari, |
| | | }, |
| | | data() { |
| | | return { |
| | | showFreeVersion: true, |
| | | dialogVisible: false, |
| | | version: "SmartAI试用版", |
| | | versionState: "尚未激活", |
| | | secrectKey: "", |
| | | input2: "", |
| | | input4: "", |
| | | input3: "", |
| | | input5: "", |
| | | }; |
| | | }, |
| | | mounted() { |
| | | getSN().then((res) => { |
| | | this.showFreeVersion = res.data.sn == ""; |
| | | }); |
| | | }, |
| | | methods: { |
| | | activateVersion() { |
| | | if (this.secrectKey.trim()=="") { |
| | | this.$message.warning("请先填写产品密钥") |
| | | return |
| | | } |
| | | activateVersion({code:this.secrectKey.trim()}).then((res) => { |
| | | debugger |
| | | if (res.code==200) { |
| | | this.$notify.success("激活成功") |
| | | this.goToSysInfo() |
| | | this.dialogVisible = false; |
| | | |
| | | }else{ |
| | | this.$notify.error(res.msg) |
| | | } |
| | | }).catch((err) => { |
| | | this.$notify.error(err.msg) |
| | | }) |
| | | }, |
| | | goToSysInfo() { |
| | | window.parent.postMessage({ msg: `toVindicate?menu=系统信息` }, "*"); |
| | | }, |
| | | gotoActive() { |
| | | this.showFreeVersion = false; |
| | | this.dialogVisible = true; |
| | | }, |
| | | uploadKey(params) { |
| | | let param = new FormData(); |
| | | param.append("code", params.file); |
| | | uploadKey(param).then( |
| | | (res) => { |
| | | this.$message.success("导入成功"); |
| | | this.secrectKey = res.data; |
| | | }, |
| | | (err) => { |
| | | this.$message.error("导入失败"); |
| | | } |
| | | ); |
| | | }, |
| | | onInput(val) { |
| | | if (this[`input${val}`].length == 4 && val < 5) { |
| | | this.$refs[`input${val + 1}`].focus(); |
| | | } |
| | | if (this[`input${val}`].length == 0 && val > 0) { |
| | | this.$refs[`input${val - 1}`].focus(); |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style lang="scss" > |
| | | .desktop { |
| | | width: 100%; |
| | | height: 100%; |
| | | .el-dialog__header { |
| | | padding: 15px 20px 10px; |
| | | text-align: left; |
| | | font-weight: 600; |
| | | } |
| | | .el-dialog__body { |
| | | text-align: left; |
| | | padding: 30px 50px; |
| | | padding-top: 20px; |
| | | } |
| | | .el-divider--horizontal { |
| | | margin: 20px 0; |
| | | } |
| | | .validate { |
| | | display: flex; |
| | | align-items: baseline; |
| | | margin-top: 15px; |
| | | } |
| | | #myForm { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 10px; |
| | | .single-input { |
| | | margin: 0 8px; |
| | | width: 60px; |
| | | } |
| | | } |
| | | .ver { |
| | | margin-bottom: 10px; |
| | | font-size: 16px; |
| | | .ver-text { |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | .info { |
| | | font-size: 15px; |
| | | margin-bottom: 10px; |
| | | } |
| | | .qr-code-img { |
| | | // width: 120px; |
| | | // height: 120px; |
| | | } |
| | | .ask { |
| | | margin-top: 20px; |
| | | font-size: 15px; |
| | | } |
| | | } |
| | | .warn-tag { |
| | | width: 35%; |
| | | text-align: left; |
| | | box-sizing: border-box; |
| | | padding: 0 25px; |
| | | height: 45px; |
| | | background-color: rgba(255, 238, 230, 1); |
| | | z-index: 99999; |
| | | position: absolute; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | top: 55px; |
| | | left: calc(50% - 17.5%); |
| | | line-height: 45px; |
| | | border-radius: 5px; |
| | | .go-to { |
| | | color: rgba(71, 153, 247, 1); |
| | | cursor: pointer; |
| | | text-decoration: underline; |
| | | font-weight: 600; |
| | | font-size: 13px; |
| | | } |
| | | .text { |
| | | font-size: 13px; |
| | | } |
| | | .icon { |
| | | font-size: 14px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | }); |
| | | this.askSysUpdate(); |
| | | this.askAppUpdate(); |
| | | |
| | | |
| | | }, |
| | | methods: { |
| | | askAppUpdate() { |
| | |
| | | <div class="tools-entry">
|
| | | <div class="entry-wrap">
|
| | | <el-carousel
|
| | | :height="rowSize==3?'600px':'770px'"
|
| | | :height="rowSize == 3 ? '600px' : '770px'"
|
| | | :autoplay="false"
|
| | | arrow="never"
|
| | | :indicator-position="carousels.length==1?'none':''"
|
| | | :indicator-position="carousels.length == 1 ? 'none' : ''"
|
| | | >
|
| | | <el-carousel-item v-for="(carousel,index) in carousels" :key="index">
|
| | | <el-carousel-item v-for="(carousel, index) in carousels" :key="index">
|
| | | <div class="app-list clearFix sdk-list">
|
| | | <!-- <draggable v-model="carousel" @start="drag=true" @end="drag=false"> -->
|
| | | <div v-for="item in carousel" :key="item.id">
|
| | |
| | | <div class="app-icon">
|
| | | <div
|
| | | class="badge"
|
| | | v-if="item.name=='algorithmManage' && badgeNum > 0"
|
| | | >{{badgeNum}}</div>
|
| | | v-if="item.name == 'algorithmManage' && badgeNum > 0"
|
| | | >
|
| | | {{ badgeNum }}
|
| | | </div>
|
| | | <img :src="item.src" :alt="item.alt" />
|
| | | </div>
|
| | | <div class="app-name">{{item.title}}</div>
|
| | | <div class="app-name">{{ item.title }}</div>
|
| | | </div>
|
| | | </div>
|
| | | <div class="app sdk" v-if="item.sdk_name">
|
| | | <div class="wrap">
|
| | | <div class="app-icon">
|
| | | <img
|
| | | :src="item.iconBlob.indexOf(',')>0? item.iconBlob:`data:image/png;base64,${item.iconBlob}`"
|
| | | :src="
|
| | | item.iconBlob.indexOf(',') > 0
|
| | | ? item.iconBlob
|
| | | : `data:image/png;base64,${item.iconBlob}`
|
| | | "
|
| | | />
|
| | | </div>
|
| | | <div class="app-name">{{item.sdk_name}}</div>
|
| | | <div class="app-name">{{ item.sdk_name }}</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | |
| | | </template>
|
| | |
|
| | | <script>
|
| | | import draggable from "vuedraggable"
|
| | | import { findAllSdk } from '@/api/taskMange';
|
| | | import bus from '@/plugin/bus'
|
| | | import draggable from "vuedraggable";
|
| | | import { findAllSdk } from "@/api/taskMange";
|
| | | import bus from "@/plugin/bus";
|
| | | export default {
|
| | | name: 'toolsEntry',
|
| | | name: "toolsEntry",
|
| | | data() {
|
| | | return {
|
| | | publicPath: process.env.BASE_URL,
|
| | |
| | | // ],
|
| | | //rowSize: 3,
|
| | | // badgeNum: 0,
|
| | | }
|
| | | };
|
| | | },
|
| | | computed: {
|
| | | stateDocks() {
|
| | | return this.$store.state.desktop.docks
|
| | | return this.$store.state.desktop.docks;
|
| | | },
|
| | | carousels() {
|
| | | let pages = 0;
|
| | | let tempArr = this.stateDocks.concat(this.installedSdk);
|
| | | let upgradeArr = tempArr.filter(item => item.isUpgrade);
|
| | | let upgradeArr = tempArr.filter((item) => item.isUpgrade);
|
| | | let arr = null;
|
| | | //根据屏幕高度来判断是展示3排还是4排 阈值:970
|
| | | if (window.innerHeight >= 930) {
|
| | |
| | | //this.rowSize = 3;
|
| | | arr = this.chunk(tempArr, 18);
|
| | | }
|
| | | return arr
|
| | | return arr;
|
| | | },
|
| | | badgeNum() {
|
| | | let tempArr = this.stateDocks.concat(this.installedSdk);
|
| | | return tempArr.filter(item => item.isUpgrade).length;
|
| | | return tempArr.filter((item) => item.isUpgrade).length;
|
| | | },
|
| | | rowSize() {
|
| | | if (window.innerHeight >= 930) {
|
| | |
| | | } else {
|
| | | return 3;
|
| | | }
|
| | | }
|
| | | },
|
| | | },
|
| | | mounted() {
|
| | | this.getAllSdk();
|
| | | let _this= this
|
| | | window.addEventListener('message', e => {
|
| | | let _this = this;
|
| | | window.addEventListener("message", (e) => {
|
| | | if (e.data && e.data.msg) {
|
| | | let msg = e.data.msg;
|
| | | if (msg === "logout") {
|
| | |
| | | }
|
| | | if (msg.indexOf("toSearch") >= 0) {
|
| | | let params = msg.substring(7);
|
| | | this.addFrameByName("search", params)
|
| | | this.addFrameByName("search", params);
|
| | | }
|
| | | if (msg.indexOf("toCluster") >= 0) {
|
| | | let params = msg.substring(8);
|
| | | this.addFrameByName("searchForCluster", params)
|
| | | this.addFrameByName("searchForCluster", params);
|
| | | }
|
| | | if (msg.indexOf("toSetting")>-1) {
|
| | | const str = msg.split("?")[1]
|
| | | this.addFrameByName("settings", str)
|
| | | if (msg.indexOf("toSetting") > -1) {
|
| | | const str = msg.split("?")[1];
|
| | | this.addFrameByName("settings", str);
|
| | | }
|
| | | if (msg.indexOf("toVindicate")>-1) {
|
| | | const str = msg.split("?")[1]
|
| | | this.addFrameByName("vindicate", str)
|
| | | if (msg.indexOf("toVindicate") > -1) {
|
| | | const str = msg.split("?")[1];
|
| | | this.addFrameByName("vindicate", str);
|
| | | }
|
| | | if (msg.indexOf("toAI")>-1) {
|
| | | const str = msg.split("?")[1]
|
| | | this.addFrameByName("algorithmManage", str)
|
| | | if (msg.indexOf("toAI") > -1) {
|
| | | const str = msg.split("?")[1];
|
| | | this.addFrameByName("algorithmManage", str);
|
| | | }
|
| | | if (msg.indexOf("toOpenApp") >= 0) {
|
| | | let id = msg.substring(10);
|
| | | this.addFrameByID(id)
|
| | | this.addFrameByID(id);
|
| | | }
|
| | | if (msg.indexOf("changeBackground")>-1) {
|
| | | const name = e.data.msg.split("?")[1]
|
| | | _this.$emit("changeBackground", `/images/desktop/${name}.png`)
|
| | | }
|
| | | // if (msg.indexOf("refreshDesk")>-1) {
|
| | | // this.getAllSdk();
|
| | | // }
|
| | | debugger
|
| | | if (msg == 'AppUpdate') {
|
| | | if (msg.indexOf("changeBackground") > -1) {
|
| | | const name = e.data.msg.split("?")[1];
|
| | | _this.$emit("changeBackground", `/images/desktop/${name}.png`);
|
| | | }
|
| | | if (msg == "AppUpdate") {
|
| | | this.getAllSdk();
|
| | | }
|
| | | }
|
| | | }
|
| | | });
|
| | | },
|
| | |
| | | size = Math.max(size, 0);
|
| | | const len = arr == null ? 0 : arr.length;
|
| | | if (!len || size < 1) {
|
| | | return []
|
| | | return [];
|
| | | }
|
| | | let index = 0;
|
| | | let resIndex = 0;
|
| | | const result = new Array(Math.ceil(len / size))
|
| | | const result = new Array(Math.ceil(len / size));
|
| | | while (index < len) {
|
| | | result[resIndex++] = arr.slice(index, index += size)
|
| | | result[resIndex++] = arr.slice(index, (index += size));
|
| | | }
|
| | | return result
|
| | | return result;
|
| | | },
|
| | | onJumpToDock(name){
|
| | | let togo |
| | | this.carousels.forEach(arr => {
|
| | | arr.forEach(x => {
|
| | | if (x.title==name) {
|
| | | togo= x
|
| | | onJumpToDock(name) {
|
| | | let togo;
|
| | | this.carousels.forEach((arr) => {
|
| | | arr.forEach((x) => {
|
| | | if (x.title == name) {
|
| | | togo = x;
|
| | | }
|
| | | });
|
| | | });
|
| | | this.dockClick(togo)
|
| | | this.dockClick(togo);
|
| | | },
|
| | | getAllSdk() {
|
| | | findAllSdk().then(res => {
|
| | | this.installedSdk = res.data.filter(item => item.installed)
|
| | | }).catch(e => {
|
| | | console.log(e)
|
| | | })
|
| | | findAllSdk()
|
| | | .then((res) => {
|
| | | this.installedSdk = res.data.filter((item) => item.installed);
|
| | | })
|
| | | .catch((e) => {
|
| | | console.log(e);
|
| | | });
|
| | | },
|
| | | dockClick(dock) {
|
| | | if (dock.type === '1') {
|
| | | if (dock.type === "1") {
|
| | | window.open(dock.url);
|
| | | } else if (dock.type === '2' && !dock.isOpen) {
|
| | | this.$store.dispatch('desktop/addFrame', {
|
| | | } else if (dock.type === "2" && !dock.isOpen) {
|
| | | this.$store.dispatch("desktop/addFrame", {
|
| | | id: dock.id,
|
| | | icon: dock.src,
|
| | | title: dock.title,
|
| | | url: dock.url
|
| | | url: dock.url,
|
| | | });
|
| | | this.$store.commit('desktop/addMinDock', {
|
| | | this.$store.commit("desktop/addMinDock", {
|
| | | id: dock.id,
|
| | | src: dock.src,
|
| | | alt: dock.title,
|
| | | type: "3",
|
| | | highlight: true,
|
| | | url: dock.url,
|
| | | screenshot: ''
|
| | | screenshot: "",
|
| | | });
|
| | | //打开应用后异步抓拍,之后的抓拍采用这张固定的
|
| | | //if(dock.name=='cameraVideo'||dock.name=='search'||dock.name=='library'||dock.name=='cameraAccess'||dock.name=='dataStack'){
|
| | | setTimeout(() => {
|
| | | this.$parent.screenShot(dock);
|
| | | }, 1500)
|
| | | }, 1500);
|
| | | //}
|
| | | } else if (dock.type === '2' && dock.isOpen) {
|
| | | this.$store.commit('desktop/resetMinFrame', dock.id);
|
| | | } else if (dock.type === "2" && dock.isOpen) {
|
| | | this.$store.commit("desktop/resetMinFrame", dock.id);
|
| | | }
|
| | | |
| | | },
|
| | | resetDockItem() {
|
| | | const dockItems = document.getElementsByClassName('dock-item');
|
| | | const dockMask = document.getElementsByClassName('dock-mask')[0];
|
| | | const dockItems = document.getElementsByClassName("dock-item");
|
| | | const dockMask = document.getElementsByClassName("dock-mask")[0];
|
| | | for (let i = 0; i < dockItems.length; i++) {
|
| | | dockItems[i].width = 60;
|
| | | if (dockItems[i].parentNode.nextElementSibling) {
|
| | | dockItems[i].parentNode.nextElementSibling.style.marginLeft = "-35px";
|
| | | }
|
| | | }
|
| | | dockMask.style.width = dockItems.length * 60 + 40 + 'px';
|
| | | dockMask.style.width = dockItems.length * 60 + 40 + "px";
|
| | | },
|
| | | addFrameByName(name, params) {
|
| | | let dock = null;
|
| | | this.$store.state.desktop.docks.forEach(app => {
|
| | | this.$store.state.desktop.docks.forEach((app) => {
|
| | | if (app.name === name) {
|
| | | dock = app;
|
| | | }
|
| | | });
|
| | | if (dock.isOpen) {
|
| | | this.$store.dispatch('desktop/closeFrame', dock);
|
| | | this.$store.dispatch("desktop/closeFrame", dock);
|
| | | }
|
| | | this.$store.dispatch('desktop/addFrame', {
|
| | | this.$store.dispatch("desktop/addFrame", {
|
| | | id: dock.id,
|
| | | icon: dock.src,
|
| | | title: dock.title,
|
| | | url: dock.url + "?" + params
|
| | | url: dock.url + "?" + params,
|
| | | });
|
| | | this.$store.commit('desktop/addMinDock', {
|
| | | this.$store.commit("desktop/addMinDock", {
|
| | | id: dock.id,
|
| | | src: dock.src,
|
| | | alt: dock.title,
|
| | | type: "3",
|
| | | highlight: true,
|
| | | url: dock.url,
|
| | | screenshot: ''
|
| | | screenshot: "",
|
| | | });
|
| | | },
|
| | | addFrameByID(id, params) {
|
| | | let dock = null;
|
| | | let toClose = null
|
| | | this.$store.state.desktop.docks.forEach(app => {
|
| | | let toClose = null;
|
| | | this.$store.state.desktop.docks.forEach((app) => {
|
| | | if (app.id == id) {
|
| | | dock = app;
|
| | | }
|
| | | if (app.name == "algorithmManage") {
|
| | | toClose = app
|
| | | toClose = app;
|
| | | }
|
| | | });
|
| | | this.dockClick(dock)
|
| | | }
|
| | | }
|
| | | this.dockClick(dock);
|
| | | },
|
| | | },
|
| | | };
|
| | | </script>
|
| | |
|
| | |
| | | }); |
| | | }; |
| | | |
| | | export const getLocalCameraTree = (query: any) => { |
| | | return request({ |
| | | url: "/data/api-v/area/localmenu", |
| | | method: "get", |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | export const getGB28181CameraTree = (query: any) => { |
| | | return request({ |
| | | url: "/data/api-v/area/gb28181Tree", |
| | |
| | | }) |
| | | }, |
| | | async testLogin() { |
| | | // location.assign("/view/desktop/") |
| | | tologin({ username: this.user.loginName, password: this.user.password }) |
| | | .then(json => { |
| | | const loginedInfo = { |
| | |
| | | <el-menu-item index="1">位置标定</el-menu-item> |
| | | <el-menu-item index="2" v-show="false">轨迹图</el-menu-item> |
| | | <el-menu-item index="3">关联摄像机</el-menu-item> |
| | | <el-menu-item index="4">视频分析</el-menu-item> |
| | | </el-menu> |
| | | </div> |
| | | <div class="act-view"> |
| | |
| | | <template v-if="actMenuIndex=='3'"> |
| | | <relate-camera></relate-camera> |
| | | </template> |
| | | <template v-if="actMenuIndex=='4'"> |
| | | <relate-camera></relate-camera> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | import moment from "moment"; |
| | | import ElementUI from 'element-ui'; |
| | | import 'element-ui/lib/theme-chalk/index.css'; |
| | | import "@/assets/css/element-variables.scss"; |
| | | // import "@/assets/css/element-variables.scss"; |
| | | import VueAwesomeSwiper from "vue-awesome-swiper"; |
| | | import "swiper/dist/css/swiper.css"; |
| | | import Mixin from "./mixins"; |
| | |
| | | data() { |
| | | return { |
| | | TreeDataPool: onlyTreeDataPool |
| | | |
| | | }; |
| | | }, |
| | | }; |
| | |
| | | return day + "天 " + hour + "小时 " + minute + "分 " + second + "秒";
|
| | | },
|
| | | uploadSound(params) {
|
| | | debugger
|
| | | let param = new FormData();
|
| | | param.append("file", params.file);
|
| | | uploadSound(param).then(
|
| | |
| | | <div class="table">
|
| | | <el-table
|
| | | class="tableBox"
|
| | | @cell-click="clickFaults"
|
| | | ref="multipleTable"
|
| | | :cell-style="styleFunc"
|
| | | highlight-current-row
|
| | | :data="tableData"
|
| | | :header-cell-style="{ background: '#f8f8f8', color: '#222222' }"
|
| | | style="width: 100%"
|
| | | v-if="!showSubTable"
|
| | | >
|
| | | <el-table-column :align="'center'" label="序号" type="index" width="50">
|
| | | </el-table-column>
|
| | | <el-table-column
|
| | | :align="'center'"
|
| | | sortable
|
| | | |
| | | prop="add_time"
|
| | | label="状态"
|
| | | ></el-table-column>
|
| | |
| | | min-width="100px"
|
| | | label="失败总量"
|
| | | ></el-table-column>
|
| | | </el-table>
|
| | | |
| | | <div class="back" v-if="showSubTable" @click="showSubTable=false">
|
| | | <span class="icon iconfont"></span>
|
| | | <span class="title">事件推送日志</span>
|
| | | </div>
|
| | | <el-table
|
| | | class="tableBox"
|
| | | ref="multipleTable"
|
| | | :cell-style="styleFunc"
|
| | | highlight-current-row
|
| | | :data="subTableData"
|
| | | :header-cell-style="{ background: '#f8f8f8', color: '#222222' }"
|
| | | style="width: 100%"
|
| | | v-if="showSubTable"
|
| | | >
|
| | | <el-table-column :align="'center'" label="序号" type="index" width="50">
|
| | | </el-table-column>
|
| | | <el-table-column
|
| | | :align="'center'"
|
| | | sortable
|
| | | prop="add_time"
|
| | | label="推送时间"
|
| | | ></el-table-column>
|
| | | <el-table-column
|
| | | sortable
|
| | | :align="'center'"
|
| | | prop="userName"
|
| | | label="推送状态"
|
| | | ></el-table-column>
|
| | | <el-table-column
|
| | | :align="'center'"
|
| | | sortable
|
| | | prop="module"
|
| | | label="详细信息"
|
| | | ></el-table-column>
|
| | | <el-table-column
|
| | | :align="'center'"
|
| | | prop="procName"
|
| | | label="再次推送时间"
|
| | | ></el-table-column>
|
| | | <el-table-column
|
| | | :align="'center'"
|
| | | sortable
|
| | | prop="result"
|
| | | label="再次推送状态"
|
| | | ></el-table-column>
|
| | |
|
| | | </el-table>
|
| | | </div>
|
| | |
| | | <script>
|
| | | import { deleteDate } from "@/api/system";
|
| | | import { pad0 } from "@/api/utils";
|
| | | import { } from "@/api/log";
|
| | | import {} from "@/api/log";
|
| | |
|
| | | export default {
|
| | | data() {
|
| | | return {
|
| | | loading: false,
|
| | | loadingText: "",
|
| | | input3: "",
|
| | | tableData: [],
|
| | | loadingText: "",showSubTable: false,
|
| | | tableData: [
|
| | | { msg: 2, userName: "车辆识别" },
|
| | | { userName: "人脸识别", msg: 4 },
|
| | | ],
|
| | | subTableData:[
|
| | |
|
| | |
|
| | | ],
|
| | | dateArr: ["今日", "近三天", "近七天", "近一个月", "近六个月"],
|
| | | levelOptions: [],
|
| | | hostNameOptions: [],
|
| | |
| | | this.getOptions();
|
| | | },
|
| | | methods: {
|
| | | styleFunc({ row, column, rowIndex, columnIndex }) {
|
| | | if (columnIndex == 6) {
|
| | | return { cursor: "pointer" };
|
| | | }
|
| | | return {};
|
| | | },
|
| | | handleSizeChange(val) {
|
| | | this.pageSize = val;
|
| | | // this.getOperationLog();
|
| | |
| | | getModules().then((res) => {
|
| | | this.levelOptions = res.data;
|
| | | });
|
| | | },
|
| | | clickFaults(row, column, cell, event) {
|
| | | this.showSubTable=true
|
| | |
|
| | |
|
| | | },
|
| | | choseRange(item, i) {
|
| | | switch (item) {
|
| | |
| | | this.activeDateChoise = i;
|
| | | },
|
| | | getOperationLog(typ) {
|
| | | if (typ==1) {
|
| | | this.page=1
|
| | | if (typ == 1) {
|
| | | this.page = 1;
|
| | | }
|
| | | // queryOperationLog({
|
| | | // timeStart: this.timeStart,
|
| | |
| | | display: flex;
|
| | | margin: 10px 0;
|
| | | padding: 0 20px;
|
| | | |
| | | .bar {
|
| | | display: flex;
|
| | | align-items: baseline;
|
| | |
| | | border-radius: 5px;
|
| | | padding: 12px;
|
| | | background-color: white;
|
| | | .back{
|
| | | display: flex;
|
| | | align-items: center;
|
| | | .icon{
|
| | | cursor: pointer; margin:0 5px;font-size: 18px;
|
| | | }
|
| | | .title{
|
| | | cursor: pointer; line-height: 30px;font-size: 14px;
|
| | |
|
| | | }
|
| | | }
|
| | | .tableBox {
|
| | | th {
|
| | | padding: 0 !important;
|
| | |
| | | };
|
| | | },
|
| | | mounted() {
|
| | | this.getTimeRange(24 * 60 * 60 * 1000);
|
| | | this.getTimeRange();
|
| | | this.getOperationLog();
|
| | | this.getOptions();
|
| | | },
|
| | |
| | | choseRange(item, i) {
|
| | | switch (item) {
|
| | | case "今日":
|
| | | this.getTimeRange(24 * 60 * 60 * 1000);
|
| | | this.getTimeRange();
|
| | | break;
|
| | | case "近三天":
|
| | | this.getTimeRange(24 * 60 * 60 * 1000 * 3);
|
| | |
| | | this.activeDateChoise = i;
|
| | | },
|
| | | getOperationLog(typ) {
|
| | | if (typ==1) {
|
| | | this.page=1
|
| | | if (typ == 1) {
|
| | | this.page = 1;
|
| | | }
|
| | | queryOperationLog({
|
| | | timeStart: this.timeStart,
|
| | |
| | | return `${date.getFullYear()}-${month}-${day} ${hour}:${minute}:${second}`;
|
| | | },
|
| | | getTimeRange(gap) {
|
| | | var date = new Date(); //当前时间
|
| | | var preDay = new Date(new Date().getTime() - gap);
|
| | | var preDay;
|
| | | preDay = gap
|
| | | ? new Date(new Date().getTime() - gap)
|
| | | : new Date(new Date().setHours(0, 0, 0, 0));
|
| | | this.timeStart = this.getTimeStr(preDay);
|
| | | this.timeEnd = this.getTimeStr(date);
|
| | | },
|
| | | },
|
| | | };
|
| | |
| | | </div> |
| | | <systemClean v-if="activePage == 1" style="width: 100%" :free="free" :full="full" @refreshPercent="getLeftPer"></systemClean> |
| | | <updateSettings v-if="activePage == 0" style="width: 100%"></updateSettings> |
| | | <back-up v-if="activePage == 3" style="width: 100%"></back-up> |
| | | <!-- <back-up v-if="activePage == 3" style="width: 100%"></back-up> --> |
| | | <restartSettings v-if="activePage == 2" style="width: 100%"></restartSettings> |
| | | <sysInfo v-if="activePage == 3" style="width: 100%"></sysInfo> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { |
| | | getClockInfo, |
| | | saveClockInfo, |
| | | testNTPserver,freedisk |
| | | freedisk |
| | | } from "@/api/system"; |
| | | import { getUrlKey } from "@/api/utils"; |
| | | import systemClean from "../views/systemClean"; |
| | | import updateSettings from "../views/updateSettings"; |
| | | import BackUp from "../views/backUp"; |
| | | import restartSettings from "../views/restartSettings"; |
| | | import sysInfo from "../views/sysInfo"; |
| | | export default { |
| | | name: "settings", |
| | | components: { |
| | | systemClean, |
| | | updateSettings, |
| | | BackUp, |
| | | restartSettings, |
| | | restartSettings,sysInfo |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | // { name: "备份还原",icon:"" }, |
| | | { name: "系统清理" ,icon:"\uea3b" }, |
| | | { name: "重启设置" ,icon:"\ue709" }, |
| | | { name: "系统信息" ,icon:"\ue709" }, |
| | | ], |
| | | activePage: 0, |
| | | free: 0, |
| | |
| | | }; |
| | | }, |
| | | mounted() { |
| | | |
| | | const menu = getUrlKey("menu"); |
| | | if (menu) { |
| | | this.activePage = this.menuArr.findIndex((x) => x.name == menu); |
| | | // this.$nextTick(() => { |
| | | // this.$refs.netSettings.openRight(2); |
| | | // }); |
| | | } |
| | | this.getLeftPer() |
| | | }, |
| | | methods: { |
| New file |
| | |
| | | <template>
|
| | | <div class="v-sys-info">
|
| | | <div class="sys-content">
|
| | | <div class="sys-right">
|
| | | <div class="auto">
|
| | | <div class="title-bg">
|
| | | <div class="title">SmartAIOS</div>
|
| | | <div class="desc">Copyright © 贝思科技术有限公司</div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="name">版本:</div>
|
| | | <div class="desc">{{ verText }}</div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="name">激活:</div>
|
| | | <div class="right-zone">
|
| | | <el-button type="primary" size="small" @click="confirmAgain"
|
| | | >导出产品密钥</el-button
|
| | | >
|
| | | <div class="desc" style="color: rgba(71, 153, 247, 1)">
|
| | | {{ sn == "" ? "未激活" : "已激活" }}
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="name">请求码:</div>
|
| | | <div class="desc" style="font-size: 12px">{{ q }}</div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="name">产品密钥:</div>
|
| | | <div class="desc" style="font-size: 12px">{{ authorization }}</div>
|
| | | </div>
|
| | | <div class="bar">
|
| | | <div class="name">到期时间:</div>
|
| | | <div class="desc">{{ expireTime }}</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <el-dialog title="再次确认" :visible.sync="dialogVisible">
|
| | | <div class="ver">
|
| | | <span class="icon iconfont" style="color: orangered"></span>
|
| | | 产品密钥导出后,系统大部分功能将无法使用,请确认是否继续?
|
| | | </div>
|
| | |
|
| | | <div class="info">
|
| | | 如需继续,请输入管理员密码,并导入你想要激活的设备请求码,然后点击“确认”。
|
| | | <span style="color: #8f949a; font-size: 14px"
|
| | | >设备请求码获取方式:如系统已激活,在激活页面导出即可;如设备未激活,在SmartAI激活页面扫码获取。</span
|
| | | >
|
| | | </div>
|
| | | <!-- -->
|
| | | <div class="pw">
|
| | | <el-input
|
| | | size="small"
|
| | | placeholder="请输入管理员密码"
|
| | | v-model="password"
|
| | | style="padding-left: 50px; width: 360px"
|
| | | ></el-input>
|
| | | </div>
|
| | | <div class="validate">
|
| | | <form id="myForm">
|
| | | <el-input
|
| | | type="textarea"
|
| | | autosize
|
| | | style="width: 360px"
|
| | | placeholder="将产品密钥粘贴在此处"
|
| | | v-model="secrectKey"
|
| | | >
|
| | | </el-input>
|
| | | </form>
|
| | |
|
| | | <!-- <el-upload
|
| | | class="upload-demo"
|
| | | action
|
| | | :http-request="uploadKey"
|
| | | :limit="1"
|
| | | :show-file-list="false"
|
| | | >
|
| | | </el-upload> -->
|
| | | <el-button size="small" @click="txtbtn" type="primary">导入文件</el-button>
|
| | | <input type="file" @change="loadTextFromFile" id="txt" style="display:none"/>
|
| | | </div>
|
| | |
|
| | | <span slot="footer" class="dialog-footer">
|
| | | <el-button @click="dialogVisible = false">取消</el-button>
|
| | | <el-button type="primary" @click="confirmCancel">确定</el-button>
|
| | | </span>
|
| | | </el-dialog>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import { getSN, cancelAuthorization } from "@/api/system";
|
| | | export default {
|
| | | mounted() {
|
| | | getSN().then((res) => {
|
| | | if (res.code == 200) {
|
| | | this.authorization = res.data.authorization;
|
| | | this.expireTime = res.data.expireTime;
|
| | | this.sn = res.data.sn;
|
| | | this.q = res.data.q;
|
| | | }
|
| | | });
|
| | | },
|
| | | data() {
|
| | | return {
|
| | | authorization: "",
|
| | | expireTime: "",
|
| | | sn: "",
|
| | | secrectKey: "",
|
| | | q: "",
|
| | | verText: "SmartAIOS正式版",
|
| | | activeState: "已激活",
|
| | | password: "",
|
| | | dialogVisible: false,
|
| | | };
|
| | | },
|
| | | methods: {
|
| | | confirmAgain() {
|
| | | // this.$confirm("您是否确认立即备份所有应用的配置数据?", "立即备份", {
|
| | | // confirmButtonText: "确定",
|
| | | // cancelButtonText: "取消",
|
| | | // }).then(() => {
|
| | | // this.$message({
|
| | | // type: "success",
|
| | | // message: "备份成功",
|
| | | // });
|
| | | // });
|
| | | this.dialogVisible = true;
|
| | | },
|
| | | txtbtn() {
|
| | | document.getElementById("txt").click();
|
| | | },
|
| | | loadTextFromFile(e) {
|
| | | const file = e.target.files[0];
|
| | | var reader = new FileReader(); //new一个FileReader实例
|
| | | let that = this
|
| | | reader.onload = function () {
|
| | | debugger
|
| | | that.secrectKey = this.result.trim()
|
| | | console.log(this.result);
|
| | | };
|
| | | reader.readAsText(file);
|
| | | },
|
| | | confirmCancel() {
|
| | | this.secrectKey = this.secrectKey.trim();
|
| | | this.password = this.password.trim();
|
| | | if (this.secrectKey == "" || this.password == "") {
|
| | | this.$message.warning("请先填写密码和请求码");
|
| | | return;
|
| | | }
|
| | | cancelAuthorization({
|
| | | q: this.secrectKey,
|
| | | passwd: this.password,
|
| | | down: 1,
|
| | | }).then((res) => {
|
| | | debugger;
|
| | | let url = window.URL.createObjectURL(
|
| | | new Blob([res], {
|
| | | type: "text/plain",
|
| | | })
|
| | | );
|
| | | let a = document.createElement("a");
|
| | | a.href = url;
|
| | | a.download = "key.txt";
|
| | | a.click();
|
| | | window.URL.revokeObjectURL(url);
|
| | | });
|
| | | },
|
| | | },
|
| | | };
|
| | | </script>
|
| | | <style lang="scss">
|
| | | .v-sys-info {
|
| | | width: 100%;
|
| | | .el-dialog__header {
|
| | | padding: 15px 20px 10px;
|
| | | text-align: left;
|
| | | font-weight: 600;
|
| | | }
|
| | | .el-dialog__body {
|
| | | text-align: left;
|
| | | padding: 0;
|
| | | padding-bottom: 10px;
|
| | | }
|
| | | .el-divider--horizontal {
|
| | | margin: 20px 0;
|
| | | }
|
| | | .validate {
|
| | | padding: 0 50px;
|
| | | display: flex;
|
| | | align-items: baseline;
|
| | | margin-top: 15px;
|
| | | }
|
| | | #myForm {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | margin-right: 10px;
|
| | | .single-input {
|
| | | margin: 0 8px;
|
| | | width: 60px;
|
| | | }
|
| | | }
|
| | | .ver {
|
| | | margin-bottom: 10px;
|
| | | background-color: rgba(242, 242, 242, 1);
|
| | | font-size: 16px;
|
| | | height: 60px;
|
| | | padding-left: 50px;
|
| | | line-height: 60px;
|
| | | .ver-text {
|
| | | font-weight: 600;
|
| | | }
|
| | | }
|
| | | .info {
|
| | | padding: 0 50px;
|
| | | font-size: 15px;
|
| | | line-height: 25px;
|
| | | margin: 15px 0;
|
| | | }
|
| | | .qr-code-img {
|
| | | width: 100px;
|
| | | height: 100px;
|
| | | }
|
| | | .ask {
|
| | | margin-top: 20px;
|
| | | font-size: 15px;
|
| | | }
|
| | | }
|
| | |
|
| | | .sys-content {
|
| | | height: 100%;
|
| | | display: flex;
|
| | | flex-direction: row;
|
| | | flex: 1;
|
| | | flex-basis: auto;
|
| | | box-sizing: border-box;
|
| | | .sys-right {
|
| | | flex: 1;
|
| | | flex-basis: auto;
|
| | | overflow: auto;
|
| | | box-sizing: border-box;
|
| | | position: relative;
|
| | | padding: 20px 40px;
|
| | | .el-form-item.is-required:not(.is-no-asterisk)
|
| | | > .el-form-item__label:before,
|
| | | .el-form-item.is-required:not(.is-no-asterisk)
|
| | | .el-form-item__label-wrap
|
| | | > .el-form-item__label:before {
|
| | | display: none;
|
| | | }
|
| | | .el-select {
|
| | | width: 100%;
|
| | | }
|
| | | .el-form-item {
|
| | | margin-bottom: 10px;
|
| | | height: 50px;
|
| | | background: #f8f8f8;
|
| | | padding: 4px 20px;
|
| | | -webkit-box-sizing: border-box;
|
| | | box-sizing: border-box;
|
| | | border-radius: 10px;
|
| | | .el-form-item__label {
|
| | | text-align: left;
|
| | | line-height: 42px;
|
| | | }
|
| | | }
|
| | | .el-form-item__content {
|
| | | line-height: 40px;
|
| | | position: relative;
|
| | | font-size: 14px;
|
| | | }
|
| | | .ip-input-container {
|
| | | max-width: none !important;
|
| | | }
|
| | | .auto {
|
| | | .title-bg {
|
| | | background-color: #f8f8f8;
|
| | | height: 150px;
|
| | | border-radius: 12px;
|
| | | margin-bottom: 20px;
|
| | | display: flex;
|
| | | flex-direction: column;
|
| | | justify-content: center;
|
| | | .title {
|
| | | font-size: 34px;
|
| | | font-weight: 600;
|
| | | line-height: 50px;
|
| | | }
|
| | | .desc {
|
| | | font-size: 16px;
|
| | | line-height: 30px;
|
| | | }
|
| | | }
|
| | | .bar {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | padding: 12px 25px;
|
| | | background-color: #f8f8f8;
|
| | | justify-content: space-between;
|
| | | border-radius: 12px;
|
| | | margin-bottom: 10px;
|
| | | .right-zone {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | }
|
| | | .name {
|
| | | font-size: 15px;
|
| | | text-align: left;
|
| | | min-width: 180px;
|
| | | }
|
| | | .desc {
|
| | | font-size: 15px;
|
| | | margin-left: 20px;
|
| | | max-width: 600px;
|
| | | /* overflow: hidden; */
|
| | | /* text-overflow: ellipsis; */
|
| | | /* white-space: nowrap; */
|
| | | line-height: normal;
|
| | | word-wrap: break-word;
|
| | | text-align: left;
|
| | | }
|
| | | .el-input {
|
| | | width: 100%;
|
| | | .el-input {
|
| | | height: auto;
|
| | | }
|
| | | .el-input__inner {
|
| | | border: none;
|
| | | border-radius: 8px;
|
| | | background-color: rgba(240, 240, 240, 1);
|
| | | text-align: left;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | </style>
|
| | |
| | | if (isAutoUpdate==1) {
|
| | | this.checking = false
|
| | | this.upgradeNewVersion()
|
| | | // this.showWelcome = false;
|
| | | // this.activeIndex = this.menuArr.findIndex((x) => x.name == menu);
|
| | | // this.$nextTick(() => {
|
| | | // this.$refs.netSettings.openRight(2);
|
| | | // });
|
| | | }else{
|
| | | this.fetchUpgradInfo();
|
| | | }
|
| | |
| | | } |
| | | |
| | | onMediaSourceClose() { |
| | | console.log('media source closed'); |
| | | // console.log('media source closed'); |
| | | } |
| | | |
| | | onMediaSourceEnded() { |
| | |
| | | this.client = data.websocket |
| | | this.client.onopen = this.initSocketClient.bind(this) |
| | | this.client.onclose = function (e) { |
| | | console.log('Websocket Disconnected!') |
| | | // console.log('Websocket Disconnected!') |
| | | } |
| | | } |
| | | } |