Commit 8ab61264 by 潘建波

暂存

2 parents e432fae1 4288a81d
...@@ -4,6 +4,8 @@ import task from "./task"; ...@@ -4,6 +4,8 @@ import task from "./task";
import show from "./show"; import show from "./show";
import search from "./search"; import search from "./search";
import device from "./device" import device from "./device"
import resource from "./resource"
import ops from "./ops"
let wsIP = "192.168.9.133:20080"; let wsIP = "192.168.9.133:20080";
switch (process.env.NODE_ENV) { switch (process.env.NODE_ENV) {
case "development": case "development":
...@@ -24,5 +26,7 @@ export default { ...@@ -24,5 +26,7 @@ export default {
show, show,
search, search,
device, device,
resource,
ops,
wsIP wsIP
}; };
...@@ -7,9 +7,7 @@ let service = axios.create({ ...@@ -7,9 +7,7 @@ let service = axios.create({
timeout: 60000 timeout: 60000
}) })
// 设置 post、put 默认 Content-Type
service.defaults.headers.post['Content-Type'] = 'application/json'
service.defaults.headers.put['Content-Type'] = 'application/json'
// 添加请求拦截器 // 添加请求拦截器
service.interceptors.request.use( service.interceptors.request.use(
...@@ -17,12 +15,7 @@ service.interceptors.request.use( ...@@ -17,12 +15,7 @@ service.interceptors.request.use(
if (store.state.users.atoken) { // 判断是否存在token,如果存在的话,则每个http header都加上token if (store.state.users.atoken) { // 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers.authorization = store.state.users.atoken; config.headers.authorization = store.state.users.atoken;
} }
if (config.method == 'post') { if (config.method == 'get') {
config.data = {
...config.data,
// _t: Date.parse(new Date()) / 1000
}
} else if (config.method == 'get') {
config.params = { config.params = {
_t: Date.parse(new Date()) / 1000, _t: Date.parse(new Date()) / 1000,
...config.params ...config.params
......
...@@ -6,6 +6,9 @@ export default { ...@@ -6,6 +6,9 @@ export default {
login(params,id) { login(params,id) {
return api.post(urls.login,params) return api.post(urls.login,params)
}, },
getMenus(params,id){
return api.get(urls.menus,params)
},
algocombs(params,id){ algocombs(params,id){
return api.get(urls.algocombs,params) return api.get(urls.algocombs,params)
}, },
...@@ -17,5 +20,8 @@ export default { ...@@ -17,5 +20,8 @@ export default {
}, },
codes(params,id){ codes(params,id){
return api.get(urls.codes+id+'/codes',params) return api.get(urls.codes+id+'/codes',params)
} },
customCode(params,id){
return api.get(urls.customCode,params)
},
} }
...@@ -4,5 +4,7 @@ export default { ...@@ -4,5 +4,7 @@ export default {
algocombs: baseUrl + "/api/v1/devconf_fx/algo_combs", algocombs: baseUrl + "/api/v1/devconf_fx/algo_combs",
storeconfs: baseUrl + "/api/v1/devconf_fx/store_confs", storeconfs: baseUrl + "/api/v1/devconf_fx/store_confs",
cates: baseUrl + "/api/v1/codes/traffic/cates", cates: baseUrl + "/api/v1/codes/traffic/cates",
codes: baseUrl + "/api/v1/codes/traffic/cates/" codes: baseUrl + "/api/v1/codes/traffic/cates/",
customCode:baseUrl + "/api/v1/codes/custom/cates",
menus:baseUrl + "/api/v1/auth/menu_tree"
}; };
import api from '../index'
import baseUrl from '../baseUrl'
export default {
getUserList(params){
return api.get(`${baseUrl}/api/v1/devconf_fx/users`, params)
},
getRoleList(params,id) {
return api.get(`${baseUrl}/api/v1/devconf_fx/roles`, params)
},
addUser(params){
return api.post(`${baseUrl}/api/v1/devconf_fx/users`, params)
},
editUser(params,id) {
return api.post(`${baseUrl}/api/v1/devconf_fx/users/${id}`, params)
},
resetPwd(params,id) {
return api.post(`${baseUrl}/api/v1/devconf_fx/users/${id}/reset`, params)
},
delUser(params,id){
return api.delete(`${baseUrl}/api/v1/devconf_fx/users/${id}`, params)
},
getMenuList(params){
return api.get(`${baseUrl}/api/v1/devconf_fx/menu/list`, params)
},
addRole(params){
return api.post(`${baseUrl}/api/v1/devconf_fx/roles`, params)
},
logList(params){
return api.get(`${baseUrl}/api/v1/devconf_fx/logs`, params)
},
}
\ No newline at end of file \ No newline at end of file
import api from '../index'
import baseUrl from '../baseUrl'
export default {
devs(params){
return api.get(`${baseUrl}/api/v1/devconf_fx/devs`, params)
},
treeList(params,id) {
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchan_struct`, params)
},
getVideoList(params,id) {
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchans`, params)
},
addCode(params,id) {
return api.post(`${baseUrl}/api/v1/codes/custom/cates/${id}/codes`, params)
},
addNode(params,id){
return api.post(`${baseUrl}/api/v1/org`, params)
},
getCode(params,id){
return api.get(`${baseUrl}/api/v1/codes/custom/cates/${id}/codes`, params)
},
editCamera(params,id,unid){
return api.post(`${baseUrl}/api/v1/codes/custom/cates/${id}/codes/${unid}`, params)
},
delCode(params,id,unid){
return api.delete(`${baseUrl}/api/v1/codes/custom/cates/${id}/codes/${unid}`, params)
},
delOrg(params,id){
return api.delete(`${baseUrl}/api/v1/org/${id}`, params)
},
delCamera(params,id,id2){
return api.delete(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchans/${id2}`, params)
},
getCameraTable(params,id,id2){
console.log(id2)
if(id2){
console.log('aa')
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchans/${id2}`, params)
}else{
console.log('bb')
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchans`, params)
}
},
editCamera(params,id,id2){
return api.post(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vchans/${id2}`, params)
},
uploadFile(params,id){
return api.post(`${baseUrl}/api/v1/devconf_fx/devs/${id}/vfile_vchans`, params,{'Content-Type': 'multipart/form-data'})
},
getResource(params,id){
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/status`, params)
},
getDevsName(params,id){
return api.get(`${baseUrl}/api/v1/devconf_fx/devs/${id}/fx_devs`, params)
},
getStoreConList(params){
return api.get(`${baseUrl}/api/v1/devconf_fx/store_confs`, params)
},
getSubTask(params,id){
return api.get(`${baseUrl}/api/v1/devconf_fx/tasks/${id}/subtasks`, params)
},
delStore(params,id){
return api.delete(`${baseUrl}/api/v1/devconf_fx/store_confs/${id}`, params)
},
}
\ No newline at end of file \ No newline at end of file
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
.el-input.is-active .el-input__inner, .el-input__inner:focus{ .el-input.is-active .el-input__inner, .el-input__inner:focus{
border-color: #3BB7FF; border-color: #3BB7FF;
} }
.el-tooltip__popper{
max-width: 300px;
}
/* 下拉框重置 */ /* 下拉框重置 */
.el-select .el-input.is-focus .el-input__inner{ .el-select .el-input.is-focus .el-input__inner{
border-color: #3BB7FF; border-color: #3BB7FF;
......
...@@ -36,6 +36,10 @@ a:active{ ...@@ -36,6 +36,10 @@ a:active{
display: inline-block; display: inline-block;
width: 150px; width: 150px;
} }
.maxHeight{
max-height: 400px;
overflow-y: auto;
}
.innnerBox{ .innnerBox{
padding: 10px;background: #FFFFFF;margin: 10px; padding: 10px;background: #FFFFFF;margin: 10px;
} }
......
import Vue from "vue"; import Vue from "vue";
import App from "./App.vue"; import App from "./App.vue";
import ElementUI from "element-ui"; import ElementUI from "element-ui";
import axios from "axios";
import "element-ui/lib/theme-chalk/index.css"; import "element-ui/lib/theme-chalk/index.css";
import router from "./router"; import router from "./router";
import store from "./store"; import store from "./store";
...@@ -17,6 +18,7 @@ Vue.prototype.$echarts = echarts; ...@@ -17,6 +18,7 @@ Vue.prototype.$echarts = echarts;
Vue.prototype.$moment = moment; Vue.prototype.$moment = moment;
Vue.prototype.$buildCode = buildCode; Vue.prototype.$buildCode = buildCode;
Vue.prototype.oParse = new XML.ObjTree(); Vue.prototype.oParse = new XML.ObjTree();
Vue.prototype.axios=axios;
Vue.use(api); Vue.use(api);
Vue.use(ElementUI, { size: "small", zIndex: 3000 }); Vue.use(ElementUI, { size: "small", zIndex: 3000 });
Vue.use(resetCss); Vue.use(resetCss);
......
...@@ -126,17 +126,14 @@ export const asyncRouterMap = [ ...@@ -126,17 +126,14 @@ export const asyncRouterMap = [
meta: { meta: {
icon: "el-icon-location" icon: "el-icon-location"
}, },
component: resolve => component: resolve => require(["../views/search/traficflow.vue"], resolve),
require(["../views/search/traficflow.vue"], resolve) },{
},
{
path: "/search/flow", path: "/search/flow",
name: "公共客流", name: "公共客流",
meta: { meta: {
icon: "el-icon-location" icon: "el-icon-location"
}, },
component: resolve => component: resolve => require(["../views/search/publicFlow.vue"], resolve),
require(["../views/search/publicFlow.vue"], resolve)
} }
] ]
}, },
...@@ -147,7 +144,71 @@ export const asyncRouterMap = [ ...@@ -147,7 +144,71 @@ export const asyncRouterMap = [
meta: { meta: {
icon: "el-icon-location" icon: "el-icon-location"
}, },
children: [] children: [
{
path: "/resource/video",
name: "视频设备",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/resource/videoEquipment.vue"], resolve),
},
{
path: "/resource/equipment",
name: "分析设备",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/resource/analysis.vue"], resolve),
},
{
path: "/resource/store_confs",
name: "存储配置",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/resource/store_confs.vue"], resolve),
},
]
},{
path: "/ops",
name: "系统运维",
component: resolve => require(["../views/Layout/index.vue"], resolve),
meta: {
icon: "el-icon-location"
},
children: [
{
path: "/ops/equipment_manage",
name: "设备管理",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/ops/equipment_manage"], resolve),
},{
path: "/ops/user_manage",
name: "用户管理",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/ops/user_manage.vue"], resolve),
},{
path: "/ops/role_manage",
name: "角色管理",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/ops/role_manage.vue"], resolve),
},{
path: "/ops/log_manage",
name: "日志管理",
meta: {
icon: "el-icon-location"
},
component: resolve => require(["../views/ops/log_manage.vue"], resolve),
}
]
} }
]; ];
const router = new VueRouter({ const router = new VueRouter({
......
...@@ -46,7 +46,7 @@ import types from '../store/types.js' ...@@ -46,7 +46,7 @@ import types from '../store/types.js'
login(){ login(){
this.$api.login.login({ this.$api.login.login({
user_name: this.username, user_name: this.username,
user_password: sha1(this.password), user_password: sha1(this.),
}).then(res => { }).then(res => {
if(!res.ecode){ if(!res.ecode){
this.$store.commit(types.ATOKEN,res.token); this.$store.commit(types.ATOKEN,res.token);
......
<template>
</template>
<script>
</script>
<style>
</style>
<template>
<div>
<!-- 外层内容 -->
<div class="leftBox">
<div class="titles">分析设备列表</div>
<div class="treeBox">
<el-tree
:data="treeData"
:props="defaultProps"
accordion
highlight-current
:expand-on-click-node=false
@node-click="handleNodeClick">
</el-tree>
</div>
</div>
<div class="rightBox">
</div>
<div style="clear: both;"></div>
</div>
</template>
<script>
export default{
data(){
return{
treeData: [],
defaultProps: {
children: 'childs',
label: 'device_name'
},
dev_unid:sessionStorage.getItem('dev_unid')
}
},
mounted(){
console.log(this.setvisible)
},
methods:{
getTree(){
this.$api.resource.getDevsName({
is_leaf: 0
},this.dev_unid).then(res=>{
this.treeData=res.list_data;
this.treeData.forEach(item=>{
this.getChild(item.device_id)
})
})
},
getChild(id){
this.$api.resource.getDevsName({
limit: 9999,
offset: 0,
parent_id: id,
},this.dev_unid).then((res)=>{
this.treeData.forEach(item=>{
if(item.device_id==id){
this.treeData.childs=res.list_data
}
})
}).catch((error)=>{
})
},
handleNodeClick(data) {
console.log(data);
},
}
}
</script>
<style scoped="scoped" lang="scss">
.bofangIcon{
cursor: pointer;
color:#cccccc;
font-size:16px;
margin-left: 26px;
}
.moveIcon{
cursor: pointer;
color:#34b3a2;
font-size:16px;
}
.delIcon{
cursor: pointer;
color:#f2365a;
font-size:16px;
}
.leftBox{
width: 233px;
height: 630px;
border:1px solid rgba(229,229,229,1);
float: left;
}
.titles{
height: 30px;
line-height: 30px;
padding-left: 13px;
background: $title-backgroud;
font-size: 14px;
color: $title-color;
}
.treeBox{
padding: 6px;
}
.rightBox{
float: left;
margin-left: 14px;
}
.imgBox{
width: 587px;
height: 330px;
border:1px solid #444444;
margin-bottom: 14px;
}
</style>
<template>
<div class="innnerBox">
<el-col :span="22">
<el-form ref="form" label-width="80px" inline>
<el-form-item label="用户名" >
<span class="inputBox">
<el-input placeholder="请输入用户名" v-model="conditions.username_like"></el-input>
</span>
</el-form-item>
<el-form-item label="起始时间">
<span class="dateBox">
<el-date-picker
v-model="dates"
value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</span>
</el-form-item>
</el-form>
</el-col>
<el-col :span="2">
<el-button type="primary" style="" @click="query" class="block">查询</el-button>
</el-col>
<div style="">
<el-table
:data="tableData"
height="574"
stripe
border>
<el-table-column
align="center"
prop="num"
:formatter="numFormatter"
label="序号">
</el-table-column>
<el-table-column
prop="log_type"
align="center"
:formatter="typeFormatter"
label="日志类型">
</el-table-column>
<el-table-column
prop="log_time"
align="center"
label="操作时间">
</el-table-column>
<el-table-column
prop="user_name"
align="center"
label="操作用户名">
</el-table-column>
<el-table-column
prop="client_ip"
align="center"
label="操作用户IP地址">
</el-table-column>
<el-table-column
prop="log_content"
align="center"
label="操作内容">
</el-table-column>
</el-table>
<div style="margin-top: 28px;">
<el-pagination
style="float: right;"
background
prev-text="上一页"
next-text="下一页"
:page-sizes="[30, 50, 100, 200]"
layout="prev, pager, next,sizes"
:current-page="page"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="total">
</el-pagination>
<div style="clear: both;"></div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
let start_dt = this.$moment().format('YYYY-MM-DD')+' 00:00:00';
let end_dt = this.$moment().format('YYYY-MM-DD')+' 23:59:59';
return{
dates:[ start_dt,end_dt ],
conditions: {
start_dt:start_dt,
end_dt:end_dt,
username_like:''
},
tableData:[],
total:0,
page:1,
pageSize:30,
}
},
watch:{
dates(val){
this.conditions.start_dt=val[0];
this.conditions.end_dt=val[1];
}
},
components:{},
mounted(){
this.getData()
},
methods:{
numFormatter(row, column, cellValue, index) {
return (index+1)*this.page;
},
typeFormatter(row, column, cellValue, index){
if(cellValue==1){
return '系统日志'
}else if(cellValue==0){
return '操作日志'
}else{
return '无'
}
},
handleSizeChange(val) {
this.pageSize=val;
this.getData();
},
handleCurrentChange(val) {
this.page=val;
this.getData();
},
query(){
this.getData();
},
getData(){
this.tableData=[];
let offset = (this.page - 1) * this.pageSize;
let search_params = {
limit: this.pageSize,
offset: offset,
start_time: this.$moment(this.conditions.start_dt).utc().format('YYYY-MM-DD HH:mm:ss'),
end_time:this.$moment(this.conditions.end_dt).utc().format('YYYY-MM-DD HH:mm:ss'),
username_like: this.conditions.username_like ? this.conditions.username_like.replace(/\s\s*/g, '') : this.conditions.username_like
}
this.$api.ops.logList(search_params
).then((res)=>{
this.total=res.total_num;
this.tableData = res.list_data;
}).catch((err)=>{
})
},
},
}
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file \ No newline at end of file
<template>
<div class="contentBox">
<div class="content">
<div style="padding: 20px 15px 20px 23px;">
<span style="float: right;">
<el-button type="info" @click="addRole">添加新用户</el-button>
</span>
<div style="clear: both;"></div>
</div>
<div style="padding: 0 15px 20px 23px;">
<el-table
height="574"
:data="tableData"
stripe
border
style="width: 100%">
<el-table-column
align="center"
prop="num"
:formatter="numFormatter"
label="序号">
</el-table-column>
<el-table-column
align="center"
prop="role_name"
label="角色名">
</el-table-column>
<el-table-column
align="center"
prop="create_dt"
width="300"
label="创建时间">
</el-table-column>
<el-table-column
align="center"
width="300"
prop="operation"
label="操作">
<template slot-scope="scope">
<el-tooltip content="编辑角色" placement="bottom" effect="light" :visible-arrow=false>
<span class="iconfont icon-xiugai editIcon" @click="editUser(scope.$index, scope.row)"></span>
</el-tooltip>
<span class="tableSpanBorder"></span>
<el-tooltip content="删除角色" placement="bottom" effect="light" :visible-arrow=false>
<span class="iconfont icon-detail delIcon" @click="delFun(scope.$index, scope.row)"></span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 28px;">
<el-pagination
style="float: right;"
background
prev-text="上一页"
next-text="下一页"
:page-sizes="[30, 50, 100, 200]"
layout="prev, pager, next,sizes"
:current-page="page"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="total">
</el-pagination>
<div style="clear: both;"></div>
</div>
</div>
</div>
<!-- 新增 -->
<el-dialog
title="新增用户"
:visible.sync="addVisible"
@open="openAddDialog"
width="30%">
<div class="maxHeight">
<el-form label-position="left" label-width="80px" :model="addForm" :rules="rules" ref="addForm" inline-message hide-required-asterisk>
<el-form-item label="角色名" prop="role_name">
<el-input v-model="addForm.role_name"></el-input>
</el-form-item>
<el-form-item label="权限菜单" prop="menu_unids">
<el-tree
:data="treeData"
@current-change="treeChange"
show-checkbox
ref="addTree"
node-key="menu_unid"
:props="defaultProps">
</el-tree>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible = false">取 消</el-button>
<el-button type="primary" @click="addFun('addForm')">确 定</el-button>
</span>
</el-dialog>
<!-- 编辑 -->
<el-dialog
title="编辑用户"
:visible.sync="editVisible"
width="30%">
<div class="maxHeight">
<el-form label-position="left" label-width="80px" :model="editForm" :rules="rules" ref="editForm" inline-message hide-required-asterisk>
<el-form-item label="角色选项" prop="role_unid">
<el-select v-model="editForm.role_unid" placeholder="请选择" :popper-append-to-body=false>
<el-option
v-for="item in roleList"
:key="item.role_unid"
:label="item.role_name"
:value="item.role_unid">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="用户名" prop="user_name">
<el-input v-model="editForm.user_name"></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<el-button type="primary" @click="editFun('editForm')">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data(){
var checkRole = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入角色名'));
} else {
callback();
}
};
var checkMenu_unids = (rule, value, callback) => {
if (value.length==0) {
callback(new Error('请至少选择一个权限'));
} else {
callback();
}
};
return{
treeData:[],
defaultProps: {
children: 'childs',
label: 'menu_name'
},
total:0,
page:1,
pageSize:30,
addForm:{
role_name:'',
menu_unids:[]
},
editForm:{
role_name:'',
menu_unids:[]
},
editUnid:'',
tableData: [],
addVisible:false,
editVisible:false,
roleList:[],
userId:sessionStorage.getItem('user_unid'),
rules: {
role_name: [
{ validator: checkRole, trigger: 'change' }
],
menu_unids: [
{ validator: checkMenu_unids, trigger: 'change' }
],
}
}
},
components:{
},
mounted(){
this.getTableList();
this.getMenuList();
},
methods:{
treeChange(data,node){
console.log(data,node)
},
numFormatter(row, column, cellValue, index) {
return (index+1)*this.page;
},
handleSizeChange(val) {
this.pageSize=val;
this.getTableList();
},
handleCurrentChange(val) {
this.page=val;
this.getTableList();
},
getMenuList(){
this.treeData=[];
this.$api.ops.getMenuList({
limit: 9999,
offset: 0,
}).then((res)=>{
this.treeData = res;
}).catch((error)=>{
})
},
getTableList(){
this.tableData=[];
let offset = (this.page - 1) * this.pageSize;
this.$api.ops.getRoleList({
limit: this.pageSize,
offset: offset,
}).then((res)=>{
this.total=res.total_num;
if(res.list_data==null){
this.tableData=[]
}else{
this.tableData=res.list_data;
}
}).catch((error)=>{
})
},
delFun(index,row){
this.$confirm('此操作将永久删除该选项, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$api.ops.delUser({},row.unid).then(res=>{
if(res.ecode==200){
this.$message({
type: 'success',
message: '删除成功!'
});
this.getTableList();
}else{
this.$message({
type: 'error',
message: '删除失败!'
});
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
editUser(index,row){
this.editForm.role_unid=row.role_unid;
this.editForm.user_name=row.user_name;
this.editUnid=row.unid;
this.editVisible=true;
},
openAddDialog(){
this.$refs['addForm'].resetFields();
},
addRole(){
this.addVisible=true;
},
addFun(formName){
this.addForm.menu_unids=this.$refs.addTree.getCheckedKeys().sort((a, b) => { return a - b; });
this.$refs[formName].validate((valid) => {
if (valid) {
this.$api.ops.addRole(this.addForm).then(res=>{
if(!res.ecode){
this.$message({
type: 'success',
message: '添加成功!'
});
this.addVisible=false;
this.getTableList();
}else{
this.$message({
type: 'error',
message: res.enote
});
}
})
} else {
return false;
}
});
},
editFun(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
this.$api.ops.editUser(this.editForm,this.editUnid).then(res=>{
if(!res.ecode){
this.$message({
type: 'success',
message: '修改成功!'
});
this.editVisible=false;
this.getTableList();
}else{
this.$message({
type: 'error',
message: '修改失败!'
});
}
})
} else {
return false;
}
});
}
},
}
</script>
<style lang="scss" scoped>
.topCon{
background: $white-back-color;
margin-bottom: 12px;
height: 100px;
.left{
display: inline-block;
margin: {
top: 22px;
left: 30px;
};
img{
width:65px ;
height: 55px;
margin-right: 11px;
}
.topText{
font-size:24px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
margin-bottom: 4px;
}
.bottomText{
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.right{
float: right;
.topText{
font-size:28px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
}
.bottomText{
position: relative;
top: -1px;
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.textCon{
display: inline-block;
vertical-align: top;
}
.border{
display: inline-block;
height: 40px;
border: {
left: 2px solid $border-color;
};
}
.rightBox{
margin-top: 14px;
display: inline-block;
img{
margin:{
top:15px;
right: 22px;
}
}
}
.rightBox:nth-of-type(1){
img{
width: 34px;
height: 34px;
}
.textCon{
margin-right:114px ;
}
}
.rightBox:nth-of-type(2){
position: relative;
top: 4px;
img{
width: 40px;
height: 40px;
margin-left: 102px;
}
.textCon{
margin-right:101px ;
}
}
.rightBox:nth-of-type(3){
img{
width: 34px;
height: 35px;
margin-left: 104px;
}
.textCon{
margin-right:184px ;
}
}
}
.content{
background: #FFFFFF;
}
.inputBox{
margin-right: 20px;
}
.selectBox{
margin-right: 20px;
}
.editIcon{
cursor: pointer;
color:#0069ff;
font-size:16px;
}
.editIcon2{
cursor: pointer;
color:#87d14b;
font-size:16px;
}
.playIcon{
cursor: pointer;
color:#34b3a2;
font-size:16px;
}
.pauseIcon{
cursor: pointer;
color:#ffc62e;
font-size:14px;
}
.delIcon{
cursor: pointer;
color:#f2365a;
font-size:16px;
}
</style>
\ No newline at end of file \ No newline at end of file
<template>
<div class="ocx-box" id="ocx-box" v-show="isShow">
<object id="VionVideo1" classid="clsid:93F960BB-5AF9-402B-A3DF-06112F14DC02" codebase="VionPlatformVideo.ocx" width="100%"
height="100%">
<!-- <param name="_Version" value="65536">
<param name="_ExtentX" value="2646">
<param name="_ExtentY" value="1323">
<param name="_StockProps" value="0"> -->
</object>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
export default {
data() {
return {
urlFlag:false,
isShow:true
};
},
props: ['playurl', 'type'],
methods: {
videoPlay: function () {
this.urlFlag = false
if (!this.playurl.sip_serv_ip) {
let url = this.playurl.rtsp_url
let ocxPlayRes = document.getElementById('VionVideo1').StartPlay(url, 0);
console.log('video Ocx播放rtsp流返回值:', ocxPlayRes);
if (ocxPlayRes != 0) {
alert('播放失败!');
}
} else {
let OcxResponse = document.getElementById('VionVideo1').StartPlaySip(this.playurl.sip_serv_id, this.playurl.sip_serv_ip,
this.playurl.sip_serv_port, this.playurl.sip_unid, this.playurl.sip_password, this.playurl.devId, 0)
console.log('video Ocx播放sip流返回值:', OcxResponse);
if (OcxResponse != 0 && OcxResponse != 200) {
alert('播放失败!');
}
}
},
downOcx: function () {
if (this.fileUrl !== '' && !this.installOcx) {
location.href = this.fileUrl;
}
},
installOcxInfo: function () {
this.$confirm('为了正常使用,是否安装OCX控件?', '友情提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.installOcx = false;
this.downOcx();
}).catch(() => {
this.installOcxInfo();
});
},
initocx() {
VionVideo1.Init(0, 'Null', 4);
},
downloadOCx() {
// if (navigator.userAgent.indexOf('Trident') > -1) {
// this.axios.get(IP + "/api/v1/device/dlfile", {
// params: {
// file_type: "video_ocx"
// }
// })
// .then(response => {
// location.href = response.data.file_url;
// });
// } else {
// this.$message.error("视频控件加载失败请用IE10及以上版本打开!");
// }
},
checkIE() {
var agent = navigator.userAgent.toLowerCase();
if (/(msie\s|trident.*rv:)([\w.]+)/.test(agent) && document.documentMode < 10) {
this.$message.error("IE 版本过低请升级到IE10级以上版本!");
}
}
},
created() {
// this.checkIE();
},
computed: {
...mapState(['ocxstate'])
},
mounted() {
// VionVideo1.Init(0, 'Null', 4);
// try {
// if (document.getElementById("VionVideo1").GetVersion()) {
// }
// } catch (error) {
// this.downloadOCx();s
// }
},
watch: {
ocxstate(val) {
try {
if(val == 0){
this.isShow = false
document.getElementById("VionVideo1").StartPlay(1);
} else {
this.isShow = true
document.getElementById("VionVideo1").StartPlay(0);
}
} catch (error) {
console.log(error)
}
},
},
beforeDestroy: function () {
// if (this.videoplayer.techName_ == "Flash" && this.videoplayer.pause) {
// this.videoplayer.pause();
// }
}
};
</script>
<style lang="stylus" scoped>
.ocx-box{
height 100%
width 100%
}
</style>
<template>
<div class="item">
<div class="player">
<div class="ocx-box">
<!-- <object id="VionVideo" classid="clsid:96DFBBAF-4220-4978-9681-4ABA534A7718"
width="98%" height="450" style="margin-left:.9%">
</object> -->
<object height="90%" width="100%" id="nvrTotalOcx" name="nvrTotalOcx"
classid="CLSID:96DFBBAF-4220-4978-9681-4ABA534A7718"
style="margin-top:20px"
>
<param name="BorderStyle" value="1" />
<param name="MousePointer" value="0" />
<param name="Enabled" value="1" />
<param name="Min" value="0" />
<param name="Max" value="10" />
<embed wmode="opaque"></embed>
<param name="wmode" value="transparent">
</object>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
props: ["playersrc", "vnum"],
methods: {
initocx(){
VionVideo.Init(0, 'Null', 4);
},
downloadOCx() {
if (navigator.userAgent.indexOf('Trident') > -1) {
this.axios.get(IP + "/api/v1/device/dlfile", {
params: {
file_type: "video_ocx"
}
})
.then(response => {
location.href = response.data.file_url;
});
} else {
this.$message.error("视频控件加载失败请用IE10及以上版本打开!");
}
},
checkIE() {
var agent = navigator.userAgent.toLowerCase();
if (/(msie\s|trident.*rv:)([\w.]+)/.test(agent) && document.documentMode < 10) {
this.$message.error("IE 版本过低请升级到IE10级以上版本!");
}
}
},
created() {
this.checkIE();
},
computed(){
},
mounted() {
var testStr = 'Null';
nvrTotalOcx.Init(0, testStr, 4);
nvrTotalOcx.SetSingleWindow(true);
nvrTotalOcx.SetParam("SetLanguage", "Chinese");
nvrTotalOcx.SetParam("VideoSize", 0);
var medianame = '视频0';
var hostname = window.location.hostname;
var port,url;
port=8554;
url = "rtsp://192.168.9.133:8554//opt/data/vedio/1579253441478.264";
let a = ''
setTimeout(()=>{
a = nvrTotalOcx.PlayRealVideo(url,1,'video','192.168.9.133',0);
},500)
setTimeout(()=>{
a = nvrTotalOcx.PlayRealVideo(url,1,'video','192.168.9.133',0);
},1000)
console.log('shipin'+a)
},
watch: {
},
beforeDestroy: function () {
if (this.videoplayer.techName_ == "Flash" && this.videoplayer.pause) {
this.videoplayer.pause();
}
}
};
</script>
<style lang="stylus" scoped>
.ocx-box{
height 50vh
width 35vw
}
</style>
<template>
<div class="contentBox">
<div class="content">
<div style="padding: 20px 15px 20px 23px;">
<span class="selectBox">
<el-select v-model="selectDevs" placeholder="请选择" @change="devsChange" :popper-append-to-body=false>
<el-option v-for="item in devsList" :value="item.device_id" :label='item.device_name'></el-option>
</el-select>
</span>
<div class="resourceDiv">
<span>图片可用分析资源:{{resource.picture_free}}</span>
<span>图片在用分析资源:{{resource.picture_busy}}</span>
<span>视频可用分析资源:{{resource.video_free}}</span>
<span>视频在用分析资源:{{resource.video_busy}}</span>
</div>
</div>
<div style="padding: 0 15px 20px 23px;">
<el-table
height="574"
:data="tableData"
stripe
border
style="width: 100%">
<el-table-column
align="center"
prop="device_name"
label="设备名称">
</el-table-column>
<el-table-column
prop="in_ip"
align="center"
label="ip地址">
</el-table-column>
<el-table-column
align="center"
prop="online"
:formatter="statusFormatter"
label="在线状态">
</el-table-column>
<el-table-column
align="center"
prop="video_total"
label="分析资源数">
</el-table-column>
<el-table-column
align="center"
prop="video_free"
label="可用分析资源数">
</el-table-column>
<el-table-column
align="center"
prop="working_status"
label="工作状态">
</el-table-column>
<el-table-column
align="center"
width="300"
prop="operation"
label="操作">
<template slot-scope="scope">
<el-tooltip content="详情" placement="bottom" effect="light" :visible-arrow=false>
<span class="iconfont icon-xiugai editIcon" @click="detail(scope.$index, scope.row)"></span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 28px;">
<el-pagination
style="float: right;"
background
prev-text="上一页"
next-text="下一页"
:page-sizes="[30, 50, 100, 200]"
layout="prev, pager, next,sizes"
:current-page="page"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="total">
</el-pagination>
<div style="clear: both;"></div>
</div>
</div>
</div>
<el-dialog title="详情" :visible.sync="detailVisible">
<el-table height="574"
:data="detailData"
stripe
border>
<li>{{detail.online == 1 ? (detail.status.hardWareInfo.temperature[0]?detail.status.hardWareInfo.temperature[0].curTemperature : ''):''}}</li>
<el-table-column prop="device_name" align="center" label="核心板名称"></el-table-column>
<el-table-column prop="in_ip" align="center" label="核心板IP"></el-table-column>
<el-table-column
align="center"
prop="online"
:formatter="statusFormatter"
label="在线状态">
</el-table-column>
<el-table-column prop="cpuUse" align="center" label="CPU使用率" :formatter="cpuUseFormatter"></el-table-column>
<el-table-column prop="cpuTem" align="center" label="CPU温度(℃)" :formatter="cpuTemFormatter"></el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
export default {
data(){
return{
detailData:[],
dev_unid: sessionStorage.getItem('dev_unid'),
resource:{
picture_busy: 0,
picture_free: 0,
video_busy: 0,
video_free: 0,
},
total:0,
page:1,
pageSize:30,
tableData: [],
devsList:[],
selectDevs:'',
detailVisible:false
}
},
components:{
},
mounted(){
this.getResource();
this.getDevsName();
},
methods:{
devsChange(){
this.getTableList();
},
getResource(){
this.$api.resource.getResource({},this.dev_unid).then(res=>{
this.resource=res.works;
})
},
getDevsName(){
this.$api.resource.getDevsName({
is_leaf: 0
},this.dev_unid).then(res=>{
this.devsList=res.list_data;
if(res.list_data.length>0){
this.selectDevs=res.list_data[0].device_id;
}
this.getTableList();
})
},
statusFormatter(row, column, cellValue, index){
if(cellValue == 1){
return '在线'
}else if(cellValue == 0){
return '离线'
}else {
return '未知'
}
},
cpuUseFormatter(row, column, cellValue, index){
if(row.online == 1){
return parseInt(row.status.hardWareInfo.usedResourceInfo.cpuRatio*60)+'%'
}else{
return ''
}
},
cpuTemFormatter(row, column, cellValue, index){
if(row.online == 1){
if(row.status.hardWareInfo.temperature[0]){
return row.status.hardWareInfo.temperature[0].curTemperature
}else{
return ''
}
}else{
return ''
}
},
handleSizeChange(val) {
this.pageSize=val;
this.getTableList();
},
handleCurrentChange(val) {
this.page=val;
this.getTableList();
},
getTableList(){
this.tableData=[];
let offset = (this.page - 1) * this.pageSize;
this.$api.resource.getDevsName({
limit: this.pageSize,
offset: offset,
parent_id: this.selectDevs,
},this.dev_unid).then((res)=>{
this.total=res.total_num;
if(res.list_data==null){
this.tableData=[]
}else{
this.tableData=res.list_data;
}
}).catch((error)=>{
})
},
detail(index,row){
this.detailData=[];
this.detailVisible=true;
this.$api.resource.getDevsName({
parent_id:row.device_id,
offset: 0,
limit: 10000,
},this.dev_unid).then(res=>{
this.detailData=res.list_data;
this.detailData.unshift(row)
})
},
},
}
</script>
<style lang="scss" scoped>
.topCon{
background: $white-back-color;
margin-bottom: 12px;
height: 100px;
.left{
display: inline-block;
margin: {
top: 22px;
left: 30px;
};
img{
width:65px ;
height: 55px;
margin-right: 11px;
}
.topText{
font-size:24px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
margin-bottom: 4px;
}
.bottomText{
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.right{
float: right;
.topText{
font-size:28px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
}
.bottomText{
position: relative;
top: -1px;
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.textCon{
display: inline-block;
vertical-align: top;
}
.border{
display: inline-block;
height: 40px;
border: {
left: 2px solid $border-color;
};
}
.rightBox{
margin-top: 14px;
display: inline-block;
img{
margin:{
top:15px;
right: 22px;
}
}
}
.rightBox:nth-of-type(1){
img{
width: 34px;
height: 34px;
}
.textCon{
margin-right:114px ;
}
}
.rightBox:nth-of-type(2){
position: relative;
top: 4px;
img{
width: 40px;
height: 40px;
margin-left: 102px;
}
.textCon{
margin-right:101px ;
}
}
.rightBox:nth-of-type(3){
img{
width: 34px;
height: 35px;
margin-left: 104px;
}
.textCon{
margin-right:184px ;
}
}
}
.resourceDiv{
display: inline-block;
margin-left: 10%;
span{
margin-right: 5%;
}
}
.content{
background: #FFFFFF;
}
.inputBox{
margin-right: 20px;
}
.selectBox{
margin-right: 20px;
}
.editIcon{
cursor: pointer;
color:#0069ff;
font-size:16px;
}
.editIcon2{
cursor: pointer;
color:#87d14b;
font-size:16px;
}
.playIcon{
cursor: pointer;
color:#34b3a2;
font-size:16px;
}
.pauseIcon{
cursor: pointer;
color:#ffc62e;
font-size:14px;
}
.delIcon{
cursor: pointer;
color:#f2365a;
font-size:16px;
}
</style>
\ No newline at end of file \ No newline at end of file
<template>
<div class="contentBox">
<div class="content">
<div style="padding: 20px 15px 20px 23px;">
<span class="inputBox">
<el-input v-model="storename" placeholder="请输入存储配置名称"></el-input>
</span>
<el-button type="primary" style="position: relative;top: -2px;" @click="query">查询</el-button>
<span style="float: right;">
<el-button type="info" icon="el-icon-search" @click="add">添加</el-button>
</span>
</div>
<div style="padding: 0 15px 20px 23px;">
<el-table
height="574"
:data="tableData"
stripe
border
style="width: 100%">
<el-table-column
align="center"
prop="name"
label="名称">
</el-table-column>
<el-table-column
prop="create_dt"
align="center"
label="上传时间">
</el-table-column>
<el-table-column
align="center"
prop="task_list"
label="应用任务">
<template slot-scope="scope">
<el-tooltip :content="scope.row.ellipsis" placement="bottom" effect="light" :visible-arrow=false>
<span class="ellipsis">{{scope.row.ellipsis}}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column
align="center"
width="300"
prop="operation"
label="操作">
<template slot-scope="scope">
<el-tooltip content="详情" placement="bottom" effect="light" :visible-arrow=false>
<span class="iconfont icon-xiugai editIcon" @click="detail(scope.$index, scope.row)"></span>
</el-tooltip>
<span class="tableSpanBorder"></span>
<el-tooltip content="删除" placement="bottom" effect="light" :visible-arrow=false>
<span class="iconfont icon-detail delIcon" @click="delFun(scope.$index, scope.row)"></span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 28px;">
<el-pagination
style="float: right;"
background
prev-text="上一页"
next-text="下一页"
:page-sizes="[30, 50, 100, 200]"
layout="prev, pager, next,sizes"
:current-page="page"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="total">
</el-pagination>
<div style="clear: both;"></div>
</div>
</div>
</div>
<el-dialog title="详情" :visible.sync="detailVisible" width="30%">
<div class="title">任务列表</div>
<div class="maxHeight">
<el-tree
:props="props"
:load="loadNode"
lazy>
</el-tree>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data(){
return{
props: {
label: 'name',
children: 'child',
isLeaf: 'leaf'
},
detailData:[],
dev_unid: sessionStorage.getItem('dev_unid'),
resource:{
picture_busy: 0,
picture_free: 0,
video_busy: 0,
video_free: 0,
},
total:0,
page:1,
pageSize:30,
tableData: [],
devsList:[],
selectDevs:'',
detailVisible:false,
storename:'',
curentSubList:[]
}
},
components:{
},
mounted(){
this.query();
},
methods:{
loadNode(node, resolve) {
if (node.level === 0) {
return resolve(this.curentSubList);
}
if (node.level > 1) return resolve([]);
this.$api.resource.getSubTask({},node.data.unid).then(res=>{
if(res.list_data==null){
res.list_data=[];
}
res.list_data.forEach(item=>{
item.name=item.subtask_name;
item['leaf']=true;
})
resolve(res.list_data)
})
},
query(){
this.tableData=[];
let offset = (this.page - 1) * this.pageSize;
this.$api.resource.getStoreConList({
limit: this.pageSize,
offset: offset,
name__like: this.storename,
},this.dev_unid).then((res)=>{
this.total=res.total_num;
if(res.list_data==null){
this.tableData=[]
}else{
this.tableData=res.list_data;
}
this.tableData.forEach(list=>{
let ellipsisText='';
list.task_list.forEach(item=>{
ellipsisText+=item.name+','
})
ellipsisText=ellipsisText.substring(0,ellipsisText.length-1);
list['ellipsis']=ellipsisText;
//树状图有子节点
list['leaf']=false;
})
console.log(this.tableData)
}).catch((error)=>{
})
},
add(){
},
taskFormatter(row, column, cellValue, index){
let columnText='';
row.task_list.forEach(item=>{
columnText+=item.name+','
})
columnText=columnText.substring(0,columnText.length-1);
return columnText
},
handleSizeChange(val) {
this.pageSize=val;
this.query();
},
handleCurrentChange(val) {
this.page=val;
this.query();
},
detail(index,row){
this.detailVisible=true;
this.curentSubList=[];
this.curentSubList=row.task_list;
},
delFun(index,row){
this.$confirm('此操作将永久删除该选项, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$api.resource.delStore({},row.unid).then(res=>{
if(res.ecode==200){
this.$message({
type: 'success',
message: '删除成功!'
});
this.query();
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
}
</script>
<style lang="scss" scoped>
.topCon{
background: $white-back-color;
margin-bottom: 12px;
height: 100px;
.left{
display: inline-block;
margin: {
top: 22px;
left: 30px;
};
img{
width:65px ;
height: 55px;
margin-right: 11px;
}
.topText{
font-size:24px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
margin-bottom: 4px;
}
.bottomText{
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.right{
float: right;
.topText{
font-size:28px;
font-family:MicrosoftYaHeiUI-Bold,MicrosoftYaHeiUI;
font-weight:bold;
}
.bottomText{
position: relative;
top: -1px;
font-size:14px;
font-family:MicrosoftYaHeiUI;
}
}
.textCon{
display: inline-block;
vertical-align: top;
}
.border{
display: inline-block;
height: 40px;
border: {
left: 2px solid $border-color;
};
}
.rightBox{
margin-top: 14px;
display: inline-block;
img{
margin:{
top:15px;
right: 22px;
}
}
}
.rightBox:nth-of-type(1){
img{
width: 34px;
height: 34px;
}
.textCon{
margin-right:114px ;
}
}
.rightBox:nth-of-type(2){
position: relative;
top: 4px;
img{
width: 40px;
height: 40px;
margin-left: 102px;
}
.textCon{
margin-right:101px ;
}
}
.rightBox:nth-of-type(3){
img{
width: 34px;
height: 35px;
margin-left: 104px;
}
.textCon{
margin-right:184px ;
}
}
}
.title{
font-size: 18px;
margin-bottom: 6px;
}
.maxHeight{
max-height: 400px;
overflow-y: auto;
}
.ellipsis{
display: inline-block;
width: 200px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.resourceDiv{
display: inline-block;
margin-left: 10%;
span{
margin-right: 5%;
}
}
.content{
background: #FFFFFF;
}
.inputBox{
margin-right: 20px;
}
.selectBox{
margin-right: 20px;
}
.editIcon{
cursor: pointer;
color:#0069ff;
font-size:16px;
}
.editIcon2{
cursor: pointer;
color:#87d14b;
font-size:16px;
}
.playIcon{
cursor: pointer;
color:#34b3a2;
font-size:16px;
}
.pauseIcon{
cursor: pointer;
color:#ffc62e;
font-size:14px;
}
.delIcon{
cursor: pointer;
color:#f2365a;
font-size:16px;
}
</style>
\ No newline at end of file \ No newline at end of file
<template>
<div>
<!-- 添加相机 -->
<el-dialog
title="添加相机"
:visible.sync="cameraAddVisible"
width="450px">
<div>
<el-form label-position="left" label-width="120px" :model="addVideoParam" :rules="rules" ref="cameraDialog" inline-message hide-required-asterisk>
<el-form-item label="组织编号">
<el-input v-model="initParam.orgId" disabled></el-input>
</el-form-item>
<el-form-item label="组织名称">
<el-input v-model="initParam.orgName" disabled></el-input>
</el-form-item>
<el-form-item label="地点编号">
<el-input v-model="initParam.addr_code" disabled></el-input>
</el-form-item>
<el-form-item label="地点名称">
<el-input v-model="initParam.addr_name" disabled></el-input>
</el-form-item>
<el-form-item label="设备编号" prop="vchan_refid">
<el-input v-model="addVideoParam.vchan_refid" :disabled="type=='edit'"></el-input>
</el-form-item>
<el-form-item label="设备名称" prop="name">
<el-input v-model="addVideoParam.name"></el-input>
</el-form-item>
<el-form-item label="方向">
<el-select v-model="addVideoParam.dir_code" placeholder="请选择方向" :popper-append-to-body=false>
<el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in dirCodeList"></el-option>
</el-select>
</el-form-item>
<el-form-item label="IP地址">
<el-input v-model="addVideoParam.ip"></el-input>
</el-form-item>
<el-form-item label="端口" prop="port">
<el-input v-model="addVideoParam.port"></el-input>
</el-form-item>
<el-form-item label="协议">
<el-select v-model="addVideoParam.video_protocol_id" placeholder="请选择协议" :popper-append-to-body=false>
<el-option label="rtsp" value="rtsp"></el-option>
<el-option label="onvif" value="onvif"></el-option>
</el-select>
</el-form-item>
<el-form-item label="取流地址" prop="video_source_url">
<el-input v-model="addVideoParam.video_source_url"></el-input>
</el-form-item>
<el-form-item label="用户名">
<el-input v-model="addVideoParam.user_name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="addVideoParam.password"></el-input>
</el-form-item>
<el-form-item label="扩展字段1">
<el-input v-model="addVideoParam.extend_1"></el-input>
</el-form-item>
<el-form-item label="扩展字段2">
<el-input v-model="addVideoParam.extend_2"></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="cameraAddVisible=false">取 消</el-button>
<el-button type="primary" @click="save" v-if="type!='detail'">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default{
data(){
return{
addVideoParam:{
vchan_refid:'',
name:'',
port:'',
video_source_url:'',
addr_unid:'',
dir_code:'',
ip:'',
video_protocol_id:'',
user_name:'',
password:'',
extend_1:'',
extend_2:'',
is_dome:false,
vchan_type:'camera'
},
initParam:{
},
cameraAddVisible:false,
dirCodeList:JSON.parse(localStorage.getItem('卡口方向')),
type:'',
devsId:'',
rules: {
vchan_refid: [
{ required: true, message: '设备编号不能为空', trigger: 'change' }
],
name:[
{ required: true, message: '设备名称不能为空', trigger: 'change' }
],
port:[
{ required: true, message: '端口不能为空', trigger: 'change' }
],
video_source_url:[
{ required: true, message: '取流地址不能为空', trigger: 'change' }
]
}
}
},
methods:{
initDialog(node,type,devsId){
this.cameraAddVisible=true;
this.devsId=devsId;
if(type == 'add'){
this.type='add'
this.addVideoParam.addr_unid=node.data.unid;
this.initParam.addr_name = node.data.org_name;
this.initParam.addr_code = node.data.org_code;
this.initParam.orgName = node.parent.data.org_name;
this.initParam.orgId = node.parent.data.org_code;
}else if(type == 'edit'){
this.type = 'edit';
this.addVideoParam.addr_unid = node.addrNode.unid;
this.initParam.addr_name = node.addrNode.org_name;
this.initParam.addr_code = node.addrNode.org_code;
this.initParam.orgName = node.orgNode.org_name;
this.initParam.orgId = node.orgNode.org_code;
this.addVideoParam.vchan_refid = node.id;
this.addVideoParam.name = node.label;
this.addVideoParam.dir_code=node.dir_code;
this.addVideoParam.ip=node.ip;
this.addVideoParam.port=node.port;
this.addVideoParam.video_protocol_id=node.video_proto;
this.addVideoParam.video_source_url=node.url;
this.addVideoParam.user_name=node.username;
this.addVideoParam.password=node.password;
this.addVideoParam.extend_1=node.extend_1;
this.addVideoParam.extend_2=node.extend_2;
}else if(type == 'detail'){
this.type = 'detail';
this.addVideoParam.addr_unid = node.addrNode.unid;
this.initParam.addr_name = node.addrNode.org_name;
this.initParam.addr_code = node.addrNode.org_code;
this.initParam.orgName = node.orgNode.org_name;
this.initParam.orgId = node.orgNode.org_code;
this.addVideoParam.vchan_refid = node.id;
this.addVideoParam.name = node.label;
this.addVideoParam.dir_code=node.dir_code;
this.addVideoParam.ip=node.ip;
this.addVideoParam.port=node.port;
this.addVideoParam.video_protocol_id=node.video_proto;
this.addVideoParam.video_source_url=node.url;
this.addVideoParam.user_name=node.username;
this.addVideoParam.password=node.password;
this.addVideoParam.extend_1=node.extend_1;
this.addVideoParam.extend_2=node.extend_2;
}
},
save(){
if(this.type == 'add'){
this.$refs['cameraDialog'].validate((valid) => {
if (valid) {
this.$api.resource.addCamera(this.addVideoParam,this.devsId).then(res=>{
if(res.ecode==200){
this.$message({
message: res.enote,
type: 'success'
});
let data={
org_type:"address",
unid:this.addVideoParam.addr_unid
}
this.$parent.submitLaterGet(data)
this.cameraAddVisible=false;
}else{
this.$message.error(res.enote);
}
})
} else {
console.log('error submit!!');
return false;
}
});
}else if(this.type == 'edit'){
this.addVideoParam.is_dome=false;
this.$refs['cameraDialog'].validate((valid) => {
if (valid) {
this.$api.resource.editCamera(this.addVideoParam,this.devsId,this.addVideoParam.vchan_refid).then(res=>{
if(res.ecode==200){
this.$message({
message: res.enote,
type: 'success'
});
let data={
org_type:"address",
unid:this.addVideoParam.addr_unid
}
this.$parent.submitLaterGet(data)
this.cameraAddVisible=false;
}else{
this.$message.error(res.enote);
}
})
} else {
console.log('error submit!!');
return false;
}
});
}
}
}
}
</script>
<style>
</style>
...@@ -2,88 +2,300 @@ ...@@ -2,88 +2,300 @@
<div> <div>
<el-tree <el-tree
class="filter-tree" class="filter-tree"
:data="data" :data="treeData"
:props="defaultProps" :props='defaultProps'
default-expand-all default-expand-all
@node-click="handleNodeClick"
:expand-on-click-node="false"
:filter-node-method="filterNode" :filter-node-method="filterNode"
ref="tree"> ref="tree">
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span> <span>
<span class="tree-label">{{ data.label }}</span> <span class="tree-label" v-if="data.org_name||data.org_name==''">{{ data.org_name=="" ? '未命名' : data.org_name}}</span>
<span class="tree-label" v-else-if="!data.org_name">{{ data.vchan_name=="" ? '未命名' : data.vchan_name}}</span>
</span> </span>
<span class="tree-btn"> <span class="tree-btn" v-if="data.org_name||data.org_name==''">
<i class="el-icon-plus" @click.stop="nodeAdd(node,data)"></i> <i class="el-icon-plus" @click.stop="nodeAddClick(node,data)"></i>
<i class="el-icon-edit" @click.stop="nodeEdit(node,data)"></i> <i class="el-icon-edit" @click.stop="nodeEditClick(node,data)" v-if="data.org_type!='root'"></i>
<i class="el-icon-delete" @click.stop="nodeDel(node,data)"></i> <i class="el-icon-delete" @click.stop="nodeDelClick(node,data)" v-if="data.org_type!='root'"></i>
</span> </span>
</span> </span>
</el-tree> </el-tree>
<el-dialog
title="添加"
:visible.sync="addVisible"
width="450px">
<div>
<el-form label-position="left" label-width="120px" :model="formData">
<el-form-item label="添加目标类型">
<el-select v-model="formData.targetType" placeholder="请选择" :popper-append-to-body=false>
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in targetOpt"> </el-option>
</el-select>
</el-form-item>
<div v-if="formData.targetType=='org'">
<el-form-item label="组织编号">
<el-input v-model="formData.code"></el-input>
</el-form-item>
<el-form-item label="组织名称">
<el-input v-model="formData.name"></el-input>
</el-form-item>
</div>
<div v-else-if="formData.targetType=='address'">
<el-form-item label="地点编号">
<el-input v-model="formData.code"></el-input>
</el-form-item>
<el-form-item label="地点名称">
<el-input v-model="formData.name"></el-input>
</el-form-item>
</div>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible=false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</span>
</el-dialog>
<!-- 编辑dialog -->
<el-dialog
title="修改"
:visible.sync="editVisible"
width="450px">
<div>
<el-form label-position="left" label-width="120px" :model="editForm">
<div v-if="editForm.targetType=='org'">
<el-form-item label="组织编号">
<el-input v-model="editForm.code" disabled></el-input>
</el-form-item>
<el-form-item label="组织名称">
<el-input v-model="editForm.name"></el-input>
</el-form-item>
</div>
<div v-else-if="editForm.targetType=='address'">
<el-form-item label="地点编号">
<el-input v-model="editForm.code" disabled></el-input>
</el-form-item>
<el-form-item label="地点名称">
<el-input v-model="editForm.name"></el-input>
</el-form-item>
</div>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="editVisible=false">取 消</el-button>
<el-button type="primary" @click="editFinish">确 定</el-button>
</span>
</el-dialog>
<addCamera ref="addCamera"></addCamera>
</div> </div>
</template> </template>
<script> <script>
import addCamera from './cameraDialog'
export default{ export default{
data(){ data(){
return{ return{
data: [{ formData:{
id: 1, targetType:'org'
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}, },
editForm:{
targetType:'',
name:'',
code:''
},
addVideoParam:{
},
treeData: [
{
unid: '0',
org_pid: '0',
org_name: '手动添加相机资源',
org_type: 'root',
childs: []
}
],
currentNodeId:'',
defaultProps:{
children: "childs",
disabled: "disabled",
label: "org_name"
},
addVisible:false,
editVisible:false,
targetOpt:[],
} }
}, },
components:{
addCamera
},
props:{ props:{
filterText:{ filterText:{
type:String, type:String,
default:false default:''
},
treeDatas:{
type:Array,
defalut:[]
}, },
}, },
watch:{ watch:{
filterText(val) { filterText(val) {
this.$refs.tree.filter(val); this.$refs.tree.filter(val);
},
treeDatas(val){
this.treeData[0].childs=val;
} }
}, },
methods:{ methods:{
nodeAdd(node,data){ handleNodeClick(data){
console.log(node,data) this.$parent.$parent.getTable(data,'camera')
},
nodeDelClick(node,data){
this.$confirm('此操作将永久删除该选项, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let cate_unid = this.getCustomCate('组织', 'residence');
this.$api.resource.getCode({
limit:9999
},cate_unid).then(res=>{
let editObj=[];
editObj=res.list_data.filter(item => item.code==data.org_code);
this.$api.resource.delCode({},cate_unid,editObj[0].unid).then(res=>{
})
this.$api.resource.delOrg({},data.unid).then(res=>{
if(!res.enote){
this.$message({
type: 'success',
message: '删除成功!'
});
this.$parent.$parent.getCameraTree();
}
})
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
nodeEditClick(node,data){
this.editForm.targetType=data.org_type;
this.editForm.code=data.org_code;
this.editForm.name=data.org_name;
this.editVisible=true;
},
editFinish(){
let cate_unid = this.getCustomCate('组织', 'residence');
this.$api.resource.getCode({
limit:9999
},cate_unid).then(res=>{
let editObj=[];
editObj=res.list_data.filter(item => item.code==this.editForm.code);
this.$api.resource.editCamera({
name:this.editForm.name,
code:this.editForm.code
},cate_unid,editObj[0].unid).then(data=>{
if(res.ecode) {
this.$message({
type: 'error',
message: res.enote
})
} else {
this.editVisible=false;
this.$parent.$parent.getCameraTree();
}
})
})
},
nodeAddClick(node,data){
if(data.org_type == 'address'){
//添加视频
this.$refs.addCamera.initDialog(node,'add',this.devsId)
}else{
//添加组织关系
this.currentNodeId=data.unid;
this.formData={
targetType:'org',
name:'',
code:''
}
if(data.org_type === "root") {
this.targetOpt = [{
label: '组织',
value: 'org'
}];
} else if(data.org_type === "org") {
this.targetOpt = [{
label: '组织',
value: 'org'
},{
label: '地点',
value: 'address'
}];
} else {
this.targetOpt = [{
label: '地点',
value: 'address'
}];
}
this.addVisible=true;
}
},
getCustomCate(name, cate) {
let localKey = name + '-' + cate;
return window.localStorage.getItem(localKey);
},
save(){
let cate_unid = this.getCustomCate('组织', 'residence');
// console.log('添加节点分类unid:', cate_unid);
if(cate_unid) {
this.$api.resource.addCode({
code: this.formData.code,
name: this.formData.name
},cate_unid).then(res=>{
if(res.ecode) {
this.$message({
type: 'error',
message: res.enote
})
} else {
this.orgServ(); // org service
}
})
}
},
orgServ() {
this.$api.resource.addNode({
org_pid: this.currentNodeId,
org_type: this.formData.targetType,
org_code: this.formData.code,
is_leaf: false
}).then(res=>{
if(res.ecode) {
this.$message({
type: 'error',
message: res.enote
})
} else {
this.$message({
type: 'success',
message: '添加成功!'
})
this.addVisible = false;
this.$parent.$parent.getCameraTree();
}
})
}, },
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data.label.indexOf(value) !== -1; return data.org_name.indexOf(value) !== -1;
}, },
} }
} }
......
<template>
<div>
<el-tree
class="filter-tree"
:data="treeData"
:props='defaultProps'
default-expand-all
@node-click="handleNodeClick"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>
<span class="tree-label">{{ data.vchan_name=="" ? '未命名' : data.vchan_name}}</span>
</span>
<span class="tree-btn" v-if="data.org_type">
<i class="el-icon-plus" @click.stop="nodeAddClick(node,data)"></i>
</span>
</span>
</el-tree>
<el-dialog
title="添加"
:visible.sync="addVisible"
width="450px">
<div>
<el-form label-position="left" label-width="120px">
<el-form-item label="添加录像">
<el-upload
ref="upload"
action="uploadUrl"
:http-request="httpRequest"
multiple
:data="uploadData"
name="file"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<!-- <div slot="tip" class="el-upload__tip">只能上传视频文件</div> -->
</el-upload>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible=false">取 消</el-button>
<el-button type="primary" @click="save">上 传</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import baseUrl from '../../../api/baseUrl'
export default{
data(){
return{
uploadUrl: '',
file:[],
treeData: [
{
unid: '0',
org_pid: '0',
vchan_name: '手动添加录像资源',
org_type: 'root',
childs: []
}
],
uploadData:{
vchan_type:'vfile',
vchan_refid:new Date().getTime()
},
defaultProps:{
children: "childs",
disabled: "disabled",
label: "vchan_name"
},
addVisible:false,
}
},
components:{
},
props:{
filterText:{
type:String,
default:''
},
treeDatas:{
type:Array,
defalut:[]
},
devsId:{
type:String,
default:''
}
},
watch:{
filterText(val) {
this.$refs.tree.filter(val);
},
treeDatas(val){
this.treeData[0].childs=val;
},
devsId(val){
this.devsId=val;
}
},
methods:{
// 自定义的上传函数
httpRequest(param) {
this.file=[];
// 一般情况下是在这里创建FormData对象,但我们需要上传多个文件,为避免发送多次请求,因此在这里只进行文件的获取,param可以拿到文件上传的所有信息
this.file.push(param.file)
},
handleNodeClick(data){
this.$parent.$parent.getVideoTable(data,'video')
},
nodeAddClick(node,data){
this.addVisible=true;
},
save(){
this.$refs.upload.submit(); // 这里是执行文件上传的函数,其实也就是获取我们要上传的文件
// 最重要的就是这段代码
var upData = new FormData() // 首先创建FormData对象
this.file.forEach(function (file) {
upData.append('file', file); // 因为要上传多个文件,所以需要遍历一下才行
upData.append('name', file.name);
upData.append('vchan_type', 'vfile');
upData.append('vchan_refid', '11111111');
})
console.log(upData.getAll('file'))
// this.axios.post('http://192.168.9.133:20080/api/v1/devconf_fx/devs/'+this.devsId+'/vfile_vchans', upData, {
// headers: {
// 'Content-Type': 'multipart/form-data',
// },
// }).then(res => {
// console.log(res);
// }).catch(err => {
// console.log(err);
// });
this.$api.resource.uploadFile(upData,this.devsId).then(res=>{
console.log(res)
})
},
filterNode(value, data) {
if (!value) return true;
return data.org_name.indexOf(value) !== -1;
},
}
}
</script>
<style>
</style>
...@@ -7,8 +7,14 @@ ...@@ -7,8 +7,14 @@
<!-- <eventList></eventList> --> <!-- <eventList></eventList> -->
<devInfo></devInfo> <devInfo></devInfo>
</div> </div>
<!-- <div class="video-box"> <div class="video-box" v-show="ocxstatus">
</div> --> <div class="video-box-close" @click="closeocx"></div>
<!-- <mPlayvideo :playersrc="playurl"></mPlayvideo> -->
<!-- <videoPlay ref="mapvideo1" :playurl="playurl"></videoPlay> -->
<videoPlay2 ref="mapvideo2" :playurl="playurl2"></videoPlay2>
<!-- <videoPlay ref="mapvideo" :playurl="playurl"></videoPlay> -->
</div>
</div> </div>
<div style="clear: both;"></div> <div style="clear: both;"></div>
</el-col> </el-col>
...@@ -98,6 +104,9 @@ ...@@ -98,6 +104,9 @@
</template> </template>
<script> <script>
// import mPlayvideo from "../public/mapvideo"
// import videoPlay from "../public/mapvideo";
import videoPlay2 from "../public/mapvideo2";
import showmap from "./map"; import showmap from "./map";
import illegaltrend from "./illegaltrend"; import illegaltrend from "./illegaltrend";
import eventTypedis from "./eventTypedis"; import eventTypedis from "./eventTypedis";
...@@ -113,9 +122,11 @@ export default { ...@@ -113,9 +122,11 @@ export default {
keyVehicleData: [], keyVehicleData: [],
illageList: [], illageList: [],
setShow: false, setShow: false,
ocxstatus:true,
archiveUnid: 0, archiveUnid: 0,
snap_num: 0, snap_num: 0,
playurl: "", playurl: {},
playurl2:"",
audit_num: 0, audit_num: 0,
snapData: { snapData: {
illega_total_snap_num: 0, illega_total_snap_num: 0,
...@@ -127,18 +138,38 @@ export default { ...@@ -127,18 +138,38 @@ export default {
}, },
components: { components: {
showmap, showmap,
// mPlayvideo,
// videoPlay,
videoPlay2,
illegaltrend, illegaltrend,
eventTypedis, eventTypedis,
alarmEvent, alarmEvent,
devInfo, devInfo,
eventList eventList
}, },
mounted() {}, mounted() {
// let urlarr = ["rtsp://192.168.9.133:8554//opt/data/vedio/1579253441478.264","tsp://192.168.9.133:8554//opt/data/vedio/1577516797543.264"]
// urlarr.forEach((ele) => {
// let obj = {}
// obj.rtsp_url =ele;
// setTimeout(()=>{
// let obj = {}
// obj.rtsp_url = ele
// this.playurl = obj
// this.$refs.mapvideo.videoPlay();
// },100)
// })
},
methods: { methods: {
alarmevent(data) { alarmevent(data) {
//移动地图 //移动地图
this.$refs.map.movemap(data); this.$refs.map.movemap(data);
}, },
closeocx(){
this.ocxstatus=false;
},
getTrafficSnap() { getTrafficSnap() {
this.$api.show.getTrafficSnap().then(res => { this.$api.show.getTrafficSnap().then(res => {
this.snapData = res; this.snapData = res;
...@@ -378,10 +409,10 @@ export default { ...@@ -378,10 +409,10 @@ export default {
.video-box { .video-box {
position: absolute; position: absolute;
height: 46.5vh; height 48vh
width: 30vw; width 35vw
margin-bottom: 1vh; margin-bottom: 1vh;
background: #444444; background: #f0f0f0;
left: 0; left: 0;
right: 0; right: 0;
top: 0; top: 0;
...@@ -389,4 +420,20 @@ export default { ...@@ -389,4 +420,20 @@ export default {
margin: auto; margin: auto;
z-index: 1000; z-index: 1000;
} }
.video-box-close{
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.video-box-close:after {
height:20px;
width:20px;
content: "✖";
color:#444444;
}
.play-item{
width:200px;
height:200px;
}
</style> </style>
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
class="ol-popup-closer" class="ol-popup-closer"
@click="closepopup" @click="closepopup"
></a> ></a>
<div id="t-popup-content"></div> <div class="" id="t-popup-content">
</div>
</div> </div>
<div id="videopopup" class="ol-popup"> <div id="videopopup" class="ol-popup">
<a <a
...@@ -17,8 +18,8 @@ ...@@ -17,8 +18,8 @@
class="ol-popup-closer" class="ol-popup-closer"
@click="closevideopopup" @click="closevideopopup"
></a> ></a>
<div id=""> <div class="mapvideo">
<videoPlay ref="ocx" :playurl="playurl"></videoPlay> <videoPlay ref="mapvideo" :playurl="playurl"></videoPlay>
</div> </div>
</div> </div>
</div> </div>
...@@ -73,7 +74,8 @@ var overlay = ""; ...@@ -73,7 +74,8 @@ var overlay = "";
export default { export default {
data() { data() {
return { return {
devList: [] devList: [],
playurl:{}
}; };
}, },
components: { components: {
...@@ -292,23 +294,23 @@ export default { ...@@ -292,23 +294,23 @@ export default {
autoPan: true, autoPan: true,
position: pos, position: pos,
autoPanAnimation: { autoPanAnimation: {
duration: 500 duration: 50
} }
}); });
map.addOverlay(overlay); map.addOverlay(overlay);
let obj = {}; let obj = {};
if (data.vchan_name == "视频1") { if (data.vchan_name == "视频1") {
obj.rtsp_url = obj.rtsp_url =
"rtsp://192.168.9.133:20090/6af6f0f9a445463d8b07273fe538694d"; "rtsp://192.168.9.133:8554//opt/data/vedio/1579253441478.264";
} else if (data.vchan_name == "视频2") { } else if (data.vchan_name == "视频2") {
obj.rtsp_url = obj.rtsp_url =
"rtsp://192.168.9.133:20090/68504674201c4490bfe1a9d18c86b6ac"; "rtsp://192.168.9.133:8554//opt/data/vedio/1577516797543.264";
} }
this.playurl = obj; this.playurl = obj;
// this.$store.commit('setocxstate', 1)
setTimeout(() => { setTimeout(() => {
this.$refs.ocx.videoPlay(); this.$refs.mapvideo.videoPlay();
}, 0); }, 100);
//获取视频流 //获取视频流
// this.$api.device.getFxStream(this.dev_unid, data.vchan_refid).then(res => { // this.$api.device.getFxStream(this.dev_unid, data.vchan_refid).then(res => {
// debugger // debugger
...@@ -447,4 +449,8 @@ export default { ...@@ -447,4 +449,8 @@ export default {
color: red color: red
} }
} }
.mapvideo{
height 100%;
width 100%;
}
</style> </style>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!