[1078] 合并新UI

This commit is contained in:
lin 2025-05-16 15:17:35 +08:00
parent 7c5cee5d87
commit 420b3889c5
4 changed files with 105 additions and 138 deletions

View File

@ -1,8 +1,8 @@
package com.genersoft.iot.vmp.conf.ftpServer; package com.genersoft.iot.vmp.conf.ftpServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.ftpserver.*; import org.apache.ftpserver.*;
import org.apache.ftpserver.ftplet.FtpException; import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.listener.Listener; import org.apache.ftpserver.listener.Listener;
import org.apache.ftpserver.listener.ListenerFactory; import org.apache.ftpserver.listener.ListenerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -15,13 +15,17 @@ import java.util.Map;
@Configuration @Configuration
@ConditionalOnProperty(value = "ftp.enable", havingValue = "true") @ConditionalOnProperty(value = "ftp.enable", havingValue = "true")
@Slf4j
public class FtpServerConfig { public class FtpServerConfig {
@Autowired @Autowired
private UserManager userManager; private UserManager userManager;
@Autowired @Autowired
private ftplet ftpPlet; private Ftplet ftpPlet;
@Autowired
private FtpSetting ftpSetting;
/** /**
* ftp server init * ftp server init
@ -30,17 +34,17 @@ public class FtpServerConfig {
public FtpServer ftpServer() { public FtpServer ftpServer() {
FtpServerFactory serverFactory = new FtpServerFactory(); FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory listenerFactory = new ListenerFactory(); ListenerFactory listenerFactory = new ListenerFactory();
// //1设置服务端口 // 1设置服务端口
listenerFactory.setPort(3131); listenerFactory.setPort(ftpSetting.getPort());
// 2设置被动模式数据上传的接口范围,云服务器需要开放对应区间的端口给客户端 // 2设置被动模式数据上传的接口范围,云服务器需要开放对应区间的端口给客户端
DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory(); DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
dataConnectionConfFactory.setPassivePorts("10000-10500"); dataConnectionConfFactory.setPassivePorts(ftpSetting.getPassivePorts());
listenerFactory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration()); listenerFactory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
// 4替换默认的监听器 // 4替换默认的监听器
Listener listener = listenerFactory.createListener(); Listener listener = listenerFactory.createListener();
serverFactory.addListener("default", listener); serverFactory.addListener("default", listener);
// 5配置自定义用户事件 // 5配置自定义用户事件
Map<String, Ftplet> ftpLets = new HashMap(); Map<String, org.apache.ftpserver.ftplet.Ftplet> ftpLets = new HashMap<>();
ftpLets.put("ftpService", ftpPlet); ftpLets.put("ftpService", ftpPlet);
serverFactory.setFtplets(ftpLets); serverFactory.setFtplets(ftpLets);
// 6读取用户的配置信息 // 6读取用户的配置信息
@ -50,8 +54,11 @@ public class FtpServerConfig {
FtpServer server = serverFactory.createServer(); FtpServer server = serverFactory.createServer();
try { try {
server.start(); server.start();
if (!server.isStopped()) {
log.info("[FTP服务] 已启动, 端口: {}", ftpSetting.getPort());
}
} catch (FtpException e) { } catch (FtpException e) {
System.out.println("ftp-启动失败" + e.getMessage()); log.info("[FTP服务] 启动失败 ", e);
} }
return server; return server;
} }

View File

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.conf.ftpServer; package com.genersoft.iot.vmp.conf.ftpServer;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -10,6 +11,7 @@ import org.springframework.stereotype.Component;
@Component @Component
@ConfigurationProperties(prefix = "ftp", ignoreInvalidFields = true) @ConfigurationProperties(prefix = "ftp", ignoreInvalidFields = true)
@Order(0) @Order(0)
@Data
public class FtpSetting { public class FtpSetting {
private Boolean enable = Boolean.FALSE; private Boolean enable = Boolean.FALSE;
@ -18,44 +20,5 @@ public class FtpSetting {
private int port = 21; private int port = 21;
private String username = "admin"; private String username = "admin";
private String password = "admin"; private String password = "admin";
private String passivePorts = "10000-10500";
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
} }

View File

@ -13,9 +13,9 @@ import java.io.IOException;
@Component @Component
public class ftplet extends DefaultFtplet { public class Ftplet extends DefaultFtplet {
private final Logger logger = LoggerFactory.getLogger(ftplet.class); private final Logger logger = LoggerFactory.getLogger(Ftplet.class);
@Value("${ftp.username}") @Value("${ftp.username}")
private String username; private String username;

View File

@ -89,17 +89,25 @@
title="截图" title="截图"
@click="snap()" @click="snap()"
/> />
<a
target="_blank"
class="record-play-control-item iconfont icon-xiazai1"
title="下载录像"
@click="chooseTimeForRecord()"
/>
<!-- <a target="_blank" class="record-play-control-item iconfont icon-xiazai011" title="下载" @click="gbPause()" />--> <!-- <a target="_blank" class="record-play-control-item iconfont icon-xiazai011" title="下载" @click="gbPause()" />-->
</div> </div>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
<div class="record-play-control"> <div class="record-play-control">
<el-dropdown @command="scale">
<a
target="_blank"
class="record-play-control-item record-play-control-speed"
title="倍速播放"
>快退</a>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="[4, 1]">1X</el-dropdown-item>
<el-dropdown-item :command="[4, 2]">2X</el-dropdown-item>
<el-dropdown-item :command="[4, 4]">4X</el-dropdown-item>
<el-dropdown-item :command="[4, 8]">8X</el-dropdown-item>
<el-dropdown-item :command="[4, 16]">16X</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<a <a
v-if="chooseFileIndex > 0" v-if="chooseFileIndex > 0"
target="_blank" target="_blank"
@ -114,12 +122,6 @@
class="record-play-control-item iconfont icon-diyigeshipin" class="record-play-control-item iconfont icon-diyigeshipin"
title="上一个" title="上一个"
/> />
<a
target="_blank"
class="record-play-control-item iconfont icon-kuaijin"
title="快退五秒"
@click="seekBackward()"
/>
<a <a
target="_blank" target="_blank"
class="record-play-control-item iconfont icon-stop1" class="record-play-control-item iconfont icon-stop1"
@ -134,12 +136,12 @@
title="暂停" title="暂停"
@click="pausePlay()" @click="pausePlay()"
/> />
<a v-if="!playing" target="_blank" class="record-play-control-item iconfont icon-kaishi" title="播放" @click="play()" />
<a <a
v-if="!playing"
target="_blank" target="_blank"
class="record-play-control-item iconfont icon-houtui" class="record-play-control-item iconfont icon-kaishi"
title="快进五秒" title="播放"
@click="seekForward()" @click="play()"
/> />
<a <a
v-if="chooseFileIndex < detailFiles.length - 1" v-if="chooseFileIndex < detailFiles.length - 1"
@ -156,23 +158,18 @@
title="下一个" title="下一个"
@click="playNext()" @click="playNext()"
/> />
<el-dropdown @command="changePlaySpeed"> <el-dropdown @command="scale">
<a <a
target="_blank" target="_blank"
class="record-play-control-item record-play-control-speed" class="record-play-control-item record-play-control-speed"
title="倍速播放" title="倍速播放"
>快进/快退</a> >快进</a>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="[3, 1]">正常快进</el-dropdown-item> <el-dropdown-item :command="[3, 1]">1X</el-dropdown-item>
<el-dropdown-item :command="[3, 2]">2倍速快进</el-dropdown-item> <el-dropdown-item :command="[3, 2]">2X</el-dropdown-item>
<el-dropdown-item :command="[3, 4]">4倍速快进</el-dropdown-item> <el-dropdown-item :command="[3, 4]">4X</el-dropdown-item>
<el-dropdown-item :command="[3, 8]">8倍速快进</el-dropdown-item> <el-dropdown-item :command="[3, 8]">8X</el-dropdown-item>
<el-dropdown-item :command="[3, 16]">16倍速快进</el-dropdown-item> <el-dropdown-item :command="[3, 16]">16X</el-dropdown-item>
<el-dropdown-item :command="[4, 1]">正常快退</el-dropdown-item>
<el-dropdown-item :command="[4, 2]">2倍速快退</el-dropdown-item>
<el-dropdown-item :command="[4, 4]">4倍速快退</el-dropdown-item>
<el-dropdown-item :command="[4, 8]">8倍速快退</el-dropdown-item>
<el-dropdown-item :command="[4, 16]">16倍速快退</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</div> </div>
@ -302,25 +299,6 @@ export default {
snap() { snap() {
this.$refs.recordVideoPlayer.screenshot() this.$refs.recordVideoPlayer.screenshot()
}, },
chooseTimeForRecord() {
let startTime = this.startTime
let endTime = this.endTime
if (this.detailFiles.length > 0) {
startTime = this.detailFiles[0].startTime
endTime = this.detailFiles[this.detailFiles.length - 1].endTime
}
console.log(startTime)
console.log(endTime)
this.$refs.chooseTimeRange.openDialog([new Date(startTime), new Date(endTime)], (time) => {
console.log(time)
const startTime = moment(time[0]).format('YYYY-MM-DD HH:mm:ss')
const endTime = moment(time[1]).format('YYYY-MM-DD HH:mm:ss')
this.downloadFile({
startTime: startTime,
endTime: endTime
})
})
},
playLast() { playLast() {
// //
if (this.chooseFileIndex === 0) { if (this.chooseFileIndex === 0) {
@ -335,36 +313,30 @@ export default {
} }
this.chooseFile(this.chooseFileIndex + 1) this.chooseFile(this.chooseFileIndex + 1)
}, },
changePlaySpeed(speed) { scale(command) {
console.log(this.streamInfo) this.control(command[0], command[1])
console.log(speed) },
control(command, playbackSpeed, time) {
// //
this.playSpeed = speed this.playSpeed = playbackSpeed
this.$store.dispatch('playback/setSpeed', [this.streamInfo.stream, speed]) this.$refs.recordVideoPlayer.setPlaybackRate(parseFloat(this.playSpeed))
.then(data => { this.$store.dispatch('jtDevice/controlPlayback', {
this.$refs.recordVideoPlayer.setPlaybackRate(this.playSpeed) phoneNumber: this.phoneNumber,
channelId: this.channelId,
command: command,
playbackSpeed: playbackSpeed,
time: time
}) })
.catch((err) => {
console.log(err)
})
},
seekBackward() {
// 退
this.playSeekValue -= 5 * 1000
this.play()
},
seekForward() {
//
this.playSeekValue += 5 * 1000
this.play()
}, },
stopPLay() { stopPLay() {
// //
this.$refs.recordVideoPlayer.destroy() this.$refs.recordVideoPlayer.destroy()
this.stopPlayRecord()
}, },
pausePlay() { pausePlay() {
// //
this.$refs.recordVideoPlayer.pause() this.$refs.recordVideoPlayer.pause()
this.control(1, 0)
}, },
play() { play() {
if (this.$refs.recordVideoPlayer.loaded) { if (this.$refs.recordVideoPlayer.loaded) {
@ -448,6 +420,7 @@ export default {
playRecord(startTime, endTime) { playRecord(startTime, endTime) {
if (this.streamInfo !== null) { if (this.streamInfo !== null) {
this.stopPlayRecord(() => { this.stopPlayRecord(() => {
this.streamInfo = null
this.playRecord(startTime, endTime) this.playRecord(startTime, endTime)
}) })
} else { } else {
@ -491,22 +464,46 @@ export default {
this.downloadFile(row) this.downloadFile(row)
}) })
} else { } else {
this.downloadRecord(row)
}
},
downloadRecord: function(row) {
const loading = this.$loading({ const loading = this.$loading({
lock: true, lock: true,
text: '正在请求录像', text: '正在请求录像',
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
this.$store.dispatch('gbRecord/startDownLoad', [ const baseUrl = window.baseUrl ? window.baseUrl : ''
this.deviceId, this.channelId, row.startTime, row.endTime, this.playSpeedRange[this.playSpeedRange.length - 1] const downloadFileUrl = ((process.env.NODE_ENV === 'development') ? process.env.VUE_APP_BASE_API : baseUrl) +
]) `/api/jt1078/playback/download?phoneNumber=${this.phoneNumber}&channelId=${this.channelId}&startTime=${row.startTime}&endTime=${row.endTime}` +
.then(streamInfo => { `&alarmSign=${row.alarmSign}&mediaType=${row.mediaType}&streamType=${row.streamType}&storageType=${row.storageType}&access-token=${this.$store.getters.token}`
this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId) const x = new XMLHttpRequest()
}) x.open('GET', downloadFileUrl, true)
.finally(() => { x.responseType = 'blob'
x.onload = (e) => {
const url = window.URL.createObjectURL(x.response)
const a = document.createElement('a')
a.href = url
a.download = this.phoneNumber + '-' + this.channelId + '.mp4'
a.click()
loading.close() loading.close()
}
x.ontimeout = (e) => {
loading.close()
this.$message.error({
showClose: true,
message: '加载超时'
}) })
} }
x.onerror = (e) => {
loading.close()
this.$message.error({
showClose: true,
message: e.error
})
}
x.send()
}, },
getFileShowName(item) { getFileShowName(item) {
return moment(item.startTime).format('HH:mm:ss') + '-' + moment(item.endTime).format('HH:mm:ss') return moment(item.startTime).format('HH:mm:ss') + '-' + moment(item.endTime).format('HH:mm:ss')