Commit d76da1203619251f8778789f2891ec432ed90b54

Authored by 王鑫
1 parent 4bfd97b7

fix():修改历史记录位置,增加12宫格,修改历史记录搜索问题

web_src/config/index.js
@@ -11,14 +11,14 @@ module.exports = { @@ -11,14 +11,14 @@ module.exports = {
11 assetsPublicPath: "/", 11 assetsPublicPath: "/",
12 proxyTable: { 12 proxyTable: {
13 "/debug": { 13 "/debug": {
14 - target: "http://118.113.164.50:18989", 14 + target: "http://127.0.0.1:28080",
15 changeOrigin: true, 15 changeOrigin: true,
16 pathRewrite: { 16 pathRewrite: {
17 "^/debug": "/", 17 "^/debug": "/",
18 }, 18 },
19 }, 19 },
20 "/static/snap": { 20 "/static/snap": {
21 - target: "http://118.113.164.50:18989", 21 + target: "http://127.0.0.1:28080",
22 changeOrigin: true, 22 changeOrigin: true,
23 // pathRewrite: { 23 // pathRewrite: {
24 // '^/static/snap': '/static/snap' 24 // '^/static/snap': '/static/snap'
web_src/package.json
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 "axios": "^0.24.0", 17 "axios": "^0.24.0",
18 "core-js": "^2.6.5", 18 "core-js": "^2.6.5",
19 "echarts": "^4.9.0", 19 "echarts": "^4.9.0",
  20 + "el-tree-transfer": "^2.4.7",
20 "element-ui": "^2.15.6", 21 "element-ui": "^2.15.6",
21 "fingerprintjs2": "^2.1.2", 22 "fingerprintjs2": "^2.1.2",
22 "flv.js": "^1.6.2", 23 "flv.js": "^1.6.2",
web_src/src/components/DeviceList1078.vue
1 <template> 1 <template>
2 <div id="devicePosition" style="width:100vw; height: 91vh"> 2 <div id="devicePosition" style="width:100vw; height: 91vh">
3 -  
4 <el-container v-loading="loading" style="height: 91vh;" element-loading-text="拼命加载中"> 3 <el-container v-loading="loading" style="height: 91vh;" element-loading-text="拼命加载中">
5 <el-aside width="300px" style="background-color: #ffffff"> 4 <el-aside width="300px" style="background-color: #ffffff">
6 <div class="device-tree-main-box"> 5 <div class="device-tree-main-box">
7 <div id="DeviceTree" style="width: 100%;height: 100%; background-color: #FFFFFF; overflow: auto"> 6 <div id="DeviceTree" style="width: 100%;height: 100%; background-color: #FFFFFF; overflow: auto">
8 <el-container> 7 <el-container>
9 <el-header>设备列表</el-header> 8 <el-header>设备列表</el-header>
10 - <el-main style="background-color: #ffffff;">  
11 - <tree :nodes="nodes" @onClick="onClick" @onCheck="onCheck" @onExpand="onExpand" @onRightClick="treeRightMenuFun" @onCreated="handleCreated" :props="defaultProps"/>  
12 - </el-main>  
13 - </el-container>  
14 - </div> 9 + <el-main style="background-color: #ffffff;">
  10 + <tree :nodes="nodes" @onClick="onClick" @onCheck="onCheck" @onExpand="onExpand"
  11 + @onRightClick="treeRightMenuFun" @onCreated="handleCreated" :props="defaultProps"/>
  12 + </el-main>
  13 + </el-container>
  14 + </div>
15 </div> 15 </div>
16 </el-aside> 16 </el-aside>
17 <el-container> 17 <el-container>
18 -  
19 - <el-header height="5vh" style="text-align: left;font-size: 17px;line-height:5vh;width:90%">  
20 - 分屏:  
21 - <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spiltClickFun(1)"/>  
22 - <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spiltClickFun(4)"/>  
23 - <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spiltClickFun(9)"/>  
24 -  
25 - <button style="margin-left: 15px;" @click="openViewDIalog()">历史数据</button>  
26 - <button style="margin-left: 15px;" @click="OneClickPlayback()">一键播放车辆视频</button>  
27 - <button style="margin-left: 15px;" @click="closeSelectItem()">关闭选中画面流</button>  
28 - <button style="margin-left: 15px;" @click="closeSelectCarItem()">一键关闭选中车辆流</button>  
29 - </el-header>  
30 -  
31 - 18 + <el-header height="5vh" style="text-align: left;font-size: 17px;line-height:5vh;width:90%">
  19 +
  20 + <i class="el-icon-s-platform btn" :class="{active:spilt==1}" @click="spiltClickFun(1)"/>
  21 + <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spiltClickFun(4)"/>
  22 + <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spiltClickFun(9)"/>
  23 + <i class="el-icon-full-screen btn" :class="{active:spilt==12}" @click="spiltClickFun(12)"/>
  24 +
  25 + <el-button size="mini" style="margin-left: 15px;" @click="oneClickPlayback()">一键播放车辆视频</el-button>
  26 + <el-button size="mini" style="margin-left: 15px;" @click="closeSelectItem()">关闭选中画面流</el-button>
  27 + <el-button size="mini" style="margin-left: 15px;" @click="closeSelectCarItem()">一键关闭选中车辆流</el-button>
  28 + <el-button size="mini" style="margin-left: 15px;" @click="inspectionsDialog">视屏巡查</el-button>
  29 + </el-header>
  30 +
32 <el-main style="padding: 0;"> 31 <el-main style="padding: 0;">
33 - <div style="width: 99%;height: 85vh;display: flex;flex-wrap: wrap;background-color: #000;"> 32 + <div class="scroll-container" style="width: 100%;height: 85vh;display: flex;flex-wrap: wrap;background-color: #000;">
34 <div v-for="i in spilt" :key="i" class="play-box" 33 <div v-for="i in spilt" :key="i" class="play-box"
35 :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" 34 :style="liveStyle" :class="{redborder:playerIdx == (i-1)}"
36 @click="playerIdx = (i-1)"> 35 @click="playerIdx = (i-1)">
37 <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{ i }}</div> 36 <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{ i }}</div>
38 <player ref="player" v-else :videoUrl="videoUrl[i-1]" fluent autoplay @screenshot="shot" 37 <player ref="player" v-else :videoUrl="videoUrl[i-1]" fluent autoplay @screenshot="shot"
39 - @destroy="destroy"/> 38 + @destroy="destroy" style="width: 100%;"/>
40 </div> 39 </div>
41 </div> 40 </div>
42 </el-main> 41 </el-main>
@@ -45,100 +44,100 @@ @@ -45,100 +44,100 @@
45 44
46 <div id="carRMenu" class="rMenu"> 45 <div id="carRMenu" class="rMenu">
47 <ul> 46 <ul>
48 - <li id="m_add" @click="OneClickPlayback();">一键播放视频</li> 47 + <li id="m_add" @click="oneClickPlayback();">一键播放视频</li>
49 <li id="m_del" @click="closeSelectCarItem();">一键关闭选中车辆流</li> 48 <li id="m_del" @click="closeSelectCarItem();">一键关闭选中车辆流</li>
50 </ul> 49 </ul>
51 </div> 50 </div>
52 51
53 <div id="channelCarRMenu" class="rMenu"> 52 <div id="channelCarRMenu" class="rMenu">
54 <ul> 53 <ul>
55 - <li id="m_add" @click="OneClickPlayback();">一键播放视频</li> 54 + <li id="m_add" @click="oneClickPlayback();">一键播放视频</li>
56 <li id="m_del" @click="closeSelectCarItem();">一键关闭选中车辆流</li> 55 <li id="m_del" @click="closeSelectCarItem();">一键关闭选中车辆流</li>
57 - <li id="m_del" @click="openViewDIalog();">历史数据</li>  
58 </ul> 56 </ul>
59 </div> 57 </div>
60 58
61 -  
62 -  
63 - <el-dialog title="历史视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog"  
64 - v-if="showVideoDialog" width="800px" :close-delay="5000" :fullscreen="true" :show-close="false">  
65 - <el-container v-loading="loading" style="height: 88vh;" element-loading-text="拼命加载中">  
66 -  
67 - <div style="width:100%;display: flex;flex-direction: column;justify-content: space-between;">  
68 - <div style="width: 90%;text-align:left;margin-bottom:5px;margin-left: 25px;">  
69 - <el-date-picker size="smaill" v-model="startTime" type="datetime" style="width:220px" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间" />  
70 - <el-date-picker size="smaill" v-model="endTime" type="datetime" style="width:220px" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间" />  
71 -  
72 - <button @click="searchHitoryList()">搜索</button>  
73 - <button @click="downloadFunction()">下载播放视频</button>  
74 - <button @click="close()">关闭窗口</button>  
75 - </div>  
76 -  
77 - <div style="width: 100%;display:flex;flex-direction:row; justify-content:space-between;">  
78 - <div style="width:20%" v-html="historyPlayListHtml" @click="playHistoryItem">  
79 -  
80 - </div>  
81 - <div style="width: 78%;">  
82 - <div style="width: 95%;height: 80vh;display: flex;flex-wrap: wrap;background-color: #000;">  
83 - <div v-if="!videoUrl[0]" style="color: #ffffff;font-size: 30px;font-weight: bold;"></div>  
84 - <player ref="player" v-else :videoUrl="videoUrl[0]" fluent autoplay @screenshot="shot"  
85 - @destroy="destroy"/>  
86 - </div>  
87 - </div>  
88 - </div>  
89 - </div>  
90 - </el-container>  
91 - </el-dialog>  
92 - 59 + <el-dialog title="视屏巡查设置" width="600" append-to-body
  60 + :close-on-click-modal="false"
  61 + :visible.sync="showVideoDialog" >
  62 + <tree-transfer
  63 + style="text-align: left; display: inline-block"
  64 + :to_data="targetValue"
  65 + :filter="true"
  66 + :title="['源列表', '巡查列表']"
  67 + @change="handleChange"
  68 + :from_data="sourceValue">
  69 + </tree-transfer>
  70 + <div slot="footer" class="dialog-footer">
  71 + <el-button type="primary" @click="submitForm">确 定</el-button>
  72 + <el-button @click="cancel">取 消</el-button>
  73 + </div>
  74 + </el-dialog>
93 </div> 75 </div>
94 </template> 76 </template>
95 -  
96 <script> 77 <script>
97 import tree from "vue-giant-tree"; 78 import tree from "vue-giant-tree";
98 import uiHeader from "../layout/UiHeader.vue"; 79 import uiHeader from "../layout/UiHeader.vue";
99 -import player from './common/jessibuca.vue' 80 +import player from './common/jessibuca.vue';
100 import DeviceTree from './common/DeviceTree.vue' 81 import DeviceTree from './common/DeviceTree.vue'
101 -import { isEmpty } from "ol/extent";  
102 -  
103 - 82 +import treeTransfer from "el-tree-transfer";
104 export default { 83 export default {
105 name: "live", 84 name: "live",
106 components: { 85 components: {
107 - uiHeader, player, DeviceTree,tree 86 + uiHeader, player, DeviceTree, tree, treeTransfer
108 }, 87 },
109 data() { 88 data() {
110 return { 89 return {
  90 + //穿梭框数据-----------↓
  91 + //源列表数据
  92 + sourceValue: [],
  93 + //目标列表数据
  94 + targetValue: [],
  95 + //prop参数
  96 + treeProps:{
  97 + children: 'children',
  98 + label: 'label',
  99 + name: 'name'
  100 + },
  101 + //巡查按钮
  102 + patrolValue: false,
  103 + //巡查数据定时器
  104 + carInfoTimeout: '',
  105 + //巡查定时器
  106 + timer : '',
  107 + //上线车辆
  108 + onlineCar: new Map(),
  109 + //车载key集合
  110 + onlineCarKeys: [],
111 videoUrl: [''], 111 videoUrl: [''],
112 videoUrlHistory: "", 112 videoUrlHistory: "",
113 spilt: 1,//分屏 113 spilt: 1,//分屏
114 playerIdx: 0,//激活播放器 114 playerIdx: 0,//激活播放器
115 -  
116 updateLooper: 0, //数据刷新轮训标志 115 updateLooper: 0, //数据刷新轮训标志
117 count: 15, 116 count: 15,
118 - historyLoadingFlag:true, 117 + historyLoadingFlag: true,
119 total: 0, 118 total: 0,
120 - startTime:'',  
121 - endTime:'', 119 + startTime: '',
  120 + endTime: '',
122 //channel 121 //channel
123 loading: false, 122 loading: false,
124 device: null, 123 device: null,
125 - nodes:[],  
126 - carPlayTimer:null,  
127 - carTreeNode:null,  
128 - ztreeObj:null,  
129 - ztreeNode:null,  
130 - fullscreenLoading:true,  
131 - fullscreenLoadingStyle:'',  
132 - showVideoDialog:false,  
133 - historyPlayListHtml:'',  
134 - hisotoryPlayFlag:false,  
135 - downloadURL:null,  
136 - rightMenuId:null,  
137 - port:-1,  
138 - httpPort:-1,  
139 - stream:"",  
140 - sim:"",  
141 - channel:"", 124 + nodes: [],
  125 + carPlayTimer: null,
  126 + carTreeNode: null,
  127 + ztreeObj: null,
  128 + ztreeNode: null,
  129 + fullscreenLoading: true,
  130 + fullscreenLoadingStyle: '',
  131 + showVideoDialog: false,
  132 + historyPlayListHtml: '',
  133 + hisotoryPlayFlag: false,
  134 + downloadURL: null,
  135 + rightMenuId: null,
  136 + port: -1,
  137 + httpPort: -1,
  138 + stream: "",
  139 + sim: "",
  140 + channel: "",
142 setting: { 141 setting: {
143 callback: { 142 callback: {
144 beforeExpand: this.beforeExpand 143 beforeExpand: this.beforeExpand
@@ -157,23 +156,26 @@ export default { @@ -157,23 +156,26 @@ export default {
157 isLeaf: 'spread', 156 isLeaf: 'spread',
158 nameIsHTML: true, 157 nameIsHTML: true,
159 view: { 158 view: {
160 - nameIsHTML: true  
161 - }  
162 - } 159 + nameIsHTML: true
  160 + }
  161 + },
163 }; 162 };
164 }, 163 },
165 -  
166 mounted() { 164 mounted() {
167 let that = this; 165 let that = this;
168 - that.initTreeData(); 166 + that.initTreeData();
169 }, 167 },
170 created() { 168 created() {
171 - this.checkPlayByParam() 169 + this.checkPlayByParam();
  170 + },
  171 + beforeDestroy() {
  172 + if (!this.isEmpty(this.timer)) {
  173 + clearInterval(this.timer);
  174 + }
172 }, 175 },
173 -  
174 computed: { 176 computed: {
175 liveStyle() { 177 liveStyle() {
176 - let style = {width: '100%', height: '100%'} 178 + let style = {width: '99%', height: '99%'}
177 switch (this.spilt) { 179 switch (this.spilt) {
178 case 4: 180 case 4:
179 style = {width: '49%', height: '49%'} 181 style = {width: '49%', height: '49%'}
@@ -181,6 +183,9 @@ export default { @@ -181,6 +183,9 @@ export default {
181 case 9: 183 case 9:
182 style = {width: '32%', height: '32%'} 184 style = {width: '32%', height: '32%'}
183 break 185 break
  186 + case 12:
  187 + style = {width: '24.5%', height: '32%'}
  188 + break
184 } 189 }
185 this.$nextTick(() => { 190 this.$nextTick(() => {
186 for (let i = 0; i < this.spilt; i++) { 191 for (let i = 0; i < this.spilt; i++) {
@@ -206,24 +211,99 @@ export default { @@ -206,24 +211,99 @@ export default {
206 that.$refs['player' + i].resize() 211 that.$refs['player' + i].resize()
207 } 212 }
208 }) 213 })
209 -  
210 } 214 }
211 window.localStorage.setItem('split', newValue) 215 window.localStorage.setItem('split', newValue)
212 }, 216 },
213 '$route.fullPath': 'checkPlayByParam' 217 '$route.fullPath': 'checkPlayByParam'
214 }, 218 },
215 destroyed() { 219 destroyed() {
216 - this.sendIORequestStop(this.sim,this.channel); 220 + this.sendIORequestStop(this.sim, this.channel);
217 clearTimeout(this.updateLooper); 221 clearTimeout(this.updateLooper);
218 - if(!this.isEmpty(this.carPlayTimer)){  
219 - console.log("bbbbbbbbbbbbbbb");  
220 - 222 + if (!this.isEmpty(this.carPlayTimer)) {
221 clearTimeout(this.carPlayTimer); 223 clearTimeout(this.carPlayTimer);
222 } 224 }
223 }, 225 },
224 methods: { 226 methods: {
  227 + handleChange(value, direction, movedKeys) {
  228 + console.log(value, direction, movedKeys);
  229 + },
  230 + //查询车辆信息
  231 + getCarInfo(){
  232 + this.$axios({
  233 + method: 'get',
  234 + url: `/api/jt1078/query/car/tree/100`,
  235 + }).then((res) => {
  236 + if (res && res.data && res.data.data) {
  237 + if (res.data.data.code == 1) {
  238 + l
  239 +
  240 +
  241 +
  242 + this.carInfoTimeout = setTimeout(function () {
  243 + this.getCarInfo()
  244 + }, 15000);
  245 + } else if (res.data.data.message) {
  246 + this.$message.error(res.data.data.message);
  247 + }
  248 + } else {
  249 + this.$message.error("请求错误,请刷新再试");
  250 + }
  251 + })
  252 + },
  253 + inspectionsDialog(){
  254 + if (this.nodes.length < 1) {
  255 +
  256 + }
  257 + this.showVideoDialog = true
  258 + },
  259 +
  260 + //视频巡查按钮改变事件
  261 + videoPatrolChange(newValue) {
  262 + if (newValue) {
  263 + this.videoPatrolStart();
  264 + }else {
  265 + if (!this.isEmpty(this.timer)) {
  266 + //关闭巡查定时器
  267 + clearInterval(this.timer);
  268 + }
  269 + }
  270 + },
  271 + //开启巡查定时器
  272 + videoPatrolStart(itemData){
  273 + let onlineCarKeys = this.onlineCarKeys;
  274 + if (!onlineCarKeys || onlineCarKeys.length === 0 ) {
  275 + this.$message.error("没有在线设备")
  276 + return
  277 + }
  278 + let count = this.onlineCarKeys.length - 1;
  279 + setInterval(() => {
  280 + if (itemData){
  281 + this.sendDevicePush(itemData);
  282 + itemData = null
  283 + }else {
  284 + if (count == -1){
  285 + count = this.onlineCarKeys.length - 1
  286 + }
  287 + let onlineCarKey = onlineCarKeys[count];
  288 + let split = onlineCarKey.split("-");
  289 + let onlineCar = this.onlineCar.get(split[0])
  290 + let sim = onlineCar.sim
  291 + let data = {
  292 + channelId: split[1],
  293 + deviceId: sim,
  294 + sim: sim
  295 + }
  296 + this.sendDevicePush(data);
  297 + count --;
  298 + }
  299 + },30000)
  300 + },
  301 +
  302 +
  303 +
  304 +
  305 +
225 destroy(idx) { 306 destroy(idx) {
226 - console.log(idx);  
227 this.clear(idx.substring(idx.length - 1)) 307 this.clear(idx.substring(idx.length - 1))
228 }, 308 },
229 treeChannelClick(device, data, isCatalog) { 309 treeChannelClick(device, data, isCatalog) {
@@ -232,19 +312,22 @@ export default { @@ -232,19 +312,22 @@ export default {
232 this.$message.error('设备离线!不允许点播'); 312 this.$message.error('设备离线!不允许点播');
233 this.closeLoading(); 313 this.closeLoading();
234 return false; 314 return false;
235 - }else {  
236 - let pageObj = this;  
237 -  
238 - pageObj.sendDevicePush(data);  
239 - 315 + } else {
  316 + this.isSendDevicePush(data,this.patrolValue);
240 } 317 }
241 } 318 }
242 }, 319 },
243 contextMenuEvent: function (device, event, data, isCatalog) { 320 contextMenuEvent: function (device, event, data, isCatalog) {
244 - 321 + },
  322 + isSendDevicePush(itemData, patrolValue) {
  323 + if (patrolValue){
  324 + this.videoPatrolStart(itemData);
  325 + }else {
  326 + this.sendDevicePush(itemData);
  327 + }
245 }, 328 },
246 //通知设备上传媒体流 329 //通知设备上传媒体流
247 - sendDevicePush: function (itemData,fun) { 330 + sendDevicePush: function (itemData, fun) {
248 // if (itemData.status === 0) { 331 // if (itemData.status === 0) {
249 // this.$message.error('设备离线!'); 332 // this.$message.error('设备离线!');
250 // return 333 // return
@@ -253,35 +336,26 @@ export default { @@ -253,35 +336,26 @@ export default {
253 let deviceId = itemData.deviceId; 336 let deviceId = itemData.deviceId;
254 // this.isLoging = true; 337 // this.isLoging = true;
255 let channelId = itemData.channelId; 338 let channelId = itemData.channelId;
256 -  
257 - if(this.isEmpty(deviceId)){ 339 + if (this.isEmpty(deviceId)) {
258 this.$message.error("没有获取到sim卡,请检查设备是否接入"); 340 this.$message.error("没有获取到sim卡,请检查设备是否接入");
259 this.closeLoading(); 341 this.closeLoading();
260 - if(fun){  
261 - fun();  
262 - } 342 + if (fun) {fun();}
263 return; 343 return;
264 } 344 }
265 -  
266 -  
267 console.log("通知设备推流1:" + deviceId + " : " + channelId); 345 console.log("通知设备推流1:" + deviceId + " : " + channelId);
268 let idxTmp = this.playerIdx 346 let idxTmp = this.playerIdx
269 let that = this; 347 let that = this;
270 -  
271 this.$axios({ 348 this.$axios({
272 method: 'get', 349 method: 'get',
273 url: '/api/jt1078/query/send/request/io/' + deviceId + '/' + channelId 350 url: '/api/jt1078/query/send/request/io/' + deviceId + '/' + channelId
274 }).then(function (res) { 351 }).then(function (res) {
275 -  
276 - if (res.data.code === 0 && res.data.data && (res.data.data.code ==="1" || res.data.data.code==1) ) { 352 + if (res.data.code === 0 && res.data.data && (res.data.data.code === "1" || res.data.data.code == 1)) {
277 let videoUrl; 353 let videoUrl;
278 - that.port=res.data.data.port; 354 + that.port = res.data.data.port;
279 that.httpPort = res.data.data.httpPort; 355 that.httpPort = res.data.data.httpPort;
280 that.stream = res.data.data.stream; 356 that.stream = res.data.data.stream;
281 -  
282 console.log(res.data.data.data); 357 console.log(res.data.data.data);
283 -  
284 - if(!that.isEmpty(res.data.data.data)){ 358 + if (!that.isEmpty(res.data.data.data)) {
285 that.downloadURL = res.data.data.data.flv; 359 that.downloadURL = res.data.data.data.flv;
286 if (location.protocol === "https:") { 360 if (location.protocol === "https:") {
287 videoUrl = res.data.data.data.wss_flv; 361 videoUrl = res.data.data.data.wss_flv;
@@ -289,44 +363,29 @@ export default { @@ -289,44 +363,29 @@ export default {
289 videoUrl = res.data.data.data.ws_flv; 363 videoUrl = res.data.data.data.ws_flv;
290 } 364 }
291 console.log(videoUrl); 365 console.log(videoUrl);
292 -  
293 -  
294 itemData.playUrl = videoUrl; 366 itemData.playUrl = videoUrl;
295 that.setPlayUrl(videoUrl, idxTmp); 367 that.setPlayUrl(videoUrl, idxTmp);
296 } 368 }
297 -  
298 - }else {  
299 - if(!that.isEmpty(res.data.data) && !that.isEmpty( res.data.data.msg)){ 369 + } else {
  370 + if (!that.isEmpty(res.data.data) && !that.isEmpty(res.data.data.msg)) {
300 that.$message.error(res.data.data.msg); 371 that.$message.error(res.data.data.msg);
301 - }else{  
302 - 372 + } else {
303 that.$message.error(res.data.msg); 373 that.$message.error(res.data.msg);
304 } 374 }
305 -  
306 - }  
307 -  
308 - if(fun){  
309 -  
310 - fun();  
311 } 375 }
  376 + if (fun) {fun();}
312 }).catch(function (e) { 377 }).catch(function (e) {
313 - if(fun){  
314 - fun();  
315 - } 378 + if (fun) {fun();}
316 }).finally(() => { 379 }).finally(() => {
317 this.closeLoading(); 380 this.closeLoading();
318 }); 381 });
319 -  
320 -  
321 }, 382 },
322 setPlayUrl(url, idx) { 383 setPlayUrl(url, idx) {
323 -  
324 this.$set(this.videoUrl, idx, url) 384 this.$set(this.videoUrl, idx, url)
325 let _this = this 385 let _this = this
326 setTimeout(() => { 386 setTimeout(() => {
327 window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl)) 387 window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl))
328 }, 100) 388 }, 100)
329 -  
330 }, 389 },
331 checkPlayByParam() { 390 checkPlayByParam() {
332 let {deviceId, channelId} = this.$route.query 391 let {deviceId, channelId} = this.$route.query
@@ -371,362 +430,290 @@ export default { @@ -371,362 +430,290 @@ export default {
371 console.log(data); 430 console.log(data);
372 window.localStorage.setItem('playData', JSON.stringify(data)) 431 window.localStorage.setItem('playData', JSON.stringify(data))
373 }, 432 },
374 - initTreeData(){ 433 + initTreeData() {
375 this.showLoading(); 434 this.showLoading();
376 this.$axios({ 435 this.$axios({
377 - method: 'get',  
378 - url:`/api/jt1078/query/company/tree`, 436 + method: 'get',
  437 + url: `/api/jt1078/query/company/tree`,
379 }).then((res) => { 438 }).then((res) => {
380 - if(res && res.data && res.data.data){  
381 - if(res.data.data.code == 1){ 439 + if (res && res.data && res.data.data) {
  440 + if (res.data.data.code == 1) {
382 let data = res.data.data.result; 441 let data = res.data.data.result;
383 - this.initDate(this.nodes,data);  
384 - }else if(res.data.data.message){ 442 + this.initDate(this.nodes, data);
  443 + } else if (res.data.data.message) {
385 this.$message.error(res.data.data.message); 444 this.$message.error(res.data.data.message);
386 } 445 }
387 - }else{ 446 + } else {
388 this.$message.error("请求错误,请刷新再试"); 447 this.$message.error("请求错误,请刷新再试");
389 } 448 }
390 -  
391 this.closeLoading(); 449 this.closeLoading();
392 -  
393 -  
394 }); 450 });
395 - },  
396 -  
397 - initDate(nodes,datas){  
398 - if(nodes && datas){  
399 - let len = datas.length;  
400 - for (let i = 0; i < len; i++) {  
401 - if(null == datas[i].id || undefined == datas[i].id || "" == datas[i].id){  
402 - continue;  
403 - }  
404 -  
405 - let node = this.combationNodeValue(datas[i].name,datas[i].id,datas[i].type,true,datas[i].sim,datas[i].abnormalStatus)  
406 -  
407 - nodes.push(node);  
408 - if(datas[i].children){  
409 - node.children = [];  
410 - this.initDate(node.children,datas[i].children);  
411 - }  
412 - }  
413 - }  
414 - },  
415 - combationNodeValue(name,id,type,isParent,sim,abnormalStatus){  
416 - if(this.isEmpty(sim)){  
417 - sim = "";  
418 - }  
419 -  
420 - if(abnormalStatus >= 10 && abnormalStatus < 20){  
421 - name = "<view style='color:red'>" + name + "</view>";  
422 - }else if(abnormalStatus >= 20 && abnormalStatus < 30){  
423 - name = "<view style='color:#ccc'>" + name + "</view>";  
424 - }  
425 -  
426 - return {  
427 - name: name,  
428 - id: id,  
429 - abnormalStatus:abnormalStatus,  
430 - sim:sim,  
431 - type: type,  
432 - isParent: isParent,  
433 -  
434 - }  
435 - },  
436 - onClick(evt, treeId, treeNode) {  
437 - this.combationChildNode(treeNode);  
438 - },  
439 - onCheck(evt, treeId, treeNode) {  
440 -  
441 - },  
442 - beforeExpand(treeId, treeNode) {  
443 -  
444 - return true;  
445 - },  
446 - onExpand(evt, treeId, treeNode) {  
447 - this.combationChildNode(treeNode);  
448 - },  
449 - handleCreated(ztreeObj) {  
450 - this.ztreeObj = ztreeObj;  
451 - this.ztreeObj.setting.view.nameIsHTML=true;  
452 -  
453 - },  
454 -  
455 - combationChildNode(treeNo){  
456 - this.ztreeNode = treeNo;  
457 - if(treeNo.seachChild && (treeNo.seachChild == 'true')){  
458 - return;  
459 - }  
460 -  
461 - this.showLoading();  
462 -  
463 - if(treeNo.type == 401 || treeNo.type == '401'){  
464 - let device = new Object();  
465 - if(this.isEmpty(treeNo.online)){  
466 - treeNo.online = 1;  
467 - }  
468 - device.online = treeNo.online;  
469 -  
470 - if(this.spilt == 1){  
471 - this.videoUrl=[]  
472 - }  
473 -  
474 - this.closeLoading();  
475 -  
476 - let pageObj = this;  
477 -  
478 - if(!this.isEmpty(this.sim) && !this.channel && this.sim != treeNo.sim && this.channel != treeNo.id){  
479 - let data = new Object();  
480 - data.channelId =treeNo.id;  
481 - data.sim = treeNo.sim;  
482 - data.deviceId = treeNo.sim;  
483 - this.sim = treeNo.sim;  
484 - this.channel = treeNo.id;  
485 - console.log("stop");  
486 -  
487 - this.sendIORequestStop(data.sim,data.channelId,function(){  
488 -  
489 - let flag = pageObj.treeChannelClick(device,data,false);  
490 - if(false == flag){  
491 - treeNo.online = 0;  
492 - }  
493 - });  
494 - }else{  
495 - let data = new Object();  
496 - data.channelId =treeNo.id;  
497 - data.sim = treeNo.sim;  
498 - data.deviceId = treeNo.sim;  
499 - this.sim = treeNo.sim;  
500 - this.channel = treeNo.id;  
501 -  
502 - let flag = pageObj.treeChannelClick(device,data,false);  
503 - if(false == flag){  
504 - treeNo.online = 0;  
505 - }  
506 - }  
507 - }else if(treeNo.type ==301 || treeNo.type=='301'){  
508 - this.addChannel(treeNo);  
509 - this.carTreeNode = treeNo;  
510 - this.channel = null;  
511 - }else if(treeNo.type==2|| treeNo.type=='2') {  
512 - this.requestChildNode(treeNo);  
513 - this.sim = null;  
514 - this.channel = null;  
515 - this.carTreeNode = null;  
516 - }else{  
517 - this.carTreeNode = null;  
518 - this.sim = null;  
519 - this.channel = null;  
520 - this.closeLoading(); 451 + },
  452 + initDate(nodes, datas) {
  453 + if (nodes && datas) {
  454 + let len = datas.length;
  455 + for (let i = 0; i < len; i++) {
  456 + if (null == datas[i].id || undefined == datas[i].id || "" == datas[i].id) {
  457 + continue;
521 } 458 }
522 -  
523 - },  
524 - addChannel(treeNo){  
525 -  
526 -  
527 - let labels=['ADAS','DSM','路况','司机','整车前','中门','倒车','前门客流','后面客流'];  
528 - let children=[];  
529 - let len = labels.length;  
530 - let i = 0;  
531 -  
532 - let pageObj = this;  
533 - for(;i<len;i++){  
534 - console.log(treeNo.abnormalStatus+"==========================>"+i);  
535 -  
536 - let node = this.combationNodeValue(labels[i],i+1,401,false,treeNo.sim,treeNo.abnormalStatus);  
537 - node.sim = treeNo.sim;  
538 - node.zbh = treeNo.name;  
539 - node.id=i+1;  
540 - children.push(node); 459 + let node = this.combationNodeValue(datas[i].name, datas[i].id, datas[i].type, true, datas[i].sim, datas[i].abnormalStatus)
  460 + nodes.push(node);
  461 + if (datas[i].children) {
  462 + node.children = [];
  463 + this.initDate(node.children, datas[i].children);
541 } 464 }
542 - this.ztreeObj.addNodes(treeNo,0,children,true);  
543 - treeNo.seachChild='true'; 465 + }
  466 + }
  467 + },
  468 + combationNodeValue(name, id, type, isParent, sim, abnormalStatus) {
  469 + if (this.isEmpty(sim)) {
  470 + sim = "";
  471 + }
  472 + if (abnormalStatus >= 10 && abnormalStatus < 20) {
  473 + name = "<view style='color:red'>" + name + "</view>";
  474 + } else if (abnormalStatus >= 20 && abnormalStatus < 30) {
  475 + name = "<view style='color:#ccc'>" + name + "</view>";
  476 + }
  477 + return {
  478 + name: name,
  479 + id: id,
  480 + abnormalStatus: abnormalStatus,
  481 + sim: sim,
  482 + type: type,
  483 + isParent: isParent,
  484 + }
  485 + },
  486 + onClick(evt, treeId, treeNode) {
  487 + this.combationChildNode(treeNode);
  488 + },
  489 + onCheck(evt, treeId, treeNode) {
544 490
545 - pageObj.sim = treeNo.sim; 491 + },
  492 + beforeExpand(treeId, treeNode) {
546 493
547 - this.closeLoading();  
548 -  
549 - },  
550 - requestChildNode(treeNo){  
551 -  
552 - if(treeNo.spread==='false' || !treeNo.spread){  
553 - let id = treeNo.id;  
554 - let that = this;  
555 - this.$axios({  
556 - method: 'get',  
557 - url:`/api/jt1078/query/car/tree/`+id,  
558 - }).then((res) => {  
559 -  
560 - if(res && res.data && res.data.data){  
561 - if(res.data.data.code == 1){  
562 - let children =[];  
563 - this.initDate(children,res.data.data.result);  
564 -  
565 - this.ztreeObj.addNodes(treeNo,-1,children,true);  
566 - treeNo.seachChild='true';  
567 -  
568 - this.carPlayTimer = setTimeout(function(){  
569 - that.requestChildNode1();  
570 - },15000);  
571 -  
572 - }else if(res.data.data.message){  
573 - this.$message.error(res.data.data.message);  
574 - }  
575 - }else{  
576 - this.$message.error("请求错误,请刷新再试");  
577 - } 494 + return true;
  495 + },
  496 + onExpand(evt, treeId, treeNode) {
  497 + this.combationChildNode(treeNode);
  498 + },
  499 + handleCreated(ztreeObj) {
  500 + this.ztreeObj = ztreeObj;
  501 + this.ztreeObj.setting.view.nameIsHTML = true;
578 502
579 - this.closeLoading();  
580 - }) 503 + },
  504 + combationChildNode(treeNo) {
  505 + this.ztreeNode = treeNo;
  506 + if (treeNo.seachChild && (treeNo.seachChild == 'true')) {
  507 + return;
  508 + }
  509 + this.showLoading();
  510 + if (treeNo.type == 401 || treeNo.type == '401') {
  511 + let device = new Object();
  512 + if (this.isEmpty(treeNo.online)) {
  513 + treeNo.online = 1;
581 } 514 }
582 - },  
583 - requestChildNode1(treeNo){  
584 - let that = this;  
585 - this.$axios({  
586 - method: 'get',  
587 - url:`/api/jt1078/query/car/tree/`+100,  
588 - }).then((res) => {  
589 -  
590 - if(res && res.data && res.data.data){  
591 - if(res.data.data.code == 1){  
592 - this.refreshRequestRefresh(res.data.data.result);  
593 -  
594 - }else if(res.data.data.message){  
595 - this.$message.error(res.data.data.message);  
596 - }  
597 - }else{  
598 - this.$message.error("请求错误,请刷新再试"); 515 + device.online = treeNo.online;
  516 + if (this.spilt == 1) {
  517 + this.videoUrl = []
  518 + }
  519 + this.closeLoading();
  520 + let pageObj = this;
  521 + if (!this.isEmpty(this.sim) && !this.channel && this.sim != treeNo.sim && this.channel != treeNo.id) {
  522 + let data = new Object();
  523 + data.channelId = treeNo.id;
  524 + data.sim = treeNo.sim;
  525 + data.deviceId = treeNo.sim;
  526 + this.sim = treeNo.sim;
  527 + this.channel = treeNo.id;
  528 + console.log("stop");
  529 + this.sendIORequestStop(data.sim, data.channelId, function () {
  530 + let flag = pageObj.treeChannelClick(device, data, false);
  531 + if (false == flag) {
  532 + treeNo.online = 0;
599 } 533 }
600 - }) 534 + });
  535 + } else {
  536 + let data = new Object();
  537 + data.channelId = treeNo.id;
  538 + data.sim = treeNo.sim;
  539 + data.deviceId = treeNo.sim;
  540 + this.sim = treeNo.sim;
  541 + this.channel = treeNo.id;
  542 +
  543 + let flag = pageObj.treeChannelClick(device, data, false);
  544 + if (false == flag) {
  545 + treeNo.online = 0;
  546 + }
  547 + }
  548 + } else if (treeNo.type == 301 || treeNo.type == '301') {
  549 + this.addChannel(treeNo);
  550 + this.carTreeNode = treeNo;
  551 + this.channel = null;
  552 + } else if (treeNo.type == 2 || treeNo.type == '2') {
  553 + this.requestChildNode(treeNo);
  554 + this.sim = null;
  555 + this.channel = null;
  556 + this.carTreeNode = null;
  557 + } else {
  558 + this.carTreeNode = null;
  559 + this.sim = null;
  560 + this.channel = null;
  561 + this.closeLoading();
  562 + }
601 }, 563 },
602 -  
603 - refreshRequestRefresh(nodes){  
604 - if(nodes){  
605 - let length = nodes.length;  
606 - for(let i=0;i<length;i++){  
607 - let findNode = this.ztreeObj.getNodeByParam("id",nodes[i].id+"",null);  
608 - if(findNode){  
609 - findNode.name = nodes[i].name;  
610 - if(findNode.type==301 || findNode.type=='301'){  
611 - findNode.name = nodes[i].name;  
612 - }else{  
613 - findNode.name = nodes[i].name;  
614 - }  
615 - this.ztreeObj.updateNode(findNode);  
616 -  
617 - if(nodes[i].children){  
618 - this.refreshRequestRefresh(nodes[i].children);  
619 - } 564 + addChannel(treeNo) {
  565 + let labels = ['ADAS', 'DSM', '路况', '司机', '整车前', '中门', '倒车', '前门客流', '后面客流'];
  566 + let children = [];
  567 + let len = labels.length;
  568 + let i = 0;
  569 + let pageObj = this;
  570 + for (; i < len; i++) {
  571 + console.log(treeNo.abnormalStatus + "==========================>" + i);
  572 + let node = this.combationNodeValue(labels[i], i + 1, 401, false, treeNo.sim, treeNo.abnormalStatus);
  573 + node.sim = treeNo.sim;
  574 + node.zbh = treeNo.name;
  575 + node.id = i + 1;
  576 + children.push(node);
  577 + }
  578 + this.ztreeObj.addNodes(treeNo, 0, children, true);
  579 + treeNo.seachChild = 'true';
  580 + pageObj.sim = treeNo.sim;
  581 + this.closeLoading();
  582 + },
  583 + requestChildNode(treeNo) {
  584 + if (treeNo.spread === 'false' || !treeNo.spread) {
  585 + let id = treeNo.id;
  586 + this.$axios({
  587 + method: 'get',
  588 + url: `/api/jt1078/query/car/tree/` + id,
  589 + }).then((res) => {
  590 + if (res && res.data && res.data.data) {
  591 + if (res.data.data.code == 1) {
  592 + let children = [];
  593 + this.initDate(children, res.data.data.result);
  594 + this.ztreeObj.addNodes(treeNo, -1, children, true);
  595 + treeNo.seachChild = 'true';
  596 + this.carPlayTimer = setTimeout(function () {
  597 + this.requestChildNode1();
  598 + }, 15000);
  599 + } else if (res.data.data.message) {
  600 + this.$message.error(res.data.data.message);
620 } 601 }
621 -  
622 - 602 + } else {
  603 + this.$message.error("请求错误,请刷新再试");
623 } 604 }
624 - } 605 + this.closeLoading();
  606 + })
  607 + }
625 }, 608 },
626 - showLoading(){  
627 -  
628 -  
629 - this.loading = true;  
630 - this.fullscreenLoading = true;  
631 - // this.fullscreenLoadingStyle ='display:block';  
632 - },  
633 - closeLoading(){  
634 - this.loading = false;  
635 - //this.fullscreenLoadingStyle ='display:none';  
636 - this.fullscreenLoading = false;  
637 - console.log("已经关闭");  
638 -  
639 -  
640 - },  
641 - sendIORequestStop(sim,channel,fun){  
642 - if(this.isEmpty(sim) || this.isEmpty(channel)){  
643 - console.log("sim:"+sim+";channel:"+channel);  
644 - if(fun){  
645 - fun(); 609 + requestChildNode1() {
  610 + this.$axios({
  611 + method: 'get',
  612 + url: `/api/jt1078/query/car/tree/` + 100,
  613 + }).then((res) => {
  614 + if (res && res.data && res.data.data) {
  615 + if (res.data.data.code == 1) {
  616 + this.refreshRequestRefresh(res.data.data.result);
  617 + } else if (res.data.data.message) {
  618 + this.$message.error(res.data.data.message);
646 } 619 }
647 - return; 620 + } else {
  621 + this.$message.error("请求错误,请刷新再试");
648 } 622 }
649 -  
650 - this.videoUrl=[''];  
651 - this.$axios({  
652 - method: 'get',  
653 - url:`/api/jt1078/query/send/stop/io/`+sim+"/"+channel+"/"+this.stream+"/"+this.port+"/"+this.httpPort,  
654 - }).then((res) => {  
655 - console.log(res);  
656 - if(fun){  
657 - fun();  
658 - }  
659 - });  
660 - }, 623 + })
  624 + },
  625 + refreshRequestRefresh(nodes) {
  626 + if (nodes) {
  627 + let length = nodes.length;
  628 + for (let i = 0; i < length; i++) {
  629 + let findNode = this.ztreeObj.getNodeByParam("id", nodes[i].id + "", null);
  630 + if (findNode) {
  631 + findNode.name = nodes[i].name;
  632 + if (findNode.type == 301 || findNode.type == '301') {
  633 + findNode.name = nodes[i].name;
  634 + } else {
  635 + findNode.name = nodes[i].name;
  636 + }
  637 + this.ztreeObj.updateNode(findNode);
661 638
662 - sendIORequestStop1(sim,channel,fun){  
663 - if(this.isEmpty(sim) || this.isEmpty(channel)){  
664 - console.log("sim:"+sim+";channel:"+channel);  
665 - if(fun){  
666 - fun(); 639 + if (nodes[i].children) {
  640 + this.refreshRequestRefresh(nodes[i].children);
  641 + }
667 } 642 }
668 - return;  
669 } 643 }
670 -  
671 - this.videoUrl=[''];  
672 - this.$axios({  
673 - method: 'get',  
674 - url:`/api/jt1078/query/send/stop/io/`+sim+"/"+channel,  
675 - }).then((res) => {  
676 - console.log(res);  
677 - if(fun){  
678 - fun();  
679 - }  
680 - });  
681 - },  
682 -  
683 - isEmpty(val){  
684 - return null == val || undefined == val || "" == val;  
685 - },  
686 - openViewDIalog(){  
687 - if(this.isEmpty(this.carTreeNode)){  
688 - this.$message.error('请选择车辆');  
689 - return; 644 + }
  645 + },
  646 + showLoading() {
  647 + this.loading = true;
  648 + this.fullscreenLoading = true;
  649 + // this.fullscreenLoadingStyle ='display:block';
  650 + },
  651 + closeLoading() {
  652 + this.loading = false;
  653 + //this.fullscreenLoadingStyle ='display:none';
  654 + this.fullscreenLoading = false;
  655 + console.log("已经关闭");
  656 + },
  657 + sendIORequestStop(sim, channel, fun) {
  658 + if (this.isEmpty(sim) || this.isEmpty(channel)) {
  659 + console.log("sim:" + sim + ";channel:" + channel);
  660 + if (fun) {
  661 + fun();
690 } 662 }
691 - if(this.isEmpty(this.sim)){  
692 - this.$message.error('无法获取SIM卡信息,请检查设备');  
693 - return; 663 + return;
  664 + }
  665 + this.videoUrl = [''];
  666 + this.$axios({
  667 + method: 'get',
  668 + url: `/api/jt1078/query/send/stop/io/` + sim + "/" + channel + "/" + this.stream + "/" + this.port + "/" + this.httpPort,
  669 + }).then((res) => {
  670 + console.log(res);
  671 + if (fun) {
  672 + fun();
694 } 673 }
695 -  
696 - if(this.isEmpty(this.channel)){  
697 -  
698 - this.$message.error('请选择通道');  
699 - return; 674 + });
  675 + },
  676 + sendIORequestStop1(sim, channel, fun) {
  677 + if (this.isEmpty(sim) || this.isEmpty(channel)) {
  678 + console.log("sim:" + sim + ";channel:" + channel);
  679 + if (fun) {
  680 + fun();
700 } 681 }
701 - this.showLoading();  
702 - let pageObj =this;  
703 - this.videoUrl=[''];  
704 -  
705 -  
706 - pageObj.showVideoDialog = true;  
707 - pageObj.closeLoading();  
708 -  
709 -  
710 - },  
711 - close() {  
712 - let pageObj = this;  
713 - this.showLoading();  
714 - this.historyPlayListHtml =null;  
715 - this.startTime = null;  
716 - this.endTime = null;  
717 - if(this.hisotoryPlayFlag){  
718 - this.sendIORequestStop(this.sim,this.channel,function(){  
719 - pageObj.showVideoDialog = false;  
720 - pageObj.videoUrl=[''];  
721 - pageObj.closeLoading();  
722 - console.log("关闭弹窗");  
723 - });  
724 - }else{ 682 + return;
  683 + }
  684 + this.videoUrl = [''];
  685 + this.$axios({
  686 + method: 'get',
  687 + url: `/api/jt1078/query/send/stop/io/` + sim + "/" + channel,
  688 + }).then((res) => {
  689 + console.log(res);
  690 + if (fun) {
  691 + fun();
  692 + }
  693 + });
  694 + },
  695 + isEmpty(val) {
  696 + return null == val || undefined == val || "" == val;
  697 + },
  698 + close() {
  699 + let pageObj = this;
  700 + this.showLoading();
  701 + this.historyPlayListHtml = null;
  702 + this.startTime = null;
  703 + this.endTime = null;
  704 + if (this.hisotoryPlayFlag) {
  705 + this.sendIORequestStop(this.sim, this.channel, function () {
725 pageObj.showVideoDialog = false; 706 pageObj.showVideoDialog = false;
  707 + pageObj.videoUrl = [''];
726 pageObj.closeLoading(); 708 pageObj.closeLoading();
727 - }  
728 - },  
729 - searchHitoryList(){ 709 + console.log("关闭弹窗");
  710 + });
  711 + } else {
  712 + pageObj.showVideoDialog = false;
  713 + pageObj.closeLoading();
  714 + }
  715 + },
  716 + searchHitoryList(){
730 if(this.isEmpty(this.carTreeNode)){ 717 if(this.isEmpty(this.carTreeNode)){
731 this.$message.error('请选择车辆'); 718 this.$message.error('请选择车辆');
732 return; 719 return;
@@ -751,7 +738,7 @@ export default { @@ -751,7 +738,7 @@ export default {
751 this.$message.error('请选择结束时间'); 738 this.$message.error('请选择结束时间');
752 return; 739 return;
753 } 740 }
754 - 741 +
755 this.showLoading(); 742 this.showLoading();
756 743
757 let pageObj = this; 744 let pageObj = this;
@@ -759,8 +746,8 @@ export default { @@ -759,8 +746,8 @@ export default {
759 method: 'get', 746 method: 'get',
760 url: '/api/jt1078/query/history/list/' + this.sim + '/' + this.channel+"/"+this.startTime+"/"+this.endTime 747 url: '/api/jt1078/query/history/list/' + this.sim + '/' + this.channel+"/"+this.startTime+"/"+this.endTime
761 }).then(function (res) { 748 }).then(function (res) {
762 -  
763 - 749 +
  750 +
764 if(res &&res.data && res.data.data && res.data.data.obj && res.data.data.code==1 && res.data.data.obj.data && res.data.data.obj.data.items){ 751 if(res &&res.data && res.data.data && res.data.data.obj && res.data.data.code==1 && res.data.data.obj.data && res.data.data.obj.data.items){
765 let length = res.data.data.obj.data.items.length; 752 let length = res.data.data.obj.data.items.length;
766 let html = "<div class='historyListDiv'><ul>"; 753 let html = "<div class='historyListDiv'><ul>";
@@ -781,225 +768,190 @@ export default { @@ -781,225 +768,190 @@ export default {
781 } 768 }
782 }); 769 });
783 }, 770 },
784 - playHistoryItem(e){  
785 - if(this.isEmpty(this.carTreeNode)){  
786 - this.$message.error('请选择车辆');  
787 - return;  
788 - }  
789 - if(this.isEmpty(this.sim)){  
790 - this.$message.error('无法获取SIM卡信息,请检查设备');  
791 - return;  
792 - }  
793 - 771 + playHistoryItem(e){
  772 + if(this.isEmpty(this.carTreeNode)){
  773 + this.$message.error('请选择车辆');
  774 + return;
  775 + }
  776 + if(this.isEmpty(this.sim)){
  777 + this.$message.error('无法获取SIM卡信息,请检查设备');
  778 + return;
  779 + }
794 780
795 - if(this.isEmpty(this.channel)){  
796 - this.$message.error('请选择通道');  
797 - return;  
798 - }  
799 781
800 - if(this.isEmpty(this.startTime)){  
801 - this.$message.error('请选择开始时间');  
802 - return;  
803 - } 782 + if(this.isEmpty(this.channel)){
  783 + this.$message.error('请选择通道');
  784 + return;
  785 + }
804 786
805 - if(this.isEmpty(this.endTime)){  
806 - this.$message.error('请选择结束时间');  
807 - return;  
808 - } 787 + if(this.isEmpty(this.startTime)){
  788 + this.$message.error('请选择开始时间');
  789 + return;
  790 + }
809 791
810 - let pageObj = this;  
811 -  
812 -  
813 - this.videoUrl =[];  
814 -  
815 -  
816 - pageObj.$axios({  
817 - method: 'get',  
818 - url: '/api/jt1078/query/send/request/io/history/' + pageObj.sim + '/' + pageObj.channel+"/"+e.target.getAttribute('startTime')+"/"+e.target.getAttribute('endTime')+"/"+e.target.getAttribute('channelMapping')  
819 - }).then(function (res) {  
820 -  
821 -  
822 - if (res.data && res.data.data && res.data.data.data) {  
823 - let videoUrl1;  
824 - if (location.protocol === "https:") {  
825 - videoUrl1 = res.data.data.data.wss_flv;  
826 - } else {  
827 - videoUrl1 = res.data.data.data.ws_flv;  
828 - }  
829 - pageObj.downloadURL = res.data.data.data.flv;  
830 - pageObj.port=res.data.data.port;  
831 - pageObj.httpPort = res.data.data.httpPort;  
832 - pageObj.stream = res.data.data.stream;  
833 - pageObj.videoUrlHistory = videoUrl1;  
834 -  
835 - let itemData = new Object();  
836 - itemData.deviceId = pageObj.sim;  
837 - // this.isLoging = true;  
838 - itemData.channelId= pageObj.channel;  
839 - itemData.playUrl = videoUrl1;  
840 - console.log(pageObj.playerIdx);  
841 -  
842 - pageObj.setPlayUrl(videoUrl1, 0);  
843 - pageObj.hisotoryPlayFlag = true;  
844 - // pageObj.$nextTick(() => {  
845 - // pageObj.createdPlay();  
846 - // pageObj.closeLoading();  
847 - // })  
848 - } else if(res.data.data && res.data.data.msg){  
849 - pageObj.$message.error(res.data.data.msg);  
850 - } else if(res.data.msg){  
851 - pageObj.$message.error(res.data.msg);  
852 - }else if(res.msg){  
853 - pageObj.$message.error(res.msg);  
854 - }  
855 - pageObj.closeLoading();  
856 - });  
857 -  
858 - },  
859 - createdPlay() {  
860 - if (flvjs.isSupported()) {  
861 - // var videoDom = document.getElementById('myVideo')  
862 - console.log(this.videoUrlHistory);  
863 - let videoDom = this.$refs.myVideo  
864 - // 创建一个播放器实例  
865 - var player = flvjs.createPlayer({  
866 - type: 'flv', // 媒体类型,默认是 flv,  
867 - isLive: false, // 是否是直播流  
868 - url: this.videoUrlHistory // 流地址  
869 - }, {  
870 - // 其他的配置项可以根据项目实际情况参考 api 去配置  
871 - autoCleanupMinBackwardDuration: true, // 清除缓存 对 SourceBuffer 进行自动清理  
872 - })  
873 - player.attachMediaElement(videoDom)  
874 - player.load()  
875 - player.play()  
876 - this.player = player 792 + if(this.isEmpty(this.endTime)){
  793 + this.$message.error('请选择结束时间');
  794 + return;
877 } 795 }
878 - },  
879 - OneClickPlayback(){  
880 - console.log(this.carTreeNode);  
881 -  
882 - if(this.isEmpty(this.carTreeNode)){  
883 - this.$message.error('请选择车辆');  
884 - return;  
885 - }  
886 796
887 - if(this.isEmpty(this.carTreeNode.abnormalStatus)){  
888 - this.$message.error('请检查车辆状态');  
889 - return;  
890 - } 797 + let pageObj = this;
891 798
892 -  
893 - if(this.carTreeNode.abnormalStatus!=1){  
894 - this.$message.error('车辆设备离线,请检查设备');  
895 - return;  
896 - }  
897 - if(this.isEmpty(this.sim)){  
898 - this.$message.error('无法获取SIM卡信息,请检查设备');  
899 - return;  
900 - }  
901 799
902 - this.spilt = 9; 800 + this.videoUrl =[];
  801 +
903 802
904 - this.playOneAllChannel(0); 803 + pageObj.$axios({
  804 + method: 'get',
  805 + url: '/api/jt1078/query/send/request/io/history/' + pageObj.sim + '/' + pageObj.channel+"/"+e.target.getAttribute('startTime')+"/"+e.target.getAttribute('endTime')+"/"+e.target.getAttribute('channelMapping')
  806 + }).then(function (res) {
  807 +
  808 +
  809 + if (res.data && res.data.data && res.data.data.data) {
  810 + let videoUrl1;
  811 + if (location.protocol === "https:") {
  812 + videoUrl1 = res.data.data.data.wss_flv;
  813 + } else {
  814 + videoUrl1 = res.data.data.data.ws_flv;
  815 + }
  816 + pageObj.downloadURL = res.data.data.data.flv;
  817 + pageObj.port=res.data.data.port;
  818 + pageObj.httpPort = res.data.data.httpPort;
  819 + pageObj.stream = res.data.data.stream;
  820 + pageObj.videoUrlHistory = videoUrl1;
  821 +
  822 + let itemData = new Object();
  823 + itemData.deviceId = pageObj.sim;
  824 + // this.isLoging = true;
  825 + itemData.channelId= pageObj.channel;
  826 + itemData.playUrl = videoUrl1;
  827 + console.log(pageObj.playerIdx);
  828 +
  829 + pageObj.setPlayUrl(videoUrl1, 0);
  830 + pageObj.hisotoryPlayFlag = true;
  831 + // pageObj.$nextTick(() => {
  832 + // pageObj.createdPlay();
  833 + // pageObj.closeLoading();
  834 + // })
  835 + } else if(res.data.data && res.data.data.msg){
  836 + pageObj.$message.error(res.data.data.msg);
  837 + } else if(res.data.msg){
  838 + pageObj.$message.error(res.data.msg);
  839 + }else if(res.msg){
  840 + pageObj.$message.error(res.msg);
  841 + }
  842 + pageObj.closeLoading();
  843 + });
  844 +
  845 + },
  846 + oneClickPlayback() {
  847 + if (this.isEmpty(this.carTreeNode)) {
  848 + this.$message.error('请选择车辆');
  849 + return;
  850 + }
  851 + if (this.isEmpty(this.carTreeNode.abnormalStatus)) {
  852 + this.$message.error('请检查车辆状态');
  853 + return;
  854 + }
  855 + if (this.carTreeNode.abnormalStatus != 1) {
  856 + this.$message.error('车辆设备离线,请检查设备');
  857 + return;
  858 + }
  859 + if (this.isEmpty(this.sim)) {
  860 + this.$message.error('无法获取SIM卡信息,请检查设备');
  861 + return;
  862 + }
  863 + this.spilt = 12;
  864 + this.playOneAllChannel(0);
905 }, 865 },
906 - playOneAllChannel(channel){  
907 - if(channel ==9){ 866 + playOneAllChannel(channel) {
  867 + if (channel == 9) {
908 return; 868 return;
909 } 869 }
910 let item = new Object(); 870 let item = new Object();
911 item.deviceId = this.sim; 871 item.deviceId = this.sim;
912 - item.channelId = 1+channel;  
913 - this.playerIdx=channel; 872 + item.channelId = 1 + channel;
  873 + this.playerIdx = channel;
914 let that = this; 874 let that = this;
915 - this.sendDevicePush(item,function(){  
916 - that.playOneAllChannel(1+channel); 875 + this.sendDevicePush(item, function () {
  876 + that.playOneAllChannel(1 + channel);
917 }); 877 });
918 }, 878 },
919 - spiltClickFun(val){  
920 - this.spilt = val;  
921 - if(val-1 < this.playerIdx){  
922 - this.playerIdx = val-1;  
923 - } 879 + spiltClickFun(val) {
  880 + this.spilt = val;
  881 + if (val - 1 < this.playerIdx) {
  882 + this.playerIdx = val - 1;
  883 + }
924 }, 884 },
925 downloadFunction(){ 885 downloadFunction(){
926 console.log(this.downloadURL); 886 console.log(this.downloadURL);
927 - 887 +
928 if(this.isEmpty(this.downloadURL)){ 888 if(this.isEmpty(this.downloadURL)){
929 - return; 889 + return;
930 } 890 }
931 - 891 +
932 window.open(this.downloadURL,"_download"); 892 window.open(this.downloadURL,"_download");
933 }, 893 },
934 - closeSelectItem(){  
935 - console.log("============================>"+this.playerIdx);  
936 - this.setPlayUrl(null,this.playerIdx) 894 +
  895 + closeSelectItem() {
  896 + console.log("============================>" + this.playerIdx);
  897 + this.setPlayUrl(null, this.playerIdx)
937 // this.videoUrl[this.playerIdx]=null; 898 // this.videoUrl[this.playerIdx]=null;
938 - // this.sendIORequestStop1(this.sim,this.playerIdx+1);  
939 - 899 + // this.sendIORequestStop1(this.sim,this.playerIdx+1);
940 }, 900 },
941 - closeSelectCarItem(){ 901 + closeSelectCarItem() {
942 for (let index = 0; index < 9; index++) { 902 for (let index = 0; index < 9; index++) {
943 - this.setPlayUrl(null,index)  
944 - // this.videoUrl[this.playerIdx]=null;  
945 - this.sendIORequestStop1(this.sim,index+1);  
946 - 903 + this.setPlayUrl(null, index)
  904 + // this.videoUrl[this.playerIdx]=null;
  905 + this.sendIORequestStop1(this.sim, index + 1);
947 } 906 }
948 -  
949 -  
950 }, 907 },
951 - treeRightMenuFun(event,treeId,treeNode){  
952 - if(treeNode.type == '301' || treeNode.type==301){  
953 - this.rightMenuId = "carRMenu";  
954 - this.showRMenu(event);  
955 - this.carTreeNode = treeNode;  
956 - this.sim = treeNode.sim;  
957 - this.channel = null;  
958 - }else if(treeNode.type == '401' || treeNode.type==401){  
959 - this.rightMenuId ="channelCarRMenu";  
960 - this.showRMenu(event);  
961 - this.channel = treeNode.id;  
962 - }else{ 908 + treeRightMenuFun(event, treeId, treeNode) {
  909 + if (treeNode.type == '301' || treeNode.type == 301) {
  910 + this.rightMenuId = "carRMenu";
  911 + this.showRMenu(event);
  912 + this.carTreeNode = treeNode;
  913 + this.sim = treeNode.sim;
  914 + this.channel = null;
  915 + } else if (treeNode.type == '401' || treeNode.type == 401) {
  916 + this.rightMenuId = "channelCarRMenu";
  917 + this.showRMenu(event);
  918 + this.channel = treeNode.id;
  919 + } else {
963 this.carTreeNode = null; 920 this.carTreeNode = null;
964 - this.sim = null; 921 + this.sim = null;
965 this.channel = null; 922 this.channel = null;
966 hidden(); 923 hidden();
967 } 924 }
968 }, 925 },
969 - showRMenu(event) {  
970 - if(this.isEmpty(this.rightMenuId)){  
971 - return ;  
972 - }  
973 - let carMenu = document.getElementById(this.rightMenuId);  
974 - carMenu.setAttribute("style","display:block");  
975 -  
976 - let x = event.clientX;  
977 - let y = event.clientY;  
978 - carMenu.setAttribute("style","display:block;top:"+y+"px;left:"+x+"px");  
979 - document.addEventListener("click", this.hideMenu);  
980 -  
981 - console.log(this.rightMenuId);  
982 - 926 + showRMenu(event) {
  927 + if (this.isEmpty(this.rightMenuId)) {
  928 + return;
  929 + }
  930 + let carMenu = document.getElementById(this.rightMenuId);
  931 + carMenu.setAttribute("style", "display:block");
  932 +
  933 + let x = event.clientX;
  934 + let y = event.clientY;
  935 + carMenu.setAttribute("style", "display:block;top:" + y + "px;left:" + x + "px");
  936 + document.addEventListener("click", this.hideMenu);
  937 + console.log(this.rightMenuId);
983 }, 938 },
984 - hideMenu() {  
985 - if(this.isEmpty(this.rightMenuId)){  
986 - return ;  
987 - } 939 + hideMenu() {
  940 + if (this.isEmpty(this.rightMenuId)) {
  941 + return;
  942 + }
988 let carMenu = document.getElementById(this.rightMenuId); 943 let carMenu = document.getElementById(this.rightMenuId);
989 - carMenu.setAttribute("style","display:none"); 944 + carMenu.setAttribute("style", "display:none");
990 this.rightMenuId = null; 945 this.rightMenuId = null;
991 } 946 }
992 -  
993 } 947 }
994 }; 948 };
995 -  
996 -  
997 </script> 949 </script>
998 -  
999 <style> 950 <style>
1000 -.device-tree-main-box{ 951 +.device-tree-main-box {
1001 text-align: left; 952 text-align: left;
1002 } 953 }
  954 +
1003 .btn { 955 .btn {
1004 margin: 0 10px; 956 margin: 0 10px;
1005 957
@@ -1025,51 +977,54 @@ export default { @@ -1025,51 +977,54 @@ export default {
1025 align-items: center; 977 align-items: center;
1026 justify-content: center; 978 justify-content: center;
1027 } 979 }
1028 -.historyListLi{  
1029 - width: 97%;  
1030 - white-space: nowrap; 980 +
  981 +.historyListLi {
  982 + width: 97%;
  983 + white-space: nowrap;
1031 text-overflow: ellipsis; 984 text-overflow: ellipsis;
1032 cursor: pointer; 985 cursor: pointer;
1033 padding: 3px; 986 padding: 3px;
1034 margin-bottom: 6px; 987 margin-bottom: 6px;
1035 border: 1px solid #000000; 988 border: 1px solid #000000;
1036 } 989 }
1037 -.historyListDiv{  
1038 - height:80vh;  
1039 - width:100%;  
1040 - overflow-y:auto;  
1041 - overflow-x:hidden; 990 +
  991 +.historyListDiv {
  992 + height: 80vh;
  993 + width: 100%;
  994 + overflow-y: auto;
  995 + overflow-x: hidden;
1042 } 996 }
1043 997
1044 998
1045 - /* 菜单的样式 */ 999 +/* 菜单的样式 */
1046 .rMenu { 1000 .rMenu {
1047 - position:absolute;  
1048 - top:0;  
1049 - display: none;  
1050 - margin: 0;  
1051 - padding: 0;  
1052 - text-align: left;  
1053 - border: 1px solid #BFBFBF;  
1054 - border-radius: 3px;  
1055 - background-color: #EEE;  
1056 - box-shadow: 0 0 10px #AAA; 1001 + position: absolute;
  1002 + top: 0;
  1003 + display: none;
  1004 + margin: 0;
  1005 + padding: 0;
  1006 + text-align: left;
  1007 + border: 1px solid #BFBFBF;
  1008 + border-radius: 3px;
  1009 + background-color: #EEE;
  1010 + box-shadow: 0 0 10px #AAA;
1057 } 1011 }
1058 1012
1059 .rMenu li { 1013 .rMenu li {
1060 - width: 170px;  
1061 - list-style: none outside none;  
1062 - cursor: default;  
1063 - color: #666;  
1064 - margin-left: -20px; 1014 + width: 170px;
  1015 + list-style: none outside none;
  1016 + cursor: default;
  1017 + color: #666;
  1018 + margin-left: -20px;
1065 } 1019 }
  1020 +
1066 .rMenu li:hover { 1021 .rMenu li:hover {
1067 - color: #EEE;  
1068 - background-color: #666; 1022 + color: #EEE;
  1023 + background-color: #666;
1069 } 1024 }
1070 1025
1071 li#menu-item-delete, li#menu-item-rename { 1026 li#menu-item-delete, li#menu-item-rename {
1072 - margin-top: 1px; 1027 + margin-top: 1px;
1073 } 1028 }
1074 </style> 1029 </style>
1075 <style> 1030 <style>
@@ -1145,4 +1100,14 @@ li#menu-item-delete, li#menu-item-rename { @@ -1145,4 +1100,14 @@ li#menu-item-delete, li#menu-item-rename {
1145 .baidumap > .anchorBL { 1100 .baidumap > .anchorBL {
1146 display: none !important; 1101 display: none !important;
1147 } 1102 }
1148 -</style>  
1149 \ No newline at end of file 1103 \ No newline at end of file
  1104 +
  1105 +.scroll-container {
  1106 + max-height: 85vh; /* 设置最大高度为85%的视口高度 */
  1107 + overflow-y: auto; /* 内容超出时显示垂直滚动条 */
  1108 + overflow-x: hidden; /* 隐藏水平滚动条 */
  1109 +}
  1110 +.transfer-footer {
  1111 + margin-left: 20px;
  1112 + padding: 6px 5px;
  1113 +}
  1114 +</style>
web_src/src/components/HistoricalRecord.vue 0 → 100644
  1 +<template>
  2 + <div style="width: 2000px">
  3 + <el-container v-loading="loading" style="height: 100%;width: 100%" element-loading-text="拼命加载中">
  4 + <div style="width:100%;display: flex;flex-direction: column;justify-content: space-between;">
  5 + <div class="block" style="width: 99%;text-align:left;margin-bottom:15px;">
  6 + <el-card class="box-card" style="width: 100%">
  7 + <car-tree v-model="sim_channel"/>
  8 + <el-date-picker
  9 + v-model="date"
  10 + align="right"
  11 + type="date"
  12 + placeholder="选择日期"
  13 + :picker-options="pickerOptions">
  14 + </el-date-picker>
  15 + <el-time-picker
  16 + is-range
  17 + v-model="timeList"
  18 + range-separator="至"
  19 + start-placeholder="开始时间"
  20 + end-placeholder="结束时间"
  21 + placeholder="选择时间范围">
  22 + </el-time-picker>
  23 + <el-button @click="searchHitoryList()">搜索</el-button>
  24 + <el-button @click="downloadFunction()">下载播放视频</el-button>
  25 + </el-card>
  26 + </div>
  27 +
  28 + <div style="width: 100%;display:flex;flex-direction:row; justify-content:space-between;">
  29 + <div style="width:20%;height: 80vh" >
  30 + <historical-data :history-data="historyData" @click="clickHistoricalPlay" />
  31 + </div>
  32 + <div style="width: 78%;">
  33 + <div style="width: 99%;height: 80vh;display: flex;flex-wrap: wrap;background-color: #000;">
  34 + <div v-if="!videoUrl[0]" style="color: #ffffff;font-size: 30px;font-weight: bold;"></div>
  35 + <player ref="player" v-else :videoUrl="videoUrl[0]" fluent autoplay @screenshot="shot"
  36 + @destroy="destroy" style="width: 100%;height: 100%;"/>
  37 + </div>
  38 + </div>
  39 + </div>
  40 + </div>
  41 + </el-container>
  42 + </div>
  43 +</template>
  44 +
  45 +<script>
  46 +//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等),
  47 +//例如:import 《组件名称》 from '《组件路径》,
  48 +import player from "./common/jessibuca.vue";
  49 +import CarTree from "./JT1078Components/cascader/CarTree.vue";
  50 +import {parseTime} from "../../utils/ruoyi";
  51 +import HistoricalData from "./JT1078Components/historical/HistoricalDataTree.vue";
  52 +
  53 +export default {
  54 + //import引入的组件需要注入到对象中才能使用"
  55 + components: {HistoricalData, CarTree, player},
  56 + props: {},
  57 + data() {
  58 + //这里存放数据"
  59 + return {
  60 + historyData: [],
  61 + //遮罩层
  62 + loading: false,
  63 + //sim号和通道号,格式为:sim-channel
  64 + sim_channel: null,
  65 + //日期快捷选择
  66 + pickerOptions: {
  67 + disabledDate(time) {
  68 + return time.getTime() > Date.now();
  69 + },
  70 + shortcuts: [{
  71 + text: '今天',
  72 + onClick(picker) {
  73 + picker.$emit('pick', new Date());
  74 + }
  75 + }, {
  76 + text: '昨天',
  77 + onClick(picker) {
  78 + const date = new Date();
  79 + date.setTime(date.getTime() - 3600 * 1000 * 24);
  80 + picker.$emit('pick', date);
  81 + }
  82 + }, {
  83 + text: '一周前',
  84 + onClick(picker) {
  85 + const date = new Date();
  86 + date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
  87 + picker.$emit('pick', date);
  88 + }
  89 + }]
  90 + },
  91 + //选中的时间
  92 + timeList: [new Date(2016, 9, 10, 0, 1),
  93 + new Date(2016, 9, 10, 0, 1)],
  94 + //选中的日期
  95 + date: null,
  96 + historyPlayListHtml: '',
  97 + videoUrl: []
  98 + };
  99 + },
  100 + //计算属性 类似于data概念",
  101 + computed: {},
  102 + //监控data中的数据变化",
  103 + watch: {},
  104 + //方法集合",
  105 + methods: {
  106 + /**
  107 + * 点击播放视频
  108 + */
  109 + clickHistoricalPlay(data) {
  110 + this.playHistoryItem(data)
  111 + },
  112 + simChannelChange(val) {
  113 + console.log(val);
  114 + console.log(this.sim_channel)
  115 + },
  116 + /**
  117 + * 下载历史视频
  118 + */
  119 + downloadFunction() {
  120 + this.getDateTime();
  121 + console.log(this.downloadURL);
  122 + if (this.isEmpty(this.downloadURL)) {
  123 + return;
  124 + }
  125 + window.open(this.downloadURL, "_download");
  126 + },
  127 + /**
  128 + * 搜索历史视频
  129 + */
  130 + searchHitoryList() {
  131 + this.getDateTime();
  132 + let simChannel = this.sim_channel;
  133 + if (this.isEmpty(simChannel)) {
  134 + this.$message.error('请选择车辆');
  135 + return;
  136 + }
  137 + let split = simChannel[simChannel.length - 1].split('-');
  138 + let sim = split[0];
  139 + if (this.isEmpty(sim)) {
  140 + this.$message.error('无法获取SIM卡信息,请检查设备');
  141 + return;
  142 + }
  143 + let channel = split[1];
  144 + if (this.isEmpty(channel)) {
  145 + this.$message.error('请选择通道');
  146 + return;
  147 + }
  148 + if (this.isEmpty(this.startTime) || this.isEmpty(this.endTime)) {
  149 + this.$message.error('请选择开始和结束时间');
  150 + return;
  151 + }
  152 + this.loading = true
  153 + this.$axios({
  154 + method: 'get',
  155 + url: '/api/jt1078/query/history/list/' + sim + '/' + channel + "/" + this.startTime + "/" + this.endTime
  156 + }).then(
  157 + res=>{
  158 + let items = res.data.data.obj.data.items;
  159 + if (res && res.data && res.data.data && res.data.data.obj && res.data.data.code == 1 && res.data.data.obj.data && items) {
  160 + for (let i in items) {
  161 + items[i].sim = res.data.data.obj.data.clientId;
  162 + items[i].name = items[i].startTime + '-' + items[i].endTime;
  163 + }
  164 + this.historyData = items
  165 + this.loading = false
  166 + } else if (res && res.data && res.data.data && res.data.data.msg) {
  167 + this.$message.error(res.data.data.msg);
  168 + this.loading = false
  169 + } else {
  170 + this.loading = false
  171 + }
  172 + });
  173 + },
  174 + /**
  175 + * 时间转换
  176 + */
  177 + getDateTime() {
  178 + let date = this.date;
  179 + let timeList = this.timeList;
  180 + console.log(date)
  181 + console.log(timeList)
  182 + if (this.isEmpty(date)) {
  183 + this.$message.error("请选择日期")
  184 + return false;
  185 + }
  186 + if (this.isEmpty(timeList)) {
  187 + this.$message.error("请选择起始时间")
  188 + return false;
  189 + }
  190 + let year = date.getFullYear();
  191 + let month = date.getMonth();
  192 + let day = date.getDate()
  193 + let startTime = timeList[0];
  194 + startTime.setFullYear(year);
  195 + startTime.setMonth(month);
  196 + startTime.setDate(day);
  197 + let endTime = timeList[1];
  198 + endTime.setFullYear(year);
  199 + endTime.setMonth(month);
  200 + endTime.setDate(day);
  201 + startTime = parseTime(startTime, '{y}-{m}-{d} {h}:{i}:{s}');
  202 + endTime = parseTime(endTime, '{y}-{m}-{d} {h}:{i}:{s}');
  203 + console.log("startTime:" + startTime)
  204 + console.log("endTime:" + endTime)
  205 + this.startTime = startTime;
  206 + this.endTime = endTime;
  207 + return true
  208 + },
  209 + /**
  210 + * 播放历史数据
  211 + */
  212 + playHistoryItem(e) {
  213 + this.videoUrl = [];
  214 + this.$axios({
  215 + method: 'get',
  216 + url: '/api/jt1078/query/send/request/io/history/' + e.sim + '/' + e.channelNo + "/" + e.startTime + "/" + e.endTime + "/" + e.channelMapping
  217 + }).then(res=> {
  218 + if (res.data && res.data.data && res.data.data.data) {
  219 + let videoUrl1;
  220 + if (location.protocol === "https:") {
  221 + videoUrl1 = res.data.data.data.wss_flv;
  222 + } else {
  223 + videoUrl1 = res.data.data.data.ws_flv;
  224 + }
  225 + this.downloadURL = res.data.data.data.flv;
  226 + this.port = res.data.data.port;
  227 + this.httpPort = res.data.data.httpPort;
  228 + this.stream = res.data.data.stream;
  229 + this.videoUrlHistory = videoUrl1;
  230 +
  231 + let itemData = new Object();
  232 + itemData.deviceId = this.sim;
  233 + itemData.channelId = this.channel;
  234 + itemData.playUrl = videoUrl1;
  235 + console.log(this.playerIdx);
  236 + this.setPlayUrl(videoUrl1, 0);
  237 + this.hisotoryPlayFlag = true;
  238 +
  239 + } else if (res.data.data && res.data.data.msg) {
  240 + this.$message.error(res.data.data.msg);
  241 + } else if (res.data.msg) {
  242 + this.$message.error(res.data.msg);
  243 + } else if (res.msg) {
  244 + this.$message.error(res.msg);
  245 + }
  246 + this.closeLoading();
  247 + })
  248 + },
  249 +
  250 + /**
  251 + * 实时访问播放地址
  252 + * @param url
  253 + * @param idx
  254 + */
  255 + setPlayUrl(url, idx) {
  256 + this.$set(this.videoUrl, idx, url)
  257 + let _this = this
  258 + setTimeout(() => {
  259 + window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl))
  260 + }, 100)
  261 + },
  262 +
  263 + shot(e) {
  264 + // console.log(e)
  265 + // send({code:'image',data:e})
  266 + var base64ToBlob = function (code) {
  267 + let parts = code.split(';base64,');
  268 + let contentType = parts[0].split(':')[1];
  269 + let raw = window.atob(parts[1]);
  270 + let rawLength = raw.length;
  271 + let uInt8Array = new Uint8Array(rawLength);
  272 + for (let i = 0; i < rawLength; ++i) {
  273 + uInt8Array[i] = raw.charCodeAt(i);
  274 + }
  275 + return new Blob([uInt8Array], {
  276 + type: contentType
  277 + });
  278 + };
  279 + let aLink = document.createElement('a');
  280 + let blob = base64ToBlob(e); //new Blob([content]);
  281 + let evt = document.createEvent("HTMLEvents");
  282 + evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
  283 + aLink.download = '截图';
  284 + aLink.href = URL.createObjectURL(blob);
  285 + aLink.click();
  286 + },
  287 + destroy(idx) {
  288 + console.log(idx);
  289 + this.clear(idx.substring(idx.length - 1))
  290 + },
  291 +
  292 + createdPlay() {
  293 + if (flvjs.isSupported()) {
  294 + // var videoDom = document.getElementById('myVideo')
  295 + console.log(this.videoUrlHistory);
  296 + let videoDom = this.$refs.myVideo
  297 + // 创建一个播放器实例
  298 + var player = flvjs.createPlayer({
  299 + type: 'flv', // 媒体类型,默认是 flv,
  300 + isLive: false, // 是否是直播流
  301 + url: this.videoUrlHistory // 流地址
  302 + }, {
  303 + // 其他的配置项可以根据项目实际情况参考 api 去配置
  304 + autoCleanupMinBackwardDuration: true, // 清除缓存 对 SourceBuffer 进行自动清理
  305 + })
  306 + player.attachMediaElement(videoDom)
  307 + player.load()
  308 + player.play()
  309 + this.player = player
  310 + }
  311 + },
  312 + isEmpty(val) {
  313 + return null == val || undefined == val || "" == val;
  314 + }
  315 +
  316 +
  317 + },
  318 + //生命周期 - 创建完成(可以访问当前this实例)",
  319 + created() {
  320 + },
  321 + //生命周期 - 挂载完成(可以访问DOM元素)",
  322 + mounted() {
  323 + },
  324 + beforeCreate() {
  325 + }, //生命周期 - 创建之前",
  326 + beforeMount() {
  327 + }, //生命周期 - 挂载之前",
  328 + beforeUpdate() {
  329 + }, //生命周期 - 更新之前",
  330 + updated() {
  331 + }, //生命周期 - 更新之后",
  332 + beforeDestroy() {
  333 + }, //生命周期 - 销毁之前",
  334 + destroyed() {
  335 + }, //生命周期 - 销毁完成",
  336 + activated() {
  337 + } //如果页面有keep-alive缓存功能,这个函数会触发",
  338 +};
  339 +</script>
  340 +<style scoped>
  341 +.device-tree-main-box {
  342 + text-align: left;
  343 +}
  344 +
  345 +.btn {
  346 + margin: 0 10px;
  347 +
  348 +}
  349 +
  350 +.btn:hover {
  351 + color: #409EFF;
  352 +}
  353 +
  354 +.btn.active {
  355 + color: #409EFF;
  356 +
  357 +}
  358 +
  359 +.redborder {
  360 + border: 2px solid red !important;
  361 +}
  362 +
  363 +.play-box {
  364 + background-color: #000000;
  365 + border: 2px solid #505050;
  366 + display: flex;
  367 + align-items: center;
  368 + justify-content: center;
  369 +}
  370 +
  371 +.historyListLi {
  372 + width: 97%;
  373 + white-space: nowrap;
  374 + text-overflow: ellipsis;
  375 + cursor: pointer;
  376 + padding: 3px;
  377 + margin-bottom: 6px;
  378 + border: 1px solid #000000;
  379 +}
  380 +
  381 +.historyListDiv {
  382 + height: 80vh;
  383 + width: 100%;
  384 + overflow-y: auto;
  385 + overflow-x: hidden;
  386 +}
  387 +
  388 +
  389 +/* 菜单的样式 */
  390 +.rMenu {
  391 + position: absolute;
  392 + top: 0;
  393 + display: none;
  394 + margin: 0;
  395 + padding: 0;
  396 + text-align: left;
  397 + border: 1px solid #BFBFBF;
  398 + border-radius: 3px;
  399 + background-color: #EEE;
  400 + box-shadow: 0 0 10px #AAA;
  401 +}
  402 +
  403 +.rMenu li {
  404 + width: 170px;
  405 + list-style: none outside none;
  406 + cursor: default;
  407 + color: #666;
  408 + margin-left: -20px;
  409 +}
  410 +
  411 +.rMenu li:hover {
  412 + color: #EEE;
  413 + background-color: #666;
  414 +}
  415 +
  416 +li#menu-item-delete, li#menu-item-rename {
  417 + margin-top: 1px;
  418 +}
  419 +</style>
  420 +<style>
  421 +.videoList {
  422 + display: flex;
  423 + flex-wrap: wrap;
  424 + align-content: flex-start;
  425 +}
  426 +
  427 +.video-item {
  428 + position: relative;
  429 + width: 15rem;
  430 + height: 10rem;
  431 + margin-right: 1rem;
  432 + background-color: #000000;
  433 +}
  434 +
  435 +.video-item-img {
  436 + position: absolute;
  437 + top: 0;
  438 + bottom: 0;
  439 + left: 0;
  440 + right: 0;
  441 + margin: auto;
  442 + width: 100%;
  443 + height: 100%;
  444 +}
  445 +
  446 +.video-item-img:after {
  447 + content: "";
  448 + display: inline-block;
  449 + position: absolute;
  450 + z-index: 2;
  451 + top: 0;
  452 + bottom: 0;
  453 + left: 0;
  454 + right: 0;
  455 + margin: auto;
  456 + width: 3rem;
  457 + height: 3rem;
  458 + background-image: url("../assets/loading.png");
  459 + background-size: cover;
  460 + background-color: #000000;
  461 +}
  462 +
  463 +.video-item-title {
  464 + position: absolute;
  465 + bottom: 0;
  466 + color: #000000;
  467 + background-color: #ffffff;
  468 + line-height: 1.5rem;
  469 + padding: 0.3rem;
  470 + width: 14.4rem;
  471 +}
  472 +
  473 +.baidumap {
  474 + width: 100%;
  475 + height: 100%;
  476 + border: none;
  477 + position: absolute;
  478 + left: 0;
  479 + top: 0;
  480 + right: 0;
  481 + bottom: 0;
  482 + margin: auto;
  483 +}
  484 +
  485 +/* 去除百度地图版权那行字 和 百度logo */
  486 +.baidumap > .BMap_cpyCtrl {
  487 + display: none !important;
  488 +}
  489 +
  490 +.baidumap > .anchorBL {
  491 + display: none !important;
  492 +}
  493 +</style>
web_src/src/components/JT1078Components/cascader/CarTree.vue 0 → 100644
  1 +<template>
  2 + <el-cascader
  3 + placeholder="请选择/搜索车辆"
  4 + :options="options"
  5 + filterable
  6 + clearable
  7 + :props="prop"
  8 + v-model="valueList"
  9 + @change="getValue">
  10 + </el-cascader>
  11 +</template>
  12 +
  13 +<script>
  14 +//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等),
  15 +//例如:import 《组件名称》 from '《组件路径》,
  16 + export default {
  17 + //import引入的组件需要注入到对象中才能使用"
  18 + components: {},
  19 + props: {
  20 + value: {
  21 + type: Array,
  22 + default: []
  23 + }
  24 + },
  25 + data() {
  26 + //这里存放数据"
  27 + return {
  28 + options: [],
  29 + prop: {
  30 + value: 'sim',
  31 + label: `name`,
  32 + children: 'children',
  33 + },
  34 +
  35 + };
  36 + },
  37 + //计算属性 类似于data概念",
  38 + computed: {
  39 + valueList: {
  40 + get(){
  41 + let value = this.value;
  42 + if (value || value === null || value.length === 0) {
  43 + return value
  44 + }
  45 + return value[ value.length - 1 ];
  46 + },
  47 + set(val){
  48 + if (val || val === null || val.length === 0) {
  49 + this.$emit("input",val)
  50 + }
  51 + return val[ val.length - 1 ]
  52 +
  53 + console.log(val)
  54 + }
  55 + }
  56 + },
  57 + //监控data中的数据变化",
  58 + watch: {},
  59 + //方法集合",
  60 + methods: {
  61 + getValue(val){
  62 + console.log(val)
  63 + },
  64 + /**
  65 + * 查询级联数据列表
  66 + */
  67 + initTreeData() {
  68 + this.$axios({
  69 + method: 'get',
  70 + url: `/api/jt1078/query/car/tree/` + 100,
  71 + }).then((res) => {
  72 + if (res && res.data && res.data.data) {
  73 + if (res.data.data.code == 1) {
  74 + let data1 = res.data.data.result;
  75 + this.addChannel(data1);
  76 + } else if (res.data.data.message) {
  77 + this.$message.error(res.data.data.message);
  78 + }
  79 + } else {
  80 + this.$message.error("请求错误,请刷新再试");
  81 + }
  82 +
  83 + });
  84 + },
  85 + /**
  86 + * 整理数据结构
  87 + * @param treeNo
  88 + */
  89 + addChannel(data) {
  90 + for (let i in data) {
  91 + if (data[i] && data[i].sim){
  92 + data[i].name = data[i].code;
  93 + data[i].children = this.transformItems(data[i].sim)
  94 + }else if (data[i].children && data[i].children.length > 0){
  95 + this.addChannel(data[i].children);
  96 + }
  97 + }
  98 + this.options = data
  99 + },
  100 + /**
  101 + * 添加通道
  102 + */
  103 + transformItems(sim) {
  104 + let originalArray = ['ADAS', 'DSM', '路况', '司机', '整车前', '中门', '倒车', '前门客流', '后面客流'];
  105 + return originalArray.map((name, index) => ({
  106 + sim: `${sim}-${index + 1}`, // 创建唯一值,使用SIM号和索引
  107 + name: name
  108 + }));
  109 + }
  110 + },
  111 + //生命周期 - 创建完成(可以访问当前this实例)",
  112 + created() {
  113 + this.initTreeData();
  114 + },
  115 + //生命周期 - 挂载完成(可以访问DOM元素)",
  116 + mounted() {
  117 + },
  118 + beforeCreate() {
  119 + }, //生命周期 - 创建之前",
  120 + beforeMount() {
  121 + }, //生命周期 - 挂载之前",
  122 + beforeUpdate() {
  123 + }, //生命周期 - 更新之前",
  124 + updated() {
  125 + }, //生命周期 - 更新之后",
  126 + beforeDestroy() {
  127 + }, //生命周期 - 销毁之前",
  128 + destroyed() {
  129 + }, //生命周期 - 销毁完成",
  130 + activated() {
  131 + } //如果页面有keep-alive缓存功能,这个函数会触发",
  132 + };
  133 +</script>
  134 +<style scoped>
  135 +
  136 +</style>
web_src/src/components/JT1078Components/historical/HistoricalDataTree.vue 0 → 100644
  1 +<template>
  2 + <el-card class="box-card" style="width: 100%;height: 100%">
  3 + <el-tree v-if="historyData.length > 0" :data="historyData">
  4 + <span class="custom-tree-node" slot-scope="{ node , data }">
  5 + <span>
  6 + <el-button @click="clickButton(data)" style="margin-top: 30px;margin-left: -12px">{{ data.name }}</el-button>
  7 + </span>
  8 + </span>
  9 + </el-tree>
  10 + <el-empty v-else></el-empty>
  11 + </el-card>
  12 +</template>
  13 +<script>
  14 +export default {
  15 + name: 'historical-data',
  16 + props: {
  17 + historyData: {}
  18 + },
  19 + //计算属性 类似于data概念",
  20 + computed: {},
  21 + //监控data中的数据变化",
  22 + watch: {},
  23 + //方法集合",
  24 + methods: {
  25 + //点击事件
  26 + clickButton(data){
  27 + this.$emit('click', data);
  28 + }
  29 + },
  30 + //生命周期 - 创建完成(可以访问当前this实例)",
  31 + created() {
  32 + },
  33 + //生命周期 - 挂载完成(可以访问DOM元素)",
  34 + mounted() {
  35 + },
  36 + beforeCreate() {
  37 + }, //生命周期 - 创建之前",
  38 + beforeMount() {
  39 + }, //生命周期 - 挂载之前",
  40 + beforeUpdate() {
  41 + }, //生命周期 - 更新之前",
  42 + updated() {
  43 + }, //生命周期 - 更新之后",
  44 + beforeDestroy() {
  45 + }, //生命周期 - 销毁之前",
  46 + destroyed() {
  47 + }, //生命周期 - 销毁完成",
  48 + activated() {
  49 + } //如果页面有keep-alive缓存功能,这个函数会触发",
  50 +};
  51 +</script>
  52 +<style>
  53 +
  54 +
  55 +/* 菜单的样式 */
  56 +
  57 +.rMenu li {
  58 + width: 170px;
  59 + list-style: none outside none;
  60 + cursor: default;
  61 + color: #666;
  62 + margin-left: -20px;
  63 +}
  64 +
  65 +.rMenu li:hover {
  66 + color: #EEE;
  67 + background-color: #666;
  68 +}
  69 +.el-tree-node__content {
  70 + padding-bottom: 30px;
  71 + height: 20px;
  72 +}
  73 +
  74 +</style>
web_src/src/components/common/ h265web.vue deleted 100755 → 0
1 -<template>  
2 - <div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #000000;margin:0 auto;">  
3 - <div class="buttons-box" id="buttonsBox">  
4 - <div class="buttons-box-left">  
5 - <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>  
6 - <i v-if="playing" class="iconfont icon-pause jessibuca-btn" @click="pause"></i>  
7 - <i class="iconfont icon-stop jessibuca-btn" @click="destroy"></i>  
8 - <i v-if="isNotMute" class="iconfont icon-audio-high jessibuca-btn" @click="mute()"></i>  
9 - <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="cancelMute()"></i>  
10 - </div>  
11 - <div class="buttons-box-right">  
12 - <span class="jessibuca-btn">{{ kBps }} kb/s</span>  
13 - <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->  
14 - <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->  
15 - <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)"  
16 - style="font-size: 1rem !important"></i>  
17 - <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>  
18 - <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>  
19 - <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i>  
20 - </div>  
21 - </div>  
22 - </div>  
23 -</template>  
24 -  
25 -<script>  
26 -let jessibucaPlayer = {};  
27 -export default {  
28 - name: 'jessibuca',  
29 - data() {  
30 - return {  
31 - playing: false,  
32 - isNotMute: false,  
33 - quieting: false,  
34 - fullscreen: false,  
35 - loaded: false, // mute  
36 - speed: 0,  
37 - performance: "", // 工作情况  
38 - kBps: 0,  
39 - btnDom: null,  
40 - videoInfo: null,  
41 - volume: 1,  
42 - rotate: 0,  
43 - vod: true, // 点播  
44 - forceNoOffscreen: false,  
45 - };  
46 - },  
47 - props: ['videoUrl', 'error', 'hasAudio', 'height'],  
48 - mounted() {  
49 - window.onerror = (msg) => {  
50 - // console.error(msg)  
51 - };  
52 - console.log(this._uid)  
53 - let paramUrl = decodeURIComponent(this.$route.params.url)  
54 - this.$nextTick(() => {  
55 - this.updatePlayerDomSize()  
56 - window.onresize = () => {  
57 - this.updatePlayerDomSize()  
58 - }  
59 - if (typeof (this.videoUrl) == "undefined") {  
60 - this.videoUrl = paramUrl;  
61 - }  
62 - this.btnDom = document.getElementById("buttonsBox");  
63 - console.log("初始化时的地址为: " + this.videoUrl)  
64 - this.play(this.videoUrl)  
65 - })  
66 - },  
67 - watch: {  
68 - videoUrl(newData, oldData) {  
69 - this.play(newData)  
70 - },  
71 - immediate: true  
72 - },  
73 - methods: {  
74 - updatePlayerDomSize() {  
75 - let dom = this.$refs.container;  
76 - let width = dom.parentNode.clientWidth  
77 - let height = (9 / 16) * width  
78 -  
79 - const clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight)  
80 - if (height > clientHeight) {  
81 - height = clientHeight  
82 - width = (16 / 9) * height  
83 - }  
84 -  
85 - dom.style.width = width + 'px';  
86 - dom.style.height = height + "px";  
87 - },  
88 - create() {  
89 - let options = {};  
90 - console.log("hasAudio " + this.hasAudio)  
91 -  
92 - jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign(  
93 - {  
94 - container: this.$refs.container,  
95 - videoBuffer: 0.2, // 最大缓冲时长,单位秒  
96 - isResize: true,  
97 - decoder: "static/js/jessibuca/decoder.js",  
98 - useMSE: false,  
99 - showBandwidth: false,  
100 - isFlv: true,  
101 - // text: "WVP-PRO",  
102 - // background: "static/images/zlm-logo.png",  
103 - loadingText: "加载中",  
104 - hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio,  
105 - debug: false,  
106 - supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。  
107 - operateBtns: {  
108 - fullscreen: false,  
109 - screenshot: false,  
110 - play: false,  
111 - audio: false,  
112 - recorder: false,  
113 - },  
114 - record: "record",  
115 - vod: this.vod,  
116 - forceNoOffscreen: this.forceNoOffscreen,  
117 - isNotMute: this.isNotMute,  
118 - },  
119 - options  
120 - ));  
121 - let jessibuca = jessibucaPlayer[this._uid];  
122 - let _this = this;  
123 - jessibuca.on("load", function () {  
124 - console.log("on load init");  
125 - });  
126 -  
127 - jessibuca.on("log", function (msg) {  
128 - console.log("on log", msg);  
129 - });  
130 - jessibuca.on("record", function (msg) {  
131 - console.log("on record:", msg);  
132 - });  
133 - jessibuca.on("pause", function () {  
134 - _this.playing = false;  
135 - });  
136 - jessibuca.on("play", function () {  
137 - _this.playing = true;  
138 - });  
139 - jessibuca.on("fullscreen", function (msg) {  
140 - console.log("on fullscreen", msg);  
141 - _this.fullscreen = msg  
142 - });  
143 -  
144 - jessibuca.on("mute", function (msg) {  
145 - console.log("on mute", msg);  
146 - _this.isNotMute = !msg;  
147 - });  
148 - jessibuca.on("audioInfo", function (msg) {  
149 - // console.log("audioInfo", msg);  
150 - });  
151 -  
152 - jessibuca.on("videoInfo", function (msg) {  
153 - // this.videoInfo = msg;  
154 - console.log("videoInfo", msg);  
155 -  
156 - });  
157 -  
158 - jessibuca.on("bps", function (bps) {  
159 - // console.log('bps', bps);  
160 -  
161 - });  
162 - let _ts = 0;  
163 - jessibuca.on("timeUpdate", function (ts) {  
164 - // console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);  
165 - _ts = ts;  
166 - });  
167 -  
168 - jessibuca.on("videoInfo", function (info) {  
169 - console.log("videoInfo", info);  
170 - });  
171 -  
172 - jessibuca.on("error", function (error) {  
173 - console.log("error", error);  
174 - });  
175 -  
176 - jessibuca.on("timeout", function () {  
177 - console.log("timeout");  
178 - });  
179 -  
180 - jessibuca.on('start', function () {  
181 - console.log('start');  
182 - })  
183 -  
184 - jessibuca.on("performance", function (performance) {  
185 - let show = "卡顿";  
186 - if (performance === 2) {  
187 - show = "非常流畅";  
188 - } else if (performance === 1) {  
189 - show = "流畅";  
190 - }  
191 - _this.performance = show;  
192 - });  
193 - jessibuca.on('buffer', function (buffer) {  
194 - // console.log('buffer', buffer);  
195 - })  
196 -  
197 - jessibuca.on('stats', function (stats) {  
198 - // console.log('stats', stats);  
199 - })  
200 -  
201 - jessibuca.on('kBps', function (kBps) {  
202 - _this.kBps = Math.round(kBps);  
203 - });  
204 -  
205 - // 显示时间戳 PTS  
206 - jessibuca.on('videoFrame', function () {  
207 -  
208 - })  
209 -  
210 - //  
211 - jessibuca.on('metadata', function () {  
212 -  
213 - });  
214 - },  
215 - playBtnClick: function (event) {  
216 - this.play(this.videoUrl)  
217 - },  
218 - play: function (url) {  
219 - console.log(url)  
220 - if (jessibucaPlayer[this._uid]) {  
221 - this.destroy();  
222 - }  
223 - this.create();  
224 - jessibucaPlayer[this._uid].on("play", () => {  
225 - this.playing = true;  
226 - this.loaded = true;  
227 - this.quieting = jessibuca.quieting;  
228 - });  
229 - if (jessibucaPlayer[this._uid].hasLoaded()) {  
230 - jessibucaPlayer[this._uid].play(url);  
231 - } else {  
232 - jessibucaPlayer[this._uid].on("load", () => {  
233 - console.log("load 播放")  
234 - jessibucaPlayer[this._uid].play(url);  
235 - });  
236 - }  
237 - },  
238 - pause: function () {  
239 - if (jessibucaPlayer[this._uid]) {  
240 - jessibucaPlayer[this._uid].pause();  
241 - }  
242 - this.playing = false;  
243 - this.err = "";  
244 - this.performance = "";  
245 - },  
246 - mute: function () {  
247 - if (jessibucaPlayer[this._uid]) {  
248 - jessibucaPlayer[this._uid].mute();  
249 - }  
250 - },  
251 - cancelMute: function () {  
252 - if (jessibucaPlayer[this._uid]) {  
253 - jessibucaPlayer[this._uid].cancelMute();  
254 - }  
255 - },  
256 - destroy: function () {  
257 - if (jessibucaPlayer[this._uid]) {  
258 - jessibucaPlayer[this._uid].destroy();  
259 - }  
260 - if (document.getElementById("buttonsBox") == null) {  
261 - this.$refs.container.appendChild(this.btnDom)  
262 - }  
263 - jessibucaPlayer[this._uid] = null;  
264 - this.playing = false;  
265 - this.err = "";  
266 - this.performance = "";  
267 -  
268 - },  
269 - eventcallbacK: function (type, message) {  
270 - // console.log("player 事件回调")  
271 - // console.log(type)  
272 - // console.log(message)  
273 - },  
274 - fullscreenSwich: function () {  
275 - let isFull = this.isFullscreen()  
276 - jessibucaPlayer[this._uid].setFullscreen(!isFull)  
277 - this.fullscreen = !isFull;  
278 - },  
279 - isFullscreen: function () {  
280 - return document.fullscreenElement ||  
281 - document.msFullscreenElement ||  
282 - document.mozFullScreenElement ||  
283 - document.webkitFullscreenElement || false;  
284 - }  
285 - },  
286 - destroyed() {  
287 - if (jessibucaPlayer[this._uid]) {  
288 - jessibucaPlayer[this._uid].destroy();  
289 - }  
290 - this.playing = false;  
291 - this.loaded = false;  
292 - this.performance = "";  
293 - },  
294 -}  
295 -</script>  
296 -  
297 -<style>  
298 -.buttons-box {  
299 - width: 100%;  
300 - height: 28px;  
301 - background-color: rgba(43, 51, 63, 0.7);  
302 - position: absolute;  
303 - display: -webkit-box;  
304 - display: -ms-flexbox;  
305 - display: flex;  
306 - left: 0;  
307 - bottom: 0;  
308 - user-select: none;  
309 - z-index: 10;  
310 -}  
311 -  
312 -.jessibuca-btn {  
313 - width: 20px;  
314 - color: rgb(255, 255, 255);  
315 - line-height: 27px;  
316 - margin: 0px 10px;  
317 - padding: 0px 2px;  
318 - cursor: pointer;  
319 - text-align: center;  
320 - font-size: 0.8rem !important;  
321 -}  
322 -  
323 -.buttons-box-right {  
324 - position: absolute;  
325 - right: 0;  
326 -}  
327 -</style>  
web_src/src/layout/UiHeader.vue
@@ -5,9 +5,11 @@ @@ -5,9 +5,11 @@
5 active-text-color="#1890ff" mode="horizontal"> 5 active-text-color="#1890ff" mode="horizontal">
6 6
7 <el-menu-item index="/console">控制台</el-menu-item> 7 <el-menu-item index="/console">控制台</el-menu-item>
8 - 8 +
9 <el-menu-item index="/deviceList1078">设备列表</el-menu-item> 9 <el-menu-item index="/deviceList1078">设备列表</el-menu-item>
10 - 10 +
  11 + <el-menu-item index="/historicalRecord">历史记录</el-menu-item>
  12 +
11 <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item> 13 <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item>
12 14
13 <!-- <el-submenu index="/setting">--> 15 <!-- <el-submenu index="/setting">-->
web_src/src/router/index.js
@@ -26,6 +26,7 @@ import web from &#39;../components/setting/Web.vue&#39; @@ -26,6 +26,7 @@ import web from &#39;../components/setting/Web.vue&#39;
26 26
27 import wasmPlayer from '../components/common/jessibuca.vue' 27 import wasmPlayer from '../components/common/jessibuca.vue'
28 import rtcPlayer from '../components/dialog/rtcPlayer.vue' 28 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
  29 +import historicalRecord from "../components/HistoricalRecord.vue";
29 30
30 const originalPush = VueRouter.prototype.push 31 const originalPush = VueRouter.prototype.push
31 VueRouter.prototype.push = function push(location) { 32 VueRouter.prototype.push = function push(location) {
@@ -61,6 +62,10 @@ export default new VueRouter({ @@ -61,6 +62,10 @@ export default new VueRouter({
61 component: deviceList1078, 62 component: deviceList1078,
62 }, 63 },
63 { 64 {
  65 + path: '/historicalRecord',
  66 + component: historicalRecord,
  67 + },
  68 + {
64 path: '/minhang/deviceList', 69 path: '/minhang/deviceList',
65 name: 'minhang', 70 name: 'minhang',
66 component: minhang, 71 component: minhang,
web_src/utils/cache.js 0 → 100644
  1 +const sessionCache = {
  2 + set (key, value) {
  3 + if (!sessionStorage) {
  4 + return
  5 + }
  6 + if (key != null && value != null) {
  7 + sessionStorage.setItem(key, value)
  8 + }
  9 + },
  10 + get (key) {
  11 + if (!sessionStorage) {
  12 + return null
  13 + }
  14 + if (key == null) {
  15 + return null
  16 + }
  17 + return sessionStorage.getItem(key)
  18 + },
  19 + setJSON (key, jsonValue) {
  20 + if (jsonValue != null) {
  21 + this.set(key, JSON.stringify(jsonValue))
  22 + }
  23 + },
  24 + getJSON (key) {
  25 + const value = this.get(key)
  26 + if (value != null) {
  27 + return JSON.parse(value)
  28 + }
  29 + },
  30 + remove (key) {
  31 + sessionStorage.removeItem(key);
  32 + }
  33 +}
  34 +const localCache = {
  35 + set (key, value) {
  36 + if (!localStorage) {
  37 + return
  38 + }
  39 + if (key != null && value != null) {
  40 + localStorage.setItem(key, value)
  41 + }
  42 + },
  43 + get (key) {
  44 + if (!localStorage) {
  45 + return null
  46 + }
  47 + if (key == null) {
  48 + return null
  49 + }
  50 + return localStorage.getItem(key)
  51 + },
  52 + setJSON (key, jsonValue) {
  53 + if (jsonValue != null) {
  54 + this.set(key, JSON.stringify(jsonValue))
  55 + }
  56 + },
  57 + getJSON (key) {
  58 + const value = this.get(key)
  59 + if (value != null) {
  60 + return JSON.parse(value)
  61 + }
  62 + },
  63 + remove (key) {
  64 + localStorage.removeItem(key);
  65 + }
  66 +}
  67 +
  68 +export default {
  69 + /**
  70 + * 会话级缓存
  71 + */
  72 + session: sessionCache,
  73 + /**
  74 + * 本地缓存
  75 + */
  76 + local: localCache
  77 +}
web_src/utils/request.js 0 → 100644
  1 +import axios from 'axios'
  2 +import { Notification, MessageBox, Message, Loading } from 'element-ui'
  3 +import store from '@/store'
  4 +import { getToken } from '@/utils/auth'
  5 +import errorCode from '@/utils/errorCode'
  6 +import { tansParams, blobValidate } from "@/utils/bashap";
  7 +import cache from '@/utils/cache'
  8 +import { saveAs } from 'file-saver'
  9 +
  10 +let downloadLoadingInstance;
  11 +// 是否显示重新登录
  12 +export let isRelogin = { show: false };
  13 +
  14 +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
  15 +// 创建axios实例
  16 +const service = axios.create({
  17 + // axios中请求配置有baseURL选项,表示请求URL公共部分
  18 + baseURL: process.env.VUE_APP_BASE_API,
  19 + // 超时
  20 + timeout: 10000
  21 +})
  22 +
  23 +// request拦截器
  24 +service.interceptors.request.use(config => {
  25 + // 是否需要设置 token
  26 + const isToken = (config.headers || {}).isToken === false
  27 + // 是否需要防止数据重复提交
  28 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  29 + if (getToken() && !isToken) {
  30 + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  31 + }
  32 + // get请求映射params参数
  33 + if (config.method === 'get' && config.params) {
  34 + let url = config.url + '?' + tansParams(config.params);
  35 + url = url.slice(0, -1);
  36 + config.params = {};
  37 + config.url = url;
  38 + }
  39 + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
  40 + const requestObj = {
  41 + url: config.url,
  42 + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
  43 + time: new Date().getTime()
  44 + }
  45 + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
  46 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
  47 + if (requestSize >= limitSize) {
  48 + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
  49 + return config;
  50 + }
  51 + const sessionObj = cache.session.getJSON('sessionObj')
  52 + if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
  53 + cache.session.setJSON('sessionObj', requestObj)
  54 + } else {
  55 + const s_url = sessionObj.url; // 请求地址
  56 + const s_data = sessionObj.data; // 请求数据
  57 + const s_time = sessionObj.time; // 请求时间
  58 + const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
  59 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
  60 + const message = '数据正在处理,请勿重复提交';
  61 + console.warn(`[${s_url}]: ` + message)
  62 + return Promise.reject(new Error(message))
  63 + } else {
  64 + cache.session.setJSON('sessionObj', requestObj)
  65 + }
  66 + }
  67 + }
  68 + return config
  69 +}, error => {
  70 + console.log(error)
  71 + Promise.reject(error)
  72 +})
  73 +
  74 +// 响应拦截器
  75 +service.interceptors.response.use(res => {
  76 + // 未设置状态码则默认成功状态
  77 + const code = res.data.code || 200;
  78 + // 获取错误信息
  79 + const msg = errorCode[code] || res.data.msg || errorCode['default']
  80 + // 二进制数据则直接返回
  81 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
  82 + return res.data
  83 + }
  84 + if (code === 401) {
  85 + if (!isRelogin.show) {
  86 + isRelogin.show = true;
  87 + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
  88 + store.dispatch('LogOut').then(() => {
  89 + // location.href = '/index';
  90 + //单点开始
  91 + location.href = '/getInfo';
  92 + //单点结束
  93 + })
  94 + }).catch(() => {
  95 + isRelogin.show = false;
  96 + });
  97 + }
  98 + return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  99 + } else if (code === 500) {
  100 + Message({ message: msg, type: 'error' })
  101 + return Promise.reject(new Error(msg))
  102 + } else if (code === 601) {
  103 + Message({ message: msg, type: 'warning' })
  104 + return Promise.reject('error')
  105 + } else if (code !== 200) {
  106 + Notification.error({ title: msg })
  107 + return Promise.reject('error')
  108 + } else {
  109 + return res.data
  110 + }
  111 + },
  112 + error => {
  113 + console.log('err' + error)
  114 + let { message } = error;
  115 + if (message == "Network Error") {
  116 + message = "后端接口连接异常";
  117 + } else if (message.includes("timeout")) {
  118 + message = "系统接口请求超时";
  119 + } else if (message.includes("Request failed with status code")) {
  120 + message = "系统接口" + message.substr(message.length - 3) + "异常";
  121 + }
  122 + Message({ message: message, type: 'error', duration: 5 * 1000 })
  123 + return Promise.reject(error)
  124 + }
  125 +)
  126 +
  127 +// 通用下载方法
  128 +export function download(url, params, filename, config) {
  129 + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  130 + return service.post(url, params, {
  131 + transformRequest: [(params) => { return tansParams(params) }],
  132 + headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  133 + responseType: 'blob',
  134 + ...config
  135 + }).then(async (data) => {
  136 + const isBlob = blobValidate(data);
  137 + if (isBlob) {
  138 + const blob = new Blob([data])
  139 + saveAs(blob, filename)
  140 + } else {
  141 + const resText = await data.text();
  142 + const rspObj = JSON.parse(resText);
  143 + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  144 + Message.error(errMsg);
  145 + }
  146 + downloadLoadingInstance.close();
  147 + }).catch((r) => {
  148 + console.error(r)
  149 + Message.error('下载文件出现错误,请联系管理员!')
  150 + downloadLoadingInstance.close();
  151 + })
  152 +}
  153 +
  154 +export default service
web_src/utils/ruoyi.js 0 → 100644
  1 +
  2 +
  3 +/**
  4 + * 通用js方法封装处理
  5 + * Copyright (c) 2019 ruoyi
  6 + */
  7 +
  8 +// 日期格式化
  9 +export function parseTime(time, pattern) {
  10 + if (arguments.length === 0 || !time) {
  11 + return null
  12 + }
  13 + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  14 + let date
  15 + if (typeof time === 'object') {
  16 + date = time
  17 + } else {
  18 + if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
  19 + time = parseInt(time)
  20 + } else if (typeof time === 'string') {
  21 + time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
  22 + }
  23 + if ((typeof time === 'number') && (time.toString().length === 10)) {
  24 + time = time * 1000
  25 + }
  26 + date = new Date(time)
  27 + }
  28 + const formatObj = {
  29 + y: date.getFullYear(),
  30 + m: date.getMonth() + 1,
  31 + d: date.getDate(),
  32 + h: date.getHours(),
  33 + i: date.getMinutes(),
  34 + s: date.getSeconds(),
  35 + a: date.getDay()
  36 + }
  37 + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
  38 + let value = formatObj[key]
  39 + // Note: getDay() returns 0 on Sunday
  40 + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
  41 + if (result.length > 0 && value < 10) {
  42 + value = '0' + value
  43 + }
  44 + return value || 0
  45 + })
  46 + return time_str
  47 +}
  48 +
  49 +// 表单重置
  50 +export function resetForm(refName) {
  51 + if (this.$refs[refName]) {
  52 + this.$refs[refName].resetFields();
  53 + }
  54 +}
  55 +
  56 +// 添加日期范围
  57 +export function addDateRange(params, dateRange, propName) {
  58 + let search = params;
  59 + search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
  60 + dateRange = Array.isArray(dateRange) ? dateRange : [];
  61 + if (typeof (propName) === 'undefined') {
  62 + search.params['beginTime'] = dateRange[0];
  63 + search.params['endTime'] = dateRange[1];
  64 + } else {
  65 + search.params['begin' + propName] = dateRange[0];
  66 + search.params['end' + propName] = dateRange[1];
  67 + }
  68 + return search;
  69 +}
  70 +
  71 +// 回显数据字典
  72 +export function selectDictLabel(datas, value) {
  73 + if (value === undefined) {
  74 + return "";
  75 + }
  76 + var actions = [];
  77 + Object.keys(datas).some((key) => {
  78 + if (datas[key].value == ('' + value)) {
  79 + actions.push(datas[key].label);
  80 + return true;
  81 + }
  82 + })
  83 + if (actions.length === 0) {
  84 + actions.push(value);
  85 + }
  86 + return actions.join('');
  87 +}
  88 +
  89 +// 回显数据字典(字符串、数组)
  90 +export function selectDictLabels(datas, value, separator) {
  91 + if (value === undefined || value.length ===0) {
  92 + return "";
  93 + }
  94 + if (Array.isArray(value)) {
  95 + value = value.join(",");
  96 + }
  97 + var actions = [];
  98 + var currentSeparator = undefined === separator ? "," : separator;
  99 + var temp = value.split(currentSeparator);
  100 + Object.keys(value.split(currentSeparator)).some((val) => {
  101 + var match = false;
  102 + Object.keys(datas).some((key) => {
  103 + if (datas[key].value == ('' + temp[val])) {
  104 + actions.push(datas[key].label + currentSeparator);
  105 + match = true;
  106 + }
  107 + })
  108 + if (!match) {
  109 + actions.push(temp[val] + currentSeparator);
  110 + }
  111 + })
  112 + return actions.join('').substring(0, actions.join('').length - 1);
  113 +}
  114 +
  115 +// 字符串格式化(%s )
  116 +export function sprintf(str) {
  117 + var args = arguments, flag = true, i = 1;
  118 + str = str.replace(/%s/g, function () {
  119 + var arg = args[i++];
  120 + if (typeof arg === 'undefined') {
  121 + flag = false;
  122 + return '';
  123 + }
  124 + return arg;
  125 + });
  126 + return flag ? str : '';
  127 +}
  128 +
  129 +// 转换字符串,undefined,null等转化为""
  130 +export function parseStrEmpty(str) {
  131 + if (!str || str == "undefined" || str == "null") {
  132 + return "";
  133 + }
  134 + return str;
  135 +}
  136 +
  137 +// 数据合并
  138 +export function mergeRecursive(source, target) {
  139 + for (var p in target) {
  140 + try {
  141 + if (target[p].constructor == Object) {
  142 + source[p] = mergeRecursive(source[p], target[p]);
  143 + } else {
  144 + source[p] = target[p];
  145 + }
  146 + } catch (e) {
  147 + source[p] = target[p];
  148 + }
  149 + }
  150 + return source;
  151 +};
  152 +
  153 +/**
  154 + * 构造树型结构数据
  155 + * @param {*} data 数据源
  156 + * @param {*} id id字段 默认 'id'
  157 + * @param {*} parentId 父节点字段 默认 'parentId'
  158 + * @param {*} children 孩子节点字段 默认 'children'
  159 + */
  160 +export function handleTree(data, id, parentId, children) {
  161 + let config = {
  162 + id: id || 'id',
  163 + parentId: parentId || 'parentId',
  164 + childrenList: children || 'children'
  165 + };
  166 +
  167 + var childrenListMap = {};
  168 + var nodeIds = {};
  169 + var tree = [];
  170 +
  171 + for (let d of data) {
  172 + let parentId = d[config.parentId];
  173 + if (childrenListMap[parentId] == null) {
  174 + childrenListMap[parentId] = [];
  175 + }
  176 + nodeIds[d[config.id]] = d;
  177 + childrenListMap[parentId].push(d);
  178 + }
  179 +
  180 + for (let d of data) {
  181 + let parentId = d[config.parentId];
  182 + if (nodeIds[parentId] == null) {
  183 + tree.push(d);
  184 + }
  185 + }
  186 +
  187 + for (let t of tree) {
  188 + adaptToChildrenList(t);
  189 + }
  190 +
  191 + function adaptToChildrenList(o) {
  192 + if (childrenListMap[o[config.id]] !== null) {
  193 + o[config.childrenList] = childrenListMap[o[config.id]];
  194 + }
  195 + if (o[config.childrenList]) {
  196 + for (let c of o[config.childrenList]) {
  197 + adaptToChildrenList(c);
  198 + }
  199 + }
  200 + }
  201 + return tree;
  202 +}
  203 +
  204 +/**
  205 +* 参数处理
  206 +* @param {*} params 参数
  207 +*/
  208 +export function tansParams(params) {
  209 + let result = ''
  210 + for (const propName of Object.keys(params)) {
  211 + const value = params[propName];
  212 + var part = encodeURIComponent(propName) + "=";
  213 + if (value !== null && value !== "" && typeof (value) !== "undefined") {
  214 + if (typeof value === 'object') {
  215 + for (const key of Object.keys(value)) {
  216 + if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
  217 + let params = propName + '[' + key + ']';
  218 + var subPart = encodeURIComponent(params) + "=";
  219 + result += subPart + encodeURIComponent(value[key]) + "&";
  220 + }
  221 + }
  222 + } else {
  223 + result += part + encodeURIComponent(value) + "&";
  224 + }
  225 + }
  226 + }
  227 + return result
  228 +}
  229 +
  230 +// 验证是否为blob格式
  231 +export function blobValidate(data) {
  232 + return data.type !== 'application/json'
  233 +}