@ -1,74 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 节点基类 |
|
||||
* |
|
||||
*/ |
|
||||
public class BaseNode<T> implements INode<T> { |
|
||||
|
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键ID |
|
||||
*/ |
|
||||
protected String channelId; |
|
||||
|
|
||||
/** |
|
||||
* 父节点ID |
|
||||
*/ |
|
||||
protected String parentId; |
|
||||
|
|
||||
/** |
|
||||
* 子孙节点 |
|
||||
*/ |
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
|
||||
protected List<T> children = new ArrayList<T>(); |
|
||||
|
|
||||
/** |
|
||||
* 是否有子孙节点 |
|
||||
*/ |
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
|
||||
private Boolean hasChildren; |
|
||||
|
|
||||
/** |
|
||||
* 是否有子孙节点 |
|
||||
* |
|
||||
* @return Boolean |
|
||||
*/ |
|
||||
@Override |
|
||||
public Boolean getHasChildren() { |
|
||||
if (children.size() > 0) { |
|
||||
return true; |
|
||||
} else { |
|
||||
return this.hasChildren; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public String getChannelId() { |
|
||||
return channelId; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public String getParentId() { |
|
||||
return parentId; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public List<T> getChildren() { |
|
||||
return children; |
|
||||
} |
|
||||
|
|
||||
public void setChildren(List<T> children) { |
|
||||
this.children = children; |
|
||||
} |
|
||||
|
|
||||
public void setHasChildren(Boolean hasChildren) { |
|
||||
this.hasChildren = hasChildren; |
|
||||
} |
|
||||
} |
|
@ -1,31 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 森林节点类 |
|
||||
* |
|
||||
*/ |
|
||||
public class ForestNode extends BaseNode<ForestNode> { |
|
||||
|
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 节点内容 |
|
||||
*/ |
|
||||
private Object content; |
|
||||
|
|
||||
public ForestNode(String id, String parentId, Object content) { |
|
||||
this.channelId = id; |
|
||||
this.parentId = parentId; |
|
||||
this.content = content; |
|
||||
} |
|
||||
|
|
||||
public Object getContent() { |
|
||||
return content; |
|
||||
} |
|
||||
|
|
||||
public void setContent(Object content) { |
|
||||
this.content = content; |
|
||||
} |
|
||||
} |
|
@ -1,68 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
import com.google.common.collect.ImmutableMap; |
|
||||
import com.google.common.collect.Maps; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
/** |
|
||||
* 森林管理类 |
|
||||
* |
|
||||
* @author smallchill |
|
||||
*/ |
|
||||
public class ForestNodeManager<T extends INode<T>> { |
|
||||
|
|
||||
/** |
|
||||
* 森林的所有节点 |
|
||||
*/ |
|
||||
private final ImmutableMap<String, T> nodeMap; |
|
||||
|
|
||||
/** |
|
||||
* 森林的父节点ID |
|
||||
*/ |
|
||||
private final Map<String, Object> parentIdMap = Maps.newHashMap(); |
|
||||
|
|
||||
public ForestNodeManager(List<T> nodes) { |
|
||||
nodeMap = Maps.uniqueIndex(nodes, INode::getChannelId); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 根据节点ID获取一个节点 |
|
||||
* |
|
||||
* @param id 节点ID |
|
||||
* @return 对应的节点对象 |
|
||||
*/ |
|
||||
public INode<T> getTreeNodeAt(String id) { |
|
||||
if (nodeMap.containsKey(id)) { |
|
||||
return nodeMap.get(id); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 增加父节点ID |
|
||||
* |
|
||||
* @param parentId 父节点ID |
|
||||
*/ |
|
||||
public void addParentId(String parentId) { |
|
||||
parentIdMap.put(parentId, ""); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取树的根节点(一个森林对应多颗树) |
|
||||
* |
|
||||
* @return 树的根节点集合 |
|
||||
*/ |
|
||||
public List<T> getRoot() { |
|
||||
List<T> roots = new ArrayList<>(); |
|
||||
nodeMap.forEach((key, node) -> { |
|
||||
if (node.getParentId() == null || parentIdMap.containsKey(node.getChannelId())) { |
|
||||
roots.add(node); |
|
||||
} |
|
||||
}); |
|
||||
return roots; |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -1,51 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
import com.genersoft.iot.vmp.utils.CollectionUtil; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 森林节点归并类 |
|
||||
* |
|
||||
*/ |
|
||||
public class ForestNodeMerger { |
|
||||
|
|
||||
/** |
|
||||
* 将节点数组归并为一个森林(多棵树)(填充节点的children域) |
|
||||
* 时间复杂度为O(n^2) |
|
||||
* |
|
||||
* @param items 节点域 |
|
||||
* @return 多棵树的根节点集合 |
|
||||
*/ |
|
||||
public static <T extends INode<T>> List<T> merge(List<T> items) { |
|
||||
ForestNodeManager<T> forestNodeManager = new ForestNodeManager<>(items); |
|
||||
items.forEach(forestNode -> { |
|
||||
if (forestNode.getParentId() != null) { |
|
||||
INode<T> node = forestNodeManager.getTreeNodeAt(forestNode.getParentId()); |
|
||||
if (node != null) { |
|
||||
node.getChildren().add(forestNode); |
|
||||
} else { |
|
||||
forestNodeManager.addParentId(forestNode.getChannelId()); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
return forestNodeManager.getRoot(); |
|
||||
} |
|
||||
|
|
||||
public static <T extends INode<T>> List<T> merge(List<T> items, String[] parentIds) { |
|
||||
ForestNodeManager<T> forestNodeManager = new ForestNodeManager<>(items); |
|
||||
items.forEach(forestNode -> { |
|
||||
if (forestNode.getParentId() != null) { |
|
||||
INode<T> node = forestNodeManager.getTreeNodeAt(forestNode.getParentId()); |
|
||||
if (CollectionUtil.contains(parentIds, forestNode.getChannelId())){ |
|
||||
forestNodeManager.addParentId(forestNode.getChannelId()); |
|
||||
} else { |
|
||||
if (node != null){ |
|
||||
node.getChildren().add(forestNode); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
return forestNodeManager.getRoot(); |
|
||||
} |
|
||||
} |
|
@ -1,42 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
import java.io.Serializable; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* 节点 |
|
||||
*/ |
|
||||
public interface INode<T> extends Serializable { |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
* |
|
||||
* @return String |
|
||||
*/ |
|
||||
String getChannelId(); |
|
||||
|
|
||||
/** |
|
||||
* 父主键 |
|
||||
* |
|
||||
* @return String |
|
||||
*/ |
|
||||
String getParentId(); |
|
||||
|
|
||||
/** |
|
||||
* 子孙节点 |
|
||||
* |
|
||||
* @return List<T> |
|
||||
*/ |
|
||||
List<T> getChildren(); |
|
||||
|
|
||||
/** |
|
||||
* 是否有子孙节点 |
|
||||
* |
|
||||
* @return Boolean |
|
||||
*/ |
|
||||
default Boolean getHasChildren() { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -1,42 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.utils.node; |
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 树型节点类 |
|
||||
* |
|
||||
*/ |
|
||||
public class TreeNode extends BaseNode<TreeNode> { |
|
||||
|
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
private String title; |
|
||||
|
|
||||
private String key; |
|
||||
|
|
||||
private String value; |
|
||||
|
|
||||
public String getTitle() { |
|
||||
return title; |
|
||||
} |
|
||||
|
|
||||
public void setTitle(String title) { |
|
||||
this.title = title; |
|
||||
} |
|
||||
|
|
||||
public String getKey() { |
|
||||
return key; |
|
||||
} |
|
||||
|
|
||||
public void setKey(String key) { |
|
||||
this.key = key; |
|
||||
} |
|
||||
|
|
||||
public String getValue() { |
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
public void setValue(String value) { |
|
||||
this.value = value; |
|
||||
} |
|
||||
} |
|
@ -1,121 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.vmanager.bean; |
|
||||
|
|
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
|
||||
import com.genersoft.iot.vmp.utils.node.INode; |
|
||||
import io.swagger.annotations.ApiModel; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
|
|
||||
@ApiModel(value = "DeviceChannelTree对象", description = "DeviceChannelTree对象") |
|
||||
public class DeviceChannelTree extends DeviceChannel implements INode<DeviceChannelTree> { |
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键ID |
|
||||
*/ |
|
||||
private int id; |
|
||||
|
|
||||
/** |
|
||||
* 父节点ID |
|
||||
*/ |
|
||||
private String parentId; |
|
||||
|
|
||||
private String parentName; |
|
||||
|
|
||||
private String title; |
|
||||
|
|
||||
private String key; |
|
||||
|
|
||||
private String value; |
|
||||
|
|
||||
/** |
|
||||
* 子孙节点 |
|
||||
*/ |
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
|
||||
private List<DeviceChannelTree> children; |
|
||||
|
|
||||
/** |
|
||||
* 是否有子孙节点 |
|
||||
*/ |
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
|
||||
private Boolean hasChildren; |
|
||||
|
|
||||
@Override |
|
||||
public List<DeviceChannelTree> getChildren() { |
|
||||
if (this.children == null) { |
|
||||
this.children = new ArrayList<>(); |
|
||||
} |
|
||||
return this.children; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean getHasChildren() { |
|
||||
if (children.size() > 0) { |
|
||||
return true; |
|
||||
} else { |
|
||||
return this.hasChildren; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public int getId() { |
|
||||
return id; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void setId(int id) { |
|
||||
this.id = id; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public String getParentId() { |
|
||||
return parentId; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void setParentId(String parentId) { |
|
||||
this.parentId = parentId; |
|
||||
} |
|
||||
|
|
||||
public String getParentName() { |
|
||||
return parentName; |
|
||||
} |
|
||||
|
|
||||
public void setParentName(String parentName) { |
|
||||
this.parentName = parentName; |
|
||||
} |
|
||||
|
|
||||
public String getTitle() { |
|
||||
return title; |
|
||||
} |
|
||||
|
|
||||
public void setTitle(String title) { |
|
||||
this.title = title; |
|
||||
} |
|
||||
|
|
||||
public String getKey() { |
|
||||
return key; |
|
||||
} |
|
||||
|
|
||||
public void setKey(String key) { |
|
||||
this.key = key; |
|
||||
} |
|
||||
|
|
||||
public String getValue() { |
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
public void setValue(String value) { |
|
||||
this.value = value; |
|
||||
} |
|
||||
|
|
||||
public void setChildren(List<DeviceChannelTree> children) { |
|
||||
this.children = children; |
|
||||
} |
|
||||
|
|
||||
public void setHasChildren(Boolean hasChildren) { |
|
||||
this.hasChildren = hasChildren; |
|
||||
} |
|
||||
} |
|
@ -1,56 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.vmanager.bean; |
|
||||
|
|
||||
import com.genersoft.iot.vmp.utils.node.TreeNode; |
|
||||
|
|
||||
public class DeviceChannelTreeNode extends TreeNode { |
|
||||
|
|
||||
private Integer status; |
|
||||
|
|
||||
private String deviceId; |
|
||||
|
|
||||
private String channelId; |
|
||||
|
|
||||
private Double lng; |
|
||||
|
|
||||
private Double lat; |
|
||||
|
|
||||
public Integer getStatus() { |
|
||||
return status; |
|
||||
} |
|
||||
|
|
||||
public void setStatus(Integer status) { |
|
||||
this.status = status; |
|
||||
} |
|
||||
|
|
||||
public String getDeviceId() { |
|
||||
return deviceId; |
|
||||
} |
|
||||
|
|
||||
public void setDeviceId(String deviceId) { |
|
||||
this.deviceId = deviceId; |
|
||||
} |
|
||||
|
|
||||
public String getChannelId() { |
|
||||
return channelId; |
|
||||
} |
|
||||
|
|
||||
public void setChannelId(String channelId) { |
|
||||
this.channelId = channelId; |
|
||||
} |
|
||||
|
|
||||
public Double getLng() { |
|
||||
return lng; |
|
||||
} |
|
||||
|
|
||||
public void setLng(Double lng) { |
|
||||
this.lng = lng; |
|
||||
} |
|
||||
|
|
||||
public Double getLat() { |
|
||||
return lat; |
|
||||
} |
|
||||
|
|
||||
public void setLat(Double lat) { |
|
||||
this.lat = lat; |
|
||||
} |
|
||||
} |
|
@ -1,19 +0,0 @@ |
|||||
import axios from 'axios'; |
|
||||
|
|
||||
export const tree = (deviceId) => { |
|
||||
return axios({ |
|
||||
url: `/api/device/query/${deviceId}/tree`, |
|
||||
method: 'get' |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
export const deviceList = (page, count) => { |
|
||||
return axios({ |
|
||||
method: 'get', |
|
||||
url:`/api/device/query/devices`, |
|
||||
params: { |
|
||||
page, |
|
||||
count |
|
||||
} |
|
||||
}) |
|
||||
} |
|
@ -1,70 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<el-tree :data="channelList" :props="props" @node-click="sendDevicePush"> |
|
||||
<span slot-scope="{ node }"> |
|
||||
<span v-if="node.isLeaf"> |
|
||||
<i class="el-icon-video-camera" :style="{color:node.disabled==1?'#67C23A':'#F56C6C'}"></i> |
|
||||
</span> |
|
||||
<span v-else> |
|
||||
<i class="el-icon-folder"></i> |
|
||||
</span> |
|
||||
<span> |
|
||||
{{ node.label }} |
|
||||
</span> |
|
||||
</span> |
|
||||
</el-tree> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script> |
|
||||
import ChannelTreeItem from "@/components/channelTreeItem" |
|
||||
import {tree} from '@/api/deviceApi' |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
ChannelTreeItem, |
|
||||
}, |
|
||||
props:{ |
|
||||
device: { |
|
||||
type: Object, |
|
||||
required: true |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading: false, |
|
||||
channelList: [], |
|
||||
props: { |
|
||||
label: 'title', |
|
||||
children: 'children', |
|
||||
isLeaf: 'hasChildren', |
|
||||
disabled: 'status' |
|
||||
}, |
|
||||
} |
|
||||
}, |
|
||||
computed: { |
|
||||
|
|
||||
}, |
|
||||
mounted() { |
|
||||
this.leafs = [] |
|
||||
this.getTree() |
|
||||
}, |
|
||||
methods: { |
|
||||
getTree() { |
|
||||
this.loading = true |
|
||||
var that = this |
|
||||
tree(this.device.deviceId).then(function (res) { |
|
||||
console.log(res.data.data); |
|
||||
that.channelList = res.data.data; |
|
||||
that.loading = false; |
|
||||
}).catch(function (error) { |
|
||||
console.log(error); |
|
||||
that.loading = false; |
|
||||
}); |
|
||||
}, |
|
||||
sendDevicePush(c) { |
|
||||
if(c.hasChildren) return |
|
||||
this.$emit('sendDevicePush',c) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
@ -1,74 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<!-- <div :index="item.key" v-for="(item,i) in list" :key="i+'-'"> |
|
||||
<el-submenu v-if="item.hasChildren"> |
|
||||
<template slot="title"> |
|
||||
<i class="el-icon-video-camera"></i> |
|
||||
<span slot="title">{{item.title || item.deviceId}}</span> |
|
||||
</template> |
|
||||
<channel-list :list="item.children" @sendDevicePush="sendDevicePush"></channel-list> |
|
||||
</el-submenu> |
|
||||
<el-menu-item v-else :index="item.key" @click="sendDevicePush(item)"> |
|
||||
<template slot="title" > |
|
||||
<i class="el-icon-switch-button" :style="{color:item.status==1?'#67C23A':'#F56C6C'}"></i> |
|
||||
<span slot="title">{{item.title}}</span> |
|
||||
</template> |
|
||||
</el-menu-item> |
|
||||
</div> --> |
|
||||
<div > |
|
||||
<template v-if="!item.hasChildren"> |
|
||||
<el-menu-item :index="item.key" @click="sendDevicePush(item)"> |
|
||||
<i class="el-icon-video-camera" :style="{color:item.status==1?'#67C23A':'#F56C6C'}"></i> |
|
||||
{{item.title}} |
|
||||
</el-menu-item> |
|
||||
</template> |
|
||||
|
|
||||
<el-submenu v-else :index="item.key"> |
|
||||
<template slot="title" > |
|
||||
<i class="el-icon-location-outline"></i> |
|
||||
{{item.title}} |
|
||||
</template> |
|
||||
|
|
||||
<template v-for="child in item.children"> |
|
||||
<channel-item |
|
||||
v-if="child.hasChildren" |
|
||||
:item="child" |
|
||||
:key="child.key" |
|
||||
@sendDevicePush="sendDevicePush"/> |
|
||||
<el-menu-item v-else :key="child.key" :index="child.key" @click="sendDevicePush(child)"> |
|
||||
<i class="el-icon-video-camera" :style="{color:child.status==1?'#67C23A':'#F56C6C'}"></i> |
|
||||
{{child.title}} |
|
||||
</el-menu-item> |
|
||||
</template> |
|
||||
</el-submenu> |
|
||||
</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script> |
|
||||
export default { |
|
||||
name:'ChannelItem', |
|
||||
props:{ |
|
||||
list:Array, |
|
||||
channelId: String, |
|
||||
item: { |
|
||||
type: Object, |
|
||||
required: true |
|
||||
} |
|
||||
}, |
|
||||
data () { |
|
||||
return { |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
watch: { |
|
||||
channelId(val) { |
|
||||
console.log(val); |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
sendDevicePush(c) { |
|
||||
this.$emit('sendDevicePush',c) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
@ -1,260 +1,353 @@ |
|||||
<template> |
<template> |
||||
<div id="devicePosition" style="height: 100%"> |
<div id="devicePosition" style="width: 100vw; height: 91vh;"> |
||||
<el-container style="height: 100%"> |
<el-container style="height: 91vh;" v-loading="isLoging"> |
||||
<el-header> |
<el-aside width="auto" style="background-color: #ffffff"> |
||||
<uiHeader></uiHeader> |
<DeviceTree ref="deviceTree" :clickEvent="clickEvent" :contextMenuEvent="contextmenuEventHandler" ></DeviceTree> |
||||
</el-header> |
</el-aside> |
||||
<el-container> |
<el-main style="height: 91vh; padding: 0"> |
||||
<el-aside width="250px" height="100%" style="background-color: #FFFFFF; margin: 0 0 20px 20px;"> |
<MapComponent ref="map"></MapComponent> |
||||
<div style=" padding-top: 10px"> |
</el-main> |
||||
<el-tree class="el-scrollbar" |
</el-container> |
||||
ref="tree" |
<div ref="infobox" v-if="channel != null " > |
||||
id="deviceTree" |
<div v-if="channel != null" class="infobox-content"> |
||||
empty-text="未知节点" |
<el-descriptions class="margin-top" :title="channel.name" :column="1" :colon="true" size="mini" :labelStyle="labelStyle" > |
||||
node-key="id" |
<el-descriptions-item label="生产厂商">{{channel.manufacture}}</el-descriptions-item> |
||||
:highlight-current="false" |
<el-descriptions-item label="型号">{{channel.model}}</el-descriptions-item> |
||||
:expand-on-click-node="false" |
<el-descriptions-item label="设备归属" >{{channel.owner}}</el-descriptions-item> |
||||
:props="props" |
<el-descriptions-item label="行政区域" >{{channel.civilCode}}</el-descriptions-item> |
||||
:load="loadNode" |
<el-descriptions-item label="安装地址" >{{channel.address == null?'未知': channel.address}}</el-descriptions-item> |
||||
@node-contextmenu="contextmenuEventHandler" |
<el-descriptions-item label="云台类型" >{{channel.ptztypeText}}</el-descriptions-item> |
||||
@node-click="nodeClickHandler" |
<el-descriptions-item label="经纬度" >{{channel.longitude}},{{channel.latitude}}</el-descriptions-item> |
||||
lazy> |
<el-descriptions-item label="状态"> |
||||
</el-tree> |
<el-tag size="small" v-if="channel.status === 1">在线</el-tag> |
||||
</div> |
<el-tag size="small" type="info" v-if="channel.status === 0">离线</el-tag> |
||||
|
</el-descriptions-item> |
||||
</el-aside> |
</el-descriptions> |
||||
<el-main> |
<div style="padding-top: 10px"> |
||||
<MapComponent></MapComponent> |
<el-button type="primary" size="small" title="播放" icon="el-icon-video-play" @click="play(channel)"></el-button> |
||||
</el-main> |
<el-button type="primary" size="small" title="编辑位置" icon="el-icon-edit" @click="edit(channel)"></el-button> |
||||
</el-container> |
<el-button type="primary" size="small" title="轨迹查询" icon="el-icon-map-location" @click="getTrace(channel)"></el-button> |
||||
</el-container> |
</div> |
||||
|
<span class="infobox-close el-icon-close" @click="closeInfoBox()"></span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<devicePlayer ref="devicePlayer" ></devicePlayer> |
||||
|
<queryTrace ref="queryTrace" ></queryTrace> |
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
import uiHeader from "./UiHeader.vue"; |
|
||||
import MapComponent from "./common/MapComponent.vue"; |
import MapComponent from "./common/MapComponent.vue"; |
||||
import DeviceService from "./service/DeviceService"; |
import DeviceService from "./service/DeviceService"; |
||||
|
import DeviceTree from "./common/DeviceTree"; |
||||
|
import channelMapInfobox from "./dialog/channelMapInfobox"; |
||||
|
import devicePlayer from './dialog/devicePlayer.vue' |
||||
|
import queryTrace from './dialog/queryTrace.vue' |
||||
|
|
||||
export default { |
export default { |
||||
name: "devicePosition", |
name: "devicePosition", |
||||
components: { |
components: { |
||||
MapComponent, |
MapComponent, |
||||
uiHeader, |
DeviceTree, |
||||
}, |
channelMapInfobox, |
||||
data() { |
devicePlayer, |
||||
return { |
queryTrace, |
||||
deviceService: new DeviceService(), |
}, |
||||
props: { |
data() { |
||||
label: 'name', |
return { |
||||
children: 'children', |
deviceService: new DeviceService(), |
||||
isLeaf: 'leaf' |
layer: null, |
||||
}, |
lineLayer: null, |
||||
}; |
channel: null, |
||||
}, |
infoBoxId: null, |
||||
created() { |
labelStyle: { |
||||
this.init(); |
width: "56px" |
||||
}, |
}, |
||||
destroyed() { |
isLoging: false, |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
if (this.$route.query.deviceId) { |
||||
|
console.log(this.$route.query.deviceId) |
||||
|
// this.$refs.deviceTree.openByDeivceId(this.$route.query.deivceId) |
||||
|
setTimeout(()=>{ // 延迟以等待地图加载完成 TODO 后续修改为通过是实际这;状态加回调完成 |
||||
|
this.deviceService.getAllChannel(false, this.$route.query.deviceId, this.channelsHandler) |
||||
|
}, 1000) |
||||
|
|
||||
}, |
} |
||||
methods: { |
}, |
||||
init(){ |
destroyed() { |
||||
|
|
||||
}, |
}, |
||||
loadNode: function(node, resolve){ |
methods: { |
||||
if (node.level === 0) { |
clickEvent: function (data) { |
||||
this.deviceService.getAllDeviceList((data)=>{ |
if (data.channelId && data.subCount == 0) { |
||||
console.log("all deivce") |
// 点击通道 |
||||
console.log(data) |
if (data.longitude * data.latitude === 0) { |
||||
if (data.length > 0) { |
this.$message.error('未获取到位置信息'); |
||||
let nodeList = [] |
} else { |
||||
for (let i = 0; i < data.length; i++) { |
if (this.layer != null) { |
||||
let node = { |
this.$refs.map.removeLayer(this.layer); |
||||
name: data[i].name || data[i].deviceId, |
} |
||||
id: data[i].deviceId, |
this.closeInfoBox() |
||||
online: data[i].online, |
this.layer = this.$refs.map.addLayer([{ |
||||
deviceId: data[i].deviceId, |
position: [data.longitude, data.latitude], |
||||
} |
image: { |
||||
nodeList.push(node); |
src: this.getImageByChannel(data), |
||||
|
anchor: [0.5, 1] |
||||
|
}, |
||||
|
data: data |
||||
|
}], this.featureClickEvent) |
||||
|
this.$refs.map.panTo([data.longitude, data.latitude], mapParam.maxZoom) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
contextmenuEventHandler: function (event, data) { |
||||
|
if (data.channelId && data.subCount == 0) { |
||||
|
// 点击通道 |
||||
|
this.$contextmenu({ |
||||
|
items: [ |
||||
|
{ |
||||
|
label: "播放", |
||||
|
icon: "el-icon-video-play", |
||||
|
disabled: false, |
||||
|
onClick: () => { |
||||
|
this.play(data); |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
label: "编辑位置", |
||||
|
icon: "el-icon-edit", |
||||
|
disabled: false, |
||||
|
onClick: () => { |
||||
|
this.edit(data) |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
label: "轨迹查询", |
||||
|
icon: "el-icon-map-location", |
||||
|
disabled: false, |
||||
|
onClick: () => { |
||||
|
this.getTrace(data) |
||||
} |
} |
||||
resolve(nodeList) |
|
||||
}else { |
|
||||
resolve([]) |
|
||||
} |
} |
||||
}, (error)=>{ |
], |
||||
|
event, // 鼠标事件信息 |
||||
|
customClass: "custom-class", // 自定义菜单 class |
||||
|
zIndex: 3000, // 菜单样式 z-index |
||||
|
}); |
||||
|
} else { |
||||
|
this.deviceOrSubChannelMenu(event, data) |
||||
|
} |
||||
|
|
||||
}) |
}, |
||||
} |
deviceOrSubChannelMenu: function (event, data) { |
||||
if (node.level === 1){ |
// 点击设备 |
||||
console.log(node) |
this.$contextmenu({ |
||||
this.deviceService.getAllCatalog(node.data.deviceId, (data)=>{ |
items: [ |
||||
console.log("all Catalog") |
{ |
||||
console.log(data) |
label: "定位", |
||||
if (data.length > 0) { |
icon: "el-icon-s-promotion", |
||||
let nodeList = [] |
disabled: false, |
||||
for (let i = 0; i < data.length; i++) { |
onClick: () => { |
||||
let node = { |
if (!data.channelId) { |
||||
name: data[i].name || data[i].channelId, |
this.deviceService.getAllChannel(false, data.deviceId, this.channelsHandler) |
||||
id: data[i].channelId, |
} |
||||
online: data[i].status === 1, |
if (data.channelId && data.subCount > 0) { |
||||
deviceId: data[i].deviceId, |
// 点击子目录 |
||||
channelId: data[i].channelId, |
this.deviceService.getAllSubChannel(false, data.deviceId, data.channelId, this.channelsHandler) |
||||
} |
|
||||
nodeList.push(node); |
|
||||
} |
} |
||||
resolve(nodeList) |
|
||||
}else { |
|
||||
resolve([]) |
|
||||
} |
} |
||||
}, (error)=>{ |
} |
||||
|
], |
||||
|
event, // 鼠标事件信息 |
||||
|
customClass: "custom-class", // 自定义菜单 class |
||||
|
zIndex: 3000, // 菜单样式 z-index |
||||
|
}); |
||||
|
|
||||
}) |
}, |
||||
|
channelsHandler: function (channels) { |
||||
|
console.log(2) |
||||
|
if (channels.length > 0) { |
||||
|
this.clean() |
||||
|
this.closeInfoBox() |
||||
|
let params = []; |
||||
|
for (let i = 0; i < channels.length; i++) { |
||||
|
if (channels[i].longitude * channels[i].latitude === 0) { |
||||
|
continue; |
||||
|
} |
||||
|
let item = { |
||||
|
position: [channels[i].longitude, channels[i].latitude], |
||||
|
image: { |
||||
|
src: this.getImageByChannel(channels[i]), |
||||
|
anchor: [0.5, 1] |
||||
|
}, |
||||
|
data: channels[i] |
||||
|
} |
||||
|
params.push(item); |
||||
} |
} |
||||
|
console.log(3) |
||||
|
|
||||
if (node.level > 1) { |
this.layer = this.$refs.map.addLayer(params, this.featureClickEvent) |
||||
console.log(node.data.channelId) |
console.log(4) |
||||
this.deviceService.getAllSubCatalog(node.data.deviceId, node.data.channelId, (data)=>{ |
if (params.length === 1) { |
||||
console.log("all Catalog") |
this.$refs.map.panTo([channels[0].longitude, channels[0].latitude], mapParam.maxZoom) |
||||
console.log(data) |
} else if (params.length > 1) { |
||||
if (data.length > 0) { |
this.$refs.map.fit(this.layer) |
||||
let nodeList = [] |
} else { |
||||
for (let i = 0; i < data.length; i++) { |
this.$message.error('未获取到位置信息'); |
||||
let node = { |
|
||||
name: data[i].name || data[i].channelId, |
|
||||
id: data[i].channelId, |
|
||||
online: data[i].status === 1, |
|
||||
deviceId: data[i].deviceId, |
|
||||
channelId: data[i].channelId, |
|
||||
} |
|
||||
nodeList.push(node); |
|
||||
} |
|
||||
resolve(nodeList) |
|
||||
}else { |
|
||||
resolve([]) |
|
||||
} |
|
||||
}, (error)=>{ |
|
||||
|
|
||||
}) |
|
||||
} |
} |
||||
}, |
} else { |
||||
contextmenuEventHandler: function (event,data,node,element){ |
this.$message.error('未获取到位置信息'); |
||||
if (node.data.type !== 0) { |
} |
||||
data.parentId = node.parent.data.id; |
}, |
||||
this.$contextmenu({ |
getImageByChannel: function (channel) { |
||||
items: [ |
let src = "static/images/gis/camera.png" |
||||
{ |
switch (channel.ptztype) { |
||||
label: "移除通道", |
case 1: |
||||
icon: "el-icon-delete", |
if (channel.status === 1) { |
||||
disabled: false, |
src = "static/images/gis/camera1.png" |
||||
onClick: () => { |
} else { |
||||
this.$axios({ |
src = "static/images/gis/camera1-offline.png" |
||||
method:"delete", |
} |
||||
url:"/api/platform/catalog/relation/del", |
break; |
||||
data: data |
case 2: |
||||
}).then((res)=>{ |
if (channel.status === 1) { |
||||
console.log("移除成功") |
src = "static/images/gis/camera2.png" |
||||
node.parent.loaded = false |
} else { |
||||
node.parent.expand(); |
src = "static/images/gis/camera2-offline.png" |
||||
}).catch(function (error) { |
} |
||||
console.log(error); |
break; |
||||
}); |
case 3: |
||||
} |
if (channel.status === 1) { |
||||
} |
src = "static/images/gis/camera3.png" |
||||
], |
} else { |
||||
event, // 鼠标事件信息 |
src = "static/images/gis/camera3-offline.png" |
||||
customClass: "custom-class", // 自定义菜单 class |
} |
||||
zIndex: 3000, // 菜单样式 z-index |
break; |
||||
}); |
default: |
||||
}else { |
if (channel.status === 1) { |
||||
this.$contextmenu({ |
src = "static/images/gis/camera.png" |
||||
items: [ |
} else { |
||||
{ |
src = "static/images/gis/camera-offline.png" |
||||
label: "刷新节点", |
} |
||||
icon: "el-icon-refresh", |
} |
||||
disabled: false, |
return src; |
||||
onClick: () => { |
}, |
||||
this.refreshCatalog(node); |
featureClickEvent: function (channels) { |
||||
} |
this.closeInfoBox() |
||||
}, |
if (channels.length > 0) { |
||||
{ |
this.channel = channels[0] |
||||
label: "新建节点", |
} |
||||
icon: "el-icon-plus", |
this.$nextTick(() => { |
||||
disabled: false, |
this.infoBoxId = this.$refs.map.openInfoBox([this.channel.longitude, this.channel.latitude], this.$refs.infobox, [0, -50]) |
||||
onClick: () => { |
}) |
||||
this.addCatalog(data.id, node); |
}, |
||||
} |
closeInfoBox: function () { |
||||
}, |
if (this.infoBoxId != null) { |
||||
{ |
this.$refs.map.closeInfoBox(this.infoBoxId) |
||||
label: "修改节点", |
} |
||||
icon: "el-icon-edit", |
}, |
||||
disabled: node.level === 1, |
play: function (channel) { |
||||
onClick: () => { |
|
||||
this.editCatalog(data, node); |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
label: "删除节点", |
|
||||
icon: "el-icon-delete", |
|
||||
disabled: node.level === 1, |
|
||||
divided: true, |
|
||||
onClick: () => { |
|
||||
this.$confirm('确定删除?', '提示', { |
|
||||
confirmButtonText: '确定', |
|
||||
cancelButtonText: '取消', |
|
||||
type: 'warning' |
|
||||
}).then(() => { |
|
||||
this.removeCatalog(data.id, node) |
|
||||
}).catch(() => { |
|
||||
|
|
||||
}); |
let deviceId = channel.deviceId; |
||||
} |
this.isLoging = true; |
||||
}, |
let channelId = channel.channelId; |
||||
{ |
console.log("通知设备推流1:" + deviceId + " : " + channelId); |
||||
label: "设为默认", |
let that = this; |
||||
icon: "el-icon-folder-checked", |
this.$axios({ |
||||
disabled: node.data.id === this.defaultCatalogIdSign, |
method: 'get', |
||||
onClick: () => { |
url: '/api/play/start/' + deviceId + '/' + channelId |
||||
this.setDefaultCatalog(data.id) |
}).then(function (res) { |
||||
}, |
that.isLoging = false; |
||||
}, |
if (res.data.code === 0) { |
||||
// { |
|
||||
// label: "导出", |
|
||||
// icon: "el-icon-download", |
|
||||
// disabled: false, |
|
||||
// children: [ |
|
||||
// { |
|
||||
// label: "导出到文件", |
|
||||
// onClick: () => { |
|
||||
// |
|
||||
// }, |
|
||||
// }, |
|
||||
// { |
|
||||
// label: "导出到其他平台", |
|
||||
// onClick: () => { |
|
||||
// |
|
||||
// }, |
|
||||
// } |
|
||||
// ] |
|
||||
// }, |
|
||||
|
|
||||
], |
that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { |
||||
event, // 鼠标事件信息 |
streamInfo: res.data.data, |
||||
customClass: "custom-class", // 自定义菜单 class |
hasAudio: channel.hasAudio |
||||
zIndex: 3000, // 菜单样式 z-index |
|
||||
}); |
}); |
||||
|
|
||||
|
} else { |
||||
|
that.$message.error(res.data.msg); |
||||
} |
} |
||||
|
}).catch(function (e) { |
||||
|
}); |
||||
|
}, |
||||
|
edit: function (data) { |
||||
|
this.$message.warning('暂不支持'); |
||||
|
}, |
||||
|
getTrace: function (data) { |
||||
|
// this.$message.warning('暂不支持'); |
||||
|
this.clean() |
||||
|
this.$refs.queryTrace.openDialog(data, (channelPositions) => { |
||||
|
console.log("getTrace") |
||||
|
console.log(channelPositions) |
||||
|
if (channelPositions.length === 0) { |
||||
|
this.$message.success('未查询到轨迹信息'); |
||||
|
} else { |
||||
|
let positions = []; |
||||
|
for (let i = 0; i < channelPositions.length; i++) { |
||||
|
if (channelPositions[i].cnLng * channelPositions[i].cnLat > 0) { |
||||
|
positions.push([channelPositions[i].cnLng, channelPositions[i].cnLat]) |
||||
|
} |
||||
|
|
||||
return false; |
} |
||||
}, |
if (positions.length === 0) { |
||||
nodeClickHandler: function (data, node, tree){ |
this.$message.success('未查询到轨迹信息'); |
||||
this.chooseId = data.id; |
return; |
||||
this.chooseName = data.name; |
} |
||||
if (this.catalogIdChange)this.catalogIdChange(this.chooseId, this.chooseName); |
this.lineLayer = this.$refs.map.addLineLayer(positions) |
||||
} |
this.$refs.map.fit(this.lineLayer) |
||||
|
} |
||||
|
}) |
||||
}, |
}, |
||||
|
clean: function (){ |
||||
|
if (this.lineLayer != null) { |
||||
|
this.$refs.map.removeLayer(this.lineLayer) |
||||
|
} |
||||
|
if (this.infoBoxId != null) { |
||||
|
this.$refs.map.closeInfoBox(this.infoBoxId) |
||||
|
} |
||||
|
if (this.layer != null) { |
||||
|
this.$refs.map.removeLayer(this.layer) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
}; |
}; |
||||
</script> |
</script> |
||||
|
|
||||
<style> |
<style> |
||||
|
.infobox-content{ |
||||
|
width: 260px; |
||||
|
background-color: #FFFFFF; |
||||
|
padding: 10px; |
||||
|
border-radius: 10px; |
||||
|
border: 1px solid #e2e2e2; |
||||
|
} |
||||
|
|
||||
|
.infobox-content::after { |
||||
|
position: absolute; |
||||
|
bottom: -11px; |
||||
|
left: 130px; |
||||
|
display: block; |
||||
|
content: ""; |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
background: url('~@static/images/arrow.png') no-repeat center; |
||||
|
} |
||||
|
.infobox-close { |
||||
|
position: absolute; |
||||
|
right: 1rem; |
||||
|
top: 1rem; |
||||
|
color: #000000; |
||||
|
cursor:pointer |
||||
|
} |
||||
|
.el-descriptions__title { |
||||
|
font-size: 1rem; |
||||
|
font-weight: 700; |
||||
|
padding: 20px 20px 0px 23px; |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
} |
||||
</style> |
</style> |
||||
|
@ -0,0 +1,65 @@ |
|||||
|
<template> |
||||
|
<div id="channelMapInfobox" style="display: none"> |
||||
|
<div > |
||||
|
<el-descriptions class="margin-top" title="channel.name" :column="4" direction="vertical"> |
||||
|
<el-descriptions-item label="生产厂商">{{channel.manufacture}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="型号">{{channel.model}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="设备归属" >{{channel.owner}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="行政区域" >{{channel.civilCode}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="安装地址" >{{channel.address}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="云台类型" >{{channel.ptztypeText}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="经纬度" >{{channel.longitude}},{{channel.latitude}}</el-descriptions-item> |
||||
|
<el-descriptions-item label="状态"> |
||||
|
<el-tag size="small" v-if="channel.status === 1">在线</el-tag> |
||||
|
<el-tag size="small" v-if="channel.status === 0">离线</el-tag> |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</div> |
||||
|
|
||||
|
<devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import devicePlayer from '../dialog/devicePlayer.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: "channelMapInfobox", |
||||
|
props: ['channel'], |
||||
|
computed: {devicePlayer}, |
||||
|
created() {}, |
||||
|
data() { |
||||
|
return { |
||||
|
showDialog: false, |
||||
|
isLoging: false |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
|
||||
|
play: function (){ |
||||
|
let deviceId = this.channel.deviceId; |
||||
|
this.isLoging = true; |
||||
|
let channelId = this.channel.channelId; |
||||
|
console.log("通知设备推流1:" + deviceId + " : " + channelId); |
||||
|
let that = this; |
||||
|
this.$axios({ |
||||
|
method: 'get', |
||||
|
url: '/api/play/start/' + deviceId + '/' + channelId |
||||
|
}).then(function (res) { |
||||
|
that.isLoging = false; |
||||
|
if (res.data.code === 0) { |
||||
|
that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { |
||||
|
streamInfo: res.data.data, |
||||
|
hasAudio: this.channel.hasAudio |
||||
|
}); |
||||
|
} else { |
||||
|
that.$message.error(res.data.msg); |
||||
|
} |
||||
|
}).catch(function (e) { |
||||
|
}); |
||||
|
}, |
||||
|
close: function () { |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
@ -0,0 +1,100 @@ |
|||||
|
<template> |
||||
|
<div id="queryTrace" > |
||||
|
<el-dialog |
||||
|
title="查询轨迹" |
||||
|
width="40%" |
||||
|
top="2rem" |
||||
|
:close-on-click-modal="false" |
||||
|
:visible.sync="showDialog" |
||||
|
:destroy-on-close="true" |
||||
|
@close="close()" |
||||
|
> |
||||
|
<div v-loading="isLoging"> |
||||
|
<el-date-picker v-model="searchFrom" type="datetime" placeholder="选择开始日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> |
||||
|
<el-date-picker v-model="searchTo" type="datetime" placeholder="选择结束日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> |
||||
|
<el-button icon="el-icon-search" size="mini" type="primary" @click="onSubmit">查询</el-button> |
||||
|
</div> |
||||
|
|
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import DeviceService from '../service/DeviceService' |
||||
|
|
||||
|
export default { |
||||
|
name: "deviceEdit", |
||||
|
props: [], |
||||
|
computed: {}, |
||||
|
created() {}, |
||||
|
data() { |
||||
|
return { |
||||
|
deviceService: new DeviceService(), |
||||
|
pickerOptions: { |
||||
|
shortcuts: [{ |
||||
|
text: '今天', |
||||
|
onClick(picker) { |
||||
|
picker.$emit('pick', new Date()); |
||||
|
} |
||||
|
}, { |
||||
|
text: '昨天', |
||||
|
onClick(picker) { |
||||
|
const date = new Date(); |
||||
|
date.setTime(date.getTime() - 3600 * 1000 * 24); |
||||
|
picker.$emit('pick', date); |
||||
|
} |
||||
|
}, { |
||||
|
text: '一周前', |
||||
|
onClick(picker) { |
||||
|
const date = new Date(); |
||||
|
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); |
||||
|
picker.$emit('pick', date); |
||||
|
} |
||||
|
}] |
||||
|
}, |
||||
|
searchFrom: null, |
||||
|
searchTo: null, |
||||
|
listChangeCallback: null, |
||||
|
showDialog: false, |
||||
|
isLoging: false, |
||||
|
channel: null, |
||||
|
callback: null, |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
openDialog: function (channel, callback) { |
||||
|
console.log(channel) |
||||
|
this.showDialog = true; |
||||
|
this.callback = callback; |
||||
|
this.channel = channel; |
||||
|
}, |
||||
|
|
||||
|
onSubmit: function () { |
||||
|
console.log("onSubmit"); |
||||
|
this.isLoging = true; |
||||
|
this.$axios.get(`/api/position/history/${this.channel.deviceId}/${this.channel.channelId}`, { |
||||
|
}).then((res)=> { |
||||
|
this.isLoging = false; |
||||
|
if (typeof this.callback == "function") { |
||||
|
if (res.data.code == 0) { |
||||
|
this.callback(res.data.data) |
||||
|
this.close() |
||||
|
}else { |
||||
|
this.$message.error(res.data.msg); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}).catch(function (error) { |
||||
|
this.isLoging = false; |
||||
|
console.error(error); |
||||
|
}) |
||||
|
}, |
||||
|
close: function () { |
||||
|
this.showDialog = false; |
||||
|
this.isLoging = false; |
||||
|
this.callback = null; |
||||
|
this.channel = null; |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 13 KiB |